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