Initial commit.
commit
a865abc08b
|
@ -0,0 +1,3 @@
|
||||||
|
.*.swp
|
||||||
|
*.png
|
||||||
|
*.dot
|
|
@ -0,0 +1,98 @@
|
||||||
|
--[[
|
||||||
|
Copyright (c) 2010-2013 Matthias Richter
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name(s) of the above copyright holders
|
||||||
|
shall not be used in advertising or otherwise to promote the sale, use or
|
||||||
|
other dealings in this Software without prior written authorization.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local function include_helper(to, from, seen)
|
||||||
|
if from == nil then
|
||||||
|
return to
|
||||||
|
elseif type(from) ~= 'table' then
|
||||||
|
return from
|
||||||
|
elseif seen[from] then
|
||||||
|
return seen[from]
|
||||||
|
end
|
||||||
|
|
||||||
|
seen[from] = to
|
||||||
|
for k,v in pairs(from) do
|
||||||
|
k = include_helper({}, k, seen) -- keys might also be tables
|
||||||
|
if to[k] == nil then
|
||||||
|
to[k] = include_helper({}, v, seen)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return to
|
||||||
|
end
|
||||||
|
|
||||||
|
-- deeply copies `other' into `class'. keys in `other' that are already
|
||||||
|
-- defined in `class' are omitted
|
||||||
|
local function include(class, other)
|
||||||
|
return include_helper(class, other, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- returns a deep copy of `other'
|
||||||
|
local function clone(other)
|
||||||
|
return setmetatable(include({}, other), getmetatable(other))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function new(class)
|
||||||
|
-- mixins
|
||||||
|
class = class or {} -- class can be nil
|
||||||
|
local inc = class.__includes or {}
|
||||||
|
if getmetatable(inc) then inc = {inc} end
|
||||||
|
|
||||||
|
for _, other in ipairs(inc) do
|
||||||
|
if type(other) == "string" then
|
||||||
|
other = _G[other]
|
||||||
|
end
|
||||||
|
include(class, other)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- class implementation
|
||||||
|
class.__index = class
|
||||||
|
class.init = class.init or class[1] or function() end
|
||||||
|
class.include = class.include or include
|
||||||
|
class.clone = class.clone or clone
|
||||||
|
|
||||||
|
-- constructor call
|
||||||
|
return setmetatable(class, {__call = function(c, ...)
|
||||||
|
local o = setmetatable({}, c)
|
||||||
|
o:init(...)
|
||||||
|
return o
|
||||||
|
end})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- interface for cross class-system compatibility (see https://github.com/bartbes/Class-Commons).
|
||||||
|
if class_commons ~= false and not common then
|
||||||
|
common = {}
|
||||||
|
function common.class(name, prototype, parent)
|
||||||
|
return new{__includes = {prototype, parent}}
|
||||||
|
end
|
||||||
|
function common.instance(class, ...)
|
||||||
|
return class(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- the module
|
||||||
|
return setmetatable({new = new, include = include, clone = clone},
|
||||||
|
{__call = function(_,...) return new(...) end})
|
|
@ -0,0 +1,128 @@
|
||||||
|
#!/usr/bin/lua
|
||||||
|
|
||||||
|
--require 'strict'
|
||||||
|
|
||||||
|
local Class = require 'class'
|
||||||
|
|
||||||
|
Edge = Class {
|
||||||
|
init = function (self, s_node, e_node, label)
|
||||||
|
self.s = s_node
|
||||||
|
self.e = e_node
|
||||||
|
self.label = label
|
||||||
|
self.directed = false
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
Node = Class {
|
||||||
|
init = function (self, label)
|
||||||
|
self.label = label
|
||||||
|
self.edges = {}
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
Graph = Class {
|
||||||
|
init = function (self, name)
|
||||||
|
self.name = name
|
||||||
|
self.start_node = {}
|
||||||
|
self.end_node = {}
|
||||||
|
self.nodes = {}
|
||||||
|
self.edges = {}
|
||||||
|
end,
|
||||||
|
|
||||||
|
writeDotFile = function (self, filename)
|
||||||
|
print ("writing file: " .. filename .. ".png")
|
||||||
|
local outfile = io.open (filename .. ".dot", "w+")
|
||||||
|
|
||||||
|
outfile:write("digraph dungeon {\n")
|
||||||
|
|
||||||
|
for i,e in ipairs (self.edges) do
|
||||||
|
outfile:write (e.s.label .. " -> " .. e.e.label)
|
||||||
|
|
||||||
|
local options = {}
|
||||||
|
|
||||||
|
if e.directed == false then
|
||||||
|
table.insert (options, "dir=none")
|
||||||
|
end
|
||||||
|
|
||||||
|
if e.label ~= "" then
|
||||||
|
table.insert (options, "label=" .. e.label)
|
||||||
|
end
|
||||||
|
|
||||||
|
local have_options = #options > 0
|
||||||
|
if have_options then
|
||||||
|
outfile:write (" [")
|
||||||
|
end
|
||||||
|
|
||||||
|
for i,v in ipairs(options) do
|
||||||
|
if i > 1 then
|
||||||
|
outfile:write (", ")
|
||||||
|
end
|
||||||
|
outfile:write (v)
|
||||||
|
end
|
||||||
|
|
||||||
|
if have_options then
|
||||||
|
outfile:write(" ]")
|
||||||
|
end
|
||||||
|
|
||||||
|
outfile:write ("\n")
|
||||||
|
end
|
||||||
|
outfile:write("}\n")
|
||||||
|
|
||||||
|
outfile:close()
|
||||||
|
|
||||||
|
os.execute ("dot -Tpng " .. filename .. ".dot -o " .. filename .. ".png")
|
||||||
|
os.execute ("eog " .. filename .. ".png")
|
||||||
|
end,
|
||||||
|
|
||||||
|
insertSubGraph = function (self, edge_index, subgraph)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_simple()
|
||||||
|
local graph = Graph("simple")
|
||||||
|
|
||||||
|
local start_node = Node("SimpleStart")
|
||||||
|
local goal_node = Node("SimpleGoal")
|
||||||
|
local se_edge = Edge(start_node, goal_node, "se")
|
||||||
|
se_edge.directed = true
|
||||||
|
local es_edge = Edge(goal_node, start_node, "es")
|
||||||
|
|
||||||
|
graph.start_node = start_node
|
||||||
|
graph.goal_node = goal_node
|
||||||
|
table.insert (graph.nodes, start_node)
|
||||||
|
table.insert (graph.nodes, goal_node)
|
||||||
|
table.insert (graph.edges, se_edge)
|
||||||
|
table.insert (graph.edges, es_edge)
|
||||||
|
|
||||||
|
return graph
|
||||||
|
end
|
||||||
|
|
||||||
|
function create_lock()
|
||||||
|
local graph = Graph("lock")
|
||||||
|
|
||||||
|
local start_node = Node("LockStart")
|
||||||
|
local goal_node = Node("LockGoal")
|
||||||
|
local lock_node = Node("Lock")
|
||||||
|
local sl_edge = Edge(start_node, lock_node, "sl")
|
||||||
|
local ls_edge = Edge(lock_node, start_node, "ls_key")
|
||||||
|
ls_edge.directed = true
|
||||||
|
local lg_edge = Edge(lock_node, goal_node, "lg")
|
||||||
|
|
||||||
|
graph.start_node = start_node
|
||||||
|
graph.goal_node = goal_node
|
||||||
|
|
||||||
|
table.insert (graph.nodes, start_node)
|
||||||
|
table.insert (graph.nodes, lock_node)
|
||||||
|
table.insert (graph.nodes, goal_node)
|
||||||
|
table.insert (graph.edges, sl_edge)
|
||||||
|
table.insert (graph.edges, ls_edge)
|
||||||
|
table.insert (graph.edges, lg_edge)
|
||||||
|
|
||||||
|
return graph
|
||||||
|
end
|
||||||
|
|
||||||
|
local simple = create_simple()
|
||||||
|
simple:writeDotFile("simple")
|
||||||
|
|
||||||
|
local lock = create_lock()
|
||||||
|
lock:writeDotFile("lock_graph")
|
|
@ -0,0 +1,122 @@
|
||||||
|
--- Checks uses of undeclared global variables.
|
||||||
|
-- All global variables must be 'declared' through a regular assignment
|
||||||
|
-- (even assigning nil will do) in a main chunk before being used
|
||||||
|
-- anywhere or assigned to inside a function. Existing metatables __newindex and __index
|
||||||
|
-- metamethods are respected.
|
||||||
|
--
|
||||||
|
-- You can set any table to have strict behaviour using strict.module. Creating a new
|
||||||
|
-- module with strict.closed_module makes the module immune to monkey-patching, if
|
||||||
|
-- you don't wish to encourage monkey business.
|
||||||
|
--
|
||||||
|
-- If the global PENLIGHT_NO_GLOBAL_STRICT is defined, then this module won't make the
|
||||||
|
-- global environment strict - if you just want to explicitly set table strictness.
|
||||||
|
--
|
||||||
|
-- @module pl.strict
|
||||||
|
|
||||||
|
require 'debug' -- for Lua 5.2
|
||||||
|
local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget
|
||||||
|
local strict = {}
|
||||||
|
|
||||||
|
local function what ()
|
||||||
|
local d = getinfo(3, "S")
|
||||||
|
return d and d.what or "C"
|
||||||
|
end
|
||||||
|
|
||||||
|
--- make an existing table strict.
|
||||||
|
-- @string name name of table (optional)
|
||||||
|
-- @tab[opt] mod table - if nil then we'll return a new table
|
||||||
|
-- @tab[opt] predeclared - table of variables that are to be considered predeclared.
|
||||||
|
-- @return the given table, or a new table
|
||||||
|
function strict.module (name,mod,predeclared)
|
||||||
|
local mt, old_newindex, old_index, old_index_type, global, closed
|
||||||
|
if predeclared then
|
||||||
|
global = predeclared.__global
|
||||||
|
closed = predeclared.__closed
|
||||||
|
end
|
||||||
|
if type(mod) == 'table' then
|
||||||
|
mt = getmetatable(mod)
|
||||||
|
if mt and rawget(mt,'__declared') then return end -- already patched...
|
||||||
|
else
|
||||||
|
mod = {}
|
||||||
|
end
|
||||||
|
if mt == nil then
|
||||||
|
mt = {}
|
||||||
|
setmetatable(mod, mt)
|
||||||
|
else
|
||||||
|
old_newindex = mt.__newindex
|
||||||
|
old_index = mt.__index
|
||||||
|
old_index_type = type(old_index)
|
||||||
|
end
|
||||||
|
mt.__declared = predeclared or {}
|
||||||
|
mt.__newindex = function(t, n, v)
|
||||||
|
if old_newindex then
|
||||||
|
old_newindex(t, n, v)
|
||||||
|
if rawget(t,n)~=nil then return end
|
||||||
|
end
|
||||||
|
if not mt.__declared[n] then
|
||||||
|
if global then
|
||||||
|
local w = what()
|
||||||
|
if w ~= "main" and w ~= "C" then
|
||||||
|
error("assign to undeclared global '"..n.."'", 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
mt.__declared[n] = true
|
||||||
|
end
|
||||||
|
rawset(t, n, v)
|
||||||
|
end
|
||||||
|
mt.__index = function(t,n)
|
||||||
|
if not mt.__declared[n] and what() ~= "C" then
|
||||||
|
if old_index then
|
||||||
|
if old_index_type == "table" then
|
||||||
|
local fallback = old_index[n]
|
||||||
|
if fallback ~= nil then
|
||||||
|
return fallback
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local res = old_index(t, n)
|
||||||
|
if res then return res end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local msg = "variable '"..n.."' is not declared"
|
||||||
|
if name then
|
||||||
|
msg = msg .. " in '"..name.."'"
|
||||||
|
end
|
||||||
|
error(msg, 2)
|
||||||
|
end
|
||||||
|
return rawget(t, n)
|
||||||
|
end
|
||||||
|
return mod
|
||||||
|
end
|
||||||
|
|
||||||
|
--- make all tables in a table strict.
|
||||||
|
-- So strict.make_all_strict(_G) prevents monkey-patching
|
||||||
|
-- of any global table
|
||||||
|
-- @tab T
|
||||||
|
function strict.make_all_strict (T)
|
||||||
|
for k,v in pairs(T) do
|
||||||
|
if type(v) == 'table' and v ~= T then
|
||||||
|
strict.module(k,v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- make a new module table which is closed to further changes.
|
||||||
|
function strict.closed_module (mod,name)
|
||||||
|
local M = {}
|
||||||
|
mod = mod or {}
|
||||||
|
local mt = getmetatable(mod)
|
||||||
|
if not mt then
|
||||||
|
mt = {}
|
||||||
|
setmetatable(mod,mt)
|
||||||
|
end
|
||||||
|
mt.__newindex = function(t,k,v)
|
||||||
|
M[k] = v
|
||||||
|
end
|
||||||
|
return strict.module(name,M)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not rawget(_G,'PENLIGHT_NO_GLOBAL_STRICT') then
|
||||||
|
strict.module(nil,_G,{_PROMPT=true,__global=true})
|
||||||
|
end
|
||||||
|
|
||||||
|
return strict
|
Loading…
Reference in New Issue