From 00a60a6e56d2be6c9d0da3d42f842c4cc98a259e Mon Sep 17 00:00:00 2001 From: Grey-Echo Date: Wed, 29 Mar 2017 23:03:03 +0200 Subject: [PATCH] Add the precompiled Lua 5.1, in order to be used by the install script. Note tha LF had to be converted to CRLF. Doesn't seem to ba an issue though. --- .../LuaFiles/lua/5.1/include/lauxlib.h | 174 +++ .../LuaFiles/lua/5.1/include/lua.h | 388 +++++ .../LuaFiles/lua/5.1/include/lua.hpp | 9 + .../LuaFiles/lua/5.1/include/luaconf.h | 763 +++++++++ .../LuaFiles/lua/5.1/include/lualib.h | 53 + .../LuaFiles/lua/5.1/lib/liblua.a | Bin 0 -> 254464 bytes .../LuaFiles/lua/5.1/lib/lua/5.1/checks.dll | Bin 0 -> 29651 bytes .../LuaFiles/lua/5.1/lib/lua/5.1/lfs.dll | Bin 0 -> 41109 bytes .../rocks/checks/1.0-1/checks-1.0-1.rockspec | 36 + .../luarocks/rocks/checks/1.0-1/rock_manifest | 6 + .../rocks/luadocumentor/0.1.5-1/doc/LICENSE | 198 +++ .../rocks/luadocumentor/0.1.5-1/doc/README.md | 7 + .../0.1.5-1/luadocumentor-0.1.5-1.rockspec | 57 + .../rocks/luadocumentor/0.1.5-1/rock_manifest | 39 + .../luafilesystem/1.6.3-2/doc/us/doc.css | 212 +++ .../1.6.3-2/doc/us/examples.html | 103 ++ .../luafilesystem/1.6.3-2/doc/us/index.html | 218 +++ .../luafilesystem/1.6.3-2/doc/us/license.html | 122 ++ .../1.6.3-2/doc/us/luafilesystem.png | Bin 0 -> 8535 bytes .../luafilesystem/1.6.3-2/doc/us/manual.html | 280 ++++ .../1.6.3-2/luafilesystem-1.6.3-2.rockspec | 29 + .../rocks/luafilesystem/1.6.3-2/rock_manifest | 19 + .../luafilesystem/1.6.3-2/tests/test.lua | 175 +++ .../lua/5.1/lib/luarocks/rocks/manifest | 599 ++++++++ .../markdown/0.32-2/markdown-0.32-2.rockspec | 23 + .../rocks/markdown/0.32-2/rock_manifest | 6 + .../0.7.3-1/doc/README-compiler.md | 104 ++ .../0.7.3-1/doc/README-parser.md | 177 +++ .../metalua-compiler/0.7.3-1/doc/README.md | 13 + .../0.7.3-1/metalua-compiler-0.7.3-1.rockspec | 47 + .../metalua-compiler/0.7.3-1/rock_manifest | 33 + .../0.7.3-2/doc/README-compiler.md | 104 ++ .../0.7.3-2/doc/README-parser.md | 177 +++ .../metalua-parser/0.7.3-2/doc/README.md | 13 + .../0.7.3-2/metalua-parser-0.7.3-2.rockspec | 38 + .../metalua-parser/0.7.3-2/rock_manifest | 34 + .../0.9.8-1/penlight-0.9.8-1.rockspec | 66 + .../rocks/penlight/0.9.8-1/rock_manifest | 45 + .../LuaFiles/lua/5.1/man/man1/lua.1 | 163 ++ .../LuaFiles/lua/5.1/man/man1/luac.1 | 136 ++ .../lua/5.1/share/lua/5.1/defaultcss.lua | 270 ++++ .../lua/5.1/share/lua/5.1/docgenerator.lua | 87 ++ .../lua/5.1/share/lua/5.1/extractors.lua | 102 ++ .../LuaFiles/lua/5.1/share/lua/5.1/fs/lfs.lua | 130 ++ .../lua/5.1/share/lua/5.1/lddextractor.lua | 113 ++ .../lua/5.1/share/lua/5.1/markdown.lua | 1359 +++++++++++++++++ .../5.1/share/lua/5.1/metalua/compiler.lua | 181 +++ .../lua/5.1/metalua/compiler/ast_to_src.mlua | 682 +++++++++ .../lua/5.1/metalua/compiler/bytecode.lua | 29 + .../5.1/metalua/compiler/bytecode/compile.lua | 1263 +++++++++++++++ .../5.1/metalua/compiler/bytecode/lcode.lua | 1038 +++++++++++++ .../5.1/metalua/compiler/bytecode/ldump.lua | 448 ++++++ .../metalua/compiler/bytecode/lopcodes.lua | 442 ++++++ .../lua/5.1/metalua/compiler/globals.lua | 86 ++ .../share/lua/5.1/metalua/compiler/parser.lua | 42 + .../compiler/parser/annot/generator.lua | 48 + .../metalua/compiler/parser/annot/grammar.lua | 112 ++ .../lua/5.1/metalua/compiler/parser/expr.lua | 206 +++ .../lua/5.1/metalua/compiler/parser/ext.lua | 96 ++ .../lua/5.1/metalua/compiler/parser/lexer.lua | 43 + .../lua/5.1/metalua/compiler/parser/meta.lua | 138 ++ .../lua/5.1/metalua/compiler/parser/misc.lua | 176 +++ .../lua/5.1/metalua/compiler/parser/stat.lua | 279 ++++ .../lua/5.1/metalua/compiler/parser/table.lua | 77 + .../5.1/metalua/extension/comprehension.mlua | 282 ++++ .../lua/5.1/metalua/extension/match.mlua | 400 +++++ .../lua/5.1/metalua/grammar/generator.lua | 834 ++++++++++ .../share/lua/5.1/metalua/grammar/lexer.lua | 672 ++++++++ .../lua/5.1/share/lua/5.1/metalua/loader.lua | 133 ++ .../lua/5.1/share/lua/5.1/metalua/pprint.lua | 295 ++++ .../lua/5.1/share/lua/5.1/metalua/repl.mlua | 108 ++ .../5.1/share/lua/5.1/metalua/treequery.mlua | 488 ++++++ .../share/lua/5.1/metalua/treequery/walk.mlua | 266 ++++ .../lua/5.1/share/lua/5.1/models/apimodel.lua | 241 +++ .../share/lua/5.1/models/apimodelbuilder.lua | 459 ++++++ .../share/lua/5.1/models/internalmodel.lua | 65 + .../lua/5.1/models/internalmodelbuilder.mlua | 861 +++++++++++ .../lua/5.1/share/lua/5.1/models/ldparser.lua | 656 ++++++++ .../lua/5.1/share/lua/5.1/pl/Date.lua | 546 +++++++ .../lua/5.1/share/lua/5.1/pl/List.lua | 553 +++++++ .../LuaFiles/lua/5.1/share/lua/5.1/pl/Map.lua | 108 ++ .../lua/5.1/share/lua/5.1/pl/MultiMap.lua | 65 + .../lua/5.1/share/lua/5.1/pl/OrderedMap.lua | 150 ++ .../LuaFiles/lua/5.1/share/lua/5.1/pl/Set.lua | 127 ++ .../LuaFiles/lua/5.1/share/lua/5.1/pl/app.lua | 143 ++ .../lua/5.1/share/lua/5.1/pl/array2d.lua | 391 +++++ .../lua/5.1/share/lua/5.1/pl/class.lua | 155 ++ .../5.1/share/lua/5.1/pl/comprehension.lua | 288 ++++ .../lua/5.1/share/lua/5.1/pl/config.lua | 169 ++ .../lua/5.1/share/lua/5.1/pl/data.lua | 588 +++++++ .../LuaFiles/lua/5.1/share/lua/5.1/pl/dir.lua | 478 ++++++ .../lua/5.1/share/lua/5.1/pl/file.lua | 69 + .../lua/5.1/share/lua/5.1/pl/func.lua | 379 +++++ .../lua/5.1/share/lua/5.1/pl/init.lua | 47 + .../lua/5.1/share/lua/5.1/pl/input.lua | 172 +++ .../lua/5.1/share/lua/5.1/pl/lapp.lua | 350 +++++ .../lua/5.1/share/lua/5.1/pl/lexer.lua | 461 ++++++ .../lua/5.1/share/lua/5.1/pl/luabalanced.lua | 264 ++++ .../lua/5.1/share/lua/5.1/pl/operator.lua | 197 +++ .../lua/5.1/share/lua/5.1/pl/path.lua | 335 ++++ .../lua/5.1/share/lua/5.1/pl/permute.lua | 65 + .../5.1/share/lua/5.1/pl/platf/luajava.lua | 101 ++ .../lua/5.1/share/lua/5.1/pl/pretty.lua | 224 +++ .../LuaFiles/lua/5.1/share/lua/5.1/pl/seq.lua | 527 +++++++ .../LuaFiles/lua/5.1/share/lua/5.1/pl/sip.lua | 335 ++++ .../lua/5.1/share/lua/5.1/pl/strict.lua | 71 + .../lua/5.1/share/lua/5.1/pl/stringio.lua | 144 ++ .../lua/5.1/share/lua/5.1/pl/stringx.lua | 441 ++++++ .../lua/5.1/share/lua/5.1/pl/tablex.lua | 766 ++++++++++ .../lua/5.1/share/lua/5.1/pl/template.lua | 99 ++ .../lua/5.1/share/lua/5.1/pl/test.lua | 116 ++ .../lua/5.1/share/lua/5.1/pl/text.lua | 241 +++ .../lua/5.1/share/lua/5.1/pl/utils.lua | 529 +++++++ .../LuaFiles/lua/5.1/share/lua/5.1/pl/xml.lua | 676 ++++++++ .../lua/5.1/share/lua/5.1/template/file.lua | 106 ++ .../lua/5.1/share/lua/5.1/template/index.lua | 28 + .../lua/5.1/template/index/recordtypedef.lua | 23 + .../lua/5.1/share/lua/5.1/template/item.lua | 167 ++ .../lua/5.1/share/lua/5.1/template/page.lua | 68 + .../share/lua/5.1/template/recordtypedef.lua | 36 + .../lua/5.1/share/lua/5.1/template/usage.lua | 33 + .../lua/5.1/share/lua/5.1/template/utils.lua | 470 ++++++ .../lua/5.1/share/lua/5.1/templateengine.lua | 116 ++ 123 files changed, 29290 insertions(+) create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lauxlib.h create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lua.h create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lua.hpp create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/include/luaconf.h create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lualib.h create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/liblua.a create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/lua/5.1/checks.dll create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/lua/5.1/lfs.dll create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/checks/1.0-1/checks-1.0-1.rockspec create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/checks/1.0-1/rock_manifest create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/doc/LICENSE create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/doc/README.md create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/luadocumentor-0.1.5-1.rockspec create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/rock_manifest create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/doc.css create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/examples.html create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/index.html create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/license.html create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/luafilesystem.png create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/manual.html create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/luafilesystem-1.6.3-2.rockspec create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/rock_manifest create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/tests/test.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/manifest create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/markdown/0.32-2/markdown-0.32-2.rockspec create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/markdown/0.32-2/rock_manifest create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/doc/README-compiler.md create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/doc/README-parser.md create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/doc/README.md create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/metalua-compiler-0.7.3-1.rockspec create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/rock_manifest create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/doc/README-compiler.md create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/doc/README-parser.md create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/doc/README.md create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/metalua-parser-0.7.3-2.rockspec create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/rock_manifest create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/penlight/0.9.8-1/penlight-0.9.8-1.rockspec create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/penlight/0.9.8-1/rock_manifest create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/man/man1/lua.1 create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/man/man1/luac.1 create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/defaultcss.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/docgenerator.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/extractors.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/fs/lfs.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/lddextractor.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/markdown.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/ast_to_src.mlua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/compile.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/lcode.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/ldump.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/lopcodes.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/globals.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/annot/generator.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/annot/grammar.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/expr.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/ext.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/lexer.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/meta.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/misc.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/stat.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/table.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/extension/comprehension.mlua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/extension/match.mlua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/grammar/generator.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/grammar/lexer.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/loader.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/pprint.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/repl.mlua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/treequery.mlua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/treequery/walk.mlua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/apimodel.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/apimodelbuilder.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/internalmodel.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/internalmodelbuilder.mlua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/ldparser.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Date.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/List.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Map.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/MultiMap.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/OrderedMap.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Set.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/app.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/array2d.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/class.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/comprehension.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/config.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/data.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/dir.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/file.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/func.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/init.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/input.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/lapp.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/lexer.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/luabalanced.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/operator.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/path.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/permute.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/platf/luajava.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/pretty.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/seq.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/sip.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/strict.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/stringio.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/stringx.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/tablex.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/template.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/test.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/text.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/utils.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/xml.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/file.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/index.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/index/recordtypedef.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/item.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/page.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/recordtypedef.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/usage.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/utils.lua create mode 100644 Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/templateengine.lua diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lauxlib.h b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lauxlib.h new file mode 100644 index 000000000..34258235d --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lauxlib.h @@ -0,0 +1,174 @@ +/* +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + +#if defined(LUA_COMPAT_GETN) +LUALIB_API int (luaL_getn) (lua_State *L, int t); +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +#else +#define luaL_getn(L,i) ((int)lua_objlen(L, i)) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + +#if defined(LUA_COMPAT_OPENLIB) +#define luaI_openlib luaL_openlib +#endif + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + + +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l); +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, + const char *name); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname, int szhint); + + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_addchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +/* compatibility only */ +#define luaL_putchar(B,c) luaL_addchar(B,c) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + + +/* }====================================================== */ + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + +#define luaL_reg luaL_Reg + +#endif + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lua.h b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lua.h new file mode 100644 index 000000000..a4b73e743 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lua.h @@ -0,0 +1,388 @@ +/* +** $Id: lua.h,v 1.218.1.7 2012/01/13 20:36:20 roberto Exp $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.5" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + +/* mark for precompiled code (`Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* thread status; 0 is OK */ +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getfenv) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setfenv) (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yield) (lua_State *L, int nresults); +LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_strlen(L,i) lua_objlen(L, (i)) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** compatibility macros and functions +*/ + +#define lua_open() luaL_newstate() + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) + +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) + +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer + + +/* hack */ +LUA_API void lua_setlevel (lua_State *from, lua_State *to); + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debuger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2012 Lua.org, PUC-Rio. All rights reserved. +* +* 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. +* +* 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. +******************************************************************************/ + + +#endif diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lua.hpp b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lua.hpp new file mode 100644 index 000000000..ec417f594 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/luaconf.h b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/luaconf.h new file mode 100644 index 000000000..e2cb26163 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/luaconf.h @@ -0,0 +1,763 @@ +/* +** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_WIN +#endif + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_DL_DYLD /* does not need extra library */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#endif + + +/* +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +@* Lua check to set its paths. +@@ LUA_INIT is the name of the environment variable that Lua +@* checks for initialization code. +** CHANGE them if you want different names. +*/ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" + +#else +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_PATH_DEFAULT \ + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" +#endif + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_PATHSEP is the character that separates templates in a path. +@@ LUA_PATH_MARK is the string that marks the substitution points in a +@* template. +@@ LUA_EXECDIR in a Windows path is replaced by the executable's +@* directory. +@@ LUA_IGMARK is a mark to ignore all before it when bulding the +@* luaopen_ function name. +** CHANGE them if for some reason your system cannot use those +** characters. (E.g., if one of those characters is a common character +** in file/directory names.) Probably you do not need to change them. +*/ +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(dllexport) +#else +#define LUA_API __declspec(dllimport) +#endif + +#else + +#define LUA_API extern + +#endif + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DATA is a mark for all extern (const) variables that are not to +@* be exported to outside modules. +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ + +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC + +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== +** Stand-alone configuration +** =================================================================== +*/ + +#if defined(lua_c) || defined(luaall_c) + +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " + + +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" + + +/* +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. +*/ +#define LUA_MAXINPUT 512 + + +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*/ +#if defined(LUA_USE_READLINE) +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) +#else +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } +#endif + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +@* as a percentage. +** CHANGE it if you want the GC to run faster or slower (higher values +** mean larger pauses which mean slower collection.) You can also change +** this value dynamically. +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the default speed of garbage collection relative to +@* memory allocation as a percentage. +** CHANGE it if you want to change the granularity of the garbage +** collection. (Higher values mean coarser collections. 0 represents +** infinity, where each step performs a full collection.) You can also +** change this value dynamically. +*/ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ + + + +/* +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +** CHANGE it (define it) if you want exact compatibility with the +** behavior of setn/getn in Lua 5.0. +*/ +#undef LUA_COMPAT_GETN + +/* +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +** CHANGE it to undefined as soon as you do not need a global 'loadlib' +** function (the function is still available as 'package.loadlib'). +*/ +#undef LUA_COMPAT_LOADLIB + +/* +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +** CHANGE it to undefined as soon as your programs use only '...' to +** access vararg parameters (instead of the old 'arg' table). +*/ +#define LUA_COMPAT_VARARG + +/* +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +** CHANGE it to undefined as soon as your programs use 'math.fmod' or +** the new '%' operator instead of 'math.mod'. +*/ +#define LUA_COMPAT_MOD + +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +** CHANGE it to undefined as soon as you rename 'string.gfind' to +** 'string.gmatch'. +*/ +#define LUA_COMPAT_GFIND + +/* +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +@* behavior. +** CHANGE it to undefined as soon as you replace to 'luaL_register' +** your uses of 'luaL_openlib' +*/ +#define LUA_COMPAT_OPENLIB + + + +/* +@@ luai_apicheck is the assert macro used by the Lua-C API. +** CHANGE luai_apicheck if you want Lua to perform some checks in the +** parameters it gets from API calls. This may slow down the interpreter +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,o) { (void)L; assert(o); } +#else +#define luai_apicheck(L,o) { (void)L; } +#endif + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + + +/* +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else +/* 16-bit ints */ +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif + + +/* +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. +*/ +#define LUAI_MAXCALLS 20000 + + +/* +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. (must be smaller than +** -LUA_REGISTRYINDEX) +*/ +#define LUAI_MAXCSTACK 8000 + + + +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ + + +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 + + +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 + + +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE BUFSIZ + +/* }================================================================== */ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ +#if defined(LUA_CORE) +#include +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(a,b) (pow(a,b)) +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + +/* +@@ lua_number2int is a macro to convert lua_Number to int. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE them if you know a faster way to convert a lua_Number to +** int (with any rounding method and without throwing errors) in your +** system. In Pentium machines, a naive typecast from double to int +** in C is extremely slow, so any alternative is worth trying. +*/ + +/* On a Pentium, resort to a trick */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) + +/* On a Microsoft compiler, use assembler */ +#if defined(_MSC_VER) + +#define lua_number2int(i,d) __asm fld d __asm fistp i +#define lua_number2integer(i,n) lua_number2int(i, n) + +/* the next trick should work on any Pentium, but sometimes clashes + with a DirectX idiosyncrasy */ +#else + +union luai_Cast { double l_d; long l_l; }; +#define lua_number2int(i,d) \ + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +#define lua_number2integer(i,n) lua_number2int(i, n) + +#endif + + +/* this option always works, but may be slow */ +#else +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } + + +/* +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +** CHANGE them if you prefer to use longjmp/setjmp even with C++ +** or if want/don't to use _longjmp/_setjmp instead of regular +** longjmp/setjmp. By default, Lua handles errors with exceptions when +** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +** and with longjmp/setjmp otherwise. +*/ +#if defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + + +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 + + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#endif + +#endif + + +/* +@@ lua_popen spawns a new process connected to the current one through +@* the file streams. +** CHANGE it if you have a way to implement it in your system. +*/ +#if defined(LUA_USE_POPEN) + +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) + +#elif defined(LUA_WIN) + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) + +#else + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) + +#endif + +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** If you do not want any kind of dynamic library, undefine all these +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +*/ +#if defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#endif + + +/* +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +@* (the data goes just *before* the lua_State pointer). +** CHANGE (define) this if you really need that. This value must be +** a multiple of the maximum alignment required for your machine. +*/ +#define LUAI_EXTRASPACE 0 + + +/* +@@ luai_userstate* allow user-specific actions on threads. +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +** extra when a thread is created/deleted/resumed/yielded. +*/ +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) + + +/* +@@ LUA_INTFRMLEN is the length modifier for integer conversions +@* in 'string.format'. +@@ LUA_INTFRM_T is the integer type correspoding to the previous length +@* modifier. +** CHANGE them if your system supports long long or does not support long. +*/ + +#if defined(LUA_USELONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lualib.h b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lualib.h new file mode 100644 index 000000000..469417f67 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/include/lualib.h @@ -0,0 +1,53 @@ +/* +** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* Key to file-handle type */ +#define LUA_FILEHANDLE "FILE*" + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int (luaopen_base) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int (luaopen_string) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUALIB_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/liblua.a b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/liblua.a new file mode 100644 index 0000000000000000000000000000000000000000..f4d65be6491b48253237e463434e0117bdaeda22 GIT binary patch literal 254464 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 5.1" +} + +build = { + type = 'builtin', + modules = { + checks = 'checks.c' + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/checks/1.0-1/rock_manifest b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/checks/1.0-1/rock_manifest new file mode 100644 index 000000000..07ae2133a --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/checks/1.0-1/rock_manifest @@ -0,0 +1,6 @@ +rock_manifest = { + ["checks-1.0-1.rockspec"] = "70af2f5dd173774a16b9e7cfdfd12ecd", + lib = { + ["checks.dll"] = "5342726d76176ca95ebe25c7b07ca6ac" + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/doc/LICENSE b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/doc/LICENSE new file mode 100644 index 000000000..11ecb7958 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/doc/LICENSE @@ -0,0 +1,198 @@ +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation + distributed under this Agreement, and +b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + + where such changes and/or additions to the Program originate from and are + distributed by that particular Contributor. A Contribution 'originates' from + a Contributor if it was added to the Program by such Contributor itself or + anyone acting on such Contributor's behalf. Contributions do not include + additions to the Program which: (i) are separate modules of software + distributed in conjunction with the Program under their own license + agreement, and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or when +combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + a) Subject to the terms of this Agreement, each Contributor hereby grants + Recipient a non-exclusive, worldwide, royalty-free copyright license to + reproduce, prepare derivative works of, publicly display, publicly perform, + distribute and sublicense the Contribution of such Contributor, if any, and + such derivative works, in source code and object code form. + b) Subject to the terms of this Agreement, each Contributor hereby grants + Recipient a non-exclusive, worldwide, royalty-free patent license under + Licensed Patents to make, use, sell, offer to sell, import and otherwise + transfer the Contribution of such Contributor, if any, in source code and + object code form. This patent license shall apply to the combination of the + Contribution and the Program if, at the time the Contribution is added by + the Contributor, such addition of the Contribution causes such combination + to be covered by the Licensed Patents. The patent license shall not apply + to any other combinations which include the Contribution. No hardware per + se is licensed hereunder. + c) Recipient understands that although each Contributor grants the licenses to + its Contributions set forth herein, no assurances are provided by any + Contributor that the Program does not infringe the patent or other + intellectual property rights of any other entity. Each Contributor + disclaims any liability to Recipient for claims brought by any other entity + based on infringement of intellectual property rights or otherwise. As a + condition to exercising the rights and licenses granted hereunder, each + Recipient hereby assumes sole responsibility to secure any other + intellectual property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to distribute the Program, it + is Recipient's responsibility to acquire that license before distributing + the Program. + d) Each Contributor represents that to its knowledge it has sufficient + copyright rights in its Contribution, if any, to grant the copyright + license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its +own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + b) its license agreement: + i) effectively disclaims on behalf of all Contributors all warranties and + conditions, express and implied, including warranties or conditions of + title and non-infringement, and implied warranties or conditions of + merchantability and fitness for a particular purpose; + ii) effectively excludes on behalf of all Contributors all liability for + damages, including direct, indirect, special, incidental and + consequential damages, such as lost profits; + iii) states that any provisions which differ from this Agreement are offered + by that Contributor alone and not by any other party; and + iv) states that source code for the Program is available from such + Contributor, and informs licensees how to obtain it in a reasonable + manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + b) a copy of this Agreement must be included with each copy of the Program. + Contributors may not remove or alter any copyright notices contained within + the Program. + +Each Contributor must identify itself as the originator of its Contribution, if +any, in a manner that reasonably allows subsequent Recipients to identify the +originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, if +a Contributor includes the Program in a commercial product offering, such +Contributor ("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and other legal +actions brought by a third party against the Indemnified Contributor to the +extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor to +control, and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may participate in +any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. If that +Commercial Contributor then makes performance claims, or offers warranties +related to Product X, those performance claims and warranties are such +Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each +Recipient is solely responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its exercise of +rights under this Agreement , including but not limited to the risks and costs +of program errors, compliance with applicable laws, damage to or loss of data, +programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable +law, it shall not affect the validity or enforceability of the remainder of the +terms of this Agreement, and without further action by the parties hereto, such +provision shall be reformed to the minimum extent necessary to make such +provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Program itself +(excluding combinations of the Program with other software or hardware) +infringes such Recipient's patent(s), then such Recipient's rights granted under +Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and does +not cure such failure in a reasonable period of time after becoming aware of +such noncompliance. If all Recipient's rights under this Agreement terminate, +Recipient agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall continue and +survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in +order to avoid inconsistency the Agreement is copyrighted and may only be +modified in the following manner. The Agreement Steward reserves the right to +publish new versions (including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation +may assign the responsibility to serve as the Agreement Steward to a suitable +separate entity. Each new version of the Agreement will be given a +distinguishing version number. The Program (including Contributions) may always +be distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to distribute the Program (including its Contributions) +under the new version. Except as expressly stated in Sections 2(a) and 2(b) +above, Recipient receives no rights or licenses to the intellectual property of +any Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted under +this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to this +Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial in +any resulting litigation. diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/doc/README.md b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/doc/README.md new file mode 100644 index 000000000..03611d630 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/doc/README.md @@ -0,0 +1,7 @@ +# Lua Documentor + +LuaDocumentor allow users to generate HTML and API files from code documented +using Lua documentation language. + +Documentation is +[available here](http://wiki.eclipse.org/Koneki/LDT/User_Area/LuaDocumentor). diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/luadocumentor-0.1.5-1.rockspec b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/luadocumentor-0.1.5-1.rockspec new file mode 100644 index 000000000..9ed686c3f --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/luadocumentor-0.1.5-1.rockspec @@ -0,0 +1,57 @@ +package = 'LuaDocumentor' +version = '0.1.5-1' +description = { + summary = 'LuaDocumentor allow users to generate HTML and API files from code documented using Lua documentation language.', + detailed = [[ + This is an example for the LuaRocks tutorial. + Here we would put a detailed, typically + paragraph-long description. + ]], + homepage = 'http://wiki.eclipse.org/Koneki/LDT/User_Area/LuaDocumentor', + license = 'EPL' +} +source = { + url = 'git://github.com/LuaDevelopmentTools/luadocumentor.git', + tag = 'v0.1.5-1' +} +dependencies = { + 'lua ~> 5.1', + 'luafilesystem ~> 1.6', + 'markdown ~> 0.32', + 'metalua-compiler ~> 0.7', + 'penlight ~> 0.9' +} +build = { + type = 'builtin', + install = { + bin = { + luadocumentor = 'luadocumentor.lua' + }, + lua = { + ['models.internalmodelbuilder'] = 'models/internalmodelbuilder.mlua' + } + }, + modules = { + defaultcss = 'defaultcss.lua', + docgenerator = 'docgenerator.lua', + extractors = 'extractors.lua', + lddextractor = 'lddextractor.lua', + templateengine = 'templateengine.lua', + + ['fs.lfs'] = 'fs/lfs.lua', + + ['models.apimodel'] = 'models/apimodel.lua', + ['models.apimodelbuilder'] = 'models/apimodelbuilder.lua', + ['models.internalmodel'] = 'models/internalmodel.lua', + ['models.ldparser'] = 'models/ldparser.lua', + + ['template.file'] = 'template/file.lua', + ['template.index'] = 'template/index.lua', + ['template.index.recordtypedef'] = 'template/index/recordtypedef.lua', + ['template.item'] = 'template/item.lua', + ['template.page'] = 'template/page.lua', + ['template.recordtypedef'] = 'template/recordtypedef.lua', + ['template.usage'] = 'template/usage.lua', + ['template.utils'] = 'template/utils.lua', + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/rock_manifest b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/rock_manifest new file mode 100644 index 000000000..c286d43bd --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luadocumentor/0.1.5-1/rock_manifest @@ -0,0 +1,39 @@ +rock_manifest = { + bin = { + luadocumentor = "bc5cc07f56db2cf1dbe80f0827332873" + }, + doc = { + LICENSE = "52a21f73ac77fd790dc40dc5acda0fc2", + ["README.md"] = "fcef1f43c69f3559b347d854b2626deb" + }, + lua = { + ["defaultcss.lua"] = "dd9b2b89e5080972bbb52056247c0c65", + ["docgenerator.lua"] = "92d0a3947d88226340014d2f033be37f", + ["extractors.lua"] = "74191695e5217706ee355925e5ca40fa", + fs = { + ["lfs.lua"] = "4d00f9bc942b02a86ccea16544d3e85d" + }, + ["lddextractor.lua"] = "56edde775a5d57818aa0a07b4f723536", + models = { + ["apimodel.lua"] = "3c401de18691b1222b0ad253958260ee", + ["apimodelbuilder.lua"] = "4c4a3c0b48b404973542dd99f994eb2c", + ["internalmodel.lua"] = "a1a21e50af8db0f0a0b9d164ccc08853", + ["internalmodelbuilder.mlua"] = "ff95dfca573ccc1c19a79434e96a492d", + ["ldparser.lua"] = "538904a3adbfff4ff83deda029847323" + }, + template = { + ["file.lua"] = "41f095bc049ef161060d8e3b4ac9de63", + index = { + ["recordtypedef.lua"] = "0977ff0048a837389c2ac10285eb1ce1" + }, + ["index.lua"] = "5a3b3cface3b1fd9cb2d56f1edd5487b", + ["item.lua"] = "5d5a6d9bffd8935c4ed283105ede331b", + ["page.lua"] = "351f4a7215272f7e448faeece4945bc0", + ["recordtypedef.lua"] = "69938e1d60e94eed7f95b0999f1386ca", + ["usage.lua"] = "979503deb84877cb221130a5be7c1535", + ["utils.lua"] = "ad97fb4e3de9fb6480b25cdd877b50d9" + }, + ["templateengine.lua"] = "09bfc6350e14f4ab509d14fb0fb295c0" + }, + ["luadocumentor-0.1.5-1.rockspec"] = "4ba1b88898dce89e7fd8fb6a700496a4" +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/doc.css b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/doc.css new file mode 100644 index 000000000..e816a7e2c --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/doc.css @@ -0,0 +1,212 @@ +body { + margin-left: 1em; + margin-right: 1em; + font-family: arial, helvetica, geneva, sans-serif; + background-color:#ffffff; margin:0px; +} + +code { + font-family: "Andale Mono", monospace; +} + +tt { + font-family: "Andale Mono", monospace; +} + +body, td, th { font-size: 11pt; } + +h1, h2, h3, h4 { margin-left: 0em; } + +textarea, pre, tt { font-size:10pt; } +body, td, th { color:#000000; } +small { font-size:0.85em; } +h1 { font-size:1.5em; } +h2 { font-size:1.25em; } +h3 { font-size:1.15em; } +h4 { font-size:1.06em; } + +a:link { font-weight:bold; color: #004080; text-decoration: none; } +a:visited { font-weight:bold; color: #006699; text-decoration: none; } +a:link:hover { text-decoration:underline; } +hr { color:#cccccc } +img { border-width: 0px; } + +h3 { padding-top: 1em; } + +p { margin-left: 1em; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; + margin-left: 0em; +} + +blockquote { margin-left: 3em; } + +.example { + background-color: rgb(245, 245, 245); + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-style: solid; + border-right-style: solid; + border-bottom-style: solid; + border-left-style: solid; + border-top-color: silver; + border-right-color: silver; + border-bottom-color: silver; + border-left-color: silver; + padding: 1em; + margin-left: 1em; + margin-right: 1em; + font-family: "Andale Mono", monospace; + font-size: smaller; +} + +hr { + margin-left: 0em; + background: #00007f; + border: 0px; + height: 1px; +} + +ul { list-style-type: disc; } + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } +table.index ul { padding-top: 0em; margin-top: 0em; } + +table { + border: 1px solid black; + border-collapse: collapse; + margin-left: auto; + margin-right: auto; +} + +th { + border: 1px solid black; + padding: 0.5em; +} + +td { + border: 1px solid black; + padding: 0.5em; +} +div.header, div.footer { margin-left: 0em; } + +#container { + margin-left: 1em; + margin-right: 1em; + background-color: #f0f0f0; +} + +#product { + text-align: center; + border-bottom: 1px solid #cccccc; + background-color: #ffffff; +} + +#product big { + font-size: 2em; +} + +#product_logo { +} + +#product_name { +} + +#product_description { +} + +#main { + background-color: #f0f0f0; + border-left: 2px solid #cccccc; +} + +#navigation { + float: left; + width: 12em; + margin: 0; + vertical-align: top; + background-color: #f0f0f0; + overflow:visible; +} + +#navigation h1 { + background-color:#e7e7e7; + font-size:1.1em; + color:#000000; + text-align:left; + margin:0px; + padding:0.2em; + border-top:1px solid #dddddd; + border-bottom:1px solid #dddddd; +} + +#navigation ul { + font-size:1em; + list-style-type: none; + padding: 0; + margin: 1px; +} + +#navigation li { + text-indent: -1em; + margin: 0em 0em 0em 0.5em; + display: block; + padding: 3px 0px 0px 12px; +} + +#navigation li li a { + padding: 0px 3px 0px -1em; +} + +#content { + margin-left: 12em; + padding: 1em; + border-left: 2px solid #cccccc; + border-right: 2px solid #cccccc; + background-color: #ffffff; +} + +#about { + clear: both; + margin: 0; + padding: 5px; + border-top: 2px solid #cccccc; + background-color: #ffffff; +} + +@media print { + body { + font: 10pt "Times New Roman", "TimeNR", Times, serif; + } + a { + font-weight:bold; color: #004080; text-decoration: underline; + } + #main { + background-color: #ffffff; border-left: 0px; + } + #container { + margin-left: 2%; margin-right: 2%; background-color: #ffffff; + } + #content { + margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff; + } + #navigation { + display: none; + } + #product_logo { + display: none; + } + #about img { + display: none; + } + .example { + font-family: "Andale Mono", monospace; + font-size: 8pt; + page-break-inside: avoid; + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/examples.html b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/examples.html new file mode 100644 index 000000000..2c1644cb8 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/examples.html @@ -0,0 +1,103 @@ + + + + LuaFileSystem + + + + + + +
+ +
+ +
LuaFileSystem
+
File System Library for the Lua Programming Language
+
+ +
+ + + +
+ +

Examples

+ +

Directory iterator

+ +

The following example iterates over a directory and recursively lists the +attributes for each file inside it.

+ +
+local lfs = require"lfs"
+
+function attrdir (path)
+    for file in lfs.dir(path) do
+        if file ~= "." and file ~= ".." then
+            local f = path..'/'..file
+            print ("\t "..f)
+            local attr = lfs.attributes (f)
+            assert (type(attr) == "table")
+            if attr.mode == "directory" then
+                attrdir (f)
+            else
+                for name, value in pairs(attr) do
+                    print (name, value)
+                end
+            end
+        end
+    end
+end
+
+attrdir (".")
+
+ +
+ +
+ +
+

Valid XHTML 1.0!

+

$Id: examples.html,v 1.8 2007/12/14 15:28:04 carregal Exp $

+
+ +
+ + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/index.html b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/index.html new file mode 100644 index 000000000..2bb7f5d2c --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/index.html @@ -0,0 +1,218 @@ + + + + LuaFileSystem + + + + + + +
+ +
+ +
LuaFileSystem
+
File System Library for the Lua Programming Language
+
+ +
+ + + +
+ +

Overview

+ +

LuaFileSystem is a Lua library +developed to complement the set of functions related to file +systems offered by the standard Lua distribution.

+ +

LuaFileSystem offers a portable way to access +the underlying directory structure and file attributes.

+ +

LuaFileSystem is free software and uses the same +license as Lua 5.1.

+ +

Status

+ +

Current version is 1.6.3. It works with Lua 5.1, 5.2 and 5.3.

+ +

Download

+ +

LuaFileSystem source can be downloaded from its +Github +page.

+ +

History

+ +
+
Version 1.6.3 [15/Jan/2015]
+
    +
  • Lua 5.3 support.
  • +
  • Assorted bugfixes.
  • +
+ +
Version 1.6.2 [??/Oct/2012]
+
    +
  • Full Lua 5.2 compatibility (with Lua 5.1 fallbacks)
  • +
+ +
Version 1.6.1 [01/Oct/2012]
+
    +
  • fix build for Lua 5.2
  • +
+ +
Version 1.6.0 [26/Sep/2012]
+
    +
  • getcwd fix for Android
  • +
  • support for Lua 5.2
  • +
  • add lfs.link
  • +
  • other bug fixes
  • +
+ +
Version 1.5.0 [20/Oct/2009]
+
    +
  • Added explicit next and close methods to second return value of lfs.dir +(the directory object), for explicit iteration or explicit closing.
  • +
  • Added directory locking via lfs.lock_dir function (see the manual).
  • +
+
Version 1.4.2 [03/Feb/2009]
+
+
    +
  • fixed bug [#13198] + lfs.attributes(filename, 'size') overflow on files > 2 Gb again (bug report and patch by KUBO Takehiro).
  • +
  • fixed bug [#39794] + Compile error on Solaris 10 (bug report and patch by Aaron B).
  • +
  • fixed compilation problems with Borland C.
  • +
+
+ +
Version 1.4.1 [07/May/2008]
+
+
    +
  • documentation review
  • +
  • fixed Windows compilation issues
  • +
  • fixed bug in the Windows tests (patch by Shmuel Zeigerman)
  • +
  • fixed bug [#2185] + lfs.attributes(filename, 'size') overflow on files > 2 Gb +
  • +
+
+ +
Version 1.4.0 [13/Feb/2008]
+
+
    +
  • added function + lfs.setmode + (works only in Windows systems).
  • +
  • lfs.attributes + raises an error if attribute does not exist
  • +
+
+ +
Version 1.3.0 [26/Oct/2007]
+
+ +
+ +
Version 1.2.1 [08/May/2007]
+
+
    +
  • compatible only with Lua 5.1 (Lua 5.0 support was dropped)
  • +
+
+ +
Version 1.2 [15/Mar/2006]
+
+ +
+ +
Version 1.1 [30/May/2005]
+
+ +
+ +
Version 1.0 [21/Jan/2005]
+
+ +
Version 1.0 Beta [10/Nov/2004]
+
+
+ +

Credits

+ +

LuaFileSystem was designed by Roberto Ierusalimschy, +André Carregal and Tomás Guisasola as part of the +Kepler Project, +which holds its copyright. LuaFileSystem is currently maintained by Fábio Mascarenhas.

+ +

Contact us

+ +

For more information please +contact us. +Comments are welcome!

+ +

You can also reach other Kepler developers and users on the Kepler Project +mailing list.

+ +
+ +
+ +
+

Valid XHTML 1.0!

+

$Id: index.html,v 1.44 2009/02/04 21:21:33 carregal Exp $

+
+ +
+ + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/license.html b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/license.html new file mode 100644 index 000000000..300338172 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/license.html @@ -0,0 +1,122 @@ + + + + LuaFileSystem + + + + + + +
+ +
+ +
LuaFileSystem
+
File System Library for the Lua Programming Language
+
+ +
+ + + +
+ +

License

+ +

+LuaFileSystem is free software: it can be used for both academic +and commercial purposes at absolutely no cost. There are no +royalties or GNU-like "copyleft" restrictions. LuaFileSystem +qualifies as +Open Source +software. +Its licenses are compatible with +GPL. +LuaFileSystem is not in the public domain and the +Kepler Project +keep its copyright. +The legal details are below. +

+ +

The spirit of the license is that you are free to use +LuaFileSystem for any purpose at no cost without having to ask us. +The only requirement is that if you do use LuaFileSystem, then you +should give us credit by including the appropriate copyright notice +somewhere in your product or its documentation.

+ +

The LuaFileSystem library is designed and implemented by Roberto +Ierusalimschy, André Carregal and Tomás Guisasola. +The implementation is not derived from licensed software.

+ +
+

Copyright © 2003 Kepler Project.

+ +

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.

+ +

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.

+ +
+ +
+ +
+

Valid XHTML 1.0!

+

$Id: license.html,v 1.13 2008/02/11 22:42:21 carregal Exp $

+
+ +
+ + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/luafilesystem.png b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/doc/us/luafilesystem.png new file mode 100644 index 0000000000000000000000000000000000000000..e1dd8c65b5211ba5dd37f2e86da987fdd517d6c6 GIT binary patch literal 8535 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 + + + LuaFileSystem + + + + + + +
+ +
+ +
LuaFileSystem
+
File System Library for the Lua Programming Language
+
+ +
+ + + +
+ +

Introduction

+ +

LuaFileSystem is a Lua library +developed to complement the set of functions related to file +systems offered by the standard Lua distribution.

+ +

LuaFileSystem offers a portable way to access +the underlying directory structure and file attributes.

+ +

Building

+ +

+LuaFileSystem should be built with Lua 5.1 so the language library +and header files for the target version must be installed properly. +

+ +

+LuaFileSystem offers a Makefile and a separate configuration file, +config, +which should be edited to suit your installation before running +make. +The file has some definitions like paths to the external libraries, +compiler options and the like. +

+ +

On Windows, the C runtime used to compile LuaFileSystem must be the same +runtime that Lua uses, or some LuaFileSystem functions will not work.

+ +

Installation

+ +

The easiest way to install LuaFileSystem is to use LuaRocks:

+ +
+luarocks install luafilesystem
+
+ +

If you prefer to install LuaFileSystem manually, the compiled binary should be copied to a directory in your +C path.

+ +

Reference

+ +

+LuaFileSystem offers the following functions: +

+ +
+
lfs.attributes (filepath [, aname])
+
Returns a table with the file attributes corresponding to + filepath (or nil followed by an error message + in case of error). + If the second optional argument is given, then only the value of the + named attribute is returned (this use is equivalent to + lfs.attributes(filepath).aname, but the table is not created + and only one attribute is retrieved from the O.S.). + The attributes are described as follows; + attribute mode is a string, all the others are numbers, + and the time related attributes use the same time reference of + os.time: +
+
dev
+
on Unix systems, this represents the device that the inode resides on. On Windows systems, + represents the drive number of the disk containing the file
+ +
ino
+
on Unix systems, this represents the inode number. On Windows systems this has no meaning
+ +
mode
+
string representing the associated protection mode (the values could be + file, directory, link, socket, + named pipe, char device, block device or + other)
+ +
nlink
+
number of hard links to the file
+ +
uid
+
user-id of owner (Unix only, always 0 on Windows)
+ +
gid
+
group-id of owner (Unix only, always 0 on Windows)
+ +
rdev
+
on Unix systems, represents the device type, for special file inodes. + On Windows systems represents the same as dev
+ +
access
+
time of last access
+ +
modification
+
time of last data modification
+ +
change
+
time of last file status change
+ +
size
+
file size, in bytes
+ +
blocks
+
block allocated for file; (Unix only)
+ +
blksize
+
optimal file system I/O blocksize; (Unix only)
+
+ This function uses stat internally thus if the given + filepath is a symbolic link, it is followed (if it points to + another link the chain is followed recursively) and the information + is about the file it refers to. + To obtain information about the link itself, see function + lfs.symlinkattributes. +
+ +
lfs.chdir (path)
+
Changes the current working directory to the given + path.
+ Returns true in case of success or nil plus an + error string.
+ +
lfs.lock_dir(path, [seconds_stale])
+
Creates a lockfile (called lockfile.lfs) in path if it does not + exist and returns the lock. If the lock already exists checks if + it's stale, using the second parameter (default for the second + parameter is INT_MAX, which in practice means the lock will never + be stale. To free the the lock call lock:free().
+ In case of any errors it returns nil and the error message. In + particular, if the lock exists and is not stale it returns the + "File exists" message.
+ +
lfs.currentdir ()
+
Returns a string with the current working directory or nil + plus an error string.
+ +
iter, dir_obj = lfs.dir (path)
+
+ Lua iterator over the entries of a given directory. + Each time the iterator is called with dir_obj it returns a directory entry's name as a string, or + nil if there are no more entries. You can also iterate by calling dir_obj:next(), and + explicitly close the directory before the iteration finished with dir_obj:close(). + Raises an error if path is not a directory. +
+ +
lfs.lock (filehandle, mode[, start[, length]])
+
Locks a file or a part of it. This function works on open files; the + file handle should be specified as the first argument. + The string mode could be either + r (for a read/shared lock) or w (for a + write/exclusive lock). The optional arguments start + and length can be used to specify a starting point and + its length; both should be numbers.
+ Returns true if the operation was successful; in + case of error, it returns nil plus an error string. +
+ +
lfs.link (old, new[, symlink])
+
Creates a link. The first argument is the object to link to + and the second is the name of the link. If the optional third + argument is true, the link will by a symbolic link (by default, a + hard link is created). +
+ +
lfs.mkdir (dirname)
+
Creates a new directory. The argument is the name of the new + directory.
+ Returns true if the operation was successful; + in case of error, it returns nil plus an error string. +
+ +
lfs.rmdir (dirname)
+
Removes an existing directory. The argument is the name of the directory.
+ Returns true if the operation was successful; + in case of error, it returns nil plus an error string.
+ +
lfs.setmode (file, mode)
+
Sets the writing mode for a file. The mode string can be either "binary" or "text". + Returns true followed the previous mode string for the file, or + nil followed by an error string in case of errors. + On non-Windows platforms, where the two modes are identical, + setting the mode has no effect, and the mode is always returned as binary. +
+ +
lfs.symlinkattributes (filepath [, aname])
+
Identical to lfs.attributes except that + it obtains information about the link itself (not the file it refers to). + On Windows this function does not yet support links, and is identical to + lfs.attributes. +
+ +
lfs.touch (filepath [, atime [, mtime]])
+
Set access and modification times of a file. This function is + a bind to utime function. The first argument is the + filename, the second argument (atime) is the access time, + and the third argument (mtime) is the modification time. + Both times are provided in seconds (which should be generated with + Lua standard function os.time). + If the modification time is omitted, the access time provided is used; + if both times are omitted, the current time is used.
+ Returns true if the operation was successful; + in case of error, it returns nil plus an error string. +
+ +
lfs.unlock (filehandle[, start[, length]])
+
Unlocks a file or a part of it. This function works on + open files; the file handle should be specified as the first + argument. The optional arguments start and + length can be used to specify a starting point and its + length; both should be numbers.
+ Returns true if the operation was successful; + in case of error, it returns nil plus an error string. +
+
+ +
+ +
+ +
+

Valid XHTML 1.0!

+

$Id: manual.html,v 1.45 2009/06/03 20:53:55 mascarenhas Exp $

+
+ +
+ + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/luafilesystem-1.6.3-2.rockspec b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/luafilesystem-1.6.3-2.rockspec new file mode 100644 index 000000000..c27e2b711 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/luafilesystem-1.6.3-2.rockspec @@ -0,0 +1,29 @@ +package = "LuaFileSystem" +version = "1.6.3-2" +source = { + url = "git://github.com/keplerproject/luafilesystem", + tag = "v_1_6_3" +} +description = { + summary = "File System Library for the Lua Programming Language", + detailed = [[ + LuaFileSystem is a Lua library developed to complement the set of + functions related to file systems offered by the standard Lua + distribution. LuaFileSystem offers a portable way to access the + underlying directory structure and file attributes. + ]], + homepage = "http://keplerproject.github.io/luafilesystem", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1" +} +build = { + type = "builtin", + modules = { + lfs = "src/lfs.c" + }, + copy_directories = { + "doc", "tests" + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/rock_manifest b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/rock_manifest new file mode 100644 index 000000000..b0f7b6332 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/rock_manifest @@ -0,0 +1,19 @@ +rock_manifest = { + doc = { + us = { + ["doc.css"] = "d0a913514fb190240b3b4033d105cbc0", + ["examples.html"] = "5832f72021728374cf57b621d62ce0ff", + ["index.html"] = "96885bdda963939f0a363b5fa6b16b59", + ["license.html"] = "e3a756835cb7c8ae277d5e513c8e32ee", + ["luafilesystem.png"] = "81e923e976e99f894ea0aa8b52baff29", + ["manual.html"] = "d6473799b73ce486c3ea436586cb3b34" + } + }, + lib = { + ["lfs.dll"] = "165694685cffa6014be4ca8cbb7d920b" + }, + ["luafilesystem-1.6.3-2.rockspec"] = "eb0ef7c190516892eb8357af799eea5f", + tests = { + ["test.lua"] = "7b4ddb5bdb7e0b1b1ed0150d473535c9" + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/tests/test.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/tests/test.lua new file mode 100644 index 000000000..abfbd4d96 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/luafilesystem/1.6.3-2/tests/test.lua @@ -0,0 +1,175 @@ +#!/usr/bin/env lua5.1 + +local tmp = "/tmp" +local sep = string.match (package.config, "[^\n]+") +local upper = ".." + +local lfs = require"lfs" +print (lfs._VERSION) + +io.write(".") +io.flush() + +function attrdir (path) + for file in lfs.dir(path) do + if file ~= "." and file ~= ".." then + local f = path..sep..file + print ("\t=> "..f.." <=") + local attr = lfs.attributes (f) + assert (type(attr) == "table") + if attr.mode == "directory" then + attrdir (f) + else + for name, value in pairs(attr) do + print (name, value) + end + end + end + end +end + +-- Checking changing directories +local current = assert (lfs.currentdir()) +local reldir = string.gsub (current, "^.*%"..sep.."([^"..sep.."])$", "%1") +assert (lfs.chdir (upper), "could not change to upper directory") +assert (lfs.chdir (reldir), "could not change back to current directory") +assert (lfs.currentdir() == current, "error trying to change directories") +assert (lfs.chdir ("this couldn't be an actual directory") == nil, "could change to a non-existent directory") + +io.write(".") +io.flush() + +-- Changing creating and removing directories +local tmpdir = current..sep.."lfs_tmp_dir" +local tmpfile = tmpdir..sep.."tmp_file" +-- Test for existence of a previous lfs_tmp_dir +-- that may have resulted from an interrupted test execution and remove it +if lfs.chdir (tmpdir) then + assert (lfs.chdir (upper), "could not change to upper directory") + assert (os.remove (tmpfile), "could not remove file from previous test") + assert (lfs.rmdir (tmpdir), "could not remove directory from previous test") +end + +io.write(".") +io.flush() + +-- tries to create a directory +assert (lfs.mkdir (tmpdir), "could not make a new directory") +local attrib, errmsg = lfs.attributes (tmpdir) +if not attrib then + error ("could not get attributes of file `"..tmpdir.."':\n"..errmsg) +end +local f = io.open(tmpfile, "w") +f:close() + +io.write(".") +io.flush() + +-- Change access time +local testdate = os.time({ year = 2007, day = 10, month = 2, hour=0}) +assert (lfs.touch (tmpfile, testdate)) +local new_att = assert (lfs.attributes (tmpfile)) +assert (new_att.access == testdate, "could not set access time") +assert (new_att.modification == testdate, "could not set modification time") + +io.write(".") +io.flush() + +-- Change access and modification time +local testdate1 = os.time({ year = 2007, day = 10, month = 2, hour=0}) +local testdate2 = os.time({ year = 2007, day = 11, month = 2, hour=0}) + +assert (lfs.touch (tmpfile, testdate2, testdate1)) +local new_att = assert (lfs.attributes (tmpfile)) +assert (new_att.access == testdate2, "could not set access time") +assert (new_att.modification == testdate1, "could not set modification time") + +io.write(".") +io.flush() + +-- Checking link (does not work on Windows) +if lfs.link (tmpfile, "_a_link_for_test_", true) then + assert (lfs.attributes"_a_link_for_test_".mode == "file") + assert (lfs.symlinkattributes"_a_link_for_test_".mode == "link") + assert (lfs.link (tmpfile, "_a_hard_link_for_test_")) + assert (lfs.attributes (tmpfile, "nlink") == 2) + assert (os.remove"_a_link_for_test_") + assert (os.remove"_a_hard_link_for_test_") +end + +io.write(".") +io.flush() + +-- Checking text/binary modes (only has an effect in Windows) +local f = io.open(tmpfile, "w") +local result, mode = lfs.setmode(f, "binary") +assert(result) -- on non-Windows platforms, mode is always returned as "binary" +result, mode = lfs.setmode(f, "text") +assert(result and mode == "binary") +f:close() + +io.write(".") +io.flush() + +-- Restore access time to current value +assert (lfs.touch (tmpfile, attrib.access, attrib.modification)) +new_att = assert (lfs.attributes (tmpfile)) +assert (new_att.access == attrib.access) +assert (new_att.modification == attrib.modification) + +io.write(".") +io.flush() + +-- Check consistency of lfs.attributes values +local attr = lfs.attributes (tmpfile) +for key, value in pairs(attr) do + assert (value == lfs.attributes (tmpfile, key), + "lfs.attributes values not consistent") +end + +-- Remove new file and directory +assert (os.remove (tmpfile), "could not remove new file") +assert (lfs.rmdir (tmpdir), "could not remove new directory") +assert (lfs.mkdir (tmpdir..sep.."lfs_tmp_dir") == nil, "could create a directory inside a non-existent one") + +io.write(".") +io.flush() + +-- Trying to get attributes of a non-existent file +assert (lfs.attributes ("this couldn't be an actual file") == nil, "could get attributes of a non-existent file") +assert (type(lfs.attributes (upper)) == "table", "couldn't get attributes of upper directory") + +io.write(".") +io.flush() + +-- Stressing directory iterator +count = 0 +for i = 1, 4000 do + for file in lfs.dir (tmp) do + count = count + 1 + end +end + +io.write(".") +io.flush() + +-- Stressing directory iterator, explicit version +count = 0 +for i = 1, 4000 do + local iter, dir = lfs.dir(tmp) + local file = dir:next() + while file do + count = count + 1 + file = dir:next() + end + assert(not pcall(dir.next, dir)) +end + +io.write(".") +io.flush() + +-- directory explicit close +local iter, dir = lfs.dir(tmp) +dir:close() +assert(not pcall(dir.next, dir)) +print"Ok!" diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/manifest b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/manifest new file mode 100644 index 000000000..3b022bd4f --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/manifest @@ -0,0 +1,599 @@ +commands = { + luadocumentor = { + "luadocumentor/0.1.5-1" + } +} +dependencies = { + checks = { + ["1.0-1"] = { + { + constraints = { + { + op = ">=", + version = { + 5, 1, string = "5.1" + } + } + }, + name = "lua" + } + } + }, + luadocumentor = { + ["0.1.5-1"] = { + { + constraints = { + { + op = "~>", + version = { + 5, 1, string = "5.1" + } + } + }, + name = "lua" + }, { + constraints = { + { + op = "~>", + version = { + 1, 6, string = "1.6" + } + } + }, + name = "luafilesystem" + }, { + constraints = { + { + op = "~>", + version = { + 0, 32, string = "0.32" + } + } + }, + name = "markdown" + }, { + constraints = { + { + op = "~>", + version = { + 0, 7, string = "0.7" + } + } + }, + name = "metalua-compiler" + }, { + constraints = { + { + op = "~>", + version = { + 0, 9, string = "0.9" + } + } + }, + name = "penlight" + } + } + }, + luafilesystem = { + ["1.6.3-2"] = { + { + constraints = { + { + op = ">=", + version = { + 5, 1, string = "5.1" + } + } + }, + name = "lua" + } + } + }, + markdown = { + ["0.32-2"] = { + { + constraints = { + { + op = ">=", + version = { + 5, 1, string = "5.1" + } + } + }, + name = "lua" + } + } + }, + ["metalua-compiler"] = { + ["0.7.3-1"] = { + { + constraints = { + { + op = "~>", + version = { + 5, 1, string = "5.1" + } + } + }, + name = "lua" + }, { + constraints = { + { + op = "~>", + version = { + 1, 6, string = "1.6" + } + } + }, + name = "luafilesystem" + }, { + constraints = { + { + op = ">=", + version = { + 0, 7, 3, string = "0.7.3" + } + } + }, + name = "metalua-parser" + } + } + }, + ["metalua-parser"] = { + ["0.7.3-2"] = { + { + constraints = { + { + op = ">=", + version = { + 5, 1, string = "5.1" + } + } + }, + name = "lua" + } + } + }, + penlight = { + ["0.9.8-1"] = { + { + constraints = {}, + name = "luafilesystem" + } + } + } +} +modules = { + checks = { + "checks/1.0-1" + }, + defaultcss = { + "luadocumentor/0.1.5-1" + }, + docgenerator = { + "luadocumentor/0.1.5-1" + }, + extractors = { + "luadocumentor/0.1.5-1" + }, + ["fs.lfs"] = { + "luadocumentor/0.1.5-1" + }, + lddextractor = { + "luadocumentor/0.1.5-1" + }, + lfs = { + "luafilesystem/1.6.3-2" + }, + markdown = { + "markdown/0.32-2" + }, + ["metalua.compiler"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.bytecode"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua.compiler.bytecode.compile"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua.compiler.bytecode.lcode"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua.compiler.bytecode.ldump"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua.compiler.bytecode.lopcodes"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua.compiler.globals"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua.compiler.parser"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.parser.annot.generator"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.parser.annot.grammar"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.parser.expr"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.parser.ext"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.parser.lexer"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.parser.meta"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.parser.misc"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.parser.stat"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.compiler.parser.table"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.grammar.generator"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.grammar.lexer"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua.loader"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua.pprint"] = { + "metalua-parser/0.7.3-2" + }, + ["metalua/compiler/ast_to_src.mlua"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua/extension/comprehension.mlua"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua/extension/match.mlua"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua/repl.mlua"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua/treequery.mlua"] = { + "metalua-compiler/0.7.3-1" + }, + ["metalua/treequery/walk.mlua"] = { + "metalua-compiler/0.7.3-1" + }, + ["models.apimodel"] = { + "luadocumentor/0.1.5-1" + }, + ["models.apimodelbuilder"] = { + "luadocumentor/0.1.5-1" + }, + ["models.internalmodel"] = { + "luadocumentor/0.1.5-1" + }, + ["models.ldparser"] = { + "luadocumentor/0.1.5-1" + }, + ["models/internalmodelbuilder.mlua"] = { + "luadocumentor/0.1.5-1" + }, + pl = { + "penlight/0.9.8-1" + }, + ["pl.Date"] = { + "penlight/0.9.8-1" + }, + ["pl.List"] = { + "penlight/0.9.8-1" + }, + ["pl.Map"] = { + "penlight/0.9.8-1" + }, + ["pl.MultiMap"] = { + "penlight/0.9.8-1" + }, + ["pl.OrderedMap"] = { + "penlight/0.9.8-1" + }, + ["pl.Set"] = { + "penlight/0.9.8-1" + }, + ["pl.app"] = { + "penlight/0.9.8-1" + }, + ["pl.array2d"] = { + "penlight/0.9.8-1" + }, + ["pl.class"] = { + "penlight/0.9.8-1" + }, + ["pl.comprehension"] = { + "penlight/0.9.8-1" + }, + ["pl.config"] = { + "penlight/0.9.8-1" + }, + ["pl.data"] = { + "penlight/0.9.8-1" + }, + ["pl.dir"] = { + "penlight/0.9.8-1" + }, + ["pl.file"] = { + "penlight/0.9.8-1" + }, + ["pl.func"] = { + "penlight/0.9.8-1" + }, + ["pl.input"] = { + "penlight/0.9.8-1" + }, + ["pl.lapp"] = { + "penlight/0.9.8-1" + }, + ["pl.lexer"] = { + "penlight/0.9.8-1" + }, + ["pl.luabalanced"] = { + "penlight/0.9.8-1" + }, + ["pl.operator"] = { + "penlight/0.9.8-1" + }, + ["pl.path"] = { + "penlight/0.9.8-1" + }, + ["pl.permute"] = { + "penlight/0.9.8-1" + }, + ["pl.platf.luajava"] = { + "penlight/0.9.8-1" + }, + ["pl.pretty"] = { + "penlight/0.9.8-1" + }, + ["pl.seq"] = { + "penlight/0.9.8-1" + }, + ["pl.sip"] = { + "penlight/0.9.8-1" + }, + ["pl.strict"] = { + "penlight/0.9.8-1" + }, + ["pl.stringio"] = { + "penlight/0.9.8-1" + }, + ["pl.stringx"] = { + "penlight/0.9.8-1" + }, + ["pl.tablex"] = { + "penlight/0.9.8-1" + }, + ["pl.template"] = { + "penlight/0.9.8-1" + }, + ["pl.test"] = { + "penlight/0.9.8-1" + }, + ["pl.text"] = { + "penlight/0.9.8-1" + }, + ["pl.utils"] = { + "penlight/0.9.8-1" + }, + ["pl.xml"] = { + "penlight/0.9.8-1" + }, + ["template.file"] = { + "luadocumentor/0.1.5-1" + }, + ["template.index"] = { + "luadocumentor/0.1.5-1" + }, + ["template.index.recordtypedef"] = { + "luadocumentor/0.1.5-1" + }, + ["template.item"] = { + "luadocumentor/0.1.5-1" + }, + ["template.page"] = { + "luadocumentor/0.1.5-1" + }, + ["template.recordtypedef"] = { + "luadocumentor/0.1.5-1" + }, + ["template.usage"] = { + "luadocumentor/0.1.5-1" + }, + ["template.utils"] = { + "luadocumentor/0.1.5-1" + }, + templateengine = { + "luadocumentor/0.1.5-1" + } +} +repository = { + checks = { + ["1.0-1"] = { + { + arch = "installed", + commands = {}, + dependencies = {}, + modules = { + checks = "checks.dll" + } + } + } + }, + luadocumentor = { + ["0.1.5-1"] = { + { + arch = "installed", + commands = { + luadocumentor = "luadocumentor" + }, + dependencies = { + luafilesystem = "1.6.3-2", + markdown = "0.32-2", + ["metalua-compiler"] = "0.7.3-1", + ["metalua-parser"] = "0.7.3-2", + penlight = "0.9.8-1" + }, + modules = { + defaultcss = "defaultcss.lua", + docgenerator = "docgenerator.lua", + extractors = "extractors.lua", + ["fs.lfs"] = "fs/lfs.lua", + lddextractor = "lddextractor.lua", + ["models.apimodel"] = "models/apimodel.lua", + ["models.apimodelbuilder"] = "models/apimodelbuilder.lua", + ["models.internalmodel"] = "models/internalmodel.lua", + ["models.ldparser"] = "models/ldparser.lua", + ["models/internalmodelbuilder.mlua"] = "models/internalmodelbuilder.mlua", + ["template.file"] = "template/file.lua", + ["template.index"] = "template/index.lua", + ["template.index.recordtypedef"] = "template/index/recordtypedef.lua", + ["template.item"] = "template/item.lua", + ["template.page"] = "template/page.lua", + ["template.recordtypedef"] = "template/recordtypedef.lua", + ["template.usage"] = "template/usage.lua", + ["template.utils"] = "template/utils.lua", + templateengine = "templateengine.lua" + } + } + } + }, + luafilesystem = { + ["1.6.3-2"] = { + { + arch = "installed", + commands = {}, + dependencies = {}, + modules = { + lfs = "lfs.dll" + } + } + } + }, + markdown = { + ["0.32-2"] = { + { + arch = "installed", + commands = {}, + dependencies = {}, + modules = { + markdown = "markdown.lua" + } + } + } + }, + ["metalua-compiler"] = { + ["0.7.3-1"] = { + { + arch = "installed", + commands = {}, + dependencies = { + luafilesystem = "1.6.3-2", + ["metalua-parser"] = "0.7.3-2" + }, + modules = { + ["metalua.compiler.bytecode"] = "metalua/compiler/bytecode.lua", + ["metalua.compiler.bytecode.compile"] = "metalua/compiler/bytecode/compile.lua", + ["metalua.compiler.bytecode.lcode"] = "metalua/compiler/bytecode/lcode.lua", + ["metalua.compiler.bytecode.ldump"] = "metalua/compiler/bytecode/ldump.lua", + ["metalua.compiler.bytecode.lopcodes"] = "metalua/compiler/bytecode/lopcodes.lua", + ["metalua.compiler.globals"] = "metalua/compiler/globals.lua", + ["metalua.loader"] = "metalua/loader.lua", + ["metalua/compiler/ast_to_src.mlua"] = "metalua/compiler/ast_to_src.mlua", + ["metalua/extension/comprehension.mlua"] = "metalua/extension/comprehension.mlua", + ["metalua/extension/match.mlua"] = "metalua/extension/match.mlua", + ["metalua/repl.mlua"] = "metalua/repl.mlua", + ["metalua/treequery.mlua"] = "metalua/treequery.mlua", + ["metalua/treequery/walk.mlua"] = "metalua/treequery/walk.mlua" + } + } + } + }, + ["metalua-parser"] = { + ["0.7.3-2"] = { + { + arch = "installed", + commands = {}, + dependencies = {}, + modules = { + ["metalua.compiler"] = "metalua/compiler.lua", + ["metalua.compiler.parser"] = "metalua/compiler/parser.lua", + ["metalua.compiler.parser.annot.generator"] = "metalua/compiler/parser/annot/generator.lua", + ["metalua.compiler.parser.annot.grammar"] = "metalua/compiler/parser/annot/grammar.lua", + ["metalua.compiler.parser.expr"] = "metalua/compiler/parser/expr.lua", + ["metalua.compiler.parser.ext"] = "metalua/compiler/parser/ext.lua", + ["metalua.compiler.parser.lexer"] = "metalua/compiler/parser/lexer.lua", + ["metalua.compiler.parser.meta"] = "metalua/compiler/parser/meta.lua", + ["metalua.compiler.parser.misc"] = "metalua/compiler/parser/misc.lua", + ["metalua.compiler.parser.stat"] = "metalua/compiler/parser/stat.lua", + ["metalua.compiler.parser.table"] = "metalua/compiler/parser/table.lua", + ["metalua.grammar.generator"] = "metalua/grammar/generator.lua", + ["metalua.grammar.lexer"] = "metalua/grammar/lexer.lua", + ["metalua.pprint"] = "metalua/pprint.lua" + } + } + } + }, + penlight = { + ["0.9.8-1"] = { + { + arch = "installed", + commands = {}, + dependencies = { + luafilesystem = "1.6.3-2" + }, + modules = { + pl = "pl/init.lua", + ["pl.Date"] = "pl/Date.lua", + ["pl.List"] = "pl/List.lua", + ["pl.Map"] = "pl/Map.lua", + ["pl.MultiMap"] = "pl/MultiMap.lua", + ["pl.OrderedMap"] = "pl/OrderedMap.lua", + ["pl.Set"] = "pl/Set.lua", + ["pl.app"] = "pl/app.lua", + ["pl.array2d"] = "pl/array2d.lua", + ["pl.class"] = "pl/class.lua", + ["pl.comprehension"] = "pl/comprehension.lua", + ["pl.config"] = "pl/config.lua", + ["pl.data"] = "pl/data.lua", + ["pl.dir"] = "pl/dir.lua", + ["pl.file"] = "pl/file.lua", + ["pl.func"] = "pl/func.lua", + ["pl.input"] = "pl/input.lua", + ["pl.lapp"] = "pl/lapp.lua", + ["pl.lexer"] = "pl/lexer.lua", + ["pl.luabalanced"] = "pl/luabalanced.lua", + ["pl.operator"] = "pl/operator.lua", + ["pl.path"] = "pl/path.lua", + ["pl.permute"] = "pl/permute.lua", + ["pl.platf.luajava"] = "pl/platf/luajava.lua", + ["pl.pretty"] = "pl/pretty.lua", + ["pl.seq"] = "pl/seq.lua", + ["pl.sip"] = "pl/sip.lua", + ["pl.strict"] = "pl/strict.lua", + ["pl.stringio"] = "pl/stringio.lua", + ["pl.stringx"] = "pl/stringx.lua", + ["pl.tablex"] = "pl/tablex.lua", + ["pl.template"] = "pl/template.lua", + ["pl.test"] = "pl/test.lua", + ["pl.text"] = "pl/text.lua", + ["pl.utils"] = "pl/utils.lua", + ["pl.xml"] = "pl/xml.lua" + } + } + } + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/markdown/0.32-2/markdown-0.32-2.rockspec b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/markdown/0.32-2/markdown-0.32-2.rockspec new file mode 100644 index 000000000..abbfc89e1 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/markdown/0.32-2/markdown-0.32-2.rockspec @@ -0,0 +1,23 @@ +package = "Markdown" +version = "0.32-2" +source = { + url = "http://www.frykholm.se/files/markdown-0.32.tar.gz", + dir = "." +} +description = { + summary = "Markdown text-to-html markup system.", + detailed = [[ + A pure-lua implementation of the Markdown text-to-html markup system. + ]], + license = "MIT", + homepage = "http://www.frykholm.se/files/markdown.lua" +} +dependencies = { + "lua >= 5.1", +} +build = { + type = "none", + install = { + lua = { "markdown.lua" }, + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/markdown/0.32-2/rock_manifest b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/markdown/0.32-2/rock_manifest new file mode 100644 index 000000000..8f3d633ca --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/markdown/0.32-2/rock_manifest @@ -0,0 +1,6 @@ +rock_manifest = { + lua = { + ["markdown.lua"] = "0ea5f9d6d22a6c9aa4fdf63cf1d7d066" + }, + ["markdown-0.32-2.rockspec"] = "83f0335058d8fbd078d4f2c1ce941df0" +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/doc/README-compiler.md b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/doc/README-compiler.md new file mode 100644 index 000000000..b2679cdb5 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/doc/README-compiler.md @@ -0,0 +1,104 @@ +Metalua Compiler +================ + +## Metalua compiler + +This module `metalua-compiler` depends on `metalua-parser`. Its main +feature is to compile ASTs into Lua 5.1 bytecode, allowing to convert +them into bytecode files and executable functions. This opens the +following possibilities: + +* compiler objects generated with `require 'metalua.compiler'.new()` + support methods `:xxx_to_function()` and `:xxx_to_bytecode()`; + +* Compile-time meta-programming: use of `-{...}` splices in source + code, to generate code during compilation; + +* Some syntax extensions, such as structural pattern matching and + lists by comprehension; + +* Some AST manipulation facilities such as `treequery`, which are + implemented with Metalua syntax extensions. + +## What's new in Metalua 0.7 + +This is a major overhaul of the compiler's architecture. Some of the +most noteworthy changes are: + +* No more installation or bootstrap script. Some Metalua source files + have been rewritten in plain Lua, and module sources have been + refactored, so that if you just drop the `metalua` folder somewhere + in your `LUA_PATH`, it works. + +* The compiler can be cut in two parts: + + * a parser which generates ASTs out of Lua sources, and should be + either portable or easily ported to Lua 5.2; + + * a compiler, which can turn sources and AST into executable + Lua 5.1 bytecode and run it. It also supports compile-time + meta-programming, i.e. code included between `-{ ... }` is + executed during compilation, and the ASTs it produces are + included in the resulting bytecode. + +* Both parts are packaged as separate LuaRocks, `metalua-parser` and + `metalua-compiler` respectively, so that you can install the former + without the latter. + +* The parser is not a unique object anymore. Instead, + `require "metalua.compiler".new()` returns a different compiler + instance every time it's called. Compiler instances can be reused on + as many source files as wanted, but extending one instance's grammar + doesn't affect other compiler instances. + +* Included standard library has been shed. There are too many standard + libs in Lua, and none of them is standard enough, offering + yet-another-one, coupled with a specific compiler can only add to + confusion. + +* Many syntax extensions, which either were arguably more code samples + than actual production-ready tools, or relied too heavily on the + removed runtime standard libraries, have been removed. + +* The remaining libraries and samples are: + + * `metalua.compiler` converts sources into ASTs, bytecode, + functions, and ASTs back into sources. + + * `metalua` compiles and/or executes files from the command line, + can start an interactive REPL session. + + * `metalua.loader` adds a package loader which allows to use modules + written in Metalua, even from a plain Lua program. + + * `metalua.treequery` is an advanced DSL allowing to search ASTs in + a smart way, e.g. "_search `return` statements which return a + `local` variable but aren't in a nested `function`_". + + * `metalua.extension.comprehension` is a language extension which + supports lists by comprehension + (`even = { i for i=1, 100 if i%2==0 }`) and improved loops + (`for i=1, 10 for j=1,10 if i~=j do print(i,j) end`). + + * `metalua.extension.match` is a language extension which offers + Haskell/ML structural pattern matching + (``match AST with `Function{ args, body } -> ... | `Number{ 0 } -> ...end``) + + * **TODO Move basic extensions in a separate module.** + +* To remove the compilation speed penalty associated with + metaprogramming, when environment variable `LUA_MCACHE` or Lua + variable `package.mcache` is defined and LuaFileSystem is available, + the results of Metalua source compilations is cached. Unless the + source file is more recent than the latest cached bytecode file, the + latter is loaded instead of the former. + +* The Luarock install for the full compiler lists dependencies towards + Readline, LuaFileSytem, and Alt-Getopts. Those projects are + optional, but having them automatically installed by LuaRocks offers + a better user experience. + +* The license has changed from MIT to double license MIT + EPL. This + has been done in order to provide the IP guarantees expected by the + Eclipse Foundation, to include Metalua in Eclipse's + [Lua Development Tools](http://www.eclipse.org/koneki/ldt/). diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/doc/README-parser.md b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/doc/README-parser.md new file mode 100644 index 000000000..98e34ee43 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/doc/README-parser.md @@ -0,0 +1,177 @@ +Metalua Parser +============== + +`metalua-parser` is a subset of the Metalua compiler, which turns +valid Lua source files and strings into abstract syntax trees +(AST). This README includes a description of this AST format. People +interested by Lua code analysis and generation are encouraged to +produce and/or consume this format to represent ASTs. + +It has been designed for Lua 5.1. It hasn't been tested against +Lua 5.2, but should be easily ported. + +## Usage + +Module `metalua.compiler` has a `new()` function, which returns a +compiler instance. This instance has a set of methods of the form +`:xxx_to_yyy(input)`, where `xxx` and `yyy` must be one of the +following: + +* `srcfile` the name of a Lua source file; +* `src` a string containing the Lua sources of a list of statements; +* `lexstream` a lexical tokens stream; +* `ast` an abstract syntax tree; +* `bytecode` a chunk of Lua bytecode that can be loaded in a Lua 5.1 + VM (not available if you only installed the parser); +* `function` an executable Lua function. + +Compiling into bytecode or executable functions requires the whole +Metalua compiler, not only the parser. The most frequently used +functions are `:src_to_ast(source_string)` and +`:srcfile_to_ast("path/to/source/file.lua")`. + + mlc = require 'metalua.compiler'.new() + ast = mlc :src_to_ast[[ return 123 ]] + +A compiler instance can be reused as much as you want; it's only +interesting to work with more than one compiler instance when you +start extending their grammars. + +## Abstract Syntax Trees definition + +### Notation + +Trees are written below with some Metalua syntax sugar, which +increases their readability. the backquote symbol introduces a `tag`, +i.e. a string stored in the `"tag"` field of a table: + +* `` `Foo{ 1, 2, 3 }`` is a shortcut for `{tag="Foo", 1, 2, 3}`; +* `` `Foo`` is a shortcut for `{tag="Foo"}`; +* `` `Foo 123`` is a shortcut for `` `Foo{ 123 }``, and therefore + `{tag="Foo", 123 }`; the expression after the tag must be a literal + number or string. + +When using a Metalua interpreter or compiler, the backtick syntax is +supported and can be used directly. Metalua's pretty-printing helpers +also try to use backtick syntax whenever applicable. + +### Tree elements + +Tree elements are mainly categorized into statements `stat`, +expressions `expr` and lists of statements `block`. Auxiliary +definitions include function applications/method invocation `apply`, +are both valid statements and expressions, expressions admissible on +the left-hand-side of an assignment statement `lhs`. + + block: { stat* } + + stat: + `Do{ stat* } + | `Set{ {lhs+} {expr+} } -- lhs1, lhs2... = e1, e2... + | `While{ expr block } -- while e do b end + | `Repeat{ block expr } -- repeat b until e + | `If{ (expr block)+ block? } -- if e1 then b1 [elseif e2 then b2] ... [else bn] end + | `Fornum{ ident expr expr expr? block } -- for ident = e, e[, e] do b end + | `Forin{ {ident+} {expr+} block } -- for i1, i2... in e1, e2... do b end + | `Local{ {ident+} {expr+}? } -- local i1, i2... = e1, e2... + | `Localrec{ ident expr } -- only used for 'local function' + | `Goto{ } -- goto str + | `Label{ } -- ::str:: + | `Return{ } -- return e1, e2... + | `Break -- break + | apply + + expr: + `Nil | `Dots | `True | `False + | `Number{ } + | `String{ } + | `Function{ { ident* `Dots? } block } + | `Table{ ( `Pair{ expr expr } | expr )* } + | `Op{ opid expr expr? } + | `Paren{ expr } -- significant to cut multiple values returns + | apply + | lhs + + apply: + `Call{ expr expr* } + | `Invoke{ expr `String{ } expr* } + + ident: `Id{ } + + lhs: ident | `Index{ expr expr } + + opid: 'add' | 'sub' | 'mul' | 'div' + | 'mod' | 'pow' | 'concat'| 'eq' + | 'lt' | 'le' | 'and' | 'or' + | 'not' | 'len' + +### Meta-data (lineinfo) + + +ASTs also embed some metadata, allowing to map them to their source +representation. Those informations are stored in a `"lineinfo"` field +in each tree node, which points to the range of characters in the +source string which represents it, and to the content of any comment +that would appear immediately before or after that node. + +Lineinfo objects have two fields, `"first"` and `"last"`, describing +respectively the beginning and the end of the subtree in the +sources. For instance, the sub-node ``Number{123}` produced by parsing +`[[return 123]]` will have `lineinfo.first` describing offset 8, and +`lineinfo.last` describing offset 10: + + + > mlc = require 'metalua.compiler'.new() + > ast = mlc :src_to_ast "return 123 -- comment" + > print(ast[1][1].lineinfo) + + > + +A lineinfo keeps track of character offsets relative to the beginning +of the source string/file ("K8-10" above), line numbers (L1 above; a +lineinfo spanning on several lines would read something like "L1-10"), +columns i.e. offset within the line ("C8-10" above), and a filename if +available (the "?" mark above indicating that we have no file name, as +the AST comes from a string). The final "|C>" indicates that there's a +comment immediately after the node; an initial " 5.1", -- Lua 5.2 bytecode not supported + "luafilesystem ~> 1.6", -- Cached compilation based on file timestamps + "metalua-parser >= 0.7.3", -- AST production +} + +build = { + type="builtin", + modules={ + ["metalua.compiler.bytecode"] = "metalua/compiler/bytecode.lua", + ["metalua.compiler.globals"] = "metalua/compiler/globals.lua", + ["metalua.compiler.bytecode.compile"] = "metalua/compiler/bytecode/compile.lua", + ["metalua.compiler.bytecode.lcode"] = "metalua/compiler/bytecode/lcode.lua", + ["metalua.compiler.bytecode.lopcodes"] = "metalua/compiler/bytecode/lopcodes.lua", + ["metalua.compiler.bytecode.ldump"] = "metalua/compiler/bytecode/ldump.lua", + ["metalua.loader"] = "metalua/loader.lua", + }, + install={ + lua={ + ["metalua.treequery"] = "metalua/treequery.mlua", + ["metalua.compiler.ast_to_src"] = "metalua/compiler/ast_to_src.mlua", + ["metalua.treequery.walk"] = "metalua/treequery/walk.mlua", + ["metalua.extension.match"] = "metalua/extension/match.mlua", + ["metalua.extension.comprehension"] = "metalua/extension/comprehension.mlua", + ["metalua.repl"] = "metalua/repl.mlua", + } + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/rock_manifest b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/rock_manifest new file mode 100644 index 000000000..7452a8f94 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-compiler/0.7.3-1/rock_manifest @@ -0,0 +1,33 @@ +rock_manifest = { + doc = { + ["README-compiler.md"] = "292523d759247d210d32fb2f6153e0f4", + ["README-parser.md"] = "b44e3673d96dd296f2c0e92a6c87ee18", + ["README.md"] = "20bfb490cddef9e101e44688791abcda" + }, + lua = { + metalua = { + compiler = { + ["ast_to_src.mlua"] = "1309f76df37585ef8e1f67f748b07b22", + bytecode = { + ["compile.lua"] = "430e4a6fac8b64b5ebb3ae585ebae75a", + ["lcode.lua"] = "3ad8755ebe8ea8eca6b1d2846eec92c4", + ["ldump.lua"] = "295e1d9657fb0126ce3471b3366da694", + ["lopcodes.lua"] = "a0f15cfc93b026b0a868466d066f1d21" + }, + ["bytecode.lua"] = "1032e5233455fd4e504daf5d2893527b", + ["globals.lua"] = "80ae19c6e640de0746348c91633c4c55" + }, + extension = { + ["comprehension.mlua"] = "426f5856896bda4c3763bd5f61410685", + ["match.mlua"] = "79960265331e8b2f46199c2411a103de" + }, + ["loader.lua"] = "1cdbf6cdf6ca97c55540d068474f1d8a", + ["repl.mlua"] = "729456f3a8cc073788acee564a0495f0", + treequery = { + ["walk.mlua"] = "5159aaddbec55936f91ea4236f6451d3" + }, + ["treequery.mlua"] = "97ffcee0825ac3bc776d01566767b2e8" + } + }, + ["metalua-compiler-0.7.3-1.rockspec"] = "b3883b25641d862db6828300bb755d51" +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/doc/README-compiler.md b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/doc/README-compiler.md new file mode 100644 index 000000000..b2679cdb5 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/doc/README-compiler.md @@ -0,0 +1,104 @@ +Metalua Compiler +================ + +## Metalua compiler + +This module `metalua-compiler` depends on `metalua-parser`. Its main +feature is to compile ASTs into Lua 5.1 bytecode, allowing to convert +them into bytecode files and executable functions. This opens the +following possibilities: + +* compiler objects generated with `require 'metalua.compiler'.new()` + support methods `:xxx_to_function()` and `:xxx_to_bytecode()`; + +* Compile-time meta-programming: use of `-{...}` splices in source + code, to generate code during compilation; + +* Some syntax extensions, such as structural pattern matching and + lists by comprehension; + +* Some AST manipulation facilities such as `treequery`, which are + implemented with Metalua syntax extensions. + +## What's new in Metalua 0.7 + +This is a major overhaul of the compiler's architecture. Some of the +most noteworthy changes are: + +* No more installation or bootstrap script. Some Metalua source files + have been rewritten in plain Lua, and module sources have been + refactored, so that if you just drop the `metalua` folder somewhere + in your `LUA_PATH`, it works. + +* The compiler can be cut in two parts: + + * a parser which generates ASTs out of Lua sources, and should be + either portable or easily ported to Lua 5.2; + + * a compiler, which can turn sources and AST into executable + Lua 5.1 bytecode and run it. It also supports compile-time + meta-programming, i.e. code included between `-{ ... }` is + executed during compilation, and the ASTs it produces are + included in the resulting bytecode. + +* Both parts are packaged as separate LuaRocks, `metalua-parser` and + `metalua-compiler` respectively, so that you can install the former + without the latter. + +* The parser is not a unique object anymore. Instead, + `require "metalua.compiler".new()` returns a different compiler + instance every time it's called. Compiler instances can be reused on + as many source files as wanted, but extending one instance's grammar + doesn't affect other compiler instances. + +* Included standard library has been shed. There are too many standard + libs in Lua, and none of them is standard enough, offering + yet-another-one, coupled with a specific compiler can only add to + confusion. + +* Many syntax extensions, which either were arguably more code samples + than actual production-ready tools, or relied too heavily on the + removed runtime standard libraries, have been removed. + +* The remaining libraries and samples are: + + * `metalua.compiler` converts sources into ASTs, bytecode, + functions, and ASTs back into sources. + + * `metalua` compiles and/or executes files from the command line, + can start an interactive REPL session. + + * `metalua.loader` adds a package loader which allows to use modules + written in Metalua, even from a plain Lua program. + + * `metalua.treequery` is an advanced DSL allowing to search ASTs in + a smart way, e.g. "_search `return` statements which return a + `local` variable but aren't in a nested `function`_". + + * `metalua.extension.comprehension` is a language extension which + supports lists by comprehension + (`even = { i for i=1, 100 if i%2==0 }`) and improved loops + (`for i=1, 10 for j=1,10 if i~=j do print(i,j) end`). + + * `metalua.extension.match` is a language extension which offers + Haskell/ML structural pattern matching + (``match AST with `Function{ args, body } -> ... | `Number{ 0 } -> ...end``) + + * **TODO Move basic extensions in a separate module.** + +* To remove the compilation speed penalty associated with + metaprogramming, when environment variable `LUA_MCACHE` or Lua + variable `package.mcache` is defined and LuaFileSystem is available, + the results of Metalua source compilations is cached. Unless the + source file is more recent than the latest cached bytecode file, the + latter is loaded instead of the former. + +* The Luarock install for the full compiler lists dependencies towards + Readline, LuaFileSytem, and Alt-Getopts. Those projects are + optional, but having them automatically installed by LuaRocks offers + a better user experience. + +* The license has changed from MIT to double license MIT + EPL. This + has been done in order to provide the IP guarantees expected by the + Eclipse Foundation, to include Metalua in Eclipse's + [Lua Development Tools](http://www.eclipse.org/koneki/ldt/). diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/doc/README-parser.md b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/doc/README-parser.md new file mode 100644 index 000000000..98e34ee43 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/doc/README-parser.md @@ -0,0 +1,177 @@ +Metalua Parser +============== + +`metalua-parser` is a subset of the Metalua compiler, which turns +valid Lua source files and strings into abstract syntax trees +(AST). This README includes a description of this AST format. People +interested by Lua code analysis and generation are encouraged to +produce and/or consume this format to represent ASTs. + +It has been designed for Lua 5.1. It hasn't been tested against +Lua 5.2, but should be easily ported. + +## Usage + +Module `metalua.compiler` has a `new()` function, which returns a +compiler instance. This instance has a set of methods of the form +`:xxx_to_yyy(input)`, where `xxx` and `yyy` must be one of the +following: + +* `srcfile` the name of a Lua source file; +* `src` a string containing the Lua sources of a list of statements; +* `lexstream` a lexical tokens stream; +* `ast` an abstract syntax tree; +* `bytecode` a chunk of Lua bytecode that can be loaded in a Lua 5.1 + VM (not available if you only installed the parser); +* `function` an executable Lua function. + +Compiling into bytecode or executable functions requires the whole +Metalua compiler, not only the parser. The most frequently used +functions are `:src_to_ast(source_string)` and +`:srcfile_to_ast("path/to/source/file.lua")`. + + mlc = require 'metalua.compiler'.new() + ast = mlc :src_to_ast[[ return 123 ]] + +A compiler instance can be reused as much as you want; it's only +interesting to work with more than one compiler instance when you +start extending their grammars. + +## Abstract Syntax Trees definition + +### Notation + +Trees are written below with some Metalua syntax sugar, which +increases their readability. the backquote symbol introduces a `tag`, +i.e. a string stored in the `"tag"` field of a table: + +* `` `Foo{ 1, 2, 3 }`` is a shortcut for `{tag="Foo", 1, 2, 3}`; +* `` `Foo`` is a shortcut for `{tag="Foo"}`; +* `` `Foo 123`` is a shortcut for `` `Foo{ 123 }``, and therefore + `{tag="Foo", 123 }`; the expression after the tag must be a literal + number or string. + +When using a Metalua interpreter or compiler, the backtick syntax is +supported and can be used directly. Metalua's pretty-printing helpers +also try to use backtick syntax whenever applicable. + +### Tree elements + +Tree elements are mainly categorized into statements `stat`, +expressions `expr` and lists of statements `block`. Auxiliary +definitions include function applications/method invocation `apply`, +are both valid statements and expressions, expressions admissible on +the left-hand-side of an assignment statement `lhs`. + + block: { stat* } + + stat: + `Do{ stat* } + | `Set{ {lhs+} {expr+} } -- lhs1, lhs2... = e1, e2... + | `While{ expr block } -- while e do b end + | `Repeat{ block expr } -- repeat b until e + | `If{ (expr block)+ block? } -- if e1 then b1 [elseif e2 then b2] ... [else bn] end + | `Fornum{ ident expr expr expr? block } -- for ident = e, e[, e] do b end + | `Forin{ {ident+} {expr+} block } -- for i1, i2... in e1, e2... do b end + | `Local{ {ident+} {expr+}? } -- local i1, i2... = e1, e2... + | `Localrec{ ident expr } -- only used for 'local function' + | `Goto{ } -- goto str + | `Label{ } -- ::str:: + | `Return{ } -- return e1, e2... + | `Break -- break + | apply + + expr: + `Nil | `Dots | `True | `False + | `Number{ } + | `String{ } + | `Function{ { ident* `Dots? } block } + | `Table{ ( `Pair{ expr expr } | expr )* } + | `Op{ opid expr expr? } + | `Paren{ expr } -- significant to cut multiple values returns + | apply + | lhs + + apply: + `Call{ expr expr* } + | `Invoke{ expr `String{ } expr* } + + ident: `Id{ } + + lhs: ident | `Index{ expr expr } + + opid: 'add' | 'sub' | 'mul' | 'div' + | 'mod' | 'pow' | 'concat'| 'eq' + | 'lt' | 'le' | 'and' | 'or' + | 'not' | 'len' + +### Meta-data (lineinfo) + + +ASTs also embed some metadata, allowing to map them to their source +representation. Those informations are stored in a `"lineinfo"` field +in each tree node, which points to the range of characters in the +source string which represents it, and to the content of any comment +that would appear immediately before or after that node. + +Lineinfo objects have two fields, `"first"` and `"last"`, describing +respectively the beginning and the end of the subtree in the +sources. For instance, the sub-node ``Number{123}` produced by parsing +`[[return 123]]` will have `lineinfo.first` describing offset 8, and +`lineinfo.last` describing offset 10: + + + > mlc = require 'metalua.compiler'.new() + > ast = mlc :src_to_ast "return 123 -- comment" + > print(ast[1][1].lineinfo) + + > + +A lineinfo keeps track of character offsets relative to the beginning +of the source string/file ("K8-10" above), line numbers (L1 above; a +lineinfo spanning on several lines would read something like "L1-10"), +columns i.e. offset within the line ("C8-10" above), and a filename if +available (the "?" mark above indicating that we have no file name, as +the AST comes from a string). The final "|C>" indicates that there's a +comment immediately after the node; an initial "= 5.1" +} +build = { + type="builtin", + modules={ + ["metalua.grammar.generator"] = "metalua/grammar/generator.lua", + ["metalua.grammar.lexer"] = "metalua/grammar/lexer.lua", + ["metalua.compiler.parser"] = "metalua/compiler/parser.lua", + ["metalua.compiler.parser.table"] = "metalua/compiler/parser/table.lua", + ["metalua.compiler.parser.ext"] = "metalua/compiler/parser/ext.lua", + ["metalua.compiler.parser.annot.generator"] = "metalua/compiler/parser/annot/generator.lua", + ["metalua.compiler.parser.annot.grammar"] = "metalua/compiler/parser/annot/grammar.lua", + ["metalua.compiler.parser.stat"] = "metalua/compiler/parser/stat.lua", + ["metalua.compiler.parser.misc"] = "metalua/compiler/parser/misc.lua", + ["metalua.compiler.parser.lexer"] = "metalua/compiler/parser/lexer.lua", + ["metalua.compiler.parser.meta"] = "metalua/compiler/parser/meta.lua", + ["metalua.compiler.parser.expr"] = "metalua/compiler/parser/expr.lua", + ["metalua.compiler"] = "metalua/compiler.lua", + ["metalua.pprint"] = "metalua/pprint.lua", + } +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/rock_manifest b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/rock_manifest new file mode 100644 index 000000000..4640e3d33 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/metalua-parser/0.7.3-2/rock_manifest @@ -0,0 +1,34 @@ +rock_manifest = { + doc = { + ["README-compiler.md"] = "292523d759247d210d32fb2f6153e0f4", + ["README-parser.md"] = "b44e3673d96dd296f2c0e92a6c87ee18", + ["README.md"] = "20bfb490cddef9e101e44688791abcda" + }, + lua = { + metalua = { + compiler = { + parser = { + annot = { + ["generator.lua"] = "d86f7507d66ba6a3692a6f8611e9939b", + ["grammar.lua"] = "7d195bde7992efd9923771751b67b18f" + }, + ["expr.lua"] = "3a0b1984a6f92280e2e63b074fdcec10", + ["ext.lua"] = "a99e31a07bc390b826f6653bcc47d89b", + ["lexer.lua"] = "eac0f9d475d9dae4ea5a2724014cebec", + ["meta.lua"] = "12870bceda6395695020b739196e2a92", + ["misc.lua"] = "49d59f4fc1bfb77b36f78d4f87ae258f", + ["stat.lua"] = "83f10ac899be12ca4df58bbe8645299f", + ["table.lua"] = "5d2389e89603b7f78c731e6918aa1a9b" + }, + ["parser.lua"] = "e6ae68ce200de8071bb0fefad97f9b79" + }, + ["compiler.lua"] = "ca65ee9a3053581f4315821a31d0c1fd", + grammar = { + ["generator.lua"] = "b8a29e817d6798c12f40a230a0f6d0af", + ["lexer.lua"] = "7cb7c835479a9be884130eaacb9be60a" + }, + ["pprint.lua"] = "0b9bd8757b45c2d4be30106abcbd45b2" + } + }, + ["metalua-parser-0.7.3-2.rockspec"] = "a56680900b0b51701db7cd7abf49af92" +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/penlight/0.9.8-1/penlight-0.9.8-1.rockspec b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/penlight/0.9.8-1/penlight-0.9.8-1.rockspec new file mode 100644 index 000000000..d1d8b0f85 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/penlight/0.9.8-1/penlight-0.9.8-1.rockspec @@ -0,0 +1,66 @@ +package = "penlight" +version = "0.9.8-1" + +source = { + dir = "penlight-0.9.8", + url = "http://stevedonovan.github.com/files/penlight-0.9.8-core.zip", +} + +description = { + summary = "Lua utility libraries loosely based on the Python standard libraries", + homepage = "http://stevedonovan.github.com/Penlight", + license = "MIT/X11", + maintainer = "steve.j.donovan@gmail.com", + detailed = [[ +Penlight is a set of pure Lua libraries for making it easier to work with common tasks like +iterating over directories, reading configuration files and the like. Provides functional operations +on tables and sequences. +]] +} + +dependencies = { + "luafilesystem", +} + +build = { + type = "builtin", + modules = { + ["pl.strict"] = "lua/pl/strict.lua", + ["pl.dir"] = "lua/pl/dir.lua", + ["pl.operator"] = "lua/pl/operator.lua", + ["pl.input"] = "lua/pl/input.lua", + ["pl.config"] = "lua/pl/config.lua", + ["pl.seq"] = "lua/pl/seq.lua", + ["pl.stringio"] = "lua/pl/stringio.lua", + ["pl.text"] = "lua/pl/text.lua", + ["pl.test"] = "lua/pl/test.lua", + ["pl.tablex"] = "lua/pl/tablex.lua", + ["pl.app"] = "lua/pl/app.lua", + ["pl.stringx"] = "lua/pl/stringx.lua", + ["pl.lexer"] = "lua/pl/lexer.lua", + ["pl.utils"] = "lua/pl/utils.lua", + ["pl.sip"] = "lua/pl/sip.lua", + ["pl.permute"] = "lua/pl/permute.lua", + ["pl.pretty"] = "lua/pl/pretty.lua", + ["pl.class"] = "lua/pl/class.lua", + ["pl.List"] = "lua/pl/List.lua", + ["pl.data"] = "lua/pl/data.lua", + ["pl.Date"] = "lua/pl/Date.lua", + ["pl"] = "lua/pl/init.lua", + ["pl.luabalanced"] = "lua/pl/luabalanced.lua", + ["pl.comprehension"] = "lua/pl/comprehension.lua", + ["pl.path"] = "lua/pl/path.lua", + ["pl.array2d"] = "lua/pl/array2d.lua", + ["pl.func"] = "lua/pl/func.lua", + ["pl.lapp"] = "lua/pl/lapp.lua", + ["pl.file"] = "lua/pl/file.lua", + ['pl.template'] = "lua/pl/template.lua", + ["pl.Map"] = "lua/pl/Map.lua", + ["pl.MultiMap"] = "lua/pl/MultiMap.lua", + ["pl.OrderedMap"] = "lua/pl/OrderedMap.lua", + ["pl.Set"] = "lua/pl/Set.lua", + ["pl.xml"] = "lua/pl/xml.lua", + ["pl.platf.luajava"] = "lua/pl/platf/luajava.lua" + }, +} + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/penlight/0.9.8-1/rock_manifest b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/penlight/0.9.8-1/rock_manifest new file mode 100644 index 000000000..8565ebbd3 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/lib/luarocks/rocks/penlight/0.9.8-1/rock_manifest @@ -0,0 +1,45 @@ +rock_manifest = { + lua = { + pl = { + ["Date.lua"] = "d2131d59151ce978c4db6a648fcd275a", + ["List.lua"] = "1236c5eb08956619daacd25a462a9682", + ["Map.lua"] = "0297a536ac0595ac59e8828f8c867f53", + ["MultiMap.lua"] = "e5f898fe2443e51c38825e9bc3d1aee5", + ["OrderedMap.lua"] = "bd8e39c59e22c582a33e2f025d3ae914", + ["Set.lua"] = "346ff7392fd4aeda418fb832e8da7a7f", + ["app.lua"] = "23ffb79e69a3fd679013cf82d95ed792", + ["array2d.lua"] = "77618ec2e2de4d6d237484dfd742cd73", + ["class.lua"] = "6f58bf39e7f90711b6840ad6955d258e", + ["comprehension.lua"] = "f8600ba945dde5d959194500a687c69f", + ["config.lua"] = "9ea3ce0ac3cdf2ce0e17f1353f32abb6", + ["data.lua"] = "be446ff813b5bcf30b4063601165df6a", + ["dir.lua"] = "3d60d4c1caeaabe199fe361e4e9b14a4", + ["file.lua"] = "f5c9527ea14b511d2cb9af80b219c562", + ["func.lua"] = "cc50d73512b6d0518f6587b82844de8c", + ["init.lua"] = "9232be7d8790d4f907972a00dec7949d", + ["input.lua"] = "bab7c64ca9a740df5e9fb9909610bbc4", + ["lapp.lua"] = "1cc81f048bc3fcd775c40cd9a2d601a7", + ["lexer.lua"] = "da0db5e323a2d37545ccb02592d0d3c8", + ["luabalanced.lua"] = "00b94a997a9ea4d73f54c10893f3b35f", + ["operator.lua"] = "e606629c738966cf497bb938457adebd", + ["path.lua"] = "b0714bc337c068b7252f64250fe59604", + ["permute.lua"] = "b0ed9ba2787119ef99468329a54ea16a", + platf = { + ["luajava.lua"] = "9c2898667281ad9501cc05a8e31a6f53" + }, + ["pretty.lua"] = "3ece64317ce05916eaba91fa96d9e7c0", + ["seq.lua"] = "e99e420345ab11120a7b741d8184920a", + ["sip.lua"] = "bde74f65e7246017d3ef034d178100ea", + ["strict.lua"] = "720e939931dbbe42fad8fd4e7736435e", + ["stringio.lua"] = "a8f4c786ea1b62f16ed05e6b09840044", + ["stringx.lua"] = "43f57755969c6b4001316226506a3744", + ["tablex.lua"] = "dec027cc3a3901766bd933c5fc0f3e93", + ["template.lua"] = "f358175bbb84c401c6213c953ce295a4", + ["test.lua"] = "1c45f7b1c438673f1eb668e2ca592f1c", + ["text.lua"] = "c30f90cab2d00186a6432e408ba1fe14", + ["utils.lua"] = "68cd38638a29b4ab5f1cc0eae38dce77", + ["xml.lua"] = "e13ed468c450fccb9a8e858a0f787eef" + } + }, + ["penlight-0.9.8-1.rockspec"] = "96edac3ff1d0ac57cb45d6551a56a775" +} diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/man/man1/lua.1 b/Moose Development Evironment Setup/LuaFiles/lua/5.1/man/man1/lua.1 new file mode 100644 index 000000000..24809cc6c --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/man/man1/lua.1 @@ -0,0 +1,163 @@ +.\" $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $ +.TH LUA 1 "$Date: 2006/01/06 16:03:34 $" +.SH NAME +lua \- Lua interpreter +.SH SYNOPSIS +.B lua +[ +.I options +] +[ +.I script +[ +.I args +] +] +.SH DESCRIPTION +.B lua +is the stand-alone Lua interpreter. +It loads and executes Lua programs, +either in textual source form or +in precompiled binary form. +(Precompiled binaries are output by +.BR luac , +the Lua compiler.) +.B lua +can be used as a batch interpreter and also interactively. +.LP +The given +.I options +(see below) +are executed and then +the Lua program in file +.I script +is loaded and executed. +The given +.I args +are available to +.I script +as strings in a global table named +.BR arg . +If these arguments contain spaces or other characters special to the shell, +then they should be quoted +(but note that the quotes will be removed by the shell). +The arguments in +.B arg +start at 0, +which contains the string +.RI ' script '. +The index of the last argument is stored in +.BR arg.n . +The arguments given in the command line before +.IR script , +including the name of the interpreter, +are available in negative indices in +.BR arg . +.LP +At the very start, +before even handling the command line, +.B lua +executes the contents of the environment variable +.BR LUA_INIT , +if it is defined. +If the value of +.B LUA_INIT +is of the form +.RI '@ filename ', +then +.I filename +is executed. +Otherwise, the string is assumed to be a Lua statement and is executed. +.LP +Options start with +.B '\-' +and are described below. +You can use +.B "'\--'" +to signal the end of options. +.LP +If no arguments are given, +then +.B "\-v \-i" +is assumed when the standard input is a terminal; +otherwise, +.B "\-" +is assumed. +.LP +In interactive mode, +.B lua +prompts the user, +reads lines from the standard input, +and executes them as they are read. +If a line does not contain a complete statement, +then a secondary prompt is displayed and +lines are read until a complete statement is formed or +a syntax error is found. +So, one way to interrupt the reading of an incomplete statement is +to force a syntax error: +adding a +.B ';' +in the middle of a statement is a sure way of forcing a syntax error +(except inside multiline strings and comments; these must be closed explicitly). +If a line starts with +.BR '=' , +then +.B lua +displays the values of all the expressions in the remainder of the +line. The expressions must be separated by commas. +The primary prompt is the value of the global variable +.BR _PROMPT , +if this value is a string; +otherwise, the default prompt is used. +Similarly, the secondary prompt is the value of the global variable +.BR _PROMPT2 . +So, +to change the prompts, +set the corresponding variable to a string of your choice. +You can do that after calling the interpreter +or on the command line +(but in this case you have to be careful with quotes +if the prompt string contains a space; otherwise you may confuse the shell.) +The default prompts are "> " and ">> ". +.SH OPTIONS +.TP +.B \- +load and execute the standard input as a file, +that is, +not interactively, +even when the standard input is a terminal. +.TP +.BI \-e " stat" +execute statement +.IR stat . +You need to quote +.I stat +if it contains spaces, quotes, +or other characters special to the shell. +.TP +.B \-i +enter interactive mode after +.I script +is executed. +.TP +.BI \-l " name" +call +.BI require(' name ') +before executing +.IR script . +Typically used to load libraries. +.TP +.B \-v +show version information. +.SH "SEE ALSO" +.BR luac (1) +.br +http://www.lua.org/ +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +R. Ierusalimschy, +L. H. de Figueiredo, +and +W. Celes +.\" EOF diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/man/man1/luac.1 b/Moose Development Evironment Setup/LuaFiles/lua/5.1/man/man1/luac.1 new file mode 100644 index 000000000..d8146782d --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/man/man1/luac.1 @@ -0,0 +1,136 @@ +.\" $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $ +.TH LUAC 1 "$Date: 2006/01/06 16:03:34 $" +.SH NAME +luac \- Lua compiler +.SH SYNOPSIS +.B luac +[ +.I options +] [ +.I filenames +] +.SH DESCRIPTION +.B luac +is the Lua compiler. +It translates programs written in the Lua programming language +into binary files that can be later loaded and executed. +.LP +The main advantages of precompiling chunks are: +faster loading, +protecting source code from accidental user changes, +and +off-line syntax checking. +.LP +Pre-compiling does not imply faster execution +because in Lua chunks are always compiled into bytecodes before being executed. +.B luac +simply allows those bytecodes to be saved in a file for later execution. +.LP +Pre-compiled chunks are not necessarily smaller than the corresponding source. +The main goal in pre-compiling is faster loading. +.LP +The binary files created by +.B luac +are portable only among architectures with the same word size and byte order. +.LP +.B luac +produces a single output file containing the bytecodes +for all source files given. +By default, +the output file is named +.BR luac.out , +but you can change this with the +.B \-o +option. +.LP +In the command line, +you can mix +text files containing Lua source and +binary files containing precompiled chunks. +This is useful to combine several precompiled chunks, +even from different (but compatible) platforms, +into a single precompiled chunk. +.LP +You can use +.B "'\-'" +to indicate the standard input as a source file +and +.B "'\--'" +to signal the end of options +(that is, +all remaining arguments will be treated as files even if they start with +.BR "'\-'" ). +.LP +The internal format of the binary files produced by +.B luac +is likely to change when a new version of Lua is released. +So, +save the source files of all Lua programs that you precompile. +.LP +.SH OPTIONS +Options must be separate. +.TP +.B \-l +produce a listing of the compiled bytecode for Lua's virtual machine. +Listing bytecodes is useful to learn about Lua's virtual machine. +If no files are given, then +.B luac +loads +.B luac.out +and lists its contents. +.TP +.BI \-o " file" +output to +.IR file , +instead of the default +.BR luac.out . +(You can use +.B "'\-'" +for standard output, +but not on platforms that open standard output in text mode.) +The output file may be a source file because +all files are loaded before the output file is written. +Be careful not to overwrite precious files. +.TP +.B \-p +load files but do not generate any output file. +Used mainly for syntax checking and for testing precompiled chunks: +corrupted files will probably generate errors when loaded. +Lua always performs a thorough integrity test on precompiled chunks. +Bytecode that passes this test is completely safe, +in the sense that it will not break the interpreter. +However, +there is no guarantee that such code does anything sensible. +(None can be given, because the halting problem is unsolvable.) +If no files are given, then +.B luac +loads +.B luac.out +and tests its contents. +No messages are displayed if the file passes the integrity test. +.TP +.B \-s +strip debug information before writing the output file. +This saves some space in very large chunks, +but if errors occur when running a stripped chunk, +then the error messages may not contain the full information they usually do. +For instance, +line numbers and names of local variables are lost. +.TP +.B \-v +show version information. +.SH FILES +.TP 15 +.B luac.out +default output file +.SH "SEE ALSO" +.BR lua (1) +.br +http://www.lua.org/ +.SH DIAGNOSTICS +Error messages should be self explanatory. +.SH AUTHORS +L. H. de Figueiredo, +R. Ierusalimschy and +W. Celes +.\" EOF diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/defaultcss.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/defaultcss.lua new file mode 100644 index 000000000..2c2b331cc --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/defaultcss.lua @@ -0,0 +1,270 @@ +return [[html { + color: #000; + background: #FFF; +} +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { + margin: 0; + padding: 0; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +fieldset,img { + border: 0; +} +address,caption,cite,code,dfn,em,strong,th,var,optgroup { + font-style: inherit; + font-weight: inherit; +} +del,ins { + text-decoration: none; +} +li { + list-style: bullet; + margin-left: 20px; +} +caption,th { + text-align: left; +} +h1,h2,h3,h4,h5,h6 { + font-size: 100%; + font-weight: bold; +} +q:before,q:after { + content: ''; +} +abbr,acronym { + border: 0; + font-variant: normal; +} +sup { + vertical-align: baseline; +} +sub { + vertical-align: baseline; +} +legend { + color: #000; +} +input,button,textarea,select,optgroup,option { + font-family: inherit; + font-size: inherit; + font-style: inherit; + font-weight: inherit; +} +input,button,textarea,select {*font-size:100%; +} +/* END RESET */ + +body { + margin-left: 1em; + margin-right: 1em; + font-family: arial, helvetica, geneva, sans-serif; + background-color: #ffffff; margin: 0px; +} + +code, tt { font-family: monospace; } + +body, p, td, th { font-size: .95em; line-height: 1.2em;} + +p, ul { margin: 10px 0 0 10px;} + +strong { font-weight: bold;} + +em { font-style: italic;} + +h1 { + font-size: 1.5em; + margin: 25px 0 20px 0; +} +h2, h3, h4 { margin: 15px 0 10px 0; } +h2 { font-size: 1.25em; } +h3 { font-size: 1.15em; } +h4 { font-size: 1.06em; } + +a:link { font-weight: bold; color: #004080; text-decoration: none; } +a:visited { font-weight: bold; color: #006699; text-decoration: none; } +a:link:hover { text-decoration: underline; } + +hr { + color:#cccccc; + background: #00007f; + height: 1px; +} + +blockquote { margin-left: 3em; } + +ul { list-style-type: disc; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; +} + +p:first-child { + margin-top: 0px; +} + +pre.example { + background-color: rgb(245, 245, 245); + border: 1px solid silver; + padding: 10px; + margin: 10px 0 10px 0; + font-family: "Andale Mono", monospace; + font-size: .85em; +} + +pre { + background-color: rgb(245, 245, 245); + border: 1px solid silver; + padding: 10px; + margin: 10px 0 10px 0; + font-family: "Andale Mono", monospace; +} + + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } + +#container { + margin-left: 1em; + margin-right: 1em; + background-color: #f0f0f0; +} + +#product { + text-align: center; + border-bottom: 1px solid #cccccc; + background-color: #ffffff; +} + +#product big { + font-size: 2em; +} + +#main { + background-color: #f0f0f0; + border-left: 2px solid #cccccc; +} + +#navigation { + float: left; + width: 18em; + vertical-align: top; + background-color: #f0f0f0; + overflow: scroll; + position: fixed; + height:100%; +} + +#navigation h2 { + background-color:#e7e7e7; + font-size:1.1em; + color:#000000; + text-align: left; + padding:0.2em; + border-top:1px solid #dddddd; + border-bottom:1px solid #dddddd; +} + +#navigation ul +{ + font-size:1em; + list-style-type: none; + margin: 1px 1px 10px 1px; +} + +#navigation li { + text-indent: -1em; + display: block; + margin: 3px 0px 0px 22px; +} + +#navigation li li a { + margin: 0px 3px 0px -1em; +} + +#content { + margin-left: 18em; + padding: 1em; + border-left: 2px solid #cccccc; + border-right: 2px solid #cccccc; + background-color: #ffffff; +} + +#about { + clear: both; + padding: 5px; + border-top: 2px solid #cccccc; + background-color: #ffffff; +} + +@media print { + body { + font: 12pt "Times New Roman", "TimeNR", Times, serif; + } + a { font-weight: bold; color: #004080; text-decoration: underline; } + + #main { + background-color: #ffffff; + border-left: 0px; + } + + #container { + margin-left: 2%; + margin-right: 2%; + background-color: #ffffff; + } + + #content { + padding: 1em; + background-color: #ffffff; + } + + #navigation { + display: none; + } + pre.example { + font-family: "Andale Mono", monospace; + font-size: 10pt; + page-break-inside: avoid; + } +} + +table.module_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.module_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.module_list td.name { background-color: #f0f0f0; } +table.module_list td.summary { width: 100%; } + + +table.function_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.function_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.function_list td.name { background-color: #f0f0f0; } +table.function_list td.summary { width: 100%; } + +dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} +dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;} +dl.table h3, dl.function h3 {font-size: .95em;} + +]] diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/docgenerator.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/docgenerator.lua new file mode 100644 index 000000000..2a4d88812 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/docgenerator.lua @@ -0,0 +1,87 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- + +-- +-- Load documentation generator and update its path +-- +local templateengine = require 'templateengine' +for name, def in pairs( require 'template.utils' ) do + templateengine.env [ name ] = def +end + +-- Load documentation extractor and set handled languages +local lddextractor = require 'lddextractor' + +local M = {} +M.defaultsitemainpagename = 'index' + +function M.generatedocforfiles(filenames, cssname,noheuristic) + if not filenames then return nil, 'No files provided.' end + -- + -- Generate API model elements for all files + -- + local generatedfiles = {} + local wrongfiles = {} + for _, filename in pairs( filenames ) do + -- Load file content + local file, error = io.open(filename, 'r') + if not file then return nil, 'Unable to read "'..filename..'"\n'..err end + local code = file:read('*all') + file:close() + -- Get module for current file + local apimodule, err = lddextractor.generateapimodule(filename, code,noheuristic) + + -- Handle modules with module name + if apimodule and apimodule.name then + generatedfiles[ apimodule.name ] = apimodule + elseif not apimodule then + -- Track faulty files + table.insert(wrongfiles, 'Unable to extract comments from "'..filename..'".\n'..err) + elseif not apimodule.name then + -- Do not generate documentation for unnamed modules + table.insert(wrongfiles, 'Unable to create documentation for "'..filename..'", no module name provided.') + end + end + -- + -- Defining index, which will summarize all modules + -- + local index = { + modules = generatedfiles, + name = M.defaultsitemainpagename, + tag='index' + } + generatedfiles[ M.defaultsitemainpagename ] = index + + -- + -- Define page cursor + -- + local page = { + currentmodule = nil, + headers = { [[]] }, + modules = generatedfiles, + tag = 'page' + } + + -- + -- Iterate over modules, generating complete doc pages + -- + for _, module in pairs( generatedfiles ) do + -- Update current cursor page + page.currentmodule = module + -- Generate page + local content, error = templateengine.applytemplate(page) + if not content then return nil, error end + module.body = content + end + return generatedfiles, wrongfiles +end +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/extractors.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/extractors.lua new file mode 100644 index 000000000..aa5235ea9 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/extractors.lua @@ -0,0 +1,102 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +local M = {} +require 'metalua.loader' +local compiler = require 'metalua.compiler' +local mlc = compiler.new() +local Q = require 'metalua.treequery' + +-- Enable to retrieve all Javadoc-like comments from C code +function M.c(code) + if not code then return nil, 'No code provided' end + local comments = {} + -- Loop over comments stripping cosmetic '*' + for comment in code:gmatch('%s*/%*%*+(.-)%*+/') do + -- All Lua special comment are prefixed with an '-', + -- so we also comment C comment to make them compliant + table.insert(comments, '-'..comment) + end + return comments +end + +-- Enable to retrieve "---" comments from Lua code +function M.lua( code ) + if not code then return nil, 'No code provided' end + + -- manage shebang + if code then code = code:gsub("^(#.-\n)", function (s) return string.rep(' ',string.len(s)) end) end + + -- check for errors + local f, err = loadstring(code,'source_to_check') + if not f then + return nil, 'Syntax error.\n' .. err + end + + -- Get ast from file + local status, ast = pcall(mlc.src_to_ast, mlc, code) + -- + -- Detect parsing errors + -- + if not status then + return nil, 'There might be a syntax error.\n' .. ast + end + + -- + -- Extract commented nodes from AST + -- + + -- Function enabling commented node selection + local function acceptcommentednode(node) + return node.lineinfo and ( node.lineinfo.last.comments or node.lineinfo.first.comments ) + end + + -- Fetch commented node from AST + local commentednodes = Q(ast):filter( acceptcommentednode ):list() + + -- Comment cache to avoid selecting same comment twice + local commentcache = {} + -- Will contain selected comments + local comments = {} + + -- Loop over commented nodes + for _, node in ipairs( commentednodes ) do + + -- A node can is relateds to comment before and after itself, + -- the following gathers them. + local commentlists = {} + if node.lineinfo and node.lineinfo.first.comments then + table.insert(commentlists, node.lineinfo.first.comments) + end + if node.lineinfo and node.lineinfo.last.comments then + table.insert(commentlists, node.lineinfo.last.comments) + end + -- Now that we have comments before and fater the node, + -- collect them in a single table + for _, list in ipairs( commentlists ) do + for _, commenttable in ipairs(list) do + -- Only select special comments + local firstcomment = #commenttable > 0 and #commenttable[1] > 0 and commenttable[1] + if firstcomment:sub(1, 1) == '-' then + for _, comment in ipairs( commenttable ) do + -- Only comments which were not already collected + if not commentcache[comment] then + commentcache[comment] = true + table.insert(comments, comment) + end + end + end + end + end + end + return comments +end +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/fs/lfs.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/fs/lfs.lua new file mode 100644 index 000000000..3fc513542 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/fs/lfs.lua @@ -0,0 +1,130 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +local lfs = require 'lfs' +local M = {} +local function iswindows() + local p = io.popen("echo %os%") + if not p then + return false + end + local result =p:read("*l") + p:close() + return result == "Windows_NT" +end +M.separator = iswindows() and [[\]] or [[/]] +--- +-- Will recursively browse given directories and list files encountered +-- @param tab Table, list where files will be added +-- @param dirorfiles list of path to browse in order to build list. +-- Files from this list will be added to tab list. +-- @return tab list, table containing all files from directories +-- and files contained in dirorfile +local function appendfiles(tab, dirorfile) + + -- Nothing to process + if #dirorfile < 1 then return tab end + + -- Append all files to list + local dirs = {} + for _, path in ipairs( dirorfile ) do + -- Determine element nature + local elementnature = lfs.attributes (path, "mode") + + -- Handle files + if elementnature == 'file' then + table.insert(tab, path) + else if elementnature == 'directory' then + + -- Check if folder is accessible + local status, error = pcall(lfs.dir, path) + if not status then return nil, error end + + -- + -- Handle folders + -- + for diskelement in lfs.dir(path) do + + -- Format current file name + local currentfilename + if path:sub(#path) == M.separator then + currentfilename = path .. diskelement + else + currentfilename = path .. M.separator .. diskelement + end + + -- Handle folder elements + local nature, err = lfs.attributes (currentfilename, "mode") + -- Append file to current list + if nature == 'file' then + table.insert(tab, currentfilename) + elseif nature == 'directory' then + -- Avoid current and parent directory in order to avoid + -- endless recursion + if diskelement ~= '.' and diskelement ~= '..' then + -- Handle subfolders + table.insert(dirs, currentfilename) + end + end + end + end + end + end + -- If we only encountered files, going deeper is useless + if #dirs == 0 then return tab end + -- Append files from encountered directories + return appendfiles(tab, dirs) +end +--- +-- Provide a list of files from a directory +-- @param list Table of directories to browse +-- @return table of string, path to files contained in given directories +function M.filelist(list) + if not list then return nil, 'No directory list provided' end + return appendfiles({}, list) +end +function M.checkdirectory( dirlist ) + if not dirlist then return false end + local missingdirs = {} + for _, filename in ipairs( dirlist ) do + if not lfs.attributes(filename, 'mode') then + table.insert(missingdirs, filename) + end + end + if #missingdirs > 0 then + return false, missingdirs + end + return true +end +function M.fill(filename, content) + -- + -- Ensure parent directory exists + -- + local parent = filename:gmatch([[(.*)]] .. M.separator ..[[(.+)]])() + local parentnature = lfs.attributes(parent, 'mode') + -- Create parent directory while absent + if not parentnature then + lfs.mkdir( parent ) + elseif parentnature ~= 'directory' then + -- Notify that disk element already exists + return nil, parent..' is a '..parentnature..'.' + end + + -- Create actual file + local file, error = io.open(filename, 'w') + if not file then + return nil, error + end + file:write( content ) + file:close() + return true +end +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/lddextractor.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/lddextractor.lua new file mode 100644 index 000000000..b2cea2ea3 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/lddextractor.lua @@ -0,0 +1,113 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +require 'metalua.loader' +local compiler = require 'metalua.compiler' +local mlc = compiler.new() +local M = {} + +-- +-- Define default supported languages +-- +M.supportedlanguages = {} +local extractors = require 'extractors' + +-- Support Lua comment extracting +M.supportedlanguages['lua'] = extractors.lua + +-- Support C comment extracting +for _,c in ipairs({'c', 'cpp', 'c++'}) do + M.supportedlanguages[c] = extractors.c +end + +-- Extract comment from code, +-- type of code is deduced from filename extension +function M.extract(filename, code) + -- Check parameters + if not code then return nil, 'No code provided' end + if type(filename) ~= "string" then + return nil, 'No string for file name provided' + end + + -- Extract file extension + local fileextension = filename:gmatch('.*%.(.*)')() + if not fileextension then + return nil, 'File '..filename..' has no extension, could not determine how to extract documentation.' + end + + -- Check if it is possible to extract documentation from these files + local extractor = M.supportedlanguages[ fileextension ] + if not extractor then + return nil, 'Unable to extract documentation from '.. fileextension .. ' file.' + end + return extractor( code ) +end +-- Generate a file gathering only comments from given code +function M.generatecommentfile(filename, code) + local comments, error = M.extract(filename, code) + if not comments then + return nil, 'Unable to generate comment file.\n'..error + end + local filecontent = {} + for _, comment in ipairs( comments ) do + table.insert(filecontent, "--[[") + table.insert(filecontent, comment) + table.insert(filecontent, "\n]]\n\n") + end + return table.concat(filecontent)..'return nil\n' +end +-- Create API Model module from a 'comment only' lua file +function M.generateapimodule(filename, code,noheuristic) + if not filename then return nil, 'No file name given.' end + if not code then return nil, 'No code provided.' end + if type(filename) ~= "string" then return nil, 'No string for file name provided' end + + -- for non lua file get comment file + if filename:gmatch('.*%.(.*)')() ~= 'lua' then + local err + code, err = M.generatecommentfile(filename, code) + if not code then + return nil, 'Unable to create api module for "'..filename..'".\n'..err + end + else + + -- manage shebang + if code then code = code:gsub("^(#.-\n)", function (s) return string.rep(' ',string.len(s)) end) end + + -- check for errors + local f, err = loadstring(code,'source_to_check') + if not f then + return nil, 'File'..filename..'contains syntax error.\n' .. err + end + end + + local status, ast = pcall(mlc.src_to_ast, mlc, code) + if not status then + return nil, 'Unable to compute ast for "'..filename..'".\n'..ast + end + + -- Extract module name as the filename without extension + local modulename + local matcher = string.gmatch(filename,'.*/(.*)%..*$') + if matcher then modulename = matcher() end + + -- Create api model + local apimodelbuilder = require 'models.apimodelbuilder' + local _file, comment2apiobj = apimodelbuilder.createmoduleapi(ast, modulename) + + -- Create internal model + if not noheuristic then + local internalmodelbuilder = require "models.internalmodelbuilder" + local _internalcontent = internalmodelbuilder.createinternalcontent(ast,_file,comment2apiobj, modulename) + end + return _file +end +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/markdown.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/markdown.lua new file mode 100644 index 000000000..b16d43b3d --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/markdown.lua @@ -0,0 +1,1359 @@ +#!/usr/bin/env lua + +--[[ +# markdown.lua -- version 0.32 + + + +**Author:** Niklas Frykholm, +**Date:** 31 May 2008 + +This is an implementation of the popular text markup language Markdown in pure Lua. +Markdown can convert documents written in a simple and easy to read text format +to well-formatted HTML. For a more thourough description of Markdown and the Markdown +syntax, see . + +The original Markdown source is written in Perl and makes heavy use of advanced +regular expression techniques (such as negative look-ahead, etc) which are not available +in Lua's simple regex engine. Therefore this Lua port has been rewritten from the ground +up. It is probably not completely bug free. If you notice any bugs, please report them to +me. A unit test that exposes the error is helpful. + +## Usage + + require "markdown" + markdown(source) + +``markdown.lua`` exposes a single global function named ``markdown(s)`` which applies the +Markdown transformation to the specified string. + +``markdown.lua`` can also be used directly from the command line: + + lua markdown.lua test.md + +Creates a file ``test.html`` with the converted content of ``test.md``. Run: + + lua markdown.lua -h + +For a description of the command-line options. + +``markdown.lua`` uses the same license as Lua, the MIT license. + +## License + +Copyright © 2008 Niklas Frykholm. + +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. + +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. + +## Version history + +- **0.32** -- 31 May 2008 + - Fix for links containing brackets +- **0.31** -- 1 Mar 2008 + - Fix for link definitions followed by spaces +- **0.30** -- 25 Feb 2008 + - Consistent behavior with Markdown when the same link reference is reused +- **0.29** -- 24 Feb 2008 + - Fix for
 blocks with spaces in them
+-	**0.28** -- 18 Feb 2008
+	-	Fix for link encoding
+-	**0.27** -- 14 Feb 2008
+	-	Fix for link database links with ()
+-	**0.26** -- 06 Feb 2008
+	-	Fix for nested italic and bold markers
+-	**0.25** -- 24 Jan 2008
+	-	Fix for encoding of naked <
+-	**0.24** -- 21 Jan 2008
+	-	Fix for link behavior.
+-	**0.23** -- 10 Jan 2008
+	-	Fix for a regression bug in longer expressions in italic or bold.
+-	**0.22** -- 27 Dec 2007
+	-	Fix for crash when processing blocks with a percent sign in them.
+-	**0.21** -- 27 Dec 2007
+	- 	Fix for combined strong and emphasis tags
+-	**0.20** -- 13 Oct 2007
+	-	Fix for < as well in image titles, now matches Dingus behavior
+-	**0.19** -- 28 Sep 2007
+	-	Fix for quotation marks " and ampersands & in link and image titles.
+-	**0.18** -- 28 Jul 2007
+	-	Does not crash on unmatched tags (behaves like standard markdown)
+-	**0.17** -- 12 Apr 2007
+	-	Fix for links with %20 in them.
+-	**0.16** -- 12 Apr 2007
+	-	Do not require arg global to exist.
+-	**0.15** -- 28 Aug 2006
+	-	Better handling of links with underscores in them.
+-	**0.14** -- 22 Aug 2006
+	-	Bug for *`foo()`*
+-	**0.13** -- 12 Aug 2006
+	-	Added -l option for including stylesheet inline in document.
+	-	Fixed bug in -s flag.
+	-	Fixed emphasis bug.
+-	**0.12** -- 15 May 2006
+	-	Fixed several bugs to comply with MarkdownTest 1.0 
+-	**0.11** -- 12 May 2006
+	-	Fixed bug for escaping `*` and `_` inside code spans.
+	-	Added license terms.
+	-	Changed join() to table.concat().
+-	**0.10** -- 3 May 2006
+	-	Initial public release.
+
+// Niklas
+]]
+
+
+-- Set up a table for holding local functions to avoid polluting the global namespace
+local M = {}
+local MT = {__index = _G}
+setmetatable(M, MT)
+setfenv(1, M)
+
+----------------------------------------------------------------------
+-- Utility functions
+----------------------------------------------------------------------
+
+-- Locks table t from changes, writes an error if someone attempts to change the table.
+-- This is useful for detecting variables that have "accidently" been made global. Something
+-- I tend to do all too much.
+function lock(t)
+	function lock_new_index(t, k, v)
+		error("module has been locked -- " .. k .. " must be declared local", 2)
+	end
+
+	local mt = {__newindex = lock_new_index}
+	if getmetatable(t) then mt.__index = getmetatable(t).__index end
+	setmetatable(t, mt)
+end
+
+-- Returns the result of mapping the values in table t through the function f
+function map(t, f)
+	local out = {}
+	for k,v in pairs(t) do out[k] = f(v,k) end
+	return out
+end
+
+-- The identity function, useful as a placeholder.
+function identity(text) return text end
+
+-- Functional style if statement. (NOTE: no short circuit evaluation)
+function iff(t, a, b) if t then return a else return b end end
+
+-- Splits the text into an array of separate lines.
+function split(text, sep)
+	sep = sep or "\n"
+	local lines = {}
+	local pos = 1
+	while true do
+		local b,e = text:find(sep, pos)
+		if not b then table.insert(lines, text:sub(pos)) break end
+		table.insert(lines, text:sub(pos, b-1))
+		pos = e + 1
+	end
+	return lines
+end
+
+-- Converts tabs to spaces
+function detab(text)
+	local tab_width = 4
+	local function rep(match)
+		local spaces = -match:len()
+		while spaces<1 do spaces = spaces + tab_width end
+		return match .. string.rep(" ", spaces)
+	end
+	text = text:gsub("([^\n]-)\t", rep)
+	return text
+end
+
+-- Applies string.find for every pattern in the list and returns the first match
+function find_first(s, patterns, index)
+	local res = {}
+	for _,p in ipairs(patterns) do
+		local match = {s:find(p, index)}
+		if #match>0 and (#res==0 or match[1] < res[1]) then res = match end
+	end
+	return unpack(res)
+end
+
+-- If a replacement array is specified, the range [start, stop] in the array is replaced
+-- with the replacement array and the resulting array is returned. Without a replacement
+-- array the section of the array between start and stop is returned.
+function splice(array, start, stop, replacement)
+	if replacement then
+		local n = stop - start + 1
+		while n > 0 do
+			table.remove(array, start)
+			n = n - 1
+		end
+		for i,v in ipairs(replacement) do
+			table.insert(array, start, v)
+		end
+		return array
+	else
+		local res = {}
+		for i = start,stop do
+			table.insert(res, array[i])
+		end
+		return res
+	end
+end
+
+-- Outdents the text one step.
+function outdent(text)
+	text = "\n" .. text
+	text = text:gsub("\n  ? ? ?", "\n")
+	text = text:sub(2)
+	return text
+end
+
+-- Indents the text one step.
+function indent(text)
+	text = text:gsub("\n", "\n    ")
+	return text
+end
+
+-- Does a simple tokenization of html data. Returns the data as a list of tokens. 
+-- Each token is a table with a type field (which is either "tag" or "text") and
+-- a text field (which contains the original token data).
+function tokenize_html(html)
+	local tokens = {}
+	local pos = 1
+	while true do
+		local start = find_first(html, {"", start)
+		elseif html:match("^<%?", start) then
+			_,stop = html:find("?>", start)
+		else
+			_,stop = html:find("%b<>", start)
+		end
+		if not stop then
+			-- error("Could not match html tag " .. html:sub(start,start+30)) 
+		 	table.insert(tokens, {type="text", text=html:sub(start, start)})
+			pos = start + 1
+		else
+			table.insert(tokens, {type="tag", text=html:sub(start, stop)})
+			pos = stop + 1
+		end
+	end
+	return tokens
+end
+
+----------------------------------------------------------------------
+-- Hash
+----------------------------------------------------------------------
+
+-- This is used to "hash" data into alphanumeric strings that are unique
+-- in the document. (Note that this is not cryptographic hash, the hash
+-- function is not one-way.) The hash procedure is used to protect parts
+-- of the document from further processing.
+
+local HASH = {
+	-- Has the hash been inited.
+	inited = false,
+	
+	-- The unique string prepended to all hash values. This is to ensure
+	-- that hash values do not accidently coincide with an actual existing
+	-- string in the document.
+	identifier = "",
+	
+	-- Counter that counts up for each new hash instance.
+	counter = 0,
+	
+	-- Hash table.
+	table = {}
+}
+
+-- Inits hashing. Creates a hash_identifier that doesn't occur anywhere
+-- in the text.
+function init_hash(text)
+	HASH.inited = true
+	HASH.identifier = ""
+	HASH.counter = 0
+	HASH.table = {}
+	
+	local s = "HASH"
+	local counter = 0
+	local id
+	while true do
+		id  = s .. counter
+		if not text:find(id, 1, true) then break end
+		counter = counter + 1
+	end
+	HASH.identifier = id
+end
+
+-- Returns the hashed value for s.
+function hash(s)
+	assert(HASH.inited)
+	if not HASH.table[s] then
+		HASH.counter = HASH.counter + 1
+		local id = HASH.identifier .. HASH.counter .. "X"
+		HASH.table[s] = id
+	end
+	return HASH.table[s]
+end
+
+----------------------------------------------------------------------
+-- Protection
+----------------------------------------------------------------------
+
+-- The protection module is used to "protect" parts of a document
+-- so that they are not modified by subsequent processing steps. 
+-- Protected parts are saved in a table for later unprotection
+
+-- Protection data
+local PD = {
+	-- Saved blocks that have been converted
+	blocks = {},
+
+	-- Block level tags that will be protected
+	tags = {"p", "div", "h1", "h2", "h3", "h4", "h5", "h6", "blockquote",
+	"pre", "table", "dl", "ol", "ul", "script", "noscript", "form", "fieldset",
+	"iframe", "math", "ins", "del"}
+}
+
+-- Pattern for matching a block tag that begins and ends in the leftmost
+-- column and may contain indented subtags, i.e.
+-- 
+-- A nested block. +--
+-- Nested data. +--
+--
+function block_pattern(tag) + return "\n<" .. tag .. ".-\n[ \t]*\n" +end + +-- Pattern for matching a block tag that begins and ends with a newline +function line_pattern(tag) + return "\n<" .. tag .. ".-[ \t]*\n" +end + +-- Protects the range of characters from start to stop in the text and +-- returns the protected string. +function protect_range(text, start, stop) + local s = text:sub(start, stop) + local h = hash(s) + PD.blocks[h] = s + text = text:sub(1,start) .. h .. text:sub(stop) + return text +end + +-- Protect every part of the text that matches any of the patterns. The first +-- matching pattern is protected first, etc. +function protect_matches(text, patterns) + while true do + local start, stop = find_first(text, patterns) + if not start then break end + text = protect_range(text, start, stop) + end + return text +end + +-- Protects blocklevel tags in the specified text +function protect(text) + -- First protect potentially nested block tags + text = protect_matches(text, map(PD.tags, block_pattern)) + -- Then protect block tags at the line level. + text = protect_matches(text, map(PD.tags, line_pattern)) + -- Protect
and comment tags + text = protect_matches(text, {"\n]->[ \t]*\n"}) + text = protect_matches(text, {"\n[ \t]*\n"}) + return text +end + +-- Returns true if the string s is a hash resulting from protection +function is_protected(s) + return PD.blocks[s] +end + +-- Unprotects the specified text by expanding all the nonces +function unprotect(text) + for k,v in pairs(PD.blocks) do + v = v:gsub("%%", "%%%%") + text = text:gsub(k, v) + end + return text +end + + +---------------------------------------------------------------------- +-- Block transform +---------------------------------------------------------------------- + +-- The block transform functions transform the text on the block level. +-- They work with the text as an array of lines rather than as individual +-- characters. + +-- Returns true if the line is a ruler of (char) characters. +-- The line must contain at least three char characters and contain only spaces and +-- char characters. +function is_ruler_of(line, char) + if not line:match("^[ %" .. char .. "]*$") then return false end + if not line:match("%" .. char .. ".*%" .. char .. ".*%" .. char) then return false end + return true +end + +-- Identifies the block level formatting present in the line +function classify(line) + local info = {line = line, text = line} + + if line:match("^ ") then + info.type = "indented" + info.outdented = line:sub(5) + return info + end + + for _,c in ipairs({'*', '-', '_', '='}) do + if is_ruler_of(line, c) then + info.type = "ruler" + info.ruler_char = c + return info + end + end + + if line == "" then + info.type = "blank" + return info + end + + if line:match("^(#+)[ \t]*(.-)[ \t]*#*[ \t]*$") then + local m1, m2 = line:match("^(#+)[ \t]*(.-)[ \t]*#*[ \t]*$") + info.type = "header" + info.level = m1:len() + info.text = m2 + return info + end + + if line:match("^ ? ? ?(%d+)%.[ \t]+(.+)") then + local number, text = line:match("^ ? ? ?(%d+)%.[ \t]+(.+)") + info.type = "list_item" + info.list_type = "numeric" + info.number = 0 + number + info.text = text + return info + end + + if line:match("^ ? ? ?([%*%+%-])[ \t]+(.+)") then + local bullet, text = line:match("^ ? ? ?([%*%+%-])[ \t]+(.+)") + info.type = "list_item" + info.list_type = "bullet" + info.bullet = bullet + info.text= text + return info + end + + if line:match("^>[ \t]?(.*)") then + info.type = "blockquote" + info.text = line:match("^>[ \t]?(.*)") + return info + end + + if is_protected(line) then + info.type = "raw" + info.html = unprotect(line) + return info + end + + info.type = "normal" + return info +end + +-- Find headers constisting of a normal line followed by a ruler and converts them to +-- header entries. +function headers(array) + local i = 1 + while i <= #array - 1 do + if array[i].type == "normal" and array[i+1].type == "ruler" and + (array[i+1].ruler_char == "-" or array[i+1].ruler_char == "=") then + local info = {line = array[i].line} + info.text = info.line + info.type = "header" + info.level = iff(array[i+1].ruler_char == "=", 1, 2) + table.remove(array, i+1) + array[i] = info + end + i = i + 1 + end + return array +end + +-- Find list blocks and convert them to protected data blocks +function lists(array, sublist) + local function process_list(arr) + local function any_blanks(arr) + for i = 1, #arr do + if arr[i].type == "blank" then return true end + end + return false + end + + local function split_list_items(arr) + local acc = {arr[1]} + local res = {} + for i=2,#arr do + if arr[i].type == "list_item" then + table.insert(res, acc) + acc = {arr[i]} + else + table.insert(acc, arr[i]) + end + end + table.insert(res, acc) + return res + end + + local function process_list_item(lines, block) + while lines[#lines].type == "blank" do + table.remove(lines) + end + + local itemtext = lines[1].text + for i=2,#lines do + itemtext = itemtext .. "\n" .. outdent(lines[i].line) + end + if block then + itemtext = block_transform(itemtext, true) + if not itemtext:find("
") then itemtext = indent(itemtext) end
+				return "    
  • " .. itemtext .. "
  • " + else + local lines = split(itemtext) + lines = map(lines, classify) + lines = lists(lines, true) + lines = blocks_to_html(lines, true) + itemtext = table.concat(lines, "\n") + if not itemtext:find("
    ") then itemtext = indent(itemtext) end
    +				return "    
  • " .. itemtext .. "
  • " + end + end + + local block_list = any_blanks(arr) + local items = split_list_items(arr) + local out = "" + for _, item in ipairs(items) do + out = out .. process_list_item(item, block_list) .. "\n" + end + if arr[1].list_type == "numeric" then + return "
      \n" .. out .. "
    " + else + return "
      \n" .. out .. "
    " + end + end + + -- Finds the range of lines composing the first list in the array. A list + -- starts with (^ list_item) or (blank list_item) and ends with + -- (blank* $) or (blank normal). + -- + -- A sublist can start with just (list_item) does not need a blank... + local function find_list(array, sublist) + local function find_list_start(array, sublist) + if array[1].type == "list_item" then return 1 end + if sublist then + for i = 1,#array do + if array[i].type == "list_item" then return i end + end + else + for i = 1, #array-1 do + if array[i].type == "blank" and array[i+1].type == "list_item" then + return i+1 + end + end + end + return nil + end + local function find_list_end(array, start) + local pos = #array + for i = start, #array-1 do + if array[i].type == "blank" and array[i+1].type ~= "list_item" + and array[i+1].type ~= "indented" and array[i+1].type ~= "blank" then + pos = i-1 + break + end + end + while pos > start and array[pos].type == "blank" do + pos = pos - 1 + end + return pos + end + + local start = find_list_start(array, sublist) + if not start then return nil end + return start, find_list_end(array, start) + end + + while true do + local start, stop = find_list(array, sublist) + if not start then break end + local text = process_list(splice(array, start, stop)) + local info = { + line = text, + type = "raw", + html = text + } + array = splice(array, start, stop, {info}) + end + + -- Convert any remaining list items to normal + for _,line in ipairs(array) do + if line.type == "list_item" then line.type = "normal" end + end + + return array +end + +-- Find and convert blockquote markers. +function blockquotes(lines) + local function find_blockquote(lines) + local start + for i,line in ipairs(lines) do + if line.type == "blockquote" then + start = i + break + end + end + if not start then return nil end + + local stop = #lines + for i = start+1, #lines do + if lines[i].type == "blank" or lines[i].type == "blockquote" then + elseif lines[i].type == "normal" then + if lines[i-1].type == "blank" then stop = i-1 break end + else + stop = i-1 break + end + end + while lines[stop].type == "blank" do stop = stop - 1 end + return start, stop + end + + local function process_blockquote(lines) + local raw = lines[1].text + for i = 2,#lines do + raw = raw .. "\n" .. lines[i].text + end + local bt = block_transform(raw) + if not bt:find("
    ") then bt = indent(bt) end
    +		return "
    \n " .. bt .. + "\n
    " + end + + while true do + local start, stop = find_blockquote(lines) + if not start then break end + local text = process_blockquote(splice(lines, start, stop)) + local info = { + line = text, + type = "raw", + html = text + } + lines = splice(lines, start, stop, {info}) + end + return lines +end + +-- Find and convert codeblocks. +function codeblocks(lines) + local function find_codeblock(lines) + local start + for i,line in ipairs(lines) do + if line.type == "indented" then start = i break end + end + if not start then return nil end + + local stop = #lines + for i = start+1, #lines do + if lines[i].type ~= "indented" and lines[i].type ~= "blank" then + stop = i-1 + break + end + end + while lines[stop].type == "blank" do stop = stop - 1 end + return start, stop + end + + local function process_codeblock(lines) + local raw = detab(encode_code(outdent(lines[1].line))) + for i = 2,#lines do + raw = raw .. "\n" .. detab(encode_code(outdent(lines[i].line))) + end + return "
    " .. raw .. "\n
    " + end + + while true do + local start, stop = find_codeblock(lines) + if not start then break end + local text = process_codeblock(splice(lines, start, stop)) + local info = { + line = text, + type = "raw", + html = text + } + lines = splice(lines, start, stop, {info}) + end + return lines +end + +-- Convert lines to html code +function blocks_to_html(lines, no_paragraphs) + local out = {} + local i = 1 + while i <= #lines do + local line = lines[i] + if line.type == "ruler" then + table.insert(out, "
    ") + elseif line.type == "raw" then + table.insert(out, line.html) + elseif line.type == "normal" then + local s = line.line + + while i+1 <= #lines and lines[i+1].type == "normal" do + i = i + 1 + s = s .. "\n" .. lines[i].line + end + + if no_paragraphs then + table.insert(out, span_transform(s)) + else + table.insert(out, "

    " .. span_transform(s) .. "

    ") + end + elseif line.type == "header" then + local s = "" .. span_transform(line.text) .. "" + table.insert(out, s) + else + table.insert(out, line.line) + end + i = i + 1 + end + return out +end + +-- Perform all the block level transforms +function block_transform(text, sublist) + local lines = split(text) + lines = map(lines, classify) + lines = headers(lines) + lines = lists(lines, sublist) + lines = codeblocks(lines) + lines = blockquotes(lines) + lines = blocks_to_html(lines) + local text = table.concat(lines, "\n") + return text +end + +-- Debug function for printing a line array to see the result +-- of partial transforms. +function print_lines(lines) + for i, line in ipairs(lines) do + print(i, line.type, line.text or line.line) + end +end + +---------------------------------------------------------------------- +-- Span transform +---------------------------------------------------------------------- + +-- Functions for transforming the text at the span level. + +-- These characters may need to be escaped because they have a special +-- meaning in markdown. +escape_chars = "'\\`*_{}[]()>#+-.!'" +escape_table = {} + +function init_escape_table() + escape_table = {} + for i = 1,#escape_chars do + local c = escape_chars:sub(i,i) + escape_table[c] = hash(c) + end +end + +-- Adds a new escape to the escape table. +function add_escape(text) + if not escape_table[text] then + escape_table[text] = hash(text) + end + return escape_table[text] +end + +-- Escape characters that should not be disturbed by markdown. +function escape_special_chars(text) + local tokens = tokenize_html(text) + + local out = "" + for _, token in ipairs(tokens) do + local t = token.text + if token.type == "tag" then + -- In tags, encode * and _ so they don't conflict with their use in markdown. + t = t:gsub("%*", escape_table["*"]) + t = t:gsub("%_", escape_table["_"]) + else + t = encode_backslash_escapes(t) + end + out = out .. t + end + return out +end + +-- Encode backspace-escaped characters in the markdown source. +function encode_backslash_escapes(t) + for i=1,escape_chars:len() do + local c = escape_chars:sub(i,i) + t = t:gsub("\\%" .. c, escape_table[c]) + end + return t +end + +-- Unescape characters that have been encoded. +function unescape_special_chars(t) + local tin = t + for k,v in pairs(escape_table) do + k = k:gsub("%%", "%%%%") + t = t:gsub(v,k) + end + if t ~= tin then t = unescape_special_chars(t) end + return t +end + +-- Encode/escape certain characters inside Markdown code runs. +-- The point is that in code, these characters are literals, +-- and lose their special Markdown meanings. +function encode_code(s) + s = s:gsub("%&", "&") + s = s:gsub("<", "<") + s = s:gsub(">", ">") + for k,v in pairs(escape_table) do + s = s:gsub("%"..k, v) + end + return s +end + +-- Handle backtick blocks. +function code_spans(s) + s = s:gsub("\\\\", escape_table["\\"]) + s = s:gsub("\\`", escape_table["`"]) + + local pos = 1 + while true do + local start, stop = s:find("`+", pos) + if not start then return s end + local count = stop - start + 1 + -- Find a matching numbert of backticks + local estart, estop = s:find(string.rep("`", count), stop+1) + local brstart = s:find("\n", stop+1) + if estart and (not brstart or estart < brstart) then + local code = s:sub(stop+1, estart-1) + code = code:gsub("^[ \t]+", "") + code = code:gsub("[ \t]+$", "") + code = code:gsub(escape_table["\\"], escape_table["\\"] .. escape_table["\\"]) + code = code:gsub(escape_table["`"], escape_table["\\"] .. escape_table["`"]) + code = "" .. encode_code(code) .. "" + code = add_escape(code) + s = s:sub(1, start-1) .. code .. s:sub(estop+1) + pos = start + code:len() + else + pos = stop + 1 + end + end + return s +end + +-- Encode alt text... enodes &, and ". +function encode_alt(s) + if not s then return s end + s = s:gsub('&', '&') + s = s:gsub('"', '"') + s = s:gsub('<', '<') + return s +end + +-- Handle image references +function images(text) + local function reference_link(alt, id) + alt = encode_alt(alt:match("%b[]"):sub(2,-2)) + id = id:match("%[(.*)%]"):lower() + if id == "" then id = text:lower() end + link_database[id] = link_database[id] or {} + if not link_database[id].url then return nil end + local url = link_database[id].url or id + url = encode_alt(url) + local title = encode_alt(link_database[id].title) + if title then title = " title=\"" .. title .. "\"" else title = "" end + return add_escape ('' .. alt .. '") + end + + local function inline_link(alt, link) + alt = encode_alt(alt:match("%b[]"):sub(2,-2)) + local url, title = link:match("%(?[ \t]*['\"](.+)['\"]") + url = url or link:match("%(?%)") + url = encode_alt(url) + title = encode_alt(title) + if title then + return add_escape('' .. alt .. '') + else + return add_escape('' .. alt .. '') + end + end + + text = text:gsub("!(%b[])[ \t]*\n?[ \t]*(%b[])", reference_link) + text = text:gsub("!(%b[])(%b())", inline_link) + return text +end + +-- Handle anchor references +function anchors(text) + local function reference_link(text, id) + text = text:match("%b[]"):sub(2,-2) + id = id:match("%b[]"):sub(2,-2):lower() + if id == "" then id = text:lower() end + link_database[id] = link_database[id] or {} + if not link_database[id].url then return nil end + local url = link_database[id].url or id + url = encode_alt(url) + local title = encode_alt(link_database[id].title) + if title then title = " title=\"" .. title .. "\"" else title = "" end + return add_escape("") .. text .. add_escape("") + end + + local function inline_link(text, link) + text = text:match("%b[]"):sub(2,-2) + local url, title = link:match("%(?[ \t]*['\"](.+)['\"]") + title = encode_alt(title) + url = url or link:match("%(?%)") or "" + url = encode_alt(url) + if title then + return add_escape("") .. text .. "" + else + return add_escape("") .. text .. add_escape("") + end + end + + text = text:gsub("(%b[])[ \t]*\n?[ \t]*(%b[])", reference_link) + text = text:gsub("(%b[])(%b())", inline_link) + return text +end + +-- Handle auto links, i.e. . +function auto_links(text) + local function link(s) + return add_escape("") .. s .. "" + end + -- Encode chars as a mix of dec and hex entitites to (perhaps) fool + -- spambots. + local function encode_email_address(s) + -- Use a deterministic encoding to make unit testing possible. + -- Code 45% hex, 45% dec, 10% plain. + local hex = {code = function(c) return "&#x" .. string.format("%x", c:byte()) .. ";" end, count = 1, rate = 0.45} + local dec = {code = function(c) return "&#" .. c:byte() .. ";" end, count = 0, rate = 0.45} + local plain = {code = function(c) return c end, count = 0, rate = 0.1} + local codes = {hex, dec, plain} + local function swap(t,k1,k2) local temp = t[k2] t[k2] = t[k1] t[k1] = temp end + + local out = "" + for i = 1,s:len() do + for _,code in ipairs(codes) do code.count = code.count + code.rate end + if codes[1].count < codes[2].count then swap(codes,1,2) end + if codes[2].count < codes[3].count then swap(codes,2,3) end + if codes[1].count < codes[2].count then swap(codes,1,2) end + + local code = codes[1] + local c = s:sub(i,i) + -- Force encoding of "@" to make email address more invisible. + if c == "@" and code == plain then code = codes[2] end + out = out .. code.code(c) + code.count = code.count - 1 + end + return out + end + local function mail(s) + s = unescape_special_chars(s) + local address = encode_email_address("mailto:" .. s) + local text = encode_email_address(s) + return add_escape("") .. text .. "" + end + -- links + text = text:gsub("<(https?:[^'\">%s]+)>", link) + text = text:gsub("<(ftp:[^'\">%s]+)>", link) + + -- mail + text = text:gsub("%s]+)>", mail) + text = text:gsub("<([-.%w]+%@[-.%w]+)>", mail) + return text +end + +-- Encode free standing amps (&) and angles (<)... note that this does not +-- encode free >. +function amps_and_angles(s) + -- encode amps not part of &..; expression + local pos = 1 + while true do + local amp = s:find("&", pos) + if not amp then break end + local semi = s:find(";", amp+1) + local stop = s:find("[ \t\n&]", amp+1) + if not semi or (stop and stop < semi) or (semi - amp) > 15 then + s = s:sub(1,amp-1) .. "&" .. s:sub(amp+1) + pos = amp+1 + else + pos = amp+1 + end + end + + -- encode naked <'s + s = s:gsub("<([^a-zA-Z/?$!])", "<%1") + s = s:gsub("<$", "<") + + -- what about >, nothing done in the original markdown source to handle them + return s +end + +-- Handles emphasis markers (* and _) in the text. +function emphasis(text) + for _, s in ipairs {"%*%*", "%_%_"} do + text = text:gsub(s .. "([^%s][%*%_]?)" .. s, "%1") + text = text:gsub(s .. "([^%s][^<>]-[^%s][%*%_]?)" .. s, "%1") + end + for _, s in ipairs {"%*", "%_"} do + text = text:gsub(s .. "([^%s_])" .. s, "%1") + text = text:gsub(s .. "([^%s_])" .. s, "%1") + text = text:gsub(s .. "([^%s_][^<>_]-[^%s_])" .. s, "%1") + text = text:gsub(s .. "([^<>_]-[^<>_]-[^<>_]-)" .. s, "%1") + end + return text +end + +-- Handles line break markers in the text. +function line_breaks(text) + return text:gsub(" +\n", "
    \n") +end + +-- Perform all span level transforms. +function span_transform(text) + text = code_spans(text) + text = escape_special_chars(text) + text = images(text) + text = anchors(text) + text = auto_links(text) + text = amps_and_angles(text) + text = emphasis(text) + text = line_breaks(text) + return text +end + +---------------------------------------------------------------------- +-- Markdown +---------------------------------------------------------------------- + +-- Cleanup the text by normalizing some possible variations to make further +-- processing easier. +function cleanup(text) + -- Standardize line endings + text = text:gsub("\r\n", "\n") -- DOS to UNIX + text = text:gsub("\r", "\n") -- Mac to UNIX + + -- Convert all tabs to spaces + text = detab(text) + + -- Strip lines with only spaces and tabs + while true do + local subs + text, subs = text:gsub("\n[ \t]+\n", "\n\n") + if subs == 0 then break end + end + + return "\n" .. text .. "\n" +end + +-- Strips link definitions from the text and stores the data in a lookup table. +function strip_link_definitions(text) + local linkdb = {} + + local function link_def(id, url, title) + id = id:match("%[(.+)%]"):lower() + linkdb[id] = linkdb[id] or {} + linkdb[id].url = url or linkdb[id].url + linkdb[id].title = title or linkdb[id].title + return "" + end + + local def_no_title = "\n ? ? ?(%b[]):[ \t]*\n?[ \t]*]+)>?[ \t]*" + local def_title1 = def_no_title .. "[ \t]+\n?[ \t]*[\"'(]([^\n]+)[\"')][ \t]*" + local def_title2 = def_no_title .. "[ \t]*\n[ \t]*[\"'(]([^\n]+)[\"')][ \t]*" + local def_title3 = def_no_title .. "[ \t]*\n?[ \t]+[\"'(]([^\n]+)[\"')][ \t]*" + + text = text:gsub(def_title1, link_def) + text = text:gsub(def_title2, link_def) + text = text:gsub(def_title3, link_def) + text = text:gsub(def_no_title, link_def) + return text, linkdb +end + +link_database = {} + +-- Main markdown processing function +function markdown(text) + init_hash(text) + init_escape_table() + + text = cleanup(text) + text = protect(text) + text, link_database = strip_link_definitions(text) + text = block_transform(text) + text = unescape_special_chars(text) + return text +end + +---------------------------------------------------------------------- +-- End of module +---------------------------------------------------------------------- + +setfenv(1, _G) +M.lock(M) + +-- Expose markdown function to the world +markdown = M.markdown + +-- Class for parsing command-line options +local OptionParser = {} +OptionParser.__index = OptionParser + +-- Creates a new option parser +function OptionParser:new() + local o = {short = {}, long = {}} + setmetatable(o, self) + return o +end + +-- Calls f() whenever a flag with specified short and long name is encountered +function OptionParser:flag(short, long, f) + local info = {type = "flag", f = f} + if short then self.short[short] = info end + if long then self.long[long] = info end +end + +-- Calls f(param) whenever a parameter flag with specified short and long name is encountered +function OptionParser:param(short, long, f) + local info = {type = "param", f = f} + if short then self.short[short] = info end + if long then self.long[long] = info end +end + +-- Calls f(v) for each non-flag argument +function OptionParser:arg(f) + self.arg = f +end + +-- Runs the option parser for the specified set of arguments. Returns true if all arguments +-- where successfully parsed and false otherwise. +function OptionParser:run(args) + local pos = 1 + while pos <= #args do + local arg = args[pos] + if arg == "--" then + for i=pos+1,#args do + if self.arg then self.arg(args[i]) end + return true + end + end + if arg:match("^%-%-") then + local info = self.long[arg:sub(3)] + if not info then print("Unknown flag: " .. arg) return false end + if info.type == "flag" then + info.f() + pos = pos + 1 + else + param = args[pos+1] + if not param then print("No parameter for flag: " .. arg) return false end + info.f(param) + pos = pos+2 + end + elseif arg:match("^%-") then + for i=2,arg:len() do + local c = arg:sub(i,i) + local info = self.short[c] + if not info then print("Unknown flag: -" .. c) return false end + if info.type == "flag" then + info.f() + else + if i == arg:len() then + param = args[pos+1] + if not param then print("No parameter for flag: -" .. c) return false end + info.f(param) + pos = pos + 1 + else + param = arg:sub(i+1) + info.f(param) + end + break + end + end + pos = pos + 1 + else + if self.arg then self.arg(arg) end + pos = pos + 1 + end + end + return true +end + +-- Handles the case when markdown is run from the command line +local function run_command_line(arg) + -- Generate output for input s given options + local function run(s, options) + s = markdown(s) + if not options.wrap_header then return s end + local header = "" + if options.header then + local f = io.open(options.header) or error("Could not open file: " .. options.header) + header = f:read("*a") + f:close() + else + header = [[ + + + + + TITLE + + + +]] + local title = options.title or s:match("

    (.-)

    ") or s:match("

    (.-)

    ") or + s:match("

    (.-)

    ") or "Untitled" + header = header:gsub("TITLE", title) + if options.inline_style then + local style = "" + local f = io.open(options.stylesheet) + if f then + style = f:read("*a") f:close() + else + error("Could not include style sheet " .. options.stylesheet .. ": File not found") + end + header = header:gsub('', + "") + else + header = header:gsub("STYLESHEET", options.stylesheet) + end + header = header:gsub("CHARSET", options.charset) + end + local footer = "" + if options.footer then + local f = io.open(options.footer) or error("Could not open file: " .. options.footer) + footer = f:read("*a") + f:close() + end + return header .. s .. footer + end + + -- Generate output path name from input path name given options. + local function outpath(path, options) + if options.append then return path .. ".html" end + local m = path:match("^(.+%.html)[^/\\]+$") if m then return m end + m = path:match("^(.+%.)[^/\\]*$") if m and path ~= m .. "html" then return m .. "html" end + return path .. ".html" + end + + -- Default commandline options + local options = { + wrap_header = true, + header = nil, + footer = nil, + charset = "utf-8", + title = nil, + stylesheet = "default.css", + inline_style = false + } + local help = [[ +Usage: markdown.lua [OPTION] [FILE] +Runs the markdown text markup to HTML converter on each file specified on the +command line. If no files are specified, runs on standard input. + +No header: + -n, --no-wrap Don't wrap the output in ... tags. +Custom header: + -e, --header FILE Use content of FILE for header. + -f, --footer FILE Use content of FILE for footer. +Generated header: + -c, --charset SET Specifies charset (default utf-8). + -i, --title TITLE Specifies title (default from first

    tag). + -s, --style STYLE Specifies style sheet file (default default.css). + -l, --inline-style Include the style sheet file inline in the header. +Generated files: + -a, --append Append .html extension (instead of replacing). +Other options: + -h, --help Print this help text. + -t, --test Run the unit tests. +]] + + local run_stdin = true + local op = OptionParser:new() + op:flag("n", "no-wrap", function () options.wrap_header = false end) + op:param("e", "header", function (x) options.header = x end) + op:param("f", "footer", function (x) options.footer = x end) + op:param("c", "charset", function (x) options.charset = x end) + op:param("i", "title", function(x) options.title = x end) + op:param("s", "style", function(x) options.stylesheet = x end) + op:flag("l", "inline-style", function(x) options.inline_style = true end) + op:flag("a", "append", function() options.append = true end) + op:flag("t", "test", function() + local n = arg[0]:gsub("markdown.lua", "markdown-tests.lua") + local f = io.open(n) + if f then + f:close() dofile(n) + else + error("Cannot find markdown-tests.lua") + end + run_stdin = false + end) + op:flag("h", "help", function() print(help) run_stdin = false end) + op:arg(function(path) + local file = io.open(path) or error("Could not open file: " .. path) + local s = file:read("*a") + file:close() + s = run(s, options) + file = io.open(outpath(path, options), "w") or error("Could not open output file: " .. outpath(path, options)) + file:write(s) + file:close() + run_stdin = false + end + ) + + if not op:run(arg) then + print(help) + run_stdin = false + end + + if run_stdin then + local s = io.read("*a") + s = run(s, options) + io.write(s) + end +end + +-- If we are being run from the command-line, act accordingly +if arg and arg[0]:find("markdown%.lua$") then + run_command_line(arg) +else + return markdown +end \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler.lua new file mode 100644 index 000000000..202b254fd --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler.lua @@ -0,0 +1,181 @@ +--------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +-- +-- Convert between various code representation formats. Atomic +-- converters are written in extenso, others are composed automatically +-- by chaining the atomic ones together in a closure. +-- +-- Supported formats are: +-- +-- * srcfile: the name of a file containing sources. +-- * src: these sources as a single string. +-- * lexstream: a stream of lexemes. +-- * ast: an abstract syntax tree. +-- * proto: a (Yueliang) struture containing a high level +-- representation of bytecode. Largely based on the +-- Proto structure in Lua's VM +-- * bytecode: a string dump of the function, as taken by +-- loadstring() and produced by string.dump(). +-- * function: an executable lua function in RAM. +-- +-------------------------------------------------------------------------------- + +local checks = require 'checks' + +local M = { } + +-------------------------------------------------------------------------------- +-- Order of the transformations. if 'a' is on the left of 'b', then a 'a' can +-- be transformed into a 'b' (but not the other way around). +-- M.sequence goes for numbers to format names, M.order goes from format +-- names to numbers. +-------------------------------------------------------------------------------- +M.sequence = { + 'srcfile', 'src', 'lexstream', 'ast', 'proto', 'bytecode', 'function' } + +local arg_types = { + srcfile = { 'string', '?string' }, + src = { 'string', '?string' }, + lexstream = { 'lexer.stream', '?string' }, + ast = { 'table', '?string' }, + proto = { 'table', '?string' }, + bytecode = { 'string', '?string' }, +} + +if false then + -- if defined, runs on every newly-generated AST + function M.check_ast(ast) + local function rec(x, n, parent) + if not x.lineinfo and parent.lineinfo then + local pp = require 'metalua.pprint' + pp.printf("WARNING: Missing lineinfo in child #%s `%s{...} of node at %s", + n, x.tag or '', tostring(parent.lineinfo)) + end + for i, child in ipairs(x) do + if type(child)=='table' then rec(child, i, x) end + end + end + rec(ast, -1, { }) + end +end + + +M.order= { }; for a,b in pairs(M.sequence) do M.order[b]=a end + +local CONV = { } -- conversion metatable __index + +function CONV :srcfile_to_src(x, name) + checks('metalua.compiler', 'string', '?string') + name = name or '@'..x + local f, msg = io.open (x, 'rb') + if not f then error(msg) end + local r, msg = f :read '*a' + if not r then error("Cannot read file '"..x.."': "..msg) end + f :close() + return r, name +end + +function CONV :src_to_lexstream(src, name) + checks('metalua.compiler', 'string', '?string') + local r = self.parser.lexer :newstream (src, name) + return r, name +end + +function CONV :lexstream_to_ast(lx, name) + checks('metalua.compiler', 'lexer.stream', '?string') + local r = self.parser.chunk(lx) + r.source = name + if M.check_ast then M.check_ast (r) end + return r, name +end + +local bytecode_compiler = nil -- cache to avoid repeated `pcall(require(...))` +local function get_bytecode_compiler() + if bytecode_compiler then return bytecode_compiler else + local status, result = pcall(require, 'metalua.compiler.bytecode') + if status then + bytecode_compiler = result + return result + elseif string.match(result, "not found") then + error "Compilation only available with full Metalua" + else error (result) end + end +end + +function CONV :ast_to_proto(ast, name) + checks('metalua.compiler', 'table', '?string') + return get_bytecode_compiler().ast_to_proto(ast, name), name +end + +function CONV :proto_to_bytecode(proto, name) + return get_bytecode_compiler().proto_to_bytecode(proto), name +end + +function CONV :bytecode_to_function(bc, name) + checks('metalua.compiler', 'string', '?string') + return loadstring(bc, name) +end + +-- Create all sensible combinations +for i=1,#M.sequence do + local src = M.sequence[i] + for j=i+2, #M.sequence do + local dst = M.sequence[j] + local dst_name = src.."_to_"..dst + local my_arg_types = arg_types[src] + local functions = { } + for k=i, j-1 do + local name = M.sequence[k].."_to_"..M.sequence[k+1] + local f = assert(CONV[name], name) + table.insert (functions, f) + end + CONV[dst_name] = function(self, a, b) + checks('metalua.compiler', unpack(my_arg_types)) + for _, f in ipairs(functions) do + a, b = f(self, a, b) + end + return a, b + end + --printf("Created M.%s out of %s", dst_name, table.concat(n, ', ')) + end +end + + +-------------------------------------------------------------------------------- +-- This one goes in the "wrong" direction, cannot be composed. +-------------------------------------------------------------------------------- +function CONV :function_to_bytecode(...) return string.dump(...) end + +function CONV :ast_to_src(...) + require 'metalua.loader' -- ast_to_string isn't written in plain lua + return require 'metalua.compiler.ast_to_src' (...) +end + +local MT = { __index=CONV, __type='metalua.compiler' } + +function M.new() + local parser = require 'metalua.compiler.parser' .new() + local self = { parser = parser } + setmetatable(self, MT) + return self +end + +return M \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/ast_to_src.mlua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/ast_to_src.mlua new file mode 100644 index 000000000..ca80a12d2 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/ast_to_src.mlua @@ -0,0 +1,682 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +-{ extension ('match', ...) } + +local M = { } +M.__index = M +M.__call = |self, ...| self:run(...) + +local pp=require 'metalua.pprint' + +-------------------------------------------------------------------------------- +-- Instanciate a new AST->source synthetizer +-------------------------------------------------------------------------------- +function M.new () + local self = { + _acc = { }, -- Accumulates pieces of source as strings + current_indent = 0, -- Current level of line indentation + indent_step = " " -- Indentation symbol, normally spaces or '\t' + } + return setmetatable (self, M) +end + +-------------------------------------------------------------------------------- +-- Run a synthetizer on the `ast' arg and return the source as a string. +-- Can also be used as a static method `M.run (ast)'; in this case, +-- a temporary Metizer is instanciated on the fly. +-------------------------------------------------------------------------------- +function M:run (ast) + if not ast then + self, ast = M.new(), self + end + self._acc = { } + self:node (ast) + return table.concat (self._acc) +end + +-------------------------------------------------------------------------------- +-- Accumulate a piece of source file in the synthetizer. +-------------------------------------------------------------------------------- +function M:acc (x) + if x then table.insert (self._acc, x) end +end + +-------------------------------------------------------------------------------- +-- Accumulate an indented newline. +-- Jumps an extra line if indentation is 0, so that +-- toplevel definitions are separated by an extra empty line. +-------------------------------------------------------------------------------- +function M:nl () + if self.current_indent == 0 then self:acc "\n" end + self:acc ("\n" .. self.indent_step:rep (self.current_indent)) +end + +-------------------------------------------------------------------------------- +-- Increase indentation and accumulate a new line. +-------------------------------------------------------------------------------- +function M:nlindent () + self.current_indent = self.current_indent + 1 + self:nl () +end + +-------------------------------------------------------------------------------- +-- Decrease indentation and accumulate a new line. +-------------------------------------------------------------------------------- +function M:nldedent () + self.current_indent = self.current_indent - 1 + self:acc ("\n" .. self.indent_step:rep (self.current_indent)) +end + +-------------------------------------------------------------------------------- +-- Keywords, which are illegal as identifiers. +-------------------------------------------------------------------------------- +local keywords_list = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", + "repeat", "return", "then", "true", "until", + "while" } +local keywords = { } +for _, kw in pairs(keywords_list) do keywords[kw]=true end + +-------------------------------------------------------------------------------- +-- Return true iff string `id' is a legal identifier name. +-------------------------------------------------------------------------------- +local function is_ident (id) + return string['match'](id, "^[%a_][%w_]*$") and not keywords[id] +end + +-------------------------------------------------------------------------------- +-- Return true iff ast represents a legal function name for +-- syntax sugar ``function foo.bar.gnat() ... end'': +-- a series of nested string indexes, with an identifier as +-- the innermost node. +-------------------------------------------------------------------------------- +local function is_idx_stack (ast) + match ast with + | `Id{ _ } -> return true + | `Index{ left, `String{ _ } } -> return is_idx_stack (left) + | _ -> return false + end +end + +-------------------------------------------------------------------------------- +-- Operator precedences, in increasing order. +-- This is not directly used, it's used to generate op_prec below. +-------------------------------------------------------------------------------- +local op_preprec = { + { "or", "and" }, + { "lt", "le", "eq", "ne" }, + { "concat" }, + { "add", "sub" }, + { "mul", "div", "mod" }, + { "unary", "not", "len" }, + { "pow" }, + { "index" } } + +-------------------------------------------------------------------------------- +-- operator --> precedence table, generated from op_preprec. +-------------------------------------------------------------------------------- +local op_prec = { } + +for prec, ops in ipairs (op_preprec) do + for _, op in ipairs (ops) do + op_prec[op] = prec + end +end + +-------------------------------------------------------------------------------- +-- operator --> source representation. +-------------------------------------------------------------------------------- +local op_symbol = { + add = " + ", sub = " - ", mul = " * ", + div = " / ", mod = " % ", pow = " ^ ", + concat = " .. ", eq = " == ", ne = " ~= ", + lt = " < ", le = " <= ", ["and"] = " and ", + ["or"] = " or ", ["not"] = "not ", len = "# " } + +-------------------------------------------------------------------------------- +-- Accumulate the source representation of AST `node' in +-- the synthetizer. Most of the work is done by delegating to +-- the method having the name of the AST tag. +-- If something can't be converted to normal sources, it's +-- instead dumped as a `-{ ... }' splice in the source accumulator. +-------------------------------------------------------------------------------- +function M:node (node) + assert (self~=M and self._acc) + if node==nil then self:acc'<>' + elseif not self.custom_printer or not self.custom_printer (self, node) then + if not node.tag then -- tagless (henceunindented) block. + self:list (node, self.nl) + else + local f = M[node.tag] + if type (f) == "function" then -- Delegate to tag method. + f (self, node, unpack (node)) + elseif type (f) == "string" then -- tag string. + self:acc (f) + else -- No appropriate method, fall back to splice dumping. + -- This cannot happen in a plain Lua AST. + self:acc " -{ " + self:acc (pp.tostring (node, {metalua_tag=1, hide_hash=1}), 80) + self:acc " }" + end + end + end +end + +function M:block(body) + if not self.custom_printer or not self.custom_printer (self, body) then + self:nlindent () + self:list (body, self.nl) + self:nldedent () + end +end + +-------------------------------------------------------------------------------- +-- Convert every node in the AST list `list' passed as 1st arg. +-- `sep' is an optional separator to be accumulated between each list element, +-- it can be a string or a synth method. +-- `start' is an optional number (default == 1), indicating which is the +-- first element of list to be converted, so that we can skip the begining +-- of a list. +-------------------------------------------------------------------------------- +function M:list (list, sep, start) + for i = start or 1, # list do + self:node (list[i]) + if list[i + 1] then + if not sep then + elseif type (sep) == "function" then sep (self) + elseif type (sep) == "string" then self:acc (sep) + else error "Invalid list separator" end + end + end +end + +-------------------------------------------------------------------------------- +-- +-- Tag methods. +-- ------------ +-- +-- Specific AST node dumping methods, associated to their node kinds +-- by their name, which is the corresponding AST tag. +-- synth:node() is in charge of delegating a node's treatment to the +-- appropriate tag method. +-- +-- Such tag methods are called with the AST node as 1st arg. +-- As a convenience, the n node's children are passed as args #2 ... n+1. +-- +-- There are several things that could be refactored into common subroutines +-- here: statement blocks dumping, function dumping... +-- However, given their small size and linear execution +-- (they basically perform series of :acc(), :node(), :list(), +-- :nl(), :nlindent() and :nldedent() calls), it seems more readable +-- to avoid multiplication of such tiny functions. +-- +-- To make sense out of these, you need to know metalua's AST syntax, as +-- found in the reference manual or in metalua/doc/ast.txt. +-- +-------------------------------------------------------------------------------- + +function M:Do (node) + self:acc "do" + self:block (node) + self:acc "end" +end + +function M:Set (node) + match node with + | `Set{ { `Index{ lhs, `String{ method } } }, + { `Function{ { `Id "self", ... } == params, body } } } + if is_idx_stack (lhs) and is_ident (method) -> + -- ``function foo:bar(...) ... end'' -- + self:acc "function " + self:node (lhs) + self:acc ":" + self:acc (method) + self:acc " (" + self:list (params, ", ", 2) + self:acc ")" + self:block (body) + self:acc "end" + + | `Set{ { lhs }, { `Function{ params, body } } } if is_idx_stack (lhs) -> + -- ``function foo(...) ... end'' -- + self:acc "function " + self:node (lhs) + self:acc " (" + self:list (params, ", ") + self:acc ")" + self:block (body) + self:acc "end" + + | `Set{ { `Id{ lhs1name } == lhs1, ... } == lhs, rhs } + if not is_ident (lhs1name) -> + -- ``foo, ... = ...'' when foo is *not* a valid identifier. + -- In that case, the spliced 1st variable must get parentheses, + -- to be distinguished from a statement splice. + -- This cannot happen in a plain Lua AST. + self:acc "(" + self:node (lhs1) + self:acc ")" + if lhs[2] then -- more than one lhs variable + self:acc ", " + self:list (lhs, ", ", 2) + end + self:acc " = " + self:list (rhs, ", ") + + | `Set{ lhs, rhs } -> + -- ``... = ...'', no syntax sugar -- + self:list (lhs, ", ") + self:acc " = " + self:list (rhs, ", ") + | `Set{ lhs, rhs, annot } -> + -- ``... = ...'', no syntax sugar, annotation -- + local n = #lhs + for i=1,n do + local ell, a = lhs[i], annot[i] + self:node (ell) + if a then + self:acc ' #' + self:node(a) + end + if i~=n then self:acc ', ' end + end + self:acc " = " + self:list (rhs, ", ") + end +end + +function M:While (node, cond, body) + self:acc "while " + self:node (cond) + self:acc " do" + self:block (body) + self:acc "end" +end + +function M:Repeat (node, body, cond) + self:acc "repeat" + self:block (body) + self:acc "until " + self:node (cond) +end + +function M:If (node) + for i = 1, #node-1, 2 do + -- for each ``if/then'' and ``elseif/then'' pair -- + local cond, body = node[i], node[i+1] + self:acc (i==1 and "if " or "elseif ") + self:node (cond) + self:acc " then" + self:block (body) + end + -- odd number of children --> last one is an `else' clause -- + if #node%2 == 1 then + self:acc "else" + self:block (node[#node]) + end + self:acc "end" +end + +function M:Fornum (node, var, first, last) + local body = node[#node] + self:acc "for " + self:node (var) + self:acc " = " + self:node (first) + self:acc ", " + self:node (last) + if #node==5 then -- 5 children --> child #4 is a step increment. + self:acc ", " + self:node (node[4]) + end + self:acc " do" + self:block (body) + self:acc "end" +end + +function M:Forin (node, vars, generators, body) + self:acc "for " + self:list (vars, ", ") + self:acc " in " + self:list (generators, ", ") + self:acc " do" + self:block (body) + self:acc "end" +end + +function M:Local (node, lhs, rhs, annots) + if next (lhs) then + self:acc "local " + if annots then + local n = #lhs + for i=1, n do + self:node (lhs) + local a = annots[i] + if a then + self:acc ' #' + self:node (a) + end + if i~=n then self:acc ', ' end + end + else + self:list (lhs, ", ") + end + if rhs[1] then + self:acc " = " + self:list (rhs, ", ") + end + else -- Can't create a local statement with 0 variables in plain Lua + self:acc (pp.tostring (node, {metalua_tag=1, hide_hash=1, fix_indent=2})) + end +end + +function M:Localrec (node, lhs, rhs) + match node with + | `Localrec{ { `Id{name} }, { `Function{ params, body } } } + if is_ident (name) -> + -- ``local function name() ... end'' -- + self:acc "local function " + self:acc (name) + self:acc " (" + self:list (params, ", ") + self:acc ")" + self:block (body) + self:acc "end" + + | _ -> + -- Other localrec are unprintable ==> splice them -- + -- This cannot happen in a plain Lua AST. -- + self:acc "-{ " + self:acc (pp.tostring (node, {metalua_tag=1, hide_hash=1, fix_indent=2})) + self:acc " }" + end +end + +function M:Call (node, f) + -- single string or table literal arg ==> no need for parentheses. -- + local parens + match node with + | `Call{ _, `String{_} } + | `Call{ _, `Table{...}} -> parens = false + | _ -> parens = true + end + self:node (f) + self:acc (parens and " (" or " ") + self:list (node, ", ", 2) -- skip `f'. + self:acc (parens and ")") +end + +function M:Invoke (node, f, method) + -- single string or table literal arg ==> no need for parentheses. -- + local parens + match node with + | `Invoke{ _, _, `String{_} } + | `Invoke{ _, _, `Table{...}} -> parens = false + | _ -> parens = true + end + self:node (f) + self:acc ":" + self:acc (method[1]) + self:acc (parens and " (" or " ") + self:list (node, ", ", 3) -- Skip args #1 and #2, object and method name. + self:acc (parens and ")") +end + +function M:Return (node) + self:acc "return " + self:list (node, ", ") +end + +M.Break = "break" +M.Nil = "nil" +M.False = "false" +M.True = "true" +M.Dots = "..." + +function M:Number (node, n) + self:acc (tostring (n)) +end + +function M:String (node, str) + -- format "%q" prints '\n' in an umpractical way IMO, + -- so this is fixed with the :gsub( ) call. + self:acc (string.format ("%q", str):gsub ("\\\n", "\\n")) +end + +function M:Function (node, params, body, annots) + self:acc "function (" + if annots then + local n = #params + for i=1,n do + local p, a = params[i], annots[i] + self:node(p) + if annots then + self:acc " #" + self:node(a) + end + if i~=n then self:acc ', ' end + end + else + self:list (params, ", ") + end + self:acc ")" + self:block (body) + self:acc "end" +end + +function M:Table (node) + if not node[1] then self:acc "{ }" else + self:acc "{" + if #node > 1 then self:nlindent () else self:acc " " end + for i, elem in ipairs (node) do + match elem with + | `Pair{ `String{ key }, value } if is_ident (key) -> + -- ``key = value''. -- + self:acc (key) + self:acc " = " + self:node (value) + + | `Pair{ key, value } -> + -- ``[key] = value''. -- + self:acc "[" + self:node (key) + self:acc "] = " + self:node (value) + + | _ -> + -- ``value''. -- + self:node (elem) + end + if node [i+1] then + self:acc "," + self:nl () + end + end + if #node > 1 then self:nldedent () else self:acc " " end + self:acc "}" + end +end + +function M:Op (node, op, a, b) + -- Transform ``not (a == b)'' into ``a ~= b''. -- + match node with + | `Op{ "not", `Op{ "eq", _a, _b } } + | `Op{ "not", `Paren{ `Op{ "eq", _a, _b } } } -> + op, a, b = "ne", _a, _b + | _ -> + end + + if b then -- binary operator. + local left_paren, right_paren + match a with + | `Op{ op_a, ...} if op_prec[op] >= op_prec[op_a] -> left_paren = true + | _ -> left_paren = false + end + + match b with -- FIXME: might not work with right assoc operators ^ and .. + | `Op{ op_b, ...} if op_prec[op] >= op_prec[op_b] -> right_paren = true + | _ -> right_paren = false + end + + self:acc (left_paren and "(") + self:node (a) + self:acc (left_paren and ")") + + self:acc (op_symbol [op]) + + self:acc (right_paren and "(") + self:node (b) + self:acc (right_paren and ")") + + else -- unary operator. + local paren + match a with + | `Op{ op_a, ... } if op_prec[op] >= op_prec[op_a] -> paren = true + | _ -> paren = false + end + self:acc (op_symbol[op]) + self:acc (paren and "(") + self:node (a) + self:acc (paren and ")") + end +end + +function M:Paren (node, content) + self:acc "(" + self:node (content) + self:acc ")" +end + +function M:Index (node, table, key) + local paren_table + -- Check precedence, see if parens are needed around the table -- + match table with + | `Op{ op, ... } if op_prec[op] < op_prec.index -> paren_table = true + | _ -> paren_table = false + end + + self:acc (paren_table and "(") + self:node (table) + self:acc (paren_table and ")") + + match key with + | `String{ field } if is_ident (field) -> + -- ``table.key''. -- + self:acc "." + self:acc (field) + | _ -> + -- ``table [key]''. -- + self:acc "[" + self:node (key) + self:acc "]" + end +end + +function M:Id (node, name) + if is_ident (name) then + self:acc (name) + else -- Unprintable identifier, fall back to splice representation. + -- This cannot happen in a plain Lua AST. + self:acc "-{`Id " + self:String (node, name) + self:acc "}" + end +end + + +M.TDyn = '*' +M.TDynbar = '**' +M.TPass = 'pass' +M.TField = 'field' +M.TIdbar = M.TId +M.TReturn = M.Return + + +function M:TId (node, name) self:acc(name) end + + +function M:TCatbar(node, te, tebar) + self:acc'(' + self:node(te) + self:acc'|' + self:tebar(tebar) + self:acc')' +end + +function M:TFunction(node, p, r) + self:tebar(p) + self:acc '->' + self:tebar(r) +end + +function M:TTable (node, default, pairs) + self:acc '[' + self:list (pairs, ', ') + if default.tag~='TField' then + self:acc '|' + self:node (default) + end + self:acc ']' +end + +function M:TPair (node, k, v) + self:node (k) + self:acc '=' + self:node (v) +end + +function M:TIdbar (node, name) + self :acc (name) +end + +function M:TCatbar (node, a, b) + self:node(a) + self:acc ' ++ ' + self:node(b) +end + +function M:tebar(node) + if node.tag then self:node(node) else + self:acc '(' + self:list(node, ', ') + self:acc ')' + end +end + +function M:TUnkbar(node, name) + self:acc '~~' + self:acc (name) +end + +function M:TUnk(node, name) + self:acc '~' + self:acc (name) +end + +for name, tag in pairs{ const='TConst', var='TVar', currently='TCurrently', just='TJust' } do + M[tag] = function(self, node, te) + self:acc (name..' ') + self:node(te) + end +end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode.lua new file mode 100644 index 000000000..b3afbdb73 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode.lua @@ -0,0 +1,29 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +local compile = require 'metalua.compiler.bytecode.compile' +local ldump = require 'metalua.compiler.bytecode.ldump' + +local M = { } + +M.ast_to_proto = compile.ast_to_proto +M.proto_to_bytecode = ldump.dump_string +M.proto_to_file = ldump.dump_file + +return M \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/compile.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/compile.lua new file mode 100644 index 000000000..011517f3d --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/compile.lua @@ -0,0 +1,1263 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Kein-Hong Man, Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Kein-Hong Man - Initial implementation for Lua 5.0, part of Yueliang +-- Fabien Fleutot - Port to Lua 5.1, integration with Metalua +-- +------------------------------------------------------------------------------- + +---------------------------------------------------------------------- +-- +-- This code mainly results from the borrowing, then ruthless abuse, of +-- Yueliang's implementation of Lua 5.0 compiler. +-- +--------------------------------------------------------------------- + +local pp = require 'metalua.pprint' + +local luaK = require 'metalua.compiler.bytecode.lcode' +local luaP = require 'metalua.compiler.bytecode.lopcodes' + +local debugf = function() end +--local debugf=printf + +local stat = { } +local expr = { } + +local M = { } + +M.MAX_INT = 2147483645 -- INT_MAX-2 for 32-bit systems (llimits.h) +M.MAXVARS = 200 -- (llimits.h) +M.MAXUPVALUES = 32 -- (llimits.h) +M.MAXPARAMS = 100 -- (llimits.h) +M.LUA_MAXPARSERLEVEL = 200 -- (llimits.h) + +-- from lobject.h +M.VARARG_HASARG = 1 +M.VARARG_ISVARARG = 2 +M.VARARG_NEEDSARG = 4 + +local function hasmultret (k) + return k=="VCALL" or k=="VVARARG" +end + +----------------------------------------------------------------------- +-- Some ASTs take expression lists as children; it should be +-- acceptible to give an expression instead, and to automatically +-- interpret it as a single element list. That's what does this +-- function, adding a surrounding list iff needed. +-- +-- WARNING: "Do" is the tag for chunks, which are essentially lists. +-- Therefore, we don't listify stuffs with a "Do" tag. +----------------------------------------------------------------------- +local function ensure_list (ast) + return ast.tag and ast.tag ~= "Do" and {ast} or ast end + +----------------------------------------------------------------------- +-- Get a localvar structure { varname, startpc, endpc } from a +-- (zero-based) index of active variable. The catch is: don't get +-- confused between local index and active index. +-- +-- locvars[x] contains { varname, startpc, endpc }; +-- actvar[i] contains the index of the variable in locvars +----------------------------------------------------------------------- +local function getlocvar (fs, i) + return fs.f.locvars[fs.actvar[i]] +end + +local function removevars (fs, tolevel) + while fs.nactvar > tolevel do + fs.nactvar = fs.nactvar - 1 + -- There may be dummy locvars due to expr.Stat + -- FIXME: strange that they didn't disappear?! + local locvar = getlocvar (fs, fs.nactvar) + --printf("[REMOVEVARS] removing var #%i = %s", fs.nactvar, + -- locvar and tostringv(locvar) or "") + if locvar then locvar.endpc = fs.pc end + end +end + +----------------------------------------------------------------------- +-- [f] has a list of all its local variables, active and inactive. +-- Some local vars can correspond to the same register, if they exist +-- in different scopes. +-- [fs.nlocvars] is the total number of local variables, not to be +-- confused with [fs.nactvar] the numebr of variables active at the +-- current PC. +-- At this stage, the existence of the variable is not yet aknowledged, +-- since [fs.nactvar] and [fs.freereg] aren't updated. +----------------------------------------------------------------------- +local function registerlocalvar (fs, varname) + --debugf("[locvar: %s = reg %i]", varname, fs.nlocvars) + local f = fs.f + f.locvars[fs.nlocvars] = { } -- LocVar + f.locvars[fs.nlocvars].varname = varname + local nlocvars = fs.nlocvars + fs.nlocvars = fs.nlocvars + 1 + return nlocvars +end + +----------------------------------------------------------------------- +-- update the active vars counter in [fs] by adding [nvars] of them, +-- and sets those variables' [startpc] to the current [fs.pc]. +-- These variables were allready created, but not yet counted, by +-- new_localvar. +----------------------------------------------------------------------- +local function adjustlocalvars (fs, nvars) + --debugf("adjustlocalvars, nvars=%i, previous fs.nactvar=%i,".. + -- " #locvars=%i, #actvar=%i", + -- nvars, fs.nactvar, #fs.f.locvars, #fs.actvar) + + fs.nactvar = fs.nactvar + nvars + for i = nvars, 1, -1 do + --printf ("adjusting actvar #%i", fs.nactvar - i) + getlocvar (fs, fs.nactvar - i).startpc = fs.pc + end +end + +------------------------------------------------------------------------ +-- check whether, in an assignment to a local variable, the local variable +-- is needed in a previous assignment (to a table). If so, save original +-- local value in a safe place and use this safe copy in the previous +-- assignment. +------------------------------------------------------------------------ +local function check_conflict (fs, lh, v) + local extra = fs.freereg -- eventual position to save local variable + local conflict = false + while lh do + if lh.v.k == "VINDEXED" then + if lh.v.info == v.info then -- conflict? + conflict = true + lh.v.info = extra -- previous assignment will use safe copy + end + if lh.v.aux == v.info then -- conflict? + conflict = true + lh.v.aux = extra -- previous assignment will use safe copy + end + end + lh = lh.prev + end + if conflict then + luaK:codeABC (fs, "OP_MOVE", fs.freereg, v.info, 0) -- make copy + luaK:reserveregs (fs, 1) + end +end + +----------------------------------------------------------------------- +-- Create an expdesc. To be updated when expdesc is lua-ified. +----------------------------------------------------------------------- +local function init_exp (e, k, i) + e.f, e.t, e.k, e.info = luaK.NO_JUMP, luaK.NO_JUMP, k, i end + +----------------------------------------------------------------------- +-- Reserve the string in tthe constant pool, and return an expdesc +-- referring to it. +----------------------------------------------------------------------- +local function codestring (fs, e, str) + --printf( "codestring(%s)", disp.ast(str)) + init_exp (e, "VK", luaK:stringK (fs, str)) +end + +----------------------------------------------------------------------- +-- search for a local variable named [name] in the function being +-- built by [fs]. Doesn't try to visit upvalues. +----------------------------------------------------------------------- +local function searchvar (fs, name) + for i = fs.nactvar - 1, 0, -1 do + -- Because of expr.Stat, there can be some actvars which don't + -- correspond to any locvar. Hence the checking for locvar's + -- nonnilness before getting the varname. + local locvar = getlocvar(fs, i) + if locvar and name == locvar.varname then + --printf("Found local var: %s; i = %i", tostringv(locvar), i) + return i + end + end + return -1 -- not found +end + +----------------------------------------------------------------------- +-- create and return a new proto [f] +----------------------------------------------------------------------- +local function newproto () + local f = {} + f.k = {} + f.sizek = 0 + f.p = {} + f.sizep = 0 + f.code = {} + f.sizecode = 0 + f.sizelineinfo = 0 + f.sizeupvalues = 0 + f.nups = 0 + f.upvalues = {} + f.numparams = 0 + f.is_vararg = 0 + f.maxstacksize = 0 + f.lineinfo = {} + f.sizelocvars = 0 + f.locvars = {} + f.lineDefined = 0 + f.source = nil + return f +end + +------------------------------------------------------------------------ +-- create and return a function state [new_fs] as a sub-funcstate of [fs]. +------------------------------------------------------------------------ +local function open_func (old_fs) + local new_fs = { } + new_fs.upvalues = { } + new_fs.actvar = { } + local f = newproto () + new_fs.f = f + new_fs.prev = old_fs -- linked list of funcstates + new_fs.pc = 0 + new_fs.lasttarget = -1 + new_fs.jpc = luaK.NO_JUMP + new_fs.freereg = 0 + new_fs.nk = 0 + new_fs.h = {} -- constant table; was luaH_new call + new_fs.np = 0 + new_fs.nlocvars = 0 + new_fs.nactvar = 0 + new_fs.bl = nil + new_fs.nestlevel = old_fs and old_fs.nestlevel or 0 + f.maxstacksize = 2 -- registers 0/1 are always valid + new_fs.lastline = 0 + new_fs.forward_gotos = { } + new_fs.labels = { } + return new_fs +end + +------------------------------------------------------------------------ +-- Finish to set up [f] according to final state of [fs] +------------------------------------------------------------------------ +local function close_func (fs) + local f = fs.f + --printf("[CLOSE_FUNC] remove any remaining var") + removevars (fs, 0) + luaK:ret (fs, 0, 0) + f.sizecode = fs.pc + f.sizelineinfo = fs.pc + f.sizek = fs.nk + f.sizep = fs.np + f.sizelocvars = fs.nlocvars + f.sizeupvalues = f.nups + assert (fs.bl == nil) + if next(fs.forward_gotos) then + local x = pp.tostring(fs.forward_gotos) + error ("Unresolved goto: "..x) + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function pushclosure(fs, func, v) + local f = fs.f + f.p [fs.np] = func.f + fs.np = fs.np + 1 + init_exp (v, "VRELOCABLE", luaK:codeABx (fs, "OP_CLOSURE", 0, fs.np - 1)) + for i = 0, func.f.nups - 1 do + local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL" + luaK:codeABC (fs, o, 0, func.upvalues[i].info, 0) + end +end + +------------------------------------------------------------------------ +-- FIXME: is there a need for f=fs.f? if yes, why not always using it? +------------------------------------------------------------------------ +local function indexupvalue(fs, name, v) + local f = fs.f + for i = 0, f.nups - 1 do + if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then + assert(fs.f.upvalues[i] == name) + return i + end + end + -- new one + f.upvalues[f.nups] = name + assert (v.k == "VLOCAL" or v.k == "VUPVAL") + fs.upvalues[f.nups] = { k = v.k; info = v.info } + local nups = f.nups + f.nups = f.nups + 1 + return nups +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function markupval(fs, level) + local bl = fs.bl + while bl and bl.nactvar > level do bl = bl.previous end + if bl then bl.upval = true end +end + + +--for debug only +--[[ +local function bldepth(fs) + local i, x= 1, fs.bl + while x do i=i+1; x=x.previous end + return i +end +--]] + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function enterblock (fs, bl, isbreakable) + bl.breaklist = luaK.NO_JUMP + bl.isbreakable = isbreakable + bl.nactvar = fs.nactvar + bl.upval = false + bl.previous = fs.bl + fs.bl = bl + assert (fs.freereg == fs.nactvar) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function leaveblock (fs) + local bl = fs.bl + fs.bl = bl.previous + --printf("[LEAVEBLOCK] Removing vars...") + removevars (fs, bl.nactvar) + --printf("[LEAVEBLOCK] ...Vars removed") + if bl.upval then + luaK:codeABC (fs, "OP_CLOSE", bl.nactvar, 0, 0) + end + -- a block either controls scope or breaks (never both) + assert (not bl.isbreakable or not bl.upval) + assert (bl.nactvar == fs.nactvar) + fs.freereg = fs.nactvar -- free registers + luaK:patchtohere (fs, bl.breaklist) +end + + +------------------------------------------------------------------------ +-- read a list of expressions from a list of ast [astlist] +-- starts at the [offset]th element of the list (defaults to 1) +------------------------------------------------------------------------ +local function explist(fs, astlist, v, offset) + offset = offset or 1 + if #astlist < offset then error "I don't handle empty expr lists yet" end + --printf("[EXPLIST] about to precompile 1st element %s", disp.ast(astlist[offset])) + expr.expr (fs, astlist[offset], v) + --printf("[EXPLIST] precompiled first element v=%s", tostringv(v)) + for i = offset+1, #astlist do + luaK:exp2nextreg (fs, v) + --printf("[EXPLIST] flushed v=%s", tostringv(v)) + expr.expr (fs, astlist[i], v) + --printf("[EXPLIST] precompiled element v=%s", tostringv(v)) + end + return #astlist - offset + 1 +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function funcargs (fs, ast, v, idx_from) + local args = { } -- expdesc + local nparams + if #ast < idx_from then args.k = "VVOID" else + explist(fs, ast, args, idx_from) + luaK:setmultret(fs, args) + end + assert(v.k == "VNONRELOC") + local base = v.info -- base register for call + if hasmultret(args.k) then nparams = luaK.LUA_MULTRET else -- open call + if args.k ~= "VVOID" then + luaK:exp2nextreg(fs, args) end -- close last argument + nparams = fs.freereg - (base + 1) + end + init_exp(v, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2)) + if ast.lineinfo then + luaK:fixline(fs, ast.lineinfo.first.line) + else + luaK:fixline(fs, ast.line) + end + fs.freereg = base + 1 -- call remove function and arguments and leaves + -- (unless changed) one result +end + +------------------------------------------------------------------------ +-- calculates log value for encoding the hash portion's size +------------------------------------------------------------------------ +local function log2(x) + -- math result is always one more than lua0_log2() + local mn, ex = math.frexp(x) + return ex - 1 +end + +------------------------------------------------------------------------ +-- converts an integer to a "floating point byte", represented as +-- (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm) +------------------------------------------------------------------------ + +-- local function int2fb(x) +-- local m = 0 -- mantissa +-- while x >= 8 do x = math.floor((x + 1) / 2); m = m + 1 end +-- return m * 8 + x +-- end + +local function int2fb(x) + local e = 0 + while x >= 16 do + x = math.floor ( (x+1) / 2) + e = e+1 + end + if x<8 then return x + else return (e+1) * 8 + x - 8 end +end + + +------------------------------------------------------------------------ +-- FIXME: to be unified with singlevar +------------------------------------------------------------------------ +local function singlevaraux(fs, n, var, base) +--[[ +print("\n\nsinglevaraux: fs, n, var, base") +printv(fs) +printv(n) +printv(var) +printv(base) +print("\n") +--]] + if fs == nil then -- no more levels? + init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable + return "VGLOBAL" + else + local v = searchvar(fs, n) -- look up at current level + if v >= 0 then + init_exp(var, "VLOCAL", v) + if not base then + markupval(fs, v) -- local will be used as an upval + end + else -- not found at current level; try upper one + if singlevaraux(fs.prev, n, var, false) == "VGLOBAL" then + return "VGLOBAL" end + var.info = indexupvalue (fs, n, var) + var.k = "VUPVAL" + return "VUPVAL" + end + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function singlevar(fs, varname, var) + if singlevaraux(fs, varname, var, true) == "VGLOBAL" then + var.info = luaK:stringK (fs, varname) end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function new_localvar (fs, name, n) + assert (type (name) == "string") + if fs.nactvar + n > M.MAXVARS then error ("too many local vars") end + fs.actvar[fs.nactvar + n] = registerlocalvar (fs, name) + --printf("[NEW_LOCVAR] %i = %s", fs.nactvar+n, name) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function parlist (fs, ast_params) + local dots = (#ast_params > 0 and ast_params[#ast_params].tag == "Dots") + local nparams = dots and #ast_params - 1 or #ast_params + for i = 1, nparams do + assert (ast_params[i].tag == "Id", "Function parameters must be Ids") + new_localvar (fs, ast_params[i][1], i-1) + end + -- from [code_param]: + --checklimit (fs, fs.nactvar, self.M.MAXPARAMS, "parameters") + fs.f.numparams = fs.nactvar + fs.f.is_vararg = dots and M.VARARG_ISVARARG or 0 + adjustlocalvars (fs, nparams) + fs.f.numparams = fs.nactvar --FIXME vararg must be taken in account + luaK:reserveregs (fs, fs.nactvar) -- reserve register for parameters +end + +------------------------------------------------------------------------ +-- if there's more variables than expressions in an assignment, +-- some assignations to nil are made for extraneous vars. +-- Also handles multiret functions +------------------------------------------------------------------------ +local function adjust_assign (fs, nvars, nexps, e) + local extra = nvars - nexps + if hasmultret (e.k) then + extra = extra+1 -- includes call itself + if extra <= 0 then extra = 0 end + luaK:setreturns(fs, e, extra) -- call provides the difference + if extra > 1 then luaK:reserveregs(fs, extra-1) end + else + if e.k ~= "VVOID" then + luaK:exp2nextreg(fs, e) end -- close last expression + if extra > 0 then + local reg = fs.freereg + luaK:reserveregs(fs, extra) + luaK:_nil(fs, reg, extra) + end + end +end + + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function enterlevel (fs) + fs.nestlevel = fs.nestlevel + 1 + assert (fs.nestlevel <= M.LUA_MAXPARSERLEVEL, "too many syntax levels") +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function leavelevel (fs) + fs.nestlevel = fs.nestlevel - 1 +end + +------------------------------------------------------------------------ +-- Parse conditions in if/then/else, while, repeat +------------------------------------------------------------------------ +local function cond (fs, ast) + local v = { } + expr.expr(fs, ast, v) -- read condition + if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here + luaK:goiftrue (fs, v) + return v.f +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function chunk (fs, ast) + enterlevel (fs) + assert (not ast.tag) + for i=1, #ast do + stat.stat (fs, ast[i]); + fs.freereg = fs.nactvar + end + leavelevel (fs) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function block (fs, ast) + local bl = {} + enterblock (fs, bl, false) + for i=1, #ast do + stat.stat (fs, ast[i]) + fs.freereg = fs.nactvar + end + assert (bl.breaklist == luaK.NO_JUMP) + leaveblock (fs) +end + +------------------------------------------------------------------------ +-- Forin / Fornum body parser +-- [fs] +-- [body] +-- [base] +-- [nvars] +-- [isnum] +------------------------------------------------------------------------ +local function forbody (fs, ast_body, base, nvars, isnum) + local bl = {} -- BlockCnt + adjustlocalvars (fs, 3) -- control variables + local prep = + isnum and luaK:codeAsBx (fs, "OP_FORPREP", base, luaK.NO_JUMP) + or luaK:jump (fs) + enterblock (fs, bl, false) -- loop block + adjustlocalvars (fs, nvars) -- scope for declared variables + luaK:reserveregs (fs, nvars) + block (fs, ast_body) + leaveblock (fs) + --luaK:patchtohere (fs, prep-1) + luaK:patchtohere (fs, prep) + local endfor = + isnum and luaK:codeAsBx (fs, "OP_FORLOOP", base, luaK.NO_JUMP) + or luaK:codeABC (fs, "OP_TFORLOOP", base, 0, nvars) + luaK:fixline (fs, ast_body.line) -- pretend that 'OP_FOR' starts the loop + luaK:patchlist (fs, isnum and endfor or luaK:jump(fs), prep + 1) +end + + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function recfield (fs, ast, cc) + local reg = fs.freereg + local key, val = {}, {} -- expdesc + --FIXME: expr + exp2val = index --> + -- check reduncancy between exp2val and exp2rk + cc.nh = cc.nh + 1 + expr.expr(fs, ast[1], key); + luaK:exp2val (fs, key) + local keyreg = luaK:exp2RK (fs, key) + expr.expr(fs, ast[2], val) + local valreg = luaK:exp2RK (fs, val) + luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, keyreg, valreg) + fs.freereg = reg -- free registers +end + + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function listfield(fs, ast, cc) + expr.expr(fs, ast, cc.v) + assert (cc.na <= luaP.MAXARG_Bx) -- FIXME check <= or < + cc.na = cc.na + 1 + cc.tostore = cc.tostore + 1 +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +local function closelistfield(fs, cc) + if cc.v.k == "VVOID" then return end -- there is no list item + luaK:exp2nextreg(fs, cc.v) + cc.v.k = "VVOID" + if cc.tostore == luaP.LFIELDS_PER_FLUSH then + luaK:setlist (fs, cc.t.info, cc.na, cc.tostore) + cc.tostore = 0 + end +end + +------------------------------------------------------------------------ +-- The last field might be a call to a multireturn function. In that +-- case, we must unfold all of its results into the list. +------------------------------------------------------------------------ +local function lastlistfield(fs, cc) + if cc.tostore == 0 then return end + if hasmultret (cc.v.k) then + luaK:setmultret(fs, cc.v) + luaK:setlist (fs, cc.t.info, cc.na, luaK.LUA_MULTRET) + cc.na = cc.na - 1 + else + if cc.v.k ~= "VVOID" then luaK:exp2nextreg(fs, cc.v) end + luaK:setlist (fs, cc.t.info, cc.na, cc.tostore) + end +end +------------------------------------------------------------------------ +------------------------------------------------------------------------ +-- +-- Statement parsers table +-- +------------------------------------------------------------------------ +------------------------------------------------------------------------ + +function stat.stat (fs, ast) + if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end + --debugf (" - Statement %s", table.tostring (ast) ) + + if not ast.tag then chunk (fs, ast) else + + local parser = stat [ast.tag] + if not parser then + error ("A statement cannot have tag `"..ast.tag) end + parser (fs, ast) + end + --debugf (" - /Statement `%s", ast.tag) +end + +------------------------------------------------------------------------ + +stat.Do = block + +------------------------------------------------------------------------ + +function stat.Break (fs, ast) + -- if ast.lineinfo then fs.lastline = ast.lineinfo.last.line + local bl, upval = fs.bl, false + while bl and not bl.isbreakable do + if bl.upval then upval = true end + bl = bl.previous + end + assert (bl, "no loop to break") + if upval then luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) end + bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs)) +end + +------------------------------------------------------------------------ + +function stat.Return (fs, ast) + local e = {} -- expdesc + local first -- registers with returned values + local nret = #ast + + if nret == 0 then first = 0 + else + --printf("[RETURN] compiling explist") + explist (fs, ast, e) + --printf("[RETURN] explist e=%s", tostringv(e)) + if hasmultret (e.k) then + luaK:setmultret(fs, e) + if e.k == "VCALL" and nret == 1 then + luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL") + assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar) + end + first = fs.nactvar + nret = luaK.LUA_MULTRET -- return all values + elseif nret == 1 then + first = luaK:exp2anyreg(fs, e) + else + --printf("* Return multiple vals in nextreg %i", fs.freereg) + luaK:exp2nextreg(fs, e) -- values must go to the 'stack' + first = fs.nactvar -- return all 'active' values + assert(nret == fs.freereg - first) + end + end + luaK:ret(fs, first, nret) +end +------------------------------------------------------------------------ + +function stat.Local (fs, ast) + local names, values = ast[1], ast[2] or { } + for i = 1, #names do new_localvar (fs, names[i][1], i-1) end + local e = { } + if #values == 0 then e.k = "VVOID" else explist (fs, values, e) end + adjust_assign (fs, #names, #values, e) + adjustlocalvars (fs, #names) +end + +------------------------------------------------------------------------ + +function stat.Localrec (fs, ast) + assert(#ast[1]==1 and #ast[2]==1, "Multiple letrecs not implemented yet") + local ast_var, ast_val, e_var, e_val = ast[1][1], ast[2][1], { }, { } + new_localvar (fs, ast_var[1], 0) + init_exp (e_var, "VLOCAL", fs.freereg) + luaK:reserveregs (fs, 1) + adjustlocalvars (fs, 1) + expr.expr (fs, ast_val, e_val) + luaK:storevar (fs, e_var, e_val) + getlocvar (fs, fs.nactvar-1).startpc = fs.pc +end + +------------------------------------------------------------------------ + +function stat.If (fs, ast) + local astlen = #ast + -- Degenerate case #1: no statement + if astlen==0 then return block(fs, { }) end + -- Degenerate case #2: only an else statement + if astlen==1 then return block(fs, ast[1]) end + + local function test_then_block (fs, test, body) + local condexit = cond (fs, test); + block (fs, body) + return condexit + end + + local escapelist = luaK.NO_JUMP + + local flist = test_then_block (fs, ast[1], ast[2]) -- 'then' statement + for i = 3, #ast - 1, 2 do -- 'elseif' statement + escapelist = luaK:concat( fs, escapelist, luaK:jump(fs)) + luaK:patchtohere (fs, flist) + flist = test_then_block (fs, ast[i], ast[i+1]) + end + if #ast % 2 == 1 then -- 'else' statement + escapelist = luaK:concat(fs, escapelist, luaK:jump(fs)) + luaK:patchtohere(fs, flist) + block (fs, ast[#ast]) + else + escapelist = luaK:concat(fs, escapelist, flist) + end + luaK:patchtohere(fs, escapelist) +end + +------------------------------------------------------------------------ + +function stat.Forin (fs, ast) + local vars, vals, body = ast[1], ast[2], ast[3] + -- imitating forstat: + local bl = { } + enterblock (fs, bl, true) + -- imitating forlist: + local e, base = { }, fs.freereg + new_localvar (fs, "(for generator)", 0) + new_localvar (fs, "(for state)", 1) + new_localvar (fs, "(for control)", 2) + for i = 1, #vars do new_localvar (fs, vars[i][1], i+2) end + explist (fs, vals, e) + adjust_assign (fs, 3, #vals, e) + luaK:checkstack (fs, 3) + forbody (fs, body, base, #vars, false) + -- back to forstat: + leaveblock (fs) +end + +------------------------------------------------------------------------ + +function stat.Fornum (fs, ast) + + local function exp1 (ast_e) + local e = { } + expr.expr (fs, ast_e, e) + luaK:exp2nextreg (fs, e) + end + -- imitating forstat: + local bl = { } + enterblock (fs, bl, true) + -- imitating fornum: + local base = fs.freereg + new_localvar (fs, "(for index)", 0) + new_localvar (fs, "(for limit)", 1) + new_localvar (fs, "(for step)", 2) + new_localvar (fs, ast[1][1], 3) + exp1 (ast[2]) -- initial value + exp1 (ast[3]) -- limit + if #ast == 5 then exp1 (ast[4]) else -- default step = 1 + luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1)) + luaK:reserveregs(fs, 1) + end + forbody (fs, ast[#ast], base, 1, true) + -- back to forstat: + leaveblock (fs) +end + +------------------------------------------------------------------------ +function stat.Repeat (fs, ast) + local repeat_init = luaK:getlabel (fs) + local bl1, bl2 = { }, { } + enterblock (fs, bl1, true) + enterblock (fs, bl2, false) + chunk (fs, ast[1]) + local condexit = cond (fs, ast[2]) + if not bl2.upval then + leaveblock (fs) + luaK:patchlist (fs, condexit, repeat_init) + else + stat.Break (fs) + luaK:patchtohere (fs, condexit) + leaveblock (fs) + luaK:patchlist (fs, luaK:jump (fs), repeat_init) + end + leaveblock (fs) +end + +------------------------------------------------------------------------ + +function stat.While (fs, ast) + local whileinit = luaK:getlabel (fs) + local condexit = cond (fs, ast[1]) + local bl = { } + enterblock (fs, bl, true) + block (fs, ast[2]) + luaK:patchlist (fs, luaK:jump (fs), whileinit) + leaveblock (fs) + luaK:patchtohere (fs, condexit); +end + +------------------------------------------------------------------------ + +-- FIXME: it's cumbersome to write this in this semi-recursive way. +function stat.Set (fs, ast) + local ast_lhs, ast_vals, e = ast[1], ast[2], { } + + --print "\n\nSet ast_lhs ast_vals:" + --print(disp.ast(ast_lhs)) + --print(disp.ast(ast_vals)) + + local function let_aux (lhs, nvars) + local legal = { VLOCAL=1, VUPVAL=1, VGLOBAL=1, VINDEXED=1 } + --printv(lhs) + if not legal [lhs.v.k] then + error ("Bad lhs expr: "..pp.tostring(ast_lhs)) + end + if nvars < #ast_lhs then -- this is not the last lhs + local nv = { v = { }, prev = lhs } + expr.expr (fs, ast_lhs [nvars+1], nv.v) + if nv.v.k == "VLOCAL" then check_conflict (fs, lhs, nv.v) end + let_aux (nv, nvars+1) + else -- this IS the last lhs + explist (fs, ast_vals, e) + if #ast_vals < nvars then + adjust_assign (fs, nvars, #ast_vals, e) + elseif #ast_vals > nvars then + adjust_assign (fs, nvars, #ast_vals, e) + fs.freereg = fs.freereg - #ast_vals + nvars + else -- #ast_vals == nvars (and we're at last lhs) + luaK:setoneret (fs, e) -- close last expression + luaK:storevar (fs, lhs.v, e) + return -- avoid default + end + end + init_exp (e, "VNONRELOC", fs.freereg - 1) -- default assignment + luaK:storevar (fs, lhs.v, e) + end + + local lhs = { v = { }, prev = nil } + expr.expr (fs, ast_lhs[1], lhs.v) + let_aux( lhs, 1) +end + +------------------------------------------------------------------------ + +function stat.Call (fs, ast) + local v = { } + expr.Call (fs, ast, v) + luaP:SETARG_C (luaK:getcode(fs, v), 1) +end + +------------------------------------------------------------------------ + +function stat.Invoke (fs, ast) + local v = { } + expr.Invoke (fs, ast, v) + --FIXME: didn't check that, just copied from stat.Call + luaP:SETARG_C (luaK:getcode(fs, v), 1) +end + + +local function patch_goto (fs, src, dst) + +end + + +------------------------------------------------------------------------ +-- Goto/Label data: +-- fs.labels :: string => { nactvar :: int; pc :: int } +-- fs.forward_gotos :: string => list(int) +-- +-- fs.labels goes from label ids to the number of active variables at +-- the label's PC, and that PC +-- +-- fs.forward_gotos goes from label ids to the list of the PC where +-- some goto wants to jump to this label. Since gotos are actually made +-- up of two instructions OP_CLOSE and OP_JMP, it's the first instruction's +-- PC that's stored in fs.forward_gotos +-- +-- Note that backward gotos aren't stored: since their destination is knowns +-- when they're compiled, their target is directly set. +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- Set a Label to jump to with Goto +------------------------------------------------------------------------ +function stat.Label (fs, ast) + local label_id = ast[1] + if type(label_id)=='table' then label_id=label_id[1] end + -- printf("Label %s at PC %i", label_id, fs.pc) + ------------------------------------------------------------------- + -- Register the label, so that future gotos can use it. + ------------------------------------------------------------------- + if fs.labels [label_id] then error "Duplicate label in function" + else fs.labels [label_id] = { pc = fs.pc; nactvar = fs.nactvar } end + local gotos = fs.forward_gotos [label_id] + if gotos then + ---------------------------------------------------------------- + -- Patch forward gotos which were targetting this label. + ---------------------------------------------------------------- + for _, goto_pc in ipairs(gotos) do + local close_instr = fs.f.code[goto_pc] + local jmp_instr = fs.f.code[goto_pc+1] + local goto_nactvar = luaP:GETARG_A (close_instr) + if fs.nactvar < goto_nactvar then + luaP:SETARG_A (close_instr, fs.nactvar) end + luaP:SETARG_sBx (jmp_instr, fs.pc - goto_pc - 2) + end + ---------------------------------------------------------------- + -- Gotos are patched, they can be forgotten about (when the + -- function will be finished, it will be checked that all gotos + -- have been patched, by checking that forward_goto is empty). + ---------------------------------------------------------------- + fs.forward_gotos[label_id] = nil + end +end + +------------------------------------------------------------------------ +-- jumps to a label set with stat.Label. +-- Argument must be a String or an Id +-- FIXME/optim: get rid of useless OP_CLOSE when nactvar doesn't change. +-- Thsi must be done both here for backward gotos, and in +-- stat.Label for forward gotos. +------------------------------------------------------------------------ +function stat.Goto (fs, ast) + local label_id = ast[1] + if type(label_id)=='table' then label_id=label_id[1] end + -- printf("Goto %s at PC %i", label_id, fs.pc) + local label = fs.labels[label_id] + if label then + ---------------------------------------------------------------- + -- Backward goto: the label already exists, so I can get its + -- nactvar and address directly. nactvar is used to close + -- upvalues if we get out of scoping blocks by jumping. + ---------------------------------------------------------------- + if fs.nactvar > label.nactvar then + luaK:codeABC (fs, "OP_CLOSE", label.nactvar, 0, 0) end + local offset = label.pc - fs.pc - 1 + luaK:codeAsBx (fs, "OP_JMP", 0, offset) + else + ---------------------------------------------------------------- + -- Forward goto: will be patched when the matching label is + -- found, forward_gotos[label_id] keeps the PC of the CLOSE + -- instruction just before the JMP. [stat.Label] will use it to + -- patch the OP_CLOSE and the OP_JMP. + ---------------------------------------------------------------- + if not fs.forward_gotos[label_id] then + fs.forward_gotos[label_id] = { } end + table.insert (fs.forward_gotos[label_id], fs.pc) + luaK:codeABC (fs, "OP_CLOSE", fs.nactvar, 0, 0) + luaK:codeAsBx (fs, "OP_JMP", 0, luaK.NO_JUMP) + end +end + +------------------------------------------------------------------------ +------------------------------------------------------------------------ +-- +-- Expression parsers table +-- +------------------------------------------------------------------------ +------------------------------------------------------------------------ + +function expr.expr (fs, ast, v) + if type(ast) ~= "table" then + error ("Expr AST expected, got "..pp.tostring(ast)) end + + if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end + + --debugf (" - Expression %s", table.tostring (ast)) + local parser = expr[ast.tag] + if parser then parser (fs, ast, v) + elseif not ast.tag then + error ("No tag in expression ".. + pp.tostring(ast, {line_max=80, hide_hash=1, metalua_tag=1})) + else + error ("No parser for node `"..ast.tag) end + --debugf (" - /Expression `%s", ast.tag) +end + +------------------------------------------------------------------------ + +function expr.Nil (fs, ast, v) init_exp (v, "VNIL", 0) end +function expr.True (fs, ast, v) init_exp (v, "VTRUE", 0) end +function expr.False (fs, ast, v) init_exp (v, "VFALSE", 0) end +function expr.String (fs, ast, v) codestring (fs, v, ast[1]) end +function expr.Number (fs, ast, v) + init_exp (v, "VKNUM", 0) + v.nval = ast[1] +end + +function expr.Paren (fs, ast, v) + expr.expr (fs, ast[1], v) + luaK:setoneret (fs, v) +end + +function expr.Dots (fs, ast, v) + assert (fs.f.is_vararg ~= 0, "No vararg in this function") + -- NEEDSARG flag is set if and only if the function is a vararg, + -- but no vararg has been used yet in its code. + if fs.f.is_vararg < M.VARARG_NEEDSARG then + fs.f.is_varag = fs.f.is_vararg - M.VARARG_NEEDSARG end + init_exp (v, "VVARARG", luaK:codeABC (fs, "OP_VARARG", 0, 1, 0)) +end + +------------------------------------------------------------------------ + +function expr.Table (fs, ast, v) + local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0) + local cc = { v = { } , na = 0, nh = 0, tostore = 0, t = v } -- ConsControl + init_exp (v, "VRELOCABLE", pc) + init_exp (cc.v, "VVOID", 0) -- no value (yet) + luaK:exp2nextreg (fs, v) -- fix it at stack top (for gc) + for i = 1, #ast do + assert(cc.v.k == "VVOID" or cc.tostore > 0) + closelistfield(fs, cc); + (ast[i].tag == "Pair" and recfield or listfield) (fs, ast[i], cc) + end + lastlistfield(fs, cc) + + -- Configure [OP_NEWTABLE] dimensions + luaP:SETARG_B(fs.f.code[pc], int2fb(cc.na)) -- set initial array size + luaP:SETARG_C(fs.f.code[pc], int2fb(cc.nh)) -- set initial table size + --printv(fs.f.code[pc]) +end + + +------------------------------------------------------------------------ + +function expr.Function (fs, ast, v) + if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end + + local new_fs = open_func(fs) + if ast.lineinfo then + new_fs.f.lineDefined, new_fs.f.lastLineDefined = + ast.lineinfo.first.line, ast.lineinfo.last.line + end + parlist (new_fs, ast[1]) + chunk (new_fs, ast[2]) + close_func (new_fs) + pushclosure(fs, new_fs, v) +end + +------------------------------------------------------------------------ + +function expr.Op (fs, ast, v) + if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end + local op = ast[1] + + if #ast == 2 then + expr.expr (fs, ast[2], v) + luaK:prefix (fs, op, v) + elseif #ast == 3 then + local v2 = { } + expr.expr (fs, ast[2], v) + luaK:infix (fs, op, v) + expr.expr (fs, ast[3], v2) + luaK:posfix (fs, op, v, v2) + else + error "Wrong arg number" + end +end + +------------------------------------------------------------------------ + +function expr.Call (fs, ast, v) + expr.expr (fs, ast[1], v) + luaK:exp2nextreg (fs, v) + funcargs(fs, ast, v, 2) + --debugf("after expr.Call: %s, %s", v.k, luaP.opnames[luaK:getcode(fs, v).OP]) +end + +------------------------------------------------------------------------ +-- `Invoke{ table key args } +function expr.Invoke (fs, ast, v) + expr.expr (fs, ast[1], v) + luaK:dischargevars (fs, v) + local key = { } + codestring (fs, key, ast[2][1]) + luaK:_self (fs, v, key) + funcargs (fs, ast, v, 3) +end + +------------------------------------------------------------------------ + +function expr.Index (fs, ast, v) + if #ast ~= 2 then + print"\n\nBAD INDEX AST:" + pp.print(ast) + error "generalized indexes not implemented" end + + if ast.lineinfo then fs.lastline = ast.lineinfo.last.line end + + --assert(fs.lastline ~= 0, ast.tag) + + expr.expr (fs, ast[1], v) + luaK:exp2anyreg (fs, v) + + local k = { } + expr.expr (fs, ast[2], k) + luaK:exp2val (fs, k) + luaK:indexed (fs, v, k) +end + +------------------------------------------------------------------------ + +function expr.Id (fs, ast, v) + assert (ast.tag == "Id") + singlevar (fs, ast[1], v) +end + +------------------------------------------------------------------------ + +function expr.Stat (fs, ast, v) + --printf(" * Stat: %i actvars, first freereg is %i", fs.nactvar, fs.freereg) + --printf(" actvars: %s", table.tostring(fs.actvar)) + + -- Protect temporary stack values by pretending they are local + -- variables. Local vars are in registers 0 ... fs.nactvar-1, + -- and temporary unnamed variables in fs.nactvar ... fs.freereg-1 + local save_nactvar = fs.nactvar + + -- Eventually, the result should go on top of stack *after all + -- `Stat{ } related computation and string usage is over. The index + -- of this destination register is kept here: + local dest_reg = fs.freereg + + -- There might be variables in actvar whose register is > nactvar, + -- and therefore will not be protected by the "nactvar := freereg" + -- trick. Indeed, `Local only increases nactvar after the variable + -- content has been computed. Therefore, in + -- "local foo = -{`Stat{...}}", variable foo will be messed up by + -- the compilation of `Stat. + -- FIX: save the active variables at indices >= nactvar in + -- save_actvar, and restore them after `Stat has been computed. + -- + -- I use a while rather than for loops and length operators because + -- fs.actvar is a 0-based array... + local save_actvar = { } do + local i = fs.nactvar + while true do + local v = fs.actvar[i] + if not v then break end + --printf("save hald-baked actvar %s at index %i", table.tostring(v), i) + save_actvar[i] = v + i=i+1 + end + end + + fs.nactvar = fs.freereg -- Now temp unnamed registers are protected + enterblock (fs, { }, false) + chunk (fs, ast[1]) + expr.expr (fs, ast[2], v) + luaK:exp2nextreg (fs, v) + leaveblock (fs) + luaK:exp2reg (fs, v, dest_reg) + + -- Reserve the newly allocated stack level + -- Puzzled note: here was written "fs.freereg = fs.freereg+1". + -- I'm pretty sure it should rather be dest_reg+1, but maybe + -- both are equivalent? + fs.freereg = dest_reg+1 + + -- Restore nactvar, so that intermediate stacked value stop + -- being protected. + --printf(" nactvar back from %i to %i", fs.nactvar, save_nactvar) + fs.nactvar = save_nactvar + + -- restore messed-up unregistered local vars + for i, j in pairs(save_actvar) do + --printf(" Restoring actvar %i", i) + fs.actvar[i] = j + end + --printf(" * End of Stat") +end + +------------------------------------------------------------------------ +-- Main function: ast --> proto +------------------------------------------------------------------------ +function M.ast_to_proto (ast, source) + local fs = open_func (nil) + fs.f.is_vararg = M.VARARG_ISVARARG + chunk (fs, ast) + close_func (fs) + assert (fs.prev == nil) + assert (fs.f.nups == 0) + assert (fs.nestlevel == 0) + if source then fs.f.source = source end + return fs.f, source +end + +return M \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/lcode.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/lcode.lua new file mode 100644 index 000000000..ede1a1c45 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/lcode.lua @@ -0,0 +1,1038 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2005-2013 Kein-Hong Man, Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Kein-Hong Man - Initial implementation for Lua 5.0, part of Yueliang +-- Fabien Fleutot - Port to Lua 5.1, integration with Metalua +-- +------------------------------------------------------------------------------- + +--[[-------------------------------------------------------------------- + + $Id$ + + lcode.lua + Lua 5 code generator in Lua + This file is part of Yueliang. + + Copyright (c) 2005 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +------------------------------------------------------------------------ + + [FF] Slightly modified, mainly to produce Lua 5.1 bytecode. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * one function manipulate a pointer argument with a simple data type +-- (can't be emulated by a table, ambiguous), now returns that value: +-- luaK:concat(fs, l1, l2) +-- * some function parameters changed to boolean, additional code +-- translates boolean back to 1/0 for instruction fields +-- * Added: +-- luaK:ttisnumber(o) (from lobject.h) +-- luaK:nvalue(o) (from lobject.h) +-- luaK:setnilvalue(o) (from lobject.h) +-- luaK:setsvalue(o) (from lobject.h) +-- luaK:setnvalue(o) (from lobject.h) +-- luaK:sethvalue(o) (from lobject.h) +----------------------------------------------------------------------]] + +local luaP = require 'metalua.compiler.bytecode.lopcodes' + +local function debugf() end + +local luaK = { } + +luaK.MAXSTACK = 250 -- (llimits.h, used in lcode.lua) +luaK.LUA_MULTRET = -1 -- (lua.h) + +------------------------------------------------------------------------ +-- Marks the end of a patch list. It is an invalid value both as an absolute +-- address, and as a list link (would link an element to itself). +------------------------------------------------------------------------ +luaK.NO_JUMP = -1 + +--FF 5.1 +function luaK:isnumeral(e) + return e.k=="VKNUM" and e.t==self.NO_JUMP and e.t==self.NO_JUMP +end + +------------------------------------------------------------------------ +-- emulation of TObject macros (these are from lobject.h) +-- * TObject is a table since lcode passes references around +-- * tt member field removed, using Lua's type() instead +------------------------------------------------------------------------ +function luaK:ttisnumber(o) + if o then return type(o.value) == "number" else return false end +end +function luaK:nvalue(o) return o.value end +function luaK:setnilvalue(o) o.value = nil end +function luaK:setsvalue(o, s) o.value = s end +luaK.setnvalue = luaK.setsvalue +luaK.sethvalue = luaK.setsvalue + +------------------------------------------------------------------------ +-- returns the instruction object for given e (expdesc) +------------------------------------------------------------------------ +function luaK:getcode(fs, e) + return fs.f.code[e.info] +end + +------------------------------------------------------------------------ +-- codes an instruction with a signed Bx (sBx) field +------------------------------------------------------------------------ +function luaK:codeAsBx(fs, o, A, sBx) + return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:hasjumps(e) + return e.t ~= e.f +end + +------------------------------------------------------------------------ +-- FF updated 5.1 +------------------------------------------------------------------------ +function luaK:_nil(fs, from, n) + if fs.pc > fs.lasttarget then -- no jumps to current position? + if fs.pc == 0 then return end --function start, positions are already clean + local previous = fs.f.code[fs.pc - 1] + if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then + local pfrom = luaP:GETARG_A(previous) + local pto = luaP:GETARG_B(previous) + if pfrom <= from and from <= pto + 1 then -- can connect both? + if from + n - 1 > pto then + luaP:SETARG_B(previous, from + n - 1) + end + return + end + end + end + self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:jump(fs) + local jpc = fs.jpc -- save list of jumps to here + fs.jpc = self.NO_JUMP + local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP) + return self:concat(fs, j, jpc) -- keep them on hold +end + +--FF 5.1 +function luaK:ret (fs, first, nret) + luaK:codeABC (fs, "OP_RETURN", first, nret+1, 0) +end + + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:condjump(fs, op, A, B, C) + self:codeABC(fs, op, A, B, C) + return self:jump(fs) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:fixjump(fs, pc, dest) + local jmp = fs.f.code[pc] + local offset = dest - (pc + 1) + assert(dest ~= self.NO_JUMP) + if math.abs(offset) > luaP.MAXARG_sBx then + error("control structure too long") + end + luaP:SETARG_sBx(jmp, offset) +end + +------------------------------------------------------------------------ +-- returns current 'pc' and marks it as a jump target (to avoid wrong +-- optimizations with consecutive instructions not in the same basic block). +------------------------------------------------------------------------ +function luaK:getlabel(fs) + fs.lasttarget = fs.pc + return fs.pc +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:getjump(fs, pc) + local offset = luaP:GETARG_sBx(fs.f.code[pc]) + if offset == self.NO_JUMP then -- point to itself represents end of list + return self.NO_JUMP -- end of list + else + return (pc + 1) + offset -- turn offset into absolute position + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:getjumpcontrol(fs, pc) + local pi = fs.f.code[pc] + local ppi = fs.f.code[pc - 1] + if pc >= 1 and luaP:testOpMode(luaP:GET_OPCODE(ppi), "OpModeT") then + return ppi + else + return pi + end +end + +------------------------------------------------------------------------ +-- check whether list has any jump that do not produce a value +-- (or produce an inverted value) +------------------------------------------------------------------------ +--FF updated 5.1 +function luaK:need_value(fs, list, cond) + while list ~= self.NO_JUMP do + local i = self:getjumpcontrol(fs, list) + if luaP:GET_OPCODE(i) ~= "OP_TESTSET" or + luaP:GETARG_A(i) ~= luaP.NO_REG or + luaP:GETARG_C(i) ~= cond then + return true + end + list = self:getjump(fs, list) + end + return false -- not found +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +--FF updated 5.1 +function luaK:patchtestreg(fs, node, reg) + assert(reg) -- pour assurer, vu que j'ai ajoute un parametre p/r a 5.0 + local i = self:getjumpcontrol(fs, node) + if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then + return false end -- cannot patch other instructions + if reg ~= luaP.NO_REG and reg ~= luaP:GETARG_B(i) then + luaP:SETARG_A(i, reg) + else + -- no register to put value or register already has the value + luaP:SET_OPCODE(i, "OP_TEST") + luaP:SETARG_A(i, luaP:GETARG_B(i)) + luaP:SETARG_B(i, 0) + luaP:SETARG_C(i, luaP:GETARG_C(i)) + end + return true +end + +--FF added 5.1 +function luaK:removevalues (fs, list) + while list ~= self.NO_JUMP do + self:patchtestreg (fs, list, luaP.NO_REG) + list = self:getjump (fs, list) + end +end + +------------------------------------------------------------------------ +-- FF updated 5.1 +------------------------------------------------------------------------ +function luaK:patchlistaux(fs, list, vtarget, reg, dtarget) + while list ~= self.NO_JUMP do + local _next = self:getjump(fs, list) + if self:patchtestreg (fs, list, reg) then + self:fixjump(fs, list, vtarget) + else + self:fixjump (fs, list, dtarget) + end + list = _next + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:dischargejpc(fs) + self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc) + fs.jpc = self.NO_JUMP +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:patchlist(fs, list, target) + if target == fs.pc then + self:patchtohere(fs, list) + else + assert(target < fs.pc) + self:patchlistaux(fs, list, target, luaP.NO_REG, target) + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:patchtohere(fs, list) + self:getlabel(fs) + fs.jpc = self:concat(fs, fs.jpc, list) +end + +------------------------------------------------------------------------ +-- * l1 was a pointer, now l1 is returned and callee assigns the value +------------------------------------------------------------------------ +function luaK:concat(fs, l1, l2) + if l2 == self.NO_JUMP then return l1 -- unchanged + elseif l1 == self.NO_JUMP then + return l2 -- changed + else + local list = l1 + local _next = self:getjump(fs, list) + while _next ~= self.NO_JUMP do -- find last element + list = _next + _next = self:getjump(fs, list) + end + self:fixjump(fs, list, l2) + end + return l1 -- unchanged +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:checkstack(fs, n) + local newstack = fs.freereg + n + if newstack > fs.f.maxstacksize then + if newstack >= luaK.MAXSTACK then + error("function or expression too complex") + end + fs.f.maxstacksize = newstack + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:reserveregs(fs, n) + self:checkstack(fs, n) + fs.freereg = fs.freereg + n +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:freereg(fs, reg) + if not luaP:ISK (reg) and reg >= fs.nactvar then + fs.freereg = fs.freereg - 1 + assert(reg == fs.freereg, + string.format("reg=%i, fs.freereg=%i", reg, fs.freereg)) + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:freeexp(fs, e) + if e.k == "VNONRELOC" then + self:freereg(fs, e.info) + end +end + +------------------------------------------------------------------------ +-- k is a constant, v is... what? +-- fs.h is a hash value --> index in f.k +------------------------------------------------------------------------ +-- * luaH_get, luaH_set deleted; direct table access used instead +-- * luaO_rawequalObj deleted in first assert +-- * setobj2n deleted in assignment of v to f.k table +------------------------------------------------------------------------ +--FF radically updated, not completely understood +function luaK:addk(fs, k, v) + local idx = fs.h[k.value] + local f = fs.f +-- local oldsize = f.sizek + if self:ttisnumber (idx) then + --TODO this assert currently FAILS + --assert(fs.f.k[self:nvalue(idx)] == v) + return self:nvalue(idx) + else -- constant not found; create a new entry + do + local t = type (v.value) + assert(t=="nil" or t=="string" or t=="number" or t=="boolean") + end + --debugf("[const: k[%i] = %s ]", fs.nk, tostringv(v.value)) + fs.f.k[fs.nk] = v + fs.h[k.value] = { } + self:setnvalue(fs.h[k.value], fs.nk) + local nk = fs.nk + fs.nk = fs.nk+1 + return nk + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:stringK(fs, s) + assert (type(s)=="string") + local o = {} -- TObject + self:setsvalue(o, s) + return self:addk(fs, o, o) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:numberK(fs, r) + assert (type(r)=="number") + local o = {} -- TObject + self:setnvalue(o, r) + return self:addk(fs, o, o) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:boolK(fs, r) + assert (type(r)=="boolean") + local o = {} -- TObject + self:setnvalue(o, r) + return self:addk(fs, o, o) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:nilK(fs) + local k, v = {}, {} -- TObject + self:setnilvalue(v) + self:sethvalue(k, fs.h) -- cannot use nil as key; instead use table itself + return self:addk(fs, k, v) +end + + +--FF 5.1 +function luaK:setreturns (fs, e, nresults) + if e.k == "VCALL" then -- expression is an open function call? + luaP:SETARG_C(self:getcode(fs, e), nresults + 1) + elseif e.k == "VVARARG" then + luaP:SETARG_B (self:getcode (fs, e), nresults + 1) + luaP:SETARG_A (self:getcode (fs, e), fs.freereg) + self:reserveregs (fs, 1) + end +end + +--FF 5.1 +function luaK:setmultret (fs, e) + self:setreturns (fs, e, self.LUA_MULTRET) +end + +--FF 5.1 +function luaK:setoneret (fs, e) + if e.k == "VCALL" then -- expression is an open function call? + e.k = "VNONRELOC" + e.info = luaP:GETARG_A(self:getcode(fs, e)) + elseif e.k == "VVARARG" then + luaP:SETARG_B (self:getcode (fs, e), 2) + e.k = "VRELOCABLE" + end +end + + +------------------------------------------------------------------------ +--FF deprecated in 5.1 +------------------------------------------------------------------------ +function luaK:setcallreturns(fs, e, nresults) + assert (false, "setcallreturns deprecated") + --print "SCR:" + --printv(e) + --printv(self:getcode(fs, e)) + if e.k == "VCALL" then -- expression is an open function call? + luaP:SETARG_C(self:getcode(fs, e), nresults + 1) + if nresults == 1 then -- 'regular' expression? + e.k = "VNONRELOC" + e.info = luaP:GETARG_A(self:getcode(fs, e)) + end + elseif e.k == "VVARARG" then + --printf("Handle vararg return on expr %s, whose code is %s", + -- tostringv(e), tostringv(self:getcode(fs, e))) + if nresults == 1 then + luaP:SETARG_B (self:getcode (fs, e), 2) + e.k = "VRELOCABLE" +--FIXME: why no SETARG_A??? + else + luaP:SETARG_B (self:getcode (fs, e), nresults + 1) + luaP:SETARG_A (self:getcode (fs, e), fs.freereg) + self:reserveregs (fs, 1) + --printf("Now code is %s", tostringv(self:getcode(fs, e))) + end + end +end + +------------------------------------------------------------------------ +-- Ajoute le code pour effectuer l'extraction de la locvar/upval/globvar +-- /idx, sachant +------------------------------------------------------------------------ +function luaK:dischargevars(fs, e) +--printf("\ndischargevars\n") + local k = e.k + if k == "VLOCAL" then + e.k = "VNONRELOC" + elseif k == "VUPVAL" then + e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0) + e.k = "VRELOCABLE" + elseif k == "VGLOBAL" then + e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info) + e.k = "VRELOCABLE" + elseif k == "VINDEXED" then + self:freereg(fs, e.aux) + self:freereg(fs, e.info) + e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux) + e.k = "VRELOCABLE" + elseif k == "VCALL" or k == "VVARARG" then + self:setoneret(fs, e) + else + -- there is one value available (somewhere) + end +--printf("\n/dischargevars\n") +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:code_label(fs, A, b, jump) + self:getlabel(fs) -- those instructions may be jump targets + return self:codeABC(fs, "OP_LOADBOOL", A, b, jump) +end + +------------------------------------------------------------------------ +-- FF updated 5.1 +------------------------------------------------------------------------ +function luaK:discharge2reg(fs, e, reg) + self:dischargevars(fs, e) + local k = e.k + if k == "VNIL" then + self:_nil(fs, reg, 1) + elseif k == "VFALSE" or k == "VTRUE" then + self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0) + elseif k == "VKNUM" then + self:codeABx (fs, "OP_LOADK", reg, self:numberK(fs, e.nval)) + elseif k == "VK" then + self:codeABx(fs, "OP_LOADK", reg, e.info) + elseif k == "VRELOCABLE" then + local pc = self:getcode(fs, e) + luaP:SETARG_A(pc, reg) + elseif k == "VNONRELOC" then + if reg ~= e.info then + self:codeABC(fs, "OP_MOVE", reg, e.info, 0) + end + else + assert(e.k == "VVOID" or e.k == "VJMP") + return -- nothing to do... + end + e.info = reg + e.k = "VNONRELOC" +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:discharge2anyreg(fs, e) + if e.k ~= "VNONRELOC" then + self:reserveregs(fs, 1) + self:discharge2reg(fs, e, fs.freereg - 1) + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:exp2reg(fs, e, reg) + self:discharge2reg(fs, e, reg) + if e.k == "VJMP" then + e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list + end + if self:hasjumps(e) then + local final -- position after whole expression + local p_f = self.NO_JUMP -- position of an eventual LOAD false + local p_t = self.NO_JUMP -- position of an eventual LOAD true + if self:need_value(fs, e.t, 1) or self:need_value(fs, e.f, 0) then + local fj = self.NO_JUMP -- first jump (over LOAD ops.) + if e.k ~= "VJMP" then fj = self:jump(fs) end + p_f = self:code_label(fs, reg, 0, 1) + p_t = self:code_label(fs, reg, 1, 0) + self:patchtohere(fs, fj) + end + final = self:getlabel(fs) + self:patchlistaux(fs, e.f, final, reg, p_f) + self:patchlistaux(fs, e.t, final, reg, p_t) + end + e.f, e.t = self.NO_JUMP, self.NO_JUMP + e.info = reg + e.k = "VNONRELOC" +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:exp2nextreg(fs, e) + self:dischargevars(fs, e) + --[FF] Allready in place (added for expr.Stat) + if e.k == "VNONRELOC" and e.info == fs.freereg then + --printf("Expression already in next reg %i: %s", fs.freereg, tostringv(e)) + return end + self:freeexp(fs, e) + self:reserveregs(fs, 1) + self:exp2reg(fs, e, fs.freereg - 1) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:exp2anyreg(fs, e) + --printf("exp2anyregs(e=%s)", tostringv(e)) + self:dischargevars(fs, e) + if e.k == "VNONRELOC" then + if not self:hasjumps(e) then -- exp is already in a register + return e.info + end + if e.info >= fs.nactvar then -- reg. is not a local? + self:exp2reg(fs, e, e.info) -- put value on it + return e.info + end + end + self:exp2nextreg(fs, e) -- default + return e.info +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:exp2val(fs, e) + if self:hasjumps(e) then + self:exp2anyreg(fs, e) + else + self:dischargevars(fs, e) + end +end + +------------------------------------------------------------------------ +-- FF updated 5.1 +------------------------------------------------------------------------ +function luaK:exp2RK(fs, e) + self:exp2val(fs, e) + local k = e.k + if k=="VNIL" or k=="VTRUE" or k=="VFALSE" or k=="VKNUM" then + if fs.nk <= luaP.MAXINDEXRK then + if k=="VNIL" then e.info = self:nilK(fs) + elseif k=="VKNUM" then e.info = self:numberK (fs, e.nval) + else e.info = self:boolK(fs, e.k=="VTRUE") end + e.k = "VK" + return luaP:RKASK(e.info) + end + elseif k == "VK" then + if e.info <= luaP.MAXINDEXRK then -- constant fit in argC? + return luaP:RKASK (e.info) + end + end + -- not a constant in the right range: put it in a register + return self:exp2anyreg(fs, e) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:storevar(fs, var, exp) + --print("STOREVAR") + --printf("var=%s", tostringv(var)) + --printf("exp=%s", tostringv(exp)) + + local k = var.k + if k == "VLOCAL" then + self:freeexp(fs, exp) + self:exp2reg(fs, exp, var.info) + return + elseif k == "VUPVAL" then + local e = self:exp2anyreg(fs, exp) + self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0) + elseif k == "VGLOBAL" then + --printf("store global, exp=%s", tostringv(exp)) + local e = self:exp2anyreg(fs, exp) + self:codeABx(fs, "OP_SETGLOBAL", e, var.info) + elseif k == "VINDEXED" then + local e = self:exp2RK(fs, exp) + self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e) + else + assert(0) -- invalid var kind to store + end + self:freeexp(fs, exp) + --print("/STOREVAR") +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:_self(fs, e, key) + self:exp2anyreg(fs, e) + self:freeexp(fs, e) + local func = fs.freereg + self:reserveregs(fs, 2) + self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key)) + self:freeexp(fs, key) + e.info = func + e.k = "VNONRELOC" +end + +------------------------------------------------------------------------ +-- FF updated 5.1 +------------------------------------------------------------------------ +function luaK:invertjump(fs, e) + --printf("invertjump on jump instruction #%i", e.info) + --printv(self:getcode(fs, e)) + local pc = self:getjumpcontrol(fs, e.info) + assert(luaP:testOpMode(luaP:GET_OPCODE(pc), "OpModeT") and + luaP:GET_OPCODE(pc) ~= "OP_TESTSET" and + luaP:GET_OPCODE(pc) ~= "OP_TEST") + --printf("Before invert:") + --printv(pc) + luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0) + --printf("After invert:") + --printv(pc) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:jumponcond(fs, e, cond) + if e.k == "VRELOCABLE" then + local ie = self:getcode(fs, e) + if luaP:GET_OPCODE(ie) == "OP_NOT" then + fs.pc = fs.pc - 1 -- remove previous OP_NOT + return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), 0, + cond and 0 or 1) + end + -- else go through + end + self:discharge2anyreg(fs, e) + self:freeexp(fs, e) + return self:condjump(fs, "OP_TESTSET", luaP.NO_REG, e.info, cond and 1 or 0) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:goiftrue(fs, e) + local pc -- pc of last jump + self:dischargevars(fs, e) + local k = e.k + if k == "VK" or k == "VTRUE" or k == "VKNUM" then + pc = self.NO_JUMP -- always true; do nothing + elseif k == "VFALSE" then + pc = self:jump(fs) -- always jump + elseif k == "VJMP" then + self:invertjump(fs, e) + pc = e.info + else + pc = self:jumponcond(fs, e, false) + end + e.f = self:concat(fs, e.f, pc) -- insert last jump in 'f' list + self:patchtohere(fs, e.t) + e.t = self.NO_JUMP +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:goiffalse(fs, e) + local pc -- pc of last jump + self:dischargevars(fs, e) + local k = e.k + if k == "VNIL" or k == "VFALSE"then + pc = self.NO_JUMP -- always false; do nothing + elseif k == "VTRUE" then + pc = self:jump(fs) -- always jump + elseif k == "VJMP" then + pc = e.info + else + pc = self:jumponcond(fs, e, true) + end + e.t = self:concat(fs, e.t, pc) -- insert last jump in 't' list + self:patchtohere(fs, e.f) + e.f = self.NO_JUMP +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:codenot(fs, e) + self:dischargevars(fs, e) + local k = e.k + if k == "VNIL" or k == "VFALSE" then + e.k = "VTRUE" + elseif k == "VK" or k == "VKNUM" or k == "VTRUE" then + e.k = "VFALSE" + elseif k == "VJMP" then + self:invertjump(fs, e) + elseif k == "VRELOCABLE" or k == "VNONRELOC" then + self:discharge2anyreg(fs, e) + self:freeexp(fs, e) + e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0) + e.k = "VRELOCABLE" + else + assert(0) -- cannot happen + end + -- interchange true and false lists + e.f, e.t = e.t, e.f + self:removevalues(fs, e.f) + self:removevalues(fs, e.t) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:indexed(fs, t, k) + t.aux = self:exp2RK(fs, k) + t.k = "VINDEXED" +end + +--FF 5.1 +function luaK:constfolding (op, e1, e2) + if not self:isnumeral(e1) or not self:isnumeral(e2) then return false end + local v1, v2, e, r = e1.nval, e2 and e2.nval, nil + if op == "OP_ADD" then r = v1+v2 + elseif op == "OP_SUB" then r = v1-v2 + elseif op == "OP_MUL" then r = v1*v2 + elseif op == "OP_DIV" then if v2==0 then return false end r = v1/v2 + elseif op == "OP_MOD" then if v2==0 then return false end r = v1%v2 + elseif op == "OP_POW" then r = v1^v2 + elseif op == "OP_UNM" then r = -v1 + elseif op == "OP_LEN" then return false + else assert (false, "Unknown numeric value") end + e1.nval = r + return true +end + +--FF 5.1 +function luaK:codearith (fs, op, e1, e2) + if self:constfolding (op, e1, e2) then return else + local o1 = self:exp2RK (fs, e1) + local o2 = 0 + if op ~= "OP_UNM" and op ~= "OP_LEN" then + o2 = self:exp2RK (fs, e2) end + self:freeexp(fs, e2) + self:freeexp(fs, e1) + e1.info = self:codeABC (fs, op, 0, o1, o2) + e1.k = "VRELOCABLE" + end +end + +--FF 5.1 +function luaK:codecomp (fs, op, cond, e1, e2) + assert (type (cond) == "boolean") + local o1 = self:exp2RK (fs, e1) + local o2 = self:exp2RK (fs, e2) + self:freeexp (fs, e2) + self:freeexp (fs, e1) + if not cond and op ~= "OP_EQ" then + local temp = o1; o1=o2; o2=temp cond = true end + e1.info = self:condjump (fs, op, cond and 1 or 0, o1, o2) + e1.k = "VJMP" +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:prefix (fs, op, e) + local e2 = { t = self.NO_JUMP; f = self.NO_JUMP; + k = "VKNUM"; nval = 0 } + if op == "unm" then + if e.k == "VK" then + self:exp2anyreg (fs, e) end + self:codearith (fs, "OP_UNM", e, e2) + elseif op == "not" then + self:codenot (fs, e) + elseif op == "len" then + self:exp2anyreg (fs, e) + self:codearith (fs, "OP_LEN", e, e2) + else + assert (false, "Unknown unary operator") + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:infix (fs, op, v) + if op == "and" then + self:goiftrue(fs, v) + elseif op == "or" then + self:goiffalse(fs, v) + elseif op == "concat" then + self:exp2nextreg(fs, v) -- operand must be on the 'stack' + else + if not self:isnumeral (v) then self:exp2RK(fs, v) end + end +end + +------------------------------------------------------------------------ +-- +-- grep "ORDER OPR" if you change these enums +------------------------------------------------------------------------ +luaK.arith_opc = { -- done as a table lookup instead of a calc + add = "OP_ADD", + sub = "OP_SUB", + mul = "OP_MUL", + mod = "OP_MOD", + div = "OP_DIV", + pow = "OP_POW", + len = "OP_LEN", + ["not"] = "OP_NOT" +} +luaK.test_opc = { -- was ops[] in the codebinop function + eq = {opc="OP_EQ", cond=true}, + lt = {opc="OP_LT", cond=true}, + le = {opc="OP_LE", cond=true}, + + -- Pseudo-ops, with no metatable equivalent: + ne = {opc="OP_EQ", cond=false}, + gt = {opc="OP_LT", cond=false}, + ge = {opc="OP_LE", cond=false} +} + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:posfix(fs, op, e1, e2) + if op == "and" then + assert(e1.t == self.NO_JUMP) -- list must be closed + self:dischargevars(fs, e2) + e2.f = self:concat(fs, e2.f, e1.f) + for k,v in pairs(e2) do e1[k]=v end -- *e1 = *e2 + elseif op == "or" then + assert(e1.f == self.NO_JUMP) -- list must be closed + self:dischargevars(fs, e2) + e2.t = self:concat(fs, e2.t, e1.t) + for k,v in pairs(e2) do e1[k]=v end -- *e1 = *e2 + elseif op == "concat" then + self:exp2val(fs, e2) + if e2.k == "VRELOCABLE" + and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then + assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1) + self:freeexp(fs, e1) + luaP:SETARG_B(self:getcode(fs, e2), e1.info) + e1.k = "VRELOCABLE"; e1.info = e2.info + else + self:exp2nextreg(fs, e2) + self:codearith (fs, "OP_CONCAT", e1, e2) + end + else + local opc = self.arith_opc[op] + if opc then self:codearith (fs, opc, e1, e2) else + opc = self.test_opc[op] or error ("Unknown operator "..op) + self:codecomp (fs, opc.opc, opc.cond, e1, e2) + end + end +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:fixline(fs, line) + --assert (line) + if not line then + --print(debug.traceback "fixline (line == nil)") + end + fs.f.lineinfo[fs.pc - 1] = line or 0 +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:code(fs, i, line) + if not line then + line = 0 + --print(debug.traceback "line == nil") + end + local f = fs.f + + do -- print it + local params = { } + for _,x in ipairs{"A","B","Bx", "sBx", "C"} do + if i[x] then table.insert (params, string.format ("%s=%i", x, i[x])) end + end + debugf ("[code:\t%s\t%s]", luaP.opnames[i.OP], table.concat (params, ", ")) + end + + self:dischargejpc(fs) -- 'pc' will change + + f.code[fs.pc] = i + f.lineinfo[fs.pc] = line + + if line == 0 then + f.lineinfo[fs.pc] = fs.lastline + if fs.lastline == 0 then + --print(debug.traceback()) + end + end + + if f.lineinfo[fs.pc] == 0 then + f.lineinfo[fs.pc] = 42 + end + + local pc = fs.pc + fs.pc = fs.pc + 1 + return pc +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:codeABC(fs, o, a, b, c) + assert(luaP:getOpMode(o) == "iABC", o.." is not an ABC operation") + --assert getbmode(o) ~= opargn or b == 0 + --assert getcmode(o) ~= opargn or c == 0 + --FF + --return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline) + return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.lastline) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:codeABx(fs, o, a, bc) + assert(luaP:getOpMode(o) == "iABx" or luaP:getOpMode(o) == "iAsBx") + --assert getcmode(o) == opargn + --FF + --return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline) + return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.lastline) +end + +------------------------------------------------------------------------ +-- +------------------------------------------------------------------------ +function luaK:setlist (fs, base, nelems, tostore) + local c = math.floor ((nelems-1) / luaP.LFIELDS_PER_FLUSH + 1) + local b = tostore == self.LUA_MULTRET and 0 or tostore + assert (tostore ~= 0) + if c <= luaP.MAXARG_C then self:codeABC (fs, "OP_SETLIST", base, b, c) + else + self:codeABC (fs, "OP_SETLIST", base, b, 0) + self:code (fs, c, fs.lastline)--FIXME + end + fs.freereg = base + 1 +end + +return luaK \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/ldump.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/ldump.lua new file mode 100644 index 000000000..6ac76179f --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/ldump.lua @@ -0,0 +1,448 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2005-2013 Kein-Hong Man, Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Kein-Hong Man - Initial implementation for Lua 5.0, part of Yueliang +-- Fabien Fleutot - Port to Lua 5.1, integration with Metalua +-- +------------------------------------------------------------------------------- + +--[[-------------------------------------------------------------------- + + ldump.lua + Save bytecodes in Lua + This file is part of Yueliang. + + Copyright (c) 2005 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + +------------------------------------------------------------------------ + + [FF] Slightly modified, mainly to produce Lua 5.1 bytecode. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * LUA_NUMBER (double), byte order (little endian) and some other +-- header values hard-coded; see other notes below... +-- * One significant difference is that instructions are still in table +-- form (with OP/A/B/C/Bx fields) and luaP:Instruction() is needed to +-- convert them into 4-char strings +-- * Deleted: +-- luaU:DumpVector: folded into DumpLines, DumpCode +-- * Added: +-- luaU:endianness() (from lundump.c) +-- luaU:make_setS: create a chunk writer that writes to a string +-- luaU:make_setF: create a chunk writer that writes to a file +-- (lua.h contains a typedef for a Chunkwriter pointer, and +-- a Lua-based implementation exists, writer() in lstrlib.c) +-- luaU:from_double(x): encode double value for writing +-- luaU:from_int(x): encode integer value for writing +-- (error checking is limited for these conversion functions) +-- (double conversion does not support denormals or NaNs) +-- luaU:ttype(o) (from lobject.h) +----------------------------------------------------------------------]] + +local luaP = require 'metalua.compiler.bytecode.lopcodes' + +local M = { } + +local format = { } +format.header = string.dump(function()end):sub(1, 12) +format.little_endian, format.int_size, +format.size_t_size, format.instr_size, +format.number_size, format.integral = format.header:byte(7, 12) +format.little_endian = format.little_endian~=0 +format.integral = format.integral ~=0 + +assert(format.integral or format.number_size==8, "Number format not supported by dumper") +assert(format.little_endian, "Big endian architectures not supported by dumper") + +--requires luaP +local luaU = { } +M.luaU = luaU + +luaU.format = format + +-- constants used by dumper +luaU.LUA_TNIL = 0 +luaU.LUA_TBOOLEAN = 1 +luaU.LUA_TNUMBER = 3 -- (all in lua.h) +luaU.LUA_TSTRING = 4 +luaU.LUA_TNONE = -1 + +-- definitions for headers of binary files +--luaU.LUA_SIGNATURE = "\27Lua" -- binary files start with "Lua" +--luaU.VERSION = 81 -- 0x50; last format change was in 5.0 +--luaU.FORMAT_VERSION = 0 -- 0 is official version. yeah I know I'm a liar. + +-- a multiple of PI for testing native format +-- multiplying by 1E7 gives non-trivial integer values +--luaU.TEST_NUMBER = 3.14159265358979323846E7 + +--[[-------------------------------------------------------------------- +-- Additional functions to handle chunk writing +-- * to use make_setS and make_setF, see test_ldump.lua elsewhere +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- works like the lobject.h version except that TObject used in these +-- scripts only has a 'value' field, no 'tt' field (native types used) +------------------------------------------------------------------------ +function luaU:ttype(o) + local tt = type(o.value) + if tt == "number" then return self.LUA_TNUMBER + elseif tt == "string" then return self.LUA_TSTRING + elseif tt == "nil" then return self.LUA_TNIL + elseif tt == "boolean" then return self.LUA_TBOOLEAN + else + return self.LUA_TNONE -- the rest should not appear + end +end + +------------------------------------------------------------------------ +-- create a chunk writer that writes to a string +-- * returns the writer function and a table containing the string +-- * to get the final result, look in buff.data +------------------------------------------------------------------------ +function luaU:make_setS() + local buff = {} + buff.data = "" + local writer = + function(s, buff) -- chunk writer + if not s then return end + buff.data = buff.data..s + end + return writer, buff +end + +------------------------------------------------------------------------ +-- create a chunk writer that writes to a file +-- * returns the writer function and a table containing the file handle +-- * if a nil is passed, then writer should close the open file +------------------------------------------------------------------------ +function luaU:make_setF(filename) + local buff = {} + buff.h = io.open(filename, "wb") + if not buff.h then return nil end + local writer = + function(s, buff) -- chunk writer + if not buff.h then return end + if not s then buff.h:close(); return end + buff.h:write(s) + end + return writer, buff +end + +----------------------------------------------------------------------- +-- converts a IEEE754 double number to an 8-byte little-endian string +-- * luaU:from_double() and luaU:from_int() are from ChunkBake project +-- * supports +/- Infinity, but not denormals or NaNs +----------------------------------------------------------------------- +function luaU:from_double(x) + local function grab_byte(v) + return math.floor(v / 256), + string.char(math.mod(math.floor(v), 256)) + end + local sign = 0 + if x < 0 then sign = 1; x = -x end + local mantissa, exponent = math.frexp(x) + if x == 0 then -- zero + mantissa, exponent = 0, 0 + elseif x == 1/0 then + mantissa, exponent = 0, 2047 + else + mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, 53) + exponent = exponent + 1022 + end + local v, byte = "" -- convert to bytes + x = mantissa + for i = 1,6 do + x, byte = grab_byte(x); v = v..byte -- 47:0 + end + x, byte = grab_byte(exponent * 16 + x); v = v..byte -- 55:48 + x, byte = grab_byte(sign * 128 + x); v = v..byte -- 63:56 + return v +end + +----------------------------------------------------------------------- +-- converts a number to a little-endian 32-bit integer string +-- * input value assumed to not overflow, can be signed/unsigned +----------------------------------------------------------------------- +function luaU:from_int(x, size) + local v = "" + x = math.floor(x) + if x >= 0 then + for i = 1, size do + v = v..string.char(math.mod(x, 256)); x = math.floor(x / 256) + end + else -- x < 0 + x = -x + local carry = 1 + for i = 1, size do + local c = 255 - math.mod(x, 256) + carry + if c == 256 then c = 0; carry = 1 else carry = 0 end + v = v..string.char(c); x = math.floor(x / 256) + end + end + return v +end + +--[[-------------------------------------------------------------------- +-- Functions to make a binary chunk +-- * many functions have the size parameter removed, since output is +-- in the form of a string and some sizes are implicit or hard-coded +-- * luaU:DumpVector has been deleted (used in DumpCode & DumpLines) +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- dump a block of literal bytes +------------------------------------------------------------------------ +function luaU:DumpLiteral(s, D) self:DumpBlock(s, D) end + +--[[-------------------------------------------------------------------- +-- struct DumpState: +-- L -- lua_State (not used in this script) +-- write -- lua_Chunkwriter (chunk writer function) +-- data -- void* (chunk writer context or data already written) +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- dumps a block of bytes +-- * lua_unlock(D.L), lua_lock(D.L) deleted +------------------------------------------------------------------------ +function luaU:DumpBlock(b, D) D.write(b, D.data) end + +------------------------------------------------------------------------ +-- dumps a single byte +------------------------------------------------------------------------ +function luaU:DumpByte(y, D) + self:DumpBlock(string.char(y), D) +end + +------------------------------------------------------------------------ +-- dumps a signed integer of size `format.int_size` (for int) +------------------------------------------------------------------------ +function luaU:DumpInt(x, D) + self:DumpBlock(self:from_int(x, format.int_size), D) +end + +------------------------------------------------------------------------ +-- dumps an unsigned integer of size `format.size_t_size` (for size_t) +------------------------------------------------------------------------ +function luaU:DumpSize(x, D) + self:DumpBlock(self:from_int(x, format.size_t_size), D) +end + +------------------------------------------------------------------------ +-- dumps a LUA_NUMBER; can be an int or double depending on the VM. +------------------------------------------------------------------------ +function luaU:DumpNumber(x, D) + if format.integral then + self:DumpBlock(self:from_int(x, format.number_size), D) + else + self:DumpBlock(self:from_double(x), D) + end +end + +------------------------------------------------------------------------ +-- dumps a Lua string +------------------------------------------------------------------------ +function luaU:DumpString(s, D) + if s == nil then + self:DumpSize(0, D) + else + s = s.."\0" -- include trailing '\0' + self:DumpSize(string.len(s), D) + self:DumpBlock(s, D) + end +end + +------------------------------------------------------------------------ +-- dumps instruction block from function prototype +------------------------------------------------------------------------ +function luaU:DumpCode(f, D) + local n = f.sizecode + self:DumpInt(n, D) + --was DumpVector + for i = 0, n - 1 do + self:DumpBlock(luaP:Instruction(f.code[i]), D) + end +end + +------------------------------------------------------------------------ +-- dumps local variable names from function prototype +------------------------------------------------------------------------ +function luaU:DumpLocals(f, D) + local n = f.sizelocvars + self:DumpInt(n, D) + for i = 0, n - 1 do + -- Dirty temporary fix: + -- `Stat{ } keeps properly count of the number of local vars, + -- but fails to keep score of their debug info (names). + -- It therefore might happen that #f.localvars < f.sizelocvars, or + -- that a variable's startpc and endpc fields are left unset. + -- FIXME: This might not be needed anymore, check the bug report + -- by J. Belmonte. + local var = f.locvars[i] + if not var then break end + -- printf("[DUMPLOCALS] dumping local var #%i = %s", i, table.tostring(var)) + self:DumpString(var.varname, D) + self:DumpInt(var.startpc or 0, D) + self:DumpInt(var.endpc or 0, D) + end +end + +------------------------------------------------------------------------ +-- dumps line information from function prototype +------------------------------------------------------------------------ +function luaU:DumpLines(f, D) + local n = f.sizelineinfo + self:DumpInt(n, D) + --was DumpVector + for i = 0, n - 1 do + self:DumpInt(f.lineinfo[i], D) -- was DumpBlock + --print(i, f.lineinfo[i]) + end +end + +------------------------------------------------------------------------ +-- dump upvalue names from function prototype +------------------------------------------------------------------------ +function luaU:DumpUpvalues(f, D) + local n = f.sizeupvalues + self:DumpInt(n, D) + for i = 0, n - 1 do + self:DumpString(f.upvalues[i], D) + end +end + +------------------------------------------------------------------------ +-- dump constant pool from function prototype +-- * nvalue(o) and tsvalue(o) macros removed +------------------------------------------------------------------------ +function luaU:DumpConstants(f, D) + local n = f.sizek + self:DumpInt(n, D) + for i = 0, n - 1 do + local o = f.k[i] -- TObject + local tt = self:ttype(o) + assert (tt >= 0) + self:DumpByte(tt, D) + if tt == self.LUA_TNUMBER then + self:DumpNumber(o.value, D) + elseif tt == self.LUA_TSTRING then + self:DumpString(o.value, D) + elseif tt == self.LUA_TBOOLEAN then + self:DumpByte (o.value and 1 or 0, D) + elseif tt == self.LUA_TNIL then + else + assert(false) -- cannot happen + end + end +end + + +function luaU:DumpProtos (f, D) + local n = f.sizep + assert (n) + self:DumpInt(n, D) + for i = 0, n - 1 do + self:DumpFunction(f.p[i], f.source, D) + end +end + +function luaU:DumpDebug(f, D) + self:DumpLines(f, D) + self:DumpLocals(f, D) + self:DumpUpvalues(f, D) +end + + +------------------------------------------------------------------------ +-- dump child function prototypes from function prototype +--FF completely reworked for 5.1 format +------------------------------------------------------------------------ +function luaU:DumpFunction(f, p, D) + -- print "Dumping function:" + -- table.print(f, 60) + + local source = f.source + if source == p then source = nil end + self:DumpString(source, D) + self:DumpInt(f.lineDefined, D) + self:DumpInt(f.lastLineDefined or 42, D) + self:DumpByte(f.nups, D) + self:DumpByte(f.numparams, D) + self:DumpByte(f.is_vararg, D) + self:DumpByte(f.maxstacksize, D) + self:DumpCode(f, D) + self:DumpConstants(f, D) + self:DumpProtos( f, D) + self:DumpDebug(f, D) +end + +------------------------------------------------------------------------ +-- dump Lua header section (some sizes hard-coded) +--FF: updated for version 5.1 +------------------------------------------------------------------------ +function luaU:DumpHeader(D) + self:DumpLiteral(format.header, D) +end + +------------------------------------------------------------------------ +-- dump function as precompiled chunk +-- * w, data are created from make_setS, make_setF +--FF: suppressed extraneous [L] param +------------------------------------------------------------------------ +function luaU:dump (Main, w, data) + local D = {} -- DumpState + D.write = w + D.data = data + self:DumpHeader(D) + self:DumpFunction(Main, nil, D) + -- added: for a chunk writer writing to a file, this final call with + -- nil data is to indicate to the writer to close the file + D.write(nil, D.data) +end + +------------------------------------------------------------------------ +-- find byte order (from lundump.c) +-- * hard-coded to little-endian +------------------------------------------------------------------------ +function luaU:endianness() + return 1 +end + +-- FIXME: ugly concat-base generation in [make_setS], bufferize properly! +function M.dump_string (proto) + local writer, buff = luaU:make_setS() + luaU:dump (proto, writer, buff) + return buff.data +end + +-- FIXME: [make_setS] sucks, perform synchronous file writing +-- Now unused +function M.dump_file (proto, filename) + local writer, buff = luaU:make_setS() + luaU:dump (proto, writer, buff) + local file = io.open (filename, "wb") + file:write (buff.data) + io.close(file) + --if UNIX_SHARPBANG then os.execute ("chmod a+x "..filename) end +end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/lopcodes.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/lopcodes.lua new file mode 100644 index 000000000..e49285e6f --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/bytecode/lopcodes.lua @@ -0,0 +1,442 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2005-2013 Kein-Hong Man, Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Kein-Hong Man - Initial implementation for Lua 5.0, part of Yueliang +-- Fabien Fleutot - Port to Lua 5.1, integration with Metalua +-- +------------------------------------------------------------------------------- + +--[[-------------------------------------------------------------------- + + $Id$ + + lopcodes.lua + Lua 5 virtual machine opcodes in Lua + This file is part of Yueliang. + + Copyright (c) 2005 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +------------------------------------------------------------------------ + + [FF] Slightly modified, mainly to produce Lua 5.1 bytecode. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * an Instruction is a table with OP, A, B, C, Bx elements; this +-- should allow instruction handling to work with doubles and ints +-- * Added: +-- luaP:Instruction(i): convert field elements to a 4-char string +-- luaP:DecodeInst(x): convert 4-char string into field elements +-- * WARNING luaP:Instruction outputs instructions encoded in little- +-- endian form and field size and positions are hard-coded +----------------------------------------------------------------------]] + +local function debugf() end + +local luaP = { } + +--[[ +=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + 'A' : 8 bits + 'B' : 9 bits + 'C' : 9 bits + 'Bx' : 18 bits ('B' and 'C' together) + 'sBx' : signed Bx + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. +=========================================================================== +--]] + +luaP.OpMode = {"iABC", "iABx", "iAsBx"} -- basic instruction format + +------------------------------------------------------------------------ +-- size and position of opcode arguments. +-- * WARNING size and position is hard-coded elsewhere in this script +------------------------------------------------------------------------ +luaP.SIZE_C = 9 +luaP.SIZE_B = 9 +luaP.SIZE_Bx = luaP.SIZE_C + luaP.SIZE_B +luaP.SIZE_A = 8 + +luaP.SIZE_OP = 6 + +luaP.POS_C = luaP.SIZE_OP +luaP.POS_B = luaP.POS_C + luaP.SIZE_C +luaP.POS_Bx = luaP.POS_C +luaP.POS_A = luaP.POS_B + luaP.SIZE_B + +--FF from 5.1 +luaP.BITRK = 2^(luaP.SIZE_B - 1) +function luaP:ISK(x) return x >= self.BITRK end +luaP.MAXINDEXRK = luaP.BITRK - 1 +function luaP:RKASK(x) + if x < self.BITRK then return x+self.BITRK else return x end +end + + + +------------------------------------------------------------------------ +-- limits for opcode arguments. +-- we use (signed) int to manipulate most arguments, +-- so they must fit in BITS_INT-1 bits (-1 for sign) +------------------------------------------------------------------------ +-- removed "#if SIZE_Bx < BITS_INT-1" test, assume this script is +-- running on a Lua VM with double or int as LUA_NUMBER + +luaP.MAXARG_Bx = math.ldexp(1, luaP.SIZE_Bx) - 1 +luaP.MAXARG_sBx = math.floor(luaP.MAXARG_Bx / 2) -- 'sBx' is signed + +luaP.MAXARG_A = math.ldexp(1, luaP.SIZE_A) - 1 +luaP.MAXARG_B = math.ldexp(1, luaP.SIZE_B) - 1 +luaP.MAXARG_C = math.ldexp(1, luaP.SIZE_C) - 1 + +-- creates a mask with 'n' 1 bits at position 'p' +-- MASK1(n,p) deleted +-- creates a mask with 'n' 0 bits at position 'p' +-- MASK0(n,p) deleted + +--[[-------------------------------------------------------------------- + Visual representation for reference: + + 31 | | | 0 bit position + +-----+-----+-----+----------+ + | B | C | A | Opcode | iABC format + +-----+-----+-----+----------+ + - 9 - 9 - 8 - 6 - field sizes + +-----+-----+-----+----------+ + | [s]Bx | A | Opcode | iABx | iAsBx format + +-----+-----+-----+----------+ +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- the following macros help to manipulate instructions +-- * changed to a table object representation, very clean compared to +-- the [nightmare] alternatives of using a number or a string +------------------------------------------------------------------------ + +-- these accept or return opcodes in the form of string names +function luaP:GET_OPCODE(i) return self.ROpCode[i.OP] end +function luaP:SET_OPCODE(i, o) i.OP = self.OpCode[o] end + +function luaP:GETARG_A(i) return i.A end +function luaP:SETARG_A(i, u) i.A = u end + +function luaP:GETARG_B(i) return i.B end +function luaP:SETARG_B(i, b) i.B = b end + +function luaP:GETARG_C(i) return i.C end +function luaP:SETARG_C(i, b) i.C = b end + +function luaP:GETARG_Bx(i) return i.Bx end +function luaP:SETARG_Bx(i, b) i.Bx = b end + +function luaP:GETARG_sBx(i) return i.Bx - self.MAXARG_sBx end +function luaP:SETARG_sBx(i, b) i.Bx = b + self.MAXARG_sBx end + +function luaP:CREATE_ABC(o,a,b,c) + return {OP = self.OpCode[o], A = a, B = b, C = c} +end + +function luaP:CREATE_ABx(o,a,bc) + return {OP = self.OpCode[o], A = a, Bx = bc} +end + +------------------------------------------------------------------------ +-- Bit shuffling stuffs +------------------------------------------------------------------------ + +if false and pcall (require, 'bit') then + ------------------------------------------------------------------------ + -- Return a 4-char string little-endian encoded form of an instruction + ------------------------------------------------------------------------ + function luaP:Instruction(i) + --FIXME + end +else + ------------------------------------------------------------------------ + -- Version without bit manipulation library. + ------------------------------------------------------------------------ + local p2 = {1,2,4,8,16,32,64,128,256, 512, 1024, 2048, 4096} + -- keeps [n] bits from [x] + local function keep (x, n) return x % p2[n+1] end + -- shifts bits of [x] [n] places to the right + local function srb (x,n) return math.floor (x / p2[n+1]) end + -- shifts bits of [x] [n] places to the left + local function slb (x,n) return x * p2[n+1] end + + ------------------------------------------------------------------------ + -- Return a 4-char string little-endian encoded form of an instruction + ------------------------------------------------------------------------ + function luaP:Instruction(i) + -- printf("Instr->string: %s %s", self.opnames[i.OP], table.tostring(i)) + local c0, c1, c2, c3 + -- change to OP/A/B/C format if needed + if i.Bx then i.C = keep (i.Bx, 9); i.B = srb (i.Bx, 9) end + -- c0 = 6B from opcode + 2LSB from A (flushed to MSB) + c0 = i.OP + slb (keep (i.A, 2), 6) + -- c1 = 6MSB from A + 2LSB from C (flushed to MSB) + c1 = srb (i.A, 2) + slb (keep (i.C, 2), 6) + -- c2 = 7MSB from C + 1LSB from B (flushed to MSB) + c2 = srb (i.C, 2) + slb (keep (i.B, 1), 7) + -- c3 = 8MSB from B + c3 = srb (i.B, 1) + --printf ("Instruction: %s %s", self.opnames[i.OP], tostringv (i)) + --printf ("Bin encoding: %x %x %x %x", c0, c1, c2, c3) + return string.char(c0, c1, c2, c3) + end +end +------------------------------------------------------------------------ +-- decodes a 4-char little-endian string into an instruction struct +------------------------------------------------------------------------ +function luaP:DecodeInst(x) + error "Not implemented" +end + +------------------------------------------------------------------------ +-- invalid register that fits in 8 bits +------------------------------------------------------------------------ +luaP.NO_REG = luaP.MAXARG_A + +------------------------------------------------------------------------ +-- R(x) - register +-- Kst(x) - constant (in constant table) +-- RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK) +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- grep "ORDER OP" if you change these enums +------------------------------------------------------------------------ + +--[[-------------------------------------------------------------------- +Lua virtual machine opcodes (enum OpCode): +------------------------------------------------------------------------ +name args description +------------------------------------------------------------------------ +OP_MOVE A B R(A) := R(B) +OP_LOADK A Bx R(A) := Kst(Bx) +OP_LOADBOOL A B C R(A) := (Bool)B; if (C) PC++ +OP_LOADNIL A B R(A) := ... := R(B) := nil +OP_GETUPVAL A B R(A) := UpValue[B] +OP_GETGLOBAL A Bx R(A) := Gbl[Kst(Bx)] +OP_GETTABLE A B C R(A) := R(B)[RK(C)] +OP_SETGLOBAL A Bx Gbl[Kst(Bx)] := R(A) +OP_SETUPVAL A B UpValue[B] := R(A) +OP_SETTABLE A B C R(A)[RK(B)] := RK(C) +OP_NEWTABLE A B C R(A) := {} (size = B,C) +OP_SELF A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] +OP_ADD A B C R(A) := RK(B) + RK(C) +OP_SUB A B C R(A) := RK(B) - RK(C) +OP_MUL A B C R(A) := RK(B) * RK(C) +OP_DIV A B C R(A) := RK(B) / RK(C) +OP_POW A B C R(A) := RK(B) ^ RK(C) +OP_UNM A B R(A) := -R(B) +OP_NOT A B R(A) := not R(B) +OP_CONCAT A B C R(A) := R(B).. ... ..R(C) +OP_JMP sBx PC += sBx +OP_EQ A B C if ((RK(B) == RK(C)) ~= A) then pc++ +OP_LT A B C if ((RK(B) < RK(C)) ~= A) then pc++ +OP_LE A B C if ((RK(B) <= RK(C)) ~= A) then pc++ +OP_TEST A B C if (R(B) <=> C) then R(A) := R(B) else pc++ +OP_CALL A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) +OP_TAILCALL A B C return R(A)(R(A+1), ... ,R(A+B-1)) +OP_RETURN A B return R(A), ... ,R(A+B-2) (see note) +OP_FORLOOP A sBx R(A)+=R(A+2); if R(A) =) R(A) +OP_CLOSURE A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) +----------------------------------------------------------------------]] + +luaP.opnames = {} -- opcode names +luaP.OpCode = {} -- lookup name -> number +luaP.ROpCode = {} -- lookup number -> name + +local i = 0 +for v in string.gfind([[ +MOVE -- 0 +LOADK +LOADBOOL +LOADNIL +GETUPVAL +GETGLOBAL -- 5 +GETTABLE +SETGLOBAL +SETUPVAL +SETTABLE +NEWTABLE -- 10 +SELF +ADD +SUB +MUL +DIV -- 15 +MOD +POW +UNM +NOT +LEN -- 20 +CONCAT +JMP +EQ +LT +LE -- 25 +TEST +TESTSET +CALL +TAILCALL +RETURN -- 30 +FORLOOP +FORPREP +TFORLOOP +SETLIST +CLOSE -- 35 +CLOSURE +VARARG +]], "[%a]+") do + local n = "OP_"..v + luaP.opnames[i] = v + luaP.OpCode[n] = i + luaP.ROpCode[i] = n + i = i + 1 +end +luaP.NUM_OPCODES = i + +--[[ +=========================================================================== + Notes: + (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, + and can be 0: OP_CALL then sets 'top' to last_result+1, so + next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use 'top'. + + (2) In OP_RETURN, if (B == 0) then return up to 'top' + + (3) For comparisons, B specifies what conditions the test should accept. + + (4) All 'skips' (pc++) assume that next instruction is a jump + + (5) OP_SETLISTO is used when the last item in a table constructor is a + function, so the number of elements set is up to top of stack +=========================================================================== +--]] + +------------------------------------------------------------------------ +-- masks for instruction properties +------------------------------------------------------------------------ +-- was enum OpModeMask: +luaP.OpModeBreg = 2 -- B is a register +luaP.OpModeBrk = 3 -- B is a register/constant +luaP.OpModeCrk = 4 -- C is a register/constant +luaP.OpModesetA = 5 -- instruction set register A +luaP.OpModeK = 6 -- Bx is a constant +luaP.OpModeT = 1 -- operator is a test + +------------------------------------------------------------------------ +-- get opcode mode, e.g. "iABC" +------------------------------------------------------------------------ +function luaP:getOpMode(m) + --printv(m) + --printv(self.OpCode[m]) + --printv(self.opmodes [self.OpCode[m]+1]) + return self.OpMode[tonumber(string.sub(self.opmodes[self.OpCode[m] + 1], 7, 7))] +end + +------------------------------------------------------------------------ +-- test an instruction property flag +-- * b is a string, e.g. "OpModeBreg" +------------------------------------------------------------------------ +function luaP:testOpMode(m, b) + return (string.sub(self.opmodes[self.OpCode[m] + 1], self[b], self[b]) == "1") +end + +-- number of list items to accumulate before a SETLIST instruction +-- (must be a power of 2) +-- * used in lparser, lvm, ldebug, ltests +luaP.LFIELDS_PER_FLUSH = 50 --FF updated to match 5.1 + +-- luaP_opnames[] is set above, as the luaP.opnames table +-- opmode(t,b,bk,ck,sa,k,m) deleted + +--[[-------------------------------------------------------------------- + Legend for luaP:opmodes: + 1 T -> T (is a test?) + 2 B -> B is a register + 3 b -> B is an RK register/constant combination + 4 C -> C is an RK register/constant combination + 5 A -> register A is set by the opcode + 6 K -> Bx is a constant + 7 m -> 1 if iABC layout, + 2 if iABx layout, + 3 if iAsBx layout +----------------------------------------------------------------------]] + +luaP.opmodes = { +-- TBbCAKm opcode + "0100101", -- OP_MOVE 0 + "0000112", -- OP_LOADK + "0000101", -- OP_LOADBOOL + "0100101", -- OP_LOADNIL + "0000101", -- OP_GETUPVAL + "0000112", -- OP_GETGLOBAL 5 + "0101101", -- OP_GETTABLE + "0000012", -- OP_SETGLOBAL + "0000001", -- OP_SETUPVAL + "0011001", -- OP_SETTABLE + "0000101", -- OP_NEWTABLE 10 + "0101101", -- OP_SELF + "0011101", -- OP_ADD + "0011101", -- OP_SUB + "0011101", -- OP_MUL + "0011101", -- OP_DIV 15 + "0011101", -- OP_MOD + "0011101", -- OP_POW + "0100101", -- OP_UNM + "0100101", -- OP_NOT + "0100101", -- OP_LEN 20 + "0101101", -- OP_CONCAT + "0000003", -- OP_JMP + "1011001", -- OP_EQ + "1011001", -- OP_LT + "1011001", -- OP_LE 25 + "1000101", -- OP_TEST + "1100101", -- OP_TESTSET + "0000001", -- OP_CALL + "0000001", -- OP_TAILCALL + "0000001", -- OP_RETURN 30 + "0000003", -- OP_FORLOOP + "0000103", -- OP_FORPREP + "1000101", -- OP_TFORLOOP + "0000001", -- OP_SETLIST + "0000001", -- OP_CLOSE 35 + "0000102", -- OP_CLOSURE + "0000101" -- OP_VARARG +} + +return luaP \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/globals.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/globals.lua new file mode 100644 index 000000000..d5f7459e9 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/globals.lua @@ -0,0 +1,86 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +--*-lua-*----------------------------------------------------------------------- +-- Override Lua's default compilation functions, so that they support Metalua +-- rather than only plain Lua +-------------------------------------------------------------------------------- + +local mlc = require 'metalua.compiler' + +local M = { } + +-- Original versions +local original_lua_versions = { + load = load, + loadfile = loadfile, + loadstring = loadstring, + dofile = dofile } + +local lua_loadstring = loadstring +local lua_loadfile = loadfile + +function M.loadstring(str, name) + if type(str) ~= 'string' then error 'string expected' end + if str:match '^\027LuaQ' then return lua_loadstring(str) end + local n = str:match '^#![^\n]*\n()' + if n then str=str:sub(n, -1) end + -- FIXME: handle erroneous returns (return nil + error msg) + return mlc.new():src_to_function(str, name) +end + +function M.loadfile(filename) + local f, err_msg = io.open(filename, 'rb') + if not f then return nil, err_msg end + local success, src = pcall( f.read, f, '*a') + pcall(f.close, f) + if success then return M.loadstring (src, '@'..filename) + else return nil, src end +end + +function M.load(f, name) + local acc = { } + while true do + local x = f() + if not x then break end + assert(type(x)=='string', "function passed to load() must return strings") + table.insert(acc, x) + end + return M.loadstring(table.concat(acc)) +end + +function M.dostring(src) + local f, msg = M.loadstring(src) + if not f then error(msg) end + return f() +end + +function M.dofile(name) + local f, msg = M.loadfile(name) + if not f then error(msg) end + return f() +end + +-- Export replacement functions as globals +for name, f in pairs(M) do _G[name] = f end + +-- To be done *after* exportation +M.lua = original_lua_versions + +return M \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser.lua new file mode 100644 index 000000000..74997aef2 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser.lua @@ -0,0 +1,42 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +-- Export all public APIs from sub-modules, squashed into a flat spacename + +local MT = { __type='metalua.compiler.parser' } + +local MODULE_REL_NAMES = { "annot.grammar", "expr", "meta", "misc", + "stat", "table", "ext" } + +local function new() + local M = { + lexer = require "metalua.compiler.parser.lexer" (); + extensions = { } } + for _, rel_name in ipairs(MODULE_REL_NAMES) do + local abs_name = "metalua.compiler.parser."..rel_name + local extender = require (abs_name) + if not M.extensions[abs_name] then + if type (extender) == 'function' then extender(M) end + M.extensions[abs_name] = extender + end + end + return setmetatable(M, MT) +end + +return { new = new } diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/annot/generator.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/annot/generator.lua new file mode 100644 index 000000000..3a805ad42 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/annot/generator.lua @@ -0,0 +1,48 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +local checks = require 'checks' +local gg = require 'metalua.grammar.generator' +local M = { } + +function M.opt(mlc, primary, a_type) + checks('table', 'table|function', 'string') + return gg.sequence{ + primary, + gg.onkeyword{ "#", function() return assert(mlc.annot[a_type]) end }, + builder = function(x) + local t, annot = unpack(x) + return annot and { tag='Annot', t, annot } or t + end } +end + +-- split a list of "foo" and "`Annot{foo, annot}" into a list of "foo" +-- and a list of "annot". +-- No annot list is returned if none of the elements were annotated. +function M.split(lst) + local x, a, some = { }, { }, false + for i, p in ipairs(lst) do + if p.tag=='Annot' then + some, x[i], a[i] = true, unpack(p) + else x[i] = p end + end + if some then return x, a else return lst end +end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/annot/grammar.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/annot/grammar.lua new file mode 100644 index 000000000..7ce3ec41b --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/annot/grammar.lua @@ -0,0 +1,112 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +local gg = require 'metalua.grammar.generator' + +return function(M) + local _M = gg.future(M) + M.lexer :add '->' + local A = { } + local _A = gg.future(A) + M.annot = A + + -- Type identifier: Lua keywords such as `"nil"` allowed. + function M.annot.tid(lx) + local w = lx :next() + local t = w.tag + if t=='Keyword' and w[1] :match '^[%a_][%w_]*$' or w.tag=='Id' + then return {tag='TId'; lineinfo=w.lineinfo; w[1]} + else return gg.parse_error (lx, 'tid expected') end + end + + local field_types = { var='TVar'; const='TConst'; + currently='TCurrently'; field='TField' } + + -- TODO check lineinfo + function M.annot.tf(lx) + local tk = lx:next() + local w = tk[1] + local tag = field_types[w] + if not tag then error ('Invalid field type '..w) + elseif tag=='TField' then return {tag='TField'} else + local te = M.te(lx) + return {tag=tag; te} + end + end + + M.annot.tebar_content = gg.list{ + name = 'tebar content', + primary = _A.te, + separators = { ",", ";" }, + terminators = ")" } + + M.annot.tebar = gg.multisequence{ + name = 'annot.tebar', + --{ '*', builder = 'TDynbar' }, -- maybe not user-available + { '(', _A.tebar_content, ')', + builder = function(x) return x[1] end }, + { _A.te } + } + + M.annot.te = gg.multisequence{ + name = 'annot.te', + { _A.tid, builder=function(x) return x[1] end }, + { '*', builder = 'TDyn' }, + { "[", + gg.list{ + primary = gg.sequence{ + _M.expr, "=", _A.tf, + builder = 'TPair' + }, + separators = { ",", ";" }, + terminators = { "]", "|" } }, + gg.onkeyword{ "|", _A.tf }, + "]", + builder = function(x) + local fields, other = unpack(x) + return { tag='TTable', other or {tag='TField'}, fields } + end }, -- "[ ... ]" + { '(', _A.tebar_content, ')', '->', '(', _A.tebar_content, ')', + builder = function(x) + local p, r = unpack(x) + return {tag='TFunction', p, r } + end } } + + M.annot.ts = gg.multisequence{ + name = 'annot.ts', + { 'return', _A.tebar_content, builder='TReturn' }, + { _A.tid, builder = function(x) + if x[1][1]=='pass' then return {tag='TPass'} + else error "Bad statement type" end + end } } + +-- TODO: add parsers for statements: +-- #return tebar +-- #alias = te +-- #ell = tf +--[[ + M.annot.stat_annot = gg.sequence{ + gg.list{ primary=_A.tid, separators='.' }, + '=', + XXX??, + builder = 'Annot' } +--]] + + return M.annot +end \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/expr.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/expr.lua new file mode 100644 index 000000000..8ce4677a5 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/expr.lua @@ -0,0 +1,206 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- +-- Exported API: +-- * [mlp.expr()] +-- * [mlp.expr_list()] +-- * [mlp.func_val()] +-- +------------------------------------------------------------------------------- + +local pp = require 'metalua.pprint' +local gg = require 'metalua.grammar.generator' +local annot = require 'metalua.compiler.parser.annot.generator' + +return function(M) + local _M = gg.future(M) + local _table = gg.future(M, 'table') + local _meta = gg.future(M, 'meta') -- TODO move to ext? + local _annot = gg.future(M, 'annot') -- TODO move to annot + + -------------------------------------------------------------------------------- + -- Non-empty expression list. Actually, this isn't used here, but that's + -- handy to give to users. + -------------------------------------------------------------------------------- + M.expr_list = gg.list{ primary=_M.expr, separators="," } + + -------------------------------------------------------------------------------- + -- Helpers for function applications / method applications + -------------------------------------------------------------------------------- + M.func_args_content = gg.list{ + name = "function arguments", + primary = _M.expr, + separators = ",", + terminators = ")" } + + -- Used to parse methods + M.method_args = gg.multisequence{ + name = "function argument(s)", + { "{", _table.content, "}" }, + { "(", _M.func_args_content, ")", builder = unpack }, + { "+{", _meta.quote_content, "}" }, + -- TODO lineinfo? + function(lx) local r = M.opt_string(lx); return r and {r} or { } end } + + -------------------------------------------------------------------------------- + -- [func_val] parses a function, from opening parameters parenthese to + -- "end" keyword included. Used for anonymous functions as well as + -- function declaration statements (both local and global). + -- + -- It's wrapped in a [_func_val] eta expansion, so that when expr + -- parser uses the latter, they will notice updates of [func_val] + -- definitions. + -------------------------------------------------------------------------------- + M.func_params_content = gg.list{ + name="function parameters", + gg.multisequence{ { "...", builder = "Dots" }, annot.opt(M, _M.id, 'te') }, + separators = ",", terminators = {")", "|"} } + + -- TODO move to annot + M.func_val = gg.sequence{ + name = "function body", + "(", _M.func_params_content, ")", _M.block, "end", + builder = function(x) + local params, body = unpack(x) + local annots, some = { }, false + for i, p in ipairs(params) do + if p.tag=='Annot' then + params[i], annots[i], some = p[1], p[2], true + else annots[i] = false end + end + if some then return { tag='Function', params, body, annots } + else return { tag='Function', params, body } end + end } + + local func_val = function(lx) return M.func_val(lx) end + + -------------------------------------------------------------------------------- + -- Default parser for primary expressions + -------------------------------------------------------------------------------- + function M.id_or_literal (lx) + local a = lx:next() + if a.tag~="Id" and a.tag~="String" and a.tag~="Number" then + local msg + if a.tag=='Eof' then + msg = "End of file reached when an expression was expected" + elseif a.tag=='Keyword' then + msg = "An expression was expected, and `"..a[1].. + "' can't start an expression" + else + msg = "Unexpected expr token " .. pp.tostring (a) + end + gg.parse_error (lx, msg) + end + return a + end + + + -------------------------------------------------------------------------------- + -- Builder generator for operators. Wouldn't be worth it if "|x|" notation + -- were allowed, but then lua 5.1 wouldn't compile it + -------------------------------------------------------------------------------- + + -- opf1 = |op| |_,a| `Op{ op, a } + local function opf1 (op) return + function (_,a) return { tag="Op", op, a } end end + + -- opf2 = |op| |a,_,b| `Op{ op, a, b } + local function opf2 (op) return + function (a,_,b) return { tag="Op", op, a, b } end end + + -- opf2r = |op| |a,_,b| `Op{ op, b, a } -- (args reversed) + local function opf2r (op) return + function (a,_,b) return { tag="Op", op, b, a } end end + + local function op_ne(a, _, b) + -- This version allows to remove the "ne" operator from the AST definition. + -- However, it doesn't always produce the exact same bytecode as Lua 5.1. + return { tag="Op", "not", + { tag="Op", "eq", a, b, lineinfo= { + first = a.lineinfo.first, last = b.lineinfo.last } } } + end + + + -------------------------------------------------------------------------------- + -- + -- complete expression + -- + -------------------------------------------------------------------------------- + + -- FIXME: set line number. In [expr] transformers probably + M.expr = gg.expr { + name = "expression", + primary = gg.multisequence{ + name = "expr primary", + { "(", _M.expr, ")", builder = "Paren" }, + { "function", _M.func_val, builder = unpack }, + { "-{", _meta.splice_content, "}", builder = unpack }, + { "+{", _meta.quote_content, "}", builder = unpack }, + { "nil", builder = "Nil" }, + { "true", builder = "True" }, + { "false", builder = "False" }, + { "...", builder = "Dots" }, + { "{", _table.content, "}", builder = unpack }, + _M.id_or_literal }, + + infix = { + name = "expr infix op", + { "+", prec = 60, builder = opf2 "add" }, + { "-", prec = 60, builder = opf2 "sub" }, + { "*", prec = 70, builder = opf2 "mul" }, + { "/", prec = 70, builder = opf2 "div" }, + { "%", prec = 70, builder = opf2 "mod" }, + { "^", prec = 90, builder = opf2 "pow", assoc = "right" }, + { "..", prec = 40, builder = opf2 "concat", assoc = "right" }, + { "==", prec = 30, builder = opf2 "eq" }, + { "~=", prec = 30, builder = op_ne }, + { "<", prec = 30, builder = opf2 "lt" }, + { "<=", prec = 30, builder = opf2 "le" }, + { ">", prec = 30, builder = opf2r "lt" }, + { ">=", prec = 30, builder = opf2r "le" }, + { "and",prec = 20, builder = opf2 "and" }, + { "or", prec = 10, builder = opf2 "or" } }, + + prefix = { + name = "expr prefix op", + { "not", prec = 80, builder = opf1 "not" }, + { "#", prec = 80, builder = opf1 "len" }, + { "-", prec = 80, builder = opf1 "unm" } }, + + suffix = { + name = "expr suffix op", + { "[", _M.expr, "]", builder = function (tab, idx) + return {tag="Index", tab, idx[1]} end}, + { ".", _M.id, builder = function (tab, field) + return {tag="Index", tab, _M.id2string(field[1])} end }, + { "(", _M.func_args_content, ")", builder = function(f, args) + return {tag="Call", f, unpack(args[1])} end }, + { "{", _table.content, "}", builder = function (f, arg) + return {tag="Call", f, arg[1]} end}, + { ":", _M.id, _M.method_args, builder = function (obj, post) + local m_name, args = unpack(post) + return {tag="Invoke", obj, _M.id2string(m_name), unpack(args)} end}, + { "+{", _meta.quote_content, "}", builder = function (f, arg) + return {tag="Call", f, arg[1] } end }, + default = { name="opt_string_arg", parse = _M.opt_string, builder = function(f, arg) + return {tag="Call", f, arg } end } } } + return M +end \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/ext.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/ext.lua new file mode 100644 index 000000000..4e9d3950f --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/ext.lua @@ -0,0 +1,96 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +-- +-- Non-Lua syntax extensions +-- +-------------------------------------------------------------------------------- + +local gg = require 'metalua.grammar.generator' + +return function(M) + + local _M = gg.future(M) + + --------------------------------------------------------------------------- + -- Algebraic Datatypes + ---------------------------------------------------------------------------- + local function adt (lx) + local node = _M.id (lx) + local tagval = node[1] + -- tagkey = `Pair{ `String "key", `String{ -{tagval} } } + local tagkey = { tag="Pair", {tag="String", "tag"}, {tag="String", tagval} } + if lx:peek().tag == "String" or lx:peek().tag == "Number" then + -- TODO support boolean litterals + return { tag="Table", tagkey, lx:next() } + elseif lx:is_keyword (lx:peek(), "{") then + local x = M.table.table (lx) + table.insert (x, 1, tagkey) + return x + else return { tag="Table", tagkey } end + end + + M.adt = gg.sequence{ "`", adt, builder = unpack } + + M.expr.primary :add(M.adt) + + ---------------------------------------------------------------------------- + -- Anonymous lambda + ---------------------------------------------------------------------------- + M.lambda_expr = gg.sequence{ + "|", _M.func_params_content, "|", _M.expr, + builder = function (x) + local li = x[2].lineinfo + return { tag="Function", x[1], + { {tag="Return", x[2], lineinfo=li }, lineinfo=li } } + end } + + M.expr.primary :add (M.lambda_expr) + + -------------------------------------------------------------------------------- + -- Allows to write "a `f` b" instead of "f(a, b)". Taken from Haskell. + -------------------------------------------------------------------------------- + function M.expr_in_backquotes (lx) return M.expr(lx, 35) end -- 35=limited precedence + M.expr.infix :add{ name = "infix function", + "`", _M.expr_in_backquotes, "`", prec = 35, assoc="left", + builder = function(a, op, b) return {tag="Call", op[1], a, b} end } + + -------------------------------------------------------------------------------- + -- C-style op+assignments + -- TODO: no protection against side-effects in LHS vars. + -------------------------------------------------------------------------------- + local function op_assign(kw, op) + local function rhs(a, b) return { tag="Op", op, a, b } end + local function f(a,b) + if #a ~= #b then gg.parse_error "assymetric operator+assignment" end + local right = { } + local r = { tag="Set", a, right } + for i=1, #a do right[i] = { tag="Op", op, a[i], b[i] } end + return r + end + M.lexer :add (kw) + M.assignments[kw] = f + end + + local ops = { add='+='; sub='-='; mul='*='; div='/=' } + for ast_op_name, keyword in pairs(ops) do op_assign(keyword, ast_op_name) end + + return M +end \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/lexer.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/lexer.lua new file mode 100644 index 000000000..2b5ff7e9d --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/lexer.lua @@ -0,0 +1,43 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2006-2014 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +---------------------------------------------------------------------- +-- Generate a new lua-specific lexer, derived from the generic lexer. +---------------------------------------------------------------------- + +local generic_lexer = require 'metalua.grammar.lexer' + +return function() + local lexer = generic_lexer.lexer :clone() + + local keywords = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", + "goto", -- Lua5.2 + "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "...", "..", "==", ">=", "<=", "~=", + "::", -- Lua5,2 + "+{", "-{" } -- Metalua + + for _, w in ipairs(keywords) do lexer :add (w) end + + return lexer +end \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/meta.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/meta.lua new file mode 100644 index 000000000..71eb3c358 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/meta.lua @@ -0,0 +1,138 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2014 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +-- Compile-time metaprogramming features: splicing ASTs generated during compilation, +-- AST quasi-quoting helpers. + +local gg = require 'metalua.grammar.generator' + +return function(M) + local _M = gg.future(M) + M.meta={ } + local _MM = gg.future(M.meta) + + -------------------------------------------------------------------------------- + -- External splicing: compile an AST into a chunk, load and evaluate + -- that chunk, and replace the chunk by its result (which must also be + -- an AST). + -------------------------------------------------------------------------------- + + -- TODO: that's not part of the parser + function M.meta.eval (ast) + -- TODO: should there be one mlc per splice, or per parser instance? + local mlc = require 'metalua.compiler'.new() + local f = mlc :ast_to_function (ast, '=splice') + local result=f(M) -- splices act on the current parser + return result + end + + ---------------------------------------------------------------------------- + -- Going from an AST to an AST representing that AST + -- the only hash-part key being lifted is `"tag"`. + -- Doesn't lift subtrees protected inside a `Splice{ ... }. + -- e.g. change `Foo{ 123 } into + -- `Table{ `Pair{ `String "tag", `String "foo" }, `Number 123 } + ---------------------------------------------------------------------------- + local function lift (t) + --print("QUOTING:", table.tostring(t, 60,'nohash')) + local cases = { } + function cases.table (t) + local mt = { tag = "Table" } + --table.insert (mt, { tag = "Pair", quote "quote", { tag = "True" } }) + if t.tag == "Splice" then + assert (#t==1, "Invalid splice") + local sp = t[1] + return sp + elseif t.tag then + table.insert (mt, { tag="Pair", lift "tag", lift(t.tag) }) + end + for _, v in ipairs (t) do + table.insert (mt, lift(v)) + end + return mt + end + function cases.number (t) return { tag = "Number", t, quote = true } end + function cases.string (t) return { tag = "String", t, quote = true } end + function cases.boolean (t) return { tag = t and "True" or "False", t, quote = true } end + local f = cases [type(t)] + if f then return f(t) else error ("Cannot quote an AST containing "..tostring(t)) end + end + M.meta.lift = lift + + -------------------------------------------------------------------------------- + -- when this variable is false, code inside [-{...}] is compiled and + -- avaluated immediately. When it's true (supposedly when we're + -- parsing data inside a quasiquote), [-{foo}] is replaced by + -- [`Splice{foo}], which will be unpacked by [quote()]. + -------------------------------------------------------------------------------- + local in_a_quote = false + + -------------------------------------------------------------------------------- + -- Parse the inside of a "-{ ... }" + -------------------------------------------------------------------------------- + function M.meta.splice_content (lx) + local parser_name = "expr" + if lx:is_keyword (lx:peek(2), ":") then + local a = lx:next() + lx:next() -- skip ":" + assert (a.tag=="Id", "Invalid splice parser name") + parser_name = a[1] + end + -- TODO FIXME running a new parser with the old lexer?! + local parser = require 'metalua.compiler.parser'.new() + local ast = parser [parser_name](lx) + if in_a_quote then -- only prevent quotation in this subtree + --printf("SPLICE_IN_QUOTE:\n%s", _G.table.tostring(ast, "nohash", 60)) + return { tag="Splice", ast } + else -- convert in a block, eval, replace with result + if parser_name == "expr" then ast = { { tag="Return", ast } } + elseif parser_name == "stat" then ast = { ast } + elseif parser_name ~= "block" then + error ("splice content must be an expr, stat or block") end + --printf("EXEC THIS SPLICE:\n%s", _G.table.tostring(ast, "nohash", 60)) + return M.meta.eval (ast) + end + end + + M.meta.splice = gg.sequence{ "-{", _MM.splice_content, "}", builder=unpack } + + -------------------------------------------------------------------------------- + -- Parse the inside of a "+{ ... }" + -------------------------------------------------------------------------------- + function M.meta.quote_content (lx) + local parser + if lx:is_keyword (lx:peek(2), ":") then -- +{parser: content } + local parser_name = M.id(lx)[1] + parser = M[parser_name] + lx:next() -- skip ":" + else -- +{ content } + parser = M.expr + end + + local prev_iq = in_a_quote + in_a_quote = true + --print("IN_A_QUOTE") + local content = parser (lx) + local q_content = M.meta.lift (content) + in_a_quote = prev_iq + return q_content + end + + return M +end \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/misc.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/misc.lua new file mode 100644 index 000000000..f7dde0923 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/misc.lua @@ -0,0 +1,176 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- +-- Summary: metalua parser, miscellaneous utility functions. +-- +------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +-- +-- Exported API: +-- * [mlp.fget()] +-- * [mlp.id()] +-- * [mlp.opt_id()] +-- * [mlp.id_list()] +-- * [mlp.string()] +-- * [mlp.opt_string()] +-- * [mlp.id2string()] +-- +-------------------------------------------------------------------------------- + +local pp = require 'metalua.pprint' +local gg = require 'metalua.grammar.generator' + +-- TODO: replace splice-aware versions with naive ones, move etensions in ./meta + +return function(M) + local _M = gg.future(M) + +--[[ metaprog-free versions: + function M.id(lx) + if lx:peek().tag~='Id' then gg.parse_error(lx, "Identifier expected") + else return lx:next() end + end + + function M.opt_id(lx) + if lx:peek().tag~='Id' then return lx:next() else return false end + end + + function M.string(lx) + if lx:peek().tag~='String' then gg.parse_error(lx, "String expected") + else return lx:next() end + end + + function M.opt_string(lx) + if lx:peek().tag~='String' then return lx:next() else return false end + end + + -------------------------------------------------------------------------------- + -- Converts an identifier into a string. Hopefully one day it'll handle + -- splices gracefully, but that proves quite tricky. + -------------------------------------------------------------------------------- + function M.id2string (id) + if id.tag == "Id" then id.tag = "String"; return id + else error ("Identifier expected: "..table.tostring(id, 'nohash')) end + end +--]] + + -------------------------------------------------------------------------------- + -- Try to read an identifier (possibly as a splice), or return [false] if no + -- id is found. + -------------------------------------------------------------------------------- + function M.opt_id (lx) + local a = lx:peek(); + if lx:is_keyword (a, "-{") then + local v = M.meta.splice(lx) + if v.tag ~= "Id" and v.tag ~= "Splice" then + gg.parse_error(lx, "Bad id splice") + end + return v + elseif a.tag == "Id" then return lx:next() + else return false end + end + + -------------------------------------------------------------------------------- + -- Mandatory reading of an id: causes an error if it can't read one. + -------------------------------------------------------------------------------- + function M.id (lx) + return M.opt_id (lx) or gg.parse_error(lx,"Identifier expected") + end + + -------------------------------------------------------------------------------- + -- Common helper function + -------------------------------------------------------------------------------- + M.id_list = gg.list { primary = _M.id, separators = "," } + + -------------------------------------------------------------------------------- + -- Converts an identifier into a string. Hopefully one day it'll handle + -- splices gracefully, but that proves quite tricky. + -------------------------------------------------------------------------------- + function M.id2string (id) + --print("id2string:", disp.ast(id)) + if id.tag == "Id" then id.tag = "String"; return id + elseif id.tag == "Splice" then + error ("id2string on splice not implemented") + -- Evaluating id[1] will produce `Id{ xxx }, + -- and we want it to produce `String{ xxx }. + -- The following is the plain notation of: + -- +{ `String{ `Index{ `Splice{ -{id[1]} }, `Number 1 } } } + return { tag="String", { tag="Index", { tag="Splice", id[1] }, + { tag="Number", 1 } } } + else error ("Identifier expected: "..pp.tostring (id, {metalua_tag=1, hide_hash=1})) end + end + + -------------------------------------------------------------------------------- + -- Read a string, possibly spliced, or return an error if it can't + -------------------------------------------------------------------------------- + function M.string (lx) + local a = lx:peek() + if lx:is_keyword (a, "-{") then + local v = M.meta.splice(lx) + if v.tag ~= "String" and v.tag ~= "Splice" then + gg.parse_error(lx,"Bad string splice") + end + return v + elseif a.tag == "String" then return lx:next() + else error "String expected" end + end + + -------------------------------------------------------------------------------- + -- Try to read a string, or return false if it can't. No splice allowed. + -------------------------------------------------------------------------------- + function M.opt_string (lx) + return lx:peek().tag == "String" and lx:next() + end + + -------------------------------------------------------------------------------- + -- Chunk reader: block + Eof + -------------------------------------------------------------------------------- + function M.skip_initial_sharp_comment (lx) + -- Dirty hack: I'm happily fondling lexer's private parts + -- FIXME: redundant with lexer:newstream() + lx :sync() + local i = lx.src:match ("^#.-\n()", lx.i) + if i then + lx.i = i + lx.column_offset = i + lx.line = lx.line and lx.line + 1 or 1 + end + end + + local function chunk (lx) + if lx:peek().tag == 'Eof' then + return { } -- handle empty files + else + M.skip_initial_sharp_comment (lx) + local chunk = M.block (lx) + if lx:peek().tag ~= "Eof" then + gg.parse_error(lx, "End-of-file expected") + end + return chunk + end + end + + -- chunk is wrapped in a sequence so that it has a "transformer" field. + M.chunk = gg.sequence { chunk, builder = unpack } + + return M +end \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/stat.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/stat.lua new file mode 100644 index 000000000..5d5e3a91d --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/stat.lua @@ -0,0 +1,279 @@ +------------------------------------------------------------------------------ +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- +-- Summary: metalua parser, statement/block parser. This is part of the +-- definition of module [mlp]. +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- +-- Exports API: +-- * [mlp.stat()] +-- * [mlp.block()] +-- * [mlp.for_header()] +-- +------------------------------------------------------------------------------- + +local lexer = require 'metalua.grammar.lexer' +local gg = require 'metalua.grammar.generator' + +local annot = require 'metalua.compiler.parser.annot.generator' + +-------------------------------------------------------------------------------- +-- List of all keywords that indicate the end of a statement block. Users are +-- likely to extend this list when designing extensions. +-------------------------------------------------------------------------------- + + +return function(M) + local _M = gg.future(M) + + M.block_terminators = { "else", "elseif", "end", "until", ")", "}", "]" } + + -- FIXME: this must be handled from within GG!!! + -- FIXME: there's no :add method in the list anyway. Added by gg.list?! + function M.block_terminators :add(x) + if type (x) == "table" then for _, y in ipairs(x) do self :add (y) end + else table.insert (self, x) end + end + + ---------------------------------------------------------------------------- + -- list of statements, possibly followed by semicolons + ---------------------------------------------------------------------------- + M.block = gg.list { + name = "statements block", + terminators = M.block_terminators, + primary = function (lx) + -- FIXME use gg.optkeyword() + local x = M.stat (lx) + if lx:is_keyword (lx:peek(), ";") then lx:next() end + return x + end } + + ---------------------------------------------------------------------------- + -- Helper function for "return " parsing. + -- Called when parsing return statements. + -- The specific test for initial ";" is because it's not a block terminator, + -- so without it gg.list would choke on "return ;" statements. + -- We don't make a modified copy of block_terminators because this list + -- is sometimes modified at runtime, and the return parser would get out of + -- sync if it was relying on a copy. + ---------------------------------------------------------------------------- + local return_expr_list_parser = gg.multisequence{ + { ";" , builder = function() return { } end }, + default = gg.list { + _M.expr, separators = ",", terminators = M.block_terminators } } + + + local for_vars_list = gg.list{ + name = "for variables list", + primary = _M.id, + separators = ",", + terminators = "in" } + + ---------------------------------------------------------------------------- + -- for header, between [for] and [do] (exclusive). + -- Return the `Forxxx{...} AST, without the body element (the last one). + ---------------------------------------------------------------------------- + function M.for_header (lx) + local vars = M.id_list(lx) + if lx :is_keyword (lx:peek(), "=") then + if #vars ~= 1 then + gg.parse_error (lx, "numeric for only accepts one variable") + end + lx:next() -- skip "=" + local exprs = M.expr_list (lx) + if #exprs < 2 or #exprs > 3 then + gg.parse_error (lx, "numeric for requires 2 or 3 boundaries") + end + return { tag="Fornum", vars[1], unpack (exprs) } + else + if not lx :is_keyword (lx :next(), "in") then + gg.parse_error (lx, '"=" or "in" expected in for loop') + end + local exprs = M.expr_list (lx) + return { tag="Forin", vars, exprs } + end + end + + ---------------------------------------------------------------------------- + -- Function def parser helper: id ( . id ) * + ---------------------------------------------------------------------------- + local function fn_builder (list) + local acc = list[1] + local first = acc.lineinfo.first + for i = 2, #list do + local index = M.id2string(list[i]) + local li = lexer.new_lineinfo(first, index.lineinfo.last) + acc = { tag="Index", acc, index, lineinfo=li } + end + return acc + end + local func_name = gg.list{ _M.id, separators = ".", builder = fn_builder } + + ---------------------------------------------------------------------------- + -- Function def parser helper: ( : id )? + ---------------------------------------------------------------------------- + local method_name = gg.onkeyword{ name = "method invocation", ":", _M.id, + transformers = { function(x) return x and x.tag=='Id' and M.id2string(x) end } } + + ---------------------------------------------------------------------------- + -- Function def builder + ---------------------------------------------------------------------------- + local function funcdef_builder(x) + local name, method, func = unpack(x) + if method then + name = { tag="Index", name, method, + lineinfo = { + first = name.lineinfo.first, + last = method.lineinfo.last } } + table.insert (func[1], 1, {tag="Id", "self"}) + end + local r = { tag="Set", {name}, {func} } + r[1].lineinfo = name.lineinfo + r[2].lineinfo = func.lineinfo + return r + end + + + ---------------------------------------------------------------------------- + -- if statement builder + ---------------------------------------------------------------------------- + local function if_builder (x) + local cond_block_pairs, else_block, r = x[1], x[2], {tag="If"} + local n_pairs = #cond_block_pairs + for i = 1, n_pairs do + local cond, block = unpack(cond_block_pairs[i]) + r[2*i-1], r[2*i] = cond, block + end + if else_block then table.insert(r, #r+1, else_block) end + return r + end + + -------------------------------------------------------------------------------- + -- produce a list of (expr,block) pairs + -------------------------------------------------------------------------------- + local elseifs_parser = gg.list { + gg.sequence { _M.expr, "then", _M.block , name='elseif parser' }, + separators = "elseif", + terminators = { "else", "end" } + } + + local annot_expr = gg.sequence { + _M.expr, + gg.onkeyword{ "#", gg.future(M, 'annot').tf }, + builder = function(x) + local e, a = unpack(x) + if a then return { tag='Annot', e, a } + else return e end + end } + + local annot_expr_list = gg.list { + primary = annot.opt(M, _M.expr, 'tf'), separators = ',' } + + ------------------------------------------------------------------------ + -- assignments and calls: statements that don't start with a keyword + ------------------------------------------------------------------------ + local function assign_or_call_stat_parser (lx) + local e = annot_expr_list (lx) + local a = lx:is_keyword(lx:peek()) + local op = a and M.assignments[a] + -- TODO: refactor annotations + if op then + --FIXME: check that [e] is a LHS + lx :next() + local annots + e, annots = annot.split(e) + local v = M.expr_list (lx) + if type(op)=="string" then return { tag=op, e, v, annots } + else return op (e, v) end + else + assert (#e > 0) + if #e > 1 then + gg.parse_error (lx, + "comma is not a valid statement separator; statement can be ".. + "separated by semicolons, or not separated at all") + elseif e[1].tag ~= "Call" and e[1].tag ~= "Invoke" then + local typename + if e[1].tag == 'Id' then + typename = '("'..e[1][1]..'") is an identifier' + elseif e[1].tag == 'Op' then + typename = "is an arithmetic operation" + else typename = "is of type '"..(e[1].tag or "").."'" end + gg.parse_error (lx, + "This expression %s; ".. + "a statement was expected, and only function and method call ".. + "expressions can be used as statements", typename); + end + return e[1] + end + end + + M.local_stat_parser = gg.multisequence{ + -- local function + { "function", _M.id, _M.func_val, builder = + function(x) + local vars = { x[1], lineinfo = x[1].lineinfo } + local vals = { x[2], lineinfo = x[2].lineinfo } + return { tag="Localrec", vars, vals } + end }, + -- local ( = )? + default = gg.sequence{ + gg.list{ + primary = annot.opt(M, _M.id, 'tf'), + separators = ',' }, + gg.onkeyword{ "=", _M.expr_list }, + builder = function(x) + local annotated_left, right = unpack(x) + local left, annotations = annot.split(annotated_left) + return {tag="Local", left, right or { }, annotations } + end } } + + ------------------------------------------------------------------------ + -- statement + ------------------------------------------------------------------------ + M.stat = gg.multisequence { + name = "statement", + { "do", _M.block, "end", builder = + function (x) return { tag="Do", unpack (x[1]) } end }, + { "for", _M.for_header, "do", _M.block, "end", builder = + function (x) x[1][#x[1]+1] = x[2]; return x[1] end }, + { "function", func_name, method_name, _M.func_val, builder=funcdef_builder }, + { "while", _M.expr, "do", _M.block, "end", builder = "While" }, + { "repeat", _M.block, "until", _M.expr, builder = "Repeat" }, + { "local", _M.local_stat_parser, builder = unpack }, + { "return", return_expr_list_parser, builder = + function(x) x[1].tag='Return'; return x[1] end }, + { "break", builder = function() return { tag="Break" } end }, + { "-{", gg.future(M, 'meta').splice_content, "}", builder = unpack }, + { "if", gg.nonempty(elseifs_parser), gg.onkeyword{ "else", M.block }, "end", + builder = if_builder }, + default = assign_or_call_stat_parser } + + M.assignments = { + ["="] = "Set" + } + + function M.assignments:add(k, v) self[k] = v end + + return M +end \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/table.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/table.lua new file mode 100644 index 000000000..11102d9ec --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/compiler/parser/table.lua @@ -0,0 +1,77 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +-- +-- Exported API: +-- * [M.table_bracket_field()] +-- * [M.table_field()] +-- * [M.table_content()] +-- * [M.table()] +-- +-- KNOWN BUG: doesn't handle final ";" or "," before final "}" +-- +-------------------------------------------------------------------------------- + +local gg = require 'metalua.grammar.generator' + +return function(M) + + M.table = { } + local _table = gg.future(M.table) + local _expr = gg.future(M).expr + + -------------------------------------------------------------------------------- + -- `[key] = value` table field definition + -------------------------------------------------------------------------------- + M.table.bracket_pair = gg.sequence{ "[", _expr, "]", "=", _expr, builder = "Pair" } + + -------------------------------------------------------------------------------- + -- table element parser: list value, `id = value` pair or `[value] = value` pair. + -------------------------------------------------------------------------------- + function M.table.element (lx) + if lx :is_keyword (lx :peek(), "[") then return M.table.bracket_pair(lx) end + local e = M.expr (lx) + if not lx :is_keyword (lx :peek(), "=") then return e end + lx :next(); -- skip the "=" + local key = M.id2string(e) -- will fail on non-identifiers + local val = M.expr(lx) + local r = { tag="Pair", key, val } + r.lineinfo = { first = key.lineinfo.first, last = val.lineinfo.last } + return r + end + + ----------------------------------------------------------------------------- + -- table constructor, without enclosing braces; returns a full table object + ----------------------------------------------------------------------------- + M.table.content = gg.list { + -- eta expansion to allow patching the element definition + primary = _table.element, + separators = { ",", ";" }, + terminators = "}", + builder = "Table" } + + -------------------------------------------------------------------------------- + -- complete table constructor including [{...}] + -------------------------------------------------------------------------------- + -- TODO beware, stat and expr use only table.content, this can't be patched. + M.table.table = gg.sequence{ "{", _table.content, "}", builder = unpack } + + return M +end \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/extension/comprehension.mlua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/extension/comprehension.mlua new file mode 100644 index 000000000..8917b9a92 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/extension/comprehension.mlua @@ -0,0 +1,282 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- +-- +-- This extension implements list comprehensions, similar to Haskell and +-- Python syntax, to easily describe lists. +-- +-- * x[a ... b] is the list { x[a], x[a+1], ..., x[b] } +-- * { f()..., b } contains all the elements returned by f(), then b +-- (allows to expand list fields other than the last one) +-- * list comprehensions a la python, with "for" and "if" suffixes: +-- {i+10*j for i=1,3 for j=1,3 if i~=j} is { 21, 31, 12, 32, 13, 23 } +-- +------------------------------------------------------------------------------- + +-{ extension ("match", ...) } + +local SUPPORT_IMPROVED_LOOPS = true +local SUPPORT_IMPROVED_INDEXES = false -- depends on deprecated table.isub +local SUPPORT_CONTINUE = true +local SUPPORT_COMP_LISTS = true + +assert (SUPPORT_IMPROVED_LOOPS or not SUPPORT_CONTINUE, + "Can't support 'continue' without improved loop headers") + +local gg = require 'metalua.grammar.generator' +local Q = require 'metalua.treequery' + +local function dots_list_suffix_builder (x) return `DotsSuffix{ x } end + +local function for_list_suffix_builder (list_element, suffix) + local new_header = suffix[1] + match list_element with + | `Comp{ _, acc } -> table.insert (acc, new_header); return list_element + | _ -> return `Comp{ list_element, { new_header } } + end +end + +local function if_list_suffix_builder (list_element, suffix) + local new_header = `If{ suffix[1] } + match list_element with + | `Comp{ _, acc } -> table.insert (acc, new_header); return list_element + | _ -> return `Comp{ list_element, { new_header } } + end +end + +-- Builds a statement from a table element, which adds this element to +-- a table `t`, potentially thanks to an alias `tinsert` to +-- `table.insert`. +-- @param core the part around which the loops are built. +-- either `DotsSuffix{expr}, `Pair{ expr } or a plain expression +-- @param list comprehension suffixes, in the order in which they appear +-- either `Forin{ ... } or `Fornum{ ...} or `If{ ... }. In each case, +-- it misses a last child node as its body. +-- @param t a variable containing the table to fill +-- @param tinsert a variable containing `table.insert`. +-- +-- @return fill a statement which fills empty table `t` with the denoted element +local function comp_list_builder(core, list, t, tinsert) + local filler + -- 1 - Build the loop's core: if it has suffix "...", every elements of the + -- multi-return must be inserted, hence the extra [for] loop. + match core with + | `DotsSuffix{ element } -> + local x = gg.gensym() + filler = +{stat: for _, -{x} in pairs{ -{element} } do (-{tinsert})(-{t}, -{x}) end } + | `Pair{ key, value } -> + --filler = +{ -{t}[-{key}] = -{value} } + filler = `Set{ { `Index{ t, key } }, { value } } + | _ -> filler = +{ (-{tinsert})(-{t}, -{core}) } + end + + -- 2 - Stack the `if` and `for` control structures, from outside to inside. + -- This is done in a destructive way for the elements of [list]. + for i = #list, 1, -1 do + table.insert (list[i], {filler}) + filler = list[i] + end + + return filler +end + +local function table_content_builder (list) + local special = false -- Does the table need a special builder? + for _, element in ipairs(list) do + local etag = element.tag + if etag=='Comp' or etag=='DotsSuffix' then special=true; break end + end + if not special then list.tag='Table'; return list end + + local t, tinsert = gg.gensym 'table', gg.gensym 'table_insert' + local filler_block = { +{stat: local -{t}, -{tinsert} = { }, table.insert } } + for _, element in ipairs(list) do + local filler + match element with + | `Comp{ core, comp } -> filler = comp_list_builder(core, comp, t, tinsert) + | _ -> filler = comp_list_builder(element, { }, t, tinsert) + end + table.insert(filler_block, filler) + end + return `Stat{ filler_block, t } +end + + +-------------------------------------------------------------------------------- +-- Back-end for improved index operator. +local function index_builder(a, suffix) + match suffix[1] with + -- Single index, no range: keep the native semantics + | { { e, false } } -> return `Index{ a, e } + -- Either a range, or multiple indexes, or both + | ranges -> + local r = `Call{ +{table.isub}, a } + local function acc (x,y) table.insert (r,x); table.insert (r,y) end + for _, seq in ipairs (ranges) do + match seq with + | { e, false } -> acc(e,e) + | { e, f } -> acc(e,f) + end + end + return r + end +end + +------------------------------------------------------------------- +-- Find continue statements in a loop body, change them into goto +-- end-of-body. +local function transform_continue_statements(body) + local continue_statements = Q(body) + :if_unknown() -- tolerate unknown 'Continue' statements + :not_under ('Forin', 'Fornum', 'While', 'Repeat') + :filter ('Continue') + :list() + if next(continue_statements) then + local continue_label = gg.gensym 'continue' [1] + table.insert(body, `Label{ continue_label }) + for _, statement in ipairs(continue_statements) do + statement.tag = 'Goto' + statement[1] = continue_label + end + return true + else return false end +end + +------------------------------------------------------------------------------- +-- Back-end for loops with a multi-element header +local function loop_builder(x) + local first, elements, body = unpack(x) + + -- Change continue statements into gotos. + if SUPPORT_CONTINUE then transform_continue_statements(body) end + + ------------------------------------------------------------------- + -- If it's a regular loop, don't bloat the code + if not next(elements) then + table.insert(first, body) + return first + end + + ------------------------------------------------------------------- + -- There's no reason to treat the first element in a special way + table.insert(elements, 1, first) + + ------------------------------------------------------------------- + -- Change breaks into gotos that escape all loops at once. + local exit_label = nil + local function break_to_goto(break_node) + if not exit_label then exit_label = gg.gensym 'break' [1] end + break_node = break_node or { } + break_node.tag = 'Goto' + break_node[1] = exit_label + return break_node + end + Q(body) + :not_under('Function', 'Forin', 'Fornum', 'While', 'Repeat') + :filter('Break') + :foreach (break_to_goto) + + ------------------------------------------------------------------- + -- Compile all headers elements, from last to first. + -- invariant: `body` is a block (not a statement) + local result = body + for i = #elements, 1, -1 do + local e = elements[i] + match e with + | `If{ cond } -> + result = { `If{ cond, result } } + | `Until{ cond } -> + result = +{block: if -{cond} then -{break_to_goto()} else -{result} end } + | `While{ cond } -> + if i==1 then result = { `While{ cond, result } } -- top-level while + else result = +{block: if -{cond} then -{result} else -{break_to_goto()} end } end + | `Forin{ ... } | `Fornum{ ... } -> + table.insert (e, result); result={e} + | _-> require'metalua.pprint'.printf("Bad loop header element %s", e) + end + end + + + ------------------------------------------------------------------- + -- If some breaks had to be changed into gotos, insert the label + if exit_label then result = { result, `Label{ exit_label } } end + + return result +end + + +-------------------------------------------------------------------------------- +-- Improved "[...]" index operator: +-- * support for multi-indexes ("foo[bar, gnat]") +-- * support for ranges ("foo[bar ... gnat]") +-------------------------------------------------------------------------------- +local function extend(M) + + local _M = gg.future(M) + + if SUPPORT_COMP_LISTS then + -- support for "for" / "if" comprehension suffixes in literal tables + local original_table_element = M.table.element + M.table.element = gg.expr{ name="table cell", + primary = original_table_element, + suffix = { name="table cell suffix", + { "...", builder = dots_list_suffix_builder }, + { "for", _M.for_header, builder = for_list_suffix_builder }, + { "if", _M.expr, builder = if_list_suffix_builder } } } + M.table.content.builder = table_content_builder + end + + if SUPPORT_IMPROVED_INDEXES then + -- Support for ranges and multiple indices in bracket suffixes + M.expr.suffix:del '[' + M.expr.suffix:add{ name="table index/range", + "[", gg.list{ + gg.sequence { _M.expr, gg.onkeyword{ "...", _M.expr } } , + separators = { ",", ";" } }, + "]", builder = index_builder } + end + + if SUPPORT_IMPROVED_LOOPS then + local original_for_header = M.for_header + M.stat :del 'for' + M.stat :del 'while' + + M.loop_suffix = gg.multisequence{ + { 'while', _M.expr, builder = |x| `Until{ `Op{ 'not', x[1] } } }, + { 'until', _M.expr, builder = |x| `Until{ x[1] } }, + { 'if', _M.expr, builder = |x| `If{ x[1] } }, + { 'for', original_for_header, builder = |x| x[1] } } + + M.loop_suffix_list = gg.list{ _M.loop_suffix, terminators='do' } + + M.stat :add{ + 'for', original_for_header, _M.loop_suffix_list, 'do', _M.block, 'end', + builder = loop_builder } + + M.stat :add{ + 'while', _M.expr, _M.loop_suffix_list, 'do', _M.block, 'end', + builder = |x| loop_builder{ `While{x[1]}, x[2], x[3] } } + end + + if SUPPORT_CONTINUE then + M.lexer :add 'continue' + M.stat :add{ 'continue', builder='Continue' } + end +end + +return extend diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/extension/match.mlua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/extension/match.mlua new file mode 100644 index 000000000..f55ff4140 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/extension/match.mlua @@ -0,0 +1,400 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- +-- Glossary: +-- +-- * term_seq: the tested stuff, a sequence of terms +-- * pattern_element: might match one term of a term seq. Represented +-- as expression ASTs. +-- * pattern_seq: might match a term_seq +-- * pattern_group: several pattern seqs, one of them might match +-- the term seq. +-- * case: pattern_group * guard option * block +-- * match_statement: tested term_seq * case list +-- +-- Hence a complete match statement is a: +-- +-- { list(expr), list{ list(list(expr)), expr or false, block } } +-- +-- Implementation hints +-- ==================== +-- +-- The implementation is made as modular as possible, so that parts +-- can be reused in other extensions. The priviledged way to share +-- contextual information across functions is through the 'cfg' table +-- argument. Its fields include: +-- +-- * code: code generated from pattern. A pattern_(element|seq|group) +-- is compiled as a sequence of instructions which will jump to +-- label [cfg.on_failure] if the tested term doesn't match. +-- +-- * on_failure: name of the label where the code will jump if the +-- pattern doesn't match +-- +-- * locals: names of local variables used by the pattern. This +-- includes bound variables, and temporary variables used to +-- destructure tables. Names are stored as keys of the table, +-- values are meaningless. +-- +-- * after_success: label where the code must jump after a pattern +-- succeeded to capture a term, and the guard suceeded if there is +-- any, and the conditional block has run. +-- +-- * ntmp: number of temporary variables used to destructurate table +-- in the current case. +-- +-- Code generation is performed by acc_xxx() functions, which accumulate +-- code in cfg.code: +-- +-- * acc_test(test, cfg) will generate a jump to cfg.on_failure +-- *when the test returns TRUE* +-- +-- * acc_stat accumulates a statement +-- +-- * acc_assign accumulate an assignment statement, and makes sure that +-- the LHS variable the registered as local in cfg.locals. +-- +------------------------------------------------------------------------------- + +-- TODO: hygiene wrt type() +-- TODO: cfg.ntmp isn't reset as often as it could. I'm not even sure +-- the corresponding locals are declared. + +local checks = require 'checks' +local gg = require 'metalua.grammar.generator' +local pp = require 'metalua.pprint' + +---------------------------------------------------------------------- +-- This would have been best done through library 'metalua.walk', +-- but walk depends on match, so we have to break the dependency. +-- It replaces all instances of `...' in `ast' with `term', unless +-- it appears in a function. +---------------------------------------------------------------------- +local function replace_dots (ast, term) + local function rec (node) + for i, child in ipairs(node) do + if type(child)~="table" then -- pass + elseif child.tag=='Dots' then + if term=='ambiguous' then + error ("You can't use `...' on the right of a match case when it appears ".. + "more than once on the left") + else node[i] = term end + elseif child.tag=='Function' then return nil + else rec(child) end + end + end + return rec(ast) +end + +local tmpvar_base = gg.gensym 'submatch.' [1] + +local function next_tmpvar(cfg) + assert (cfg.ntmp, "No cfg.ntmp imbrication level in the match compiler") + cfg.ntmp = cfg.ntmp+1 + return `Id{ tmpvar_base .. cfg.ntmp } +end + +-- Code accumulators +local acc_stat = |x,cfg| table.insert (cfg.code, x) +local acc_test = |x,cfg| acc_stat(+{stat: if -{x} then -{`Goto{cfg.on_failure}} end}, cfg) +-- lhs :: `Id{ string } +-- rhs :: expr +local function acc_assign (lhs, rhs, cfg) + assert(lhs.tag=='Id') + cfg.locals[lhs[1]] = true + acc_stat (`Set{ {lhs}, {rhs} }, cfg) +end + +local literal_tags = { String=1, Number=1, True=1, False=1, Nil=1 } + +-- pattern :: `Id{ string } +-- term :: expr +local function id_pattern_element_builder (pattern, term, cfg) + assert (pattern.tag == "Id") + if pattern[1] == "_" then + -- "_" is used as a dummy var ==> no assignment, no == checking + cfg.locals._ = true + elseif cfg.locals[pattern[1]] then + -- This var is already bound ==> test for equality + acc_test (+{ -{term} ~= -{pattern} }, cfg) + else + -- Free var ==> bind it, and remember it for latter linearity checking + acc_assign (pattern, term, cfg) + cfg.locals[pattern[1]] = true + end +end + +-- mutually recursive with table_pattern_element_builder +local pattern_element_builder + +-- pattern :: pattern and `Table{ } +-- term :: expr +local function table_pattern_element_builder (pattern, term, cfg) + local seen_dots, len = false, 0 + acc_test (+{ type( -{term} ) ~= "table" }, cfg) + for i = 1, #pattern do + local key, sub_pattern + if pattern[i].tag=="Pair" then -- Explicit key/value pair + key, sub_pattern = unpack (pattern[i]) + assert (literal_tags[key.tag], "Invalid key") + else -- Implicit key + len, key, sub_pattern = len+1, `Number{ len+1 }, pattern[i] + end + + -- '...' can only appear in final position + -- Could be fixed actually... + assert (not seen_dots, "Wrongly placed `...' ") + + if sub_pattern.tag == "Id" then + -- Optimization: save a useless [ v(n+1)=v(n).key ] + id_pattern_element_builder (sub_pattern, `Index{ term, key }, cfg) + if sub_pattern[1] ~= "_" then + acc_test (+{ -{sub_pattern} == nil }, cfg) + end + elseif sub_pattern.tag == "Dots" then + -- Remember where the capture is, and thatt arity checking shouldn't occur + seen_dots = true + else + -- Business as usual: + local v2 = next_tmpvar(cfg) + acc_assign (v2, `Index{ term, key }, cfg) + pattern_element_builder (sub_pattern, v2, cfg) + -- TODO: restore ntmp? + end + end + if seen_dots then -- remember how to retrieve `...' + -- FIXME: check, but there might be cases where the variable -{term} + -- will be overridden in contrieved tables. + -- ==> save it now, and clean the setting statement if unused + if cfg.dots_replacement then cfg.dots_replacement = 'ambiguous' + else cfg.dots_replacement = +{ select (-{`Number{len}}, unpack(-{term})) } end + else -- Check arity + acc_test (+{ #-{term} ~= -{`Number{len}} }, cfg) + end +end + +-- mutually recursive with pattern_element_builder +local eq_pattern_element_builder, regexp_pattern_element_builder + +-- Concatenate code in [cfg.code], that will jump to label +-- [cfg.on_failure] if [pattern] doesn't match [term]. [pattern] +-- should be an identifier, or at least cheap to compute and +-- side-effects free. +-- +-- pattern :: pattern_element +-- term :: expr +function pattern_element_builder (pattern, term, cfg) + if literal_tags[pattern.tag] then + acc_test (+{ -{term} ~= -{pattern} }, cfg) + elseif "Id" == pattern.tag then + id_pattern_element_builder (pattern, term, cfg) + elseif "Op" == pattern.tag and "div" == pattern[1] then + regexp_pattern_element_builder (pattern, term, cfg) + elseif "Op" == pattern.tag and "eq" == pattern[1] then + eq_pattern_element_builder (pattern, term, cfg) + elseif "Table" == pattern.tag then + table_pattern_element_builder (pattern, term, cfg) + else + error ("Invalid pattern at ".. + tostring(pattern.lineinfo).. + ": "..pp.tostring(pattern, {hide_hash=true})) + end +end + +function eq_pattern_element_builder (pattern, term, cfg) + local _, pat1, pat2 = unpack (pattern) + local ntmp_save = cfg.ntmp + pattern_element_builder (pat1, term, cfg) + cfg.ntmp = ntmp_save + pattern_element_builder (pat2, term, cfg) +end + +-- pattern :: `Op{ 'div', string, list{`Id string} or `Id{ string }} +-- term :: expr +local function regexp_pattern_element_builder (pattern, term, cfg) + local op, regexp, sub_pattern = unpack(pattern) + + -- Sanity checks -- + assert (op=='div', "Don't know what to do with that op in a pattern") + assert (regexp.tag=="String", + "Left hand side operand for '/' in a pattern must be ".. + "a literal string representing a regular expression") + if sub_pattern.tag=="Table" then + for _, x in ipairs(sub_pattern) do + assert (x.tag=="Id" or x.tag=='Dots', + "Right hand side operand for '/' in a pattern must be ".. + "a list of identifiers") + end + else + assert (sub_pattern.tag=="Id", + "Right hand side operand for '/' in a pattern must be ".. + "an identifier or a list of identifiers") + end + + -- Regexp patterns can only match strings + acc_test (+{ type(-{term}) ~= 'string' }, cfg) + -- put all captures in a list + local capt_list = +{ { string.strmatch(-{term}, -{regexp}) } } + -- save them in a var_n for recursive decomposition + local v2 = next_tmpvar(cfg) + acc_stat (+{stat: local -{v2} = -{capt_list} }, cfg) + -- was capture successful? + acc_test (+{ not next (-{v2}) }, cfg) + pattern_element_builder (sub_pattern, v2, cfg) +end + + +-- Jumps to [cfg.on_faliure] if pattern_seq doesn't match +-- term_seq. +local function pattern_seq_builder (pattern_seq, term_seq, cfg) + if #pattern_seq ~= #term_seq then error ("Bad seq arity") end + cfg.locals = { } -- reset bound variables between alternatives + for i=1, #pattern_seq do + cfg.ntmp = 1 -- reset the tmp var generator + pattern_element_builder(pattern_seq[i], term_seq[i], cfg) + end +end + +-------------------------------------------------- +-- for each case i: +-- pattern_seq_builder_i: +-- * on failure, go to on_failure_i +-- * on success, go to on_success +-- label on_success: +-- block +-- goto after_success +-- label on_failure_i +-------------------------------------------------- +local function case_builder (case, term_seq, cfg) + local patterns_group, guard, block = unpack(case) + local on_success = gg.gensym 'on_success' [1] + for i = 1, #patterns_group do + local pattern_seq = patterns_group[i] + cfg.on_failure = gg.gensym 'match_fail' [1] + cfg.dots_replacement = false + pattern_seq_builder (pattern_seq, term_seq, cfg) + if i<#patterns_group then + acc_stat (`Goto{on_success}, cfg) + acc_stat (`Label{cfg.on_failure}, cfg) + end + end + acc_stat (`Label{on_success}, cfg) + if guard then acc_test (+{not -{guard}}, cfg) end + if cfg.dots_replacement then + replace_dots (block, cfg.dots_replacement) + end + block.tag = 'Do' + acc_stat (block, cfg) + acc_stat (`Goto{cfg.after_success}, cfg) + acc_stat (`Label{cfg.on_failure}, cfg) +end + +local function match_builder (x) + local term_seq, cases = unpack(x) + local cfg = { + code = `Do{ }, + after_success = gg.gensym "_after_success" } + + + -- Some sharing issues occur when modifying term_seq, + -- so it's replaced by a copy new_term_seq. + -- TODO: clean that up, and re-suppress the useless copies + -- (cf. remarks about capture bug below). + local new_term_seq = { } + + local match_locals + + -- Make sure that all tested terms are variables or literals + for i=1, #term_seq do + local t = term_seq[i] + -- Capture problem: the following would compile wrongly: + -- `match x with x -> end' + -- Temporary workaround: suppress the condition, so that + -- all external variables are copied into unique names. + --if t.tag ~= 'Id' and not literal_tags[t.tag] then + local v = gg.gensym 'v' + if not match_locals then match_locals = `Local{ {v}, {t} } else + table.insert(match_locals[1], v) + table.insert(match_locals[2], t) + end + new_term_seq[i] = v + --end + end + term_seq = new_term_seq + + if match_locals then acc_stat(match_locals, cfg) end + + for i=1, #cases do + local case_cfg = { + after_success = cfg.after_success, + code = `Do{ } + -- locals = { } -- unnecessary, done by pattern_seq_builder + } + case_builder (cases[i], term_seq, case_cfg) + if next (case_cfg.locals) then + local case_locals = { } + table.insert (case_cfg.code, 1, `Local{ case_locals, { } }) + for v, _ in pairs (case_cfg.locals) do + table.insert (case_locals, `Id{ v }) + end + end + acc_stat(case_cfg.code, cfg) + end + local li = `String{tostring(cases.lineinfo)} + acc_stat(+{error('mismatch at '..-{li})}, cfg) + acc_stat(`Label{cfg.after_success}, cfg) + return cfg.code +end + +---------------------------------------------------------------------- +-- Syntactical front-end +---------------------------------------------------------------------- + +local function extend(M) + + local _M = gg.future(M) + + checks('metalua.compiler.parser') + M.lexer:add{ "match", "with", "->" } + M.block.terminators:add "|" + + local match_cases_list_parser = gg.list{ name = "match cases list", + gg.sequence{ name = "match case", + gg.list{ name = "match case patterns list", + primary = _M.expr_list, + separators = "|", + terminators = { "->", "if" } }, + gg.onkeyword{ "if", _M.expr, consume = true }, + "->", + _M.block }, + separators = "|", + terminators = "end" } + + M.stat:add{ name = "match statement", + "match", + _M.expr_list, + "with", gg.optkeyword "|", + match_cases_list_parser, + "end", + builder = |x| match_builder{ x[1], x[3] } } +end + +return extend \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/grammar/generator.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/grammar/generator.lua new file mode 100644 index 000000000..2680d8a53 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/grammar/generator.lua @@ -0,0 +1,834 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +-- +-- Summary: parser generator. Collection of higher order functors, +-- which allow to build and combine parsers. Relies on a lexer +-- that supports the same API as the one exposed in mll.lua. +-- +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +-- +-- Exported API: +-- +-- Parser generators: +-- * [gg.sequence()] +-- * [gg.multisequence()] +-- * [gg.expr()] +-- * [gg.list()] +-- * [gg.onkeyword()] +-- * [gg.optkeyword()] +-- +-- Other functions: +-- * [gg.parse_error()] +-- * [gg.make_parser()] +-- * [gg.is_parser()] +-- +-------------------------------------------------------------------------------- + +local M = { } + +local checks = require 'checks' +local lexer = require 'metalua.grammar.lexer' +local pp = require 'metalua.pprint' + +-------------------------------------------------------------------------------- +-- Symbol generator: [gensym()] returns a guaranteed-to-be-unique identifier. +-- The main purpose is to avoid variable capture in macros. +-- +-- If a string is passed as an argument, theis string will be part of the +-- id name (helpful for macro debugging) +-------------------------------------------------------------------------------- +local gensymidx = 0 + +function M.gensym (arg) + gensymidx = gensymidx + 1 + return { tag="Id", string.format(".%i.%s", gensymidx, arg or "")} +end + + +------------------------------------------------------------------------------- +-- parser metatable, which maps __call to method parse, and adds some +-- error tracing boilerplate. +------------------------------------------------------------------------------- +local parser_metatable = { } + +function parser_metatable :__call (lx, ...) + return self :parse (lx, ...) +end + +------------------------------------------------------------------------------- +-- Turn a table into a parser, mainly by setting the metatable. +------------------------------------------------------------------------------- +function M.make_parser(kind, p) + p.kind = kind + if not p.transformers then p.transformers = { } end + function p.transformers:add (x) + table.insert (self, x) + end + setmetatable (p, parser_metatable) + return p +end + +------------------------------------------------------------------------------- +-- Return true iff [x] is a parser. +-- If it's a gg-generated parser, return the name of its kind. +------------------------------------------------------------------------------- +function M.is_parser (x) + return type(x)=="function" or getmetatable(x)==parser_metatable and x.kind +end + +------------------------------------------------------------------------------- +-- Parse a sequence, without applying builder nor transformers. +------------------------------------------------------------------------------- +local function raw_parse_sequence (lx, p) + local r = { } + for i=1, #p do + local e=p[i] + if type(e) == "string" then + local kw = lx :next() + if not lx :is_keyword (kw, e) then + M.parse_error( + lx, "A keyword was expected, probably `%s'.", e) + end + elseif M.is_parser (e) then + table.insert (r, e(lx)) + else -- Invalid parser definition, this is *not* a parsing error + error(string.format( + "Sequence `%s': element #%i is neither a string nor a parser: %s", + p.name, i, pp.tostring(e))) + end + end + return r +end + +------------------------------------------------------------------------------- +-- Parse a multisequence, without applying multisequence transformers. +-- The sequences are completely parsed. +------------------------------------------------------------------------------- +local function raw_parse_multisequence (lx, sequence_table, default) + local seq_parser = sequence_table[lx:is_keyword(lx:peek())] + if seq_parser then return seq_parser (lx) + elseif default then return default (lx) + else return false end +end + +------------------------------------------------------------------------------- +-- Applies all transformers listed in parser on ast. +------------------------------------------------------------------------------- +local function transform (ast, parser, fli, lli) + if parser.transformers then + for _, t in ipairs (parser.transformers) do ast = t(ast) or ast end + end + if type(ast) == 'table' then + local ali = ast.lineinfo + if not ali or ali.first~=fli or ali.last~=lli then + ast.lineinfo = lexer.new_lineinfo(fli, lli) + end + end + return ast +end + +------------------------------------------------------------------------------- +-- Generate a tracable parsing error (not implemented yet) +------------------------------------------------------------------------------- +function M.parse_error(lx, fmt, ...) + local li = lx:lineinfo_left() + local file, line, column, offset, positions + if li then + file, line, column, offset = li.source, li.line, li.column, li.offset + positions = { first = li, last = li } + else + line, column, offset = -1, -1, -1 + end + + local msg = string.format("line %i, char %i: "..fmt, line, column, ...) + if file and file~='?' then msg = "file "..file..", "..msg end + + local src = lx.src + if offset>0 and src then + local i, j = offset, offset + while src:sub(i,i) ~= '\n' and i>=0 do i=i-1 end + while src:sub(j,j) ~= '\n' and j<=#src do j=j+1 end + local srcline = src:sub (i+1, j-1) + local idx = string.rep (" ", column).."^" + msg = string.format("%s\n>>> %s\n>>> %s", msg, srcline, idx) + end + --lx :kill() + error(msg) +end + +------------------------------------------------------------------------------- +-- +-- Sequence parser generator +-- +------------------------------------------------------------------------------- +-- Input fields: +-- +-- * [builder]: how to build an AST out of sequence parts. let [x] be the list +-- of subparser results (keywords are simply omitted). [builder] can be: +-- - [nil], in which case the result of parsing is simply [x] +-- - a string, which is then put as a tag on [x] +-- - a function, which takes [x] as a parameter and returns an AST. +-- +-- * [name]: the name of the parser. Used for debug messages +-- +-- * [transformers]: a list of AST->AST functions, applied in order on ASTs +-- returned by the parser. +-- +-- * Table-part entries corresponds to keywords (strings) and subparsers +-- (function and callable objects). +-- +-- After creation, the following fields are added: +-- * [parse] the parsing function lexer->AST +-- * [kind] == "sequence" +-- * [name] is set, if it wasn't in the input. +-- +------------------------------------------------------------------------------- +function M.sequence (p) + M.make_parser ("sequence", p) + + ------------------------------------------------------------------- + -- Parsing method + ------------------------------------------------------------------- + function p:parse (lx) + + -- Raw parsing: + local fli = lx:lineinfo_right() + local seq = raw_parse_sequence (lx, self) + local lli = lx:lineinfo_left() + + -- Builder application: + local builder, tb = self.builder, type (self.builder) + if tb == "string" then seq.tag = builder + elseif tb == "function" or builder and builder.__call then seq = builder(seq) + elseif builder == nil then -- nothing + else error ("Invalid builder of type "..tb.." in sequence") end + seq = transform (seq, self, fli, lli) + assert (not seq or seq.lineinfo) + return seq + end + + ------------------------------------------------------------------- + -- Construction + ------------------------------------------------------------------- + -- Try to build a proper name + if p.name then + -- don't touch existing name + elseif type(p[1])=="string" then -- find name based on 1st keyword + if #p==1 then p.name=p[1] + elseif type(p[#p])=="string" then + p.name = p[1] .. " ... " .. p[#p] + else p.name = p[1] .. " ..." end + else -- can't find a decent name + p.name = "unnamed_sequence" + end + + return p +end -- + + +------------------------------------------------------------------------------- +-- +-- Multiple, keyword-driven, sequence parser generator +-- +------------------------------------------------------------------------------- +-- in [p], useful fields are: +-- +-- * [transformers]: as usual +-- +-- * [name]: as usual +-- +-- * Table-part entries must be sequence parsers, or tables which can +-- be turned into a sequence parser by [gg.sequence]. These +-- sequences must start with a keyword, and this initial keyword +-- must be different for each sequence. The table-part entries will +-- be removed after [gg.multisequence] returns. +-- +-- * [default]: the parser to run if the next keyword in the lexer is +-- none of the registered initial keywords. If there's no default +-- parser and no suitable initial keyword, the multisequence parser +-- simply returns [false]. +-- +-- After creation, the following fields are added: +-- +-- * [parse] the parsing function lexer->AST +-- +-- * [sequences] the table of sequences, indexed by initial keywords. +-- +-- * [add] method takes a sequence parser or a config table for +-- [gg.sequence], and adds/replaces the corresponding sequence +-- parser. If the keyword was already used, the former sequence is +-- removed and a warning is issued. +-- +-- * [get] method returns a sequence by its initial keyword +-- +-- * [kind] == "multisequence" +-- +------------------------------------------------------------------------------- +function M.multisequence (p) + M.make_parser ("multisequence", p) + + ------------------------------------------------------------------- + -- Add a sequence (might be just a config table for [gg.sequence]) + ------------------------------------------------------------------- + function p :add (s) + -- compile if necessary: + local keyword = type(s)=='table' and s[1] + if type(s)=='table' and not M.is_parser(s) then M.sequence(s) end + if M.is_parser(s)~='sequence' or type(keyword)~='string' then + if self.default then -- two defaults + error ("In a multisequence parser, all but one sequences ".. + "must start with a keyword") + else self.default = s end -- first default + else + if self.sequences[keyword] then -- duplicate keyword + -- TODO: warn that initial keyword `keyword` is overloaded in multiseq + end + self.sequences[keyword] = s + end + end -- + + ------------------------------------------------------------------- + -- Get the sequence starting with this keyword. [kw :: string] + ------------------------------------------------------------------- + function p :get (kw) return self.sequences [kw] end + + ------------------------------------------------------------------- + -- Remove the sequence starting with keyword [kw :: string] + ------------------------------------------------------------------- + function p :del (kw) + if not self.sequences[kw] then + -- TODO: warn that we try to delete a non-existent entry + end + local removed = self.sequences[kw] + self.sequences[kw] = nil + return removed + end + + ------------------------------------------------------------------- + -- Parsing method + ------------------------------------------------------------------- + function p :parse (lx) + local fli = lx:lineinfo_right() + local x = raw_parse_multisequence (lx, self.sequences, self.default) + local lli = lx:lineinfo_left() + return transform (x, self, fli, lli) + end + + ------------------------------------------------------------------- + -- Construction + ------------------------------------------------------------------- + -- Register the sequences passed to the constructor. They're going + -- from the array part of the parser to the hash part of field + -- [sequences] + p.sequences = { } + for i=1, #p do p :add (p[i]); p[i] = nil end + + -- FIXME: why is this commented out? + --if p.default and not is_parser(p.default) then sequence(p.default) end + return p +end -- + + +------------------------------------------------------------------------------- +-- +-- Expression parser generator +-- +------------------------------------------------------------------------------- +-- +-- Expression configuration relies on three tables: [prefix], [infix] +-- and [suffix]. Moreover, the primary parser can be replaced by a +-- table: in this case the [primary] table will be passed to +-- [gg.multisequence] to create a parser. +-- +-- Each of these tables is a modified multisequence parser: the +-- differences with respect to regular multisequence config tables are: +-- +-- * the builder takes specific parameters: +-- - for [prefix], it takes the result of the prefix sequence parser, +-- and the prefixed expression +-- - for [infix], it takes the left-hand-side expression, the results +-- of the infix sequence parser, and the right-hand-side expression. +-- - for [suffix], it takes the suffixed expression, and the result +-- of the suffix sequence parser. +-- +-- * the default field is a list, with parameters: +-- - [parser] the raw parsing function +-- - [transformers], as usual +-- - [prec], the operator's precedence +-- - [assoc] for [infix] table, the operator's associativity, which +-- can be "left", "right" or "flat" (default to left) +-- +-- In [p], useful fields are: +-- * [transformers]: as usual +-- * [name]: as usual +-- * [primary]: the atomic expression parser, or a multisequence config +-- table (mandatory) +-- * [prefix]: prefix operators config table, see above. +-- * [infix]: infix operators config table, see above. +-- * [suffix]: suffix operators config table, see above. +-- +-- After creation, these fields are added: +-- * [kind] == "expr" +-- * [parse] as usual +-- * each table is turned into a multisequence, and therefore has an +-- [add] method +-- +------------------------------------------------------------------------------- +function M.expr (p) + M.make_parser ("expr", p) + + ------------------------------------------------------------------- + -- parser method. + -- In addition to the lexer, it takes an optional precedence: + -- it won't read expressions whose precedence is lower or equal + -- to [prec]. + ------------------------------------------------------------------- + function p :parse (lx, prec) + prec = prec or 0 + + ------------------------------------------------------ + -- Extract the right parser and the corresponding + -- options table, for (pre|in|suff)fix operators. + -- Options include prec, assoc, transformers. + ------------------------------------------------------ + local function get_parser_info (tab) + local p2 = tab :get (lx :is_keyword (lx :peek())) + if p2 then -- keyword-based sequence found + local function parser(lx) return raw_parse_sequence(lx, p2) end + return parser, p2 + else -- Got to use the default parser + local d = tab.default + if d then return d.parse or d.parser, d + else return false, false end + end + end + + ------------------------------------------------------ + -- Look for a prefix sequence. Multiple prefixes are + -- handled through the recursive [p.parse] call. + -- Notice the double-transform: one for the primary + -- expr, and one for the one with the prefix op. + ------------------------------------------------------ + local function handle_prefix () + local fli = lx :lineinfo_right() + local p2_func, p2 = get_parser_info (self.prefix) + local op = p2_func and p2_func (lx) + if op then -- Keyword-based sequence found + local ili = lx :lineinfo_right() -- Intermediate LineInfo + local e = p2.builder (op, self :parse (lx, p2.prec)) + local lli = lx :lineinfo_left() + return transform (transform (e, p2, ili, lli), self, fli, lli) + else -- No prefix found, get a primary expression + local e = self.primary(lx) + local lli = lx :lineinfo_left() + return transform (e, self, fli, lli) + end + end -- + + ------------------------------------------------------ + -- Look for an infix sequence+right-hand-side operand. + -- Return the whole binary expression result, + -- or false if no operator was found. + ------------------------------------------------------ + local function handle_infix (e) + local p2_func, p2 = get_parser_info (self.infix) + if not p2 then return false end + + ----------------------------------------- + -- Handle flattening operators: gather all operands + -- of the series in [list]; when a different operator + -- is found, stop, build from [list], [transform] and + -- return. + ----------------------------------------- + if (not p2.prec or p2.prec>prec) and p2.assoc=="flat" then + local fli = lx:lineinfo_right() + local pflat, list = p2, { e } + repeat + local op = p2_func(lx) + if not op then break end + table.insert (list, self:parse (lx, p2.prec)) + local _ -- We only care about checking that p2==pflat + _, p2 = get_parser_info (self.infix) + until p2 ~= pflat + local e2 = pflat.builder (list) + local lli = lx:lineinfo_left() + return transform (transform (e2, pflat, fli, lli), self, fli, lli) + + ----------------------------------------- + -- Handle regular infix operators: [e] the LHS is known, + -- just gather the operator and [e2] the RHS. + -- Result goes in [e3]. + ----------------------------------------- + elseif p2.prec and p2.prec>prec or + p2.prec==prec and p2.assoc=="right" then + local fli = e.lineinfo.first -- lx:lineinfo_right() + local op = p2_func(lx) + if not op then return false end + local e2 = self:parse (lx, p2.prec) + local e3 = p2.builder (e, op, e2) + local lli = lx:lineinfo_left() + return transform (transform (e3, p2, fli, lli), self, fli, lli) + + ----------------------------------------- + -- Check for non-associative operators, and complain if applicable. + ----------------------------------------- + elseif p2.assoc=="none" and p2.prec==prec then + M.parse_error (lx, "non-associative operator!") + + ----------------------------------------- + -- No infix operator suitable at that precedence + ----------------------------------------- + else return false end + + end -- + + ------------------------------------------------------ + -- Look for a suffix sequence. + -- Return the result of suffix operator on [e], + -- or false if no operator was found. + ------------------------------------------------------ + local function handle_suffix (e) + -- FIXME bad fli, must take e.lineinfo.first + local p2_func, p2 = get_parser_info (self.suffix) + if not p2 then return false end + if not p2.prec or p2.prec>=prec then + --local fli = lx:lineinfo_right() + local fli = e.lineinfo.first + local op = p2_func(lx) + if not op then return false end + local lli = lx:lineinfo_left() + e = p2.builder (e, op) + e = transform (transform (e, p2, fli, lli), self, fli, lli) + return e + end + return false + end -- + + ------------------------------------------------------ + -- Parser body: read suffix and (infix+operand) + -- extensions as long as we're able to fetch more at + -- this precedence level. + ------------------------------------------------------ + local e = handle_prefix() + repeat + local x = handle_suffix (e); e = x or e + local y = handle_infix (e); e = y or e + until not (x or y) + + -- No transform: it already happened in operators handling + return e + end -- + + ------------------------------------------------------------------- + -- Construction + ------------------------------------------------------------------- + if not p.primary then p.primary=p[1]; p[1]=nil end + for _, t in ipairs{ "primary", "prefix", "infix", "suffix" } do + if not p[t] then p[t] = { } end + if not M.is_parser(p[t]) then M.multisequence(p[t]) end + end + function p:add(...) return self.primary:add(...) end + return p +end -- + + +------------------------------------------------------------------------------- +-- +-- List parser generator +-- +------------------------------------------------------------------------------- +-- In [p], the following fields can be provided in input: +-- +-- * [builder]: takes list of subparser results, returns AST +-- * [transformers]: as usual +-- * [name]: as usual +-- +-- * [terminators]: list of strings representing the keywords which +-- might mark the end of the list. When non-empty, the list is +-- allowed to be empty. A string is treated as a single-element +-- table, whose element is that string, e.g. ["do"] is the same as +-- [{"do"}]. +-- +-- * [separators]: list of strings representing the keywords which can +-- separate elements of the list. When non-empty, one of these +-- keyword has to be found between each element. Lack of a separator +-- indicates the end of the list. A string is treated as a +-- single-element table, whose element is that string, e.g. ["do"] +-- is the same as [{"do"}]. If [terminators] is empty/nil, then +-- [separators] has to be non-empty. +-- +-- After creation, the following fields are added: +-- * [parse] the parsing function lexer->AST +-- * [kind] == "list" +-- +------------------------------------------------------------------------------- +function M.list (p) + M.make_parser ("list", p) + + ------------------------------------------------------------------- + -- Parsing method + ------------------------------------------------------------------- + function p :parse (lx) + + ------------------------------------------------------ + -- Used to quickly check whether there's a terminator + -- or a separator immediately ahead + ------------------------------------------------------ + local function peek_is_in (keywords) + return keywords and lx:is_keyword(lx:peek(), unpack(keywords)) end + + local x = { } + local fli = lx :lineinfo_right() + + -- if there's a terminator to start with, don't bother trying + local is_empty_list = self.terminators and (peek_is_in (self.terminators) or lx:peek().tag=="Eof") + if not is_empty_list then + repeat + local item = self.primary(lx) + table.insert (x, item) -- read one element + until + -- There's a separator list specified, and next token isn't in it. + -- Otherwise, consume it with [lx:next()] + self.separators and not(peek_is_in (self.separators) and lx:next()) or + -- Terminator token ahead + peek_is_in (self.terminators) or + -- Last reason: end of file reached + lx:peek().tag=="Eof" + end + + local lli = lx:lineinfo_left() + + -- Apply the builder. It can be a string, or a callable value, + -- or simply nothing. + local b = self.builder + if b then + if type(b)=="string" then x.tag = b -- b is a string, use it as a tag + elseif type(b)=="function" then x=b(x) + else + local bmt = getmetatable(b) + if bmt and bmt.__call then x=b(x) end + end + end + return transform (x, self, fli, lli) + end -- + + ------------------------------------------------------------------- + -- Construction + ------------------------------------------------------------------- + if not p.primary then p.primary = p[1]; p[1] = nil end + if type(p.terminators) == "string" then p.terminators = { p.terminators } + elseif p.terminators and #p.terminators == 0 then p.terminators = nil end + if type(p.separators) == "string" then p.separators = { p.separators } + elseif p.separators and #p.separators == 0 then p.separators = nil end + + return p +end -- + + +------------------------------------------------------------------------------- +-- +-- Keyword-conditioned parser generator +-- +------------------------------------------------------------------------------- +-- +-- Only apply a parser if a given keyword is found. The result of +-- [gg.onkeyword] parser is the result of the subparser (modulo +-- [transformers] applications). +-- +-- lineinfo: the keyword is *not* included in the boundaries of the +-- resulting lineinfo. A review of all usages of gg.onkeyword() in the +-- implementation of metalua has shown that it was the appropriate choice +-- in every case. +-- +-- Input fields: +-- +-- * [name]: as usual +-- +-- * [transformers]: as usual +-- +-- * [peek]: if non-nil, the conditioning keyword is left in the lexeme +-- stream instead of being consumed. +-- +-- * [primary]: the subparser. +-- +-- * [keywords]: list of strings representing triggering keywords. +-- +-- * Table-part entries can contain strings, and/or exactly one parser. +-- Strings are put in [keywords], and the parser is put in [primary]. +-- +-- After the call, the following fields will be set: +-- +-- * [parse] the parsing method +-- * [kind] == "onkeyword" +-- * [primary] +-- * [keywords] +-- +------------------------------------------------------------------------------- +function M.onkeyword (p) + M.make_parser ("onkeyword", p) + + ------------------------------------------------------------------- + -- Parsing method + ------------------------------------------------------------------- + function p :parse (lx) + if lx :is_keyword (lx:peek(), unpack(self.keywords)) then + local fli = lx:lineinfo_right() + if not self.peek then lx:next() end + local content = self.primary (lx) + local lli = lx:lineinfo_left() + local li = content.lineinfo or { } + fli, lli = li.first or fli, li.last or lli + return transform (content, p, fli, lli) + else return false end + end + + ------------------------------------------------------------------- + -- Construction + ------------------------------------------------------------------- + if not p.keywords then p.keywords = { } end + for _, x in ipairs(p) do + if type(x)=="string" then table.insert (p.keywords, x) + else assert (not p.primary and M.is_parser (x)); p.primary = x end + end + assert (next (p.keywords), "Missing trigger keyword in gg.onkeyword") + assert (p.primary, 'no primary parser in gg.onkeyword') + return p +end -- + + +------------------------------------------------------------------------------- +-- +-- Optional keyword consummer pseudo-parser generator +-- +------------------------------------------------------------------------------- +-- +-- This doesn't return a real parser, just a function. That function parses +-- one of the keywords passed as parameters, and returns it. It returns +-- [false] if no matching keyword is found. +-- +-- Notice that tokens returned by lexer already carry lineinfo, therefore +-- there's no need to add them, as done usually through transform() calls. +------------------------------------------------------------------------------- +function M.optkeyword (...) + local args = {...} + if type (args[1]) == "table" then + assert (#args == 1) + args = args[1] + end + for _, v in ipairs(args) do assert (type(v)=="string") end + return function (lx) + local x = lx:is_keyword (lx:peek(), unpack (args)) + if x then lx:next(); return x + else return false end + end +end + + +------------------------------------------------------------------------------- +-- +-- Run a parser with a special lexer +-- +------------------------------------------------------------------------------- +-- +-- This doesn't return a real parser, just a function. +-- First argument is the lexer class to be used with the parser, +-- 2nd is the parser itself. +-- The resulting parser returns whatever the argument parser does. +-- +------------------------------------------------------------------------------- +function M.with_lexer(new_lexer, parser) + + ------------------------------------------------------------------- + -- Most gg functions take their parameters in a table, so it's + -- better to silently accept when with_lexer{ } is called with + -- its arguments in a list: + ------------------------------------------------------------------- + if not parser and #new_lexer==2 and type(new_lexer[1])=='table' then + return M.with_lexer(unpack(new_lexer)) + end + + ------------------------------------------------------------------- + -- Save the current lexer, switch it for the new one, run the parser, + -- restore the previous lexer, even if the parser caused an error. + ------------------------------------------------------------------- + return function (lx) + local old_lexer = getmetatable(lx) + lx:sync() + setmetatable(lx, new_lexer) + local status, result = pcall(parser, lx) + lx:sync() + setmetatable(lx, old_lexer) + if status then return result else error(result) end + end +end + +-------------------------------------------------------------------------------- +-- +-- Make sure a parser is used and returns successfully. +-- +-------------------------------------------------------------------------------- +function M.nonempty(primary) + local p = M.make_parser('non-empty list', { primary = primary, name=primary.name }) + function p :parse (lx) + local fli = lx:lineinfo_right() + local content = self.primary (lx) + local lli = lx:lineinfo_left() + local li = content.lineinfo or { } + fli, lli = li.first or fli, li.last or lli + if #content == 0 then + M.parse_error (lx, "`%s' must not be empty.", self.name or "list") + else + return transform (content, self, fli, lli) + end + end + return p +end + +local FUTURE_MT = { } +function FUTURE_MT:__tostring() return "" end +function FUTURE_MT:__newindex(key, value) error "don't write in futures" end +function FUTURE_MT :__index (parser_name) + return function(...) + local p, m = rawget(self, '__path'), self.__module + if p then for _, name in ipairs(p) do + m=rawget(m, name) + if not m then error ("Submodule '"..name.."' undefined") end + end end + local f = rawget(m, parser_name) + if not f then error ("Parser '"..parser_name.."' undefined") end + return f(...) + end +end + +function M.future(module, ...) + checks('table') + local path = ... and {...} + if path then for _, x in ipairs(path) do + assert(type(x)=='string', "Bad future arg") + end end + local self = { __module = module, + __path = path } + return setmetatable(self, FUTURE_MT) +end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/grammar/lexer.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/grammar/lexer.lua new file mode 100644 index 000000000..0f96f8edf --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/grammar/lexer.lua @@ -0,0 +1,672 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +local checks = require 'checks' + +local M = { } + +local lexer = { alpha={ }, sym={ } } +lexer.__index=lexer +lexer.__type='lexer.stream' + +M.lexer = lexer + + +local debugf = function() end +-- local debugf=printf + +---------------------------------------------------------------------- +-- Some locale settings produce bad results, e.g. French locale +-- expect float numbers to use commas instead of periods. +-- TODO: change number parser into something loclae-independent, +-- locales are nasty. +---------------------------------------------------------------------- +os.setlocale('C') + +local MT = { } + +M.metatables=MT + +---------------------------------------------------------------------- +-- Create a new metatable, for a new class of objects. +---------------------------------------------------------------------- +local function new_metatable(name) + local mt = { __type = 'lexer.'..name }; + mt.__index = mt + MT[name] = mt +end + + +---------------------------------------------------------------------- +-- Position: represent a point in a source file. +---------------------------------------------------------------------- +new_metatable 'position' + +local position_idx=1 + +function M.new_position(line, column, offset, source) + checks('number', 'number', 'number', 'string') + local id = position_idx; position_idx = position_idx+1 + return setmetatable({line=line, column=column, offset=offset, + source=source, id=id}, MT.position) +end + +function MT.position :__tostring() + return string.format("<%s%s|L%d|C%d|K%d>", + self.comments and "C|" or "", + self.source, self.line, self.column, self.offset) +end + + + +---------------------------------------------------------------------- +-- Position factory: convert offsets into line/column/offset positions. +---------------------------------------------------------------------- +new_metatable 'position_factory' + +function M.new_position_factory(src, src_name) + -- assert(type(src)=='string') + -- assert(type(src_name)=='string') + local lines = { 1 } + for offset in src :gmatch '\n()' do table.insert(lines, offset) end + local max = #src+1 + table.insert(lines, max+1) -- +1 includes Eof + return setmetatable({ src_name=src_name, line2offset=lines, max=max }, + MT.position_factory) +end + +function MT.position_factory :get_position (offset) + -- assert(type(offset)=='number') + assert(offset<=self.max) + local line2offset = self.line2offset + local left = self.last_left or 1 + if offset", + fli.comments and "C|" or "", + fli.source, line, column, offset, + lli.comments and "|C" or "") +end + +---------------------------------------------------------------------- +-- Token: atomic Lua language element, with a category, a content, +-- and some lineinfo relating it to its original source. +---------------------------------------------------------------------- +new_metatable 'token' + +function M.new_token(tag, content, lineinfo) + --printf("TOKEN `%s{ %q, lineinfo = %s} boundaries %d, %d", + -- tag, content, tostring(lineinfo), lineinfo.first.id, lineinfo.last.id) + return setmetatable({tag=tag, lineinfo=lineinfo, content}, MT.token) +end + +function MT.token :__tostring() + --return string.format("`%s{ %q, %s }", self.tag, self[1], tostring(self.lineinfo)) + return string.format("`%s %q", self.tag, self[1]) +end + + +---------------------------------------------------------------------- +-- Comment: series of comment blocks with associated lineinfo. +-- To be attached to the tokens just before and just after them. +---------------------------------------------------------------------- +new_metatable 'comment' + +function M.new_comment(lines) + local first = lines[1].lineinfo.first + local last = lines[#lines].lineinfo.last + local lineinfo = M.new_lineinfo(first, last) + return setmetatable({lineinfo=lineinfo, unpack(lines)}, MT.comment) +end + +function MT.comment :text() + local last_line = self[1].lineinfo.last.line + local acc = { } + for i, line in ipairs(self) do + local nreturns = line.lineinfo.first.line - last_line + table.insert(acc, ("\n"):rep(nreturns)) + table.insert(acc, line[1]) + end + return table.concat(acc) +end + +function M.new_comment_line(text, lineinfo, nequals) + checks('string', 'lexer.lineinfo', '?number') + return { lineinfo = lineinfo, text, nequals } +end + + + +---------------------------------------------------------------------- +-- Patterns used by [lexer :extract] to decompose the raw string into +-- correctly tagged tokens. +---------------------------------------------------------------------- +lexer.patterns = { + spaces = "^[ \r\n\t]*()", + short_comment = "^%-%-([^\n]*)\n?()", + --final_short_comment = "^%-%-([^\n]*)()$", + long_comment = "^%-%-%[(=*)%[\n?(.-)%]%1%]()", + long_string = "^%[(=*)%[\n?(.-)%]%1%]()", + number_mantissa = { "^%d+%.?%d*()", "^%d*%.%d+()" }, + number_mantissa_hex = { "^%x+%.?%x*()", "^%x*%.%x+()" }, --Lua5.1 and Lua5.2 + number_exponant = "^[eE][%+%-]?%d+()", + number_exponant_hex = "^[pP][%+%-]?%d+()", --Lua5.2 + number_hex = "^0[xX]()", + word = "^([%a_][%w_]*)()" +} + +---------------------------------------------------------------------- +-- unescape a whole string, applying [unesc_digits] and +-- [unesc_letter] as many times as required. +---------------------------------------------------------------------- +local function unescape_string (s) + + -- Turn the digits of an escape sequence into the corresponding + -- character, e.g. [unesc_digits("123") == string.char(123)]. + local function unesc_digits (backslashes, digits) + if #backslashes%2==0 then + -- Even number of backslashes, they escape each other, not the digits. + -- Return them so that unesc_letter() can treat them + return backslashes..digits + else + -- Remove the odd backslash, which escapes the number sequence. + -- The rest will be returned and parsed by unesc_letter() + backslashes = backslashes :sub (1,-2) + end + local k, j, i = digits :reverse() :byte(1, 3) + local z = string.byte "0" + local code = (k or z) + 10*(j or z) + 100*(i or z) - 111*z + if code > 255 then + error ("Illegal escape sequence '\\"..digits.. + "' in string: ASCII codes must be in [0..255]") + end + local c = string.char (code) + if c == '\\' then c = '\\\\' end -- parsed by unesc_letter (test: "\092b" --> "\\b") + return backslashes..c + end + + -- Turn hex digits of escape sequence into char. + local function unesc_hex(backslashes, digits) + if #backslashes%2==0 then + return backslashes..'x'..digits + else + backslashes = backslashes :sub (1,-2) + end + local c = string.char(tonumber(digits,16)) + if c == '\\' then c = '\\\\' end -- parsed by unesc_letter (test: "\x5cb" --> "\\b") + return backslashes..c + end + + -- Handle Lua 5.2 \z sequences + local function unesc_z(backslashes, more) + if #backslashes%2==0 then + return backslashes..more + else + return backslashes :sub (1,-2) + end + end + + -- Take a letter [x], and returns the character represented by the + -- sequence ['\\'..x], e.g. [unesc_letter "n" == "\n"]. + local function unesc_letter(x) + local t = { + a = "\a", b = "\b", f = "\f", + n = "\n", r = "\r", t = "\t", v = "\v", + ["\\"] = "\\", ["'"] = "'", ['"'] = '"', ["\n"] = "\n" } + return t[x] or x + end + + s = s: gsub ("(\\+)(z%s*)", unesc_z) -- Lua 5.2 + s = s: gsub ("(\\+)([0-9][0-9]?[0-9]?)", unesc_digits) + s = s: gsub ("(\\+)x([0-9a-fA-F][0-9a-fA-F])", unesc_hex) -- Lua 5.2 + s = s: gsub ("\\(%D)",unesc_letter) + return s +end + +lexer.extractors = { + "extract_long_comment", "extract_short_comment", + "extract_short_string", "extract_word", "extract_number", + "extract_long_string", "extract_symbol" } + + + +---------------------------------------------------------------------- +-- Really extract next token from the raw string +-- (and update the index). +-- loc: offset of the position just after spaces and comments +-- previous_i: offset in src before extraction began +---------------------------------------------------------------------- +function lexer :extract () + local attached_comments = { } + local function gen_token(...) + local token = M.new_token(...) + if #attached_comments>0 then -- attach previous comments to token + local comments = M.new_comment(attached_comments) + token.lineinfo.first.comments = comments + if self.lineinfo_last_extracted then + self.lineinfo_last_extracted.comments = comments + end + attached_comments = { } + end + token.lineinfo.first.facing = self.lineinfo_last_extracted + self.lineinfo_last_extracted.facing = assert(token.lineinfo.first) + self.lineinfo_last_extracted = assert(token.lineinfo.last) + return token + end + while true do -- loop until a non-comment token is found + + -- skip whitespaces + self.i = self.src:match (self.patterns.spaces, self.i) + if self.i>#self.src then + local fli = self.posfact :get_position (#self.src+1) + local lli = self.posfact :get_position (#self.src+1) -- ok? + local tok = gen_token("Eof", "eof", M.new_lineinfo(fli, lli)) + tok.lineinfo.last.facing = lli + return tok + end + local i_first = self.i -- loc = position after whitespaces + + -- try every extractor until a token is found + for _, extractor in ipairs(self.extractors) do + local tag, content, xtra = self [extractor] (self) + if tag then + local fli = self.posfact :get_position (i_first) + local lli = self.posfact :get_position (self.i-1) + local lineinfo = M.new_lineinfo(fli, lli) + if tag=='Comment' then + local prev_comment = attached_comments[#attached_comments] + if not xtra -- new comment is short + and prev_comment and not prev_comment[2] -- prev comment is short + and prev_comment.lineinfo.last.line+1==fli.line then -- adjascent lines + -- concat with previous comment + prev_comment[1] = prev_comment[1].."\n"..content -- TODO quadratic, BAD! + prev_comment.lineinfo.last = lli + else -- accumulate comment + local comment = M.new_comment_line(content, lineinfo, xtra) + table.insert(attached_comments, comment) + end + break -- back to skipping spaces + else -- not a comment: real token, then + return gen_token(tag, content, lineinfo) + end -- if token is a comment + end -- if token found + end -- for each extractor + end -- while token is a comment +end -- :extract() + + + + +---------------------------------------------------------------------- +-- Extract a short comment. +---------------------------------------------------------------------- +function lexer :extract_short_comment() + -- TODO: handle final_short_comment + local content, j = self.src :match (self.patterns.short_comment, self.i) + if content then self.i=j; return 'Comment', content, nil end +end + +---------------------------------------------------------------------- +-- Extract a long comment. +---------------------------------------------------------------------- +function lexer :extract_long_comment() + local equals, content, j = self.src:match (self.patterns.long_comment, self.i) + if j then self.i = j; return "Comment", content, #equals end +end + +---------------------------------------------------------------------- +-- Extract a '...' or "..." short string. +---------------------------------------------------------------------- +function lexer :extract_short_string() + local k = self.src :sub (self.i,self.i) -- first char + if k~=[[']] and k~=[["]] then return end -- no match' + local i = self.i + 1 + local j = i + while true do + local x,y; x, j, y = self.src :match ("([\\\r\n"..k.."])()(.?)", j) -- next interesting char + if x == '\\' then + if y == 'z' then -- Lua 5.2 \z + j = self.src :match ("^%s*()", j+1) + else + j=j+1 -- escaped char + end + elseif x == k then break -- end of string + else + assert (not x or x=='\r' or x=='\n') + return nil, 'Unterminated string' + end + end + self.i = j + + return 'String', unescape_string (self.src :sub (i,j-2)) +end + +---------------------------------------------------------------------- +-- Extract Id or Keyword. +---------------------------------------------------------------------- +function lexer :extract_word() + local word, j = self.src:match (self.patterns.word, self.i) + if word then + self.i = j + return (self.alpha [word] and 'Keyword' or 'Id'), word + end +end + +---------------------------------------------------------------------- +-- Extract Number. +---------------------------------------------------------------------- +function lexer :extract_number() + local j = self.src:match(self.patterns.number_hex, self.i) + if j then + j = self.src:match (self.patterns.number_mantissa_hex[1], j) or + self.src:match (self.patterns.number_mantissa_hex[2], j) + if j then + j = self.src:match (self.patterns.number_exponant_hex, j) or j + end + else + j = self.src:match (self.patterns.number_mantissa[1], self.i) or + self.src:match (self.patterns.number_mantissa[2], self.i) + if j then + j = self.src:match (self.patterns.number_exponant, j) or j + end + end + if not j then return end + -- Number found, interpret with tonumber() and return it + local str = self.src:sub (self.i, j-1) + -- :TODO: tonumber on Lua5.2 floating hex may or may not work on Lua5.1 + local n = tonumber (str) + if not n then error(str.." is not a valid number according to tonumber()") end + self.i = j + return 'Number', n +end + +---------------------------------------------------------------------- +-- Extract long string. +---------------------------------------------------------------------- +function lexer :extract_long_string() + local _, content, j = self.src :match (self.patterns.long_string, self.i) + if j then self.i = j; return 'String', content end +end + +---------------------------------------------------------------------- +-- Extract symbol. +---------------------------------------------------------------------- +function lexer :extract_symbol() + local k = self.src:sub (self.i,self.i) + local symk = self.sym [k] -- symbols starting with `k` + if not symk then + self.i = self.i + 1 + return 'Keyword', k + end + for _, sym in pairs (symk) do + if sym == self.src:sub (self.i, self.i + #sym - 1) then + self.i = self.i + #sym + return 'Keyword', sym + end + end + self.i = self.i+1 + return 'Keyword', k +end + +---------------------------------------------------------------------- +-- Add a keyword to the list of keywords recognized by the lexer. +---------------------------------------------------------------------- +function lexer :add (w, ...) + assert(not ..., "lexer :add() takes only one arg, although possibly a table") + if type (w) == "table" then + for _, x in ipairs (w) do self :add (x) end + else + if w:match (self.patterns.word .. "$") then self.alpha [w] = true + elseif w:match "^%p%p+$" then + local k = w:sub(1,1) + local list = self.sym [k] + if not list then list = { }; self.sym [k] = list end + table.insert (list, w) + elseif w:match "^%p$" then return + else error "Invalid keyword" end + end +end + +---------------------------------------------------------------------- +-- Return the [n]th next token, without consuming it. +-- [n] defaults to 1. If it goes pass the end of the stream, an EOF +-- token is returned. +---------------------------------------------------------------------- +function lexer :peek (n) + if not n then n=1 end + if n > #self.peeked then + for i = #self.peeked+1, n do + self.peeked [i] = self :extract() + end + end + return self.peeked [n] +end + +---------------------------------------------------------------------- +-- Return the [n]th next token, removing it as well as the 0..n-1 +-- previous tokens. [n] defaults to 1. If it goes pass the end of the +-- stream, an EOF token is returned. +---------------------------------------------------------------------- +function lexer :next (n) + n = n or 1 + self :peek (n) + local a + for i=1,n do + a = table.remove (self.peeked, 1) + -- TODO: is this used anywhere? I think not. a.lineinfo.last may be nil. + --self.lastline = a.lineinfo.last.line + end + self.lineinfo_last_consumed = a.lineinfo.last + return a +end + +---------------------------------------------------------------------- +-- Returns an object which saves the stream's current state. +---------------------------------------------------------------------- +-- FIXME there are more fields than that to save +function lexer :save () return { self.i; {unpack(self.peeked) } } end + +---------------------------------------------------------------------- +-- Restore the stream's state, as saved by method [save]. +---------------------------------------------------------------------- +-- FIXME there are more fields than that to restore +function lexer :restore (s) self.i=s[1]; self.peeked=s[2] end + +---------------------------------------------------------------------- +-- Resynchronize: cancel any token in self.peeked, by emptying the +-- list and resetting the indexes +---------------------------------------------------------------------- +function lexer :sync() + local p1 = self.peeked[1] + if p1 then + local li_first = p1.lineinfo.first + if li_first.comments then li_first=li_first.comments.lineinfo.first end + self.i = li_first.offset + self.column_offset = self.i - li_first.column + self.peeked = { } + self.attached_comments = p1.lineinfo.first.comments or { } + end +end + +---------------------------------------------------------------------- +-- Take the source and offset of an old lexer. +---------------------------------------------------------------------- +function lexer :takeover(old) + self :sync(); old :sync() + for _, field in ipairs{ 'i', 'src', 'attached_comments', 'posfact' } do + self[field] = old[field] + end + return self +end + +---------------------------------------------------------------------- +-- Return the current position in the sources. This position is between +-- two tokens, and can be within a space / comment area, and therefore +-- have a non-null width. :lineinfo_left() returns the beginning of the +-- separation area, :lineinfo_right() returns the end of that area. +-- +-- ____ last consummed token ____ first unconsummed token +-- / / +-- XXXXX YYYYY +-- \____ \____ +-- :lineinfo_left() :lineinfo_right() +---------------------------------------------------------------------- +function lexer :lineinfo_right() + return self :peek(1).lineinfo.first +end + +function lexer :lineinfo_left() + return self.lineinfo_last_consumed +end + +---------------------------------------------------------------------- +-- Create a new lexstream. +---------------------------------------------------------------------- +function lexer :newstream (src_or_stream, name) + name = name or "?" + if type(src_or_stream)=='table' then -- it's a stream + return setmetatable ({ }, self) :takeover (src_or_stream) + elseif type(src_or_stream)=='string' then -- it's a source string + local src = src_or_stream + local pos1 = M.new_position(1, 1, 1, name) + local stream = { + src_name = name; -- Name of the file + src = src; -- The source, as a single string + peeked = { }; -- Already peeked, but not discarded yet, tokens + i = 1; -- Character offset in src + attached_comments = { },-- comments accumulator + lineinfo_last_extracted = pos1, + lineinfo_last_consumed = pos1, + posfact = M.new_position_factory (src_or_stream, name) + } + setmetatable (stream, self) + + -- Skip initial sharp-bang for Unix scripts + -- FIXME: redundant with mlp.chunk() + if src and src :match "^#!" then + local endofline = src :find "\n" + stream.i = endofline and (endofline + 1) or #src + end + return stream + else + assert(false, ":newstream() takes a source string or a stream, not a ".. + type(src_or_stream)) + end +end + +---------------------------------------------------------------------- +-- If there's no ... args, return the token a (whose truth value is +-- true) if it's a `Keyword{ }, or nil. If there are ... args, they +-- have to be strings. if the token a is a keyword, and it's content +-- is one of the ... args, then returns it (it's truth value is +-- true). If no a keyword or not in ..., return nil. +---------------------------------------------------------------------- +function lexer :is_keyword (a, ...) + if not a or a.tag ~= "Keyword" then return false end + local words = {...} + if #words == 0 then return a[1] end + for _, w in ipairs (words) do + if w == a[1] then return w end + end + return false +end + +---------------------------------------------------------------------- +-- Cause an error if the next token isn't a keyword whose content +-- is listed among ... args (which have to be strings). +---------------------------------------------------------------------- +function lexer :check (...) + local words = {...} + local a = self :next() + local function err () + error ("Got " .. tostring (a) .. + ", expected one of these keywords : '" .. + table.concat (words,"', '") .. "'") end + if not a or a.tag ~= "Keyword" then err () end + if #words == 0 then return a[1] end + for _, w in ipairs (words) do + if w == a[1] then return w end + end + err () +end + +---------------------------------------------------------------------- +-- +---------------------------------------------------------------------- +function lexer :clone() + local alpha_clone, sym_clone = { }, { } + for word in pairs(self.alpha) do alpha_clone[word]=true end + for letter, list in pairs(self.sym) do sym_clone[letter] = { unpack(list) } end + local clone = { alpha=alpha_clone, sym=sym_clone } + setmetatable(clone, self) + clone.__index = clone + return clone +end + +---------------------------------------------------------------------- +-- Cancel everything left in a lexer, all subsequent attempts at +-- `:peek()` or `:next()` will return `Eof`. +---------------------------------------------------------------------- +function lexer :kill() + self.i = #self.src+1 + self.peeked = { } + self.attached_comments = { } + self.lineinfo_last = self.posfact :get_position (#self.src+1) +end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/loader.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/loader.lua new file mode 100644 index 000000000..e535fef32 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/loader.lua @@ -0,0 +1,133 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +-------------------------------------------------------------------------------- + +local M = require "package" -- extend Lua's basic "package" module +local checks = require 'checks' + +M.metalua_extension_prefix = 'metalua.extension.' + +-- Initialize package.mpath from package.path +M.mpath = M.mpath or os.getenv 'LUA_MPATH' or + (M.path..";") :gsub("%.(lua[:;])", ".m%1") :sub(1, -2) + +M.mcache = M.mcache or os.getenv 'LUA_MCACHE' + +---------------------------------------------------------------------- +-- resc(k) returns "%"..k if it's a special regular expression char, +-- or just k if it's normal. +---------------------------------------------------------------------- +local regexp_magic = { } +for k in ("^$()%.[]*+-?") :gmatch "." do regexp_magic[k]="%"..k end + +local function resc(k) return regexp_magic[k] or k end + +---------------------------------------------------------------------- +-- Take a Lua module name, return the open file and its name, +-- or and an error message. +---------------------------------------------------------------------- +function M.findfile(name, path_string) + local config_regexp = ("([^\n])\n"):rep(5):sub(1, -2) + local dir_sep, path_sep, path_mark, execdir, igmark = + M.config :match (config_regexp) + name = name:gsub ('%.', dir_sep) + local errors = { } + local path_pattern = string.format('[^%s]+', resc(path_sep)) + for path in path_string:gmatch (path_pattern) do + --printf('path = %s, rpath_mark=%s, name=%s', path, resc(path_mark), name) + local filename = path:gsub (resc (path_mark), name) + --printf('filename = %s', filename) + local file = io.open (filename, 'rb') + if file then return file, filename end + table.insert(errors, string.format("\tno file %q", filename)) + end + return false, '\n'..table.concat(errors, "\n")..'\n' +end + +---------------------------------------------------------------------- +-- Before compiling a metalua source module, try to find and load +-- a more recent bytecode dump. Requires lfs +---------------------------------------------------------------------- +local function metalua_cache_loader(name, src_filename, src) + if not M.mcache:find('%?') then + -- This is highly suspicious... + print("WARNING: no '?' character in $LUA_MCACHE/package.mcache") + end + local mlc = require 'metalua.compiler'.new() + local lfs = require 'lfs' + local dir_sep = M.config:sub(1,1) + local dst_filename = M.mcache :gsub ('%?', (name:gsub('%.', dir_sep))) + local src_a = lfs.attributes(src_filename) + local src_date = src_a and src_a.modification or 0 + local dst_a = lfs.attributes(dst_filename) + local dst_date = dst_a and dst_a.modification or 0 + local delta = dst_date - src_date + local bytecode, file, msg + if delta <= 0 then + --print ("(need to recompile "..src_filename.." into "..dst_filename..")") + bytecode = mlc :src_to_bytecode (src, '@'..src_filename) + for x in dst_filename :gmatch('()'..dir_sep) do + lfs.mkdir(dst_filename:sub(1,x)) + end + file, msg = io.open(dst_filename, 'wb') + if not file then error(msg) end + file :write (bytecode) + file :close() + else + file, msg = io.open(dst_filename, 'rb') + if not file then error(msg) end + bytecode = file :read '*a' + file :close() + end + return mlc :bytecode_to_function (bytecode, '@'..src_filename) +end + +---------------------------------------------------------------------- +-- Load a metalua source file. +---------------------------------------------------------------------- +function M.metalua_loader (name) + local file, filename_or_msg = M.findfile (name, M.mpath) + if not file then return filename_or_msg end + local luastring = file:read '*a' + file:close() + if M.mcache and pcall(require, 'lfs') then + return metalua_cache_loader(name, filename_or_msg, luastring) + else return require 'metalua.compiler'.new() :src_to_function (luastring, '@'..filename_or_msg) end +end + + +---------------------------------------------------------------------- +-- Placed after lua/luac loader, so precompiled files have +-- higher precedence. +---------------------------------------------------------------------- +table.insert(M.loaders, M.metalua_loader) + +---------------------------------------------------------------------- +-- Load an extension. +---------------------------------------------------------------------- +function extension (name, mlp) + local complete_name = M.metalua_extension_prefix..name + local extend_func = require (complete_name) + if not mlp.extensions[complete_name] then + local ast =extend_func(mlp) + mlp.extensions[complete_name] =extend_func + return ast + end +end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/pprint.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/pprint.lua new file mode 100644 index 000000000..73a842b63 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/pprint.lua @@ -0,0 +1,295 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +---------------------------------------------------------------------- + +---------------------------------------------------------------------- +---------------------------------------------------------------------- +-- +-- Lua objects pretty-printer +-- +---------------------------------------------------------------------- +---------------------------------------------------------------------- + +local M = { } + +M.DEFAULT_CFG = { + hide_hash = false; -- Print the non-array part of tables? + metalua_tag = true; -- Use Metalua's backtick syntax sugar? + fix_indent = nil; -- If a number, number of indentation spaces; + -- If false, indent to the previous brace. + line_max = nil; -- If a number, tries to avoid making lines with + -- more than this number of chars. + initial_indent = 0; -- If a number, starts at this level of indentation + keywords = { }; -- Set of keywords which must not use Lua's field + -- shortcuts {["foo"]=...} -> {foo=...} +} + +local function valid_id(cfg, x) + if type(x) ~= "string" then return false end + if not x:match "^[a-zA-Z_][a-zA-Z0-9_]*$" then return false end + if cfg.keywords and cfg.keywords[x] then return false end + return true +end + +local __tostring_cache = setmetatable({ }, {__mode='k'}) + +-- Retrieve the string produced by `__tostring` metamethod if present, +-- return `false` otherwise. Cached in `__tostring_cache`. +local function __tostring(x) + local the_string = __tostring_cache[x] + if the_string~=nil then return the_string end + local mt = getmetatable(x) + if mt then + local __tostring = mt.__tostring + if __tostring then + the_string = __tostring(x) + __tostring_cache[x] = the_string + return the_string + end + end + if x~=nil then __tostring_cache[x] = false end -- nil is an illegal key + return false +end + +local xlen -- mutually recursive with `xlen_type` + +local xlen_cache = setmetatable({ }, {__mode='k'}) + +-- Helpers for the `xlen` function +local xlen_type = { + ["nil"] = function ( ) return 3 end; + number = function (x) return #tostring(x) end; + boolean = function (x) return x and 4 or 5 end; + string = function (x) return #string.format("%q",x) end; +} + +function xlen_type.table (adt, cfg, nested) + local custom_string = __tostring(adt) + if custom_string then return #custom_string end + + -- Circular referenced objects are printed with the plain + -- `tostring` function in nested positions. + if nested [adt] then return #tostring(adt) end + nested [adt] = true + + local has_tag = cfg.metalua_tag and valid_id(cfg, adt.tag) + local alen = #adt + local has_arr = alen>0 + local has_hash = false + local x = 0 + + if not cfg.hide_hash then + -- first pass: count hash-part + for k, v in pairs(adt) do + if k=="tag" and has_tag then + -- this is the tag -> do nothing! + elseif type(k)=="number" and k<=alen and math.fmod(k,1)==0 and k>0 then + -- array-part pair -> do nothing! + else + has_hash = true + if valid_id(cfg, k) then x=x+#k + else x = x + xlen (k, cfg, nested) + 2 end -- count surrounding brackets + x = x + xlen (v, cfg, nested) + 5 -- count " = " and ", " + end + end + end + + for i = 1, alen do x = x + xlen (adt[i], nested) + 2 end -- count ", " + + nested[adt] = false -- No more nested calls + + if not (has_tag or has_arr or has_hash) then return 3 end + if has_tag then x=x+#adt.tag+1 end + if not (has_arr or has_hash) then return x end + if not has_hash and alen==1 and type(adt[1])~="table" then + return x-2 -- substract extraneous ", " + end + return x+2 -- count "{ " and " }", substract extraneous ", " +end + + +-- Compute the number of chars it would require to display the table +-- on a single line. Helps to decide whether some carriage returns are +-- required. Since the size of each sub-table is required many times, +-- it's cached in [xlen_cache]. +xlen = function (x, cfg, nested) + -- no need to compute length for 1-line prints + if not cfg.line_max then return 0 end + nested = nested or { } + if x==nil then return #"nil" end + local len = xlen_cache[x] + if len then return len end + local f = xlen_type[type(x)] + if not f then return #tostring(x) end + len = f (x, cfg, nested) + xlen_cache[x] = len + return len +end + +local function consider_newline(p, len) + if not p.cfg.line_max then return end + if p.current_offset + len <= p.cfg.line_max then return end + if p.indent < p.current_offset then + p:acc "\n"; p:acc ((" "):rep(p.indent)) + p.current_offset = p.indent + end +end + +local acc_value + +local acc_type = { + ["nil"] = function(p) p:acc("nil") end; + number = function(p, adt) p:acc (tostring (adt)) end; + string = function(p, adt) p:acc ((string.format ("%q", adt):gsub("\\\n", "\\n"))) end; + boolean = function(p, adt) p:acc (adt and "true" or "false") end } + +-- Indentation: +-- * if `cfg.fix_indent` is set to a number: +-- * add this number of space for each level of depth +-- * return to the line as soon as it flushes things further left +-- * if not, tabulate to one space after the opening brace. +-- * as a result, it never saves right-space to return before first element + +function acc_type.table(p, adt) + if p.nested[adt] then p:acc(tostring(adt)); return end + p.nested[adt] = true + + local has_tag = p.cfg.metalua_tag and valid_id(p.cfg, adt.tag) + local alen = #adt + local has_arr = alen>0 + local has_hash = false + + local previous_indent = p.indent + + if has_tag then p:acc("`"); p:acc(adt.tag) end + + local function indent(p) + if not p.cfg.fix_indent then p.indent = p.current_offset + else p.indent = p.indent + p.cfg.fix_indent end + end + + -- First pass: handle hash-part + if not p.cfg.hide_hash then + for k, v in pairs(adt) do + + if has_tag and k=='tag' then -- pass the 'tag' field + elseif type(k)=="number" and k<=alen and k>0 and math.fmod(k,1)==0 then + -- pass array-part keys (consecutive ints less than `#adt`) + else -- hash-part keys + if has_hash then p:acc ", " else -- 1st hash-part pair ever found + p:acc "{ "; indent(p) + end + + -- Determine whether a newline is required + local is_id, expected_len=valid_id(p.cfg, k) + if is_id then expected_len=#k+xlen(v, p.cfg, p.nested)+#" = , " + else expected_len = xlen(k, p.cfg, p.nested)+xlen(v, p.cfg, p.nested)+#"[] = , " end + consider_newline(p, expected_len) + + -- Print the key + if is_id then p:acc(k); p:acc " = " else + p:acc "["; acc_value (p, k); p:acc "] = " + end + + acc_value (p, v) -- Print the value + has_hash = true + end + end + end + + -- Now we know whether there's a hash-part, an array-part, and a tag. + -- Tag and hash-part are already printed if they're present. + if not has_tag and not has_hash and not has_arr then p:acc "{ }"; + elseif has_tag and not has_hash and not has_arr then -- nothing, tag already in acc + else + assert (has_hash or has_arr) -- special case { } already handled + local no_brace = false + if has_hash and has_arr then p:acc ", " + elseif has_tag and not has_hash and alen==1 and type(adt[1])~="table" then + -- No brace required; don't print "{", remember not to print "}" + p:acc (" "); acc_value (p, adt[1]) -- indent= indent+(cfg.fix_indent or 0)) + no_brace = true + elseif not has_hash then + -- Braces required, but not opened by hash-part handler yet + p:acc "{ "; indent(p) + end + + -- 2nd pass: array-part + if not no_brace and has_arr then + local expected_len = xlen(adt[1], p.cfg, p.nested) + consider_newline(p, expected_len) + acc_value(p, adt[1]) -- indent+(cfg.fix_indent or 0) + for i=2, alen do + p:acc ", "; + consider_newline(p, xlen(adt[i], p.cfg, p.nested)) + acc_value (p, adt[i]) --indent+(cfg.fix_indent or 0) + end + end + if not no_brace then p:acc " }" end + end + p.nested[adt] = false -- No more nested calls + p.indent = previous_indent +end + + +function acc_value(p, v) + local custom_string = __tostring(v) + if custom_string then p:acc(custom_string) else + local f = acc_type[type(v)] + if f then f(p, v) else p:acc(tostring(v)) end + end +end + + +-- FIXME: new_indent seems to be always nil?!s detection +-- FIXME: accumulator function should be configurable, +-- so that print() doesn't need to bufferize the whole string +-- before starting to print. +function M.tostring(t, cfg) + + cfg = cfg or M.DEFAULT_CFG or { } + + local p = { + cfg = cfg; + indent = 0; + current_offset = cfg.initial_indent or 0; + buffer = { }; + nested = { }; + acc = function(self, str) + table.insert(self.buffer, str) + self.current_offset = self.current_offset + #str + end; + } + acc_value(p, t) + return table.concat(p.buffer) +end + +function M.print(...) return print(M.tostring(...)) end +function M.sprintf(fmt, ...) + local args={...} + for i, v in pairs(args) do + local t=type(v) + if t=='table' then args[i]=M.tostring(v) + elseif t=='nil' then args[i]='nil' end + end + return string.format(fmt, unpack(args)) +end + +function M.printf(...) print(M.sprintf(...)) end + +return M \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/repl.mlua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/repl.mlua new file mode 100644 index 000000000..0c89bc0b4 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/repl.mlua @@ -0,0 +1,108 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +-- Keep these global: +PRINT_AST = true +LINE_WIDTH = 60 +PROMPT = "M> " +PROMPT2 = ">> " + +local pp=require 'metalua.pprint' +local M = { } + +mlc = require 'metalua.compiler'.new() + +local readline + +do -- set readline() to a line reader, either editline otr a default + local status, editline = pcall(require, 'editline') + if status then + local rl_handle = editline.init 'metalua' + readline = |p| rl_handle:read(p) + else + local status, rl = pcall(require, 'readline') + if status then + rl.set_options{histfile='~/.metalua_history', keeplines=100, completion=false } + readline = rl.readline + else -- neither editline nor readline available + function readline (p) + io.write (p) + io.flush () + return io.read '*l' + end + end + end +end + +local function reached_eof(lx, msg) + return lx:peek().tag=='Eof' or msg:find "token `Eof" +end + + +function M.run() + pp.printf ("Metalua, interactive REPLoop.\n".. + "(c) 2006-2013 ") + local lines = { } + while true do + local src, lx, ast, f, results, success + repeat + local line = readline(next(lines) and PROMPT2 or PROMPT) + if not line then print(); os.exit(0) end -- line==nil iff eof on stdin + if not next(lines) then + line = line:gsub('^%s*=', 'return ') + end + table.insert(lines, line) + src = table.concat (lines, "\n") + until #line>0 + lx = mlc :src_to_lexstream(src) + success, ast = pcall(mlc.lexstream_to_ast, mlc, lx) + if success then + success, f = pcall(mlc.ast_to_function, mlc, ast, '=stdin') + if success then + results = { xpcall(f, debug.traceback) } + success = table.remove (results, 1) + if success then + -- Success! + for _, x in ipairs(results) do + pp.print(x, {line_max=LINE_WIDTH, metalua_tag=true}) + end + lines = { } + else + print "Evaluation error:" + print (results[1]) + lines = { } + end + else + print "Can't compile into bytecode:" + print (f) + lines = { } + end + else + -- If lx has been read entirely, try to read + -- another line before failing. + if not reached_eof(lx, ast) then + print "Can't compile source into AST:" + print (ast) + lines = { } + end + end + end +end + +return M \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/treequery.mlua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/treequery.mlua new file mode 100644 index 000000000..e369b9954 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/treequery.mlua @@ -0,0 +1,488 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +local walk = require 'metalua.treequery.walk' + +local M = { } +-- support for old-style modules +treequery = M + +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- +-- +-- multimap helper mmap: associate a key to a set of values +-- +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- + +local function mmap_add (mmap, node, x) + if node==nil then return false end + local set = mmap[node] + if set then set[x] = true + else mmap[node] = {[x]=true} end +end + +-- currently unused, I throw the whole set away +local function mmap_remove (mmap, node, x) + local set = mmap[node] + if not set then return false + elseif not set[x] then return false + elseif next(set) then set[x]=nil + else mmap[node] = nil end + return true +end + +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- +-- +-- TreeQuery object. +-- +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- + +local ACTIVE_SCOPE = setmetatable({ }, {__mode="k"}) + +-- treequery metatable +local Q = { }; Q.__index = Q + +--- treequery constructor +-- the resultingg object will allow to filter ans operate on the AST +-- @param root the AST to visit +-- @return a treequery visitor instance +function M.treequery(root) + return setmetatable({ + root = root, + unsatisfied = 0, + predicates = { }, + until_up = { }, + from_up = { }, + up_f = false, + down_f = false, + filters = { }, + }, Q) +end + +-- helper to share the implementations of positional filters +local function add_pos_filter(self, position, inverted, inclusive, f, ...) + if type(f)=='string' then f = M.has_tag(f, ...) end + if not inverted then self.unsatisfied += 1 end + local x = { + pred = f, + position = position, + satisfied = false, + inverted = inverted or false, + inclusive = inclusive or false } + table.insert(self.predicates, x) + return self +end + +function Q :if_unknown(f) + self.unknown_handler = f or (||nil) + return self +end + +-- TODO: offer an API for inclusive pos_filters + +--- select nodes which are after one which satisfies predicate f +Q.after = |self, f, ...| add_pos_filter(self, 'after', false, false, f, ...) +--- select nodes which are not after one which satisfies predicate f +Q.not_after = |self, f, ...| add_pos_filter(self, 'after', true, false, f, ...) +--- select nodes which are under one which satisfies predicate f +Q.under = |self, f, ...| add_pos_filter(self, 'under', false, false, f, ...) +--- select nodes which are not under one which satisfies predicate f +Q.not_under = |self, f, ...| add_pos_filter(self, 'under', true, false, f, ...) + +--- select nodes which satisfy predicate f +function Q :filter(f, ...) + if type(f)=='string' then f = M.has_tag(f, ...) end + table.insert(self.filters, f); + return self +end + +--- select nodes which satisfy predicate f +function Q :filter_not(f, ...) + if type(f)=='string' then f = M.has_tag(f, ...) end + table.insert(self.filters, |...| not f(...)) + return self +end + +-- private helper: apply filters and execute up/down callbacks when applicable +function Q :execute() + local cfg = { } + -- TODO: optimize away not_under & not_after by pruning the tree + function cfg.down(...) + --printf ("[down]\t%s\t%s", self.unsatisfied, table.tostring((...))) + ACTIVE_SCOPE[...] = cfg.scope + local satisfied = self.unsatisfied==0 + for _, x in ipairs(self.predicates) do + if not x.satisfied and x.pred(...) then + x.satisfied = true + local node, parent = ... + local inc = x.inverted and 1 or -1 + if x.position=='under' then + -- satisfied from after we get down this node... + self.unsatisfied += inc + -- ...until before we get up this node + mmap_add(self.until_up, node, x) + elseif x.position=='after' then + -- satisfied from after we get up this node... + mmap_add(self.from_up, node, x) + -- ...until before we get up this node's parent + mmap_add(self.until_up, parent, x) + elseif x.position=='under_or_after' then + -- satisfied from after we get down this node... + self.satisfied += inc + -- ...until before we get up this node's parent... + mmap_add(self.until_up, parent, x) + else + error "position not understood" + end -- position + if x.inclusive then satisfied = self.unsatisfied==0 end + end -- predicate passed + end -- for predicates + + if satisfied then + for _, f in ipairs(self.filters) do + if not f(...) then satisfied=false; break end + end + if satisfied and self.down_f then self.down_f(...) end + end + end + + function cfg.up(...) + --printf ("[up]\t%s", table.tostring((...))) + + -- Remove predicates which are due before we go up this node + local preds = self.until_up[...] + if preds then + for x, _ in pairs(preds) do + local inc = x.inverted and -1 or 1 + self.unsatisfied += inc + x.satisfied = false + end + self.until_up[...] = nil + end + + -- Execute the up callback + -- TODO: cache the filter passing result from the down callback + -- TODO: skip if there's no callback + local satisfied = self.unsatisfied==0 + if satisfied then + for _, f in ipairs(self.filters) do + if not f(self, ...) then satisfied=false; break end + end + if satisfied and self.up_f then self.up_f(...) end + end + + -- Set predicate which are due after we go up this node + local preds = self.from_up[...] + if preds then + for p, _ in pairs(preds) do + local inc = p.inverted and 1 or -1 + self.unsatisfied += inc + end + self.from_up[...] = nil + end + ACTIVE_SCOPE[...] = nil + end + + function cfg.binder(id_node, ...) + --printf(" >>> Binder called on %s, %s", table.tostring(id_node), + -- table.tostring{...}:sub(2,-2)) + cfg.down(id_node, ...) + cfg.up(id_node, ...) + --printf("down/up on binder done") + end + + cfg.unknown = self.unknown_handler + + --function cfg.occurrence (binder, occ) + -- if binder then OCC2BIND[occ] = binder[1] end + --printf(" >>> %s is an occurrence of %s", occ[1], table.tostring(binder and binder[2])) + --end + + --function cfg.binder(...) cfg.down(...); cfg.up(...) end + return walk.guess(cfg, self.root) +end + +--- Execute a function on each selected node +-- @down: function executed when we go down a node, i.e. before its children +-- have been examined. +-- @up: function executed when we go up a node, i.e. after its children +-- have been examined. +function Q :foreach(down, up) + if not up and not down then + error "iterator missing" + end + self.up_f = up + self.down_f = down + return self :execute() +end + +--- Return the list of nodes selected by a given treequery. +function Q :list() + local acc = { } + self :foreach(|x| table.insert(acc, x)) + return acc +end + +--- Return the first matching element +-- TODO: dirty hack, to implement properly with a 'break' return. +-- Also, it won't behave correctly if a predicate causes an error, +-- or if coroutines are involved. +function Q :first() + local result = { } + local function f(...) result = {...}; error() end + pcall(|| self :foreach(f)) + return unpack(result) +end + +--- Pretty printer for queries +function Q :__tostring() return "" end + +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- +-- +-- Predicates. +-- +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- + +--- Return a predicate which is true if the tested node's tag is among the +-- one listed as arguments +-- @param ... a sequence of tag names +function M.has_tag(...) + local args = {...} + if #args==1 then + local tag = ... + return (|node| node.tag==tag) + --return function(self, node) printf("node %s has_tag %s?", table.tostring(node), tag); return node.tag==tag end + else + local tags = { } + for _, tag in ipairs(args) do tags[tag]=true end + return function(node) + local node_tag = node.tag + return node_tag and tags[node_tag] + end + end +end + +--- Predicate to test whether a node represents an expression. +M.is_expr = M.has_tag('Nil', 'Dots', 'True', 'False', 'Number','String', + 'Function', 'Table', 'Op', 'Paren', 'Call', 'Invoke', + 'Id', 'Index') + +-- helper for is_stat +local STAT_TAGS = { Do=1, Set=1, While=1, Repeat=1, If=1, Fornum=1, + Forin=1, Local=1, Localrec=1, Return=1, Break=1 } + +--- Predicate to test whether a node represents a statement. +-- It is context-aware, i.e. it recognizes `Call and `Invoke nodes +-- used in a statement context as such. +function M.is_stat(node, parent) + local tag = node.tag + if not tag then return false + elseif STAT_TAGS[tag] then return true + elseif tag=='Call' or tag=='Invoke' then return parent and parent.tag==nil + else return false end +end + +--- Predicate to test whether a node represents a statements block. +function M.is_block(node) return node.tag==nil end + +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- +-- +-- Variables and scopes. +-- +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- + +local BINDER_PARENT_TAG = { + Local=true, Localrec=true, Forin=true, Function=true } + +--- Test whether a node is a binder. This is local predicate, although it +-- might need to inspect the parent node. +function M.is_binder(node, parent) + --printf('is_binder(%s, %s)', table.tostring(node), table.tostring(parent)) + if node.tag ~= 'Id' or not parent then return false end + if parent.tag=='Fornum' then return parent[1]==node end + if not BINDER_PARENT_TAG[parent.tag] then return false end + for _, binder in ipairs(parent[1]) do + if binder==node then return true end + end + return false +end + +--- Retrieve the binder associated to an occurrence within root. +-- @param occurrence an Id node representing an occurrence in `root`. +-- @param root the tree in which `node` and its binder occur. +-- @return the binder node, and its ancestors up to root if found. +-- @return nil if node is global (or not an occurrence) in `root`. +function M.binder(occurrence, root) + local cfg, id_name, result = { }, occurrence[1], { } + function cfg.occurrence(id) + if id == occurrence then result = cfg.scope :get(id_name) end + -- TODO: break the walker + end + walk.guess(cfg, root) + return unpack(result) +end + +--- Predicate to filter occurrences of a given binder. +-- Warning: it relies on internal scope book-keeping, +-- and for this reason, it only works as query method argument. +-- It won't work outside of a query. +-- @param binder the binder whose occurrences must be kept by predicate +-- @return a predicate + +-- function M.is_occurrence_of(binder) +-- return function(node, ...) +-- if node.tag ~= 'Id' then return nil end +-- if M.is_binder(node, ...) then return nil end +-- local scope = ACTIVE_SCOPE[node] +-- if not scope then return nil end +-- local result = scope :get (node[1]) or { } +-- if result[1] ~= binder then return nil end +-- return unpack(result) +-- end +-- end + +function M.is_occurrence_of(binder) + return function(node, ...) + local b = M.get_binder(node) + return b and b==binder + end +end + +function M.get_binder(occurrence, ...) + if occurrence.tag ~= 'Id' then return nil end + if M.is_binder(occurrence, ...) then return nil end + local scope = ACTIVE_SCOPE[occurrence] + local binder_hierarchy = scope :get(occurrence[1]) + return unpack (binder_hierarchy or { }) +end + +--- Transform a predicate on a node into a predicate on this node's +-- parent. For instance if p tests whether a node has property P, +-- then parent(p) tests whether this node's parent has property P. +-- The ancestor level is precised with n, with 1 being the node itself, +-- 2 its parent, 3 its grand-parent etc. +-- @param[optional] n the parent to examine, default=2 +-- @param pred the predicate to transform +-- @return a predicate +function M.parent(n, pred, ...) + if type(n)~='number' then n, pred = 2, n end + if type(pred)=='string' then pred = M.has_tag(pred, ...) end + return function(self, ...) + return select(n, ...) and pred(self, select(n, ...)) + end +end + +--- Transform a predicate on a node into a predicate on this node's +-- n-th child. +-- @param n the child's index number +-- @param pred the predicate to transform +-- @return a predicate +function M.child(n, pred) + return function(node, ...) + local child = node[n] + return child and pred(child, node, ...) + end +end + +--- Predicate to test the position of a node in its parent. +-- The predicate succeeds if the node is the n-th child of its parent, +-- and a <= n <= b. +-- nth(a) is equivalent to nth(a, a). +-- Negative indices are admitted, and count from the last child, +-- as done for instance by string.sub(). +-- +-- TODO: This is wrong, this tests the table relationship rather than the +-- AST node relationship. +-- Must build a getindex helper, based on pattern matching, then build +-- the predicate around it. +-- +-- @param a lower bound +-- @param a upper bound +-- @return a predicate +function M.is_nth(a, b) + b = b or a + return function(self, node, parent) + if not parent then return false end + local nchildren = #parent + local a = a<=0 and nchildren+a+1 or a + if a>nchildren then return false end + local b = b<=0 and nchildren+b+1 or b>nchildren and nchildren or b + for i=a,b do if parent[i]==node then return true end end + return false + end +end + +--- Returns a list of the direct children of AST node `ast`. +-- Children are only expressions, statements and blocks, +-- not intermediates such as `Pair` nodes or internal lists +-- in `Local` or `Set` nodes. +-- Children are returned in parsing order, which isn't necessarily +-- the same as source code order. For instance, the right-hand-side +-- of a `Local` node is listed before the left-hand-side, because +-- semantically the right is evaluated before the variables on the +-- left enter scope. +-- +-- @param ast the node whose children are needed +-- @return a list of the direct children of `ast` +function M.children(ast) + local acc = { } + local cfg = { } + function cfg.down(x) + if x~=ast then table.insert(acc, x); return 'break' end + end + walk.guess(cfg, ast) + return acc +end + +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- +-- +-- Comments parsing. +-- +-- ----------------------------------------------------------------------------- +-- ----------------------------------------------------------------------------- + +local comment_extractor = |which_side| function (node) + local x = node.lineinfo + x = x and x[which_side] + x = x and x.comments + if not x then return nil end + local lines = { } + for _, record in ipairs(x) do + table.insert(lines, record[1]) + end + return table.concat(lines, '\n') +end + +M.comment_prefix = comment_extractor 'first' +M.comment_suffix = comment_extractor 'last' + + +--- Shortcut for the query constructor +function M :__call(...) return self.treequery(...) end +setmetatable(M, M) + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/treequery/walk.mlua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/treequery/walk.mlua new file mode 100644 index 000000000..94fc5d65d --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/metalua/treequery/walk.mlua @@ -0,0 +1,266 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2006-2013 Fabien Fleutot and others. +-- +-- All rights reserved. +-- +-- This program and the accompanying materials are made available +-- under the terms of the Eclipse Public License v1.0 which +-- accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- This program and the accompanying materials are also made available +-- under the terms of the MIT public license which accompanies this +-- distribution, and is available at http://www.lua.org/license.html +-- +-- Contributors: +-- Fabien Fleutot - API and implementation +-- +------------------------------------------------------------------------------- + +-- Low level AST traversal library. +-- +-- This library is a helper for the higher-level `treequery` library. +-- It walks through every node of an AST, depth-first, and executes +-- some callbacks contained in its `cfg` config table: +-- +-- * `cfg.down(...)` is called when it walks down a node, and receive as +-- parameters the node just entered, followed by its parent, grand-parent +-- etc. until the root node. +-- +-- * `cfg.up(...)` is called when it walks back up a node, and receive as +-- parameters the node just entered, followed by its parent, grand-parent +-- etc. until the root node. +-- +-- * `cfg.occurrence(binder, id_node, ...)` is called when it visits +-- an `` `Id{ }`` node which isn't a local variable creator. binder +-- is a reference to its binder with its context. The binder is the +-- `` `Id{ }`` node which created this local variable. By "binder +-- and its context", we mean a list starting with the `` `Id{ }``, +-- and followed by every ancestor of the binder node, up until the +-- common root node. `binder` is nil if the variable is global. +-- `id_node` is followed by its ancestor, up until the root node. +-- +-- `cfg.scope` is maintained during the traversal, associating a +-- variable name to the binder which creates it in the context of the +-- node currently visited. +-- +-- `walk.traverse.xxx` functions are in charge of the recursive +-- descent into children nodes. They're private helpers. They are also +-- in charge of calling appropriate `cfg.xxx` callbacks. + +-{ extension ("match", ...) } + +local pp = require 'metalua.pprint' + +local M = { traverse = { }; tags = { }; debug = false } + +local function table_transpose(t) + local tt = { }; for a, b in pairs(t) do tt[b]=a end; return tt +end + +-------------------------------------------------------------------------------- +-- Standard tags: can be used to guess the type of an AST, or to check +-- that the type of an AST is respected. +-------------------------------------------------------------------------------- +M.tags.stat = table_transpose{ + 'Do', 'Set', 'While', 'Repeat', 'Local', 'Localrec', 'Return', + 'Fornum', 'Forin', 'If', 'Break', 'Goto', 'Label', + 'Call', 'Invoke' } +M.tags.expr = table_transpose{ + 'Paren', 'Call', 'Invoke', 'Index', 'Op', 'Function', 'Stat', + 'Table', 'Nil', 'Dots', 'True', 'False', 'Number', 'String', 'Id' } + +-------------------------------------------------------------------------------- +-- These [M.traverse.xxx()] functions are in charge of actually going through +-- ASTs. At each node, they make sure to call the appropriate walker. +-------------------------------------------------------------------------------- + +function M.traverse.stat (cfg, x, ...) + if M.debug then pp.printf("traverse stat %s", x) end + local ancestors = {...} + local B = |y| M.block (cfg, y, x, unpack(ancestors)) -- Block + local S = |y| M.stat (cfg, y, x, unpack(ancestors)) -- Statement + local E = |y| M.expr (cfg, y, x, unpack(ancestors)) -- Expression + local EL = |y| M.expr_list (cfg, y, x, unpack(ancestors)) -- Expression List + local IL = |y| M.binder_list (cfg, y, x, unpack(ancestors)) -- Id binders List + local OS = || cfg.scope :save() -- Open scope + local CS = || cfg.scope :restore() -- Close scope + + match x with + | {...} if x.tag == nil -> for _, y in ipairs(x) do M.stat(cfg, y, ...) end + -- no tag --> node not inserted in the history ancestors + | `Do{...} -> OS(x); for _, y in ipairs(x) do S(y) end; CS(x) + | `Set{ lhs, rhs } -> EL(lhs); EL(rhs) + | `While{ cond, body } -> E(cond); OS(); B(body); CS() + | `Repeat{ body, cond } -> OS(body); B(body); E(cond); CS(body) + | `Local{ lhs } -> IL(lhs) + | `Local{ lhs, rhs } -> EL(rhs); IL(lhs) + | `Localrec{ lhs, rhs } -> IL(lhs); EL(rhs) + | `Fornum{ i, a, b, body } -> E(a); E(b); OS(); IL{i}; B(body); CS() + | `Fornum{ i, a, b, c, body } -> E(a); E(b); E(c); OS(); IL{i}; B(body); CS() + | `Forin{ i, rhs, body } -> EL(rhs); OS(); IL(i); B(body); CS() + | `If{...} -> + for i=1, #x-1, 2 do + E(x[i]); OS(); B(x[i+1]); CS() + end + if #x%2 == 1 then + OS(); B(x[#x]); CS() + end + | `Call{...}|`Invoke{...}|`Return{...} -> EL(x) + | `Break | `Goto{ _ } | `Label{ _ } -> -- nothing + | { tag=tag, ...} if M.tags.stat[tag]-> + M.malformed (cfg, x, unpack (ancestors)) + | _ -> + M.unknown (cfg, x, unpack (ancestors)) + end +end + +function M.traverse.expr (cfg, x, ...) + if M.debug then pp.printf("traverse expr %s", x) end + local ancestors = {...} + local B = |y| M.block (cfg, y, x, unpack(ancestors)) -- Block + local S = |y| M.stat (cfg, y, x, unpack(ancestors)) -- Statement + local E = |y| M.expr (cfg, y, x, unpack(ancestors)) -- Expression + local EL = |y| M.expr_list (cfg, y, x, unpack(ancestors)) -- Expression List + local IL = |y| M.binder_list (cfg, y, x, unpack(ancestors)) -- Id binders list + local OS = || cfg.scope :save() -- Open scope + local CS = || cfg.scope :restore() -- Close scope + + match x with + | `Paren{ e } -> E(e) + | `Call{...} | `Invoke{...} -> EL(x) + | `Index{ a, b } -> E(a); E(b) + | `Op{ opid, ... } -> E(x[2]); if #x==3 then E(x[3]) end + | `Function{ params, body } -> OS(body); IL(params); B(body); CS(body) + | `Stat{ b, e } -> OS(b); B(b); E(e); CS(b) + | `Id{ name } -> M.occurrence(cfg, x, unpack(ancestors)) + | `Table{ ... } -> + for i = 1, #x do match x[i] with + | `Pair{ k, v } -> E(k); E(v) + | v -> E(v) + end end + | `Nil|`Dots|`True|`False|`Number{_}|`String{_} -> -- terminal node + | { tag=tag, ...} if M.tags.expr[tag]-> M.malformed (cfg, x, unpack (ancestors)) + | _ -> M.unknown (cfg, x, unpack (ancestors)) + end +end + +function M.traverse.block (cfg, x, ...) + assert(type(x)=='table', "traverse.block() expects a table") + if x.tag then M.malformed(cfg, x, ...) + else for _, y in ipairs(x) do M.stat(cfg, y, x, ...) end + end +end + +function M.traverse.expr_list (cfg, x, ...) + assert(type(x)=='table', "traverse.expr_list() expects a table") + -- x doesn't appear in the ancestors + for _, y in ipairs(x) do M.expr(cfg, y, ...) end +end + +function M.malformed(cfg, x, ...) + local f = cfg.malformed or cfg.error + if f then f(x, ...) else + error ("Malformed node of tag "..(x.tag or '(nil)')) + end +end + +function M.unknown(cfg, x, ...) + local f = cfg.unknown or cfg.error + if f then f(x, ...) else + error ("Unknown node tag "..(x.tag or '(nil)')) + end +end + +function M.occurrence(cfg, x, ...) + if cfg.occurrence then cfg.occurrence(cfg.scope :get(x[1]), x, ...) end +end + +-- TODO: Is it useful to call each error handling function? +function M.binder_list (cfg, id_list, ...) + local f = cfg.binder + local ferror = cfg.error or cfg.malformed or cfg.unknown + for i, id_node in ipairs(id_list) do + local down, up = cfg.down, cfg.up + if id_node.tag == 'Id' then + cfg.scope :set (id_node[1], { id_node, ... }) + if down then down(id_node, ...) end + if f then f(id_node, ...) end + if up then up(id_node, ...) end + elseif i==#id_list and id_node.tag=='Dots' then + if down then down(id_node, ...) end + if up then up(id_node, ...) end + -- Do nothing, those are valid `Dots + elseif ferror then + -- Traverse error handling function + ferror(id_node, ...) + else + error("Invalid binders list") + end + end +end + +---------------------------------------------------------------------- +-- Generic walker generator. +-- * if `cfg' has an entry matching the tree name, use this entry +-- * if not, try to use the entry whose name matched the ast kind +-- * if an entry is a table, look for 'up' and 'down' entries +-- * if it is a function, consider it as a `down' traverser. +---------------------------------------------------------------------- +local walker_builder = function(traverse) + assert(traverse) + return function (cfg, ...) + if not cfg.scope then cfg.scope = M.newscope() end + local down, up = cfg.down, cfg.up + local broken = down and down(...) + if broken ~= 'break' then M.traverse[traverse] (cfg, ...) end + if up then up(...) end + end +end + +---------------------------------------------------------------------- +-- Declare [M.stat], [M.expr], [M.block]. +-- `M.binder_list` is not here, because `cfg.up` and `cfg.down` must +-- be called on individual binders, not on the list itself. +-- It's therefore handled in `traverse.binder_list()` +---------------------------------------------------------------------- +for _, w in ipairs{ "stat", "expr", "block" } do --, "malformed", "unknown" } do + M[w] = walker_builder (w, M.traverse[w]) +end + +-- Don't call up/down callbacks on expr lists +M.expr_list = M.traverse.expr_list + + +---------------------------------------------------------------------- +-- Try to guess the type of the AST then choose the right walkker. +---------------------------------------------------------------------- +function M.guess (cfg, x, ...) + assert(type(x)=='table', "arg #2 in a walker must be an AST") + if M.tags.expr[x.tag] then return M.expr(cfg, x, ...) end + if M.tags.stat[x.tag] then return M.stat(cfg, x, ...) end + if not x.tag then return M.block(cfg, x, ...) end + error ("Can't guess the AST type from tag "..(x.tag or '')) +end + +local S = { }; S.__index = S + +function M.newscope() + local instance = { current = { } } + instance.stack = { instance.current } + setmetatable (instance, S) + return instance +end + +function S :save(...) + local current_copy = { } + for a, b in pairs(self.current) do current_copy[a]=b end + table.insert (self.stack, current_copy) + if ... then return self :add(...) end +end + +function S :restore() self.current = table.remove (self.stack) end +function S :get (var_name) return self.current[var_name] end +function S :set (key, val) self.current[key] = val end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/apimodel.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/apimodel.lua new file mode 100644 index 000000000..e0ed1c968 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/apimodel.lua @@ -0,0 +1,241 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2011-2012 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Simon BERNARD +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +local M = {} + +-------------------------------------------------------------------------------- +-- API MODEL +-------------------------------------------------------------------------------- + +function M._file() + local file = { + -- FIELDS + tag = "file", + name = nil, -- string + shortdescription = "", -- string + description = "", -- string + types = {}, -- map from typename to type + globalvars = {}, -- map from varname to item + returns = {}, -- list of return + + -- FUNCTIONS + addtype = function (self,type) + self.types[type.name] = type + type.parent = self + end, + + mergetype = function (self,newtype,erase,erasesourcerangefield) + local currenttype = self.types[newtype.name] + if currenttype then + -- merge recordtypedef + if currenttype.tag =="recordtypedef" and newtype.tag == "recordtypedef" then + -- merge fields + for fieldname ,field in pairs( newtype.fields) do + local currentfield = currenttype.fields[fieldname] + if erase or not currentfield then + currenttype:addfield(field) + elseif erasesourcerangefield then + if field.sourcerange.min and field.sourcerange.max then + currentfield.sourcerange.min = field.sourcerange.min + currentfield.sourcerange.max = field.sourcerange.max + end + end + end + + -- merge descriptions and source ranges + if erase then + if newtype.description or newtype.description == "" then currenttype.description = newtype.description end + if newtype.shortdescription or newtype.shortdescription == "" then currenttype.shortdescription = newtype.shortdescription end + if newtype.sourcerange.min and newtype.sourcerange.max then + currenttype.sourcerange.min = newtype.sourcerange.min + currenttype.sourcerange.max = newtype.sourcerange.max + end + end + -- merge functiontypedef + elseif currenttype.tag == "functiontypedef" and newtype.tag == "functiontypedef" then + -- merge params + for i, param1 in ipairs(newtype.params) do + local missing = true + for j, param2 in ipairs(currenttype.params) do + if param1.name == param2.name then + missing = false + break + end + end + if missing then + table.insert(currenttype.params,param1) + end + end + + -- merge descriptions and source ranges + if erase then + if newtype.description or newtype.description == "" then currenttype.description = newtype.description end + if newtype.shortdescription or newtype.shortdescription == "" then currenttype.shortdescription = newtype.shortdescription end + if newtype.sourcerange.min and newtype.sourcerange.max then + currenttype.sourcerange.min = newtype.sourcerange.min + currenttype.sourcerange.max = newtype.sourcerange.max + end + end + end + else + self:addtype(newtype) + end + end, + + addglobalvar = function (self,item) + self.globalvars[item.name] = item + item.parent = self + end, + + moduletyperef = function (self) + if self and self.returns[1] and self.returns[1].types[1] then + local typeref = self.returns[1].types[1] + return typeref + end + end + } + return file +end + +function M._recordtypedef(name) + local recordtype = { + -- FIELDS + tag = "recordtypedef", + name = name, -- string (mandatory) + shortdescription = "", -- string + description = "", -- string + fields = {}, -- map from fieldname to field + sourcerange = {min=0,max=0}, + + -- FUNCTIONS + addfield = function (self,field) + self.fields[field.name] = field + field.parent = self + end + } + return recordtype +end + +function M._functiontypedef(name) + return { + tag = "functiontypedef", + name = name, -- string (mandatory) + shortdescription = "", -- string + description = "", -- string + params = {}, -- list of parameter + returns = {} -- list of return + } +end + +function M._parameter(name) + return { + tag = "parameter", + name = name, -- string (mandatory) + description = "", -- string + type = nil -- typeref (external or internal or primitive typeref) + } +end + +function M._item(name) + return { + -- FIELDS + tag = "item", + name = name, -- string (mandatory) + shortdescription = "", -- string + description = "", -- string + type = nil, -- typeref (external or internal or primitive typeref) + occurrences = {}, -- list of identifier (see internalmodel) + sourcerange = {min=0, max=0}, + + -- This is A TRICK + -- This value is ALWAYS nil, except for internal purposes (short references). + external = nil, + + -- FUNCTIONS + addoccurence = function (self,occ) + table.insert(self.occurrences,occ) + occ.definition = self + end, + + resolvetype = function (self,file) + if self and self.type then + if self.type.tag =="internaltyperef" then + -- if file is not given try to retrieve it. + if not file then + if self.parent and self.parent.tag == 'recordtypedef' then + file = self.parent.parent + elseif self.parent.tag == 'file' then + file = self.parent + end + end + if file then return file.types[self.type.typename] end + elseif self.type.tag =="inlinetyperef" then + return self.type.def + end + end + end + } +end + +function M._externaltypref(modulename, typename) + return { + tag = "externaltyperef", + modulename = modulename, -- string + typename = typename -- string + } +end + +function M._internaltyperef(typename) + return { + tag = "internaltyperef", + typename = typename -- string + } +end + +function M._primitivetyperef(typename) + return { + tag = "primitivetyperef", + typename = typename -- string + } +end + +function M._moduletyperef(modulename,returnposition) + return { + tag = "moduletyperef", + modulename = modulename, -- string + returnposition = returnposition -- number + } +end + +function M._exprtyperef(expression,returnposition) + return { + tag = "exprtyperef", + expression = expression, -- expression (see internal model) + returnposition = returnposition -- number + } +end + +function M._inlinetyperef(definition) + return { + tag = "inlinetyperef", + def = definition, -- expression (see internal model) + + } +end + +function M._return(description) + return { + tag = "return", + description = description or "", -- string + types = {} -- list of typref (external or internal or primitive typeref) + } +end +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/apimodelbuilder.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/apimodelbuilder.lua new file mode 100644 index 000000000..6fcd3c8f5 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/apimodelbuilder.lua @@ -0,0 +1,459 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2011-2012 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Simon BERNARD +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +local apimodel = require "models.apimodel" +local ldp = require "models.ldparser" +local Q = require "metalua.treequery" + +local M = {} + +local handledcomments={} -- cache to know the comment already handled + +---- +-- UTILITY METHODS +local primitivetypes = { + ['boolean'] = true, + ['function'] = true, + ['nil'] = true, + ['number'] = true, + ['string'] = true, + ['table'] = true, + ['thread'] = true, + ['userdata'] = true +} + +-- get or create the typedef with the name "name" +local function gettypedef(_file,name,kind,sourcerangemin,sourcerangemax) + local kind = kind or "recordtypedef" + local _typedef = _file.types[name] + if _typedef then + if _typedef.tag == kind then return _typedef end + else + if kind == "recordtypedef" and name ~= "global" then + local _recordtypedef = apimodel._recordtypedef(name) + + -- define sourcerange + _recordtypedef.sourcerange.min = sourcerangemin + _recordtypedef.sourcerange.max = sourcerangemax + + -- add to file if a name is defined + if _recordtypedef.name then _file:addtype(_recordtypedef) end + return _recordtypedef + elseif kind == "functiontypedef" then + -- TODO support function + return nil + else + return nil + end + end + return nil +end + + +-- create a typeref from the typref doc_tag +local function createtyperef(dt_typeref,_file,sourcerangemin,sourcerangemax) + local _typeref + if dt_typeref.tag == "typeref" then + if dt_typeref.module then + -- manage external type + _typeref = apimodel._externaltypref() + _typeref.modulename = dt_typeref.module + _typeref.typename = dt_typeref.type + else + if primitivetypes[dt_typeref.type] then + -- manage primitive type + _typeref = apimodel._primitivetyperef() + _typeref.typename = dt_typeref.type + else + -- manage internal type + _typeref = apimodel._internaltyperef() + _typeref.typename = dt_typeref.type + if _file then + gettypedef(_file, _typeref.typename, "recordtypedef", sourcerangemin,sourcerangemax) + end + end + end + end + return _typeref +end + +-- create a return from the return doc_tag +local function createreturn(dt_return,_file,sourcerangemin,sourcerangemax) + local _return = apimodel._return() + + _return.description = dt_return.description + + -- manage typeref + if dt_return.types then + for _, dt_typeref in ipairs(dt_return.types) do + local _typeref = createtyperef(dt_typeref,_file,sourcerangemin,sourcerangemax) + if _typeref then + table.insert(_return.types,_typeref) + end + end + end + return _return +end + +-- create a item from the field doc_tag +local function createfield(dt_field,_file,sourcerangemin,sourcerangemax) + local _item = apimodel._item(dt_field.name) + + if dt_field.shortdescription then + _item.shortdescription = dt_field.shortdescription + _item.description = dt_field.description + else + _item.shortdescription = dt_field.description + end + + -- manage typeref + local dt_typeref = dt_field.type + if dt_typeref then + _item.type = createtyperef(dt_typeref,_file,sourcerangemin,sourcerangemax) + end + return _item +end + +-- create a param from the param doc_tag +local function createparam(dt_param,_file,sourcerangemin,sourcerangemax) + if not dt_param.name then return nil end + + local _parameter = apimodel._parameter(dt_param.name) + _parameter.description = dt_param.description + + -- manage typeref + local dt_typeref = dt_param.type + if dt_typeref then + _parameter.type = createtyperef(dt_typeref,_file,sourcerangemin,sourcerangemax) + end + return _parameter +end + +-- get or create the typedef with the name "name" +function M.additemtoparent(_file,_item,scope,sourcerangemin,sourcerangemax) + if scope and not scope.module then + if _item.name then + if scope.type == "global" then + _file:addglobalvar(_item) + else + local _recordtypedef = gettypedef (_file, scope.type ,"recordtypedef",sourcerangemin,sourcerangemax) + _recordtypedef:addfield(_item) + end + else + -- if no item name precise we store the scope in the item to be able to add it to the right parent later + _item.scope = scope + end + end +end + +-- Function type counter +local i = 0 + +-- Reset function type counter +local function resetfunctiontypeidgenerator() + i = 0 +end + +-- Provides an unique index for a function type +local function generatefunctiontypeid() + i = i + 1 + return i +end + +-- generate a function type name +local function generatefunctiontypename(_functiontypedef) + local name = {"__"} + if _functiontypedef.returns and _functiontypedef.returns[1] then + local ret = _functiontypedef.returns[1] + for _, type in ipairs(ret.types) do + if type.typename then + if type.modulename then + table.insert(name,type.modulename) + end + table.insert(name,"#") + table.insert(name,type.typename) + end + end + + end + table.insert(name,"=") + if _functiontypedef.params then + for _, param in ipairs(_functiontypedef.params) do + local type = param.type + if type then + if type.typename then + if type.modulename then + table.insert(name,type.modulename) + end + table.insert(name,"#") + table.insert(name,type.typename) + else + table.insert(name,"#unknown") + end + end + table.insert(name,"[") + table.insert(name,param.name) + table.insert(name,"]") + end + end + table.insert(name,"__") + table.insert(name, generatefunctiontypeid()) + return table.concat(name) +end + + + +------------------------------------------------------ +-- create the module api +function M.createmoduleapi(ast,modulename) + + -- Initialise function type naming + resetfunctiontypeidgenerator() + + local _file = apimodel._file() + + local _comment2apiobj = {} + + local function handlecomment(comment) + + -- Extract information from tagged comments + local parsedcomment = ldp.parse(comment[1]) + if not parsedcomment then return nil end + + -- Get tags from the languages + local regulartags = parsedcomment.tags + + -- Will contain last API object generated from comments + local _lastapiobject + + -- if comment is an ld comment + if regulartags then + -- manage "module" comment + if regulartags["module"] then + -- get name + _file.name = regulartags["module"][1].name or modulename + _lastapiobject = _file + + -- manage descriptions + _file.shortdescription = parsedcomment.shortdescription + _file.description = parsedcomment.description + + local sourcerangemin = comment.lineinfo.first.offset + local sourcerangemax = comment.lineinfo.last.offset + + -- manage returns + if regulartags ["return"] then + for _, dt_return in ipairs(regulartags ["return"]) do + local _return = createreturn(dt_return,_file,sourcerangemin,sourcerangemax) + table.insert(_file.returns,_return) + end + end + -- if no returns on module create a defaultreturn of type #modulename + if #_file.returns == 0 and _file.name then + -- create internal type ref + local _typeref = apimodel._internaltyperef() + _typeref.typename = _file.name + + -- create return + local _return = apimodel._return() + table.insert(_return.types,_typeref) + + -- add return + table.insert(_file.returns,_return) + + --create recordtypedef is not define + gettypedef(_file,_typeref.typename,"recordtypedef",sourcerangemin,sourcerangemax) + end + -- manage "type" comment + elseif regulartags["type"] and regulartags["type"][1].name ~= "global" then + local dt_type = regulartags["type"][1]; + -- create record type if it doesn't exist + local sourcerangemin = comment.lineinfo.first.offset + local sourcerangemax = comment.lineinfo.last.offset + local _recordtypedef = gettypedef (_file, dt_type.name ,"recordtypedef",sourcerangemin,sourcerangemax) + _lastapiobject = _recordtypedef + + -- re-set sourcerange in case the type was created before the type tag + _recordtypedef.sourcerange.min = sourcerangemin + _recordtypedef.sourcerange.max = sourcerangemax + + -- manage description + _recordtypedef.shortdescription = parsedcomment.shortdescription + _recordtypedef.description = parsedcomment.description + + -- manage fields + if regulartags["field"] then + for _, dt_field in ipairs(regulartags["field"]) do + local _item = createfield(dt_field,_file,sourcerangemin,sourcerangemax) + -- define sourcerange only if we create it + _item.sourcerange.min = sourcerangemin + _item.sourcerange.max = sourcerangemax + if _item then _recordtypedef:addfield(_item) end + end + end + elseif regulartags["field"] then + local dt_field = regulartags["field"][1] + + -- create item + local sourcerangemin = comment.lineinfo.first.offset + local sourcerangemax = comment.lineinfo.last.offset + local _item = createfield(dt_field,_file,sourcerangemin,sourcerangemax) + _item.shortdescription = parsedcomment.shortdescription + _item.description = parsedcomment.description + _lastapiobject = _item + + -- define sourcerange + _item.sourcerange.min = sourcerangemin + _item.sourcerange.max = sourcerangemax + + -- add item to its parent + local scope = regulartags["field"][1].parent + M.additemtoparent(_file,_item,scope,sourcerangemin,sourcerangemax) + elseif regulartags["function"] or regulartags["param"] or regulartags["return"] then + -- create item + local _item = apimodel._item() + _item.shortdescription = parsedcomment.shortdescription + _item.description = parsedcomment.description + _lastapiobject = _item + + -- set name + if regulartags["function"] then _item.name = regulartags["function"][1].name end + + -- define sourcerange + local sourcerangemin = comment.lineinfo.first.offset + local sourcerangemax = comment.lineinfo.last.offset + _item.sourcerange.min = sourcerangemin + _item.sourcerange.max = sourcerangemax + + + -- create function type + local _functiontypedef = apimodel._functiontypedef() + _functiontypedef.shortdescription = parsedcomment.shortdescription + _functiontypedef.description = parsedcomment.description + + + -- manage params + if regulartags["param"] then + for _, dt_param in ipairs(regulartags["param"]) do + local _param = createparam(dt_param,_file,sourcerangemin,sourcerangemax) + table.insert(_functiontypedef.params,_param) + end + end + + -- manage returns + if regulartags["return"] then + for _, dt_return in ipairs(regulartags["return"]) do + local _return = createreturn(dt_return,_file,sourcerangemin,sourcerangemax) + table.insert(_functiontypedef.returns,_return) + end + end + + -- add type name + _functiontypedef.name = generatefunctiontypename(_functiontypedef) + _file:addtype(_functiontypedef) + + -- create ref to this type + local _internaltyperef = apimodel._internaltyperef() + _internaltyperef.typename = _functiontypedef.name + _item.type=_internaltyperef + + -- add item to its parent + local sourcerangemin = comment.lineinfo.first.offset + local sourcerangemax = comment.lineinfo.last.offset + local scope = (regulartags["function"] and regulartags["function"][1].parent) or nil + M.additemtoparent(_file,_item,scope,sourcerangemin,sourcerangemax) + end + end + + -- when we could not know which type of api object it is, we suppose this is an item + if not _lastapiobject then + _lastapiobject = apimodel._item() + _lastapiobject.shortdescription = parsedcomment.shortdescription + _lastapiobject.description = parsedcomment.description + _lastapiobject.sourcerange.min = comment.lineinfo.first.offset + _lastapiobject.sourcerange.max = comment.lineinfo.last.offset + end + + -- + -- Store user defined tags + -- + local thirdtags = parsedcomment and parsedcomment.unknowntags + if thirdtags then + -- Define a storage index for user defined tags on current API element + if not _lastapiobject.metadata then _lastapiobject.metadata = {} end + + -- Loop over user defined tags + for usertag, taglist in pairs(thirdtags) do + if not _lastapiobject.metadata[ usertag ] then + _lastapiobject.metadata[ usertag ] = { + tag = usertag + } + end + for _, tag in ipairs( taglist ) do + table.insert(_lastapiobject.metadata[usertag], tag) + end + end + end + + -- if we create an api object linked it to + _comment2apiobj[comment] =_lastapiobject + end + + local function parsecomment(node, parent, ...) + -- check for comments before this node + if node.lineinfo and node.lineinfo.first.comments then + local comments = node.lineinfo.first.comments + -- check all comments + for _,comment in ipairs(comments) do + -- if not already handled + if not handledcomments[comment] then + handlecomment(comment) + handledcomments[comment]=true + end + end + end + -- check for comments after this node + if node.lineinfo and node.lineinfo.last.comments then + local comments = node.lineinfo.last.comments + -- check all comments + for _,comment in ipairs(comments) do + -- if not already handled + if not handledcomments[comment] then + handlecomment(comment) + handledcomments[comment]=true + end + end + end + end + Q(ast):filter(function(x) return x.tag~=nil end):foreach(parsecomment) + return _file, _comment2apiobj +end + + +function M.extractlocaltype ( commentblock,_file) + if not commentblock then return nil end + + local stringcomment = commentblock[1] + + local parsedtag = ldp.parseinlinecomment(stringcomment) + if parsedtag then + local sourcerangemin = commentblock.lineinfo.first.offset + local sourcerangemax = commentblock.lineinfo.last.offset + + return createtyperef(parsedtag,_file,sourcerangemin,sourcerangemax), parsedtag.description + end + + return nil, stringcomment +end + +M.generatefunctiontypename = generatefunctiontypename + +return M \ No newline at end of file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/internalmodel.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/internalmodel.lua new file mode 100644 index 000000000..552521052 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/internalmodel.lua @@ -0,0 +1,65 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +local M = {} + +function M._internalcontent() + return { + content = nil, -- block + unknownglobalvars = {}, -- list of item + tag = "MInternalContent" + } +end + +function M._block() + return { + content = {}, -- list of expr (identifier, index, call, invoke, block) + localvars = {}, -- list of {var=item, scope ={min,max}} + sourcerange = {min=0,max=0}, + tag = "MBlock" + } +end + +function M._identifier() + return { + definition = nil, -- item + sourcerange = {min=0,max=0}, + tag = "MIdentifier" + } +end + +function M._index(key, value) + return { + left= key, -- expr (identifier, index, call, invoke, block) + right= value, -- string + sourcerange = {min=0,max=0}, + tag = "MIndex" + } +end + +function M._call(funct) + return { + func = funct, -- expr (identifier, index, call, invoke, block) + sourcerange = {min=0,max=0}, + tag = "MCall" + } +end + +function M._invoke(name, expr) + return { + functionname = name, -- string + record = expr, -- expr (identifier, index, call, invoke, block) + sourcerange = {min=0,max=0}, + tag = "MInvoke" + } +end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/internalmodelbuilder.mlua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/internalmodelbuilder.mlua new file mode 100644 index 000000000..4aeafa6cb --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/internalmodelbuilder.mlua @@ -0,0 +1,861 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2011-2012 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Simon BERNARD +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +-{ extension ('match', ...) } + +local Q = require 'metalua.treequery' + +local internalmodel = require 'models.internalmodel' +local apimodel = require 'models.apimodel' +local apimodelbuilder = require 'models.apimodelbuilder' + +local M = {} + +-- Analyzes an AST and returns two tables +-- * `locals`, which associates `Id{ } nodes which create a local variable +-- to a list of the `Id{ } occurrence nodes of that variable; +-- * `globals` which associates variable names to occurrences of +-- global variables having that name. +function bindings(ast) + local locals, globals = { }, { } + local function f(id, ...) + local name = id[1] + if Q.is_binder(id, ...) then + local binder = ... -- parent is the binder + locals[binder] = locals[binder] or { } + locals[binder][name]={ } + else + local _, binder = Q.get_binder(id, ...) + if binder then -- this is a local + table.insert(locals[binder][name], id) + else + local g = globals[name] + if g then table.insert(g, id) else globals[name]={id} end + end + end + end + Q(ast) :filter('Id') :foreach(f) + return locals, globals +end + +-- -------------------------------------- + +-- ---------------------------------------------------------- +-- return the comment linked before to this node +-- ---------------------------------------------------------- +local function getlinkedcommentbefore(node) + local function _getlinkedcomment(node,line) + if node and node.lineinfo and node.lineinfo.first.line == line then + -- get the last comment before (the nearest of code) + local comments = node.lineinfo.first.comments + local comment = comments and comments[#comments] + if comment and comment.lineinfo.last.line == line-1 then + -- ignore the comment if there are code before on the same line + if node.lineinfo.first.facing and (node.lineinfo.first.facing.line ~= comment.lineinfo.first.line) then + return comment + end + else + return _getlinkedcomment(node.parent,line) + end + end + return nil + end + + if node.lineinfo and node.lineinfo.first.line then + return _getlinkedcomment(node,node.lineinfo.first.line) + else + return nil + end +end + +-- ---------------------------------------------------------- +-- return the comment linked after to this node +-- ---------------------------------------------------------- +local function getlinkedcommentafter(node) + local function _getlinkedcomment(node,line) + if node and node.lineinfo and node.lineinfo.last.line == line then + -- get the first comment after (the nearest of code) + local comments = node.lineinfo.last.comments + local comment = comments and comments[1] + if comment and comment.lineinfo.first.line == line then + return comment + else + return _getlinkedcomment(node.parent,line) + end + end + return nil + end + + if node.lineinfo and node.lineinfo.last.line then + return _getlinkedcomment(node,node.lineinfo.last.line) + else + return nil + end +end + +-- ---------------------------------------------------------- +-- return true if this node is a block for the internal representation +-- ---------------------------------------------------------- +local supported_b = { + Function = true, + Do = true, + While = true, + Fornum = true, + Forin = true, + Repeat = true, +} +local function supportedblock(node, parent) + return supported_b[ node.tag ] or + (parent and parent.tag == "If" and node.tag == nil) +end + +-- ---------------------------------------------------------- +-- create a block from the metalua node +-- ---------------------------------------------------------- +local function createblock(block, parent) + local _block = internalmodel._block() + match block with + | `Function{param, body} + | `Do{...} + | `Fornum {identifier, min, max, body} + | `Forin {identifiers, exprs, body} + | `Repeat {body, expr} -> + _block.sourcerange.min = block.lineinfo.first.offset + _block.sourcerange.max = block.lineinfo.last.offset + | `While {expr, body} -> + _block.sourcerange.min = body.lineinfo.first.facing.offset + _block.sourcerange.max = body.lineinfo.last.facing.offset + | _ -> + if parent and parent.tag == "If" and block.tag == nil then + _block.sourcerange.min = block.lineinfo.first.facing.offset + _block.sourcerange.max = block.lineinfo.last.facing.offset + end + end + return _block +end + +-- ---------------------------------------------------------- +-- return true if this node is a expression in the internal representation +-- ---------------------------------------------------------- +local supported_e = { + Index = true, + Id = true, + Call = true, + Invoke = true +} +local function supportedexpr(node) + return supported_e[ node.tag ] +end + +local idto_block = {} -- cache from metalua id to internal model block +local idto_identifier = {} -- cache from metalua id to internal model indentifier +local expreto_expression = {} -- cache from metalua expression to internal model expression + +-- ---------------------------------------------------------- +-- create an expression from a metalua node +-- ---------------------------------------------------------- +local function createexpr(expr,_block) + local _expr = nil + + match expr with + | `Id { name } -> + -- we store the block which hold this node + -- to be able to define + idto_block[expr]= _block + + -- if expr has not line info, it means expr has no representation in the code + -- so we don't need it. + if not expr.lineinfo then return nil end + + -- create identifier + local _identifier = internalmodel._identifier() + idto_identifier[expr]= _identifier + _expr = _identifier + | `Index { innerexpr, `String{fieldname} } -> + if not expr.lineinfo then return nil end + -- create index + local _expression = createexpr(innerexpr,_block) + if _expression then _expr = internalmodel._index(_expression,fieldname) end + | `Call{innerexpr, ...} -> + if not expr.lineinfo then return nil end + -- create call + local _expression = createexpr(innerexpr,_block) + if _expression then _expr = internalmodel._call(_expression) end + | `Invoke{innerexpr,`String{functionname},...} -> + if not expr.lineinfo then return nil end + -- create invoke + local _expression = createexpr(innerexpr,_block) + if _expression then _expr = internalmodel._invoke(functionname,_expression) end + | _ -> + end + + if _expr then + _expr.sourcerange.min = expr.lineinfo.first.offset + _expr.sourcerange.max = expr.lineinfo.last.offset + + expreto_expression[expr] = _expr + end + + return _expr +end + +-- ---------------------------------------------------------- +-- create block and expression node +-- ---------------------------------------------------------- +local function createtreestructure(ast) + -- create internal content + local _internalcontent = internalmodel._internalcontent() + + -- create root block + local _block = internalmodel._block() + local _blocks = { _block } + _block.sourcerange.min = ast.lineinfo.first.facing.offset + -- TODO remove the math.max when we support partial AST + _block.sourcerange.max = math.max(ast.lineinfo.last.facing.offset, 10000) + + _internalcontent.content = _block + + -- visitor function (down) + local function down (node,parent) + if supportedblock(node,parent) then + -- create the block + local _block = createblock(node,parent) + -- add it to parent block + table.insert(_blocks[#_blocks].content, _block) + -- enqueue the last block to know the "current" block + table.insert(_blocks,_block) + elseif supportedexpr(node) then + -- we handle expression only if it was not already do + if not expreto_expression[node] then + -- create expr + local _expression = createexpr(node,_blocks[#_blocks]) + -- add it to parent block + if _expression then + table.insert(_blocks[#_blocks].content, _expression) + end + end + end + end + + -- visitor function (up) + local function up (node, parent) + if supportedblock(node,parent) then + -- dequeue the last block to know the "current" block + table.remove(_blocks,#_blocks) + end + end + + -- visit ast and build internal model + Q(ast):foreach(down,up) + + return _internalcontent +end + +local getitem + +-- ---------------------------------------------------------- +-- create the type from the node and position +-- ---------------------------------------------------------- +local function createtype(node,position,comment2apiobj,file) + -- create module type ref + match node with + | `Call{ `Id "require", `String {modulename}} -> + return apimodel._moduletyperef(modulename,position) + | `Function {params, body} -> + -- create the functiontypedef from code + local _functiontypedef = apimodel._functiontypedef() + for _, p in ipairs(params) do + -- create parameters + local paramname + if p.tag=="Dots" then + paramname = "..." + else + paramname = p[1] + end + local _param = apimodel._parameter(paramname) + table.insert(_functiontypedef.params,_param) + end + _functiontypedef.name = "___" -- no name for inline type + + return apimodel._inlinetyperef(_functiontypedef) + | `String {value} -> + local typeref = apimodel._primitivetyperef("string") + return typeref + | `Number {value} -> + local typeref = apimodel._primitivetyperef("number") + return typeref + | `True | `False -> + local typeref = apimodel._primitivetyperef("boolean") + return typeref + | `Table {...} -> + -- create recordtypedef from code + local _recordtypedef = apimodel._recordtypedef("___") -- no name for inline type + -- for each element of the table + for i=1,select("#", ...) do + local pair = select(i, ...) + -- if this is a pair we create a new item in the type + if pair.tag == "Pair" then + -- create an item + local _item = getitem(pair,nil, comment2apiobj,file) + if _item then + _recordtypedef:addfield(_item) + end + end + end + return apimodel._inlinetyperef(_recordtypedef) + | _ -> + end + -- if node is an expression supported + local supportedexpr = expreto_expression[node] + if supportedexpr then + -- create expression type ref + return apimodel._exprtyperef(supportedexpr,position) + end + +end + +local function completeapidoctype(apidoctype,itemname,init,file,comment2apiobj) + if not apidoctype.name then + apidoctype.name = itemname + file:mergetype(apidoctype) + end + + -- create type from code + local typeref = createtype(init,1,comment2apiobj,file) + if typeref and typeref.tag == "inlinetyperef" + and typeref.def.tag == "recordtypedef" then + + -- set the name + typeref.def.name = apidoctype.name + + -- merge the type with priority to documentation except for source range + file:mergetype(typeref.def,false,true) + end +end + +local function completeapidocitem (apidocitem, itemname, init, file, binder, comment2apiobj) + -- manage the case item has no name + if not apidocitem.name then + apidocitem.name = itemname + + -- if item has no name this means it could not be attach to a parent + if apidocitem.scope then + apimodelbuilder.additemtoparent(file,apidocitem,apidocitem.scope,apidocitem.sourcerange.min,apidocitem.sourcerange.max) + apidocitem.scope = nil + end + end + + -- for function try to merge definition + local apitype = apidocitem:resolvetype(file) + if apitype and apitype.tag == "functiontypedef" then + local codetype = createtype(init,1,comment2apiobj,file) + if codetype and codetype.tag =="inlinetyperef" then + codetype.def.name = apitype.name + file:mergetype(codetype.def) + end + end + + -- manage the case item has no type + if not apidocitem.type then + -- extract typing from comment + local type, desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file) + + if type then + apidocitem.type = type + else + -- if not found extracttype from code + apidocitem.type = createtype(init,1,comment2apiobj,file) + end + end +end + +-- ---------------------------------------------------------- +-- create or get the item finding in the binder with the given itemname +-- return also the ast node corresponding to this item +-- ---------------------------------------------------------- +getitem = function (binder, itemname, comment2apiobj, file) + + -- local function to create item + local function createitem(itemname, astnode, itemtype, description) + local _item = apimodel._item(itemname) + if description then _item.description = description end + _item.type = itemtype + if astnode and astnode.lineinfo then + _item.sourcerange.min = astnode.lineinfo.first.offset + _item.sourcerange.max = astnode.lineinfo.last.offset + end + return _item, astnode + end + + -- try to match binder with known patter of item declaration + match binder with + | `Pair {string, init} + | `Set { {`Index { right , string}}, {init,...}} if string and string.tag =="String" -> + -- Pair and set is for searching field from type .. + -- if the itemname is given this mean we search for a local or a global not a field type. + if not itemname then + local itemname = string[1] + + -- check for luadoc typing + local commentbefore = getlinkedcommentbefore(binder) + local apiobj = comment2apiobj[commentbefore] -- find apiobj linked to this comment + if apiobj then + if apiobj.tag=="item" then + if not apiobj.name or apiobj.name == itemname then + -- use code to complete api information if it's necessary + completeapidocitem(apiobj, itemname, init,file,binder,comment2apiobj) + -- for item use code source range rather than doc source range + if string and string.lineinfo then + apiobj.sourcerange.min = string.lineinfo.first.offset + apiobj.sourcerange.max = string.lineinfo.last.offset + end + return apiobj, string + end + elseif apiobj.tag=="recordtypedef" then + -- use code to complete api information if it's necessary + completeapidoctype(apiobj, itemname, init,file,comment2apiobj) + return createitem(itemname, string, apimodel._internaltyperef(apiobj.name), nil) + end + + -- if the apiobj could not be associated to the current obj, + -- we do not use the documentation neither + commentbefore = nil + end + + -- else we use code to extract the type and description + -- check for "local" typing + local type, desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file) + local desc = desc or (commentbefore and commentbefore[1]) + if type then + return createitem(itemname, string, type, desc ) + else + -- if no "local typing" extract type from code + return createitem(itemname, string, createtype(init,1,comment2apiobj,file), desc) + end + end + | `Set {ids, inits} + | `Local {ids, inits} -> + -- if this is a single local var declaration + -- we check if there are a comment block linked and try to extract the type + if #ids == 1 then + local currentid, currentinit = ids[1],inits[1] + -- ignore non Ids node + if currentid.tag ~= 'Id' or currentid[1] ~= itemname then return nil end + + -- check for luadoc typing + local commentbefore = getlinkedcommentbefore(binder) + local apiobj = comment2apiobj[commentbefore] -- find apiobj linked to this comment + if apiobj then + if apiobj.tag=="item" then + -- use code to complete api information if it's necessary + if not apiobj.name or apiobj.name == itemname then + completeapidocitem(apiobj, itemname, currentinit,file,binder,comment2apiobj) + -- if this is a global var or if is has no parent + -- we do not create a new item + if not apiobj.parent or apiobj.parent == file then + -- for item use code source range rather than doc source range + if currentid and currentid.lineinfo then + apiobj.sourcerange.min = currentid.lineinfo.first.offset + apiobj.sourcerange.max = currentid.lineinfo.last.offset + end + return apiobj, currentid + else + return createitem(itemname, currentid, apiobj.type, nil) + end + end + elseif apiobj.tag=="recordtypedef" then + -- use code to complete api information if it's necessary + completeapidoctype(apiobj, itemname, currentinit,file,comment2apiobj) + return createitem(itemname, currentid, apimodel._internaltyperef(apiobj.name), nil) + end + + -- if the apiobj could not be associated to the current obj, + -- we do not use the documentation neither + commentbefore = nil + end + + -- else we use code to extract the type and description + -- check for "local" typing + local type,desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file) + desc = desc or (commentbefore and commentbefore[1]) + if type then + return createitem(itemname, currentid, type, desc) + else + -- if no "local typing" extract type from code + return createitem(itemname, currentid, createtype(currentinit,1,comment2apiobj,file), desc) + end + end + -- else we use code to extract the type + local init,returnposition = nil,1 + for i,id in ipairs(ids) do + -- calculate the current return position + if init and (init.tag == "Call" or init.tag == "Invoke") then + -- if previous init was a call or an invoke + -- we increment the returnposition + returnposition= returnposition+1 + else + -- if init is not a function call + -- we change the init used to determine the type + init = inits[i] + end + + -- get the name of the current id + local idname = id[1] + + -- if this is the good id + if itemname == idname then + -- create type from init node and return position + return createitem (itemname, id, createtype(init,returnposition,comment2apiobj,file),nil) + end + end + | `Function {params, body} -> + for i,id in ipairs(params) do + -- get the name of the current id + local idname = id[1] + -- if this is the good id + if itemname == idname then + -- extract param's type from luadocumentation + local obj = comment2apiobj[getlinkedcommentbefore(binder)] + if obj and obj.tag=="item" then + local typedef = obj:resolvetype(file) + if typedef and typedef.tag =="functiontypedef" then + for j, param in ipairs(typedef.params) do + if i==j then + if i ==1 and itemname == "self" and param.type == nil + and obj.parent and obj.parent.tag == "recordtypedef" and obj.parent.name then + param.type = apimodel._internaltyperef(obj.parent.name) + end + -- TODO perhaps we must clone the typeref + return createitem(itemname,id, param.type,param.description) + end + end + end + end + return createitem(itemname,id) + end + end + | `Forin {ids, expr, body} -> + for i,id in ipairs(ids) do + -- get the name of the current id + local idname = id[1] + -- if this is the good id + if itemname == idname then + -- return data : we can not guess the type for now + return createitem(itemname,id) + end + end + | `Fornum {id, ...} -> + -- get the name of the current id + local idname = id[1] + -- if this is the good id + if itemname == idname then + -- return data : we can not guess the type for now + return createitem(itemname,id) + end + | `Localrec {{id}, {func}} -> + -- get the name of the current id + local idname = id[1] + -- if this is the good id + if itemname == idname then + -- check for luadoc typing + local commentbefore = getlinkedcommentbefore(binder) + local apiobj = comment2apiobj[commentbefore] -- find apiobj linked to this comment + if apiobj then + if apiobj.tag=="item" then + if not apiobj.name or apiobj.name == itemname then + -- use code to complete api information if it's necessary + completeapidocitem(apiobj, itemname, func,file,binder,comment2apiobj) + return createitem(itemname,id,apiobj.type,nil) + end + end + + -- if the apiobj could not be associated to the current obj, + -- we do not use the documentation neither + commentbefore = nil + end + + -- else we use code to extract the type and description + -- check for "local" typing + local type,desc = apimodelbuilder.extractlocaltype(getlinkedcommentafter(binder),file) + desc = desc or (commentbefore and commentbefore[1]) + if type then + return createitem(itemname, id, type, desc) + else + -- if no "local typing" extract type from code + return createitem(itemname, id, createtype(func,1,comment2apiobj,file), desc) + end + end + | _ -> + end +end + +-- ---------------------------------------------------------- +-- Search from Id node to Set node to find field of type. +-- +-- Lua code : table.field1.field2 = 12 +-- looks like that in metalua : +-- `Set{ +-- `Index { `Index { `Id "table", `String "field1" }, +-- `String "field2"}, +-- `Number "12"} +-- ---------------------------------------------------------- +local function searchtypefield(node,_currentitem,comment2apiobj,file) + + -- we are just interested : + -- by item which is field of recordtypedef + -- by ast node which are Index + if _currentitem then + local type = _currentitem:resolvetype(file) + if type and type.tag == "recordtypedef" then + if node and node.tag == "Index" then + local rightpart = node[2] + local _newcurrentitem = type.fields[rightpart[1]] + + if _newcurrentitem then + -- if this index represent a known field of the type we continue to search + searchtypefield (node.parent,_newcurrentitem,comment2apiobj,file) + else + -- if not, this is perhaps a new field, but + -- to be a new field this index must be include in a Set + if node.parent and node.parent.tag =="Set" then + -- in this case we create the new item ans add it to the type + local set = node.parent + local item, string = getitem(set,nil, comment2apiobj,file) + -- add this item to the type, only if it has no parent and if this type does not contain already this field + if item and not item.parent and string and not type.fields[string[1]] then + type:addfield(item) + end + end + end + end + end + end +end + +-- ---------------------------------------------------------- +-- create local vars, global vars and linked it with theirs occurences +-- ---------------------------------------------------------- +local function createvardefinitions(_internalcontent,ast,file,comment2apiobj) + -- use bindings to get locals and globals definition + local locals, globals = bindings( ast ) + + -- create locals var + for binder, namesAndOccurrences in pairs(locals) do + for name, occurrences in pairs(namesAndOccurrences) do + -- get item, id + local _item, id = getitem(binder, name,comment2apiobj,file) + if id then + -- add definition as occurence + -- we consider the identifier in the binder as an occurence + local _identifierdef = idto_identifier[id] + if _identifierdef then + table.insert(_item.occurrences, _identifierdef) + _identifierdef.definition = _item + end + + -- add occurences + for _,occurrence in ipairs(occurrences) do + searchtypefield(occurrence.parent, _item,comment2apiobj,file) + local _identifier = idto_identifier[occurrence] + if _identifier then + table.insert(_item.occurrences, _identifier) + _identifier.definition = _item + end + end + + -- add item to block + local _block = idto_block[id] + table.insert(_block.localvars,{item=_item,scope = {min=0,max=0}}) + end + end + end + + -- create globals var + for name, occurrences in pairs( globals ) do + + -- get or create definition + local _item = file.globalvars[name] + local binder = occurrences[1].parent + if not _item then + -- global declaration is only if the first occurence in left part of a 'Set' + if binder and binder.tag == "Set" then + _item = getitem(binder, name,comment2apiobj,file) + end + + -- if we find and item this is a global var declaration + if _item then + file:addglobalvar(_item) + else + -- else it is an unknown global var + _item = apimodel._item(name) + local _firstoccurrence = idto_identifier[occurrences[1]] + if _firstoccurrence then + _item.sourcerange.min = _firstoccurrence.sourcerange.min + _item.sourcerange.max = _firstoccurrence.sourcerange.max + end + table.insert(_internalcontent.unknownglobalvars,_item) + end + else + -- if the global var definition already exists, we just try to it + if binder then + match binder with + | `Set {ids, inits} -> + -- manage case only if there are 1 element in the Set + if #ids == 1 then + local currentid, currentinit = ids[1],inits[1] + -- ignore non Ids node and bad name + if currentid.tag == 'Id' and currentid[1] == name then + completeapidocitem(_item, name, currentinit,file,binder,comment2apiobj) + + if currentid and currentid.lineinfo then + _item.sourcerange.min = currentid.lineinfo.first.offset + _item.sourcerange.max = currentid.lineinfo.last.offset + end + end + end + | _ -> + end + end + end + + -- add occurences + for _,occurence in ipairs(occurrences) do + local _identifier = idto_identifier[occurence] + searchtypefield(occurence.parent, _item,comment2apiobj,file) + if _identifier then + table.insert(_item.occurrences, _identifier) + _identifier.definition = _item + end + end + end +end + +-- ---------------------------------------------------------- +-- add parent to all ast node +-- ---------------------------------------------------------- +local function addparents(ast) + -- visitor function (down) + local function down (node,parent) + node.parent = parent + end + + -- visit ast and build internal model + Q(ast):foreach(down,up) +end + +-- ---------------------------------------------------------- +-- try to detect a module declaration from code +-- ---------------------------------------------------------- +local function searchmodule(ast,file,comment2apiobj,modulename) + -- if the last statement is a return + if ast then + local laststatement = ast[#ast] + if laststatement and laststatement.tag == "Return" then + -- and if the first expression returned is an identifier. + local firstexpr = laststatement[1] + if firstexpr and firstexpr.tag == "Id" then + -- get identifier in internal model + local _identifier = idto_identifier [firstexpr] + -- the definition should be an inline type + if _identifier + and _identifier.definition + and _identifier.definition.type + and _identifier.definition.type.tag == "inlinetyperef" + and _identifier.definition.type.def.tag == "recordtypedef" then + + --set modulename if needed + if not file.name then file.name = modulename end + + -- create or merge type + local _type = _identifier.definition.type.def + _type.name = modulename + + -- if file (module) has no documentation add item documentation to it + -- else add it to the type. + if not file.description or file.description == "" then + file.description = _identifier.definition.description + else + _type.description = _identifier.definition.description + end + _identifier.definition.description = "" + if not file.shortdescription or file.shortdescription == "" then + file.shortdescription = _identifier.definition.shortdescription + else + _type.shortdescription = _identifier.definition.shortdescription + end + _identifier.definition.shortdescription = "" + + -- WORKAROUND FOR BUG 421622: [outline]module selection in outline does not select it in texteditor + --_type.sourcerange.min = _identifier.definition.sourcerange.min + --_type.sourcerange.max = _identifier.definition.sourcerange.max + + -- merge the type with priority to documentation except for source range + file:mergetype(_type,false,true) + + -- create return if needed + if not file.returns[1] then + file.returns[1] = apimodel._return() + file.returns[1].types = { apimodel._internaltyperef(modulename) } + end + + -- change the type of the identifier + _identifier.definition.type = apimodel._internaltyperef(modulename) + end + end + end + end +end + +-- ---------------------------------------------------------- +-- create the internalcontent from an ast metalua +-- ---------------------------------------------------------- +function M.createinternalcontent (ast,file,comment2apiobj,modulename) + -- init cache + idto_block = {} + idto_identifier = {} + expreto_expression = {} + comment2apiobj = comment2apiobj or {} + file = file or apimodel._file() + + -- execute code safely to be sure to clean cache correctly + local internalcontent + local ok, errmsg = pcall(function () + -- add parent to all node + addparents(ast) + + -- create block and expression node + internalcontent = createtreestructure(ast) + + -- create Local vars, global vars and linked occurences (Items) + createvardefinitions(internalcontent,ast,file,comment2apiobj) + + -- try to dectect module information from code + local moduletyperef = file:moduletyperef() + if moduletyperef and moduletyperef.tag == "internaltyperef" then + modulename = moduletyperef.typename or modulename + end + if modulename then + searchmodule(ast,file,comment2apiobj,modulename) + end + end) + + -- clean cache + idto_block = {} + idto_identifier = {} + expreto_expression = {} + + -- if not ok raise an error + if not ok then error (errmsg) end + + return internalcontent +end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/ldparser.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/ldparser.lua new file mode 100644 index 000000000..d74071bf4 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/models/ldparser.lua @@ -0,0 +1,656 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2011-2013 Sierra Wireless and others. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Sierra Wireless - initial API and implementation +------------------------------------------------------------------------------- +local mlc = require ('metalua.compiler').new() +local gg = require 'metalua.grammar.generator' +local lexer = require 'metalua.grammar.lexer' +local mlp = mlc.parser + +local M = {} -- module +local lx -- lexer used to parse tag +local registeredparsers -- table {tagname => {list de parsers}} + +-- ---------------------------------------------------- +-- raise an error if result contains a node error +-- ---------------------------------------------------- +local function raiserror(result) + for i, node in ipairs(result) do + assert(not node or node.tag ~= "Error") + end +end + + +-- ---------------------------------------------------- +-- copy key and value from one table to an other +-- ---------------------------------------------------- +local function copykey(tablefrom, tableto) + for key, value in pairs(tablefrom) do + if key ~= "lineinfos" then + tableto[key] = value + end + end +end + +-- ---------------------------------------------------- +-- Handle keyword and identifiers as word +-- ---------------------------------------------------- +local function parseword(lx) + local word = lx :peek() + local tag = word.tag + + if tag=='Keyword' or tag=='Id' then + lx:next() + return {tag='Word', lineinfo=word.lineinfo, word[1]} + else + return gg.parse_error(lx,'Id or Keyword expected') + end +end + +-- ---------------------------------------------------- +-- parse an id +-- return a table {name, lineinfo) +-- ---------------------------------------------------- +local idparser = gg.sequence({ + builder = function (result) + raiserror(result) + return { name = result[1][1] } + end, + parseword +}) + +-- ---------------------------------------------------- +-- parse a modulename (id.)?id +-- return a table {name, lineinfo) +-- ---------------------------------------------------- +local modulenameparser = gg.list({ + builder = function (result) + raiserror(result) + local ids = {} + for i, id in ipairs(result) do + table.insert(ids,id.name) + end + return {name = table.concat(ids,".")} + end, + primary = idparser, + separators = '.' +}) +-- ---------------------------------------------------- +-- parse a typename (id.)?id +-- return a table {name, lineinfo) +-- ---------------------------------------------------- +local typenameparser= modulenameparser + +-- ---------------------------------------------------- +-- parse an internaltype ref +-- return a table {name, lineinfo) +-- ---------------------------------------------------- +local internaltyperefparser = gg.sequence({ + builder = function(result) + raiserror(result) + return {tag = "typeref",type=result[1].name} + end, + "#", typenameparser +}) + +-- ---------------------------------------------------- +-- parse en external type ref +-- return a table {name, lineinfo) +-- ---------------------------------------------------- +local externaltyperefparser = gg.sequence({ + builder = function(result) + raiserror(result) + return {tag = "typeref",module=result[1].name,type=result[2].name} + end, + modulenameparser,"#", typenameparser +}) + + +-- ---------------------------------------------------- +-- parse a typeref +-- return a table {name, lineinfo) +-- ---------------------------------------------------- +local typerefparser = gg.multisequence{ + internaltyperefparser, + externaltyperefparser} + +-- ---------------------------------------------------- +-- parse a list of typeref +-- return a list of table {name, lineinfo) +-- ---------------------------------------------------- +local typereflistparser = gg.list({ + primary = typerefparser, + separators = ',' +}) + +-- ---------------------------------------------------- +-- TODO use a more generic way to parse (modifier if not always a typeref) +-- TODO support more than one modifier +-- ---------------------------------------------------- +local modifiersparser = gg.sequence({ + builder = function(result) + raiserror(result) + return {[result[1].name]=result[2]} + end, + "[", idparser , "=" , internaltyperefparser , "]" +}) + +-- ---------------------------------------------------- +-- parse a return tag +-- ---------------------------------------------------- +local returnparsers = { + -- full parser + gg.sequence({ + builder = function (result) + raiserror(result) + return { types= result[1]} + end, + '@','return', typereflistparser + }), + -- parser without typerefs + gg.sequence({ + builder = function (result) + raiserror(result) + return { types = {}} + end, + '@','return' + }) +} + +-- ---------------------------------------------------- +-- parse a param tag +-- ---------------------------------------------------- +local paramparsers = { + -- full parser + gg.sequence({ + builder = function (result) + raiserror(result) + return { name = result[2].name, type = result[1]} + end, + '@','param', typerefparser, idparser + }), + + -- full parser without type + gg.sequence({ + builder = function (result) + raiserror(result) + return { name = result[1].name} + end, + '@','param', idparser + }), + + -- Parser for `Dots + gg.sequence({ + builder = function (result) + raiserror(result) + return { name = '...' } + end, + '@','param', '...' + }), +} +-- ---------------------------------------------------- +-- parse a field tag +-- ---------------------------------------------------- +local fieldparsers = { + -- full parser + gg.sequence({ + builder = function (result) + raiserror(result) + local tag = {} + copykey(result[1],tag) + tag.type = result[2] + tag.name = result[3].name + return tag + end, + '@','field', modifiersparser, typerefparser, idparser + }), + + -- parser without name + gg.sequence({ + builder = function (result) + raiserror(result) + local tag = {} + copykey(result[1],tag) + tag.type = result[2] + return tag + end, + '@','field', modifiersparser, typerefparser + }), + + -- parser without type + gg.sequence({ + builder = function (result) + raiserror(result) + local tag = {} + copykey(result[1],tag) + tag.name = result[2].name + return tag + end, + '@','field', modifiersparser, idparser + }), + + -- parser without type and name + gg.sequence({ + builder = function (result) + raiserror(result) + local tag = {} + copykey(result[1],tag) + return tag + end, + '@','field', modifiersparser + }), + + -- parser without modifiers + gg.sequence({ + builder = function (result) + raiserror(result) + return { name = result[2].name, type = result[1]} + end, + '@','field', typerefparser, idparser + }), + + -- parser without modifiers and name + gg.sequence({ + builder = function (result) + raiserror(result) + return {type = result[1]} + end, + '@','field', typerefparser + }), + + -- parser without type and modifiers + gg.sequence({ + builder = function (result) + raiserror(result) + return { name = result[1].name} + end, + '@','field', idparser + }), + + -- parser with nothing + gg.sequence({ + builder = function (result) + raiserror(result) + return {} + end, + '@','field' + }) +} + +-- ---------------------------------------------------- +-- parse a function tag +-- TODO use a more generic way to parse modifier ! +-- ---------------------------------------------------- +local functionparsers = { + -- full parser + gg.sequence({ + builder = function (result) + raiserror(result) + local tag = {} + copykey(result[1],tag) + tag.name = result[2].name + return tag + end, + '@','function', modifiersparser, idparser + }), + + -- parser without name + gg.sequence({ + builder = function (result) + raiserror(result) + local tag = {} + copykey(result[1],tag) + return tag + end, + '@','function', modifiersparser + }), + + -- parser without modifier + gg.sequence({ + builder = function (result) + raiserror(result) + local tag = {} + tag.name = result[1].name + return tag + end, + '@','function', idparser + }), + + -- empty parser + gg.sequence({ + builder = function (result) + raiserror(result) + return {} + end, + '@','function' + }) +} + +-- ---------------------------------------------------- +-- parse a type tag +-- ---------------------------------------------------- +local typeparsers = { + -- full parser + gg.sequence({ + builder = function (result) + raiserror(result) + return { name = result[1].name} + end, + '@','type',typenameparser + }), + -- parser without name + gg.sequence({ + builder = function (result) + raiserror(result) + return {} + end, + '@','type' + }) +} + +-- ---------------------------------------------------- +-- parse a module tag +-- ---------------------------------------------------- +local moduleparsers = { + -- full parser + gg.sequence({ + builder = function (result) + raiserror(result) + return { name = result[1].name } + end, + '@','module', modulenameparser + }), + -- parser without name + gg.sequence({ + builder = function (result) + raiserror(result) + return {} + end, + '@','module' + }) +} + +-- ---------------------------------------------------- +-- parse a third tag +-- ---------------------------------------------------- +local thirdtagsparser = gg.sequence({ + builder = function (result) + raiserror(result) + return { name = result[1][1] } + end, + '@', mlp.id +}) +-- ---------------------------------------------------- +-- init parser +-- ---------------------------------------------------- +local function initparser() + -- register parsers + -- each tag name has several parsers + registeredparsers = { + ["module"] = moduleparsers, + ["return"] = returnparsers, + ["type"] = typeparsers, + ["field"] = fieldparsers, + ["function"] = functionparsers, + ["param"] = paramparsers + } + + -- create lexer used for parsing + lx = lexer.lexer:clone() + lx.extractors = { + -- "extract_long_comment", + -- "extract_short_comment", + -- "extract_long_string", + "extract_short_string", + "extract_word", + "extract_number", + "extract_symbol" + } + + -- Add dots as keyword + local tagnames = { '...' } + + -- Add tag names as key word + for tagname, _ in pairs(registeredparsers) do + table.insert(tagnames,tagname) + end + lx:add(tagnames) + + return lx, parsers +end + +initparser() + +-- ---------------------------------------------------- +-- get the string pattern to remove for each line of description +-- the goal is to fix the indentation problems +-- ---------------------------------------------------- +local function getstringtoremove (stringcomment,commentstart) + local _,_,capture = string.find(stringcomment,"\n?([ \t]*)@[^{]+",commentstart) + if not capture then + _,_,capture = string.find(stringcomment,"^([ \t]*)",commentstart) + end + capture = string.gsub(capture,"(.)","%1?") + return capture +end + +-- ---------------------------------------------------- +-- parse comment tag partition and return table structure +-- ---------------------------------------------------- +local function parsetag(part) + if part.comment:find("^@") then + -- check if the part start by a supported tag + for tagname,parsers in pairs(registeredparsers) do + if (part.comment:find("^@"..tagname)) then + -- try the registered parsers for this tag + local result + for i, parser in ipairs(parsers) do + local valid, tag = pcall(parser, lx:newstream(part.comment, tagname .. 'tag lexer')) + if valid then + -- add tagname + tag.tagname = tagname + + -- add description + local endoffset = tag.lineinfo.last.offset + tag.description = part.comment:sub(endoffset+2,-1) + return tag + end + end + end + end + end + return nil +end + +-- ---------------------------------------------------- +-- Parse third party tags. +-- +-- Enable to parse a tag not defined in language. +-- So for, accepted format is: @sometagname adescription +-- ---------------------------------------------------- +local function parsethirdtag( part ) + + -- Check it there is someting to process + if not part.comment:find("^@") then + return nil, 'No tag to parse' + end + + -- Apply parser + local status, parsedtag = pcall(thirdtagsparser, lx:newstream(part.comment, 'Third party tag lexer')) + if not status then + return nil, "Unable to parse given string." + end + + -- Retrieve description + local endoffset = parsedtag.lineinfo.last.offset + local tag = { + description = part.comment:sub(endoffset+2,-1) + } + return parsedtag.name, tag +end + +-- --------------------------------------------------------- +-- split string comment in several part +-- return list of {comment = string, offset = number} +-- the first part is the part before the first tag +-- the others are the part from a tag to the next one +-- ---------------------------------------------------- +local function split(stringcomment,commentstart) + local partstart = commentstart + local result = {} + + -- manage case where the comment start by @ + -- (we must ignore the inline see tag @{..}) + local at_startoffset, at_endoffset = stringcomment:find("^[ \t]*@[^{]",partstart) + if at_endoffset then + partstart = at_endoffset-1 -- we start before the @ and the non '{' character + end + + -- split comment + -- (we must ignore the inline see tag @{..}) + repeat + at_startoffset, at_endoffset = stringcomment:find("\n[ \t]*@[^{]",partstart) + local partend + if at_startoffset then + partend= at_startoffset-1 -- the end is before the separator pattern (just before the \n) + else + partend = #stringcomment -- we don't find any pattern so the end is the end of the string + end + table.insert(result, { comment = stringcomment:sub (partstart,partend) , + offset = partstart}) + if at_endoffset then + partstart = at_endoffset-1 -- the new start is befire the @ and the non { char + end + until not at_endoffset + return result +end + + +-- ---------------------------------------------------- +-- parse a comment block and return a table +-- ---------------------------------------------------- +function M.parse(stringcomment) + + local _comment = {description="", shortdescription=""} + + -- clean windows carriage return + stringcomment = string.gsub(stringcomment,"\r\n","\n") + + -- check if it's a ld comment + -- get the begin of the comment + -- ============================ + if not stringcomment:find("^-") then + -- if this comment don't start by -, we will not handle it. + return nil + end + + -- retrieve the real start + local commentstart = 2 --after the first hyphen + -- if the first line is an empty comment line with at least 3 hyphens we ignore it + local _ , endoffset = stringcomment:find("^-+[ \t]*\n") + if endoffset then + commentstart = endoffset+1 + end + + -- clean comments + -- =================== + -- remove line of "-" + stringcomment = string.sub(stringcomment,commentstart) + -- clean indentation + local pattern = getstringtoremove (stringcomment,1) + stringcomment = string.gsub(stringcomment,"^"..pattern,"") + stringcomment = string.gsub(stringcomment,"\n"..pattern,"\n") + + -- split comment part + -- ==================== + local commentparts = split(stringcomment, 1) + + -- Extract descriptions + -- ==================== + local firstpart = commentparts[1].comment + if firstpart:find("^[^@]") or firstpart:find("^@{") then + -- if the comment part don't start by @ + -- it's the part which contains descriptions + -- (there are an exception for the in-line see tag @{..}) + local shortdescription, description = string.match(firstpart,'^(.-[.?])(%s.+)') + -- store description + if shortdescription then + _comment.shortdescription = shortdescription + -- clean description + -- remove always the first space character + -- (this manage the case short and long description is on the same line) + description = string.gsub(description, "^[ \t]","") + -- if first line is only an empty string remove it + description = string.gsub(description, "^[ \t]*\n","") + _comment.description = description + else + _comment.shortdescription = firstpart + _comment.description = "" + end + end + + -- Extract tags + -- =================== + -- Parse regular tags + local tag + for i, part in ipairs(commentparts) do + tag = parsetag(part) + --if it's a supported tag (so tag is not nil, it's a table) + if tag then + if not _comment.tags then _comment.tags = {} end + if not _comment.tags[tag.tagname] then + _comment.tags[tag.tagname] = {} + end + table.insert(_comment.tags[tag.tagname], tag) + else + + -- Try user defined tags, so far they will look like + -- @identifier description + local tagname, thirdtag = parsethirdtag( part ) + if tagname then + -- + -- Append found tag + -- + local reservedname = 'unknowntags' + if not _comment.unknowntags then + _comment.unknowntags = {} + end + + -- Create specific section for parsed tag + if not _comment.unknowntags[tagname] then + _comment.unknowntags[tagname] = {} + end + -- Append to specific section + table.insert(_comment.unknowntags[tagname], thirdtag) + end + end + end + return _comment +end + + +function M.parseinlinecomment(stringcomment) + --TODO this code is use to activate typage only on --- comments. (deactivate for now) + -- if not stringcomment or not stringcomment:find("^-") then + -- -- if this comment don't start by -, we will not handle it. + -- return nil + -- end + -- -- remove the first '-' + -- stringcomment = string.sub(stringcomment,2) + -- print (stringcomment) + -- io.flush() + local valid, parsedtag = pcall(typerefparser, lx:newstream(stringcomment, 'typeref parser')) + if valid then + local endoffset = parsedtag.lineinfo.last.offset + parsedtag.description = stringcomment:sub(endoffset+2,-1) + return parsedtag + end +end + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Date.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Date.lua new file mode 100644 index 000000000..c11a9ef18 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Date.lua @@ -0,0 +1,546 @@ +--- Date and Date Format classes. +-- See the Guide. +-- @class module +-- @name pl.Date +-- @pragma nostrip + +--[[ +module("pl.Date") +]] + +local class = require 'pl.class' +local os_time, os_date = os.time, os.date +local stringx = require 'pl.stringx' + +local Date = class() +Date.Format = class() + +--- Date constructor. +-- @param t this can be either
      +--
    • nil - use current date and time
    • +--
    • number - seconds since epoch (as returned by @{os.time})
    • +--
    • Date - copy constructor
    • +--
    • table - table containing year, month, etc as for os.time() +-- You may leave out year, month or day, in which case current values will be used. +--
    • +--
    • two to six numbers: year, month, day, hour, min, sec +--
    +-- @function Date +function Date:_init(t,...) + local time + if select('#',...) > 0 then + local extra = {...} + local year = t + t = { + year = year, + month = extra[1], + day = extra[2], + hour = extra[3], + min = extra[4], + sec = extra[5] + } + end + if t == nil then + time = os_time() + elseif type(t) == 'number' then + time = t + elseif type(t) == 'table' then + if getmetatable(t) == Date then -- copy ctor + time = t.time + else + if not (t.year and t.month and t.year) then + local lt = os.date('*t') + if not t.year and not t.month and not t.day then + t.year = lt.year + t.month = lt.month + t.day = lt.day + else + t.year = t.year or lt.year + t.month = t.month or (t.day and lt.month or 1) + t.day = t.day or 1 + end + end + time = os_time(t) + end + end + self:set(time) +end + +local thour,tmin + +--- get the time zone offset from UTC. +-- @return hours ahead of UTC +-- @return minutes ahead of UTC +function Date.tzone () + if not thour then + local t = os.time() + local ut = os.date('!*t',t) + local lt = os.date('*t',t) + thour = lt.hour - ut.hour + tmin = lt.min - ut.min + end + return thour, tmin +end + +--- convert this date to UTC. +function Date:toUTC () + local th, tm = Date.tzone() + self:add { hour = -th } + + if tm > 0 then self:add {min = -tm} end +end + +--- convert this UTC date to local. +function Date:toLocal () + local th, tm = Date.tzone() + self:add { hour = th } + if tm > 0 then self:add {min = tm} end +end + +--- set the current time of this Date object. +-- @param t seconds since epoch +function Date:set(t) + self.time = t + self.tab = os_date('*t',self.time) +end + +--- set the year. +-- @param y Four-digit year +-- @class function +-- @name Date:year + +--- set the month. +-- @param m month +-- @class function +-- @name Date:month + +--- set the day. +-- @param d day +-- @class function +-- @name Date:day + +--- set the hour. +-- @param h hour +-- @class function +-- @name Date:hour + +--- set the minutes. +-- @param min minutes +-- @class function +-- @name Date:min + +--- set the seconds. +-- @param sec seconds +-- @class function +-- @name Date:sec + +--- set the day of year. +-- @class function +-- @param yday day of year +-- @name Date:yday + +--- get the year. +-- @param y Four-digit year +-- @class function +-- @name Date:year + +--- get the month. +-- @class function +-- @name Date:month + +--- get the day. +-- @class function +-- @name Date:day + +--- get the hour. +-- @class function +-- @name Date:hour + +--- get the minutes. +-- @class function +-- @name Date:min + +--- get the seconds. +-- @class function +-- @name Date:sec + +--- get the day of year. +-- @class function +-- @name Date:yday + + +for _,c in ipairs{'year','month','day','hour','min','sec','yday'} do + Date[c] = function(self,val) + if val then + self.tab[c] = val + self:set(os_time(self.tab)) + return self + else + return self.tab[c] + end + end +end + +--- name of day of week. +-- @param full abbreviated if true, full otherwise. +-- @return string name +function Date:weekday_name(full) + return os_date(full and '%A' or '%a',self.time) +end + +--- name of month. +-- @param full abbreviated if true, full otherwise. +-- @return string name +function Date:month_name(full) + return os_date(full and '%B' or '%b',self.time) +end + +--- is this day on a weekend?. +function Date:is_weekend() + return self.tab.wday == 0 or self.tab.wday == 6 +end + +--- add to a date object. +-- @param t a table containing one of the following keys and a value:
    +-- year,month,day,hour,min,sec +-- @return this date +function Date:add(t) + local key,val = next(t) + self.tab[key] = self.tab[key] + val + self:set(os_time(self.tab)) + return self +end + +--- last day of the month. +-- @return int day +function Date:last_day() + local d = 28 + local m = self.tab.month + while self.tab.month == m do + d = d + 1 + self:add{day=1} + end + self:add{day=-1} + return self +end + +--- difference between two Date objects. +-- Note: currently the result is a regular @{Date} object, +-- but also has `interval` field set, which means a more +-- appropriate string rep is used. +-- @param other Date object +-- @return a Date object +function Date:diff(other) + local dt = self.time - other.time + if dt < 0 then error("date difference is negative!",2) end + local date = Date(dt) + date.interval = true + return date +end + +--- long numerical ISO data format version of this date. +function Date:__tostring() + if not self.interval then + return os_date('%Y-%m-%d %H:%M:%S',self.time) + else + local t, res = self.tab, '' + local y,m,d = t.year - 1970, t.month - 1, t.day - 1 + if y > 0 then res = res .. y .. ' years ' end + if m > 0 then res = res .. m .. ' months ' end + if d > 0 then res = res .. d .. ' days ' end + if y == 0 and m == 0 then + local h = t.hour - Date.tzone() -- not accounting for UTC mins! + if h > 0 then res = res .. h .. ' hours ' end + if t.min > 0 then res = res .. t.min .. ' min ' end + if t.sec > 0 then res = res .. t.sec .. ' sec ' end + end + return res + end +end + +--- equality between Date objects. +function Date:__eq(other) + return self.time == other.time +end + +--- equality between Date objects. +function Date:__lt(other) + return self.time < other.time +end + + +------------ Date.Format class: parsing and renderinig dates ------------ + +-- short field names, explicit os.date names, and a mask for allowed field repeats +local formats = { + d = {'day',{true,true}}, + y = {'year',{false,true,false,true}}, + m = {'month',{true,true}}, + H = {'hour',{true,true}}, + M = {'min',{true,true}}, + S = {'sec',{true,true}}, +} + +-- + +--- Date.Format constructor. +-- @param fmt. A string where the following fields are significant:
      +--
    • d day (either d or dd)
    • +--
    • y year (either yy or yyy)
    • +--
    • m month (either m or mm)
    • +--
    • H hour (either H or HH)
    • +--
    • M minute (either M or MM)
    • +--
    • S second (either S or SS)
    • +--
    +-- Alternatively, if fmt is nil then this returns a flexible date parser +-- that tries various date/time schemes in turn: +--
      +--
    1. ISO 8601, +-- like 2010-05-10 12:35:23Z or 2008-10-03T14:30+02
    2. +--
    3. times like 15:30 or 8.05pm (assumed to be today's date)
    4. +--
    5. dates like 28/10/02 (European order!) or 5 Feb 2012
    6. +--
    7. month name like march or Mar (case-insensitive, first 3 letters); +-- here the day will be 1 and the year this current year
    8. +--
    +-- A date in format 3 can be optionally followed by a time in format 2. +-- Please see test-date.lua in the tests folder for more examples. +-- @usage df = Date.Format("yyyy-mm-dd HH:MM:SS") +-- @class function +-- @name Date.Format +function Date.Format:_init(fmt) + if not fmt then return end + local append = table.insert + local D,PLUS,OPENP,CLOSEP = '\001','\002','\003','\004' + local vars,used = {},{} + local patt,outf = {},{} + local i = 1 + while i < #fmt do + local ch = fmt:sub(i,i) + local df = formats[ch] + if df then + if used[ch] then error("field appeared twice: "..ch,2) end + used[ch] = true + -- this field may be repeated + local _,inext = fmt:find(ch..'+',i+1) + local cnt = not _ and 1 or inext-i+1 + if not df[2][cnt] then error("wrong number of fields: "..ch,2) end + -- single chars mean 'accept more than one digit' + local p = cnt==1 and (D..PLUS) or (D):rep(cnt) + append(patt,OPENP..p..CLOSEP) + append(vars,ch) + if ch == 'y' then + append(outf,cnt==2 and '%y' or '%Y') + else + append(outf,'%'..ch) + end + i = i + cnt + else + append(patt,ch) + append(outf,ch) + i = i + 1 + end + end + -- escape any magic characters + fmt = table.concat(patt):gsub('[%-%.%+%[%]%(%)%$%^%%%?%*]','%%%1') + -- replace markers with their magic equivalents + fmt = fmt:gsub(D,'%%d'):gsub(PLUS,'+'):gsub(OPENP,'('):gsub(CLOSEP,')') + self.fmt = fmt + self.outf = table.concat(outf) + self.vars = vars + +end + +local parse_date + +--- parse a string into a Date object. +-- @param str a date string +-- @return date object +function Date.Format:parse(str) + if not self.fmt then + return parse_date(str,self.us) + end + local res = {str:match(self.fmt)} + if #res==0 then return nil, 'cannot parse '..str end + local tab = {} + for i,v in ipairs(self.vars) do + local name = formats[v][1] -- e.g. 'y' becomes 'year' + tab[name] = tonumber(res[i]) + end + -- os.date() requires these fields; if not present, we assume + -- that the time set is for the current day. + if not (tab.year and tab.month and tab.year) then + local today = Date() + tab.year = tab.year or today:year() + tab.month = tab.month or today:month() + tab.day = tab.day or today:month() + end + local Y = tab.year + if Y < 100 then -- classic Y2K pivot + tab.year = Y + (Y < 35 and 2000 or 1999) + elseif not Y then + tab.year = 1970 + end + --dump(tab) + return Date(tab) +end + +--- convert a Date object into a string. +-- @param d a date object, or a time value as returned by @{os.time} +-- @return string +function Date.Format:tostring(d) + local tm = type(d) == 'number' and d or d.time + if self.outf then + return os.date(self.outf,tm) + else + return tostring(Date(d)) + end +end + +function Date.Format:US_order(yesno) + self.us = yesno +end + +local months = {jan=1,feb=2,mar=3,apr=4,may=5,jun=6,jul=7,aug=8,sep=9,oct=10,nov=11,dec=12} + +--[[ +Allowed patterns: +- [day] [monthname] [year] [time] +- [day]/[month][/year] [time] + +]] + + +local is_word = stringx.isalpha +local is_number = stringx.isdigit +local function tonum(s,l1,l2,kind) + kind = kind or '' + local n = tonumber(s) + if not n then error(("%snot a number: '%s'"):format(kind,s)) end + if n < l1 or n > l2 then + error(("%s out of range: %s is not between %d and %d"):format(kind,s,l1,l2)) + end + return n +end + +local function parse_iso_end(p,ns,sec) + -- may be fractional part of seconds + local _,nfrac,secfrac = p:find('^%.%d+',ns+1) + if secfrac then + sec = sec .. secfrac + p = p:sub(nfrac+1) + else + p = p:sub(ns+1) + end + -- ISO 8601 dates may end in Z (for UTC) or [+-][isotime] + if p:match 'z$' then return sec, {h=0,m=0} end -- we're UTC! + p = p:gsub(':','') -- turn 00:30 to 0030 + local _,_,sign,offs = p:find('^([%+%-])(%d+)') + if not sign then return sec, nil end -- not UTC + + if #offs == 2 then offs = offs .. '00' end -- 01 to 0100 + local tz = { h = tonumber(offs:sub(1,2)), m = tonumber(offs:sub(3,4)) } + if sign == '-' then tz.h = -tz.h; tz.m = -tz.m end + return sec, tz +end + +local function parse_date_unsafe (s,US) + s = s:gsub('T',' ') -- ISO 8601 + local parts = stringx.split(s:lower()) + local i,p = 1,parts[1] + local function nextp() i = i + 1; p = parts[i] end + local year,min,hour,sec,apm + local tz + local _,nxt,day, month = p:find '^(%d+)/(%d+)' + if day then + -- swop for US case + if US then + day, month = month, day + end + _,_,year = p:find('^/(%d+)',nxt+1) + nextp() + else -- ISO + year,month,day = p:match('^(%d+)%-(%d+)%-(%d+)') + if year then + nextp() + end + end + if p and not year and is_number(p) then -- has to be date + day = p + nextp() + end + if p and is_word(p) then + p = p:sub(1,3) + local mon = months[p] + if mon then + month = mon + else error("not a month: " .. p) end + nextp() + end + if p and not year and is_number(p) then + year = p + nextp() + end + + if p then -- time is hh:mm[:ss], hhmm[ss] or H.M[am|pm] + _,nxt,hour,min = p:find '^(%d+):(%d+)' + local ns + if nxt then -- are there seconds? + _,ns,sec = p:find ('^:(%d+)',nxt+1) + --if ns then + sec,tz = parse_iso_end(p,ns or nxt,sec) + --end + else -- might be h.m + _,ns,hour,min = p:find '^(%d+)%.(%d+)' + if ns then + apm = p:match '[ap]m$' + else -- or hhmm[ss] + local hourmin + _,nxt,hourmin = p:find ('^(%d+)') + if nxt then + hour = hourmin:sub(1,2) + min = hourmin:sub(3,4) + sec = hourmin:sub(5,6) + if #sec == 0 then sec = nil end + sec,tz = parse_iso_end(p,nxt,sec) + end + end + end + end + local today + if not (year and month and day) then + today = Date() + end + day = day and tonum(day,1,31,'day') or (month and 1 or today:day()) + month = month and tonum(month,1,12,'month') or today:month() + year = year and tonumber(year) or today:year() + if year < 100 then -- two-digit year pivot + year = year + (year < 35 and 2000 or 1900) + end + hour = hour and tonum(hour,1,apm and 12 or 24,'hour') or 12 + if apm == 'pm' then + hour = hour + 12 + end + min = min and tonum(min,1,60) or 0 + sec = sec and tonum(sec,1,60) or 0 + local res = Date {year = year, month = month, day = day, hour = hour, min = min, sec = sec} + if tz then -- ISO 8601 UTC time + res:toUTC() + res:add {hour = tz.h} + if tz.m ~= 0 then res:add {min = tz.m} end + end + return res +end + +function parse_date (s) + local ok, d = pcall(parse_date_unsafe,s) + if not ok then -- error + d = d:gsub('.-:%d+: ','') + return nil, d + else + return d + end +end + + +return Date + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/List.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/List.lua new file mode 100644 index 000000000..776f4d938 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/List.lua @@ -0,0 +1,553 @@ +--- Python-style list class.

    +-- Based on original code by Nick Trout. +--

    +-- Please Note: methods that change the list will return the list. +-- This is to allow for method chaining, but please note that ls = ls:sort() +-- does not mean that a new copy of the list is made. In-place (mutable) methods +-- are marked as returning 'the list' in this documentation. +--

    +-- See the Guide for further discussion +--

    +-- See http://www.python.org/doc/current/tut/tut.html, section 5.1 +--

    +-- Note: The comments before some of the functions are from the Python docs +-- and contain Python code. +--

    +-- Written for Lua version 4.0
    +-- Redone for Lua 5.1, Steve Donovan. +-- @class module +-- @name pl.List +-- @pragma nostrip + +local tinsert,tremove,concat,tsort = table.insert,table.remove,table.concat,table.sort +local setmetatable, getmetatable,type,tostring,assert,string,next = setmetatable,getmetatable,type,tostring,assert,string,next +local write = io.write +local tablex = require 'pl.tablex' +local filter,imap,imap2,reduce,transform,tremovevalues = tablex.filter,tablex.imap,tablex.imap2,tablex.reduce,tablex.transform,tablex.removevalues +local tablex = tablex +local tsub = tablex.sub +local utils = require 'pl.utils' +local function_arg = utils.function_arg +local is_type = utils.is_type +local split = utils.split +local assert_arg = utils.assert_arg +local normalize_slice = tablex._normalize_slice + +--[[ +module ('pl.List',utils._module) +]] + +local Multimap = utils.stdmt.MultiMap +-- metatable for our list objects +local List = utils.stdmt.List +List.__index = List +List._class = List + +local iter + +-- we give the metatable its own metatable so that we can call it like a function! +setmetatable(List,{ + __call = function (tbl,arg) + return List.new(arg) + end, +}) + +local function makelist (t,obj) + local klass = List + if obj then + klass = getmetatable(obj) + end + return setmetatable(t,klass) +end + +local function is_list(t) + return getmetatable(t) == List +end + +local function simple_table(t) + return type(t) == 'table' and not is_list(t) and #t > 0 +end + +function List:_init (src) + if src then + for v in iter(src) do + tinsert(self,v) + end + end +end + +--- Create a new list. Can optionally pass a table; +-- passing another instance of List will cause a copy to be created +-- we pass anything which isn't a simple table to iterate() to work out +-- an appropriate iterator @see List.iterate +-- @param t An optional list-like table +-- @return a new List +-- @usage ls = List(); ls = List {1,2,3,4} +function List.new(t) + local ls + if not simple_table(t) then + ls = {} + List._init(ls,t) + else + ls = t + end + makelist(ls) + return ls +end + +function List:clone() + local ls = makelist({},self) + List._init(ls,self) + return ls +end + +function List.default_map_with(T) + return function(self,name) + local f = T[name] + if f then + return function(self,...) + return self:map(f,...) + end + else + error("method not found: "..name,2) + end + end +end + + +---Add an item to the end of the list. +-- @param i An item +-- @return the list +function List:append(i) + tinsert(self,i) + return self +end + +List.push = tinsert + +--- Extend the list by appending all the items in the given list. +-- equivalent to 'a[len(a):] = L'. +-- @param L Another List +-- @return the list +function List:extend(L) + assert_arg(1,L,'table') + for i = 1,#L do tinsert(self,L[i]) end + return self +end + +--- Insert an item at a given position. i is the index of the +-- element before which to insert. +-- @param i index of element before whichh to insert +-- @param x A data item +-- @return the list +function List:insert(i, x) + assert_arg(1,i,'number') + tinsert(self,i,x) + return self +end + +--- Insert an item at the begining of the list. +-- @param x a data item +-- @return the list +function List:put (x) + return self:insert(1,x) +end + +--- Remove an element given its index. +-- (equivalent of Python's del s[i]) +-- @param i the index +-- @return the list +function List:remove (i) + assert_arg(1,i,'number') + tremove(self,i) + return self +end + +--- Remove the first item from the list whose value is given. +-- (This is called 'remove' in Python; renamed to avoid confusion +-- with table.remove) +-- Return nil if there is no such item. +-- @param x A data value +-- @return the list +function List:remove_value(x) + for i=1,#self do + if self[i]==x then tremove(self,i) return self end + end + return self + end + +--- Remove the item at the given position in the list, and return it. +-- If no index is specified, a:pop() returns the last item in the list. +-- The item is also removed from the list. +-- @param i An index +-- @return the item +function List:pop(i) + if not i then i = #self end + assert_arg(1,i,'number') + return tremove(self,i) +end + +List.get = List.pop + +--- Return the index in the list of the first item whose value is given. +-- Return nil if there is no such item. +-- @class function +-- @name List:index +-- @param x A data value +-- @param idx where to start search (default 1) +-- @return the index, or nil if not found. + +local tfind = tablex.find +List.index = tfind + +--- does this list contain the value?. +-- @param x A data value +-- @return true or false +function List:contains(x) + return tfind(self,x) and true or false +end + +--- Return the number of times value appears in the list. +-- @param x A data value +-- @return number of times x appears +function List:count(x) + local cnt=0 + for i=1,#self do + if self[i]==x then cnt=cnt+1 end + end + return cnt +end + +--- Sort the items of the list, in place. +-- @param cmp an optional comparison function; '<' is used if not given. +-- @return the list +function List:sort(cmp) + tsort(self,cmp) + return self +end + +--- Reverse the elements of the list, in place. +-- @return the list +function List:reverse() + local t = self + local n = #t + local n2 = n/2 + for i = 1,n2 do + local k = n-i+1 + t[i],t[k] = t[k],t[i] + end + return self +end + +--- Emulate list slicing. like 'list[first:last]' in Python. +-- If first or last are negative then they are relative to the end of the list +-- eg. slice(-2) gives last 2 entries in a list, and +-- slice(-4,-2) gives from -4th to -2nd +-- @param first An index +-- @param last An index +-- @return a new List +function List:slice(first,last) + return tsub(self,first,last) +end + +--- empty the list. +-- @return the list +function List:clear() + for i=1,#self do tremove(self,i) end + return self +end + +local eps = 1.0e-10 + +--- Emulate Python's range(x) function. +-- Include it in List table for tidiness +-- @param start A number +-- @param finish A number greater than start; if zero, then 0..start-1 +-- @param incr an optional increment (may be less than 1) +-- @usage List.range(0,3) == List {0,1,2,3} +function List.range(start,finish,incr) + if not finish then + start = 0 + finish = finish - 1 + end + if incr then + if not utils.is_integer(incr) then finish = finish + eps end + else + incr = 1 + end + assert_arg(1,start,'number') + assert_arg(2,finish,'number') + local t = List.new() + for i=start,finish,incr do tinsert(t,i) end + return t +end + +--- list:len() is the same as #list. +function List:len() + return #self +end + +-- Extended operations -- + +--- Remove a subrange of elements. +-- equivalent to 'del s[i1:i2]' in Python. +-- @param i1 start of range +-- @param i2 end of range +-- @return the list +function List:chop(i1,i2) + return tremovevalues(self,i1,i2) +end + +--- Insert a sublist into a list +-- equivalent to 's[idx:idx] = list' in Python +-- @param idx index +-- @param list list to insert +-- @return the list +-- @usage l = List{10,20}; l:splice(2,{21,22}); assert(l == List{10,21,22,20}) +function List:splice(idx,list) + assert_arg(1,idx,'number') + idx = idx - 1 + local i = 1 + for v in iter(list) do + tinsert(self,i+idx,v) + i = i + 1 + end + return self +end + +--- general slice assignment s[i1:i2] = seq. +-- @param i1 start index +-- @param i2 end index +-- @param seq a list +-- @return the list +function List:slice_assign(i1,i2,seq) + assert_arg(1,i1,'number') + assert_arg(1,i2,'number') + i1,i2 = normalize_slice(self,i1,i2) + if i2 >= i1 then self:chop(i1,i2) end + self:splice(i1,seq) + return self +end + +--- concatenation operator. +-- @param L another List +-- @return a new list consisting of the list with the elements of the new list appended +function List:__concat(L) + assert_arg(1,L,'table') + local ls = self:clone() + ls:extend(L) + return ls +end + +--- equality operator ==. True iff all elements of two lists are equal. +-- @param L another List +-- @return true or false +function List:__eq(L) + if #self ~= #L then return false end + for i = 1,#self do + if self[i] ~= L[i] then return false end + end + return true +end + +--- join the elements of a list using a delimiter.
    +-- This method uses tostring on all elements. +-- @param delim a delimiter string, can be empty. +-- @return a string +function List:join (delim) + delim = delim or '' + assert_arg(1,delim,'string') + return concat(imap(tostring,self),delim) +end + +--- join a list of strings.
    +-- Uses table.concat directly. +-- @class function +-- @name List:concat +-- @param delim a delimiter +-- @return a string +List.concat = concat + +local function tostring_q(val) + local s = tostring(val) + if type(val) == 'string' then + s = '"'..s..'"' + end + return s +end + +--- how our list should be rendered as a string. Uses join(). +-- @see List:join +function List:__tostring() + return '{'..self:join(',',tostring_q)..'}' +end + +--[[ +-- NOTE: this works, but is unreliable. If you leave the loop before finishing, +-- then the iterator is not reset. +--- can iterate over a list directly. +-- @usage for v in ls do print(v) end +function List:__call() + if not self.key then self.key = 1 end + local value = self[self.key] + self.key = self.key + 1 + if not value then self.key = nil end + return value +end +--]] + +--[[ +function List.__call(t,v,i) + i = (i or 0) + 1 + v = t[i] + if v then return i, v end +end +--]] + +--- call the function for each element of the list. +-- @param fun a function or callable object +-- @param ... optional values to pass to function +function List:foreach (fun,...) + local t = self + fun = function_arg(1,fun) + for i = 1,#t do + fun(t[i],...) + end +end + +--- create a list of all elements which match a function. +-- @param fun a boolean function +-- @param arg optional argument to be passed as second argument of the predicate +-- @return a new filtered list. +function List:filter (fun,arg) + return makelist(filter(self,fun,arg),self) +end + +--- split a string using a delimiter. +-- @param s the string +-- @param delim the delimiter (default spaces) +-- @return a List of strings +-- @see pl.utils.split +function List.split (s,delim) + assert_arg(1,s,'string') + return makelist(split(s,delim)) +end + +--- apply a function to all elements. +-- Any extra arguments will be passed to the function +-- @param fun a function of at least one argument +-- @param ... arbitrary extra arguments. +-- @return a new list: {f(x) for x in self} +-- @see pl.tablex.imap +function List:map (fun,...) + return makelist(imap(fun,self,...),self) +end + +--- apply a function to all elements, in-place. +-- Any extra arguments are passed to the function. +-- @param fun A function that takes at least one argument +-- @param ... arbitrary extra arguments. +function List:transform (fun,...) + transform(fun,self,...) +end + +--- apply a function to elements of two lists. +-- Any extra arguments will be passed to the function +-- @param fun a function of at least two arguments +-- @param ls another list +-- @param ... arbitrary extra arguments. +-- @return a new list: {f(x,y) for x in self, for x in arg1} +-- @see pl.tablex.imap2 +function List:map2 (fun,ls,...) + return makelist(imap2(fun,self,ls,...),self) +end + +--- apply a named method to all elements. +-- Any extra arguments will be passed to the method. +-- @param name name of method +-- @param ... extra arguments +-- @return a new list of the results +-- @see pl.seq.mapmethod +function List:mapm (name,...) + local res = {} + local t = self + for i = 1,#t do + local val = t[i] + local fn = val[name] + if not fn then error(type(val).." does not have method "..name,2) end + res[i] = fn(val,...) + end + return makelist(res,self) +end + +--- 'reduce' a list using a binary function. +-- @param fun a function of two arguments +-- @return result of the function +-- @see pl.tablex.reduce +function List:reduce (fun) + return reduce(fun,self) +end + +--- partition a list using a classifier function. +-- The function may return nil, but this will be converted to the string key ''. +-- @param fun a function of at least one argument +-- @param ... will also be passed to the function +-- @return a table where the keys are the returned values, and the values are Lists +-- of values where the function returned that key. It is given the type of Multimap. +-- @see pl.MultiMap +function List:partition (fun,...) + fun = function_arg(1,fun) + local res = {} + for i = 1,#self do + local val = self[i] + local klass = fun(val,...) + if klass == nil then klass = '' end + if not res[klass] then res[klass] = List() end + res[klass]:append(val) + end + return setmetatable(res,Multimap) +end + +--- return an iterator over all values. +function List:iter () + return iter(self) +end + +--- Create an iterator over a seqence. +-- This captures the Python concept of 'sequence'. +-- For tables, iterates over all values with integer indices. +-- @param seq a sequence; a string (over characters), a table, a file object (over lines) or an iterator function +-- @usage for x in iterate {1,10,22,55} do io.write(x,',') end ==> 1,10,22,55 +-- @usage for ch in iterate 'help' do do io.write(ch,' ') end ==> h e l p +function List.iterate(seq) + if type(seq) == 'string' then + local idx = 0 + local n = #seq + local sub = string.sub + return function () + idx = idx + 1 + if idx > n then return nil + else + return sub(seq,idx,idx) + end + end + elseif type(seq) == 'table' then + local idx = 0 + local n = #seq + return function() + idx = idx + 1 + if idx > n then return nil + else + return seq[idx] + end + end + elseif type(seq) == 'function' then + return seq + elseif type(seq) == 'userdata' and io.type(seq) == 'file' then + return seq:lines() + end +end +iter = List.iterate + +return List + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Map.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Map.lua new file mode 100644 index 000000000..8b7284037 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Map.lua @@ -0,0 +1,108 @@ +--- A Map class. +-- @class module +-- @name pl.Map + +--[[ +module ('pl.Map') +]] +local tablex = require 'pl.tablex' +local utils = require 'pl.utils' +local stdmt = utils.stdmt +local is_callable = utils.is_callable +local tmakeset,deepcompare,merge,keys,difference,tupdate = tablex.makeset,tablex.deepcompare,tablex.merge,tablex.keys,tablex.difference,tablex.update + +local pretty_write = require 'pl.pretty' . write +local Map = stdmt.Map +local Set = stdmt.Set +local List = stdmt.List + +local class = require 'pl.class' + +-- the Map class --------------------- +class(nil,nil,Map) + +local function makemap (m) + return setmetatable(m,Map) +end + +function Map:_init (t) + local mt = getmetatable(t) + if mt == Set or mt == Map then + self:update(t) + else + return t -- otherwise assumed to be a map-like table + end +end + + +local function makelist(t) + return setmetatable(t,List) +end + +--- list of keys. +Map.keys = tablex.keys + +--- list of values. +Map.values = tablex.values + +--- return an iterator over all key-value pairs. +function Map:iter () + return pairs(self) +end + +--- return a List of all key-value pairs, sorted by the keys. +function Map:items() + local ls = makelist(tablex.pairmap (function (k,v) return makelist {k,v} end, self)) + ls:sort(function(t1,t2) return t1[1] < t2[1] end) + return ls +end + +-- Will return the existing value, or if it doesn't exist it will set +-- a default value and return it. +function Map:setdefault(key, defaultval) + return self[key] or self:set(key,defaultval) or defaultval +end + +--- size of map. +-- note: this is a relatively expensive operation! +-- @class function +-- @name Map:len +Map.len = tablex.size + +--- put a value into the map. +-- @param key the key +-- @param val the value +function Map:set (key,val) + self[key] = val +end + +--- get a value from the map. +-- @param key the key +-- @return the value, or nil if not found. +function Map:get (key) + return rawget(self,key) +end + +local index_by = tablex.index_by + +-- get a list of values indexed by a list of keys. +-- @param keys a list-like table of keys +-- @return a new list +function Map:getvalues (keys) + return makelist(index_by(self,keys)) +end + +Map.iter = pairs + +Map.update = tablex.update + +function Map:__eq (m) + -- note we explicitly ask deepcompare _not_ to use __eq! + return deepcompare(self,m,true) +end + +function Map:__tostring () + return pretty_write(self,'') +end + +return Map diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/MultiMap.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/MultiMap.lua new file mode 100644 index 000000000..f1c430db5 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/MultiMap.lua @@ -0,0 +1,65 @@ +--- MultiMap, a Map which has multiple values per key.
    +-- @class module +-- @name pl.MultiMap + +--[[ +module ('pl.MultiMap') +]] + +local classes = require 'pl.class' +local tablex = require 'pl.tablex' +local utils = require 'pl.utils' +local List = require 'pl.List' + +local index_by,tsort,concat = tablex.index_by,table.sort,table.concat +local append,extend,slice = List.append,List.extend,List.slice +local append = table.insert +local is_type = utils.is_type + +local class = require 'pl.class' +local Map = require 'pl.Map' + +-- MultiMap is a standard MT +local MultiMap = utils.stdmt.MultiMap + +class(Map,nil,MultiMap) +MultiMap._name = 'MultiMap' + +function MultiMap:_init (t) + if not t then return end + self:update(t) +end + +--- update a MultiMap using a table. +-- @param t either a Multimap or a map-like table. +-- @return the map +function MultiMap:update (t) + utils.assert_arg(1,t,'table') + if Map:class_of(t) then + for k,v in pairs(t) do + self[k] = List() + self[k]:append(v) + end + else + for k,v in pairs(t) do + self[k] = List(v) + end + end +end + +--- add a new value to a key. Setting a nil value removes the key. +-- @param key the key +-- @param val the value +-- @return the map +function MultiMap:set (key,val) + if val == nil then + self[key] = nil + else + if not self[key] then + self[key] = List() + end + self[key]:append(val) + end +end + +return MultiMap diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/OrderedMap.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/OrderedMap.lua new file mode 100644 index 000000000..7cc79635a --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/OrderedMap.lua @@ -0,0 +1,150 @@ +--- OrderedMap, a pl.Map which preserves ordering. +-- @class module +-- @name pl.OrderedMap + +--[[ +module ('pl.OrderedMap') +]] + +local tablex = require 'pl.tablex' +local utils = require 'pl.utils' +local List = require 'pl.List' +local index_by,tsort,concat = tablex.index_by,table.sort,table.concat + +local class = require 'pl.class' +local Map = require 'pl.Map' + +local OrderedMap = class(Map) +OrderedMap._name = 'OrderedMap' + +--- construct an OrderedMap. +-- Will throw an error if the argument is bad. +-- @param t optional initialization table, same as for @{OrderedMap:update} +function OrderedMap:_init (t) + self._keys = List() + if t then + local map,err = self:update(t) + if not map then error(err,2) end + end +end + +local assert_arg,raise = utils.assert_arg,utils.raise + +--- update an OrderedMap using a table.
    +-- If the table is itself an OrderedMap, then its entries will be appended.
    +-- if it s a table of the form {{key1=val1},{key2=val2},...} these will be appended.
    +-- Otherwise, it is assumed to be a map-like table, and order of extra entries is arbitrary. +-- @param t a table. +-- @return the map, or nil in case of error +-- @return the error message +function OrderedMap:update (t) + assert_arg(1,t,'table') + if OrderedMap:class_of(t) then + for k,v in t:iter() do + self:set(k,v) + end + elseif #t > 0 then -- an array must contain {key=val} tables + if type(t[1]) == 'table' then + for _,pair in ipairs(t) do + local key,value = next(pair) + if not key then return raise 'empty pair initialization table' end + self:set(key,value) + end + else + return raise 'cannot use an array to initialize an OrderedMap' + end + else + for k,v in pairs(t) do + self:set(k,v) + end + end + return self +end + +--- set the key's value. This key will be appended at the end of the map.
    +-- If the value is nil, then the key is removed. +-- @param key the key +-- @param val the value +-- @return the map +function OrderedMap:set (key,val) + if not self[key] and val ~= nil then -- ensure that keys are unique + self._keys:append(key) + elseif val == nil then -- removing a key-value pair + self._keys:remove_value(key) + end + self[key] = val + return self +end + +--- insert a key/value pair before a given position. +-- Note: if the map already contains the key, then this effectively +-- moves the item to the new position by first removing at the old position. +-- Has no effect if the key does not exist and val is nil +-- @param pos a position starting at 1 +-- @param key the key +-- @param val the value; if nil use the old value +function OrderedMap:insert (pos,key,val) + local oldval = self[key] + val = val or oldval + if oldval then + self._keys:remove_value(key) + end + if val then + self._keys:insert(pos,key) + self[key] = val + end + return self +end + +--- return the keys in order. +-- (Not a copy!) +-- @return List +function OrderedMap:keys () + return self._keys +end + +--- return the values in order. +-- this is relatively expensive. +-- @return List +function OrderedMap:values () + return List(index_by(self,self._keys)) +end + +--- sort the keys. +-- @param cmp a comparison function as for @{table.sort} +-- @return the map +function OrderedMap:sort (cmp) + tsort(self._keys,cmp) + return self +end + +--- iterate over key-value pairs in order. +function OrderedMap:iter () + local i = 0 + local keys = self._keys + local n,idx = #keys + return function() + i = i + 1 + if i > #keys then return nil end + idx = keys[i] + return idx,self[idx] + end +end + +function OrderedMap:__tostring () + local res = {} + for i,v in ipairs(self._keys) do + local val = self[v] + local vs = tostring(val) + if type(val) ~= 'number' then + vs = '"'..vs..'"' + end + res[i] = tostring(v)..'='..vs + end + return '{'..concat(res,',')..'}' +end + +return OrderedMap + + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Set.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Set.lua new file mode 100644 index 000000000..fd6de90ba --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/Set.lua @@ -0,0 +1,127 @@ +---- A Set class. +-- @class module +-- @name pl.Set + +--[[ +module ('pl.Set') +]] +local tablex = require 'pl.tablex' +local utils = require 'pl.utils' +local stdmt = utils.stdmt +local tmakeset,deepcompare,merge,keys,difference,tupdate = tablex.makeset,tablex.deepcompare,tablex.merge,tablex.keys,tablex.difference,tablex.update +local Map = stdmt.Map +local Set = stdmt.Set +local List = stdmt.List +local class = require 'pl.class' + +-- the Set class -------------------- +class(Map,nil,Set) + +local function makeset (t) + return setmetatable(t,Set) +end + +--- create a set.
    +-- @param t may be a Set, Map or list-like table. +-- @class function +-- @name Set +function Set:_init (t) + local mt = getmetatable(t) + if mt == Set or mt == Map then + for k in pairs(t) do self[k] = true end + else + for _,v in ipairs(t) do self[v] = true end + end +end + +function Set:__tostring () + return '['..self:keys():join ','..']' +end + +--- add a value to a set. +-- @param key a value +function Set:set (key) + self[key] = true +end + +--- remove a value from a set. +-- @param key a value +function Set:unset (key) + self[key] = nil +end + +--- get a list of the values in a set. +-- @class function +-- @name Set:values +Set.values = Map.keys + +--- map a function over the values of a set. +-- @param fn a function +-- @param ... extra arguments to pass to the function. +-- @return a new set +function Set:map (fn,...) + fn = utils.function_arg(1,fn) + local res = {} + for k in pairs(self) do + res[fn(k,...)] = true + end + return makeset(res) +end + +--- union of two sets (also +). +-- @param set another set +-- @return a new set +function Set:union (set) + return merge(self,set,true) +end +Set.__add = Set.union + +--- intersection of two sets (also *). +-- @param set another set +-- @return a new set +function Set:intersection (set) + return merge(self,set,false) +end +Set.__mul = Set.intersection + +--- new set with elements in the set that are not in the other (also -). +-- @param set another set +-- @return a new set +function Set:difference (set) + return difference(self,set,false) +end +Set.__sub = Set.difference + +-- a new set with elements in _either_ the set _or_ other but not both (also ^). +-- @param set another set +-- @return a new set +function Set:symmetric_difference (set) + return difference(self,set,true) +end +Set.__pow = Set.symmetric_difference + +--- is the first set a subset of the second?. +-- @return true or false +function Set:issubset (set) + for k in pairs(self) do + if not set[k] then return false end + end + return true +end +Set.__lt = Set.subset + +--- is the set empty?. +-- @return true or false +function Set:issempty () + return next(self) == nil +end + +--- are the sets disjoint? (no elements in common). +-- Uses naive definition, i.e. that intersection is empty +-- @param set another set +-- @return true or false +function Set:isdisjoint (set) + return self:intersection(set):isempty() +end + +return Set diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/app.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/app.lua new file mode 100644 index 000000000..845255094 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/app.lua @@ -0,0 +1,143 @@ +--- Application support functions. +--

    See the Guide +-- @class module +-- @name pl.app + +local io,package,require = _G.io, _G.package, _G.require +local utils = require 'pl.utils' +local path = require 'pl.path' +local lfs = require 'lfs' + + +local app = {} + +local function check_script_name () + if _G.arg == nil then error('no command line args available\nWas this run from a main script?') end + return _G.arg[0] +end + +--- add the current script's path to the Lua module path. +-- Applies to both the source and the binary module paths. It makes it easy for +-- the main file of a multi-file program to access its modules in the same directory. +-- `base` allows these modules to be put in a specified subdirectory, to allow for +-- cleaner deployment and resolve potential conflicts between a script name and its +-- library directory. +-- @param base optional base directory. +-- @return the current script's path with a trailing slash +function app.require_here (base) + local p = path.dirname(check_script_name()) + if not path.isabs(p) then + p = path.join(lfs.currentdir(),p) + end + if p:sub(-1,-1) ~= path.sep then + p = p..path.sep + end + if base then + p = p..base..path.sep + end + local so_ext = path.is_windows and 'dll' or 'so' + local lsep = package.path:find '^;' and '' or ';' + local csep = package.cpath:find '^;' and '' or ';' + package.path = ('%s?.lua;%s?%sinit.lua%s%s'):format(p,p,path.sep,lsep,package.path) + package.cpath = ('%s?.%s%s%s'):format(p,so_ext,csep,package.cpath) + return p +end + +--- return a suitable path for files private to this application. +-- These will look like '~/.SNAME/file', with '~' as with expanduser and +-- SNAME is the name of the script without .lua extension. +-- @param file a filename (w/out path) +-- @return a full pathname, or nil +-- @return 'cannot create' error +function app.appfile (file) + local sname = path.basename(check_script_name()) + local name,ext = path.splitext(sname) + local dir = path.join(path.expanduser('~'),'.'..name) + if not path.isdir(dir) then + local ret = lfs.mkdir(dir) + if not ret then return utils.raise ('cannot create '..dir) end + end + return path.join(dir,file) +end + +--- return string indicating operating system. +-- @return 'Windows','OSX' or whatever uname returns (e.g. 'Linux') +function app.platform() + if path.is_windows then + return 'Windows' + else + local f = io.popen('uname') + local res = f:read() + if res == 'Darwin' then res = 'OSX' end + f:close() + return res + end +end + +--- parse command-line arguments into flags and parameters. +-- Understands GNU-style command-line flags; short (-f) and long (--flag). +-- These may be given a value with either '=' or ':' (-k:2,--alpha=3.2,-n2); +-- note that a number value can be given without a space. +-- Multiple short args can be combined like so: (-abcd). +-- @param args an array of strings (default is the global 'arg') +-- @param flags_with_values any flags that take values, e.g. {out=true} +-- @return a table of flags (flag=value pairs) +-- @return an array of parameters +-- @raise if args is nil, then the global `args` must be available! +function app.parse_args (args,flags_with_values) + if not args then + args = _G.arg + if not args then error "Not in a main program: 'arg' not found" end + end + flags_with_values = flags_with_values or {} + local _args = {} + local flags = {} + local i = 1 + while i <= #args do + local a = args[i] + local v = a:match('^-(.+)') + local is_long + if v then -- we have a flag + if v:find '^-' then + is_long = true + v = v:sub(2) + end + if flags_with_values[v] then + if i == #_args or args[i+1]:find '^-' then + return utils.raise ("no value for '"..v.."'") + end + flags[v] = args[i+1] + i = i + 1 + else + -- a value can be indicated with = or : + local var,val = utils.splitv (v,'[=:]') + var = var or v + val = val or true + if not is_long then + if #var > 1 then + if var:find '.%d+' then -- short flag, number value + val = var:sub(2) + var = var:sub(1,1) + else -- multiple short flags + for i = 1,#var do + flags[var:sub(i,i)] = true + end + val = nil -- prevents use of var as a flag below + end + else -- single short flag (can have value, defaults to true) + val = val or true + end + end + if val then + flags[var] = val + end + end + else + _args[#_args+1] = a + end + i = i + 1 + end + return flags,_args +end + +return app diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/array2d.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/array2d.lua new file mode 100644 index 000000000..e178df975 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/array2d.lua @@ -0,0 +1,391 @@ +--- Operations on two-dimensional arrays. +-- @class module +-- @name pl.array2d + +local require, type,tonumber,assert,tostring,io,ipairs,string,table = + _G.require, _G.type,_G.tonumber,_G.assert,_G.tostring,_G.io,_G.ipairs,_G.string,_G.table +local ops = require 'pl.operator' +local tablex = require 'pl.tablex' +local utils = require 'pl.utils' + +local imap,tmap,reduce,keys,tmap2,tset,index_by = tablex.imap,tablex.map,tablex.reduce,tablex.keys,tablex.map2,tablex.set,tablex.index_by +local remove = table.remove +local perm = require 'pl.permute' +local splitv,fprintf,assert_arg = utils.splitv,utils.fprintf,utils.assert_arg +local byte = string.byte +local stdout = io.stdout + +--[[ +module ('pl.array2d',utils._module) +]] + +local array2d = {} + +--- extract a column from the 2D array. +-- @param a 2d array +-- @param key an index or key +-- @return 1d array +function array2d.column (a,key) + assert_arg(1,a,'table') + return imap(ops.index,a,key) +end +local column = array2d.column + +--- map a function over a 2D array +-- @param f a function of at least one argument +-- @param a 2d array +-- @param arg an optional extra argument to be passed to the function. +-- @return 2d array +function array2d.map (f,a,arg) + assert_arg(1,a,'table') + f = utils.function_arg(1,f) + return imap(function(row) return imap(f,row,arg) end, a) +end + +--- reduce the rows using a function. +-- @param f a binary function +-- @param a 2d array +-- @return 1d array +-- @see pl.tablex.reduce +function array2d.reduce_rows (f,a) + assert_arg(1,a,'table') + return tmap(function(row) return reduce(f,row) end, a) +end + + + +--- reduce the columns using a function. +-- @param f a binary function +-- @param a 2d array +-- @return 1d array +-- @see pl.tablex.reduce +function array2d.reduce_cols (f,a) + assert_arg(1,a,'table') + return tmap(function(c) return reduce(f,column(a,c)) end, keys(a[1])) +end + +--- reduce a 2D array into a scalar, using two operations. +-- @param opc operation to reduce the final result +-- @param opr operation to reduce the rows +-- @param a 2D array +function array2d.reduce2 (opc,opr,a) + assert_arg(3,a,'table') + local tmp = array2d.reduce_rows(opr,a) + return reduce(opc,tmp) +end + +local function dimension (t) + return type(t[1])=='table' and 2 or 1 +end + +--- map a function over two arrays. +-- They can be both or either 2D arrays +-- @param f function of at least two arguments +-- @param ad order of first array +-- @param bd order of second array +-- @param a 1d or 2d array +-- @param b 1d or 2d array +-- @param arg optional extra argument to pass to function +-- @return 2D array, unless both arrays are 1D +function array2d.map2 (f,ad,bd,a,b,arg) + assert_arg(1,a,'table') + assert_arg(2,b,'table') + f = utils.function_arg(1,f) + --local ad,bd = dimension(a),dimension(b) + if ad == 1 and bd == 2 then + return imap(function(row) + return tmap2(f,a,row,arg) + end, b) + elseif ad == 2 and bd == 1 then + return imap(function(row) + return tmap2(f,row,b,arg) + end, a) + elseif ad == 1 and bd == 1 then + return tmap2(f,a,b) + elseif ad == 2 and bd == 2 then + return tmap2(function(rowa,rowb) + return tmap2(f,rowa,rowb,arg) + end, a,b) + end +end + +--- cartesian product of two 1d arrays. +-- @param f a function of 2 arguments +-- @param t1 a 1d table +-- @param t2 a 1d table +-- @return 2d table +-- @usage product('..',{1,2},{'a','b'}) == {{'1a','2a'},{'1b','2b'}} +function array2d.product (f,t1,t2) + f = utils.function_arg(1,f) + assert_arg(2,t1,'table') + assert_arg(3,t2,'table') + local res, map = {}, tablex.map + for i,v in ipairs(t2) do + res[i] = map(f,t1,v) + end + return res +end + +--- flatten a 2D array. +-- (this goes over columns first.) +-- @param t 2d table +-- @return a 1d table +-- @usage flatten {{1,2},{3,4},{5,6}} == {1,2,3,4,5,6} +function array2d.flatten (t) + local res = {} + local k = 1 + for _,a in ipairs(t) do -- for all rows + for i = 1,#a do + res[k] = a[i] + k = k + 1 + end + end + return res +end + +--- swap two rows of an array. +-- @param t a 2d array +-- @param i1 a row index +-- @param i2 a row index +function array2d.swap_rows (t,i1,i2) + assert_arg(1,t,'table') + t[i1],t[i2] = t[i2],t[i1] +end + +--- swap two columns of an array. +-- @param t a 2d array +-- @param j1 a column index +-- @param j2 a column index +function array2d.swap_cols (t,j1,j2) + assert_arg(1,t,'table') + for i = 1,#t do + local row = t[i] + row[j1],row[j2] = row[j2],row[j1] + end +end + +--- extract the specified rows. +-- @param t 2d array +-- @param ridx a table of row indices +function array2d.extract_rows (t,ridx) + return index_by(t,ridx) +end + +--- extract the specified columns. +-- @param t 2d array +-- @param cidx a table of column indices +function array2d.extract_cols (t,cidx) + assert_arg(1,t,'table') + for i = 1,#t do + t[i] = index_by(t[i],cidx) + end +end + +--- remove a row from an array. +-- @class function +-- @name array2d.remove_row +-- @param t a 2d array +-- @param i a row index +array2d.remove_row = remove + +--- remove a column from an array. +-- @param t a 2d array +-- @param j a column index +function array2d.remove_col (t,j) + assert_arg(1,t,'table') + for i = 1,#t do + remove(t[i],j) + end +end + +local Ai = byte 'A' + +local function _parse (s) + local c,r + if s:sub(1,1) == 'R' then + r,c = s:match 'R(%d+)C(%d+)' + r,c = tonumber(r),tonumber(c) + else + c,r = s:match '(.)(.)' + c = byte(c) - byte 'A' + 1 + r = tonumber(r) + end + assert(c ~= nil and r ~= nil,'bad cell specifier: '..s) + return r,c +end + +--- parse a spreadsheet range. +-- The range can be specified either as 'A1:B2' or 'R1C1:R2C2'; +-- a special case is a single element (e.g 'A1' or 'R1C1') +-- @param s a range. +-- @return start col +-- @return start row +-- @return end col +-- @return end row +function array2d.parse_range (s) + if s:find ':' then + local start,finish = splitv(s,':') + local i1,j1 = _parse(start) + local i2,j2 = _parse(finish) + return i1,j1,i2,j2 + else -- single value + local i,j = _parse(s) + return i,j + end +end + +--- get a slice of a 2D array using spreadsheet range notation. @see parse_range +-- @param t a 2D array +-- @param rstr range expression +-- @return a slice +-- @see array2d.parse_range +-- @see array2d.slice +function array2d.range (t,rstr) + assert_arg(1,t,'table') + local i1,j1,i2,j2 = array2d.parse_range(rstr) + if i2 then + return array2d.slice(t,i1,j1,i2,j2) + else -- single value + return t[i1][j1] + end +end + +local function default_range (t,i1,j1,i2,j2) + assert(t and type(t)=='table','not a table') + i1,j1 = i1 or 1, j1 or 1 + i2,j2 = i2 or #t, j2 or #t[1] + return i1,j1,i2,j2 +end + +--- get a slice of a 2D array. Note that if the specified range has +-- a 1D result, the rank of the result will be 1. +-- @param t a 2D array +-- @param i1 start row (default 1) +-- @param j1 start col (default 1) +-- @param i2 end row (default N) +-- @param j2 end col (default M) +-- @return an array, 2D in general but 1D in special cases. +function array2d.slice (t,i1,j1,i2,j2) + assert_arg(1,t,'table') + i1,j1,i2,j2 = default_range(t,i1,j1,i2,j2) + local res = {} + for i = i1,i2 do + local val + local row = t[i] + if j1 == j2 then + val = row[j1] + else + val = {} + for j = j1,j2 do + val[#val+1] = row[j] + end + end + res[#res+1] = val + end + if i1 == i2 then res = res[1] end + return res +end + +--- set a specified range of an array to a value. +-- @param t a 2D array +-- @param value the value +-- @param i1 start row (default 1) +-- @param j1 start col (default 1) +-- @param i2 end row (default N) +-- @param j2 end col (default M) +function array2d.set (t,value,i1,j1,i2,j2) + i1,j1,i2,j2 = default_range(t,i1,j1,i2,j2) + for i = i1,i2 do + tset(t[i],value) + end +end + +--- write a 2D array to a file. +-- @param t a 2D array +-- @param f a file object (default stdout) +-- @param fmt a format string (default is just to use tostring) +-- @param i1 start row (default 1) +-- @param j1 start col (default 1) +-- @param i2 end row (default N) +-- @param j2 end col (default M) +function array2d.write (t,f,fmt,i1,j1,i2,j2) + assert_arg(1,t,'table') + f = f or stdout + local rowop + if fmt then + rowop = function(row,j) fprintf(f,fmt,row[j]) end + else + rowop = function(row,j) f:write(tostring(row[j]),' ') end + end + local function newline() + f:write '\n' + end + array2d.forall(t,rowop,newline,i1,j1,i2,j2) +end + +--- perform an operation for all values in a 2D array. +-- @param t 2D array +-- @param row_op function to call on each value +-- @param end_row_op function to call at end of each row +-- @param i1 start row (default 1) +-- @param j1 start col (default 1) +-- @param i2 end row (default N) +-- @param j2 end col (default M) +function array2d.forall (t,row_op,end_row_op,i1,j1,i2,j2) + assert_arg(1,t,'table') + i1,j1,i2,j2 = default_range(t,i1,j1,i2,j2) + for i = i1,i2 do + local row = t[i] + for j = j1,j2 do + row_op(row,j) + end + if end_row_op then end_row_op(i) end + end +end + +--- iterate over all elements in a 2D array, with optional indices. +-- @param a 2D array +-- @param indices with indices (default false) +-- @param i1 start row (default 1) +-- @param j1 start col (default 1) +-- @param i2 end row (default N) +-- @param j2 end col (default M) +-- @return either value or i,j,value depending on indices +function array2d.iter (a,indices,i1,j1,i2,j2) + assert_arg(1,a,'table') + local norowset = not (i2 and j2) + i1,j1,i2,j2 = default_range(a,i1,j1,i2,j2) + local n,i,j = i2-i1+1,i1-1,j1-1 + local row,nr = nil,0 + local onr = j2 - j1 + 1 + return function() + j = j + 1 + if j > nr then + j = j1 + i = i + 1 + if i > i2 then return nil end + row = a[i] + nr = norowset and #row or onr + end + if indices then + return i,j,row[j] + else + return row[j] + end + end +end + +function array2d.columns (a) + assert_arg(1,a,'table') + local n = a[1][1] + local i = 0 + return function() + i = i + 1 + if i > n then return nil end + return column(a,i) + end +end + +return array2d + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/class.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/class.lua new file mode 100644 index 000000000..5cfbf991d --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/class.lua @@ -0,0 +1,155 @@ +--- Provides a reuseable and convenient framework for creating classes in Lua. +-- Two possible notations:
    B = class(A) or class.B(A) .
    +--

    The latter form creates a named class.

    +-- See the Guide for further discussion +-- @module pl.class + +local error, getmetatable, io, pairs, rawget, rawset, setmetatable, tostring, type = + _G.error, _G.getmetatable, _G.io, _G.pairs, _G.rawget, _G.rawset, _G.setmetatable, _G.tostring, _G.type +-- this trickery is necessary to prevent the inheritance of 'super' and +-- the resulting recursive call problems. +local function call_ctor (c,obj,...) + -- nice alias for the base class ctor + local base = rawget(c,'_base') + if base then obj.super = rawget(base,'_init') end + local res = c._init(obj,...) + obj.super = nil + return res +end + +local function is_a(self,klass) + local m = getmetatable(self) + if not m then return false end --*can't be an object! + while m do + if m == klass then return true end + m = rawget(m,'_base') + end + return false +end + +local function class_of(klass,obj) + if type(klass) ~= 'table' or not rawget(klass,'is_a') then return false end + return klass.is_a(obj,klass) +end + +local function _class_tostring (obj) + local mt = obj._class + local name = rawget(mt,'_name') + setmetatable(obj,nil) + local str = tostring(obj) + setmetatable(obj,mt) + if name then str = name ..str:gsub('table','') end + return str +end + +local function tupdate(td,ts) + for k,v in pairs(ts) do + td[k] = v + end +end + +local function _class(base,c_arg,c) + c = c or {} -- a new class instance, which is the metatable for all objects of this type + -- the class will be the metatable for all its objects, + -- and they will look up their methods in it. + local mt = {} -- a metatable for the class instance + + if type(base) == 'table' then + -- our new class is a shallow copy of the base class! + tupdate(c,base) + c._base = base + -- inherit the 'not found' handler, if present + if rawget(c,'_handler') then mt.__index = c._handler end + elseif base ~= nil then + error("must derive from a table type",3) + end + + c.__index = c + setmetatable(c,mt) + c._init = nil + + if base and rawget(base,'_class_init') then + base._class_init(c,c_arg) + end + + -- expose a ctor which can be called by () + mt.__call = function(class_tbl,...) + local obj = {} + setmetatable(obj,c) + + if rawget(c,'_init') then -- explicit constructor + local res = call_ctor(c,obj,...) + if res then -- _if_ a ctor returns a value, it becomes the object... + obj = res + setmetatable(obj,c) + end + elseif base and rawget(base,'_init') then -- default constructor + -- make sure that any stuff from the base class is initialized! + call_ctor(base,obj,...) + end + + if base and rawget(base,'_post_init') then + base._post_init(obj) + end + + if not rawget(c,'__tostring') then + c.__tostring = _class_tostring + end + return obj + end + -- Call Class.catch to set a handler for methods/properties not found in the class! + c.catch = function(handler) + c._handler = handler + mt.__index = handler + end + c.is_a = is_a + c.class_of = class_of + c._class = c + -- any object can have a specified delegate which is called with unrecognized methods + -- if _handler exists and obj[key] is nil, then pass onto handler! + c.delegate = function(self,obj) + mt.__index = function(tbl,key) + local method = obj[key] + if method then + return function(self,...) + return method(obj,...) + end + elseif self._handler then + return self._handler(tbl,key) + end + end + end + return c +end + +--- create a new class, derived from a given base class.
    +-- Supporting two class creation syntaxes: +-- either Name = class(base) or class.Name(base) +-- @class function +-- @name class +-- @param base optional base class +-- @param c_arg optional parameter to class ctor +-- @param c optional table to be used as class +local class +class = setmetatable({},{ + __call = function(fun,...) + return _class(...) + end, + __index = function(tbl,key) + if key == 'class' then + io.stderr:write('require("pl.class").class is deprecated. Use require("pl.class")\n') + return class + end + local env = _G + return function(...) + local c = _class(...) + c._name = key + rawset(env,key,c) + return c + end + end +}) + + +return class + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/comprehension.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/comprehension.lua new file mode 100644 index 000000000..9765bbf87 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/comprehension.lua @@ -0,0 +1,288 @@ +--- List comprehensions implemented in Lua.

    +-- +-- See the wiki page +--

    +--   local C= require 'pl.comprehension' . new()
    +--
    +--    C ('x for x=1,10') ()
    +--    ==> {1,2,3,4,5,6,7,8,9,10}
    +--    C 'x^2 for x=1,4' ()
    +--    ==> {1,4,9,16}
    +--    C '{x,x^2} for x=1,4' ()
    +--    ==> {{1,1},{2,4},{3,9},{4,16}}
    +--    C '2*x for x' {1,2,3}
    +--    ==> {2,4,6}
    +--    dbl = C '2*x for x'
    +--    dbl {10,20,30}
    +--    ==> {20,40,60}
    +--    C 'x for x if x % 2 == 0' {1,2,3,4,5}
    +--    ==> {2,4}
    +--    C '{x,y} for x = 1,2 for y = 1,2' ()
    +--    ==> {{1,1},{1,2},{2,1},{2,2}}
    +--    C '{x,y} for x for y' ({1,2},{10,20})
    +--    ==> {{1,10},{1,20},{2,10},{2,20}}
    +--   assert(C 'sum(x^2 for x)' {2,3,4} == 2^2+3^2+4^2)
    +-- 
    +-- +--

    (c) 2008 David Manura. Licensed under the same terms as Lua (MIT license). +--

    -- See the Guide +-- @class module +-- @name pl.comprehension + +local utils = require 'pl.utils' + +--~ local _VERSION, assert, getfenv, ipairs, load, math, pcall, require, setmetatable, table, tonumber = +--~ _G._VERSION, _G.assert, _G.getfenv, _G.ipairs, _G.load, _G.math, _G.pcall, _G.require, _G.setmetatable, _G.table, _G.tonumber + +local status,lb = pcall(require, "pl.luabalanced") +if not status then + lb = require 'luabalanced' +end + +local math_max = math.max +local table_concat = table.concat + +-- fold operations +-- http://en.wikipedia.org/wiki/Fold_(higher-order_function) +local ops = { + list = {init=' {} ', accum=' __result[#__result+1] = (%s) '}, + table = {init=' {} ', accum=' local __k, __v = %s __result[__k] = __v '}, + sum = {init=' 0 ', accum=' __result = __result + (%s) '}, + min = {init=' nil ', accum=' local __tmp = %s ' .. + ' if __result then if __tmp < __result then ' .. + '__result = __tmp end else __result = __tmp end '}, + max = {init=' nil ', accum=' local __tmp = %s ' .. + ' if __result then if __tmp > __result then ' .. + '__result = __tmp end else __result = __tmp end '}, +} + + +-- Parses comprehension string expr. +-- Returns output expression list string, array of for types +-- ('=', 'in' or nil) , array of input variable name +-- strings , array of input variable value strings +-- , array of predicate expression strings , +-- operation name string , and number of placeholder +-- parameters . +-- +-- The is equivalent to the mathematical set-builder notation: +-- +-- { | in , } +-- +-- @usage "x^2 for x" -- array values +-- @usage "x^2 for x=1,10,2" -- numeric for +-- @usage "k^v for k,v in pairs(_1)" -- iterator for +-- @usage "(x+y)^2 for x for y if x > y" -- nested +-- +local function parse_comprehension(expr) + local t = {} + local pos = 1 + + -- extract opname (if exists) + local opname + local tok, post = expr:match('^%s*([%a_][%w_]*)%s*%(()', pos) + local pose = #expr + 1 + if tok then + local tok2, posb = lb.match_bracketed(expr, post-1) + assert(tok2, 'syntax error') + if expr:match('^%s*$', posb) then + opname = tok + pose = posb - 1 + pos = post + end + end + opname = opname or "list" + + -- extract out expression list + local out; out, pos = lb.match_explist(expr, pos) + assert(out, "syntax error: missing expression list") + out = table_concat(out, ', ') + + -- extract "for" clauses + local fortypes = {} + local invarlists = {} + local invallists = {} + while 1 do + local post = expr:match('^%s*for%s+()', pos) + if not post then break end + pos = post + + -- extract input vars + local iv; iv, pos = lb.match_namelist(expr, pos) + assert(#iv > 0, 'syntax error: zero variables') + for _,ident in ipairs(iv) do + assert(not ident:match'^__', + "identifier " .. ident .. " may not contain __ prefix") + end + invarlists[#invarlists+1] = iv + + -- extract '=' or 'in' (optional) + local fortype, post = expr:match('^(=)%s*()', pos) + if not fortype then fortype, post = expr:match('^(in)%s+()', pos) end + if fortype then + pos = post + -- extract input value range + local il; il, pos = lb.match_explist(expr, pos) + assert(#il > 0, 'syntax error: zero expressions') + assert(fortype ~= '=' or #il == 2 or #il == 3, + 'syntax error: numeric for requires 2 or three expressions') + fortypes[#invarlists] = fortype + invallists[#invarlists] = il + else + fortypes[#invarlists] = false + invallists[#invarlists] = false + end + end + assert(#invarlists > 0, 'syntax error: missing "for" clause') + + -- extract "if" clauses + local preds = {} + while 1 do + local post = expr:match('^%s*if%s+()', pos) + if not post then break end + pos = post + local pred; pred, pos = lb.match_expression(expr, pos) + assert(pred, 'syntax error: predicated expression not found') + preds[#preds+1] = pred + end + + -- extract number of parameter variables (name matching "_%d+") + local stmp = ''; lb.gsub(expr, function(u, sin) -- strip comments/strings + if u == 'e' then stmp = stmp .. ' ' .. sin .. ' ' end + end) + local max_param = 0; stmp:gsub('[%a_][%w_]*', function(s) + local s = s:match('^_(%d+)$') + if s then max_param = math_max(max_param, tonumber(s)) end + end) + + if pos ~= pose then + assert(false, "syntax error: unrecognized " .. expr:sub(pos)) + end + + --DEBUG: + --print('----\n', string.format("%q", expr), string.format("%q", out), opname) + --for k,v in ipairs(invarlists) do print(k,v, invallists[k]) end + --for k,v in ipairs(preds) do print(k,v) end + + return out, fortypes, invarlists, invallists, preds, opname, max_param +end + + +-- Create Lua code string representing comprehension. +-- Arguments are in the form returned by parse_comprehension. +local function code_comprehension( + out, fortypes, invarlists, invallists, preds, opname, max_param +) + local op = assert(ops[opname]) + local code = op.accum:gsub('%%s', out) + + for i=#preds,1,-1 do local pred = preds[i] + code = ' if ' .. pred .. ' then ' .. code .. ' end ' + end + for i=#invarlists,1,-1 do + if not fortypes[i] then + local arrayname = '__in' .. i + local idx = '__idx' .. i + code = + ' for ' .. idx .. ' = 1, #' .. arrayname .. ' do ' .. + ' local ' .. invarlists[i][1] .. ' = ' .. arrayname .. '['..idx..'] ' .. + code .. ' end ' + else + code = + ' for ' .. + table_concat(invarlists[i], ', ') .. + ' ' .. fortypes[i] .. ' ' .. + table_concat(invallists[i], ', ') .. + ' do ' .. code .. ' end ' + end + end + code = ' local __result = ( ' .. op.init .. ' ) ' .. code + return code +end + + +-- Convert code string represented by code_comprehension +-- into Lua function. Also must pass ninputs = #invarlists, +-- max_param, and invallists (from parse_comprehension). +-- Uses environment env. +local function wrap_comprehension(code, ninputs, max_param, invallists, env) + assert(ninputs > 0) + local ts = {} + for i=1,max_param do + ts[#ts+1] = '_' .. i + end + for i=1,ninputs do + if not invallists[i] then + local name = '__in' .. i + ts[#ts+1] = name + end + end + if #ts > 0 then + code = ' local ' .. table_concat(ts, ', ') .. ' = ... ' .. code + end + code = code .. ' return __result ' + --print('DEBUG:', code) + local f, err = utils.load(code,'tmp','t',env) + if not f then assert(false, err .. ' with generated code ' .. code) end + return f +end + + +-- Build Lua function from comprehension string. +-- Uses environment env. +local function build_comprehension(expr, env) + local out, fortypes, invarlists, invallists, preds, opname, max_param + = parse_comprehension(expr) + local code = code_comprehension( + out, fortypes, invarlists, invallists, preds, opname, max_param) + local f = wrap_comprehension(code, #invarlists, max_param, invallists, env) + return f +end + + +-- Creates new comprehension cache. +-- Any list comprehension function created are set to the environment +-- env (defaults to caller of new). +local function new(env) + -- Note: using a single global comprehension cache would have had + -- security implications (e.g. retrieving cached functions created + -- in other environments). + -- The cache lookup function could have instead been written to retrieve + -- the caller's environment, lookup up the cache private to that + -- environment, and then looked up the function in that cache. + -- That would avoid the need for this call to + -- explicitly manage caches; however, that might also have an undue + -- performance penalty. + + if not env then + env = getfenv(2) + end + + local mt = {} + local cache = setmetatable({}, mt) + + -- Index operator builds, caches, and returns Lua function + -- corresponding to comprehension expression string. + -- + -- Example: f = comprehension['x^2 for x'] + -- + function mt:__index(expr) + local f = build_comprehension(expr, env) + self[expr] = f -- cache + return f + end + + -- Convenience syntax. + -- Allows comprehension 'x^2 for x' instead of comprehension['x^2 for x']. + mt.__call = mt.__index + + cache.new = new + + return cache +end + + +local comprehension = {} +comprehension.new = new + +return comprehension diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/config.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/config.lua new file mode 100644 index 000000000..bd6b89781 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/config.lua @@ -0,0 +1,169 @@ +--- Reads configuration files into a Lua table.

    +-- Understands INI files, classic Unix config files, and simple +-- delimited columns of values.

    +--

    +--    # test.config
    +--    # Read timeout in seconds
    +--    read.timeout=10
    +--    # Write timeout in seconds
    +--    write.timeout=5
    +--    #acceptable ports
    +--    ports = 1002,1003,1004
    +--
    +--        -- readconfig.lua
    +--    require 'pl'
    +--    local t = config.read 'test.config'
    +--    print(pretty.write(t))
    +--
    +--    ### output #####
    +--   {
    +--      ports = {
    +--        1002,
    +--        1003,
    +--        1004
    +--      },
    +--      write_timeout = 5,
    +--      read_timeout = 10
    +--    }
    +-- 
    +-- See the Guide for further discussion +-- @class module +-- @name pl.config + +local type,tonumber,ipairs,io, table = _G.type,_G.tonumber,_G.ipairs,_G.io,_G.table + +local function split(s,re) + local res = {} + local t_insert = table.insert + re = '[^'..re..']+' + for k in s:gmatch(re) do t_insert(res,k) end + return res +end + +local function strip(s) + return s:gsub('^%s+',''):gsub('%s+$','') +end + +local function strip_quotes (s) + return s:gsub("['\"](.*)['\"]",'%1') +end + +local config = {} + +--- like io.lines(), but allows for lines to be continued with '\'. +-- @param file a file-like object (anything where read() returns the next line) or a filename. +-- Defaults to stardard input. +-- @return an iterator over the lines, or nil +-- @return error 'not a file-like object' or 'file is nil' +function config.lines(file) + local f,openf,err + local line = '' + if type(file) == 'string' then + f,err = io.open(file,'r') + if not f then return nil,err end + openf = true + else + f = file or io.stdin + if not file.read then return nil, 'not a file-like object' end + end + if not f then return nil, 'file is nil' end + return function() + local l = f:read() + while l do + -- does the line end with '\'? + local i = l:find '\\%s*$' + if i then -- if so, + line = line..l:sub(1,i-1) + elseif line == '' then + return l + else + l = line..l + line = '' + return l + end + l = f:read() + end + if openf then f:close() end + end +end + +--- read a configuration file into a table +-- @param file either a file-like object or a string, which must be a filename +-- @param cnfg a configuration table that may contain these fields: +--
      +--
    • variablilize make names into valid Lua identifiers (default true)
    • +--
    • convert_numbers try to convert values into numbers (default true)
    • +--
    • trim_space ensure that there is no starting or trailing whitespace with values (default true)
    • +--
    • trim_quotes remove quotes from strings (default false)
    • +--
    • list_delim delimiter to use when separating columns (default ',')
    • +--
    +-- @return a table containing items, or nil +-- @return error message (same as @{config.lines} +function config.read(file,cnfg) + local f,openf,err + cnfg = cnfg or {} + local function check_cnfg (var,def) + local val = cnfg[var] + if val == nil then return def else return val end + end + local t = {} + local top_t = t + local variablilize = check_cnfg ('variabilize',true) + local list_delim = check_cnfg('list_delim',',') + local convert_numbers = check_cnfg('convert_numbers',true) + local trim_space = check_cnfg('trim_space',true) + local trim_quotes = check_cnfg('trim_quotes',false) + local ignore_assign = check_cnfg('ignore_assign',false) + + local function process_name(key) + if variablilize then + key = key:gsub('[^%w]','_') + end + return key + end + + local function process_value(value) + if list_delim and value:find(list_delim) then + value = split(value,list_delim) + for i,v in ipairs(value) do + value[i] = process_value(v) + end + elseif convert_numbers and value:find('^[%d%+%-]') then + local val = tonumber(value) + if val then value = val end + end + if type(value) == 'string' then + if trim_space then value = strip(value) end + if trim_quotes then value = strip_quotes(value) end + end + return value + end + + local iter,err = config.lines(file) + if not iter then return nil,err end + for line in iter do + -- strips comments + local ci = line:find('%s*[#;]') + if ci then line = line:sub(1,ci-1) end + -- and ignore blank lines + if line:find('^%s*$') then + elseif line:find('^%[') then -- section! + local section = process_name(line:match('%[([^%]]+)%]')) + t = top_t + t[section] = {} + t = t[section] + else + local i1,i2 = line:find('%s*=%s*') + if i1 and not ignore_assign then -- key,value assignment + local key = process_name(line:sub(1,i1-1)) + local value = process_value(line:sub(i2+1)) + t[key] = value + else -- a plain list of values... + t[#t+1] = process_value(line) + end + end + end + return top_t +end + +return config diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/data.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/data.lua new file mode 100644 index 000000000..931c92692 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/data.lua @@ -0,0 +1,588 @@ +--- Reading and querying simple tabular data. +--
    +-- data.read 'test.txt'
    +-- ==> {{10,20},{2,5},{40,50},fieldnames={'x','y'},delim=','}
    +-- 
    +-- Provides a way of creating basic SQL-like queries. +--
    +--    require 'pl'
    +--    local d = data.read('xyz.txt')
    +--    local q = d:select('x,y,z where x > 3 and z < 2 sort by y')
    +--    for x,y,z in q do
    +--        print(x,y,z)
    +--    end
    +-- 
    +--

    See the Guide +-- @class module +-- @name pl.data + +local utils = require 'pl.utils' +local _DEBUG = rawget(_G,'_DEBUG') + +local patterns,function_arg,usplit = utils.patterns,utils.function_arg,utils.split +local append,concat = table.insert,table.concat +local gsub = string.gsub +local io = io +local _G,print,loadstring,type,tonumber,ipairs,setmetatable,pcall,error,setfenv = _G,print,loadstring,type,tonumber,ipairs,setmetatable,pcall,error,setfenv + +--[[ +module ('pl.data',utils._module) +]] + +local data = {} + +local parse_select + +local function count(s,chr) + chr = utils.escape(chr) + local _,cnt = s:gsub(chr,' ') + return cnt +end + +local function rstrip(s) + return s:gsub('%s+$','') +end + +local function make_list(l) + return setmetatable(l,utils.stdmt.List) +end + +local function split(s,delim) + return make_list(usplit(s,delim)) +end + +local function map(fun,t) + local res = {} + for i = 1,#t do + append(res,fun(t[i])) + end + return res +end + +local function find(t,v) + for i = 1,#t do + if v == t[i] then return i end + end +end + +local DataMT = { + column_by_name = function(self,name) + if type(name) == 'number' then + name = '$'..name + end + local arr = {} + for res in data.query(self,name) do + append(arr,res) + end + return make_list(arr) + end, + + copy_select = function(self,condn) + condn = parse_select(condn,self) + local iter = data.query(self,condn) + local res = {} + local row = make_list{iter()} + while #row > 0 do + append(res,row) + row = make_list{iter()} + end + res.delim = self.delim + return data.new(res,split(condn.fields,',')) + end, + + column_names = function(self) + return self.fieldnames + end, +} +DataMT.__index = DataMT + +--- return a particular column as a list of values (Method).
    +-- @param name either name of column, or numerical index. +-- @class function +-- @name Data.column_by_name + +--- return a query iterator on this data object (Method).
    +-- @param condn the query expression +-- @class function +-- @name Data.select +-- @see data.query + +--- return a new data object based on this query (Method).
    +-- @param condn the query expression +-- @class function +-- @name Data.copy_select + +--- return the field names of this data object (Method).
    +-- @class function +-- @name Data.column_names + +--- write out a row (Method).
    +-- @param f file-like object +-- @class function +-- @name Data.write_row + +--- write data out to file(Method).
    +-- @param f file-like object +-- @class function +-- @name Data.write + + +-- [guessing delimiter] We check for comma, tab and spaces in that order. +-- [issue] any other delimiters to be checked? +local delims = {',','\t',' ',';'} + +local function guess_delim (line) + for _,delim in ipairs(delims) do + if count(line,delim) > 0 then + return delim == ' ' and '%s+' or delim + end + end + return ' ' +end + +-- [file parameter] If it's a string, we try open as a filename. If nil, then +-- either stdin or stdout depending on the mode. Otherwise, check if this is +-- a file-like object (implements read or write depending) +local function open_file (f,mode) + local opened, err + local reading = mode == 'r' + if type(f) == 'string' then + if f == 'stdin' then + f = io.stdin + elseif f == 'stdout' then + f = io.stdout + else + f,err = io.open(f,mode) + if not f then return nil,err end + opened = true + end + end + if f and ((reading and not f.read) or (not reading and not f.write)) then + return nil, "not a file-like object" + end + return f,nil,opened +end + +local function all_n () + +end + +--- read a delimited file in a Lua table. +-- By default, attempts to treat first line as separated list of fieldnames. +-- @param file a filename or a file-like object (default stdin) +-- @param cnfg options table: can override delim (a string pattern), fieldnames (a list), +-- specify no_convert (default is to convert), numfields (indices of columns known +-- to be numbers) and thousands_dot (thousands separator in Excel CSV is '.') +function data.read(file,cnfg) + local convert,err,opened + local D = {} + if not cnfg then cnfg = {} end + local f,err,opened = open_file(file,'r') + if not f then return nil, err end + local thousands_dot = cnfg.thousands_dot + + local function try_tonumber(x) + if thousands_dot then x = x:gsub('%.(...)','%1') end + return tonumber(x) + end + + local line = f:read() + if not line then return nil, "empty file" end + -- first question: what is the delimiter? + D.delim = cnfg.delim and cnfg.delim or guess_delim(line) + local delim = D.delim + local collect_end = cnfg.last_field_collect + local numfields = cnfg.numfields + -- some space-delimited data starts with a space. This should not be a column, + -- although it certainly would be for comma-separated, etc. + local strip + if delim == '%s+' and line:find(delim) == 1 then + strip = function(s) return s:gsub('^%s+','') end + line = strip(line) + end + -- first line will usually be field names. Unless fieldnames are specified, + -- we check if it contains purely numerical values for the case of reading + -- plain data files. + if not cnfg.fieldnames then + local fields = split(line,delim) + local nums = map(tonumber,fields) + if #nums == #fields then + convert = tonumber + append(D,nums) + numfields = {} + for i = 1,#nums do numfields[i] = i end + else + cnfg.fieldnames = fields + end + line = f:read() + if strip then line = strip(line) end + elseif type(cnfg.fieldnames) == 'string' then + cnfg.fieldnames = split(cnfg.fieldnames,delim) + end + -- at this point, the column headers have been read in. If the first + -- row consisted of numbers, it has already been added to the dataset. + if cnfg.fieldnames then + D.fieldnames = cnfg.fieldnames + -- [conversion] unless @no_convert, we need the numerical field indices + -- of the first data row. Can also be specified by @numfields. + if not cnfg.no_convert then + if not numfields then + numfields = {} + local fields = split(line,D.delim) + for i = 1,#fields do + if tonumber(fields[i]) then + append(numfields,i) + end + end + end + if #numfields > 0 then -- there are numerical fields + -- note that using dot as the thousands separator (@thousands_dot) + -- requires a special conversion function! + convert = thousands_dot and try_tonumber or tonumber + end + end + end + -- keep going until finished + while line do + if not line:find ('^%s*$') then + if strip then line = strip(line) end + local fields = split(line,delim) + if convert then + for k = 1,#numfields do + local i = numfields[k] + local val = convert(fields[i]) + if val == nil then + return nil, "not a number: "..fields[i] + else + fields[i] = val + end + end + end + -- [collecting end field] If @last_field_collect then we will collect + -- all extra space-delimited fields into a single last field. + if collect_end and #fields > #D.fieldnames then + local ends,N = {},#D.fieldnames + for i = N+1,#fields do + append(ends,fields[i]) + end + ends = concat(ends,' ') + local cfields = {} + for i = 1,N do cfields[i] = fields[i] end + cfields[N] = cfields[N]..' '..ends + fields = cfields + end + append(D,fields) + end + line = f:read() + end + if opened then f:close() end + if delim == '%s+' then D.delim = ' ' end + if not D.fieldnames then D.fieldnames = {} end + return data.new(D) +end + +local function write_row (data,f,row) + f:write(concat(row,data.delim),'\n') +end + +DataMT.write_row = write_row + +local function write (data,file) + local f,err,opened = open_file(file,'w') + if not f then return nil, err end + if #data.fieldnames > 0 then + f:write(concat(data.fieldnames,data.delim),'\n') + end + for i = 1,#data do + write_row(data,f,data[i]) + end + if opened then f:close() end +end + +DataMT.write = write + +local function massage_fieldnames (fields) + -- [fieldnames must be valid Lua identifiers] fix 0.8 was %A + for i = 1,#fields do + fields[i] = fields[i]:gsub('%W','_') + end +end + + +--- create a new dataset from a table of rows.
    +-- Can specify the fieldnames, else the table must have a field called +-- 'fieldnames', which is either a string of delimiter-separated names, +-- or a table of names.
    +-- If the table does not have a field called 'delim', then an attempt will be +-- made to guess it from the fieldnames string, defaults otherwise to tab. +-- @param d the table. +-- @param fieldnames optional fieldnames +-- @return the table. +function data.new (d,fieldnames) + d.fieldnames = d.fieldnames or fieldnames + if not d.delim and type(d.fieldnames) == 'string' then + d.delim = guess_delim(d.fieldnames) + d.fieldnames = split(d.fieldnames,d.delim) + end + d.fieldnames = make_list(d.fieldnames) + massage_fieldnames(d.fieldnames) + setmetatable(d,DataMT) + -- a query with just the fieldname will return a sequence + -- of values, which seq.copy turns into a table. + return d +end + +local sorted_query = [[ +return function (t) + local i = 0 + local v + local ls = {} + for i,v in ipairs(t) do + if CONDITION then + ls[#ls+1] = v + end + end + table.sort(ls,function(v1,v2) + return SORT_EXPR + end) + local n = #ls + return function() + i = i + 1 + v = ls[i] + if i > n then return end + return FIELDLIST + end +end +]] + +-- question: is this optimized case actually worth the extra code? +local simple_query = [[ +return function (t) + local n = #t + local i = 0 + local v + return function() + repeat + i = i + 1 + v = t[i] + until i > n or CONDITION + if i > n then return end + return FIELDLIST + end +end +]] + +local function is_string (s) + return type(s) == 'string' +end + +local field_error + +local function fieldnames_as_string (data) + return concat(data.fieldnames,',') +end + +local function massage_fields(data,f) + local idx + if f:find '^%d+$' then + idx = tonumber(f) + else + idx = find(data.fieldnames,f) + end + if idx then + return 'v['..idx..']' + else + field_error = f..' not found in '..fieldnames_as_string(data) + return f + end +end + +local List = require 'pl.List' + +local function process_select (data,parms) + --- preparing fields ---- + local res,ret + field_error = nil + local fields = parms.fields + local numfields = fields:find '%$' or #data.fieldnames == 0 + if fields:find '^%s*%*%s*' then + if not numfields then + fields = fieldnames_as_string(data) + else + local ncol = #data[1] + fields = {} + for i = 1,ncol do append(fields,'$'..i) end + fields = concat(fields,',') + end + end + local idpat = patterns.IDEN + if numfields then + idpat = '%$(%d+)' + else + -- massage field names to replace non-identifier chars + fields = rstrip(fields):gsub('[^,%w]','_') + end + local massage_fields = utils.bind1(massage_fields,data) + ret = gsub(fields,idpat,massage_fields) + if field_error then return nil,field_error end + parms.fields = fields + parms.proc_fields = ret + parms.where = parms.where or 'true' + if is_string(parms.where) then + parms.where = gsub(parms.where,idpat,massage_fields) + field_error = nil + end + return true +end + + +parse_select = function(s,data) + local endp + local parms = {} + local w1,w2 = s:find('where ') + local s1,s2 = s:find('sort by ') + if w1 then -- where clause! + endp = (s1 or 0)-1 + parms.where = s:sub(w2+1,endp) + end + if s1 then -- sort by clause (must be last!) + parms.sort_by = s:sub(s2+1) + end + endp = (w1 or s1 or 0)-1 + parms.fields = s:sub(1,endp) + local status,err = process_select(data,parms) + if not status then return nil,err + else return parms end +end + +--- create a query iterator from a select string. +-- Select string has this format:
    +-- FIELDLIST [ where LUA-CONDN [ sort by FIELD] ]
    +-- FIELDLIST is a comma-separated list of valid fields, or '*'.

    +-- The condition can also be a table, with fields 'fields' (comma-sep string or +-- table), 'sort_by' (string) and 'where' (Lua expression string or function) +-- @param data table produced by read +-- @param condn select string or table +-- @param context a list of tables to be searched when resolving functions +-- @param return_row if true, wrap the results in a row table +-- @return an iterator over the specified fields, or nil +-- @return an error message +function data.query(data,condn,context,return_row) + local err + if is_string(condn) then + condn,err = parse_select(condn,data) + if not condn then return nil,err end + elseif type(condn) == 'table' then + if type(condn.fields) == 'table' then + condn.fields = concat(condn.fields,',') + end + if not condn.proc_fields then + local status,err = process_select(data,condn) + if not status then return nil,err end + end + else + return nil, "condition must be a string or a table" + end + local query, k + if condn.sort_by then -- use sorted_query + query = sorted_query + else + query = simple_query + end + local fields = condn.proc_fields or condn.fields + if return_row then + fields = '{'..fields..'}' + end + query,k = query:gsub('FIELDLIST',fields) + if is_string(condn.where) then + query = query:gsub('CONDITION',condn.where) + condn.where = nil + else + query = query:gsub('CONDITION','_condn(v)') + condn.where = function_arg(0,condn.where,'condition.where must be callable') + end + if condn.sort_by then + local expr,sort_var,sort_dir + local sort_by = condn.sort_by + local i1,i2 = sort_by:find('%s+') + if i1 then + sort_var,sort_dir = sort_by:sub(1,i1-1),sort_by:sub(i2+1) + else + sort_var = sort_by + sort_dir = 'asc' + end + if sort_var:match '^%$' then sort_var = sort_var:sub(2) end + sort_var = massage_fields(data,sort_var) + if field_error then return nil,field_error end + if sort_dir == 'asc' then + sort_dir = '<' + else + sort_dir = '>' + end + expr = ('%s %s %s'):format(sort_var:gsub('v','v1'),sort_dir,sort_var:gsub('v','v2')) + query = query:gsub('SORT_EXPR',expr) + end + if condn.where then + query = 'return function(_condn) '..query..' end' + end + if _DEBUG then print(query) end + + local fn,err = loadstring(query,'tmp') + if not fn then return nil,err end + fn = fn() -- get the function + if condn.where then + fn = fn(condn.where) + end + local qfun = fn(data) + if context then + -- [specifying context for condition] @context is a list of tables which are + -- 'injected'into the condition's custom context + append(context,_G) + local lookup = {} + setfenv(qfun,lookup) + setmetatable(lookup,{ + __index = function(tbl,key) + -- _G.print(tbl,key) + for k,t in ipairs(context) do + if t[key] then return t[key] end + end + end + }) + end + return qfun +end + + +DataMT.select = data.query +DataMT.select_row = function(d,condn,context) + return data.query(d,condn,context,true) +end + +--- Filter input using a query. +-- @param Q a query string +-- @param infile filename or file-like object +-- @param outfile filename or file-like object +-- @param dont_fail true if you want to return an error, not just fail +function data.filter (Q,infile,outfile,dont_fail) + local err + local d = data.read(infile or 'stdin') + local out = open_file(outfile or 'stdout') + local iter,err = d:select(Q) + local delim = d.delim + if not iter then + err = 'error: '..err + if dont_fail then + return nil,err + else + utils.quit(1,err) + end + end + while true do + local res = {iter()} + if #res == 0 then break end + out:write(concat(res,delim),'\n') + end +end + +return data + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/dir.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/dir.lua new file mode 100644 index 000000000..5cea49e27 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/dir.lua @@ -0,0 +1,478 @@ +--- Useful functions for getting directory contents and matching them against wildcards. +-- @class module +-- @name pl.dir + +local utils = require 'pl.utils' +local path = require 'pl.path' +local is_windows = path.is_windows +local tablex = require 'pl.tablex' +local ldir = path.dir +local chdir = path.chdir +local mkdir = path.mkdir +local rmdir = path.rmdir +local sub = string.sub +local os,pcall,ipairs,pairs,require,setmetatable,_G = os,pcall,ipairs,pairs,require,setmetatable,_G +local remove = os.remove +local append = table.insert +local wrap = coroutine.wrap +local yield = coroutine.yield +local assert_arg,assert_string,raise = utils.assert_arg,utils.assert_string,utils.raise +local List = utils.stdmt.List + +--[[ +module ('pl.dir',utils._module) +]] + +local dir = {} + +local function assert_dir (n,val) + assert_arg(n,val,'string',path.isdir,'not a directory') +end + +local function assert_file (n,val) + assert_arg(n,val,'string',path.isfile,'not a file') +end + +local function filemask(mask) + mask = utils.escape(mask) + return mask:gsub('%%%*','.+'):gsub('%%%?','.')..'$' +end + +--- does the filename match the shell pattern?. +-- (cf. fnmatch.fnmatch in Python, 11.8) +-- @param file A file name +-- @param pattern A shell pattern +-- @return true or false +-- @raise file and pattern must be strings +function dir.fnmatch(file,pattern) + assert_string(1,file) + assert_string(2,pattern) + return path.normcase(file):find(filemask(pattern)) ~= nil +end + +--- return a list of all files which match the pattern. +-- (cf. fnmatch.filter in Python, 11.8) +-- @param files A table containing file names +-- @param pattern A shell pattern. +-- @return list of files +-- @raise file and pattern must be strings +function dir.filter(files,pattern) + assert_arg(1,files,'table') + assert_string(2,pattern) + local res = {} + local mask = filemask(pattern) + for i,f in ipairs(files) do + if f:find(mask) then append(res,f) end + end + return setmetatable(res,List) +end + +local function _listfiles(dir,filemode,match) + local res = {} + local check = utils.choose(filemode,path.isfile,path.isdir) + if not dir then dir = '.' end + for f in ldir(dir) do + if f ~= '.' and f ~= '..' then + local p = path.join(dir,f) + if check(p) and (not match or match(p)) then + append(res,p) + end + end + end + return setmetatable(res,List) +end + +--- return a list of all files in a directory which match the a shell pattern. +-- @param dir A directory. If not given, all files in current directory are returned. +-- @param mask A shell pattern. If not given, all files are returned. +-- @return lsit of files +-- @raise dir and mask must be strings +function dir.getfiles(dir,mask) + assert_dir(1,dir) + assert_string(2,mask) + local match + if mask then + mask = filemask(mask) + match = function(f) + return f:find(mask) + end + end + return _listfiles(dir,true,match) +end + +--- return a list of all subdirectories of the directory. +-- @param dir A directory +-- @return a list of directories +-- @raise dir must be a string +function dir.getdirectories(dir) + assert_dir(1,dir) + return _listfiles(dir,false) +end + +local function quote_argument (f) + f = path.normcase(f) + if f:find '%s' then + return '"'..f..'"' + else + return f + end +end + + +local alien,ffi,ffi_checked,CopyFile,MoveFile,GetLastError,win32_errors,cmd_tmpfile + +local function execute_command(cmd,parms) + if not cmd_tmpfile then cmd_tmpfile = path.tmpname () end + local err = path.is_windows and ' > ' or ' 2> ' + cmd = cmd..' '..parms..err..cmd_tmpfile + local ret = utils.execute(cmd) + if not ret then + return false,(utils.readfile(cmd_tmpfile):gsub('\n(.*)','')) + else + return true + end +end + +local function find_ffi_copyfile () + if not ffi_checked then + ffi_checked = true + local res + res,alien = pcall(require,'alien') + if not res then + alien = nil + res, ffi = pcall(require,'ffi') + end + if not res then + ffi = nil + return + end + else + return + end + if alien then + -- register the Win32 CopyFile and MoveFile functions + local kernel = alien.load('kernel32.dll') + CopyFile = kernel.CopyFileA + CopyFile:types{'string','string','int',ret='int',abi='stdcall'} + MoveFile = kernel.MoveFileA + MoveFile:types{'string','string',ret='int',abi='stdcall'} + GetLastError = kernel.GetLastError + GetLastError:types{ret ='int', abi='stdcall'} + elseif ffi then + ffi.cdef [[ + int CopyFileA(const char *src, const char *dest, int iovr); + int MoveFileA(const char *src, const char *dest); + int GetLastError(); + ]] + CopyFile = ffi.C.CopyFileA + MoveFile = ffi.C.MoveFileA + GetLastError = ffi.C.GetLastError + end + win32_errors = { + ERROR_FILE_NOT_FOUND = 2, + ERROR_PATH_NOT_FOUND = 3, + ERROR_ACCESS_DENIED = 5, + ERROR_WRITE_PROTECT = 19, + ERROR_BAD_UNIT = 20, + ERROR_NOT_READY = 21, + ERROR_WRITE_FAULT = 29, + ERROR_READ_FAULT = 30, + ERROR_SHARING_VIOLATION = 32, + ERROR_LOCK_VIOLATION = 33, + ERROR_HANDLE_DISK_FULL = 39, + ERROR_BAD_NETPATH = 53, + ERROR_NETWORK_BUSY = 54, + ERROR_DEV_NOT_EXIST = 55, + ERROR_FILE_EXISTS = 80, + ERROR_OPEN_FAILED = 110, + ERROR_INVALID_NAME = 123, + ERROR_BAD_PATHNAME = 161, + ERROR_ALREADY_EXISTS = 183, + } +end + +local function two_arguments (f1,f2) + return quote_argument(f1)..' '..quote_argument(f2) +end + +local function file_op (is_copy,src,dest,flag) + if flag == 1 and path.exists(dest) then + return false,"cannot overwrite destination" + end + if is_windows then + -- if we haven't tried to load Alien/LuaJIT FFI before, then do so + find_ffi_copyfile() + -- fallback if there's no Alien, just use DOS commands *shudder* + -- 'rename' involves a copy and then deleting the source. + if not CopyFile then + src = path.normcase(src) + dest = path.normcase(dest) + local cmd = is_copy and 'copy' or 'rename' + local res, err = execute_command('copy',two_arguments(src,dest)) + if not res then return nil,err end + if not is_copy then + return execute_command('del',quote_argument(src)) + end + else + if path.isdir(dest) then + dest = path.join(dest,path.basename(src)) + end + local ret + if is_copy then ret = CopyFile(src,dest,flag) + else ret = MoveFile(src,dest) end + if ret == 0 then + local err = GetLastError() + for name,value in pairs(win32_errors) do + if value == err then return false,name end + end + return false,"Error #"..err + else return true + end + end + else -- for Unix, just use cp for now + return execute_command(is_copy and 'cp' or 'mv', + two_arguments(src,dest)) + end +end + +--- copy a file. +-- @param src source file +-- @param dest destination file or directory +-- @param flag true if you want to force the copy (default) +-- @return true if operation succeeded +-- @raise src and dest must be strings +function dir.copyfile (src,dest,flag) + assert_string(1,src) + assert_string(2,dest) + flag = flag==nil or flag + return file_op(true,src,dest,flag and 0 or 1) +end + +--- move a file. +-- @param src source file +-- @param dest destination file or directory +-- @return true if operation succeeded +-- @raise src and dest must be strings +function dir.movefile (src,dest) + assert_string(1,src) + assert_string(2,dest) + return file_op(false,src,dest,0) +end + +local function _dirfiles(dir,attrib) + local dirs = {} + local files = {} + for f in ldir(dir) do + if f ~= '.' and f ~= '..' then + local p = path.join(dir,f) + local mode = attrib(p,'mode') + if mode=='directory' then + append(dirs,f) + else + append(files,f) + end + end + end + return setmetatable(dirs,List),setmetatable(files,List) +end + + +local function _walker(root,bottom_up,attrib) + local dirs,files = _dirfiles(root,attrib) + if not bottom_up then yield(root,dirs,files) end + for i,d in ipairs(dirs) do + _walker(root..path.sep..d,bottom_up,attrib) + end + if bottom_up then yield(root,dirs,files) end +end + +--- return an iterator which walks through a directory tree starting at root. +-- The iterator returns (root,dirs,files) +-- Note that dirs and files are lists of names (i.e. you must say path.join(root,d) +-- to get the actual full path) +-- If bottom_up is false (or not present), then the entries at the current level are returned +-- before we go deeper. This means that you can modify the returned list of directories before +-- continuing. +-- This is a clone of os.walk from the Python libraries. +-- @param root A starting directory +-- @param bottom_up False if we start listing entries immediately. +-- @param follow_links follow symbolic links +-- @return an iterator returning root,dirs,files +-- @raise root must be a string +function dir.walk(root,bottom_up,follow_links) + assert_string(1,root) + if not path.isdir(root) then return raise 'not a directory' end + local attrib + if path.is_windows or not follow_links then + attrib = path.attrib + else + attrib = path.link_attrib + end + return wrap(function () _walker(root,bottom_up,attrib) end) +end + +--- remove a whole directory tree. +-- @param fullpath A directory path +-- @return true or nil +-- @return error if failed +-- @raise fullpath must be a string +function dir.rmtree(fullpath) + assert_string(1,fullpath) + if not path.isdir(fullpath) then return raise 'not a directory' end + if path.islink(fullpath) then return false,'will not follow symlink' end + for root,dirs,files in dir.walk(fullpath,true) do + for i,f in ipairs(files) do + remove(path.join(root,f)) + end + rmdir(root) + end + return true +end + +local dirpat +if path.is_windows then + dirpat = '(.+)\\[^\\]+$' +else + dirpat = '(.+)/[^/]+$' +end + +local _makepath +function _makepath(p) + -- windows root drive case + if p:find '^%a:[\\]*$' then + return true + end + if not path.isdir(p) then + local subp = p:match(dirpat) + if not _makepath(subp) then return raise ('cannot create '..subp) end + return mkdir(p) + else + return true + end +end + +--- create a directory path. +-- This will create subdirectories as necessary! +-- @param p A directory path +-- @return a valid created path +-- @raise p must be a string +function dir.makepath (p) + assert_string(1,p) + return _makepath(path.normcase(path.abspath(p))) +end + + +--- clone a directory tree. Will always try to create a new directory structure +-- if necessary. +-- @param path1 the base path of the source tree +-- @param path2 the new base path for the destination +-- @param file_fun an optional function to apply on all files +-- @param verbose an optional boolean to control the verbosity of the output. +-- It can also be a logging function that behaves like print() +-- @return true, or nil +-- @return error message, or list of failed directory creations +-- @return list of failed file operations +-- @raise path1 and path2 must be strings +-- @usage clonetree('.','../backup',copyfile) +function dir.clonetree (path1,path2,file_fun,verbose) + assert_string(1,path1) + assert_string(2,path2) + if verbose == true then verbose = print end + local abspath,normcase,isdir,join = path.abspath,path.normcase,path.isdir,path.join + local faildirs,failfiles = {},{} + if not isdir(path1) then return raise 'source is not a valid directory' end + path1 = abspath(normcase(path1)) + path2 = abspath(normcase(path2)) + if verbose then verbose('normalized:',path1,path2) end + -- particularly NB that the new path isn't fully contained in the old path + if path1 == path2 then return raise "paths are the same" end + local i1,i2 = path2:find(path1,1,true) + if i2 == #path1 and path2:sub(i2+1,i2+1) == path.sep then + return raise 'destination is a subdirectory of the source' + end + local cp = path.common_prefix (path1,path2) + local idx = #cp + if idx == 0 then -- no common path, but watch out for Windows paths! + if path1:sub(2,2) == ':' then idx = 3 end + end + for root,dirs,files in dir.walk(path1) do + local opath = path2..root:sub(idx) + if verbose then verbose('paths:',opath,root) end + if not isdir(opath) then + local ret = dir.makepath(opath) + if not ret then append(faildirs,opath) end + if verbose then verbose('creating:',opath,ret) end + end + if file_fun then + for i,f in ipairs(files) do + local p1 = join(root,f) + local p2 = join(opath,f) + local ret = file_fun(p1,p2) + if not ret then append(failfiles,p2) end + if verbose then + verbose('files:',p1,p2,ret) + end + end + end + end + return true,faildirs,failfiles +end + +--- return an iterator over all entries in a directory tree +-- @param d a directory +-- @return an iterator giving pathname and mode (true for dir, false otherwise) +-- @raise d must be a non-empty string +function dir.dirtree( d ) + assert( d and d ~= "", "directory parameter is missing or empty" ) + local exists, isdir = path.exists, path.isdir + local sep = path.sep + + local last = sub ( d, -1 ) + if last == sep or last == '/' then + d = sub( d, 1, -2 ) + end + + local function yieldtree( dir ) + for entry in ldir( dir ) do + if entry ~= "." and entry ~= ".." then + entry = dir .. sep .. entry + if exists(entry) then -- Just in case a symlink is broken. + local is_dir = isdir(entry) + yield( entry, is_dir ) + if is_dir then + yieldtree( entry ) + end + end + end + end + end + + return wrap( function() yieldtree( d ) end ) +end + + +--- Recursively returns all the file starting at path. It can optionally take a shell pattern and +-- only returns files that match pattern. If a pattern is given it will do a case insensitive search. +-- @param start_path {string} A directory. If not given, all files in current directory are returned. +-- @param pattern {string} A shell pattern. If not given, all files are returned. +-- @return Table containing all the files found recursively starting at path and filtered by pattern. +-- @raise start_path must be a string +function dir.getallfiles( start_path, pattern ) + assert( type( start_path ) == "string", "bad argument #1 to 'GetAllFiles' (Expected string but recieved " .. type( start_path ) .. ")" ) + pattern = pattern or "" + + local files = {} + local normcase = path.normcase + for filename, mode in dir.dirtree( start_path ) do + if not mode then + local mask = filemask( pattern ) + if normcase(filename):find( mask ) then + files[#files + 1] = filename + end + end + end + + return files +end + +return dir diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/file.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/file.lua new file mode 100644 index 000000000..6c82e2859 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/file.lua @@ -0,0 +1,69 @@ +--- File manipulation functions: reading, writing, moving and copying. +-- @class module +-- @name pl.file +local os = os +local utils = require 'pl.utils' +local dir = require 'pl.dir' +local path = require 'pl.path' + +--[[ +module ('pl.file',utils._module) +]] +local file = {} + +--- return the contents of a file as a string +-- @class function +-- @name file.read +-- @param filename The file path +-- @return file contents +file.read = utils.readfile + +--- write a string to a file +-- @class function +-- @name file.write +-- @param filename The file path +-- @param str The string +file.write = utils.writefile + +--- copy a file. +-- @class function +-- @name file.copy +-- @param src source file +-- @param dest destination file +-- @param flag true if you want to force the copy (default) +-- @return true if operation succeeded +file.copy = dir.copyfile + +--- move a file. +-- @class function +-- @name file.move +-- @param src source file +-- @param dest destination file +-- @return true if operation succeeded, else false and the reason for the error. +file.move = dir.movefile + +--- Return the time of last access as the number of seconds since the epoch. +-- @class function +-- @name file.access_time +-- @param path A file path +file.access_time = path.getatime + +---Return when the file was created. +-- @class function +-- @name file.creation_time +-- @param path A file path +file.creation_time = path.getctime + +--- Return the time of last modification +-- @class function +-- @name file.modified_time +-- @param path A file path +file.modified_time = path.getmtime + +--- Delete a file +-- @class function +-- @name file.delete +-- @param path A file path +file.delete = os.remove + +return file diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/func.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/func.lua new file mode 100644 index 000000000..3711c9a71 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/func.lua @@ -0,0 +1,379 @@ +--- Functional helpers like composition, binding and placeholder expressions. +-- Placeholder expressions are useful for short anonymous functions, and were +-- inspired by the Boost Lambda library. +--

    +-- utils.import 'pl.func'
    +-- ls = List{10,20,30}
    +-- = ls:map(_1+1)
    +--    {11,21,31}
    +-- 
    +-- They can also be used to bind particular arguments of a function. +--
    +-- p = bind(print,'start>',_0)
    +-- p(10,20,30)
    +-- start>   10   20  30
    +-- 
    +-- See the Guide +-- @class module +-- @name pl.func +local type,select,setmetatable,getmetatable,rawset = type,select,setmetatable,getmetatable,rawset +local concat,append = table.concat,table.insert +local max = math.max +local print,tostring = print,tostring +local pairs,ipairs,loadstring,rawget,unpack = pairs,ipairs,loadstring,rawget,unpack +local _G = _G +local utils = require 'pl.utils' +local tablex = require 'pl.tablex' +local map = tablex.map +local _DEBUG = rawget(_G,'_DEBUG') +local assert_arg = utils.assert_arg + +--[[ +module ('pl.func',utils._module) +]] + +local func = {} + +-- metatable for Placeholder Expressions (PE) +local _PEMT = {} + +local function P (t) + setmetatable(t,_PEMT) + return t +end + +func.PE = P + +local function isPE (obj) + return getmetatable(obj) == _PEMT +end + +func.isPE = isPE + +-- construct a placeholder variable (e.g _1 and _2) +local function PH (idx) + return P {op='X',repr='_'..idx, index=idx} +end + +-- construct a constant placeholder variable (e.g _C1 and _C2) +local function CPH (idx) + return P {op='X',repr='_C'..idx, index=idx} +end + +func._1,func._2,func._3,func._4,func._5 = PH(1),PH(2),PH(3),PH(4),PH(5) +func._0 = P{op='X',repr='...',index=0} + +function func.Var (name) + local ls = utils.split(name,'[%s,]+') + local res = {} + for _,n in ipairs(ls) do + append(res,P{op='X',repr=n,index=0}) + end + return unpack(res) +end + +function func._ (value) + return P{op='X',repr=value,index='wrap'} +end + +local repr + +func.Nil = func.Var 'nil' + +function _PEMT.__index(obj,key) + return P{op='[]',obj,key} +end + +function _PEMT.__call(fun,...) + return P{op='()',fun,...} +end + +function _PEMT.__tostring (e) + return repr(e) +end + +function _PEMT.__unm(arg) + return P{op='-',arg} +end + +function func.Not (arg) + return P{op='not',arg} +end + +function func.Len (arg) + return P{op='#',arg} +end + + +local function binreg(context,t) + for name,op in pairs(t) do + rawset(context,name,function(x,y) + return P{op=op,x,y} + end) + end +end + +local function import_name (name,fun,context) + rawset(context,name,function(...) + return P{op='()',fun,...} + end) +end + +local imported_functions = {} + +local function is_global_table (n) + return type(_G[n]) == 'table' +end + +--- wrap a table of functions. This makes them available for use in +-- placeholder expressions. +-- @param tname a table name +-- @param context context to put results, defaults to environment of caller +function func.import(tname,context) + assert_arg(1,tname,'string',is_global_table,'arg# 1: not a name of a global table') + local t = _G[tname] + context = context or _G + for name,fun in pairs(t) do + import_name(name,fun,context) + imported_functions[fun] = name + end +end + +--- register a function for use in placeholder expressions. +-- @param fun a function +-- @param name an optional name +-- @return a placeholder functiond +function func.register (fun,name) + assert_arg(1,fun,'function') + if name then + assert_arg(2,name,'string') + imported_functions[fun] = name + end + return function(...) + return P{op='()',fun,...} + end +end + +function func.lookup_imported_name (fun) + return imported_functions[fun] +end + +local function _arg(...) return ... end + +function func.Args (...) + return P{op='()',_arg,...} +end + +-- binary and unary operators, with their precedences (see 2.5.6) +local operators = { + ['or'] = 0, + ['and'] = 1, + ['=='] = 2, ['~='] = 2, ['<'] = 2, ['>'] = 2, ['<='] = 2, ['>='] = 2, + ['..'] = 3, + ['+'] = 4, ['-'] = 4, + ['*'] = 5, ['/'] = 5, ['%'] = 5, + ['not'] = 6, ['#'] = 6, ['-'] = 6, + ['^'] = 7 +} + +-- comparisons (as prefix functions) +binreg (func,{And='and',Or='or',Eq='==',Lt='<',Gt='>',Le='<=',Ge='>='}) + +-- standard binary operators (as metamethods) +binreg (_PEMT,{__add='+',__sub='-',__mul='*',__div='/',__mod='%',__pow='^',__concat='..'}) + +binreg (_PEMT,{__eq='=='}) + +--- all elements of a table except the first. +-- @param ls a list-like table. +function func.tail (ls) + assert_arg(1,ls,'table') + local res = {} + for i = 2,#ls do + append(res,ls[i]) + end + return res +end + +--- create a string representation of a placeholder expression. +-- @param e a placeholder expression +-- @param lastpred not used +function repr (e,lastpred) + local tail = func.tail + if isPE(e) then + local pred = operators[e.op] + local ls = map(repr,e,pred) + if pred then --unary or binary operator + if #ls ~= 1 then + local s = concat(ls,' '..e.op..' ') + if lastpred and lastpred > pred then + s = '('..s..')' + end + return s + else + return e.op..' '..ls[1] + end + else -- either postfix, or a placeholder + if e.op == '[]' then + return ls[1]..'['..ls[2]..']' + elseif e.op == '()' then + local fn + if ls[1] ~= nil then -- was _args, undeclared! + fn = ls[1] + else + fn = '' + end + return fn..'('..concat(tail(ls),',')..')' + else + return e.repr + end + end + elseif type(e) == 'string' then + return '"'..e..'"' + elseif type(e) == 'function' then + local name = func.lookup_imported_name(e) + if name then return name else return tostring(e) end + else + return tostring(e) --should not really get here! + end +end +func.repr = repr + +-- collect all the non-PE values in this PE into vlist, and replace each occurence +-- with a constant PH (_C1, etc). Return the maximum placeholder index found. +local collect_values +function collect_values (e,vlist) + if isPE(e) then + if e.op ~= 'X' then + local m = 0 + for i,subx in ipairs(e) do + local pe = isPE(subx) + if pe then + if subx.op == 'X' and subx.index == 'wrap' then + subx = subx.repr + pe = false + else + m = max(m,collect_values(subx,vlist)) + end + end + if not pe then + append(vlist,subx) + e[i] = CPH(#vlist) + end + end + return m + else -- was a placeholder, it has an index... + return e.index + end + else -- plain value has no placeholder dependence + return 0 + end +end +func.collect_values = collect_values + +--- instantiate a PE into an actual function. First we find the largest placeholder used, +-- e.g. _2; from this a list of the formal parameters can be build. Then we collect and replace +-- any non-PE values from the PE, and build up a constant binding list. +-- Finally, the expression can be compiled, and e.__PE_function is set. +-- @param e a placeholder expression +-- @return a function +function func.instantiate (e) + local consts,values,parms = {},{},{} + local rep, err, fun + local n = func.collect_values(e,values) + for i = 1,#values do + append(consts,'_C'..i) + if _DEBUG then print(i,values[i]) end + end + for i =1,n do + append(parms,'_'..i) + end + consts = concat(consts,',') + parms = concat(parms,',') + rep = repr(e) + local fstr = ('return function(%s) return function(%s) return %s end end'):format(consts,parms,rep) + if _DEBUG then print(fstr) end + fun,err = loadstring(fstr,'fun') + if not fun then return nil,err end + fun = fun() -- get wrapper + fun = fun(unpack(values)) -- call wrapper (values could be empty) + e.__PE_function = fun + return fun +end + +--- instantiate a PE unless it has already been done. +-- @param e a placeholder expression +-- @return the function +function func.I(e) + if rawget(e,'__PE_function') then + return e.__PE_function + else return func.instantiate(e) + end +end + +utils.add_function_factory(_PEMT,func.I) + +--- bind the first parameter of the function to a value. +-- @class function +-- @name func.curry +-- @param fn a function of one or more arguments +-- @param p a value +-- @return a function of one less argument +-- @usage (curry(math.max,10))(20) == math.max(10,20) +func.curry = utils.bind1 + +--- create a function which chains two functions. +-- @param f a function of at least one argument +-- @param g a function of at least one argument +-- @return a function +-- @usage printf = compose(io.write,string.format) +function func.compose (f,g) + return function(...) return f(g(...)) end +end + +--- bind the arguments of a function to given values. +-- bind(fn,v,_2) is equivalent to curry(fn,v). +-- @param fn a function of at least one argument +-- @param ... values or placeholder variables +-- @return a function +-- @usage (bind(f,_1,a))(b) == f(a,b) +-- @usage (bind(f,_2,_1))(a,b) == f(b,a) +function func.bind(fn,...) + local args = table.pack(...) + local holders,parms,bvalues,values = {},{},{'fn'},{} + local nv,maxplace,varargs = 1,0,false + for i = 1,args.n do + local a = args[i] + if isPE(a) and a.op == 'X' then + append(holders,a.repr) + maxplace = max(maxplace,a.index) + if a.index == 0 then varargs = true end + else + local v = '_v'..nv + append(bvalues,v) + append(holders,v) + append(values,a) + nv = nv + 1 + end + end + for np = 1,maxplace do + append(parms,'_'..np) + end + if varargs then append(parms,'...') end + bvalues = concat(bvalues,',') + parms = concat(parms,',') + holders = concat(holders,',') + local fstr = ([[ +return function (%s) + return function(%s) return fn(%s) end +end +]]):format(bvalues,parms,holders) + if _DEBUG then print(fstr) end + local res,err = loadstring(fstr) + res = res() + return res(fn,unpack(values)) +end + +return func + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/init.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/init.lua new file mode 100644 index 000000000..ee336e57c --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/init.lua @@ -0,0 +1,47 @@ +-------------- +-- entry point for loading all PL libraries only on demand. +-- Requiring 'pl' means that whenever a module is accesssed (e.g. utils.split) +-- then that module is dynamically loaded. The submodules are all brought into +-- the global space. +-- @class module +-- @name pl + +local modules = { + utils = true,path=true,dir=true,tablex=true,stringio=true,sip=true, + input=true,seq=true,lexer=true,stringx=true, + config=true,pretty=true,data=true,func=true,text=true, + operator=true,lapp=true,array2d=true, + comprehension=true,xml=true, + test = true, app = true, file = true, class = true, List = true, + Map = true, Set = true, OrderedMap = true, MultiMap = true, + Date = true, + -- classes -- +} +_G.utils = require 'pl.utils' + +for name,klass in pairs(_G.utils.stdmt) do + klass.__index = function(t,key) + return require ('pl.'..name)[key] + end; +end + +local _hook +setmetatable(_G,{ + hook = function(handler) + _hook = handler + end, + __index = function(t,name) + local found = modules[name] + -- either true, or the name of the module containing this class. + -- either way, we load the required module and make it globally available. + if found then + -- e..g pretty.dump causes pl.pretty to become available as 'pretty' + rawset(_G,name,require('pl.'..name)) + return _G[name] + elseif _hook then + return _hook(t,name) + end + end +}) + +if _G.PENLIGHT_STRICT then require 'pl.strict' end diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/input.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/input.lua new file mode 100644 index 000000000..ea566f470 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/input.lua @@ -0,0 +1,172 @@ +--- Iterators for extracting words or numbers from an input source. +--
    +--    require 'pl'
    +--    local total,n = seq.sum(input.numbers())
    +--    print('average',total/n)
    +-- 
    +--

    See here +-- @class module +-- @name pl.input +local strfind = string.find +local strsub = string.sub +local strmatch = string.match +local pairs,type,unpack,tonumber = pairs,type,unpack,tonumber +local utils = require 'pl.utils' +local patterns = utils.patterns +local io = io +local assert_arg = utils.assert_arg + +--[[ +module ('pl.input',utils._module) +]] + +local input = {} + +--- create an iterator over all tokens. +-- based on allwords from PiL, 7.1 +-- @param getter any function that returns a line of text +-- @param pattern +-- @param fn Optionally can pass a function to process each token as it/s found. +-- @return an iterator +function input.alltokens (getter,pattern,fn) + local line = getter() -- current line + local pos = 1 -- current position in the line + return function () -- iterator function + while line do -- repeat while there are lines + local s, e = strfind(line, pattern, pos) + if s then -- found a word? + pos = e + 1 -- next position is after this token + local res = strsub(line, s, e) -- return the token + if fn then res = fn(res) end + return res + else + line = getter() -- token not found; try next line + pos = 1 -- restart from first position + end + end + return nil -- no more lines: end of traversal + end +end +local alltokens = input.alltokens + +-- question: shd this _split_ a string containing line feeds? + +--- create a function which grabs the next value from a source. If the source is a string, then the getter +-- will return the string and thereafter return nil. If not specified then the source is assumed to be stdin. +-- @param f a string or a file-like object (i.e. has a read() method which returns the next line) +-- @return a getter function +function input.create_getter(f) + if f then + if type(f) == 'string' then + local ls = utils.split(f,'\n') + local i,n = 0,#ls + return function() + i = i + 1 + if i > n then return nil end + return ls[i] + end + else + -- anything that supports the read() method! + if not f.read then error('not a file-like object') end + return function() return f:read() end + end + else + return io.read -- i.e. just read from stdin + end +end + +--- generate a sequence of numbers from a source. +-- @param f A source +-- @return An iterator +function input.numbers(f) + return alltokens(input.create_getter(f), + '('..patterns.FLOAT..')',tonumber) +end + +--- generate a sequence of words from a source. +-- @param f A source +-- @return An iterator +function input.words(f) + return alltokens(input.create_getter(f),"%w+") +end + +local function apply_tonumber (no_fail,...) + local args = {...} + for i = 1,#args do + local n = tonumber(args[i]) + if n == nil then + if not no_fail then return nil,args[i] end + else + args[i] = n + end + end + return args +end + +--- parse an input source into fields. +-- By default, will fail if it cannot convert a field to a number. +-- @param ids a list of field indices, or a maximum field index +-- @param delim delimiter to parse fields (default space) +-- @param f a source @see create_getter +-- @param opts option table, {no_fail=true} +-- @return an iterator with the field values +-- @usage for x,y in fields {2,3} do print(x,y) end -- 2nd and 3rd fields from stdin +function input.fields (ids,delim,f,opts) + local sep + local s + local getter = input.create_getter(f) + local no_fail = opts and opts.no_fail + local no_convert = opts and opts.no_convert + if not delim or delim == ' ' then + delim = '%s' + sep = '%s+' + s = '%s*' + else + sep = delim + s = '' + end + local max_id = 0 + if type(ids) == 'table' then + for i,id in pairs(ids) do + if id > max_id then max_id = id end + end + else + max_id = ids + ids = {} + for i = 1,max_id do ids[#ids+1] = i end + end + local pat = '[^'..delim..']*' + local k = 1 + for i = 1,max_id do + if ids[k] == i then + k = k + 1 + s = s..'('..pat..')' + else + s = s..pat + end + if i < max_id then + s = s..sep + end + end + local linecount = 1 + return function() + local line,results,err + repeat + line = getter() + linecount = linecount + 1 + if not line then return nil end + if no_convert then + results = {strmatch(line,s)} + else + results,err = apply_tonumber(no_fail,strmatch(line,s)) + if not results then + utils.quit("line "..(linecount-1)..": cannot convert '"..err.."' to number") + end + end + until #results > 0 + return unpack(results) + end +end + +return input + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/lapp.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/lapp.lua new file mode 100644 index 000000000..80a81294a --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/lapp.lua @@ -0,0 +1,350 @@ +--- Simple command-line parsing using human-readable specification. +-- Supports GNU-style parameters. +--

    +--      lapp = require 'pl.lapp'
    +--      local args = lapp [[
    +--      Does some calculations
    +--        -o,--offset (default 0.0)  Offset to add to scaled number
    +--        -s,--scale  (number)  Scaling factor
    +--         <number> (number )  Number to be scaled
    +--      ]]
    +--
    +--      print(args.offset + args.scale * args.number)
    +-- 
    +-- Lines begining with '-' are flags; there may be a short and a long name; +-- lines begining wih '<var>' are arguments. Anything in parens after +-- the flag/argument is either a default, a type name or a range constraint. +--

    See the Guide +-- @class module +-- @name pl.lapp + +local status,sip = pcall(require,'pl.sip') +if not status then + sip = require 'sip' +end +local match = sip.match_at_start +local append,tinsert = table.insert,table.insert + +--[[ +module('pl.lapp') +]] + +local function lines(s) return s:gmatch('([^\n]*)\n') end +local function lstrip(str) return str:gsub('^%s+','') end +local function strip(str) return lstrip(str):gsub('%s+$','') end +local function at(s,k) return s:sub(k,k) end +local function isdigit(s) return s:find('^%d+$') == 1 end + +local lapp = {} + +local open_files,parms,aliases,parmlist,usage,windows,script + +lapp.callback = false -- keep Strict happy + +local filetypes = { + stdin = {io.stdin,'file-in'}, stdout = {io.stdout,'file-out'}, + stderr = {io.stderr,'file-out'} +} + +--- controls whether to dump usage on error. +-- Defaults to true +lapp.show_usage_error = true + +--- quit this script immediately. +-- @param msg optional message +-- @param no_usage suppress 'usage' display +function lapp.quit(msg,no_usage) + if msg then + io.stderr:write(msg..'\n\n') + end + if not no_usage then + io.stderr:write(usage) + end + os.exit(1); +end + +--- print an error to stderr and quit. +-- @param msg a message +-- @param no_usage suppress 'usage' display +function lapp.error(msg,no_usage) + if not lapp.show_usage_error then + no_usage = true + end + lapp.quit(script..':'..msg,no_usage) +end + +--- open a file. +-- This will quit on error, and keep a list of file objects for later cleanup. +-- @param file filename +-- @param opt same as second parameter of io.open +function lapp.open (file,opt) + local val,err = io.open(file,opt) + if not val then lapp.error(err,true) end + append(open_files,val) + return val +end + +--- quit if the condition is false. +-- @param condn a condition +-- @param msg an optional message +function lapp.assert(condn,msg) + if not condn then + lapp.error(msg) + end +end + +local function range_check(x,min,max,parm) + lapp.assert(min <= x and max >= x,parm..' out of range') +end + +local function xtonumber(s) + local val = tonumber(s) + if not val then lapp.error("unable to convert to number: "..s) end + return val +end + +local function is_filetype(type) + return type == 'file-in' or type == 'file-out' +end + +local types + +local function convert_parameter(ps,val) + if ps.converter then + val = ps.converter(val) + end + if ps.type == 'number' then + val = xtonumber(val) + elseif is_filetype(ps.type) then + val = lapp.open(val,(ps.type == 'file-in' and 'r') or 'w' ) + elseif ps.type == 'boolean' then + val = true + end + if ps.constraint then + ps.constraint(val) + end + return val +end + +--- add a new type to Lapp. These appear in parens after the value like +-- a range constraint, e.g. ' (integer) Process PID' +-- @param name name of type +-- @param converter either a function to convert values, or a Lua type name. +-- @param constraint optional function to verify values, should use lapp.error +-- if failed. +function lapp.add_type (name,converter,constraint) + types[name] = {converter=converter,constraint=constraint} +end + +local function force_short(short) + lapp.assert(#short==1,short..": short parameters should be one character") +end + +local function process_default (sval) + local val = tonumber(sval) + if val then -- we have a number! + return val,'number' + elseif filetypes[sval] then + local ft = filetypes[sval] + return ft[1],ft[2] + else + if sval:match '^["\']' then sval = sval:sub(2,-2) end + return sval,'string' + end +end + +--- process a Lapp options string. +-- Usually called as lapp(). +-- @param str the options text +-- @return a table with parameter-value pairs +function lapp.process_options_string(str) + local results = {} + local opts = {at_start=true} + local varargs + open_files = {} + parms = {} + aliases = {} + parmlist = {} + types = {} + + local function check_varargs(s) + local res,cnt = s:gsub('^%.%.%.%s*','') + return res, (cnt > 0) + end + + local function set_result(ps,parm,val) + if not ps.varargs then + results[parm] = val + else + if not results[parm] then + results[parm] = { val } + else + append(results[parm],val) + end + end + end + + usage = str + + for line in lines(str) do + local res = {} + local optspec,optparm,i1,i2,defval,vtype,constraint,rest + line = lstrip(line) + local function check(str) + return match(str,line,res) + end + + -- flags: either '-', '-,--' or '--' + if check '-$v{short}, --$v{long} $' or check '-$v{short} $' or check '--$v{long} $' then + if res.long then + optparm = res.long + if res.short then aliases[res.short] = optparm end + else + optparm = res.short + end + if res.short then force_short(res.short) end + res.rest, varargs = check_varargs(res.rest) + elseif check '$<{name} $' then -- is it ? + -- so becomes input_file ... + optparm,rest = res.name:match '([^%.]+)(.*)' + optparm = optparm:gsub('%A','_') + varargs = rest == '...' + append(parmlist,optparm) + end + if res.rest then -- this is not a pure doc line + line = res.rest + res = {} + -- do we have (default ) or ()? + if match('$({def} $',line,res) or match('$({def}',line,res) then + local typespec = strip(res.def) + if match('default $',typespec,res) then + defval,vtype = process_default(res[1]) + elseif match('$f{min}..$f{max}',typespec,res) then + local min,max = res.min,res.max + vtype = 'number' + constraint = function(x) + range_check(x,min,max,optparm) + end + else -- () just contains type of required parameter + vtype = typespec + end + else -- must be a plain flag, no extra parameter required + defval = false + vtype = 'boolean' + end + local ps = { + type = vtype, + defval = defval, + required = defval == nil, + comment = res.rest or optparm, + constraint = constraint, + varargs = varargs + } + varargs = nil + if types[vtype] then + local converter = types[vtype].converter + if type(converter) == 'string' then + ps.type = converter + else + ps.converter = converter + end + ps.constraint = types[vtype].constraint + end + parms[optparm] = ps + end + end + -- cool, we have our parms, let's parse the command line args + local iparm = 1 + local iextra = 1 + local i = 1 + local parm,ps,val + + while i <= #arg do + local theArg = arg[i] + local res = {} + -- look for a flag, - or -- + if match('--$v{long}',theArg,res) or match('-$v{short}',theArg,res) then + if res.long then -- long option + parm = res.long + elseif #res.short == 1 then + parm = res.short + else + local parmstr = res.short + parm = at(parmstr,1) + if isdigit(at(parmstr,2)) then + -- a short option followed by a digit is an exception (for AW;)) + -- push ahead into the arg array + tinsert(arg,i+1,parmstr:sub(2)) + else + -- push multiple flags into the arg array! + for k = 2,#parmstr do + tinsert(arg,i+k-1,'-'..at(parmstr,k)) + end + end + end + if parm == 'h' or parm == 'help' then + lapp.quit() + end + if aliases[parm] then parm = aliases[parm] end + else -- a parameter + parm = parmlist[iparm] + if not parm then + -- extra unnamed parameters are indexed starting at 1 + parm = iextra + ps = { type = 'string' } + parms[parm] = ps + iextra = iextra + 1 + else + ps = parms[parm] + end + if not ps.varargs then + iparm = iparm + 1 + end + val = theArg + end + ps = parms[parm] + if not ps then lapp.error("unrecognized parameter: "..parm) end + if ps.type ~= 'boolean' then -- we need a value! This should follow + if not val then + i = i + 1 + val = arg[i] + end + lapp.assert(val,parm.." was expecting a value") + end + ps.used = true + val = convert_parameter(ps,val) + set_result(ps,parm,val) + if is_filetype(ps.type) then + set_result(ps,parm..'_name',theArg) + end + if lapp.callback then + lapp.callback(parm,theArg,res) + end + i = i + 1 + val = nil + end + -- check unused parms, set defaults and check if any required parameters were missed + for parm,ps in pairs(parms) do + if not ps.used then + if ps.required then lapp.error("missing required parameter: "..parm) end + set_result(ps,parm,ps.defval) + end + end + return results +end + +if arg then + script = arg[0]:gsub('.+[\\/]',''):gsub('%.%a+$','') +else + script = "inter" +end + + +setmetatable(lapp, { + __call = function(tbl,str) return lapp.process_options_string(str) end, +}) + + +return lapp + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/lexer.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/lexer.lua new file mode 100644 index 000000000..5b9fa0c80 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/lexer.lua @@ -0,0 +1,461 @@ +--- Lexical scanner for creating a sequence of tokens from text.
    +--

    lexer.scan(s) returns an iterator over all tokens found in the +-- string s. This iterator returns two values, a token type string +-- (such as 'string' for quoted string, 'iden' for identifier) and the value of the +-- token. +--

    +-- Versions specialized for Lua and C are available; these also handle block comments +-- and classify keywords as 'keyword' tokens. For example: +--

    +-- > s = 'for i=1,n do'
    +-- > for t,v in lexer.lua(s)  do print(t,v) end
    +-- keyword for
    +-- iden    i
    +-- =       =
    +-- number  1
    +-- ,       ,
    +-- iden    n
    +-- keyword do
    +-- 
    +-- See the Guide for further discussion
    +-- @class module +-- @name pl.lexer + +local yield,wrap = coroutine.yield,coroutine.wrap +local strfind = string.find +local strsub = string.sub +local append = table.insert +--[[ +module ('pl.lexer',utils._module) +]] + +local function assert_arg(idx,val,tp) + if type(val) ~= tp then + error("argument "..idx.." must be "..tp, 2) + end +end + +local lexer = {} + +local NUMBER1 = '^[%+%-]?%d+%.?%d*[eE][%+%-]?%d+' +local NUMBER2 = '^[%+%-]?%d+%.?%d*' +local NUMBER3 = '^0x[%da-fA-F]+' +local NUMBER4 = '^%d+%.?%d*[eE][%+%-]?%d+' +local NUMBER5 = '^%d+%.?%d*' +local IDEN = '^[%a_][%w_]*' +local WSPACE = '^%s+' +local STRING1 = [[^'.-[^\\]']] +local STRING2 = [[^".-[^\\]"]] +local STRING3 = "^((['\"])%2)" -- empty string +local PREPRO = '^#.-[^\\]\n' + +local plain_matches,lua_matches,cpp_matches,lua_keyword,cpp_keyword + +local function tdump(tok) + return yield(tok,tok) +end + +local function ndump(tok,options) + if options and options.number then + tok = tonumber(tok) + end + return yield("number",tok) +end + +-- regular strings, single or double quotes; usually we want them +-- without the quotes +local function sdump(tok,options) + if options and options.string then + tok = tok:sub(2,-2) + end + return yield("string",tok) +end + +-- long Lua strings need extra work to get rid of the quotes +local function sdump_l(tok,options) + if options and options.string then + tok = tok:sub(3,-3) + end + return yield("string",tok) +end + +local function chdump(tok,options) + if options and options.string then + tok = tok:sub(2,-2) + end + return yield("char",tok) +end + +local function cdump(tok) + return yield('comment',tok) +end + +local function wsdump (tok) + return yield("space",tok) +end + +local function pdump (tok) + return yield('prepro',tok) +end + +local function plain_vdump(tok) + return yield("iden",tok) +end + +local function lua_vdump(tok) + if lua_keyword[tok] then + return yield("keyword",tok) + else + return yield("iden",tok) + end +end + +local function cpp_vdump(tok) + if cpp_keyword[tok] then + return yield("keyword",tok) + else + return yield("iden",tok) + end +end + +--- create a plain token iterator from a string or file-like object. +-- @param s the string +-- @param matches an optional match table (set of pattern-action pairs) +-- @param filter a table of token types to exclude, by default {space=true} +-- @param options a table of options; by default, {number=true,string=true}, +-- which means convert numbers and strip string quotes. +function lexer.scan (s,matches,filter,options) + --assert_arg(1,s,'string') + local file = type(s) ~= 'string' and s + filter = filter or {space=true} + options = options or {number=true,string=true} + if filter then + if filter.space then filter[wsdump] = true end + if filter.comments then + filter[cdump] = true + end + end + if not matches then + if not plain_matches then + plain_matches = { + {WSPACE,wsdump}, + {NUMBER3,ndump}, + {IDEN,plain_vdump}, + {NUMBER1,ndump}, + {NUMBER2,ndump}, + {STRING3,sdump}, + {STRING1,sdump}, + {STRING2,sdump}, + {'^.',tdump} + } + end + matches = plain_matches + end + local function lex () + local i1,i2,idx,res1,res2,tok,pat,fun,capt + local line = 1 + if file then s = file:read()..'\n' end + local sz = #s + local idx = 1 + --print('sz',sz) + while true do + for _,m in ipairs(matches) do + pat = m[1] + fun = m[2] + i1,i2 = strfind(s,pat,idx) + if i1 then + tok = strsub(s,i1,i2) + idx = i2 + 1 + if not (filter and filter[fun]) then + lexer.finished = idx > sz + res1,res2 = fun(tok,options) + end + if res1 then + local tp = type(res1) + -- insert a token list + if tp=='table' then + yield('','') + for _,t in ipairs(res1) do + yield(t[1],t[2]) + end + elseif tp == 'string' then -- or search up to some special pattern + i1,i2 = strfind(s,res1,idx) + if i1 then + tok = strsub(s,i1,i2) + idx = i2 + 1 + yield('',tok) + else + yield('','') + idx = sz + 1 + end + --if idx > sz then return end + else + yield(line,idx) + end + end + if idx > sz then + if file then + --repeat -- next non-empty line + line = line + 1 + s = file:read() + if not s then return end + --until not s:match '^%s*$' + s = s .. '\n' + idx ,sz = 1,#s + break + else + return + end + else break end + end + end + end + end + return wrap(lex) +end + +local function isstring (s) + return type(s) == 'string' +end + +--- insert tokens into a stream. +-- @param tok a token stream +-- @param a1 a string is the type, a table is a token list and +-- a function is assumed to be a token-like iterator (returns type & value) +-- @param a2 a string is the value +function lexer.insert (tok,a1,a2) + if not a1 then return end + local ts + if isstring(a1) and isstring(a2) then + ts = {{a1,a2}} + elseif type(a1) == 'function' then + ts = {} + for t,v in a1() do + append(ts,{t,v}) + end + else + ts = a1 + end + tok(ts) +end + +--- get everything in a stream upto a newline. +-- @param tok a token stream +-- @return a string +function lexer.getline (tok) + local t,v = tok('.-\n') + return v +end + +--- get current line number.
    +-- Only available if the input source is a file-like object. +-- @param tok a token stream +-- @return the line number and current column +function lexer.lineno (tok) + return tok(0) +end + +--- get the rest of the stream. +-- @param tok a token stream +-- @return a string +function lexer.getrest (tok) + local t,v = tok('.+') + return v +end + +--- get the Lua keywords as a set-like table. +-- So res["and"] etc would be true. +-- @return a table +function lexer.get_keywords () + if not lua_keyword then + lua_keyword = { + ["and"] = true, ["break"] = true, ["do"] = true, + ["else"] = true, ["elseif"] = true, ["end"] = true, + ["false"] = true, ["for"] = true, ["function"] = true, + ["if"] = true, ["in"] = true, ["local"] = true, ["nil"] = true, + ["not"] = true, ["or"] = true, ["repeat"] = true, + ["return"] = true, ["then"] = true, ["true"] = true, + ["until"] = true, ["while"] = true + } + end + return lua_keyword +end + + +--- create a Lua token iterator from a string or file-like object. +-- Will return the token type and value. +-- @param s the string +-- @param filter a table of token types to exclude, by default {space=true,comments=true} +-- @param options a table of options; by default, {number=true,string=true}, +-- which means convert numbers and strip string quotes. +function lexer.lua(s,filter,options) + filter = filter or {space=true,comments=true} + lexer.get_keywords() + if not lua_matches then + lua_matches = { + {WSPACE,wsdump}, + {NUMBER3,ndump}, + {IDEN,lua_vdump}, + {NUMBER4,ndump}, + {NUMBER5,ndump}, + {STRING3,sdump}, + {STRING1,sdump}, + {STRING2,sdump}, + {'^%-%-%[%[.-%]%]',cdump}, + {'^%-%-.-\n',cdump}, + {'^%[%[.-%]%]',sdump_l}, + {'^==',tdump}, + {'^~=',tdump}, + {'^<=',tdump}, + {'^>=',tdump}, + {'^%.%.%.',tdump}, + {'^%.%.',tdump}, + {'^.',tdump} + } + end + return lexer.scan(s,lua_matches,filter,options) +end + +--- create a C/C++ token iterator from a string or file-like object. +-- Will return the token type type and value. +-- @param s the string +-- @param filter a table of token types to exclude, by default {space=true,comments=true} +-- @param options a table of options; by default, {number=true,string=true}, +-- which means convert numbers and strip string quotes. +function lexer.cpp(s,filter,options) + filter = filter or {comments=true} + if not cpp_keyword then + cpp_keyword = { + ["class"] = true, ["break"] = true, ["do"] = true, ["sizeof"] = true, + ["else"] = true, ["continue"] = true, ["struct"] = true, + ["false"] = true, ["for"] = true, ["public"] = true, ["void"] = true, + ["private"] = true, ["protected"] = true, ["goto"] = true, + ["if"] = true, ["static"] = true, ["const"] = true, ["typedef"] = true, + ["enum"] = true, ["char"] = true, ["int"] = true, ["bool"] = true, + ["long"] = true, ["float"] = true, ["true"] = true, ["delete"] = true, + ["double"] = true, ["while"] = true, ["new"] = true, + ["namespace"] = true, ["try"] = true, ["catch"] = true, + ["switch"] = true, ["case"] = true, ["extern"] = true, + ["return"] = true,["default"] = true,['unsigned'] = true,['signed'] = true, + ["union"] = true, ["volatile"] = true, ["register"] = true,["short"] = true, + } + end + if not cpp_matches then + cpp_matches = { + {WSPACE,wsdump}, + {PREPRO,pdump}, + {NUMBER3,ndump}, + {IDEN,cpp_vdump}, + {NUMBER4,ndump}, + {NUMBER5,ndump}, + {STRING3,sdump}, + {STRING1,chdump}, + {STRING2,sdump}, + {'^//.-\n',cdump}, + {'^/%*.-%*/',cdump}, + {'^==',tdump}, + {'^!=',tdump}, + {'^<=',tdump}, + {'^>=',tdump}, + {'^->',tdump}, + {'^&&',tdump}, + {'^||',tdump}, + {'^%+%+',tdump}, + {'^%-%-',tdump}, + {'^%+=',tdump}, + {'^%-=',tdump}, + {'^%*=',tdump}, + {'^/=',tdump}, + {'^|=',tdump}, + {'^%^=',tdump}, + {'^::',tdump}, + {'^.',tdump} + } + end + return lexer.scan(s,cpp_matches,filter,options) +end + +--- get a list of parameters separated by a delimiter from a stream. +-- @param tok the token stream +-- @param endtoken end of list (default ')'). Can be '\n' +-- @param delim separator (default ',') +-- @return a list of token lists. +function lexer.get_separated_list(tok,endtoken,delim) + endtoken = endtoken or ')' + delim = delim or ',' + local parm_values = {} + local level = 1 -- used to count ( and ) + local tl = {} + local function tappend (tl,t,val) + val = val or t + append(tl,{t,val}) + end + local is_end + if endtoken == '\n' then + is_end = function(t,val) + return t == 'space' and val:find '\n' + end + else + is_end = function (t) + return t == endtoken + end + end + local token,value + while true do + token,value=tok() + if not token then return nil,'EOS' end -- end of stream is an error! + if is_end(token,value) and level == 1 then + append(parm_values,tl) + break + elseif token == '(' then + level = level + 1 + tappend(tl,'(') + elseif token == ')' then + level = level - 1 + if level == 0 then -- finished with parm list + append(parm_values,tl) + break + else + tappend(tl,')') + end + elseif token == delim and level == 1 then + append(parm_values,tl) -- a new parm + tl = {} + else + tappend(tl,token,value) + end + end + return parm_values,{token,value} +end + +--- get the next non-space token from the stream. +-- @param tok the token stream. +function lexer.skipws (tok) + local t,v = tok() + while t == 'space' do + t,v = tok() + end + return t,v +end + +local skipws = lexer.skipws + +--- get the next token, which must be of the expected type. +-- Throws an error if this type does not match! +-- @param tok the token stream +-- @param expected_type the token type +-- @param no_skip_ws whether we should skip whitespace +function lexer.expecting (tok,expected_type,no_skip_ws) + assert_arg(1,tok,'function') + assert_arg(2,expected_type,'string') + local t,v + if no_skip_ws then + t,v = tok() + else + t,v = skipws(tok) + end + if t ~= expected_type then error ("expecting "..expected_type,2) end + return v +end + +return lexer diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/luabalanced.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/luabalanced.lua new file mode 100644 index 000000000..bb2377836 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/luabalanced.lua @@ -0,0 +1,264 @@ +--- Extract delimited Lua sequences from strings. +-- Inspired by Damian Conway's Text::Balanced in Perl.
    +--
      +--
    • [1] Lua Wiki Page
    • +--
    • [2] http://search.cpan.org/dist/Text-Balanced/lib/Text/Balanced.pm
    • +--

    +--
    +-- local lb = require "pl.luabalanced"
    +-- --Extract Lua expression starting at position 4.
    +--  print(lb.match_expression("if x^2 + x > 5 then print(x) end", 4))
    +--  --> x^2 + x > 5     16
    +-- --Extract Lua string starting at (default) position 1.
    +-- print(lb.match_string([["test\"123" .. "more"]]))
    +-- --> "test\"123"     12
    +-- 
    +-- (c) 2008, David Manura, Licensed under the same terms as Lua (MIT license). +-- @class module +-- @name pl.luabalanced + +local M = {} + +local assert = assert +local table_concat = table.concat + +-- map opening brace <-> closing brace. +local ends = { ['('] = ')', ['{'] = '}', ['['] = ']' } +local begins = {}; for k,v in pairs(ends) do begins[v] = k end + + +-- Match Lua string in string starting at position . +-- Returns , , where is the matched +-- string (or nil on no match) and is the character +-- following the match (or on no match). +-- Supports all Lua string syntax: "...", '...', [[...]], [=[...]=], etc. +local function match_string(s, pos) + pos = pos or 1 + local posa = pos + local c = s:sub(pos,pos) + if c == '"' or c == "'" then + pos = pos + 1 + while 1 do + pos = assert(s:find("[" .. c .. "\\]", pos), 'syntax error') + if s:sub(pos,pos) == c then + local part = s:sub(posa, pos) + return part, pos + 1 + else + pos = pos + 2 + end + end + else + local sc = s:match("^%[(=*)%[", pos) + if sc then + local _; _, pos = s:find("%]" .. sc .. "%]", pos) + assert(pos) + local part = s:sub(posa, pos) + return part, pos + 1 + else + return nil, pos + end + end +end +M.match_string = match_string + + +-- Match bracketed Lua expression, e.g. "(...)", "{...}", "[...]", "[[...]]", +-- [=[...]=], etc. +-- Function interface is similar to match_string. +local function match_bracketed(s, pos) + pos = pos or 1 + local posa = pos + local ca = s:sub(pos,pos) + if not ends[ca] then + return nil, pos + end + local stack = {} + while 1 do + pos = s:find('[%(%{%[%)%}%]\"\']', pos) + assert(pos, 'syntax error: unbalanced') + local c = s:sub(pos,pos) + if c == '"' or c == "'" then + local part; part, pos = match_string(s, pos) + assert(part) + elseif ends[c] then -- open + local mid, posb + if c == '[' then mid, posb = s:match('^%[(=*)%[()', pos) end + if mid then + pos = s:match('%]' .. mid .. '%]()', posb) + assert(pos, 'syntax error: long string not terminated') + if #stack == 0 then + local part = s:sub(posa, pos-1) + return part, pos + end + else + stack[#stack+1] = c + pos = pos + 1 + end + else -- close + assert(stack[#stack] == assert(begins[c]), 'syntax error: unbalanced') + stack[#stack] = nil + if #stack == 0 then + local part = s:sub(posa, pos) + return part, pos+1 + end + pos = pos + 1 + end + end +end +M.match_bracketed = match_bracketed + + +-- Match Lua comment, e.g. "--...\n", "--[[...]]", "--[=[...]=]", etc. +-- Function interface is similar to match_string. +local function match_comment(s, pos) + pos = pos or 1 + if s:sub(pos, pos+1) ~= '--' then + return nil, pos + end + pos = pos + 2 + local partt, post = match_string(s, pos) + if partt then + return '--' .. partt, post + end + local part; part, pos = s:match('^([^\n]*\n?)()', pos) + return '--' .. part, pos +end + + +-- Match Lua expression, e.g. "a + b * c[e]". +-- Function interface is similar to match_string. +local wordop = {['and']=true, ['or']=true, ['not']=true} +local is_compare = {['>']=true, ['<']=true, ['~']=true} +local function match_expression(s, pos) + pos = pos or 1 + local posa = pos + local lastident + local poscs, posce + while pos do + local c = s:sub(pos,pos) + if c == '"' or c == "'" or c == '[' and s:find('^[=%[]', pos+1) then + local part; part, pos = match_string(s, pos) + assert(part, 'syntax error') + elseif c == '-' and s:sub(pos+1,pos+1) == '-' then + -- note: handle adjacent comments in loop to properly support + -- backtracing (poscs/posce). + poscs = pos + while s:sub(pos,pos+1) == '--' do + local part; part, pos = match_comment(s, pos) + assert(part) + pos = s:match('^%s*()', pos) + posce = pos + end + elseif c == '(' or c == '{' or c == '[' then + local part; part, pos = match_bracketed(s, pos) + elseif c == '=' and s:sub(pos+1,pos+1) == '=' then + pos = pos + 2 -- skip over two-char op containing '=' + elseif c == '=' and is_compare[s:sub(pos-1,pos-1)] then + pos = pos + 1 -- skip over two-char op containing '=' + elseif c:match'^[%)%}%];,=]' then + local part = s:sub(posa, pos-1) + return part, pos + elseif c:match'^[%w_]' then + local newident,newpos = s:match('^([%w_]+)()', pos) + if pos ~= posa and not wordop[newident] then -- non-first ident + local pose = ((posce == pos) and poscs or pos) - 1 + while s:match('^%s', pose) do pose = pose - 1 end + local ce = s:sub(pose,pose) + if ce:match'[%)%}\'\"%]]' or + ce:match'[%w_]' and not wordop[lastident] + then + local part = s:sub(posa, pos-1) + return part, pos + end + end + lastident, pos = newident, newpos + else + pos = pos + 1 + end + pos = s:find('[%(%{%[%)%}%]\"\';,=%w_%-]', pos) + end + local part = s:sub(posa, #s) + return part, #s+1 +end +M.match_expression = match_expression + + +-- Match name list (zero or more names). E.g. "a,b,c" +-- Function interface is similar to match_string, +-- but returns array as match. +local function match_namelist(s, pos) + pos = pos or 1 + local list = {} + while 1 do + local c = #list == 0 and '^' or '^%s*,%s*' + local item, post = s:match(c .. '([%a_][%w_]*)%s*()', pos) + if item then pos = post else break end + list[#list+1] = item + end + return list, pos +end +M.match_namelist = match_namelist + + +-- Match expression list (zero or more expressions). E.g. "a+b,b*c". +-- Function interface is similar to match_string, +-- but returns array as match. +local function match_explist(s, pos) + pos = pos or 1 + local list = {} + while 1 do + if #list ~= 0 then + local post = s:match('^%s*,%s*()', pos) + if post then pos = post else break end + end + local item; item, pos = match_expression(s, pos) + assert(item, 'syntax error') + list[#list+1] = item + end + return list, pos +end +M.match_explist = match_explist + + +-- Replace snippets of code in Lua code string +-- using replacement function f(u,sin) --> sout. +-- is the type of snippet ('c' = comment, 's' = string, +-- 'e' = any other code). +-- Snippet is replaced with (unless is nil or false, in +-- which case the original snippet is kept) +-- This is somewhat analogous to string.gsub . +local function gsub(s, f) + local pos = 1 + local posa = 1 + local sret = '' + while 1 do + pos = s:find('[%-\'\"%[]', pos) + if not pos then break end + if s:match('^%-%-', pos) then + local exp = s:sub(posa, pos-1) + if #exp > 0 then sret = sret .. (f('e', exp) or exp) end + local comment; comment, pos = match_comment(s, pos) + sret = sret .. (f('c', assert(comment)) or comment) + posa = pos + else + local posb = s:find('^[\'\"%[]', pos) + local str + if posb then str, pos = match_string(s, posb) end + if str then + local exp = s:sub(posa, posb-1) + if #exp > 0 then sret = sret .. (f('e', exp) or exp) end + sret = sret .. (f('s', str) or str) + posa = pos + else + pos = pos + 1 + end + end + end + local exp = s:sub(posa) + if #exp > 0 then sret = sret .. (f('e', exp) or exp) end + return sret +end +M.gsub = gsub + + +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/operator.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/operator.lua new file mode 100644 index 000000000..48c8a10b4 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/operator.lua @@ -0,0 +1,197 @@ +--- Lua operators available as functions. +-- (similar to the Python module of the same name)
    +-- There is a module field optable which maps the operator strings +-- onto these functions, e.g.
    operator.optable['()']==operator.call
    +--

    Operator strings like '>' and '{}' can be passed to most Penlight functions +-- expecting a function argument.

    +-- @class module +-- @name pl.operator + +local strfind = string.find +local utils = require 'pl.utils' + +local operator = {} + +--- apply function to some arguments () +-- @param fn a function or callable object +-- @param ... arguments +function operator.call(fn,...) + return fn(...) +end + +--- get the indexed value from a table [] +-- @param t a table or any indexable object +-- @param k the key +function operator.index(t,k) + return t[k] +end + +--- returns true if arguments are equal == +-- @param a value +-- @param b value +function operator.eq(a,b) + return a==b +end + +--- returns true if arguments are not equal ~= + -- @param a value +-- @param b value +function operator.neq(a,b) + return a~=b +end + +--- returns true if a is less than b < +-- @param a value +-- @param b value +function operator.lt(a,b) + return a < b +end + +--- returns true if a is less or equal to b <= +-- @param a value +-- @param b value +function operator.le(a,b) + return a <= b +end + +--- returns true if a is greater than b > +-- @param a value +-- @param b value +function operator.gt(a,b) + return a > b +end + +--- returns true if a is greater or equal to b >= +-- @param a value +-- @param b value +function operator.ge(a,b) + return a >= b +end + +--- returns length of string or table # +-- @param a a string or a table +function operator.len(a) + return #a +end + +--- add two values + +-- @param a value +-- @param b value +function operator.add(a,b) + return a+b +end + +--- subtract b from a - +-- @param a value +-- @param b value +function operator.sub(a,b) + return a-b +end + +--- multiply two values * +-- @param a value +-- @param b value +function operator.mul(a,b) + return a*b +end + +--- divide first value by second / +-- @param a value +-- @param b value +function operator.div(a,b) + return a/b +end + +--- raise first to the power of second ^ +-- @param a value +-- @param b value +function operator.pow(a,b) + return a^b +end + +--- modulo; remainder of a divided by b % +-- @param a value +-- @param b value +function operator.mod(a,b) + return a%b +end + +--- concatenate two values (either strings or __concat defined) .. +-- @param a value +-- @param b value +function operator.concat(a,b) + return a..b +end + +--- return the negative of a value - +-- @param a value +-- @param b value +function operator.unm(a) + return -a +end + +--- false if value evaluates as true not +-- @param a value +function operator.lnot(a) + return not a +end + +--- true if both values evaluate as true and +-- @param a value +-- @param b value +function operator.land(a,b) + return a and b +end + +--- true if either value evaluate as true or +-- @param a value +-- @param b value +function operator.lor(a,b) + return a or b +end + +--- make a table from the arguments {} +-- @param ... non-nil arguments +-- @return a table +function operator.table (...) + return {...} +end + +--- match two strings ~ +-- uses @{string.find} +function operator.match (a,b) + return strfind(a,b)~=nil +end + +--- the null operation. +-- @param ... arguments +-- @return the arguments +function operator.nop (...) + return ... +end + + operator.optable = { + ['+']=operator.add, + ['-']=operator.sub, + ['*']=operator.mul, + ['/']=operator.div, + ['%']=operator.mod, + ['^']=operator.pow, + ['..']=operator.concat, + ['()']=operator.call, + ['[]']=operator.index, + ['<']=operator.lt, + ['<=']=operator.le, + ['>']=operator.gt, + ['>=']=operator.ge, + ['==']=operator.eq, + ['~=']=operator.neq, + ['#']=operator.len, + ['and']=operator.land, + ['or']=operator.lor, + ['{}']=operator.table, + ['~']=operator.match, + ['']=operator.nop, +} + +return operator diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/path.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/path.lua new file mode 100644 index 000000000..9055f3f4b --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/path.lua @@ -0,0 +1,335 @@ +--- Path manipulation and file queries.
    +-- This is modelled after Python's os.path library (11.1) +-- @class module +-- @name pl.path + +-- imports and locals +local _G = _G +local sub = string.sub +local getenv = os.getenv +local tmpnam = os.tmpname +local attributes, currentdir, link_attrib +local package = package +local io = io +local append = table.insert +local ipairs = ipairs +local utils = require 'pl.utils' +local assert_arg,assert_string,raise = utils.assert_arg,utils.assert_string,utils.raise + +--[[ +module ('pl.path',utils._module) +]] + +local path, attrib + +if _G.luajava then + path = require 'pl.platf.luajava' +else + path = {} + + local res,lfs = _G.pcall(_G.require,'lfs') + if res then + attributes = lfs.attributes + currentdir = lfs.currentdir + link_attrib = lfs.symlinkattributes + else + error("pl.path requires LuaFileSystem") + end + + attrib = attributes + path.attrib = attrib + path.link_attrib = link_attrib + path.dir = lfs.dir + path.mkdir = lfs.mkdir + path.rmdir = lfs.rmdir + path.chdir = lfs.chdir + + --- is this a directory? + -- @param P A file path + function path.isdir(P) + if P:match("\\$") then + P = P:sub(1,-2) + end + return attrib(P,'mode') == 'directory' + end + + --- is this a file?. + -- @param P A file path + function path.isfile(P) + return attrib(P,'mode') == 'file' + end + + -- is this a symbolic link? + -- @param P A file path + function path.islink(P) + if link_attrib then + return link_attrib(P,'mode')=='link' + else + return false + end + end + + --- return size of a file. + -- @param P A file path + function path.getsize(P) + return attrib(P,'size') + end + + --- does a path exist?. + -- @param P A file path + -- @return the file path if it exists, nil otherwise + function path.exists(P) + return attrib(P,'mode') ~= nil and P + end + + --- Return the time of last access as the number of seconds since the epoch. + -- @param P A file path + function path.getatime(P) + return attrib(P,'access') + end + + --- Return the time of last modification + -- @param P A file path + function path.getmtime(P) + return attrib(P,'modification') + end + + ---Return the system's ctime. + -- @param P A file path + function path.getctime(P) + return path.attrib(P,'change') + end +end + + +local function at(s,i) + return sub(s,i,i) +end + +path.is_windows = utils.dir_separator == '\\' + +local other_sep +-- !constant sep is the directory separator for this platform. +if path.is_windows then + path.sep = '\\'; other_sep = '/' + path.dirsep = ';' +else + path.sep = '/' + path.dirsep = ':' +end +local sep,dirsep = path.sep,path.dirsep + +--- are we running Windows? +-- @class field +-- @name path.is_windows + +--- path separator for this platform. +-- @class field +-- @name path.sep + +--- separator for PATH for this platform +-- @class field +-- @name path.dirsep + +--- given a path, return the directory part and a file part. +-- if there's no directory part, the first value will be empty +-- @param P A file path +function path.splitpath(P) + assert_string(1,P) + local i = #P + local ch = at(P,i) + while i > 0 and ch ~= sep and ch ~= other_sep do + i = i - 1 + ch = at(P,i) + end + if i == 0 then + return '',P + else + return sub(P,1,i-1), sub(P,i+1) + end +end + +--- return an absolute path. +-- @param P A file path +function path.abspath(P) + assert_string(1,P) + if not currentdir then return P end + P = P:gsub('[\\/]$','') + local pwd = currentdir() + if not path.isabs(P) then + return path.join(pwd,P) + elseif path.is_windows and at(P,2) ~= ':' and at(P,2) ~= '\\' then + return pwd:sub(1,2)..P + else + return P + end +end + +--- given a path, return the root part and the extension part. +-- if there's no extension part, the second value will be empty +-- @param P A file path +function path.splitext(P) + assert_string(1,P) + local i = #P + local ch = at(P,i) + while i > 0 and ch ~= '.' do + if ch == sep or ch == other_sep then + return P,'' + end + i = i - 1 + ch = at(P,i) + end + if i == 0 then + return P,'' + else + return sub(P,1,i-1),sub(P,i) + end +end + +--- return the directory part of a path +-- @param P A file path +function path.dirname(P) + assert_string(1,P) + local p1,p2 = path.splitpath(P) + return p1 +end + +--- return the file part of a path +-- @param P A file path +function path.basename(P) + assert_string(1,P) + local p1,p2 = path.splitpath(P) + return p2 +end + +--- get the extension part of a path. +-- @param P A file path +function path.extension(P) + assert_string(1,P) + local p1,p2 = path.splitext(P) + return p2 +end + +--- is this an absolute path?. +-- @param P A file path +function path.isabs(P) + assert_string(1,P) + if path.is_windows then + return at(P,1) == '/' or at(P,1)=='\\' or at(P,2)==':' + else + return at(P,1) == '/' + end +end + +--- return the P resulting from combining the two paths. +-- if the second is already an absolute path, then it returns it. +-- @param p1 A file path +-- @param p2 A file path +function path.join(p1,p2) + assert_string(1,p1) + assert_string(2,p2) + if path.isabs(p2) then return p2 end + local endc = at(p1,#p1) + if endc ~= path.sep and endc ~= other_sep then + p1 = p1..path.sep + end + return p1..p2 +end + +--- normalize the case of a pathname. On Unix, this returns the path unchanged; +-- for Windows, it converts the path to lowercase, and it also converts forward slashes +-- to backward slashes. +-- @param P A file path +function path.normcase(P) + assert_string(1,P) + if path.is_windows then + return (P:lower():gsub('/','\\')) + else + return P + end +end + +--- normalize a path name. +-- A//B, A/./B and A/foo/../B all become A/B. +-- @param P a file path +function path.normpath (P) + assert_string(1,P) + if path.is_windows then + P = P:gsub('/','\\') + return (P:gsub('[^\\]+\\%.%.\\',''):gsub('\\%.?\\','\\')) + else + return (P:gsub('[^/]+/%.%./',''):gsub('/%.?/','/')) + end +end + + +--- Replace a starting '~' with the user's home directory. +-- In windows, if HOME isn't set, then USERPROFILE is used in preference to +-- HOMEDRIVE HOMEPATH. This is guaranteed to be writeable on all versions of Windows. +-- @param P A file path +function path.expanduser(P) + assert_string(1,P) + if at(P,1) == '~' then + local home = getenv('HOME') + if not home then -- has to be Windows + home = getenv 'USERPROFILE' or (getenv 'HOMEDRIVE' .. getenv 'HOMEPATH') + end + return home..sub(P,2) + else + return P + end +end + + +---Return a suitable full path to a new temporary file name. +-- unlike os.tmpnam(), it always gives you a writeable path (uses %TMP% on Windows) +function path.tmpname () + local res = tmpnam() + if path.is_windows then res = getenv('TMP')..res end + return res +end + +--- return the largest common prefix path of two paths. +-- @param path1 a file path +-- @param path2 a file path +function path.common_prefix (path1,path2) + assert_string(1,path1) + assert_string(2,path2) + -- get them in order! + if #path1 > #path2 then path2,path1 = path1,path2 end + for i = 1,#path1 do + local c1 = at(path1,i) + if c1 ~= at(path2,i) then + local cp = path1:sub(1,i-1) + if at(path1,i-1) ~= sep then + cp = path.dirname(cp) + end + return cp + end + end + if at(path2,#path1+1) ~= sep then path1 = path.dirname(path1) end + return path1 + --return '' +end + + +--- return the full path where a particular Lua module would be found. +-- Both package.path and package.cpath is searched, so the result may +-- either be a Lua file or a shared libarary. +-- @param mod name of the module +-- @return on success: path of module, lua or binary +-- @return on error: nil,error string +function path.package_path(mod) + assert_string(1,mod) + local res + mod = mod:gsub('%.',sep) + res = package.searchpath(mod,package.path) + if res then return res,true end + res = package.searchpath(mod,package.cpath) + if res then return res,false end + return raise 'cannot find module on path' +end + + +---- finis ----- +return path diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/permute.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/permute.lua new file mode 100644 index 000000000..8c2e66fa9 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/permute.lua @@ -0,0 +1,65 @@ +--- Permutation operations. +-- @class module +-- @name pl.permute +local tablex = require 'pl.tablex' +local utils = require 'pl.utils' +local copy = tablex.deepcopy +local append = table.insert +local coroutine = coroutine +local resume = coroutine.resume +local assert_arg = utils.assert_arg + +--[[ +module ('pl.permute',utils._module) +]] + +local permute = {} + +-- PiL, 9.3 + +local permgen +permgen = function (a, n, fn) + if n == 0 then + fn(a) + else + for i=1,n do + -- put i-th element as the last one + a[n], a[i] = a[i], a[n] + + -- generate all permutations of the other elements + permgen(a, n - 1, fn) + + -- restore i-th element + a[n], a[i] = a[i], a[n] + + end + end +end + +--- an iterator over all permutations of the elements of a list. +-- Please note that the same list is returned each time, so do not keep references! +-- @param a list-like table +-- @return an iterator which provides the next permutation as a list +function permute.iter (a) + assert_arg(1,a,'table') + local n = #a + local co = coroutine.create(function () permgen(a, n, coroutine.yield) end) + return function () -- iterator + local code, res = resume(co) + return res + end +end + +--- construct a table containing all the permutations of a list. +-- @param a list-like table +-- @return a table of tables +-- @usage permute.table {1,2,3} --> {{2,3,1},{3,2,1},{3,1,2},{1,3,2},{2,1,3},{1,2,3}} +function permute.table (a) + assert_arg(1,a,'table') + local res = {} + local n = #a + permgen(a,n,function(t) append(res,copy(t)) end) + return res +end + +return permute diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/platf/luajava.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/platf/luajava.lua new file mode 100644 index 000000000..4fb82e619 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/platf/luajava.lua @@ -0,0 +1,101 @@ +-- experimental support for LuaJava +-- +local path = {} + + +path.link_attrib = nil + +local File = luajava.bindClass("java.io.File") +local Array = luajava.bindClass('java.lang.reflect.Array') + +local function file(s) + return luajava.new(File,s) +end + +function path.dir(P) + local ls = file(P):list() + print(ls) + local idx,n = -1,Array:getLength(ls) + return function () + idx = idx + 1 + if idx == n then return nil + else + return Array:get(ls,idx) + end + end +end + +function path.mkdir(P) + return file(P):mkdir() +end + +function path.rmdir(P) + return file(P):delete() +end + +--- is this a directory? +-- @param P A file path +function path.isdir(P) + if P:match("\\$") then + P = P:sub(1,-2) + end + return file(P):isDirectory() +end + +--- is this a file?. +-- @param P A file path +function path.isfile(P) + return file(P):isFile() +end + +-- is this a symbolic link? +-- Direct support for symbolic links is not provided. +-- see http://stackoverflow.com/questions/813710/java-1-6-determine-symbolic-links +-- and the caveats therein. +-- @param P A file path +function path.islink(P) + local f = file(P) + local canon + local parent = f:getParent() + if not parent then + canon = f + else + parent = f.getParentFile():getCanonicalFile() + canon = luajava.new(File,parent,f:getName()) + end + return canon:getCanonicalFile() ~= canon:getAbsoluteFile() +end + +--- return size of a file. +-- @param P A file path +function path.getsize(P) + return file(P):length() +end + +--- does a path exist?. +-- @param P A file path +-- @return the file path if it exists, nil otherwise +function path.exists(P) + return file(P):exists() and P +end + +--- Return the time of last access as the number of seconds since the epoch. +-- @param P A file path +function path.getatime(P) + return path.getmtime(P) +end + +--- Return the time of last modification +-- @param P A file path +function path.getmtime(P) + -- Java time is no. of millisec since the epoch + return file(P):lastModified()/1000 +end + +---Return the system's ctime. +-- @param P A file path +function path.getctime(P) + return path.getmtime(P) +end + +return path diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/pretty.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/pretty.lua new file mode 100644 index 000000000..c414c9d5c --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/pretty.lua @@ -0,0 +1,224 @@ +--- Pretty-printing Lua tables. +-- Also provides a sandboxed Lua table reader and +-- a function to present large numbers in human-friendly format. +-- @class module +-- @name pl.pretty + +local append = table.insert +local concat = table.concat +local utils = require 'pl.utils' +local lexer = require 'pl.lexer' +local assert_arg = utils.assert_arg + +local pretty = {} + +--- read a string representation of a Lua table. +-- Uses load(), but tries to be cautious about loading arbitrary code! +-- It is expecting a string of the form '{...}', with perhaps some whitespace +-- before or after the curly braces. An empty environment is used, and +-- any occurance of the keyword 'function' will be considered a problem. +-- @param s {string} string of the form '{...}', with perhaps some whitespace +-- before or after the curly braces. +function pretty.read(s) + assert_arg(1,s,'string') + if not s:find '^%s*%b{}%s*$' then return nil,"not a Lua table" end + if s:find '[^\'"%w_]function[^\'"%w_]' then + local tok = lexer.lua(s) + for t,v in tok do + if t == 'keyword' then + return nil,"cannot have Lua keywords in table definition" + end + end + end + local chunk,err = utils.load('return '..s,'tbl','t',{}) + if not chunk then return nil,err end + return chunk() +end + +local function quote_if_necessary (v) + if not v then return '' + else + if v:find ' ' then v = '"'..v..'"' end + end + return v +end + +local keywords + + +--- Create a string representation of a Lua table. +-- This function never fails, but may complain by returning an +-- extra value. Normally puts out one item per line, using +-- the provided indent; set the second parameter to '' if +-- you want output on one line. +-- @param tbl {table} Table to serialize to a string. +-- @param space {string} (optional) The indent to use. +-- Defaults to two spaces. +-- @param not_clever {bool} (optional) Use for plain output, e.g {['key']=1}. +-- Defaults to false. +-- @return a string +-- @return a possible error message +function pretty.write (tbl,space,not_clever) + if type(tbl) ~= 'table' then + local res = tostring(tbl) + if type(tbl) == 'string' then res = '"'..res..'"' end + return res, 'not a table' + end + if not keywords then + keywords = lexer.get_keywords() + end + local set = ' = ' + if space == '' then set = '=' end + space = space or ' ' + local lines = {} + local line = '' + local tables = {} + + local function is_identifier (s) + return (s:find('^[%a_][%w_]*$')) and not keywords[s] + end + + local function put(s) + if #s > 0 then + line = line..s + end + end + + local function putln (s) + if #line > 0 then + line = line..s + append(lines,line) + line = '' + else + append(lines,s) + end + end + + local function eat_last_comma () + local n,lastch = #lines + local lastch = lines[n]:sub(-1,-1) + if lastch == ',' then + lines[n] = lines[n]:sub(1,-2) + end + end + + local function quote (s) + return ('%q'):format(tostring(s)) + end + + local function index (numkey,key) + if not numkey then key = quote(key) end + return '['..key..']' + end + + local writeit + writeit = function (t,oldindent,indent) + local tp = type(t) + if tp ~= 'string' and tp ~= 'table' then + putln(quote_if_necessary(tostring(t))..',') + elseif tp == 'string' then + if t:find('\n') then + putln('[[\n'..t..']],') + else + putln(quote(t)..',') + end + elseif tp == 'table' then + if tables[t] then + putln(',') + return + end + tables[t] = true + local newindent = indent..space + putln('{') + local used = {} + if not not_clever then + for i,val in ipairs(t) do + put(indent) + writeit(val,indent,newindent) + used[i] = true + end + end + for key,val in pairs(t) do + local numkey = type(key) == 'number' + if not_clever then + key = tostring(key) + put(indent..index(numkey,key)..set) + writeit(val,indent,newindent) + else + if not numkey or not used[key] then -- non-array indices + if numkey or not is_identifier(key) then + key = index(numkey,key) + end + put(indent..key..set) + writeit(val,indent,newindent) + end + end + end + eat_last_comma() + putln(oldindent..'},') + else + putln(tostring(t)..',') + end + end + writeit(tbl,'',space) + eat_last_comma() + return concat(lines,#space > 0 and '\n' or '') +end + +--- Dump a Lua table out to a file or stdout. +-- @param t {table} The table to write to a file or stdout. +-- @param ... {string} (optional) File name to write too. Defaults to writing +-- to stdout. +function pretty.dump (t,...) + if select('#',...)==0 then + print(pretty.write(t)) + return true + else + return utils.writefile(...,pretty.write(t)) + end +end + +local memp,nump = {'B','KiB','MiB','GiB'},{'','K','M','B'} + +local comma +function comma (val) + local thou = math.floor(val/1000) + if thou > 0 then return comma(thou)..','..(val % 1000) + else return tostring(val) end +end + +--- format large numbers nicely for human consumption. +-- @param num a number +-- @param kind one of 'M' (memory in KiB etc), 'N' (postfixes are 'K','M' and 'B') +-- and 'T' (use commas as thousands separator) +-- @param prec number of digits to use for 'M' and 'N' (default 1) +function pretty.number (num,kind,prec) + local fmt = '%.'..(prec or 1)..'f%s' + if kind == 'T' then + return comma(num) + else + local postfixes, fact + if kind == 'M' then + fact = 1024 + postfixes = memp + else + fact = 1000 + postfixes = nump + end + local div = fact + local k = 1 + while num >= div and k <= #postfixes do + div = div * fact + k = k + 1 + end + div = div / fact + if k > #postfixes then k = k - 1; div = div/fact end + if k > 1 then + return fmt:format(num/div,postfixes[k] or 'duh') + else + return num..postfixes[1] + end + end +end + +return pretty diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/seq.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/seq.lua new file mode 100644 index 000000000..479a12a6e --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/seq.lua @@ -0,0 +1,527 @@ +--- Manipulating sequences as iterators. +-- @class module +-- @name pl.seq + +local next,assert,type,pairs,tonumber,type,setmetatable,getmetatable,_G = next,assert,type,pairs,tonumber,type,setmetatable,getmetatable,_G +local strfind = string.find +local strmatch = string.match +local format = string.format +local mrandom = math.random +local remove,tsort,tappend = table.remove,table.sort,table.insert +local io = io +local utils = require 'pl.utils' +local function_arg = utils.function_arg +local _List = utils.stdmt.List +local _Map = utils.stdmt.Map +local assert_arg = utils.assert_arg +require 'debug' + +--[[ +module("pl.seq",utils._module) +]] + +local seq = {} + +-- given a number, return a function(y) which returns true if y > x +-- @param x a number +function seq.greater_than(x) + return function(v) + return tonumber(v) > x + end +end + +-- given a number, returns a function(y) which returns true if y < x +-- @param x a number +function seq.less_than(x) + return function(v) + return tonumber(v) < x + end +end + +-- given any value, return a function(y) which returns true if y == x +-- @param x a value +function seq.equal_to(x) + if type(x) == "number" then + return function(v) + return tonumber(v) == x + end + else + return function(v) + return v == x + end + end +end + +--- given a string, return a function(y) which matches y against the string. +-- @param s a string +function seq.matching(s) + return function(v) + return strfind(v,s) + end +end + +--- sequence adaptor for a table. Note that if any generic function is +-- passed a table, it will automatically use seq.list() +-- @param t a list-like table +-- @usage sum(list(t)) is the sum of all elements of t +-- @usage for x in list(t) do...end +function seq.list(t) + assert_arg(1,t,'table') + local key,value + return function() + key,value = next(t,key) + return value + end +end + +--- return the keys of the table. +-- @param t a list-like table +-- @return iterator over keys +function seq.keys(t) + assert_arg(1,t,'table') + local key,value + return function() + key,value = next(t,key) + return key + end +end + +local list = seq.list +local function default_iter(iter) + if type(iter) == 'table' then return list(iter) + else return iter end +end + +seq.iter = default_iter + +--- create an iterator over a numerical range. Like the standard Python function xrange. +-- @param start a number +-- @param finish a number greater than start +function seq.range(start,finish) + local i = start - 1 + return function() + i = i + 1 + if i > finish then return nil + else return i end + end +end + +-- count the number of elements in the sequence which satisfy the predicate +-- @param iter a sequence +-- @param condn a predicate function (must return either true or false) +-- @param optional argument to be passed to predicate as second argument. +function seq.count(iter,condn,arg) + local i = 0 + seq.foreach(iter,function(val) + if condn(val,arg) then i = i + 1 end + end) + return i +end + +--- return the minimum and the maximum value of the sequence. +-- @param iter a sequence +function seq.minmax(iter) + local vmin,vmax = 1e70,-1e70 + for v in default_iter(iter) do + v = tonumber(v) + if v < vmin then vmin = v end + if v > vmax then vmax = v end + end + return vmin,vmax +end + +--- return the sum and element count of the sequence. +-- @param iter a sequence +-- @param fn an optional function to apply to the values +function seq.sum(iter,fn) + local s = 0 + local i = 0 + for v in default_iter(iter) do + if fn then v = fn(v) end + s = s + v + i = i + 1 + end + return s,i +end + +--- create a table from the sequence. (This will make the result a List.) +-- @param iter a sequence +-- @return a List +-- @usage copy(list(ls)) is equal to ls +-- @usage copy(list {1,2,3}) == List{1,2,3} +function seq.copy(iter) + local res = {} + for v in default_iter(iter) do + tappend(res,v) + end + setmetatable(res,_List) + return res +end + +--- create a table of pairs from the double-valued sequence. +-- @param iter a double-valued sequence +-- @param i1 used to capture extra iterator values +-- @param i2 as with pairs & ipairs +-- @usage copy2(ipairs{10,20,30}) == {{1,10},{2,20},{3,30}} +-- @return a list-like table +function seq.copy2 (iter,i1,i2) + local res = {} + for v1,v2 in iter,i1,i2 do + tappend(res,{v1,v2}) + end + return res +end + +--- create a table of 'tuples' from a multi-valued sequence. +-- A generalization of copy2 above +-- @param iter a multiple-valued sequence +-- @return a list-like table +function seq.copy_tuples (iter) + iter = default_iter(iter) + local res = {} + local row = {iter()} + while #row > 0 do + tappend(res,row) + row = {iter()} + end + return res +end + +--- return an iterator of random numbers. +-- @param n the length of the sequence +-- @param l same as the first optional argument to math.random +-- @param u same as the second optional argument to math.random +-- @return a sequnce +function seq.random(n,l,u) + local rand + assert(type(n) == 'number') + if u then + rand = function() return mrandom(l,u) end + elseif l then + rand = function() return mrandom(l) end + else + rand = mrandom + end + + return function() + if n == 0 then return nil + else + n = n - 1 + return rand() + end + end +end + +--- return an iterator to the sorted elements of a sequence. +-- @param iter a sequence +-- @param comp an optional comparison function (comp(x,y) is true if x < y) +function seq.sort(iter,comp) + local t = seq.copy(iter) + tsort(t,comp) + return list(t) +end + +--- return an iterator which returns elements of two sequences. +-- @param iter1 a sequence +-- @param iter2 a sequence +-- @usage for x,y in seq.zip(ls1,ls2) do....end +function seq.zip(iter1,iter2) + iter1 = default_iter(iter1) + iter2 = default_iter(iter2) + return function() + return iter1(),iter2() + end +end + +--- A table where the key/values are the values and value counts of the sequence. +-- This version works with 'hashable' values like strings and numbers.
    +-- pl.tablex.count_map is more general. +-- @param iter a sequence +-- @return a map-like table +-- @return a table +-- @see pl.tablex.count_map +function seq.count_map(iter) + local t = {} + local v + for s in default_iter(iter) do + v = t[s] + if v then t[s] = v + 1 + else t[s] = 1 end + end + return setmetatable(t,_Map) +end + +-- given a sequence, return all the unique values in that sequence. +-- @param iter a sequence +-- @param returns_table true if we return a table, not a sequence +-- @return a sequence or a table; defaults to a sequence. +function seq.unique(iter,returns_table) + local t = seq.count_map(iter) + local res = {} + for k in pairs(t) do tappend(res,k) end + table.sort(res) + if returns_table then + return res + else + return list(res) + end +end + +-- print out a sequence @iter, with a separator @sep (default space) +-- and maximum number of values per line @nfields (default 7) +-- @fmt is an optional format function to create a representation of each value. +function seq.printall(iter,sep,nfields,fmt) + local write = io.write + if not sep then sep = ' ' end + if not nfields then + if sep == '\n' then nfields = 1e30 + else nfields = 7 end + end + if fmt then + local fstr = fmt + fmt = function(v) return format(fstr,v) end + end + local k = 1 + for v in default_iter(iter) do + if fmt then v = fmt(v) end + if k < nfields then + write(v,sep) + k = k + 1 + else + write(v,'\n') + k = 1 + end + end + write '\n' +end + +-- return an iterator running over every element of two sequences (concatenation). +-- @param iter1 a sequence +-- @param iter2 a sequence +function seq.splice(iter1,iter2) + iter1 = default_iter(iter1) + iter2 = default_iter(iter2) + local iter = iter1 + return function() + local ret = iter() + if ret == nil then + if iter == iter1 then + iter = iter2 + return iter() + else return nil end + else + return ret + end + end +end + +--- return a sequence where every element of a sequence has been transformed +-- by a function. If you don't supply an argument, then the function will +-- receive both values of a double-valued sequence, otherwise behaves rather like +-- tablex.map. +-- @param fn a function to apply to elements; may take two arguments +-- @param iter a sequence of one or two values +-- @param arg optional argument to pass to function. +function seq.map(fn,iter,arg) + fn = function_arg(1,fn) + iter = default_iter(iter) + return function() + local v1,v2 = iter() + if v1 == nil then return nil end + if arg then return fn(v1,arg) or false + else return fn(v1,v2) or false + end + end +end + +--- filter a sequence using a predicate function +-- @param iter a sequence of one or two values +-- @param pred a boolean function; may take two arguments +-- @param arg optional argument to pass to function. +function seq.filter (iter,pred,arg) + pred = function_arg(2,pred) + return function () + local v1,v2 + while true do + v1,v2 = iter() + if v1 == nil then return nil end + if arg then + if pred(v1,arg) then return v1,v2 end + else + if pred(v1,v2) then return v1,v2 end + end + end + end +end + +--- 'reduce' a sequence using a binary function. +-- @param fun a function of two arguments +-- @param iter a sequence +-- @param oldval optional initial value +-- @usage seq.reduce(operator.add,seq.list{1,2,3,4}) == 10 +-- @usage seq.reduce('-',{1,2,3,4,5}) == -13 +function seq.reduce (fun,iter,oldval) + fun = function_arg(1,fun) + iter = default_iter(iter) + if not oldval then + oldval = iter() + end + local val = oldval + for v in iter do + val = fun(val,v) + end + return val +end + +--- take the first n values from the sequence. +-- @param iter a sequence of one or two values +-- @param n number of items to take +-- @return a sequence of at most n items +function seq.take (iter,n) + local i = 1 + iter = default_iter(iter) + return function() + if i > n then return end + local val1,val2 = iter() + if not val1 then return end + i = i + 1 + return val1,val2 + end +end + +--- skip the first n values of a sequence +-- @param iter a sequence of one or more values +-- @param n number of items to skip +function seq.skip (iter,n) + n = n or 1 + for i = 1,n do iter() end + return iter +end + +--- a sequence with a sequence count and the original value.
    +-- enum(copy(ls)) is a roundabout way of saying ipairs(ls). +-- @param iter a single or double valued sequence +-- @return sequence of (i,v), i = 1..n and v is from iter. +function seq.enum (iter) + local i = 0 + iter = default_iter(iter) + return function () + local val1,val2 = iter() + if not val1 then return end + i = i + 1 + return i,val1,val2 + end +end + +--- map using a named method over a sequence. +-- @param iter a sequence +-- @param name the method name +-- @param arg1 optional first extra argument +-- @param arg2 optional second extra argument +function seq.mapmethod (iter,name,arg1,arg2) + iter = default_iter(iter) + return function() + local val = iter() + if not val then return end + local fn = val[name] + if not fn then error(type(val).." does not have method "..name) end + return fn(val,arg1,arg2) + end +end + +--- a sequence of (last,current) values from another sequence. +-- This will return S(i-1),S(i) if given S(i) +-- @param iter a sequence +function seq.last (iter) + iter = default_iter(iter) + local l = iter() + if l == nil then return nil end + return function () + local val,ll + val = iter() + if val == nil then return nil end + ll = l + l = val + return val,ll + end +end + +--- call the function on each element of the sequence. +-- @param iter a sequence with up to 3 values +-- @param fn a function +function seq.foreach(iter,fn) + fn = function_arg(2,fn) + for i1,i2,i3 in default_iter(iter) do fn(i1,i2,i3) end +end + +---------------------- Sequence Adapters --------------------- + +local SMT +local callable = utils.is_callable + +local function SW (iter,...) + if callable(iter) then + return setmetatable({iter=iter},SMT) + else + return iter,... + end +end + + +-- can't directly look these up in seq because of the wrong argument order... +local map,reduce,mapmethod = seq.map, seq.reduce, seq.mapmethod +local overrides = { + map = function(self,fun,arg) + return map(fun,self,arg) + end, + reduce = function(self,fun) + return reduce(fun,self) + end +} + +SMT = { + __index = function (tbl,key) + local s = overrides[key] or seq[key] + if s then + return function(sw,...) return SW(s(sw.iter,...)) end + else + return function(sw,...) return SW(mapmethod(sw.iter,key,...)) end + end + end, + __call = function (sw) + return sw.iter() + end, +} + +setmetatable(seq,{ + __call = function(tbl,iter) + if not callable(iter) then + if type(iter) == 'table' then iter = seq.list(iter) + else return iter + end + end + return setmetatable({iter=iter},SMT) + end +}) + +--- create a wrapped iterator over all lines in the file. +-- @param f either a filename or nil (for standard input) +-- @return a sequence wrapper +function seq.lines (f) + local iter = f and io.lines(f) or io.lines() + return SW(iter) +end + +function seq.import () + _G.debug.setmetatable(function() end,{ + __index = function(tbl,key) + local s = overrides[key] or seq[key] + if s then return s + else + return function(s,...) return seq.mapmethod(s,key,...) end + end + end + }) +end + +return seq diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/sip.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/sip.lua new file mode 100644 index 000000000..c739a54ca --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/sip.lua @@ -0,0 +1,335 @@ +--- Simple Input Patterns (SIP).

    +-- SIP patterns start with '$', then a +-- one-letter type, and then an optional variable in curly braces.

    +-- Example: +--

    +--  sip.match('$v=$q','name="dolly"',res)
    +--  ==> res=={'name','dolly'}
    +--  sip.match('($q{first},$q{second})','("john","smith")',res)
    +--  ==> res=={second='smith',first='john'}
    +-- 
    +--
    +-- Type names
    +-- v    identifier
    +-- i     integer
    +-- f     floating-point
    +-- q    quoted string
    +-- ([{<  match up to closing bracket
    +-- 
    +--

    +-- See the Guide +-- @class module +-- @name pl.sip + +local append,concat = table.insert,table.concat +local concat = table.concat +local ipairs,loadstring,type,unpack = ipairs,loadstring,type,unpack +local io,_G = io,_G +local print,rawget = print,rawget + +local patterns = { + FLOAT = '[%+%-%d]%d*%.?%d*[eE]?[%+%-]?%d*', + INTEGER = '[+%-%d]%d*', + IDEN = '[%a_][%w_]*', + FILE = '[%a%.\\][:%][%w%._%-\\]*' +} + +local function assert_arg(idx,val,tp) + if type(val) ~= tp then + error("argument "..idx.." must be "..tp, 2) + end +end + + +--[[ +module ('pl.sip',utils._module) +]] + +local sip = {} + +local brackets = {['<'] = '>', ['('] = ')', ['{'] = '}', ['['] = ']' } +local stdclasses = {a=1,c=0,d=1,l=1,p=0,u=1,w=1,x=1,s=0} + +local _patterns = {} + + +local function group(s) + return '('..s..')' +end + +-- escape all magic characters except $, which has special meaning +-- Also, un-escape any characters after $, so $( passes through as is. +local function escape (spec) + --_G.print('spec',spec) + local res = spec:gsub('[%-%.%+%[%]%(%)%^%%%?%*]','%%%1'):gsub('%$%%(%S)','$%1') + --_G.print('res',res) + return res +end + +local function imcompressible (s) + return s:gsub('%s+','\001') +end + +-- [handling of spaces in patterns] +-- spaces may be 'compressed' (i.e will match zero or more spaces) +-- unless this occurs within a number or an identifier. So we mark +-- the four possible imcompressible patterns first and then replace. +-- The possible alnum patterns are v,f,a,d,x,l and u. +local function compress_spaces (s) + s = s:gsub('%$[vifadxlu]%s+%$[vfadxlu]',imcompressible) + s = s:gsub('[%w_]%s+[%w_]',imcompressible) + s = s:gsub('[%w_]%s+%$[vfadxlu]',imcompressible) + s = s:gsub('%$[vfadxlu]%s+[%w_]',imcompressible) + s = s:gsub('%s+','%%s*') + s = s:gsub('\001',' ') + return s +end + +--- convert a SIP pattern into the equivalent Lua string pattern. +-- @param spec a SIP pattern +-- @param options a table; only the at_start field is +-- currently meaningful and esures that the pattern is anchored +-- at the start of the string. +-- @return a Lua string pattern. +function sip.create_pattern (spec,options) + assert_arg(1,spec,'string') + local fieldnames,fieldtypes = {},{} + + if type(spec) == 'string' then + spec = escape(spec) + else + local res = {} + for i,s in ipairs(spec) do + res[i] = escape(s) + end + spec = concat(res,'.-') + end + + local kount = 1 + + local function addfield (name,type) + if not name then name = kount end + if fieldnames then append(fieldnames,name) end + if fieldtypes then fieldtypes[name] = type end + kount = kount + 1 + end + + local named_vars, pattern + named_vars = spec:find('{%a+}') + pattern = '%$%S' + + if options and options.at_start then + spec = '^'..spec + end + if spec:sub(-1,-1) == '$' then + spec = spec:sub(1,-2)..'$r' + if named_vars then spec = spec..'{rest}' end + end + + + local names + + if named_vars then + names = {} + spec = spec:gsub('{(%a+)}',function(name) + append(names,name) + return '' + end) + end + spec = compress_spaces(spec) + + local k = 1 + local err + local r = (spec:gsub(pattern,function(s) + local type,name + type = s:sub(2,2) + if names then name = names[k]; k=k+1 end + -- this kludge is necessary because %q generates two matches, and + -- we want to ignore the first. Not a problem for named captures. + if not names and type == 'q' then + addfield(nil,'Q') + else + addfield(name,type) + end + local res + if type == 'v' then + res = group(patterns.IDEN) + elseif type == 'i' then + res = group(patterns.INTEGER) + elseif type == 'f' then + res = group(patterns.FLOAT) + elseif type == 'r' then + res = '(%S.*)' + elseif type == 'q' then + -- some Lua pattern matching voodoo; we want to match '...' as + -- well as "...", and can use the fact that %n will match a + -- previous capture. Adding the extra field above comes from needing + -- to accomodate the extra spurious match (which is either ' or ") + addfield(name,type) + res = '(["\'])(.-)%'..(kount-2) + elseif type == 'p' then + res = '([%a]?[:]?[\\/%.%w_]+)' + else + local endbracket = brackets[type] + if endbracket then + res = '(%b'..type..endbracket..')' + elseif stdclasses[type] or stdclasses[type:lower()] then + res = '(%'..type..'+)' + else + err = "unknown format type or character class" + end + end + return res + end)) + --print(r,err) + if err then + return nil,err + else + return r,fieldnames,fieldtypes + end +end + + +local function tnumber (s) + return s == 'd' or s == 'i' or s == 'f' +end + +function sip.create_spec_fun(spec,options) + local fieldtypes,fieldnames + local ls = {} + spec,fieldnames,fieldtypes = sip.create_pattern(spec,options) + if not spec then return spec,fieldnames end + local named_vars = type(fieldnames[1]) == 'string' + for i = 1,#fieldnames do + append(ls,'mm'..i) + end + local fun = ('return (function(s,res)\n\tlocal %s = s:match(%q)\n'):format(concat(ls,','),spec) + fun = fun..'\tif not mm1 then return false end\n' + local k=1 + for i,f in ipairs(fieldnames) do + if f ~= '_' then + local var = 'mm'..i + if tnumber(fieldtypes[f]) then + var = 'tonumber('..var..')' + elseif brackets[fieldtypes[f]] then + var = var..':sub(2,-2)' + end + if named_vars then + fun = ('%s\tres.%s = %s\n'):format(fun,f,var) + else + if fieldtypes[f] ~= 'Q' then -- we skip the string-delim capture + fun = ('%s\tres[%d] = %s\n'):format(fun,k,var) + k = k + 1 + end + end + end + end + return fun..'\treturn true\nend)\n', named_vars +end + +--- convert a SIP pattern into a matching function. +-- The returned function takes two arguments, the line and an empty table. +-- If the line matched the pattern, then this function return true +-- and the table is filled with field-value pairs. +-- @param spec a SIP pattern +-- @param options optional table; {anywhere=true} will stop pattern anchoring at start +-- @return a function if successful, or nil, +function sip.compile(spec,options) + assert_arg(1,spec,'string') + local fun,names = sip.create_spec_fun(spec,options) + if not fun then return nil,names end + if rawget(_G,'_DEBUG') then print(fun) end + local chunk,err = loadstring(fun,'tmp') + if err then return nil,err end + return chunk(),names +end + +local cache = {} + +--- match a SIP pattern against a string. +-- @param spec a SIP pattern +-- @param line a string +-- @param res a table to receive values +-- @param options (optional) option table +-- @return true or false +function sip.match (spec,line,res,options) + assert_arg(1,spec,'string') + assert_arg(2,line,'string') + assert_arg(3,res,'table') + if not cache[spec] then + cache[spec] = sip.compile(spec,options) + end + return cache[spec](line,res) +end + +--- match a SIP pattern against the start of a string. +-- @param spec a SIP pattern +-- @param line a string +-- @param res a table to receive values +-- @return true or false +function sip.match_at_start (spec,line,res) + return sip.match(spec,line,res,{at_start=true}) +end + +--- given a pattern and a file object, return an iterator over the results +-- @param spec a SIP pattern +-- @param f a file - use standard input if not specified. +function sip.fields (spec,f) + assert_arg(1,spec,'string') + f = f or io.stdin + local fun,err = sip.compile(spec) + if not fun then return nil,err end + local res = {} + return function() + while true do + local line = f:read() + if not line then return end + if fun(line,res) then + local values = res + res = {} + return unpack(values) + end + end + end +end + +--- register a match which will be used in the read function. +-- @param spec a SIP pattern +-- @param fun a function to be called with the results of the match +-- @see read +function sip.pattern (spec,fun) + assert_arg(1,spec,'string') + local pat,named = sip.compile(spec) + append(_patterns,{pat=pat,named=named,callback=fun or false}) +end + +--- enter a loop which applies all registered matches to the input file. +-- @param f a file object; if nil, then io.stdin is assumed. +function sip.read (f) + local owned,err + f = f or io.stdin + if type(f) == 'string' then + f,err = io.open(f) + if not f then return nil,err end + owned = true + end + local res = {} + for line in f:lines() do + for _,item in ipairs(_patterns) do + if item.pat(line,res) then + if item.callback then + if item.named then + item.callback(res) + else + item.callback(unpack(res)) + end + end + res = {} + break + end + end + end + if owned then f:close() end +end + +return sip diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/strict.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/strict.lua new file mode 100644 index 000000000..f7d8c94c8 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/strict.lua @@ -0,0 +1,71 @@ +--- 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. +-- @class module +-- @name pl.strict + +require 'debug' +local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget +local handler,hooked + +local mt = getmetatable(_G) +if mt == nil then + mt = {} + setmetatable(_G, mt) +elseif mt.hook then + hooked = true +end + +-- predeclaring _PROMPT keeps the Lua Interpreter happy +mt.__declared = {_PROMPT=true} + +local function what () + local d = getinfo(3, "S") + return d and d.what or "C" +end + +mt.__newindex = function (t, n, v) + if not mt.__declared[n] then + local w = what() + if w ~= "main" and w ~= "C" then + error("assign to undeclared variable '"..n.."'", 2) + end + mt.__declared[n] = true + end + rawset(t, n, v) +end + +handler = function(t,n) + if not mt.__declared[n] and what() ~= "C" then + error("variable '"..n.."' is not declared", 2) + end + return rawget(t, n) +end + +function package.strict (mod) + local mt = getmetatable(mod) + if mt == nil then + mt = {} + setmetatable(mod, mt) + end + mt.__declared = {} + mt.__newindex = function(t, n, v) + mt.__declared[n] = true + rawset(t, n, v) + end + mt.__index = function(t,n) + if not mt.__declared[n] then + error("variable '"..n.."' is not declared", 2) + end + return rawget(t, n) + end +end + +if not hooked then + mt.__index = handler +else + mt.hook(handler) +end + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/stringio.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/stringio.lua new file mode 100644 index 000000000..0129ddd56 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/stringio.lua @@ -0,0 +1,144 @@ +--- Reading and writing strings using file-like objects.
    +--

    +--  f = stringio.open(text)
    +--  l1 = f:read()  -- read first line
    +--  n,m = f:read ('*n','*n') -- read two numbers
    +--  for line in f:lines() do print(line) end -- iterate over all lines
    +--  f = stringio.create()
    +--  f:write('hello')
    +--  f:write('dolly')
    +--  assert(f:value(),'hellodolly')
    +-- 
    +-- See the Guide. +-- @class module +-- @name pl.stringio + +local getmetatable,tostring,unpack,tonumber = getmetatable,tostring,unpack,tonumber +local concat,append = table.concat,table.insert + +local stringio = {} + +--- Writer class +local SW = {} +SW.__index = SW + +local function xwrite(self,...) + local args = {...} --arguments may not be nil! + for i = 1, #args do + append(self.tbl,args[i]) + end +end + +function SW:write(arg1,arg2,...) + if arg2 then + xwrite(self,arg1,arg2,...) + else + append(self.tbl,arg1) + end +end + +function SW:writef(fmt,...) + self:write(fmt:format(...)) +end + +function SW:value() + return concat(self.tbl) +end + +function SW:close() -- for compatibility only +end + +function SW:seek() +end + +--- Reader class +local SR = {} +SR.__index = SR + +function SR:_read(fmt) + local i,str = self.i,self.str + local sz = #str + if i >= sz then return nil end + local res + if fmt == nil or fmt == '*l' then + local idx = str:find('\n',i) or (sz+1) + res = str:sub(i,idx-1) + self.i = idx+1 + elseif fmt == '*a' then + res = str:sub(i) + self.i = sz + elseif fmt == '*n' then + local _,i2,i2,idx + _,idx = str:find ('%s*%d+',i) + _,i2 = str:find ('%.%d+',idx+1) + if i2 then idx = i2 end + _,i2 = str:find ('[eE][%+%-]*%d+',idx+1) + if i2 then idx = i2 end + local val = str:sub(i,idx) + res = tonumber(val) + self.i = idx+1 + elseif type(fmt) == 'number' then + res = str:sub(i,i+fmt-1) + self.i = i + fmt + else + error("bad read format",2) + end + return res +end + +function SR:read(...) + local fmts = {...} + if #fmts <= 1 then + return self:_read(fmts[1]) + else + local res = {} + for i = 1, #fmts do + res[i] = self:_read(fmts[i]) + end + return unpack(res) + end +end + +function SR:seek(whence,offset) + local base + whence = whence or 'cur' + offset = offset or 0 + if whence == 'set' then + base = 1 + elseif whence == 'cur' then + base = self.i + elseif whence == 'end' then + base = #self.str + end + self.i = base + offset + return self.i +end + +function SR:lines() + return function() + return self:read() + end +end + +function SR:close() -- for compatibility only +end + +--- create a file-like object which can be used to construct a string. +-- The resulting object has an extra value() method for +-- retrieving the string value. +-- @usage f = create(); f:write('hello, dolly\n'); print(f:value()) +function stringio.create() + return setmetatable({tbl={}},SW) +end + +--- create a file-like object for reading from a given string. +-- @param s The input string. +function stringio.open(s) + return setmetatable({str=s,i=1},SR) +end + +function stringio.lines(s) + return stringio.open(s):lines() +end + +return stringio diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/stringx.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/stringx.lua new file mode 100644 index 000000000..5699b2039 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/stringx.lua @@ -0,0 +1,441 @@ +--- Python-style string library.

    +-- see 3.6.1 of the Python reference.

    +-- If you want to make these available as string methods, then say +-- stringx.import() to bring them into the standard string +-- table. +-- @class module +-- @name pl.stringx +local string = string +local find = string.find +local type,setmetatable,getmetatable,ipairs,unpack = type,setmetatable,getmetatable,ipairs,unpack +local error,tostring = error,tostring +local gsub = string.gsub +local rep = string.rep +local sub = string.sub +local concat = table.concat +local utils = require 'pl.utils' +local escape = utils.escape +local ceil = math.ceil +local _G = _G +local assert_arg,usplit,list_MT = utils.assert_arg,utils.split,utils.stdmt.List +local lstrip + +local function assert_string (n,s) + assert_arg(n,s,'string') +end + +local function non_empty(s) + return #s > 0 +end + +local function assert_nonempty_string(n,s) + assert_arg(n,s,'string',non_empty,'must be a non-empty string') +end + +--[[ +module ('pl.stringx',utils._module) +]] + +local stringx = {} + +--- does s only contain alphabetic characters?. +-- @param s a string +function stringx.isalpha(s) + assert_string(1,s) + return find(s,'^%a+$') == 1 +end + +--- does s only contain digits?. +-- @param s a string +function stringx.isdigit(s) + assert_string(1,s) + return find(s,'^%d+$') == 1 +end + +--- does s only contain alphanumeric characters?. +-- @param s a string +function stringx.isalnum(s) + assert_string(1,s) + return find(s,'^%w+$') == 1 +end + +--- does s only contain spaces?. +-- @param s a string +function stringx.isspace(s) + assert_string(1,s) + return find(s,'^%s+$') == 1 +end + +--- does s only contain lower case characters?. +-- @param s a string +function stringx.islower(s) + assert_string(1,s) + return find(s,'^[%l%s]+$') == 1 +end + +--- does s only contain upper case characters?. +-- @param s a string +function stringx.isupper(s) + assert_string(1,s) + return find(s,'^[%u%s]+$') == 1 +end + +--- concatenate the strings using this string as a delimiter. +-- @param self the string +-- @param seq a table of strings or numbers +-- @usage (' '):join {1,2,3} == '1 2 3' +function stringx.join (self,seq) + assert_string(1,self) + return concat(seq,self) +end + +--- does string start with the substring?. +-- @param self the string +-- @param s2 a string +function stringx.startswith(self,s2) + assert_string(1,self) + assert_string(2,s2) + return find(self,s2,1,true) == 1 +end + +local function _find_all(s,sub,first,last) + if sub == '' then return #s+1,#s end + local i1,i2 = find(s,sub,first,true) + local res + local k = 0 + while i1 do + res = i1 + k = k + 1 + i1,i2 = find(s,sub,i2+1,true) + if last and i1 > last then break end + end + return res,k +end + +--- does string end with the given substring?. +-- @param s a string +-- @param send a substring or a table of suffixes +function stringx.endswith(s,send) + assert_string(1,s) + if type(send) == 'string' then + return #s >= #send and s:find(send, #s-#send+1, true) and true or false + elseif type(send) == 'table' then + local endswith = stringx.endswith + for _,suffix in ipairs(send) do + if endswith(s,suffix) then return true end + end + return false + else + error('argument #2: either a substring or a table of suffixes expected') + end +end + +-- break string into a list of lines +-- @param self the string +-- @param keepends (currently not used) +function stringx.splitlines (self,keepends) + assert_string(1,self) + local res = usplit(self,'[\r\n]') + -- we are currently hacking around a problem with utils.split (see stringx.split) + if #res == 0 then res = {''} end + return setmetatable(res,list_MT) +end + +local function tab_expand (self,n) + return (gsub(self,'([^\t]*)\t', function(s) + return s..(' '):rep(n - #s % n) + end)) +end + +--- replace all tabs in s with n spaces. If not specified, n defaults to 8. +-- with 0.9.5 this now correctly expands to the next tab stop (if you really +-- want to just replace tabs, use :gsub('\t',' ') etc) +-- @param self the string +-- @param n number of spaces to expand each tab, (default 8) +function stringx.expandtabs(self,n) + assert_string(1,self) + n = n or 8 + if not self:find '\n' then return tab_expand(self,n) end + local res,i = {},1 + for line in stringx.lines(self) do + res[i] = tab_expand(line,n) + i = i + 1 + end + return table.concat(res,'\n') +end + +--- find index of first instance of sub in s from the left. +-- @param self the string +-- @param sub substring +-- @param i1 start index +function stringx.lfind(self,sub,i1) + assert_string(1,self) + assert_string(2,sub) + local idx = find(self,sub,i1,true) + if idx then return idx else return nil end +end + +--- find index of first instance of sub in s from the right. +-- @param self the string +-- @param sub substring +-- @param first first index +-- @param last last index +function stringx.rfind(self,sub,first,last) + assert_string(1,self) + assert_string(2,sub) + local idx = _find_all(self,sub,first,last) + if idx then return idx else return nil end +end + +--- replace up to n instances of old by new in the string s. +-- if n is not present, replace all instances. +-- @param s the string +-- @param old the target substring +-- @param new the substitution +-- @param n optional maximum number of substitutions +-- @return result string +-- @return the number of substitutions +function stringx.replace(s,old,new,n) + assert_string(1,s) + assert_string(1,old) + return (gsub(s,escape(old),new:gsub('%%','%%%%'),n)) +end + +--- split a string into a list of strings using a delimiter. +-- @class function +-- @name split +-- @param self the string +-- @param re a delimiter (defaults to whitespace) +-- @param n maximum number of results +-- @usage #(('one two'):split()) == 2 +-- @usage ('one,two,three'):split(',') == List{'one','two','three'} +-- @usage ('one,two,three'):split(',',2) == List{'one','two,three'} +function stringx.split(self,re,n) + local s = self + local plain = true + if not re then -- default spaces + s = lstrip(s) + plain = false + end + local res = usplit(s,re,plain,n) + if re and re ~= '' and find(s,re,-#re,true) then + res[#res+1] = "" + end + return setmetatable(res,list_MT) +end + +--- split a string using a pattern. Note that at least one value will be returned! +-- @param self the string +-- @param re a Lua string pattern (defaults to whitespace) +-- @return the parts of the string +-- @usage a,b = line:splitv('=') +function stringx.splitv (self,re) + assert_string(1,self) + return utils.splitv(self,re) +end + +local function copy(self) + return self..'' +end + +--- count all instances of substring in string. +-- @param self the string +-- @param sub substring +function stringx.count(self,sub) + assert_string(1,self) + local i,k = _find_all(self,sub,1) + return k +end + +local function _just(s,w,ch,left,right) + local n = #s + if w > n then + if not ch then ch = ' ' end + local f1,f2 + if left and right then + local ln = ceil((w-n)/2) + local rn = w - n - ln + f1 = rep(ch,ln) + f2 = rep(ch,rn) + elseif right then + f1 = rep(ch,w-n) + f2 = '' + else + f2 = rep(ch,w-n) + f1 = '' + end + return f1..s..f2 + else + return copy(s) + end +end + +--- left-justify s with width w. +-- @param self the string +-- @param w width of justification +-- @param ch padding character, default ' ' +function stringx.ljust(self,w,ch) + assert_string(1,self) + assert_arg(2,w,'number') + return _just(self,w,ch,true,false) +end + +--- right-justify s with width w. +-- @param s the string +-- @param w width of justification +-- @param ch padding character, default ' ' +function stringx.rjust(s,w,ch) + assert_string(1,s) + assert_arg(2,w,'number') + return _just(s,w,ch,false,true) +end + +--- center-justify s with width w. +-- @param s the string +-- @param w width of justification +-- @param ch padding character, default ' ' +function stringx.center(s,w,ch) + assert_string(1,s) + assert_arg(2,w,'number') + return _just(s,w,ch,true,true) +end + +local function _strip(s,left,right,chrs) + if not chrs then + chrs = '%s' + else + chrs = '['..escape(chrs)..']' + end + if left then + local i1,i2 = find(s,'^'..chrs..'*') + if i2 >= i1 then + s = sub(s,i2+1) + end + end + if right then + local i1,i2 = find(s,chrs..'*$') + if i2 >= i1 then + s = sub(s,1,i1-1) + end + end + return s +end + +--- trim any whitespace on the left of s. +-- @param self the string +-- @param chrs default space, can be a string of characters to be trimmed +function stringx.lstrip(self,chrs) + assert_string(1,self) + return _strip(self,true,false,chrs) +end +lstrip = stringx.lstrip + +--- trim any whitespace on the right of s. +-- @param s the string +-- @param chrs default space, can be a string of characters to be trimmed +function stringx.rstrip(s,chrs) + assert_string(1,s) + return _strip(s,false,true,chrs) +end + +--- trim any whitespace on both left and right of s. +-- @param self the string +-- @param chrs default space, can be a string of characters to be trimmed +function stringx.strip(self,chrs) + assert_string(1,self) + return _strip(self,true,true,chrs) +end + +-- The partition functions split a string using a delimiter into three parts: +-- the part before, the delimiter itself, and the part afterwards +local function _partition(p,delim,fn) + local i1,i2 = fn(p,delim) + if not i1 or i1 == -1 then + return p,'','' + else + if not i2 then i2 = i1 end + return sub(p,1,i1-1),sub(p,i1,i2),sub(p,i2+1) + end +end + +--- partition the string using first occurance of a delimiter +-- @param self the string +-- @param ch delimiter +-- @return part before ch +-- @return ch +-- @return part after ch +function stringx.partition(self,ch) + assert_string(1,self) + assert_nonempty_string(2,ch) + return _partition(self,ch,stringx.lfind) +end + +--- partition the string p using last occurance of a delimiter +-- @param self the string +-- @param ch delimiter +-- @return part before ch +-- @return ch +-- @return part after ch +function stringx.rpartition(self,ch) + assert_string(1,self) + assert_nonempty_string(2,ch) + return _partition(self,ch,stringx.rfind) +end + +--- return the 'character' at the index. +-- @param self the string +-- @param idx an index (can be negative) +-- @return a substring of length 1 if successful, empty string otherwise. +function stringx.at(self,idx) + assert_string(1,self) + assert_arg(2,idx,'number') + return sub(self,idx,idx) +end + +--- return an interator over all lines in a string +-- @param self the string +-- @return an iterator +function stringx.lines (self) + assert_string(1,self) + local s = self + if not s:find '\n$' then s = s..'\n' end + return s:gmatch('([^\n]*)\n') +end + +--- iniital word letters uppercase ('title case'). +-- Here 'words' mean chunks of non-space characters. +-- @param self the string +-- @return a string with each word's first letter uppercase +function stringx.title(self) + return (self:gsub('(%S)(%S*)',function(f,r) + return f:upper()..r:lower() + end)) +end + +stringx.capitalize = stringx.title + +local elipsis = '...' +local n_elipsis = #elipsis + +--- return a shorted version of a string. +-- @param self the string +-- @param sz the maxinum size allowed +-- @param tail true if we want to show the end of the string (head otherwise) +function stringx.shorten(self,sz,tail) + if #self > sz then + if sz < n_elipsis then return elipsis:sub(1,sz) end + if tail then + local i = #self - sz + 1 + n_elipsis + return elipsis .. self:sub(i) + else + return self:sub(1,sz-n_elipsis) .. elipsis + end + end + return self +end + +function stringx.import(dont_overload) + utils.import(stringx,string) +end + +return stringx diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/tablex.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/tablex.lua new file mode 100644 index 000000000..bfddb4b70 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/tablex.lua @@ -0,0 +1,766 @@ +--- Extended operations on Lua tables. +-- @class module +-- @name pl.tablex +local getmetatable,setmetatable,require = getmetatable,setmetatable,require +local append,remove = table.insert,table.remove +local min,max = math.min,math.max +local pairs,type,unpack,next,ipairs,select,tostring = pairs,type,unpack,next,ipairs,select,tostring +local utils = require ('pl.utils') +local function_arg = utils.function_arg +local Set = utils.stdmt.Set +local List = utils.stdmt.List +local Map = utils.stdmt.Map +local assert_arg = utils.assert_arg + +--[[ +module ('pl.tablex',utils._module) +]] + +local tablex = {} + +-- generally, functions that make copies of tables try to preserve the metatable. +-- However, when the source has no obvious type, then we attach appropriate metatables +-- like List, Map, etc to the result. +local function setmeta (res,tbl,def) + return setmetatable(res,getmetatable(tbl) or def) +end + +local function makelist (res) + return setmetatable(res,List) +end + +--- copy a table into another, in-place. +-- @param t1 destination table +-- @param t2 source table +-- @return first table +function tablex.update (t1,t2) + assert_arg(1,t1,'table') + assert_arg(2,t2,'table') + for k,v in pairs(t2) do + t1[k] = v + end + return t1 +end + +--- total number of elements in this table.
    +-- Note that this is distinct from #t, which is the number +-- of values in the array part; this value will always +-- be greater or equal. The difference gives the size of +-- the hash part, for practical purposes. +-- @param t a table +-- @return the size +function tablex.size (t) + assert_arg(1,t,'table') + local i = 0 + for k in pairs(t) do i = i + 1 end + return i +end + +--- make a shallow copy of a table +-- @param t source table +-- @return new table +function tablex.copy (t) + assert_arg(1,t,'table') + local res = {} + for k,v in pairs(t) do + res[k] = v + end + return res +end + +--- make a deep copy of a table, recursively copying all the keys and fields. +-- This will also set the copied table's metatable to that of the original. +-- @param t A table +-- @return new table +function tablex.deepcopy(t) + assert_arg(1,t,'table') + if type(t) ~= 'table' then return t end + local mt = getmetatable(t) + local res = {} + for k,v in pairs(t) do + if type(v) == 'table' then + v = tablex.deepcopy(v) + end + res[k] = v + end + setmetatable(res,mt) + return res +end + +local abs = math.abs + +--- compare two values. +-- if they are tables, then compare their keys and fields recursively. +-- @param t1 A value +-- @param t2 A value +-- @param ignore_mt if true, ignore __eq metamethod (default false) +-- @param eps if defined, then used for any number comparisons +-- @return true or false +function tablex.deepcompare(t1,t2,ignore_mt,eps) + local ty1 = type(t1) + local ty2 = type(t2) + if ty1 ~= ty2 then return false end + -- non-table types can be directly compared + if ty1 ~= 'table' then + if ty1 == 'number' and eps then return abs(t1-t2) < eps end + return t1 == t2 + end + -- as well as tables which have the metamethod __eq + local mt = getmetatable(t1) + if not ignore_mt and mt and mt.__eq then return t1 == t2 end + for k1,v1 in pairs(t1) do + local v2 = t2[k1] + if v2 == nil or not tablex.deepcompare(v1,v2,ignore_mt,eps) then return false end + end + for k2,v2 in pairs(t2) do + local v1 = t1[k2] + if v1 == nil or not tablex.deepcompare(v1,v2,ignore_mt,eps) then return false end + end + return true +end + +--- compare two list-like tables using a predicate. +-- @param t1 a table +-- @param t2 a table +-- @param cmp A comparison function +function tablex.compare (t1,t2,cmp) + assert_arg(1,t1,'table') + assert_arg(2,t2,'table') + if #t1 ~= #t2 then return false end + cmp = function_arg(3,cmp) + for k in ipairs(t1) do + if not cmp(t1[k],t2[k]) then return false end + end + return true +end + +--- compare two list-like tables using an optional predicate, without regard for element order. +-- @param t1 a list-like table +-- @param t2 a list-like table +-- @param cmp A comparison function (may be nil) +function tablex.compare_no_order (t1,t2,cmp) + assert_arg(1,t1,'table') + assert_arg(2,t2,'table') + if cmp then cmp = function_arg(3,cmp) end + if #t1 ~= #t2 then return false end + local visited = {} + for i = 1,#t1 do + local val = t1[i] + local gotcha + for j = 1,#t2 do if not visited[j] then + local match + if cmp then match = cmp(val,t2[j]) else match = val == t2[j] end + if match then + gotcha = j + break + end + end end + if not gotcha then return false end + visited[gotcha] = true + end + return true +end + + +--- return the index of a value in a list. +-- Like string.find, there is an optional index to start searching, +-- which can be negative. +-- @param t A list-like table (i.e. with numerical indices) +-- @param val A value +-- @param idx index to start; -1 means last element,etc (default 1) +-- @return index of value or nil if not found +-- @usage find({10,20,30},20) == 2 +-- @usage find({'a','b','a','c'},'a',2) == 3 + +function tablex.find(t,val,idx) + assert_arg(1,t,'table') + idx = idx or 1 + if idx < 0 then idx = #t + idx + 1 end + for i = idx,#t do + if t[i] == val then return i end + end + return nil +end + +--- return the index of a value in a list, searching from the end. +-- Like string.find, there is an optional index to start searching, +-- which can be negative. +-- @param t A list-like table (i.e. with numerical indices) +-- @param val A value +-- @param idx index to start; -1 means last element,etc (default 1) +-- @return index of value or nil if not found +-- @usage rfind({10,10,10},10) == 3 +function tablex.rfind(t,val,idx) + assert_arg(1,t,'table') + idx = idx or #t + if idx < 0 then idx = #t + idx + 1 end + for i = idx,1,-1 do + if t[i] == val then return i end + end + return nil +end + + +--- return the index (or key) of a value in a table using a comparison function. +-- @param t A table +-- @param cmp A comparison function +-- @param arg an optional second argument to the function +-- @return index of value, or nil if not found +-- @return value returned by comparison function +function tablex.find_if(t,cmp,arg) + assert_arg(1,t,'table') + cmp = function_arg(2,cmp) + for k,v in pairs(t) do + local c = cmp(v,arg) + if c then return k,c end + end + return nil +end + +--- return a list of all values in a table indexed by another list. +-- @param tbl a table +-- @param idx an index table (a list of keys) +-- @return a list-like table +-- @usage index_by({10,20,30,40},{2,4}) == {20,40} +-- @usage index_by({one=1,two=2,three=3},{'one','three'}) == {1,3} +function tablex.index_by(tbl,idx) + assert_arg(1,tbl,'table') + assert_arg(2,idx,'table') + local res = {} + for _,i in ipairs(idx) do + append(res,tbl[i]) + end + return setmeta(res,tbl,List) +end + +--- apply a function to all values of a table. +-- This returns a table of the results. +-- Any extra arguments are passed to the function. +-- @param fun A function that takes at least one argument +-- @param t A table +-- @param ... optional arguments +-- @usage map(function(v) return v*v end, {10,20,30,fred=2}) is {100,400,900,fred=4} +function tablex.map(fun,t,...) + assert_arg(1,t,'table') + fun = function_arg(1,fun) + local res = {} + for k,v in pairs(t) do + res[k] = fun(v,...) + end + return setmeta(res,t) +end + +--- apply a function to all values of a list. +-- This returns a table of the results. +-- Any extra arguments are passed to the function. +-- @param fun A function that takes at least one argument +-- @param t a table (applies to array part) +-- @param ... optional arguments +-- @return a list-like table +-- @usage imap(function(v) return v*v end, {10,20,30,fred=2}) is {100,400,900} +function tablex.imap(fun,t,...) + assert_arg(1,t,'table') + fun = function_arg(1,fun) + local res = {} + for i = 1,#t do + res[i] = fun(t[i],...) or false + end + return setmeta(res,t,List) +end + +--- apply a named method to values from a table. +-- @param name the method name +-- @param t a list-like table +-- @param ... any extra arguments to the method +function tablex.map_named_method (name,t,...) + assert_arg(1,name,'string') + assert_arg(2,t,'table') + local res = {} + for i = 1,#t do + local val = t[i] + local fun = val[name] + res[i] = fun(val,...) + end + return setmeta(res,t,List) +end + + +--- apply a function to all values of a table, in-place. +-- Any extra arguments are passed to the function. +-- @param fun A function that takes at least one argument +-- @param t a table +-- @param ... extra arguments +function tablex.transform (fun,t,...) + assert_arg(1,t,'table') + fun = function_arg(1,fun) + for k,v in pairs(t) do + t[v] = fun(v,...) + end +end + +--- generate a table of all numbers in a range +-- @param start number +-- @param finish number +-- @param step optional increment (default 1 for increasing, -1 for decreasing) +function tablex.range (start,finish,step) + local res = {} + local k = 1 + if not step then + if finish > start then step = finish > start and 1 or -1 end + end + for i=start,finish,step do res[k]=i; k=k+1 end + return res +end + +--- apply a function to values from two tables. +-- @param fun a function of at least two arguments +-- @param t1 a table +-- @param t2 a table +-- @param ... extra arguments +-- @return a table +-- @usage map2('+',{1,2,3,m=4},{10,20,30,m=40}) is {11,22,23,m=44} +function tablex.map2 (fun,t1,t2,...) + assert_arg(1,t1,'table') + assert_arg(2,t2,'table') + fun = function_arg(1,fun) + local res = {} + for k,v in pairs(t1) do + res[k] = fun(v,t2[k],...) + end + return setmeta(res,t1,List) +end + +--- apply a function to values from two arrays. +-- @param fun a function of at least two arguments +-- @param t1 a list-like table +-- @param t2 a list-like table +-- @param ... extra arguments +-- @usage imap2('+',{1,2,3,m=4},{10,20,30,m=40}) is {11,22,23} +function tablex.imap2 (fun,t1,t2,...) + assert_arg(2,t1,'table') + assert_arg(3,t2,'table') + fun = function_arg(1,fun) + local res = {} + for i = 1,#t1 do + res[i] = fun(t1[i],t2[i],...) + end + return res +end + +--- 'reduce' a list using a binary function. +-- @param fun a function of two arguments +-- @param t a list-like table +-- @return the result of the function +-- @usage reduce('+',{1,2,3,4}) == 10 +function tablex.reduce (fun,t) + assert_arg(2,t,'table') + fun = function_arg(1,fun) + local n = #t + local res = t[1] + for i = 2,n do + res = fun(res,t[i]) + end + return res +end + +--- apply a function to all elements of a table. +-- The arguments to the function will be the value, +-- the key and finally any extra arguments passed to this function. +-- Note that the Lua 5.0 function table.foreach passed the key first. +-- @param t a table +-- @param fun a function with at least one argument +-- @param ... extra arguments +function tablex.foreach(t,fun,...) + assert_arg(1,t,'table') + fun = function_arg(2,fun) + for k,v in pairs(t) do + fun(v,k,...) + end +end + +--- apply a function to all elements of a list-like table in order. +-- The arguments to the function will be the value, +-- the index and finally any extra arguments passed to this function +-- @param t a table +-- @param fun a function with at least one argument +-- @param ... optional arguments +function tablex.foreachi(t,fun,...) + assert_arg(1,t,'table') + fun = function_arg(2,fun) + for k,v in ipairs(t) do + fun(v,k,...) + end +end + + +--- Apply a function to a number of tables. +-- A more general version of map +-- The result is a table containing the result of applying that function to the +-- ith value of each table. Length of output list is the minimum length of all the lists +-- @param fun a function of n arguments +-- @param ... n tables +-- @usage mapn(function(x,y,z) return x+y+z end, {1,2,3},{10,20,30},{100,200,300}) is {111,222,333} +-- @usage mapn(math.max, {1,20,300},{10,2,3},{100,200,100}) is {100,200,300} +-- @param fun A function that takes as many arguments as there are tables +function tablex.mapn(fun,...) + fun = function_arg(1,fun) + local res = {} + local lists = {...} + local minn = 1e40 + for i = 1,#lists do + minn = min(minn,#(lists[i])) + end + for i = 1,minn do + local args = {} + for j = 1,#lists do + args[#args+1] = lists[j][i] + end + res[#res+1] = fun(unpack(args)) + end + return res +end + +--- call the function with the key and value pairs from a table. +-- The function can return a value and a key (note the order!). If both +-- are not nil, then this pair is inserted into the result. If only value is not nil, then +-- it is appended to the result. +-- @param fun A function which will be passed each key and value as arguments, plus any extra arguments to pairmap. +-- @param t A table +-- @param ... optional arguments +-- @usage pairmap({fred=10,bonzo=20},function(k,v) return v end) is {10,20} +-- @usage pairmap({one=1,two=2},function(k,v) return {k,v},k end) is {one={'one',1},two={'two',2}} +function tablex.pairmap(fun,t,...) + assert_arg(1,t,'table') + fun = function_arg(1,fun) + local res = {} + for k,v in pairs(t) do + local rv,rk = fun(k,v,...) + if rk then + res[rk] = rv + else + res[#res+1] = rv + end + end + return res +end + +local function keys_op(i,v) return i end + +--- return all the keys of a table in arbitrary order. +-- @param t A table +function tablex.keys(t) + assert_arg(1,t,'table') + return makelist(tablex.pairmap(keys_op,t)) +end + +local function values_op(i,v) return v end + +--- return all the values of the table in arbitrary order +-- @param t A table +function tablex.values(t) + assert_arg(1,t,'table') + return makelist(tablex.pairmap(values_op,t)) +end + +local function index_map_op (i,v) return i,v end + +--- create an index map from a list-like table. The original values become keys, +-- and the associated values are the indices into the original list. +-- @param t a list-like table +-- @return a map-like table +function tablex.index_map (t) + assert_arg(1,t,'table') + return setmetatable(tablex.pairmap(index_map_op,t),Map) +end + +local function set_op(i,v) return true,v end + +--- create a set from a list-like table. A set is a table where the original values +-- become keys, and the associated values are all true. +-- @param t a list-like table +-- @return a set (a map-like table) +function tablex.makeset (t) + assert_arg(1,t,'table') + return setmetatable(tablex.pairmap(set_op,t),Set) +end + + +--- combine two tables, either as union or intersection. Corresponds to +-- set operations for sets () but more general. Not particularly +-- useful for list-like tables. +-- @param t1 a table +-- @param t2 a table +-- @param dup true for a union, false for an intersection. +-- @usage merge({alice=23,fred=34},{bob=25,fred=34}) is {fred=34} +-- @usage merge({alice=23,fred=34},{bob=25,fred=34},true) is {bob=25,fred=34,alice=23} +-- @see tablex.index_map +function tablex.merge (t1,t2,dup) + assert_arg(1,t1,'table') + assert_arg(2,t2,'table') + local res = {} + for k,v in pairs(t1) do + if dup or t2[k] then res[k] = v end + end + for k,v in pairs(t2) do + if dup or t1[k] then res[k] = v end + end + return setmeta(res,t1,Map) +end + +--- a new table which is the difference of two tables. +-- With sets (where the values are all true) this is set difference and +-- symmetric difference depending on the third parameter. +-- @param s1 a map-like table or set +-- @param s2 a map-like table or set +-- @param symm symmetric difference (default false) +-- @return a map-like table or set +function tablex.difference (s1,s2,symm) + assert_arg(1,s1,'table') + assert_arg(2,s2,'table') + local res = {} + for k,v in pairs(s1) do + if not s2[k] then res[k] = v end + end + if symm then + for k,v in pairs(s2) do + if not s1[k] then res[k] = v end + end + end + return setmeta(res,s1,Map) +end + +--- A table where the key/values are the values and value counts of the table. +-- @param t a list-like table +-- @param cmp a function that defines equality (otherwise uses ==) +-- @return a map-like table +-- @see seq.count_map +function tablex.count_map (t,cmp) + assert_arg(1,t,'table') + local res,mask = {},{} + cmp = function_arg(2,cmp) + local n = #t + for i,v in ipairs(t) do + if not mask[v] then + mask[v] = true + -- check this value against all other values + res[v] = 1 -- there's at least one instance + for j = i+1,n do + local w = t[j] + if cmp and cmp(v,w) or v == w then + res[v] = res[v] + 1 + mask[w] = true + end + end + end + end + return setmetatable(res,Map) +end + +--- filter a table's values using a predicate function +-- @param t a list-like table +-- @param pred a boolean function +-- @param arg optional argument to be passed as second argument of the predicate +function tablex.filter (t,pred,arg) + assert_arg(1,t,'table') + pred = function_arg(2,pred) + local res = {} + for k,v in ipairs(t) do + if pred(v,arg) then append(res,v) end + end + return setmeta(res,t,List) +end + +--- return a table where each element is a table of the ith values of an arbitrary +-- number of tables. It is equivalent to a matrix transpose. +-- @usage zip({10,20,30},{100,200,300}) is {{10,100},{20,200},{30,300}} +function tablex.zip(...) + return tablex.mapn(function(...) return {...} end,...) +end + +local _copy +function _copy (dest,src,idest,isrc,nsrc,clean_tail) + idest = idest or 1 + isrc = isrc or 1 + local iend + if not nsrc then + nsrc = #src + iend = #src + else + iend = isrc + min(nsrc-1,#src-isrc) + end + if dest == src then -- special case + if idest > isrc and iend >= idest then -- overlapping ranges + src = tablex.sub(src,isrc,nsrc) + isrc = 1; iend = #src + end + end + for i = isrc,iend do + dest[idest] = src[i] + idest = idest + 1 + end + if clean_tail then + tablex.clear(dest,idest) + end + return dest +end + +--- copy an array into another one, resizing the destination if necessary.
    +-- @param dest a list-like table +-- @param src a list-like table +-- @param idest where to start copying values from source (default 1) +-- @param isrc where to start copying values into destination (default 1) +-- @param nsrc number of elements to copy from source (default source size) +function tablex.icopy (dest,src,idest,isrc,nsrc) + assert_arg(1,dest,'table') + assert_arg(2,src,'table') + return _copy(dest,src,idest,isrc,nsrc,true) +end + +--- copy an array into another one.
    +-- @param dest a list-like table +-- @param src a list-like table +-- @param idest where to start copying values from source (default 1) +-- @param isrc where to start copying values into destination (default 1) +-- @param nsrc number of elements to copy from source (default source size) +function tablex.move (dest,src,idest,isrc,nsrc) + assert_arg(1,dest,'table') + assert_arg(2,src,'table') + return _copy(dest,src,idest,isrc,nsrc,false) +end + +function tablex._normalize_slice(self,first,last) + local sz = #self + if not first then first=1 end + if first<0 then first=sz+first+1 end + -- make the range _inclusive_! + if not last then last=sz end + if last < 0 then last=sz+1+last end + return first,last +end + +--- Extract a range from a table, like 'string.sub'. +-- If first or last are negative then they are relative to the end of the list +-- eg. sub(t,-2) gives last 2 entries in a list, and +-- sub(t,-4,-2) gives from -4th to -2nd +-- @param t a list-like table +-- @param first An index +-- @param last An index +-- @return a new List +function tablex.sub(t,first,last) + assert_arg(1,t,'table') + first,last = tablex._normalize_slice(t,first,last) + local res={} + for i=first,last do append(res,t[i]) end + return setmeta(res,t,List) +end + +--- set an array range to a value. If it's a function we use the result +-- of applying it to the indices. +-- @param t a list-like table +-- @param val a value +-- @param i1 start range (default 1) +-- @param i2 end range (default table size) +function tablex.set (t,val,i1,i2) + i1,i2 = i1 or 1,i2 or #t + if utils.is_callable(val) then + for i = i1,i2 do + t[i] = val(i) + end + else + for i = i1,i2 do + t[i] = val + end + end +end + +--- create a new array of specified size with initial value. +-- @param n size +-- @param val initial value (can be nil, but don't expect # to work!) +-- @return the table +function tablex.new (n,val) + local res = {} + tablex.set(res,val,1,n) + return res +end + +--- clear out the contents of a table. +-- @param t a table +-- @param istart optional start position +function tablex.clear(t,istart) + istart = istart or 1 + for i = istart,#t do remove(t) end +end + +--- insert values into a table.
    +-- insertvalues(t, [pos,] values)
    +-- similar to table.insert but inserts values from given table "values", +-- not the object itself, into table "t" at position "pos". +function tablex.insertvalues(t, ...) + local pos, values + if select('#', ...) == 1 then + pos,values = #t+1, ... + else + pos,values = ... + end + if #values > 0 then + for i=#t,pos,-1 do + t[i+#values] = t[i] + end + local offset = 1 - pos + for i=pos,pos+#values-1 do + t[i] = values[i + offset] + end + end + return t +end + +--- remove a range of values from a table. +-- @param t a list-like table +-- @param i1 start index +-- @param i2 end index +-- @return the table +function tablex.removevalues (t,i1,i2) + i1,i2 = tablex._normalize_slice(t,i1,i2) + for i = i1,i2 do + remove(t,i1) + end + return t +end + +local _find +_find = function (t,value,tables) + for k,v in pairs(t) do + if v == value then return k end + end + for k,v in pairs(t) do + if not tables[v] and type(v) == 'table' then + tables[v] = true + local res = _find(v,value,tables) + if res then + res = tostring(res) + if type(k) ~= 'string' then + return '['..k..']'..res + else + return k..'.'..res + end + end + end + end +end + +--- find a value in a table by recursive search. +-- @param t the table +-- @param value the value +-- @param exclude any tables to avoid searching +-- @usage search(_G,math.sin,{package.path}) == 'math.sin' +-- @return a fieldspec, e.g. 'a.b' or 'math.sin' +function tablex.search (t,value,exclude) + assert_arg(1,t,'table') + local tables = {[t]=true} + if exclude then + for _,v in pairs(exclude) do tables[v] = true end + end + return _find(t,value,tables) +end + +return tablex diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/template.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/template.lua new file mode 100644 index 000000000..dbff1f2fc --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/template.lua @@ -0,0 +1,99 @@ +--- A template preprocessor. +-- Originally by Ricki Lake +--

    There are two rules:

      +--
    • lines starting with # are Lua
    • +--
    • otherwise, `$(expr)` is the result of evaluating `expr`
    • +--
    +--
    +-- #  for i = 1,3 do
    +--    $(i) Hello, Word!
    +-- #  end
    +-- 
    +-- Other escape characters can be used, when the defaults conflict +-- with the output language. +--
    +-- > for _,n in pairs{'one','two','three'} do
    +--  static int l_${n} (luaState *state);
    +-- > end
    +-- 
    +-- See the Guide. +-- @class module +-- @name pl.template + +--[[ + module('pl.template') +]] + +local utils = require 'pl.utils' +local append,format = table.insert,string.format + +local function parseHashLines(chunk,brackets,esc) + local exec_pat = "()$(%b"..brackets..")()" + + local function parseDollarParen(pieces, chunk, s, e) + local s = 1 + for term, executed, e in chunk:gmatch (exec_pat) do + executed = '('..executed:sub(2,-2)..')' + append(pieces, + format("%q..(%s or '')..",chunk:sub(s, term - 1), executed)) + s = e + end + append(pieces, format("%q", chunk:sub(s))) + end + + local esc_pat = esc.."+([^\n]*\n?)" + local esc_pat1, esc_pat2 = "^"..esc_pat, "\n"..esc_pat + local pieces, s = {"return function(_put) ", n = 1}, 1 + while true do + local ss, e, lua = chunk:find (esc_pat1, s) + if not e then + ss, e, lua = chunk:find(esc_pat2, s) + append(pieces, "_put(") + parseDollarParen(pieces, chunk:sub(s, ss)) + append(pieces, ")") + if not e then break end + end + append(pieces, lua) + s = e + 1 + end + append(pieces, " end") + return table.concat(pieces) +end + +local template = {} + +--- expand the template using the specified environment. +-- @param str the template string +-- @param env the environment (by default empty).
    +-- There are three special fields in the environment table
      +--
    • _parent continue looking up in this table
    • +--
    • _brackets; default is '()', can be any suitable bracket pair
    • +--
    • _escape; default is '#'
    • +--
    +function template.substitute(str,env) + env = env or {} + if rawget(env,"_parent") then + setmetatable(env,{__index = env._parent}) + end + local brackets = rawget(env,"_brackets") or '()' + local escape = rawget(env,"_escape") or '#' + local code = parseHashLines(str,brackets,escape) + local fn,err = utils.load(code,'TMP','t',env) + if not fn then return nil,err end + fn = fn() + local out = {} + local res,err = xpcall(function() fn(function(s) + out[#out+1] = s + end) end,debug.traceback) + if not res then + if env._debug then print(code) end + return nil,err + end + return table.concat(out) +end + +return template + + + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/test.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/test.lua new file mode 100644 index 000000000..162337968 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/test.lua @@ -0,0 +1,116 @@ +--- Useful test utilities. +-- @module pl.test + +local tablex = require 'pl.tablex' +local utils = require 'pl.utils' +local pretty = require 'pl.pretty' +local path = require 'pl.path' +local print,type = print,type +local clock = os.clock +local debug = require 'debug' +local io,debug = io,debug + +local function dump(x) + if type(x) == 'table' and not (getmetatable(x) and getmetatable(x).__tostring) then + return pretty.write(x,' ',true) + else + return tostring(x) + end +end + +local test = {} + +local function complain (x,y,msg) + local i = debug.getinfo(3) + local err = io.stderr + err:write(path.basename(i.short_src)..':'..i.currentline..': assertion failed\n') + err:write("got:\t",dump(x),'\n') + err:write("needed:\t",dump(y),'\n') + utils.quit(1,msg or "these values were not equal") +end + +--- like assert, except takes two arguments that must be equal and can be tables. +-- If they are plain tables, it will use tablex.deepcompare. +-- @param x any value +-- @param y a value equal to x +-- @param eps an optional tolerance for numerical comparisons +function test.asserteq (x,y,eps) + local res = x == y + if not res then + res = tablex.deepcompare(x,y,true,eps) + end + if not res then + complain(x,y) + end +end + +--- assert that the first string matches the second. +-- @param s1 a string +-- @param s2 a string +function test.assertmatch (s1,s2) + if not s1:match(s2) then + complain (s1,s2,"these strings did not match") + end +end + +function test.assertraise(fn,e) + local ok, err = pcall(unpack(fn)) + if not err or err:match(e)==nil then + complain (err,e,"these errors did not match") + end +end + +--- a version of asserteq that takes two pairs of values. +-- x1==y1 and x2==y2 must be true. Useful for functions that naturally +-- return two values. +-- @param x1 any value +-- @param x2 any value +-- @param y1 any value +-- @param y2 any value +function test.asserteq2 (x1,x2,y1,y2) + if x1 ~= y1 then complain(x1,y1) end + if x2 ~= y2 then complain(x2,y2) end +end + +-- tuple type -- + +local tuple_mt = {} + +function tuple_mt.__tostring(self) + local ts = {} + for i=1, self.n do + local s = self[i] + ts[i] = type(s) == 'string' and string.format('%q', s) or tostring(s) + end + return 'tuple(' .. table.concat(ts, ', ') .. ')' +end + +function tuple_mt.__eq(a, b) + if a.n ~= b.n then return false end + for i=1, a.n do + if a[i] ~= b[i] then return false end + end + return true +end + +--- encode an arbitrary argument list as a tuple. +-- This can be used to compare to other argument lists, which is +-- very useful for testing functions which return a number of values. +-- @usage asserteq(tuple( ('ab'):find 'a'), tuple(1,1)) +function test.tuple(...) + return setmetatable({n=select('#', ...), ...}, tuple_mt) +end + +--- Time a function. Call the function a given number of times, and report the number of seconds taken, +-- together with a message. Any extra arguments will be passed to the function. +-- @param msg a descriptive message +-- @param n number of times to call the function +-- @param fun the function +-- @param ... optional arguments to fun +function test.timer(msg,n,fun,...) + local start = clock() + for i = 1,n do fun(...) end + utils.printf("%s: took %7.2f sec\n",msg,clock()-start) +end + +return test diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/text.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/text.lua new file mode 100644 index 000000000..4c09c7003 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/text.lua @@ -0,0 +1,241 @@ +--- Text processing utilities.

    +-- This provides a Template class (modeled after the same from the Python +-- libraries, see string.Template). It also provides similar functions to those +-- found in the textwrap module. +-- See the Guide. +--

    +-- Calling text.format_operator() overloads the % operator for strings to give Python/Ruby style formated output. +-- This is extended to also do template-like substitution for map-like data. +--

    +-- > require 'pl.text'.format_operator()
    +-- > = '%s = %5.3f' % {'PI',math.pi}
    +-- PI = 3.142
    +-- > = '$name = $value' % {name='dog',value='Pluto'}
    +-- dog = Pluto
    +-- 
    +-- @class module +-- @name pl.text + +local gsub = string.gsub +local concat,append = table.concat,table.insert +local utils = require 'pl.utils' +local bind1,usplit,assert_arg,is_callable = utils.bind1,utils.split,utils.assert_arg,utils.is_callable + +local function lstrip(str) return (str:gsub('^%s+','')) end +local function strip(str) return (lstrip(str):gsub('%s+$','')) end +local function make_list(l) return setmetatable(l,utils.stdmt.List) end +local function split(s,delim) return make_list(usplit(s,delim)) end + +local function imap(f,t,...) + local res = {} + for i = 1,#t do res[i] = f(t[i],...) end + return res +end + +--[[ +module ('pl.text',utils._module) +]] + +local text = {} + +local function _indent (s,sp) + local sl = split(s,'\n') + return concat(imap(bind1('..',sp),sl),'\n')..'\n' +end + +--- indent a multiline string. +-- @param s the string +-- @param n the size of the indent +-- @param ch the character to use when indenting (default ' ') +-- @return indented string +function text.indent (s,n,ch) + assert_arg(1,s,'string') + assert_arg(2,s,'number') + return _indent(s,string.rep(ch or ' ',n)) +end + +--- dedent a multiline string by removing any initial indent. +-- useful when working with [[..]] strings. +-- @param s the string +-- @return a string with initial indent zero. +function text.dedent (s) + assert_arg(1,s,'string') + local sl = split(s,'\n') + local i1,i2 = sl[1]:find('^%s*') + sl = imap(string.sub,sl,i2+1) + return concat(sl,'\n')..'\n' +end + +--- format a paragraph into lines so that they fit into a line width. +-- It will not break long words, so lines can be over the length +-- to that extent. +-- @param s the string +-- @param width the margin width, default 70 +-- @return a list of lines +function text.wrap (s,width) + assert_arg(1,s,'string') + width = width or 70 + s = s:gsub('\n',' ') + local i,nxt = 1 + local lines,line = {} + while i < #s do + nxt = i+width + if s:find("[%w']",nxt) then -- inside a word + nxt = s:find('%W',nxt+1) -- so find word boundary + end + line = s:sub(i,nxt) + i = i + #line + append(lines,strip(line)) + end + return make_list(lines) +end + +--- format a paragraph so that it fits into a line width. +-- @param s the string +-- @param width the margin width, default 70 +-- @return a string +-- @see wrap +function text.fill (s,width) + return concat(text.wrap(s,width),'\n') .. '\n' +end + +local Template = {} +text.Template = Template +Template.__index = Template +setmetatable(Template, { + __call = function(obj,tmpl) + return Template.new(tmpl) + end}) + +function Template.new(tmpl) + assert_arg(1,tmpl,'string') + local res = {} + res.tmpl = tmpl + setmetatable(res,Template) + return res +end + +local function _substitute(s,tbl,safe) + local subst + if is_callable(tbl) then + subst = tbl + else + function subst(f) + local s = tbl[f] + if not s then + if safe then + return f + else + error("not present in table "..f) + end + else + return s + end + end + end + local res = gsub(s,'%${([%w_]+)}',subst) + return (gsub(res,'%$([%w_]+)',subst)) +end + +--- substitute values into a template, throwing an error. +-- This will throw an error if no name is found. +-- @param tbl a table of name-value pairs. +function Template:substitute(tbl) + assert_arg(1,tbl,'table') + return _substitute(self.tmpl,tbl,false) +end + +--- substitute values into a template. +-- This version just passes unknown names through. +-- @param tbl a table of name-value pairs. +function Template:safe_substitute(tbl) + assert_arg(1,tbl,'table') + return _substitute(self.tmpl,tbl,true) +end + +--- substitute values into a template, preserving indentation.
    +-- If the value is a multiline string _or_ a template, it will insert +-- the lines at the correct indentation.
    +-- Furthermore, if a template, then that template will be subsituted +-- using the same table. +-- @param tbl a table of name-value pairs. +function Template:indent_substitute(tbl) + assert_arg(1,tbl,'table') + if not self.strings then + self.strings = split(self.tmpl,'\n') + end + -- the idea is to substitute line by line, grabbing any spaces as + -- well as the $var. If the value to be substituted contains newlines, + -- then we split that into lines and adjust the indent before inserting. + local function subst(line) + return line:gsub('(%s*)%$([%w_]+)',function(sp,f) + local subtmpl + local s = tbl[f] + if not s then error("not present in table "..f) end + if getmetatable(s) == Template then + subtmpl = s + s = s.tmpl + else + s = tostring(s) + end + if s:find '\n' then + s = _indent(s,sp) + end + if subtmpl then return _substitute(s,tbl) + else return s + end + end) + end + local lines = imap(subst,self.strings) + return concat(lines,'\n')..'\n' +end + +------- Python-style formatting operator ------ +-- (see the lua-users wiki) -- + +function text.format_operator() + + local format = string.format + + -- a more forgiving version of string.format, which applies + -- tostring() to any value with a %s format. + local function formatx (fmt,...) + local args = {...} + local i = 1 + for p in fmt:gmatch('%%.') do + if p == '%s' and type(args[i]) ~= 'string' then + args[i] = tostring(args[i]) + end + i = i + 1 + end + return format(fmt,unpack(args)) + end + + local function basic_subst(s,t) + return (s:gsub('%$([%w_]+)',t)) + end + + -- Note this goes further than the original, and will allow these cases: + -- 1. a single value + -- 2. a list of values + -- 3. a map of var=value pairs + -- 4. a function, as in gsub + -- For the second two cases, it uses $-variable substituion. + getmetatable("").__mod = function(a, b) + if b == nil then + return a + elseif type(b) == "table" and getmetatable(b) == nil then + if #b == 0 then -- assume a map-like table + return _substitute(a,b,true) + else + return formatx(a,unpack(b)) + end + elseif type(b) == 'function' then + return basic_subst(a,b) + else + return formatx(a,b) + end + end +end + +return text diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/utils.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/utils.lua new file mode 100644 index 000000000..af1553b2f --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/utils.lua @@ -0,0 +1,529 @@ +--- Generally useful routines. +-- See the Guide. +-- @class module +-- @name pl.utils +local format,gsub,byte = string.format,string.gsub,string.byte +local clock = os.clock +local stdout = io.stdout +local append = table.insert + +local collisions = {} + +local utils = {} + +utils._VERSION = "0.9.4" + +utils.dir_separator = _G.package.config:sub(1,1) + +--- end this program gracefully. +-- @param code The exit code or a message to be printed +-- @param ... extra arguments for message's format' +-- @see utils.fprintf +function utils.quit(code,...) + if type(code) == 'string' then + utils.fprintf(io.stderr,code,...) + code = -1 + else + utils.fprintf(io.stderr,...) + end + io.stderr:write('\n') + os.exit(code) +end + +--- print an arbitrary number of arguments using a format. +-- @param fmt The format (see string.format) +-- @param ... Extra arguments for format +function utils.printf(fmt,...) + utils.fprintf(stdout,fmt,...) +end + +--- write an arbitrary number of arguments to a file using a format. +-- @param f File handle to write to. +-- @param fmt The format (see string.format). +-- @param ... Extra arguments for format +function utils.fprintf(f,fmt,...) + utils.assert_string(2,fmt) + f:write(format(fmt,...)) +end + +local function import_symbol(T,k,v,libname) + local key = rawget(T,k) + -- warn about collisions! + if key and k ~= '_M' and k ~= '_NAME' and k ~= '_PACKAGE' and k ~= '_VERSION' then + utils.printf("warning: '%s.%s' overrides existing symbol\n",libname,k) + end + rawset(T,k,v) +end + +local function lookup_lib(T,t) + for k,v in pairs(T) do + if v == t then return k end + end + return '?' +end + +local already_imported = {} + +--- take a table and 'inject' it into the local namespace. +-- @param t The Table +-- @param T An optional destination table (defaults to callers environment) +function utils.import(t,T) + T = T or _G + t = t or utils + if type(t) == 'string' then + t = require (t) + end + local libname = lookup_lib(T,t) + if already_imported[t] then return end + already_imported[t] = libname + for k,v in pairs(t) do + import_symbol(T,k,v,libname) + end +end + +utils.patterns = { + FLOAT = '[%+%-%d]%d*%.?%d*[eE]?[%+%-]?%d*', + INTEGER = '[+%-%d]%d*', + IDEN = '[%a_][%w_]*', + FILE = '[%a%.\\][:%][%w%._%-\\]*' +} + +--- escape any 'magic' characters in a string +-- @param s The input string +function utils.escape(s) + utils.assert_string(1,s) + return (s:gsub('[%-%.%+%[%]%(%)%$%^%%%?%*]','%%%1')) +end + +--- return either of two values, depending on a condition. +-- @param cond A condition +-- @param value1 Value returned if cond is true +-- @param value2 Value returned if cond is false (can be optional) +function utils.choose(cond,value1,value2) + if cond then return value1 + else return value2 + end +end + +local raise + +--- return the contents of a file as a string +-- @param filename The file path +-- @param is_bin open in binary mode +-- @return file contents +function utils.readfile(filename,is_bin) + local mode = is_bin and 'b' or '' + utils.assert_string(1,filename) + local f,err = io.open(filename,'r'..mode) + if not f then return utils.raise (err) end + local res,err = f:read('*a') + f:close() + if not res then return raise (err) end + return res +end + +--- write a string to a file +-- @param filename The file path +-- @param str The string +-- @return true or nil +-- @return error message +-- @raise error if filename or str aren't strings +function utils.writefile(filename,str) + utils.assert_string(1,filename) + utils.assert_string(2,str) + local f,err = io.open(filename,'w') + if not f then return raise(err) end + f:write(str) + f:close() + return true +end + +--- return the contents of a file as a list of lines +-- @param filename The file path +-- @return file contents as a table +-- @raise errror if filename is not a string +function utils.readlines(filename) + utils.assert_string(1,filename) + local f,err = io.open(filename,'r') + if not f then return raise(err) end + local res = {} + for line in f:lines() do + append(res,line) + end + f:close() + return res +end + +--- split a string into a list of strings separated by a delimiter. +-- @param s The input string +-- @param re A Lua string pattern; defaults to '%s+' +-- @param plain don't use Lua patterns +-- @param n optional maximum number of splits +-- @return a list-like table +-- @raise error if s is not a string +function utils.split(s,re,plain,n) + utils.assert_string(1,s) + local find,sub,append = string.find, string.sub, table.insert + local i1,ls = 1,{} + if not re then re = '%s+' end + if re == '' then return {s} end + while true do + local i2,i3 = find(s,re,i1,plain) + if not i2 then + local last = sub(s,i1) + if last ~= '' then append(ls,last) end + if #ls == 1 and ls[1] == '' then + return {} + else + return ls + end + end + append(ls,sub(s,i1,i2-1)) + if n and #ls == n then + ls[#ls] = sub(s,i1) + return ls + end + i1 = i3+1 + end +end + +--- split a string into a number of values. +-- @param s the string +-- @param re the delimiter, default space +-- @return n values +-- @usage first,next = splitv('jane:doe',':') +-- @see split +function utils.splitv (s,re) + return unpack(utils.split(s,re)) +end + +local lua52 = table.pack ~= nil +local lua51_load = load + +if not lua52 then -- define Lua 5.2 style load() + function utils.load(str,src,mode,env) + local chunk,err + if type(str) == 'string' then + chunk,err = loadstring(str,src) + else + chunk,err = lua51_load(str,src) + end + if chunk and env then setfenv(chunk,env) end + return chunk,err + end +else + utils.load = load + -- setfenv/getfenv replacements for Lua 5.2 + -- by Sergey Rozhenko + -- http://lua-users.org/lists/lua-l/2010-06/msg00313.html + -- Roberto Ierusalimschy notes that it is possible for getfenv to return nil + -- in the case of a function with no globals: + -- http://lua-users.org/lists/lua-l/2010-06/msg00315.html + function setfenv(f, t) + f = (type(f) == 'function' and f or debug.getinfo(f + 1, 'f').func) + local name + local up = 0 + repeat + up = up + 1 + name = debug.getupvalue(f, up) + until name == '_ENV' or name == nil + if name then + debug.upvaluejoin(f, up, function() return name end, 1) -- use unique upvalue + debug.setupvalue(f, up, t) + end + end + + function getfenv(f) + f = (type(f) == 'function' and f or debug.getinfo(f + 1, 'f').func) + local name, val + local up = 0 + repeat + up = up + 1 + name, val = debug.getupvalue(f, up) + until name == '_ENV' or name == nil + return val + end +end + + +--- execute a shell command. +-- This is a compatibility function that returns the same for Lua 5.1 and Lua 5.2 +-- @param cmd a shell command +-- @return true if successful +-- @return actual return code +function utils.execute (cmd) + local res1,res2,res2 = os.execute(cmd) + if not lua52 then + return res1==0,res1 + else + return res1,res2 + end +end + +if not lua52 then + function table.pack (...) + local n = select('#',...) + return {n=n; ...},n + end + local sep = package.config:sub(1,1) + function package.searchpath (mod,path) + mod = mod:gsub('%.',sep) + for m in path:gmatch('[^;]+') do + local nm = m:gsub('?',mod) + local f = io.open(nm,'r') + if f then f:close(); return nm end + end + end +end + +if not table.pack then table.pack = _G.pack end +if not rawget(_G,"pack") then _G.pack = table.pack end + +--- take an arbitrary set of arguments and make into a table. +-- This returns the table and the size; works fine for nil arguments +-- @param ... arguments +-- @return table +-- @return table size +-- @usage local t,n = utils.args(...) + +--- 'memoize' a function (cache returned value for next call). +-- This is useful if you have a function which is relatively expensive, +-- but you don't know in advance what values will be required, so +-- building a table upfront is wasteful/impossible. +-- @param func a function of at least one argument +-- @return a function with at least one argument, which is used as the key. +function utils.memoize(func) + return setmetatable({}, { + __index = function(self, k, ...) + local v = func(k,...) + self[k] = v + return v + end, + __call = function(self, k) return self[k] end + }) +end + +--- is the object either a function or a callable object?. +-- @param obj Object to check. +function utils.is_callable (obj) + return type(obj) == 'function' or getmetatable(obj) and getmetatable(obj).__call +end + +--- is the object of the specified type?. +-- If the type is a string, then use type, otherwise compare with metatable +-- @param obj An object to check +-- @param tp String of what type it should be +function utils.is_type (obj,tp) + if type(tp) == 'string' then return type(obj) == tp end + local mt = getmetatable(obj) + return tp == mt +end + +local fileMT = getmetatable(io.stdout) + +--- a string representation of a type. +-- For tables with metatables, we assume that the metatable has a `_name` +-- field. Knows about Lua file objects. +-- @param obj an object +-- @return a string like 'number', 'table' or 'List' +function utils.type (obj) + local t = type(obj) + if t == 'table' or t == 'userdata' then + local mt = getmetatable(obj) + if mt == fileMT then + return 'file' + else + return mt._name or "unknown "..t + end + else + return t + end +end + +--- is this number an integer? +-- @param x a number +-- @raise error if x is not a number +function utils.is_integer (x) + return math.ceil(x)==x +end + +utils.stdmt = { + List = {_name='List'}, Map = {_name='Map'}, + Set = {_name='Set'}, MultiMap = {_name='MultiMap'} +} + +local _function_factories = {} + +--- associate a function factory with a type. +-- A function factory takes an object of the given type and +-- returns a function for evaluating it +-- @param mt metatable +-- @param fun a callable that returns a function +function utils.add_function_factory (mt,fun) + _function_factories[mt] = fun +end + +local function _string_lambda(f) + local raise = utils.raise + if f:find '^|' or f:find '_' then + local args,body = f:match '|([^|]*)|(.+)' + if f:find '_' then + args = '_' + body = f + else + if not args then return raise 'bad string lambda' end + end + local fstr = 'return function('..args..') return '..body..' end' + local fn,err = loadstring(fstr) + if not fn then return raise(err) end + fn = fn() + return fn + else return raise 'not a string lambda' + end +end + +--- an anonymous function as a string. This string is either of the form +-- '|args| expression' or is a function of one argument, '_' +-- @param lf function as a string +-- @return a function +-- @usage string_lambda '|x|x+1' (2) == 3 +-- @usage string_lambda '_+1 (2) == 3 +utils.string_lambda = utils.memoize(_string_lambda) + +local ops + +--- process a function argument. +-- This is used throughout Penlight and defines what is meant by a function: +-- Something that is callable, or an operator string as defined by pl.operator, +-- such as '>' or '#'. If a function factory has been registered for the type, it will +-- be called to get the function. +-- @param idx argument index +-- @param f a function, operator string, or callable object +-- @param msg optional error message +-- @return a callable +-- @raise if idx is not a number or if f is not callable +-- @see utils.is_callable +function utils.function_arg (idx,f,msg) + utils.assert_arg(1,idx,'number') + local tp = type(f) + if tp == 'function' then return f end -- no worries! + -- ok, a string can correspond to an operator (like '==') + if tp == 'string' then + if not ops then ops = require 'pl.operator'.optable end + local fn = ops[f] + if fn then return fn end + local fn, err = utils.string_lambda(f) + if not fn then error(err..': '..f) end + return fn + elseif tp == 'table' or tp == 'userdata' then + local mt = getmetatable(f) + if not mt then error('not a callable object',2) end + local ff = _function_factories[mt] + if not ff then + if not mt.__call then error('not a callable object',2) end + return f + else + return ff(f) -- we have a function factory for this type! + end + end + if not msg then msg = " must be callable" end + if idx > 0 then + error("argument "..idx..": "..msg,2) + else + error(msg,2) + end +end + +--- bind the first argument of the function to a value. +-- @param fn a function of at least two values (may be an operator string) +-- @param p a value +-- @return a function such that f(x) is fn(p,x) +-- @raise same as @{function_arg} +-- @see pl.func.curry +function utils.bind1 (fn,p) + fn = utils.function_arg(1,fn) + return function(...) return fn(p,...) end +end + +--- assert that the given argument is in fact of the correct type. +-- @param n argument index +-- @param val the value +-- @param tp the type +-- @param verify an optional verfication function +-- @param msg an optional custom message +-- @param lev optional stack position for trace, default 2 +-- @raise if the argument n is not the correct type +-- @usage assert_arg(1,t,'table') +-- @usage assert_arg(n,val,'string',path.isdir,'not a directory') +function utils.assert_arg (n,val,tp,verify,msg,lev) + if type(val) ~= tp then + error(("argument %d expected a '%s', got a '%s'"):format(n,tp,type(val)),2) + end + if verify and not verify(val) then + error(("argument %d: '%s' %s"):format(n,val,msg),lev or 2) + end +end + +--- assert the common case that the argument is a string. +-- @param n argument index +-- @param val a value that must be a string +-- @raise val must be a string +function utils.assert_string (n,val) + utils.assert_arg(n,val,'string',nil,nil,nil,3) +end + +local err_mode = 'default' + +--- control the error strategy used by Penlight. +-- Controls how utils.raise works; the default is for it +-- to return nil and the error string, but if the mode is 'error' then +-- it will throw an error. If mode is 'quit' it will immediately terminate +-- the program. +-- @param mode - either 'default', 'quit' or 'error' +-- @see utils.raise +function utils.on_error (mode) + err_mode = mode +end + +--- used by Penlight functions to return errors. Its global behaviour is controlled +-- by utils.on_error +-- @param err the error string. +-- @see utils.on_error +function utils.raise (err) + if err_mode == 'default' then return nil,err + elseif err_mode == 'quit' then utils.quit(err) + else error(err,2) + end +end + +raise = utils.raise + +--- load a code string or bytecode chunk. +-- @param code Lua code as a string or bytecode +-- @param name for source errors +-- @param mode kind of chunk, 't' for text, 'b' for bytecode, 'bt' for all (default) +-- @param env the environment for the new chunk (default nil) +-- @return compiled chunk +-- @return error message (chunk is nil) +-- @function utils.load + + +--- Lua 5.2 Compatible Functions +-- @section lua52 + +--- pack an argument list into a table. +-- @param ... any arguments +-- @return a table with field n set to the length +-- @return the length +-- @function table.pack + +------ +-- return the full path where a Lua module name would be matched. +-- @param mod module name, possibly dotted +-- @param path a path in the same form as package.path or package.cpath +-- @see path.package_path +-- @function package.searchpath + +return utils + + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/xml.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/xml.lua new file mode 100644 index 000000000..a452b26a0 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/pl/xml.lua @@ -0,0 +1,676 @@ +--- XML LOM Utilities. +-- This implements some useful things on LOM documents, such as returned by lxp.lom.parse. +-- In particular, it can convert LOM back into XML text, with optional pretty-printing control. +-- It's based on stanza.lua from Prosody http://hg.prosody.im/trunk/file/4621c92d2368/util/stanza.lua) +-- +-- Can be used as a lightweight one-stop-shop for simple XML processing; a simple XML parser is included +-- but the default is to use lxp.lom if it can be found. +--
    +-- Prosody IM
    +-- Copyright (C) 2008-2010 Matthew Wild
    +-- Copyright (C) 2008-2010 Waqas Hussain
    +--
    +-- classic Lua XML parser by Roberto Ierusalimschy.
    +-- modified to output LOM format.
    +-- http://lua-users.org/wiki/LuaXml
    +-- 
    +-- @module pl.xml + +local t_insert = table.insert; +local t_concat = table.concat; +local t_remove = table.remove; +local s_format = string.format; +local s_match = string.match; +local tostring = tostring; +local setmetatable = setmetatable; +local getmetatable = getmetatable; +local pairs = pairs; +local ipairs = ipairs; +local type = type; +local next = next; +local print = print; +local unpack = unpack or table.unpack; +local s_gsub = string.gsub; +local s_char = string.char; +local s_find = string.find; +local os = os; +local pcall,require,io = pcall,require,io +local split = require 'pl.utils'.split + +local _M = {} +local Doc = { __type = "doc" }; +Doc.__index = Doc; + +--- create a new document node. +-- @param tag the tag name +-- @param attr optional attributes (table of name-value pairs) +function _M.new(tag, attr) + local doc = { tag = tag, attr = attr or {}, last_add = {}}; + return setmetatable(doc, Doc); +end + +--- parse an XML document. By default, this uses lxp.lom.parse, but +-- falls back to basic_parse, or if use_basic is true +-- @param text_or_file file or string representation +-- @param is_file whether text_or_file is a file name or not +-- @param use_basic do a basic parse +-- @return a parsed LOM document with the document metatatables set +-- @return nil, error the error can either be a file error or a parse error +function _M.parse(text_or_file, is_file, use_basic) + local parser,status,lom + if use_basic then parser = _M.basic_parse + else + status,lom = pcall(require,'lxp.lom') + if not status then parser = _M.basic_parse else parser = lom.parse end + end + if is_file then + local f,err = io.open(text_or_file) + if not f then return nil,err end + text_or_file = f:read '*a' + f:close() + end + local doc,err = parser(text_or_file) + if not doc then return nil,err end + if lom then + _M.walk(doc,false,function(_,d) + setmetatable(d,Doc) + end) + end + return doc +end + +---- convenient function to add a document node, This updates the last inserted position. +-- @param tag a tag name +-- @param attrs optional set of attributes (name-string pairs) +function Doc:addtag(tag, attrs) + local s = _M.new(tag, attrs); + (self.last_add[#self.last_add] or self):add_direct_child(s); + t_insert(self.last_add, s); + return self; +end + +--- convenient function to add a text node. This updates the last inserted position. +-- @param text a string +function Doc:text(text) + (self.last_add[#self.last_add] or self):add_direct_child(text); + return self; +end + +---- go up one level in a document +function Doc:up() + t_remove(self.last_add); + return self; +end + +function Doc:reset() + local last_add = self.last_add; + for i = 1,#last_add do + last_add[i] = nil; + end + return self; +end + +--- append a child to a document directly. +-- @param child a child node (either text or a document) +function Doc:add_direct_child(child) + t_insert(self, child); +end + +--- append a child to a document at the last element added +-- @param child a child node (either text or a document) +function Doc:add_child(child) + (self.last_add[#self.last_add] or self):add_direct_child(child); + return self; +end + +--accessing attributes: useful not to have to expose implementation (attr) +--but also can allow attr to be nil in any future optimizations + +--- set attributes of a document node. +-- @param t a table containing attribute/value pairs +function Doc:set_attribs (t) + for k,v in pairs(t) do + self.attr[k] = v + end +end + +--- set a single attribute of a document node. +-- @param a attribute +-- @param v its value +function Doc:set_attrib(a,v) + self.attr[a] = v +end + +--- access the attributes of a document node. +function Doc:get_attribs() + return self.attr +end + +--- function to create an element with a given tag name and a set of children. +-- @param tag a tag name +-- @param items either text or a table where the hash part is the attributes and the list part is the children. +function _M.elem(tag,items) + local s = _M.new(tag) + if type(items) == 'string' then items = {items} end + if _M.is_tag(items) then + t_insert(s,items) + elseif type(items) == 'table' then + for k,v in pairs(items) do + if type(k) == 'string' then + s.attr[k] = v + t_insert(s.attr,k) + else + s[k] = v + end + end + end + return s +end + +--- given a list of names, return a number of element constructors. +-- @param list a list of names, or a comma-separated string. +-- @usage local parent,children = doc.tags 'parent,children'
    +-- doc = parent {child 'one', child 'two'} +function _M.tags(list) + local ctors = {} + local elem = _M.elem + if type(list) == 'string' then list = split(list,'%s*,%s*') end + for _,tag in ipairs(list) do + local ctor = function(items) return _M.elem(tag,items) end + t_insert(ctors,ctor) + end + return unpack(ctors) +end + +local templ_cache = {} + +local function is_data(data) + return #data == 0 or type(data[1]) ~= 'table' +end + +local function prepare_data(data) + -- a hack for ensuring that $1 maps to first element of data, etc. + -- Either this or could change the gsub call just below. + for i,v in ipairs(data) do + data[tostring(i)] = v + end +end + +--- create a substituted copy of a document, +-- @param templ may be a document or a string representation which will be parsed and cached +-- @param data a table of name-value pairs or a list of such tables +-- @return an XML document +function Doc.subst(templ, data) + if type(data) ~= 'table' or not next(data) then return nil, "data must be a non-empty table" end + if is_data(data) then + prepare_data(data) + end + if type(templ) == 'string' then + if templ_cache[templ] then + templ = templ_cache[templ] + else + local str,err = templ + templ,err = _M.parse(str) + if not templ then return nil,err end + templ_cache[str] = templ + end + end + local function _subst(item) + return _M.clone(templ,function(s) + return s:gsub('%$(%w+)',item) + end) + end + if is_data(data) then return _subst(data) end + local list = {} + for _,item in ipairs(data) do + prepare_data(item) + t_insert(list,_subst(item)) + end + if data.tag then + list = _M.elem(data.tag,list) + end + return list +end + + +--- get the first child with a given tag name. +-- @param tag the tag name +function Doc:child_with_name(tag) + for _, child in ipairs(self) do + if child.tag == tag then return child; end + end +end + +local _children_with_name +function _children_with_name(self,tag,list,recurse) + for _, child in ipairs(self) do if type(child) == 'table' then + if child.tag == tag then t_insert(list,child) end + if recurse then _children_with_name(child,tag,list,recurse) end + end end +end + +--- get all elements in a document that have a given tag. +-- @param tag a tag name +-- @param dont_recurse optionally only return the immediate children with this tag name +-- @return a list of elements +function Doc:get_elements_with_name(tag,dont_recurse) + local res = {} + _children_with_name(self,tag,res,not dont_recurse) + return res +end + +-- iterate over all children of a document node, including text nodes. +function Doc:children() + local i = 0; + return function (a) + i = i + 1 + return a[i]; + end, self, i; +end + +-- return the first child element of a node, if it exists. +function Doc:first_childtag() + if #self == 0 then return end + for _,t in ipairs(self) do + if type(t) == 'table' then return t end + end +end + +function Doc:matching_tags(tag, xmlns) + xmlns = xmlns or self.attr.xmlns; + local tags = self; + local start_i, max_i = 1, #tags; + return function () + for i=start_i,max_i do + v = tags[i]; + if (not tag or v.tag == tag) + and (not xmlns or xmlns == v.attr.xmlns) then + start_i = i+1; + return v; + end + end + end, tags, i; +end + +--- iterate over all child elements of a document node. +function Doc:childtags() + local i = 0; + return function (a) + local v + repeat + i = i + 1 + v = self[i] + if v and type(v) == 'table' then return v; end + until not v + end, self[1], i; +end + +--- visit child element of a node and call a function, possibility modifying the document. +-- @param callback a function passed the node (text or element). If it returns nil, that node will be removed. +-- If it returns a value, that will replace the current node. +function Doc:maptags(callback) + local is_tag = _M.is_tag + local i = 1; + while i <= #self do + if is_tag(self[i]) then + local ret = callback(self[i]); + if ret == nil then + t_remove(self, i); + else + self[i] = ret; + i = i + 1; + end + end + end + return self; +end + +local xml_escape +do + local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; + function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end + _M.xml_escape = xml_escape; +end + +-- pretty printing +-- if indent, then put each new tag on its own line +-- if attr_indent, put each new attribute on its own line +local function _dostring(t, buf, self, xml_escape, parentns, idn, indent, attr_indent) + local nsid = 0; + local tag = t.tag + local lf,alf = ""," " + if indent then lf = '\n'..idn end + if attr_indent then alf = '\n'..idn..attr_indent end + t_insert(buf, lf.."<"..tag); + for k, v in pairs(t.attr) do + if type(k) ~= 'number' then -- LOM attr table has list-like part + if s_find(k, "\1", 1, true) then + local ns, attrk = s_match(k, "^([^\1]*)\1?(.*)$"); + nsid = nsid + 1; + t_insert(buf, " xmlns:ns"..nsid.."='"..xml_escape(ns).."' ".."ns"..nsid..":"..attrk.."='"..xml_escape(v).."'"); + elseif not(k == "xmlns" and v == parentns) then + t_insert(buf, alf..k.."='"..xml_escape(v).."'"); + end + end + end + local len,has_children = #t; + if len == 0 then + local out = "/>" + if attr_indent then out = '\n'..idn..out end + t_insert(buf, out); + else + t_insert(buf, ">"); + for n=1,len do + local child = t[n]; + if child.tag then + self(child, buf, self, xml_escape, t.attr.xmlns,idn and idn..indent, indent, attr_indent ); + has_children = true + else -- text element + t_insert(buf, xml_escape(child)); + end + end + t_insert(buf, (has_children and lf or '')..""); + end +end + +---- pretty-print an XML document +--- @param t an XML document +--- @param idn an initial indent (indents are all strings) +--- @param indent an indent for each level +--- @param attr_indent if given, indent each attribute pair and put on a separate line +--- @return a string representation +function _M.tostring(t,idn,indent, attr_indent) + local buf = {}; + _dostring(t, buf, _dostring, xml_escape, nil,idn,indent, attr_indent); + return t_concat(buf); +end + +Doc.__tostring = _M.tostring + +--- get the full text value of an element +function Doc:get_text() + local res = {} + for i,el in ipairs(self) do + if type(el) == 'string' then t_insert(res,el) end + end + return t_concat(res); +end + +--- make a copy of a document +-- @param doc the original document +-- @param strsubst an optional function for handling string copying which could do substitution, etc. +function _M.clone(doc, strsubst) + local lookup_table = {}; + local function _copy(object) + if type(object) ~= "table" then + if strsubst and type(object) == 'string' then return strsubst(object) + else return object; + end + elseif lookup_table[object] then + return lookup_table[object]; + end + local new_table = {}; + lookup_table[object] = new_table; + for index, value in pairs(object) do + new_table[_copy(index)] = _copy(value); -- is cloning keys much use, hm? + end + return setmetatable(new_table, getmetatable(object)); + end + + return _copy(doc) +end + +--- compare two documents. +-- @param t1 any value +-- @param t2 any value +function _M.compare(t1,t2) + local ty1 = type(t1) + local ty2 = type(t2) + if ty1 ~= ty2 then return false, 'type mismatch' end + if ty1 == 'string' then + return t1 == t2 and true or 'text '..t1..' ~= text '..t2 + end + if ty1 ~= 'table' or ty2 ~= 'table' then return false, 'not a document' end + if t1.tag ~= t2.tag then return false, 'tag '..t1.tag..' ~= tag '..t2.tag end + if #t1 ~= #t2 then return false, 'size '..#t1..' ~= size '..#t2..' for tag '..t1.tag end + -- compare attributes + for k,v in pairs(t1.attr) do + if t2.attr[k] ~= v then return false, 'mismatch attrib' end + end + for k,v in pairs(t2.attr) do + if t1.attr[k] ~= v then return false, 'mismatch attrib' end + end + -- compare children + for i = 1,#t1 do + local yes,err = _M.compare(t1[i],t2[i]) + if not yes then return err end + end + return true +end + +--- is this value a document element? +-- @param d any value +function _M.is_tag(d) + return type(d) == 'table' and type(d.tag) == 'string' +end + +--- call the desired function recursively over the document. +-- @param doc the document +-- @param depth_first visit child notes first, then the current node +-- @param operation a function which will receive the current tag name and current node. +function _M.walk (doc, depth_first, operation) + if not depth_first then operation(doc.tag,doc) end + for _,d in ipairs(doc) do + if _M.is_tag(d) then + _M.walk(d,depth_first,operation) + end + end + if depth_first then operation(doc.tag,doc) end +end + +local escapes = { quot = "\"", apos = "'", lt = "<", gt = ">", amp = "&" } +local function unescape(str) return (str:gsub( "&(%a+);", escapes)); end + +local function parseargs(s) + local arg = {} + s:gsub("([%w:]+)%s*=%s*([\"'])(.-)%2", function (w, _, a) + arg[w] = unescape(a) + end) + return arg +end + +--- Parse a simple XML document using a pure Lua parser based on Robero Ierusalimschy's original version. +-- @param s the XML document to be parsed. +-- @param all_text if true, preserves all whitespace. Otherwise only text containing non-whitespace is included. +function _M.basic_parse(s,all_text) + local t_insert,t_remove = table.insert,table.remove + local s_find,s_sub = string.find,string.sub + local stack = {} + local top = {} + t_insert(stack, top) + local ni,c,label,xarg, empty + local i, j = 1, 1 + -- we're not interested in + local _,istart = s_find(s,'^%s*<%?[^%?]+%?>%s*') + if istart then i = istart+1 end + while true do + ni,j,c,label,xarg, empty = s_find(s, "<(%/?)([%w:%-_]+)(.-)(%/?)>", i) + if not ni then break end + local text = s_sub(s, i, ni-1) + if all_text or not s_find(text, "^%s*$") then + t_insert(top, unescape(text)) + end + if empty == "/" then -- empty element tag + t_insert(top, setmetatable({tag=label, attr=parseargs(xarg), empty=1},Doc)) + elseif c == "" then -- start tag + top = setmetatable({tag=label, attr=parseargs(xarg)},Doc) + t_insert(stack, top) -- new level + else -- end tag + local toclose = t_remove(stack) -- remove top + top = stack[#stack] + if #stack < 1 then + error("nothing to close with "..label) + end + if toclose.tag ~= label then + error("trying to close "..toclose.tag.." with "..label) + end + t_insert(top, toclose) + end + i = j+1 + end + local text = s_sub(s, i) + if all_text or not s_find(text, "^%s*$") then + t_insert(stack[#stack], unescape(text)) + end + if #stack > 1 then + error("unclosed "..stack[#stack].tag) + end + local res = stack[1] + return type(res[1])=='string' and res[2] or res[1] +end + +local function empty(attr) return not attr or not next(attr) end +local function is_text(s) return type(s) == 'string' end +local function is_element(d) return type(d) == 'table' and d.tag ~= nil end + +-- returns the key,value pair from a table if it has exactly one entry +local function has_one_element(t) + local key,value = next(t) + if next(t,key) ~= nil then return false end + return key,value +end + +local function append_capture(res,tbl) + if not empty(tbl) then -- no point in capturing empty tables... + local key + if tbl._ then -- if $_ was set then it is meant as the top-level key for the captured table + key = tbl._ + tbl._ = nil + if empty(tbl) then return end + end + -- a table with only one pair {[0]=value} shall be reduced to that value + local numkey,val = has_one_element(tbl) + if numkey == 0 then tbl = val end + if key then + res[key] = tbl + else -- otherwise, we append the captured table + t_insert(res,tbl) + end + end +end + +local function make_number(pat) + if pat:find '^%d+$' then -- $1 etc means use this as an array location + pat = tonumber(pat) + end + return pat +end + +local function capture_attrib(res,pat,value) + pat = make_number(pat:sub(2)) + res[pat] = value + return true +end + +local match +function match(d,pat,res,keep_going) + local ret = true + if d == nil then return false end + -- attribute string matching is straight equality, except if the pattern is a $ capture, + -- which always succeeds. + if type(d) == 'string' then + if type(pat) ~= 'string' then return false end + if _M.debug then print(d,pat) end + if pat:find '^%$' then + return capture_attrib(res,pat,d) + else + return d == pat + end + else + if _M.debug then print(d.tag,pat.tag) end + -- this is an element node. For a match to succeed, the attributes must + -- match as well. + -- a tagname in the pattern ending with '-' is a wildcard and matches like an attribute + local tagpat = pat.tag:match '^(.-)%-$' + if tagpat then + tagpat = make_number(tagpat) + res[tagpat] = d.tag + end + if d.tag == pat.tag or tagpat then + + if not empty(pat.attr) then + if empty(d.attr) then ret = false + else + for prop,pval in pairs(pat.attr) do + local dval = d.attr[prop] + if not match(dval,pval,res) then ret = false; break end + end + end + end + -- the pattern may have child nodes. We match partially, so that {P1,P2} shall match {X,P1,X,X,P2,..} + if ret and #pat > 0 then + local i,j = 1,1 + local function next_elem() + j = j + 1 -- next child element of data + if is_text(d[j]) then j = j + 1 end + return j <= #d + end + repeat + local p = pat[i] + -- repeated {{<...>}} patterns shall match one or more elements + -- so e.g. {P+} will match {X,X,P,P,X,P,X,X,X} + if is_element(p) and p.repeated then + local found + repeat + local tbl = {} + ret = match(d[j],p,tbl,false) + if ret then + found = false --true + append_capture(res,tbl) + end + until not next_elem() or (found and not ret) + i = i + 1 + else + ret = match(d[j],p,res,false) + if ret then i = i + 1 end + end + until not next_elem() or i > #pat -- run out of elements or patterns to match + -- if every element in our pattern matched ok, then it's been a successful match + if i > #pat then return true end + end + if ret then return true end + else + ret = false + end + -- keep going anyway - look at the children! + if keep_going then + for child in d:childtags() do + ret = match(child,pat,res,keep_going) + if ret then break end + end + end + end + return ret +end + +function Doc:match(pat) + if is_text(pat) then + pat = _M.parse(pat,false,true) + end + _M.walk(pat,false,function(_,d) + if is_text(d[1]) and is_element(d[2]) and is_text(d[3]) and + d[1]:find '%s*{{' and d[3]:find '}}%s*' then + t_remove(d,1) + t_remove(d,2) + d[1].repeated = true + end + end) + + local res = {} + local ret = match(self,pat,res,true) + return res,ret +end + + +return _M + diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/file.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/file.lua new file mode 100644 index 000000000..e562c9d55 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/file.lua @@ -0,0 +1,106 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +return[[# +
    +# -- +# -- Module name +# -- +# if _file.name then + Module $(_file.name) +# end +# -- +# -- Descriptions +# -- +# if _file.shortdescription then + $( format(_file.shortdescription) ) +# end +# if _file.description and #_file.description > 0 then + $( format(_file.description) ) +# end +# -- +# -- Handle "@usage" special tag +# -- +#if _file.metadata and _file.metadata.usage then + $( applytemplate(_file.metadata.usage, i+1) ) +#end +# -- +# -- Show quick description of current type +# -- +# +# -- show quick description for globals +# if not isempty(_file.globalvars) then + Global(s) + +# for _, item in sortedpairs(_file.globalvars) do + + + + +# end +
    $( fulllinkto(item) )$( format(item.shortdescription) )
    +# end +# +# -- get type corresponding to this file (module) +# local currenttype +# local typeref = _file:moduletyperef() +# if typeref and typeref.tag == "internaltyperef" then +# local typedef = _file.types[typeref.typename] +# if typedef and typedef.tag == "recordtypedef" then +# currenttype = typedef +# end +# end +# +# -- show quick description type exposed by module +# if currenttype and not isempty(currenttype.fields) then + Type $(currenttype.name) + $( applytemplate(currenttype, i+2, 'index') ) +# end +# -- +# -- Show quick description of other types +# -- +# if _file.types then +# for name, type in sortedpairs( _file.types ) do +# if type ~= currenttype and type.tag == 'recordtypedef' and not isempty(type.fields) then + Type $(name) + $( applytemplate(type, i+2, 'index') ) +# end +# end +# end +# -- +# -- Long description of globals +# -- +# if not isempty(_file.globalvars) then + Global(s) +# for name, item in sortedpairs(_file.globalvars) do + $( applytemplate(item, i+2) ) +# end +# end +# -- +# -- Long description of current type +# -- +# if currenttype then + Type $(currenttype.name) + $( applytemplate(currenttype, i+2) ) +# end +# -- +# -- Long description of other types +# -- +# if not isempty( _file.types ) then +# for name, type in sortedpairs( _file.types ) do +# if type ~= currenttype and type.tag == 'recordtypedef' then + Type $(name) + $( applytemplate(type, i+2) ) +# end +# end +# end +
    +]] diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/index.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/index.lua new file mode 100644 index 000000000..555c2d373 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/index.lua @@ -0,0 +1,28 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +return +[[# +#if _index.modules then +
    +

    Module$( #_index.modules > 1 and 's' )

    + +# for _, module in sortedpairs( _index.modules ) do +# if module.tag ~= 'index' then + + + + +# end +# end +
    $( fulllinkto(module) )$( module.description and format(module.shortdescription) )
    +
    +#end ]] diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/index/recordtypedef.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/index/recordtypedef.lua new file mode 100644 index 000000000..8dfdbc4ce --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/index/recordtypedef.lua @@ -0,0 +1,23 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +return [[# +# if not isempty(_recordtypedef.fields) then + +# for _, item in sortedpairs( _recordtypedef.fields ) do + + + + +# end +
    $( fulllinkto(item) )$( format(item.shortdescription) )
    +# end +# ]] diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/item.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/item.lua new file mode 100644 index 000000000..122006185 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/item.lua @@ -0,0 +1,167 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +return +[[
    +
    +# -- +# -- Resolve item type definition +# -- +# local typedef = _item:resolvetype() + +# -- +# -- Show item type for internal type +# -- +#if _item.type and (not typedef or typedef.tag ~= 'functiontypedef') then +# --Show link only when available +# local link = fulllinkto(_item.type) +# if link then + $( link ) +# else + $(prettyname(_item.type)) +# end +#end + +$( prettyname(_item) ) + +
    +
    +# if _item.shortdescription then + $( format(_item.shortdescription) ) +# end +# if _item.description and #_item.description > 0 then + $( format(_item.description) ) +# end +# +# -- +# -- For function definitions, describe parameters and return values +# -- +#if typedef and typedef.tag == 'functiontypedef' then +# -- +# -- Describe parameters +# -- +# local fdef = typedef +# +# -- Adjust parameter count if first one is 'self' +# local paramcount +# if #fdef.params > 0 and isinvokable(_item) then +# paramcount = #fdef.params - 1 +# else +# paramcount = #fdef.params +# end +# +# -- List parameters +# if paramcount > 0 then + Parameter$( paramcount > 1 and 's' ) +
      +# for position, param in ipairs( fdef.params ) do +# if not (position == 1 and isinvokable(_item)) then +
    • +# local paramline = "" +# if param.type then +# local link = linkto( param.type ) +# local name = prettyname( param.type ) +# if link then +# paramline = paramline .. '' .. name .. "" +# else +# paramline = paramline .. name +# end +# end +# +# paramline = paramline .. " " .. param.name .. " " +# +# if param.optional then +# paramline = paramline .. "optional" .. " " +# end +# if param.hidden then +# paramline = paramline .. "hidden" +# end +# +# paramline = paramline .. ": " +# +# if param.description and #param.description > 0 then +# paramline = paramline .. "\n" .. param.description +# end +# + $( format (paramline)) +
    • +# end +# end +
    +# end +# +# -- +# -- Describe returns types +# -- +# if fdef and #fdef.returns > 0 then + Return value$(#fdef.returns > 1 and 's') +# -- +# -- Format nice type list +# -- +# local function niceparmlist( parlist ) +# local typelist = {} +# for position, type in ipairs(parlist) do +# local link = linkto( type ) +# local name = prettyname( type ) +# if link then +# typelist[#typelist + 1] = ''..name..'' +# else +# typelist[#typelist + 1] = name +# end +# -- Append end separator or separating comma +# typelist[#typelist + 1] = position == #parlist and ':' or ', ' +# end +# return table.concat( typelist ) +# end +# -- +# -- Generate a list if they are several return clauses +# -- +# if #fdef.returns > 1 then +
      +# for position, ret in ipairs(fdef.returns) do +
    1. +# local returnline = ""; +# +# local paramlist = niceparmlist(ret.types) +# if #ret.types > 0 and #paramlist > 0 then +# returnline = "" .. paramlist .. "" +# end +# returnline = returnline .. "\n" .. ret.description + $( format (returnline)) +
    2. +# end +
    +# else +# local paramlist = niceparmlist(fdef.returns[1].types) +# local isreturn = fdef.returns and #fdef.returns > 0 and #paramlist > 0 +# local isdescription = fdef.returns and fdef.returns[1].description and #format(fdef.returns[1].description) > 0 +# +# local returnline = ""; +# -- Show return type if provided +# if isreturn then +# returnline = ""..paramlist.."" +# end +# if isdescription then +# returnline = returnline .. "\n" .. fdef.returns[1].description +# end + $( format(returnline)) +# end +# end +#end +# +#-- +#-- Show usage samples +#-- +#if _item.metadata and _item.metadata.usage then + $( applytemplate(_item.metadata.usage, i) ) +#end +
    +
    ]] diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/page.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/page.lua new file mode 100644 index 000000000..32e1957c4 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/page.lua @@ -0,0 +1,68 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +return +[[ + +#if _page.headers and #_page.headers > 0 then + +# for _, header in ipairs(_page.headers) do + $(header) +# end + +#end + +
    +
    + +
    +
    +
    +
    +# -- +# -- Generating lateral menu +# -- + + $( applytemplate(_page.currentmodule) ) +
    + + +]] diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/recordtypedef.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/recordtypedef.lua new file mode 100644 index 000000000..758f1e0b0 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/recordtypedef.lua @@ -0,0 +1,36 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +return [[# +# -- +# -- Descriptions +# -- +#if _recordtypedef.shortdescription and #_recordtypedef.shortdescription > 0 then + $( format( _recordtypedef.shortdescription ) ) +#end +#if _recordtypedef.description and #_recordtypedef.description > 0 then + $( format( _recordtypedef.description ) ) +#end +#-- +#-- Describe usage +#-- +#if _recordtypedef.metadata and _recordtypedef.metadata.usage then + $( applytemplate(_recordtypedef.metadata.usage, i) ) +#end +# -- +# -- Describe type fields +# -- +#if not isempty( _recordtypedef.fields ) then + Field(s) +# for name, item in sortedpairs( _recordtypedef.fields ) do + $( applytemplate(item, i) ) +# end +#end ]] diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/usage.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/usage.lua new file mode 100644 index 000000000..93a8c7148 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/usage.lua @@ -0,0 +1,33 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Marc AUBRY +-- - initial API and implementation +-------------------------------------------------------------------------------- +return[[# +#-- +#-- Show usage samples +#-- +#if _usage then +# if #_usage > 1 then +# -- Show all usages + Usages: +
      +# -- Loop over several usage description +# for _, usage in ipairs(_usage) do +
    • $( securechevrons(usage.description) )
    • +# end +
    +# elseif #_usage == 1 then +# -- Show unique usage sample + Usage: +# local usage = _usage[1] +
    $( securechevrons(usage.description) )
    +# end +#end +#]] diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/utils.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/utils.lua new file mode 100644 index 000000000..f2fd01f40 --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/template/utils.lua @@ -0,0 +1,470 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2012-2014 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +local apimodel = require 'models.apimodel' + +--- +-- @module docutils +-- Handles link generation, node quick description. +-- +-- Provides: +-- * link generation +-- * anchor generation +-- * node quick description +local M = {} + +function M.isempty(map) + local f = pairs(map) + return f(map) == nil +end + +--- +-- Provide a handling function for all supported anchor types +-- recordtypedef => #(typename) +-- item (field of recordtypedef) => #(typename).itemname +-- item (global) => itemname +M.anchortypes = { + recordtypedef = function (o) return string.format('#(%s)', o.name) end, + item = function(o) + if not o.parent or o.parent.tag == 'file' then + -- Handle items referencing globals + return o.name + elseif o.parent and o.parent.tag == 'recordtypedef' then + -- Handle items included in recordtypedef + local recordtypedef = o.parent + local recordtypedefanchor = M.anchor(recordtypedef) + if not recordtypedefanchor then + return nil, 'Unable to generate anchor for `recordtypedef parent.' + end + return string.format('%s.%s', recordtypedefanchor, o.name) + end + return nil, 'Unable to generate anchor for `item' + end +} + +--- +-- Provides anchor string for an object of API mode +-- +-- @function [parent = #docutils] anchor +-- @param modelobject Object form API model +-- @result #string Anchor for an API model object, this function __may rise an error__ +-- @usage # -- In a template +-- # local anchorname = anchor(someobject) +-- +function M.anchor( modelobject ) + local tag = modelobject.tag + if M.anchortypes[ tag ] then + return M.anchortypes[ tag ](modelobject) + end + return nil, string.format('No anchor available for `%s', tag) +end + +local function getexternalmodule( item ) + -- Get file which contains this item + local file + if item.parent then + if item.parent.tag =='recordtypedef' then + local recordtypedefparent = item.parent.parent + if recordtypedefparent and recordtypedefparent.tag =='file'then + file = recordtypedefparent + end + elseif item.parent.tag =='file' then + file = item.parent + else + return nil, 'Unable to fetch item parent' + end + end + return file +end + +--- +-- Provide a handling function for all supported link types +-- +-- internaltyperef => ##(typename) +-- => #anchor(recordtyperef) +-- externaltyperef => modulename.html##(typename) +-- => linkto(file)#anchor(recordtyperef) +-- file(module) => modulename.html +-- index => index.html +-- recordtypedef => ##(typename) +-- => #anchor(recordtyperef) +-- item (internal field of recordtypedef) => ##(typename).itemname +-- => #anchor(item) +-- item (internal global) => #itemname +-- => #anchor(item) +-- item (external field of recordtypedef) => modulename.html##(typename).itemname +-- => linkto(file)#anchor(item) +-- item (externalglobal) => modulename.html#itemname +-- => linkto(file)#anchor(item) +M.linktypes = { + internaltyperef = function(o) return string.format('##(%s)', o.typename) end, + externaltyperef = function(o) return string.format('%s.html##(%s)', o.modulename, o.typename) end, + file = function(o) return string.format('%s.html', o.name) end, + index = function() return 'index.html' end, + recordtypedef = function(o) + local anchor = M.anchor(o) + if not anchor then + return nil, 'Unable to generate anchor for `recordtypedef.' + end + return string.format('#%s', anchor) + end, + item = function(o) + + -- For every item get anchor + local anchor = M.anchor(o) + if not anchor then + return nil, 'Unable to generate anchor for `item.' + end + + -- Built local link to item + local linktoitem = string.format('#%s', anchor) + + -- + -- For external item, prefix with the link to the module. + -- + -- The "external item" concept is used only here for short/embedded + -- notation purposed. This concept and the `.external` field SHALL NOT + -- be used elsewhere. + -- + if o.external then + + -- Get link to file which contains this item + local file = getexternalmodule( o ) + local linktofile = file and M.linkto( file ) + if not linktofile then + return nil, 'Unable to generate link for external `item.' + end + + -- Built external link to item + linktoitem = string.format("%s%s", linktofile, linktoitem) + end + + return linktoitem + end +} + +--- +-- Generates text for HTML links from API model element +-- +-- @function [parent = #docutils] +-- @param modelobject Object form API model +-- @result #string Links text for an API model element, this function __may rise an error__. +-- @usage # -- In a template +-- Some text +function M.linkto( apiobject ) + local tag = apiobject.tag + if M.linktypes[ tag ] then + return M.linktypes[tag](apiobject) + end + if not tag then + return nil, 'Link generation is impossible as no tag has been provided.' + end + return nil, string.format('No link generation available for `%s.', tag) +end + +--- +-- Provide a handling function for all supported pretty name types +-- primitivetyperef => #typename +-- internaltyperef => #typename +-- externaltyperef => modulename#typename +-- file(module) => modulename +-- index => index +-- recordtypedef => typename +-- item (internal function of recordtypedef) => typename.itemname(param1, param2,...) +-- item (internal func with self of recordtypedef) => typename:itemname(param2) +-- item (internal non func field of recordtypedef) => typename.itemname +-- item (internal func global) => functionname(param1, param2,...) +-- item (internal non func global) => itemname +-- item (external function of recordtypedef) => modulename#typename.itemname(param1, param2,...) +-- item (external func with self of recordtypedef) => modulename#typename:itemname(param2) +-- item (external non func field of recordtypedef) => modulename#typename.itemname +-- item (external func global) => functionname(param1, param2,...) +-- item (external non func global) => itemname +M.prettynametypes = { + primitivetyperef = function(o) return string.format('#%s', o.typename) end, + externaltyperef = function(o) return string.format('%s#%s', o.modulename, o.typename) end, + index = function(o) return "index" end, + file = function(o) return o.name end, + recordtypedef = function(o) return o.name end, + item = function( o ) + + -- Determine item name + -- ---------------------- + local itemname = o.name + + -- Determine scope + -- ---------------------- + local parent = o.parent + local isglobal = parent and parent.tag == 'file' + local isfield = parent and parent.tag == 'recordtypedef' + + -- Determine type name + -- ---------------------- + + local typename = isfield and parent.name + + -- Fetch item definition + -- ---------------------- + -- Get file object + local file + if isglobal then + file = parent + elseif isfield then + file = parent.parent + end + -- Get definition + local definition = o:resolvetype (file) + + + + -- Build prettyname + -- ---------------------- + local prettyname + if not definition or definition.tag ~= 'functiontypedef' then + -- Fields + if isglobal or not typename then + prettyname = itemname + else + prettyname = string.format('%s.%s', typename, itemname) + end + else + -- Functions + -- Build parameter list + local paramlist = {} + local isinvokable = M.isinvokable(o) + for position, param in ipairs(definition.params) do + -- For non global function, when first parameter is 'self', + -- it will not be part of listed parameters + if not (position == 1 and isinvokable and isfield) then + table.insert(paramlist, param.name) + if position ~= #definition.params then + table.insert(paramlist, ', ') + end + end + end + + if isglobal or not typename then + prettyname = string.format('%s(%s)',itemname, table.concat(paramlist)) + else + -- Determine function prefix operator, + -- ':' if 'self' is first parameter, '.' else way + local operator = isinvokable and ':' or '.' + + -- Append function parameters + prettyname = string.format('%s%s%s(%s)',typename, operator, itemname, table.concat(paramlist)) + end + end + + -- Manage external Item prettyname + -- ---------------------- + local externalmodule = o.external and getexternalmodule( o ) + local externalmodulename = externalmodule and externalmodule.name + + if externalmodulename then + return string.format('%s#%s',externalmodulename,prettyname) + else + return prettyname + end + end +} +M.prettynametypes.internaltyperef = M.prettynametypes.primitivetyperef + +--- +-- Check if the given item is a function that can be invoked +function M.isinvokable(item) + --test if the item is global + if item.parent and item.parent.tag == 'file' then + return false + end + -- check first param + local definition = item:resolvetype() + if definition and definition.tag == 'functiontypedef' then + if (#definition.params > 0) then + return definition.params[1].name == 'self' + end + end +end + +--- +-- Provide human readable overview from an API model element +-- +-- Resolve all element needed to summurize nicely an element form API model. +-- @usage $ print( prettyname(item) ) +-- module:somefunction(secondparameter) +-- @function [parent = #docutils] +-- @param apiobject Object form API model +-- @result #string Human readable description of given element. +-- @result #nil, #string In case of error. +function M.prettyname( apiobject ) + local tag = apiobject.tag + if M.prettynametypes[tag] then + return M.prettynametypes[tag](apiobject) + elseif not tag then + return nil, 'No pretty name available as no tag has been provided.' + end + return nil, string.format('No pretty name for `%s.', tag) +end + +--- +-- Just make a string print table in HTML. +-- @function [parent = #docutils] securechevrons +-- @param #string String to convert. +-- @usage securechevrons('') => '<markup>' +-- @return #string Converted string. +function M.securechevrons( str ) + if not str then return nil, 'String expected.' end + return string.gsub(str:gsub('<', '<'), '>', '>') +end + +------------------------------------------------------------------------------- +-- Handling format of @{some#type} tag. +-- Following functions enable to recognize several type of references between +-- "{}". +------------------------------------------------------------------------------- + +--- +-- Provide API Model elements from string describing global elements +-- such as: +-- * `global#foo` +-- * `foo#global.bar` +local globals = function(str) + -- Handling globals from modules + for modulename, fieldname in str:gmatch('([%a%.%d_]+)#global%.([%a%.%d_]+)') do + local item = apimodel._item(fieldname) + local file = apimodel._file() + file.name = modulename + file:addglobalvar( item ) + return item + end + -- Handling other globals + for name in str:gmatch('global#([%a%.%d_]+)') do + -- print("globale", name) + return apimodel._externaltypref('global', name) + end + return nil +end + +--- +-- Transform a string like `module#(type).field` in an API Model item +local field = function( str ) + + -- Match `module#type.field` + local mod, typename, fieldname = str:gmatch('([%a%.%d_]*)#([%a%.%d_]+)%.([%a%.%d_]+)')() + + -- Try matching `module#(type).field` + if not mod then + mod, typename, fieldname = str:gmatch('([%a%.%d_]*)#%(([%a%.%d_]+)%)%.([%a%.%d_]+)')() + if not mod then + -- No match + return nil + end + end + + -- Build according `item + local modulefielditem = apimodel._item( fieldname ) + local moduletype = apimodel._recordtypedef(typename) + moduletype:addfield( modulefielditem ) + local typeref + if #mod > 0 then + local modulefile = apimodel._file() + modulefile.name = mod + modulefile:addtype( moduletype ) + typeref = apimodel._externaltypref(mod, typename) + modulefielditem.external = true + else + typeref = apimodel._internaltyperef(typename) + end + modulefielditem.type = typeref + return modulefielditem +end + +--- +-- Build an API internal reference from a string like: `#typeref` +local internal = function ( typestring ) + for name in typestring:gmatch('#([%a%.%d_]+)') do + -- Do not handle this name is it starts with reserved name "global" + if name:find("global.") == 1 then return nil end + return apimodel._internaltyperef(name) + end + return nil +end + +--- +-- Build an API external reference from a string like: `mod.ule#type` +local extern = function (type) + + -- Match `mod.ule#ty.pe` + local modulename, typename = type:gmatch('([%a%.%d_]+)#([%a%.%d_]+)')() + + -- Trying `mod.ule#(ty.pe)` + if not modulename then + modulename, typename = type:gmatch('([%a%.%d_]+)#%(([%a%.%d_]+)%)')() + + -- No match at all + if not modulename then + return nil + end + end + return apimodel._externaltypref(modulename, typename) +end + +--- +-- Build an API external reference from a string like: `mod.ule` +local file = function (type) + for modulename in type:gmatch('([%a%.%d_]+)') do + local file = apimodel._file() + file.name = modulename + return file + end + return nil +end + + +--- +-- Provide API Model element from a string +-- @usage local externaltyperef = getelement("somemodule#somefield") +function M.getelement( str ) + + -- Order matters, more restrictive are at begin of table + local extractors = { + globals, + field, + extern, + internal, + file + } + -- Loop over extractors. + -- First valid result is used + for _, extractor in ipairs( extractors ) do + local result = extractor( str ) + if result then return result end + end + return nil +end + +-------------------------------------------------------------------------------- +-- Iterator that iterates on the table in key ascending order. +-- +-- @function [parent=#utils.table] sortedPairs +-- @param t table to iterate. +-- @return iterator function. +function M.sortedpairs(t) + local a = {} + local insert = table.insert + for n in pairs(t) do insert(a, n) end + table.sort(a) + local i = 0 + return function() + i = i + 1 + return a[i], t[a[i]] + end +end +return M diff --git a/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/templateengine.lua b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/templateengine.lua new file mode 100644 index 000000000..efa976b8a --- /dev/null +++ b/Moose Development Evironment Setup/LuaFiles/lua/5.1/share/lua/5.1/templateengine.lua @@ -0,0 +1,116 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2011-2012 Sierra Wireless. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- Kevin KIN-FOO +-- - initial API and implementation and initial documentation +-------------------------------------------------------------------------------- +--- +-- This library provide html description of elements from the externalapi +local M = {} + +-- Load template engine +local pltemplate = require 'pl.template' + +-- Markdown handling +local markdown = require 'markdown' + +-- apply template to the given element +function M.applytemplate(elem, ident, templatetype) + -- define environment + local env = M.getenv(elem, ident) + + -- load template + local template = M.gettemplate(elem,templatetype) + if not template then + templatetype = templatetype and string.format(' "%s"', templatetype) or '' + local elementname = string.format(' for %s', elem.tag or 'untagged element') + error(string.format('Unable to load %s template %s', templatetype, elementname)) + end + + -- apply template + local str, err = pltemplate.substitute(template, env) + + --manage errors + if not str then + local templateerror = templatetype and string.format(' parsing "%s" template ', templatetype) or '' + error(string.format('An error occured%s for "%s"\n%s',templateerror, elem.tag, err)) + end + return str +end + +-- get the a new environment for this element +function M.getenv(elem, ident) + local currentenv ={} + for k,v in pairs(M.env) do currentenv[k] = v end + if elem and elem.tag then + currentenv['_'..elem.tag]= elem + end + currentenv['i']= ident or 1 + return currentenv +end + +-- get the template for this element +function M.gettemplate(elem,templatetype) + local tag = elem and elem.tag + if tag then + if templatetype then + return require ("template." .. templatetype.. "." .. tag) + else + return require ("template." .. tag) + end + end +end + + +--- +-- Allow user to format text in descriptions. +-- Default implementation replaces @{---} tags with links and apply markdown. +-- @return #string +local function format(string) + -- Allow to replace encountered tags with valid links + local replace = function(found) + local apiobj = M.env.getelement(found) + if apiobj then + return M.env.fulllinkto(apiobj) + end + return found + end + string = string:gsub('@{%s*(.-)%s*}', replace) + return M.env.markdown( string ) +end +--- +-- Provide a full link to an element using `prettyname` and `linkto`. +-- Default implementation is for HTML. +local function fulllinkto(o) + local ref = M.env.linkto(o) + local name = M.env.prettyname(o) + if not ref then + return name + end + return string.format('%s', ref, name) +end +-- +-- Define default template environnement +-- +local defaultenv = { + table = table, + ipairs = ipairs, + pairs = pairs, + markdown = markdown, + applytemplate = M.applytemplate, + format = format, + linkto = function(str) return str end, + fulllinkto = fulllinkto, + prettyname = function(s) return s end, + getelement = function(s) return nil end +} + +-- this is the global env accessible in the templates +-- env should be redefine by docgenerator user to add functions or redefine it. +M.env = defaultenv +return M