From 2d1df4714e2736dbde7855ddcd76b4c1de822fa5 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 23 Jan 2012 21:58:02 +1000 Subject: Added a big bunch of example lua scripts for testing the speed of lua compiling. --- LuaSL/testLua/ilua.lua | 381 +++++ LuaSL/testLua/lua.lua | 357 ++++ LuaSL/testLua/yueliang-0.4.1/COPYRIGHT | 39 + LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua5 | 34 + LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua51 | 34 + LuaSL/testLua/yueliang-0.4.1/Changelog | 680 ++++++++ LuaSL/testLua/yueliang-0.4.1/Manifest | 180 ++ LuaSL/testLua/yueliang-0.4.1/OlderNews | 43 + LuaSL/testLua/yueliang-0.4.1/README | 156 ++ LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/README | 122 ++ .../testLua/yueliang-0.4.1/nat-5.0.3/llex_mk2.lua | 309 ++++ .../testLua/yueliang-0.4.1/nat-5.0.3/llex_mk3.lua | 266 +++ .../testLua/yueliang-0.4.1/nat-5.0.3/llex_mk4.lua | 285 ++++ .../yueliang-0.4.1/nat-5.0.3/lparser_mk3.lua | 1027 ++++++++++++ .../yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua | 1121 +++++++++++++ .../testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk2.lua | 106 ++ .../testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk4.lua | 82 + .../nat-5.0.3/test/bench_llex_mk2.lua | 94 ++ .../nat-5.0.3/test/bench_llex_mk3.lua | 92 ++ .../nat-5.0.3/test/bench_llex_mk4.lua | 94 ++ .../nat-5.0.3/test/parser_log/sample_01.lua | 9 + .../nat-5.0.3/test/parser_log/sample_02.lua | 10 + .../nat-5.0.3/test/parser_log/sample_03.lua | 21 + .../nat-5.0.3/test/parser_log/sample_04.lua | 31 + .../nat-5.0.3/test/parser_log/sample_05.lua | 129 ++ .../nat-5.0.3/test/parser_log/sample_06.lua | 132 ++ .../nat-5.0.3/test/parser_log/sample_07.lua | 147 ++ .../nat-5.0.3/test/parser_log/sample_08.lua | 66 + .../nat-5.0.3/test/parser_log/sample_09.lua | 97 ++ .../nat-5.0.3/test/parser_log/sample_10.lua | 106 ++ .../nat-5.0.3/test/parser_log/sample_11.lua | 175 ++ .../nat-5.0.3/test/parser_log/sample_12.lua | 46 + .../nat-5.0.3/test/parser_log/sample_13.lua | 99 ++ .../nat-5.0.3/test/parser_log/sample_14.lua | 107 ++ .../nat-5.0.3/test/parser_log/sample_15.lua | 135 ++ .../nat-5.0.3/test/parser_log/sample_16.lua | 87 + .../nat-5.0.3/test/parser_log/sample_17.lua | 110 ++ .../nat-5.0.3/test/parser_log/sample_b_01.lua | 26 + .../nat-5.0.3/test/parser_log/sample_b_02.lua | 35 + .../nat-5.0.3/test/parser_log/sample_b_03.lua | 64 + .../nat-5.0.3/test/parser_log/sample_b_04.lua | 77 + .../nat-5.0.3/test/parser_log/sample_b_05.lua | 43 + .../nat-5.0.3/test/parser_log/sample_b_06.lua | 70 + .../nat-5.0.3/test/parser_log/sample_b_07.lua | 84 + .../nat-5.0.3/test/parser_log/sample_b_08.lua | 159 ++ .../nat-5.0.3/test/parser_log/sample_b_09.lua | 53 + .../nat-5.0.3/test/parser_log/sample_b_10.lua | 49 + .../nat-5.0.3/test/parser_log/sample_b_11.lua | 79 + .../nat-5.0.3/test/parser_log/sample_b_12.lua | 94 ++ .../nat-5.0.3/test/parser_log/sample_b_13.lua | 117 ++ .../nat-5.0.3/test/parser_log/sample_b_14.lua | 125 ++ .../yueliang-0.4.1/nat-5.0.3/test/sample.lua | 3 + .../nat-5.0.3/test/test_llex_mk2.lua | 499 ++++++ .../nat-5.0.3/test/test_llex_mk3.lua | 500 ++++++ .../nat-5.0.3/test/test_llex_mk4.lua | 499 ++++++ .../nat-5.0.3/test/test_lparser_mk3.lua | 218 +++ .../nat-5.0.3/test/test_lparser_mk3_2.lua | 158 ++ .../nat-5.0.3/test/test_lparser_mk3b.lua | 188 +++ .../nat-5.0.3/test/test_lparser_mk3b_2.lua | 158 ++ .../nat-5.0.3/test/test_lzio_mk2.lua | 53 + LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/README | 55 + .../testLua/yueliang-0.4.1/nat-5.1.3/llex_mk2.lua | 314 ++++ .../yueliang-0.4.1/nat-5.1.3/lparser_mk2.lua | 1294 +++++++++++++++ .../nat-5.1.3/test/parser_log/sample_01.lua | 9 + .../nat-5.1.3/test/parser_log/sample_02.lua | 10 + .../nat-5.1.3/test/parser_log/sample_03.lua | 21 + .../nat-5.1.3/test/parser_log/sample_04.lua | 31 + .../nat-5.1.3/test/parser_log/sample_05.lua | 129 ++ .../nat-5.1.3/test/parser_log/sample_06.lua | 132 ++ .../nat-5.1.3/test/parser_log/sample_07.lua | 147 ++ .../nat-5.1.3/test/parser_log/sample_08.lua | 66 + .../nat-5.1.3/test/parser_log/sample_09.lua | 103 ++ .../nat-5.1.3/test/parser_log/sample_10.lua | 100 ++ .../nat-5.1.3/test/parser_log/sample_11.lua | 192 +++ .../nat-5.1.3/test/parser_log/sample_12.lua | 52 + .../nat-5.1.3/test/parser_log/sample_13.lua | 108 ++ .../nat-5.1.3/test/parser_log/sample_14.lua | 112 ++ .../nat-5.1.3/test/parser_log/sample_15.lua | 140 ++ .../nat-5.1.3/test/parser_log/sample_16.lua | 128 ++ .../nat-5.1.3/test/parser_log/sample_17.lua | 110 ++ .../nat-5.1.3/test/parser_log/sample_18.lua | 26 + .../nat-5.1.3/test/parser_log/sample_19.lua | 35 + .../nat-5.1.3/test/parser_log/sample_20.lua | 64 + .../nat-5.1.3/test/parser_log/sample_21.lua | 77 + .../nat-5.1.3/test/parser_log/sample_22.lua | 43 + .../nat-5.1.3/test/parser_log/sample_23.lua | 70 + .../nat-5.1.3/test/parser_log/sample_24.lua | 84 + .../nat-5.1.3/test/parser_log/sample_25.lua | 159 ++ .../nat-5.1.3/test/parser_log/sample_26.lua | 53 + .../nat-5.1.3/test/parser_log/sample_27.lua | 48 + .../nat-5.1.3/test/parser_log/sample_28.lua | 79 + .../nat-5.1.3/test/parser_log/sample_29.lua | 94 ++ .../nat-5.1.3/test/parser_log/sample_30.lua | 119 ++ .../nat-5.1.3/test/parser_log/sample_31.lua | 127 ++ .../nat-5.1.3/test/test_llex_mk2.lua | 566 +++++++ .../nat-5.1.3/test/test_lparser_mk2.lua | 329 ++++ .../nat-5.1.3/test/test_lparser_mk2_2.lua | 159 ++ LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/README | 51 + LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua | 902 ++++++++++ LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/ldump.lua | 362 ++++ LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/llex.lua | 531 ++++++ .../testLua/yueliang-0.4.1/orig-5.0.3/lopcodes.lua | 349 ++++ .../testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua | 1706 +++++++++++++++++++ LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/luac.lua | 71 + LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lzio.lua | 120 ++ .../yueliang-0.4.1/orig-5.0.3/test/bench_llex.lua | 99 ++ .../yueliang-0.4.1/orig-5.0.3/test/sample.lua | 3 + .../yueliang-0.4.1/orig-5.0.3/test/test_ldump.lua | 98 ++ .../yueliang-0.4.1/orig-5.0.3/test/test_llex.lua | 504 ++++++ .../orig-5.0.3/test/test_lparser.lua | 60 + .../orig-5.0.3/test/test_lparser2.lua | 202 +++ .../yueliang-0.4.1/orig-5.0.3/test/test_lzio.lua | 55 + .../yueliang-0.4.1/orig-5.0.3/test/test_number.lua | 174 ++ .../yueliang-0.4.1/orig-5.0.3/tools/call_graph.lua | 254 +++ .../yueliang-0.4.1/orig-5.0.3/tools/calls.log | 152 ++ .../orig-5.0.3/tools/sample_expr.lua | 195 +++ LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/README | 54 + LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lcode.lua | 1125 +++++++++++++ LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/ldump.lua | 372 +++++ LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/llex.lua | 686 ++++++++ .../testLua/yueliang-0.4.1/orig-5.1.3/lopcodes.lua | 432 +++++ .../testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua | 1747 ++++++++++++++++++++ LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/luac.lua | 71 + LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lzio.lua | 125 ++ .../yueliang-0.4.1/orig-5.1.3/test/bench_llex.lua | 99 ++ .../yueliang-0.4.1/orig-5.1.3/test/sample.lua | 3 + .../yueliang-0.4.1/orig-5.1.3/test/test_ldump.lua | 99 ++ .../yueliang-0.4.1/orig-5.1.3/test/test_llex.lua | 580 +++++++ .../orig-5.1.3/test/test_lparser.lua | 59 + .../orig-5.1.3/test/test_lparser2.lua | 202 +++ .../yueliang-0.4.1/orig-5.1.3/test/test_lzio.lua | 41 + .../yueliang-0.4.1/orig-5.1.3/test/test_number.lua | 174 ++ .../testLua/yueliang-0.4.1/test_lua/5.0/bisect.lua | 27 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/cf.lua | 16 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/echo.lua | 5 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/env.lua | 7 + .../yueliang-0.4.1/test_lua/5.0/factorial.lua | 32 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/fib.lua | 40 + .../testLua/yueliang-0.4.1/test_lua/5.0/fibfor.lua | 13 + .../yueliang-0.4.1/test_lua/5.0/globals.lua | 13 + .../testLua/yueliang-0.4.1/test_lua/5.0/hello.lua | 3 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/life.lua | 111 ++ LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/luac.lua | 7 + .../testLua/yueliang-0.4.1/test_lua/5.0/printf.lua | 7 + .../yueliang-0.4.1/test_lua/5.0/readonly.lua | 12 + .../testLua/yueliang-0.4.1/test_lua/5.0/sieve.lua | 29 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/sort.lua | 66 + .../testLua/yueliang-0.4.1/test_lua/5.0/table.lua | 12 + .../yueliang-0.4.1/test_lua/5.0/trace-calls.lua | 32 + .../yueliang-0.4.1/test_lua/5.0/trace-globals.lua | 38 + .../yueliang-0.4.1/test_lua/5.0/undefined.lua | 9 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/xd.lua | 14 + .../testLua/yueliang-0.4.1/test_lua/5.1/bisect.lua | 27 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/cf.lua | 16 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/echo.lua | 5 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/env.lua | 7 + .../yueliang-0.4.1/test_lua/5.1/factorial.lua | 32 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/fib.lua | 40 + .../testLua/yueliang-0.4.1/test_lua/5.1/fibfor.lua | 13 + .../yueliang-0.4.1/test_lua/5.1/globals.lua | 13 + .../testLua/yueliang-0.4.1/test_lua/5.1/hello.lua | 3 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/life.lua | 111 ++ LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/luac.lua | 7 + .../testLua/yueliang-0.4.1/test_lua/5.1/printf.lua | 7 + .../yueliang-0.4.1/test_lua/5.1/readonly.lua | 12 + .../testLua/yueliang-0.4.1/test_lua/5.1/sieve.lua | 29 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/sort.lua | 66 + .../testLua/yueliang-0.4.1/test_lua/5.1/table.lua | 12 + .../yueliang-0.4.1/test_lua/5.1/trace-calls.lua | 32 + .../yueliang-0.4.1/test_lua/5.1/trace-globals.lua | 38 + LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/xd.lua | 14 + LuaSL/testLua/yueliang-0.4.1/test_lua/README | 65 + .../yueliang-0.4.1/test_lua/files-lua-5.0.txt | 21 + .../yueliang-0.4.1/test_lua/files-lua-5.1.txt | 20 + .../yueliang-0.4.1/test_lua/files-other-5.0.txt | 21 + .../yueliang-0.4.1/test_lua/files-other-5.1.txt | 3 + .../yueliang-0.4.1/test_lua/files-yueliang-5.0.txt | 34 + .../yueliang-0.4.1/test_lua/files-yueliang-5.1.txt | 19 + .../yueliang-0.4.1/test_lua/test_parser-5.0.lua | 761 +++++++++ .../yueliang-0.4.1/test_lua/test_parser-5.1.lua | 783 +++++++++ .../yueliang-0.4.1/test_lua/test_scripts-5.0.lua | 158 ++ .../yueliang-0.4.1/test_lua/test_scripts-5.1.lua | 158 ++ 182 files changed, 30522 insertions(+) create mode 100644 LuaSL/testLua/ilua.lua create mode 100644 LuaSL/testLua/lua.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/COPYRIGHT create mode 100644 LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua5 create mode 100644 LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua51 create mode 100644 LuaSL/testLua/yueliang-0.4.1/Changelog create mode 100644 LuaSL/testLua/yueliang-0.4.1/Manifest create mode 100644 LuaSL/testLua/yueliang-0.4.1/OlderNews create mode 100644 LuaSL/testLua/yueliang-0.4.1/README create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/README create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk3.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk4.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk4.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk3.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk4.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_01.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_02.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_03.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_04.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_05.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_06.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_07.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_08.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_09.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_10.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_11.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_12.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_13.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_14.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_15.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_16.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_17.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_01.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_02.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_03.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_04.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_05.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_06.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_07.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_08.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_09.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_10.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_11.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_12.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_13.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_14.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/sample.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk3.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk4.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3_2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3b.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3b_2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lzio_mk2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/README create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/llex_mk2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/lparser_mk2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_01.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_02.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_03.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_04.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_05.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_06.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_07.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_08.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_09.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_10.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_11.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_12.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_13.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_14.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_15.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_16.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_17.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_18.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_19.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_20.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_21.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_22.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_23.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_24.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_25.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_26.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_27.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_28.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_29.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_30.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_31.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_llex_mk2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_lparser_mk2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_lparser_mk2_2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/README create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/ldump.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/llex.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lopcodes.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/luac.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lzio.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/bench_llex.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/sample.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_ldump.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_llex.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lzio.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_number.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/call_graph.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/calls.log create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/README create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lcode.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/ldump.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/llex.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lopcodes.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/luac.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lzio.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/bench_llex.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/sample.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_ldump.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_llex.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser2.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lzio.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_number.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/bisect.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/cf.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/echo.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/env.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/factorial.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/fib.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/fibfor.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/globals.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/hello.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/life.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/luac.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/printf.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/readonly.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/sieve.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/sort.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/table.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/trace-calls.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/trace-globals.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/undefined.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/xd.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/bisect.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/cf.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/echo.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/env.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/factorial.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/fib.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/fibfor.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/globals.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/hello.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/life.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/luac.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/printf.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/readonly.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/sieve.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/sort.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/table.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/trace-calls.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/trace-globals.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/xd.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/README create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/files-lua-5.0.txt create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/files-lua-5.1.txt create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/files-other-5.0.txt create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/files-other-5.1.txt create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/files-yueliang-5.0.txt create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/files-yueliang-5.1.txt create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/test_parser-5.0.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/test_parser-5.1.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/test_scripts-5.0.lua create mode 100644 LuaSL/testLua/yueliang-0.4.1/test_lua/test_scripts-5.1.lua (limited to 'LuaSL/testLua') diff --git a/LuaSL/testLua/ilua.lua b/LuaSL/testLua/ilua.lua new file mode 100644 index 0000000..f58505a --- /dev/null +++ b/LuaSL/testLua/ilua.lua @@ -0,0 +1,381 @@ +-- ilua.lua +-- A more friendly Lua interactive prompt +-- doesn't need '=' +-- will try to print out tables recursively, subject to the pretty_print_limit value. +-- Steve Donovan, 2007 +-- +local pretty_print_limit = 20 +local max_depth = 7 +local table_clever = true +local prompt = '> ' +local verbose = false +local strict = true +-- suppress strict warnings +_ = true + +-- imported global functions +local sub = string.sub +local match = string.match +local find = string.find +local push = table.insert +local pop = table.remove +local append = table.insert +local concat = table.concat +local floor = math.floor +local write = io.write +local read = io.read + +local savef +local collisions = {} +local G_LIB = {} +local declared = {} +local line_handler_fn, global_handler_fn +local print_handlers = {} + +ilua = {} +local num_prec +local num_all + +local jstack = {} + +local function oprint(...) + if savef then + savef:write(concat({...},' '),'\n') + end + print(...) +end + +local function join(tbl,delim,limit,depth) + if not limit then limit = pretty_print_limit end + if not depth then depth = max_depth end + local n = #tbl + local res = '' + local k = 0 + -- very important to avoid disgracing ourselves with circular referencs... + if #jstack > depth then + return "..." + end + for i,t in ipairs(jstack) do + if tbl == t then + return "" + end + end + push(jstack,tbl) + -- this is a hack to work out if a table is 'list-like' or 'map-like' + -- you can switch it off with ilua.table_options {clever = false} + local is_list + if table_clever then + local index1 = n > 0 and tbl[1] + local index2 = n > 1 and tbl[2] + is_list = index1 and index2 + end + if is_list then + for i,v in ipairs(tbl) do + res = res..delim..val2str(v) + k = k + 1 + if k > limit then + res = res.." ... " + break + end + end + else + for key,v in pairs(tbl) do + if type(key) == 'number' then + key = '['..tostring(key)..']' + else + key = tostring(key) + end + res = res..delim..key..'='..val2str(v) + k = k + 1 + if k > limit then + res = res.." ... " + break + end + end + end + pop(jstack) + return sub(res,2) +end + + +function val2str(val) + local tp = type(val) + if print_handlers[tp] then + local s = print_handlers[tp](val) + return s or '?' + end + if tp == 'function' then + return tostring(val) + elseif tp == 'table' then + if val.__tostring then + return tostring(val) + else + return '{'..join(val,',')..'}' + end + elseif tp == 'string' then + return "'"..val.."'" + elseif tp == 'number' then + -- we try only to apply floating-point precision for numbers deemed to be floating-point, + -- unless the 3rd arg to precision() is true. + if num_prec and (num_all or floor(val) ~= val) then + return num_prec:format(val) + else + return tostring(val) + end + else + return tostring(val) + end +end + +function _pretty_print(...) + for i,val in ipairs(arg) do + oprint(val2str(val)) + end + _G['_'] = arg[1] +end + +function compile(line) + if verbose then oprint(line) end + local f,err = loadstring(line,'local') + return err,f +end + +function evaluate(chunk) + local ok,res = pcall(chunk) + if not ok then + return res + end + return nil -- meaning, fine! +end + +function eval_lua(line) + if savef then + savef:write(prompt,line,'\n') + end + -- is the line handler interested? + if line_handler_fn then + line = line_handler_fn(line) + -- returning nil here means that the handler doesn't want + -- Lua to see the string + if not line then return end + end + -- is it an expression? + local err,chunk = compile('_pretty_print('..line..')') + if err then + -- otherwise, a statement? + err,chunk = compile(line) + end + -- if compiled ok, then evaluate the chunk + if not err then + err = evaluate(chunk) + end + -- if there was any error, print it out + if err then + oprint(err) + end +end + +local function quit(code,msg) + io.stderr:write(msg,'\n') + os.exit(code) +end + +-- functions available in scripts +function ilua.precision(len,prec,all) + if not len then num_prec = nil + else + num_prec = '%'..len..'.'..prec..'f' + end + num_all = all +end + +function ilua.table_options(t) + if t.limit then pretty_print_limit = t.limit end + if t.depth then max_depth = t.depth end + if t.clever ~= nil then table_clever = t.clever end +end + +-- inject @tbl into the global namespace +function ilua.import(tbl,dont_complain,lib) + lib = lib or '' + if type(tbl) == 'table' then + for k,v in pairs(tbl) do + local key = rawget(_G,k) + -- NB to keep track of collisions! + if key and k ~= '_M' and k ~= '_NAME' and k ~= '_PACKAGE' and k ~= '_VERSION' then + append(collisions,{k,lib,G_LIB[k]}) + end + _G[k] = v + G_LIB[k] = lib + end + end + if not dont_complain and #collisions > 0 then + for i, coll in ipairs(collisions) do + local name,lib,oldlib = coll[1],coll[2],coll[3] + write('warning: ',lib,'.',name,' overwrites ') + if oldlib then + write(oldlib,'.',name,'\n') + else + write('global ',name,'\n') + end + end + end +end + +function ilua.print_handler(name,handler) + print_handlers[name] = handler +end + +function ilua.line_handler(handler) + line_handler_fn = handler +end + +function ilua.global_handler(handler) + global_handler_fn = handler +end + +function ilua.print_variables() + for name,v in pairs(declared) do + print(name,type(_G[name])) + end +end +-- +-- strict.lua +-- 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. +-- +local function set_strict() + local mt = getmetatable(_G) + if mt == nil then + mt = {} + setmetatable(_G, mt) + end + + local function what () + local d = debug.getinfo(3, "S") + return d and d.what or "C" + end + + mt.__newindex = function (t, n, v) + declared[n] = true + rawset(t, n, v) + end + + mt.__index = function (t, n) + if not declared[n] and what() ~= "C" then + local lookup = global_handler_fn and global_handler_fn(n) + if not lookup then + error("variable '"..n.."' is not declared", 2) + else + return lookup + end + end + return rawget(t, n) + end + +end + +--- Initial operations which may not succeed! +-- try to bring in any ilua configuration file; don't complain if this is unsuccessful +pcall(function() + require 'ilua-defs' +end) + +-- Unix readline support, if readline.so is available... +local rl,readline,saveline +err = pcall(function() + rl = require 'readline' + readline = rl.readline + saveline = rl.add_history +end) +if not rl then + readline = function(prompt) + write(prompt) + return read() + end + saveline = function(s) end +end + +-- process command-line parameters +if arg then + local i = 1 + + local function parm_value(opt,parm,def) + local val = parm:sub(3) + if #val == 0 then + i = i + 1 + if i > #arg then + if not def then + quit(-1,"expecting parameter for option '-"..opt.."'") + else + return def + end + end + val = arg[i] + end + return val + end + + while i <= #arg do + local v = arg[i] + local opt = v:sub(1,1) + if opt == '-' then + opt = v:sub(2,2) + if opt == 'h' then + quit(0,"ilua (-l lib) (-L lib) (lua files)") + elseif opt == 'l' then + require (parm_value(opt,v)) + elseif opt == 'L' then + local lib = parm_value(opt,v) + local tbl = require (lib) + -- we cannot always trust require to return the table! + if type(tbl) ~= 'table' then + tbl = _G[lib] + end + ilua.import(tbl,true,lib) + elseif opt == 't' or opt == 'T' then + local file + if opt == 'T' then + file = 'ilua_'..os.date ('%y_%m_%d_%H_%M')..'.log' + else + file = parm_value(opt,v,"ilua.log") + end + print('saving transcript "'..file..'"') + savef = io.open(file,'w') + savef:write('! ilua ',concat(arg,' '),'\n') + elseif opt == 's' then + strict = false + elseif opt == 'v' then + verbose = true + end + else -- a plain file to be executed immediately + dofile(v) + end + i = i + 1 + end +end + +print 'ILUA: Lua 5.1.2 Copyright (C) 1994-2007 Lua.org, PUC-Rio\n"quit" to end' + +-- any import complaints? +ilua.import() + +-- enable 'not declared' error +if strict then + set_strict() +end + +local line = readline(prompt) +while line do + if line == 'quit' then break end + eval_lua(line) + saveline(line) + line = readline(prompt) +end + +if savef then + savef:close() +end + diff --git a/LuaSL/testLua/lua.lua b/LuaSL/testLua/lua.lua new file mode 100644 index 0000000..40d0eb8 --- /dev/null +++ b/LuaSL/testLua/lua.lua @@ -0,0 +1,357 @@ +-- lua.lua - Lua 5.1 interpreter (lua.c) reimplemented in Lua. +-- +-- WARNING: This is not completed but was quickly done just an experiment. +-- Fix omissions/bugs and test if you want to use this in production. +-- Particularly pay attention to error handling. +-- +-- (c) David Manura, 2008-08 +-- Licensed under the same terms as Lua itself. +-- Based on lua.c from Lua 5.1.3. +-- Improvements by Shmuel Zeigerman. + +-- Variables analogous to those in luaconf.h +local LUA_INIT = "LUA_INIT" +local LUA_PROGNAME = "lua" +local LUA_PROMPT = "> " +local LUA_PROMPT2 = ">> " +local function LUA_QL(x) return "'" .. x .. "'" end + +-- Variables analogous to those in lua.h +local LUA_RELEASE = "Lua 5.1.3" +local LUA_COPYRIGHT = "Copyright (C) 1994-2008 Lua.org, PUC-Rio" + + +-- Note: don't allow user scripts to change implementation. +-- Check for globals with "cat lua.lua | luac -p -l - | grep ETGLOBAL" +local _G = _G +local assert = assert +local collectgarbage = collectgarbage +local loadfile = loadfile +local loadstring = loadstring +local pcall = pcall +local rawget = rawget +local select = select +local tostring = tostring +local type = type +local unpack = unpack +local xpcall = xpcall +local io_stderr = io.stderr +local io_stdout = io.stdout +local io_stdin = io.stdin +local string_format = string.format +local string_sub = string.sub +local os_getenv = os.getenv +local os_exit = os.exit + + +local progname = LUA_PROGNAME + +-- Use external functions, if available +local lua_stdin_is_tty = function() return true end +local setsignal = function() end + +local function print_usage() + io_stderr:write(string_format( + "usage: %s [options] [script [args]].\n" .. + "Available options are:\n" .. + " -e stat execute string " .. LUA_QL("stat") .. "\n" .. + " -l name require library " .. LUA_QL("name") .. "\n" .. + " -i enter interactive mode after executing " .. + LUA_QL("script") .. "\n" .. + " -v show version information\n" .. + " -- stop handling options\n" .. + " - execute stdin and stop handling options\n" + , + progname)) + io_stderr:flush() +end + +local function l_message (pname, msg) + if pname then io_stderr:write(string_format("%s: ", pname)) end + io_stderr:write(string_format("%s\n", msg)) + io_stderr:flush() +end + +local function report(status, msg) + if not status and msg ~= nil then + msg = (type(msg) == 'string' or type(msg) == 'number') and tostring(msg) + or "(error object is not a string)" + l_message(progname, msg); + end + return status +end + +local function tuple(...) + return {n=select('#', ...), ...} +end + +local function traceback (message) + local tp = type(message) + if tp ~= "string" and tp ~= "number" then return message end + local debug = _G.debug + if type(debug) ~= "table" then return message end + local tb = debug.traceback + if type(tb) ~= "function" then return message end + return tb(message, 2) +end + +local function docall(f, ...) + local tp = {...} -- no need in tuple (string arguments only) + local F = function() return f(unpack(tp)) end + setsignal(true) + local result = tuple(xpcall(F, traceback)) + setsignal(false) + -- force a complete garbage collection in case of errors + if not result[1] then collectgarbage("collect") end + return unpack(result, 1, result.n) +end + +local function dofile(name) + local f, msg = loadfile(name) + if f then f, msg = docall(f) end + return report(f, msg) +end + +local function dostring(s, name) + local f, msg = loadstring(s, name) + if f then f, msg = docall(f) end + return report(f, msg) +end + +local function dolibrary (name) + return report(docall(_G.require, name)) +end + +local function print_version() + l_message(nil, LUA_RELEASE .. " " .. LUA_COPYRIGHT) +end + +local function getargs (argv, n) + local arg = {} + for i=1,#argv do arg[i - n] = argv[i] end + if _G.arg then + local i = 0 + while _G.arg[i] do + arg[i - n] = _G.arg[i] + i = i - 1 + end + end + return arg +end + +--FIX? readline support +local history = {} +local function saveline(s) +-- if #s > 0 then +-- history[#history+1] = s +-- end +end + + +local function get_prompt (firstline) + -- use rawget to play fine with require 'strict' + local pmt = rawget(_G, firstline and "_PROMPT" or "_PROMPT2") + local tp = type(pmt) + if tp == "string" or tp == "number" then + return tostring(pmt) + end + return firstline and LUA_PROMPT or LUA_PROMPT2 +end + + +local function incomplete (msg) + if msg then + local ender = LUA_QL("") + if string_sub(msg, -#ender) == ender then + return true + end + end + return false +end + + +local function pushline (firstline) + local prmt = get_prompt(firstline) + io_stdout:write(prmt) + io_stdout:flush() + local b = io_stdin:read'*l' + if not b then return end -- no input + if firstline and string_sub(b, 1, 1) == '=' then + return "return " .. string_sub(b, 2) -- change '=' to `return' + else + return b + end +end + + +local function loadline () + local b = pushline(true) + if not b then return -1 end -- no input + local f, msg + while true do -- repeat until gets a complete line + f, msg = loadstring(b, "=stdin") + if not incomplete(msg) then break end -- cannot try to add lines? + local b2 = pushline(false) + if not b2 then -- no more input? + return -1 + end + b = b .. "\n" .. b2 -- join them + end + + saveline(b) + + return f, msg +end + + +local function dotty () + local oldprogname = progname + progname = nil + while true do + local result + local status, msg = loadline() + if status == -1 then break end + if status then + result = tuple(docall(status)) + status, msg = result[1], result[2] + end + report(status, msg) + if status and result.n > 1 then -- any result to print? + status, msg = pcall(_G.print, unpack(result, 2, result.n)) + if not status then + l_message(progname, string_format( + "error calling %s (%s)", + LUA_QL("print"), msg)) + end + end + end + io_stdout:write"\n" + io_stdout:flush() + progname = oldprogname +end + + +local function handle_script(argv, n) + _G.arg = getargs(argv, n) -- collect arguments + local fname = argv[n] + if fname == "-" and argv[n-1] ~= "--" then + fname = nil -- stdin + end + local status, msg = loadfile(fname) + if status then + status, msg = docall(status, unpack(_G.arg)) + end + return report(status, msg) +end + + +local function collectargs (argv, p) + local i = 1 + while i <= #argv do + if string_sub(argv[i], 1, 1) ~= '-' then -- not an option? + return i + end + local prefix = string_sub(argv[i], 1, 2) + if prefix == '--' then + if #argv[i] > 2 then return -1 end + return argv[i+1] and i+1 or 0 + elseif prefix == '-' then + return i + elseif prefix == '-i' then + if #argv[i] > 2 then return -1 end + p.i = true + p.v = true + elseif prefix == '-v' then + if #argv[i] > 2 then return -1 end + p.v = true + elseif prefix == '-e' then + p.e = true + if #argv[i] == 2 then + i = i + 1 + if argv[i] == nil then return -1 end + end + elseif prefix == '-l' then + if #argv[i] == 2 then + i = i + 1 + if argv[i] == nil then return -1 end + end + else + return -1 -- invalid option + end + i = i + 1 + end + return 0 +end + + +local function runargs(argv, n) + local i = 1 + while i <= n do if argv[i] then + assert(string_sub(argv[i], 1, 1) == '-') + local c = string_sub(argv[i], 2, 2) -- option + if c == 'e' then + local chunk = string_sub(argv[i], 3) + if chunk == '' then i = i + 1; chunk = argv[i] end + assert(chunk) + if not dostring(chunk, "=(command line)") then return false end + elseif c == 'l' then + local filename = string_sub(argv[i], 3) + if filename == '' then i = i + 1; filename = argv[i] end + assert(filename) + if not dolibrary(filename) then return false end + end + i = i + 1 + end end + return true +end + + +local function handle_luainit() + local init = os_getenv(LUA_INIT) + if init == nil then + return -- status OK + elseif string_sub(init, 1, 1) == '@' then + dofile(string_sub(init, 2)) + else + dostring(init, "=" .. LUA_INIT) + end +end + + +local import = _G.import +if import then + lua_stdin_is_tty = import.lua_stdin_is_tty or lua_stdin_is_tty + setsignal = import.setsignal or setsignal + LUA_RELEASE = import.LUA_RELEASE or LUA_RELEASE + LUA_COPYRIGHT = import.LUA_COPYRIGHT or LUA_COPYRIGHT + _G.import = nil +end + +if _G.arg and _G.arg[0] and #_G.arg[0] > 0 then progname = _G.arg[0] end +local argv = {...} +handle_luainit() +local has = {i=false, v=false, e=false} +local script = collectargs(argv, has) +if script < 0 then -- invalid args? + print_usage() + os_exit(1) +end +if has.v then print_version() end +local status = runargs(argv, (script > 0) and script-1 or #argv) +if not status then os_exit(1) end +if script ~= 0 then + status = handle_script(argv, script) + if not status then os_exit(1) end +else + _G.arg = nil +end +if has.i then + dotty() +elseif script == 0 and not has.e and not has.v then + if lua_stdin_is_tty() then + print_version() + dotty() + else dofile(nil) -- executes stdin as a file + end +end + diff --git a/LuaSL/testLua/yueliang-0.4.1/COPYRIGHT b/LuaSL/testLua/yueliang-0.4.1/COPYRIGHT new file mode 100644 index 0000000..0290bff --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/COPYRIGHT @@ -0,0 +1,39 @@ +Yueliang License +---------------- + +Yueliang is licensed under the terms of the MIT license reproduced +below. This means that Yueliang is free software and can be used +for both academic and commercial purposes at absolutely no cost. + +Yueliang is based on Lua 5 code. See COPYRIGHT_Lua5 (Lua 5.0.3) and +COPYRIGHT_Lua51 (Lua 5.1.3) for Lua 5 license information. + +For details and rationale, see http://www.lua.org/license.html . + +=============================================================================== + +Yueliang Copyright (C) 2005-2008 Kein-Hong Man +Lua 5.0.3 Copyright (C) 2003-2006 Tecgraf, PUC-Rio. +Lua 5.1.3 Copyright (C) 1994-2008 Lua.org, PUC-Rio. + +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. + +=============================================================================== + +(end of COPYRIGHT) diff --git a/LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua5 b/LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua5 new file mode 100644 index 0000000..2cd57d3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua5 @@ -0,0 +1,34 @@ +Lua License +----------- + +Lua is licensed under the terms of the MIT license reproduced below. +This means that Lua is free software and can be used for both academic +and commercial purposes at absolutely no cost. + +For details and rationale, see http://www.lua.org/license.html . + +=============================================================================== + +Copyright (C) 2003-2006 Tecgraf, PUC-Rio. + +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. + +=============================================================================== + +(end of COPYRIGHT) diff --git a/LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua51 b/LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua51 new file mode 100644 index 0000000..3a53e74 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/COPYRIGHT_Lua51 @@ -0,0 +1,34 @@ +Lua License +----------- + +Lua is licensed under the terms of the MIT license reproduced below. +This means that Lua is free software and can be used for both academic +and commercial purposes at absolutely no cost. + +For details and rationale, see http://www.lua.org/license.html . + +=============================================================================== + +Copyright (C) 1994-2008 Lua.org, PUC-Rio. + +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. + +=============================================================================== + +(end of COPYRIGHT) diff --git a/LuaSL/testLua/yueliang-0.4.1/Changelog b/LuaSL/testLua/yueliang-0.4.1/Changelog new file mode 100644 index 0000000..60faa5e --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/Changelog @@ -0,0 +1,680 @@ +yueliang changelog +------------------ + +2008-05-31 Kein-Hong Man + + * nat-5.0.3/README: updated notes + * nat-5.1.3/README: updated notes + * Manifest: updated + * README: updated + * Version: 0.4.1 + +2008-05-31 Kein-Hong Man + + * test/test_lparser_mk3_2.lua: added better parser tester that + covers whole grammar, all tests passes + * test/test_lparser_mk3_2.lua: added better parser tester that + covers whole grammar, all tests passes + * nat-5.0.3/test/bench_llex_mk2.lua, nat-5.0.3/test/bench_llex_mk3.lua, + nat-5.0.3/test/bench_llex_mk4.lua, nat-5.0.3/test/test_lzio_mk2.lua, + nat-5.0.3/test/test_lparser_mk3.lua, nat-5.0.3/test/test_lparser_mk3b.lua, + nat-5.0.3/test/test_llex_mk2.lua, nat-5.0.3/test/test_llex_mk3.lua, + nat-5.0.3/test/test_llex_mk4.lua: + adjusted require() call to loose .lua extension, better? + * nat-5.0.3/README: updated info + * orig-5.0.3/test/test_ldump.lua, orig-5.0.3/test/test_llex.lua, + orig-5.0.3/test/bench_llex.lua, orig-5.0.3/test/test_lparser.lua, + orig-5.0.3/test/test_number.lua, orig-5.0.3/test/test_lparser2.lua, + orig-5.0.3/test/test_lzio.lua, test_lua/test_scripts-5.0.lua: + adjusted require() call to loose .lua extension, better? + * orig-5.0.3/test/test_llex.lua: fixed minor change in test case + output, probably something changed between 5.0.2 and 5.0.3 + * nat-5.1.3/test/test_lparser_mk2_2.lua: added better parser tester + that covers whole grammar, all tests passes + +2008-05-29 Kein-Hong Man + + * nat-5.1.3/lparser_mk2.lua: bug, binopr_* missing '%' operator + +2008-05-28 Kein-Hong Man + + * nat-5.1.3/lparser_mk2.lua: bug, unopr[] missing '#' operator + +2008-05-23 Kein-Hong Man + + * orig-5.0.3/test/test_llex.lua: removed duplicate test entry + * orig-5.1.3/test/test_llex.lua: removed duplicate test entry + * nat-5.0.3/test/test_llex_mk2.lua: removed duplicate test entry + * nat-5.0.3/test/test_llex_mk3.lua: removed duplicate test entry + * nat-5.0.3/test/test_llex_mk4.lua: removed duplicate test entry + * nat-5.1.3/test/test_llex_mk2.lua: removed duplicate test entry + +2008-05-22 Kein-Hong Man + + * nat-5.1.3/lparser_mk2.lua: finish debugging, all test sample + appear to work + * nat-5.1.3/test/test_lparser_mk2.lua: added test script, works + * nat-5.1.3/test/parser_log/sample_*.lua: added parser output + log message samples + * nat-5.1.3/README: updated notes + * Manifest: updated + * README: updated + * OlderNews: updated + * Version: 0.4.0 + +2008-05-22 Kein-Hong Man + + * nat-5.1.3/lparser_mk2.lua (init): mistake in naming llex.llex + * nat-5.1.3/lparser_mk2.lua (str_checkname): forgot to remove + original C parameter 'ls' in call to check() + * nat-5.1.3/lparser_mk2.lua (constructor): missed name change + from luaX to llex + * nat-5.1.3/lparser_mk2.lua: added a local _G for *_stat lookups + * nat-5.1.3/lparser_mk2.lua (test_then_block): v parm not needed + * nat-5.1.3/lparser_mk2.lua (cond): v parm not needed, added + a local v creation before calling expr() in body, removed not + needed v creation in functions that call cond() + * nat-5.1.3/lparser_mk2.lua (simpleexp): check_condition() for + fs.is_vararg, wrong sense + * nat-5.1.3/lparser_mk2.lua: reset top_fs each time initialized; + added forward references for local functions + +2008-05-20 Kein-Hong Man + + * nat-5.1.3/lparser_mk2.lua: new file, bits and pieces for + native 5.1.x parser, ongoing + * nat-5.1.3/lparser_mk2.lua: completed initial coding, + untested + +2008-05-20 Kein-Hong Man + + * nat-5.0.3/README: updated with caveats about line ending + normalization in strings and long strings + * nat-5.1.3/README: updated notes + * README: updated + * Version: 0.3.2 + +2008-05-20 Kein-Hong Man + + * nat-5.1.3/test/test_llex_mk2.lua: native 5.1.x lexer tester + * nat-5.1.3/test/test_llex_mk2.lua: deleted deprecated tests + * nat-5.1.3/llex_mk2.lua: adjusted require call + * nat-5.1.3/llex_mk2.lua: made sourceid handling more robust + * nat-5.1.3/llex_mk2.lua (llex): mistake in porting code from + 5.0.x native lexer -- variable kept as q when it was renamed p + * nat-5.1.3/llex_mk2.lua (read_long_string): missing reassign + main value I of lexing position for ']' negative test + * nat-5.1.3/llex_mk2.lua (read_long_string): missing add string + segment to buffer for ']' negative test + * nat-5.1.3/llex_mk2.lua (read_string): fixed \xxx sequence + conversion from number to string, forgot how old code worked + * nat-5.1.3/llex_mk2.lua: works + * nat-5.1.3/test/test_llex_mk2.lua: all tests run + * nat-5.1.3/README: updated + +2008-05-19 Kein-Hong Man + + * nat-5.1.3/: created for 5.1.x lexer/parser work + * nat-5.1.3/test: created for test scripts + * nat-5.1.3/llex_mk2.lua: preliminary native lexer for Lua 5.1.x + complete (except for next() and lookahead()), untested + * nat-5.1.3/README: added + +2008-05-19 Kein-Hong Man + + * orig-5.0.3/lparser.lua: added comments for calls + * nat-5.0.3/lparser_mk3b.lua: new native parser, same as + lparser_mk3.lua except with variable management code added + * nat-5.0.3/test/test_lparser_mk3b.lua: new test script, + started testing variable management code + * nat-5.0.3/lparser_mk3b.lua (luaY:new_localvar, luaY:searchvar): + fixed var lookup bug due to fs.bl=nil at function top level + * nat-5.0.3/lparser_mk3b.lua (luaY:singlevaraux): fixed bug due + to wrong name used, 'v' instead of the correct 'var' + * nat-5.0.3/lparser_mk3b.lua: fixed extra 'ls' parms that ought + to be removed, when adding code to manage variables; copied from + lparser.lua without thinking + * nat-5.0.3/test/parser_log/sample_b_*.lua: added log samples + * nat-5.0.3/README: updated + * Manifest: updated for parser log samples + * README: updated + * OlderNews: updated + * Version: 0.3.1 + +2008-04-13 Kein-Hong Man + + * nat-5.0.3/test/parser_log/: new subdirectory for log samples + * nat-5.0.3/test/parser_log/sample_*.lua: added log samples + * nat-5.0.3/README: updated + * Manifest: updated for parser log samples + * test_lua/files-yueliang-5.1.txt: updated directory name change + * README: updated + * Version: 0.3.0 + +2008-04-13 Kein-Hong Man + + * nat-5.0.3/test/test_lparser_mk3.lua: if_stat tests, + return_stat tests, while_stat tests, repeat_stat tests + * nat-5.0.3/lparser_mk3.lua: logging for if_stat, + return_stat, while_stat, repeat_stat, and comment tweaks + * nat-5.0.3/test/test_lparser_mk3.lua: tests for break_stat, + for_stat, local_stat, function_stat, anonymous functions, + table constructors + * nat-5.0.3/lparser_mk3.lua: logging written for break_stat, + for_stat, local_stat, function_stat, anonymous functions, + table constructors + * nat-5.0.3/lparser_mk3.lua (luaY:localfunc): missing struct b + * nat-5.0.3/lparser_mk3.lua: everything seems to work + +2008-04-12 Kein-Hong Man + + * nat-5.0.3/test/test_lparser_mk3.lua: basic expr tests + * nat-5.0.3/lparser_mk3.lua: logging for expressions mostly + done, fixed bugs in luaY:subexpr caused by simplification of + orig-5.0.3 sources, seems okay now + * nat-5.0.3/README: updated + * Manifest: updated + * README: updated + * Version: 0.2.4 + +2008-04-12 Kein-Hong Man + + * nat-5.0.3/test/test_lparser_mk3.lua: added log message + dumper function, added test script exerciser + * nat-5.0.3/lparser_mk3.lua (luaY:open_func): tweaked to + allow early logging + * nat-5.0.3/lparser_mk3.lua: added some logging messages + * nat-5.0.3/test/test_lparser_mk3.lua: added output indenter + * nat-5.0.3/lparser_mk3.lua (luaY:syntaxerror): bug, ref + to self.tok when it should be tok + * nat-5.0.3/lparser_mk3.lua: more logging messages, tests + +2008-04-12 Kein-Hong Man + + * nat-5.0.3/lparser_mk3.lua: removed old attempt at + writing a native parser skeleton + * nat-5.0.3/lparser_mk3.lua: added preliminary new + native 5.0.3 parser skeleton + * nat-5.0.3/test/test_lparser_mk3.lua: renamed from + test_lparser.lua to match mk numbering + * nat-5.0.3/lparser_mk3.lua (luaY:next): missing 'end' + * nat-5.0.3/test/test_lparser_mk3.lua: runs, no die + +2008-04-10 Kein-Hong Man + + * nat-5.0.3/test/test_lparser.lua: new, preliminary native + parser test code + * nat-5.0.3/lparser_mk3.lua: fixed regex for binary + operator priority string + * nat-5.0.3/lparser_mk3.lua: renamed variable clash + with function peek -> peek_tok, added missing init + * nat-5.0.3/lparser_mk3.lua: function name clash, + one changed to localstat -> localdeclstat + * nat-5.0.3/test/test_lparser.lua: passed simple string + * nat-5.0.3/test/sample.lua: added test file + * nat-5.0.3/test/test_lparser.lua: added longer test, fail + * nat-5.0.3/lparser_mk3.lua (luaY:subexpr): inconsistent + call parameters, might prefer to rewrite whole thing + +2008-04-09 Kein-Hong Man + + * orig-5.1.2/lcode.lua (luaK:prefix): 5.1.3 fix + * orig-5.1.2/lparser.lua (luaY:assignment): 5.1.3 fix + * orig-5.1.3: renamed from orig-5.1.2, updated names + * orig-5.1.3/README: updated + * COPYRIGHT, COPYRIGHT_Lua51: updated year + * README: updated + * Version: 0.2.3 + +2007-11-21 Kein-Hong Man + + * orig-5.1.1/lparser.lua (luaY:listfield): 5.1.2 fixes + * orig-5.1.1/lcode.lua (luaK:infix, luaK:codearith, + luaK:_nil): 5.1.2 fixes + * orig-5.1.2: renamed from orig-5.1.1, updated names + * COPYRIGHT, COPYRIGHT_Lua51: updated + * README: updated + * test_lua/files-*, README: directory name adjustment + * test_lua/5.0, 5.1: renamed from 5.0.3, 5.1.1 + * test_lua: renamed files, adjusted directory references + * Version: 0.2.2 + +2006-11-28 Kein-Hong Man + + * orig-5.0.3/test/test_lparser2.lua: added option to dump + all error messages for failure cases, to check whether test + cases trip the parser where intended + * orig-5.1.1/test/test_lparser2.lua: ditto + +2006-11-27 Kein-Hong Man + + * test_lua/README: updated + * orig-5.0.3/README: updated + * orig-5.1.1/README: updated + * Manifest: updated + * README: updated + * COPYRIGHT: updated version number + * Version: 0.2.1 + +2006-11-27 Kein-Hong Man + + * test_lua/test_parser-5.1.lua: parser test case file + for Lua 5.1.x + * orig-5.1.1/test/test_lparser2.lua: added a parser tester + for the 5.1.1 front end, fixed one bug, 524 tests passed + * orig-5.1.1/lparser.lua (luaY:simpleexp): fixed test + on fs.f.is_vararg, numerical not boolean + +2006-11-27 Kein-Hong Man + + * nat-5.0.3/lparser_mk3.lua: updated expression type + information passing, needed to detect VCALLs + * test_lua/test_parser-5.0.lua: preliminary parser test + case file for Lua 5.0.x + * test_lua/test_parser-5.0.lua: fixed use of [==[! + * test_lua/test_parser-5.0.lua: updated test cases after + verifying with native Lua + * orig-5.0.3/test/test_lparser2.lua: added a parser tester + for the 5.0.3 front end, 503 tests passed + * nat-5.0.3/README: updated with info on lparser_mk3.lua + +2006-11-23 Kein-Hong Man + + * orig-5.0.3/lparser.lua: fixed comment typo + * orig-5.1.1/lparser.lua: fixed comment typo + * nat-5.0.3/lparser_mk3.lua: preliminary parser skeleton + +2006-11-22 Kein-Hong Man + + * test_lua/README: updated with test status + * test_lua/files-yueliang-5.0.3.txt: updated filenames + * test_lua/files-yueliang-5.1.1.txt: added for 5.1.1 + * test_lua/files-lua-5.1.1.txt: added for 5.1.1 + * test_lua/files-other-5.1.1.txt: added for 5.1.1 + * test_lua/test_scripts: to accomodate 5.1.1 material, + renamed to test_lua/test_scripts-5.0.3.lua + * test_lua/test_scripts-5.1.1.lua: added, after debugging, + all files compiled successfully + * Manifest: updated + * README: updated + * Version: 0.2.0 + +2006-11-22 Kein-Hong Man + + * orig-5.1.1/lparser.lua (luaY:parlist): missing 'self', + (luaY:test_then_block): missing 'self', + (luaY:yindex) check should be checknext, + (luaY:adjustlocalvars) nvars should be loop index i + * orig-5.1.1/lcode.lua (luaK:addk): redo fs.h[] code, + (luaK:nilK) forgot to change from old name nil_constant + (luaK:posfix) copyexp() added to copy expdesc structs + (luaK:patchlistaux) incorrectly placed loop iterator + * orig-5.1.1/lparser.lua: + (luaY:breakstat) luaK:concat returns a value! + (luaY:new_localvarliteral) forgot to correct parameter + (luaY:ifstat) luaK:concat returns a value! + (luaY:whilestat) typo, "whileint" + (luaY:simpleexp) missing 'self' for VARARG_NEEDSARG + (luaY:repeatstat) type, "zself" + (luaY:repeatstat) failed to clear away old code + * orig-5.1.1/lcode.lua: (luaK:constfolding): missing 'self' + (luaK:isnumeral) incorrect type of NO_JUMP + (luaK:need_value) missing interator converting for loop + * orig-5.1.1/llex.lua (luaX:next): must be copy-by-value + (luaK:patchtestreg) cannot replace an inst table + * orig-5.1.1/ldump.lua (luaU:DumpConstants): typo for + constant name, LUA_BOOLEAN -> LUA_TBOOLEAN + +2006-11-22 Kein-Hong Man + + * orig-5.1.1/test/bench_llex.lua: added performance + tester for Lua 5.1.1 lexer + * orig-5.1.1/README: added preliminary performance data + * orig-5.1.1/lparser.lua: debugging, + (luaY:checklimit) missing 'end' + (luaY:repeatstat) extra 'end' + (luaY:parser) added nCcalls initialization for LuaState + (luaY:exprstat) should be luaK:getcode + * orig-5.1.1/llex.lua: debugging, luaX:lex renamed to + luaX:llex to follow Lua 5.1.1 + * orig-5.1.1/test/test_llex.lua: luaX:lex -> luaX:llex + * orig-5.1.1/test/bench_llex.lua: luaX:lex -> luaX:llex + * orig-5.1.1/lcode.lua: debugging, + (luaK:addK) adjusted value storage, removed setnvalue call + (luaK:codeABC) luaP instead of self, 2 cases + * orig-5.1.1/lopcodes.lua: fixed string parameter type for + instruction information lookup functions, + (luaP:ISK) fixed MSB bit testing to denote constants + (luaP:Instruction) fixed instruction encoding into bytes + +2006-11-21 Kein-Hong Man + + * orig-5.0.3/lcode.lua: noted failed assert, adjusted + names of set*value lobject.h macros + * README: noted two cases needing following up: a failed + assert (see above) and a missing luaG_checkcode() + * orig-5.1.1/lopcodes.lua: added luaP:CREATE_Inst(c) for + luaK:setlist, implementation of OP_SETLIST + * orig-5.1.1/lcode.lua: added preliminary ported file + +2006-11-21 Kein-Hong Man + + * orig-5.1.1/lparser.lua: added preliminary ported file + * orig-5.1.1/lparser.lua: fixed syntax porting bugs (3): + (luaY:hasmultret): || changed to or in return statement + (luaY:indexupvalue): || changed to or in assert statement + (luaY:singlevaraux): missing return before return value + +2006-11-17 Kein-Hong Man + + * Manifest: updated + * README: updated + * Version: 0.1.4 + +2006-11-17 Kein-Hong Man + + * orig-5.1.1/ldump.lua: removed string.len in 2 places + * orig-5.0.3/lopcodes.lua: (luaP:DecodeInst) comments + adjusted, a regexp changed elsewhere + * orig-5.1.1/ldump.lua: fixed porting bug (function name) + * orig-5.1.1/test/test_ldump.lua: tested binary dumper + * orig-5.1.1/test/test_llex.lua: tested lexer, developed + new test cases to cover changes in Lua 5.1.x + * orig-5.1.1/llex.lua: fixed bugs in lexer in order to + run test cases successfully + (luaX:token2str) variable c should be token + (luaX:lexerror) incorrect call to luaX:chunkid + (luaX:read_numeral) scanning bug, %w captures EOZ too + (luaX:read_long_string) LUA_COMPAT_LSTR is in self + (luaX:lex) incorrect variable used in keyword lookup + * orig-5.0.3/lopcodes.lua: changed a gfind to gmatch + * test_llex*.lua: some tweaks to printout statement + +2006-11-17 Kein-Hong Man + + * orig-5.1.1/ldump.lua: added binary chunk dumper + * orig-5.1.1/README: added preliminary information + * orig-5.1.1/test/test_lzio.lua: tested chunk reader + * orig-5.1.1/test/test_number.lua: tested number conversion + * test_number.lua: added FLT_MIN, FLT_MAX test values for + completeness, in case conversion to float is needed + +2006-11-16 Kein-Hong Man + + * test_lua/5.0.2: directory renamed to test_lua/5.0.3 + * test_lua: front end test script and associated files + updated for 5.0.3 + * orig-5.0.2: directory renamed to orig-5.0.3, some + references to 5.0.2 changed + * nat-5.0.2: directory renamed to nat-5.0.3, some + references to 5.0.2 changed + * orig-5.1: directory renamed to orig-5.1.1, some + references to 5.1 changed + +2006-11-16 Kein-Hong Man + + * orig-5.0.2/lcode.lua: updating to Lua 5.0.3, this is the + only front end file in orig-5.0.2 that has changed; + (luaK:need_value): body changed + (luaK:removevalues): new function, used in luaK:codenot + (luaK:patchlistaux): definition and body changed + (luaK:dischargejpc): body changed (due to luaK:patchlistaux) + (luaK:patchlist): body changed (due to luaK:patchlistaux) + (luaK:exp2reg): body changed (due to luaK:patchlistaux) + (luaK:jumponcond): body changed + (luaK:codenot): body changed (added luaK:removevalues) + +2006-11-16 Kein-Hong Man + + * test_lua: moved 5.0.2 sample scripts to its own directory + * test_lua/test_scripts.lua: adjusted file paths of sample + files used for parser testing + * test_lua/test_scripts.lua: changed file list specification + to load several separate files for better flexibility and + easier maintenance + * test_lua/files-lua-5.0.2.txt: added sample file list + * test_lua/files-other-5.0.2.txt: added sample file list + * test_lua/files-yueliang-5.0.2.txt: added sample file list + * test_lua/README: updated + * Manifest: updated + +2006-11-13 Kein-Hong Man + + * orig-5.0.2/lcode.lua: added function comments + +2006-11-13 Kein-Hong Man + + * orig-5.0.2/test/bench_llex.lua: simple lexer benchmark + * nat-5.0.2/test/bench_llex_mk2.lua: adapted for mk2 lexer + * nat-5.0.2/test/bench_llex_mk3.lua: adapted for mk3 lexer + * nat-5.0.2/test/bench_llex_mk4.lua: adapted for mk4 lexer + * nat-5.0.2/README: added lexer benchmark results + +2006-11-11 Kein-Hong Man + + * Manifest: updated + * README: updated + * Version: 0.1.3 + +2006-11-11 Kein-Hong Man + + * nat-5.0.2/llex_mk3.lua: further size optimization work on + new lexer, down to 3286 bytes (stripped) + * nat-5.0.2/llex_mk3.lua: fixed bug in short comment handling + * nat-5.0.2/README: added information for native lexers + * nat-5.0.2/llex_mk4.lua: line-based native lexer, see size + performance data in README + * nat-5.0.2/lzio_mk4.lua: line-based stream reader function + * nat-5.0.2/test/test_llex_mk4.lua: adapted version of test + cases, all tests passed + +2006-11-10 Kein-Hong Man + + * orig-5.0.2/lparser.lua: added comments for parser + functions, one or more visual tweaks, no code changes + +2006-11-09 Kein-Hong Man + + * nat-5.0.2/llex_mk3.lua: new minimal size lexer, but takes + in all the source code at once, 3346 bytes (stripped) + * nat-5.0.2/test/test_llex_mk3.lua: adapted version of test + cases, all tests passed + +2006-11-08 Kein-Hong Man + + * nat-5.0.2/lzio_mk2.lua: renamed from lzio.lua + * nat-5.0.2/test/test_lzio_mk2.lua: renamed from test_lzio.lua + * nat-5.0.2/llex_mk2.lua: renamed from llex.lua + * nat-5.0.2/test/test_llex_mk2.lua: renamed from test_llex.lua + +2006-03-27 Kein-Hong Man + + * nat-5.0.2/llex.lua: optimizations to reduce file size, + size down to 4003 bytes (stripped) from 4155 bytes + +2006-03-27 Kein-Hong Man + + * orig-5.1: lzio.lua: minor formatting change + * orig-5.0.2/test/test_llex.lua: fix filename spec + * nat-5.0.2/lzio.lua: new simplified 'native' version + * nat-5.0.2/test/test_lzio.lua: test for the above + * nat-5.0.2/llex.lua: new simplified 'native' version + * nat-5.0.2/test/test_llex.lua: test for the above + +2006-03-25 Kein-Hong Man + + * orig-5.0.2/llex.lua: typo fix + * orig-5.1/llex.lua: Lua 5.1 lexer + * Manifest: updated + +2006-03-23 Kein-Hong Man + + * orig-5.0.2/tools/call_graph.lua: added display of contents + of expdesc structures + +2006-03-23 Kein-Hong Man + + * orig-5.1: new directory for 5.1 front-end + * orig-5.1/lzio.lua: Lua 5.1 input stream reader + * COPYRIGHT: updated with Lua 5.1 information + * COPYRIGHT_Lua51: added for Lua 5.1 + * Manifest: updated + * orig-5.0.2/lzio.lua: updated comments + * orig-5.1/lzio.lua (luaZ:fill): fixed porting bug + +2005-05-04 Kein-Hong Man + + * orig-5.0.2/tools/sample_expr.lua: a Lua-style expression + parsing interactive demonstrator + * orig-5.0.2/tools/sample_expr.lua: fixed parsing bugs, + (1) unop subexpr, (2) assign to op before testing for binop + * orig-5.0.2/lparser.lua: fixed some comments which have + incorrect description of Lua syntax + +2005-04-18 Kein-Hong Man + + * Version: 0.1.2 + +2005-04-17 Kein-Hong Man + + * orig-5.0.2/lparser.lua: added descriptive comments for some + expression parsing functions + * orig-5.0.2/test/test_number.lua: test cases for number + conversion functions in ldump.lua + * test_lua/test_scripts.lua: updated with some new test entries + * orig-5.0.2/ldump.lua (luaU:from_double): added support for + +/- infinity + +2005-04-14 Kein-Hong Man + + * moved project to a Subversion repository + +2005-03-24 Kein-Hong Man + + * orig-5.0.2/lopcodes.lua: added luaP:DecodeInst to decode + instruction from a 4-char string + * orig-5.0.2/lopcodes.lua (getOpMode, testOpMode): add 'self.' + +2005-03-22 Kein-Hong Man + + * orig-5.0.2/tools/call_graph.lua: added comments, check for + namespace collision when selecting new name for orig function + * test_lua/test_scripts.lua: added comments, some test files + +2005-03-21 Kein-Hong Man + + * orig-5.0.2/tools/call_graph.lua: added allow/deny of specific + functions, display of return values + * orig-5.0.2/tools/calls.log: sample output + * Version: 0.1.1 + +2005-03-20 Kein-Hong Man + + * orig-5.0.2/tools/call_graph.lua: added script to generate + a call graph from selected modules + +2005-03-19 Kein-Hong Man + + * README: added some size statistics for comparison + * test_lua/README: updated description + * orig-5.0.2/README: added notes + * orig-5.0.2/lzio.lua: fixed bug when calling zgetc after + EOF for a file chunk reader (Thanks to Adam429) + * orig-5.0.2/test/test_lzio.lua: added manual test for above + +2005-03-17 Kein-Hong Man + + * orig-5.0.2/lparser.lua (indexupvalue): struct expdesc copy + * orig-5.0.2/luac.lua: simple luac; can compile luac.lua + * orig-5.0.2/lparser.lua (assignment, constructor): missing + 'self:' + * test_lua: added sample Lua scripts from Lua 5.0.2 + * test_lua/README: add source attribution for example scripts + * orig-5.0.2/lcode.lua (arith_opc): typo OP_MULT -> OP_MUL + * orig-5.0.2/ldump.lua (DumpString): fixed handling for "" + * orig-5.0.2/ldump.lua (DumpFunction): fixed f.source handling + * orig-5.0.2/lcode.lua (jump, codebinop): 'luaK:' -> 'self:' + * orig-5.0.2/lcode.lua (need_value, exp2reg): comparison of + boolean cond with 0/1 C field, changed back to all 0/1 + * orig-5.0.2/lzio.lua (init): test for nil reader argument + * test_lua/test_scripts.lua: Lua 5.0.2 examples all compiles + correctly, as does Yueliang files + * orig-5.0.2/lzio.lua (make_getF): changed file mode to "r" + so that chunk reader behaves like luac for \r\n-style files + * test_lua/test_scripts.lua: added Lua code from LuaSrcDiet, + SciTELuaExporters, ChunkBake, ChunkSpy, all works + * README: preliminary documentation + * some pre-release cosmetic changes + * initial public release + * Version: 0.1.0 + +2005-03-16 Kein-Hong Man + + * orig-5.0.2/test/test_lparser.lua: basic parser/codegen test + * orig-5.0.2/lparser.lua: added FuncState.actvar = {} init + * orig-5.0.2/lcode.lua (ttisnumber): handle nil entries + * orig-5.0.2/lopcodes.lua (getOpMode): string opcode parm + * orig-5.0.2/lcode.lua (exp2reg): missing 'self:' prefixes + * orig-5.0.2/lopcodes.lua (CREATE_ABC, CREATE_ABx): convert + string opcode representation to number when storing in field OP + * orig-5.0.2/lcode.lua (setsvalue, setnvalue, sethvalue): + missing second argument cause addk to fail + * orig-5.0.2/lparser.lua (check_match): missing 'self:' + * orig-5.0.2/test/test_lparser.lua: two simple tests successful + * orig-5.0.2/lcode.lua (exp2val, exp2anyreg, invertjump): + missing 'self:' + * orig-5.0.2/lparser.lua (parlist, subexpr): missing 'self:' + * orig-5.0.2/lopcodes.lua (testOpMode): string opcode parm + * orig-5.0.2/lparser.lua (subexpr): convert string operator name + to BinOpr number when looking up binop operator priority + * orig-5.0.2/lparser.lua (adjustlocalvars): wrong loop index + * orig-5.0.2/lcode.lua (addk): fixed constant lookup + +2005-03-15 Kein-Hong Man + + * orig-5.0.2/lcode.lua: completed porting (untested) + * orig-5.0.2/ldump.lua: completed porting (untested) + * orig-5.0.2/test/test_ldump.lua: added chunk writer tests + * orig-5.0.2/test/test_ldump.lua: basic test writing binary + chunk from a simple function prototype table successful + +2005-03-14 Kein-Hong Man + + * orig-5.0.2/lparser.lua: updated representation of constants + * orig-5.0.2/lopcodes.lua: completed porting (untested) + * orig-5.0.2/test_lzio.lua: moved to orig-5.0.2/test subdir + * orig-5.0.2/test_llex.lua: moved to orig-5.0.2/test subdir + +2005-03-13 Kein-Hong Man + + * orig-5.0.2/lparser.lua: completed porting (untested), + can't be tested without lcode/ldump + +2005-03-11 Kein-Hong Man + + * orig-5.0.2/test_llex.lua: added manual test for llex.lua + * orig-5.0.2/llex.lua: code review; put Token parameter to + replace seminfo pointer in luaX:lex and related functions + * orig-5.0.2/llex.lua (chunkid): fixed buffer handling bug + * orig-5.0.2/llex.lua (read_string): escaped \n index bug + * orig-5.0.2/test_llex.lua: adjusted calling code to properly + use Token struct t in LS same as in original lparser.c calls + * orig-5.0.2/llex.lua (token2str): put back an assert as comment + * orig-5.0.2/llex.lua (readname): bug reading name up to EOZ + * orig-5.0.2/llex.lua (read_string): forgot c = self:next(LS) + * orig-5.0.2/llex.lua (readname): %w (alnum) instead of %a + * orig-5.0.2/llex.lua (lex): string.byte(c) for ctrl char msg + * orig-5.0.2/test_llex.lua: added automatic testing, all test + cases work after bug fixes (see above entries) to llex.lua + * orig-5.0.2/llex.lua: complete + +2005-03-10 Kein-Hong Man + + * orig-5.0.2/llex.lua: completed porting + +2005-03-09 Kein-Hong Man + + * started work on porting files (llex|lparser|lcode).(h|c) + * orig-5.0.2/lzio.lua: done parts needed for llex.lua, manually + tested with both string and file chunk readers + * orig-5.0.2/test_lzio.lua: created manual test diff --git a/LuaSL/testLua/yueliang-0.4.1/Manifest b/LuaSL/testLua/yueliang-0.4.1/Manifest new file mode 100644 index 0000000..5894dd5 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/Manifest @@ -0,0 +1,180 @@ +Changelog +Manifest +README +OlderNews +COPYRIGHT +COPYRIGHT_Lua5 +COPYRIGHT_Lua51 +orig-5.0.3/README +orig-5.0.3/lzio.lua +orig-5.0.3/ldump.lua +orig-5.0.3/lopcodes.lua +orig-5.0.3/llex.lua +orig-5.0.3/lparser.lua +orig-5.0.3/lcode.lua +orig-5.0.3/luac.lua +orig-5.0.3/test/test_number.lua +orig-5.0.3/test/test_lzio.lua +orig-5.0.3/test/test_ldump.lua +orig-5.0.3/test/test_llex.lua +orig-5.0.3/test/test_lparser.lua +orig-5.0.3/test/test_lparser2.lua +orig-5.0.3/test/sample.lua +orig-5.0.3/test/bench_llex.lua +orig-5.0.3/tools/call_graph.lua +orig-5.0.3/tools/calls.log +orig-5.0.3/tools/sample_expr.lua +orig-5.1.3/README +orig-5.1.3/lzio.lua +orig-5.1.3/ldump.lua +orig-5.1.3/lopcodes.lua +orig-5.1.3/llex.lua +orig-5.1.3/lparser.lua +orig-5.1.3/lcode.lua +orig-5.1.3/luac.lua +orig-5.1.3/test/test_number.lua +orig-5.1.3/test/test_lzio.lua +orig-5.1.3/test/test_ldump.lua +orig-5.1.3/test/test_llex.lua +orig-5.1.3/test/bench_llex.lua +orig-5.1.3/test/test_lparser.lua +orig-5.1.3/test/test_lparser2.lua +orig-5.1.3/test/sample.lua +nat-5.0.3/README +nat-5.0.3/lzio_mk2.lua +nat-5.0.3/lzio_mk4.lua +nat-5.0.3/llex_mk2.lua +nat-5.0.3/llex_mk3.lua +nat-5.0.3/llex_mk4.lua +nat-5.0.3/lparser_mk3.lua +nat-5.0.3/lparser_mk3b.lua +nat-5.0.3/test/test_lzio_mk2.lua +nat-5.0.3/test/test_llex_mk2.lua +nat-5.0.3/test/test_llex_mk3.lua +nat-5.0.3/test/test_llex_mk4.lua +nat-5.0.3/test/bench_llex_mk2.lua +nat-5.0.3/test/bench_llex_mk3.lua +nat-5.0.3/test/bench_llex_mk4.lua +nat-5.0.3/test/test_lparser_mk3.lua +nat-5.0.3/test/test_lparser_mk3_2.lua +nat-5.0.3/test/test_lparser_mk3b.lua +nat-5.0.3/test/test_lparser_mk3b_2.lua +nat-5.0.3/test/sample.lua +nat-5.0.3/test/parser_log/sample_01.lua +nat-5.0.3/test/parser_log/sample_02.lua +nat-5.0.3/test/parser_log/sample_03.lua +nat-5.0.3/test/parser_log/sample_04.lua +nat-5.0.3/test/parser_log/sample_05.lua +nat-5.0.3/test/parser_log/sample_06.lua +nat-5.0.3/test/parser_log/sample_07.lua +nat-5.0.3/test/parser_log/sample_08.lua +nat-5.0.3/test/parser_log/sample_09.lua +nat-5.0.3/test/parser_log/sample_10.lua +nat-5.0.3/test/parser_log/sample_11.lua +nat-5.0.3/test/parser_log/sample_12.lua +nat-5.0.3/test/parser_log/sample_13.lua +nat-5.0.3/test/parser_log/sample_14.lua +nat-5.0.3/test/parser_log/sample_15.lua +nat-5.0.3/test/parser_log/sample_16.lua +nat-5.0.3/test/parser_log/sample_17.lua +nat-5.0.3/test/parser_log/sample_b_01.lua +nat-5.0.3/test/parser_log/sample_b_02.lua +nat-5.0.3/test/parser_log/sample_b_03.lua +nat-5.0.3/test/parser_log/sample_b_04.lua +nat-5.0.3/test/parser_log/sample_b_05.lua +nat-5.0.3/test/parser_log/sample_b_06.lua +nat-5.0.3/test/parser_log/sample_b_07.lua +nat-5.0.3/test/parser_log/sample_b_08.lua +nat-5.0.3/test/parser_log/sample_b_09.lua +nat-5.0.3/test/parser_log/sample_b_10.lua +nat-5.0.3/test/parser_log/sample_b_11.lua +nat-5.0.3/test/parser_log/sample_b_12.lua +nat-5.0.3/test/parser_log/sample_b_13.lua +nat-5.0.3/test/parser_log/sample_b_14.lua +nat-5.1.3/README +nat-5.1.3/llex_mk2.lua +nat-5.1.3/lparser_mk2.lua +nat-5.1.3/test/test_llex_mk2.lua +nat-5.1.3/test/test_lparser_mk2.lua +nat-5.1.3/test/test_lparser_mk2_2.lua +nat-5.1.3/test/parser_log/sample_01.lua +nat-5.1.3/test/parser_log/sample_02.lua +nat-5.1.3/test/parser_log/sample_03.lua +nat-5.1.3/test/parser_log/sample_04.lua +nat-5.1.3/test/parser_log/sample_05.lua +nat-5.1.3/test/parser_log/sample_06.lua +nat-5.1.3/test/parser_log/sample_07.lua +nat-5.1.3/test/parser_log/sample_08.lua +nat-5.1.3/test/parser_log/sample_09.lua +nat-5.1.3/test/parser_log/sample_10.lua +nat-5.1.3/test/parser_log/sample_11.lua +nat-5.1.3/test/parser_log/sample_12.lua +nat-5.1.3/test/parser_log/sample_13.lua +nat-5.1.3/test/parser_log/sample_14.lua +nat-5.1.3/test/parser_log/sample_15.lua +nat-5.1.3/test/parser_log/sample_16.lua +nat-5.1.3/test/parser_log/sample_17.lua +nat-5.1.3/test/parser_log/sample_18.lua +nat-5.1.3/test/parser_log/sample_19.lua +nat-5.1.3/test/parser_log/sample_20.lua +nat-5.1.3/test/parser_log/sample_21.lua +nat-5.1.3/test/parser_log/sample_22.lua +nat-5.1.3/test/parser_log/sample_23.lua +nat-5.1.3/test/parser_log/sample_24.lua +nat-5.1.3/test/parser_log/sample_25.lua +nat-5.1.3/test/parser_log/sample_26.lua +nat-5.1.3/test/parser_log/sample_27.lua +nat-5.1.3/test/parser_log/sample_28.lua +nat-5.1.3/test/parser_log/sample_29.lua +nat-5.1.3/test/parser_log/sample_30.lua +nat-5.1.3/test/parser_log/sample_31.lua +test_lua/README +test_lua/test_scripts-5.0.lua +test_lua/test_scripts-5.1.lua +test_lua/test_parser-5.0.lua +test_lua/test_parser-5.1.lua +test_lua/files-lua-5.0.txt +test_lua/files-other-5.0.txt +test_lua/files-yueliang-5.0.txt +test_lua/files-lua-5.1.txt +test_lua/files-other-5.1.txt +test_lua/files-yueliang-5.1.txt +test_lua/5.0/bisect.lua +test_lua/5.0/cf.lua +test_lua/5.0/echo.lua +test_lua/5.0/env.lua +test_lua/5.0/factorial.lua +test_lua/5.0/fib.lua +test_lua/5.0/fibfor.lua +test_lua/5.0/globals.lua +test_lua/5.0/hello.lua +test_lua/5.0/life.lua +test_lua/5.0/luac.lua +test_lua/5.0/printf.lua +test_lua/5.0/readonly.lua +test_lua/5.0/sieve.lua +test_lua/5.0/sort.lua +test_lua/5.0/table.lua +test_lua/5.0/trace-calls.lua +test_lua/5.0/trace-globals.lua +test_lua/5.0/undefined.lua +test_lua/5.0/xd.lua +test_lua/5.1/fib.lua +test_lua/5.1/printf.lua +test_lua/5.1/hello.lua +test_lua/5.1/factorial.lua +test_lua/5.1/fibfor.lua +test_lua/5.1/bisect.lua +test_lua/5.1/sieve.lua +test_lua/5.1/xd.lua +test_lua/5.1/readonly.lua +test_lua/5.1/echo.lua +test_lua/5.1/life.lua +test_lua/5.1/trace-globals.lua +test_lua/5.1/globals.lua +test_lua/5.1/luac.lua +test_lua/5.1/sort.lua +test_lua/5.1/table.lua +test_lua/5.1/env.lua +test_lua/5.1/cf.lua +test_lua/5.1/trace-calls.lua diff --git a/LuaSL/testLua/yueliang-0.4.1/OlderNews b/LuaSL/testLua/yueliang-0.4.1/OlderNews new file mode 100644 index 0000000..7fe9c9e --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/OlderNews @@ -0,0 +1,43 @@ +OLDER NEWS + +Major changes for version 0.2.4 (details in the ChangeLog): +* Completely reworked native parser skeleton for 5.0.3 + (Partially working, test snippets and logging messages being written + in order to verify it. This is a test run limited to a parser + skeleton before doing a full native implementation for 5.1.x) + +Major changes for version 0.2.3 (details in the ChangeLog): +* Updated front end to 5.1.3 + +Major changes for version 0.2.2 (details in the ChangeLog): +* Updated front end to 5.1.2 + +Major changes for version 0.2.1 (details in the ChangeLog): +* Added a parser test suite for both 5.0.3 and 5.1.1 front ends +* One bug fixed for the 5.1.1 front end + +Major changes for version 0.2.0 (details in the ChangeLog): +* Yueliang can generate Lua 5.1.1 binary chunks now + +Major changes for version 0.1.4 (details in the ChangeLog): +* updated 5.0.2 material to 5.0.3, front end test script +* updated 5.1 material to 5.1.1, added ldump.lua, lopcodes.lua, + and some test scripts, lexer debugged + +Major changes for version 0.1.3 (details in the ChangeLog): +* added a Lua-style expression parsing demonstrator +* added lexer for Lua 5.1 +* native versions of Lua 5.0.2 lexer in the nat-5.0.2 directory +* 0.1.3 will be the last version of Yueliang for Lua 5.0.2 + +Major changes for version 0.1.2 (details in the ChangeLog): +* added test cases for number conversion functions in ldump.lua + (recognizes +/- infinity now) + +Major changes for version 0.1.1 (details in the ChangeLog): +* added a script to generate a call graph or hierarchy + +Major changes for version 0.1.0 (details in the ChangeLog): +* initial release: lexer/parser/code generator works, and binary + chunks can be produced + diff --git a/LuaSL/testLua/yueliang-0.4.1/README b/LuaSL/testLua/yueliang-0.4.1/README new file mode 100644 index 0000000..9ee1437 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/README @@ -0,0 +1,156 @@ + + Yueliang + Lua implemented in Lua + + Copyright (c) 2005-2008 Kein-Hong Man + The COPYRIGHT file describes the conditions under which this + software may be distributed (basically a Lua 5-style license.) + + Website: http://yueliang.luaforge.net/ + Project page: http://luaforge.net/projects/yueliang/ + +-- + +INTRODUCTION + +The goal of Yueliang is to implement Lua 5 in Lua 5. Such a codebase, if +well documented, can be a useful prototyping and educational tool. +Initially, the focus is on the front side of Lua, i.e. the lexical +analyzer, the parser and the code generator, in order to generate binary +chunks. Yueliang currently produces the exact binary chunk as the +original Lua 5 itself for Lua 5.0.3 and Lua 5.1.3. Yueliang is moon in +Mandarin. + +A port of the back side (the VM) is being considered, but note that +there is a recent project on LuaForge called LuLu that does just this. + +Note: the codebase is currently a no-brainer port of Lua's front side C +source code to Lua code, and the C heritage is retained as much as +possible to allow for easy comparison. Due to certain implementation +methods, processing might be slow (especially if the source file causes +a lot of string processing.) The initial version is not meant to be +fast. Even unused arguments are retained. Asserts are currently enabled. +While the Lua code itself is portable, portions of the code is +hard-coded to generate output for an x86-type platform (32-bit ints, +doubles, little-endian.) + +See the test_lua directory for an automatic tester, test_scripts*.lua. +Only the lexer currently has a basic test suite. Performance for the +no-brainer port of the Lua 5.0.2 front end in Yueliang 0.1.0 is 28 +seconds on an Athlon 2500+, or about 29.5KB/sec. (Native C is virtually +instantaneous, so a comparison is pointless, really.) I think a test +suite for the parser will be better than running it on random files. See +below for a list of todos. + +For versions of Yueliang corresponding to older minor releases of Lua, +for example Lua 5.0.2 or Lua 5.1.1, please look at the README files in +each of the orig-5.* directory for information on the last version of +Yueliang corresponding to the particular Lua release. + +-- + +NOTES + +* there is a failed assert in luaK:addk for both versions of lcode.lua, + the assert is currently incorrectly written +* luaG_checkcode() in both versions of lparser.lua has currently not + been implemented (better put in the runtime backend?) +* need to check compliance of lexers with recognizing characters beyond + normal ASCII (accented characters) when used in identifiers + +-- + +WHAT'S NEW + +Major changes for version 0.4.1 (details in the ChangeLog): +* Tested native 5.0.x and 5.1.x parsers with lots of test cases +* Fixed two bugs in native 5.1.x parser, # and % operator handling + +Major changes for version 0.4.0 (details in the ChangeLog): +* A working native parser skeleton for Lua 5.1.x, plus code + to deal with variable classification +* Sample parser log files covering all of the grammar + +Major changes for version 0.3.2 (details in the ChangeLog): +* A working native lexer for Lua 5.1.x + +Major changes for version 0.3.1 (details in the ChangeLog): +* Mark 2 of the native parser skeleton for 5.0.3 which does + variable classification into locals, upvalues or globals +* Sample parser log files exercising variable classification + +Major changes for version 0.3.0 (details in the ChangeLog): +* Native parser skeleton for 5.0.3 mostly works +* Sample parser log files covering all of the grammar + +Older items can be found in OlderNews + +-- + +SOME SIZE STATS + +Here are some 0.1.0 size statistics (note that embedding the sources is +redundant or pretty useless, as you will need an already present front +end to process the source code!) for the 6 files main in orig-5.0.3 +minus luac.lua: + + Size Zipped +Original sources* 130162 29546 +with LuaSrcDiet* 48308 13841 +luac 108174 32238 +luac -s 64930 21867 + +*note: embedding these would be a little pointless + +There are some more size stats in the README file in the nat-5.0.3 +directory, for native lexers. + +-- + +IMPLEMENTATION PLAN + +Here are some ideas, in no particular order or priority, with no +particular implementation time frame: + +(a) A straight no-brainer port of Lua's front side C source code to + Lua code, no optimization or heavy rewriting is done (MOSTLY DONE) +(b) A test suite for the lexer (MOSTLY DONE) +(c) A test suite for the: + (i) parser (MOSTLY DONE) + (ii) code generator (CAN ADAPT LUA'S TEST SUITE) +(d) Documentation for Lua code generation (STUDYING) +(e) A straight no-brainer port of Lua's back side C source code to + Lua code, no optimization or heavy rewriting is done (ON HIATUS) + *** NOTE: there is a Lua-on-Lua project called LuLu on LuaForge +(f) A test suite for the VM (CAN ADAPT LUA'S TEST SUITE) +(g) Partial rewrites of Yueliang. (NATIVE LEXERS AND PARSERS DONE + FOR BOTH 5.0 AND 5.1) +(h) Addition of features to Yueliang. + +-- + +ACKNOWLEDGEMENTS + +Yueliang is a straight port of Lua 5 code, so I have included the Lua +5.0.x copyright as well the Lua 5.1.x copyright files. + +Thanks to the LuaForge people for hosting this. +Developed on SciTE http://www.scintilla.org/. Two thumbs up. + +-- + +FEEDBACK + +Feedback and contributions are welcome. Your name will be acknowledged, +as long as you are willing to comply with COPYRIGHT. If your material is +self-contained, you can retain a copyright notice for those material in +your own name, as long as you use the same Lua 5/MIT-style copyright. + +I am on dial-up, so I might not be able to reply immediately. My +alternative e-mail address is: keinhong AT gmail DOT com + +Enjoy!! + +Kein-Hong Man (esq.) +Kuala Lumpur +Malaysia 20080531 diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/README b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/README new file mode 100644 index 0000000..b6a65d2 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/README @@ -0,0 +1,122 @@ +nat-5.0.3 + +This directory contains versions of front end files that are rewritten +to be more "native" to Lua. These files should be considered as +exercises in exploring ways to write the front end, for example, to +write a front end that is optimized for size, etc. See also file size +data further below. + +The following are the different versions available (mk2 == "mark 2", +this is commonly used in the UK, e.g. for aeroplanes during WWII): + +Lexers +------ + +WARNING: Theses lexer may or may not exhibit exact behaviour when lexing +strings or long strings with embedded CRLF newlines. The CRLF sequence +may be translated into LF (the reference manual is unclear on this.) The +user is advised to stick to LF line endings exclusively. + +llex_mk2 Rewritten from original ported code to become more + Lua-like. Still uses a stream-based input interface. + MK2 still scans using a per-character function that + is pretty inefficient. + + Status: TESTED + +llex_mk3 A rewritten version of MK2 that needs input to be + entered as a single string. Unless an application's + need is very unusual, this should not be a problem. + It will not work for per-line interaction, though. + MK3 no longer needs stream input functions. This + version is also heavily optimized for size. MK3 scans + using find functions and doesn't create many strings. + + Status: TESTED + +llex_mk4 A rewritten version of MK3 that is line-oriented. + This allows a command-line version that works in the + usual way to be written. + + Status: TESTED + +The following is a comparison of file sizes (as of 20061111): + + lzio llex TOTAL Speed (2) + (bytes) (bytes) (bytes) (KB/s) +---------------------------------------------- +Binary (Mingw) 416 5312 5728 N/A +---------------------------------------------- +(in orig-5.0.3:) +---------------------------------------------- +normal 2219 12639 14585 404.9 +stripped 1292 7618 8910 +---------------------------------------------- +(in nat-5.0.3:) +---------------------------------------------- +mk2 1995 7628 9623 469.5 +mk2-stripped 1195 4003 5298 +---------------------------------------------- +mk3 (1) - 6552 6552 1870.8 +mk3-stripped - 3286 3286 +---------------------------------------------- +mk4 1337 6956 8293 802.9 +mk4-stripped 798 3457 4225 +---------------------------------------------- + +(1) mk3 does not have a file input streaming function + +(2) Speed was benchmarked using a Sempron 3000+. Benchmark scripts are +in the test directories. Best of first three figures quoted. This is a +measurement of raw lexer speed, i.e. tokens are read but no processing +is done. All files are read in entirely before running the lexer. + +The performance of the orig-5.0.3 parser is probably a whole magnitude +less than the orig-5.0.3 lexer performance. + +Parsers +------- + +lparser_mk3 Written for the simplified lexer interface of llex_mk3+. + (Should be compatible with llex_mk4 too, but untested.) + This is a lexer skeleton, stripped of codegen code. See + the comments in the source code for more information. + Without logging messages and comments, it's under 600 LOC. + + Sample output of the parser message logger can be found + in the test/parser_log subdirectory. + + Tested with test_parser-5.0.lua, the Lua 5.0.x parser test + cases in the test_lua/ directory, appears to be fine. + + Status: SNIPPETS APPEAR TO WORK + +lparser_mk3b As above, with variable management code added. In order + to use the parser usefully, variable management code is + a big step forward, allowing the parser to differentiate + locals, upvalues and globals. The number of added lines + is around 100 LOC. A binary chunk of lparser_mk3b + (stripped) is 18076 bytes. + + Sample output of the parser message logger can be found + in the test/parser_log subdirectory. + + Tested with test_parser-5.0.lua, the Lua 5.0.x parser test + cases in the test_lua/ directory, appears to be fine. + + Status: SNIPPETS APPEAR TO WORK + +There will be no further development beyond lparser_mk3b. Further work +will focus on a 5.1.x equivalent, for which both a parser skeleton and a +parser with full code generation using nicely commented code is planned. + +Other notes: +------------ + +For Lua 5.0.2, see Yueliang 0.1.3, which was the last release of Lua +5.0.2 material. + +Test scripts for the lexer should probably be consolidated, but it's a +little difficult because not all lexers give the same error messages or +use the same token names or format. + diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk2.lua new file mode 100644 index 0000000..955f229 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk2.lua @@ -0,0 +1,309 @@ +--[[-------------------------------------------------------------------- + + llex.lua + Lua 5 lexical analyzer in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * parser to implement luaX_syntaxerror, call errorline with 2 parms +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- local lex_init = require("llex.lua") +-- local llex = lex_init(z, source) +-- llex:chunkid() +-- * returns formatted name of chunk id +-- llex:errorline(s, token, line) +-- * throws an error with a formatted message +-- llex:lex() +-- * returns next lexical element (token, seminfo) +----------------------------------------------------------------------]] + +return +function(z, source) +--[[-------------------------------------------------------------------- +-- lexer initialization +----------------------------------------------------------------------]] + -------------------------------------------------------------------- + -- initialize variables + -------------------------------------------------------------------- + local string = string + local EOF = "" + local z = z + local luaX = {source = source, lineno = 1,} + local curr, buff + -------------------------------------------------------------------- + -- initialize keyword list + -------------------------------------------------------------------- + local kw = {} + for v in string.gfind([[ +and break do else elseif end false for function if in +local nil not or repeat return then true until while]], "%S+") do + kw[v] = true + end +--[[-------------------------------------------------------------------- +-- support functions +----------------------------------------------------------------------]] + -------------------------------------------------------------------- + -- returns a chunk name or id + -------------------------------------------------------------------- + function luaX:chunkid() + local sub = string.sub + local first = sub(source, 1, 1) + if first == "=" or first == "@" then + return sub(source, 2) -- remove first char + end + return "[string]" + end + -------------------------------------------------------------------- + -- formats error message and throws error + -------------------------------------------------------------------- + function luaX:errorline(s, token, line) + if not line then line = self.lineno end + error(string.format("%s:%d: %s near '%s'", self:chunkid(), line, s, token)) + end + -------------------------------------------------------------------- + -- throws a lexer error + -------------------------------------------------------------------- + local function lexerror(s, token) + if not token then token = buff end + luaX:errorline(s, token) + end + -------------------------------------------------------------------- + -- gets the next character and returns it + -------------------------------------------------------------------- + local function nextc() + local c = z:getc() + curr = c + return c + end + -------------------------------------------------------------------- + -- save current character into token buffer, grabs next character + -- * save(c) merged into this and elsewhere to save space + -------------------------------------------------------------------- + local function save_next() + buff = buff..curr + return nextc() + end + -------------------------------------------------------------------- + -- move on to next line + -------------------------------------------------------------------- + local function nextline() + local luaX = luaX + nextc() -- skip '\n' + luaX.lineno = luaX.lineno + 1 + end +--[[-------------------------------------------------------------------- +-- reads a number (LUA_NUMBER) +----------------------------------------------------------------------]] + local function read_numeral(comma) + buff = "" + local find = string.find + if comma then buff = "." end + ------------------------------------------------------------------ + while find(curr, "%d") do save_next() end + if curr == "." then + if save_next() == "." then + save_next() + lexerror("ambiguous syntax (dots follows digits)") + end + end + ------------------------------------------------------------------ + while find(curr, "%d") do save_next() end + if find(curr, "^[eE]$") then + save_next() -- read 'E' and optional exponent sign + if find(curr, "^[+-]$") then save_next() end + while find(curr, "%d") do save_next() end + end + c = tonumber(buff) + if c then return c end + lexerror("malformed number") + end +--[[-------------------------------------------------------------------- +-- reads a long string or long comment +----------------------------------------------------------------------]] + local function read_long(is_str) + local cont = 0 + buff = "" + nextc() -- pass the '[[' + if curr == "\n" then -- string starts with a newline? + nextline() -- skip it + end + while true do + local c = curr + ---------------------------------------------------------------- + if c == "EOZ" then + lexerror(is_str and "unfinished long string" or + "unfinished long comment", EOF) + ---------------------------------------------------------------- + elseif c == "[" then + if save_next() == "[" then + cont = cont + 1; save_next() + end + ---------------------------------------------------------------- + elseif c == "]" then + if save_next() == "]" then + if cont == 0 then break end + cont = cont - 1; save_next() + end + ---------------------------------------------------------------- + elseif c == "\n" then + buff = buff.."\n"; nextline() + if not is_str then buff = "" end -- avoid wasting space + ---------------------------------------------------------------- + else + save_next() + ---------------------------------------------------------------- + end--if c + end--while + nextc() -- skip second ']' + return string.sub(buff, 1, -2) + end +--[[-------------------------------------------------------------------- +-- reads a string +----------------------------------------------------------------------]] + local function read_string(del) + local find = string.find + buff = "" + save_next() -- save delimiter + while curr ~= del do + local c = curr + ---------------------------------------------------------------- + -- end-of-file, newline + ---------------------------------------------------------------- + if c == "EOZ" then + lexerror("unfinished string", EOF) + elseif c == "\n" then + lexerror("unfinished string") + ---------------------------------------------------------------- + -- escapes + ---------------------------------------------------------------- + elseif c == "\\" then + c = nextc() -- do not save the '\' + if c ~= "EOZ" then -- will raise an error next loop iteration + local d = find("\nabfnrtv", c, 1, 1) + if d then + buff = buff..string.sub("\n\a\b\f\n\r\t\v", d, d) + if d == 1 then nextline() else nextc() end + elseif find(c, "%D") then + save_next() -- handles \\, \", \', and \? + else -- \xxx + c, d = 0, 0 + repeat + c = 10 * c + curr; d = d + 1; nextc() + until d >= 3 or find(curr, "%D") + if c > 255 then -- UCHAR_MAX + lexerror("escape sequence too large") + end + buff = buff..string.char(c) + end + end + ---------------------------------------------------------------- + -- a regular character + ---------------------------------------------------------------- + else + save_next() + ---------------------------------------------------------------- + end--if c + end--while + nextc() -- skip delimiter + return string.sub(buff, 2) + end +--[[-------------------------------------------------------------------- +-- main lexer function +----------------------------------------------------------------------]] + function luaX:lex() + local find = string.find + while true do + local c = curr + ---------------------------------------------------------------- + -- operators, numbers + ---------------------------------------------------------------- + local d = find("=<>~\"'-[.\n", c, 1, 1) + if d then + ------------------------------------------------------------ + if d <= 4 then -- "=<>~" (relational operators) + if nextc() ~= "=" then return c end + nextc(); return c.."=" + ------------------------------------------------------------ + elseif d <= 6 then -- "\"" or "'" (string) + return "", read_string(c) + ------------------------------------------------------------ + elseif c == "-" then -- "-" ("-", comment, or long comment) + if nextc() ~= "-" then return "-" end + c = nextc() -- otherwise it is a comment + if c == "[" and nextc() == "[" then + read_long() -- long comment + else -- short comment + while c ~= "\n" and c ~= "EOZ" do c = nextc() end + end + ------------------------------------------------------------ + elseif c == "[" then -- "[" ("[" or long string) + if nextc() ~= "[" then return c end + return "", read_long(true) + ------------------------------------------------------------ + elseif c == "." then -- "." (".", concatenation, or dots) + buff = "" + c = save_next() + if c == "." then -- interpret 2 or 3 dots + if save_next() == "." then save_next() end + return buff + end + if find(c, "%d") then + return "", read_numeral(true) + end + return "." + ------------------------------------------------------------ + else-- c == "\n" then -- "\n" (newline) + nextline() + ------------------------------------------------------------ + end--if d/c + ---------------------------------------------------------------- + -- number, end-of-file, identifier or reserved word + ---------------------------------------------------------------- + elseif find(c, "%d") then -- number + return "", read_numeral(false) + ---------------------------------------------------------------- + elseif find(c, "[_%a]") then -- reads a name + if c == "EOZ" then return EOF end -- end-of-file + buff = "" + repeat + c = save_next() + until c == "EOZ" or find(c, "[^_%w]") + c = buff + if kw[c] then return c end -- reserved word + return "", c + ---------------------------------------------------------------- + -- whitespace, other characters, control characters + ---------------------------------------------------------------- + elseif find(c, "%s") then -- whitespace + nextc() + ---------------------------------------------------------------- + elseif find(c, "%c") then -- control characters + lexerror("invalid control char", "char("..string.byte(c)..")") + ---------------------------------------------------------------- + else -- single-char tokens (+ - / etc.) + nextc(); return c + ---------------------------------------------------------------- + end--if d/c + end--while + end +--[[-------------------------------------------------------------------- +-- initial processing (shbang handling) +----------------------------------------------------------------------]] + nextc() -- read first char + if cur == "#" then -- skip first line + repeat nextc() until curr == "\n" or curr == "EOZ" + end + return luaX +--[[------------------------------------------------------------------]] +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk3.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk3.lua new file mode 100644 index 0000000..1cd22b5 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk3.lua @@ -0,0 +1,266 @@ +--[[-------------------------------------------------------------------- + + llex.lua + Lua 5 lexical analyzer in Lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * takes in the entire source at once +-- * code is heavily optimized for size +-- +-- local lex_init = require("llex.lua") +-- local llex = lex_init(z, source) +-- llex:chunkid() +-- * returns formatted name of chunk id +-- llex:errorline(s, line) +-- * throws an error with a formatted message +-- llex:lex() +-- * returns next lexical element (token, seminfo) +-- llex.ln +-- * line number +----------------------------------------------------------------------]] + +return +function(z, source) + -------------------------------------------------------------------- + -- initialize variables + -- * I is the upvalue, i is the local version for space/efficiency + -------------------------------------------------------------------- + local string = string + local find, sub = string.find, string.sub + local EOF = "" + local luaX = { ln = 1 } + local I = 1 + -------------------------------------------------------------------- + -- initialize keyword list + -------------------------------------------------------------------- + local kw = {} + for v in string.gfind([[ +and break do else elseif end false for function if in +local nil not or repeat return then true until while]], "%S+") do + kw[v] = true + end + -------------------------------------------------------------------- + -- returns a chunk name or id + -------------------------------------------------------------------- + function luaX:chunkid() + if find(source, "^[=@]") then + return sub(source, 2) -- remove first char + end + return "[string]" + end + -------------------------------------------------------------------- + -- formats error message and throws error + -- * a simplified version, does not report what token was responsible + -------------------------------------------------------------------- + function luaX:errorline(s, line) + error(string.format("%s:%d: %s", self:chunkid(), line or self.ln, s)) + end + ---------------------------------------------------------------------- + -- reads a long string or long comment + ---------------------------------------------------------------------- + local function read_long(i, is_str) + local luaX = luaX + local string = string + local cont = 1 + if sub(z, i, i) == "\n" then + i = i + 1 + luaX.ln = luaX.ln + 1 + end + local j = i + while true do + local p, q, r = find(z, "([\n%[%]])", i) -- (long range) + if not p then + luaX:errorline(is_str and "unfinished long string" or + "unfinished long comment") + end + i = p + 1 + if r == "\n" then + luaX.ln = luaX.ln + 1 + elseif sub(z, i, i) == r then -- only [[ or ]] + i = i + 1 + if r == "[" then + cont = cont + 1 + else-- r == "]" then + if cont == 1 then break end -- last ]] found + cont = cont - 1 + end + end + end--while + I = i + return sub(z, j, i - 3) + end + ---------------------------------------------------------------------- + -- reads a string + ---------------------------------------------------------------------- + local function read_string(i, del) + local luaX = luaX + local string = string + local buff = "" + while true do + local p, q, r = find(z, "([\n\\\"\'])", i) -- (long range) + if p then + if r == "\n" then + luaX:errorline("unfinished string") + end + buff = buff..sub(z, i, p - 1) -- normal portions + i = p + if r == "\\" then -- handle escapes + i = i + 1 + r = sub(z, i, i) + if r == "" then break end -- (error) + p = find("\nabfnrtv", r, 1, 1) + ------------------------------------------------------ + if p then -- special escapes + r = sub("\n\a\b\f\n\r\t\v", p, p) + if p == 1 then luaX.ln = luaX.ln + 1 end + i = i + 1 + ------------------------------------------------------ + elseif find(r, "%D") then -- other non-digits + i = i + 1 + ------------------------------------------------------ + else -- \xxx sequence + local p, q, s = find(z, "^(%d%d?%d?)", i) + i = q + 1 + if s + 1 > 256 then -- UCHAR_MAX + luaX:errorline("escape sequence too large") + end + r = string.char(s) + ------------------------------------------------------ + end--if p + else + i = i + 1 + if r == del then + I = i + return buff -- ending delimiter + end + end--if r + buff = buff..r + else + break -- (error) + end--if p + end--while + luaX:errorline("unfinished string") + end + ---------------------------------------------------------------------- + -- main lexer function + ---------------------------------------------------------------------- + function luaX:lex() + local string = string + local find, len = find, string.len + while true do--outer + local i = I + -- inner loop allows break to be used to nicely section tests + while true do--inner + ---------------------------------------------------------------- + local p, _, r = find(z, "^([_%a][_%w]*)", i) + if p then + I = i + len(r) + if kw[r] then return r end -- keyword + return "", r -- identifier + end + ---------------------------------------------------------------- + local p, q, r = find(z, "^(%.?)%d", i) + if p then -- numeral + if r == "." then i = i + 1 end + local _, n, r, s = find(z, "^%d*(%.?%.?)%d*([eE]?)", i) + q = n + i = q + 1 + if len(r) == 2 then + self:errorline("ambiguous syntax (dots follows digits)") + end + if len(s) == 1 then -- optional exponent + local _, n = find(z, "^[%+%-]?%d*", i) -- optional sign + q = n + i = q + 1 + end + r = tonumber(sub(z, p, q)) + I = i + if not r then self:errorline("malformed number") end + return "", r + end + ---------------------------------------------------------------- + local p, q, r = find(z, "^(%s)[ \t]*", i) + if p then + if r == "\n" then -- newline + self.ln = self.ln + 1 + I = i + 1 + else + I = q + 1 -- whitespace + end + break -- (continue) + end + ---------------------------------------------------------------- + local p, _, r = find(z, "^(%p)", i) -- symbols/punctuation + if p then + local q = find("-[\"\'.=<>~", r, 1, 1) + if q then -- further processing for more complex symbols + ---------------------------------------------------- + if q <= 2 then + if q == 1 then -- minus + if find(z, "^%-%-", i) then + i = i + 2 + if find(z, "^%[%[", i) then -- long comment + read_long(i + 2) + else -- short comment + I = find(z, "\n", i) or (len(z) + 1) + end + break -- (continue) + end + -- (fall through for "-") + elseif q == 2 then -- [ or long string + if find(z, "^%[%[", i) then + return "", read_long(i + 2, true) + end + -- (fall through for "[") + end + ---------------------------------------------------- + elseif q <= 5 then + if q < 5 then -- strings + return "", read_string(i + 1, r) + end + local _, _, s = find(z, "^(%.%.?%.?)", i) -- dots + r = s + -- (fall through) + ---------------------------------------------------- + else -- relational/logic + local _, _, s = find(z, "^(%p=?)", i) + r = s + -- (fall through) + end + end + I = i + len(r); return r -- for other symbols, fall through + end + ---------------------------------------------------------------- + local r = sub(z, i, i) + if r ~= "" then + if find(r, "%c") then -- invalid control char + self:errorline("invalid control char("..string.byte(r)..")") + end + I = i + 1; return r -- other single-char tokens + end + return EOF -- end of stream + ---------------------------------------------------------------- + end--while inner + end--while outer + end + -------------------------------------------------------------------- + -- initial processing (shbang handling) + -------------------------------------------------------------------- + local p, q, r = find(z, "^#[^\n]*(\n?)") + if p then -- skip first line + I = q + 1 + if r == "\n" then luaX.ln = luaX.ln + 1 end + end + return luaX + -------------------------------------------------------------------- +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk4.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk4.lua new file mode 100644 index 0000000..42559a3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/llex_mk4.lua @@ -0,0 +1,285 @@ +--[[-------------------------------------------------------------------- + + llex.lua + Lua 5 lexical analyzer in Lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * a line-oriented version of mk3 +-- +-- local lex_init = require("llex.lua") +-- local llex = lex_init(z, source) +-- llex:chunkid() +-- * returns formatted name of chunk id +-- llex:errorline(s, line) +-- * throws an error with a formatted message +-- llex:lex() +-- * returns next lexical element (token, seminfo) +-- llex.ln +-- * line number +----------------------------------------------------------------------]] + +return +function(zio, source) + -------------------------------------------------------------------- + -- initialize variables + -- * I is the upvalue, i is the local version for space/efficiency + -------------------------------------------------------------------- + local string = string + local find, sub = string.find, string.sub + local EOF = "" + local luaX = { ln = 0 } + local I, z + -------------------------------------------------------------------- + -- initialize keyword list + -------------------------------------------------------------------- + local kw = {} + for v in string.gfind([[ +and break do else elseif end false for function if in +local nil not or repeat return then true until while]], "%S+") do + kw[v] = true + end + -------------------------------------------------------------------- + -- returns a chunk name or id + -------------------------------------------------------------------- + function luaX:chunkid() + if find(source, "^[=@]") then + return sub(source, 2) -- remove first char + end + return "[string]" + end + -------------------------------------------------------------------- + -- formats error message and throws error + -- * a simplified version, does not report what token was responsible + -------------------------------------------------------------------- + function luaX:errorline(s, line) + error(string.format("%s:%d: %s", self:chunkid(), line or self.ln, s)) + end + -------------------------------------------------------------------- + -- move on to next line + -------------------------------------------------------------------- + local function nextln() + local luaX = luaX + luaX.ln = luaX.ln + 1 + z = zio:getln() + I = 1 + end + ---------------------------------------------------------------------- + -- reads a long string or long comment + ---------------------------------------------------------------------- + local function read_long(i, is_str) + local luaX = luaX + local string = string + local buff = "" + local cont = 1 + if sub(z, i, i) == "\n" then + nextln(); i = 1 + end + while true do + local p, q, r = find(z, "([\n%[%]])", i) -- (long range) + if not p then + luaX:errorline(is_str and "unfinished long string" or + "unfinished long comment") + end + buff = buff..string.sub(z, i, p - 1) -- add a portion + i = p + 1 + if sub(z, i, i) == r then -- only [[ or ]] + i = i + 1 + if r == "[" then + cont = cont + 1 + else-- r == "]" then + if cont == 1 then break end -- last ]] found + cont = cont - 1 + end + buff = buff..r..r + else -- [ or ] or \n + buff = buff..r + if r == "\n" then + nextln(); i = 1 + end + end + end--while + I = i + return buff + end + ---------------------------------------------------------------------- + -- reads a string + ---------------------------------------------------------------------- + local function read_string(i, del) + local luaX = luaX + local string = string + local buff = "" + while true do + local p, q, r = find(z, "([\n\\\"\'])", i) -- (long range) + if p then + if r == "\n" then + luaX:errorline("unfinished string") + end + buff = buff..sub(z, i, p - 1) -- normal portions + i = p + if r == "\\" then -- handle escapes + i = i + 1 + r = sub(z, i, i) + if r == "" then break end -- (error) + p = find("\nabfnrtv", r, 1, 1) + ------------------------------------------------------ + if p then -- special escapes + r = sub("\n\a\b\f\n\r\t\v", p, p) + if p == 1 then + nextln(); i = 1 + else + i = i + 1 + end + ------------------------------------------------------ + elseif find(r, "%D") then -- other non-digits + i = i + 1 + ------------------------------------------------------ + else -- \xxx sequence + local p, q, s = find(z, "^(%d%d?%d?)", i) + i = q + 1 + if s + 1 > 256 then -- UCHAR_MAX + luaX:errorline("escape sequence too large") + end + r = string.char(s) + ------------------------------------------------------ + end--if p + else + i = i + 1 + if r == del then + I = i + return buff -- ending delimiter + end + end--if r + buff = buff..r + else + break -- (error) + end--if p + end--while + luaX:errorline("unfinished string") + end + ---------------------------------------------------------------------- + -- main lexer function + ---------------------------------------------------------------------- + function luaX:lex() + local string = string + local find, len = find, string.len + while true do--outer + local i = I + -- inner loop allows break to be used to nicely section tests + while true do--inner + ---------------------------------------------------------------- + local p, _, r = find(z, "^([_%a][_%w]*)", i) + if p then + I = i + len(r) + if kw[r] then return r end -- keyword + return "", r -- identifier + end + ---------------------------------------------------------------- + local p, q, r = find(z, "^(%.?)%d", i) + if p then -- numeral + if r == "." then i = i + 1 end + local _, n, r, s = find(z, "^%d*(%.?%.?)%d*([eE]?)", i) + q = n + i = q + 1 + if len(r) == 2 then + self:errorline("ambiguous syntax (dots follows digits)") + end + if len(s) == 1 then -- optional exponent + local _, n = find(z, "^[%+%-]?%d*", i) -- optional sign + q = n + i = q + 1 + end + r = tonumber(sub(z, p, q)) + I = i + if not r then self:errorline("malformed number") end + return "", r + end + ---------------------------------------------------------------- + local p, q, r = find(z, "^(%s)[ \t]*", i) + if p then + if r == "\n" then -- newline + nextln() + else + I = q + 1 -- whitespace + end + break -- (continue) + end + ---------------------------------------------------------------- + local p, _, r = find(z, "^(%p)", i) -- symbols/punctuation + if p then + local q = find("-[\"\'.=<>~", r, 1, 1) + if q then -- further processing for more complex symbols + ---------------------------------------------------- + if q <= 2 then + if q == 1 then -- minus + if find(z, "^%-%-", i) then + i = i + 2 + if find(z, "^%[%[", i) then -- long comment + read_long(i + 2) + else -- short comment + if find(z, "\n", i) then + nextln() + else + I = len(z) + 1 + end + end + break -- (continue) + end + -- (fall through for "-") + elseif q == 2 then -- [ or long string + if find(z, "^%[%[", i) then + return "", read_long(i + 2, true) + end + -- (fall through for "[") + end + ---------------------------------------------------- + elseif q <= 5 then + if q < 5 then -- strings + return "", read_string(i + 1, r) + end + local _, _, s = find(z, "^(%.%.?%.?)", i) -- dots + r = s + -- (fall through) + ---------------------------------------------------- + else -- relational/logic + local _, _, s = find(z, "^(%p=?)", i) + r = s + -- (fall through) + end + end + I = i + len(r); return r -- for other symbols, fall through + end + ---------------------------------------------------------------- + local r = sub(z, i, i) + if r ~= "" then + if find(r, "%c") then -- invalid control char + self:errorline("invalid control char("..string.byte(r)..")") + end + I = i + 1; return r -- other single-char tokens + end + return EOF -- end of stream + ---------------------------------------------------------------- + end--while inner + end--while outer + end + -------------------------------------------------------------------- + -- initial processing (shbang handling) + -------------------------------------------------------------------- + nextln() + local p, q, r = find(z, "^#[^\n]*(\n?)") + if p then -- skip first line + I = q + 1 + if r == "\n" then nextln() end + end + return luaX + -------------------------------------------------------------------- +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3.lua new file mode 100644 index 0000000..17d6f64 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3.lua @@ -0,0 +1,1027 @@ +--[[-------------------------------------------------------------------- + + lparser.lua + Lua 5 parser in Lua + This file is part of Yueliang. + + Copyright (c) 2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * this is a Lua 5.0.x parser skeleton, for llex_mk3.lua lexer +-- * written as a module factory with recognizable lparser.c roots +-- * builds some data, performs logging for educational purposes +-- * target is to have relatively efficient and clear code +-- * needs one parameter, a lexer module that implements: +-- luaX:lex() - returns appropriate [token, semantic info] pairs +-- luaX.ln - current line number +-- luaX:errorline(s, [line]) - dies with error message +-- +-- Usage example: +-- lex_init = require("llex_mk3.lua") +-- parser_init = require("lparser_mk3.lua") +-- local luaX = lex_init(chunk, "=string") +-- local luaY = parser_init(luaX) +-- local fs = luaY:parser() +-- +-- Development notes: +-- * see test_parser-5.0.lua for grammar elements based on lparser.c +-- * lparser has a few extra items to help parsing/syntax checking +-- (a) line number (error reporting), lookahead token storage +-- (b) per-prototype states needs a storage list +-- (c) 'break' needs a per-block flag in a stack +-- (d) 'kind' (v.k) testing needed in expr_stat() and assignment() +-- for disambiguation, thus v.k manipulation is retained +-- (e) one line # var (lastln) for ambiguous (split line) function +-- call checking +-- (f) most line number function call args retained for future use +-- (g) Lua 4 compatibility code completely removed +-- (h) no variable management code! singlevar() always returns VLOCAL +-- * parsing starts from the end of this file in luaY:parser() +-- +----------------------------------------------------------------------]] + +return +function(luaX) +--[[-------------------------------------------------------------------- +-- structures and data initialization +----------------------------------------------------------------------]] + + local line -- start line # for error messages + local lastln -- last line # for ambiguous syntax chk + local tok, seminfo -- token, semantic info pair + local peek_tok, peek_sem -- ditto, for lookahead + local fs -- function state + local top_fs = {} -- top-level function state + local luaY = {} + -------------------------------------------------------------------- + local block_follow = {} -- lookahead check in chunk(), returnstat() + for v in string.gfind("else elseif end until ", "%S+") do + block_follow[v] = true + end + -------------------------------------------------------------------- + local stat_call = {} -- lookup for calls in stat() + for v in string.gfind("if while do for repeat function local return break", "%S+") do + stat_call[v] = v.."_stat" + end + -------------------------------------------------------------------- + local binopr_left = {} -- binary operators, left priority + local binopr_right = {} -- binary operators, right priority + for op, lt, rt in string.gfind([[ +{+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{^ 10 9}{.. 5 4} +{~= 3 3}{== 3 3}{< 3 3}{<= 3 3}{> 3 3}{>= 3 3} +{and 2 2}{or 1 1} +]], "{(%S+)%s(%d+)%s(%d+)}") do + binopr_left[op] = lt + 0 + binopr_right[op] = rt + 0 + end + local unopr = { ["not"] = true, ["-"] = true, } -- unary operators + +--[[-------------------------------------------------------------------- +-- logging: this logging function is for educational purposes +-- * logged data can be retrieved from the returned data structure +-- * or, replace self:log() instances with your custom code... +----------------------------------------------------------------------]] + + function luaY:log(msg) + local log = top_fs.log + if not log then log = {}; top_fs.log = log end + table.insert(top_fs.log, msg) + end + +--[[-------------------------------------------------------------------- +-- support functions +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- reads in next token + -------------------------------------------------------------------- + function luaY:next() + lastln = luaX.ln + if peek_tok then -- is there a look-ahead token? if yes, use it + tok, seminfo = peek_tok, peek_sem + peek_tok = nil + else + tok, seminfo = luaX:lex() -- read next token + end + end + -------------------------------------------------------------------- + -- peek at next token (single lookahead for table constructor) + -------------------------------------------------------------------- + function luaY:lookahead() + peek_tok, peek_sem = luaX:lex() + return peek_tok + end + + ------------------------------------------------------------------------ + -- throws a syntax error + ------------------------------------------------------------------------ + function luaY:syntaxerror(msg) + local tok = tok + if tok ~= "" and tok ~= "" then + if tok == "" then tok = seminfo end + tok = "'"..tok.."'" + end + luaX:errorline(msg.." near "..tok) + end + -------------------------------------------------------------------- + -- throws a syntax error if token expected is not there + -------------------------------------------------------------------- + function luaY:error_expected(token) + self:syntaxerror("'"..token.."' expected") + end + + -------------------------------------------------------------------- + -- verifies token conditions are met or else throw error + -------------------------------------------------------------------- + function luaY:check_match(what, who, where) + if not self:testnext(what) then + if where == luaX.ln then + self:error_expected(what) + else + self:syntaxerror("'"..what.."' expected (to close '"..who.."' at line "..where..")") + end + end + end + -------------------------------------------------------------------- + -- tests for a token, returns outcome + -- * return value changed to boolean + -------------------------------------------------------------------- + function luaY:testnext(c) + if tok == c then self:next(); return true end + end + -------------------------------------------------------------------- + -- throws error if condition not matched + -------------------------------------------------------------------- + function luaY:check_condition(c, msg) + if not c then self:syntaxerror(msg) end + end + -------------------------------------------------------------------- + -- check for existence of a token, throws error if not found + -------------------------------------------------------------------- + function luaY:check(c) + if not self:testnext(c) then self:error_expected(c) end + end + + -------------------------------------------------------------------- + -- expect that token is a name, return the name + -------------------------------------------------------------------- + function luaY:str_checkname() + self:check_condition(tok == "", " expected") + local ts = seminfo + self:next() + self:log(" str_checkname: '"..ts.."'") + return ts + end + -------------------------------------------------------------------- + -- adds given string s in string pool, sets e as VK + -------------------------------------------------------------------- + function luaY:codestring(e, s) + e.k = "VK" + self:log(" codestring: "..string.format("%q", s)) + end + -------------------------------------------------------------------- + -- consume a name token, adds it to string pool + -------------------------------------------------------------------- + function luaY:checkname(e) + self:log(" checkname:") + self:codestring(e, self:str_checkname()) + end + +--[[-------------------------------------------------------------------- +-- state management functions with open/close pairs +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- enters a code unit, initializes elements + -------------------------------------------------------------------- + function luaY:enterblock(isbreakable) + local bl = {} -- per-block state + bl.isbreakable = isbreakable + bl.prev = fs.bl + fs.bl = bl + self:log(">> enterblock(isbreakable="..tostring(isbreakable)..")") + end + -------------------------------------------------------------------- + -- leaves a code unit, close any upvalues + -------------------------------------------------------------------- + function luaY:leaveblock() + local bl = fs.bl + fs.bl = bl.prev + self:log("<< leaveblock") + end + -------------------------------------------------------------------- + -- opening of a function + -------------------------------------------------------------------- + function luaY:open_func() + local new_fs -- per-function state + if not fs then -- top_fs is created early + new_fs = top_fs + else + new_fs = {} + end + new_fs.prev = fs -- linked list of function states + new_fs.bl = nil + fs = new_fs + self:log(">> open_func") + end + -------------------------------------------------------------------- + -- closing of a function + -------------------------------------------------------------------- + function luaY:close_func() + fs = fs.prev + self:log("<< close_func") + end + +--[[-------------------------------------------------------------------- +-- variable (global|local|upvalue) handling +-- * does nothing for now, always returns "VLOCAL" +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- consume a name token, creates a variable (global|local|upvalue) + -- * used in prefixexp(), funcname() + -------------------------------------------------------------------- + function luaY:singlevar(v) + local varname = self:str_checkname() + v.k = "VLOCAL" + self:log(" singlevar: name='"..varname.."'") + end + +--[[-------------------------------------------------------------------- +-- other parsing functions +-- * for table constructor, parameter list, argument list +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- parse a function name suffix, for function call specifications + -- * used in primaryexp(), funcname() + -------------------------------------------------------------------- + function luaY:field(v) + -- field -> ['.' | ':'] NAME + local key = {} + self:log(" field: operator="..tok) + self:next() -- skip the dot or colon + self:checkname(key) + v.k = "VINDEXED" + end + -------------------------------------------------------------------- + -- parse a table indexing suffix, for constructors, expressions + -- * used in recfield(), primaryexp() + -------------------------------------------------------------------- + function luaY:index(v) + -- index -> '[' expr ']' + self:log(">> index: begin '['") + self:next() -- skip the '[' + self:expr(v) + self:check("]") + self:log("<< index: end ']'") + end + -------------------------------------------------------------------- + -- parse a table record (hash) field + -- * used in constructor() + -------------------------------------------------------------------- + function luaY:recfield(cc) + -- recfield -> (NAME | '['exp1']') = exp1 + local key, val = {}, {} + if tok == "" then + self:log("recfield: name") + self:checkname(key) + else-- tok == '[' + self:log("recfield: [ exp1 ]") + self:index(key) + end + self:check("=") + self:expr(val) + end + -------------------------------------------------------------------- + -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) + -- * note: retained in this skeleton because it modifies cc.v.k + -- * used in constructor() + -------------------------------------------------------------------- + function luaY:closelistfield(cc) + if cc.v.k == "VVOID" then return end -- there is no list item + cc.v.k = "VVOID" + end + -------------------------------------------------------------------- + -- parse a table list (array) field + -- * used in constructor() + -------------------------------------------------------------------- + function luaY:listfield(cc) + self:log("listfield: expr") + self:expr(cc.v) + end + -------------------------------------------------------------------- + -- parse a table constructor + -- * used in funcargs(), simpleexp() + -------------------------------------------------------------------- + function luaY:constructor(t) + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- field -> recfield | listfield + -- fieldsep -> ',' | ';' + self:log(">> constructor: begin") + local line = luaX.ln + local cc = {} + cc.v = {} + cc.t = t + t.k = "VRELOCABLE" + cc.v.k = "VVOID" + self:check("{") + repeat + self:testnext(";") -- compatibility only + if tok == "}" then break end + -- closelistfield(cc) here + local c = tok + if c == "" then -- may be listfields or recfields + if self:lookahead() ~= "=" then -- look ahead: expression? + self:listfield(cc) + else + self:recfield(cc) + end + elseif c == "[" then -- constructor_item -> recfield + self:recfield(cc) + else -- constructor_part -> listfield + self:listfield(cc) + end + until not self:testnext(",") and not self:testnext(";") + self:check_match("}", "{", line) + -- lastlistfield(cc) here + self:log("<< constructor: end") + end + -------------------------------------------------------------------- + -- parse the arguments (parameters) of a function declaration + -- * used in body() + -------------------------------------------------------------------- + function luaY:parlist() + -- parlist -> [ param { ',' param } ] + self:log(">> parlist: begin") + local dots = false + if tok ~= ")" then -- is 'parlist' not empty? + repeat + local c = tok + if c == "..." then + self:log("parlist: ... (dots)") + dots = true + self:next() + elseif c == "" then + local str = self:str_checkname() + else + self:syntaxerror(" or '...' expected") + end + until dots or not self:testnext(",") + end + self:log("<< parlist: end") + end + -------------------------------------------------------------------- + -- parse the parameters of a function call + -- * contrast with parlist(), used in function declarations + -- * used in primaryexp() + -------------------------------------------------------------------- + function luaY:funcargs(f) + local args = {} + local line = luaX.ln + local c = tok + if c == "(" then -- funcargs -> '(' [ explist1 ] ')' + self:log(">> funcargs: begin '('") + if line ~= lastln then + self:syntaxerror("ambiguous syntax (function call x new statement)") + end + self:next() + if tok == ")" then -- arg list is empty? + args.k = "VVOID" + else + self:explist1(args) + end + self:check_match(")", "(", line) + elseif c == "{" then -- funcargs -> constructor + self:log(">> funcargs: begin '{'") + self:constructor(args) + elseif c == "" then -- funcargs -> STRING + self:log(">> funcargs: begin ") + self:codestring(args, seminfo) + self:next() -- must use 'seminfo' before 'next' + else + self:syntaxerror("function arguments expected") + return + end--if c + f.k = "VCALL" + self:log("<< funcargs: end -- expr is a VCALL") + end + +--[[-------------------------------------------------------------------- +-- mostly expression functions +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- parses an expression in parentheses or a single variable + -- * used in primaryexp() + -------------------------------------------------------------------- + function luaY:prefixexp(v) + -- prefixexp -> NAME | '(' expr ')' + local c = tok + if c == "(" then + self:log(">> prefixexp: begin ( expr ) ") + local line = self.ln + self:next() + self:expr(v) + self:check_match(")", "(", line) + self:log("<< prefixexp: end ( expr ) ") + elseif c == "" then + self:log("prefixexp: ") + self:singlevar(v) + else + self:syntaxerror("unexpected symbol") + end--if c + end + -------------------------------------------------------------------- + -- parses a prefixexp (an expression in parentheses or a single + -- variable) or a function call specification + -- * used in simpleexp(), assignment(), expr_stat() + -------------------------------------------------------------------- + function luaY:primaryexp(v) + -- primaryexp -> + -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + self:prefixexp(v) + while true do + local c = tok + if c == "." then -- field + self:log("primaryexp: '.' field") + self:field(v) + elseif c == "[" then -- '[' exp1 ']' + self:log("primaryexp: [ exp1 ]") + local key = {} + self:index(key) + elseif c == ":" then -- ':' NAME funcargs + self:log("primaryexp: : funcargs") + local key = {} + self:next() + self:checkname(key) + self:funcargs(v) + elseif c == "(" or c == "" or c == "{" then -- funcargs + self:log("primaryexp: "..c.." funcargs") + self:funcargs(v) + else + return + end--if c + end--while + end + -------------------------------------------------------------------- + -- parses general expression types, constants handled here + -- * used in subexpr() + -------------------------------------------------------------------- + function luaY:simpleexp(v) + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | constructor + -- | FUNCTION body | primaryexp + local c = tok + if c == "" then + self:log("simpleexp: ="..seminfo) + v.k = "VK" + self:next() -- must use 'seminfo' before 'next' + elseif c == "" then + self:log("simpleexp: ="..seminfo) + self:codestring(v, seminfo) + self:next() -- must use 'seminfo' before 'next' + elseif c == "nil" then + self:log("simpleexp: nil") + v.k = "VNIL" + self:next() + elseif c == "true" then + self:log("simpleexp: true") + v.k = "VTRUE" + self:next() + elseif c == "false" then + self:log("simpleexp: false") + v.k = "VFALSE" + self:next() + elseif c == "{" then -- constructor + self:log("simpleexp: constructor") + self:constructor(v) + elseif c == "function" then + self:log("simpleexp: function") + self:next() + self:body(v, false, luaX.ln) + else + self:primaryexp(v) + end--if c + end + ------------------------------------------------------------------------ + -- Parse subexpressions. Includes handling of unary operators and binary + -- operators. A subexpr is given the rhs priority level of the operator + -- immediately left of it, if any (limit is -1 if none,) and if a binop + -- is found, limit is compared with the lhs priority level of the binop + -- in order to determine which executes first. + -- * recursively called + -- * used in expr() + ------------------------------------------------------------------------ + function luaY:subexpr(v, limit) + -- subexpr -> (simpleexp | unop subexpr) { binop subexpr } + -- * where 'binop' is any binary operator with a priority + -- higher than 'limit' + local op = tok + local uop = unopr[op] + if uop then + self:log(" subexpr: uop='"..op.."'") + self:next() + self:subexpr(v, 8) -- UNARY_PRIORITY + else + self:simpleexp(v) + end + -- expand while operators have priorities higher than 'limit' + op = tok + local binop = binopr_left[op] + while binop and binop > limit do + local v2 = {} + self:log(">> subexpr: binop='"..op.."'") + self:next() + -- read sub-expression with higher priority + local nextop = self:subexpr(v2, binopr_right[op]) + self:log("<< subexpr: -- evaluate") + op = nextop + binop = binopr_left[op] + end + return op -- return first untreated operator + end + -------------------------------------------------------------------- + -- Expression parsing starts here. Function subexpr is entered with the + -- left operator (which is non-existent) priority of -1, which is lower + -- than all actual operators. Expr information is returned in parm v. + -- * used in cond(), explist1(), index(), recfield(), listfield(), + -- prefixexp(), while_stat(), exp1() + -------------------------------------------------------------------- + function luaY:expr(v) + -- expr -> subexpr + self:log("expr:") + self:subexpr(v, -1) + end + +--[[-------------------------------------------------------------------- +-- third level parsing functions +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- parse a variable assignment sequence + -- * recursively called + -- * used in expr_stat() + -------------------------------------------------------------------- + function luaY:assignment(v) + local e = {} + local c = v.v.k + self:check_condition(c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" + or c == "VINDEXED", "syntax error") + if self:testnext(",") then -- assignment -> ',' primaryexp assignment + local nv = {} -- expdesc + nv.v = {} + self:log("assignment: ',' -- next LHS element") + self:primaryexp(nv.v) + -- lparser.c deals with some register usage conflict here + self:assignment(nv) + else -- assignment -> '=' explist1 + self:check("=") + self:log("assignment: '=' -- RHS elements follows") + self:explist1(e) + return -- avoid default + end + e.k = "VNONRELOC" + end + -------------------------------------------------------------------- + -- parse a for loop body for both versions of the for loop + -- * used in fornum(), forlist() + -------------------------------------------------------------------- + function luaY:forbody(line, isnum) + self:check("do") + self:enterblock(true) -- loop block + self:block() + self:leaveblock() + end + -------------------------------------------------------------------- + -- parse a numerical for loop, calls forbody() + -- * used in for_stat() + -------------------------------------------------------------------- + function luaY:fornum(line) + -- fornum -> NAME = exp1, exp1 [, exp1] DO body + self:log(">> fornum: begin") + self:check("=") + self:log("fornum: index start") + self:exp1() -- initial value + self:check(",") + self:log("fornum: index stop") + self:exp1() -- limit + if self:testnext(",") then + self:log("fornum: index step") + self:exp1() -- optional step + else + -- default step = 1 + end + self:log("fornum: body") + self:forbody(line, true) + self:log("<< fornum: end") + end + -------------------------------------------------------------------- + -- parse a generic for loop, calls forbody() + -- * used in for_stat() + -------------------------------------------------------------------- + function luaY:forlist() + -- forlist -> NAME {, NAME} IN explist1 DO body + self:log(">> forlist: begin") + local e = {} + while self:testnext(",") do + self:str_checkname() + end + self:check("in") + local line = line + self:log("forlist: explist1") + self:explist1(e) + self:log("forlist: body") + self:forbody(line, false) + self:log("<< forlist: end") + end + -------------------------------------------------------------------- + -- parse a function name specification + -- * used in func_stat() + -------------------------------------------------------------------- + function luaY:funcname(v) + -- funcname -> NAME {field} [':' NAME] + self:log(">> funcname: begin") + local needself = false + self:singlevar(v) + while tok == "." do + self:log("funcname: -- '.' field") + self:field(v) + end + if tok == ":" then + self:log("funcname: -- ':' field") + needself = true + self:field(v) + end + self:log("<< funcname: end") + return needself + end + -------------------------------------------------------------------- + -- parse the single expressions needed in numerical for loops + -- * used in fornum() + -------------------------------------------------------------------- + function luaY:exp1() + -- exp1 -> expr + local e = {} + self:log(">> exp1: begin") + self:expr(e) + self:log("<< exp1: end") + end + -------------------------------------------------------------------- + -- parse condition in a repeat statement or an if control structure + -- * used in repeat_stat(), test_then_block() + -------------------------------------------------------------------- + function luaY:cond(v) + -- cond -> expr + self:log(">> cond: begin") + self:expr(v) -- read condition + self:log("<< cond: end") + end + -------------------------------------------------------------------- + -- parse part of an if control structure, including the condition + -- * used in if_stat() + -------------------------------------------------------------------- + function luaY:test_then_block(v) + -- test_then_block -> [IF | ELSEIF] cond THEN block + self:next() -- skip IF or ELSEIF + self:log("test_then_block: test condition") + self:cond(v) + self:check("then") + self:log("test_then_block: then block") + self:block() -- 'then' part + end + -------------------------------------------------------------------- + -- parse a local function statement + -- * used in local_stat() + -------------------------------------------------------------------- + function luaY:localfunc() + -- localfunc -> NAME body + local v, b = {} + self:log("localfunc: begin") + local str = self:str_checkname() + v.k = "VLOCAL" + self:log("localfunc: body") + self:body(b, false, luaX.ln) + self:log("localfunc: end") + end + -------------------------------------------------------------------- + -- parse a local variable declaration statement + -- * used in local_stat() + -------------------------------------------------------------------- + function luaY:localstat() + -- localstat -> NAME {',' NAME} ['=' explist1] + self:log(">> localstat: begin") + local e = {} + repeat + local str = self:str_checkname() + until not self:testnext(",") + if self:testnext("=") then + self:log("localstat: -- assignment") + self:explist1(e) + else + e.k = "VVOID" + end + self:log("<< localstat: end") + end + -------------------------------------------------------------------- + -- parse a list of comma-separated expressions + -- * used in return_stat(), localstat(), funcargs(), assignment(), + -- forlist() + -------------------------------------------------------------------- + function luaY:explist1(e) + -- explist1 -> expr { ',' expr } + self:log(">> explist1: begin") + self:expr(e) + while self:testnext(",") do + self:log("explist1: ',' -- continuation") + self:expr(e) + end + self:log("<< explist1: end") + end + -------------------------------------------------------------------- + -- parse function declaration body + -- * used in simpleexp(), localfunc(), func_stat() + -------------------------------------------------------------------- + function luaY:body(e, needself, line) + -- body -> '(' parlist ')' chunk END + self:open_func() + self:log("body: begin") + self:check("(") + if needself then + -- handle 'self' processing here + end + self:log("body: parlist") + self:parlist() + self:check(")") + self:log("body: chunk") + self:chunk() + self:check_match("end", "function", line) + self:log("body: end") + self:close_func() + end + -------------------------------------------------------------------- + -- parse a code block or unit + -- * used in do_stat(), while_stat(), repeat_stat(), forbody(), + -- test_then_block(), if_stat() + -------------------------------------------------------------------- + function luaY:block() + -- block -> chunk + self:log("block: begin") + self:enterblock(false) + self:chunk() + self:leaveblock() + self:log("block: end") + end + +--[[-------------------------------------------------------------------- +-- second level parsing functions, all with '_stat' suffix +-- * stat() -> *_stat() +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- initial parsing for a for loop, calls fornum() or forlist() + -- * used in stat() + -------------------------------------------------------------------- + function luaY:for_stat() + -- stat -> for_stat -> fornum | forlist + local line = line + self:log("for_stat: begin") + self:enterblock(false) -- block to control variable scope + self:next() -- skip 'for' + local str = self:str_checkname() -- first variable name + local c = tok + if c == "=" then + self:log("for_stat: numerical loop") + self:fornum(line) + elseif c == "," or c == "in" then + self:log("for_stat: list-based loop") + self:forlist() + else + self:syntaxerror("'=' or 'in' expected") + end + self:check_match("end", "for", line) + self:leaveblock() + self:log("for_stat: end") + end + -------------------------------------------------------------------- + -- parse a while-do control structure, body processed by block() + -- * used in stat() + -------------------------------------------------------------------- + function luaY:while_stat() + -- stat -> while_stat -> WHILE cond DO block END + local line = line + local v = {} + self:next() -- skip WHILE + self:log("while_stat: begin/condition") + self:expr(v) -- parse condition + self:enterblock(true) + self:check("do") + self:log("while_stat: block") + self:block() + self:check_match("end", "while", line) + self:leaveblock() + self:log("while_stat: end") + end + -------------------------------------------------------------------- + -- parse a repeat-until control structure, body parsed by block() + -- * used in stat() + -------------------------------------------------------------------- + function luaY:repeat_stat() + -- stat -> repeat_stat -> REPEAT block UNTIL cond + local line = line + local v = {} + self:log("repeat_stat: begin") + self:enterblock(true) + self:next() + self:block() + self:check_match("until", "repeat", line) + self:log("repeat_stat: condition") + self:cond(v) + self:leaveblock() + self:log("repeat_stat: end") + end + -------------------------------------------------------------------- + -- parse an if control structure + -- * used in stat() + -------------------------------------------------------------------- + function luaY:if_stat() + -- stat -> if_stat -> IF cond THEN block + -- {ELSEIF cond THEN block} [ELSE block] END + local line = line + local v = {} + self:log("if_stat: if...then") + self:test_then_block(v) -- IF cond THEN block + while tok == "elseif" do + self:log("if_stat: elseif...then") + self:test_then_block(v) -- ELSEIF cond THEN block + end + if tok == "else" then + self:log("if_stat: else...") + self:next() -- skip ELSE + self:block() -- 'else' part + end + self:check_match("end", "if", line) + self:log("if_stat: end") + end + -------------------------------------------------------------------- + -- parse a return statement + -- * used in stat() + -------------------------------------------------------------------- + function luaY:return_stat() + -- stat -> return_stat -> RETURN explist + local e = {} + self:next() -- skip RETURN + local c = tok + if block_follow[c] or c == ";" then + -- return no values + self:log("return_stat: no return values") + else + self:log("return_stat: begin") + self:explist1(e) -- optional return values + self:log("return_stat: end") + end + end + -------------------------------------------------------------------- + -- parse a break statement + -- * used in stat() + -------------------------------------------------------------------- + function luaY:break_stat() + -- stat -> break_stat -> BREAK + local bl = fs.bl + self:next() -- skip BREAK + while bl and not bl.isbreakable do -- find a breakable block + bl = bl.prev + end + if not bl then + self:syntaxerror("no loop to break") + end + self:log("break_stat: -- break out of loop") + end + -------------------------------------------------------------------- + -- parse a function call with no returns or an assignment statement + -- * the struct with .prev is used for name searching in lparse.c, + -- so it is retained for now; present in assignment() also + -- * used in stat() + -------------------------------------------------------------------- + function luaY:expr_stat() + -- stat -> expr_stat -> func | assignment + local v = {} + v.v = {} + self:primaryexp(v.v) + if v.v.k == "VCALL" then -- stat -> func + -- call statement uses no results + self:log("expr_stat: function call k='"..v.v.k.."'") + else -- stat -> assignment + self:log("expr_stat: assignment k='"..v.v.k.."'") + v.prev = nil + self:assignment(v) + end + end + -------------------------------------------------------------------- + -- parse a function statement + -- * used in stat() + -------------------------------------------------------------------- + function luaY:function_stat() + -- stat -> function_stat -> FUNCTION funcname body + local line = line + local v, b = {}, {} + self:log("function_stat: begin") + self:next() -- skip FUNCTION + local needself = self:funcname(v) + self:log("function_stat: body needself='"..tostring(needself).."'") + self:body(b, needself, line) + self:log("function_stat: end") + end + -------------------------------------------------------------------- + -- parse a simple block enclosed by a DO..END pair + -- * used in stat() + -------------------------------------------------------------------- + function luaY:do_stat() + -- stat -> do_stat -> DO block END + self:next() -- skip DO + self:log("do_stat: begin") + self:block() + self:log("do_stat: end") + self:check_match("end", "do", line) + end + -------------------------------------------------------------------- + -- parse a statement starting with LOCAL + -- * used in stat() + -------------------------------------------------------------------- + function luaY:local_stat() + -- stat -> local_stat -> LOCAL FUNCTION localfunc + -- -> LOCAL localstat + self:next() -- skip LOCAL + if self:testnext("function") then -- local function? + self:log("local_stat: local function") + self:localfunc() + else + self:log("local_stat: local statement") + self:localstat() + end + end + +--[[-------------------------------------------------------------------- +-- main function, top level parsing functions +-- * [entry] -> parser() -> chunk() -> stat() +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- initial parsing for statements, calls '_stat' suffixed functions + -- * used in chunk() + -------------------------------------------------------------------- + function luaY:stat() + line = luaX.ln + local c = tok + local fn = stat_call[c] + -- handles: if while do for repeat function local return break + if fn then + self:log("-- STATEMENT: begin '"..c.."' line="..line) + self[fn](self) + self:log("-- STATEMENT: end '"..c.."'") + -- return or break must be last statement + if c == "return" or c == "break" then return true end + else + self:log("-- STATEMENT: begin 'expr' line="..line) + self:expr_stat() + self:log("-- STATEMENT: end 'expr'") + end + self:log("") + return false + end + -------------------------------------------------------------------- + -- parse a chunk, which consists of a bunch of statements + -- * used in parser(), body(), block() + -------------------------------------------------------------------- + function luaY:chunk() + -- chunk -> { stat [';'] } + self:log("chunk:") + local islast = false + while not islast and not block_follow[tok] do + islast = self:stat() + self:testnext(";") + end + end + -------------------------------------------------------------------- + -- performs parsing, returns parsed data structure + -------------------------------------------------------------------- + function luaY:parser() + self:log("-- TOP: begin") + self:open_func() + self:log("") + self:next() -- read first token + self:chunk() + self:check_condition(tok == "", " expected") + self:close_func() + self:log("-- TOP: end") + return top_fs + end + -------------------------------------------------------------------- + return luaY -- return actual module to user, done +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua new file mode 100644 index 0000000..a46edc6 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua @@ -0,0 +1,1121 @@ +--[[-------------------------------------------------------------------- + + lparser.lua + Lua 5 parser in Lua + This file is part of Yueliang. + + Copyright (c) 2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * this is a Lua 5.0.x parser skeleton, for llex_mk3.lua lexer +-- * written as a module factory with recognizable lparser.c roots +-- * builds some data, performs logging for educational purposes +-- * target is to have relatively efficient and clear code +-- * needs one parameter, a lexer module that implements: +-- luaX:lex() - returns appropriate [token, semantic info] pairs +-- luaX.ln - current line number +-- luaX:errorline(s, [line]) - dies with error message +-- +-- Usage example: +-- lex_init = require("llex_mk3.lua") +-- parser_init = require("lparser_mk3.lua") +-- local luaX = lex_init(chunk, "=string") +-- local luaY = parser_init(luaX) +-- local fs = luaY:parser() +-- +-- Development notes: +-- * see test_parser-5.0.lua for grammar elements based on lparser.c +-- * lparser has a few extra items to help parsing/syntax checking +-- (a) line number (error reporting), lookahead token storage +-- (b) per-prototype states needs a storage list +-- (c) 'break' needs a per-block flag in a stack +-- (d) 'kind' (v.k) testing needed in expr_stat() and assignment() +-- for disambiguation, thus v.k manipulation is retained +-- (e) one line # var (lastln) for ambiguous (split line) function +-- call checking +-- (f) most line number function call args retained for future use +-- (g) Lua 4 compatibility code completely removed +-- (h) minimal variable management code to differentiate each type +-- * parsing starts from the end of this file in luaY:parser() +-- +----------------------------------------------------------------------]] + +return +function(luaX) +--[[-------------------------------------------------------------------- +-- structures and data initialization +----------------------------------------------------------------------]] + + local line -- start line # for error messages + local lastln -- last line # for ambiguous syntax chk + local tok, seminfo -- token, semantic info pair + local peek_tok, peek_sem -- ditto, for lookahead + local fs -- function state + local top_fs = {} -- top-level function state + local luaY = {} + -------------------------------------------------------------------- + local block_follow = {} -- lookahead check in chunk(), returnstat() + for v in string.gfind("else elseif end until ", "%S+") do + block_follow[v] = true + end + -------------------------------------------------------------------- + local stat_call = {} -- lookup for calls in stat() + for v in string.gfind("if while do for repeat function local return break", "%S+") do + stat_call[v] = v.."_stat" + end + -------------------------------------------------------------------- + local binopr_left = {} -- binary operators, left priority + local binopr_right = {} -- binary operators, right priority + for op, lt, rt in string.gfind([[ +{+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{^ 10 9}{.. 5 4} +{~= 3 3}{== 3 3}{< 3 3}{<= 3 3}{> 3 3}{>= 3 3} +{and 2 2}{or 1 1} +]], "{(%S+)%s(%d+)%s(%d+)}") do + binopr_left[op] = lt + 0 + binopr_right[op] = rt + 0 + end + local unopr = { ["not"] = true, ["-"] = true, } -- unary operators + +--[[-------------------------------------------------------------------- +-- logging: this logging function is for educational purposes +-- * logged data can be retrieved from the returned data structure +-- * or, replace self:log() instances with your custom code... +----------------------------------------------------------------------]] + + function luaY:log(msg) + local log = top_fs.log + if not log then log = {}; top_fs.log = log end + table.insert(top_fs.log, msg) + end + +--[[-------------------------------------------------------------------- +-- support functions +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- reads in next token + -------------------------------------------------------------------- + function luaY:next() + lastln = luaX.ln + if peek_tok then -- is there a look-ahead token? if yes, use it + tok, seminfo = peek_tok, peek_sem + peek_tok = nil + else + tok, seminfo = luaX:lex() -- read next token + end + end + -------------------------------------------------------------------- + -- peek at next token (single lookahead for table constructor) + -------------------------------------------------------------------- + function luaY:lookahead() + peek_tok, peek_sem = luaX:lex() + return peek_tok + end + + ------------------------------------------------------------------------ + -- throws a syntax error + ------------------------------------------------------------------------ + function luaY:syntaxerror(msg) + local tok = tok + if tok ~= "" and tok ~= "" then + if tok == "" then tok = seminfo end + tok = "'"..tok.."'" + end + luaX:errorline(msg.." near "..tok) + end + -------------------------------------------------------------------- + -- throws a syntax error if token expected is not there + -------------------------------------------------------------------- + function luaY:error_expected(token) + self:syntaxerror("'"..token.."' expected") + end + + -------------------------------------------------------------------- + -- verifies token conditions are met or else throw error + -------------------------------------------------------------------- + function luaY:check_match(what, who, where) + if not self:testnext(what) then + if where == luaX.ln then + self:error_expected(what) + else + self:syntaxerror("'"..what.."' expected (to close '"..who.."' at line "..where..")") + end + end + end + -------------------------------------------------------------------- + -- tests for a token, returns outcome + -- * return value changed to boolean + -------------------------------------------------------------------- + function luaY:testnext(c) + if tok == c then self:next(); return true end + end + -------------------------------------------------------------------- + -- throws error if condition not matched + -------------------------------------------------------------------- + function luaY:check_condition(c, msg) + if not c then self:syntaxerror(msg) end + end + -------------------------------------------------------------------- + -- check for existence of a token, throws error if not found + -------------------------------------------------------------------- + function luaY:check(c) + if not self:testnext(c) then self:error_expected(c) end + end + + -------------------------------------------------------------------- + -- expect that token is a name, return the name + -------------------------------------------------------------------- + function luaY:str_checkname() + self:check_condition(tok == "", " expected") + local ts = seminfo + self:next() + self:log(" str_checkname: '"..ts.."'") + return ts + end + -------------------------------------------------------------------- + -- adds given string s in string pool, sets e as VK + -------------------------------------------------------------------- + function luaY:codestring(e, s) + e.k = "VK" + self:log(" codestring: "..string.format("%q", s)) + end + -------------------------------------------------------------------- + -- consume a name token, adds it to string pool + -------------------------------------------------------------------- + function luaY:checkname(e) + self:log(" checkname:") + self:codestring(e, self:str_checkname()) + end + +--[[-------------------------------------------------------------------- +-- state management functions with open/close pairs +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- enters a code unit, initializes elements + -------------------------------------------------------------------- + function luaY:enterblock(isbreakable) + local bl = {} -- per-block state + bl.isbreakable = isbreakable + bl.prev = fs.bl + bl.locallist = {} + fs.bl = bl + self:log(">> enterblock(isbreakable="..tostring(isbreakable)..")") + end + -------------------------------------------------------------------- + -- leaves a code unit, close any upvalues + -------------------------------------------------------------------- + function luaY:leaveblock() + local bl = fs.bl + fs.bl = bl.prev + self:log("<< leaveblock") + end + -------------------------------------------------------------------- + -- opening of a function + -------------------------------------------------------------------- + function luaY:open_func() + local new_fs -- per-function state + if not fs then -- top_fs is created early + new_fs = top_fs + else + new_fs = {} + end + new_fs.prev = fs -- linked list of function states + new_fs.bl = nil + new_fs.locallist = {} + fs = new_fs + self:log(">> open_func") + end + -------------------------------------------------------------------- + -- closing of a function + -------------------------------------------------------------------- + function luaY:close_func() + fs = fs.prev + self:log("<< close_func") + end + +--[[-------------------------------------------------------------------- +-- variable (global|local|upvalue) handling +-- * a pure parser does not really need this, but if we want to produce +-- useful output, might as well write minimal code to manage this... +-- * entry point is singlevar() for variable lookups +-- * three entry points for local variable creation, in order to keep +-- to original C calls, but the extra arguments such as positioning +-- are removed as we are not allocating registers -- we are only +-- doing simple classification +-- * lookup tables (bl.locallist) are maintained awkwardly in the basic +-- block data structures, PLUS the function data structure (this is +-- an inelegant hack, since bl is nil for the top level of a function) +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- register a local variable, set in active variable list + -- * used in new_localvarstr(), parlist(), fornum(), forlist(), + -- localfunc(), localstat() + -------------------------------------------------------------------- + function luaY:new_localvar(name) + local bl = fs.bl + local locallist + if bl then + locallist = bl.locallist + else + locallist = fs.locallist + end + locallist[name] = true + self:log(" new_localvar: '"..name.."'") + end + -------------------------------------------------------------------- + -- creates a new local variable given a name + -- * used in fornum(), forlist() for loop variables; in create_local() + -------------------------------------------------------------------- + function luaY:new_localvarstr(name) + self:new_localvar(name) + end + -------------------------------------------------------------------- + -- creates a single local variable and activates it + -- * used only in code_params() for "arg", body() for "self" + -------------------------------------------------------------------- + function luaY:create_local(name) + self:new_localvarstr(name) + end + + -------------------------------------------------------------------- + -- search the local variable namespace of the given fs for a match + -- * a simple lookup only, no active variable list kept, so no useful + -- index value can be returned by this function + -- * used only in singlevaraux() + -------------------------------------------------------------------- + function luaY:searchvar(fs, n) + local bl = fs.bl + if bl then + locallist = bl.locallist + while locallist do + if locallist[n] then return 1 end -- found + bl = bl.prev + locallist = bl and bl.locallist + end + end + locallist = fs.locallist + if locallist[n] then return 1 end -- found + return -1 -- not found + end + -------------------------------------------------------------------- + -- handle locals, globals and upvalues and related processing + -- * search mechanism is recursive, calls itself to search parents + -- * used only in singlevar() + -------------------------------------------------------------------- + function luaY:singlevaraux(fs, n, var, base) + if fs == nil then -- no more levels? + var.k = "VGLOBAL" -- default is global variable + else + local v = self:searchvar(fs, n) -- look up at current level + if v >= 0 then + var.k = "VLOCAL" + else -- not found at current level; try upper one + self:singlevaraux(fs.prev, n, var, 0) + if var.k == "VGLOBAL" then + -- handle global var processing here + else -- LOCAL or UPVAL + var.k = "VUPVAL" + end + end--if v + end--if fs + end + -------------------------------------------------------------------- + -- consume a name token, creates a variable (global|local|upvalue) + -- * used in prefixexp(), funcname() + -------------------------------------------------------------------- + function luaY:singlevar(v) + local varname = self:str_checkname() + self:singlevaraux(fs, varname, v, 1) + self:log(" singlevar(kind): '"..v.k.."'") + end + +--[[-------------------------------------------------------------------- +-- other parsing functions +-- * for table constructor, parameter list, argument list +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- parse a function name suffix, for function call specifications + -- * used in primaryexp(), funcname() + -------------------------------------------------------------------- + function luaY:field(v) + -- field -> ['.' | ':'] NAME + local key = {} + self:log(" field: operator="..tok) + self:next() -- skip the dot or colon + self:checkname(key) + v.k = "VINDEXED" + end + -------------------------------------------------------------------- + -- parse a table indexing suffix, for constructors, expressions + -- * used in recfield(), primaryexp() + -------------------------------------------------------------------- + function luaY:index(v) + -- index -> '[' expr ']' + self:log(">> index: begin '['") + self:next() -- skip the '[' + self:expr(v) + self:check("]") + self:log("<< index: end ']'") + end + -------------------------------------------------------------------- + -- parse a table record (hash) field + -- * used in constructor() + -------------------------------------------------------------------- + function luaY:recfield(cc) + -- recfield -> (NAME | '['exp1']') = exp1 + local key, val = {}, {} + if tok == "" then + self:log("recfield: name") + self:checkname(key) + else-- tok == '[' + self:log("recfield: [ exp1 ]") + self:index(key) + end + self:check("=") + self:expr(val) + end + -------------------------------------------------------------------- + -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) + -- * note: retained in this skeleton because it modifies cc.v.k + -- * used in constructor() + -------------------------------------------------------------------- + function luaY:closelistfield(cc) + if cc.v.k == "VVOID" then return end -- there is no list item + cc.v.k = "VVOID" + end + -------------------------------------------------------------------- + -- parse a table list (array) field + -- * used in constructor() + -------------------------------------------------------------------- + function luaY:listfield(cc) + self:log("listfield: expr") + self:expr(cc.v) + end + -------------------------------------------------------------------- + -- parse a table constructor + -- * used in funcargs(), simpleexp() + -------------------------------------------------------------------- + function luaY:constructor(t) + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- field -> recfield | listfield + -- fieldsep -> ',' | ';' + self:log(">> constructor: begin") + local line = luaX.ln + local cc = {} + cc.v = {} + cc.t = t + t.k = "VRELOCABLE" + cc.v.k = "VVOID" + self:check("{") + repeat + self:testnext(";") -- compatibility only + if tok == "}" then break end + -- closelistfield(cc) here + local c = tok + if c == "" then -- may be listfields or recfields + if self:lookahead() ~= "=" then -- look ahead: expression? + self:listfield(cc) + else + self:recfield(cc) + end + elseif c == "[" then -- constructor_item -> recfield + self:recfield(cc) + else -- constructor_part -> listfield + self:listfield(cc) + end + until not self:testnext(",") and not self:testnext(";") + self:check_match("}", "{", line) + -- lastlistfield(cc) here + self:log("<< constructor: end") + end + -------------------------------------------------------------------- + -- parse the arguments (parameters) of a function declaration + -- * used in body() + -------------------------------------------------------------------- + function luaY:parlist() + -- parlist -> [ param { ',' param } ] + self:log(">> parlist: begin") + local dots = false + if tok ~= ")" then -- is 'parlist' not empty? + repeat + local c = tok + if c == "..." then + self:log("parlist: ... (dots)") + dots = true + self:next() + elseif c == "" then + self:new_localvar(self:str_checkname()) + else + self:syntaxerror(" or '...' expected") + end + until dots or not self:testnext(",") + end + -- was code_params() + if dots then + self:create_local("arg") + end + self:log("<< parlist: end") + end + -------------------------------------------------------------------- + -- parse the parameters of a function call + -- * contrast with parlist(), used in function declarations + -- * used in primaryexp() + -------------------------------------------------------------------- + function luaY:funcargs(f) + local args = {} + local line = luaX.ln + local c = tok + if c == "(" then -- funcargs -> '(' [ explist1 ] ')' + self:log(">> funcargs: begin '('") + if line ~= lastln then + self:syntaxerror("ambiguous syntax (function call x new statement)") + end + self:next() + if tok == ")" then -- arg list is empty? + args.k = "VVOID" + else + self:explist1(args) + end + self:check_match(")", "(", line) + elseif c == "{" then -- funcargs -> constructor + self:log(">> funcargs: begin '{'") + self:constructor(args) + elseif c == "" then -- funcargs -> STRING + self:log(">> funcargs: begin ") + self:codestring(args, seminfo) + self:next() -- must use 'seminfo' before 'next' + else + self:syntaxerror("function arguments expected") + return + end--if c + f.k = "VCALL" + self:log("<< funcargs: end -- expr is a VCALL") + end + +--[[-------------------------------------------------------------------- +-- mostly expression functions +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- parses an expression in parentheses or a single variable + -- * used in primaryexp() + -------------------------------------------------------------------- + function luaY:prefixexp(v) + -- prefixexp -> NAME | '(' expr ')' + local c = tok + if c == "(" then + self:log(">> prefixexp: begin ( expr ) ") + local line = self.ln + self:next() + self:expr(v) + self:check_match(")", "(", line) + self:log("<< prefixexp: end ( expr ) ") + elseif c == "" then + self:log("prefixexp: ") + self:singlevar(v) + else + self:syntaxerror("unexpected symbol") + end--if c + end + -------------------------------------------------------------------- + -- parses a prefixexp (an expression in parentheses or a single + -- variable) or a function call specification + -- * used in simpleexp(), assignment(), expr_stat() + -------------------------------------------------------------------- + function luaY:primaryexp(v) + -- primaryexp -> + -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + self:prefixexp(v) + while true do + local c = tok + if c == "." then -- field + self:log("primaryexp: '.' field") + self:field(v) + elseif c == "[" then -- '[' exp1 ']' + self:log("primaryexp: [ exp1 ]") + local key = {} + self:index(key) + elseif c == ":" then -- ':' NAME funcargs + self:log("primaryexp: : funcargs") + local key = {} + self:next() + self:checkname(key) + self:funcargs(v) + elseif c == "(" or c == "" or c == "{" then -- funcargs + self:log("primaryexp: "..c.." funcargs") + self:funcargs(v) + else + return + end--if c + end--while + end + -------------------------------------------------------------------- + -- parses general expression types, constants handled here + -- * used in subexpr() + -------------------------------------------------------------------- + function luaY:simpleexp(v) + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | constructor + -- | FUNCTION body | primaryexp + local c = tok + if c == "" then + self:log("simpleexp: ="..seminfo) + v.k = "VK" + self:next() -- must use 'seminfo' before 'next' + elseif c == "" then + self:log("simpleexp: ="..seminfo) + self:codestring(v, seminfo) + self:next() -- must use 'seminfo' before 'next' + elseif c == "nil" then + self:log("simpleexp: nil") + v.k = "VNIL" + self:next() + elseif c == "true" then + self:log("simpleexp: true") + v.k = "VTRUE" + self:next() + elseif c == "false" then + self:log("simpleexp: false") + v.k = "VFALSE" + self:next() + elseif c == "{" then -- constructor + self:log("simpleexp: constructor") + self:constructor(v) + elseif c == "function" then + self:log("simpleexp: function") + self:next() + self:body(v, false, luaX.ln) + else + self:primaryexp(v) + end--if c + end + ------------------------------------------------------------------------ + -- Parse subexpressions. Includes handling of unary operators and binary + -- operators. A subexpr is given the rhs priority level of the operator + -- immediately left of it, if any (limit is -1 if none,) and if a binop + -- is found, limit is compared with the lhs priority level of the binop + -- in order to determine which executes first. + -- * recursively called + -- * used in expr() + ------------------------------------------------------------------------ + function luaY:subexpr(v, limit) + -- subexpr -> (simpleexp | unop subexpr) { binop subexpr } + -- * where 'binop' is any binary operator with a priority + -- higher than 'limit' + local op = tok + local uop = unopr[op] + if uop then + self:log(" subexpr: uop='"..op.."'") + self:next() + self:subexpr(v, 8) -- UNARY_PRIORITY + else + self:simpleexp(v) + end + -- expand while operators have priorities higher than 'limit' + op = tok + local binop = binopr_left[op] + while binop and binop > limit do + local v2 = {} + self:log(">> subexpr: binop='"..op.."'") + self:next() + -- read sub-expression with higher priority + local nextop = self:subexpr(v2, binopr_right[op]) + self:log("<< subexpr: -- evaluate") + op = nextop + binop = binopr_left[op] + end + return op -- return first untreated operator + end + -------------------------------------------------------------------- + -- Expression parsing starts here. Function subexpr is entered with the + -- left operator (which is non-existent) priority of -1, which is lower + -- than all actual operators. Expr information is returned in parm v. + -- * used in cond(), explist1(), index(), recfield(), listfield(), + -- prefixexp(), while_stat(), exp1() + -------------------------------------------------------------------- + function luaY:expr(v) + -- expr -> subexpr + self:log("expr:") + self:subexpr(v, -1) + end + +--[[-------------------------------------------------------------------- +-- third level parsing functions +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- parse a variable assignment sequence + -- * recursively called + -- * used in expr_stat() + -------------------------------------------------------------------- + function luaY:assignment(v) + local e = {} + local c = v.v.k + self:check_condition(c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" + or c == "VINDEXED", "syntax error") + if self:testnext(",") then -- assignment -> ',' primaryexp assignment + local nv = {} -- expdesc + nv.v = {} + self:log("assignment: ',' -- next LHS element") + self:primaryexp(nv.v) + -- lparser.c deals with some register usage conflict here + self:assignment(nv) + else -- assignment -> '=' explist1 + self:check("=") + self:log("assignment: '=' -- RHS elements follows") + self:explist1(e) + return -- avoid default + end + e.k = "VNONRELOC" + end + -------------------------------------------------------------------- + -- parse a for loop body for both versions of the for loop + -- * used in fornum(), forlist() + -------------------------------------------------------------------- + function luaY:forbody(line, isnum) + self:check("do") + self:enterblock(true) -- loop block + self:block() + self:leaveblock() + end + -------------------------------------------------------------------- + -- parse a numerical for loop, calls forbody() + -- * used in for_stat() + -------------------------------------------------------------------- + function luaY:fornum(varname, line) + -- fornum -> NAME = exp1, exp1 [, exp1] DO body + self:new_localvar(varname) + self:new_localvarstr("(for limit)") + self:new_localvarstr("(for step)") + self:log(">> fornum: begin") + self:check("=") + self:log("fornum: index start") + self:exp1() -- initial value + self:check(",") + self:log("fornum: index stop") + self:exp1() -- limit + if self:testnext(",") then + self:log("fornum: index step") + self:exp1() -- optional step + else + -- default step = 1 + end + self:log("fornum: body") + self:forbody(line, true) + self:log("<< fornum: end") + end + -------------------------------------------------------------------- + -- parse a generic for loop, calls forbody() + -- * used in for_stat() + -------------------------------------------------------------------- + function luaY:forlist(indexname) + -- forlist -> NAME {, NAME} IN explist1 DO body + self:log(">> forlist: begin") + local e = {} + self:new_localvarstr("(for generator)") + self:new_localvarstr("(for state)") + self:new_localvar(indexname) + while self:testnext(",") do + self:new_localvar(self:str_checkname()) + end + self:check("in") + local line = line + self:log("forlist: explist1") + self:explist1(e) + self:log("forlist: body") + self:forbody(line, false) + self:log("<< forlist: end") + end + -------------------------------------------------------------------- + -- parse a function name specification + -- * used in func_stat() + -------------------------------------------------------------------- + function luaY:funcname(v) + -- funcname -> NAME {field} [':' NAME] + self:log(">> funcname: begin") + local needself = false + self:singlevar(v) + while tok == "." do + self:log("funcname: -- '.' field") + self:field(v) + end + if tok == ":" then + self:log("funcname: -- ':' field") + needself = true + self:field(v) + end + self:log("<< funcname: end") + return needself + end + -------------------------------------------------------------------- + -- parse the single expressions needed in numerical for loops + -- * used in fornum() + -------------------------------------------------------------------- + function luaY:exp1() + -- exp1 -> expr + local e = {} + self:log(">> exp1: begin") + self:expr(e) + self:log("<< exp1: end") + end + -------------------------------------------------------------------- + -- parse condition in a repeat statement or an if control structure + -- * used in repeat_stat(), test_then_block() + -------------------------------------------------------------------- + function luaY:cond(v) + -- cond -> expr + self:log(">> cond: begin") + self:expr(v) -- read condition + self:log("<< cond: end") + end + -------------------------------------------------------------------- + -- parse part of an if control structure, including the condition + -- * used in if_stat() + -------------------------------------------------------------------- + function luaY:test_then_block(v) + -- test_then_block -> [IF | ELSEIF] cond THEN block + self:next() -- skip IF or ELSEIF + self:log("test_then_block: test condition") + self:cond(v) + self:check("then") + self:log("test_then_block: then block") + self:block() -- 'then' part + end + -------------------------------------------------------------------- + -- parse a local function statement + -- * used in local_stat() + -------------------------------------------------------------------- + function luaY:localfunc() + -- localfunc -> NAME body + local v, b = {} + self:log("localfunc: begin") + self:new_localvar(self:str_checkname()) + v.k = "VLOCAL" + self:log("localfunc: body") + self:body(b, false, luaX.ln) + self:log("localfunc: end") + end + -------------------------------------------------------------------- + -- parse a local variable declaration statement + -- * used in local_stat() + -------------------------------------------------------------------- + function luaY:localstat() + -- localstat -> NAME {',' NAME} ['=' explist1] + self:log(">> localstat: begin") + local e = {} + repeat + self:new_localvar(self:str_checkname()) + until not self:testnext(",") + if self:testnext("=") then + self:log("localstat: -- assignment") + self:explist1(e) + else + e.k = "VVOID" + end + self:log("<< localstat: end") + end + -------------------------------------------------------------------- + -- parse a list of comma-separated expressions + -- * used in return_stat(), localstat(), funcargs(), assignment(), + -- forlist() + -------------------------------------------------------------------- + function luaY:explist1(e) + -- explist1 -> expr { ',' expr } + self:log(">> explist1: begin") + self:expr(e) + while self:testnext(",") do + self:log("explist1: ',' -- continuation") + self:expr(e) + end + self:log("<< explist1: end") + end + -------------------------------------------------------------------- + -- parse function declaration body + -- * used in simpleexp(), localfunc(), func_stat() + -------------------------------------------------------------------- + function luaY:body(e, needself, line) + -- body -> '(' parlist ')' chunk END + self:open_func() + self:log("body: begin") + self:check("(") + if needself then + self:create_local("self") + end + self:log("body: parlist") + self:parlist() + self:check(")") + self:log("body: chunk") + self:chunk() + self:check_match("end", "function", line) + self:log("body: end") + self:close_func() + end + -------------------------------------------------------------------- + -- parse a code block or unit + -- * used in do_stat(), while_stat(), repeat_stat(), forbody(), + -- test_then_block(), if_stat() + -------------------------------------------------------------------- + function luaY:block() + -- block -> chunk + self:log("block: begin") + self:enterblock(false) + self:chunk() + self:leaveblock() + self:log("block: end") + end + +--[[-------------------------------------------------------------------- +-- second level parsing functions, all with '_stat' suffix +-- * stat() -> *_stat() +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- initial parsing for a for loop, calls fornum() or forlist() + -- * used in stat() + -------------------------------------------------------------------- + function luaY:for_stat() + -- stat -> for_stat -> fornum | forlist + local line = line + self:log("for_stat: begin") + self:enterblock(false) -- block to control variable scope + self:next() -- skip 'for' + local varname = self:str_checkname() -- first variable name + local c = tok + if c == "=" then + self:log("for_stat: numerical loop") + self:fornum(varname, line) + elseif c == "," or c == "in" then + self:log("for_stat: list-based loop") + self:forlist(varname) + else + self:syntaxerror("'=' or 'in' expected") + end + self:check_match("end", "for", line) + self:leaveblock() + self:log("for_stat: end") + end + -------------------------------------------------------------------- + -- parse a while-do control structure, body processed by block() + -- * used in stat() + -------------------------------------------------------------------- + function luaY:while_stat() + -- stat -> while_stat -> WHILE cond DO block END + local line = line + local v = {} + self:next() -- skip WHILE + self:log("while_stat: begin/condition") + self:expr(v) -- parse condition + self:enterblock(true) + self:check("do") + self:log("while_stat: block") + self:block() + self:check_match("end", "while", line) + self:leaveblock() + self:log("while_stat: end") + end + -------------------------------------------------------------------- + -- parse a repeat-until control structure, body parsed by block() + -- * used in stat() + -------------------------------------------------------------------- + function luaY:repeat_stat() + -- stat -> repeat_stat -> REPEAT block UNTIL cond + local line = line + local v = {} + self:log("repeat_stat: begin") + self:enterblock(true) + self:next() + self:block() + self:check_match("until", "repeat", line) + self:log("repeat_stat: condition") + self:cond(v) + self:leaveblock() + self:log("repeat_stat: end") + end + -------------------------------------------------------------------- + -- parse an if control structure + -- * used in stat() + -------------------------------------------------------------------- + function luaY:if_stat() + -- stat -> if_stat -> IF cond THEN block + -- {ELSEIF cond THEN block} [ELSE block] END + local line = line + local v = {} + self:log("if_stat: if...then") + self:test_then_block(v) -- IF cond THEN block + while tok == "elseif" do + self:log("if_stat: elseif...then") + self:test_then_block(v) -- ELSEIF cond THEN block + end + if tok == "else" then + self:log("if_stat: else...") + self:next() -- skip ELSE + self:block() -- 'else' part + end + self:check_match("end", "if", line) + self:log("if_stat: end") + end + -------------------------------------------------------------------- + -- parse a return statement + -- * used in stat() + -------------------------------------------------------------------- + function luaY:return_stat() + -- stat -> return_stat -> RETURN explist + local e = {} + self:next() -- skip RETURN + local c = tok + if block_follow[c] or c == ";" then + -- return no values + self:log("return_stat: no return values") + else + self:log("return_stat: begin") + self:explist1(e) -- optional return values + self:log("return_stat: end") + end + end + -------------------------------------------------------------------- + -- parse a break statement + -- * used in stat() + -------------------------------------------------------------------- + function luaY:break_stat() + -- stat -> break_stat -> BREAK + local bl = fs.bl + self:next() -- skip BREAK + while bl and not bl.isbreakable do -- find a breakable block + bl = bl.prev + end + if not bl then + self:syntaxerror("no loop to break") + end + self:log("break_stat: -- break out of loop") + end + -------------------------------------------------------------------- + -- parse a function call with no returns or an assignment statement + -- * the struct with .prev is used for name searching in lparse.c, + -- so it is retained for now; present in assignment() also + -- * used in stat() + -------------------------------------------------------------------- + function luaY:expr_stat() + -- stat -> expr_stat -> func | assignment + local v = {} + v.v = {} + self:primaryexp(v.v) + if v.v.k == "VCALL" then -- stat -> func + -- call statement uses no results + self:log("expr_stat: function call k='"..v.v.k.."'") + else -- stat -> assignment + self:log("expr_stat: assignment k='"..v.v.k.."'") + v.prev = nil + self:assignment(v) + end + end + -------------------------------------------------------------------- + -- parse a function statement + -- * used in stat() + -------------------------------------------------------------------- + function luaY:function_stat() + -- stat -> function_stat -> FUNCTION funcname body + local line = line + local v, b = {}, {} + self:log("function_stat: begin") + self:next() -- skip FUNCTION + local needself = self:funcname(v) + self:log("function_stat: body needself='"..tostring(needself).."'") + self:body(b, needself, line) + self:log("function_stat: end") + end + -------------------------------------------------------------------- + -- parse a simple block enclosed by a DO..END pair + -- * used in stat() + -------------------------------------------------------------------- + function luaY:do_stat() + -- stat -> do_stat -> DO block END + self:next() -- skip DO + self:log("do_stat: begin") + self:block() + self:log("do_stat: end") + self:check_match("end", "do", line) + end + -------------------------------------------------------------------- + -- parse a statement starting with LOCAL + -- * used in stat() + -------------------------------------------------------------------- + function luaY:local_stat() + -- stat -> local_stat -> LOCAL FUNCTION localfunc + -- -> LOCAL localstat + self:next() -- skip LOCAL + if self:testnext("function") then -- local function? + self:log("local_stat: local function") + self:localfunc() + else + self:log("local_stat: local statement") + self:localstat() + end + end + +--[[-------------------------------------------------------------------- +-- main function, top level parsing functions +-- * [entry] -> parser() -> chunk() -> stat() +----------------------------------------------------------------------]] + + -------------------------------------------------------------------- + -- initial parsing for statements, calls '_stat' suffixed functions + -- * used in chunk() + -------------------------------------------------------------------- + function luaY:stat() + line = luaX.ln + local c = tok + local fn = stat_call[c] + -- handles: if while do for repeat function local return break + if fn then + self:log("-- STATEMENT: begin '"..c.."' line="..line) + self[fn](self) + self:log("-- STATEMENT: end '"..c.."'") + -- return or break must be last statement + if c == "return" or c == "break" then return true end + else + self:log("-- STATEMENT: begin 'expr' line="..line) + self:expr_stat() + self:log("-- STATEMENT: end 'expr'") + end + self:log("") + return false + end + -------------------------------------------------------------------- + -- parse a chunk, which consists of a bunch of statements + -- * used in parser(), body(), block() + -------------------------------------------------------------------- + function luaY:chunk() + -- chunk -> { stat [';'] } + self:log("chunk:") + local islast = false + while not islast and not block_follow[tok] do + islast = self:stat() + self:testnext(";") + end + end + -------------------------------------------------------------------- + -- performs parsing, returns parsed data structure + -------------------------------------------------------------------- + function luaY:parser() + self:log("-- TOP: begin") + self:open_func() + self:log("") + self:next() -- read first token + self:chunk() + self:check_condition(tok == "", " expected") + self:close_func() + self:log("-- TOP: end") + return top_fs + end + -------------------------------------------------------------------- + return luaY -- return actual module to user, done +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk2.lua new file mode 100644 index 0000000..6378366 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk2.lua @@ -0,0 +1,106 @@ +--[[-------------------------------------------------------------------- + + lzio.lua + Lua 5 buffered streams in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- local zio_init = require("lzio.lua") +-- local z = zio_init("@") +-- local z = zio_init("") +-- z:getc() +-- * get next character from input stream +-- z:fill() +-- * fills an empty stream buffer +-- z.name +-- * name of the chunk, "@" or "=string" +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Format of z structure (ZIO) +-- z.n -- bytes still unread +-- z.p -- last read position in buffer +-- z.reader -- chunk reader function +-- z.data -- data buffer +-- z.name -- name of stream +----------------------------------------------------------------------]] + +return +function(buff) +--[[-------------------------------------------------------------------- +-- initialize reader +-- * reader should return a string, or nil if nothing else to parse +----------------------------------------------------------------------]] + local reader + local z = {} + if string.sub(buff, 1, 1) == "@" then + ---------------------------------------------------------------- + -- create a chunk reader function from a source file + ---------------------------------------------------------------- + z.name = buff + local BUFFERSIZE = 512 + local h = io.open(string.sub(buff, 2), "r") + if not h then return nil end + reader = function() + if not h or io.type(h) == "closed file" then return nil end + local buff = h:read(BUFFERSIZE) + if not buff then h:close(); h = nil end + return buff + end + else + ---------------------------------------------------------------- + -- create a chunk reader function from a source string + ---------------------------------------------------------------- + z.name = "=string" + reader = function() + if not buff then return nil end + local data = buff + buff = nil + return data + end + end +--[[-------------------------------------------------------------------- +-- fills an empty stream buffer, returns first character +----------------------------------------------------------------------]] + function z:fill() + local data = z.reader() + z.data = data + if not data or data == "" then return "EOZ" end + z.n, z.p = string.len(data) - 1, 1 + return string.sub(data, 1, 1) + end +--[[-------------------------------------------------------------------- +-- get next character, fills buffer if characters needed +----------------------------------------------------------------------]] + function z:getc() + local n, p = z.n, z.p + 1 + if n > 0 then + z.n, z.p = n - 1, p + return string.sub(z.data, p, p) + else + return self:fill() + end + end +--[[-------------------------------------------------------------------- +-- initialize input stream object +----------------------------------------------------------------------]] + if not reader then return end + z.reader = reader + z.data = "" + z.n, z.p = 0, 0 + return z +--[[------------------------------------------------------------------]] +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk4.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk4.lua new file mode 100644 index 0000000..d97c795 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lzio_mk4.lua @@ -0,0 +1,82 @@ +--[[-------------------------------------------------------------------- + + lzio.lua + Lua 5 buffered streams in Lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * this is a line-based input streamer for the MK4 lexer +-- * all EOL (end-of-line) characters are translated to "\n" +-- * if last line in a file does not have an EOL character, this +-- streamer adds one, the ambiguity is due to "*l" stripping +-- * EOF uses an empty string to simplify testing in lexer +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- local zio_init = require("lzio.lua") +-- local z = zio_init("@") +-- local z = zio_init("") +-- z:getln() +-- * get next line from input stream +-- z.name +-- * name of the chunk, "@" or "=string" +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Format of z structure (ZIO) +-- z.getln -- chunk reader function, reads line-by-line +-- z.name -- name of stream +----------------------------------------------------------------------]] + +return +function(buff) +--[[-------------------------------------------------------------------- +-- initialize reader +-- * reader should return a string with an EOL character, or an empty +-- string if there is nothing else to parse +----------------------------------------------------------------------]] + local reader + local z = {} + if string.sub(buff, 1, 1) == "@" then + ---------------------------------------------------------------- + -- create a chunk reader function from a source file + ---------------------------------------------------------------- + z.name = buff + local h = io.open(string.sub(buff, 2), "r") + if not h then return nil end + reader = function() + if not h or io.type(h) == "closed file" then return nil end + local data = h:read("*l") + if not data then h:close(); return "" end + return data.."\n" + end + else + ---------------------------------------------------------------- + -- create a chunk reader function from a source string + ---------------------------------------------------------------- + z.name = "=string" + reader = function() + if not buff then return nil end + local p, q, data, eol = string.find(buff, "([^\r\n]*)(\r?\n?)") + buff = string.sub(buff, q + 1) + if data == "" and eol == "" then return "" end + return data..eol + end + end +--[[-------------------------------------------------------------------- +-- initialize input stream object +----------------------------------------------------------------------]] + if not reader then return end + z.getln = reader + return z +--[[------------------------------------------------------------------]] +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk2.lua new file mode 100644 index 0000000..873afd1 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk2.lua @@ -0,0 +1,94 @@ +--[[-------------------------------------------------------------------- + + bench_llex.lua + Benchmark test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +local zio_init = require("../lzio_mk2") +local lex_init = require("../llex_mk2") + +------------------------------------------------------------------------ +-- load in a standard set of sample files +-- * file set is 5.0.3 front end set sans luac.lua +------------------------------------------------------------------------ + +local fileset, totalsize = {}, 0 +for fn in string.gfind([[ +../../orig-5.0.3/lcode.lua +../../orig-5.0.3/ldump.lua +../../orig-5.0.3/llex.lua +../../orig-5.0.3/lopcodes.lua +../../orig-5.0.3/lparser.lua +../../orig-5.0.3/lzio.lua +]], "%S+") do + table.insert(fileset, fn) +end + +for i = 1, table.getn(fileset) do + local fn = fileset[i] + local inf = io.open(fn, "rb") + if not inf then + error("failed to open "..fn.." for reading") + end + local data = inf:read("*a") + local data_sz = string.len(data) + inf:close() + if not data or data_sz == 0 then + error("failed to read data from "..fn.." or file is zero-length") + end + totalsize = totalsize + data_sz + fileset[i] = data +end + +------------------------------------------------------------------------ +-- benchmark tester +------------------------------------------------------------------------ + +local DURATION = 5 -- how long the benchmark should run + +local time = os.time +local lexedsize = 0 +local tnow, elapsed = time(), 0 + +while time() == tnow do end -- wait for second to click over +tnow = time() + +while true do + for i = 1, table.getn(fileset) do + ------------------------------------------------------------ + local chunk = fileset[i] + local z = zio_init(chunk) + local luaX = lex_init(z, "=string") + while true do + local tok, seminfo = luaX:lex() + if tok == "" then break end + end + ------------------------------------------------------------ + lexedsize = lexedsize + string.len(chunk) + if time() > tnow then + tnow = time() + elapsed = elapsed + 1 + if elapsed >= DURATION then + -- report performance of lexer + lexedsize = lexedsize / 1024 + local speed = lexedsize / DURATION + print("Lexer performance:") + print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) + print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) + -- repeat until user breaks program + elapsed = 0 + end + end + ------------------------------------------------------------ + end--for +end--while + +-- end of script diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk3.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk3.lua new file mode 100644 index 0000000..6b2a4a6 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk3.lua @@ -0,0 +1,92 @@ +--[[-------------------------------------------------------------------- + + bench_llex.lua + Benchmark test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +local lex_init = require("../llex_mk3") + +------------------------------------------------------------------------ +-- load in a standard set of sample files +-- * file set is 5.0.3 front end set sans luac.lua +------------------------------------------------------------------------ + +local fileset, totalsize = {}, 0 +for fn in string.gfind([[ +../../orig-5.0.3/lcode.lua +../../orig-5.0.3/ldump.lua +../../orig-5.0.3/llex.lua +../../orig-5.0.3/lopcodes.lua +../../orig-5.0.3/lparser.lua +../../orig-5.0.3/lzio.lua +]], "%S+") do + table.insert(fileset, fn) +end + +for i = 1, table.getn(fileset) do + local fn = fileset[i] + local inf = io.open(fn, "rb") + if not inf then + error("failed to open "..fn.." for reading") + end + local data = inf:read("*a") + local data_sz = string.len(data) + inf:close() + if not data or data_sz == 0 then + error("failed to read data from "..fn.." or file is zero-length") + end + totalsize = totalsize + data_sz + fileset[i] = data +end + +------------------------------------------------------------------------ +-- benchmark tester +------------------------------------------------------------------------ + +local DURATION = 5 -- how long the benchmark should run + +local time = os.time +local lexedsize = 0 +local tnow, elapsed = time(), 0 + +while time() == tnow do end -- wait for second to click over +tnow = time() + +while true do + for i = 1, table.getn(fileset) do + ------------------------------------------------------------ + local chunk = fileset[i] + local luaX = lex_init(chunk, "=string") + while true do + local tok, seminfo = luaX:lex() + if tok == "" then break end + end + ------------------------------------------------------------ + lexedsize = lexedsize + string.len(chunk) + if time() > tnow then + tnow = time() + elapsed = elapsed + 1 + if elapsed >= DURATION then + -- report performance of lexer + lexedsize = lexedsize / 1024 + local speed = lexedsize / DURATION + print("Lexer performance:") + print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) + print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) + -- repeat until user breaks program + elapsed = 0 + end + end + ------------------------------------------------------------ + end--for +end--while + +-- end of script diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk4.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk4.lua new file mode 100644 index 0000000..b94386b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/bench_llex_mk4.lua @@ -0,0 +1,94 @@ +--[[-------------------------------------------------------------------- + + bench_llex.lua + Benchmark test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +local zio_init = require("../lzio_mk4") +local lex_init = require("../llex_mk4") + +------------------------------------------------------------------------ +-- load in a standard set of sample files +-- * file set is 5.0.3 front end set sans luac.lua +------------------------------------------------------------------------ + +local fileset, totalsize = {}, 0 +for fn in string.gfind([[ +../../orig-5.0.3/lcode.lua +../../orig-5.0.3/ldump.lua +../../orig-5.0.3/llex.lua +../../orig-5.0.3/lopcodes.lua +../../orig-5.0.3/lparser.lua +../../orig-5.0.3/lzio.lua +]], "%S+") do + table.insert(fileset, fn) +end + +for i = 1, table.getn(fileset) do + local fn = fileset[i] + local inf = io.open(fn, "rb") + if not inf then + error("failed to open "..fn.." for reading") + end + local data = inf:read("*a") + local data_sz = string.len(data) + inf:close() + if not data or data_sz == 0 then + error("failed to read data from "..fn.." or file is zero-length") + end + totalsize = totalsize + data_sz + fileset[i] = data +end + +------------------------------------------------------------------------ +-- benchmark tester +------------------------------------------------------------------------ + +local DURATION = 5 -- how long the benchmark should run + +local time = os.time +local lexedsize = 0 +local tnow, elapsed = time(), 0 + +while time() == tnow do end -- wait for second to click over +tnow = time() + +while true do + for i = 1, table.getn(fileset) do + ------------------------------------------------------------ + local chunk = fileset[i] + local z = zio_init(chunk) + local luaX = lex_init(z, "=string") + while true do + local tok, seminfo = luaX:lex() + if tok == "" then break end + end + ------------------------------------------------------------ + lexedsize = lexedsize + string.len(chunk) + if time() > tnow then + tnow = time() + elapsed = elapsed + 1 + if elapsed >= DURATION then + -- report performance of lexer + lexedsize = lexedsize / 1024 + local speed = lexedsize / DURATION + print("Lexer performance:") + print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) + print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) + -- repeat until user breaks program + elapsed = 0 + end + end + ------------------------------------------------------------ + end--for +end--while + +-- end of script diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_01.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_01.lua new file mode 100644 index 0000000..379cc9d --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_01.lua @@ -0,0 +1,9 @@ +-- START OF SOURCE -- +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_02.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_02.lua new file mode 100644 index 0000000..13eb2e6 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_02.lua @@ -0,0 +1,10 @@ +-- START OF SOURCE -- +-- foobar +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_03.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_03.lua new file mode 100644 index 0000000..33df29c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_03.lua @@ -0,0 +1,21 @@ +-- START OF SOURCE -- +do +end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_04.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_04.lua new file mode 100644 index 0000000..d0fefbc --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_04.lua @@ -0,0 +1,31 @@ +-- START OF SOURCE -- +do end +do end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'do' line=2 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_05.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_05.lua new file mode 100644 index 0000000..8d6f962 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_05.lua @@ -0,0 +1,129 @@ +-- START OF SOURCE -- +foo() +foo{} +foo"" +foo:bar() +foo=false +foo.bar=true +foo[true]=nil +foo,bar=1,"a" +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + primaryexp: ( funcargs + funcargs: begin '(' + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + primaryexp: { funcargs + funcargs: begin '{' + constructor: begin + constructor: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + primaryexp: funcargs + funcargs: begin + codestring: "" + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + primaryexp: : funcargs + checkname: + str_checkname: 'bar' + codestring: "bar" + funcargs: begin '(' + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: false + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + primaryexp: '.' field + field: operator=. + checkname: + str_checkname: 'bar' + codestring: "bar" + expr_stat: assignment k='VINDEXED' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: true + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=7 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + primaryexp: [ exp1 ] + index: begin '[' + expr: + simpleexp: true + index: end ']' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: nil + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=8 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: ',' -- next LHS element + prefixexp: + str_checkname: 'bar' + singlevar: name='bar' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + explist1: ',' -- continuation + expr: + simpleexp: =a + codestring: "a" + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_06.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_06.lua new file mode 100644 index 0000000..ca7776e --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_06.lua @@ -0,0 +1,132 @@ +-- START OF SOURCE -- +foo=true +foo=false +foo=nil +foo=1.23e45 +foo=-1 +foo=(0) +foo=1+2 +foo=1+2*3-4/5 +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: true + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: false + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: nil + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1.23e+45 + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + subexpr: uop='-' + simpleexp: =1 + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: begin ( expr ) + expr: + simpleexp: =0 + prefixexp: end ( expr ) + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=7 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + subexpr: binop='+' + simpleexp: =2 + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=8 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + subexpr: binop='+' + simpleexp: =2 + subexpr: binop='*' + simpleexp: =3 + subexpr: -- evaluate + subexpr: -- evaluate + subexpr: binop='-' + simpleexp: =4 + subexpr: binop='/' + simpleexp: =5 + subexpr: -- evaluate + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_07.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_07.lua new file mode 100644 index 0000000..8c0a738 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_07.lua @@ -0,0 +1,147 @@ +-- START OF SOURCE -- +if foo then foo=1 end +if foo then foo=1 else foo=0 end +if foo then foo=1 elseif not foo then foo=0 end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'if' line=1 + if_stat: if...then + test_then_block: test condition + cond: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + cond: end + test_then_block: then block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: end + -- STATEMENT: end 'if' + + -- STATEMENT: begin 'if' line=2 + if_stat: if...then + test_then_block: test condition + cond: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + cond: end + test_then_block: then block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: else... + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =0 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: end + -- STATEMENT: end 'if' + + -- STATEMENT: begin 'if' line=3 + if_stat: if...then + test_then_block: test condition + cond: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + cond: end + test_then_block: then block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: elseif...then + test_then_block: test condition + cond: begin + expr: + subexpr: uop='not' + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + cond: end + test_then_block: then block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =0 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: end + -- STATEMENT: end 'if' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_08.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_08.lua new file mode 100644 index 0000000..d086c98 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_08.lua @@ -0,0 +1,66 @@ +-- START OF SOURCE -- +do return end +do return 123 end +do return "foo","bar" end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'do' line=2 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: begin + explist1: begin + expr: + simpleexp: =123 + explist1: end + return_stat: end + -- STATEMENT: end 'return' + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'do' line=3 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: begin + explist1: begin + expr: + simpleexp: =foo + codestring: "foo" + explist1: ',' -- continuation + expr: + simpleexp: =bar + codestring: "bar" + explist1: end + return_stat: end + -- STATEMENT: end 'return' + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_09.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_09.lua new file mode 100644 index 0000000..2236388 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_09.lua @@ -0,0 +1,97 @@ +-- START OF SOURCE -- +while true do foo=not foo end +while foo~=42 do foo=foo-1 end +while true do break end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'while' line=1 + while_stat: begin/condition + expr: + simpleexp: true + enterblock(isbreakable=true) + while_stat: block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + subexpr: uop='not' + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + while_stat: end + -- STATEMENT: end 'while' + + -- STATEMENT: begin 'while' line=2 + while_stat: begin/condition + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + subexpr: binop='~=' + simpleexp: =42 + subexpr: -- evaluate + enterblock(isbreakable=true) + while_stat: block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + subexpr: binop='-' + simpleexp: =1 + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + while_stat: end + -- STATEMENT: end 'while' + + -- STATEMENT: begin 'while' line=3 + while_stat: begin/condition + expr: + simpleexp: true + enterblock(isbreakable=true) + while_stat: block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'break' line=3 + break_stat: -- break out of loop + -- STATEMENT: end 'break' + leaveblock + block: end + leaveblock + while_stat: end + -- STATEMENT: end 'while' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_10.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_10.lua new file mode 100644 index 0000000..72f7ae3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_10.lua @@ -0,0 +1,106 @@ +-- START OF SOURCE -- +repeat foo=foo.."bar" until false +repeat foo=foo/2 until foo<1 +repeat break until false +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'repeat' line=1 + repeat_stat: begin + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + subexpr: binop='..' + simpleexp: =bar + codestring: "bar" + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + repeat_stat: condition + cond: begin + expr: + simpleexp: false + cond: end + leaveblock + repeat_stat: end + -- STATEMENT: end 'repeat' + + -- STATEMENT: begin 'repeat' line=2 + repeat_stat: begin + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + subexpr: binop='/' + simpleexp: =2 + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + repeat_stat: condition + cond: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + subexpr: binop='<' + simpleexp: =1 + subexpr: -- evaluate + cond: end + leaveblock + repeat_stat: end + -- STATEMENT: end 'repeat' + + -- STATEMENT: begin 'repeat' line=3 + repeat_stat: begin + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'break' line=3 + break_stat: -- break out of loop + -- STATEMENT: end 'break' + leaveblock + block: end + repeat_stat: condition + cond: begin + expr: + simpleexp: false + cond: end + leaveblock + repeat_stat: end + -- STATEMENT: end 'repeat' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_11.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_11.lua new file mode 100644 index 0000000..8af611b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_11.lua @@ -0,0 +1,175 @@ +-- START OF SOURCE -- +for i=1,10 do foo=i end +for i=1,10,2 do break end +for i in foo do bar=0 end +for i,j in foo,bar do baz=0 end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'for' line=1 + for_stat: begin + enterblock(isbreakable=false) + str_checkname: 'i' + for_stat: numerical loop + fornum: begin + fornum: index start + exp1: begin + expr: + simpleexp: =1 + exp1: end + fornum: index stop + exp1: begin + expr: + simpleexp: =10 + exp1: end + fornum: body + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'i' + singlevar: name='i' + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + fornum: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=2 + for_stat: begin + enterblock(isbreakable=false) + str_checkname: 'i' + for_stat: numerical loop + fornum: begin + fornum: index start + exp1: begin + expr: + simpleexp: =1 + exp1: end + fornum: index stop + exp1: begin + expr: + simpleexp: =10 + exp1: end + fornum: index step + exp1: begin + expr: + simpleexp: =2 + exp1: end + fornum: body + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'break' line=2 + break_stat: -- break out of loop + -- STATEMENT: end 'break' + leaveblock + block: end + leaveblock + fornum: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=3 + for_stat: begin + enterblock(isbreakable=false) + str_checkname: 'i' + for_stat: list-based loop + forlist: begin + forlist: explist1 + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + explist1: end + forlist: body + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'bar' + singlevar: name='bar' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =0 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + forlist: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=4 + for_stat: begin + enterblock(isbreakable=false) + str_checkname: 'i' + for_stat: list-based loop + forlist: begin + str_checkname: 'j' + forlist: explist1 + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'bar' + singlevar: name='bar' + explist1: end + forlist: body + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'baz' + singlevar: name='baz' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =0 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + forlist: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_12.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_12.lua new file mode 100644 index 0000000..916fc7f --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_12.lua @@ -0,0 +1,46 @@ +-- START OF SOURCE -- +local foo +local foo,bar,baz +local foo,bar="foo","bar" +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=2 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + str_checkname: 'bar' + str_checkname: 'baz' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=3 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + str_checkname: 'bar' + localstat: -- assignment + explist1: begin + expr: + simpleexp: =foo + codestring: "foo" + explist1: ',' -- continuation + expr: + simpleexp: =bar + codestring: "bar" + explist1: end + localstat: end + -- STATEMENT: end 'local' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_13.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_13.lua new file mode 100644 index 0000000..8ddd3ea --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_13.lua @@ -0,0 +1,99 @@ +-- START OF SOURCE -- +local function foo() return end +local function foo(a) return end +local function foo(x,y,z) return end +local function foo(x,...) return end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=2 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'a' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=3 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + str_checkname: 'y' + str_checkname: 'z' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=4 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + parlist: ... (dots) + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=4 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_14.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_14.lua new file mode 100644 index 0000000..aa0069a --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_14.lua @@ -0,0 +1,107 @@ +-- START OF SOURCE -- +function foo() return end +function foo(a) return end +function foo(x,y,z) return end +function foo(x,...) return end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar: name='foo' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=2 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar: name='foo' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'a' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=3 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar: name='foo' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + str_checkname: 'y' + str_checkname: 'z' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=4 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar: name='foo' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + parlist: ... (dots) + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=4 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_15.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_15.lua new file mode 100644 index 0000000..73cdac3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_15.lua @@ -0,0 +1,135 @@ +-- START OF SOURCE -- +function foo.bar(p) return end +function foo.bar.baz(p) return end +function foo:bar(p) return end +function foo.bar.baz(p) return end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar: name='foo' + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'p' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=2 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar: name='foo' + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'baz' + codestring: "baz" + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'p' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=3 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar: name='foo' + funcname: -- ':' field + field: operator=: + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: end + function_stat: body needself='true' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'p' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=4 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar: name='foo' + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'baz' + codestring: "baz" + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'p' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=4 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_16.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_16.lua new file mode 100644 index 0000000..b53b2fb --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_16.lua @@ -0,0 +1,87 @@ +-- START OF SOURCE -- +foo = function() return end +foo = function(x,y) return end +foo = function(...) return end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: function + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: function + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + str_checkname: 'y' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: function + open_func + body: begin + body: parlist + parlist: begin + parlist: ... (dots) + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_17.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_17.lua new file mode 100644 index 0000000..87634d3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_17.lua @@ -0,0 +1,110 @@ +-- START OF SOURCE -- +foo = {} +foo = { 1,2,3; "foo"; } +foo = { bar=77, baz=88, } +foo = { ["bar"]=77, ["baz"]=88, } +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: constructor + constructor: begin + constructor: end + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: constructor + constructor: begin + listfield: expr + expr: + simpleexp: =1 + listfield: expr + expr: + simpleexp: =2 + listfield: expr + expr: + simpleexp: =3 + listfield: expr + expr: + simpleexp: =foo + codestring: "foo" + constructor: end + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: constructor + constructor: begin + recfield: name + checkname: + str_checkname: 'bar' + codestring: "bar" + expr: + simpleexp: =77 + recfield: name + checkname: + str_checkname: 'baz' + codestring: "baz" + expr: + simpleexp: =88 + constructor: end + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'foo' + singlevar: name='foo' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: constructor + constructor: begin + recfield: [ exp1 ] + index: begin '[' + expr: + simpleexp: =bar + codestring: "bar" + index: end ']' + expr: + simpleexp: =77 + recfield: [ exp1 ] + index: begin '[' + expr: + simpleexp: =baz + codestring: "baz" + index: end ']' + expr: + simpleexp: =88 + constructor: end + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_01.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_01.lua new file mode 100644 index 0000000..732b4d6 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_01.lua @@ -0,0 +1,26 @@ +-- START OF SOURCE -- + print(a) +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VGLOBAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_02.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_02.lua new file mode 100644 index 0000000..9863b4a --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_02.lua @@ -0,0 +1,35 @@ +-- START OF SOURCE -- + local a + print(a) +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'a' + new_localvar: 'a' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_03.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_03.lua new file mode 100644 index 0000000..bc37280 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_03.lua @@ -0,0 +1,64 @@ +-- START OF SOURCE -- + do + local a + print(a) + end + print(a) +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'local' line=2 + local_stat: local statement + localstat: begin + str_checkname: 'a' + new_localvar: 'a' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VGLOBAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_04.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_04.lua new file mode 100644 index 0000000..b2bac4b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_04.lua @@ -0,0 +1,77 @@ +-- START OF SOURCE -- + local a,b,c + do + local b + print(b) + end + print(b) +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'a' + new_localvar: 'a' + str_checkname: 'b' + new_localvar: 'b' + str_checkname: 'c' + new_localvar: 'c' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'do' line=2 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'local' line=3 + local_stat: local statement + localstat: begin + str_checkname: 'b' + new_localvar: 'b' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'b' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'b' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_05.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_05.lua new file mode 100644 index 0000000..6885f01 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_05.lua @@ -0,0 +1,43 @@ +-- START OF SOURCE -- + local function foo() end + bar = foo +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + new_localvar: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_06.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_06.lua new file mode 100644 index 0000000..eb658ed --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_06.lua @@ -0,0 +1,70 @@ +-- START OF SOURCE -- + do + local function foo() end + bar = foo + end + baz = foo +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'local' line=2 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + new_localvar: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_07.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_07.lua new file mode 100644 index 0000000..6403234 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_07.lua @@ -0,0 +1,84 @@ +-- START OF SOURCE -- + local foo + local function bar() + baz = nil + foo = bar() + end + foo = bar +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + new_localvar: 'foo' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=2 + local_stat: local function + localfunc: begin + str_checkname: 'bar' + new_localvar: 'bar' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: nil + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VUPVAL' + expr_stat: assignment k='VUPVAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VUPVAL' + primaryexp: ( funcargs + funcargs: begin '(' + funcargs: end -- expr is a VCALL + explist1: end + -- STATEMENT: end 'expr' + + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_08.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_08.lua new file mode 100644 index 0000000..594e267 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_08.lua @@ -0,0 +1,159 @@ +-- START OF SOURCE -- + local foo + local function bar() + local function baz() + local foo, bar + foo = bar + foo = baz + end + foo = bar + foo = baz + end + foo = bar + foo = baz +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + new_localvar: 'foo' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=2 + local_stat: local function + localfunc: begin + str_checkname: 'bar' + new_localvar: 'bar' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'local' line=3 + local_stat: local function + localfunc: begin + str_checkname: 'baz' + new_localvar: 'baz' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'local' line=4 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + new_localvar: 'foo' + str_checkname: 'bar' + new_localvar: 'bar' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VUPVAL' + explist1: end + -- STATEMENT: end 'expr' + + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=8 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VUPVAL' + expr_stat: assignment k='VUPVAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VUPVAL' + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=9 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VUPVAL' + expr_stat: assignment k='VUPVAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=11 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=12 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VGLOBAL' + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_09.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_09.lua new file mode 100644 index 0000000..bfa3920 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_09.lua @@ -0,0 +1,53 @@ +-- START OF SOURCE -- + function foo:bar() + print(self) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: -- ':' field + field: operator=: + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: end + function_stat: body needself='true' + open_func + body: begin + new_localvar: 'self' + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'self' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_10.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_10.lua new file mode 100644 index 0000000..9a38883 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_10.lua @@ -0,0 +1,49 @@ +-- START OF SOURCE -- + function foo(...) + print(arg) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + parlist: ... (dots) + new_localvar: 'arg' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'arg' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_11.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_11.lua new file mode 100644 index 0000000..e4c9e21 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_11.lua @@ -0,0 +1,79 @@ +-- START OF SOURCE -- + local c,d + function foo(a,b,c) + print(a,c,d,e) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'c' + new_localvar: 'c' + str_checkname: 'd' + new_localvar: 'd' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'function' line=2 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'a' + new_localvar: 'a' + str_checkname: 'b' + new_localvar: 'b' + str_checkname: 'c' + new_localvar: 'c' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'c' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'd' + singlevar(kind): 'VUPVAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'e' + singlevar(kind): 'VGLOBAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_12.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_12.lua new file mode 100644 index 0000000..b278ba2 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_12.lua @@ -0,0 +1,94 @@ +-- START OF SOURCE -- + function foo(a,b) + local bar = function(c,d) + print(a,b,c,d) + end + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'a' + new_localvar: 'a' + str_checkname: 'b' + new_localvar: 'b' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'local' line=2 + local_stat: local statement + localstat: begin + str_checkname: 'bar' + new_localvar: 'bar' + localstat: -- assignment + explist1: begin + expr: + simpleexp: function + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'c' + new_localvar: 'c' + str_checkname: 'd' + new_localvar: 'd' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VUPVAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'b' + singlevar(kind): 'VUPVAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'c' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'd' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + body: end + close_func + explist1: end + localstat: end + -- STATEMENT: end 'local' + + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_13.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_13.lua new file mode 100644 index 0000000..6e4850c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_13.lua @@ -0,0 +1,117 @@ +-- START OF SOURCE -- + for i = 1,10 do + print(i) + end + for i = 1,10,-2 do + print(i) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'for' line=1 + for_stat: begin + enterblock(isbreakable=false) + str_checkname: 'i' + for_stat: numerical loop + new_localvar: 'i' + new_localvar: '(for limit)' + new_localvar: '(for step)' + fornum: begin + fornum: index start + exp1: begin + expr: + simpleexp: =1 + exp1: end + fornum: index stop + exp1: begin + expr: + simpleexp: =10 + exp1: end + fornum: body + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'i' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + fornum: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=4 + for_stat: begin + enterblock(isbreakable=false) + str_checkname: 'i' + for_stat: numerical loop + new_localvar: 'i' + new_localvar: '(for limit)' + new_localvar: '(for step)' + fornum: begin + fornum: index start + exp1: begin + expr: + simpleexp: =1 + exp1: end + fornum: index stop + exp1: begin + expr: + simpleexp: =10 + exp1: end + fornum: index step + exp1: begin + expr: + subexpr: uop='-' + simpleexp: =2 + exp1: end + fornum: body + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'i' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + fornum: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_14.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_14.lua new file mode 100644 index 0000000..f80c33f --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/parser_log/sample_b_14.lua @@ -0,0 +1,125 @@ +-- START OF SOURCE -- + for foo in bar() do + print(foo) + end + for foo,bar,baz in spring() do + print(foo,bar,baz) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'for' line=1 + for_stat: begin + enterblock(isbreakable=false) + str_checkname: 'foo' + for_stat: list-based loop + forlist: begin + new_localvar: '(for generator)' + new_localvar: '(for state)' + new_localvar: 'foo' + forlist: explist1 + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + funcargs: end -- expr is a VCALL + explist1: end + forlist: body + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + forlist: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=4 + for_stat: begin + enterblock(isbreakable=false) + str_checkname: 'foo' + for_stat: list-based loop + forlist: begin + new_localvar: '(for generator)' + new_localvar: '(for state)' + new_localvar: 'foo' + str_checkname: 'bar' + new_localvar: 'bar' + str_checkname: 'baz' + new_localvar: 'baz' + forlist: explist1 + explist1: begin + expr: + prefixexp: + str_checkname: 'spring' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + funcargs: end -- expr is a VCALL + explist1: end + forlist: body + enterblock(isbreakable=true) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + forlist: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/sample.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/sample.lua new file mode 100644 index 0000000..dc6eaee --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/sample.lua @@ -0,0 +1,3 @@ +local a = 47 +local b = "hello, world!" +print(a, b) diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk2.lua new file mode 100644 index 0000000..ff8cec5 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk2.lua @@ -0,0 +1,499 @@ +--[[-------------------------------------------------------------------- + + test_llex.lua + Test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- if BRIEF is not set to false, auto-test will silently succeed +------------------------------------------------------------------------ +BRIEF = true -- if set to true, messages are less verbose + +local zio_init = require("../lzio_mk2") +local lex_init = require("../llex_mk2") + +------------------------------------------------------------------------ +-- simple manual tests +------------------------------------------------------------------------ + +--[[ +local function dump(z, source) + local luaX = lex_init(z, source) + while true do + local tok, seminfo = luaX:lex() + if tok == "" then + seminfo = " "..seminfo + elseif tok == "" then + seminfo = " "..seminfo + elseif tok == "" then + seminfo = " '"..seminfo.."'" + else + seminfo = "" + end + io.stdout:write(tok..seminfo.."\n") + if tok == "" then break end + end +end + +local function try_string(chunk) + dump(zio_init(chunk), "=string") +end +local function try_file(filename) + local f = "@"..filename + dump(zio_init(f), f) +end + +z = try_string("local c = z:getc()") +z = try_file("test_lzio_mk2.lua") +z = try_file("test_llex_mk2.lua") +os.exit() +--]] + +------------------------------------------------------------------------ +-- auto-testing of simple test cases to validate lexer behaviour: +-- * NOTE coverage has not been checked; not comprehensive +-- * only test cases with non-empty comments are processed +-- * if no result, then the output is displayed for manual decision +-- (output may be used to set expected success or fail text) +-- * cases expected to be successful may be a partial match +-- * cases expected to fail may also be a partial match +------------------------------------------------------------------------ + +-- [[ +local function auto_test() + local PASS, FAIL = true, false + ------------------------------------------------------------------ + -- table of test cases + ------------------------------------------------------------------ + local test_cases = + { + ------------------------------------------------------------- + --{ "comment", -- comment about the test + -- "chunk", -- chunk to test + -- PASS, -- PASS or FAIL outcome + -- "output", -- output to compare against + --}, + ------------------------------------------------------------- + { "empty chunk string, test EOS", + "", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "line number counting", + "\n\n\r\n", + PASS, "4 ", + }, + ------------------------------------------------------------- + { "various whitespaces", + " \n\t\t\n \t \t \n\n", + PASS, "5 ", + }, + ------------------------------------------------------------- + { "short comment ending in EOS", + "-- moo moo", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "short comment ending in newline", + "-- moo moo\n", + PASS, "2 ", + }, + ------------------------------------------------------------- + { "several lines of short comments", + "--moo\n-- moo moo\n\n--\tmoo\n", + PASS, "5 ", + }, + ------------------------------------------------------------- + { "basic block comment", + "--[[bovine]]", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "unterminated block comment 1", + "--[[bovine", + FAIL, ":1: unfinished long comment near ''", + }, + ------------------------------------------------------------- + { "unterminated block comment 2", + "--[[bovine]", + FAIL, ":1: unfinished long comment near ''", + }, + ------------------------------------------------------------- + { "unterminated block comment 3", + "--[[bovine\nmoo moo\nwoof", + FAIL, ":3: unfinished long comment near ''", + }, + ------------------------------------------------------------- + { "basic long string", + "\n[[bovine]]\n", + PASS, "2 = bovine\n3 ", + }, + ------------------------------------------------------------- + { "first newline consumed in long string", + "[[\nmoo]]", + PASS, "2 = moo\n2 ", + }, + ------------------------------------------------------------- + { "multiline long string", + "[[moo\nmoo moo\n]]", + PASS, "3 = moo\nmoo moo\n\n3 ", + }, + ------------------------------------------------------------- + { "unterminated long string 1", + "\n[[\nbovine", + FAIL, ":3: unfinished long string near ''", + }, + ------------------------------------------------------------- + { "unterminated long string 2", + "[[bovine]", + FAIL, ":1: unfinished long string near ''", + }, + ------------------------------------------------------------- + { "unterminated long string 3", + "[[[[ \n", + FAIL, ":2: unfinished long string near ''", + }, + ------------------------------------------------------------- + { "nested long string 1", + "[[moo[[moo]]moo]]", + PASS, "moo[[moo]]moo", + }, + ------------------------------------------------------------- + { "nested long string 2", + "[[moo[[moo[[[[]]]]moo]]moo]]", + PASS, "moo[[moo[[[[]]]]moo]]moo", + }, + ------------------------------------------------------------- + { "nested long string 3", + "[[[[[[]]]][[[[]]]]]]", + PASS, "[[[[]]]][[[[]]]]", + }, + ------------------------------------------------------------- + { "brackets in long strings 1", + "[[moo[moo]]", + PASS, "moo[moo", + }, + ------------------------------------------------------------- + { "brackets in long strings 2", + "[[moo[[moo]moo]]moo]]", + PASS, "moo[[moo]moo]]moo", + }, + ------------------------------------------------------------- + { "unprocessed escapes in long strings", + [[ [[\a\b\f\n\r\t\v\123]] ]], + PASS, [[\a\b\f\n\r\t\v\123]], + }, + ------------------------------------------------------------- + { "unbalanced long string", + "[[moo]]moo]]", + PASS, "1 = moo\n1 = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 ", + }, + ------------------------------------------------------------- + { "keywords 1", + "and break do else", + PASS, "1 and\n1 break\n1 do\n1 else\n1 ", + }, + ------------------------------------------------------------- + { "keywords 2", + "elseif end false for", + PASS, "1 elseif\n1 end\n1 false\n1 for\n1 ", + }, + ------------------------------------------------------------- + { "keywords 3", + "function if in local nil", + PASS, "1 function\n1 if\n1 in\n1 local\n1 nil\n1 ", + }, + ------------------------------------------------------------- + { "keywords 4", + "not or repeat return", + PASS, "1 not\n1 or\n1 repeat\n1 return\n1 ", + }, + ------------------------------------------------------------- + { "keywords 5", + "then true until while", + PASS, "1 then\n1 true\n1 until\n1 while\n1 ", + }, + ------------------------------------------------------------- + { "concat and dots", + ".. ...", + PASS, "1 ..\n1 ...\n1 ", + }, + ------------------------------------------------------------- + { "shbang handling 1", + "#blahblah", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "shbang handling 2", + "#blahblah\nmoo moo\n", + PASS, "2 = moo\n2 = moo\n3 ", + }, + ------------------------------------------------------------- + { "empty string", + [['']], + PASS, "1 = \n1 ", + }, + ------------------------------------------------------------- + { "single-quoted string", + [['bovine']], + PASS, "1 = bovine\n1 ", + }, + ------------------------------------------------------------- + { "double-quoted string", + [["bovine"]], + PASS, "1 = bovine\n1 ", + }, + ------------------------------------------------------------- + { "unterminated string 1", + [['moo ]], + FAIL, ":1: unfinished string near ''", + }, + ------------------------------------------------------------- + { "unterminated string 2", + [["moo \n]], + FAIL, ":1: unfinished string near ''", + }, + ------------------------------------------------------------- + { "escaped newline in string, line number counted", + "\"moo\\\nmoo\\\nmoo\"", + PASS, "3 = moo\nmoo\nmoo\n3 ", + }, + ------------------------------------------------------------- + { "escaped characters in string 1", + [["moo\amoo"]], + PASS, "1 = moo\amoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 2", + [["moo\bmoo"]], + PASS, "1 = moo\bmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 3", + [["moo\f\n\r\t\vmoo"]], + PASS, "1 = moo\f\n\r\t\vmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 4", + [["\\ \" \' \? \[ \]"]], + PASS, "1 = \\ \" \' \? \[ \]", + }, + ------------------------------------------------------------- + { "escaped characters in string 5", + [["\z \k \: \;"]], + PASS, "1 = z k : ;", + }, + ------------------------------------------------------------- + { "escaped characters in string 6", + [["\8 \65 \160 \180K \097097"]], + PASS, "1 = \8 \65 \160 \180K \097097\n", + }, + ------------------------------------------------------------- + { "escaped characters in string 7", + [["\666"]], + FAIL, ":1: escape sequence too large near '\"'", + }, + ------------------------------------------------------------- + { "simple numbers", + "123 123+", + PASS, "1 = 123\n1 = 123\n1 CHAR = '+'\n1 ", + }, + ------------------------------------------------------------- + { "longer numbers", + "1234567890 12345678901234567890", + PASS, "1 = 1234567890\n1 = 1.2345678901235e+19\n", + }, + ------------------------------------------------------------- + { "fractional numbers", + ".123 .12345678901234567890", + PASS, "1 = 0.123\n1 = 0.12345678901235\n", + }, + ------------------------------------------------------------- + { "more numbers with decimal points", + "12345.67890 1.1.", + PASS, "1 = 12345.6789\n1 = 1.1\n1 CHAR = '.'\n", + }, + ------------------------------------------------------------- + { "double decimal points", + ".1.1", + FAIL, ":1: malformed number near '.1.1'", + }, + ------------------------------------------------------------- + { "double dots within numbers", + "1..1", + FAIL, ":1: ambiguous syntax (dots follows digits) near '1..'", + }, + ------------------------------------------------------------- + { "incomplete exponential numbers", + "123e", + FAIL, ":1: malformed number near '123e'", + }, + ------------------------------------------------------------- + { "exponential numbers 1", + "1234e5 1234e5.", + PASS, "1 = 123400000\n1 = 123400000\n1 CHAR = '.'", + }, + ------------------------------------------------------------- + { "exponential numbers 2", + "1234e56 1.23e123", + PASS, "1 = 1.234e+59\n1 = 1.23e+123\n", + }, + ------------------------------------------------------------- + { "exponential numbers 3", + "12.34e+", + FAIL, ":1: malformed number near '12.34e+'", + }, + ------------------------------------------------------------- + { "exponential numbers 4", + "12.34e+5 123.4e-5 1234.E+5", + PASS, "1 = 1234000\n1 = 0.001234\n1 = 123400000\n", + }, + ------------------------------------------------------------- + { "single character symbols 1", + "= > < ~", + PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n", + }, + ------------------------------------------------------------- + { "double character symbols", + "== >= <= ~=", + PASS, "1 ==\n1 >=\n1 <=\n1 ~=\n", + }, + ------------------------------------------------------------- + { "simple identifiers", + "abc ABC", + PASS, "1 = abc\n1 = ABC\n1 ", + }, + ------------------------------------------------------------- + { "more identifiers", + "_abc _ABC", + PASS, "1 = _abc\n1 = _ABC\n1 ", + }, + ------------------------------------------------------------- + { "still more identifiers", + "_aB_ _123", + PASS, "1 = _aB_\n1 = _123\n1 ", + }, + ------------------------------------------------------------- + { "invalid control character", + "\4", + FAIL, ":1: invalid control char near 'char(4)'", + }, + ------------------------------------------------------------- + { "single character symbols 2", + "` ! @ $ %", + PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", + }, + ------------------------------------------------------------- + { "single character symbols 3", + "^ & * ( )", + PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", + }, + ------------------------------------------------------------- + { "single character symbols 4", + "_ - + \\ |", + PASS, "1 = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", + }, + ------------------------------------------------------------- + { "single character symbols 5", + "{ } [ ] :", + PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", + }, + ------------------------------------------------------------- + { "single character symbols 6", + "; , . / ?", + PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", + }, + ------------------------------------------------------------- + } + ------------------------------------------------------------------ + -- perform a test case + ------------------------------------------------------------------ + function do_test_case(count, test_case) + if comment == "" then return end -- skip empty entries + local comment, chunk, outcome, matcher = unpack(test_case) + local result = PASS + local output = "" + -- initialize lexer + local z = zio_init(chunk) + local luaX = lex_init(z, "=test") + -- lexer test loop + local status, token, seminfo + repeat + -- protected call + status, token, seminfo = pcall(luaX.lex, luaX) + output = output..luaX.lineno.." " + if status then + -- successful call + if string.len(token) > 1 then + if token == "" + or token == "" + or token == "" then + token = token.." = "..seminfo + end + elseif string.byte(token) >= 32 then -- displayable chars + token = "CHAR = '"..token.."'" + else -- control characters + token = "CHAR = (".. string.byte(token)..")" + end + output = output..token.."\n" + else + -- failed call + output = output..token -- token is the error message + result = FAIL + break + end + until token == "" + -- decision making and reporting + local head = "Test "..count..": "..comment + if matcher == "" then + -- nothing to check against, display for manual check + print(head.."\nMANUAL please check manually".. + "\n--chunk---------------------------------\n"..chunk.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + return + else + if outcome == PASS then + -- success expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == PASS then + if not BRIEF then print(head.."\nOK expected success\n") end + return + end + else + -- failure expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == FAIL then + if not BRIEF then print(head.."\nOK expected failure\n") end + return + end + end + -- failed because of unmatched string or boolean result + local function passfail(status) + if status == PASS then return "PASS" else return "FAIL" end + end + print(head.." *FAILED*".. + "\noutcome="..passfail(outcome).. + "\nactual= "..passfail(result).. + "\n--chunk---------------------------------\n"..chunk.. + "\n--expected------------------------------\n"..matcher.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + end + end + ------------------------------------------------------------------ + -- perform auto testing + ------------------------------------------------------------------ + for i,test_case in ipairs(test_cases) do + do_test_case(i, test_case) + end +end + +auto_test() +--]] diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk3.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk3.lua new file mode 100644 index 0000000..8b0eec9 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk3.lua @@ -0,0 +1,500 @@ +--[[-------------------------------------------------------------------- + + test_llex.lua + Test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- if BRIEF is not set to false, auto-test will silently succeed +------------------------------------------------------------------------ +BRIEF = true -- if set to true, messages are less verbose + +local lex_init = require("../llex_mk3") + +------------------------------------------------------------------------ +-- simple manual tests +------------------------------------------------------------------------ + +--[[ +local function dump(z, source) + local luaX = lex_init(z, source) + while true do + local tok, seminfo = luaX:lex() + if tok == "" then + seminfo = " "..seminfo + elseif tok == "" then + seminfo = " "..seminfo + elseif tok == "" then + seminfo = " '"..seminfo.."'" + else + seminfo = "" + end + io.stdout:write(tok..seminfo.."\n") + if tok == "" then break end + end +end + +local function try_string(chunk) + dump(chunk, "=string") +end +local function try_file(filename) + local inf = io.open(filename, "r") + if not inf then error("file not found") end + local data = inf:read("*a") + inf:close() + dump(data, "@"..filename) +end + +z = try_string("local c = z:getc()") +z = try_file("test_lzio_mk2.lua") +z = try_file("test_llex_mk2.lua") +os.exit() +--]] + +------------------------------------------------------------------------ +-- auto-testing of simple test cases to validate lexer behaviour: +-- * NOTE coverage has not been checked; not comprehensive +-- * only test cases with non-empty comments are processed +-- * if no result, then the output is displayed for manual decision +-- (output may be used to set expected success or fail text) +-- * cases expected to be successful may be a partial match +-- * cases expected to fail may also be a partial match +------------------------------------------------------------------------ + +-- [[ +local function auto_test() + local PASS, FAIL = true, false + ------------------------------------------------------------------ + -- table of test cases + ------------------------------------------------------------------ + local test_cases = + { + ------------------------------------------------------------- + --{ "comment", -- comment about the test + -- "chunk", -- chunk to test + -- PASS, -- PASS or FAIL outcome + -- "output", -- output to compare against + --}, + ------------------------------------------------------------- + { "empty chunk string, test EOS", + "", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "line number counting", + "\n\n\r\n", + PASS, "4 ", + }, + ------------------------------------------------------------- + { "various whitespaces", + " \n\t\t\n \t \t \n\n", + PASS, "5 ", + }, + ------------------------------------------------------------- + { "short comment ending in EOS", + "-- moo moo", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "short comment ending in newline", + "-- moo moo\n", + PASS, "2 ", + }, + ------------------------------------------------------------- + { "several lines of short comments", + "--moo\n-- moo moo\n\n--\tmoo\n", + PASS, "5 ", + }, + ------------------------------------------------------------- + { "basic block comment", + "--[[bovine]]", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "unterminated block comment 1", + "--[[bovine", + FAIL, ":1: unfinished long comment", + }, + ------------------------------------------------------------- + { "unterminated block comment 2", + "--[[bovine]", + FAIL, ":1: unfinished long comment", + }, + ------------------------------------------------------------- + { "unterminated block comment 3", + "--[[bovine\nmoo moo\nwoof", + FAIL, ":3: unfinished long comment", + }, + ------------------------------------------------------------- + { "basic long string", + "\n[[bovine]]\n", + PASS, "2 = bovine\n3 ", + }, + ------------------------------------------------------------- + { "first newline consumed in long string", + "[[\nmoo]]", + PASS, "2 = moo\n2 ", + }, + ------------------------------------------------------------- + { "multiline long string", + "[[moo\nmoo moo\n]]", + PASS, "3 = moo\nmoo moo\n\n3 ", + }, + ------------------------------------------------------------- + { "unterminated long string 1", + "\n[[\nbovine", + FAIL, ":3: unfinished long string", + }, + ------------------------------------------------------------- + { "unterminated long string 2", + "[[bovine]", + FAIL, ":1: unfinished long string", + }, + ------------------------------------------------------------- + { "unterminated long string 3", + "[[[[ \n", + FAIL, ":2: unfinished long string", + }, + ------------------------------------------------------------- + { "nested long string 1", + "[[moo[[moo]]moo]]", + PASS, "moo[[moo]]moo", + }, + ------------------------------------------------------------- + { "nested long string 2", + "[[moo[[moo[[[[]]]]moo]]moo]]", + PASS, "moo[[moo[[[[]]]]moo]]moo", + }, + ------------------------------------------------------------- + { "nested long string 3", + "[[[[[[]]]][[[[]]]]]]", + PASS, "[[[[]]]][[[[]]]]", + }, + ------------------------------------------------------------- + { "brackets in long strings 1", + "[[moo[moo]]", + PASS, "moo[moo", + }, + ------------------------------------------------------------- + { "brackets in long strings 2", + "[[moo[[moo]moo]]moo]]", + PASS, "moo[[moo]moo]]moo", + }, + ------------------------------------------------------------- + { "unprocessed escapes in long strings", + [[ [[\a\b\f\n\r\t\v\123]] ]], + PASS, [[\a\b\f\n\r\t\v\123]], + }, + ------------------------------------------------------------- + { "unbalanced long string", + "[[moo]]moo]]", + PASS, "1 = moo\n1 = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 ", + }, + ------------------------------------------------------------- + { "keywords 1", + "and break do else", + PASS, "1 and\n1 break\n1 do\n1 else\n1 ", + }, + ------------------------------------------------------------- + { "keywords 2", + "elseif end false for", + PASS, "1 elseif\n1 end\n1 false\n1 for\n1 ", + }, + ------------------------------------------------------------- + { "keywords 3", + "function if in local nil", + PASS, "1 function\n1 if\n1 in\n1 local\n1 nil\n1 ", + }, + ------------------------------------------------------------- + { "keywords 4", + "not or repeat return", + PASS, "1 not\n1 or\n1 repeat\n1 return\n1 ", + }, + ------------------------------------------------------------- + { "keywords 5", + "then true until while", + PASS, "1 then\n1 true\n1 until\n1 while\n1 ", + }, + ------------------------------------------------------------- + { "concat and dots", + ".. ...", + PASS, "1 ..\n1 ...\n1 ", + }, + ------------------------------------------------------------- + { "shbang handling 1", + "#blahblah", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "shbang handling 2", + "#blahblah\nmoo moo\n", + PASS, "2 = moo\n2 = moo\n3 ", + }, + ------------------------------------------------------------- + { "empty string", + [['']], + PASS, "1 = \n1 ", + }, + ------------------------------------------------------------- + { "single-quoted string", + [['bovine']], + PASS, "1 = bovine\n1 ", + }, + ------------------------------------------------------------- + { "double-quoted string", + [["bovine"]], + PASS, "1 = bovine\n1 ", + }, + ------------------------------------------------------------- + { "unterminated string 1", + [['moo ]], + FAIL, ":1: unfinished string", + }, + ------------------------------------------------------------- + { "unterminated string 2", + [["moo \n]], + FAIL, ":1: unfinished string", + }, + ------------------------------------------------------------- + { "escaped newline in string, line number counted", + "\"moo\\\nmoo\\\nmoo\"", + PASS, "3 = moo\nmoo\nmoo\n3 ", + }, + ------------------------------------------------------------- + { "escaped characters in string 1", + [["moo\amoo"]], + PASS, "1 = moo\amoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 2", + [["moo\bmoo"]], + PASS, "1 = moo\bmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 3", + [["moo\f\n\r\t\vmoo"]], + PASS, "1 = moo\f\n\r\t\vmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 4", + [["\\ \" \' \? \[ \]"]], + PASS, "1 = \\ \" \' \? \[ \]", + }, + ------------------------------------------------------------- + { "escaped characters in string 5", + [["\z \k \: \;"]], + PASS, "1 = z k : ;", + }, + ------------------------------------------------------------- + { "escaped characters in string 6", + [["\8 \65 \160 \180K \097097"]], + PASS, "1 = \8 \65 \160 \180K \097097\n", + }, + ------------------------------------------------------------- + { "escaped characters in string 7", + [["\666"]], + FAIL, ":1: escape sequence too large", + }, + ------------------------------------------------------------- + { "simple numbers", + "123 123+", + PASS, "1 = 123\n1 = 123\n1 CHAR = '+'\n1 ", + }, + ------------------------------------------------------------- + { "longer numbers", + "1234567890 12345678901234567890", + PASS, "1 = 1234567890\n1 = 1.2345678901235e+19\n", + }, + ------------------------------------------------------------- + { "fractional numbers", + ".123 .12345678901234567890", + PASS, "1 = 0.123\n1 = 0.12345678901235\n", + }, + ------------------------------------------------------------- + { "more numbers with decimal points", + "12345.67890 1.1.", + PASS, "1 = 12345.6789\n1 = 1.1\n1 CHAR = '.'\n", + }, + ------------------------------------------------------------- + { "double decimal points", + ".1.1", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "double dots within numbers", + "1..1", + FAIL, ":1: ambiguous syntax (dots follows digits)", + }, + ------------------------------------------------------------- + { "incomplete exponential numbers", + "123e", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "exponential numbers 1", + "1234e5 1234e5.", + PASS, "1 = 123400000\n1 = 123400000\n1 CHAR = '.'", + }, + ------------------------------------------------------------- + { "exponential numbers 2", + "1234e56 1.23e123", + PASS, "1 = 1.234e+59\n1 = 1.23e+123\n", + }, + ------------------------------------------------------------- + { "exponential numbers 3", + "12.34e+", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "exponential numbers 4", + "12.34e+5 123.4e-5 1234.E+5", + PASS, "1 = 1234000\n1 = 0.001234\n1 = 123400000\n", + }, + ------------------------------------------------------------- + { "single character symbols 1", + "= > < ~", + PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n", + }, + ------------------------------------------------------------- + { "double character symbols", + "== >= <= ~=", + PASS, "1 ==\n1 >=\n1 <=\n1 ~=\n", + }, + ------------------------------------------------------------- + { "simple identifiers", + "abc ABC", + PASS, "1 = abc\n1 = ABC\n1 ", + }, + ------------------------------------------------------------- + { "more identifiers", + "_abc _ABC", + PASS, "1 = _abc\n1 = _ABC\n1 ", + }, + ------------------------------------------------------------- + { "still more identifiers", + "_aB_ _123", + PASS, "1 = _aB_\n1 = _123\n1 ", + }, + ------------------------------------------------------------- + { "invalid control character", + "\4", + FAIL, ":1: invalid control char", + }, + ------------------------------------------------------------- + { "single character symbols 2", + "` ! @ $ %", + PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", + }, + ------------------------------------------------------------- + { "single character symbols 3", + "^ & * ( )", + PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", + }, + ------------------------------------------------------------- + { "single character symbols 4", + "_ - + \\ |", + PASS, "1 = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", + }, + ------------------------------------------------------------- + { "single character symbols 5", + "{ } [ ] :", + PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", + }, + ------------------------------------------------------------- + { "single character symbols 6", + "; , . / ?", + PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", + }, + ------------------------------------------------------------- + } + ------------------------------------------------------------------ + -- perform a test case + ------------------------------------------------------------------ + function do_test_case(count, test_case) + if comment == "" then return end -- skip empty entries + local comment, chunk, outcome, matcher = unpack(test_case) + local result = PASS + local output = "" + -- initialize lexer + local luaX = lex_init(chunk, "=test") + -- lexer test loop + local status, token, seminfo + repeat + -- protected call + status, token, seminfo = pcall(luaX.lex, luaX) + output = output..luaX.ln.." " + if status then + -- successful call + if string.len(token) > 1 then + if token == "" + or token == "" + or token == "" then + token = token.." = "..seminfo + end + elseif string.byte(token) >= 32 then -- displayable chars + token = "CHAR = '"..token.."'" + else -- control characters + token = "CHAR = (".. string.byte(token)..")" + end + output = output..token.."\n" + else + -- failed call + output = output..token -- token is the error message + result = FAIL + break + end + until token == "" + -- decision making and reporting + local head = "Test "..count..": "..comment + if matcher == "" then + -- nothing to check against, display for manual check + print(head.."\nMANUAL please check manually".. + "\n--chunk---------------------------------\n"..chunk.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + return + else + if outcome == PASS then + -- success expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == PASS then + if not BRIEF then print(head.."\nOK expected success\n") end + return + end + else + -- failure expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == FAIL then + if not BRIEF then print(head.."\nOK expected failure\n") end + return + end + end + -- failed because of unmatched string or boolean result + local function passfail(status) + if status == PASS then return "PASS" else return "FAIL" end + end + print(head.." *FAILED*".. + "\noutcome="..passfail(outcome).. + "\nactual= "..passfail(result).. + "\n--chunk---------------------------------\n"..chunk.. + "\n--expected------------------------------\n"..matcher.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + end + end + ------------------------------------------------------------------ + -- perform auto testing + ------------------------------------------------------------------ + for i,test_case in ipairs(test_cases) do + do_test_case(i, test_case) + end +end + +auto_test() +--]] diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk4.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk4.lua new file mode 100644 index 0000000..316a9bf --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_llex_mk4.lua @@ -0,0 +1,499 @@ +--[[-------------------------------------------------------------------- + + test_llex.lua + Test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- if BRIEF is not set to false, auto-test will silently succeed +------------------------------------------------------------------------ +BRIEF = true -- if set to true, messages are less verbose + +local zio_init = require("../lzio_mk4") +local lex_init = require("../llex_mk4") + +------------------------------------------------------------------------ +-- simple manual tests +------------------------------------------------------------------------ + +--[[ +local function dump(z, source) + local luaX = lex_init(z, source) + while true do + local tok, seminfo = luaX:lex() + if tok == "" then + seminfo = " "..seminfo + elseif tok == "" then + seminfo = " "..seminfo + elseif tok == "" then + seminfo = " '"..seminfo.."'" + else + seminfo = "" + end + io.stdout:write(tok..seminfo.."\n") + if tok == "" then break end + end +end + +local function try_string(chunk) + dump(zio_init(chunk), "=string") +end +local function try_file(filename) + local f = "@"..filename + dump(zio_init(f), f) +end + +z = try_string("local c = z:getc()") +z = try_file("test_lzio_mk2.lua") +z = try_file("test_llex_mk2.lua") +os.exit() +--]] + +------------------------------------------------------------------------ +-- auto-testing of simple test cases to validate lexer behaviour: +-- * NOTE coverage has not been checked; not comprehensive +-- * only test cases with non-empty comments are processed +-- * if no result, then the output is displayed for manual decision +-- (output may be used to set expected success or fail text) +-- * cases expected to be successful may be a partial match +-- * cases expected to fail may also be a partial match +------------------------------------------------------------------------ + +-- [[ +local function auto_test() + local PASS, FAIL = true, false + ------------------------------------------------------------------ + -- table of test cases + ------------------------------------------------------------------ + local test_cases = + { + ------------------------------------------------------------- + --{ "comment", -- comment about the test + -- "chunk", -- chunk to test + -- PASS, -- PASS or FAIL outcome + -- "output", -- output to compare against + --}, + ------------------------------------------------------------- + { "empty chunk string, test EOS", + "", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "line number counting", + "\n\n\r\n", + PASS, "4 ", + }, + ------------------------------------------------------------- + { "various whitespaces", + " \n\t\t\n \t \t \n\n", + PASS, "5 ", + }, + ------------------------------------------------------------- + { "short comment ending in EOS", + "-- moo moo", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "short comment ending in newline", + "-- moo moo\n", + PASS, "2 ", + }, + ------------------------------------------------------------- + { "several lines of short comments", + "--moo\n-- moo moo\n\n--\tmoo\n", + PASS, "5 ", + }, + ------------------------------------------------------------- + { "basic block comment", + "--[[bovine]]", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "unterminated block comment 1", + "--[[bovine", + FAIL, ":1: unfinished long comment", + }, + ------------------------------------------------------------- + { "unterminated block comment 2", + "--[[bovine]", + FAIL, ":1: unfinished long comment", + }, + ------------------------------------------------------------- + { "unterminated block comment 3", + "--[[bovine\nmoo moo\nwoof", + FAIL, ":3: unfinished long comment", + }, + ------------------------------------------------------------- + { "basic long string", + "\n[[bovine]]\n", + PASS, "2 = bovine\n3 ", + }, + ------------------------------------------------------------- + { "first newline consumed in long string", + "[[\nmoo]]", + PASS, "2 = moo\n2 ", + }, + ------------------------------------------------------------- + { "multiline long string", + "[[moo\nmoo moo\n]]", + PASS, "3 = moo\nmoo moo\n\n3 ", + }, + ------------------------------------------------------------- + { "unterminated long string 1", + "\n[[\nbovine", + FAIL, ":3: unfinished long string", + }, + ------------------------------------------------------------- + { "unterminated long string 2", + "[[bovine]", + FAIL, ":1: unfinished long string", + }, + ------------------------------------------------------------- + { "unterminated long string 3", + "[[[[ \n", + FAIL, ":2: unfinished long string", + }, + ------------------------------------------------------------- + { "nested long string 1", + "[[moo[[moo]]moo]]", + PASS, "moo[[moo]]moo", + }, + ------------------------------------------------------------- + { "nested long string 2", + "[[moo[[moo[[[[]]]]moo]]moo]]", + PASS, "moo[[moo[[[[]]]]moo]]moo", + }, + ------------------------------------------------------------- + { "nested long string 3", + "[[[[[[]]]][[[[]]]]]]", + PASS, "[[[[]]]][[[[]]]]", + }, + ------------------------------------------------------------- + { "brackets in long strings 1", + "[[moo[moo]]", + PASS, "moo[moo", + }, + ------------------------------------------------------------- + { "brackets in long strings 2", + "[[moo[[moo]moo]]moo]]", + PASS, "moo[[moo]moo]]moo", + }, + ------------------------------------------------------------- + { "unprocessed escapes in long strings", + [[ [[\a\b\f\n\r\t\v\123]] ]], + PASS, [[\a\b\f\n\r\t\v\123]], + }, + ------------------------------------------------------------- + { "unbalanced long string", + "[[moo]]moo]]", + PASS, "1 = moo\n1 = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 ", + }, + ------------------------------------------------------------- + { "keywords 1", + "and break do else", + PASS, "1 and\n1 break\n1 do\n1 else\n1 ", + }, + ------------------------------------------------------------- + { "keywords 2", + "elseif end false for", + PASS, "1 elseif\n1 end\n1 false\n1 for\n1 ", + }, + ------------------------------------------------------------- + { "keywords 3", + "function if in local nil", + PASS, "1 function\n1 if\n1 in\n1 local\n1 nil\n1 ", + }, + ------------------------------------------------------------- + { "keywords 4", + "not or repeat return", + PASS, "1 not\n1 or\n1 repeat\n1 return\n1 ", + }, + ------------------------------------------------------------- + { "keywords 5", + "then true until while", + PASS, "1 then\n1 true\n1 until\n1 while\n1 ", + }, + ------------------------------------------------------------- + { "concat and dots", + ".. ...", + PASS, "1 ..\n1 ...\n1 ", + }, + ------------------------------------------------------------- + { "shbang handling 1", + "#blahblah", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "shbang handling 2", + "#blahblah\nmoo moo\n", + PASS, "2 = moo\n2 = moo\n3 ", + }, + ------------------------------------------------------------- + { "empty string", + [['']], + PASS, "1 = \n1 ", + }, + ------------------------------------------------------------- + { "single-quoted string", + [['bovine']], + PASS, "1 = bovine\n1 ", + }, + ------------------------------------------------------------- + { "double-quoted string", + [["bovine"]], + PASS, "1 = bovine\n1 ", + }, + ------------------------------------------------------------- + { "unterminated string 1", + [['moo ]], + FAIL, ":1: unfinished string", + }, + ------------------------------------------------------------- + { "unterminated string 2", + [["moo \n]], + FAIL, ":1: unfinished string", + }, + ------------------------------------------------------------- + { "escaped newline in string, line number counted", + "\"moo\\\nmoo\\\nmoo\"", + PASS, "3 = moo\nmoo\nmoo\n3 ", + }, + ------------------------------------------------------------- + { "escaped characters in string 1", + [["moo\amoo"]], + PASS, "1 = moo\amoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 2", + [["moo\bmoo"]], + PASS, "1 = moo\bmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 3", + [["moo\f\n\r\t\vmoo"]], + PASS, "1 = moo\f\n\r\t\vmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 4", + [["\\ \" \' \? \[ \]"]], + PASS, "1 = \\ \" \' \? \[ \]", + }, + ------------------------------------------------------------- + { "escaped characters in string 5", + [["\z \k \: \;"]], + PASS, "1 = z k : ;", + }, + ------------------------------------------------------------- + { "escaped characters in string 6", + [["\8 \65 \160 \180K \097097"]], + PASS, "1 = \8 \65 \160 \180K \097097\n", + }, + ------------------------------------------------------------- + { "escaped characters in string 7", + [["\666"]], + FAIL, ":1: escape sequence too large", + }, + ------------------------------------------------------------- + { "simple numbers", + "123 123+", + PASS, "1 = 123\n1 = 123\n1 CHAR = '+'\n1 ", + }, + ------------------------------------------------------------- + { "longer numbers", + "1234567890 12345678901234567890", + PASS, "1 = 1234567890\n1 = 1.2345678901235e+19\n", + }, + ------------------------------------------------------------- + { "fractional numbers", + ".123 .12345678901234567890", + PASS, "1 = 0.123\n1 = 0.12345678901235\n", + }, + ------------------------------------------------------------- + { "more numbers with decimal points", + "12345.67890 1.1.", + PASS, "1 = 12345.6789\n1 = 1.1\n1 CHAR = '.'\n", + }, + ------------------------------------------------------------- + { "double decimal points", + ".1.1", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "double dots within numbers", + "1..1", + FAIL, ":1: ambiguous syntax (dots follows digits)", + }, + ------------------------------------------------------------- + { "incomplete exponential numbers", + "123e", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "exponential numbers 1", + "1234e5 1234e5.", + PASS, "1 = 123400000\n1 = 123400000\n1 CHAR = '.'", + }, + ------------------------------------------------------------- + { "exponential numbers 2", + "1234e56 1.23e123", + PASS, "1 = 1.234e+59\n1 = 1.23e+123\n", + }, + ------------------------------------------------------------- + { "exponential numbers 3", + "12.34e+", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "exponential numbers 4", + "12.34e+5 123.4e-5 1234.E+5", + PASS, "1 = 1234000\n1 = 0.001234\n1 = 123400000\n", + }, + ------------------------------------------------------------- + { "single character symbols 1", + "= > < ~", + PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n", + }, + ------------------------------------------------------------- + { "double character symbols", + "== >= <= ~=", + PASS, "1 ==\n1 >=\n1 <=\n1 ~=\n", + }, + ------------------------------------------------------------- + { "simple identifiers", + "abc ABC", + PASS, "1 = abc\n1 = ABC\n1 ", + }, + ------------------------------------------------------------- + { "more identifiers", + "_abc _ABC", + PASS, "1 = _abc\n1 = _ABC\n1 ", + }, + ------------------------------------------------------------- + { "still more identifiers", + "_aB_ _123", + PASS, "1 = _aB_\n1 = _123\n1 ", + }, + ------------------------------------------------------------- + { "invalid control character", + "\4", + FAIL, ":1: invalid control char", + }, + ------------------------------------------------------------- + { "single character symbols 2", + "` ! @ $ %", + PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", + }, + ------------------------------------------------------------- + { "single character symbols 3", + "^ & * ( )", + PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", + }, + ------------------------------------------------------------- + { "single character symbols 4", + "_ - + \\ |", + PASS, "1 = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", + }, + ------------------------------------------------------------- + { "single character symbols 5", + "{ } [ ] :", + PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", + }, + ------------------------------------------------------------- + { "single character symbols 6", + "; , . / ?", + PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", + }, + ------------------------------------------------------------- + } + ------------------------------------------------------------------ + -- perform a test case + ------------------------------------------------------------------ + function do_test_case(count, test_case) + if comment == "" then return end -- skip empty entries + local comment, chunk, outcome, matcher = unpack(test_case) + local result = PASS + local output = "" + -- initialize lexer + local z = zio_init(chunk) + local luaX = lex_init(z, "=test") + -- lexer test loop + local status, token, seminfo + repeat + -- protected call + status, token, seminfo = pcall(luaX.lex, luaX) + output = output..luaX.ln.." " + if status then + -- successful call + if string.len(token) > 1 then + if token == "" + or token == "" + or token == "" then + token = token.." = "..seminfo + end + elseif string.byte(token) >= 32 then -- displayable chars + token = "CHAR = '"..token.."'" + else -- control characters + token = "CHAR = (".. string.byte(token)..")" + end + output = output..token.."\n" + else + -- failed call + output = output..token -- token is the error message + result = FAIL + break + end + until token == "" + -- decision making and reporting + local head = "Test "..count..": "..comment + if matcher == "" then + -- nothing to check against, display for manual check + print(head.."\nMANUAL please check manually".. + "\n--chunk---------------------------------\n"..chunk.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + return + else + if outcome == PASS then + -- success expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == PASS then + if not BRIEF then print(head.."\nOK expected success\n") end + return + end + else + -- failure expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == FAIL then + if not BRIEF then print(head.."\nOK expected failure\n") end + return + end + end + -- failed because of unmatched string or boolean result + local function passfail(status) + if status == PASS then return "PASS" else return "FAIL" end + end + print(head.." *FAILED*".. + "\noutcome="..passfail(outcome).. + "\nactual= "..passfail(result).. + "\n--chunk---------------------------------\n"..chunk.. + "\n--expected------------------------------\n"..matcher.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + end + end + ------------------------------------------------------------------ + -- perform auto testing + ------------------------------------------------------------------ + for i,test_case in ipairs(test_cases) do + do_test_case(i, test_case) + end +end + +auto_test() +--]] diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3.lua new file mode 100644 index 0000000..662c826 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3.lua @@ -0,0 +1,218 @@ +--[[-------------------------------------------------------------------- + + test_lparser_mk3.lua + Test for lparser_mk3.lua + This file is part of Yueliang. + + Copyright (c) 2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +local lex_init = require("../llex_mk3") +local parser_init = require("../lparser_mk3") + +------------------------------------------------------------------------ +-- dump contents of log table +------------------------------------------------------------------------ + +local function dump_log(fs) + local log = fs.log + for i = 1, table.getn(log) do + print(log[i]) + end +end + +------------------------------------------------------------------------ +-- try 1 +------------------------------------------------------------------------ + +local luaX = lex_init("local a = 1", "=string") +local luaY = parser_init(luaX) + +-- nothing is returned, so hope there is an error if problem occurs +local fs = luaY:parser() +--dump_log(fs) + +------------------------------------------------------------------------ +-- try 2 +------------------------------------------------------------------------ + +-- llex_mk3.lua cannot load files by itself +local INF = io.open("sample.lua", "rb") +if not INF then error("failed to load test file") end +local sample = INF:read("*a") +INF:close() + +luaX = lex_init(sample, "@sample.lua") +luaY = parser_init(luaX) + +-- nothing is returned, so hope there is an error if problem occurs +local fs = luaY:parser() +--dump_log(fs) + +------------------------------------------------------------------------ +-- automatic dumper of output log data +------------------------------------------------------------------------ + +local test_case = { +-- 1 +[[ +]], +-- 2 +[[ +-- foobar +]], +-- 3 +[[ +do +end +]], +-- 4 +[[ +do end +do end +]], +-- 5 +[[ +foo() +foo{} +foo"" +foo:bar() +foo=false +foo.bar=true +foo[true]=nil +foo,bar=1,"a" +]], +-- 6 +[[ +foo=true +foo=false +foo=nil +foo=1.23e45 +foo=-1 +foo=(0) +foo=1+2 +foo=1+2*3-4/5 +]], +-- 7 +[[ +if foo then foo=1 end +if foo then foo=1 else foo=0 end +if foo then foo=1 elseif not foo then foo=0 end +]], +-- 8 +[[ +do return end +do return 123 end +do return "foo","bar" end +]], +-- 9 +[[ +while true do foo=not foo end +while foo~=42 do foo=foo-1 end +while true do break end +]], +-- 10 +[[ +repeat foo=foo.."bar" until false +repeat foo=foo/2 until foo<1 +repeat break until false +]], +-- 11 +[[ +for i=1,10 do foo=i end +for i=1,10,2 do break end +for i in foo do bar=0 end +for i,j in foo,bar do baz=0 end +]], +-- 12 +[[ +local foo +local foo,bar,baz +local foo,bar="foo","bar" +]], +-- 13 +[[ +local function foo() return end +local function foo(a) return end +local function foo(x,y,z) return end +local function foo(x,...) return end +]], +-- 14 +[[ +function foo() return end +function foo(a) return end +function foo(x,y,z) return end +function foo(x,...) return end +]], +-- 15 +[[ +function foo.bar(p) return end +function foo.bar.baz(p) return end +function foo:bar(p) return end +function foo.bar.baz(p) return end +]], +-- 16 +[[ +foo = function() return end +foo = function(x,y) return end +foo = function(...) return end +]], +-- 17 +[[ +foo = {} +foo = { 1,2,3; "foo"; } +foo = { bar=77, baz=88, } +foo = { ["bar"]=77, ["baz"]=88, } +]], +} + +-- helps to skip old stuff during development of snippets +local do_beg, do_end = 1, table.getn(test_case) + +-- loop for all example snippets +for i = do_beg, do_end do + local fname = "parser_log/sample_"..string.format("%02d", i)..".lua" + local src = test_case[i] + local OUTF = io.open(fname, "wb") + if not OUTF then error("failed to write to file '"..fname.."'") end + -- write out actual source for comparison + OUTF:write( + "-- START OF SOURCE --\n".. + src.. + "-- END OF SOURCE --\n".. + "\n" + ) + -- attempt to parse + local luaX = lex_init(src, "=string") + local luaY = parser_init(luaX) + local fs = luaY:parser() + -- grab logged messages and write + local log = fs.log + local indent = 0 + for i = 1, table.getn(log) do + local ln = log[i] + -- handle indentation + local tag = string.sub(ln, 1, 2) + if tag == ">>" or tag == "<<" then + ln = string.sub(ln, 4) + end + if tag == ">>" then + indent = indent + 1 + end + OUTF:write(string.rep(" ", indent)..ln.."\n") + if tag == "<<" then + indent = indent - 1 + end + end + -- we're done + OUTF:close() +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3_2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3_2.lua new file mode 100644 index 0000000..957ee22 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3_2.lua @@ -0,0 +1,158 @@ +--[[-------------------------------------------------------------------- + + test_lparser_mk3_2.lua + Test for lparser_mk3.lua, using the test case file + This file is part of Yueliang. + + Copyright (c) 2006-2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * unlike the equivalent in the orig-5.0.3/ directory, this version +-- tests only parsing, lparser_mk3 cannot generate binary chunks +-- * the test cases are in the test_lua directory (test_parser-5.0.lua) +----------------------------------------------------------------------]] + +-- * true if you want an output of all failure cases in native Lua, +-- for checking whether test cases fail where you intend them to +local DEBUG_FAILS = false + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +local lex_init = require("../llex_mk3") +local parser_init = require("../lparser_mk3") + +------------------------------------------------------------------------ +-- load test cases +------------------------------------------------------------------------ + +require("../../test_lua/test_parser-5.0") + +local test, expect, heading = {}, {}, {} +local total, total_pass, total_fail = 0, 0, 0 + +for ln in string.gfind(tests_source, "([^\n]*)\n") do + if string.find(ln, "^%s*%-%-") then + -- comment, ignore + else + local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") + if m then + heading[total + 1] = head -- informational heading + else + total = total + 1 + local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") + if n then -- FAIL test case + ln = string.sub(ln, 1, n - 1) -- remove comment + expect[total] = "FAIL" + total_fail = total_fail + 1 + else -- PASS test case + expect[total] = "PASS" + total_pass = total_pass + 1 + end--n + test[total] = ln + end--m + end--ln +end--for + +print("Tests loaded: "..total.." (total), " + ..total_pass.." (passes), " + ..total_fail.." (fails)") + +------------------------------------------------------------------------ +-- verify test cases using native Lua +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then + last_head = head + if DEBUG_FAILS then print("\n"..head.."\n") end + end + ------------------------------------------------------------------ + -- perform test + local f, err = loadstring(test_case) + -- look at outcome + ------------------------------------------------------------------ + if f then-- actual PASS + if expected == "FAIL" then + print("\nVerified as PASS but expected to FAIL".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nVerified as FAIL but expected to PASS".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + print("ERROR: "..err) + os.exit() + end + if DEBUG_FAILS then + print("TEST: "..test_case) + print("ERROR: "..err.."\n") + end + ------------------------------------------------------------------ + end--f +end--for + +print("Test cases verified using native Lua, no anomalies.") + +------------------------------------------------------------------------ +-- test using Yueliang front end +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then last_head = head end + ------------------------------------------------------------------ + -- perform test + luaX = lex_init(test_case, "=test_sample") + luaY = parser_init(luaX) + + local status, func = pcall(luaY.parser, luaY) + -- look at outcome + ------------------------------------------------------------------ + if status then-- actual PASS + if expected == "FAIL" then + print("\nTested as PASS but expected to FAIL".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nTested as FAIL but expected to PASS".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + else + io.stdout:write("-") + end + ------------------------------------------------------------------ + end--status + io.stdout:write("\rTesting ["..i.."]...") +end--for +print(" done.") + +print("Test cases run on Yueliang, no anomalies.") + +-- end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3b.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3b.lua new file mode 100644 index 0000000..d8dc33d --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3b.lua @@ -0,0 +1,188 @@ +--[[-------------------------------------------------------------------- + + test_lparser_mk3b.lua + Test for lparser_mk3b.lua + This file is part of Yueliang. + + Copyright (c) 2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +local lex_init = require("../llex_mk3") +local parser_init = require("../lparser_mk3b") + +------------------------------------------------------------------------ +-- dump contents of log table +------------------------------------------------------------------------ + +local function dump_log(fs) + local log = fs.log + for i = 1, table.getn(log) do + print(log[i]) + end +end + +------------------------------------------------------------------------ +-- automatic dumper of output log data +------------------------------------------------------------------------ + +local test_case = { +-- 1 +[[ + print(a) +]], +-- 2 +[[ + local a + print(a) +]], +-- 3 +[[ + do + local a + print(a) + end + print(a) +]], +-- 4 +[[ + local a,b,c + do + local b + print(b) + end + print(b) +]], +-- 5 +[[ + local function foo() end + bar = foo +]], +-- 6 +[[ + do + local function foo() end + bar = foo + end + baz = foo +]], +-- 7 +[[ + local foo + local function bar() + baz = nil + foo = bar() + end + foo = bar +]], +-- 8 +[[ + local foo + local function bar() + local function baz() + local foo, bar + foo = bar + foo = baz + end + foo = bar + foo = baz + end + foo = bar + foo = baz +]], +-- 9 +[[ + function foo:bar() + print(self) + end +]], +-- 10 +[[ + function foo(...) + print(arg) + end +]], +-- 11 +[[ + local c,d + function foo(a,b,c) + print(a,c,d,e) + end +]], +-- 11 +[[ + function foo(a,b) + local bar = function(c,d) + print(a,b,c,d) + end + end +]], +-- 12 +[[ + for i = 1,10 do + print(i) + end + for i = 1,10,-2 do + print(i) + end +]], +-- 13 +[[ + for foo in bar() do + print(foo) + end + for foo,bar,baz in spring() do + print(foo,bar,baz) + end +]], +} + +-- helps to skip old stuff during development of snippets +local do_beg, do_end = 1, table.getn(test_case) + +-- loop for all example snippets +for i = do_beg, do_end do + local fname = "parser_log/sample_b_"..string.format("%02d", i)..".lua" + local src = test_case[i] + local OUTF = io.open(fname, "wb") + if not OUTF then error("failed to write to file '"..fname.."'") end + -- write out actual source for comparison + OUTF:write( + "-- START OF SOURCE --\n".. + src.. + "-- END OF SOURCE --\n".. + "\n" + ) + -- attempt to parse + local luaX = lex_init(src, "=string") + local luaY = parser_init(luaX) + local fs = luaY:parser() + -- grab logged messages and write + local log = fs.log + local indent = 0 + for i = 1, table.getn(log) do + local ln = log[i] + -- handle indentation + local tag = string.sub(ln, 1, 2) + if tag == ">>" or tag == "<<" then + ln = string.sub(ln, 4) + end + if tag == ">>" then + indent = indent + 1 + end + OUTF:write(string.rep(" ", indent)..ln.."\n") + if tag == "<<" then + indent = indent - 1 + end + end + -- we're done + OUTF:close() +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3b_2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3b_2.lua new file mode 100644 index 0000000..4d4e8c5 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lparser_mk3b_2.lua @@ -0,0 +1,158 @@ +--[[-------------------------------------------------------------------- + + test_lparser_mk3b_2.lua + Test for lparser_mk3b.lua, using the test case file + This file is part of Yueliang. + + Copyright (c) 2006-2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * unlike the equivalent in the orig-5.0.3/ directory, this version +-- tests only parsing, lparser_mk3 cannot generate binary chunks +-- * the test cases are in the test_lua directory (test_parser-5.0.lua) +----------------------------------------------------------------------]] + +-- * true if you want an output of all failure cases in native Lua, +-- for checking whether test cases fail where you intend them to +local DEBUG_FAILS = false + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +local lex_init = require("../llex_mk3") +local parser_init = require("../lparser_mk3b") + +------------------------------------------------------------------------ +-- load test cases +------------------------------------------------------------------------ + +require("../../test_lua/test_parser-5.0") + +local test, expect, heading = {}, {}, {} +local total, total_pass, total_fail = 0, 0, 0 + +for ln in string.gfind(tests_source, "([^\n]*)\n") do + if string.find(ln, "^%s*%-%-") then + -- comment, ignore + else + local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") + if m then + heading[total + 1] = head -- informational heading + else + total = total + 1 + local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") + if n then -- FAIL test case + ln = string.sub(ln, 1, n - 1) -- remove comment + expect[total] = "FAIL" + total_fail = total_fail + 1 + else -- PASS test case + expect[total] = "PASS" + total_pass = total_pass + 1 + end--n + test[total] = ln + end--m + end--ln +end--for + +print("Tests loaded: "..total.." (total), " + ..total_pass.." (passes), " + ..total_fail.." (fails)") + +------------------------------------------------------------------------ +-- verify test cases using native Lua +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then + last_head = head + if DEBUG_FAILS then print("\n"..head.."\n") end + end + ------------------------------------------------------------------ + -- perform test + local f, err = loadstring(test_case) + -- look at outcome + ------------------------------------------------------------------ + if f then-- actual PASS + if expected == "FAIL" then + print("\nVerified as PASS but expected to FAIL".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nVerified as FAIL but expected to PASS".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + print("ERROR: "..err) + os.exit() + end + if DEBUG_FAILS then + print("TEST: "..test_case) + print("ERROR: "..err.."\n") + end + ------------------------------------------------------------------ + end--f +end--for + +print("Test cases verified using native Lua, no anomalies.") + +------------------------------------------------------------------------ +-- test using Yueliang front end +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then last_head = head end + ------------------------------------------------------------------ + -- perform test + luaX = lex_init(test_case, "=test_sample") + luaY = parser_init(luaX) + + local status, func = pcall(luaY.parser, luaY) + -- look at outcome + ------------------------------------------------------------------ + if status then-- actual PASS + if expected == "FAIL" then + print("\nTested as PASS but expected to FAIL".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nTested as FAIL but expected to PASS".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + else + io.stdout:write("-") + end + ------------------------------------------------------------------ + end--status + io.stdout:write("\rTesting ["..i.."]...") +end--for +print(" done.") + +print("Test cases run on Yueliang, no anomalies.") + +-- end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lzio_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lzio_mk2.lua new file mode 100644 index 0000000..30259c8 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/test/test_lzio_mk2.lua @@ -0,0 +1,53 @@ +--[[-------------------------------------------------------------------- + + test_lzio.lua + Test for lzio.lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +-- manual test for lzio.lua lua-style chunk reader + +local zio_init = require("../lzio_mk2") + +local z +function dump(z) + while true do + local c = z:getc() + io.stdout:write("("..c..")") + if c == "EOZ" then break end + end + io.stdout:write("\n") +end + +-- z = zio_init("@") for a file +-- z = zio_init("") for a string + +-- [[ +z = zio_init("hello, world!") +dump(z) +z = zio_init("line1\nline2\n") +dump(z) +z = zio_init("@test_lzio_mk2.lua") +dump(z) +--]] + +-- test read beyond end of file +-- bug reported by Adam429 +--[[ +z = zio_init("@test_lzio_mk2.lua") +while true do + local c = z:getc() + io.stdout:write("("..c..")") + if c == "EOZ" then break end +end +print(z:getc()) +print(z:getc()) +io.stdout:write("\n") +--]] diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/README b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/README new file mode 100644 index 0000000..215b555 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/README @@ -0,0 +1,55 @@ +nat-5.1.3 + +This directory contains versions of front end files that are rewritten +to be more "native" to Lua. These files should be considered as +exercises in exploring ways to write the front end, for example, to +write a front end that is optimized for size, etc. See also file size +data further below. + +The following are the different versions available (mk2 == "mark 2", +this is commonly used in the UK, e.g. for aeroplanes during WWII): + +Lexers +------ + +NOTE: These lexers should behave mostly identically to the original C +lexer. Locale support for non-standard decimal points is missing. Also, +all strings and long strings have line endings normalized to LF. + +llex_mk2 Rewritten from original ported code to become more + Lua-like. Needs input to be entered as a single string. + Unless an application's need is very unusual, this + should not be a problem. It will not work for per-line + interaction, though. This version is also somewhat + optimized for size; its stripped binary chunk size is + 3716 bytes. + + Status: TESTED + +Parsers +------- + +lparser_mk2 Written for the simplified lexer interface of llex_mk2. + This is a lexer skeleton, stripped of codegen code. Has + a minimum of variable management code added, and tracks + the is_vararg flag of a function. See the comments in + the source code for more information. Without logging + messages and comments, it should be under 600 LOC. A + binary chunk of lparser_mk2 (stripped) is 15783 bytes. + + Sample output of the parser message logger can be found + in the test/parser_log subdirectory. + + Tested with test_parser-5.1.lua, the Lua 5.1.x parser test + cases in the test_lua/ directory, appears to be fine. + + Compared to the 5.0.x parser skeleton, the main changes + are: (a) 'arg' not implemented, so it appears as a global, + and (b) '...' recognized as the last function parameter. + + Status: SNIPPETS APPEAR TO WORK + +Other notes: +------------ + +None. diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/llex_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/llex_mk2.lua new file mode 100644 index 0000000..dae57f1 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/llex_mk2.lua @@ -0,0 +1,314 @@ +--[[-------------------------------------------------------------------- + + llex.lua + Lua 5.1 lexical analyzer in Lua + This file is part of Yueliang. + + Copyright (c) 2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * takes in the entire source at once +-- * greatly simplified chunkid, error handling +-- * NO shbang handling (it's done elsewhere in Lua 5.1) +-- * NO localized decimal point replacement magic +-- * NO limit to number of lines (MAX_INT = 2147483645) +-- * NO support for compatible long strings (LUA_COMPAT_LSTR) +-- * NO next(), lookahead() because I want next() to set tok and +-- seminfo that are locals, and that can only be done easily in +-- lparser, not llex. lastline would be handled in lparser too. +-- +-- Usage example: +-- local llex = require("llex_mk2") +-- llex.init(source_code, source_code_name) +-- repeat +-- local token, seminfo = llex.llex() +-- until token == "" +-- +----------------------------------------------------------------------]] + +local base = _G +local string = require "string" +module "llex" + +---------------------------------------------------------------------- +-- initialize keyword list +---------------------------------------------------------------------- +local kw = {} +for v in string.gmatch([[ +and break do else elseif end false for function if in +local nil not or repeat return then true until while]], "%S+") do + kw[v] = true +end + +---------------------------------------------------------------------- +-- initialize lexer for given source _z and source name _sourceid +---------------------------------------------------------------------- +local z, sourceid, I +local find = string.find +local match = string.match +local sub = string.sub + +function init(_z, _sourceid) + z = _z -- source + sourceid = _sourceid -- name of source + I = 1 -- lexer's position in source + ln = 1 -- line number +end + +---------------------------------------------------------------------- +-- returns a chunk name or id, no truncation for long names +---------------------------------------------------------------------- +function chunkid() + if sourceid and match(sourceid, "^[=@]") then + return sub(sourceid, 2) -- remove first char + end + return "[string]" +end + +---------------------------------------------------------------------- +-- formats error message and throws error +-- * a simplified version, does not report what token was responsible +---------------------------------------------------------------------- +function errorline(s, line) + base.error(string.format("%s:%d: %s", chunkid(), line or ln, s)) +end + +---------------------------------------------------------------------- +-- handles line number incrementation and end-of-line characters +---------------------------------------------------------------------- + +local function inclinenumber(i) + local sub = sub + local old = sub(z, i, i) + i = i + 1 -- skip '\n' or '\r' + local c = sub(z, i, i) + if (c == "\n" or c == "\r") and (c ~= old) then + i = i + 1 -- skip '\n\r' or '\r\n' + end + ln = ln + 1 + I = i + return i +end + +------------------------------------------------------------------------ +-- count separators ("=") in a long string delimiter +------------------------------------------------------------------------ +local function skip_sep(i) + local sub = sub + local s = sub(z, i, i) + i = i + 1 + local count = #match(z, "=*", i) -- note, take the length + i = i + count + I = i + return (sub(z, i, i) == s) and count or (-count) - 1 +end + +---------------------------------------------------------------------- +-- reads a long string or long comment +---------------------------------------------------------------------- + +local function read_long_string(is_str, sep) + local i = I + 1 -- skip 2nd '[' + local sub = sub + local buff = "" + local c = sub(z, i, i) + if c == "\r" or c == "\n" then -- string starts with a newline? + i = inclinenumber(i) -- skip it + end + local j = i + while true do + local p, q, r = find(z, "([\r\n%]])", i) -- (long range) + if not p then + errorline(is_str and "unfinished long string" or + "unfinished long comment") + end + if is_str then + buff = buff..sub(z, i, p - 1) -- save string portions + end + i = p + if r == "]" then -- delimiter test + if skip_sep(i) == sep then + i = I + 1 -- skip 2nd ']' + break + end + buff = buff..sub(z, i, I - 1) + i = I + else -- newline + buff = buff.."\n" + i = inclinenumber(i) + end + end--while + I = i + return buff +end + +---------------------------------------------------------------------- +-- reads a string +---------------------------------------------------------------------- +local function read_string(del) + local i = I + local find = find + local sub = sub + local buff = "" + while true do + local p, q, r = find(z, "([\n\r\\\"\'])", i) -- (long range) + if p then + if r == "\n" or r == "\r" then + errorline("unfinished string") + end + buff = buff..sub(z, i, p - 1) -- normal portions + i = p + if r == "\\" then -- handle escapes + i = i + 1 + r = sub(z, i, i) + if r == "" then break end -- (EOZ error) + p = find("abfnrtv\n\r", r, 1, true) + ------------------------------------------------------ + if p then -- special escapes + if p > 7 then + r = "\n" + i = inclinenumber(i) + else + r = sub("\a\b\f\n\r\t\v", p, p) + i = i + 1 + end + ------------------------------------------------------ + elseif find(r, "%D") then -- other non-digits + i = i + 1 + ------------------------------------------------------ + else -- \xxx sequence + local p, q, s = find(z, "^(%d%d?%d?)", i) + i = q + 1 + if s + 1 > 256 then -- UCHAR_MAX + errorline("escape sequence too large") + end + r = string.char(s) + ------------------------------------------------------ + end--if p + else + i = i + 1 + if r == del then -- ending delimiter + I = i; return buff -- return string + end + end--if r + buff = buff..r -- handled escapes falls through to here + else + break -- (error) + end--if p + end--while + errorline("unfinished string") +end + +------------------------------------------------------------------------ +-- main lexer function +------------------------------------------------------------------------ +function llex() + local find = find + local match = match + while true do--outer + local i = I + -- inner loop allows break to be used to nicely section tests + while true do--inner + ---------------------------------------------------------------- + local p, _, r = find(z, "^([_%a][_%w]*)", i) + if p then + I = i + #r + if kw[r] then return r end -- reserved word (keyword) + return "", r -- identifier + end + ---------------------------------------------------------------- + local p, _, r = find(z, "^(%.?)%d", i) + if p then -- numeral + if r == "." then i = i + 1 end + local _, q, r = find(z, "^%d*[%.%d]*([eE]?)", i) + i = q + 1 + if #r == 1 then -- optional exponent + if match(z, "^[%+%-]", i) then -- optional sign + i = i + 1 + end + end + local _, q = find(z, "^[_%w]*", i) + I = q + 1 + local v = base.tonumber(sub(z, p, q)) -- handles hex also + if not v then errorline("malformed number") end + return "", v + end + ---------------------------------------------------------------- + local p, q, r = find(z, "^(%s)[ \t]*", i) + if p then + if r == "\n" or r == "\r" then -- newline + inclinenumber(i) + else + I = q + 1 -- whitespace + end + break -- (continue) + end + ---------------------------------------------------------------- + local r = match(z, "^%p", i) + if r then + local p = find("-[\"\'.=<>~", r, 1, true) + if p then + -- two-level if block for punctuation/symbols + -------------------------------------------------------- + if p <= 2 then + if p == 1 then -- minus + local c = match(z, "^%-%-(%[?)", i) + if c then + i = i + 2 + local sep = -1 + if c == "[" then + sep = skip_sep(i) + end + if sep >= 0 then -- long comment + read_long_string(false, sep) + else -- short comment + I = find(z, "[\n\r]", i) or (#z + 1) + end + break -- (continue) + end + -- (fall through for "-") + else -- [ or long string + local sep = skip_sep(i) + if sep >= 0 then + return "", read_long_string(true, sep) + elseif sep == -1 then + return "[" + else + errorline("invalid long string delimiter") + end + end + -------------------------------------------------------- + elseif p <= 5 then + if p < 5 then -- strings + I = i + 1 + return "", read_string(r) + end + r = match(z, "^%.%.?%.?", i) -- .|..|... dots + -- (fall through) + -------------------------------------------------------- + else -- relational + r = match(z, "^%p=?", i) + -- (fall through) + end + end + I = i + #r; return r -- for other symbols, fall through + end + ---------------------------------------------------------------- + local r = sub(z, i, i) + if r ~= "" then + I = i + 1; return r -- other single-char tokens + end + return "" -- end of stream + ---------------------------------------------------------------- + end--while inner + end--while outer +end + +return base.getfenv() diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/lparser_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/lparser_mk2.lua new file mode 100644 index 0000000..f94fb84 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/lparser_mk2.lua @@ -0,0 +1,1294 @@ +--[[-------------------------------------------------------------------- + + lparser.lua + Lua 5.1 parser in Lua + This file is part of Yueliang. + + Copyright (c) 2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * this is a Lua 5.1.x parser skeleton, for the llex_mk2.lua lexer +-- * builds some data, performs logging for educational purposes +-- * target is to have relatively efficient and clear code +-- * NO parsing limitations, since it is only a parser skeleton. Some +-- limits set in the default sources (in luaconf.h) are: +-- LUAI_MAXVARS = 200 +-- LUAI_MAXUPVALUES = 60 +-- LUAI_MAXCCALLS = 200 +-- * NO support for 'arg' vararg functions (LUA_COMPAT_VARARG) +-- * init(llex) needs one parameter, a lexer module that implements: +-- llex.lex() - returns appropriate [token, semantic info] pairs +-- llex.ln - current line number +-- llex.errorline(s, [line]) - dies with error message +-- +-- Usage example: +-- local llex = require("llex_mk2") +-- local lparser = require("lparser_mk2") +-- llex.init(source_code, source_code_name) +-- lparser.init(llex) +-- local fs = lparser.parser() +-- +-- Development notes: +-- * see test_parser-5.1.lua for grammar elements based on lparser.c +-- * next() (renamed to nextt) and lookahead() has been moved from llex; +-- it's more convenient to keep tok, seminfo as local variables here +-- * syntaxerror() is from llex, easier to keep here since little token +-- translation needed in preparation of error message +-- * lparser has a few extra items to help parsing/syntax checking +-- (a) line number (error reporting), lookahead token storage +-- * (b) per-prototype states needs a storage list +-- * (c) 'break' needs a per-block flag in a stack +-- * (d) 'kind' (v.k) testing needed in expr_stat() and assignment() +-- for disambiguation, thus v.k manipulation is retained +-- * (e) one line # var (lastln) for ambiguous (split line) function +-- call checking +-- * (f) LUA_COMPAT_VARARG compatibility code completely removed +-- * (g) minimal variable management code to differentiate each type +-- * parsing starts from the end of this file in parser() +----------------------------------------------------------------------]] + +local base = _G +local string = require "string" +module "lparser" +local _G = base.getfenv() + +--[[-------------------------------------------------------------------- +-- variable and data structure initialization +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- initialization: main variables +---------------------------------------------------------------------- + +local llex, llex_lex -- references lexer module, function +local line -- start line # for error messages +local lastln -- last line # for ambiguous syntax chk +local tok, seminfo -- token, semantic info pair +local peek_tok, peek_sem -- ditto, for lookahead +local fs -- current function state +local top_fs -- top-level function state + +-- forward references for local functions +local explist1, expr, block, exp1, body + +---------------------------------------------------------------------- +-- initialization: data structures +---------------------------------------------------------------------- + +local gmatch = string.gmatch + +local block_follow = {} -- lookahead check in chunk(), returnstat() +for v in gmatch("else elseif end until ", "%S+") do + block_follow[v] = true +end + +local stat_call = {} -- lookup for calls in stat() +for v in gmatch("if while do for repeat function local return break", "%S+") do + stat_call[v] = v.."_stat" +end + +local binopr_left = {} -- binary operators, left priority +local binopr_right = {} -- binary operators, right priority +for op, lt, rt in gmatch([[ +{+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{% 7 7} +{^ 10 9}{.. 5 4} +{~= 3 3}{== 3 3} +{< 3 3}{<= 3 3}{> 3 3}{>= 3 3} +{and 2 2}{or 1 1} +]], "{(%S+)%s(%d+)%s(%d+)}") do + binopr_left[op] = lt + 0 + binopr_right[op] = rt + 0 +end + +local unopr = { ["not"] = true, ["-"] = true, + ["#"] = true, } -- unary operators +local UNARY_PRIORITY = 8 -- priority for unary operators + +--[[-------------------------------------------------------------------- +-- logging: this logging function is for educational purposes +-- * logged data can be retrieved from the returned data structure +----------------------------------------------------------------------]] + +local function log(msg) + local log = top_fs.log + if not log then -- initialize message table + log = {}; top_fs.log = log + end + log[#log + 1] = msg +end + +--[[-------------------------------------------------------------------- +-- support functions +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- handles incoming token, semantic information pairs; these two +-- functions are from llex, they are put here because keeping the +-- tok, seminfo variables here as locals is more convenient +-- * NOTE: 'nextt' is named 'next' originally +---------------------------------------------------------------------- + +-- reads in next token +local function nextt() + lastln = llex.ln + if peek_tok then -- is there a look-ahead token? if yes, use it + tok, seminfo = peek_tok, peek_sem + peek_tok = nil + else + tok, seminfo = llex_lex() -- read next token + end +end + +-- peek at next token (single lookahead for table constructor) +local function lookahead() + peek_tok, peek_sem = llex_lex() + return peek_tok +end + +---------------------------------------------------------------------- +-- throws a syntax error, or if token expected is not there +---------------------------------------------------------------------- + +local function syntaxerror(msg) + local tok = tok + if tok ~= "" and tok ~= "" then + if tok == "" then tok = seminfo end + tok = "'"..tok.."'" + end + llex.errorline(msg.." near "..tok) +end + +local function error_expected(token) + syntaxerror("'"..token.."' expected") +end + +---------------------------------------------------------------------- +-- tests for a token, returns outcome +-- * return value changed to boolean +---------------------------------------------------------------------- + +local function testnext(c) + if tok == c then nextt(); return true end +end + +---------------------------------------------------------------------- +-- check for existence of a token, throws error if not found +---------------------------------------------------------------------- + +local function check(c) + if tok ~= c then error_expected(c) end +end + +---------------------------------------------------------------------- +-- verify existence of a token, then skip it +---------------------------------------------------------------------- + +local function checknext(c) + check(c); nextt() +end + +---------------------------------------------------------------------- +-- throws error if condition not matched +---------------------------------------------------------------------- + +local function check_condition(c, msg) + if not c then syntaxerror(msg) end +end + +---------------------------------------------------------------------- +-- verifies token conditions are met or else throw error +---------------------------------------------------------------------- + +local function check_match(what, who, where) + if not testnext(what) then + if where == llex.ln then + error_expected(what) + else + syntaxerror("'"..what.."' expected (to close '"..who.."' at line "..where..")") + end + end +end + +---------------------------------------------------------------------- +-- expect that token is a name, return the name +---------------------------------------------------------------------- + +local function str_checkname() + check("") + local ts = seminfo + nextt() + log(" str_checkname: '"..ts.."'") + return ts +end + +---------------------------------------------------------------------- +-- adds given string s in string pool, sets e as VK +---------------------------------------------------------------------- + +local function codestring(e, s) + e.k = "VK" + log(" codestring: "..string.format("%q", s)) +end + +---------------------------------------------------------------------- +-- consume a name token, adds it to string pool +---------------------------------------------------------------------- + +local function checkname(e) + log(" checkname:") + codestring(e, str_checkname()) +end + +--[[-------------------------------------------------------------------- +-- state management functions with open/close pairs +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- enters a code unit, initializes elements +---------------------------------------------------------------------- + +local function enterblock(isbreakable) + local bl = {} -- per-block state + bl.isbreakable = isbreakable + bl.prev = fs.bl + bl.locallist = {} + fs.bl = bl + log(">> enterblock(isbreakable="..base.tostring(isbreakable)..")") +end + +---------------------------------------------------------------------- +-- leaves a code unit, close any upvalues +---------------------------------------------------------------------- + +local function leaveblock() + local bl = fs.bl + fs.bl = bl.prev + log("<< leaveblock") +end + +---------------------------------------------------------------------- +-- opening of a function +-- * top_fs is only for anchoring the top fs, so that parser() can +-- return it to the caller function along with useful output +-- * used in parser() and body() +---------------------------------------------------------------------- + +local function open_func() + local new_fs -- per-function state + if not fs then -- top_fs is created early + new_fs = top_fs + else + new_fs = {} + end + new_fs.prev = fs -- linked list of function states + new_fs.bl = nil + new_fs.locallist = {} + fs = new_fs + log(">> open_func") +end + +---------------------------------------------------------------------- +-- closing of a function +-- * used in parser() and body() +---------------------------------------------------------------------- + +local function close_func() + fs = fs.prev + log("<< close_func") +end + +--[[-------------------------------------------------------------------- +-- variable (global|local|upvalue) handling +-- * a pure parser does not really need this, but if we want to produce +-- useful output, might as well write minimal code to manage this... +-- * entry point is singlevar() for variable lookups +-- * three entry points for local variable creation, in order to keep +-- to original C calls, but the extra arguments such as positioning +-- are removed as we are not allocating registers -- we are only +-- doing simple classification +-- * lookup tables (bl.locallist) are maintained awkwardly in the basic +-- block data structures, PLUS the function data structure (this is +-- an inelegant hack, since bl is nil for the top level of a function) +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- register a local variable, set in active variable list +-- * code for a simple lookup only +-- * used in new_localvarliteral(), parlist(), fornum(), forlist(), +-- localfunc(), localstat() +---------------------------------------------------------------------- + +local function new_localvar(name) + local bl = fs.bl + local locallist + if bl then + locallist = bl.locallist + else + locallist = fs.locallist + end + locallist[name] = true + log(" new_localvar: '"..name.."'") +end + +---------------------------------------------------------------------- +-- creates a new local variable given a name +-- * used in fornum(), forlist(), parlist(), body() +---------------------------------------------------------------------- + +local function new_localvarliteral(name) + new_localvar(name) +end + +---------------------------------------------------------------------- +-- search the local variable namespace of the given fs for a match +-- * a simple lookup only, no active variable list kept, so no useful +-- index value can be returned by this function +-- * used only in singlevaraux() +---------------------------------------------------------------------- + +local function searchvar(fs, n) + local bl = fs.bl + if bl then + locallist = bl.locallist + while locallist do + if locallist[n] then return 1 end -- found + bl = bl.prev + locallist = bl and bl.locallist + end + end + locallist = fs.locallist + if locallist[n] then return 1 end -- found + return -1 -- not found +end + +---------------------------------------------------------------------- +-- handle locals, globals and upvalues and related processing +-- * search mechanism is recursive, calls itself to search parents +-- * used only in singlevar() +---------------------------------------------------------------------- + +local function singlevaraux(fs, n, var, base) + if fs == nil then -- no more levels? + var.k = "VGLOBAL" -- default is global variable + return "VGLOBAL" + else + local v = searchvar(fs, n) -- look up at current level + if v >= 0 then + var.k = "VLOCAL" + -- codegen may need to deal with upvalue here + return "VLOCAL" + else -- not found at current level; try upper one + if singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then + return "VGLOBAL" + end + -- else was LOCAL or UPVAL, handle here + var.k = "VUPVAL" -- upvalue in this level + return "VUPVAL" + end--if v + end--if fs +end + +---------------------------------------------------------------------- +-- consume a name token, creates a variable (global|local|upvalue) +-- * used in prefixexp(), funcname() +---------------------------------------------------------------------- + +local function singlevar(v) + local varname = str_checkname() + singlevaraux(fs, varname, v, 1) + log(" singlevar(kind): '"..v.k.."'") +end + +--[[-------------------------------------------------------------------- +-- other parsing functions +-- * for table constructor, parameter list, argument list +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- parse a function name suffix, for function call specifications +-- * used in primaryexp(), funcname() +---------------------------------------------------------------------- + +local function field(v) + -- field -> ['.' | ':'] NAME + local key = {} + log(" field: operator="..tok) + nextt() -- skip the dot or colon + checkname(key) + v.k = "VINDEXED" +end + +---------------------------------------------------------------------- +-- parse a table indexing suffix, for constructors, expressions +-- * used in recfield(), primaryexp() +---------------------------------------------------------------------- + +local function yindex(v) + -- index -> '[' expr ']' + log(">> index: begin '['") + nextt() -- skip the '[' + expr(v) + checknext("]") + log("<< index: end ']'") +end + +---------------------------------------------------------------------- +-- parse a table record (hash) field +-- * used in constructor() +---------------------------------------------------------------------- + +local function recfield(cc) + -- recfield -> (NAME | '['exp1']') = exp1 + local key, val = {}, {} + if tok == "" then + log("recfield: name") + checkname(key) + else-- tok == '[' + log("recfield: [ exp1 ]") + yindex(key) + end + checknext("=") + expr(val) +end + +---------------------------------------------------------------------- +-- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) +-- * note: retained in this skeleton because it modifies cc.v.k +-- * used in constructor() +---------------------------------------------------------------------- + +local function closelistfield(cc) + if cc.v.k == "VVOID" then return end -- there is no list item + cc.v.k = "VVOID" +end + +---------------------------------------------------------------------- +-- parse a table list (array) field +-- * used in constructor() +---------------------------------------------------------------------- + +local function listfield(cc) + log("listfield: expr") + expr(cc.v) +end + +---------------------------------------------------------------------- +-- parse a table constructor +-- * used in funcargs(), simpleexp() +---------------------------------------------------------------------- + +local function constructor(t) + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- field -> recfield | listfield + -- fieldsep -> ',' | ';' + log(">> constructor: begin") + local line = llex.ln + local cc = {} + cc.v = {} + cc.t = t + t.k = "VRELOCABLE" + cc.v.k = "VVOID" + checknext("{") + repeat + if tok == "}" then break end + -- closelistfield(cc) here + local c = tok + if c == "" then -- may be listfields or recfields + if lookahead() ~= "=" then -- look ahead: expression? + listfield(cc) + else + recfield(cc) + end + elseif c == "[" then -- constructor_item -> recfield + recfield(cc) + else -- constructor_part -> listfield + listfield(cc) + end + until not testnext(",") and not testnext(";") + check_match("}", "{", line) + -- lastlistfield(cc) here + log("<< constructor: end") +end + +---------------------------------------------------------------------- +-- parse the arguments (parameters) of a function declaration +-- * used in body() +---------------------------------------------------------------------- + +local function parlist() + -- parlist -> [ param { ',' param } ] + log(">> parlist: begin") + if tok ~= ")" then -- is 'parlist' not empty? + repeat + local c = tok + if c == "" then -- param -> NAME + new_localvar(str_checkname()) + elseif c == "..." then + log("parlist: ... (dots)") + nextt() + fs.is_vararg = true + else + syntaxerror(" or '...' expected") + end + until fs.is_vararg or not testnext(",") + end--if + log("<< parlist: end") +end + +---------------------------------------------------------------------- +-- parse the parameters of a function call +-- * contrast with parlist(), used in function declarations +-- * used in primaryexp() +---------------------------------------------------------------------- + +local function funcargs(f) + local args = {} + local line = llex.ln + local c = tok + if c == "(" then -- funcargs -> '(' [ explist1 ] ')' + log(">> funcargs: begin '('") + if line ~= lastln then + syntaxerror("ambiguous syntax (function call x new statement)") + end + nextt() + if tok == ")" then -- arg list is empty? + args.k = "VVOID" + else + explist1(args) + end + check_match(")", "(", line) + elseif c == "{" then -- funcargs -> constructor + log(">> funcargs: begin '{'") + constructor(args) + elseif c == "" then -- funcargs -> STRING + log(">> funcargs: begin ") + codestring(args, seminfo) + nextt() -- must use 'seminfo' before 'next' + else + syntaxerror("function arguments expected") + return + end--if c + f.k = "VCALL" + log("<< funcargs: end -- expr is a VCALL") +end + +--[[-------------------------------------------------------------------- +-- mostly expression functions +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- parses an expression in parentheses or a single variable +-- * used in primaryexp() +---------------------------------------------------------------------- + +local function prefixexp(v) + -- prefixexp -> NAME | '(' expr ')' + local c = tok + if c == "(" then + log(">> prefixexp: begin ( expr ) ") + local line = llex.ln + nextt() + expr(v) + check_match(")", "(", line) + log("<< prefixexp: end ( expr ) ") + elseif c == "" then + log("prefixexp: ") + singlevar(v) + else + syntaxerror("unexpected symbol") + end--if c +end + +---------------------------------------------------------------------- +-- parses a prefixexp (an expression in parentheses or a single +-- variable) or a function call specification +-- * used in simpleexp(), assignment(), expr_stat() +---------------------------------------------------------------------- + +local function primaryexp(v) + -- primaryexp -> + -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + prefixexp(v) + while true do + local c = tok + if c == "." then -- field + log("primaryexp: '.' field") + field(v) + elseif c == "[" then -- '[' exp1 ']' + log("primaryexp: [ exp1 ]") + local key = {} + yindex(key) + elseif c == ":" then -- ':' NAME funcargs + log("primaryexp: : funcargs") + local key = {} + nextt() + checkname(key) + funcargs(v) + elseif c == "(" or c == "" or c == "{" then -- funcargs + log("primaryexp: "..c.." funcargs") + funcargs(v) + else + return + end--if c + end--while +end + +---------------------------------------------------------------------- +-- parses general expression types, constants handled here +-- * used in subexpr() +---------------------------------------------------------------------- + +local function simpleexp(v) + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | + -- constructor | FUNCTION body | primaryexp + local c = tok + if c == "" then + log("simpleexp: ="..seminfo) + v.k = "VKNUM" + elseif c == "" then + log("simpleexp: ="..seminfo) + codestring(v, seminfo) + elseif c == "nil" then + log("simpleexp: nil") + v.k = "VNIL" + elseif c == "true" then + log("simpleexp: true") + v.k = "VTRUE" + elseif c == "false" then + log("simpleexp: false") + v.k = "VFALSE" + elseif c == "..." then -- vararg + check_condition(fs.is_vararg == true, + "cannot use '...' outside a vararg function"); + log("simpleexp: ...") + v.k = "VVARARG" + elseif c == "{" then -- constructor + log("simpleexp: constructor") + constructor(v) + return + elseif c == "function" then + log("simpleexp: function") + nextt() + body(v, false, llex.ln) + return + else + primaryexp(v) + return + end--if c + nextt() +end + +------------------------------------------------------------------------ +-- Parse subexpressions. Includes handling of unary operators and binary +-- operators. A subexpr is given the rhs priority level of the operator +-- immediately left of it, if any (limit is -1 if none,) and if a binop +-- is found, limit is compared with the lhs priority level of the binop +-- in order to determine which executes first. +-- * recursively called +-- * used in expr() +------------------------------------------------------------------------ + +local function subexpr(v, limit) + -- subexpr -> (simpleexp | unop subexpr) { binop subexpr } + -- * where 'binop' is any binary operator with a priority + -- higher than 'limit' + local op = tok + local uop = unopr[op] + if uop then + log(" subexpr: uop='"..op.."'") + nextt() + subexpr(v, UNARY_PRIORITY) + else + simpleexp(v) + end + -- expand while operators have priorities higher than 'limit' + op = tok + local binop = binopr_left[op] + while binop and binop > limit do + local v2 = {} + log(">> subexpr: binop='"..op.."'") + nextt() + -- read sub-expression with higher priority + local nextop = subexpr(v2, binopr_right[op]) + log("<< subexpr: -- evaluate") + op = nextop + binop = binopr_left[op] + end + return op -- return first untreated operator +end + +---------------------------------------------------------------------- +-- Expression parsing starts here. Function subexpr is entered with the +-- left operator (which is non-existent) priority of -1, which is lower +-- than all actual operators. Expr information is returned in parm v. +-- * used in cond(), explist1(), index(), recfield(), listfield(), +-- prefixexp(), while_stat(), exp1() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function expr(v) + -- expr -> subexpr + log("expr:") + subexpr(v, 0) +end + +--[[-------------------------------------------------------------------- +-- third level parsing functions +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- parse a variable assignment sequence +-- * recursively called +-- * used in expr_stat() +------------------------------------------------------------------------ + +local function assignment(v) + local e = {} + local c = v.v.k + check_condition(c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" + or c == "VINDEXED", "syntax error") + if testnext(",") then -- assignment -> ',' primaryexp assignment + local nv = {} -- expdesc + nv.v = {} + log("assignment: ',' -- next LHS element") + primaryexp(nv.v) + -- lparser.c deals with some register usage conflict here + assignment(nv) + else -- assignment -> '=' explist1 + checknext("=") + log("assignment: '=' -- RHS elements follows") + explist1(e) + return -- avoid default + end + e.k = "VNONRELOC" +end + +---------------------------------------------------------------------- +-- parse a for loop body for both versions of the for loop +-- * used in fornum(), forlist() +---------------------------------------------------------------------- + +local function forbody(isnum) + -- forbody -> DO block + checknext("do") + enterblock(false) -- scope for declared variables + block() + leaveblock() -- end of scope for declared variables +end + +---------------------------------------------------------------------- +-- parse a numerical for loop, calls forbody() +-- * used in for_stat() +---------------------------------------------------------------------- + +local function fornum(varname) + -- fornum -> NAME = exp1, exp1 [, exp1] DO body + local line = line + new_localvarliteral("(for index)") + new_localvarliteral("(for limit)") + new_localvarliteral("(for step)") + new_localvar(varname) + log(">> fornum: begin") + checknext("=") + log("fornum: index start") + exp1() -- initial value + checknext(",") + log("fornum: index stop") + exp1() -- limit + if testnext(",") then + log("fornum: index step") + exp1() -- optional step + else + -- default step = 1 + end + log("fornum: body") + forbody(true) + log("<< fornum: end") +end + +---------------------------------------------------------------------- +-- parse a generic for loop, calls forbody() +-- * used in for_stat() +---------------------------------------------------------------------- + +local function forlist(indexname) + -- forlist -> NAME {, NAME} IN explist1 DO body + log(">> forlist: begin") + local e = {} + -- create control variables + new_localvarliteral("(for generator)") + new_localvarliteral("(for state)") + new_localvarliteral("(for control)") + -- create declared variables + new_localvar(indexname) + while testnext(",") do + new_localvar(str_checkname()) + end + checknext("in") + local line = line + log("forlist: explist1") + explist1(e) + log("forlist: body") + forbody(false) + log("<< forlist: end") +end + +---------------------------------------------------------------------- +-- parse a function name specification +-- * used in func_stat() +---------------------------------------------------------------------- + +local function funcname(v) + -- funcname -> NAME {field} [':' NAME] + log(">> funcname: begin") + local needself = false + singlevar(v) + while tok == "." do + log("funcname: -- '.' field") + field(v) + end + if tok == ":" then + log("funcname: -- ':' field") + needself = true + field(v) + end + log("<< funcname: end") + return needself +end + +---------------------------------------------------------------------- +-- parse the single expressions needed in numerical for loops +-- * used in fornum() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function exp1() + -- exp1 -> expr + local e = {} + log(">> exp1: begin") + expr(e) + log("<< exp1: end") +end + +---------------------------------------------------------------------- +-- parse condition in a repeat statement or an if control structure +-- * used in repeat_stat(), test_then_block() +---------------------------------------------------------------------- + +local function cond() + -- cond -> expr + log(">> cond: begin") + local v = {} + expr(v) -- read condition + log("<< cond: end") +end + +---------------------------------------------------------------------- +-- parse part of an if control structure, including the condition +-- * used in if_stat() +---------------------------------------------------------------------- + +local function test_then_block() + -- test_then_block -> [IF | ELSEIF] cond THEN block + nextt() -- skip IF or ELSEIF + log("test_then_block: test condition") + cond() + checknext("then") + log("test_then_block: then block") + block() -- 'then' part +end + +---------------------------------------------------------------------- +-- parse a local function statement +-- * used in local_stat() +---------------------------------------------------------------------- + +local function localfunc() + -- localfunc -> NAME body + local v, b = {} + log("localfunc: begin") + new_localvar(str_checkname()) + v.k = "VLOCAL" + log("localfunc: body") + body(b, false, llex.ln) + log("localfunc: end") +end + +---------------------------------------------------------------------- +-- parse a local variable declaration statement +-- * used in local_stat() +---------------------------------------------------------------------- + +local function localstat() + -- localstat -> NAME {',' NAME} ['=' explist1] + log(">> localstat: begin") + local e = {} + repeat + new_localvar(str_checkname()) + until not testnext(",") + if testnext("=") then + log("localstat: -- assignment") + explist1(e) + else + e.k = "VVOID" + end + log("<< localstat: end") +end + +---------------------------------------------------------------------- +-- parse a list of comma-separated expressions +-- * used in return_stat(), localstat(), funcargs(), assignment(), +-- forlist() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function explist1(e) + -- explist1 -> expr { ',' expr } + log(">> explist1: begin") + expr(e) + while testnext(",") do + log("explist1: ',' -- continuation") + expr(e) + end + log("<< explist1: end") +end + +---------------------------------------------------------------------- +-- parse function declaration body +-- * used in simpleexp(), localfunc(), func_stat() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function body(e, needself, line) + -- body -> '(' parlist ')' chunk END + open_func() + log("body: begin") + checknext("(") + if needself then + new_localvarliteral("self") + end + log("body: parlist") + parlist() + checknext(")") + log("body: chunk") + chunk() + check_match("end", "function", line) + log("body: end") + close_func() +end + +---------------------------------------------------------------------- +-- parse a code block or unit +-- * used in do_stat(), while_stat(), forbody(), test_then_block(), +-- if_stat() +---------------------------------------------------------------------- + +-- this is a forward-referenced local +function block() + -- block -> chunk + log("block: begin") + enterblock(false) + chunk() + leaveblock() + log("block: end") +end + +--[[-------------------------------------------------------------------- +-- second level parsing functions, all with '_stat' suffix +-- * since they are called via a table lookup, they cannot be local +-- functions (a lookup table of local functions might be smaller...) +-- * stat() -> *_stat() +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- initial parsing for a for loop, calls fornum() or forlist() +-- * removed 'line' parameter (used to set debug information only) +-- * used in stat() +---------------------------------------------------------------------- + +function for_stat() + -- stat -> for_stat -> FOR (fornum | forlist) END + local line = line + log("for_stat: begin") + enterblock(true) -- scope for loop and control variables + nextt() -- skip 'for' + local varname = str_checkname() -- first variable name + local c = tok + if c == "=" then + log("for_stat: numerical loop") + fornum(varname) + elseif c == "," or c == "in" then + log("for_stat: list-based loop") + forlist(varname) + else + syntaxerror("'=' or 'in' expected") + end + check_match("end", "for", line) + leaveblock() -- loop scope (`break' jumps to this point) + log("for_stat: end") +end + +---------------------------------------------------------------------- +-- parse a while-do control structure, body processed by block() +-- * used in stat() +---------------------------------------------------------------------- + +function while_stat() + -- stat -> while_stat -> WHILE cond DO block END + local line = line + nextt() -- skip WHILE + log("while_stat: begin/condition") + cond() -- parse condition + enterblock(true) + checknext("do") + log("while_stat: block") + block() + check_match("end", "while", line) + leaveblock() + log("while_stat: end") +end + +---------------------------------------------------------------------- +-- parse a repeat-until control structure, body parsed by chunk() +-- * originally, repeatstat() calls breakstat() too if there is an +-- upvalue in the scope block; nothing is actually lexed, it is +-- actually the common code in breakstat() for closing of upvalues +-- * used in stat() +---------------------------------------------------------------------- + +function repeat_stat() + -- stat -> repeat_stat -> REPEAT block UNTIL cond + local line = line + log("repeat_stat: begin") + enterblock(true) -- loop block + enterblock(false) -- scope block + nextt() -- skip REPEAT + chunk() + check_match("until", "repeat", line) + log("repeat_stat: condition") + cond() + -- close upvalues at scope level below + leaveblock() -- finish scope + leaveblock() -- finish loop + log("repeat_stat: end") +end + +---------------------------------------------------------------------- +-- parse an if control structure +-- * used in stat() +---------------------------------------------------------------------- + +function if_stat() + -- stat -> if_stat -> IF cond THEN block + -- {ELSEIF cond THEN block} [ELSE block] END + local line = line + local v = {} + log("if_stat: if...then") + test_then_block() -- IF cond THEN block + while tok == "elseif" do + log("if_stat: elseif...then") + test_then_block() -- ELSEIF cond THEN block + end + if tok == "else" then + log("if_stat: else...") + nextt() -- skip ELSE + block() -- 'else' part + end + check_match("end", "if", line) + log("if_stat: end") +end + +---------------------------------------------------------------------- +-- parse a return statement +-- * used in stat() +---------------------------------------------------------------------- + +function return_stat() + -- stat -> return_stat -> RETURN explist + local e = {} + nextt() -- skip RETURN + local c = tok + if block_follow[c] or c == ";" then + -- return no values + log("return_stat: no return values") + else + log("return_stat: begin") + explist1(e) -- optional return values + log("return_stat: end") + end +end + +---------------------------------------------------------------------- +-- parse a break statement +-- * used in stat() +---------------------------------------------------------------------- + +function break_stat() + -- stat -> break_stat -> BREAK + local bl = fs.bl + nextt() -- skip BREAK + while bl and not bl.isbreakable do -- find a breakable block + bl = bl.prev + end + if not bl then + syntaxerror("no loop to break") + end + log("break_stat: -- break out of loop") +end + +---------------------------------------------------------------------- +-- parse a function call with no returns or an assignment statement +-- * the struct with .prev is used for name searching in lparse.c, +-- so it is retained for now; present in assignment() also +-- * used in stat() +---------------------------------------------------------------------- + +function expr_stat() + -- stat -> expr_stat -> func | assignment + local v = {} + v.v = {} + primaryexp(v.v) + if v.v.k == "VCALL" then -- stat -> func + -- call statement uses no results + log("expr_stat: function call k='"..v.v.k.."'") + else -- stat -> assignment + log("expr_stat: assignment k='"..v.v.k.."'") + v.prev = nil + assignment(v) + end +end + +---------------------------------------------------------------------- +-- parse a function statement +-- * used in stat() +---------------------------------------------------------------------- + +function function_stat() + -- stat -> function_stat -> FUNCTION funcname body + local line = line + local v, b = {}, {} + log("function_stat: begin") + nextt() -- skip FUNCTION + local needself = funcname(v) + log("function_stat: body needself='"..base.tostring(needself).."'") + body(b, needself, line) + log("function_stat: end") +end + +---------------------------------------------------------------------- +-- parse a simple block enclosed by a DO..END pair +-- * used in stat() +---------------------------------------------------------------------- + +function do_stat() + -- stat -> do_stat -> DO block END + local line = line + nextt() -- skip DO + log("do_stat: begin") + block() + log("do_stat: end") + check_match("end", "do", line) +end + +---------------------------------------------------------------------- +-- parse a statement starting with LOCAL +-- * used in stat() +---------------------------------------------------------------------- + +function local_stat() + -- stat -> local_stat -> LOCAL FUNCTION localfunc + -- -> LOCAL localstat + nextt() -- skip LOCAL + if testnext("function") then -- local function? + log("local_stat: local function") + localfunc() + else + log("local_stat: local statement") + localstat() + end +end + +--[[-------------------------------------------------------------------- +-- main functions, top level parsing functions +-- * accessible functions are: init(lexer), parser() +-- * [entry] -> parser() -> chunk() -> stat() +----------------------------------------------------------------------]] + +---------------------------------------------------------------------- +-- initial parsing for statements, calls '_stat' suffixed functions +-- * used in chunk() +---------------------------------------------------------------------- + +local function stat() + -- stat -> if_stat while_stat do_stat for_stat repeat_stat + -- function_stat local_stat return_stat break_stat + -- expr_stat + line = llex.ln -- may be needed for error messages + local c = tok + local fn = stat_call[c] + -- handles: if while do for repeat function local return break + if fn then + log("-- STATEMENT: begin '"..c.."' line="..line) + _G[fn]() + log("-- STATEMENT: end '"..c.."'") + -- return or break must be last statement + if c == "return" or c == "break" then return true end + else + log("-- STATEMENT: begin 'expr' line="..line) + expr_stat() + log("-- STATEMENT: end 'expr'") + end + log("") + return false +end + +---------------------------------------------------------------------- +-- parse a chunk, which consists of a bunch of statements +-- * used in parser(), body(), block(), repeat_stat() +---------------------------------------------------------------------- + +function chunk() + -- chunk -> { stat [';'] } + log("chunk:") + local islast = false + while not islast and not block_follow[tok] do + islast = stat() + testnext(";") + end +end + +---------------------------------------------------------------------- +-- performs parsing, returns parsed data structure +---------------------------------------------------------------------- + +function parser() + log("-- TOP: begin") + open_func() + fs.is_vararg = true -- main func. is always vararg + log("") + nextt() -- read first token + chunk() + check("") + close_func() + log("-- TOP: end") + return top_fs +end + +---------------------------------------------------------------------- +-- initialization function +---------------------------------------------------------------------- + +function init(lexer) + llex = lexer -- set lexer (assume user-initialized) + llex_lex = llex.llex + top_fs = {} -- reset top level function state +end + +return _G diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_01.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_01.lua new file mode 100644 index 0000000..379cc9d --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_01.lua @@ -0,0 +1,9 @@ +-- START OF SOURCE -- +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_02.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_02.lua new file mode 100644 index 0000000..13eb2e6 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_02.lua @@ -0,0 +1,10 @@ +-- START OF SOURCE -- +-- foobar +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_03.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_03.lua new file mode 100644 index 0000000..33df29c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_03.lua @@ -0,0 +1,21 @@ +-- START OF SOURCE -- +do +end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_04.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_04.lua new file mode 100644 index 0000000..d0fefbc --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_04.lua @@ -0,0 +1,31 @@ +-- START OF SOURCE -- +do end +do end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'do' line=2 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_05.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_05.lua new file mode 100644 index 0000000..17a9231 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_05.lua @@ -0,0 +1,129 @@ +-- START OF SOURCE -- +foo() +foo{} +foo"" +foo:bar() +foo=false +foo.bar=true +foo[true]=nil +foo,bar=1,"a" +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + primaryexp: { funcargs + funcargs: begin '{' + constructor: begin + constructor: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + primaryexp: funcargs + funcargs: begin + codestring: "" + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + primaryexp: : funcargs + checkname: + str_checkname: 'bar' + codestring: "bar" + funcargs: begin '(' + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: false + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + primaryexp: '.' field + field: operator=. + checkname: + str_checkname: 'bar' + codestring: "bar" + expr_stat: assignment k='VINDEXED' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: true + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=7 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + primaryexp: [ exp1 ] + index: begin '[' + expr: + simpleexp: true + index: end ']' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: nil + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=8 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: ',' -- next LHS element + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + explist1: ',' -- continuation + expr: + simpleexp: =a + codestring: "a" + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_06.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_06.lua new file mode 100644 index 0000000..29f1703 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_06.lua @@ -0,0 +1,132 @@ +-- START OF SOURCE -- +foo=true +foo=false +foo=nil +foo=1.23e45 +foo=-1 +foo=(0) +foo=1+2 +foo=1+2*3-4/5 +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: true + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: false + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: nil + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1.23e+45 + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + subexpr: uop='-' + simpleexp: =1 + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: begin ( expr ) + expr: + simpleexp: =0 + prefixexp: end ( expr ) + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=7 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + subexpr: binop='+' + simpleexp: =2 + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=8 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + subexpr: binop='+' + simpleexp: =2 + subexpr: binop='*' + simpleexp: =3 + subexpr: -- evaluate + subexpr: -- evaluate + subexpr: binop='-' + simpleexp: =4 + subexpr: binop='/' + simpleexp: =5 + subexpr: -- evaluate + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_07.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_07.lua new file mode 100644 index 0000000..c3a4600 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_07.lua @@ -0,0 +1,147 @@ +-- START OF SOURCE -- +if foo then foo=1 end +if foo then foo=1 else foo=0 end +if foo then foo=1 elseif not foo then foo=0 end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'if' line=1 + if_stat: if...then + test_then_block: test condition + cond: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + cond: end + test_then_block: then block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: end + -- STATEMENT: end 'if' + + -- STATEMENT: begin 'if' line=2 + if_stat: if...then + test_then_block: test condition + cond: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + cond: end + test_then_block: then block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: else... + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =0 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: end + -- STATEMENT: end 'if' + + -- STATEMENT: begin 'if' line=3 + if_stat: if...then + test_then_block: test condition + cond: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + cond: end + test_then_block: then block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =1 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: elseif...then + test_then_block: test condition + cond: begin + expr: + subexpr: uop='not' + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + cond: end + test_then_block: then block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =0 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + if_stat: end + -- STATEMENT: end 'if' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_08.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_08.lua new file mode 100644 index 0000000..d086c98 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_08.lua @@ -0,0 +1,66 @@ +-- START OF SOURCE -- +do return end +do return 123 end +do return "foo","bar" end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'do' line=2 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: begin + explist1: begin + expr: + simpleexp: =123 + explist1: end + return_stat: end + -- STATEMENT: end 'return' + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'do' line=3 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: begin + explist1: begin + expr: + simpleexp: =foo + codestring: "foo" + explist1: ',' -- continuation + expr: + simpleexp: =bar + codestring: "bar" + explist1: end + return_stat: end + -- STATEMENT: end 'return' + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_09.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_09.lua new file mode 100644 index 0000000..67c6cf3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_09.lua @@ -0,0 +1,103 @@ +-- START OF SOURCE -- +while true do foo=not foo end +while foo~=42 do foo=foo-1 end +while true do break end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'while' line=1 + while_stat: begin/condition + cond: begin + expr: + simpleexp: true + cond: end + enterblock(isbreakable=true) + while_stat: block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + subexpr: uop='not' + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + while_stat: end + -- STATEMENT: end 'while' + + -- STATEMENT: begin 'while' line=2 + while_stat: begin/condition + cond: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + subexpr: binop='~=' + simpleexp: =42 + subexpr: -- evaluate + cond: end + enterblock(isbreakable=true) + while_stat: block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + subexpr: binop='-' + simpleexp: =1 + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + while_stat: end + -- STATEMENT: end 'while' + + -- STATEMENT: begin 'while' line=3 + while_stat: begin/condition + cond: begin + expr: + simpleexp: true + cond: end + enterblock(isbreakable=true) + while_stat: block + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'break' line=3 + break_stat: -- break out of loop + -- STATEMENT: end 'break' + leaveblock + block: end + leaveblock + while_stat: end + -- STATEMENT: end 'while' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_10.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_10.lua new file mode 100644 index 0000000..b8e7754 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_10.lua @@ -0,0 +1,100 @@ +-- START OF SOURCE -- +repeat foo=foo.."bar" until false +repeat foo=foo/2 until foo<1 +repeat break until false +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'repeat' line=1 + repeat_stat: begin + enterblock(isbreakable=true) + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + subexpr: binop='..' + simpleexp: =bar + codestring: "bar" + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + repeat_stat: condition + cond: begin + expr: + simpleexp: false + cond: end + leaveblock + leaveblock + repeat_stat: end + -- STATEMENT: end 'repeat' + + -- STATEMENT: begin 'repeat' line=2 + repeat_stat: begin + enterblock(isbreakable=true) + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + subexpr: binop='/' + simpleexp: =2 + subexpr: -- evaluate + explist1: end + -- STATEMENT: end 'expr' + + repeat_stat: condition + cond: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + subexpr: binop='<' + simpleexp: =1 + subexpr: -- evaluate + cond: end + leaveblock + leaveblock + repeat_stat: end + -- STATEMENT: end 'repeat' + + -- STATEMENT: begin 'repeat' line=3 + repeat_stat: begin + enterblock(isbreakable=true) + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'break' line=3 + break_stat: -- break out of loop + -- STATEMENT: end 'break' + repeat_stat: condition + cond: begin + expr: + simpleexp: false + cond: end + leaveblock + leaveblock + repeat_stat: end + -- STATEMENT: end 'repeat' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_11.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_11.lua new file mode 100644 index 0000000..461ea82 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_11.lua @@ -0,0 +1,192 @@ +-- START OF SOURCE -- +for i=1,10 do foo=i end +for i=1,10,2 do break end +for i in foo do bar=0 end +for i,j in foo,bar do baz=0 end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'for' line=1 + for_stat: begin + enterblock(isbreakable=true) + str_checkname: 'i' + for_stat: numerical loop + new_localvar: '(for index)' + new_localvar: '(for limit)' + new_localvar: '(for step)' + new_localvar: 'i' + fornum: begin + fornum: index start + exp1: begin + expr: + simpleexp: =1 + exp1: end + fornum: index stop + exp1: begin + expr: + simpleexp: =10 + exp1: end + fornum: body + enterblock(isbreakable=false) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'i' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + fornum: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=2 + for_stat: begin + enterblock(isbreakable=true) + str_checkname: 'i' + for_stat: numerical loop + new_localvar: '(for index)' + new_localvar: '(for limit)' + new_localvar: '(for step)' + new_localvar: 'i' + fornum: begin + fornum: index start + exp1: begin + expr: + simpleexp: =1 + exp1: end + fornum: index stop + exp1: begin + expr: + simpleexp: =10 + exp1: end + fornum: index step + exp1: begin + expr: + simpleexp: =2 + exp1: end + fornum: body + enterblock(isbreakable=false) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'break' line=2 + break_stat: -- break out of loop + -- STATEMENT: end 'break' + leaveblock + block: end + leaveblock + fornum: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=3 + for_stat: begin + enterblock(isbreakable=true) + str_checkname: 'i' + for_stat: list-based loop + forlist: begin + new_localvar: '(for generator)' + new_localvar: '(for state)' + new_localvar: '(for control)' + new_localvar: 'i' + forlist: explist1 + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + explist1: end + forlist: body + enterblock(isbreakable=false) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =0 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + forlist: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=4 + for_stat: begin + enterblock(isbreakable=true) + str_checkname: 'i' + for_stat: list-based loop + forlist: begin + new_localvar: '(for generator)' + new_localvar: '(for state)' + new_localvar: '(for control)' + new_localvar: 'i' + str_checkname: 'j' + new_localvar: 'j' + forlist: explist1 + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VGLOBAL' + explist1: end + forlist: body + enterblock(isbreakable=false) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: =0 + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + forlist: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_12.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_12.lua new file mode 100644 index 0000000..c423d85 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_12.lua @@ -0,0 +1,52 @@ +-- START OF SOURCE -- +local foo +local foo,bar,baz +local foo,bar="foo","bar" +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + new_localvar: 'foo' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=2 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + new_localvar: 'foo' + str_checkname: 'bar' + new_localvar: 'bar' + str_checkname: 'baz' + new_localvar: 'baz' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=3 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + new_localvar: 'foo' + str_checkname: 'bar' + new_localvar: 'bar' + localstat: -- assignment + explist1: begin + expr: + simpleexp: =foo + codestring: "foo" + explist1: ',' -- continuation + expr: + simpleexp: =bar + codestring: "bar" + explist1: end + localstat: end + -- STATEMENT: end 'local' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_13.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_13.lua new file mode 100644 index 0000000..b5f598a --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_13.lua @@ -0,0 +1,108 @@ +-- START OF SOURCE -- +local function foo() return end +local function foo(a) return end +local function foo(x,y,z) return end +local function foo(x,...) return end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + new_localvar: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=2 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + new_localvar: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'a' + new_localvar: 'a' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=3 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + new_localvar: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + new_localvar: 'x' + str_checkname: 'y' + new_localvar: 'y' + str_checkname: 'z' + new_localvar: 'z' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=4 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + new_localvar: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + new_localvar: 'x' + parlist: ... (dots) + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=4 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_14.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_14.lua new file mode 100644 index 0000000..a6b9ad0 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_14.lua @@ -0,0 +1,112 @@ +-- START OF SOURCE -- +function foo() return end +function foo(a) return end +function foo(x,y,z) return end +function foo(x,...) return end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=2 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'a' + new_localvar: 'a' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=3 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + new_localvar: 'x' + str_checkname: 'y' + new_localvar: 'y' + str_checkname: 'z' + new_localvar: 'z' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=4 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + new_localvar: 'x' + parlist: ... (dots) + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=4 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_15.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_15.lua new file mode 100644 index 0000000..497eeaf --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_15.lua @@ -0,0 +1,140 @@ +-- START OF SOURCE -- +function foo.bar(p) return end +function foo.bar.baz(p) return end +function foo:bar(p) return end +function foo.bar.baz(p) return end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'p' + new_localvar: 'p' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=2 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'baz' + codestring: "baz" + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'p' + new_localvar: 'p' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=3 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: -- ':' field + field: operator=: + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: end + function_stat: body needself='true' + open_func + body: begin + new_localvar: 'self' + body: parlist + parlist: begin + str_checkname: 'p' + new_localvar: 'p' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + -- STATEMENT: begin 'function' line=4 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: -- '.' field + field: operator=. + checkname: + str_checkname: 'baz' + codestring: "baz" + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'p' + new_localvar: 'p' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=4 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_16.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_16.lua new file mode 100644 index 0000000..b7907b8 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_16.lua @@ -0,0 +1,128 @@ +-- START OF SOURCE -- +foo = function() return end +foo = function(x,y) return end +foo = function(...) return end +foo = function(...) local bar = ... return end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: function + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=1 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: function + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'x' + new_localvar: 'x' + str_checkname: 'y' + new_localvar: 'y' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=2 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: function + open_func + body: begin + body: parlist + parlist: begin + parlist: ... (dots) + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'return' line=3 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: function + open_func + body: begin + body: parlist + parlist: begin + parlist: ... (dots) + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'local' line=4 + local_stat: local statement + localstat: begin + str_checkname: 'bar' + new_localvar: 'bar' + localstat: -- assignment + explist1: begin + expr: + simpleexp: ... + explist1: end + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'return' line=4 + return_stat: no return values + -- STATEMENT: end 'return' + body: end + close_func + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_17.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_17.lua new file mode 100644 index 0000000..fadc7f9 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_17.lua @@ -0,0 +1,110 @@ +-- START OF SOURCE -- +foo = {} +foo = { 1,2,3; "foo"; } +foo = { bar=77, baz=88, } +foo = { ["bar"]=77, ["baz"]=88, } +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: constructor + constructor: begin + constructor: end + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: constructor + constructor: begin + listfield: expr + expr: + simpleexp: =1 + listfield: expr + expr: + simpleexp: =2 + listfield: expr + expr: + simpleexp: =3 + listfield: expr + expr: + simpleexp: =foo + codestring: "foo" + constructor: end + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: constructor + constructor: begin + recfield: name + checkname: + str_checkname: 'bar' + codestring: "bar" + expr: + simpleexp: =77 + recfield: name + checkname: + str_checkname: 'baz' + codestring: "baz" + expr: + simpleexp: =88 + constructor: end + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: constructor + constructor: begin + recfield: [ exp1 ] + index: begin '[' + expr: + simpleexp: =bar + codestring: "bar" + index: end ']' + expr: + simpleexp: =77 + recfield: [ exp1 ] + index: begin '[' + expr: + simpleexp: =baz + codestring: "baz" + index: end ']' + expr: + simpleexp: =88 + constructor: end + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_18.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_18.lua new file mode 100644 index 0000000..732b4d6 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_18.lua @@ -0,0 +1,26 @@ +-- START OF SOURCE -- + print(a) +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'expr' line=1 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VGLOBAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_19.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_19.lua new file mode 100644 index 0000000..9863b4a --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_19.lua @@ -0,0 +1,35 @@ +-- START OF SOURCE -- + local a + print(a) +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'a' + new_localvar: 'a' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_20.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_20.lua new file mode 100644 index 0000000..bc37280 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_20.lua @@ -0,0 +1,64 @@ +-- START OF SOURCE -- + do + local a + print(a) + end + print(a) +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'local' line=2 + local_stat: local statement + localstat: begin + str_checkname: 'a' + new_localvar: 'a' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VGLOBAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_21.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_21.lua new file mode 100644 index 0000000..b2bac4b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_21.lua @@ -0,0 +1,77 @@ +-- START OF SOURCE -- + local a,b,c + do + local b + print(b) + end + print(b) +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'a' + new_localvar: 'a' + str_checkname: 'b' + new_localvar: 'b' + str_checkname: 'c' + new_localvar: 'c' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'do' line=2 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'local' line=3 + local_stat: local statement + localstat: begin + str_checkname: 'b' + new_localvar: 'b' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'b' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'b' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_22.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_22.lua new file mode 100644 index 0000000..6885f01 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_22.lua @@ -0,0 +1,43 @@ +-- START OF SOURCE -- + local function foo() end + bar = foo +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + new_localvar: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_23.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_23.lua new file mode 100644 index 0000000..eb658ed --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_23.lua @@ -0,0 +1,70 @@ +-- START OF SOURCE -- + do + local function foo() end + bar = foo + end + baz = foo +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'do' line=1 + do_stat: begin + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'local' line=2 + local_stat: local function + localfunc: begin + str_checkname: 'foo' + new_localvar: 'foo' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + leaveblock + block: end + do_stat: end + -- STATEMENT: end 'do' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_24.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_24.lua new file mode 100644 index 0000000..6403234 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_24.lua @@ -0,0 +1,84 @@ +-- START OF SOURCE -- + local foo + local function bar() + baz = nil + foo = bar() + end + foo = bar +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + new_localvar: 'foo' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=2 + local_stat: local function + localfunc: begin + str_checkname: 'bar' + new_localvar: 'bar' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VGLOBAL' + expr_stat: assignment k='VGLOBAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + simpleexp: nil + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=4 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VUPVAL' + expr_stat: assignment k='VUPVAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VUPVAL' + primaryexp: ( funcargs + funcargs: begin '(' + funcargs: end -- expr is a VCALL + explist1: end + -- STATEMENT: end 'expr' + + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_25.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_25.lua new file mode 100644 index 0000000..594e267 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_25.lua @@ -0,0 +1,159 @@ +-- START OF SOURCE -- + local foo + local function bar() + local function baz() + local foo, bar + foo = bar + foo = baz + end + foo = bar + foo = baz + end + foo = bar + foo = baz +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + new_localvar: 'foo' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'local' line=2 + local_stat: local function + localfunc: begin + str_checkname: 'bar' + new_localvar: 'bar' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'local' line=3 + local_stat: local function + localfunc: begin + str_checkname: 'baz' + new_localvar: 'baz' + localfunc: body + open_func + body: begin + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'local' line=4 + local_stat: local statement + localstat: begin + str_checkname: 'foo' + new_localvar: 'foo' + str_checkname: 'bar' + new_localvar: 'bar' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=6 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VUPVAL' + explist1: end + -- STATEMENT: end 'expr' + + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=8 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VUPVAL' + expr_stat: assignment k='VUPVAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VUPVAL' + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=9 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VUPVAL' + expr_stat: assignment k='VUPVAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + body: end + close_func + localfunc: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'expr' line=11 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VLOCAL' + explist1: end + -- STATEMENT: end 'expr' + + -- STATEMENT: begin 'expr' line=12 + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + expr_stat: assignment k='VLOCAL' + assignment: '=' -- RHS elements follows + explist1: begin + expr: + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VGLOBAL' + explist1: end + -- STATEMENT: end 'expr' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_26.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_26.lua new file mode 100644 index 0000000..bfa3920 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_26.lua @@ -0,0 +1,53 @@ +-- START OF SOURCE -- + function foo:bar() + print(self) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: -- ':' field + field: operator=: + checkname: + str_checkname: 'bar' + codestring: "bar" + funcname: end + function_stat: body needself='true' + open_func + body: begin + new_localvar: 'self' + body: parlist + parlist: begin + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'self' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_27.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_27.lua new file mode 100644 index 0000000..77db3ef --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_27.lua @@ -0,0 +1,48 @@ +-- START OF SOURCE -- + function foo(...) + print(arg) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + parlist: ... (dots) + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'arg' + singlevar(kind): 'VGLOBAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_28.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_28.lua new file mode 100644 index 0000000..e4c9e21 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_28.lua @@ -0,0 +1,79 @@ +-- START OF SOURCE -- + local c,d + function foo(a,b,c) + print(a,c,d,e) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'local' line=1 + local_stat: local statement + localstat: begin + str_checkname: 'c' + new_localvar: 'c' + str_checkname: 'd' + new_localvar: 'd' + localstat: end + -- STATEMENT: end 'local' + + -- STATEMENT: begin 'function' line=2 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'a' + new_localvar: 'a' + str_checkname: 'b' + new_localvar: 'b' + str_checkname: 'c' + new_localvar: 'c' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'c' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'd' + singlevar(kind): 'VUPVAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'e' + singlevar(kind): 'VGLOBAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_29.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_29.lua new file mode 100644 index 0000000..b278ba2 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_29.lua @@ -0,0 +1,94 @@ +-- START OF SOURCE -- + function foo(a,b) + local bar = function(c,d) + print(a,b,c,d) + end + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'function' line=1 + function_stat: begin + funcname: begin + str_checkname: 'foo' + singlevar(kind): 'VGLOBAL' + funcname: end + function_stat: body needself='false' + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'a' + new_localvar: 'a' + str_checkname: 'b' + new_localvar: 'b' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'local' line=2 + local_stat: local statement + localstat: begin + str_checkname: 'bar' + new_localvar: 'bar' + localstat: -- assignment + explist1: begin + expr: + simpleexp: function + open_func + body: begin + body: parlist + parlist: begin + str_checkname: 'c' + new_localvar: 'c' + str_checkname: 'd' + new_localvar: 'd' + parlist: end + body: chunk + chunk: + -- STATEMENT: begin 'expr' line=3 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'a' + singlevar(kind): 'VUPVAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'b' + singlevar(kind): 'VUPVAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'c' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'd' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + body: end + close_func + explist1: end + localstat: end + -- STATEMENT: end 'local' + + body: end + close_func + function_stat: end + -- STATEMENT: end 'function' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_30.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_30.lua new file mode 100644 index 0000000..3807d14 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_30.lua @@ -0,0 +1,119 @@ +-- START OF SOURCE -- + for i = 1,10 do + print(i) + end + for i = 1,10,-2 do + print(i) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'for' line=1 + for_stat: begin + enterblock(isbreakable=true) + str_checkname: 'i' + for_stat: numerical loop + new_localvar: '(for index)' + new_localvar: '(for limit)' + new_localvar: '(for step)' + new_localvar: 'i' + fornum: begin + fornum: index start + exp1: begin + expr: + simpleexp: =1 + exp1: end + fornum: index stop + exp1: begin + expr: + simpleexp: =10 + exp1: end + fornum: body + enterblock(isbreakable=false) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'i' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + fornum: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=4 + for_stat: begin + enterblock(isbreakable=true) + str_checkname: 'i' + for_stat: numerical loop + new_localvar: '(for index)' + new_localvar: '(for limit)' + new_localvar: '(for step)' + new_localvar: 'i' + fornum: begin + fornum: index start + exp1: begin + expr: + simpleexp: =1 + exp1: end + fornum: index stop + exp1: begin + expr: + simpleexp: =10 + exp1: end + fornum: index step + exp1: begin + expr: + subexpr: uop='-' + simpleexp: =2 + exp1: end + fornum: body + enterblock(isbreakable=false) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'i' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + fornum: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_31.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_31.lua new file mode 100644 index 0000000..0d0a602 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/parser_log/sample_31.lua @@ -0,0 +1,127 @@ +-- START OF SOURCE -- + for foo in bar() do + print(foo) + end + for foo,bar,baz in spring() do + print(foo,bar,baz) + end +-- END OF SOURCE -- + +-- TOP: begin + open_func + + chunk: + -- STATEMENT: begin 'for' line=1 + for_stat: begin + enterblock(isbreakable=true) + str_checkname: 'foo' + for_stat: list-based loop + forlist: begin + new_localvar: '(for generator)' + new_localvar: '(for state)' + new_localvar: '(for control)' + new_localvar: 'foo' + forlist: explist1 + explist1: begin + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + funcargs: end -- expr is a VCALL + explist1: end + forlist: body + enterblock(isbreakable=false) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=2 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + forlist: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + -- STATEMENT: begin 'for' line=4 + for_stat: begin + enterblock(isbreakable=true) + str_checkname: 'foo' + for_stat: list-based loop + forlist: begin + new_localvar: '(for generator)' + new_localvar: '(for state)' + new_localvar: '(for control)' + new_localvar: 'foo' + str_checkname: 'bar' + new_localvar: 'bar' + str_checkname: 'baz' + new_localvar: 'baz' + forlist: explist1 + explist1: begin + expr: + prefixexp: + str_checkname: 'spring' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + funcargs: end -- expr is a VCALL + explist1: end + forlist: body + enterblock(isbreakable=false) + block: begin + enterblock(isbreakable=false) + chunk: + -- STATEMENT: begin 'expr' line=5 + prefixexp: + str_checkname: 'print' + singlevar(kind): 'VGLOBAL' + primaryexp: ( funcargs + funcargs: begin '(' + explist1: begin + expr: + prefixexp: + str_checkname: 'foo' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'bar' + singlevar(kind): 'VLOCAL' + explist1: ',' -- continuation + expr: + prefixexp: + str_checkname: 'baz' + singlevar(kind): 'VLOCAL' + explist1: end + funcargs: end -- expr is a VCALL + expr_stat: function call k='VCALL' + -- STATEMENT: end 'expr' + + leaveblock + block: end + leaveblock + forlist: end + leaveblock + for_stat: end + -- STATEMENT: end 'for' + + close_func +-- TOP: end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_llex_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_llex_mk2.lua new file mode 100644 index 0000000..e9ad45f --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_llex_mk2.lua @@ -0,0 +1,566 @@ +--[[-------------------------------------------------------------------- + + test_llex_mk2.lua + Test for llex_mk2.lua + This file is part of Yueliang. + + Copyright (c) 2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- if BRIEF is not set to false, auto-test will silently succeed +------------------------------------------------------------------------ +BRIEF = true -- if set to true, messages are less verbose + +package.path = "../?.lua;"..package.path +local llex = require "llex_mk2" + +------------------------------------------------------------------------ +-- simple manual tests +------------------------------------------------------------------------ + +--[[ +local function dump(z) + llex.init(z) + while true do + local token, seminfo = llex.llex() + if token == "" then + seminfo = " "..seminfo + elseif token == "" then + seminfo = " "..seminfo + elseif token == "" then + seminfo = " '"..seminfo.."'" + else + seminfo = "" + end + io.stdout:write(token..seminfo.."\n") + if token == "" then break end + end +end + +dump("local c = luaZ:zgetc(z)") +os.exit() +--]] + +------------------------------------------------------------------------ +-- auto-testing of simple test cases to validate lexer behaviour: +-- * NOTE coverage has not been checked; not comprehensive +-- * only test cases with non-empty comments are processed +-- * if no result, then the output is displayed for manual decision +-- (output may be used to set expected success or fail text) +-- * cases expected to be successful may be a partial match +-- * cases expected to fail may also be a partial match +------------------------------------------------------------------------ + +-- [=====[ +local function auto_test() + local PASS, FAIL = true, false + ------------------------------------------------------------------ + -- table of test cases + ------------------------------------------------------------------ + local test_cases = + { + ------------------------------------------------------------- + --{ "comment", -- comment about the test + -- "chunk", -- chunk to test + -- PASS, -- PASS or FAIL outcome + -- "output", -- output to compare against + --}, + ------------------------------------------------------------- + { "empty chunk string, test EOS", + "", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "line number counting", + "\n\n\r\n", + PASS, "4 ", + }, + ------------------------------------------------------------- + { "various whitespaces", + " \n\t\t\n \t \t \n\n", + PASS, "5 ", + }, + ------------------------------------------------------------- + { "short comment ending in EOS", + "-- moo moo", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "short comment ending in newline", + "-- moo moo\n", + PASS, "2 ", + }, + ------------------------------------------------------------- + { "several lines of short comments", + "--moo\n-- moo moo\n\n--\tmoo\n", + PASS, "5 ", + }, + ------------------------------------------------------------- + { "basic block comment 1", + "--[[bovine]]", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "basic block comment 2", + "--[=[bovine]=]", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "basic block comment 3", + "--[====[-[[bovine]]-]====]", + PASS, "1 ", + }, + ------------------------------------------------------------- + { "unterminated block comment 1", + "--[[bovine", + FAIL, ":1: unfinished long comment", + }, + ------------------------------------------------------------- + { "unterminated block comment 2", + "--[==[bovine", + FAIL, ":1: unfinished long comment", + }, + ------------------------------------------------------------- + { "unterminated block comment 3", + "--[[bovine]", + FAIL, ":1: unfinished long comment", + }, + ------------------------------------------------------------- + { "unterminated block comment 4", + "--[[bovine\nmoo moo\nwoof", + FAIL, ":3: unfinished long comment", + }, + ------------------------------------------------------------- + { "basic long string 1", + "\n[[bovine]]\n", + PASS, "2 = bovine\n3 ", + }, + ------------------------------------------------------------- + { "basic long string 2", + "\n[=[bovine]=]\n", + PASS, "2 = bovine\n3 ", + }, + ------------------------------------------------------------- + { "first newline consumed in long string", + "[[\nmoo]]", + PASS, "2 = moo\n2 ", + }, + ------------------------------------------------------------- + { "multiline long string 1", + "[[moo\nmoo moo\n]]", + PASS, "3 = moo\nmoo moo\n\n3 ", + }, + ------------------------------------------------------------- + { "multiline long string 2", + "[===[moo\n[=[moo moo]=]\n]===]", + PASS, "3 = moo\n[=[moo moo]=]\n\n3 ", + }, + ------------------------------------------------------------- + { "unterminated long string 1", + "\n[[\nbovine", + FAIL, ":3: unfinished long string", + }, + ------------------------------------------------------------- + { "unterminated long string 2", + "[[bovine]", + FAIL, ":1: unfinished long string", + }, + ------------------------------------------------------------- + { "unterminated long string 2", + "[==[bovine]==", + FAIL, ":1: unfinished long string", + }, + ------------------------------------------------------------- + { "complex long string 1", + "[=[moo[[moo]]moo]=]", + PASS, "moo[[moo]]moo", + }, + ------------------------------------------------------------- + { "complex long string 2", + "[=[moo[[moo[[[[]]]]moo]]moo]=]", + PASS, "moo[[moo[[[[]]]]moo]]moo", + }, + ------------------------------------------------------------- + { "complex long string 3", + "[=[[[[[]]]][[[[]]]]]=]", + PASS, "[[[[]]]][[[[]]]]", + }, + ------------------------------------------------------------- + -- NOTE: this native lexer does not support compatible long + -- strings (LUA_COMPAT_LSTR) + ------------------------------------------------------------- + --{ "deprecated long string 1", + -- "[[moo[[moo]]moo]]", + -- FAIL, ":1: nesting of [[...]] is deprecated near '['", + --}, + --------------------------------------------------------------- + --{ "deprecated long string 2", + -- "[[[[ \n", + -- FAIL, ":1: nesting of [[...]] is deprecated near '['", + --}, + --------------------------------------------------------------- + --{ "deprecated long string 3", + -- "[[moo[[moo[[[[]]]]moo]]moo]]", + -- FAIL, ":1: nesting of [[...]] is deprecated near '['", + --}, + --------------------------------------------------------------- + --{ "deprecated long string 4", + -- "[[[[[[]]]][[[[]]]]]]", + -- FAIL, ":1: nesting of [[...]] is deprecated near '['", + --}, + ------------------------------------------------------------- + { "brackets in long strings 1", + "[[moo[moo]]", + PASS, "moo[moo", + }, + ------------------------------------------------------------- + { "brackets in long strings 2", + "[=[moo[[moo]moo]]moo]=]", + PASS, "moo[[moo]moo]]moo", + }, + ------------------------------------------------------------- + { "unprocessed escapes in long strings", + [[ [=[\a\b\f\n\r\t\v\123]=] ]], + PASS, [[\a\b\f\n\r\t\v\123]], + }, + ------------------------------------------------------------- + { "unbalanced long string", + "[[moo]]moo]]", + PASS, "1 = moo\n1 = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 ", + }, + ------------------------------------------------------------- + { "keywords 1", + "and break do else", + PASS, "1 and\n1 break\n1 do\n1 else\n1 ", + }, + ------------------------------------------------------------- + { "keywords 2", + "elseif end false for", + PASS, "1 elseif\n1 end\n1 false\n1 for\n1 ", + }, + ------------------------------------------------------------- + { "keywords 3", + "function if in local nil", + PASS, "1 function\n1 if\n1 in\n1 local\n1 nil\n1 ", + }, + ------------------------------------------------------------- + { "keywords 4", + "not or repeat return", + PASS, "1 not\n1 or\n1 repeat\n1 return\n1 ", + }, + ------------------------------------------------------------- + { "keywords 5", + "then true until while", + PASS, "1 then\n1 true\n1 until\n1 while\n1 ", + }, + ------------------------------------------------------------- + { "concat and dots", + ".. ...", + PASS, "1 ..\n1 ...\n1 ", + }, + ------------------------------------------------------------- + -- NOTE: in Lua 5.1.x, shbang handling is no longer performed + -- in the lexer; it is now done in lauxlib.c (luaL_loadfile) + -- so the following cannot be performed by the lexer... + ------------------------------------------------------------- + --{ "shbang handling 1", + -- "#blahblah", + -- PASS, "1 ", + --}, + ------------------------------------------------------------- + --{ "shbang handling 2", + -- "#blahblah\nmoo moo\n", + -- PASS, "2 = moo\n2 = moo\n3 ", + --}, + ------------------------------------------------------------- + { "empty string", + [['']], + PASS, "1 = \n1 ", + }, + ------------------------------------------------------------- + { "single-quoted string", + [['bovine']], + PASS, "1 = bovine\n1 ", + }, + ------------------------------------------------------------- + { "double-quoted string", + [["bovine"]], + PASS, "1 = bovine\n1 ", + }, + ------------------------------------------------------------- + { "unterminated string 1", + [['moo ]], + FAIL, ":1: unfinished string", + }, + ------------------------------------------------------------- + { "unterminated string 2", + [["moo \n]], + FAIL, ":1: unfinished string", + }, + ------------------------------------------------------------- + { "escaped newline in string, line number counted", + "\"moo\\\nmoo\\\nmoo\"", + PASS, "3 = moo\nmoo\nmoo\n3 ", + }, + ------------------------------------------------------------- + { "escaped characters in string 1", + [["moo\amoo"]], + PASS, "1 = moo\amoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 2", + [["moo\bmoo"]], + PASS, "1 = moo\bmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 3", + [["moo\f\n\r\t\vmoo"]], + PASS, "1 = moo\f\n\r\t\vmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 4", + [["\\ \" \' \? \[ \]"]], + PASS, "1 = \\ \" \' \? \[ \]", + }, + ------------------------------------------------------------- + { "escaped characters in string 5", + [["\z \k \: \;"]], + PASS, "1 = z k : ;", + }, + ------------------------------------------------------------- + { "escaped characters in string 6", + [["\8 \65 \160 \180K \097097"]], + PASS, "1 = \8 \65 \160 \180K \097097\n", + }, + ------------------------------------------------------------- + { "escaped characters in string 7", + [["\666"]], + FAIL, ":1: escape sequence too large", + }, + ------------------------------------------------------------- + { "simple numbers", + "123 123+", + PASS, "1 = 123\n1 = 123\n1 CHAR = '+'\n1 ", + }, + ------------------------------------------------------------- + { "longer numbers", + "1234567890 12345678901234567890", + PASS, "1 = 1234567890\n1 = 1.2345678901235e+19\n", + }, + ------------------------------------------------------------- + { "fractional numbers", + ".123 .12345678901234567890", + PASS, "1 = 0.123\n1 = 0.12345678901235\n", + }, + ------------------------------------------------------------- + { "more numbers with decimal points", + "12345.67890", + PASS, "1 = 12345.6789\n", + }, + ------------------------------------------------------------- + { "malformed number with decimal points", + "1.1.", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "double decimal points", + ".1.1", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "double dots within numbers", + "1..1", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "incomplete exponential numbers", + "123e", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "exponential numbers 1", + "1234e5 1234e5.", + PASS, "1 = 123400000\n1 = 123400000\n1 CHAR = '.'", + }, + ------------------------------------------------------------- + { "exponential numbers 2", + "1234e56 1.23e123", + PASS, "1 = 1.234e+59\n1 = 1.23e+123\n", + }, + ------------------------------------------------------------- + { "exponential numbers 3", + "12.34e+", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "exponential numbers 4", + "12.34e+5 123.4e-5 1234.E+5", + PASS, "1 = 1234000\n1 = 0.001234\n1 = 123400000\n", + }, + ------------------------------------------------------------- + { "hexadecimal numbers", + "0x00FF 0X1234 0xDEADBEEF", + PASS, "1 = 255\n1 = 4660\n1 = 3735928559\n", + }, + ------------------------------------------------------------- + { "invalid hexadecimal numbers 1", + "0xFOO", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "invalid hexadecimal numbers 2", + "0.BAR", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "invalid hexadecimal numbers 3", + "0BAZ", + FAIL, ":1: malformed number", + }, + ------------------------------------------------------------- + { "single character symbols 1", + "= > < ~ #", + PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n1 CHAR = '#'\n", + }, + ------------------------------------------------------------- + { "double character symbols", + "== >= <= ~=", + PASS, "1 ==\n1 >=\n1 <=\n1 ~=\n", + }, + ------------------------------------------------------------- + { "simple identifiers", + "abc ABC", + PASS, "1 = abc\n1 = ABC\n1 ", + }, + ------------------------------------------------------------- + { "more identifiers", + "_abc _ABC", + PASS, "1 = _abc\n1 = _ABC\n1 ", + }, + ------------------------------------------------------------- + { "still more identifiers", + "_aB_ _123", + PASS, "1 = _aB_\n1 = _123\n1 ", + }, + ------------------------------------------------------------- + -- NOTE: in Lua 5.1.x, this test is no longer performed + ------------------------------------------------------------- + --{ "invalid control character", + -- "\4", + -- FAIL, ":1: invalid control char near 'char(4)'", + --}, + ------------------------------------------------------------- + { "single character symbols 2", + "` ! @ $ %", + PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", + }, + ------------------------------------------------------------- + { "single character symbols 3", + "^ & * ( )", + PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", + }, + ------------------------------------------------------------- + { "single character symbols 4", + "_ - + \\ |", + PASS, "1 = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", + }, + ------------------------------------------------------------- + { "single character symbols 5", + "{ } [ ] :", + PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", + }, + ------------------------------------------------------------- + { "single character symbols 6", + "; , . / ?", + PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", + }, + ------------------------------------------------------------- + } + ------------------------------------------------------------------ + -- perform a test case + ------------------------------------------------------------------ + function do_test_case(count, test_case) + if comment == "" then return end -- skip empty entries + local comment, chunk, outcome, matcher = unpack(test_case) + local result = PASS + local output = "" + -- initialize lexer + llex.init(chunk, "=test") + -- lexer test loop + repeat + -- protected call + local status, token, seminfo = pcall(llex.llex) + output = output..llex.ln.." " + if status then + -- successful call + if #token > 1 then + if token == "" + or token == "" + or token == "" then + token = token.." = "..seminfo + end + elseif string.byte(token) >= 32 then -- displayable chars + token = "CHAR = '"..token.."'" + else -- control characters + token = "CHAR = (".. string.byte(token)..")" + end + output = output..token.."\n" + else + -- failed call + output = output..token -- token is the error message + result = FAIL + break + end + until token == "" + -- decision making and reporting + local head = "Test "..count..": "..comment + if matcher == "" then + -- nothing to check against, display for manual check + print(head.."\nMANUAL please check manually".. + "\n--chunk---------------------------------\n"..chunk.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + return + else + if outcome == PASS then + -- success expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == PASS then + if not BRIEF then print(head.."\nOK expected success\n") end + return + end + else + -- failure expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == FAIL then + if not BRIEF then print(head.."\nOK expected failure\n") end + return + end + end + -- failed because of unmatched string or boolean result + local function passfail(status) + if status == PASS then return "PASS" else return "FAIL" end + end + print(head.." *FAILED*".. + "\noutcome="..passfail(outcome).. + "\nactual= "..passfail(result).. + "\n--chunk---------------------------------\n"..chunk.. + "\n--expected------------------------------\n"..matcher.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + end + end + ------------------------------------------------------------------ + -- perform auto testing + ------------------------------------------------------------------ + for i,test_case in ipairs(test_cases) do + do_test_case(i, test_case) + end +end + +auto_test() +--]=====] diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_lparser_mk2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_lparser_mk2.lua new file mode 100644 index 0000000..11f2827 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_lparser_mk2.lua @@ -0,0 +1,329 @@ +--[[-------------------------------------------------------------------- + + test_lparser_mk2.lua + Test for lparser_mk2.lua + This file is part of Yueliang. + + Copyright (c) 2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +package.path = "../?.lua;"..package.path +local llex = require "llex_mk2" +local lparser = require "lparser_mk2" + +------------------------------------------------------------------------ +-- dump contents of log table +------------------------------------------------------------------------ + +local function dump_log(fs) + local log = fs.log + for i = 1, #log do + print(log[i]) + end +end + +------------------------------------------------------------------------ +-- try 1 +------------------------------------------------------------------------ + +--[=[ +llex.init("local a = 1", "=string") +lparser.init(llex) +-- nothing is returned, so hope there is an error if problem occurs +local fs = lparser.parser() +dump_log(fs) +--]=] + +------------------------------------------------------------------------ +-- try 2 +------------------------------------------------------------------------ + +-- a slightly larger sample +--[=[ +llex.init([[ +local a = 47 +local b = "hello, world!" +print(a, b) +]], "@sample.lua") +lparser.init(llex) +-- nothing is returned, so hope there is an error if problem occurs +local fs = lparser.parser() +dump_log(fs) +--]=] + +------------------------------------------------------------------------ +-- automatic dumper of output log data +------------------------------------------------------------------------ + +local test_case = { +-- 1 attempts to exercise most parts, extent of coverage not known +[[ +]], +-- 2 +[[ +-- foobar +]], +-- 3 +[[ +do +end +]], +-- 4 +[[ +do end +do end +]], +-- 5 +[[ +foo() +foo{} +foo"" +foo:bar() +foo=false +foo.bar=true +foo[true]=nil +foo,bar=1,"a" +]], +-- 6 +[[ +foo=true +foo=false +foo=nil +foo=1.23e45 +foo=-1 +foo=(0) +foo=1+2 +foo=1+2*3-4/5 +]], +-- 7 +[[ +if foo then foo=1 end +if foo then foo=1 else foo=0 end +if foo then foo=1 elseif not foo then foo=0 end +]], +-- 8 +[[ +do return end +do return 123 end +do return "foo","bar" end +]], +-- 9 +[[ +while true do foo=not foo end +while foo~=42 do foo=foo-1 end +while true do break end +]], +-- 10 +[[ +repeat foo=foo.."bar" until false +repeat foo=foo/2 until foo<1 +repeat break until false +]], +-- 11 +[[ +for i=1,10 do foo=i end +for i=1,10,2 do break end +for i in foo do bar=0 end +for i,j in foo,bar do baz=0 end +]], +-- 12 +[[ +local foo +local foo,bar,baz +local foo,bar="foo","bar" +]], +-- 13 +[[ +local function foo() return end +local function foo(a) return end +local function foo(x,y,z) return end +local function foo(x,...) return end +]], +-- 14 +[[ +function foo() return end +function foo(a) return end +function foo(x,y,z) return end +function foo(x,...) return end +]], +-- 15 +[[ +function foo.bar(p) return end +function foo.bar.baz(p) return end +function foo:bar(p) return end +function foo.bar.baz(p) return end +]], +-- 16 +[[ +foo = function() return end +foo = function(x,y) return end +foo = function(...) return end +foo = function(...) local bar = ... return end +]], +-- 17 +[[ +foo = {} +foo = { 1,2,3; "foo"; } +foo = { bar=77, baz=88, } +foo = { ["bar"]=77, ["baz"]=88, } +]], +-- 18 simple tests for variable management follows +[[ + print(a) +]], +-- 19 +[[ + local a + print(a) +]], +-- 20 +[[ + do + local a + print(a) + end + print(a) +]], +-- 21 +[[ + local a,b,c + do + local b + print(b) + end + print(b) +]], +-- 22 +[[ + local function foo() end + bar = foo +]], +-- 23 +[[ + do + local function foo() end + bar = foo + end + baz = foo +]], +-- 24 +[[ + local foo + local function bar() + baz = nil + foo = bar() + end + foo = bar +]], +-- 25 +[[ + local foo + local function bar() + local function baz() + local foo, bar + foo = bar + foo = baz + end + foo = bar + foo = baz + end + foo = bar + foo = baz +]], +-- 26 +[[ + function foo:bar() + print(self) + end +]], +-- 27 +[[ + function foo(...) + print(arg) + end +]], +-- 28 +[[ + local c,d + function foo(a,b,c) + print(a,c,d,e) + end +]], +-- 29 +[[ + function foo(a,b) + local bar = function(c,d) + print(a,b,c,d) + end + end +]], +-- 30 +[[ + for i = 1,10 do + print(i) + end + for i = 1,10,-2 do + print(i) + end +]], +-- 31 +[[ + for foo in bar() do + print(foo) + end + for foo,bar,baz in spring() do + print(foo,bar,baz) + end +]], +} + +-- helps to skip old stuff during development of snippets +local do_beg, do_end = 1, #test_case + +-- loop for all example snippets +for i = do_beg, do_end do + local fname = "parser_log/sample_"..string.format("%02d", i)..".lua" + local src = test_case[i] + local OUTF = io.open(fname, "wb") + if not OUTF then error("failed to write to file '"..fname.."'") end + -- write out actual source for comparison + OUTF:write( + "-- START OF SOURCE --\n".. + src.. + "-- END OF SOURCE --\n".. + "\n" + ) + -- attempt to parse + llex.init(src, "=string") + lparser.init(llex) + local fs = lparser.parser() + -- grab logged messages and write + local log = fs.log + local indent = 0 + for i = 1, #log do + local ln = log[i] + -- handle indentation + local tag = string.sub(ln, 1, 2) + if tag == ">>" or tag == "<<" then + ln = string.sub(ln, 4) + end + if tag == ">>" then + indent = indent + 1 + end + OUTF:write(string.rep(" ", indent)..ln.."\n") + if tag == "<<" then + indent = indent - 1 + end + end + -- we're done + OUTF:close() +end diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_lparser_mk2_2.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_lparser_mk2_2.lua new file mode 100644 index 0000000..c135a8c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/nat-5.1.3/test/test_lparser_mk2_2.lua @@ -0,0 +1,159 @@ +--[[-------------------------------------------------------------------- + + test_lparser_mk2_2.lua + Test for lparser_mk2.lua, using the test case file + This file is part of Yueliang. + + Copyright (c) 2006-2008 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * unlike the equivalent in the orig-5.1.3/ directory, this version +-- tests only parsing, lparser_mk3 cannot generate binary chunks +-- * the test cases are in the test_lua directory (test_parser-5.1.lua) +----------------------------------------------------------------------]] + +-- * true if you want an output of all failure cases in native Lua, +-- for checking whether test cases fail where you intend them to +local DEBUG_FAILS = false + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +package.path = "../?.lua;"..package.path +local llex = require "llex_mk2" +local lparser = require "lparser_mk2" + +------------------------------------------------------------------------ +-- load test cases +------------------------------------------------------------------------ + +dofile("../../test_lua/test_parser-5.1.lua") + +local test, expect, heading = {}, {}, {} +local total, total_pass, total_fail = 0, 0, 0 + +for ln in string.gfind(tests_source, "([^\n]*)\n") do + if string.find(ln, "^%s*%-%-") then + -- comment, ignore + else + local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") + if m then + heading[total + 1] = head -- informational heading + else + total = total + 1 + local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") + if n then -- FAIL test case + ln = string.sub(ln, 1, n - 1) -- remove comment + expect[total] = "FAIL" + total_fail = total_fail + 1 + else -- PASS test case + expect[total] = "PASS" + total_pass = total_pass + 1 + end--n + test[total] = ln + end--m + end--ln +end--for + +print("Tests loaded: "..total.." (total), " + ..total_pass.." (passes), " + ..total_fail.." (fails)") + +------------------------------------------------------------------------ +-- verify test cases using native Lua +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then + last_head = head + if DEBUG_FAILS then print("\n"..head.."\n") end + end + ------------------------------------------------------------------ + -- perform test + local f, err = loadstring(test_case) + -- look at outcome + ------------------------------------------------------------------ + if f then-- actual PASS + if expected == "FAIL" then + print("\nVerified as PASS but expected to FAIL".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nVerified as FAIL but expected to PASS".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + print("ERROR: "..err) + os.exit() + end + if DEBUG_FAILS then + print("TEST: "..test_case) + print("ERROR: "..err.."\n") + end + ------------------------------------------------------------------ + end--f +end--for + +print("Test cases verified using native Lua, no anomalies.") + +------------------------------------------------------------------------ +-- test using Yueliang front end +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then last_head = head end + ------------------------------------------------------------------ + -- perform test + llex.init(test_case, "=test_sample") + lparser.init(llex) + + local status, func = pcall(lparser.parser) + -- look at outcome + ------------------------------------------------------------------ + if status then-- actual PASS + if expected == "FAIL" then + print("\nTested as PASS but expected to FAIL".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nTested as FAIL but expected to PASS".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + else + io.stdout:write("-") + end + ------------------------------------------------------------------ + end--status + io.stdout:write("\rTesting ["..i.."]...") +end--for +print(" done.") + +print("Test cases run on Yueliang, no anomalies.") + +-- end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/README b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/README new file mode 100644 index 0000000..e64bf50 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/README @@ -0,0 +1,51 @@ +orig-5.0.3 + +This is a straightforward port of the Lua 5.0.3 front end (lexical +analyzer, parser, code generator, binary chunk dumper.) + +The front end files are: + + lopcodes.lua opcode definition + lzio.lua input streams + llex.lua lexical analyzer + lparser.lua parser + lcode.lua code generator + ldump.lua binary chunk dumper + +Status: operational, passes all current tests (non-exhaustive) + +Major test scripts are: + + test/test_llex.lua exercises test cases + test/test_lparser2.lua exercises test cases + +luac.lua is a clone of Lua 5.0.3's luac.lua, except that it generates a +binary chunk using Yueliang's front end implementation. + +Note that performance is not a consideration. The code tries to stay +faithful to its C roots, so that if you were to do anything using this +codebase, backporting the changes to C will be easy. As such, this +codebase is meant for learning or prototyping purposes. + +Many parameters are unused, because call arguments are retained as far +as possible. Changes and deletions are described wherever possible, but +documentation of changes is not comprehensive. + +These files will stay faithful to the equivalent C files or modules in +Lua 5.0.3. For rewrites or new features, a new directory will be created +and a different set of files maintained. For Lua 5.1, a new directory +will be created. + +The test directory has several primitive test scripts. Much better +testing is planned. Eventually, the codebase will be validated using +automated tests, so that any changes that breaks the system can be +caught easily. + +The tools directory has a call graph generator, showing what gets +called. Specific modules and functions can be monitored, and some +parameters and return values are shown. This is a demonstration of the +flexibility and ease of manipulation of using a relatively inefficient +global table scheme. + +For Lua 5.0.2, see Yueliang 0.1.3, which was the last release of Lua +5.0.2 material. diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua new file mode 100644 index 0000000..c18dc08 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua @@ -0,0 +1,902 @@ +--[[-------------------------------------------------------------------- + + lcode.lua + Lua 5 code generator in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- 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, x) (from lobject.h) +-- luaK:setnvalue(o, x) (from lobject.h) +-- luaK:sethvalue(o, x) (from lobject.h) +----------------------------------------------------------------------]] + +-- requires luaP, luaX, luaY +luaK = {} + +------------------------------------------------------------------------ +-- 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 + +------------------------------------------------------------------------ +-- grep "ORDER OPR" if you change these enums +------------------------------------------------------------------------ +luaK.BinOpr = { + OPR_ADD = 0, OPR_SUB = 1, OPR_MULT = 2, OPR_DIV = 3, OPR_POW = 4, + OPR_CONCAT = 5, + OPR_NE = 6, OPR_EQ = 7, + OPR_LT = 8, OPR_LE = 9, OPR_GT = 10, OPR_GE = 11, + OPR_AND = 12, OPR_OR = 13, + OPR_NOBINOPR = 14, +} + +------------------------------------------------------------------------ +-- 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, x) o.value = x end +luaK.setnvalue = luaK.setsvalue +luaK.sethvalue = luaK.setsvalue + +------------------------------------------------------------------------ +-- * binopistest appears to be unused +-- * UnOpr is used by luaK:prefix's op argument +------------------------------------------------------------------------ +function luaK:binopistest(op) + return self.BinOpr[op] >= self.BinOpr["OPR_NE"] +end + +luaK.UnOpr = { + OPR_MINUS = 0, OPR_NOT = 1, OPR_NOUNOPR = 2 +} + +------------------------------------------------------------------------ +-- 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 + +------------------------------------------------------------------------ +-- there is a jump if patch lists are not identical +-- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val() +------------------------------------------------------------------------ +function luaK:hasjumps(e) + return e.t ~= e.f +end + +------------------------------------------------------------------------ +-- codes loading of nil, optimization done if consecutive locations +-- * used only in discharge2reg() +------------------------------------------------------------------------ +function luaK:_nil(fs, from, n) + if fs.pc > fs.lasttarget then -- no jumps to current position? + 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 + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:jumponcond(), luaK:codebinop() +------------------------------------------------------------------------ +function luaK:condjump(fs, op, A, B, C) + self:codeABC(fs, op, A, B, C) + return self:jump(fs) +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:patchlistaux(), luaK:concat() +------------------------------------------------------------------------ +function luaK:fixjump(fs, pc, dest) + local jmp = fs.f.code[pc] + local offset = dest - (pc + 1) + lua_assert(dest ~= self.NO_JUMP) + if math.abs(offset) > luaP.MAXARG_sBx then + luaX:syntaxerror(fs.ls, "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). +-- * used in multiple locations +-- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL +------------------------------------------------------------------------ +function luaK:getlabel(fs) + fs.lasttarget = fs.pc + return fs.pc +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:need_value(), luaK:patchlistaux(), luaK:concat() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:need_value(), luaK:patchlistaux(), luaK:invertjump() +------------------------------------------------------------------------ +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) +-- * used only in luaK:exp2reg() +------------------------------------------------------------------------ +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_TEST" 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 + +------------------------------------------------------------------------ +-- +-- * used only in luaK:patchlistaux() +------------------------------------------------------------------------ +function luaK:patchtestreg(i, reg) + if reg == luaP.NO_REG then reg = luaP:GETARG_B(i) end + luaP:SETARG_A(i, reg) +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:codenot() +------------------------------------------------------------------------ + +function luaK:removevalues(fs, list) + while list ~= self.NO_JUMP do + local i = self:getjumpcontrol(fs, list) + if luaP:GET_OPCODE(i) == "OP_TEST" then + self:patchtestreg(i, luaP.NO_REG) + end + list = self:getjump(fs, list) + end +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg() +------------------------------------------------------------------------ +function luaK:patchlistaux(fs, list, vtarget, reg, dtarget) + while list ~= self.NO_JUMP do + local _next = self:getjump(fs, list) + local i = self:getjumpcontrol(fs, list) + if luaP:GET_OPCODE(i) == "OP_TEST" and luaP:GETARG_A(i) == luaP.NO_REG then + self:patchtestreg(i, reg) + self:fixjump(fs, list, vtarget) + else + self:fixjump(fs, list, dtarget) -- jump to default target + end + list = _next + end +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:code() +------------------------------------------------------------------------ +function luaK:dischargejpc(fs) + self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc) + fs.jpc = self.NO_JUMP +end + +------------------------------------------------------------------------ +-- +-- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody() +------------------------------------------------------------------------ +function luaK:patchlist(fs, list, target) + if target == fs.pc then + self:patchtohere(fs, list) + else + lua_assert(target < fs.pc) + self:patchlistaux(fs, list, target, luaP.NO_REG, target) + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +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 +-- * used in multiple locations +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:reserveregs(), (lparser) luaY:forlist() +------------------------------------------------------------------------ +function luaK:checkstack(fs, n) + local newstack = fs.freereg + n + if newstack > fs.f.maxstacksize then + if newstack >= luaY.MAXSTACK then + luaX:syntaxerror(fs.ls, "function or expression too complex") + end + fs.f.maxstacksize = newstack + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:reserveregs(fs, n) + self:checkstack(fs, n) + fs.freereg = fs.freereg + n +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:freeexp(), luaK:dischargevars() +------------------------------------------------------------------------ +function luaK:freereg(fs, reg) + if reg >= fs.nactvar and reg < luaY.MAXSTACK then + fs.freereg = fs.freereg - 1 + lua_assert(reg == fs.freereg) + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:freeexp(fs, e) + if e.k == "VNONRELOC" then + self:freereg(fs, e.info) + end +end + +------------------------------------------------------------------------ +-- * 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 +-- * used in luaK:stringK(), luaK:numberK(), luaK:nil_constant() +------------------------------------------------------------------------ +function luaK:addk(fs, k, v) + local idx = fs.h[k.value] + if self:ttisnumber(idx) then + --TODO this assert currently FAILS, probably something wrong... + --lua_assert(fs.f.k[self:nvalue(idx)] == v) + return self:nvalue(idx) + else -- constant not found; create a new entry + local f = fs.f + luaY:growvector(fs.L, f.k, fs.nk, f.sizek, nil, + luaP.MAXARG_Bx, "constant table overflow") + f.k[fs.nk] = v -- setobj2n deleted + 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 + +------------------------------------------------------------------------ +-- creates and sets a string object +-- * used in (lparser) luaY:codestring(), luaY:singlevaraux() +------------------------------------------------------------------------ +function luaK:stringK(fs, s) + local o = {} -- TObject + self:setsvalue(o, s) + return self:addk(fs, o, o) +end + +------------------------------------------------------------------------ +-- creates and sets a number object +-- * used in luaK:prefix() for negative (or negation of) numbers +-- * used in (lparser) luaY:simpleexp(), luaY:fornum() +------------------------------------------------------------------------ +function luaK:numberK(fs, r) + local o = {} -- TObject + self:setnvalue(o, r) + return self:addk(fs, o, o) +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:exp2RK() +------------------------------------------------------------------------ +function luaK:nil_constant(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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:dischargevars() +-- * used in (lparser) luaY:adjust_assign(), luaY:lastlistfield(), +-- luaY:funcargs(), luaY:assignment(), luaY:exprstat(), luaY:retstat() +------------------------------------------------------------------------ +function luaK:setcallreturns(fs, e, nresults) + 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 + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:dischargevars(fs, e) + 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" then + self:setcallreturns(fs, e, 1) + else + -- there is one value available (somewhere) + end +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:exp2reg() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:discharge2anyreg(), luaK:exp2reg() +------------------------------------------------------------------------ +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 == "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 + lua_assert(e.k == "VVOID" or e.k == "VJMP") + return -- nothing to do... + end + e.info = reg + e.k = "VNONRELOC" +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:jumponcond(), luaK:codenot() +------------------------------------------------------------------------ +function luaK:discharge2anyreg(fs, e) + if e.k ~= "VNONRELOC" then + self:reserveregs(fs, 1) + self:discharge2reg(fs, e, fs.freereg - 1) + end +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:exp2nextreg(fs, e) + self:dischargevars(fs, e) + self:freeexp(fs, e) + self:reserveregs(fs, 1) + self:exp2reg(fs, e, fs.freereg - 1) +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:exp2anyreg(fs, 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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix() +-- * used in (lparser) luaY:index() +------------------------------------------------------------------------ +function luaK:exp2val(fs, e) + if self:hasjumps(e) then + self:exp2anyreg(fs, e) + else + self:dischargevars(fs, e) + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:exp2RK(fs, e) + self:exp2val(fs, e) + local k = e.k + if k == "VNIL" then + if fs.nk + luaY.MAXSTACK <= luaP.MAXARG_C then -- constant fit in argC? + e.info = self:nil_constant(fs) + e.k = "VK" + return e.info + luaY.MAXSTACK + end + elseif k == "VK" then + if e.info + luaY.MAXSTACK <= luaP.MAXARG_C then -- constant fit in argC? + return e.info + luaY.MAXSTACK + end + end + -- not a constant in the right range: put it in a register + return self:exp2anyreg(fs, e) +end + +------------------------------------------------------------------------ +-- +-- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat() +------------------------------------------------------------------------ +function luaK:storevar(fs, var, 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 + 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 + lua_assert(0) -- invalid var kind to store + end + self:freeexp(fs, exp) +end + +------------------------------------------------------------------------ +-- +-- * used only in (lparser) luaY:primaryexp() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:goiftrue(), luaK:codenot() +------------------------------------------------------------------------ +function luaK:invertjump(fs, e) + local pc = self:getjumpcontrol(fs, e.info) + lua_assert(luaP:testOpMode(luaP:GET_OPCODE(pc), "OpModeT") and + luaP:GET_OPCODE(pc) ~= "OP_TEST") + luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0) +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:goiftrue(), luaK:goiffalse() +------------------------------------------------------------------------ +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), luaP:GETARG_B(ie), + cond and 0 or 1) + end + -- else go through + end + self:discharge2anyreg(fs, e) + self:freeexp(fs, e) + return self:condjump(fs, "OP_TEST", luaP.NO_REG, e.info, cond and 1 or 0) +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:infix(), (lparser) luaY:cond() +------------------------------------------------------------------------ +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" 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 +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:infix(), (lparser) luaY:whilestat() +------------------------------------------------------------------------ +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 +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:prefix() +------------------------------------------------------------------------ +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 == "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 + lua_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 + +------------------------------------------------------------------------ +-- +-- * used in (lparser) luaY:field(), luaY:primaryexp() +------------------------------------------------------------------------ +function luaK:indexed(fs, t, k) + t.aux = self:exp2RK(fs, k) + t.k = "VINDEXED" +end + +------------------------------------------------------------------------ +-- +-- * used only in (lparser) luaY:subexpr() +------------------------------------------------------------------------ +function luaK:prefix(fs, op, e) + if op == "OPR_MINUS" then + self:exp2val(fs, e) + if e.k == "VK" and self:ttisnumber(fs.f.k[e.info]) then + e.info = self:numberK(fs, -self:nvalue(fs.f.k[e.info])) + else + self:exp2anyreg(fs, e) + self:freeexp(fs, e) + e.info = self:codeABC(fs, "OP_UNM", 0, e.info, 0) + e.k = "VRELOCABLE" + end + else -- op == NOT + self:codenot(fs, e) + end +end + +------------------------------------------------------------------------ +-- +-- * used only in (lparser) luaY:subexpr() +------------------------------------------------------------------------ +function luaK:infix(fs, op, v) + if op == "OPR_AND" then + self:goiftrue(fs, v) + self:patchtohere(fs, v.t) + v.t = self.NO_JUMP + elseif op == "OPR_OR" then + self:goiffalse(fs, v) + self:patchtohere(fs, v.f) + v.f = self.NO_JUMP + elseif op == "OPR_CONCAT" then + self:exp2nextreg(fs, v) -- operand must be on the 'stack' + else + self:exp2RK(fs, v) + end +end + +------------------------------------------------------------------------ +-- +-- grep "ORDER OPR" if you change these enums +-- * used only in luaK:posfix() +------------------------------------------------------------------------ +luaK.arith_opc = { -- done as a table lookup instead of a calc + OPR_ADD = "OP_ADD", + OPR_SUB = "OP_SUB", + OPR_MULT = "OP_MUL", + OPR_DIV = "OP_DIV", + OPR_POW = "OP_POW", +} +luaK.test_opc = { -- was ops[] in the codebinop function + OPR_NE = "OP_EQ", + OPR_EQ = "OP_EQ", + OPR_LT = "OP_LT", + OPR_LE = "OP_LE", + OPR_GT = "OP_LT", + OPR_GE = "OP_LE", +} +function luaK:codebinop(fs, res, op, o1, o2) + if self.BinOpr[op] <= self.BinOpr["OPR_POW"] then -- arithmetic operator? + local opc = self.arith_opc[op] -- ORDER OP + res.info = self:codeABC(fs, opc, 0, o1, o2) + res.k = "VRELOCABLE" + else -- test operator + local cond = true + if self.BinOpr[op] >= self.BinOpr["OPR_GT"] then -- '>' or '>='? + -- exchange args and replace by '<' or '<=' + o1, o2 = o2, o1 -- o1 <==> o2 + elseif op == "OPR_NE" then + cond = false + end + res.info = self:condjump(fs, self.test_opc[op], cond and 1 or 0, o1, o2) + res.k = "VJMP" + end +end + +------------------------------------------------------------------------ +-- +-- * used only in (lparser) luaY:subexpr() +------------------------------------------------------------------------ +function luaK:posfix(fs, op, e1, e2) + if op == "OPR_AND" then + lua_assert(e1.t == self.NO_JUMP) -- list must be closed + self:dischargevars(fs, e2) + e1.f = self:concat(fs, e1.f, e2.f) + e1.k = e2.k; e1.info = e2.info; e1.aux = e2.aux; e1.t = e2.t + elseif op == "OPR_OR" then + lua_assert(e1.f == self.NO_JUMP) -- list must be closed + self:dischargevars(fs, e2) + e1.t = self:concat(fs, e1.t, e2.t) + e1.k = e2.k; e1.info = e2.info; e1.aux = e2.aux; e1.f = e2.f + elseif op == "OPR_CONCAT" then + self:exp2val(fs, e2) + if e2.k == "VRELOCABLE" + and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then + lua_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 = e2.k; e1.info = e2.info + else + self:exp2nextreg(fs, e2) + self:freeexp(fs, e2) + self:freeexp(fs, e1) + e1.info = self:codeABC(fs, "OP_CONCAT", 0, e1.info, e2.info) + e1.k = "VRELOCABLE" + end + else + local o1 = self:exp2RK(fs, e1) + local o2 = self:exp2RK(fs, e2) + self:freeexp(fs, e2) + self:freeexp(fs, e1) + self:codebinop(fs, e1, op, o1, o2) + end +end + +------------------------------------------------------------------------ +-- adjusts debug information for last instruction written, in order to +-- change the line where item comes into existence +-- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat() +------------------------------------------------------------------------ +function luaK:fixline(fs, line) + fs.f.lineinfo[fs.pc - 1] = line +end + +------------------------------------------------------------------------ +-- general function to write an instruction into the instruction buffer, +-- sets debug information too +-- * used in luaK:codeABC(), luaK:codeABx() +-- * called directly by (lparser) luaY:whilestat() +------------------------------------------------------------------------ +function luaK:code(fs, i, line) + local f = fs.f + self:dischargejpc(fs) -- 'pc' will change + -- put new instruction in code array + luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil, + luaY.MAX_INT, "code size overflow") + f.code[fs.pc] = i + -- save corresponding line information + luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil, + luaY.MAX_INT, "code size overflow") + f.lineinfo[fs.pc] = line + local pc = fs.pc + fs.pc = fs.pc + 1 + return pc +end + +------------------------------------------------------------------------ +-- writes an instruction of type ABC +-- * calls luaK:code() +------------------------------------------------------------------------ +function luaK:codeABC(fs, o, a, b, c) + lua_assert(luaP:getOpMode(o) == "iABC") + return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline) +end + +------------------------------------------------------------------------ +-- writes an instruction of type ABx +-- * calls luaK:code(), called by luaK:codeAsBx() +------------------------------------------------------------------------ +function luaK:codeABx(fs, o, a, bc) + lua_assert(luaP:getOpMode(o) == "iABx" or luaP:getOpMode(o) == "iAsBx") + return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline) +end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/ldump.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/ldump.lua new file mode 100644 index 0000000..1b3c608 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/ldump.lua @@ -0,0 +1,362 @@ +--[[-------------------------------------------------------------------- + + 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. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- 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) +----------------------------------------------------------------------]] + +--requires luaP +luaU = {} + +-- constants used by dumper +luaU.LUA_TNUMBER = 3 -- (all in lua.h) +luaU.LUA_TSTRING = 4 +luaU.LUA_TNIL = 0 +luaU.LUA_TNONE = -1 + +-- definitions for headers of binary files +luaU.LUA_SIGNATURE = "\27Lua" -- binary files start with "Lua" +luaU.VERSION = 80 -- 0x50; last format change was in 5.0 +luaU.VERSION0 = 80 -- 0x50; last major change was in 5.0 + +-- 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 + 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) + local v = "" + x = math.floor(x) + if x >= 0 then + for i = 1, 4 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, 4 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 32-bit signed integer (for int) +------------------------------------------------------------------------ +function luaU:DumpInt(x, D) + self:DumpBlock(self:from_int(x), D) +end + +------------------------------------------------------------------------ +-- dumps a 32-bit unsigned integer (for size_t) +------------------------------------------------------------------------ +function luaU:DumpSize(x, D) + self:DumpBlock(self:from_int(x), D) +end + +------------------------------------------------------------------------ +-- dumps a LUA_NUMBER (hard-coded as a double) +------------------------------------------------------------------------ +function luaU:DumpNumber(x, D) + self:DumpBlock(self:from_double(x), D) +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 + self:DumpString(f.locvars[i].varname, D) + self:DumpInt(f.locvars[i].startpc, D) + self:DumpInt(f.locvars[i].endpc, 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 + 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) + 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_TNIL then + else + --lua_assert(0) -- cannot happen + end + end + n = f.sizep + self:DumpInt(n, D) + for i = 0, n - 1 do + self:DumpFunction(f.p[i], f.source, D) + end +end + +------------------------------------------------------------------------ +-- dump child function prototypes from function prototype +------------------------------------------------------------------------ +function luaU:DumpFunction(f, p, D) + local source = f.source + if source == p then source = nil end + self:DumpString(source, D) + self:DumpInt(f.lineDefined, D) + self:DumpByte(f.nups, D) + self:DumpByte(f.numparams, D) + self:DumpByte(f.is_vararg, D) + self:DumpByte(f.maxstacksize, D) + self:DumpLines(f, D) + self:DumpLocals(f, D) + self:DumpUpvalues(f, D) + self:DumpConstants(f, D) + self:DumpCode(f, D) +end + +------------------------------------------------------------------------ +-- dump Lua header section (some sizes hard-coded) +------------------------------------------------------------------------ +function luaU:DumpHeader(D) + self:DumpLiteral(self.LUA_SIGNATURE, D) + self:DumpByte(self.VERSION, D) + self:DumpByte(self:endianness(), D) + self:DumpByte(4, D) -- sizeof(int) + self:DumpByte(4, D) -- sizeof(size_t) + self:DumpByte(4, D) -- sizeof(Instruction) + self:DumpByte(luaP.SIZE_OP, D) + self:DumpByte(luaP.SIZE_A, D) + self:DumpByte(luaP.SIZE_B, D) + self:DumpByte(luaP.SIZE_C, D) + self:DumpByte(8, D) -- sizeof(lua_Number) + self:DumpNumber(self.TEST_NUMBER, D) +end + +------------------------------------------------------------------------ +-- dump function as precompiled chunk +-- * w, data are created from make_setS, make_setF +------------------------------------------------------------------------ +function luaU:dump(L, Main, w, data) + local D = {} -- DumpState + D.L = L + 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 diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/llex.lua new file mode 100644 index 0000000..077f1aa --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/llex.lua @@ -0,0 +1,531 @@ +--[[-------------------------------------------------------------------- + + llex.lua + Lua 5 lexical analyzer in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * intended to 'imitate' llex.c code; performance is not a concern +-- * tokens are strings; code structure largely retained +-- * deleted stuff (compared to llex.c) are noted, comments retained +-- * Added: +-- luaX:chunkid (from lobject.c) +-- * To use the lexer: +-- (1) luaX:init() to initialize the lexer +-- (2) luaX:setinput() to set the input stream to lex, get LS +-- (3) call luaX:lex() to get tokens, until "TK_EOS": +-- LS.t.token = luaX:lex(LS, LS.t) +-- * since EOZ is returned as a string, be careful when regexp testing +----------------------------------------------------------------------]] + +luaX = {} + +-- FIRST_RESERVED is not required as tokens are manipulated as strings +-- TOKEN_LEN deleted; maximum length of a reserved word + +------------------------------------------------------------------------ +-- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED +------------------------------------------------------------------------ + +-- terminal symbols denoted by reserved words: TK_AND to TK_WHILE +-- other terminal symbols: TK_NAME to TK_EOS +luaX.RESERVED = [[ +TK_AND and +TK_BREAK break +TK_DO do +TK_ELSE else +TK_ELSEIF elseif +TK_END end +TK_FALSE false +TK_FOR for +TK_FUNCTION function +TK_IF if +TK_IN in +TK_LOCAL local +TK_NIL nil +TK_NOT not +TK_OR or +TK_REPEAT repeat +TK_RETURN return +TK_THEN then +TK_TRUE true +TK_UNTIL until +TK_WHILE while +TK_NAME *name +TK_CONCAT .. +TK_DOTS ... +TK_EQ == +TK_GE >= +TK_LE <= +TK_NE ~= +TK_NUMBER *number +TK_STRING *string +TK_EOS ]] + +-- NUM_RESERVED is not required; number of reserved words + +--[[-------------------------------------------------------------------- +-- Instead of passing seminfo, the Token struct (e.g. LS.t) is passed +-- so that lexer functions can use its table element, LS.t.seminfo +-- +-- Token (struct of LS.t and LS.lookahead): +-- token -- token symbol +-- seminfo -- semantics information +-- +-- LexState (struct of LS; LS is initialized by luaX:setinput): +-- current -- current character +-- linenumber -- input line counter +-- lastline -- line of last token 'consumed' +-- t -- current token (table: struct Token) +-- lookahead -- look ahead token (table: struct Token) +-- fs -- 'FuncState' is private to the parser +-- L -- LuaState +-- z -- input stream +-- buff -- buffer for tokens +-- source -- current source name +-- nestlevel -- level of nested non-terminals +----------------------------------------------------------------------]] + +-- token2string is now a hash; see luaX:init + +------------------------------------------------------------------------ +-- initialize lexer +------------------------------------------------------------------------ +function luaX:init() + self.token2string = {} + self.string2token = {} + for v in string.gfind(self.RESERVED, "[^\n]+") do + local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)") + self.token2string[tok] = str + self.string2token[str] = tok + end +end + +luaX.MAXSRC = 80 + +------------------------------------------------------------------------ +-- returns a suitably-formatted chunk name or id +-- * from lobject.c, used in llex.c and ldebug.c +-- * the result, out, is returned (was first argument) +------------------------------------------------------------------------ +function luaX:chunkid(source, bufflen) + local out + local first = string.sub(source, 1, 1) + if first == "=" then + out = string.sub(source, 2, bufflen) -- remove first char + else -- out = "source", or "...source" + if first == "@" then + source = string.sub(source, 2) -- skip the '@' + bufflen = bufflen - string.len(" `...' ") + local l = string.len(source) + out = "" + if l > bufflen then + source = string.sub(source, 1 + l - bufflen) -- get last part of file name + out = out.."..." + end + out = out..source + else -- out = [string "string"] + local len = string.find(source, "\n", 1, 1) -- stop at first newline + len = len and (len - 1) or string.len(source) + bufflen = bufflen - string.len(" [string \"...\"] ") + if len > bufflen then len = bufflen end + out = "[string \"" + if len < string.len(source) then -- must truncate? + out = out..string.sub(source, 1, len).."..." + else + out = out..source + end + out = out.."\"]" + end + end + return out +end + +--[[-------------------------------------------------------------------- +-- Support functions for lexer +-- * all lexer errors eventually reaches errorline: + checklimit -> syntaxerror -> error -> errorline + lexerror -> error -> errorline +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- limit check, syntax error if fails (also called by parser) +------------------------------------------------------------------------ +function luaX:checklimit(ls, val, limit, msg) + if val > limit then + msg = string.format("too many %s (limit=%d)", msg, limit) + self:syntaxerror(ls, msg) + end +end + +------------------------------------------------------------------------ +-- formats error message and throws error (also called by parser) +------------------------------------------------------------------------ +function luaX:errorline(ls, s, token, line) + local buff = self:chunkid(ls.source, self.MAXSRC) + error(string.format("%s:%d: %s near `%s'", buff, line, s, token)) +end + +------------------------------------------------------------------------ +-- throws an error, adds line number +------------------------------------------------------------------------ +function luaX:error(ls, s, token) + self:errorline(ls, s, token, ls.linenumber) +end + +------------------------------------------------------------------------ +-- throws a syntax error (mainly called by parser) +-- * ls.t.token has to be set by the function calling luaX:lex +-- (see next() and lookahead() in lparser.c) +------------------------------------------------------------------------ +function luaX:syntaxerror(ls, msg) + local lasttoken + local tok = ls.t.token + if tok == "TK_NAME" then + lasttoken = ls.t.seminfo + elseif tok == "TK_STRING" or tok == "TK_NUMBER" then + lasttoken = ls.buff + else + lasttoken = self:token2str(ls.t.token) + end + self:error(ls, msg, lasttoken) +end + +------------------------------------------------------------------------ +-- look up token and return keyword if found (also called by parser) +------------------------------------------------------------------------ +function luaX:token2str(ls, token) + if string.sub(token, 1, 3) ~= "TK_" then + return token + else + --lua_assert(string.len(token) == 1) + return self.token2string[token] + end +end + +------------------------------------------------------------------------ +-- throws a lexer error +------------------------------------------------------------------------ +function luaX:lexerror(ls, s, token) + if token == "TK_EOS" then + self:error(ls, s, self:token2str(ls, token)) + else + self:error(ls, s, ls.buff) + end +end + +------------------------------------------------------------------------ +-- move on to next line +------------------------------------------------------------------------ +function luaX:inclinenumber(LS) + self:next(LS) -- skip '\n' + LS.linenumber = LS.linenumber + 1 + self:checklimit(LS, LS.linenumber, self.MAX_INT, "lines in a chunk") +end + +luaX.MAX_INT = 2147483645 -- INT_MAX-2 for 32-bit systems (llimits.h) + +------------------------------------------------------------------------ +-- initializes an input stream for lexing +-- * if LS (the lexer state) is passed as a table, then it is filled in, +-- otherwise it has to be retrieved as a return value +------------------------------------------------------------------------ +function luaX:setinput(L, LS, z, source) + if not LS then LS = {} end -- create struct + if not LS.lookahead then LS.lookahead = {} end + if not LS.t then LS.t = {} end + LS.L = L + LS.lookahead.token = "TK_EOS" -- no look-ahead token + LS.z = z + LS.fs = nil + LS.linenumber = 1 + LS.lastline = 1 + LS.source = source + self:next(LS) -- read first char + if LS.current == "#" then + repeat -- skip first line + self:next(LS) + until LS.current == "\n" or LS.current == "EOZ" + end + return LS +end + +--[[-------------------------------------------------------------------- +-- LEXICAL ANALYZER +----------------------------------------------------------------------]] + +-- NOTE the following buffer handling stuff are no longer required: +-- use buffer to store names, literal strings and numbers +-- EXTRABUFF deleted; extra space to allocate when growing buffer +-- MAXNOCHECK deleted; maximum number of chars that can be read without checking buffer size +-- checkbuffer(LS, len) deleted + +------------------------------------------------------------------------ +-- gets the next character and returns it +------------------------------------------------------------------------ +function luaX:next(LS) + local c = luaZ:zgetc(LS.z) + LS.current = c + return c +end + +------------------------------------------------------------------------ +-- saves the given character into the token buffer +------------------------------------------------------------------------ +function luaX:save(LS, c) + LS.buff = LS.buff..c +end + +------------------------------------------------------------------------ +-- save current character into token buffer, grabs next character +------------------------------------------------------------------------ +function luaX:save_and_next(LS) + self:save(LS, LS.current) + return self:next(LS) +end + +------------------------------------------------------------------------ +-- reads a name +-- * originally returns the string length +------------------------------------------------------------------------ +function luaX:readname(LS) + LS.buff = "" + repeat + self:save_and_next(LS) + until LS.current == "EOZ" or not string.find(LS.current, "[_%w]") + return LS.buff +end + +------------------------------------------------------------------------ +-- reads a number (LUA_NUMBER) +------------------------------------------------------------------------ +function luaX:read_numeral(LS, comma, Token) + LS.buff = "" + if comma then self:save(LS, '.') end + while string.find(LS.current, "%d") do + self:save_and_next(LS) + end + if LS.current == "." then + self:save_and_next(LS) + if LS.current == "." then + self:save_and_next(LS) + self:lexerror(LS, + "ambiguous syntax (decimal point x string concatenation)", + "TK_NUMBER") + end + end + while string.find(LS.current, "%d") do + self:save_and_next(LS) + end + if LS.current == "e" or LS.current == "E" then + self:save_and_next(LS) -- read 'E' + if LS.current == "+" or LS.current == "-" then + self:save_and_next(LS) -- optional exponent sign + end + while string.find(LS.current, "%d") do + self:save_and_next(LS) + end + end + local seminfo = tonumber(LS.buff) + if not seminfo then + self:lexerror(LS, "malformed number", "TK_NUMBER") + end + Token.seminfo = seminfo +end + +------------------------------------------------------------------------ +-- reads a long string or long comment +------------------------------------------------------------------------ +function luaX:read_long_string(LS, Token) + local cont = 0 + LS.buff = "" + self:save(LS, "[") -- save first '[' + self:save_and_next(LS) -- pass the second '[' + if LS.current == "\n" then -- string starts with a newline? + self:inclinenumber(LS) -- skip it + end + while true do + local c = LS.current + if c == "EOZ" then + self:lexerror(LS, Token and "unfinished long string" or + "unfinished long comment", "TK_EOS") + elseif c == "[" then + self:save_and_next(LS) + if LS.current == "[" then + cont = cont + 1 + self:save_and_next(LS) + end + elseif c == "]" then + self:save_and_next(LS) + if LS.current == "]" then + if cont == 0 then break end + cont = cont - 1 + self:save_and_next(LS) + end + elseif c == "\n" then + self:save(LS, "\n") + self:inclinenumber(LS) + if not Token then LS.buff = "" end -- reset buffer to avoid wasting space + else + self:save_and_next(LS) + end--if c + end--while + self:save_and_next(LS) -- skip the second ']' + if Token then + Token.seminfo = string.sub(LS.buff, 3, -3) + end +end + +------------------------------------------------------------------------ +-- reads a string +------------------------------------------------------------------------ +function luaX:read_string(LS, del, Token) + LS.buff = "" + self:save_and_next(LS) + while LS.current ~= del do + local c = LS.current + if c == "EOZ" then + self:lexerror(LS, "unfinished string", "TK_EOS") + elseif c == "\n" then + self:lexerror(LS, "unfinished string", "TK_STRING") + elseif c == "\\" then + c = self:next(LS) -- do not save the '\' + if c ~= "EOZ" then -- will raise an error next loop + -- escapes handling greatly simplified here: + local i = string.find("abfnrtv\n", c, 1, 1) + if i then + self:save(LS, string.sub("\a\b\f\n\r\t\v\n", i, i)) + if i == 8 then self:inclinenumber(LS) else self:next(LS) end + elseif not string.find(c, "%d") then + self:save_and_next(LS) -- handles \\, \", \', and \? + else -- \xxx + c, i = 0, 0 + repeat + c = 10 * c + LS.current + self:next(LS) + i = i + 1 + until i >= 3 or not string.find(LS.current, "%d") + if c > 255 then -- UCHAR_MAX + self:lexerror(LS, "escape sequence too large", "TK_STRING") + end + self:save(LS, string.char(c)) + end + end + else + self:save_and_next(LS) + end--if c + end--while + self:save_and_next(LS) -- skip delimiter + Token.seminfo = string.sub(LS.buff, 2, -2) +end + +------------------------------------------------------------------------ +-- main lexer function +------------------------------------------------------------------------ +function luaX:lex(LS, Token) + while true do + local c = LS.current + ---------------------------------------------------------------- + if c == "\n" then + self:inclinenumber(LS) + ---------------------------------------------------------------- + elseif c == "-" then + c = self:next(LS) + if c ~= "-" then return "-" end + -- else is a comment + c = self:next(LS) + if c == "[" and self:next(LS) == "[" then + self:read_long_string(LS) -- long comment + else -- short comment + c = LS.current + while c ~= "\n" and c ~= "EOZ" do + c = self:next(LS) + end + end + ---------------------------------------------------------------- + elseif c == "[" then + c = self:next(LS) + if c ~= "[" then return "[" + else + self:read_long_string(LS, Token) + return "TK_STRING" + end + ---------------------------------------------------------------- + elseif c == "=" then + c = self:next(LS) + if c ~= "=" then return "=" + else self:next(LS); return "TK_EQ" end + ---------------------------------------------------------------- + elseif c == "<" then + c = self:next(LS) + if c ~= "=" then return "<" + else self:next(LS); return "TK_LE" end + ---------------------------------------------------------------- + elseif c == ">" then + c = self:next(LS) + if c ~= "=" then return ">" + else self:next(LS); return "TK_GE" end + ---------------------------------------------------------------- + elseif c == "~" then + c = self:next(LS) + if c ~= "=" then return "~" + else self:next(LS); return "TK_NE" end + ---------------------------------------------------------------- + elseif c == "\"" or c == "'" then + self:read_string(LS, c, Token) + return "TK_STRING" + ---------------------------------------------------------------- + elseif c == "." then + c = self:next(LS) + if c == "." then + c = self:next(LS) + if c == "." then + self:next(LS) + return "TK_DOTS" -- ... + else + return "TK_CONCAT" -- .. + end + elseif not string.find(c, "%d") then + return '.' + else + self:read_numeral(LS, true, Token) + return "TK_NUMBER" + end + ---------------------------------------------------------------- + elseif c == "EOZ" then + return "TK_EOS" + ---------------------------------------------------------------- + else -- default + if string.find(c, "%s") then + self:next(LS) + elseif string.find(c, "%d") then + self:read_numeral(LS, false, Token) + return "TK_NUMBER" + elseif string.find(c, "[_%a]") then + -- identifier or reserved word + local l = self:readname(LS) + local tok = self.string2token[l] + if tok then return tok end -- reserved word? + Token.seminfo = l + return "TK_NAME" + else + if string.find(c, "%c") then + self:error(LS, "invalid control char", + string.format("char(%d)", string.byte(c))) + end + self:next(LS) + return c -- single-char tokens (+ - / ...) + end + ---------------------------------------------------------------- + end--if c + end--while +end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lopcodes.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lopcodes.lua new file mode 100644 index 0000000..0c4eebd --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lopcodes.lua @@ -0,0 +1,349 @@ +--[[-------------------------------------------------------------------- + + lopcodes.lua + Lua 5 virtual machine opcodes in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- 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 +----------------------------------------------------------------------]] + +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 + +------------------------------------------------------------------------ +-- 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 + +-----+-----+-----+----------+ + | A | B | C | Opcode | iABC format + +-----+-----+-----+----------+ + - 8 - 9 - 9 - 6 - field sizes + +-----+-----+-----+----------+ + | A | [s]Bx | 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 + +------------------------------------------------------------------------ +-- returns a 4-char string little-endian encoded form of an instruction +------------------------------------------------------------------------ +function luaP:Instruction(i) + local I, c0, c1, c2, c3 + if i.Bx then + -- change to OP/A/B/C format + i.C = math.mod(i.Bx, 512) + i.B = math.floor(i.Bx / 512) + end + I = i.C * 64 + i.OP + c0 = math.mod(I, 256) + I = i.B * 128 + math.floor(I / 256) -- 7 bits of C left + c1 = math.mod(I, 256) + I = math.floor(I / 256) -- 8 bits of B left + c2 = math.mod(I, 256) + c3 = math.mod(i.A, 256) + return string.char(c0, c1, c2, c3) +end + +------------------------------------------------------------------------ +-- decodes a 4-char little-endian string into an instruction struct +------------------------------------------------------------------------ +function luaP:DecodeInst(x) + local i = {} + local I = string.byte(x, 1) + local op = math.mod(I, 64) + i.OP = op + I = string.byte(x, 2) * 4 + math.floor(I / 64) -- 2 bits of c0 left + i.C = math.mod(I, 512) + i.B = string.byte(x, 3) * 2 + math.floor(I / 128) -- 1 bit of c2 left + i.A = string.byte(x, 4) + local opmode = self.OpMode[tonumber(string.sub(self.opmodes[op + 1], 7, 7))] + if opmode ~= "iABC" then + i.Bx = i.B * 512 + i.C + end + return i +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 + +-- ORDER OP +local i = 0 +for v in string.gfind([[ +MOVE LOADK LOADBOOL LOADNIL GETUPVAL +GETGLOBAL GETTABLE SETGLOBAL SETUPVAL SETTABLE +NEWTABLE SELF ADD SUB MUL +DIV POW UNM NOT CONCAT +JMP EQ LT LE TEST +CALL TAILCALL RETURN FORLOOP TFORLOOP +TFORPREP SETLIST SETLISTO CLOSE CLOSURE +]], "%S+") 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) + 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 = 32 + +-- luaP_opnames[] is set above, as the luaP.opnames table +-- opmode(t,b,bk,ck,sa,k,m) deleted + +--[[-------------------------------------------------------------------- + Legend for luaP:opmodes: + T -> T B -> B mode -> m, where iABC = 1 + Bk -> b Ck -> C iABx = 2 + sA -> A K -> K iAsBx = 3 +----------------------------------------------------------------------]] + +-- ORDER OP +luaP.opmodes = { +-- TBbCAKm opcode + "0100101", -- OP_MOVE + "0000112", -- OP_LOADK + "0000101", -- OP_LOADBOOL + "0100101", -- OP_LOADNIL + "0000101", -- OP_GETUPVAL + "0000112", -- OP_GETGLOBAL + "0101101", -- OP_GETTABLE + "0000012", -- OP_SETGLOBAL + "0000001", -- OP_SETUPVAL + "0011001", -- OP_SETTABLE + "0000101", -- OP_NEWTABLE + "0101101", -- OP_SELF + "0011101", -- OP_ADD + "0011101", -- OP_SUB + "0011101", -- OP_MUL + "0011101", -- OP_DIV + "0011101", -- OP_POW + "0100101", -- OP_UNM + "0100101", -- OP_NOT + "0101101", -- OP_CONCAT + "0000003", -- OP_JMP + "1011001", -- OP_EQ + "1011001", -- OP_LT + "1011001", -- OP_LE + "1100101", -- OP_TEST + "0000001", -- OP_CALL + "0000001", -- OP_TAILCALL + "0000001", -- OP_RETURN + "0000003", -- OP_FORLOOP + "1000001", -- OP_TFORLOOP + "0000003", -- OP_TFORPREP + "0000002", -- OP_SETLIST + "0000002", -- OP_SETLISTO + "0000001", -- OP_CLOSE + "0000102", -- OP_CLOSURE +} diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua new file mode 100644 index 0000000..3180a7f --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua @@ -0,0 +1,1706 @@ +--[[-------------------------------------------------------------------- + + lparser.lua + Lua 5 parser in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * LUA_COMPATUPSYNTAX option changed into a comment block +-- * Added: +-- some constants, see below +-- luaY:newproto (from lfunc.c) -- called by lparser, lundump, luac +-- luaY:int2fb (from lobject.c) -- called by lparser, ltests +-- luaY:log2 (from lobject.c) -- called by lparser, ltests, ltable +-- luaY:growvector (from lmem.h) -- skeleton only, limit checking +-- * Unimplemented: +-- luaG_checkcode() in lua_assert is not currently implemented +----------------------------------------------------------------------]] + +--requires luaP, luaX, luaK +luaY = {} + +------------------------------------------------------------------------ +-- constants used by parser +-- * MAX_INT duplicated in luaX.MAX_INT +------------------------------------------------------------------------ +luaY.MAX_INT = 2147483645 -- INT_MAX-2 for 32-bit systems (llimits.h) +luaY.MAXVARS = 200 -- (llimits.h) +luaY.MAXUPVALUES = 32 -- (llimits.h) +luaY.MAXPARAMS = 100 -- (llimits.h) +luaY.LUA_MAXPARSERLEVEL = 200 -- (llimits.h) +luaY.LUA_MULTRET = -1 -- (lua.h) +luaY.MAXSTACK = 250 -- (llimits.h, used in lcode.lua) + +------------------------------------------------------------------------ +-- Expression descriptor +------------------------------------------------------------------------ + +--[[-------------------------------------------------------------------- +-- * expkind changed to string constants; luaY:assignment was the only +-- function to use a relational operator with this enumeration +-- VVOID -- no value +-- VNIL -- no value +-- VTRUE -- no value +-- VFALSE -- no value +-- VK -- info = index of constant in 'k' +-- VLOCAL -- info = local register +-- VUPVAL, -- info = index of upvalue in 'upvalues' +-- VGLOBAL -- info = index of table; aux = index of global name in 'k' +-- VINDEXED -- info = table register; aux = index register (or 'k') +-- VJMP -- info = instruction pc +-- VRELOCABLE -- info = instruction pc +-- VNONRELOC -- info = result register +-- VCALL -- info = result register +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- struct expdesc: +-- k -- (enum: expkind) +-- info, aux +-- t -- patch list of 'exit when true' +-- f -- patch list of 'exit when false' +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- state needed to generate code for a given function +-- struct FuncState: +-- f -- current function header (table: Proto) +-- h -- table to find (and reuse) elements in 'k' (table: Table) +-- prev -- enclosing function (table: FuncState) +-- ls -- lexical state (table: LexState) +-- L -- copy of the Lua state (table: lua_State) +-- bl -- chain of current blocks (table: BlockCnt) +-- pc -- next position to code (equivalent to 'ncode') +-- lasttarget -- 'pc' of last 'jump target' +-- jpc -- list of pending jumps to 'pc' +-- freereg -- first free register +-- nk -- number of elements in 'k' +-- np -- number of elements in 'p' +-- nlocvars -- number of elements in 'locvars' +-- nactvar -- number of active local variables +-- upvalues[MAXUPVALUES] -- upvalues (table: expdesc) +-- actvar[MAXVARS] -- declared-variable stack +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- converts an integer to a "floating point byte", represented as +-- (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm) +------------------------------------------------------------------------ + +function luaY: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 + +------------------------------------------------------------------------ +-- calculates log value for encoding the hash portion's size +-- * there are 2 implementations: the shorter one uses math.frexp +-- while the other one is based on the original code, so pick one... +-- * since LUA_NUMBER is assumed to be a double elsewhere, the +-- shorter version works fine +------------------------------------------------------------------------ +--[[ +function luaY:log2(x) + -- this is based on the original lua0_log2 in lobject.c + local log_8 = { -- index starts from 1 + 0, + 1,1, + 2,2,2,2, + 3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 + } + if x >= 65536 then + if x >= 16777216 then + return log_8[math.mod(math.floor(x / 16777216), 256)] + 24 + else + return log_8[math.mod(math.floor(x / 65536), 256)] + 16 + end + else + if x >= 256 then + return log_8[math.mod(math.floor(x / 256), 256)] + 8 + elseif x > 0 then + return log_8[math.mod(x, 256)] + end + return -1 -- special 'log' for 0 + end +end +--]] +-- [[ +function luaY:log2(x) + -- math result is always one more than lua0_log2() + local mn, ex = math.frexp(x) + return ex - 1 +end +--]] + +------------------------------------------------------------------------ +-- this is a stripped-down luaM_growvector (from lmem.h) which is a +-- macro based on luaM_growaux (in lmem.c); all this function does is +-- reproduce the size limit checking logic of the original function +-- so that error behaviour is identical; all arguments preserved for +-- convenience, even those which are unused +-- * set the t field to nil, since this originally does a sizeof(t) +-- * size (originally a pointer) is never updated, their final values +-- are set by luaY:close_func(), so overall things should still work +------------------------------------------------------------------------ +function luaY:growvector(L, v, nelems, size, t, limit, e) + local MINSIZEARRAY = 4 -- defined in lmem.c + -- still have at least MINSIZEARRAY free places + if nelems >= limit - MINSIZEARRAY then + luaX:syntaxerror(ls, e) + end +end + +-- getlocvar(fs, i) has been placed with functions for locals, changed +-- into a function + +------------------------------------------------------------------------ +-- tracks and limits parsing depth, assert check at end of parsing +------------------------------------------------------------------------ +function luaY:enterlevel(ls) + ls.nestlevel = ls.nestlevel + 1 + if ls.nestlevel > self.LUA_MAXPARSERLEVEL then + luaX:syntaxerror(ls, "too many syntax levels") + end +end + +------------------------------------------------------------------------ +-- tracks parsing depth, a pair with luaY:enterlevel() +------------------------------------------------------------------------ +function luaY:leavelevel(ls) + ls.nestlevel = ls.nestlevel - 1 +end + +------------------------------------------------------------------------ +-- nodes for block list (list of active blocks) +------------------------------------------------------------------------ +--[[-------------------------------------------------------------------- +-- struct BlockCnt: +-- previous -- chain (table: struct BlockCnt) +-- breaklist -- list of jumps out of this loop +-- nactvar -- # active local variables outside the breakable structure +-- upval -- true if some variable in the block is an upvalue (boolean) +-- isbreakable -- true if 'block' is a loop (boolean) +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- prototypes for recursive non-terminal functions +------------------------------------------------------------------------ +-- prototypes deleted; not required in Lua + +------------------------------------------------------------------------ +-- reads in next token +-- * luaX:lex fills in ls.t.seminfo too, lookahead is handled +------------------------------------------------------------------------ +function luaY:next(ls) + ls.lastline = ls.linenumber + if ls.lookahead.token ~= "TK_EOS" then -- is there a look-ahead token? + ls.t.token = ls.lookahead.token -- use this one + ls.t.seminfo = ls.lookahead.seminfo + ls.lookahead.token = "TK_EOS" -- and discharge it + else + ls.t.token = luaX:lex(ls, ls.t) -- read next token + end +end + +------------------------------------------------------------------------ +-- peek at next token (single lookahead only) +------------------------------------------------------------------------ +function luaY:lookahead(ls) + lua_assert(ls.lookahead.token == "TK_EOS") + ls.lookahead.token = luaX:lex(ls, ls.lookahead) +end + +------------------------------------------------------------------------ +-- throws a syntax error if token expected is not there +------------------------------------------------------------------------ +function luaY:error_expected(ls, token) + luaX:syntaxerror(ls, + string.format("`%s' expected", luaX:token2str(ls, token))) +end + +------------------------------------------------------------------------ +-- tests for a token, returns outcome +-- * return value changed to boolean +------------------------------------------------------------------------ +function luaY:testnext(ls, c) + if ls.t.token == c then + self:next(ls) + return true + else + return false + end +end + +------------------------------------------------------------------------ +-- check for existence of a token, throws error if not found +------------------------------------------------------------------------ +function luaY:check(ls, c) + if not self:testnext(ls, c) then + self:error_expected(ls, c) + end +end + +------------------------------------------------------------------------ +-- throws error if condition not matched +------------------------------------------------------------------------ +function luaY:check_condition(ls, c, msg) + if not c then luaX:syntaxerror(ls, msg) end +end + +------------------------------------------------------------------------ +-- verifies token conditions are met or else throw error +------------------------------------------------------------------------ +function luaY:check_match(ls, what, who, where) + if not self:testnext(ls, what) then + if where == ls.linenumber then + self:error_expected(ls, what) + else + luaX:syntaxerror(ls, string.format( + "`%s' expected (to close `%s' at line %d)", + luaX:token2str(ls, what), luaX:token2str(ls, who), where)) + end + end +end + +------------------------------------------------------------------------ +-- expect that token is a name, return the name +------------------------------------------------------------------------ +function luaY:str_checkname(ls) + self:check_condition(ls, ls.t.token == "TK_NAME", " expected") + local ts = ls.t.seminfo + self:next(ls) + return ts +end + +------------------------------------------------------------------------ +-- initialize a struct expdesc, expression description data structure +------------------------------------------------------------------------ +function luaY:init_exp(e, k, i) + e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP + e.k = k + e.info = i +end + +------------------------------------------------------------------------ +-- adds given string s in string pool, sets e as VK +------------------------------------------------------------------------ +function luaY:codestring(ls, e, s) + self:init_exp(e, "VK", luaK:stringK(ls.fs, s)) +end + +------------------------------------------------------------------------ +-- consume a name token, adds it to string pool, sets e as VK +------------------------------------------------------------------------ +function luaY:checkname(ls, e) + self:codestring(ls, e, self:str_checkname(ls)) +end + +------------------------------------------------------------------------ +-- returns local variable entry struct for a function +------------------------------------------------------------------------ +function luaY:getlocvar(fs, i) + return fs.f.locvars[ fs.actvar[i] ] +end + +------------------------------------------------------------------------ +-- creates struct entry for a local variable +-- * used by new_localvar() only +------------------------------------------------------------------------ +function luaY:registerlocalvar(ls, varname) + local fs = ls.fs + local f = fs.f + self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars, + nil, self.MAX_INT, "") + f.locvars[fs.nlocvars] = {} -- LocVar + f.locvars[fs.nlocvars].varname = varname + local nlocvars = fs.nlocvars + fs.nlocvars = fs.nlocvars + 1 + return nlocvars +end + +------------------------------------------------------------------------ +-- register a local variable, set in active variable list +-- * used in new_localvarstr(), parlist(), fornum(), forlist(), +-- localfunc(), localstat() +------------------------------------------------------------------------ +function luaY:new_localvar(ls, name, n) + local fs = ls.fs + luaX:checklimit(ls, fs.nactvar + n + 1, self.MAXVARS, "local variables") + fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name) +end + +------------------------------------------------------------------------ +-- adds nvars number of new local variables, set debug information +-- * used in create_local(), code_params(), forbody(), localfunc(), +-- localstat() +------------------------------------------------------------------------ +function luaY:adjustlocalvars(ls, nvars) + local fs = ls.fs + fs.nactvar = fs.nactvar + nvars + for i = 1, nvars do + self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc + end +end + +------------------------------------------------------------------------ +-- removes a number of locals, set debug information +-- * used in leaveblock(), close_func() +------------------------------------------------------------------------ +function luaY:removevars(ls, tolevel) + local fs = ls.fs + while fs.nactvar > tolevel do + fs.nactvar = fs.nactvar - 1 + self:getlocvar(fs, fs.nactvar).endpc = fs.pc + end +end + +------------------------------------------------------------------------ +-- creates a new local variable given a name and an offset from nactvar +-- * used in fornum(), forlist() for loop variables; in create_local() +------------------------------------------------------------------------ +function luaY:new_localvarstr(ls, name, n) + self:new_localvar(ls, name, n) +end + +------------------------------------------------------------------------ +-- creates a single local variable and activates it +-- * used only in code_params() for "arg", body() for "self" +------------------------------------------------------------------------ +function luaY:create_local(ls, name) + self:new_localvarstr(ls, name, 0) + self:adjustlocalvars(ls, 1) +end + +------------------------------------------------------------------------ +-- returns an existing upvalue index based on the given name, or +-- creates a new upvalue struct entry and returns the new index +-- * used only in singlevaraux() +------------------------------------------------------------------------ +function luaY: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 + lua_assert(fs.f.upvalues[i] == name) + return i + end + end + -- new one + luaX:checklimit(fs.ls, f.nups + 1, self.MAXUPVALUES, "upvalues") + self:growvector(fs.L, fs.f.upvalues, f.nups, fs.f.sizeupvalues, + nil, self.MAX_INT, "") + fs.f.upvalues[f.nups] = name + -- this is a partial copy; only k & info fields used + fs.upvalues[f.nups] = { k = v.k, info = v.info } + local nups = f.nups + f.nups = f.nups + 1 + return nups +end + +------------------------------------------------------------------------ +-- search the local variable namespace of the given fs for a match +-- * used only in singlevaraux() +------------------------------------------------------------------------ +function luaY:searchvar(fs, n) + for i = fs.nactvar - 1, 0, -1 do + if n == self:getlocvar(fs, i).varname then + return i + end + end + return -1 -- not found +end + +------------------------------------------------------------------------ +-- * mark upvalue flags in function states up to a given level +-- * used only in singlevaraux() +------------------------------------------------------------------------ +function luaY: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 + +------------------------------------------------------------------------ +-- handle locals, globals and upvalues and related processing +-- * search mechanism is recursive, calls itself to search parents +-- * used only in singlevar() +------------------------------------------------------------------------ +function luaY:singlevaraux(fs, n, var, base) + if fs == nil then -- no more levels? + self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable + else + local v = self:searchvar(fs, n) -- look up at current level + if v >= 0 then + self:init_exp(var, "VLOCAL", v) + if base == 0 then + self:markupval(fs, v) -- local will be used as an upval + end + else -- not found at current level; try upper one + self:singlevaraux(fs.prev, n, var, 0) + if var.k == "VGLOBAL" then + if base ~= 0 then + var.info = luaK:stringK(fs, n) -- info points to global name + end + else -- LOCAL or UPVAL + var.info = self:indexupvalue(fs, n, var) + var.k = "VUPVAL" -- upvalue in this level + end + end--if v + end--if fs +end + +------------------------------------------------------------------------ +-- consume a name token, creates a variable (global|local|upvalue) +-- * used in prefixexp(), funcname() +------------------------------------------------------------------------ +function luaY:singlevar(ls, var, base) + local varname = self:str_checkname(ls) + self:singlevaraux(ls.fs, varname, var, base) + return varname +end + +------------------------------------------------------------------------ +-- adjust RHS to match LHS in an assignment +-- * used in assignment(), forlist(), localstat() +------------------------------------------------------------------------ +function luaY:adjust_assign(ls, nvars, nexps, e) + local fs = ls.fs + local extra = nvars - nexps + if e.k == "VCALL" then + extra = extra + 1 -- includes call itself + if extra <= 0 then extra = 0 + else luaK:reserveregs(fs, extra - 1) end + luaK:setcallreturns(fs, e, extra) -- call provides the difference + 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 + +------------------------------------------------------------------------ +-- perform initialization for a parameter list, adds arg if needed +-- * used only in parlist() +------------------------------------------------------------------------ +function luaY:code_params(ls, nparams, dots) + local fs = ls.fs + self:adjustlocalvars(ls, nparams) + luaX:checklimit(ls, fs.nactvar, self.MAXPARAMS, "parameters") + fs.f.numparams = fs.nactvar + fs.f.is_vararg = dots and 1 or 0 + if dots then + self:create_local(ls, "arg") + end + luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters +end + +------------------------------------------------------------------------ +-- enters a code unit, initializes elements +------------------------------------------------------------------------ +function luaY: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 + lua_assert(fs.freereg == fs.nactvar) +end + +------------------------------------------------------------------------ +-- leaves a code unit, close any upvalues +------------------------------------------------------------------------ +function luaY:leaveblock(fs) + local bl = fs.bl + fs.bl = bl.previous + self:removevars(fs.ls, bl.nactvar) + if bl.upval then + luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) + end + lua_assert(bl.nactvar == fs.nactvar) + fs.freereg = fs.nactvar -- free registers + luaK:patchtohere(fs, bl.breaklist) +end + +------------------------------------------------------------------------ +-- implement the instantiation of a function prototype, append list of +-- upvalues after the instantiation instruction +-- * used only in body() +------------------------------------------------------------------------ +function luaY:pushclosure(ls, func, v) + local fs = ls.fs + local f = fs.f + self:growvector(ls.L, f.p, fs.np, f.sizep, nil, + luaP.MAXARG_Bx, "constant table overflow") + f.p[fs.np] = func.f + fs.np = fs.np + 1 + self: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 + +------------------------------------------------------------------------ +-- initialize a new function prototype structure +------------------------------------------------------------------------ +function luaY:newproto(L) + local f = {} -- Proto + -- luaC_link deleted + 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 + +------------------------------------------------------------------------ +-- opening of a function +------------------------------------------------------------------------ +function luaY:open_func(ls, fs) + local f = self:newproto(ls.L) + fs.f = f + fs.prev = ls.fs -- linked list of funcstates + fs.ls = ls + fs.L = ls.L + ls.fs = fs + fs.pc = 0 + fs.lasttarget = 0 + fs.jpc = luaK.NO_JUMP + fs.freereg = 0 + fs.nk = 0 + fs.h = {} -- constant table; was luaH_new call + fs.np = 0 + fs.nlocvars = 0 + fs.nactvar = 0 + fs.bl = nil + f.source = ls.source + f.maxstacksize = 2 -- registers 0/1 are always valid +end + +------------------------------------------------------------------------ +-- closing of a function +------------------------------------------------------------------------ +function luaY:close_func(ls) + local L = ls.L + local fs = ls.fs + local f = fs.f + self:removevars(ls, 0) + luaK:codeABC(fs, "OP_RETURN", 0, 1, 0) -- final return + -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p, + -- f->locvars, f->upvalues; not required for Lua table arrays + f.sizecode = fs.pc + f.sizelineinfo = fs.pc + f.sizek = fs.nk + f.sizep = fs.np + f.sizelocvars = fs.nlocvars + f.sizeupvalues = f.nups + --lua_assert(luaG_checkcode(f)) -- currently not implemented + lua_assert(fs.bl == nil) + ls.fs = fs.prev +end + +------------------------------------------------------------------------ +-- parser initialization function +-- * note additional sub-tables needed for LexState, FuncState +------------------------------------------------------------------------ +function luaY:parser(L, z, buff) + local lexstate = {} -- LexState + lexstate.t = {} + lexstate.lookahead = {} + local funcstate = {} -- FuncState + funcstate.upvalues = {} + funcstate.actvar = {} + lexstate.buff = buff + lexstate.nestlevel = 0 + luaX:setinput(L, lexstate, z, z.name) + self:open_func(lexstate, funcstate) + self:next(lexstate) -- read first token + self:chunk(lexstate) + self:check_condition(lexstate, lexstate.t.token == "TK_EOS", " expected") + self:close_func(lexstate) + lua_assert(funcstate.prev == nil) + lua_assert(funcstate.f.nups == 0) + lua_assert(lexstate.nestlevel == 0) + return funcstate.f +end + +--[[-------------------------------------------------------------------- +-- GRAMMAR RULES +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- parse a function name suffix, for function call specifications +-- * used in primaryexp(), funcname() +------------------------------------------------------------------------ +function luaY:field(ls, v) + -- field -> ['.' | ':'] NAME + local fs = ls.fs + local key = {} -- expdesc + luaK:exp2anyreg(fs, v) + self:next(ls) -- skip the dot or colon + self:checkname(ls, key) + luaK:indexed(fs, v, key) +end + +------------------------------------------------------------------------ +-- parse a table indexing suffix, for constructors, expressions +-- * used in recfield(), primaryexp() +------------------------------------------------------------------------ +function luaY:index(ls, v) + -- index -> '[' expr ']' + self:next(ls) -- skip the '[' + self:expr(ls, v) + luaK:exp2val(ls.fs, v) + self:check(ls, "]") +end + +--[[-------------------------------------------------------------------- +-- Rules for Constructors +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- struct ConsControl: +-- v -- last list item read (table: struct expdesc) +-- t -- table descriptor (table: struct expdesc) +-- nh -- total number of 'record' elements +-- na -- total number of array elements +-- tostore -- number of array elements pending to be stored +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- parse a table record (hash) field +-- * used in constructor() +------------------------------------------------------------------------ +function luaY:recfield(ls, cc) + -- recfield -> (NAME | '['exp1']') = exp1 + local fs = ls.fs + local reg = ls.fs.freereg + local key, val = {}, {} -- expdesc + if ls.t.token == "TK_NAME" then + luaX:checklimit(ls, cc.nh, self.MAX_INT, "items in a constructor") + cc.nh = cc.nh + 1 + self:checkname(ls, key) + else -- ls->t.token == '[' + self:index(ls, key) + end + self:check(ls, "=") + luaK:exp2RK(fs, key) + self:expr(ls, val) + luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, luaK:exp2RK(fs, key), + luaK:exp2RK(fs, val)) + fs.freereg = reg -- free registers +end + +------------------------------------------------------------------------ +-- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) +-- * used in constructor() +------------------------------------------------------------------------ +function luaY: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:codeABx(fs, "OP_SETLIST", cc.t.info, cc.na - 1) -- flush + cc.tostore = 0 -- no more items pending + fs.freereg = cc.t.info + 1 -- free registers + end +end + +------------------------------------------------------------------------ +-- emit a set list instruction at the end of parsing list constructor +-- * used in constructor() +------------------------------------------------------------------------ +function luaY:lastlistfield(fs, cc) + if cc.tostore == 0 then return end + if cc.v.k == "VCALL" then + luaK:setcallreturns(fs, cc.v, self.LUA_MULTRET) + luaK:codeABx(fs, "OP_SETLISTO", cc.t.info, cc.na - 1) + else + if cc.v.k ~= "VVOID" then + luaK:exp2nextreg(fs, cc.v) + end + luaK:codeABx(fs, "OP_SETLIST", cc.t.info, cc.na - 1) + end + fs.freereg = cc.t.info + 1 -- free registers +end + +------------------------------------------------------------------------ +-- parse a table list (array) field +-- * used in constructor() +------------------------------------------------------------------------ +function luaY:listfield(ls, cc) + self:expr(ls, cc.v) + luaX:checklimit(ls, cc.na, luaP.MAXARG_Bx, "items in a constructor") + cc.na = cc.na + 1 + cc.tostore = cc.tostore + 1 +end + +------------------------------------------------------------------------ +-- parse a table constructor +-- * used in funcargs(), simpleexp() +------------------------------------------------------------------------ +function luaY:constructor(ls, t) + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- field -> recfield | listfield + -- fieldsep -> ',' | ';' + local fs = ls.fs + local line = ls.linenumber + local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0) + local cc = {} -- ConsControl + cc.v = {} + cc.na, cc.nh, cc.tostore = 0, 0, 0 + cc.t = t + self:init_exp(t, "VRELOCABLE", pc) + self:init_exp(cc.v, "VVOID", 0) -- no value (yet) + luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc) + self:check(ls, "{") + repeat + lua_assert(cc.v.k == "VVOID" or cc.tostore > 0) + self:testnext(ls, ";") -- compatibility only + if ls.t.token == "}" then break end + self:closelistfield(fs, cc) + local c = ls.t.token + if c == "TK_NAME" then -- may be listfields or recfields + self:lookahead(ls) + if ls.lookahead.token ~= "=" then -- expression? + self:listfield(ls, cc) + else + self:recfield(ls, cc) + end + elseif c == "[" then -- constructor_item -> recfield + self:recfield(ls, cc) + else -- constructor_part -> listfield + self:listfield(ls, cc) + end + until not self:testnext(ls, ",") and not self:testnext(ls, ";") + self:check_match(ls, "}", "{", line) + self:lastlistfield(fs, cc) + luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size + luaP:SETARG_C(fs.f.code[pc], self:log2(cc.nh) + 1) -- set initial table size +end + +------------------------------------------------------------------------ +-- parse the arguments (parameters) of a function declaration +-- * used in body() +------------------------------------------------------------------------ +function luaY:parlist(ls) + -- parlist -> [ param { ',' param } ] + local nparams = 0 + local dots = false + if ls.t.token ~= ")" then -- is 'parlist' not empty? + repeat + local c = ls.t.token + if c == "TK_DOTS" then + dots = true + self:next(ls) + elseif c == "TK_NAME" then + self:new_localvar(ls, self:str_checkname(ls), nparams) + nparams = nparams + 1 + else + luaX:syntaxerror(ls, " or `...' expected") + end + until dots or not self:testnext(ls, ",") + end + self:code_params(ls, nparams, dots) +end + +------------------------------------------------------------------------ +-- parse function declaration body +-- * used in simpleexp(), localfunc(), funcstat() +------------------------------------------------------------------------ +function luaY:body(ls, e, needself, line) + -- body -> '(' parlist ')' chunk END + local new_fs = {} -- FuncState + new_fs.upvalues = {} + new_fs.actvar = {} + self:open_func(ls, new_fs) + new_fs.f.lineDefined = line + self:check(ls, "(") + if needself then + self:create_local(ls, "self") + end + self:parlist(ls) + self:check(ls, ")") + self:chunk(ls) + self:check_match(ls, "TK_END", "TK_FUNCTION", line) + self:close_func(ls) + self:pushclosure(ls, new_fs, e) +end + +------------------------------------------------------------------------ +-- parse a list of comma-separated expressions +-- * used is multiple locations +------------------------------------------------------------------------ +function luaY:explist1(ls, v) + -- explist1 -> expr { ',' expr } + local n = 1 -- at least one expression + self:expr(ls, v) + while self:testnext(ls, ",") do + luaK:exp2nextreg(ls.fs, v) + self:expr(ls, v) + n = n + 1 + end + return n +end + +------------------------------------------------------------------------ +-- parse the parameters of a function call +-- * contrast with parlist(), used in function declarations +-- * used in primaryexp() +------------------------------------------------------------------------ +function luaY:funcargs(ls, f) + local fs = ls.fs + local args = {} -- expdesc + local nparams + local line = ls.linenumber + local c = ls.t.token + if c == "(" then -- funcargs -> '(' [ explist1 ] ')' + if line ~= ls.lastline then + luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)") + end + self:next(ls) + if ls.t.token == ")" then -- arg list is empty? + args.k = "VVOID" + else + self:explist1(ls, args) + luaK:setcallreturns(fs, args, self.LUA_MULTRET) + end + self:check_match(ls, ")", "(", line) + elseif c == "{" then -- funcargs -> constructor + self:constructor(ls, args) + elseif c == "TK_STRING" then -- funcargs -> STRING + self:codestring(ls, args, ls.t.seminfo) + self:next(ls) -- must use 'seminfo' before 'next' + else + luaX:syntaxerror(ls, "function arguments expected") + return + end + lua_assert(f.k == "VNONRELOC") + local base = f.info -- base register for call + if args.k == "VCALL" then + nparams = self.LUA_MULTRET -- open call + else + if args.k ~= "VVOID" then + luaK:exp2nextreg(fs, args) -- close last argument + end + nparams = fs.freereg - (base + 1) + end + self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2)) + luaK:fixline(fs, line) + fs.freereg = base + 1 -- call remove function and arguments and leaves + -- (unless changed) one result +end + +--[[-------------------------------------------------------------------- +-- Expression parsing +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- parses an expression in parentheses or a single variable +-- * used in primaryexp() +------------------------------------------------------------------------ +function luaY:prefixexp(ls, v) + -- prefixexp -> NAME | '(' expr ')' + local c = ls.t.token + if c == "(" then + local line = ls.linenumber + self:next(ls) + self:expr(ls, v) + self:check_match(ls, ")", "(", line) + luaK:dischargevars(ls.fs, v) + elseif c == "TK_NAME" then + self:singlevar(ls, v, 1) + -- LUA_COMPATUPSYNTAX +--[[ + elseif c == "%" then -- for compatibility only + local line = ls.linenumber + self:next(ls) -- skip '%' + local varname = self:singlevar(ls, v, 1) + if v.k ~= "VUPVAL" then + luaX:errorline(ls, "global upvalues are obsolete", varname, line) + end +--]] + else + luaX:syntaxerror(ls, "unexpected symbol") + end--if c + return +end + +------------------------------------------------------------------------ +-- parses a prefixexp (an expression in parentheses or a single variable) +-- or a function call specification +-- * used in simpleexp(), assignment(), exprstat() +------------------------------------------------------------------------ +function luaY:primaryexp(ls, v) + -- primaryexp -> + -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + local fs = ls.fs + self:prefixexp(ls, v) + while true do + local c = ls.t.token + if c == "." then -- field + self:field(ls, v) + elseif c == "[" then -- '[' exp1 ']' + local key = {} -- expdesc + luaK:exp2anyreg(fs, v) + self:index(ls, key) + luaK:indexed(fs, v, key) + elseif c == ":" then -- ':' NAME funcargs + local key = {} -- expdesc + self:next(ls) + self:checkname(ls, key) + luaK:_self(fs, v, key) + self:funcargs(ls, v) + elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs + luaK:exp2nextreg(fs, v) + self:funcargs(ls, v) + else + return + end--if c + end--while +end + +------------------------------------------------------------------------ +-- parses general expression types, constants handled here +-- * used in subexpr() +------------------------------------------------------------------------ +function luaY:simpleexp(ls, v) + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | constructor + -- | FUNCTION body | primaryexp + local c = ls.t.token + if c == "TK_NUMBER" then + self:init_exp(v, "VK", luaK:numberK(ls.fs, ls.t.seminfo)) + self:next(ls) -- must use 'seminfo' before 'next' + elseif c == "TK_STRING" then + self:codestring(ls, v, ls.t.seminfo) + self:next(ls) -- must use 'seminfo' before 'next' + elseif c == "TK_NIL" then + self:init_exp(v, "VNIL", 0) + self:next(ls) + elseif c == "TK_TRUE" then + self:init_exp(v, "VTRUE", 0) + self:next(ls) + elseif c == "TK_FALSE" then + self:init_exp(v, "VFALSE", 0) + self:next(ls) + elseif c == "{" then -- constructor + self:constructor(ls, v) + elseif c == "TK_FUNCTION" then + self:next(ls) + self:body(ls, v, false, ls.linenumber) + else + self:primaryexp(ls, v) + end--if c +end + +------------------------------------------------------------------------ +-- Translates unary operators tokens if found, otherwise returns +-- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr(). +-- * used in subexpr() +------------------------------------------------------------------------ +function luaY:getunopr(op) + if op == "TK_NOT" then + return "OPR_NOT" + elseif op == "-" then + return "OPR_MINUS" + else + return "OPR_NOUNOPR" + end +end + +------------------------------------------------------------------------ +-- Translates binary operator tokens if found, otherwise returns +-- OPR_NOBINOPR. Code generation uses OPR_* style tokens. +-- * used in subexpr() +------------------------------------------------------------------------ +luaY.getbinopr_table = { + ["+"] = "OPR_ADD", + ["-"] = "OPR_SUB", + ["*"] = "OPR_MULT", + ["/"] = "OPR_DIV", + ["^"] = "OPR_POW", + ["TK_CONCAT"] = "OPR_CONCAT", + ["TK_NE"] = "OPR_NE", + ["TK_EQ"] = "OPR_EQ", + ["<"] = "OPR_LT", + ["TK_LE"] = "OPR_LE", + [">"] = "OPR_GT", + ["TK_GE"] = "OPR_GE", + ["TK_AND"] = "OPR_AND", + ["TK_OR"] = "OPR_OR", +} +function luaY:getbinopr(op) + local opr = self.getbinopr_table[op] + if opr then return opr else return "OPR_NOBINOPR" end +end + +------------------------------------------------------------------------ +-- the following priority table consists of pairs of left/right values +-- for binary operators (was a static const struct); grep for ORDER OPR +------------------------------------------------------------------------ +luaY.priority = { + {6, 6}, {6, 6}, {7, 7}, {7, 7}, -- arithmetic + {10, 9}, {5, 4}, -- power and concat (right associative) + {3, 3}, {3, 3}, -- equality + {3, 3}, {3, 3}, {3, 3}, {3, 3}, -- order + {2, 2}, {1, 1} -- logical (and/or) +} + +luaY.UNARY_PRIORITY = 8 -- priority for unary operators + +------------------------------------------------------------------------ +-- subexpr -> (simpleexp | unop subexpr) { binop subexpr } +-- where 'binop' is any binary operator with a priority higher than 'limit' +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- * for priority lookups with self.priority[], 1=left and 2=right +-- +-- Parse subexpressions. Includes handling of unary operators and binary +-- operators. A subexpr is given the rhs priority level of the operator +-- immediately left of it, if any (limit is -1 if none,) and if a binop +-- is found, limit is compared with the lhs priority level of the binop +-- in order to determine which executes first. +-- +-- * recursively called +-- * used in expr() +------------------------------------------------------------------------ +function luaY:subexpr(ls, v, limit) + self:enterlevel(ls) + local uop = self:getunopr(ls.t.token) + if uop ~= "OPR_NOUNOPR" then + self:next(ls) + self:subexpr(ls, v, self.UNARY_PRIORITY) + luaK:prefix(ls.fs, uop, v) + else + self:simpleexp(ls, v) + end + -- expand while operators have priorities higher than 'limit' + local op = self:getbinopr(ls.t.token) + while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do + local v2 = {} -- expdesc + self:next(ls) + luaK:infix(ls.fs, op, v) + -- read sub-expression with higher priority + local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2]) + luaK:posfix(ls.fs, op, v, v2) + op = nextop + end + self:leavelevel(ls) + return op -- return first untreated operator +end + +------------------------------------------------------------------------ +-- Expression parsing starts here. Function subexpr is entered with the +-- left operator (which is non-existent) priority of -1, which is lower +-- than all actual operators. Expr information is returned in parm v. +-- * used in multiple locations +------------------------------------------------------------------------ +function luaY:expr(ls, v) + self:subexpr(ls, v, -1) +end + +--[[-------------------------------------------------------------------- +-- Rules for Statements +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- checks next token, used as a look-ahead +-- * returns boolean instead of 0|1 +-- * used in retstat(), chunk() +------------------------------------------------------------------------ +function luaY:block_follow(token) + if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END" + or token == "TK_UNTIL" or token == "TK_EOS" then + return true + else + return false + end +end + +------------------------------------------------------------------------ +-- parse a code block or unit +-- * used in multiple functions +------------------------------------------------------------------------ +function luaY:block(ls) + -- block -> chunk + local fs = ls.fs + local bl = {} -- BlockCnt + self:enterblock(fs, bl, false) + self:chunk(ls) + lua_assert(bl.breaklist == luaK.NO_JUMP) + self:leaveblock(fs) +end + +------------------------------------------------------------------------ +-- structure to chain all variables in the left-hand side of an +-- assignment +------------------------------------------------------------------------ +--[[-------------------------------------------------------------------- +-- struct LHS_assign: +-- prev -- (table: struct LHS_assign) +-- v -- variable (global, local, upvalue, or indexed) (table: expdesc) +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- 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. +-- * used in assignment() +------------------------------------------------------------------------ +function luaY:check_conflict(ls, lh, v) + local fs = ls.fs + 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 + +------------------------------------------------------------------------ +-- parse a variable assignment sequence +-- * recursively called +-- * used in exprstat() +------------------------------------------------------------------------ +function luaY:assignment(ls, lh, nvars) + local e = {} -- expdesc + -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED + local c = lh.v.k + self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" + or c == "VINDEXED", "syntax error") + if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment + local nv = {} -- LHS_assign + nv.v = {} + nv.prev = lh + self:primaryexp(ls, nv.v) + if nv.v.k == "VLOCAL" then + self:check_conflict(ls, lh, nv.v) + end + self:assignment(ls, nv, nvars + 1) + else -- assignment -> '=' explist1 + self:check(ls, "=") + local nexps = self:explist1(ls, e) + if nexps ~= nvars then + self:adjust_assign(ls, nvars, nexps, e) + if nexps > nvars then + ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values + end + else + luaK:setcallreturns(ls.fs, e, 1) -- close last expression + luaK:storevar(ls.fs, lh.v, e) + return -- avoid default + end + end + self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment + luaK:storevar(ls.fs, lh.v, e) +end + +------------------------------------------------------------------------ +-- parse condition in a repeat statement or an if control structure +-- * used in repeatstat(), test_then_block() +------------------------------------------------------------------------ +function luaY:cond(ls, v) + -- cond -> exp + self:expr(ls, v) -- read condition + if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here + luaK:goiftrue(ls.fs, v) + luaK:patchtohere(ls.fs, v.t) +end + +------------------------------------------------------------------------ +-- The while statement optimizes its code by coding the condition +-- after its body (and thus avoiding one jump in the loop). +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- maximum size of expressions for optimizing 'while' code +------------------------------------------------------------------------ +if not luaY.MAXEXPWHILE then + luaY.MAXEXPWHILE = 100 +end + +------------------------------------------------------------------------ +-- the call 'luaK_goiffalse' may grow the size of an expression by +-- at most this: +------------------------------------------------------------------------ +luaY.EXTRAEXP = 5 + +------------------------------------------------------------------------ +-- parse a while-do control structure, body processed by block() +-- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by +-- the function's implementation can be removed +-- * used in statements() +------------------------------------------------------------------------ +function luaY:whilestat(ls, line) + -- whilestat -> WHILE cond DO block END + -- array size of [MAXEXPWHILE + EXTRAEXP] no longer required + local codeexp = {} -- Instruction + local fs = ls.fs + local v = {} -- expdesc + local bl = {} -- BlockCnt + self:next(ls) -- skip WHILE + local whileinit = luaK:jump(fs) -- jump to condition (which will be moved) + local expinit = luaK:getlabel(fs) + self:expr(ls, v) -- parse condition + if v.k == "VK" then v.k = "VTRUE" end -- 'trues' are all equal here + local lineexp = ls.linenumber + luaK:goiffalse(fs, v) + v.f = luaK:concat(fs, v.f, fs.jpc) + fs.jpc = luaK.NO_JUMP + local sizeexp = fs.pc - expinit -- size of expression code + if sizeexp > self.MAXEXPWHILE then + luaX:syntaxerror(ls, "`while' condition too complex") + end + for i = 0, sizeexp - 1 do -- save 'exp' code + codeexp[i] = fs.f.code[expinit + i] + end + fs.pc = expinit -- remove 'exp' code + self:enterblock(fs, bl, true) + self:check(ls, "TK_DO") + local blockinit = luaK:getlabel(fs) + self:block(ls) + luaK:patchtohere(fs, whileinit) -- initial jump jumps to here + -- move 'exp' back to code + if v.t ~= luaK.NO_JUMP then v.t = v.t + fs.pc - expinit end + if v.f ~= luaK.NO_JUMP then v.f = v.f + fs.pc - expinit end + for i = 0, sizeexp - 1 do + luaK:code(fs, codeexp[i], lineexp) + end + self:check_match(ls, "TK_END", "TK_WHILE", line) + self:leaveblock(fs) + luaK:patchlist(fs, v.t, blockinit) -- true conditions go back to loop + luaK:patchtohere(fs, v.f) -- false conditions finish the loop +end + +------------------------------------------------------------------------ +-- parse a repeat-until control structure, body parsed by block() +-- * used in statements() +------------------------------------------------------------------------ +function luaY:repeatstat(ls, line) + -- repeatstat -> REPEAT block UNTIL cond + local fs = ls.fs + local repeat_init = luaK:getlabel(fs) + local v = {} -- expdesc + local bl = {} -- BlockCnt + self:enterblock(fs, bl, true) + self:next(ls) + self:block(ls) + self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line) + self:cond(ls, v) + luaK:patchlist(fs, v.f, repeat_init) + self:leaveblock(fs) +end + +------------------------------------------------------------------------ +-- parse the single expressions needed in numerical for loops +-- * used in fornum() +------------------------------------------------------------------------ +function luaY:exp1(ls) + local e = {} -- expdesc + self:expr(ls, e) + local k = e.k + luaK:exp2nextreg(ls.fs, e) + return k +end + +------------------------------------------------------------------------ +-- parse a for loop body for both versions of the for loop +-- * used in fornum(), forlist() +------------------------------------------------------------------------ +function luaY:forbody(ls, base, line, nvars, isnum) + local bl = {} -- BlockCnt + local fs = ls.fs + self:adjustlocalvars(ls, nvars) -- scope for all variables + self:check(ls, "TK_DO") + self:enterblock(fs, bl, true) -- loop block + local prep = luaK:getlabel(fs) + self:block(ls) + luaK:patchtohere(fs, prep - 1) + local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP) + or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars - 3) + luaK:fixline(fs, line) -- pretend that 'OP_FOR' starts the loop + luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep) + self:leaveblock(fs) +end + +------------------------------------------------------------------------ +-- parse a numerical for loop, calls forbody() +-- * used in forstat() +------------------------------------------------------------------------ +function luaY:fornum(ls, varname, line) + -- fornum -> NAME = exp1,exp1[,exp1] DO body + local fs = ls.fs + local base = fs.freereg + self:new_localvar(ls, varname, 0) + self:new_localvarstr(ls, "(for limit)", 1) + self:new_localvarstr(ls, "(for step)", 2) + self:check(ls, "=") + self:exp1(ls) -- initial value + self:check(ls, ",") + self:exp1(ls) -- limit + if self:testnext(ls, ",") then + self:exp1(ls) -- optional step + else -- default step = 1 + luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1)) + luaK:reserveregs(fs, 1) + end + luaK:codeABC(fs, "OP_SUB", fs.freereg - 3, fs.freereg - 3, fs.freereg - 1) + luaK:jump(fs) + self:forbody(ls, base, line, 3, true) +end + +------------------------------------------------------------------------ +-- parse a generic for loop, calls forbody() +-- * used in forstat() +------------------------------------------------------------------------ +function luaY:forlist(ls, indexname) + -- forlist -> NAME {,NAME} IN explist1 DO body + local fs = ls.fs + local e = {} -- expdesc + local nvars = 0 + local base = fs.freereg + self:new_localvarstr(ls, "(for generator)", nvars) + nvars = nvars + 1 + self:new_localvarstr(ls, "(for state)", nvars) + nvars = nvars + 1 + self:new_localvar(ls, indexname, nvars) + nvars = nvars + 1 + while self:testnext(ls, ",") do + self:new_localvar(ls, self:str_checkname(ls), nvars) + nvars = nvars + 1 + end + self:check(ls, "TK_IN") + local line = ls.linenumber + self:adjust_assign(ls, nvars, self:explist1(ls, e), e) + luaK:checkstack(fs, 3) -- extra space to call generator + luaK:codeAsBx(fs, "OP_TFORPREP", base, luaK.NO_JUMP) + self:forbody(ls, base, line, nvars, false) +end + +------------------------------------------------------------------------ +-- initial parsing for a for loop, calls fornum() or forlist() +-- * used in statements() +------------------------------------------------------------------------ +function luaY:forstat(ls, line) + -- forstat -> fornum | forlist + local fs = ls.fs + local bl = {} -- BlockCnt + self:enterblock(fs, bl, false) -- block to control variable scope + self:next(ls) -- skip 'for' + local varname = self:str_checkname(ls) -- first variable name + local c = ls.t.token + if c == "=" then + self:fornum(ls, varname, line) + elseif c == "," or c == "TK_IN" then + self:forlist(ls, varname) + else + luaX:syntaxerror(ls, "`=' or `in' expected") + end + self:check_match(ls, "TK_END", "TK_FOR", line) + self:leaveblock(fs) +end + +------------------------------------------------------------------------ +-- parse part of an if control structure, including the condition +-- * used in ifstat() +------------------------------------------------------------------------ +function luaY:test_then_block(ls, v) + -- test_then_block -> [IF | ELSEIF] cond THEN block + self:next(ls) -- skip IF or ELSEIF + self:cond(ls, v) + self:check(ls, "TK_THEN") + self:block(ls) -- 'then' part +end + +------------------------------------------------------------------------ +-- parse an if control structure +-- * used in statements() +------------------------------------------------------------------------ +function luaY:ifstat(ls, line) + -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END + local fs = ls.fs + local v = {} -- expdesc + local escapelist = luaK.NO_JUMP + self:test_then_block(ls, v) -- IF cond THEN block + while ls.t.token == "TK_ELSEIF" do + escapelist = luaK:concat(fs, escapelist, luaK:jump(fs)) + luaK:patchtohere(fs, v.f) + self:test_then_block(ls, v) -- ELSEIF cond THEN block + end + if ls.t.token == "TK_ELSE" then + escapelist = luaK:concat(fs, escapelist, luaK:jump(fs)) + luaK:patchtohere(fs, v.f) + self:next(ls) -- skip ELSE (after patch, for correct line info) + self:block(ls) -- 'else' part + else + escapelist = luaK:concat(fs, escapelist, v.f) + end + luaK:patchtohere(fs, escapelist) + self:check_match(ls, "TK_END", "TK_IF", line) +end + +------------------------------------------------------------------------ +-- parse a local function statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:localfunc(ls) + local v, b = {}, {} -- expdesc + local fs = ls.fs + self:new_localvar(ls, self:str_checkname(ls), 0) + self:init_exp(v, "VLOCAL", fs.freereg) + luaK:reserveregs(fs, 1) + self:adjustlocalvars(ls, 1) + self:body(ls, b, false, ls.linenumber) + luaK:storevar(fs, v, b) + -- debug information will only see the variable after this point! + self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc +end + +------------------------------------------------------------------------ +-- parse a local variable declaration statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:localstat(ls) + -- stat -> LOCAL NAME {',' NAME} ['=' explist1] + local nvars = 0 + local nexps + local e = {} -- expdesc + repeat + self:new_localvar(ls, self:str_checkname(ls), nvars) + nvars = nvars + 1 + until not self:testnext(ls, ",") + if self:testnext(ls, "=") then + nexps = self:explist1(ls, e) + else + e.k = "VVOID" + nexps = 0 + end + self:adjust_assign(ls, nvars, nexps, e) + self:adjustlocalvars(ls, nvars) +end + +------------------------------------------------------------------------ +-- parse a function name specification +-- * used in funcstat() +------------------------------------------------------------------------ +function luaY:funcname(ls, v) + -- funcname -> NAME {field} [':' NAME] + local needself = false + self:singlevar(ls, v, 1) + while ls.t.token == "." do + self:field(ls, v) + end + if ls.t.token == ":" then + needself = true + self:field(ls, v) + end + return needself +end + +------------------------------------------------------------------------ +-- parse a function statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:funcstat(ls, line) + -- funcstat -> FUNCTION funcname body + local v, b = {}, {} -- expdesc + self:next(ls) -- skip FUNCTION + local needself = self:funcname(ls, v) + self:body(ls, b, needself, line) + luaK:storevar(ls.fs, v, b) + luaK:fixline(ls.fs, line) -- definition 'happens' in the first line +end + +------------------------------------------------------------------------ +-- parse a function call with no returns or an assignment statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:exprstat(ls) + -- stat -> func | assignment + local fs = ls.fs + local v = {} -- LHS_assign + v.v = {} + self:primaryexp(ls, v.v) + if v.v.k == "VCALL" then -- stat -> func + luaK:setcallreturns(fs, v.v, 0) -- call statement uses no results + else -- stat -> assignment + v.prev = nil + self:assignment(ls, v, 1) + end +end + +------------------------------------------------------------------------ +-- parse a return statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:retstat(ls) + -- stat -> RETURN explist + local fs = ls.fs + local e = {} -- expdesc + local first, nret -- registers with returned values + self:next(ls) -- skip RETURN + if self:block_follow(ls.t.token) or ls.t.token == ";" then + first, nret = 0, 0 -- return no values + else + nret = self:explist1(ls, e) -- optional return values + if e.k == "VCALL" then + luaK:setcallreturns(fs, e, self.LUA_MULTRET) + if nret == 1 then -- tail call? + luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL") + lua_assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar) + end + first = fs.nactvar + nret = self.LUA_MULTRET -- return all values + else + if nret == 1 then -- only one single value? + first = luaK:exp2anyreg(fs, e) + else + luaK:exp2nextreg(fs, e) -- values must go to the 'stack' + first = fs.nactvar -- return all 'active' values + lua_assert(nret == fs.freereg - first) + end + end--if + end--if + luaK:codeABC(fs, "OP_RETURN", first, nret + 1, 0) +end + +------------------------------------------------------------------------ +-- parse a break statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:breakstat(ls) + -- stat -> BREAK + local fs = ls.fs + local bl = fs.bl + local upval = false + self:next(ls) -- skip BREAK + while bl and not bl.isbreakable do + if bl.upval then upval = true end + bl = bl.previous + end + if not bl then + luaX:syntaxerror(ls, "no loop to break") + end + if upval then + luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) + end + bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs)) +end + +------------------------------------------------------------------------ +-- initial parsing for statements, calls a lot of functions +-- * returns boolean instead of 0|1 +-- * used in chunk() +------------------------------------------------------------------------ +function luaY:statement(ls) + local line = ls.linenumber -- may be needed for error messages + local c = ls.t.token + if c == "TK_IF" then -- stat -> ifstat + self:ifstat(ls, line) + return false + elseif c == "TK_WHILE" then -- stat -> whilestat + self:whilestat(ls, line) + return false + elseif c == "TK_DO" then -- stat -> DO block END + self:next(ls) -- skip DO + self:block(ls) + self:check_match(ls, "TK_END", "TK_DO", line) + return false + elseif c == "TK_FOR" then -- stat -> forstat + self:forstat(ls, line) + return false + elseif c == "TK_REPEAT" then -- stat -> repeatstat + self:repeatstat(ls, line) + return false + elseif c == "TK_FUNCTION" then -- stat -> funcstat + self:funcstat(ls, line) + return false + elseif c == "TK_LOCAL" then -- stat -> localstat + self:next(ls) -- skip LOCAL + if self:testnext(ls, "TK_FUNCTION") then -- local function? + self:localfunc(ls) + else + self:localstat(ls) + end + return false + elseif c == "TK_RETURN" then -- stat -> retstat + self:retstat(ls) + return true -- must be last statement + elseif c == "TK_BREAK" then -- stat -> breakstat + self:breakstat(ls) + return true -- must be last statement + else + self:exprstat(ls) + return false -- to avoid warnings + end--if c +end + +------------------------------------------------------------------------ +-- parse a chunk, which consists of a bunch of statements +-- * used in parser(), body(), block() +------------------------------------------------------------------------ +function luaY:chunk(ls) + -- chunk -> { stat [';'] } + local islast = false + self:enterlevel(ls) + while not islast and not self:block_follow(ls.t.token) do + islast = self:statement(ls) + self:testnext(ls, ";") + lua_assert(ls.fs.freereg >= ls.fs.nactvar) + ls.fs.freereg = ls.fs.nactvar -- free registers + end + self:leavelevel(ls) +end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/luac.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/luac.lua new file mode 100644 index 0000000..80cc4a5 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/luac.lua @@ -0,0 +1,71 @@ +--[[-------------------------------------------------------------------- + + luac.lua + Primitive luac 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. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * based on luac.lua in the test directory of the 5.0.3 distribution +-- * usage: lua luac.lua file.lua +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- load and initialize the required modules +------------------------------------------------------------------------ +require("lzio.lua") +require("llex.lua") +require("lopcodes.lua") +require("ldump.lua") +require("lcode.lua") +require("lparser.lua") + +luaX:init() -- required by llex +local LuaState = {} -- dummy, not actually used, but retained since + -- the intention is to complete a straight port + +------------------------------------------------------------------------ +-- interfacing to yueliang +------------------------------------------------------------------------ + +-- currently asserts are enabled because the codebase hasn't been tested +-- much (if you don't want asserts, just comment them out) +function lua_assert(test) + if not test then error("assertion failed!") end +end + +function yloadfile(filename) + -- luaZ:make_getF returns a file chunk reader + -- luaZ:init returns a zio input stream + local zio = luaZ:init(luaZ:make_getF(filename), nil, "@"..filename) + if not zio then return end + -- luaY:parser parses the input stream + -- func is the function prototype in tabular form; in C, func can + -- now be used directly by the VM, this can't be done in Lua + local func = luaY:parser(LuaState, zio, nil) + -- luaU:make_setS returns a string chunk writer + local writer, buff = luaU:make_setS() + -- luaU:dump builds a binary chunk + luaU:dump(LuaState, func, writer, buff) + -- a string.dump equivalent in returned + return buff.data +end + +------------------------------------------------------------------------ +-- command line interface +------------------------------------------------------------------------ + +assert(arg[1] ~= nil and arg[2] == nil, "usage: lua luac.lua file.lua") +local f = assert(io.open("luac.out","wb")) +f:write(assert(yloadfile(arg[1]))) +io.close(f) + +--end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lzio.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lzio.lua new file mode 100644 index 0000000..7b98246 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lzio.lua @@ -0,0 +1,120 @@ +--[[-------------------------------------------------------------------- + + lzio.lua + Lua 5 buffered streams in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * EOZ is implemented as a string, "EOZ" +-- * Format of z structure (ZIO) +-- z.n -- bytes still unread +-- z.p -- last read position in buffer +-- z.reader -- chunk reader function +-- z.data -- additional data +-- z.name -- name of stream +-- * Current position, p, is now last read index instead of a pointer +-- +-- Not implemented: +-- * luaZ_lookahead: used only in lapi.c:lua_load to detect binary chunk +-- * luaZ_read: used only in lundump.c:ezread to read +1 bytes +-- * luaZ_openspace: dropped; let Lua handle buffers as strings +-- * luaZ buffer macros: dropped; unused for now +-- +-- Alternatives: +-- * zname(z) is z.name +-- +-- Added: +-- (both of the following are vaguely adapted from lauxlib.c) +-- * luaZ:make_getS: create Chunkreader from a string +-- * luaZ:make_getF: create Chunkreader that reads from a file +----------------------------------------------------------------------]] + +luaZ = {} + +------------------------------------------------------------------------ +-- * reader() should return a string, or nil if nothing else to parse. +-- Unlike Chunkreaders, there are no arguments like additional data +-- * Chunkreaders are handled in lauxlib.h, see luaL_load(file|buffer) +-- * Original Chunkreader: +-- const char * (*lua_Chunkreader) (lua_State *L, void *ud, size_t *sz); +-- * This Lua chunk reader implementation: +-- returns string or nil, no arguments to function +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- create a chunk reader from a source string +------------------------------------------------------------------------ +function luaZ:make_getS(buff) + local b = buff + return function() -- chunk reader anonymous function here + if not b then return nil end + local data = b + b = nil + return data + end +end + +------------------------------------------------------------------------ +-- create a chunk reader from a source file +------------------------------------------------------------------------ +function luaZ:make_getF(filename) + local LUAL_BUFFERSIZE = 512 + local h = io.open(filename, "r") + if not h then return nil end + return function() -- chunk reader anonymous function here + if not h or io.type(h) == "closed file" then return nil end + local buff = h:read(LUAL_BUFFERSIZE) + if not buff then h:close(); h = nil end + return buff + end +end + +------------------------------------------------------------------------ +-- creates a zio input stream +-- returns the ZIO structure, z +------------------------------------------------------------------------ +function luaZ:init(reader, data, name) + if not reader then return end + local z = {} + z.reader = reader + z.data = data or "" + z.name = name + -- set up additional data for reading + if not data or data == "" then z.n = 0 else z.n = string.len(data) end + z.p = 0 + return z +end + +------------------------------------------------------------------------ +-- fill up input buffer +------------------------------------------------------------------------ +function luaZ:fill(z) + local data = z.reader() + z.data = data + if not data or data == "" then return "EOZ" end + z.n = string.len(data) - 1 + z.p = 1 + return string.sub(data, 1, 1) +end + +------------------------------------------------------------------------ +-- get next character from the input stream +------------------------------------------------------------------------ +function luaZ:zgetc(z) + if z.n > 0 then + z.n = z.n - 1 + z.p = z.p + 1 + return string.sub(z.data, z.p, z.p) + else + return self:fill(z) + end +end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/bench_llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/bench_llex.lua new file mode 100644 index 0000000..0c9403e --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/bench_llex.lua @@ -0,0 +1,99 @@ +--[[-------------------------------------------------------------------- + + bench_llex.lua + Benchmark test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +require("../lzio") +require("../llex") +luaX:init() + +------------------------------------------------------------------------ +-- load in a standard set of sample files +-- * file set is 5.0.3 front end set sans luac.lua +------------------------------------------------------------------------ + +local fileset, totalsize = {}, 0 +for fn in string.gfind([[ +../lcode.lua +../ldump.lua +../llex.lua +../lopcodes.lua +../lparser.lua +../lzio.lua +]], "%S+") do + table.insert(fileset, fn) +end + +for i = 1, table.getn(fileset) do + local fn = fileset[i] + local inf = io.open(fn, "rb") + if not inf then + error("failed to open "..fn.." for reading") + end + local data = inf:read("*a") + local data_sz = string.len(data) + inf:close() + if not data or data_sz == 0 then + error("failed to read data from "..fn.." or file is zero-length") + end + totalsize = totalsize + data_sz + fileset[i] = data +end + +------------------------------------------------------------------------ +-- benchmark tester +------------------------------------------------------------------------ + +local DURATION = 5 -- how long the benchmark should run + +local L = {} -- LuaState +local LS = {} -- LexState + +local time = os.time +local lexedsize = 0 +local tnow, elapsed = time(), 0 + +while time() == tnow do end -- wait for second to click over +tnow = time() + +while true do + for i = 1, table.getn(fileset) do + ------------------------------------------------------------ + local chunk = fileset[i] + local z = luaZ:init(luaZ:make_getS(chunk), nil, "=string") + luaX:setinput(L, LS, z, z.name) + while true do + LS.t.token = luaX:lex(LS, LS.t) + local tok, seminfo = LS.t.token, LS.t.seminfo + if tok == "TK_EOS" then break end + end + ------------------------------------------------------------ + lexedsize = lexedsize + string.len(chunk) + if time() > tnow then + tnow = time() + elapsed = elapsed + 1 + if elapsed >= DURATION then + -- report performance of lexer + lexedsize = lexedsize / 1024 + local speed = lexedsize / DURATION + print("Lexer performance:") + print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) + print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) + -- repeat until user breaks program + elapsed = 0 + end + end + ------------------------------------------------------------ + end--for +end--while + +-- end of script diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/sample.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/sample.lua new file mode 100644 index 0000000..dc6eaee --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/sample.lua @@ -0,0 +1,3 @@ +local a = 47 +local b = "hello, world!" +print(a, b) diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_ldump.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_ldump.lua new file mode 100644 index 0000000..d867688 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_ldump.lua @@ -0,0 +1,98 @@ +--[[-------------------------------------------------------------------- + + test_ldump.lua + Test for ldump.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. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- test dump chunkwriter style +------------------------------------------------------------------------ + +require("../lopcodes") +require("../ldump") + +-- Original typedef: +--int (*lua_Chunkwriter) (lua_State *L, const void* p, size_t sz, void* ud); + +local MyWriter, MyBuff = luaU:make_setS() +if not MyWriter then + error("failed to initialize using make_setS") +end +MyWriter("hello, ", MyBuff) +MyWriter("world!", MyBuff) +print(MyBuff.data) + +local MyWriter, MyBuff = luaU:make_setF("try.txt") +if not MyWriter then + error("failed to initialize using make_setF") +end +MyWriter("hello, ", MyBuff) +MyWriter("world!", MyBuff) +MyWriter(nil, MyBuff) + +------------------------------------------------------------------------ +-- test output of a function prototype +-- * data can be copied from a ChunkSpy listing output +------------------------------------------------------------------------ +-- local a = 47 +-- local b = "hello, world!" +-- print(a, b) +------------------------------------------------------------------------ + +local F = {} +F.source = "sample.lua" +F.lineDefined = 0 +F.nups = 0 +F.numparams = 0 +F.is_vararg = 0 +F.maxstacksize = 5 +F.sizelineinfo = 7 +F.lineinfo = {} +F.lineinfo[0] = 1 +F.lineinfo[1] = 2 +F.lineinfo[2] = 3 +F.lineinfo[3] = 3 +F.lineinfo[4] = 3 +F.lineinfo[5] = 3 +F.lineinfo[6] = 3 +F.sizelocvars = 2 +F.locvars = {} +F.locvars[0] = { varname = "a", startpc = 1, endpc = 6 } +F.locvars[1] = { varname = "b", startpc = 2, endpc = 6 } +F.sizeupvalues = 0 +F.upvalues = {} +F.sizek = 3 +F.k = {} +F.k[0] = { value = 47 } +F.k[1] = { value = "hello, world!" } +F.k[2] = { value = "print" } +F.sizep = 0 +F.p = {} +F.sizecode = 7 +F.code = {} +F.code[0] = { OP = 1, A = 0, Bx = 0 } +F.code[1] = { OP = 1, A = 1, Bx = 1 } +F.code[2] = { OP = 5, A = 2, Bx = 2 } +F.code[3] = { OP = 0, A = 3, B = 0, C = 0 } +F.code[4] = { OP = 0, A = 4, B = 1, C = 0 } +F.code[5] = { OP = 25, A = 2, B = 3, C = 1 } +F.code[6] = { OP = 27, A = 0, B = 1, C = 0 } + +local L = {} +--[[ +local Writer, Buff = luaU:make_setS() +luaU:dump(L, F, Writer, Buff) +for i = 1, string.len(Buff.data) do + io.stdout:write(string.byte(string.sub(Buff.data, i, i)).." ") +end +--]] +local Writer, Buff = luaU:make_setF("try.out") +luaU:dump(L, F, Writer, Buff) diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_llex.lua new file mode 100644 index 0000000..6bc834d --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_llex.lua @@ -0,0 +1,504 @@ +--[[-------------------------------------------------------------------- + + test_llex.lua + Test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- if BRIEF is not set to false, auto-test will silently succeed +------------------------------------------------------------------------ +BRIEF = true -- if set to true, messages are less verbose + +require("../lzio") +require("../llex") +luaX:init() + +------------------------------------------------------------------------ +-- simple manual tests +------------------------------------------------------------------------ + +--[[ +local L = {} -- LuaState +local LS = {} -- LexState + +local function dump(z) + luaX:setinput(L, LS, z, z.name) + while true do + LS.t.token = luaX:lex(LS, LS.t) + local tok, seminfo = LS.t.token, LS.t.seminfo + if tok == "TK_NAME" then + seminfo = " "..seminfo + elseif tok == "TK_NUMBER" then + seminfo = " "..seminfo + elseif tok == "TK_STRING" then + seminfo = " '"..seminfo.."'" + else + seminfo = "" + end + io.stdout:write(tok..seminfo.."\n") + if tok == "TK_EOS" then break end + end +end + +local function try_string(chunk) + dump(luaZ:init(luaZ:make_getS(chunk), nil, "=string")) +end +local function try_file(filename) + dump(luaZ:init(luaZ:make_getF(filename), nil, filename)) +end + +z = try_string("local c = luaZ:zgetc(z)") +z = try_file("test_lzio.lua") +z = try_file("test_llex.lua") +os.exit() +--]] + +------------------------------------------------------------------------ +-- auto-testing of simple test cases to validate lexer behaviour: +-- * NOTE coverage has not been checked; not comprehensive +-- * only test cases with non-empty comments are processed +-- * if no result, then the output is displayed for manual decision +-- (output may be used to set expected success or fail text) +-- * cases expected to be successful may be a partial match +-- * cases expected to fail may also be a partial match +------------------------------------------------------------------------ + +-- [[ +local function auto_test() + local PASS, FAIL = true, false + ------------------------------------------------------------------ + -- table of test cases + ------------------------------------------------------------------ + local test_cases = + { + ------------------------------------------------------------- + --{ "comment", -- comment about the test + -- "chunk", -- chunk to test + -- PASS, -- PASS or FAIL outcome + -- "output", -- output to compare against + --}, + ------------------------------------------------------------- + { "empty chunk string, test EOS", + "", + PASS, "1 TK_EOS", + }, + ------------------------------------------------------------- + { "line number counting", + "\n\n\r\n", + PASS, "4 TK_EOS", + }, + ------------------------------------------------------------- + { "various whitespaces", + " \n\t\t\n \t \t \n\n", + PASS, "5 TK_EOS", + }, + ------------------------------------------------------------- + { "short comment ending in EOS", + "-- moo moo", + PASS, "1 TK_EOS", + }, + ------------------------------------------------------------- + { "short comment ending in newline", + "-- moo moo\n", + PASS, "2 TK_EOS", + }, + ------------------------------------------------------------- + { "several lines of short comments", + "--moo\n-- moo moo\n\n--\tmoo\n", + PASS, "5 TK_EOS", + }, + ------------------------------------------------------------- + { "basic block comment", + "--[[bovine]]", + PASS, "1 TK_EOS", + }, + ------------------------------------------------------------- + { "unterminated block comment 1", + "--[[bovine", + FAIL, ":1: unfinished long comment near `'", + }, + ------------------------------------------------------------- + { "unterminated block comment 2", + "--[[bovine]", + FAIL, ":1: unfinished long comment near `'", + }, + ------------------------------------------------------------- + { "unterminated block comment 3", + "--[[bovine\nmoo moo\nwoof", + FAIL, ":3: unfinished long comment near `'", + }, + ------------------------------------------------------------- + { "basic long string", + "\n[[bovine]]\n", + PASS, "2 TK_STRING = bovine\n3 TK_EOS", + }, + ------------------------------------------------------------- + { "first newline consumed in long string", + "[[\nmoo]]", + PASS, "2 TK_STRING = moo\n2 TK_EOS", + }, + ------------------------------------------------------------- + { "multiline long string", + "[[moo\nmoo moo\n]]", + PASS, "3 TK_STRING = moo\nmoo moo\n\n3 TK_EOS", + }, + ------------------------------------------------------------- + { "unterminated long string 1", + "\n[[\nbovine", + FAIL, ":3: unfinished long string near `'", + }, + ------------------------------------------------------------- + { "unterminated long string 2", + "[[bovine]", + FAIL, ":1: unfinished long string near `'", + }, + ------------------------------------------------------------- + { "unterminated long string 3", + "[[[[ \n", + FAIL, ":2: unfinished long string near `'", + }, + ------------------------------------------------------------- + { "nested long string 1", + "[[moo[[moo]]moo]]", + PASS, "moo[[moo]]moo", + }, + ------------------------------------------------------------- + { "nested long string 2", + "[[moo[[moo[[[[]]]]moo]]moo]]", + PASS, "moo[[moo[[[[]]]]moo]]moo", + }, + ------------------------------------------------------------- + { "nested long string 3", + "[[[[[[]]]][[[[]]]]]]", + PASS, "[[[[]]]][[[[]]]]", + }, + ------------------------------------------------------------- + { "brackets in long strings 1", + "[[moo[moo]]", + PASS, "moo[moo", + }, + ------------------------------------------------------------- + { "brackets in long strings 2", + "[[moo[[moo]moo]]moo]]", + PASS, "moo[[moo]moo]]moo", + }, + ------------------------------------------------------------- + { "unprocessed escapes in long strings", + [[ [[\a\b\f\n\r\t\v\123]] ]], + PASS, [[\a\b\f\n\r\t\v\123]], + }, + ------------------------------------------------------------- + { "unbalanced long string", + "[[moo]]moo]]", + PASS, "1 TK_STRING = moo\n1 TK_NAME = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 1", + "and break do else", + PASS, "1 TK_AND\n1 TK_BREAK\n1 TK_DO\n1 TK_ELSE\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 2", + "elseif end false for", + PASS, "1 TK_ELSEIF\n1 TK_END\n1 TK_FALSE\n1 TK_FOR\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 3", + "function if in local nil", + PASS, "1 TK_FUNCTION\n1 TK_IF\n1 TK_IN\n1 TK_LOCAL\n1 TK_NIL\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 4", + "not or repeat return", + PASS, "1 TK_NOT\n1 TK_OR\n1 TK_REPEAT\n1 TK_RETURN\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 5", + "then true until while", + PASS, "1 TK_THEN\n1 TK_TRUE\n1 TK_UNTIL\n1 TK_WHILE\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "concat and dots", + ".. ...", + PASS, "1 TK_CONCAT\n1 TK_DOTS\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "shbang handling 1", + "#blahblah", + PASS, "1 TK_EOS", + }, + ------------------------------------------------------------- + { "shbang handling 2", + "#blahblah\nmoo moo\n", + PASS, "2 TK_NAME = moo\n2 TK_NAME = moo\n3 TK_EOS", + }, + ------------------------------------------------------------- + { "empty string", + [['']], + PASS, "1 TK_STRING = \n1 TK_EOS", + }, + ------------------------------------------------------------- + { "single-quoted string", + [['bovine']], + PASS, "1 TK_STRING = bovine\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "double-quoted string", + [["bovine"]], + PASS, "1 TK_STRING = bovine\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "unterminated string 1", + [['moo ]], + FAIL, ":1: unfinished string near `'", + }, + ------------------------------------------------------------- + { "unterminated string 2", + [["moo \n]], + FAIL, ":1: unfinished string near `'", + }, + ------------------------------------------------------------- + { "escaped newline in string, line number counted", + "\"moo\\\nmoo\\\nmoo\"", + PASS, "3 TK_STRING = moo\nmoo\nmoo\n3 TK_EOS", + }, + ------------------------------------------------------------- + { "escaped characters in string 1", + [["moo\amoo"]], + PASS, "1 TK_STRING = moo\amoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 2", + [["moo\bmoo"]], + PASS, "1 TK_STRING = moo\bmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 3", + [["moo\f\n\r\t\vmoo"]], + PASS, "1 TK_STRING = moo\f\n\r\t\vmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 4", + [["\\ \" \' \? \[ \]"]], + PASS, "1 TK_STRING = \\ \" \' \? \[ \]", + }, + ------------------------------------------------------------- + { "escaped characters in string 5", + [["\z \k \: \;"]], + PASS, "1 TK_STRING = z k : ;", + }, + ------------------------------------------------------------- + { "escaped characters in string 6", + [["\8 \65 \160 \180K \097097"]], + PASS, "1 TK_STRING = \8 \65 \160 \180K \097097\n", + }, + ------------------------------------------------------------- + { "escaped characters in string 7", + [["\666"]], + FAIL, ":1: escape sequence too large near `\"'", + }, + ------------------------------------------------------------- + { "simple numbers", + "123 123+", + PASS, "1 TK_NUMBER = 123\n1 TK_NUMBER = 123\n1 CHAR = '+'\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "longer numbers", + "1234567890 12345678901234567890", + PASS, "1 TK_NUMBER = 1234567890\n1 TK_NUMBER = 1.2345678901235e+19\n", + }, + ------------------------------------------------------------- + { "fractional numbers", + ".123 .12345678901234567890", + PASS, "1 TK_NUMBER = 0.123\n1 TK_NUMBER = 0.12345678901235\n", + }, + ------------------------------------------------------------- + { "more numbers with decimal points", + "12345.67890 1.1.", + PASS, "1 TK_NUMBER = 12345.6789\n1 TK_NUMBER = 1.1\n1 CHAR = '.'\n", + }, + ------------------------------------------------------------- + { "double decimal points", + ".1.1", + FAIL, ":1: malformed number near `.1.1'", + }, + ------------------------------------------------------------- + { "double dots within numbers", + "1..1", + FAIL, ":1: ambiguous syntax (decimal point x string concatenation) near `1..'", + }, + ------------------------------------------------------------- + { "incomplete exponential numbers", + "123e", + FAIL, ":1: malformed number near `123e'", + }, + ------------------------------------------------------------- + { "exponential numbers 1", + "1234e5 1234e5.", + PASS, "1 TK_NUMBER = 123400000\n1 TK_NUMBER = 123400000\n1 CHAR = '.'", + }, + ------------------------------------------------------------- + { "exponential numbers 2", + "1234e56 1.23e123", + PASS, "1 TK_NUMBER = 1.234e+59\n1 TK_NUMBER = 1.23e+123\n", + }, + ------------------------------------------------------------- + { "exponential numbers 3", + "12.34e+", + FAIL, ":1: malformed number near `12.34e+'", + }, + ------------------------------------------------------------- + { "exponential numbers 4", + "12.34e+5 123.4e-5 1234.E+5", + PASS, "1 TK_NUMBER = 1234000\n1 TK_NUMBER = 0.001234\n1 TK_NUMBER = 123400000\n", + }, + ------------------------------------------------------------- + { "single character symbols 1", + "= > < ~", + PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n", + }, + ------------------------------------------------------------- + { "double character symbols", + "== >= <= ~=", + PASS, "1 TK_EQ\n1 TK_GE\n1 TK_LE\n1 TK_NE\n", + }, + ------------------------------------------------------------- + { "simple identifiers", + "abc ABC", + PASS, "1 TK_NAME = abc\n1 TK_NAME = ABC\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "more identifiers", + "_abc _ABC", + PASS, "1 TK_NAME = _abc\n1 TK_NAME = _ABC\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "still more identifiers", + "_aB_ _123", + PASS, "1 TK_NAME = _aB_\n1 TK_NAME = _123\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "invalid control character", + "\4", + FAIL, ":1: invalid control char near `char(4)'", + }, + ------------------------------------------------------------- + { "single character symbols 2", + "` ! @ $ %", + PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", + }, + ------------------------------------------------------------- + { "single character symbols 3", + "^ & * ( )", + PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", + }, + ------------------------------------------------------------- + { "single character symbols 4", + "_ - + \\ |", + PASS, "1 TK_NAME = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", + }, + ------------------------------------------------------------- + { "single character symbols 5", + "{ } [ ] :", + PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", + }, + ------------------------------------------------------------- + { "single character symbols 6", + "; , . / ?", + PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", + }, + ------------------------------------------------------------- + } + ------------------------------------------------------------------ + -- perform a test case + ------------------------------------------------------------------ + function do_test_case(count, test_case) + if comment == "" then return end -- skip empty entries + local comment, chunk, outcome, matcher = unpack(test_case) + local result = PASS + local output = "" + -- initialize lexer + local L, LS = {}, {} + local z = luaZ:init(luaZ:make_getS(chunk), nil, "=test") + luaX:setinput(L, LS, z, z.name) + -- lexer test loop + repeat + -- protected call + local status, token = pcall(luaX.lex, luaX, LS, LS.t) + LS.t.token = token + output = output..LS.linenumber.." " + if status then + -- successful call + if string.len(token) > 1 then + if token == "TK_NAME" + or token == "TK_NUMBER" + or token == "TK_STRING" then + token = token.." = "..LS.t.seminfo + end + elseif string.byte(token) >= 32 then -- displayable chars + token = "CHAR = '"..token.."'" + else -- control characters + token = "CHAR = (".. string.byte(token)..")" + end + output = output..token.."\n" + else + -- failed call + output = output..token -- token is the error message + result = FAIL + break + end + until LS.t.token == "TK_EOS" + -- decision making and reporting + local head = "Test "..count..": "..comment + if matcher == "" then + -- nothing to check against, display for manual check + print(head.."\nMANUAL please check manually".. + "\n--chunk---------------------------------\n"..chunk.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + return + else + if outcome == PASS then + -- success expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == PASS then + if not BRIEF then print(head.."\nOK expected success\n") end + return + end + else + -- failure expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == FAIL then + if not BRIEF then print(head.."\nOK expected failure\n") end + return + end + end + -- failed because of unmatched string or boolean result + local function passfail(status) + if status == PASS then return "PASS" else return "FAIL" end + end + print(head.." *FAILED*".. + "\noutcome="..passfail(outcome).. + "\nactual= "..passfail(result).. + "\n--chunk---------------------------------\n"..chunk.. + "\n--expected------------------------------\n"..matcher.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + end + end + ------------------------------------------------------------------ + -- perform auto testing + ------------------------------------------------------------------ + for i,test_case in ipairs(test_cases) do + do_test_case(i, test_case) + end +end + +auto_test() +--]] diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser.lua new file mode 100644 index 0000000..b9400cc --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser.lua @@ -0,0 +1,60 @@ +--[[-------------------------------------------------------------------- + + test_lparser.lua + Test for lparser.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. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +require("../lzio") +require("../llex") +require("../lopcodes") +require("../ldump") +require("../lcode") +require("../lparser") + +function lua_assert(test) + if not test then error("assertion failed!") end +end + +luaX:init() + +------------------------------------------------------------------------ +-- try 1 +------------------------------------------------------------------------ + +local zio = luaZ:init(luaZ:make_getS("local a = 1"), nil, "=string") +local LuaState = {} +local Func = luaY:parser(LuaState, zio, nil) + +--[[ +for i, v in Func do + if type(v) == "string" or type(v) == "number" then + print(i, v) + elseif type(v) == "table" then + print(i, "TABLE") + end +end +--]] + +local Writer, Buff = luaU:make_setF("parse1.out") +luaU:dump(LuaState, Func, Writer, Buff) + +------------------------------------------------------------------------ +-- try 2 +------------------------------------------------------------------------ + +zio = luaZ:init(luaZ:make_getF("sample.lua"), nil, "@sample.lua") +Func = luaY:parser(LuaState, zio, nil) +Writer, Buff = luaU:make_setF("parse2.out") +luaU:dump(LuaState, Func, Writer, Buff) diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser2.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser2.lua new file mode 100644 index 0000000..b912e68 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser2.lua @@ -0,0 +1,202 @@ +--[[-------------------------------------------------------------------- + + test_lparser2.lua + Test for lparser.lua, using the test case file + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * the test cases are in the test_lua directory (test_parser-5.0.lua) +----------------------------------------------------------------------]] + +-- * true if you want an output of all failure cases in native Lua, +-- for checking whether test cases fail where you intend them to +local DEBUG_FAILS = false + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +require("../lzio") +require("../llex") +require("../lopcodes") +require("../ldump") +require("../lcode") +require("../lparser") + +function lua_assert(test) + if not test then error("assertion failed!") end +end + +luaX:init() + +------------------------------------------------------------------------ +-- load test cases +------------------------------------------------------------------------ + +require("../../test_lua/test_parser-5.0") + +local test, expect, heading = {}, {}, {} +local total, total_pass, total_fail = 0, 0, 0 + +for ln in string.gfind(tests_source, "([^\n]*)\n") do + if string.find(ln, "^%s*%-%-") then + -- comment, ignore + else + local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") + if m then + heading[total + 1] = head -- informational heading + else + total = total + 1 + local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") + if n then -- FAIL test case + ln = string.sub(ln, 1, n - 1) -- remove comment + expect[total] = "FAIL" + total_fail = total_fail + 1 + else -- PASS test case + expect[total] = "PASS" + total_pass = total_pass + 1 + end--n + test[total] = ln + end--m + end--ln +end--for + +print("Tests loaded: "..total.." (total), " + ..total_pass.." (passes), " + ..total_fail.." (fails)") + +------------------------------------------------------------------------ +-- verify test cases using native Lua +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then + last_head = head + if DEBUG_FAILS then print("\n"..head.."\n") end + end + ------------------------------------------------------------------ + -- perform test + local f, err = loadstring(test_case) + -- look at outcome + ------------------------------------------------------------------ + if f then-- actual PASS + if expected == "FAIL" then + print("\nVerified as PASS but expected to FAIL".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nVerified as FAIL but expected to PASS".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + print("ERROR: "..err) + os.exit() + end + if DEBUG_FAILS then + print("TEST: "..test_case) + print("ERROR: "..err.."\n") + end + ------------------------------------------------------------------ + end--f +end--for + +print("Test cases verified using native Lua, no anomalies.") + +------------------------------------------------------------------------ +-- dump binary chunks to a file if something goes wrong +------------------------------------------------------------------------ +local function Dump(data, filename) + h = io.open(filename, "wb") + if not h then error("failed to open "..filename.." for writing") end + h:write(data) + h:close() +end + +------------------------------------------------------------------------ +-- test using Yueliang front end +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then last_head = head end + ------------------------------------------------------------------ + -- perform test + local LuaState = {} + local zio = luaZ:init(luaZ:make_getS(test_case), nil, "test") + local status, func = pcall(luaY.parser, luaY, LuaState, zio, nil) + -- look at outcome + ------------------------------------------------------------------ + if status then-- actual PASS + if expected == "PASS" then + -- actual PASS and expected PASS, so check binary chunks + local writer, buff = luaU:make_setS() + luaU:dump(LuaState, func, writer, buff) + local bc1 = buff.data -- Yueliang's output + local f = loadstring(test_case, "test") + local bc2 = string.dump(f) -- Lua's output + local die + -- compare outputs + if string.len(bc1) ~= string.len(bc2) then + Dump(bc1, "bc1.out") + Dump(bc2, "bc2.out") + die = "binary chunk sizes different" + elseif bc1 ~= bc2 then + Dump(bc1, "bc1.out") + Dump(bc2, "bc2.out") + die = "binary chunks different" + else + -- everything checks out! + end + if die then + print("\nTested PASS and expected to PASS, but chunks different".. + "\n------------------------------------------------------") + print("Reason: "..die) + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + else-- expected FAIL + print("\nTested as PASS but expected to FAIL".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nTested as FAIL but expected to PASS".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + print("ERROR: "..err) + os.exit() + end + ------------------------------------------------------------------ + end--status + io.stdout:write("\rTesting ["..i.."]...") +end--for +print(" done.") + +print("Test cases run on Yueliang, no anomalies.") + +-- end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lzio.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lzio.lua new file mode 100644 index 0000000..cfd3f4b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lzio.lua @@ -0,0 +1,55 @@ +--[[-------------------------------------------------------------------- + + test_lzio.lua + Test for lzio.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. + +----------------------------------------------------------------------]] + +-- manual test for lzio.lua lua-style chunk reader + +require("../lzio") + +local z +function dump(z) + while true do + local c = luaZ:zgetc(z) + io.stdout:write("("..c..")") + if c == "EOZ" then break end + end + io.stdout:write("\n") +end + +-- luaZ:make_getS or luaZ:make_getF creates a chunk reader +-- luaZ:init makes a zio stream + +-- [[ +z = luaZ:init(luaZ:make_getS("hello, world!"), nil, "=string") +dump(z) +z = luaZ:init(luaZ:make_getS(", world!"), "hello", "=string") +dump(z) +z = luaZ:init(luaZ:make_getS("line1\nline2\n"), "", "=string") +dump(z) +z = luaZ:init(luaZ:make_getF("test_lzio.lua"), nil, "=string") +dump(z) +--]] + +-- test read beyond end of file +-- bug reported by Adam429 +--[[ +z = luaZ:init(luaZ:make_getF("test_lzio.lua"), nil, "=string") +while true do + local c = luaZ:zgetc(z) + io.stdout:write("("..c..")") + if c == "EOZ" then break end +end +print(luaZ:zgetc(z)) +print(luaZ:zgetc(z)) +io.stdout:write("\n") +--]] diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_number.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_number.lua new file mode 100644 index 0000000..eeabecb --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_number.lua @@ -0,0 +1,174 @@ +--[[-------------------------------------------------------------------- + + test_number.lua + Test for Lua-based number conversion functions in ldump.lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * luaU:from_int(value) does not have overflow checks, but this +-- can presumably be put in for debugging purposes. +-- * TODO: double conversion does not support denormals or NaNs +-- * apparently 0/0 == 0/0 is false (Lua 5.0.2 on Win32/Mingw), so +-- can't use to check for NaNs +----------------------------------------------------------------------]] + +require("../ldump") + +------------------------------------------------------------------------ +-- convert hex string representation to a byte string +-- * must have an even number of hex digits +------------------------------------------------------------------------ +local function from_hexstring(s) + local bs = "" + for i = 1, string.len(s), 2 do + local asc = tonumber(string.sub(s, i, i + 1), 16) + bs = bs..string.char(asc) + end + return bs +end + +------------------------------------------------------------------------ +-- convert a byte string to a hex string representation +-- * big-endian, easier to grok +------------------------------------------------------------------------ +local function to_hexstring(s) + local hs = "" + for i = string.len(s), 1, -1 do + local c = string.byte(string.sub(s, i, i)) + hs = hs..string.format("%02X", c) + end + return hs +end + +------------------------------------------------------------------------ +-- tests for 32-bit signed/unsigned integer +------------------------------------------------------------------------ +local function test_int(value, expected) + local actual = to_hexstring(luaU:from_int(value)) + if not expected or expected == "" then + print(value..": "..actual) + elseif actual ~= expected then + print(value..": FAILED!\n".. + "Converted: "..actual.."\n".. + "Expected: "..expected) + return true + end + return false +end + +local table_int = { + ["0"] = "00000000", + ["1"] = "00000001", + ["256"] = "00000100", + ["-256"] = "FFFFFF00", + ["-1"] = "FFFFFFFF", + ["2147483647"] = "7FFFFFFF", -- LONG_MAX + ["-2147483648"] = "80000000", -- LONG_MIN + ["4294967295"] = "FFFFFFFF", -- ULONG_MAX + --[""] = "", +} + +local success = true +print("Testing luaU:from_int():") +for i, v in pairs(table_int) do + local test_value = tonumber(i) + local expected = v + if test_int(test_value, expected) then + success = false + end +end +if success then + print("All test numbers passed okay.\n") +else + print("There were one or more failures.\n") +end + +------------------------------------------------------------------------ +-- tests for IEEE 754 64-bit double +------------------------------------------------------------------------ + +local function test_double(value, expected) + local actual = to_hexstring(luaU:from_double(value)) + if not expected or expected == "" then + print(value..": "..actual) + elseif actual ~= expected then + print(value..": FAILED!\n".. + "Converted: "..actual.."\n".. + "Expected: "..expected) + return true + end + return false +end + +-- special values, see testing loop for actual lookup +Infinity = 1/0 +Infinity_neg = -1/0 + +-- can't seem to do a comparison test with NaN, so leave them +-- (need to check the IEEE standard on this...) +NaN = 0/0 +NaN_neg = -0/0 +--["NaN"] = "", -- 7FF8000000000000 (djgpp) +--["NaN_neg"] = "", -- FFF8000000000000 (djgpp) + +local table_double = { + -- 0 for exponent, 0 for mantissa + ["0"] = "0000000000000000", + -- 3FF is bias of 1023, so (-1)^0 * (1+0) * 2^0 + ["1"] = "3FF0000000000000", + -- BFF has sign bit on, so (-1)^1 * (1+0) * 2^0 + ["-1"] = "BFF0000000000000", + -- 3FC is bias of 1020, so (-1)^0 * (1+0) * 2^-3 + ["0.125"] = "3FC0000000000000", + ["0.250"] = "3FD0000000000000", + ["0.500"] = "3FE0000000000000", + -- 40F is bias of 1039, so (-1)^0 * (1+0) * 2^16 + ["65536"] = "40F0000000000000", + -- 7FF is bias of 2047, 0 for mantissa + ["Infinity"] = "7FF0000000000000", + -- FFF has sign bit on, 0 for mantissa + ["Infinity_neg"] = "FFF0000000000000", + -- DBL_MIN, exponent=001 ( 1), mantissa=0000000000000 + ["2.2250738585072014e-308"] = "0010000000000000", + -- DBL_MAX, exponent=7FE (2046), mantissa=FFFFFFFFFFFFF + ["1.7976931348623157e+308"] = "7FEFFFFFFFFFFFFF", +--[[ + -- * the following is for float numbers only * + -- FLT_MIN, exponent=01 ( 1), mantissa=000000 + -- altervative value for FLT_MIN: 1.17549435e-38F + ["1.1754943508222875081e-38"] = "00800000", + -- FLT_MAX, exponent=FE (254), mantissa=7FFFFF + -- altervative value for FLT_MAX: 3.402823466e+38F + ["3.4028234663852885982e+38"] = "7F7FFFFF", +--]] + --[""] = "", +} + +local success = true +print("Testing luaU:from_double():") +for i, v in pairs(table_double) do + local test_value + if not string.find(i, "%d") then + test_value = _G[i] + else + test_value = tonumber(i) + end + local expected = v + if test_double(test_value, expected) then + success = false + end +end +if success then + print("All test numbers passed okay.\n") +else + print("There were one or more failures.\n") +end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/call_graph.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/call_graph.lua new file mode 100644 index 0000000..5c60e17 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/call_graph.lua @@ -0,0 +1,254 @@ +--[[-------------------------------------------------------------------- + + call_graph.lua + Call graph generator. + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * the call tracer wraps function calls in tables to do its work +-- * not very elegant as the namespace of the table/module is affected +-- * tracing using the debugger is probably much more powerful... +-- * use of braces {} allows editors to match braces in the output +-- and do folding, if such facilities are available; for example, the +-- output looks better if Lua syntax highlighting is used on SciTE +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- options +------------------------------------------------------------------------ + +local SHOW_EXPDESC = true -- show expdesc struct data + +------------------------------------------------------------------------ +-- load and initialize modules +------------------------------------------------------------------------ +require("../lzio.lua") +require("../llex.lua") +require("../lopcodes.lua") +require("../ldump.lua") +require("../lcode.lua") +require("../lparser.lua") + +function lua_assert(test) + if not test then error("assertion failed!") end +end +luaX:init() +local LuaState = {} + +------------------------------------------------------------------------ +-- call graph generator +-- * (1) logging functions, (2) the wrapper initializer itself +------------------------------------------------------------------------ + +llog = {} + +------------------------------------------------------------------------ +-- initialize log file; the usual mode is append; can use stdout/stderr +------------------------------------------------------------------------ +function llog:init(filename) + if filename == "stdout" then self.h = io.stdout + elseif filename == "stderr" then self.h = io.stderr + else + self.h = io.open(filename, "ab") + if not self.h then + error("can't open log file "..filename.."for writing") + end + end + self.h:write("\n-- start of log --\n\n") +end + +------------------------------------------------------------------------ +-- cleanly closes log file +------------------------------------------------------------------------ +function llog:exit() + self.h:write("\n-- end of log --\n\n") + if self.h ~= io.stdout and self.h ~= io.stderr then + self.h:close() + end +end + +------------------------------------------------------------------------ +-- logs a message at a particular call depth +------------------------------------------------------------------------ +function llog:msg(msg, level) + if level then msg = string.rep(" ", level)..msg end + self.h:write(msg) + self.h:flush() +end + +------------------------------------------------------------------------ +-- set up wrapper functions to do tracing on a per-module basis +------------------------------------------------------------------------ +function llog:calltrace(parms) + ------------------------------------------------------------------ + -- process parameters + ------------------------------------------------------------------ + local module = parms.module + local modulename = parms.modulename + if type(module) ~= "table" then + error("module table parameter required") + elseif not modulename then + error("module name parameter required") + end + ------------------------------------------------------------------ + -- use either allow or deny list + ------------------------------------------------------------------ + local allow = parms.allow or {} + local deny = parms.deny or {} + if table.getn(allow) > 0 and table.getn(deny) > 0 then + error("can't apply both allow and deny lists at the same time") + end + ------------------------------------------------------------------ + -- select functions to wrap + ------------------------------------------------------------------ + local flist = {} + for i, f in pairs(module) do + local wrapthis + if table.getn(allow) > 0 then -- allow some only + wrapthis = false + for j, v in ipairs(allow) do + if i == v then wrapthis = true; break end + end + elseif table.getn(deny) > 0 then -- deny some only + wrapthis = true + for j, v in ipairs(deny) do + if i == v then wrapthis = false; break end + end + else -- default include + wrapthis = true + end + if wrapthis then flist[i] = f end + end + ------------------------------------------------------------------ + -- wrapped function(s) in a module for tracing + ------------------------------------------------------------------ + llog.level = 0 -- nesting level + for i, f in pairs(flist) do + local ModuleName = modulename..":" + local OldName, OldFunc = i, f + if type(OldFunc) == "function" then + local NewName = "__"..OldName + while module[NewName] ~= nil do -- avoid collisions + NewName = "_"..NewName + end + module[NewName] = OldFunc + module[OldName] = + ---------------------------------------------------------- + -- wrapper function for a module's function + -- old function XYZ is renamed __XYZ + ---------------------------------------------------------- + function(self, ...) + local parms = " (" + local exps = {} + -- look for expdesc structs, identify FuncState structs too + local function checkexpdesc(v) + local typ = type(v) + if typ == "table" then + if v.code then return "func" + elseif v.L then return "ls" + elseif v.seminfo then return "token" + elseif v.k then + table.insert(exps, v) + return "exp"..table.getn(exps) + end + end + return typ + end + -- format parameters for printing + for i,v in ipairs(arg) do + if type(v) == "number" then parms = parms..v.."," + elseif type(v) == "string" then parms = parms.."'"..v.."'," + elseif type(v) == "boolean" then parms = parms..tostring(v).."," + elseif SHOW_EXPDESC then parms = parms..checkexpdesc(v).."," + else parms = parms..type(v).."," + end + end + if table.getn(arg) > 0 then -- chop last comma + parms = string.sub(parms, 1, -2) + end + -- up level + llog:msg(ModuleName..OldName..parms..") {\n", llog.level) + llog.level = llog.level + 1 + -- display contents of expdesc + if SHOW_EXPDESC and table.getn(exps) > 0 then + for i,v in ipairs(exps) do + parms = "k:'"..v.k.."'," + if v.info then parms = parms.."info:"..v.info.."," end + if v.aux then parms = parms.."aux:"..v.aux.."," end + if v.t then parms = parms.."t:"..v.t.."," end + if v.f then parms = parms.."f:"..v.f.."," end + parms = string.sub(parms, 1, -2) + llog:msg("exp"..i.."("..parms..")\n", llog.level) + end + end + -- original function called here... + local retval = {self[NewName](self, unpack(arg))} + -- format return values + local rets = " = " + for i,v in ipairs(retval) do + if type(v) == "number" then rets = rets..v.."," + elseif type(v) == "string" then rets = rets.."'"..v.."'," + elseif type(v) == "boolean" then rets = rets..tostring(v).."," + else rets = rets..type(v).."," + end + end + if table.getn(retval) > 0 then -- chop last comma + rets = string.sub(rets, 1, -2) + else + rets = "" + end + -- down level + llog.level = llog.level - 1 + llog:msg("} "..ModuleName..OldName..rets.."\n", llog.level) + return unpack(retval) + end--function + ---------------------------------------------------------- + --print("patched "..OldName) + end--if + end--for +end + +------------------------------------------------------------------------ +-- testing here +-- * allow/deny works a bit like a somewhat similar Apache syntax +-- * e.g. to show only function 'lex' and 'save' -> allow={"lex","save",} +-- to not show function 'save_and_next' -> deny={"save_and_next",} +-- * you can't do both allow and deny at the same time +------------------------------------------------------------------------ + +-- select the file or stream to output to +--llog:init("calls.log") +llog:init("stdout") + +-- select modules to trace +llog:calltrace{module=luaX, modulename="luaX", allow={"lex"} } + -- here we trace only the main lex() function, to avoid showing + -- too many lexer calls; we want to focus on luaY and luaK +llog:calltrace{module=luaY, modulename="luaY", deny={"growvector"} } + -- growvector() is just a limit checker in Yueliang, so drop it + -- to simplify the output log +llog:calltrace{module=luaK, modulename="luaK"} +--llog:calltrace{module=luaU, modulename="luaU"} + +-- select input stream +local zio = luaZ:init(luaZ:make_getS("local a = 1"), nil, "=string") +--local zio = luaZ:init(luaZ:make_getF("sample.lua"), nil, "@sample.lua") + +-- compile the source +local Func = luaY:parser(LuaState, zio, nil) + +-- write binary chunk +local Writer, Buff = luaU:make_setF("call_graph.out") +luaU:dump(LuaState, Func, Writer, Buff) + +llog:exit() +--end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/calls.log b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/calls.log new file mode 100644 index 0000000..c163f6c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/calls.log @@ -0,0 +1,152 @@ + +-- start of log -- + +luaY:parser (table,table) { + luaY:open_func (table,table) { + luaY:newproto (table) { + } luaY:newproto = table + } luaY:open_func + luaY:next (table) { + luaX:lex (table,table) { + } luaX:lex = 'TK_LOCAL' + } luaY:next + luaY:chunk (table) { + luaY:enterlevel (table) { + } luaY:enterlevel + luaY:block_follow ('TK_LOCAL') { + } luaY:block_follow = false + luaY:statement (table) { + luaY:next (table) { + luaX:lex (table,table) { + } luaX:lex = 'TK_NAME' + } luaY:next + luaY:testnext (table,'TK_FUNCTION') { + } luaY:testnext = false + luaY:localstat (table) { + luaY:str_checkname (table) { + luaY:check_condition (table,true,' expected') { + } luaY:check_condition + luaY:next (table) { + luaX:lex (table,table) { + } luaX:lex = '=' + } luaY:next + } luaY:str_checkname = 'a' + luaY:new_localvar (table,'a',0) { + luaY:registerlocalvar (table,'a') { + luaY:growvector (table,table,0,0) { + } luaY:growvector + } luaY:registerlocalvar = 0 + } luaY:new_localvar + luaY:testnext (table,',') { + } luaY:testnext = false + luaY:testnext (table,'=') { + luaY:next (table) { + luaX:lex (table,table) { + } luaX:lex = 'TK_NUMBER' + } luaY:next + } luaY:testnext = true + luaY:explist1 (table,table) { + luaY:expr (table,table) { + luaY:subexpr (table,table,-1) { + luaY:enterlevel (table) { + } luaY:enterlevel + luaY:getunopr ('TK_NUMBER') { + } luaY:getunopr = 'OPR_NOUNOPR' + luaY:simpleexp (table,table) { + luaK:numberK (table,1) { + luaK:setnvalue (table,1) { + } luaK:setnvalue + luaK:addk (table,table,table) { + luaK:ttisnumber ) { + } luaK:ttisnumber = false + luaY:growvector (table,table,0,0) { + } luaY:growvector + luaK:setnvalue (table,0) { + } luaK:setnvalue + } luaK:addk = 0 + } luaK:numberK = 0 + luaY:init_exp (table,'VK',0) { + } luaY:init_exp + luaY:next (table) { + luaX:lex (table,table) { + } luaX:lex = 'TK_EOS' + } luaY:next + } luaY:simpleexp + luaY:getbinopr ('TK_EOS') { + } luaY:getbinopr = 'OPR_NOBINOPR' + luaY:leavelevel (table) { + } luaY:leavelevel + } luaY:subexpr = 'OPR_NOBINOPR' + } luaY:expr + luaY:testnext (table,',') { + } luaY:testnext = false + } luaY:explist1 = 1 + luaY:adjust_assign (table,1,1,table) { + luaK:exp2nextreg (table,table) { + luaK:dischargevars (table,table) { + } luaK:dischargevars + luaK:freeexp (table,table) { + } luaK:freeexp + luaK:reserveregs (table,1) { + luaK:checkstack (table,1) { + } luaK:checkstack + } luaK:reserveregs + luaK:exp2reg (table,table,0) { + luaK:discharge2reg (table,table,0) { + luaK:dischargevars (table,table) { + } luaK:dischargevars + luaK:codeABx (table,'OP_LOADK',0,0) { + luaK:code (table,table,1) { + luaK:dischargejpc (table) { + luaK:patchlistaux (table,-1,0,255,0,255,0) { + } luaK:patchlistaux + } luaK:dischargejpc + luaY:growvector (table,table,0,0) { + } luaY:growvector + luaY:growvector (table,table,0,0) { + } luaY:growvector + } luaK:code = 0 + } luaK:codeABx = 0 + } luaK:discharge2reg + luaK:hasjumps (table) { + } luaK:hasjumps = false + } luaK:exp2reg + } luaK:exp2nextreg + } luaY:adjust_assign + luaY:adjustlocalvars (table,1) { + luaY:getlocvar (table,0) { + } luaY:getlocvar = table + } luaY:adjustlocalvars + } luaY:localstat + } luaY:statement = false + luaY:testnext (table,';') { + } luaY:testnext = false + luaY:block_follow ('TK_EOS') { + } luaY:block_follow = true + luaY:leavelevel (table) { + } luaY:leavelevel + } luaY:chunk + luaY:check_condition (table,true,' expected') { + } luaY:check_condition + luaY:close_func (table) { + luaY:removevars (table,0) { + luaY:getlocvar (table,0) { + } luaY:getlocvar = table + } luaY:removevars + luaK:codeABC (table,'OP_RETURN',0,1,0) { + luaK:code (table,table,1) { + luaK:dischargejpc (table) { + luaK:patchlistaux (table,-1,1,255,1,255,1) { + } luaK:patchlistaux + } luaK:dischargejpc + luaY:growvector (table,table,1,0) { + } luaY:growvector + luaY:growvector (table,table,1,0) { + } luaY:growvector + } luaK:code = 1 + } luaK:codeABC = 1 + } luaY:close_func +} luaY:parser = table + +-- end of log -- + diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua new file mode 100644 index 0000000..519cd4c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua @@ -0,0 +1,195 @@ +--[[-------------------------------------------------------------------- + + sample_expr.lua + Stand-alone expression parsing demonstrator. + 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. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * this is an interactive demonstrator for implementing expression +-- parsing in ChunkBake, a Lua assembler +-- * evaluation is immediate, and a result is immediately generated +----------------------------------------------------------------------]] + +require("../lzio.lua") +require("../llex.lua") +luaX:init() + +------------------------------------------------------------------------ +-- expression parser +------------------------------------------------------------------------ + +expr = {} + +expr.unop = { + ["TK_NOT"] = true, + ["-"] = true, +} +expr.binop = { + ["^"] = 10, + ["*"] = 7, + ["/"] = 7, + ["+"] = 6, + ["-"] = 6, + ["TK_CONCAT"] = 5, + ["TK_NE"] = 3, + ["TK_EQ"] = 3, + ["<"] = 3, + ["TK_LE"] = 3, + [">"] = 3, + ["TK_GE"] = 3, + ["TK_AND"] = 2, + ["TK_OR"] = 1, +} +expr.binop_r = { + ["^"] = 9, + ["*"] = 7, + ["/"] = 7, + ["+"] = 6, + ["-"] = 6, + ["TK_CONCAT"] = 4, + ["TK_NE"] = 3, + ["TK_EQ"] = 3, + ["<"] = 3, + ["TK_LE"] = 3, + [">"] = 3, + ["TK_GE"] = 3, + ["TK_AND"] = 2, + ["TK_OR"] = 1, +} + +function expr:parse(str) + self.LS = {} + self.L = {} + self.z = luaZ:init(luaZ:make_getS(str), nil, "=string") + luaX:setinput(self.L, self.LS, self.z, self.z.name) + self:token() + local v = self:expr() + if self.tok ~= "TK_EOS" then + io.stderr:write("parse error: some tokens unparsed\n") + end + return v +end + +function expr:token() + self.tok = luaX:lex(self.LS, self.LS.t) + self.seminfo = self.LS.t.seminfo + return self.tok +end + +function expr:simpleexpr() + local tok = self.tok + if tok == "TK_NIL" then + self:token() + return nil + elseif tok == "TK_TRUE" then + self:token() + return true + elseif tok == "TK_FALSE" then + self:token() + return false + elseif tok == "TK_NUMBER" or tok == "TK_STRING" then + self:token() + return self.seminfo + elseif tok == "(" then + self:token() + local v = self:expr() + if self.tok ~= ")" then + io.stderr:write("parse error: expecting ')' to delimit\n") + else + self:token() + return v + end + end + self:token() + io.stderr:write("parse error: "..tok.." encountered, substituting nil\n") + return nil +end + +function expr:subexpr(prev_op) + local v, op + if self.unop[self.tok] then + op = self.tok + self:token() + v = self:subexpr(8) + if op == "TK_NOT" then + v = not v + else-- op == "-" then + v = -v + end + else + v = self:simpleexpr() + end + op = self.tok + if self.binop[op] then + while self.binop[op] and self.binop[op] > prev_op do + self:token() + local v2, next_op = self:subexpr(self.binop_r[op]) + if op == "^" then + v = v ^ v2 + elseif op == "*" then + v = v * v2 + elseif op == "/" then + v = v / v2 + elseif op == "+" then + v = v + v2 + elseif op == "-" then + v = v - v2 + elseif op == "TK_CONCAT" then + v = v .. v2 + elseif op == "TK_NE" then + v = v ~= v2 + elseif op == "TK_EQ" then + v = v == v2 + elseif op == "<" then + v = v < v2 + elseif op == "TK_LE" then + v = v <= v2 + elseif op == ">" then + v = v > v2 + elseif op == "TK_GE" then + v = v >= v2 + elseif op == "TK_AND" then + v = v and v2 + else-- op == "TK_OR" then + v = v or v2 + end + op = next_op + end + end + return v, op +end + +function expr:expr() + return self:subexpr(-1) +end + +------------------------------------------------------------------------ +-- interactive test code +------------------------------------------------------------------------ + +io.stdout:write([[ +Lua-style expression parsing demonstrator. +Type 'exit' or 'quit' at the prompt to terminate session. +]]) +local done = false +while not done do + io.stdout:write(":>") + io.stdout:flush() + local l = io.stdin:read("*l") + if l == nil or (l == "exit" or l == "quit" and not prevline) then + done = true + else + local v = tostring(expr:parse(l)) + io.stdout:write(v, "\n") + end +end--while +--end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/README b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/README new file mode 100644 index 0000000..06fea0a --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/README @@ -0,0 +1,54 @@ +orig-5.1.3 + +This is a straightforward port of the Lua 5.1.3 front end (lexical +analyzer, parser, code generator, binary chunk dumper.) + +The front end files are: + + lopcodes.lua opcode definition + lzio.lua input streams + llex.lua lexical analyzer + lparser.lua parser + lcode.lua code generator + ldump.lua binary chunk dumper + +Status: operational, passes all current tests (non-exhaustive) + +Major test scripts are: + + test/test_llex.lua exercises test cases + test/test_lparser2.lua exercises test cases + +luac.lua is a clone of Lua 5.1.3's luac.lua, except that it generates a +binary chunk using Yueliang's front end implementation. + +See the README file in orig-5.0.3 for a discussion. + +The following is some performance data. Note that absolutely nothing has +been done to optimize the code; it is meant to mirror the original C as +an educational tool. + + lzio llex TOTAL Speed (1) + (bytes) (bytes) (bytes) (KB/s) +---------------------------------------------- +(in orig-5.0.3:) +---------------------------------------------- +normal 2219 12639 14585 404.9 +stripped 1292 7618 8910 +---------------------------------------------- +(in orig-5.0.3:) +---------------------------------------------- +normal - - - 389.7 +stripped - - - +---------------------------------------------- + +(1) Speed was benchmarked using a Sempron 3000+. Benchmark scripts are +in the test directories. Best of first three figures quoted. This is a +measurement of raw lexer speed, i.e. tokens are read but no processing +is done. All files are read in entirely before running the lexer. + +For Lua 5.1.1, see Yueliang 0.2.1, which was the last release of Lua +5.1.1 material. + +For Lua 5.1.2, see Yueliang 0.2.2, which was the last release of Lua +5.1.2 material. diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lcode.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lcode.lua new file mode 100644 index 0000000..4dc8548 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lcode.lua @@ -0,0 +1,1125 @@ +--[[-------------------------------------------------------------------- + + lcode.lua + Lua 5 code generator in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2007 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- 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) +-- * luaM_growvector uses the faux luaY:growvector, for limit checking +-- * some function parameters changed to boolean, additional code +-- translates boolean back to 1/0 for instruction fields +-- +-- Not implemented: +-- * NOTE there is a failed assert in luaK:addk, a porting problem +-- +-- Added: +-- * constant MAXSTACK from llimits.h +-- * luaK:ttisnumber(o) (from lobject.h) +-- * luaK:nvalue(o) (from lobject.h) +-- * luaK:setnilvalue(o) (from lobject.h) +-- * luaK:setnvalue(o, x) (from lobject.h) +-- * luaK:setbvalue(o, x) (from lobject.h) +-- * luaK:sethvalue(o, x) (from lobject.h), parameter L deleted +-- * luaK:setsvalue(o, x) (from lobject.h), parameter L deleted +-- * luaK:numadd, luaK:numsub, luaK:nummul, luaK:numdiv, luaK:nummod, +-- luaK:numpow, luaK:numunm, luaK:numisnan (from luaconf.h) +-- * copyexp(e1, e2) added in luaK:posfix to copy expdesc struct +-- +-- Changed in 5.1.x: +-- * enum BinOpr has a new entry, OPR_MOD +-- * enum UnOpr has a new entry, OPR_LEN +-- * binopistest, unused in 5.0.x, has been deleted +-- * macro setmultret is new +-- * functions isnumeral, luaK_ret, boolK are new +-- * funcion nilK was named nil_constant in 5.0.x +-- * function interface changed: need_value, patchtestreg, concat +-- * TObject now a TValue +-- * functions luaK_setreturns, luaK_setoneret are new +-- * function luaK:setcallreturns deleted, to be replaced by: +-- luaK:setmultret, luaK:ret, luaK:setreturns, luaK:setoneret +-- * functions constfolding, codearith, codecomp are new +-- * luaK:codebinop has been deleted +-- * function luaK_setlist is new +-- * OPR_MULT renamed to OPR_MUL +----------------------------------------------------------------------]] + +-- requires luaP, luaX, luaY +luaK = {} + +------------------------------------------------------------------------ +-- constants used by code generator +------------------------------------------------------------------------ +-- maximum stack for a Lua function +luaK.MAXSTACK = 250 -- (from llimits.h) + +--[[-------------------------------------------------------------------- +-- other functions +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- emulation of TValue macros (these are from lobject.h) +-- * TValue is a table since lcode passes references around +-- * tt member field removed, using Lua's type() instead +-- * for setsvalue, sethvalue, parameter L (deleted here) in lobject.h +-- is used in an assert for testing, see checkliveness(g,obj) +------------------------------------------------------------------------ +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, x) o.value = x end +luaK.setnvalue = luaK.setsvalue +luaK.sethvalue = luaK.setsvalue +luaK.setbvalue = luaK.setsvalue + +------------------------------------------------------------------------ +-- The luai_num* macros define the primitive operations over numbers. +-- * this is not the entire set of primitive operations from luaconf.h +-- * used in luaK:constfolding() +------------------------------------------------------------------------ +function luaK:numadd(a, b) return a + b end +function luaK:numsub(a, b) return a - b end +function luaK:nummul(a, b) return a * b end +function luaK:numdiv(a, b) return a / b end +function luaK:nummod(a, b) return a % b end + -- ((a) - floor((a)/(b))*(b)) /* actual, for reference */ +function luaK:numpow(a, b) return a ^ b end +function luaK:numunm(a) return -a end +function luaK:numisnan(a) return not a == a end + -- a NaN cannot equal another NaN + +--[[-------------------------------------------------------------------- +-- code generator functions +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- 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 + +------------------------------------------------------------------------ +-- grep "ORDER OPR" if you change these enums +------------------------------------------------------------------------ +luaK.BinOpr = { + OPR_ADD = 0, OPR_SUB = 1, OPR_MUL = 2, OPR_DIV = 3, OPR_MOD = 4, OPR_POW = 5, + OPR_CONCAT = 6, + OPR_NE = 7, OPR_EQ = 8, + OPR_LT = 9, OPR_LE = 10, OPR_GT = 11, OPR_GE = 12, + OPR_AND = 13, OPR_OR = 14, + OPR_NOBINOPR = 15, +} + +-- * UnOpr is used by luaK:prefix's op argument, but not directly used +-- because the function receives the symbols as strings, e.g. "OPR_NOT" +luaK.UnOpr = { + OPR_MINUS = 0, OPR_NOT = 1, OPR_LEN = 2, OPR_NOUNOPR = 3 +} + +------------------------------------------------------------------------ +-- returns the instruction object for given e (expdesc), was a macro +------------------------------------------------------------------------ +function luaK:getcode(fs, e) + return fs.f.code[e.info] +end + +------------------------------------------------------------------------ +-- codes an instruction with a signed Bx (sBx) field, was a macro +-- * used in luaK:jump(), (lparser) luaY:forbody() +------------------------------------------------------------------------ +function luaK:codeAsBx(fs, o, A, sBx) + return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx) +end + +------------------------------------------------------------------------ +-- set the expdesc e instruction for multiple returns, was a macro +------------------------------------------------------------------------ +function luaK:setmultret(fs, e) + self:setreturns(fs, e, luaY.LUA_MULTRET) +end + +------------------------------------------------------------------------ +-- there is a jump if patch lists are not identical, was a macro +-- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val() +------------------------------------------------------------------------ +function luaK:hasjumps(e) + return e.t ~= e.f +end + +------------------------------------------------------------------------ +-- true if the expression is a constant number (for constant folding) +-- * used in constfolding(), infix() +------------------------------------------------------------------------ +function luaK:isnumeral(e) + return e.k == "VKNUM" and e.t == self.NO_JUMP and e.f == self.NO_JUMP +end + +------------------------------------------------------------------------ +-- codes loading of nil, optimization done if consecutive locations +-- * used in luaK:discharge2reg(), (lparser) luaY:adjust_assign() +------------------------------------------------------------------------ +function luaK:_nil(fs, from, n) + if fs.pc > fs.lasttarget then -- no jumps to current position? + if fs.pc == 0 then -- function start? + if from >= fs.nactvar then + return -- positions are already clean + end + else + 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 + end + self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +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) + j = self:concat(fs, j, jpc) -- keep them on hold + return j +end + +------------------------------------------------------------------------ +-- codes a RETURN instruction +-- * used in luaY:close_func(), luaY:retstat() +------------------------------------------------------------------------ +function luaK:ret(fs, first, nret) + self:codeABC(fs, "OP_RETURN", first, nret + 1, 0) +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:jumponcond(), luaK:codecomp() +------------------------------------------------------------------------ +function luaK:condjump(fs, op, A, B, C) + self:codeABC(fs, op, A, B, C) + return self:jump(fs) +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:patchlistaux(), luaK:concat() +------------------------------------------------------------------------ +function luaK:fixjump(fs, pc, dest) + local jmp = fs.f.code[pc] + local offset = dest - (pc + 1) + lua_assert(dest ~= self.NO_JUMP) + if math.abs(offset) > luaP.MAXARG_sBx then + luaX:syntaxerror(fs.ls, "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). +-- * used in multiple locations +-- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL +------------------------------------------------------------------------ +function luaK:getlabel(fs) + fs.lasttarget = fs.pc + return fs.pc +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:need_value(), luaK:removevalues(), luaK:patchlistaux(), +-- luaK:concat() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:need_value(), luaK:patchtestreg(), luaK:invertjump() +------------------------------------------------------------------------ +function luaK:getjumpcontrol(fs, pc) + local pi = fs.f.code[pc] + local ppi = fs.f.code[pc - 1] + if pc >= 1 and luaP:testTMode(luaP:GET_OPCODE(ppi)) ~= 0 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) +-- * return value changed to boolean +-- * used only in luaK:exp2reg() +------------------------------------------------------------------------ +function luaK:need_value(fs, list) + while list ~= self.NO_JUMP do + local i = self:getjumpcontrol(fs, list) + if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then return true end + list = self:getjump(fs, list) + end + return false -- not found +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:removevalues(), luaK:patchlistaux() +------------------------------------------------------------------------ +function luaK:patchtestreg(fs, node, reg) + local i = self:getjumpcontrol(fs, node) + if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then + return false -- cannot patch other instructions + end + 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 + -- due to use of a table as i, i cannot be replaced by another table + -- so the following is required; there is no change to ARG_C + luaP:SET_OPCODE(i, "OP_TEST") + local b = luaP:GETARG_B(i) + luaP:SETARG_A(i, b) + luaP:SETARG_B(i, 0) + -- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); /* C */ + end + return true +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:codenot() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg() +------------------------------------------------------------------------ +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) -- jump to default target + end + list = _next + end +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:code() +------------------------------------------------------------------------ +function luaK:dischargejpc(fs) + self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc) + fs.jpc = self.NO_JUMP +end + +------------------------------------------------------------------------ +-- +-- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody() +------------------------------------------------------------------------ +function luaK:patchlist(fs, list, target) + if target == fs.pc then + self:patchtohere(fs, list) + else + lua_assert(target < fs.pc) + self:patchlistaux(fs, list, target, luaP.NO_REG, target) + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +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 +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:concat(fs, l1, l2) + if l2 == self.NO_JUMP then return l1 + elseif l1 == self.NO_JUMP then + return l2 + 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 +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:reserveregs(), (lparser) luaY:forlist() +------------------------------------------------------------------------ +function luaK:checkstack(fs, n) + local newstack = fs.freereg + n + if newstack > fs.f.maxstacksize then + if newstack >= self.MAXSTACK then + luaX:syntaxerror(fs.ls, "function or expression too complex") + end + fs.f.maxstacksize = newstack + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:reserveregs(fs, n) + self:checkstack(fs, n) + fs.freereg = fs.freereg + n +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:freeexp(), luaK:dischargevars() +------------------------------------------------------------------------ +function luaK:freereg(fs, reg) + if not luaP:ISK(reg) and reg >= fs.nactvar then + fs.freereg = fs.freereg - 1 + lua_assert(reg == fs.freereg) + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:freeexp(fs, e) + if e.k == "VNONRELOC" then + self:freereg(fs, e.info) + end +end + +------------------------------------------------------------------------ +-- * TODO NOTE implementation is not 100% correct, since the assert fails +-- * luaH_set, setobj deleted; direct table access used instead +-- * used in luaK:stringK(), luaK:numberK(), luaK:boolK(), luaK:nilK() +------------------------------------------------------------------------ +function luaK:addk(fs, k, v) + local L = fs.L + local idx = fs.h[k.value] + --TValue *idx = luaH_set(L, fs->h, k); /* C */ + local f = fs.f + if self:ttisnumber(idx) then + --TODO this assert currently FAILS (last tested for 5.0.2) + --lua_assert(fs.f.k[self:nvalue(idx)] == v) + --lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); /* C */ + return self:nvalue(idx) + else -- constant not found; create a new entry + idx = {} + self:setnvalue(idx, fs.nk) + fs.h[k.value] = idx + -- setnvalue(idx, cast_num(fs->nk)); /* C */ + luaY:growvector(L, f.k, fs.nk, f.sizek, nil, + luaP.MAXARG_Bx, "constant table overflow") + -- loop to initialize empty f.k positions not required + f.k[fs.nk] = v + -- setobj(L, &f->k[fs->nk], v); /* C */ + -- luaC_barrier(L, f, v); /* GC */ + local nk = fs.nk + fs.nk = fs.nk + 1 + return nk + end + +end + +------------------------------------------------------------------------ +-- creates and sets a string object +-- * used in (lparser) luaY:codestring(), luaY:singlevar() +------------------------------------------------------------------------ +function luaK:stringK(fs, s) + local o = {} -- TValue + self:setsvalue(o, s) + return self:addk(fs, o, o) +end + +------------------------------------------------------------------------ +-- creates and sets a number object +-- * used in luaK:prefix() for negative (or negation of) numbers +-- * used in (lparser) luaY:simpleexp(), luaY:fornum() +------------------------------------------------------------------------ +function luaK:numberK(fs, r) + local o = {} -- TValue + self:setnvalue(o, r) + return self:addk(fs, o, o) +end + +------------------------------------------------------------------------ +-- creates and sets a boolean object +-- * used only in luaK:exp2RK() +------------------------------------------------------------------------ +function luaK:boolK(fs, b) + local o = {} -- TValue + self:setbvalue(o, b) + return self:addk(fs, o, o) +end + +------------------------------------------------------------------------ +-- creates and sets a nil object +-- * used only in luaK:exp2RK() +------------------------------------------------------------------------ +function luaK:nilK(fs) + local k, v = {}, {} -- TValue + self:setnilvalue(v) + -- cannot use nil as key; instead use table itself to represent nil + self:sethvalue(k, fs.h) + return self:addk(fs, k, v) +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:setmultret(), (lparser) luaY:adjust_assign() +------------------------------------------------------------------------ +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); + luaK:reserveregs(fs, 1) + end +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:dischargevars(), (lparser) luaY:assignment() +------------------------------------------------------------------------ +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" -- can relocate its simple result + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:dischargevars(fs, e) + 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 == "VVARARG" or k == "VCALL" then + self:setoneret(fs, e) + else + -- there is one value available (somewhere) + end +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:exp2reg() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:discharge2anyreg(), luaK:exp2reg() +------------------------------------------------------------------------ +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 == "VK" then + self:codeABx(fs, "OP_LOADK", reg, e.info) + elseif k == "VKNUM" then + self:codeABx(fs, "OP_LOADK", reg, self:numberK(fs, e.nval)) + 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 + lua_assert(e.k == "VVOID" or e.k == "VJMP") + return -- nothing to do... + end + e.info = reg + e.k = "VNONRELOC" +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:jumponcond(), luaK:codenot() +------------------------------------------------------------------------ +function luaK:discharge2anyreg(fs, e) + if e.k ~= "VNONRELOC" then + self:reserveregs(fs, 1) + self:discharge2reg(fs, e, fs.freereg - 1) + end +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar() +------------------------------------------------------------------------ +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) or self:need_value(fs, e.f) then + local fj = (e.k == "VJMP") and self.NO_JUMP or self:jump(fs) + 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 + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:exp2nextreg(fs, e) + self:dischargevars(fs, e) + self:freeexp(fs, e) + self:reserveregs(fs, 1) + self:exp2reg(fs, e, fs.freereg - 1) +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:exp2anyreg(fs, 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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix() +-- * used in (lparser) luaY:yindex() +------------------------------------------------------------------------ +function luaK:exp2val(fs, e) + if self:hasjumps(e) then + self:exp2anyreg(fs, e) + else + self:dischargevars(fs, e) + end +end + +------------------------------------------------------------------------ +-- +-- * used in multiple locations +------------------------------------------------------------------------ +function luaK:exp2RK(fs, e) + self:exp2val(fs, e) + local k = e.k + if k == "VKNUM" or k == "VTRUE" or k == "VFALSE" or k == "VNIL" then + if fs.nk <= luaP.MAXINDEXRK then -- constant fit in RK operand? + -- converted from a 2-deep ternary operator expression + if e.k == "VNIL" then + e.info = self:nilK(fs) + else + e.info = (e.k == "VKNUM") and self:numberK(fs, e.nval) + or 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 + else + -- default + end + -- not a constant in the right range: put it in a register + return self:exp2anyreg(fs, e) +end + +------------------------------------------------------------------------ +-- +-- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat() +------------------------------------------------------------------------ +function luaK:storevar(fs, var, ex) + local k = var.k + if k == "VLOCAL" then + self:freeexp(fs, ex) + self:exp2reg(fs, ex, var.info) + return + elseif k == "VUPVAL" then + local e = self:exp2anyreg(fs, ex) + self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0) + elseif k == "VGLOBAL" then + local e = self:exp2anyreg(fs, ex) + self:codeABx(fs, "OP_SETGLOBAL", e, var.info) + elseif k == "VINDEXED" then + local e = self:exp2RK(fs, ex) + self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e) + else + lua_assert(0) -- invalid var kind to store + end + self:freeexp(fs, ex) +end + +------------------------------------------------------------------------ +-- +-- * used only in (lparser) luaY:primaryexp() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:goiftrue(), luaK:codenot() +------------------------------------------------------------------------ +function luaK:invertjump(fs, e) + local pc = self:getjumpcontrol(fs, e.info) + lua_assert(luaP:testTMode(luaP:GET_OPCODE(pc)) ~= 0 and + luaP:GET_OPCODE(pc) ~= "OP_TESTSET" and + luaP:GET_OPCODE(pc) ~= "OP_TEST") + luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0) +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:goiftrue(), luaK:goiffalse() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:infix(), (lparser) luaY:cond() +------------------------------------------------------------------------ +function luaK:goiftrue(fs, e) + local pc -- pc of last jump + self:dischargevars(fs, e) + local k = e.k + if k == "VK" or k == "VKNUM" or k == "VTRUE" 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 + +------------------------------------------------------------------------ +-- +-- * used in luaK:infix() +------------------------------------------------------------------------ +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 + +------------------------------------------------------------------------ +-- +-- * used only in luaK:prefix() +------------------------------------------------------------------------ +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 + lua_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 + +------------------------------------------------------------------------ +-- +-- * used in (lparser) luaY:field(), luaY:primaryexp() +------------------------------------------------------------------------ +function luaK:indexed(fs, t, k) + t.aux = self:exp2RK(fs, k) + t.k = "VINDEXED" +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:codearith() +------------------------------------------------------------------------ +function luaK:constfolding(op, e1, e2) + local r + if not self:isnumeral(e1) or not self:isnumeral(e2) then return false end + local v1 = e1.nval + local v2 = e2.nval + if op == "OP_ADD" then + r = self:numadd(v1, v2) + elseif op == "OP_SUB" then + r = self:numsub(v1, v2) + elseif op == "OP_MUL" then + r = self:nummul(v1, v2) + elseif op == "OP_DIV" then + if v2 == 0 then return false end -- do not attempt to divide by 0 + r = self:numdiv(v1, v2) + elseif op == "OP_MOD" then + if v2 == 0 then return false end -- do not attempt to divide by 0 + r = self:nummod(v1, v2) + elseif op == "OP_POW" then + r = self:numpow(v1, v2) + elseif op == "OP_UNM" then + r = self:numunm(v1) + elseif op == "OP_LEN" then + return false -- no constant folding for 'len' + else + lua_assert(0) + r = 0 + end + if self:numisnan(r) then return false end -- do not attempt to produce NaN + e1.nval = r + return true +end + +------------------------------------------------------------------------ +-- +-- * used in luaK:prefix(), luaK:posfix() +------------------------------------------------------------------------ +function luaK:codearith(fs, op, e1, e2) + if self:constfolding(op, e1, e2) then + return + else + local o2 = (op ~= "OP_UNM" and op ~= "OP_LEN") and self:exp2RK(fs, e2) or 0 + local o1 = self:exp2RK(fs, e1) + if o1 > o2 then + self:freeexp(fs, e1) + self:freeexp(fs, e2) + else + self:freeexp(fs, e2) + self:freeexp(fs, e1) + end + e1.info = self:codeABC(fs, op, 0, o1, o2) + e1.k = "VRELOCABLE" + end +end + +------------------------------------------------------------------------ +-- +-- * used only in luaK:posfix() +------------------------------------------------------------------------ +function luaK:codecomp(fs, op, cond, e1, e2) + local o1 = self:exp2RK(fs, e1) + local o2 = self:exp2RK(fs, e2) + self:freeexp(fs, e2) + self:freeexp(fs, e1) + if cond == 0 and op ~= "OP_EQ" then + -- exchange args to replace by `<' or `<=' + o1, o2 = o2, o1 -- o1 <==> o2 + cond = 1 + end + e1.info = self:condjump(fs, op, cond, o1, o2) + e1.k = "VJMP" +end + +------------------------------------------------------------------------ +-- +-- * used only in (lparser) luaY:subexpr() +------------------------------------------------------------------------ +function luaK:prefix(fs, op, e) + local e2 = {} -- expdesc + e2.t, e2.f = self.NO_JUMP, self.NO_JUMP + e2.k = "VKNUM" + e2.nval = 0 + if op == "OPR_MINUS" then + if not self:isnumeral(e) then + self:exp2anyreg(fs, e) -- cannot operate on non-numeric constants + end + self:codearith(fs, "OP_UNM", e, e2) + elseif op == "OPR_NOT" then + self:codenot(fs, e) + elseif op == "OPR_LEN" then + self:exp2anyreg(fs, e) -- cannot operate on constants + self:codearith(fs, "OP_LEN", e, e2) + else + lua_assert(0) + end +end + +------------------------------------------------------------------------ +-- +-- * used only in (lparser) luaY:subexpr() +------------------------------------------------------------------------ +function luaK:infix(fs, op, v) + if op == "OPR_AND" then + self:goiftrue(fs, v) + elseif op == "OPR_OR" then + self:goiffalse(fs, v) + elseif op == "OPR_CONCAT" then + self:exp2nextreg(fs, v) -- operand must be on the 'stack' + elseif op == "OPR_ADD" or op == "OPR_SUB" or + op == "OPR_MUL" or op == "OPR_DIV" or + op == "OPR_MOD" or op == "OPR_POW" then + if not self:isnumeral(v) then self:exp2RK(fs, v) end + else + self:exp2RK(fs, v) + end +end + +------------------------------------------------------------------------ +-- +-- * used only in (lparser) luaY:subexpr() +------------------------------------------------------------------------ +-- table lookups to simplify testing +luaK.arith_op = { + OPR_ADD = "OP_ADD", OPR_SUB = "OP_SUB", OPR_MUL = "OP_MUL", + OPR_DIV = "OP_DIV", OPR_MOD = "OP_MOD", OPR_POW = "OP_POW", +} +luaK.comp_op = { + OPR_EQ = "OP_EQ", OPR_NE = "OP_EQ", OPR_LT = "OP_LT", + OPR_LE = "OP_LE", OPR_GT = "OP_LT", OPR_GE = "OP_LE", +} +luaK.comp_cond = { + OPR_EQ = 1, OPR_NE = 0, OPR_LT = 1, + OPR_LE = 1, OPR_GT = 0, OPR_GE = 0, +} +function luaK:posfix(fs, op, e1, e2) + -- needed because e1 = e2 doesn't copy values... + -- * in 5.0.x, only k/info/aux/t/f copied, t for AND, f for OR + -- but here, all elements are copied for completeness' sake + local function copyexp(e1, e2) + e1.k = e2.k + e1.info = e2.info; e1.aux = e2.aux + e1.nval = e2.nval + e1.t = e2.t; e1.f = e2.f + end + if op == "OPR_AND" then + lua_assert(e1.t == self.NO_JUMP) -- list must be closed + self:dischargevars(fs, e2) + e2.f = self:concat(fs, e2.f, e1.f) + copyexp(e1, e2) + elseif op == "OPR_OR" then + lua_assert(e1.f == self.NO_JUMP) -- list must be closed + self:dischargevars(fs, e2) + e2.t = self:concat(fs, e2.t, e1.t) + copyexp(e1, e2) + elseif op == "OPR_CONCAT" then + self:exp2val(fs, e2) + if e2.k == "VRELOCABLE" and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then + lua_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) -- operand must be on the 'stack' + self:codearith(fs, "OP_CONCAT", e1, e2) + end + else + -- the following uses a table lookup in place of conditionals + local arith = self.arith_op[op] + if arith then + self:codearith(fs, arith, e1, e2) + else + local comp = self.comp_op[op] + if comp then + self:codecomp(fs, comp, self.comp_cond[op], e1, e2) + else + lua_assert(0) + end + end--if arith + end--if op +end + +------------------------------------------------------------------------ +-- adjusts debug information for last instruction written, in order to +-- change the line where item comes into existence +-- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat() +------------------------------------------------------------------------ +function luaK:fixline(fs, line) + fs.f.lineinfo[fs.pc - 1] = line +end + +------------------------------------------------------------------------ +-- general function to write an instruction into the instruction buffer, +-- sets debug information too +-- * used in luaK:codeABC(), luaK:codeABx() +-- * called directly by (lparser) luaY:whilestat() +------------------------------------------------------------------------ +function luaK:code(fs, i, line) + local f = fs.f + self:dischargejpc(fs) -- 'pc' will change + -- put new instruction in code array + luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil, + luaY.MAX_INT, "code size overflow") + f.code[fs.pc] = i + -- save corresponding line information + luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil, + luaY.MAX_INT, "code size overflow") + f.lineinfo[fs.pc] = line + local pc = fs.pc + fs.pc = fs.pc + 1 + return pc +end + +------------------------------------------------------------------------ +-- writes an instruction of type ABC +-- * calls luaK:code() +------------------------------------------------------------------------ +function luaK:codeABC(fs, o, a, b, c) + lua_assert(luaP:getOpMode(o) == luaP.OpMode.iABC) + lua_assert(luaP:getBMode(o) ~= luaP.OpArgMask.OpArgN or b == 0) + lua_assert(luaP:getCMode(o) ~= luaP.OpArgMask.OpArgN or c == 0) + return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline) +end + +------------------------------------------------------------------------ +-- writes an instruction of type ABx +-- * calls luaK:code(), called by luaK:codeAsBx() +------------------------------------------------------------------------ +function luaK:codeABx(fs, o, a, bc) + lua_assert(luaP:getOpMode(o) == luaP.OpMode.iABx or + luaP:getOpMode(o) == luaP.OpMode.iAsBx) + lua_assert(luaP:getCMode(o) == luaP.OpArgMask.OpArgN) + return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline) +end + +------------------------------------------------------------------------ +-- +-- * used in (lparser) luaY:closelistfield(), luaY:lastlistfield() +------------------------------------------------------------------------ +function luaK:setlist(fs, base, nelems, tostore) + local c = math.floor((nelems - 1)/luaP.LFIELDS_PER_FLUSH) + 1 + local b = (tostore == luaY.LUA_MULTRET) and 0 or tostore + lua_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, luaP:CREATE_Inst(c), fs.ls.lastline) + end + fs.freereg = base + 1 -- free registers with list values +end + diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/ldump.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/ldump.lua new file mode 100644 index 0000000..b9380e1 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/ldump.lua @@ -0,0 +1,372 @@ +--[[-------------------------------------------------------------------- + + ldump.lua + Save precompiled Lua chunks + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * WARNING! byte order (little endian) and data type sizes for header +-- signature values hard-coded; see luaU:header +-- * chunk writer generators are included, see 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 +-- +-- Not implemented: +-- * DumpVar, DumpMem has been removed +-- * DumpVector folded into folded into DumpDebug, DumpCode +-- +-- Added: +-- * for convenience, the following two functions have been added: +-- 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 lua_Writer/lua_Chunkwriter, and +-- a Lua-based implementation exists, writer() in lstrlib.c) +-- * luaU:ttype(o) (from lobject.h) +-- * for converting number types to its binary equivalent: +-- 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) +-- +-- Changed in 5.1.x: +-- * the dumper was mostly rewritten in Lua 5.1.x, so notes on the +-- differences between 5.0.x and 5.1.x is limited +-- * LUAC_VERSION bumped to 0x51, LUAC_FORMAT added +-- * developer is expected to adjust LUAC_FORMAT in order to identify +-- non-standard binary chunk formats +-- * header signature code is smaller, has been simplified, and is +-- tested as a single unit; its logic is shared with the undumper +-- * no more endian conversion, invalid endianness mean rejection +-- * opcode field sizes are no longer exposed in the header +-- * code moved to front of a prototype, followed by constants +-- * debug information moved to the end of the binary chunk, and the +-- relevant functions folded into a single function +-- * luaU:dump returns a writer status code +-- * chunk writer now implements status code because dumper uses it +-- * luaU:endianness removed +----------------------------------------------------------------------]] + +--requires luaP +luaU = {} + +-- mark for precompiled code ('Lua') (from lua.h) +luaU.LUA_SIGNATURE = "\27Lua" + +-- constants used by dumper (from lua.h) +luaU.LUA_TNUMBER = 3 +luaU.LUA_TSTRING = 4 +luaU.LUA_TNIL = 0 +luaU.LUA_TBOOLEAN = 1 +luaU.LUA_TNONE = -1 + +-- constants for header of binary files (from lundump.h) +luaU.LUAC_VERSION = 0x51 -- this is Lua 5.1 +luaU.LUAC_FORMAT = 0 -- this is the official format +luaU.LUAC_HEADERSIZE = 12 -- size of header of binary files + +--[[-------------------------------------------------------------------- +-- Additional functions to handle chunk writing +-- * to use make_setS and make_setF, see test_ldump.lua elsewhere +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- 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 0 end + buff.data = buff.data..s + return 0 + 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 0 end + if not s then + if buff.h:close() then return 0 end + else + if buff.h:write(s) then return 0 end + end + return 1 + end + return writer, buff +end + +------------------------------------------------------------------------ +-- 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 + +----------------------------------------------------------------------- +-- converts a IEEE754 double number to an 8-byte little-endian string +-- * luaU:from_double() and luaU:from_int() are adapted from ChunkBake +-- * supports +/- Infinity, but not denormals or NaNs +----------------------------------------------------------------------- +function luaU:from_double(x) + local function grab_byte(v) + local c = v % 256 + return (v - c) / 256, string.char(c) + 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 = math.floor(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) + local v = "" + x = math.floor(x) + if x < 0 then x = 4294967296 + x end -- ULONG_MAX+1 + for i = 1, 4 do + local c = x % 256 + v = v..string.char(c); x = math.floor(x / 256) + 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 +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- struct DumpState: +-- L -- lua_State (not used in this script) +-- writer -- lua_Writer (chunk writer function) +-- data -- void* (chunk writer context or data already written) +-- strip -- if true, don't write any debug information +-- status -- if non-zero, an error has occured +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- dumps a block of bytes +-- * lua_unlock(D.L), lua_lock(D.L) unused +------------------------------------------------------------------------ +function luaU:DumpBlock(b, D) + if D.status == 0 then + -- lua_unlock(D->L); + D.status = D.write(b, D.data) + -- lua_lock(D->L); + end +end + +------------------------------------------------------------------------ +-- dumps a char +------------------------------------------------------------------------ +function luaU:DumpChar(y, D) + self:DumpBlock(string.char(y), D) +end + +------------------------------------------------------------------------ +-- dumps a 32-bit signed or unsigned integer (for int) (hard-coded) +------------------------------------------------------------------------ +function luaU:DumpInt(x, D) + self:DumpBlock(self:from_int(x), D) +end + +------------------------------------------------------------------------ +-- dumps a lua_Number (hard-coded as a double) +------------------------------------------------------------------------ +function luaU:DumpNumber(x, D) + self:DumpBlock(self:from_double(x), D) +end + +------------------------------------------------------------------------ +-- dumps a Lua string (size type is hard-coded) +------------------------------------------------------------------------ +function luaU:DumpString(s, D) + if s == nil then + self:DumpInt(0, D) + else + s = s.."\0" -- include trailing '\0' + self:DumpInt(#s, D) + self:DumpBlock(s, D) + end +end + +------------------------------------------------------------------------ +-- dumps instruction block from function prototype +------------------------------------------------------------------------ +function luaU:DumpCode(f, D) + local n = f.sizecode + --was DumpVector + self:DumpInt(n, D) + for i = 0, n - 1 do + self:DumpBlock(luaP:Instruction(f.code[i]), D) + end +end + +------------------------------------------------------------------------ +-- dump constant pool from function prototype +-- * bvalue(o), nvalue(o) and rawtsvalue(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] -- TValue + local tt = self:ttype(o) + self:DumpChar(tt, D) + if tt == self.LUA_TNIL then + elseif tt == self.LUA_TBOOLEAN then + self:DumpChar(o.value and 1 or 0, D) + elseif tt == self.LUA_TNUMBER then + self:DumpNumber(o.value, D) + elseif tt == self.LUA_TSTRING then + self:DumpString(o.value, D) + else + --lua_assert(0) -- cannot happen + end + end + n = f.sizep + self:DumpInt(n, D) + for i = 0, n - 1 do + self:DumpFunction(f.p[i], f.source, D) + end +end + +------------------------------------------------------------------------ +-- dump debug information +------------------------------------------------------------------------ +function luaU:DumpDebug(f, D) + local n + n = D.strip and 0 or f.sizelineinfo -- dump line information + --was DumpVector + self:DumpInt(n, D) + for i = 0, n - 1 do + self:DumpInt(f.lineinfo[i], D) + end + n = D.strip and 0 or f.sizelocvars -- dump local information + self:DumpInt(n, D) + for i = 0, n - 1 do + self:DumpString(f.locvars[i].varname, D) + self:DumpInt(f.locvars[i].startpc, D) + self:DumpInt(f.locvars[i].endpc, D) + end + n = D.strip and 0 or f.sizeupvalues -- dump upvalue information + self:DumpInt(n, D) + for i = 0, n - 1 do + self:DumpString(f.upvalues[i], D) + end +end + +------------------------------------------------------------------------ +-- dump child function prototypes from function prototype +------------------------------------------------------------------------ +function luaU:DumpFunction(f, p, D) + local source = f.source + if source == p or D.strip then source = nil end + self:DumpString(source, D) + self:DumpInt(f.lineDefined, D) + self:DumpInt(f.lastlinedefined, D) + self:DumpChar(f.nups, D) + self:DumpChar(f.numparams, D) + self:DumpChar(f.is_vararg, D) + self:DumpChar(f.maxstacksize, D) + self:DumpCode(f, D) + self:DumpConstants(f, D) + self:DumpDebug(f, D) +end + +------------------------------------------------------------------------ +-- dump Lua header section (some sizes hard-coded) +------------------------------------------------------------------------ +function luaU:DumpHeader(D) + local h = self:header() + assert(#h == self.LUAC_HEADERSIZE) -- fixed buffer now an assert + self:DumpBlock(h, D) +end + +------------------------------------------------------------------------ +-- make header (from lundump.c) +-- returns the header string +------------------------------------------------------------------------ +function luaU:header() + local x = 1 + return self.LUA_SIGNATURE.. + string.char( + self.LUAC_VERSION, + self.LUAC_FORMAT, + x, -- endianness (1=little) + 4, -- sizeof(int) + 4, -- sizeof(size_t) + 4, -- sizeof(Instruction) + 8, -- sizeof(lua_Number) + 0) -- is lua_Number integral? +end + +------------------------------------------------------------------------ +-- dump Lua function as precompiled chunk +-- (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +-- * w, data are created from make_setS, make_setF +------------------------------------------------------------------------ +function luaU:dump(L, f, w, data, strip) + local D = {} -- DumpState + D.L = L + D.write = w + D.data = data + D.strip = strip + D.status = 0 + self:DumpHeader(D) + self:DumpFunction(f, 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) + return D.status +end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/llex.lua new file mode 100644 index 0000000..7949326 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/llex.lua @@ -0,0 +1,686 @@ +--[[-------------------------------------------------------------------- + + llex.lua + Lua lexical analyzer in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * intended to 'imitate' llex.c code; performance is not a concern +-- * tokens are strings; code structure largely retained +-- * deleted stuff (compared to llex.c) are noted, comments retained +-- * nextc() returns the currently read character to simplify coding +-- here; next() in llex.c does not return anything +-- * compatibility code is marked with "--#" comments +-- +-- Added: +-- * luaX:chunkid (function luaO_chunkid from lobject.c) +-- * luaX:str2d (function luaO_str2d from lobject.c) +-- * luaX.LUA_QS used in luaX:lexerror (from luaconf.h) +-- * luaX.LUA_COMPAT_LSTR in luaX:read_long_string (from luaconf.h) +-- * luaX.MAX_INT used in luaX:inclinenumber (from llimits.h) +-- +-- To use the lexer: +-- (1) luaX:init() to initialize the lexer +-- (2) luaX:setinput() to set the input stream to lex +-- (3) call luaX:next() or luaX:luaX:lookahead() to get tokens, +-- until "TK_EOS": luaX:next() +-- * since EOZ is returned as a string, be careful when regexp testing +-- +-- Not implemented: +-- * luaX_newstring: not required by this Lua implementation +-- * buffer MAX_SIZET size limit (from llimits.h) test not implemented +-- in the interest of performance +-- * locale-aware number handling is largely redundant as Lua's +-- tonumber() function is already capable of this +-- +-- Changed in 5.1.x: +-- * TK_NAME token order moved down +-- * string representation for TK_NAME, TK_NUMBER, TK_STRING changed +-- * token struct renamed to lower case (LS -> ls) +-- * LexState struct: removed nestlevel, added decpoint +-- * error message functions have been greatly simplified +-- * token2string renamed to luaX_tokens, exposed in llex.h +-- * lexer now handles all kinds of newlines, including CRLF +-- * shbang first line handling removed from luaX:setinput; +-- it is now done in lauxlib.c (luaL_loadfile) +-- * next(ls) macro renamed to nextc(ls) due to new luaX_next function +-- * EXTRABUFF and MAXNOCHECK removed due to lexer changes +-- * checkbuffer(ls, len) macro deleted +-- * luaX:read_numeral now has 3 support functions: luaX:trydecpoint, +-- luaX:buffreplace and (luaO_str2d from lobject.c) luaX:str2d +-- * luaX:read_numeral is now more promiscuous in slurping characters; +-- hexadecimal numbers was added, locale-aware decimal points too +-- * luaX:skip_sep is new; used by luaX:read_long_string +-- * luaX:read_long_string handles new-style long blocks, with some +-- optional compatibility code +-- * luaX:llex: parts changed to support new-style long blocks +-- * luaX:llex: readname functionality has been folded in +-- * luaX:llex: removed test for control characters +----------------------------------------------------------------------]] + +luaX = {} + +-- FIRST_RESERVED is not required as tokens are manipulated as strings +-- TOKEN_LEN deleted; maximum length of a reserved word not needed + +------------------------------------------------------------------------ +-- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED +------------------------------------------------------------------------ + +-- terminal symbols denoted by reserved words: TK_AND to TK_WHILE +-- other terminal symbols: TK_NAME to TK_EOS +luaX.RESERVED = [[ +TK_AND and +TK_BREAK break +TK_DO do +TK_ELSE else +TK_ELSEIF elseif +TK_END end +TK_FALSE false +TK_FOR for +TK_FUNCTION function +TK_IF if +TK_IN in +TK_LOCAL local +TK_NIL nil +TK_NOT not +TK_OR or +TK_REPEAT repeat +TK_RETURN return +TK_THEN then +TK_TRUE true +TK_UNTIL until +TK_WHILE while +TK_CONCAT .. +TK_DOTS ... +TK_EQ == +TK_GE >= +TK_LE <= +TK_NE ~= +TK_NAME +TK_NUMBER +TK_STRING +TK_EOS ]] + +-- NUM_RESERVED is not required; number of reserved words + +--[[-------------------------------------------------------------------- +-- Instead of passing seminfo, the Token struct (e.g. ls.t) is passed +-- so that lexer functions can use its table element, ls.t.seminfo +-- +-- SemInfo (struct no longer needed, a mixed-type value is used) +-- +-- Token (struct of ls.t and ls.lookahead): +-- token -- token symbol +-- seminfo -- semantics information +-- +-- LexState (struct of ls; ls is initialized by luaX:setinput): +-- current -- current character (charint) +-- linenumber -- input line counter +-- lastline -- line of last token 'consumed' +-- t -- current token (table: struct Token) +-- lookahead -- look ahead token (table: struct Token) +-- fs -- 'FuncState' is private to the parser +-- L -- LuaState +-- z -- input stream +-- buff -- buffer for tokens +-- source -- current source name +-- decpoint -- locale decimal point +-- nestlevel -- level of nested non-terminals +----------------------------------------------------------------------]] + +-- luaX.tokens (was luaX_tokens) is now a hash; see luaX:init + +luaX.MAXSRC = 80 +luaX.MAX_INT = 2147483645 -- constants from elsewhere (see above) +luaX.LUA_QS = "'%s'" +luaX.LUA_COMPAT_LSTR = 1 +--luaX.MAX_SIZET = 4294967293 + +------------------------------------------------------------------------ +-- initialize lexer +-- * original luaX_init has code to create and register token strings +-- * luaX.tokens: TK_* -> token +-- * luaX.enums: token -> TK_* (used in luaX:llex) +------------------------------------------------------------------------ +function luaX:init() + local tokens, enums = {}, {} + for v in string.gmatch(self.RESERVED, "[^\n]+") do + local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)") + tokens[tok] = str + enums[str] = tok + end + self.tokens = tokens + self.enums = enums +end + +------------------------------------------------------------------------ +-- returns a suitably-formatted chunk name or id +-- * from lobject.c, used in llex.c and ldebug.c +-- * the result, out, is returned (was first argument) +------------------------------------------------------------------------ +function luaX:chunkid(source, bufflen) + local out + local first = string.sub(source, 1, 1) + if first == "=" then + out = string.sub(source, 2, bufflen) -- remove first char + else -- out = "source", or "...source" + if first == "@" then + source = string.sub(source, 2) -- skip the '@' + bufflen = bufflen - #" '...' " + local l = #source + out = "" + if l > bufflen then + source = string.sub(source, 1 + l - bufflen) -- get last part of file name + out = out.."..." + end + out = out..source + else -- out = [string "string"] + local len = string.find(source, "[\n\r]") -- stop at first newline + len = len and (len - 1) or #source + bufflen = bufflen - #(" [string \"...\"] ") + if len > bufflen then len = bufflen end + out = "[string \"" + if len < #source then -- must truncate? + out = out..string.sub(source, 1, len).."..." + else + out = out..source + end + out = out.."\"]" + end + end + return out +end + +--[[-------------------------------------------------------------------- +-- Support functions for lexer +-- * all lexer errors eventually reaches lexerror: + syntaxerror -> lexerror +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- look up token and return keyword if found (also called by parser) +------------------------------------------------------------------------ +function luaX:token2str(ls, token) + if string.sub(token, 1, 3) ~= "TK_" then + if string.find(token, "%c") then + return string.format("char(%d)", string.byte(token)) + end + return token + else + return self.tokens[token] + end +end + +------------------------------------------------------------------------ +-- throws a lexer error +-- * txtToken has been made local to luaX:lexerror +-- * can't communicate LUA_ERRSYNTAX, so it is unimplemented +------------------------------------------------------------------------ +function luaX:lexerror(ls, msg, token) + local function txtToken(ls, token) + if token == "TK_NAME" or + token == "TK_STRING" or + token == "TK_NUMBER" then + return ls.buff + else + return self:token2str(ls, token) + end + end + local buff = self:chunkid(ls.source, self.MAXSRC) + local msg = string.format("%s:%d: %s", buff, ls.linenumber, msg) + if token then + msg = string.format("%s near "..self.LUA_QS, msg, txtToken(ls, token)) + end + -- luaD_throw(ls->L, LUA_ERRSYNTAX) + error(msg) +end + +------------------------------------------------------------------------ +-- throws a syntax error (mainly called by parser) +-- * ls.t.token has to be set by the function calling luaX:llex +-- (see luaX:next and luaX:lookahead elsewhere in this file) +------------------------------------------------------------------------ +function luaX:syntaxerror(ls, msg) + self:lexerror(ls, msg, ls.t.token) +end + +------------------------------------------------------------------------ +-- move on to next line +------------------------------------------------------------------------ +function luaX:currIsNewline(ls) + return ls.current == "\n" or ls.current == "\r" +end + +function luaX:inclinenumber(ls) + local old = ls.current + -- lua_assert(currIsNewline(ls)) + self:nextc(ls) -- skip '\n' or '\r' + if self:currIsNewline(ls) and ls.current ~= old then + self:nextc(ls) -- skip '\n\r' or '\r\n' + end + ls.linenumber = ls.linenumber + 1 + if ls.linenumber >= self.MAX_INT then + self:syntaxerror(ls, "chunk has too many lines") + end +end + +------------------------------------------------------------------------ +-- initializes an input stream for lexing +-- * if ls (the lexer state) is passed as a table, then it is filled in, +-- otherwise it has to be retrieved as a return value +-- * LUA_MINBUFFER not used; buffer handling not required any more +------------------------------------------------------------------------ +function luaX:setinput(L, ls, z, source) + if not ls then ls = {} end -- create struct + if not ls.lookahead then ls.lookahead = {} end + if not ls.t then ls.t = {} end + ls.decpoint = "." + ls.L = L + ls.lookahead.token = "TK_EOS" -- no look-ahead token + ls.z = z + ls.fs = nil + ls.linenumber = 1 + ls.lastline = 1 + ls.source = source + self:nextc(ls) -- read first char +end + +--[[-------------------------------------------------------------------- +-- LEXICAL ANALYZER +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- checks if current character read is found in the set 'set' +------------------------------------------------------------------------ +function luaX:check_next(ls, set) + if not string.find(set, ls.current, 1, 1) then + return false + end + self:save_and_next(ls) + return true +end + +------------------------------------------------------------------------ +-- retrieve next token, checking the lookahead buffer if necessary +-- * note that the macro next(ls) in llex.c is now luaX:nextc +-- * utilized used in lparser.c (various places) +------------------------------------------------------------------------ +function luaX:next(ls) + ls.lastline = ls.linenumber + if ls.lookahead.token ~= "TK_EOS" then -- is there a look-ahead token? + -- this must be copy-by-value + ls.t.seminfo = ls.lookahead.seminfo -- use this one + ls.t.token = ls.lookahead.token + ls.lookahead.token = "TK_EOS" -- and discharge it + else + ls.t.token = self:llex(ls, ls.t) -- read next token + end +end + +------------------------------------------------------------------------ +-- fill in the lookahead buffer +-- * utilized used in lparser.c:constructor +------------------------------------------------------------------------ +function luaX:lookahead(ls) + -- lua_assert(ls.lookahead.token == "TK_EOS") + ls.lookahead.token = self:llex(ls, ls.lookahead) +end + +------------------------------------------------------------------------ +-- gets the next character and returns it +-- * this is the next() macro in llex.c; see notes at the beginning +------------------------------------------------------------------------ +function luaX:nextc(ls) + local c = luaZ:zgetc(ls.z) + ls.current = c + return c +end + +------------------------------------------------------------------------ +-- saves the given character into the token buffer +-- * buffer handling code removed, not used in this implementation +-- * test for maximum token buffer length not used, makes things faster +------------------------------------------------------------------------ + +function luaX:save(ls, c) + local buff = ls.buff + -- if you want to use this, please uncomment luaX.MAX_SIZET further up + --if #buff > self.MAX_SIZET then + -- self:lexerror(ls, "lexical element too long") + --end + ls.buff = buff..c +end + +------------------------------------------------------------------------ +-- save current character into token buffer, grabs next character +-- * like luaX:nextc, returns the character read for convenience +------------------------------------------------------------------------ +function luaX:save_and_next(ls) + self:save(ls, ls.current) + return self:nextc(ls) +end + +------------------------------------------------------------------------ +-- LUA_NUMBER +-- * luaX:read_numeral is the main lexer function to read a number +-- * luaX:str2d, luaX:buffreplace, luaX:trydecpoint are support functions +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- string to number converter (was luaO_str2d from lobject.c) +-- * returns the number, nil if fails (originally returns a boolean) +-- * conversion function originally lua_str2number(s,p), a macro which +-- maps to the strtod() function by default (from luaconf.h) +------------------------------------------------------------------------ +function luaX:str2d(s) + local result = tonumber(s) + if result then return result end + -- conversion failed + if string.lower(string.sub(s, 1, 2)) == "0x" then -- maybe an hexadecimal constant? + result = tonumber(s, 16) + if result then return result end -- most common case + -- Was: invalid trailing characters? + -- In C, this function then skips over trailing spaces. + -- true is returned if nothing else is found except for spaces. + -- If there is still something else, then it returns a false. + -- All this is not necessary using Lua's tonumber. + end + return nil +end + +------------------------------------------------------------------------ +-- single-character replacement, for locale-aware decimal points +------------------------------------------------------------------------ +function luaX:buffreplace(ls, from, to) + local result, buff = "", ls.buff + for p = 1, #buff do + local c = string.sub(buff, p, p) + if c == from then c = to end + result = result..c + end + ls.buff = result +end + +------------------------------------------------------------------------ +-- Attempt to convert a number by translating '.' decimal points to +-- the decimal point character used by the current locale. This is not +-- needed in Yueliang as Lua's tonumber() is already locale-aware. +-- Instead, the code is here in case the user implements localeconv(). +------------------------------------------------------------------------ +function luaX:trydecpoint(ls, Token) + -- format error: try to update decimal point separator + local old = ls.decpoint + -- translate the following to Lua if you implement localeconv(): + -- struct lconv *cv = localeconv(); + -- ls->decpoint = (cv ? cv->decimal_point[0] : '.'); + self:buffreplace(ls, old, ls.decpoint) -- try updated decimal separator + local seminfo = self:str2d(ls.buff) + Token.seminfo = seminfo + if not seminfo then + -- format error with correct decimal point: no more options + self:buffreplace(ls, ls.decpoint, ".") -- undo change (for error message) + self:lexerror(ls, "malformed number", "TK_NUMBER") + end +end + +------------------------------------------------------------------------ +-- main number conversion function +-- * "^%w$" needed in the scan in order to detect "EOZ" +------------------------------------------------------------------------ +function luaX:read_numeral(ls, Token) + -- lua_assert(string.find(ls.current, "%d")) + repeat + self:save_and_next(ls) + until string.find(ls.current, "%D") and ls.current ~= "." + if self:check_next(ls, "Ee") then -- 'E'? + self:check_next(ls, "+-") -- optional exponent sign + end + while string.find(ls.current, "^%w$") or ls.current == "_" do + self:save_and_next(ls) + end + self:buffreplace(ls, ".", ls.decpoint) -- follow locale for decimal point + local seminfo = self:str2d(ls.buff) + Token.seminfo = seminfo + if not seminfo then -- format error? + self:trydecpoint(ls, Token) -- try to update decimal point separator + end +end + +------------------------------------------------------------------------ +-- count separators ("=") in a long string delimiter +-- * used by luaX:read_long_string +------------------------------------------------------------------------ +function luaX:skip_sep(ls) + local count = 0 + local s = ls.current + -- lua_assert(s == "[" or s == "]") + self:save_and_next(ls) + while ls.current == "=" do + self:save_and_next(ls) + count = count + 1 + end + return (ls.current == s) and count or (-count) - 1 +end + +------------------------------------------------------------------------ +-- reads a long string or long comment +------------------------------------------------------------------------ +function luaX:read_long_string(ls, Token, sep) + local cont = 0 + self:save_and_next(ls) -- skip 2nd '[' + if self:currIsNewline(ls) then -- string starts with a newline? + self:inclinenumber(ls) -- skip it + end + while true do + local c = ls.current + if c == "EOZ" then + self:lexerror(ls, Token and "unfinished long string" or + "unfinished long comment", "TK_EOS") + elseif c == "[" then + --# compatibility code start + if self.LUA_COMPAT_LSTR then + if self:skip_sep(ls) == sep then + self:save_and_next(ls) -- skip 2nd '[' + cont = cont + 1 + --# compatibility code start + if self.LUA_COMPAT_LSTR == 1 then + if sep == 0 then + self:lexerror(ls, "nesting of [[...]] is deprecated", "[") + end + end + --# compatibility code end + end + end + --# compatibility code end + elseif c == "]" then + if self:skip_sep(ls) == sep then + self:save_and_next(ls) -- skip 2nd ']' + --# compatibility code start + if self.LUA_COMPAT_LSTR and self.LUA_COMPAT_LSTR == 2 then + cont = cont - 1 + if sep == 0 and cont >= 0 then break end + end + --# compatibility code end + break + end + elseif self:currIsNewline(ls) then + self:save(ls, "\n") + self:inclinenumber(ls) + if not Token then ls.buff = "" end -- avoid wasting space + else -- default + if Token then + self:save_and_next(ls) + else + self:nextc(ls) + end + end--if c + end--while + if Token then + local p = 3 + sep + Token.seminfo = string.sub(ls.buff, p, -p) + end +end + +------------------------------------------------------------------------ +-- reads a string +-- * has been restructured significantly compared to the original C code +------------------------------------------------------------------------ + +function luaX:read_string(ls, del, Token) + self:save_and_next(ls) + while ls.current ~= del do + local c = ls.current + if c == "EOZ" then + self:lexerror(ls, "unfinished string", "TK_EOS") + elseif self:currIsNewline(ls) then + self:lexerror(ls, "unfinished string", "TK_STRING") + elseif c == "\\" then + c = self:nextc(ls) -- do not save the '\' + if self:currIsNewline(ls) then -- go through + self:save(ls, "\n") + self:inclinenumber(ls) + elseif c ~= "EOZ" then -- will raise an error next loop + -- escapes handling greatly simplified here: + local i = string.find("abfnrtv", c, 1, 1) + if i then + self:save(ls, string.sub("\a\b\f\n\r\t\v", i, i)) + self:nextc(ls) + elseif not string.find(c, "%d") then + self:save_and_next(ls) -- handles \\, \", \', and \? + else -- \xxx + c, i = 0, 0 + repeat + c = 10 * c + ls.current + self:nextc(ls) + i = i + 1 + until i >= 3 or not string.find(ls.current, "%d") + if c > 255 then -- UCHAR_MAX + self:lexerror(ls, "escape sequence too large", "TK_STRING") + end + self:save(ls, string.char(c)) + end + end + else + self:save_and_next(ls) + end--if c + end--while + self:save_and_next(ls) -- skip delimiter + Token.seminfo = string.sub(ls.buff, 2, -2) +end + +------------------------------------------------------------------------ +-- main lexer function +------------------------------------------------------------------------ +function luaX:llex(ls, Token) + ls.buff = "" + while true do + local c = ls.current + ---------------------------------------------------------------- + if self:currIsNewline(ls) then + self:inclinenumber(ls) + ---------------------------------------------------------------- + elseif c == "-" then + c = self:nextc(ls) + if c ~= "-" then return "-" end + -- else is a comment + local sep = -1 + if self:nextc(ls) == '[' then + sep = self:skip_sep(ls) + ls.buff = "" -- 'skip_sep' may dirty the buffer + end + if sep >= 0 then + self:read_long_string(ls, nil, sep) -- long comment + ls.buff = "" + else -- else short comment + while not self:currIsNewline(ls) and ls.current ~= "EOZ" do + self:nextc(ls) + end + end + ---------------------------------------------------------------- + elseif c == "[" then + local sep = self:skip_sep(ls) + if sep >= 0 then + self:read_long_string(ls, Token, sep) + return "TK_STRING" + elseif sep == -1 then + return "[" + else + self:lexerror(ls, "invalid long string delimiter", "TK_STRING") + end + ---------------------------------------------------------------- + elseif c == "=" then + c = self:nextc(ls) + if c ~= "=" then return "=" + else self:nextc(ls); return "TK_EQ" end + ---------------------------------------------------------------- + elseif c == "<" then + c = self:nextc(ls) + if c ~= "=" then return "<" + else self:nextc(ls); return "TK_LE" end + ---------------------------------------------------------------- + elseif c == ">" then + c = self:nextc(ls) + if c ~= "=" then return ">" + else self:nextc(ls); return "TK_GE" end + ---------------------------------------------------------------- + elseif c == "~" then + c = self:nextc(ls) + if c ~= "=" then return "~" + else self:nextc(ls); return "TK_NE" end + ---------------------------------------------------------------- + elseif c == "\"" or c == "'" then + self:read_string(ls, c, Token) + return "TK_STRING" + ---------------------------------------------------------------- + elseif c == "." then + c = self:save_and_next(ls) + if self:check_next(ls, ".") then + if self:check_next(ls, ".") then + return "TK_DOTS" -- ... + else return "TK_CONCAT" -- .. + end + elseif not string.find(c, "%d") then + return "." + else + self:read_numeral(ls, Token) + return "TK_NUMBER" + end + ---------------------------------------------------------------- + elseif c == "EOZ" then + return "TK_EOS" + ---------------------------------------------------------------- + else -- default + if string.find(c, "%s") then + -- lua_assert(self:currIsNewline(ls)) + self:nextc(ls) + elseif string.find(c, "%d") then + self:read_numeral(ls, Token) + return "TK_NUMBER" + elseif string.find(c, "[_%a]") then + -- identifier or reserved word + repeat + c = self:save_and_next(ls) + until c == "EOZ" or not string.find(c, "[_%w]") + local ts = ls.buff + local tok = self.enums[ts] + if tok then return tok end -- reserved word? + Token.seminfo = ts + return "TK_NAME" + else + self:nextc(ls) + return c -- single-char tokens (+ - / ...) + end + ---------------------------------------------------------------- + end--if c + end--while +end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lopcodes.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lopcodes.lua new file mode 100644 index 0000000..e7dbbe8 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lopcodes.lua @@ -0,0 +1,432 @@ +--[[-------------------------------------------------------------------- + + lopcodes.lua + Lua 5 virtual machine opcodes in Lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * an Instruction is a table with OP, A, B, C, Bx elements; this +-- makes the code easy to follow and should allow instruction handling +-- to work with doubles and ints +-- * WARNING luaP:Instruction outputs instructions encoded in little- +-- endian form and field size and positions are hard-coded +-- +-- Not implemented: +-- * +-- +-- Added: +-- * luaP:CREATE_Inst(c): create an inst from a number (for OP_SETLIST) +-- * luaP:Instruction(i): convert field elements to a 4-char string +-- * luaP:DecodeInst(x): convert 4-char string into field elements +-- +-- Changed in 5.1.x: +-- * POS_OP added, instruction field positions changed +-- * some symbol names may have changed, e.g. LUAI_BITSINT +-- * new operators for RK indices: BITRK, ISK(x), INDEXK(r), RKASK(x) +-- * OP_MOD, OP_LEN is new +-- * OP_TEST is now OP_TESTSET, OP_TEST is new +-- * OP_FORLOOP, OP_TFORLOOP adjusted, OP_FORPREP is new +-- * OP_TFORPREP deleted +-- * OP_SETLIST and OP_SETLISTO merged and extended +-- * OP_VARARG is new +-- * many changes to implementation of OpMode data +----------------------------------------------------------------------]] + +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 = 0, iABx = 1, iAsBx = 2 } -- 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_OP = 0 +luaP.POS_A = luaP.POS_OP + luaP.SIZE_OP +luaP.POS_C = luaP.POS_A + luaP.SIZE_A +luaP.POS_B = luaP.POS_C + luaP.SIZE_C +luaP.POS_Bx = luaP.POS_C + +------------------------------------------------------------------------ +-- limits for opcode arguments. +-- we use (signed) int to manipulate most arguments, +-- so they must fit in LUAI_BITSINT-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, not required +-- creates a mask with 'n' 0 bits at position 'p' +-- MASK0(n,p) deleted, not required + +--[[-------------------------------------------------------------------- + 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 +-- * Bx is a separate element from B and C, since there is never a need +-- to split Bx in the parser or code generator +------------------------------------------------------------------------ + +-- 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 + +------------------------------------------------------------------------ +-- create an instruction from a number (for OP_SETLIST) +------------------------------------------------------------------------ +function luaP:CREATE_Inst(c) + local o = c % 64 + c = (c - o) / 64 + local a = c % 256 + c = (c - a) / 256 + return self:CREATE_ABx(o, a, c) +end + +------------------------------------------------------------------------ +-- returns a 4-char string little-endian encoded form of an instruction +------------------------------------------------------------------------ +function luaP:Instruction(i) + if i.Bx then + -- change to OP/A/B/C format + i.C = i.Bx % 512 + i.B = (i.Bx - i.C) / 512 + end + local I = i.A * 64 + i.OP + local c0 = I % 256 + I = i.C * 64 + (I - c0) / 256 -- 6 bits of A left + local c1 = I % 256 + I = i.B * 128 + (I - c1) / 256 -- 7 bits of C left + local c2 = I % 256 + local c3 = (I - c2) / 256 + return string.char(c0, c1, c2, c3) +end + +------------------------------------------------------------------------ +-- decodes a 4-char little-endian string into an instruction struct +------------------------------------------------------------------------ +function luaP:DecodeInst(x) + local byte = string.byte + local i = {} + local I = byte(x, 1) + local op = I % 64 + i.OP = op + I = byte(x, 2) * 4 + (I - op) / 64 -- 2 bits of c0 left + local a = I % 256 + i.A = a + I = byte(x, 3) * 4 + (I - a) / 256 -- 2 bits of c1 left + local c = I % 512 + i.C = c + i.B = byte(x, 4) * 2 + (I - c) / 512 -- 1 bits of c2 left + local opmode = self.OpMode[tonumber(string.sub(self.opmodes[op + 1], 7, 7))] + if opmode ~= "iABC" then + i.Bx = i.B * 512 + i.C + end + return i +end + +------------------------------------------------------------------------ +-- Macros to operate RK indices +-- * these use arithmetic instead of bit ops +------------------------------------------------------------------------ + +-- this bit 1 means constant (0 means register) +luaP.BITRK = math.ldexp(1, luaP.SIZE_B - 1) + +-- test whether value is a constant +function luaP:ISK(x) return x >= self.BITRK end + +-- gets the index of the constant +function luaP:INDEXK(r) return x - self.BITRK end + +luaP.MAXINDEXRK = luaP.BITRK - 1 + +-- code a constant index as a RK value +function luaP:RKASK(x) return x + self.BITRK 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 ISK(x) then Kst(INDEXK(x)) else R(x) +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- 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_MOD 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_LEN A B R(A) := length of 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 C if not (R(A) <=> C) then pc++ +OP_TESTSET 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)) +OP_VARARG A B R(A), R(A+1), ..., R(A+B-1) = vararg +----------------------------------------------------------------------]] + +luaP.opnames = {} -- opcode names +luaP.OpCode = {} -- lookup name -> number +luaP.ROpCode = {} -- lookup number -> name + +------------------------------------------------------------------------ +-- ORDER OP +------------------------------------------------------------------------ +local i = 0 +for v in string.gmatch([[ +MOVE LOADK LOADBOOL LOADNIL GETUPVAL +GETGLOBAL GETTABLE SETGLOBAL SETUPVAL SETTABLE +NEWTABLE SELF ADD SUB MUL +DIV MOD POW UNM NOT +LEN CONCAT JMP EQ LT +LE TEST TESTSET CALL TAILCALL +RETURN FORLOOP FORPREP TFORLOOP SETLIST +CLOSE CLOSURE VARARG +]], "%S+") 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: + (*) 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'. + (*) In OP_VARARG, if (B == 0) then use actual number of varargs and + set top (like in OP_CALL with C == 0). + (*) In OP_RETURN, if (B == 0) then return up to 'top' + (*) In OP_SETLIST, if (B == 0) then B = 'top'; + if (C == 0) then next 'instruction' is real C + (*) For comparisons, A specifies what condition the test should accept + (true or false). + (*) All 'skips' (pc++) assume that next instruction is a jump +=========================================================================== +--]] + +--[[-------------------------------------------------------------------- + masks for instruction properties. The format is: + bits 0-1: op mode + bits 2-3: C arg mode + bits 4-5: B arg mode + bit 6: instruction set register A + bit 7: operator is a test + + for OpArgMask: + OpArgN - argument is not used + OpArgU - argument is used + OpArgR - argument is a register or a jump offset + OpArgK - argument is a constant or register/constant +----------------------------------------------------------------------]] + +-- was enum OpArgMask +luaP.OpArgMask = { OpArgN = 0, OpArgU = 1, OpArgR = 2, OpArgK = 3 } + +------------------------------------------------------------------------ +-- e.g. to compare with symbols, luaP:getOpMode(...) == luaP.OpCode.iABC +-- * accepts opcode parameter as strings, e.g. "OP_MOVE" +------------------------------------------------------------------------ + +function luaP:getOpMode(m) + return self.opmodes[self.OpCode[m]] % 4 +end + +function luaP:getBMode(m) + return math.floor(self.opmodes[self.OpCode[m]] / 16) % 4 +end + +function luaP:getCMode(m) + return math.floor(self.opmodes[self.OpCode[m]] / 4) % 4 +end + +function luaP:testAMode(m) + return math.floor(self.opmodes[self.OpCode[m]] / 64) % 2 +end + +function luaP:testTMode(m) + return math.floor(self.opmodes[self.OpCode[m]] / 128) +end + +-- luaP_opnames[] is set above, as the luaP.opnames table + +-- number of list items to accumulate before a SETLIST instruction +luaP.LFIELDS_PER_FLUSH = 50 + +------------------------------------------------------------------------ +-- build instruction properties array +-- * deliberately coded to look like the C equivalent +------------------------------------------------------------------------ +local function opmode(t, a, b, c, m) + local luaP = luaP + return t * 128 + a * 64 + + luaP.OpArgMask[b] * 16 + luaP.OpArgMask[c] * 4 + luaP.OpMode[m] +end + +-- ORDER OP +luaP.opmodes = { +-- T A B C mode opcode + opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_LOADK + opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_LOADBOOL + opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LOADNIL + opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_GETUPVAL + opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_GETGLOBAL + opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_GETTABLE + opmode(0, 0, "OpArgK", "OpArgN", "iABx"), -- OP_SETGLOBAL + opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_SETUPVAL + opmode(0, 0, "OpArgK", "OpArgK", "iABC"), -- OP_SETTABLE + opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_NEWTABLE + opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_SELF + opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_ADD + opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_SUB + opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MUL + opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_DIV + opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MOD + opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_POW + opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_UNM + opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_NOT + opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LEN + opmode(0, 1, "OpArgR", "OpArgR", "iABC"), -- OP_CONCAT + opmode(0, 0, "OpArgR", "OpArgN", "iAsBx"), -- OP_JMP + opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_EQ + opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LT + opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LE + opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TEST + opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TESTSET + opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_CALL + opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_TAILCALL + opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_RETURN + opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORLOOP + opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORPREP + opmode(1, 0, "OpArgN", "OpArgU", "iABC"), -- OP_TFORLOOP + opmode(0, 0, "OpArgU", "OpArgU", "iABC"), -- OP_SETLIST + opmode(0, 0, "OpArgN", "OpArgN", "iABC"), -- OP_CLOSE + opmode(0, 1, "OpArgU", "OpArgN", "iABx"), -- OP_CLOSURE + opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_VARARG +} +-- an awkward way to set a zero-indexed table... +luaP.opmodes[0] = + opmode(0, 1, "OpArgR", "OpArgN", "iABC") -- OP_MOVE + diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua new file mode 100644 index 0000000..2535056 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua @@ -0,0 +1,1747 @@ +--[[-------------------------------------------------------------------- + + lparser.lua + Lua 5 parser in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2007 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * some unused C code that were not converted are kept as comments +-- * LUA_COMPAT_VARARG option changed into a comment block +-- * for value/size specific code added, look for 'NOTE: ' +-- +-- Not implemented: +-- * luaX_newstring not needed by this Lua implementation +-- * luaG_checkcode() in lua_assert is not currently implemented +-- +-- Added: +-- * some constants added from various header files +-- * luaY.LUA_QS used in error_expected, check_match (from luaconf.h) +-- * luaY:LUA_QL needed for error messages (from luaconf.h) +-- * luaY:growvector (from lmem.h) -- skeleton only, limit checking +-- * luaY.SHRT_MAX (from ) for registerlocalvar +-- * luaY:newproto (from lfunc.c) +-- * luaY:int2fb (from lobject.c) +-- * NOTE: HASARG_MASK, for implementing a VARARG_HASARG bit operation +-- * NOTE: value-specific code for VARARG_NEEDSARG to replace a bitop +-- +-- Changed in 5.1.x: +-- * various code changes are not detailed... +-- * names of constants may have changed, e.g. added a LUAI_ prefix +-- * struct expkind: added VKNUM, VVARARG; VCALL's info changed? +-- * struct expdesc: added nval +-- * struct FuncState: upvalues data type changed to upvaldesc +-- * macro hasmultret is new +-- * function checklimit moved to parser from lexer +-- * functions anchor_token, errorlimit, checknext are new +-- * checknext is new, equivalent to 5.0.x's check, see check too +-- * luaY:next and luaY:lookahead moved to lexer +-- * break keyword no longer skipped in luaY:breakstat +-- * function new_localvarstr replaced by new_localvarliteral +-- * registerlocalvar limits local variables to SHRT_MAX +-- * create_local deleted, new_localvarliteral used instead +-- * constant LUAI_MAXUPVALUES increased to 60 +-- * constants MAXPARAMS, LUA_MAXPARSERLEVEL, MAXSTACK removed +-- * function interface changed: singlevaraux, singlevar +-- * enterlevel and leavelevel uses nCcalls to track call depth +-- * added a name argument to main entry function, luaY:parser +-- * function luaY_index changed to yindex +-- * luaY:int2fb()'s table size encoding format has been changed +-- * luaY:log2() no longer needed for table constructors +-- * function code_params deleted, functionality folded in parlist +-- * vararg flags handling (is_vararg) changes; also see VARARG_* +-- * LUA_COMPATUPSYNTAX section for old-style upvalues removed +-- * repeatstat() calls chunk() instead of block() +-- * function interface changed: cond, test_then_block +-- * while statement implementation considerably simplified; MAXEXPWHILE +-- and EXTRAEXP no longer required, no limits to the complexity of a +-- while condition +-- * repeat, forbody statement implementation has major changes, +-- mostly due to new scoping behaviour of local variables +-- * OPR_MULT renamed to OPR_MUL +----------------------------------------------------------------------]] + +--requires luaP, luaX, luaK +luaY = {} + +--[[-------------------------------------------------------------------- +-- Expression descriptor +-- * expkind changed to string constants; luaY:assignment was the only +-- function to use a relational operator with this enumeration +-- VVOID -- no value +-- VNIL -- no value +-- VTRUE -- no value +-- VFALSE -- no value +-- VK -- info = index of constant in 'k' +-- VKNUM -- nval = numerical value +-- VLOCAL -- info = local register +-- VUPVAL, -- info = index of upvalue in 'upvalues' +-- VGLOBAL -- info = index of table; aux = index of global name in 'k' +-- VINDEXED -- info = table register; aux = index register (or 'k') +-- VJMP -- info = instruction pc +-- VRELOCABLE -- info = instruction pc +-- VNONRELOC -- info = result register +-- VCALL -- info = instruction pc +-- VVARARG -- info = instruction pc +} ----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- * expdesc in Lua 5.1.x has a union u and another struct s; this Lua +-- implementation ignores all instances of u and s usage +-- struct expdesc: +-- k -- (enum: expkind) +-- info, aux -- (int, int) +-- nval -- (lua_Number) +-- t -- patch list of 'exit when true' +-- f -- patch list of 'exit when false' +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- struct upvaldesc: +-- k -- (lu_byte) +-- info -- (lu_byte) +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- state needed to generate code for a given function +-- struct FuncState: +-- f -- current function header (table: Proto) +-- h -- table to find (and reuse) elements in 'k' (table: Table) +-- prev -- enclosing function (table: FuncState) +-- ls -- lexical state (table: LexState) +-- L -- copy of the Lua state (table: lua_State) +-- bl -- chain of current blocks (table: BlockCnt) +-- pc -- next position to code (equivalent to 'ncode') +-- lasttarget -- 'pc' of last 'jump target' +-- jpc -- list of pending jumps to 'pc' +-- freereg -- first free register +-- nk -- number of elements in 'k' +-- np -- number of elements in 'p' +-- nlocvars -- number of elements in 'locvars' +-- nactvar -- number of active local variables +-- upvalues[LUAI_MAXUPVALUES] -- upvalues (table: upvaldesc) +-- actvar[LUAI_MAXVARS] -- declared-variable stack +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- constants used by parser +-- * picks up duplicate values from luaX if required +------------------------------------------------------------------------ +luaY.LUA_QS = luaX.LUA_QS or "'%s'" -- (from luaconf.h) + +luaY.SHRT_MAX = 32767 -- (from ) +luaY.LUAI_MAXVARS = 200 -- (luaconf.h) +luaY.LUAI_MAXUPVALUES = 60 -- (luaconf.h) +luaY.MAX_INT = luaX.MAX_INT or 2147483645 -- (from llimits.h) + -- * INT_MAX-2 for 32-bit systems +luaY.LUAI_MAXCCALLS = 200 -- (from luaconf.h) + +luaY.VARARG_HASARG = 1 -- (from lobject.h) +-- NOTE: HASARG_MASK is value-specific +luaY.HASARG_MASK = 2 -- this was added for a bitop in parlist() +luaY.VARARG_ISVARARG = 2 +-- NOTE: there is some value-specific code that involves VARARG_NEEDSARG +luaY.VARARG_NEEDSARG = 4 + +luaY.LUA_MULTRET = -1 -- (lua.h) + +--[[-------------------------------------------------------------------- +-- other functions +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- LUA_QL describes how error messages quote program elements. +-- CHANGE it if you want a different appearance. (from luaconf.h) +------------------------------------------------------------------------ +function luaY:LUA_QL(x) + return "'"..x.."'" +end + +------------------------------------------------------------------------ +-- this is a stripped-down luaM_growvector (from lmem.h) which is a +-- macro based on luaM_growaux (in lmem.c); all the following does is +-- reproduce the size limit checking logic of the original function +-- so that error behaviour is identical; all arguments preserved for +-- convenience, even those which are unused +-- * set the t field to nil, since this originally does a sizeof(t) +-- * size (originally a pointer) is never updated, their final values +-- are set by luaY:close_func(), so overall things should still work +------------------------------------------------------------------------ +function luaY:growvector(L, v, nelems, size, t, limit, e) + if nelems >= limit then + error(e) -- was luaG_runerror + end +end + +------------------------------------------------------------------------ +-- initialize a new function prototype structure (from lfunc.c) +-- * used only in open_func() +------------------------------------------------------------------------ +function luaY:newproto(L) + local f = {} -- Proto + -- luaC_link(L, obj2gco(f), LUA_TPROTO); /* GC */ + 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.lastlinedefined = 0 + f.source = nil + return f +end + +------------------------------------------------------------------------ +-- converts an integer to a "floating point byte", represented as +-- (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +-- eeeee != 0 and (xxx) otherwise. +------------------------------------------------------------------------ +function luaY:int2fb(x) + local e = 0 -- exponent + 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 + +--[[-------------------------------------------------------------------- +-- parser functions +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- true of the kind of expression produces multiple return values +------------------------------------------------------------------------ +function luaY:hasmultret(k) + return k == "VCALL" or k == "VVARARG" +end + +------------------------------------------------------------------------ +-- convenience function to access active local i, returns entry +------------------------------------------------------------------------ +function luaY:getlocvar(fs, i) + return fs.f.locvars[ fs.actvar[i] ] +end + +------------------------------------------------------------------------ +-- check a limit, string m provided as an error message +------------------------------------------------------------------------ +function luaY:checklimit(fs, v, l, m) + if v > l then self:errorlimit(fs, l, m) end +end + +--[[-------------------------------------------------------------------- +-- nodes for block list (list of active blocks) +-- struct BlockCnt: +-- previous -- chain (table: BlockCnt) +-- breaklist -- list of jumps out of this loop +-- nactvar -- # active local variables outside the breakable structure +-- upval -- true if some variable in the block is an upvalue (boolean) +-- isbreakable -- true if 'block' is a loop (boolean) +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- prototypes for recursive non-terminal functions +------------------------------------------------------------------------ +-- prototypes deleted; not required in Lua + +------------------------------------------------------------------------ +-- reanchor if last token is has a constant string, see close_func() +-- * used only in close_func() +------------------------------------------------------------------------ +function luaY:anchor_token(ls) + if ls.t.token == "TK_NAME" or ls.t.token == "TK_STRING" then + -- not relevant to Lua implementation of parser + -- local ts = ls.t.seminfo + -- luaX_newstring(ls, getstr(ts), ts->tsv.len); /* C */ + end +end + +------------------------------------------------------------------------ +-- throws a syntax error if token expected is not there +------------------------------------------------------------------------ +function luaY:error_expected(ls, token) + luaX:syntaxerror(ls, + string.format(self.LUA_QS.." expected", luaX:token2str(ls, token))) +end + +------------------------------------------------------------------------ +-- prepares error message for display, for limits exceeded +-- * used only in checklimit() +------------------------------------------------------------------------ +function luaY:errorlimit(fs, limit, what) + local msg = (fs.f.linedefined == 0) and + string.format("main function has more than %d %s", limit, what) or + string.format("function at line %d has more than %d %s", + fs.f.linedefined, limit, what) + luaX:lexerror(fs.ls, msg, 0) +end + +------------------------------------------------------------------------ +-- tests for a token, returns outcome +-- * return value changed to boolean +------------------------------------------------------------------------ +function luaY:testnext(ls, c) + if ls.t.token == c then + luaX:next(ls) + return true + else + return false + end +end + +------------------------------------------------------------------------ +-- check for existence of a token, throws error if not found +------------------------------------------------------------------------ +function luaY:check(ls, c) + if ls.t.token ~= c then + self:error_expected(ls, c) + end +end + +------------------------------------------------------------------------ +-- verify existence of a token, then skip it +------------------------------------------------------------------------ +function luaY:checknext(ls, c) + self:check(ls, c) + luaX:next(ls) +end + +------------------------------------------------------------------------ +-- throws error if condition not matched +------------------------------------------------------------------------ +function luaY:check_condition(ls, c, msg) + if not c then luaX:syntaxerror(ls, msg) end +end + +------------------------------------------------------------------------ +-- verifies token conditions are met or else throw error +------------------------------------------------------------------------ +function luaY:check_match(ls, what, who, where) + if not self:testnext(ls, what) then + if where == ls.linenumber then + self:error_expected(ls, what) + else + luaX:syntaxerror(ls, string.format( + self.LUA_QS.." expected (to close "..self.LUA_QS.." at line %d)", + luaX:token2str(ls, what), luaX:token2str(ls, who), where)) + end + end +end + +------------------------------------------------------------------------ +-- expect that token is a name, return the name +------------------------------------------------------------------------ +function luaY:str_checkname(ls) + self:check(ls, "TK_NAME") + local ts = ls.t.seminfo + luaX:next(ls) + return ts +end + +------------------------------------------------------------------------ +-- initialize a struct expdesc, expression description data structure +------------------------------------------------------------------------ +function luaY:init_exp(e, k, i) + e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP + e.k = k + e.info = i +end + +------------------------------------------------------------------------ +-- adds given string s in string pool, sets e as VK +------------------------------------------------------------------------ +function luaY:codestring(ls, e, s) + self:init_exp(e, "VK", luaK:stringK(ls.fs, s)) +end + +------------------------------------------------------------------------ +-- consume a name token, adds it to string pool, sets e as VK +------------------------------------------------------------------------ +function luaY:checkname(ls, e) + self:codestring(ls, e, self:str_checkname(ls)) +end + +------------------------------------------------------------------------ +-- creates struct entry for a local variable +-- * used only in new_localvar() +------------------------------------------------------------------------ +function luaY:registerlocalvar(ls, varname) + local fs = ls.fs + local f = fs.f + self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars, + nil, self.SHRT_MAX, "too many local variables") + -- loop to initialize empty f.locvar positions not required + f.locvars[fs.nlocvars] = {} -- LocVar + f.locvars[fs.nlocvars].varname = varname + -- luaC_objbarrier(ls.L, f, varname) /* GC */ + local nlocvars = fs.nlocvars + fs.nlocvars = fs.nlocvars + 1 + return nlocvars +end + +------------------------------------------------------------------------ +-- creates a new local variable given a name and an offset from nactvar +-- * used in fornum(), forlist(), parlist(), body() +------------------------------------------------------------------------ +function luaY:new_localvarliteral(ls, v, n) + self:new_localvar(ls, v, n) +end + +------------------------------------------------------------------------ +-- register a local variable, set in active variable list +------------------------------------------------------------------------ +function luaY:new_localvar(ls, name, n) + local fs = ls.fs + self:checklimit(fs, fs.nactvar + n + 1, self.LUAI_MAXVARS, "local variables") + fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name) +end + +------------------------------------------------------------------------ +-- adds nvars number of new local variables, set debug information +------------------------------------------------------------------------ +function luaY:adjustlocalvars(ls, nvars) + local fs = ls.fs + fs.nactvar = fs.nactvar + nvars + for i = nvars, 1, -1 do + self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc + end +end + +------------------------------------------------------------------------ +-- removes a number of locals, set debug information +------------------------------------------------------------------------ +function luaY:removevars(ls, tolevel) + local fs = ls.fs + while fs.nactvar > tolevel do + fs.nactvar = fs.nactvar - 1 + self:getlocvar(fs, fs.nactvar).endpc = fs.pc + end +end + +------------------------------------------------------------------------ +-- returns an existing upvalue index based on the given name, or +-- creates a new upvalue struct entry and returns the new index +-- * used only in singlevaraux() +------------------------------------------------------------------------ +function luaY: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 + lua_assert(f.upvalues[i] == name) + return i + end + end + -- new one + self:checklimit(fs, f.nups + 1, self.LUAI_MAXUPVALUES, "upvalues") + self:growvector(fs.L, f.upvalues, f.nups, f.sizeupvalues, + nil, self.MAX_INT, "") + -- loop to initialize empty f.upvalues positions not required + f.upvalues[f.nups] = name + -- luaC_objbarrier(fs->L, f, name); /* GC */ + lua_assert(v.k == "VLOCAL" or v.k == "VUPVAL") + -- this is a partial copy; only k & info fields used + fs.upvalues[f.nups] = { k = v.k, info = v.info } + local nups = f.nups + f.nups = f.nups + 1 + return nups +end + +------------------------------------------------------------------------ +-- search the local variable namespace of the given fs for a match +-- * used only in singlevaraux() +------------------------------------------------------------------------ +function luaY:searchvar(fs, n) + for i = fs.nactvar - 1, 0, -1 do + if n == self:getlocvar(fs, i).varname then + return i + end + end + return -1 -- not found +end + +------------------------------------------------------------------------ +-- * mark upvalue flags in function states up to a given level +-- * used only in singlevaraux() +------------------------------------------------------------------------ +function luaY: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 + +------------------------------------------------------------------------ +-- handle locals, globals and upvalues and related processing +-- * search mechanism is recursive, calls itself to search parents +-- * used only in singlevar() +------------------------------------------------------------------------ +function luaY:singlevaraux(fs, n, var, base) + if fs == nil then -- no more levels? + self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable + return "VGLOBAL" + else + local v = self:searchvar(fs, n) -- look up at current level + if v >= 0 then + self:init_exp(var, "VLOCAL", v) + if base == 0 then + self:markupval(fs, v) -- local will be used as an upval + end + return "VLOCAL" + else -- not found at current level; try upper one + if self:singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then + return "VGLOBAL" + end + var.info = self:indexupvalue(fs, n, var) -- else was LOCAL or UPVAL + var.k = "VUPVAL" -- upvalue in this level + return "VUPVAL" + end--if v + end--if fs +end + +------------------------------------------------------------------------ +-- consume a name token, creates a variable (global|local|upvalue) +-- * used in prefixexp(), funcname() +------------------------------------------------------------------------ +function luaY:singlevar(ls, var) + local varname = self:str_checkname(ls) + local fs = ls.fs + if self:singlevaraux(fs, varname, var, 1) == "VGLOBAL" then + var.info = luaK:stringK(fs, varname) -- info points to global name + end +end + +------------------------------------------------------------------------ +-- adjust RHS to match LHS in an assignment +-- * used in assignment(), forlist(), localstat() +------------------------------------------------------------------------ +function luaY:adjust_assign(ls, nvars, nexps, e) + local fs = ls.fs + local extra = nvars - nexps + if self:hasmultret(e.k) then + extra = extra + 1 -- includes call itself + if extra <= 0 then extra = 0 end + luaK:setreturns(fs, e, extra) -- last exp. 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 + +------------------------------------------------------------------------ +-- tracks and limits parsing depth, assert check at end of parsing +------------------------------------------------------------------------ +function luaY:enterlevel(ls) + ls.L.nCcalls = ls.L.nCcalls + 1 + if ls.L.nCcalls > self.LUAI_MAXCCALLS then + luaX:lexerror(ls, "chunk has too many syntax levels", 0) + end +end + +------------------------------------------------------------------------ +-- tracks parsing depth, a pair with luaY:enterlevel() +------------------------------------------------------------------------ +function luaY:leavelevel(ls) + ls.L.nCcalls = ls.L.nCcalls - 1 +end + +------------------------------------------------------------------------ +-- enters a code unit, initializes elements +------------------------------------------------------------------------ +function luaY: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 + lua_assert(fs.freereg == fs.nactvar) +end + +------------------------------------------------------------------------ +-- leaves a code unit, close any upvalues +------------------------------------------------------------------------ +function luaY:leaveblock(fs) + local bl = fs.bl + fs.bl = bl.previous + self:removevars(fs.ls, bl.nactvar) + if bl.upval then + luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) + end + -- a block either controls scope or breaks (never both) + lua_assert(not bl.isbreakable or not bl.upval) + lua_assert(bl.nactvar == fs.nactvar) + fs.freereg = fs.nactvar -- free registers + luaK:patchtohere(fs, bl.breaklist) +end + +------------------------------------------------------------------------ +-- implement the instantiation of a function prototype, append list of +-- upvalues after the instantiation instruction +-- * used only in body() +------------------------------------------------------------------------ +function luaY:pushclosure(ls, func, v) + local fs = ls.fs + local f = fs.f + self:growvector(ls.L, f.p, fs.np, f.sizep, nil, + luaP.MAXARG_Bx, "constant table overflow") + -- loop to initialize empty f.p positions not required + f.p[fs.np] = func.f + fs.np = fs.np + 1 + -- luaC_objbarrier(ls->L, f, func->f); /* C */ + self: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 + +------------------------------------------------------------------------ +-- opening of a function +------------------------------------------------------------------------ +function luaY:open_func(ls, fs) + local L = ls.L + local f = self:newproto(ls.L) + fs.f = f + fs.prev = ls.fs -- linked list of funcstates + fs.ls = ls + fs.L = L + ls.fs = fs + fs.pc = 0 + fs.lasttarget = -1 + fs.jpc = luaK.NO_JUMP + fs.freereg = 0 + fs.nk = 0 + fs.np = 0 + fs.nlocvars = 0 + fs.nactvar = 0 + fs.bl = nil + f.source = ls.source + f.maxstacksize = 2 -- registers 0/1 are always valid + fs.h = {} -- constant table; was luaH_new call + -- anchor table of constants and prototype (to avoid being collected) + -- sethvalue2s(L, L->top, fs->h); incr_top(L); /* C */ + -- setptvalue2s(L, L->top, f); incr_top(L); +end + +------------------------------------------------------------------------ +-- closing of a function +------------------------------------------------------------------------ +function luaY:close_func(ls) + local L = ls.L + local fs = ls.fs + local f = fs.f + self:removevars(ls, 0) + luaK:ret(fs, 0, 0) -- final return + -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p, + -- f->locvars, f->upvalues; not required for Lua table arrays + f.sizecode = fs.pc + f.sizelineinfo = fs.pc + f.sizek = fs.nk + f.sizep = fs.np + f.sizelocvars = fs.nlocvars + f.sizeupvalues = f.nups + --lua_assert(luaG_checkcode(f)) -- currently not implemented + lua_assert(fs.bl == nil) + ls.fs = fs.prev + -- the following is not required for this implementation; kept here + -- for completeness + -- L->top -= 2; /* remove table and prototype from the stack */ + -- last token read was anchored in defunct function; must reanchor it + if fs then self:anchor_token(ls) end +end + +------------------------------------------------------------------------ +-- parser initialization function +-- * note additional sub-tables needed for LexState, FuncState +------------------------------------------------------------------------ +function luaY:parser(L, z, buff, name) + local lexstate = {} -- LexState + lexstate.t = {} + lexstate.lookahead = {} + local funcstate = {} -- FuncState + funcstate.upvalues = {} + funcstate.actvar = {} + -- the following nCcalls initialization added for convenience + L.nCcalls = 0 + lexstate.buff = buff + luaX:setinput(L, lexstate, z, name) + self:open_func(lexstate, funcstate) + funcstate.f.is_vararg = self.VARARG_ISVARARG -- main func. is always vararg + luaX:next(lexstate) -- read first token + self:chunk(lexstate) + self:check(lexstate, "TK_EOS") + self:close_func(lexstate) + lua_assert(funcstate.prev == nil) + lua_assert(funcstate.f.nups == 0) + lua_assert(lexstate.fs == nil) + return funcstate.f +end + +--[[-------------------------------------------------------------------- +-- GRAMMAR RULES +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- parse a function name suffix, for function call specifications +-- * used in primaryexp(), funcname() +------------------------------------------------------------------------ +function luaY:field(ls, v) + -- field -> ['.' | ':'] NAME + local fs = ls.fs + local key = {} -- expdesc + luaK:exp2anyreg(fs, v) + luaX:next(ls) -- skip the dot or colon + self:checkname(ls, key) + luaK:indexed(fs, v, key) +end + +------------------------------------------------------------------------ +-- parse a table indexing suffix, for constructors, expressions +-- * used in recfield(), primaryexp() +------------------------------------------------------------------------ +function luaY:yindex(ls, v) + -- index -> '[' expr ']' + luaX:next(ls) -- skip the '[' + self:expr(ls, v) + luaK:exp2val(ls.fs, v) + self:checknext(ls, "]") +end + +--[[-------------------------------------------------------------------- +-- Rules for Constructors +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- struct ConsControl: +-- v -- last list item read (table: struct expdesc) +-- t -- table descriptor (table: struct expdesc) +-- nh -- total number of 'record' elements +-- na -- total number of array elements +-- tostore -- number of array elements pending to be stored +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- parse a table record (hash) field +-- * used in constructor() +------------------------------------------------------------------------ +function luaY:recfield(ls, cc) + -- recfield -> (NAME | '['exp1']') = exp1 + local fs = ls.fs + local reg = ls.fs.freereg + local key, val = {}, {} -- expdesc + if ls.t.token == "TK_NAME" then + self:checklimit(fs, cc.nh, self.MAX_INT, "items in a constructor") + self:checkname(ls, key) + else -- ls->t.token == '[' + self:yindex(ls, key) + end + cc.nh = cc.nh + 1 + self:checknext(ls, "=") + local rkkey = luaK:exp2RK(fs, key) + self:expr(ls, val) + luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, rkkey, luaK:exp2RK(fs, val)) + fs.freereg = reg -- free registers +end + +------------------------------------------------------------------------ +-- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) +-- * used in constructor() +------------------------------------------------------------------------ +function luaY: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) -- flush + cc.tostore = 0 -- no more items pending + end +end + +------------------------------------------------------------------------ +-- emit a set list instruction at the end of parsing list constructor +-- * used in constructor() +------------------------------------------------------------------------ +function luaY:lastlistfield(fs, cc) + if cc.tostore == 0 then return end + if self:hasmultret(cc.v.k) then + luaK:setmultret(fs, cc.v) + luaK:setlist(fs, cc.t.info, cc.na, self.LUA_MULTRET) + cc.na = cc.na - 1 -- do not count last expression (unknown number of elements) + 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 + +------------------------------------------------------------------------ +-- parse a table list (array) field +-- * used in constructor() +------------------------------------------------------------------------ +function luaY:listfield(ls, cc) + self:expr(ls, cc.v) + self:checklimit(ls.fs, cc.na, self.MAX_INT, "items in a constructor") + cc.na = cc.na + 1 + cc.tostore = cc.tostore + 1 +end + +------------------------------------------------------------------------ +-- parse a table constructor +-- * used in funcargs(), simpleexp() +------------------------------------------------------------------------ +function luaY:constructor(ls, t) + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- field -> recfield | listfield + -- fieldsep -> ',' | ';' + local fs = ls.fs + local line = ls.linenumber + local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0) + local cc = {} -- ConsControl + cc.v = {} + cc.na, cc.nh, cc.tostore = 0, 0, 0 + cc.t = t + self:init_exp(t, "VRELOCABLE", pc) + self:init_exp(cc.v, "VVOID", 0) -- no value (yet) + luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc) + self:checknext(ls, "{") + repeat + lua_assert(cc.v.k == "VVOID" or cc.tostore > 0) + if ls.t.token == "}" then break end + self:closelistfield(fs, cc) + local c = ls.t.token + + if c == "TK_NAME" then -- may be listfields or recfields + luaX:lookahead(ls) + if ls.lookahead.token ~= "=" then -- expression? + self:listfield(ls, cc) + else + self:recfield(ls, cc) + end + elseif c == "[" then -- constructor_item -> recfield + self:recfield(ls, cc) + else -- constructor_part -> listfield + self:listfield(ls, cc) + end + until not self:testnext(ls, ",") and not self:testnext(ls, ";") + self:check_match(ls, "}", "{", line) + self:lastlistfield(fs, cc) + luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size + luaP:SETARG_C(fs.f.code[pc], self:int2fb(cc.nh)) -- set initial table size +end + +-- }====================================================================== + +------------------------------------------------------------------------ +-- parse the arguments (parameters) of a function declaration +-- * used in body() +------------------------------------------------------------------------ +function luaY:parlist(ls) + -- parlist -> [ param { ',' param } ] + local fs = ls.fs + local f = fs.f + local nparams = 0 + f.is_vararg = 0 + if ls.t.token ~= ")" then -- is 'parlist' not empty? + repeat + local c = ls.t.token + if c == "TK_NAME" then -- param -> NAME + self:new_localvar(ls, self:str_checkname(ls), nparams) + nparams = nparams + 1 + elseif c == "TK_DOTS" then -- param -> `...' + luaX:next(ls) +-- [[ +-- #if defined(LUA_COMPAT_VARARG) + -- use `arg' as default name + self:new_localvarliteral(ls, "arg", nparams) + nparams = nparams + 1 + f.is_vararg = self.VARARG_HASARG + self.VARARG_NEEDSARG +-- #endif +--]] + f.is_vararg = f.is_vararg + self.VARARG_ISVARARG + else + luaX:syntaxerror(ls, " or "..self:LUA_QL("...").." expected") + end + until f.is_vararg ~= 0 or not self:testnext(ls, ",") + end--if + self:adjustlocalvars(ls, nparams) + -- NOTE: the following works only when HASARG_MASK is 2! + f.numparams = fs.nactvar - (f.is_vararg % self.HASARG_MASK) + luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters +end + +------------------------------------------------------------------------ +-- parse function declaration body +-- * used in simpleexp(), localfunc(), funcstat() +------------------------------------------------------------------------ +function luaY:body(ls, e, needself, line) + -- body -> '(' parlist ')' chunk END + local new_fs = {} -- FuncState + new_fs.upvalues = {} + new_fs.actvar = {} + self:open_func(ls, new_fs) + new_fs.f.lineDefined = line + self:checknext(ls, "(") + if needself then + self:new_localvarliteral(ls, "self", 0) + self:adjustlocalvars(ls, 1) + end + self:parlist(ls) + self:checknext(ls, ")") + self:chunk(ls) + new_fs.f.lastlinedefined = ls.linenumber + self:check_match(ls, "TK_END", "TK_FUNCTION", line) + self:close_func(ls) + self:pushclosure(ls, new_fs, e) +end + +------------------------------------------------------------------------ +-- parse a list of comma-separated expressions +-- * used is multiple locations +------------------------------------------------------------------------ +function luaY:explist1(ls, v) + -- explist1 -> expr { ',' expr } + local n = 1 -- at least one expression + self:expr(ls, v) + while self:testnext(ls, ",") do + luaK:exp2nextreg(ls.fs, v) + self:expr(ls, v) + n = n + 1 + end + return n +end + +------------------------------------------------------------------------ +-- parse the parameters of a function call +-- * contrast with parlist(), used in function declarations +-- * used in primaryexp() +------------------------------------------------------------------------ +function luaY:funcargs(ls, f) + local fs = ls.fs + local args = {} -- expdesc + local nparams + local line = ls.linenumber + local c = ls.t.token + if c == "(" then -- funcargs -> '(' [ explist1 ] ')' + if line ~= ls.lastline then + luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)") + end + luaX:next(ls) + if ls.t.token == ")" then -- arg list is empty? + args.k = "VVOID" + else + self:explist1(ls, args) + luaK:setmultret(fs, args) + end + self:check_match(ls, ")", "(", line) + elseif c == "{" then -- funcargs -> constructor + self:constructor(ls, args) + elseif c == "TK_STRING" then -- funcargs -> STRING + self:codestring(ls, args, ls.t.seminfo) + luaX:next(ls) -- must use 'seminfo' before 'next' + else + luaX:syntaxerror(ls, "function arguments expected") + return + end + lua_assert(f.k == "VNONRELOC") + local base = f.info -- base register for call + if self:hasmultret(args.k) then + nparams = self.LUA_MULTRET -- open call + else + if args.k ~= "VVOID" then + luaK:exp2nextreg(fs, args) -- close last argument + end + nparams = fs.freereg - (base + 1) + end + self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2)) + luaK:fixline(fs, line) + fs.freereg = base + 1 -- call remove function and arguments and leaves + -- (unless changed) one result +end + +--[[-------------------------------------------------------------------- +-- Expression parsing +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- parses an expression in parentheses or a single variable +-- * used in primaryexp() +------------------------------------------------------------------------ +function luaY:prefixexp(ls, v) + -- prefixexp -> NAME | '(' expr ')' + local c = ls.t.token + if c == "(" then + local line = ls.linenumber + luaX:next(ls) + self:expr(ls, v) + self:check_match(ls, ")", "(", line) + luaK:dischargevars(ls.fs, v) + elseif c == "TK_NAME" then + self:singlevar(ls, v) + else + luaX:syntaxerror(ls, "unexpected symbol") + end--if c + return +end + +------------------------------------------------------------------------ +-- parses a prefixexp (an expression in parentheses or a single variable) +-- or a function call specification +-- * used in simpleexp(), assignment(), exprstat() +------------------------------------------------------------------------ +function luaY:primaryexp(ls, v) + -- primaryexp -> + -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + local fs = ls.fs + self:prefixexp(ls, v) + while true do + local c = ls.t.token + if c == "." then -- field + self:field(ls, v) + elseif c == "[" then -- '[' exp1 ']' + local key = {} -- expdesc + luaK:exp2anyreg(fs, v) + self:yindex(ls, key) + luaK:indexed(fs, v, key) + elseif c == ":" then -- ':' NAME funcargs + local key = {} -- expdesc + luaX:next(ls) + self:checkname(ls, key) + luaK:_self(fs, v, key) + self:funcargs(ls, v) + elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs + luaK:exp2nextreg(fs, v) + self:funcargs(ls, v) + else + return + end--if c + end--while +end + +------------------------------------------------------------------------ +-- parses general expression types, constants handled here +-- * used in subexpr() +------------------------------------------------------------------------ +function luaY:simpleexp(ls, v) + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | + -- constructor | FUNCTION body | primaryexp + local c = ls.t.token + if c == "TK_NUMBER" then + self:init_exp(v, "VKNUM", 0) + v.nval = ls.t.seminfo + elseif c == "TK_STRING" then + self:codestring(ls, v, ls.t.seminfo) + elseif c == "TK_NIL" then + self:init_exp(v, "VNIL", 0) + elseif c == "TK_TRUE" then + self:init_exp(v, "VTRUE", 0) + elseif c == "TK_FALSE" then + self:init_exp(v, "VFALSE", 0) + elseif c == "TK_DOTS" then -- vararg + local fs = ls.fs + self:check_condition(ls, fs.f.is_vararg ~= 0, + "cannot use "..self:LUA_QL("...").." outside a vararg function"); + -- NOTE: the following substitutes for a bitop, but is value-specific + local is_vararg = fs.f.is_vararg + if is_vararg >= self.VARARG_NEEDSARG then + fs.f.is_vararg = is_vararg - self.VARARG_NEEDSARG -- don't need 'arg' + end + self:init_exp(v, "VVARARG", luaK:codeABC(fs, "OP_VARARG", 0, 1, 0)) + elseif c == "{" then -- constructor + self:constructor(ls, v) + return + elseif c == "TK_FUNCTION" then + luaX:next(ls) + self:body(ls, v, false, ls.linenumber) + return + else + self:primaryexp(ls, v) + return + end--if c + luaX:next(ls) +end + +------------------------------------------------------------------------ +-- Translates unary operators tokens if found, otherwise returns +-- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr(). +-- * used in subexpr() +------------------------------------------------------------------------ +function luaY:getunopr(op) + if op == "TK_NOT" then + return "OPR_NOT" + elseif op == "-" then + return "OPR_MINUS" + elseif op == "#" then + return "OPR_LEN" + else + return "OPR_NOUNOPR" + end +end + +------------------------------------------------------------------------ +-- Translates binary operator tokens if found, otherwise returns +-- OPR_NOBINOPR. Code generation uses OPR_* style tokens. +-- * used in subexpr() +------------------------------------------------------------------------ +luaY.getbinopr_table = { + ["+"] = "OPR_ADD", + ["-"] = "OPR_SUB", + ["*"] = "OPR_MUL", + ["/"] = "OPR_DIV", + ["%"] = "OPR_MOD", + ["^"] = "OPR_POW", + ["TK_CONCAT"] = "OPR_CONCAT", + ["TK_NE"] = "OPR_NE", + ["TK_EQ"] = "OPR_EQ", + ["<"] = "OPR_LT", + ["TK_LE"] = "OPR_LE", + [">"] = "OPR_GT", + ["TK_GE"] = "OPR_GE", + ["TK_AND"] = "OPR_AND", + ["TK_OR"] = "OPR_OR", +} +function luaY:getbinopr(op) + local opr = self.getbinopr_table[op] + if opr then return opr else return "OPR_NOBINOPR" end +end + +------------------------------------------------------------------------ +-- the following priority table consists of pairs of left/right values +-- for binary operators (was a static const struct); grep for ORDER OPR +-- * the following struct is replaced: +-- static const struct { +-- lu_byte left; /* left priority for each binary operator */ +-- lu_byte right; /* right priority */ +-- } priority[] = { /* ORDER OPR */ +------------------------------------------------------------------------ +luaY.priority = { + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, -- `+' `-' `/' `%' + {10, 9}, {5, 4}, -- power and concat (right associative) + {3, 3}, {3, 3}, -- equality + {3, 3}, {3, 3}, {3, 3}, {3, 3}, -- order + {2, 2}, {1, 1} -- logical (and/or) +} + +luaY.UNARY_PRIORITY = 8 -- priority for unary operators + +------------------------------------------------------------------------ +-- Parse subexpressions. Includes handling of unary operators and binary +-- operators. A subexpr is given the rhs priority level of the operator +-- immediately left of it, if any (limit is -1 if none,) and if a binop +-- is found, limit is compared with the lhs priority level of the binop +-- in order to determine which executes first. +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- subexpr -> (simpleexp | unop subexpr) { binop subexpr } +-- where 'binop' is any binary operator with a priority higher than 'limit' +-- * for priority lookups with self.priority[], 1=left and 2=right +-- * recursively called +-- * used in expr() +------------------------------------------------------------------------ +function luaY:subexpr(ls, v, limit) + self:enterlevel(ls) + local uop = self:getunopr(ls.t.token) + if uop ~= "OPR_NOUNOPR" then + luaX:next(ls) + self:subexpr(ls, v, self.UNARY_PRIORITY) + luaK:prefix(ls.fs, uop, v) + else + self:simpleexp(ls, v) + end + -- expand while operators have priorities higher than 'limit' + local op = self:getbinopr(ls.t.token) + while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do + local v2 = {} -- expdesc + luaX:next(ls) + luaK:infix(ls.fs, op, v) + -- read sub-expression with higher priority + local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2]) + luaK:posfix(ls.fs, op, v, v2) + op = nextop + end + self:leavelevel(ls) + return op -- return first untreated operator +end + +------------------------------------------------------------------------ +-- Expression parsing starts here. Function subexpr is entered with the +-- left operator (which is non-existent) priority of -1, which is lower +-- than all actual operators. Expr information is returned in parm v. +-- * used in multiple locations +------------------------------------------------------------------------ +function luaY:expr(ls, v) + self:subexpr(ls, v, 0) +end + +-- }==================================================================== + +--[[-------------------------------------------------------------------- +-- Rules for Statements +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- checks next token, used as a look-ahead +-- * returns boolean instead of 0|1 +-- * used in retstat(), chunk() +------------------------------------------------------------------------ +function luaY:block_follow(token) + if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END" + or token == "TK_UNTIL" or token == "TK_EOS" then + return true + else + return false + end +end + +------------------------------------------------------------------------ +-- parse a code block or unit +-- * used in multiple functions +------------------------------------------------------------------------ +function luaY:block(ls) + -- block -> chunk + local fs = ls.fs + local bl = {} -- BlockCnt + self:enterblock(fs, bl, false) + self:chunk(ls) + lua_assert(bl.breaklist == luaK.NO_JUMP) + self:leaveblock(fs) +end + +------------------------------------------------------------------------ +-- structure to chain all variables in the left-hand side of an +-- assignment +-- struct LHS_assign: +-- prev -- (table: struct LHS_assign) +-- v -- variable (global, local, upvalue, or indexed) (table: expdesc) +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- 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. +-- * used in assignment() +------------------------------------------------------------------------ +function luaY:check_conflict(ls, lh, v) + local fs = ls.fs + 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 + +------------------------------------------------------------------------ +-- parse a variable assignment sequence +-- * recursively called +-- * used in exprstat() +------------------------------------------------------------------------ +function luaY:assignment(ls, lh, nvars) + local e = {} -- expdesc + -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED + local c = lh.v.k + self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" + or c == "VINDEXED", "syntax error") + if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment + local nv = {} -- LHS_assign + nv.v = {} + nv.prev = lh + self:primaryexp(ls, nv.v) + if nv.v.k == "VLOCAL" then + self:check_conflict(ls, lh, nv.v) + end + self:checklimit(ls.fs, nvars, self.LUAI_MAXCCALLS - ls.L.nCcalls, + "variables in assignment") + self:assignment(ls, nv, nvars + 1) + else -- assignment -> '=' explist1 + self:checknext(ls, "=") + local nexps = self:explist1(ls, e) + if nexps ~= nvars then + self:adjust_assign(ls, nvars, nexps, e) + if nexps > nvars then + ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values + end + else + luaK:setoneret(ls.fs, e) -- close last expression + luaK:storevar(ls.fs, lh.v, e) + return -- avoid default + end + end + self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment + luaK:storevar(ls.fs, lh.v, e) +end + +------------------------------------------------------------------------ +-- parse condition in a repeat statement or an if control structure +-- * used in repeatstat(), test_then_block() +------------------------------------------------------------------------ +function luaY:cond(ls) + -- cond -> exp + local v = {} -- expdesc + self:expr(ls, v) -- read condition + if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here + luaK:goiftrue(ls.fs, v) + return v.f +end + +------------------------------------------------------------------------ +-- parse a break statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:breakstat(ls) + -- stat -> BREAK + local fs = ls.fs + local bl = fs.bl + local upval = false + while bl and not bl.isbreakable do + if bl.upval then upval = true end + bl = bl.previous + end + if not bl then + luaX:syntaxerror(ls, "no loop to break") + end + if upval then + luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) + end + bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs)) +end + +------------------------------------------------------------------------ +-- parse a while-do control structure, body processed by block() +-- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by +-- the function's implementation can be removed +-- * used in statements() +------------------------------------------------------------------------ +function luaY:whilestat(ls, line) + -- whilestat -> WHILE cond DO block END + local fs = ls.fs + local bl = {} -- BlockCnt + luaX:next(ls) -- skip WHILE + local whileinit = luaK:getlabel(fs) + local condexit = self:cond(ls) + self:enterblock(fs, bl, true) + self:checknext(ls, "TK_DO") + self:block(ls) + luaK:patchlist(fs, luaK:jump(fs), whileinit) + self:check_match(ls, "TK_END", "TK_WHILE", line) + self:leaveblock(fs) + luaK:patchtohere(fs, condexit) -- false conditions finish the loop +end + +------------------------------------------------------------------------ +-- parse a repeat-until control structure, body parsed by chunk() +-- * used in statements() +------------------------------------------------------------------------ +function luaY:repeatstat(ls, line) + -- repeatstat -> REPEAT block UNTIL cond + local fs = ls.fs + local repeat_init = luaK:getlabel(fs) + local bl1, bl2 = {}, {} -- BlockCnt + self:enterblock(fs, bl1, true) -- loop block + self:enterblock(fs, bl2, false) -- scope block + luaX:next(ls) -- skip REPEAT + self:chunk(ls) + self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line) + local condexit = self:cond(ls) -- read condition (inside scope block) + if not bl2.upval then -- no upvalues? + self:leaveblock(fs) -- finish scope + luaK:patchlist(ls.fs, condexit, repeat_init) -- close the loop + else -- complete semantics when there are upvalues + self:breakstat(ls) -- if condition then break + luaK:patchtohere(ls.fs, condexit) -- else... + self:leaveblock(fs) -- finish scope... + luaK:patchlist(ls.fs, luaK:jump(fs), repeat_init) -- and repeat + end + self:leaveblock(fs) -- finish loop +end + +------------------------------------------------------------------------ +-- parse the single expressions needed in numerical for loops +-- * used in fornum() +------------------------------------------------------------------------ +function luaY:exp1(ls) + local e = {} -- expdesc + self:expr(ls, e) + local k = e.k + luaK:exp2nextreg(ls.fs, e) + return k +end + +------------------------------------------------------------------------ +-- parse a for loop body for both versions of the for loop +-- * used in fornum(), forlist() +------------------------------------------------------------------------ +function luaY:forbody(ls, base, line, nvars, isnum) + -- forbody -> DO block + local bl = {} -- BlockCnt + local fs = ls.fs + self:adjustlocalvars(ls, 3) -- control variables + self:checknext(ls, "TK_DO") + local prep = isnum and luaK:codeAsBx(fs, "OP_FORPREP", base, luaK.NO_JUMP) + or luaK:jump(fs) + self:enterblock(fs, bl, false) -- scope for declared variables + self:adjustlocalvars(ls, nvars) + luaK:reserveregs(fs, nvars) + self:block(ls) + self:leaveblock(fs) -- end of scope for declared variables + 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, line) -- pretend that `OP_FOR' starts the loop + luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep + 1) +end + +------------------------------------------------------------------------ +-- parse a numerical for loop, calls forbody() +-- * used in forstat() +------------------------------------------------------------------------ +function luaY:fornum(ls, varname, line) + -- fornum -> NAME = exp1,exp1[,exp1] forbody + local fs = ls.fs + local base = fs.freereg + self:new_localvarliteral(ls, "(for index)", 0) + self:new_localvarliteral(ls, "(for limit)", 1) + self:new_localvarliteral(ls, "(for step)", 2) + self:new_localvar(ls, varname, 3) + self:checknext(ls, '=') + self:exp1(ls) -- initial value + self:checknext(ls, ",") + self:exp1(ls) -- limit + if self:testnext(ls, ",") then + self:exp1(ls) -- optional step + else -- default step = 1 + luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1)) + luaK:reserveregs(fs, 1) + end + self:forbody(ls, base, line, 1, true) +end + +------------------------------------------------------------------------ +-- parse a generic for loop, calls forbody() +-- * used in forstat() +------------------------------------------------------------------------ +function luaY:forlist(ls, indexname) + -- forlist -> NAME {,NAME} IN explist1 forbody + local fs = ls.fs + local e = {} -- expdesc + local nvars = 0 + local base = fs.freereg + -- create control variables + self:new_localvarliteral(ls, "(for generator)", nvars) + nvars = nvars + 1 + self:new_localvarliteral(ls, "(for state)", nvars) + nvars = nvars + 1 + self:new_localvarliteral(ls, "(for control)", nvars) + nvars = nvars + 1 + -- create declared variables + self:new_localvar(ls, indexname, nvars) + nvars = nvars + 1 + while self:testnext(ls, ",") do + self:new_localvar(ls, self:str_checkname(ls), nvars) + nvars = nvars + 1 + end + self:checknext(ls, "TK_IN") + local line = ls.linenumber + self:adjust_assign(ls, 3, self:explist1(ls, e), e) + luaK:checkstack(fs, 3) -- extra space to call generator + self:forbody(ls, base, line, nvars - 3, false) +end + +------------------------------------------------------------------------ +-- initial parsing for a for loop, calls fornum() or forlist() +-- * used in statements() +------------------------------------------------------------------------ +function luaY:forstat(ls, line) + -- forstat -> FOR (fornum | forlist) END + local fs = ls.fs + local bl = {} -- BlockCnt + self:enterblock(fs, bl, true) -- scope for loop and control variables + luaX:next(ls) -- skip `for' + local varname = self:str_checkname(ls) -- first variable name + local c = ls.t.token + if c == "=" then + self:fornum(ls, varname, line) + elseif c == "," or c == "TK_IN" then + self:forlist(ls, varname) + else + luaX:syntaxerror(ls, self:LUA_QL("=").." or "..self:LUA_QL("in").." expected") + end + self:check_match(ls, "TK_END", "TK_FOR", line) + self:leaveblock(fs) -- loop scope (`break' jumps to this point) +end + +------------------------------------------------------------------------ +-- parse part of an if control structure, including the condition +-- * used in ifstat() +------------------------------------------------------------------------ +function luaY:test_then_block(ls) + -- test_then_block -> [IF | ELSEIF] cond THEN block + luaX:next(ls) -- skip IF or ELSEIF + local condexit = self:cond(ls) + self:checknext(ls, "TK_THEN") + self:block(ls) -- `then' part + return condexit +end + +------------------------------------------------------------------------ +-- parse an if control structure +-- * used in statements() +------------------------------------------------------------------------ +function luaY:ifstat(ls, line) + -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END + local fs = ls.fs + local escapelist = luaK.NO_JUMP + local flist = self:test_then_block(ls) -- IF cond THEN block + while ls.t.token == "TK_ELSEIF" do + escapelist = luaK:concat(fs, escapelist, luaK:jump(fs)) + luaK:patchtohere(fs, flist) + flist = self:test_then_block(ls) -- ELSEIF cond THEN block + end + if ls.t.token == "TK_ELSE" then + escapelist = luaK:concat(fs, escapelist, luaK:jump(fs)) + luaK:patchtohere(fs, flist) + luaX:next(ls) -- skip ELSE (after patch, for correct line info) + self:block(ls) -- 'else' part + else + escapelist = luaK:concat(fs, escapelist, flist) + end + luaK:patchtohere(fs, escapelist) + self:check_match(ls, "TK_END", "TK_IF", line) +end + +------------------------------------------------------------------------ +-- parse a local function statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:localfunc(ls) + local v, b = {}, {} -- expdesc + local fs = ls.fs + self:new_localvar(ls, self:str_checkname(ls), 0) + self:init_exp(v, "VLOCAL", fs.freereg) + luaK:reserveregs(fs, 1) + self:adjustlocalvars(ls, 1) + self:body(ls, b, false, ls.linenumber) + luaK:storevar(fs, v, b) + -- debug information will only see the variable after this point! + self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc +end + +------------------------------------------------------------------------ +-- parse a local variable declaration statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:localstat(ls) + -- stat -> LOCAL NAME {',' NAME} ['=' explist1] + local nvars = 0 + local nexps + local e = {} -- expdesc + repeat + self:new_localvar(ls, self:str_checkname(ls), nvars) + nvars = nvars + 1 + until not self:testnext(ls, ",") + if self:testnext(ls, "=") then + nexps = self:explist1(ls, e) + else + e.k = "VVOID" + nexps = 0 + end + self:adjust_assign(ls, nvars, nexps, e) + self:adjustlocalvars(ls, nvars) +end + +------------------------------------------------------------------------ +-- parse a function name specification +-- * used in funcstat() +------------------------------------------------------------------------ +function luaY:funcname(ls, v) + -- funcname -> NAME {field} [':' NAME] + local needself = false + self:singlevar(ls, v) + while ls.t.token == "." do + self:field(ls, v) + end + if ls.t.token == ":" then + needself = true + self:field(ls, v) + end + return needself +end + +------------------------------------------------------------------------ +-- parse a function statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:funcstat(ls, line) + -- funcstat -> FUNCTION funcname body + local v, b = {}, {} -- expdesc + luaX:next(ls) -- skip FUNCTION + local needself = self:funcname(ls, v) + self:body(ls, b, needself, line) + luaK:storevar(ls.fs, v, b) + luaK:fixline(ls.fs, line) -- definition 'happens' in the first line +end + +------------------------------------------------------------------------ +-- parse a function call with no returns or an assignment statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:exprstat(ls) + -- stat -> func | assignment + local fs = ls.fs + local v = {} -- LHS_assign + v.v = {} + self:primaryexp(ls, v.v) + if v.v.k == "VCALL" then -- stat -> func + luaP:SETARG_C(luaK:getcode(fs, v.v), 1) -- call statement uses no results + else -- stat -> assignment + v.prev = nil + self:assignment(ls, v, 1) + end +end + +------------------------------------------------------------------------ +-- parse a return statement +-- * used in statements() +------------------------------------------------------------------------ +function luaY:retstat(ls) + -- stat -> RETURN explist + local fs = ls.fs + local e = {} -- expdesc + local first, nret -- registers with returned values + luaX:next(ls) -- skip RETURN + if self:block_follow(ls.t.token) or ls.t.token == ";" then + first, nret = 0, 0 -- return no values + else + nret = self:explist1(ls, e) -- optional return values + if self:hasmultret(e.k) then + luaK:setmultret(fs, e) + if e.k == "VCALL" and nret == 1 then -- tail call? + luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL") + lua_assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar) + end + first = fs.nactvar + nret = self.LUA_MULTRET -- return all values + else + if nret == 1 then -- only one single value? + first = luaK:exp2anyreg(fs, e) + else + luaK:exp2nextreg(fs, e) -- values must go to the 'stack' + first = fs.nactvar -- return all 'active' values + lua_assert(nret == fs.freereg - first) + end + end--if + end--if + luaK:ret(fs, first, nret) +end + +------------------------------------------------------------------------ +-- initial parsing for statements, calls a lot of functions +-- * returns boolean instead of 0|1 +-- * used in chunk() +------------------------------------------------------------------------ +function luaY:statement(ls) + local line = ls.linenumber -- may be needed for error messages + local c = ls.t.token + if c == "TK_IF" then -- stat -> ifstat + self:ifstat(ls, line) + return false + elseif c == "TK_WHILE" then -- stat -> whilestat + self:whilestat(ls, line) + return false + elseif c == "TK_DO" then -- stat -> DO block END + luaX:next(ls) -- skip DO + self:block(ls) + self:check_match(ls, "TK_END", "TK_DO", line) + return false + elseif c == "TK_FOR" then -- stat -> forstat + self:forstat(ls, line) + return false + elseif c == "TK_REPEAT" then -- stat -> repeatstat + self:repeatstat(ls, line) + return false + elseif c == "TK_FUNCTION" then -- stat -> funcstat + self:funcstat(ls, line) + return false + elseif c == "TK_LOCAL" then -- stat -> localstat + luaX:next(ls) -- skip LOCAL + if self:testnext(ls, "TK_FUNCTION") then -- local function? + self:localfunc(ls) + else + self:localstat(ls) + end + return false + elseif c == "TK_RETURN" then -- stat -> retstat + self:retstat(ls) + return true -- must be last statement + elseif c == "TK_BREAK" then -- stat -> breakstat + luaX:next(ls) -- skip BREAK + self:breakstat(ls) + return true -- must be last statement + else + self:exprstat(ls) + return false -- to avoid warnings + end--if c +end + +------------------------------------------------------------------------ +-- parse a chunk, which consists of a bunch of statements +-- * used in parser(), body(), block(), repeatstat() +------------------------------------------------------------------------ +function luaY:chunk(ls) + -- chunk -> { stat [';'] } + local islast = false + self:enterlevel(ls) + while not islast and not self:block_follow(ls.t.token) do + islast = self:statement(ls) + self:testnext(ls, ";") + lua_assert(ls.fs.f.maxstacksize >= ls.fs.freereg and + ls.fs.freereg >= ls.fs.nactvar) + ls.fs.freereg = ls.fs.nactvar -- free registers + end + self:leavelevel(ls) +end + +-- }====================================================================== diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/luac.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/luac.lua new file mode 100644 index 0000000..5f12f79 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/luac.lua @@ -0,0 +1,71 @@ +--[[-------------------------------------------------------------------- + + luac.lua + Primitive luac in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2007 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * based on luac.lua in the test directory of the 5.1.2 distribution +-- * usage: lua luac.lua file.lua +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- load and initialize the required modules +------------------------------------------------------------------------ +dofile("lzio.lua") +dofile("llex.lua") +dofile("lopcodes.lua") +dofile("ldump.lua") +dofile("lcode.lua") +dofile("lparser.lua") + +luaX:init() -- required by llex +local LuaState = {} -- dummy, not actually used, but retained since + -- the intention is to complete a straight port + +------------------------------------------------------------------------ +-- interfacing to yueliang +------------------------------------------------------------------------ + +-- currently asserts are enabled because the codebase hasn't been tested +-- much (if you don't want asserts, just comment them out) +function lua_assert(test) + if not test then error("assertion failed!") end +end + +function yloadfile(filename) + -- luaZ:make_getF returns a file chunk reader + -- luaZ:init returns a zio input stream + local zio = luaZ:init(luaZ:make_getF(filename), nil) + if not zio then return end + -- luaY:parser parses the input stream + -- func is the function prototype in tabular form; in C, func can + -- now be used directly by the VM, this can't be done in Lua + local func = luaY:parser(LuaState, zio, nil, "@"..filename) + -- luaU:make_setS returns a string chunk writer + local writer, buff = luaU:make_setS() + -- luaU:dump builds a binary chunk + luaU:dump(LuaState, func, writer, buff) + -- a string.dump equivalent in returned + return buff.data +end + +------------------------------------------------------------------------ +-- command line interface +------------------------------------------------------------------------ + +assert(arg[1] ~= nil and arg[2] == nil, "usage: lua luac.lua file.lua") +local f = assert(io.open("luac.out","wb")) +assert(f:write(assert(yloadfile(arg[1])))) +assert(io.close(f)) + +--end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lzio.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lzio.lua new file mode 100644 index 0000000..b5ea985 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lzio.lua @@ -0,0 +1,125 @@ +--[[-------------------------------------------------------------------- + + lzio.lua + Lua buffered streams in Lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * EOZ is implemented as a string, "EOZ" +-- * Format of z structure (ZIO) +-- z.n -- bytes still unread +-- z.p -- last read position position in buffer +-- z.reader -- chunk reader function +-- z.data -- additional data +-- * Current position, p, is now last read index instead of a pointer +-- +-- Not implemented: +-- * luaZ_lookahead: used only in lapi.c:lua_load to detect binary chunk +-- * luaZ_read: used only in lundump.c:ezread to read +1 bytes +-- * luaZ_openspace: dropped; let Lua handle buffers as strings (used in +-- lundump.c:LoadString & lvm.c:luaV_concat) +-- * luaZ buffer macros: dropped; buffers are handled as strings +-- * lauxlib.c:getF reader implementation has an extraline flag to +-- skip over a shbang (#!) line, this is not implemented here +-- +-- Added: +-- (both of the following are vaguely adapted from lauxlib.c) +-- * luaZ:make_getS: create Reader from a string +-- * luaZ:make_getF: create Reader that reads from a file +-- +-- Changed in 5.1.x: +-- * Chunkreader renamed to Reader (ditto with Chunkwriter) +-- * Zio struct: no more name string, added Lua state for reader +-- (however, Yueliang readers do not require a Lua state) +----------------------------------------------------------------------]] + +luaZ = {} + +------------------------------------------------------------------------ +-- * reader() should return a string, or nil if nothing else to parse. +-- Additional data can be set only during stream initialization +-- * Readers are handled in lauxlib.c, see luaL_load(file|buffer|string) +-- * LUAL_BUFFERSIZE=BUFSIZ=512 in make_getF() (located in luaconf.h) +-- * Original Reader typedef: +-- const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); +-- * This Lua chunk reader implementation: +-- returns string or nil, no arguments to function +------------------------------------------------------------------------ + +------------------------------------------------------------------------ +-- create a chunk reader from a source string +------------------------------------------------------------------------ +function luaZ:make_getS(buff) + local b = buff + return function() -- chunk reader anonymous function here + if not b then return nil end + local data = b + b = nil + return data + end +end + +------------------------------------------------------------------------ +-- create a chunk reader from a source file +------------------------------------------------------------------------ +function luaZ:make_getF(filename) + local LUAL_BUFFERSIZE = 512 + local h = io.open(filename, "r") + if not h then return nil end + return function() -- chunk reader anonymous function here + if not h or io.type(h) == "closed file" then return nil end + local buff = h:read(LUAL_BUFFERSIZE) + if not buff then h:close(); h = nil end + return buff + end +end + +------------------------------------------------------------------------ +-- creates a zio input stream +-- returns the ZIO structure, z +------------------------------------------------------------------------ +function luaZ:init(reader, data) + if not reader then return end + local z = {} + z.reader = reader + z.data = data or "" + z.name = name + -- set up additional data for reading + if not data or data == "" then z.n = 0 else z.n = #data end + z.p = 0 + return z +end + +------------------------------------------------------------------------ +-- fill up input buffer +------------------------------------------------------------------------ +function luaZ:fill(z) + local buff = z.reader() + z.data = buff + if not buff or buff == "" then return "EOZ" end + z.n, z.p = #buff - 1, 1 + return string.sub(buff, 1, 1) +end + +------------------------------------------------------------------------ +-- get next character from the input stream +-- * local n, p are used to optimize code generation +------------------------------------------------------------------------ +function luaZ:zgetc(z) + local n, p = z.n, z.p + 1 + if n > 0 then + z.n, z.p = n - 1, p + return string.sub(z.data, p, p) + else + return self:fill(z) + end +end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/bench_llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/bench_llex.lua new file mode 100644 index 0000000..b904470 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/bench_llex.lua @@ -0,0 +1,99 @@ +--[[-------------------------------------------------------------------- + + bench_llex.lua + Benchmark test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +dofile("../lzio.lua") +dofile("../llex.lua") +luaX:init() + +------------------------------------------------------------------------ +-- load in a standard set of sample files +-- * file set is 5.0.3 front end set sans luac.lua +------------------------------------------------------------------------ + +local fileset, totalsize = {}, 0 +for fn in string.gmatch([[ +../../orig-5.0.3/lcode.lua +../../orig-5.0.3/ldump.lua +../../orig-5.0.3/llex.lua +../../orig-5.0.3/lopcodes.lua +../../orig-5.0.3/lparser.lua +../../orig-5.0.3/lzio.lua +]], "%S+") do + fileset[#fileset+1] = fn +end + +for i = 1, #fileset do + local fn = fileset[i] + local inf = io.open(fn, "rb") + if not inf then + error("failed to open "..fn.." for reading") + end + local data = inf:read("*a") + local data_sz = #data + inf:close() + if not data or data_sz == 0 then + error("failed to read data from "..fn.." or file is zero-length") + end + totalsize = totalsize + data_sz + fileset[i] = data +end + +------------------------------------------------------------------------ +-- benchmark tester +------------------------------------------------------------------------ + +local DURATION = 5 -- how long the benchmark should run + +local L = {} -- LuaState +local LS = {} -- LexState + +local time = os.time +local lexedsize = 0 +local tnow, elapsed = time(), 0 + +while time() == tnow do end -- wait for second to click over +tnow = time() + +while true do + for i = 1, #fileset do + ------------------------------------------------------------ + local chunk = fileset[i] + local z = luaZ:init(luaZ:make_getS(chunk), nil) + luaX:setinput(L, LS, z, "=string") + while true do + LS.t.token = luaX:llex(LS, LS.t) + local tok, seminfo = LS.t.token, LS.t.seminfo + if tok == "TK_EOS" then break end + end + ------------------------------------------------------------ + lexedsize = lexedsize + #chunk + if time() > tnow then + tnow = time() + elapsed = elapsed + 1 + if elapsed >= DURATION then + -- report performance of lexer + lexedsize = lexedsize / 1024 + local speed = lexedsize / DURATION + print("Lexer performance:") + print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) + print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) + -- repeat until user breaks program + elapsed = 0 + end + end + ------------------------------------------------------------ + end--for +end--while + +-- end of script diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/sample.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/sample.lua new file mode 100644 index 0000000..dc6eaee --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/sample.lua @@ -0,0 +1,3 @@ +local a = 47 +local b = "hello, world!" +print(a, b) diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_ldump.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_ldump.lua new file mode 100644 index 0000000..2d113dd --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_ldump.lua @@ -0,0 +1,99 @@ +--[[-------------------------------------------------------------------- + + test_ldump.lua + Test for ldump.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- test dump chunkwriter style +------------------------------------------------------------------------ + +dofile("../lopcodes.lua") +dofile("../ldump.lua") + +-- Original typedef: +--int (*lua_Chunkwriter) (lua_State *L, const void* p, size_t sz, void* ud); + +local MyWriter, MyBuff = luaU:make_setS() +if not MyWriter then + error("failed to initialize using make_setS") +end +MyWriter("hello, ", MyBuff) +MyWriter("world!", MyBuff) +print(MyBuff.data) + +local MyWriter, MyBuff = luaU:make_setF("try.txt") +if not MyWriter then + error("failed to initialize using make_setF") +end +MyWriter("hello, ", MyBuff) +MyWriter("world!", MyBuff) +MyWriter(nil, MyBuff) + +------------------------------------------------------------------------ +-- test output of a function prototype +-- * data can be copied from a ChunkSpy listing output +------------------------------------------------------------------------ +-- local a = 47 +-- local b = "hello, world!" +-- print(a, b) +------------------------------------------------------------------------ + +local F = {} +F.source = "sample.lua" +F.lineDefined = 0 +F.lastlinedefined = 0 +F.nups = 0 +F.numparams = 0 +F.is_vararg = 2 +F.maxstacksize = 5 +F.sizecode = 7 +F.code = {} +F.code[0] = { OP = 1, A = 0, Bx = 0 } +F.code[1] = { OP = 1, A = 1, Bx = 1 } +F.code[2] = { OP = 5, A = 2, Bx = 2 } +F.code[3] = { OP = 0, A = 3, B = 0, C = 0 } +F.code[4] = { OP = 0, A = 4, B = 1, C = 0 } +F.code[5] = { OP = 28, A = 2, B = 3, C = 1 } +F.code[6] = { OP = 30, A = 0, B = 1, C = 0 } +F.sizek = 3 +F.k = {} +F.k[0] = { value = 47 } +F.k[1] = { value = "hello, world!" } +F.k[2] = { value = "print" } +F.sizep = 0 +F.p = {} +F.sizelineinfo = 7 +F.lineinfo = {} +F.lineinfo[0] = 1 +F.lineinfo[1] = 2 +F.lineinfo[2] = 3 +F.lineinfo[3] = 3 +F.lineinfo[4] = 3 +F.lineinfo[5] = 3 +F.lineinfo[6] = 3 +F.sizelocvars = 2 +F.locvars = {} +F.locvars[0] = { varname = "a", startpc = 1, endpc = 6 } +F.locvars[1] = { varname = "b", startpc = 2, endpc = 6 } +F.sizeupvalues = 0 +F.upvalues = {} + +local L = {} +--[[ +local Writer, Buff = luaU:make_setS() +luaU:dump(L, F, Writer, Buff) +for i = 1, string.len(Buff.data) do + io.stdout:write(string.byte(string.sub(Buff.data, i, i)).." ") +end +--]] +local Writer, Buff = luaU:make_setF("try.out") +luaU:dump(L, F, Writer, Buff) diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_llex.lua new file mode 100644 index 0000000..0548476 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_llex.lua @@ -0,0 +1,580 @@ +--[[-------------------------------------------------------------------- + + test_llex.lua + Test for llex.lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- if BRIEF is not set to false, auto-test will silently succeed +------------------------------------------------------------------------ +BRIEF = true -- if set to true, messages are less verbose + +dofile("../lzio.lua") +dofile("../llex.lua") +luaX:init() + +------------------------------------------------------------------------ +-- simple manual tests +------------------------------------------------------------------------ + +--[[ +local L = {} -- LuaState +local LS = {} -- LexState + +local function dump(z) + luaX:setinput(L, LS, z, z.name) + while true do + LS.t.token = luaX:lex(LS, LS.t) + local tok, seminfo = LS.t.token, LS.t.seminfo + if tok == "TK_NAME" then + seminfo = " "..seminfo + elseif tok == "TK_NUMBER" then + seminfo = " "..seminfo + elseif tok == "TK_STRING" then + seminfo = " '"..seminfo.."'" + else + seminfo = "" + end + io.stdout:write(tok..seminfo.."\n") + if tok == "TK_EOS" then break end + end +end + +local function try_string(chunk) + dump(luaZ:init(luaZ:make_getS(chunk), nil, "=string")) +end +local function try_file(filename) + dump(luaZ:init(luaZ:make_getF(filename), nil, filename)) +end + +z = try_string("local c = luaZ:zgetc(z)") +z = try_file("test_lzio.lua") +z = try_file("test_llex.lua") +os.exit() +--]] + +------------------------------------------------------------------------ +-- auto-testing of simple test cases to validate lexer behaviour: +-- * NOTE coverage has not been checked; not comprehensive +-- * only test cases with non-empty comments are processed +-- * if no result, then the output is displayed for manual decision +-- (output may be used to set expected success or fail text) +-- * cases expected to be successful may be a partial match +-- * cases expected to fail may also be a partial match +------------------------------------------------------------------------ + +-- [[ +local function auto_test() + local PASS, FAIL = true, false + ------------------------------------------------------------------ + -- table of test cases + ------------------------------------------------------------------ + local test_cases = + { + ------------------------------------------------------------- + --{ "comment", -- comment about the test + -- "chunk", -- chunk to test + -- PASS, -- PASS or FAIL outcome + -- "output", -- output to compare against + --}, + ------------------------------------------------------------- + { "empty chunk string, test EOS", + "", + PASS, "1 TK_EOS", + }, + ------------------------------------------------------------- + { "line number counting", + "\n\n\r\n", + PASS, "4 TK_EOS", + }, + ------------------------------------------------------------- + { "various whitespaces", + " \n\t\t\n \t \t \n\n", + PASS, "5 TK_EOS", + }, + ------------------------------------------------------------- + { "short comment ending in EOS", + "-- moo moo", + PASS, "1 TK_EOS", + }, + ------------------------------------------------------------- + { "short comment ending in newline", + "-- moo moo\n", + PASS, "2 TK_EOS", + }, + ------------------------------------------------------------- + { "several lines of short comments", + "--moo\n-- moo moo\n\n--\tmoo\n", + PASS, "5 TK_EOS", + }, + ------------------------------------------------------------- + { "basic block comment 1", + "--[[bovine]]", + PASS, "1 TK_EOS", + }, + ------------------------------------------------------------- + { "basic block comment 2", + "--[=[bovine]=]", + PASS, "1 TK_EOS", + }, + ------------------------------------------------------------- + { "basic block comment 3", + "--[====[-[[bovine]]-]====]", + PASS, "1 TK_EOS", + }, + ------------------------------------------------------------- + { "unterminated block comment 1", + "--[[bovine", + FAIL, ":1: unfinished long comment near ''", + }, + ------------------------------------------------------------- + { "unterminated block comment 2", + "--[==[bovine", + FAIL, ":1: unfinished long comment near ''", + }, + ------------------------------------------------------------- + { "unterminated block comment 3", + "--[[bovine]", + FAIL, ":1: unfinished long comment near ''", + }, + ------------------------------------------------------------- + { "unterminated block comment 4", + "--[[bovine\nmoo moo\nwoof", + FAIL, ":3: unfinished long comment near ''", + }, + ------------------------------------------------------------- + { "basic long string 1", + "\n[[bovine]]\n", + PASS, "2 TK_STRING = bovine\n3 TK_EOS", + }, + ------------------------------------------------------------- + { "basic long string 2", + "\n[=[bovine]=]\n", + PASS, "2 TK_STRING = bovine\n3 TK_EOS", + }, + ------------------------------------------------------------- + { "first newline consumed in long string", + "[[\nmoo]]", + PASS, "2 TK_STRING = moo\n2 TK_EOS", + }, + ------------------------------------------------------------- + { "multiline long string 1", + "[[moo\nmoo moo\n]]", + PASS, "3 TK_STRING = moo\nmoo moo\n\n3 TK_EOS", + }, + ------------------------------------------------------------- + { "multiline long string 2", + "[===[moo\n[=[moo moo]=]\n]===]", + PASS, "3 TK_STRING = moo\n[=[moo moo]=]\n\n3 TK_EOS", + }, + ------------------------------------------------------------- + { "unterminated long string 1", + "\n[[\nbovine", + FAIL, ":3: unfinished long string near ''", + }, + ------------------------------------------------------------- + { "unterminated long string 2", + "[[bovine]", + FAIL, ":1: unfinished long string near ''", + }, + ------------------------------------------------------------- + { "unterminated long string 2", + "[==[bovine]==", + FAIL, ":1: unfinished long string near ''", + }, + ------------------------------------------------------------- + { "complex long string 1", + "[=[moo[[moo]]moo]=]", + PASS, "moo[[moo]]moo", + }, + ------------------------------------------------------------- + { "complex long string 2", + "[=[moo[[moo[[[[]]]]moo]]moo]=]", + PASS, "moo[[moo[[[[]]]]moo]]moo", + }, + ------------------------------------------------------------- + { "complex long string 3", + "[=[[[[[]]]][[[[]]]]]=]", + PASS, "[[[[]]]][[[[]]]]", + }, + ------------------------------------------------------------- + { "deprecated long string 1", + "[[moo[[moo]]moo]]", + FAIL, ":1: nesting of [[...]] is deprecated near '['", + }, + ------------------------------------------------------------- + { "deprecated long string 2", + "[[[[ \n", + FAIL, ":1: nesting of [[...]] is deprecated near '['", + }, + ------------------------------------------------------------- + { "deprecated long string 3", + "[[moo[[moo[[[[]]]]moo]]moo]]", + FAIL, ":1: nesting of [[...]] is deprecated near '['", + }, + ------------------------------------------------------------- + { "deprecated long string 4", + "[[[[[[]]]][[[[]]]]]]", + FAIL, ":1: nesting of [[...]] is deprecated near '['", + }, + ------------------------------------------------------------- + { "brackets in long strings 1", + "[[moo[moo]]", + PASS, "moo[moo", + }, + ------------------------------------------------------------- + { "brackets in long strings 2", + "[=[moo[[moo]moo]]moo]=]", + PASS, "moo[[moo]moo]]moo", + }, + ------------------------------------------------------------- + { "unprocessed escapes in long strings", + [[ [=[\a\b\f\n\r\t\v\123]=] ]], + PASS, [[\a\b\f\n\r\t\v\123]], + }, + ------------------------------------------------------------- + { "unbalanced long string", + "[[moo]]moo]]", + PASS, "1 TK_STRING = moo\n1 TK_NAME = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 1", + "and break do else", + PASS, "1 TK_AND\n1 TK_BREAK\n1 TK_DO\n1 TK_ELSE\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 2", + "elseif end false for", + PASS, "1 TK_ELSEIF\n1 TK_END\n1 TK_FALSE\n1 TK_FOR\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 3", + "function if in local nil", + PASS, "1 TK_FUNCTION\n1 TK_IF\n1 TK_IN\n1 TK_LOCAL\n1 TK_NIL\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 4", + "not or repeat return", + PASS, "1 TK_NOT\n1 TK_OR\n1 TK_REPEAT\n1 TK_RETURN\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "keywords 5", + "then true until while", + PASS, "1 TK_THEN\n1 TK_TRUE\n1 TK_UNTIL\n1 TK_WHILE\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "concat and dots", + ".. ...", + PASS, "1 TK_CONCAT\n1 TK_DOTS\n1 TK_EOS", + }, + ------------------------------------------------------------- + -- NOTE: in Lua 5.1.x, shbang handling is no longer performed + -- in the lexer; it is now done in lauxlib.c (luaL_loadfile) + -- so the following cannot be performed by the lexer... + ------------------------------------------------------------- + --{ "shbang handling 1", + -- "#blahblah", + -- PASS, "1 TK_EOS", + --}, + ------------------------------------------------------------- + --{ "shbang handling 2", + -- "#blahblah\nmoo moo\n", + -- PASS, "2 TK_NAME = moo\n2 TK_NAME = moo\n3 TK_EOS", + --}, + ------------------------------------------------------------- + { "empty string", + [['']], + PASS, "1 TK_STRING = \n1 TK_EOS", + }, + ------------------------------------------------------------- + { "single-quoted string", + [['bovine']], + PASS, "1 TK_STRING = bovine\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "double-quoted string", + [["bovine"]], + PASS, "1 TK_STRING = bovine\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "unterminated string 1", + [['moo ]], + FAIL, ":1: unfinished string near ''", + }, + ------------------------------------------------------------- + { "unterminated string 2", + [["moo \n]], + FAIL, ":1: unfinished string near ''", + }, + ------------------------------------------------------------- + { "escaped newline in string, line number counted", + "\"moo\\\nmoo\\\nmoo\"", + PASS, "3 TK_STRING = moo\nmoo\nmoo\n3 TK_EOS", + }, + ------------------------------------------------------------- + { "escaped characters in string 1", + [["moo\amoo"]], + PASS, "1 TK_STRING = moo\amoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 2", + [["moo\bmoo"]], + PASS, "1 TK_STRING = moo\bmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 3", + [["moo\f\n\r\t\vmoo"]], + PASS, "1 TK_STRING = moo\f\n\r\t\vmoo", + }, + ------------------------------------------------------------- + { "escaped characters in string 4", + [["\\ \" \' \? \[ \]"]], + PASS, "1 TK_STRING = \\ \" \' \? \[ \]", + }, + ------------------------------------------------------------- + { "escaped characters in string 5", + [["\z \k \: \;"]], + PASS, "1 TK_STRING = z k : ;", + }, + ------------------------------------------------------------- + { "escaped characters in string 6", + [["\8 \65 \160 \180K \097097"]], + PASS, "1 TK_STRING = \8 \65 \160 \180K \097097\n", + }, + ------------------------------------------------------------- + { "escaped characters in string 7", + [["\666"]], + FAIL, ":1: escape sequence too large near '\"'", + }, + ------------------------------------------------------------- + { "simple numbers", + "123 123+", + PASS, "1 TK_NUMBER = 123\n1 TK_NUMBER = 123\n1 CHAR = '+'\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "longer numbers", + "1234567890 12345678901234567890", + PASS, "1 TK_NUMBER = 1234567890\n1 TK_NUMBER = 1.2345678901235e+19\n", + }, + ------------------------------------------------------------- + { "fractional numbers", + ".123 .12345678901234567890", + PASS, "1 TK_NUMBER = 0.123\n1 TK_NUMBER = 0.12345678901235\n", + }, + ------------------------------------------------------------- + { "more numbers with decimal points", + "12345.67890", + PASS, "1 TK_NUMBER = 12345.6789\n", + }, + ------------------------------------------------------------- + { "malformed number with decimal points", + "1.1.", + FAIL, ":1: malformed number near '1.1.'", + }, + ------------------------------------------------------------- + { "double decimal points", + ".1.1", + FAIL, ":1: malformed number near '.1.1'", + }, + ------------------------------------------------------------- + { "double dots within numbers", + "1..1", + FAIL, ":1: malformed number near '1..1'", + }, + ------------------------------------------------------------- + { "incomplete exponential numbers", + "123e", + FAIL, ":1: malformed number near '123e'", + }, + ------------------------------------------------------------- + { "exponential numbers 1", + "1234e5 1234e5.", + PASS, "1 TK_NUMBER = 123400000\n1 TK_NUMBER = 123400000\n1 CHAR = '.'", + }, + ------------------------------------------------------------- + { "exponential numbers 2", + "1234e56 1.23e123", + PASS, "1 TK_NUMBER = 1.234e+59\n1 TK_NUMBER = 1.23e+123\n", + }, + ------------------------------------------------------------- + { "exponential numbers 3", + "12.34e+", + FAIL, ":1: malformed number near '12.34e+'", + }, + ------------------------------------------------------------- + { "exponential numbers 4", + "12.34e+5 123.4e-5 1234.E+5", + PASS, "1 TK_NUMBER = 1234000\n1 TK_NUMBER = 0.001234\n1 TK_NUMBER = 123400000\n", + }, + ------------------------------------------------------------- + { "hexadecimal numbers", + "0x00FF 0X1234 0xDEADBEEF", + PASS, "1 TK_NUMBER = 255\n1 TK_NUMBER = 4660\n1 TK_NUMBER = 3735928559\n", + }, + ------------------------------------------------------------- + { "invalid hexadecimal numbers 1", + "0xFOO", + FAIL, ":1: malformed number near '0xFOO'", + }, + ------------------------------------------------------------- + { "invalid hexadecimal numbers 2", + "0.BAR", + FAIL, ":1: malformed number near '0.BAR'", + }, + ------------------------------------------------------------- + { "invalid hexadecimal numbers 3", + "0BAZ", + FAIL, ":1: malformed number near '0BAZ'", + }, + ------------------------------------------------------------- + { "single character symbols 1", + "= > < ~ #", + PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n1 CHAR = '#'\n", + }, + ------------------------------------------------------------- + { "double character symbols", + "== >= <= ~=", + PASS, "1 TK_EQ\n1 TK_GE\n1 TK_LE\n1 TK_NE\n", + }, + ------------------------------------------------------------- + { "simple identifiers", + "abc ABC", + PASS, "1 TK_NAME = abc\n1 TK_NAME = ABC\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "more identifiers", + "_abc _ABC", + PASS, "1 TK_NAME = _abc\n1 TK_NAME = _ABC\n1 TK_EOS", + }, + ------------------------------------------------------------- + { "still more identifiers", + "_aB_ _123", + PASS, "1 TK_NAME = _aB_\n1 TK_NAME = _123\n1 TK_EOS", + }, + ------------------------------------------------------------- + -- NOTE: in Lua 5.1.x, this test is no longer performed + ------------------------------------------------------------- + --{ "invalid control character", + -- "\4", + -- FAIL, ":1: invalid control char near 'char(4)'", + --}, + ------------------------------------------------------------- + { "single character symbols 2", + "` ! @ $ %", + PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", + }, + ------------------------------------------------------------- + { "single character symbols 3", + "^ & * ( )", + PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", + }, + ------------------------------------------------------------- + { "single character symbols 4", + "_ - + \\ |", + PASS, "1 TK_NAME = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", + }, + ------------------------------------------------------------- + { "single character symbols 5", + "{ } [ ] :", + PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", + }, + ------------------------------------------------------------- + { "single character symbols 6", + "; , . / ?", + PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", + }, + ------------------------------------------------------------- + } + ------------------------------------------------------------------ + -- perform a test case + ------------------------------------------------------------------ + function do_test_case(count, test_case) + if comment == "" then return end -- skip empty entries + local comment, chunk, outcome, matcher = unpack(test_case) + local result = PASS + local output = "" + -- initialize lexer + local L, LS = {}, {} + local z = luaZ:init(luaZ:make_getS(chunk), nil) + luaX:setinput(L, LS, z, "=test") + -- lexer test loop + repeat + -- protected call + local status, token = pcall(luaX.llex, luaX, LS, LS.t) + LS.t.token = token + output = output..LS.linenumber.." " + if status then + -- successful call + if string.len(token) > 1 then + if token == "TK_NAME" + or token == "TK_NUMBER" + or token == "TK_STRING" then + token = token.." = "..LS.t.seminfo + end + elseif string.byte(token) >= 32 then -- displayable chars + token = "CHAR = '"..token.."'" + else -- control characters + token = "CHAR = (".. string.byte(token)..")" + end + output = output..token.."\n" + else + -- failed call + output = output..token -- token is the error message + result = FAIL + break + end + until LS.t.token == "TK_EOS" + -- decision making and reporting + local head = "Test "..count..": "..comment + if matcher == "" then + -- nothing to check against, display for manual check + print(head.."\nMANUAL please check manually".. + "\n--chunk---------------------------------\n"..chunk.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + return + else + if outcome == PASS then + -- success expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == PASS then + if not BRIEF then print(head.."\nOK expected success\n") end + return + end + else + -- failure expected, may be a partial match + if string.find(output, matcher, 1, 1) and result == FAIL then + if not BRIEF then print(head.."\nOK expected failure\n") end + return + end + end + -- failed because of unmatched string or boolean result + local function passfail(status) + if status == PASS then return "PASS" else return "FAIL" end + end + print(head.." *FAILED*".. + "\noutcome="..passfail(outcome).. + "\nactual= "..passfail(result).. + "\n--chunk---------------------------------\n"..chunk.. + "\n--expected------------------------------\n"..matcher.. + "\n--actual--------------------------------\n"..output.. + "\n\n") + end + end + ------------------------------------------------------------------ + -- perform auto testing + ------------------------------------------------------------------ + for i,test_case in ipairs(test_cases) do + do_test_case(i, test_case) + end +end + +auto_test() +--]] diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser.lua new file mode 100644 index 0000000..8c7abf4 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser.lua @@ -0,0 +1,59 @@ +--[[-------------------------------------------------------------------- + + test_lparser.lua + Test for lparser.lua + This file is part of Yueliang. + + Copyright (c) 2005-2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +dofile("../lzio.lua") +dofile("../llex.lua") +dofile("../lopcodes.lua") +dofile("../ldump.lua") +dofile("../lcode.lua") +dofile("../lparser.lua") + +function lua_assert(test) + if not test then error("assertion failed!") end +end + +luaX:init() + +------------------------------------------------------------------------ +-- try 1 +------------------------------------------------------------------------ +local zio = luaZ:init(luaZ:make_getS("local a = 1"), nil) +local LuaState = {} +local Func = luaY:parser(LuaState, zio, nil, "=string") + +--[[ +for i, v in Func do + if type(v) == "string" or type(v) == "number" then + print(i, v) + elseif type(v) == "table" then + print(i, "TABLE") + end +end +--]] + +local Writer, Buff = luaU:make_setF("parse1.out") +luaU:dump(LuaState, Func, Writer, Buff) + +------------------------------------------------------------------------ +-- try 2 +------------------------------------------------------------------------ + +zio = luaZ:init(luaZ:make_getF("sample.lua"), nil) +Func = luaY:parser(LuaState, zio, nil, "@sample.lua") +Writer, Buff = luaU:make_setF("parse2.out") +luaU:dump(LuaState, Func, Writer, Buff) diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser2.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser2.lua new file mode 100644 index 0000000..e9fa188 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser2.lua @@ -0,0 +1,202 @@ +--[[-------------------------------------------------------------------- + + test_lparser2.lua + Test for lparser.lua, using the test case file + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * the test cases are in the test_lua directory (test_parser-5.1.lua) +----------------------------------------------------------------------]] + +-- * true if you want an output of all failure cases in native Lua, +-- for checking whether test cases fail where you intend them to +local DEBUG_FAILS = false + +------------------------------------------------------------------------ +-- test the whole kaboodle +------------------------------------------------------------------------ + +dofile("../lzio.lua") +dofile("../llex.lua") +dofile("../lopcodes.lua") +dofile("../ldump.lua") +dofile("../lcode.lua") +dofile("../lparser.lua") + +function lua_assert(test) + if not test then error("assertion failed!") end +end + +luaX:init() + +------------------------------------------------------------------------ +-- load test cases +------------------------------------------------------------------------ + +dofile("../../test_lua/test_parser-5.1.lua") + +local test, expect, heading = {}, {}, {} +local total, total_pass, total_fail = 0, 0, 0 + +for ln in string.gmatch(tests_source, "([^\n]*)\n") do + if string.find(ln, "^%s*%-%-") then + -- comment, ignore + else + local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") + if m then + heading[total + 1] = head -- informational heading + else + total = total + 1 + local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") + if n then -- FAIL test case + ln = string.sub(ln, 1, n - 1) -- remove comment + expect[total] = "FAIL" + total_fail = total_fail + 1 + else -- PASS test case + expect[total] = "PASS" + total_pass = total_pass + 1 + end--n + test[total] = ln + end--m + end--ln +end--for + +print("Tests loaded: "..total.." (total), " + ..total_pass.." (passes), " + ..total_fail.." (fails)") + +------------------------------------------------------------------------ +-- verify test cases using native Lua +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then + last_head = head + if DEBUG_FAILS then print("\n"..head.."\n") end + end + ------------------------------------------------------------------ + -- perform test + local f, err = loadstring(test_case) + -- look at outcome + ------------------------------------------------------------------ + if f then-- actual PASS + if expected == "FAIL" then + print("\nVerified as PASS but expected to FAIL".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nVerified as FAIL but expected to PASS".. + "\n-------------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + print("ERROR: "..err) + os.exit() + end + if DEBUG_FAILS then + print("TEST: "..test_case) + print("ERROR: "..err.."\n") + end + ------------------------------------------------------------------ + end--f +end--for + +print("Test cases verified using native Lua, no anomalies.") + +------------------------------------------------------------------------ +-- dump binary chunks to a file if something goes wrong +------------------------------------------------------------------------ +local function Dump(data, filename) + h = io.open(filename, "wb") + if not h then error("failed to open "..filename.." for writing") end + h:write(data) + h:close() +end + +------------------------------------------------------------------------ +-- test using Yueliang front end +------------------------------------------------------------------------ + +local last_head = "TESTS: no heading yet" +for i = 1, total do + local test_case, expected, head = test[i], expect[i], heading[i] + -- show progress + if head then last_head = head end + ------------------------------------------------------------------ + -- perform test + local LuaState = {} + local zio = luaZ:init(luaZ:make_getS(test_case), nil) + local status, func = pcall(luaY.parser, luaY, LuaState, zio, nil, "test") + -- look at outcome + ------------------------------------------------------------------ + if status then-- actual PASS + if expected == "PASS" then + -- actual PASS and expected PASS, so check binary chunks + local writer, buff = luaU:make_setS() + luaU:dump(LuaState, func, writer, buff) + local bc1 = buff.data -- Yueliang's output + local f = loadstring(test_case, "test") + local bc2 = string.dump(f) -- Lua's output + local die + -- compare outputs + if #bc1 ~= #bc2 then + Dump(bc1, "bc1.out") + Dump(bc2, "bc2.out") + die = "binary chunk sizes different" + elseif bc1 ~= bc2 then + Dump(bc1, "bc1.out") + Dump(bc2, "bc2.out") + die = "binary chunks different" + else + -- everything checks out! + end + if die then + print("\nTested PASS and expected to PASS, but chunks different".. + "\n------------------------------------------------------") + print("Reason: "..die) + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + else-- expected FAIL + print("\nTested as PASS but expected to FAIL".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + os.exit() + end + ------------------------------------------------------------------ + else-- actual FAIL + if expected == "PASS" then + print("\nTested as FAIL but expected to PASS".. + "\n-----------------------------------") + print("Lastest heading: "..last_head) + print("TEST: "..test_case) + print("ERROR: "..err) + os.exit() + end + ------------------------------------------------------------------ + end--status + io.stdout:write("\rTesting ["..i.."]...") +end--for +print(" done.") + +print("Test cases run on Yueliang, no anomalies.") + +-- end diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lzio.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lzio.lua new file mode 100644 index 0000000..c3879f1 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lzio.lua @@ -0,0 +1,41 @@ +--[[-------------------------------------------------------------------- + + test_lzio.lua + Test for lzio.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +-- manual test for lzio.lua lua-style chunk reader + +dofile("../lzio.lua") + +local z +function dump(z) + while true do + local c = luaZ:zgetc(z) + io.stdout:write("("..c..")") + if c == "EOZ" then break end + end + io.stdout:write("\n") +end + +-- luaZ:make_getS or luaZ:make_getF creates a chunk reader +-- luaZ:init makes a zio stream + +-- [[ +z = luaZ:init(luaZ:make_getS("hello, world!"), nil, "=string") +dump(z) +z = luaZ:init(luaZ:make_getS(", world!"), "hello", "=string") +dump(z) +z = luaZ:init(luaZ:make_getS("line1\nline2\n"), "", "=string") +dump(z) +z = luaZ:init(luaZ:make_getF("test_lzio.lua"), nil, "=string") +dump(z) +--]] diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_number.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_number.lua new file mode 100644 index 0000000..2c94f40 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_number.lua @@ -0,0 +1,174 @@ +--[[-------------------------------------------------------------------- + + test_number.lua + Test for Lua-based number conversion functions in ldump.lua + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * luaU:from_int(value) does not have overflow checks, but this +-- can presumably be put in for debugging purposes. +-- * TODO: double conversion does not support denormals or NaNs +-- * apparently 0/0 == 0/0 is false (Lua 5.0.2 on Win32/Mingw), so +-- can't use to check for NaNs +----------------------------------------------------------------------]] + +dofile("../ldump.lua") + +------------------------------------------------------------------------ +-- convert hex string representation to a byte string +-- * must have an even number of hex digits +------------------------------------------------------------------------ +local function from_hexstring(s) + local bs = "" + for i = 1, string.len(s), 2 do + local asc = tonumber(string.sub(s, i, i + 1), 16) + bs = bs..string.char(asc) + end + return bs +end + +------------------------------------------------------------------------ +-- convert a byte string to a hex string representation +-- * big-endian, easier to grok +------------------------------------------------------------------------ +local function to_hexstring(s) + local hs = "" + for i = string.len(s), 1, -1 do + local c = string.byte(string.sub(s, i, i)) + hs = hs..string.format("%02X", c) + end + return hs +end + +------------------------------------------------------------------------ +-- tests for 32-bit signed/unsigned integer +------------------------------------------------------------------------ +local function test_int(value, expected) + local actual = to_hexstring(luaU:from_int(value)) + if not expected or expected == "" then + print(value..": "..actual) + elseif actual ~= expected then + print(value..": FAILED!\n".. + "Converted: "..actual.."\n".. + "Expected: "..expected) + return true + end + return false +end + +local table_int = { + ["0"] = "00000000", + ["1"] = "00000001", + ["256"] = "00000100", + ["-256"] = "FFFFFF00", + ["-1"] = "FFFFFFFF", + ["2147483647"] = "7FFFFFFF", -- LONG_MAX + ["-2147483648"] = "80000000", -- LONG_MIN + ["4294967295"] = "FFFFFFFF", -- ULONG_MAX + --[""] = "", +} + +local success = true +print("Testing luaU:from_int():") +for i, v in pairs(table_int) do + local test_value = tonumber(i) + local expected = v + if test_int(test_value, expected) then + success = false + end +end +if success then + print("All test numbers passed okay.\n") +else + print("There were one or more failures.\n") +end + +------------------------------------------------------------------------ +-- tests for IEEE 754 64-bit double +------------------------------------------------------------------------ + +local function test_double(value, expected) + local actual = to_hexstring(luaU:from_double(value)) + if not expected or expected == "" then + print(value..": "..actual) + elseif actual ~= expected then + print(value..": FAILED!\n".. + "Converted: "..actual.."\n".. + "Expected: "..expected) + return true + end + return false +end + +-- special values, see testing loop for actual lookup +Infinity = 1/0 +Infinity_neg = -1/0 + +-- can't seem to do a comparison test with NaN, so leave them +-- (need to check the IEEE standard on this...) +NaN = 0/0 +NaN_neg = -0/0 +--["NaN"] = "", -- 7FF8000000000000 (djgpp) +--["NaN_neg"] = "", -- FFF8000000000000 (djgpp) + +local table_double = { + -- 0 for exponent, 0 for mantissa + ["0"] = "0000000000000000", + -- 3FF is bias of 1023, so (-1)^0 * (1+0) * 2^0 + ["1"] = "3FF0000000000000", + -- BFF has sign bit on, so (-1)^1 * (1+0) * 2^0 + ["-1"] = "BFF0000000000000", + -- 3FC is bias of 1020, so (-1)^0 * (1+0) * 2^-3 + ["0.125"] = "3FC0000000000000", + ["0.250"] = "3FD0000000000000", + ["0.500"] = "3FE0000000000000", + -- 40F is bias of 1039, so (-1)^0 * (1+0) * 2^16 + ["65536"] = "40F0000000000000", + -- 7FF is bias of 2047, 0 for mantissa + ["Infinity"] = "7FF0000000000000", + -- FFF has sign bit on, 0 for mantissa + ["Infinity_neg"] = "FFF0000000000000", + -- DBL_MIN, exponent=001 ( 1), mantissa=0000000000000 + ["2.2250738585072014e-308"] = "0010000000000000", + -- DBL_MAX, exponent=7FE (2046), mantissa=FFFFFFFFFFFFF + ["1.7976931348623157e+308"] = "7FEFFFFFFFFFFFFF", +--[[ + -- * the following is for float numbers only * + -- FLT_MIN, exponent=01 ( 1), mantissa=000000 + -- altervative value for FLT_MIN: 1.17549435e-38F + ["1.1754943508222875081e-38"] = "00800000", + -- FLT_MAX, exponent=FE (254), mantissa=7FFFFF + -- altervative value for FLT_MAX: 3.402823466e+38F + ["3.4028234663852885982e+38"] = "7F7FFFFF", +--]] + --[""] = "", +} + +local success = true +print("Testing luaU:from_double():") +for i, v in pairs(table_double) do + local test_value + if not string.find(i, "%d") then + test_value = _G[i] + else + test_value = tonumber(i) + end + local expected = v + if test_double(test_value, expected) then + success = false + end +end +if success then + print("All test numbers passed okay.\n") +else + print("There were one or more failures.\n") +end diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/bisect.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/bisect.lua new file mode 100644 index 0000000..f91e69b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/bisect.lua @@ -0,0 +1,27 @@ +-- bisection method for solving non-linear equations + +delta=1e-6 -- tolerance + +function bisect(f,a,b,fa,fb) + local c=(a+b)/2 + io.write(n," c=",c," a=",a," b=",b,"\n") + if c==a or c==b or math.abs(a-b) posted to lua-l +-- modified to use ANSI terminal escape sequences +-- modified to use for instead of while + +local write=io.write + +ALIVE="¥" DEAD="þ" +ALIVE="O" DEAD="-" + +function delay() -- NOTE: SYSTEM-DEPENDENT, adjust as necessary + for i=1,10000 do end + -- local i=os.clock()+1 while(os.clock() 0 do + local xm1,x,xp1,xi=self.w-1,self.w,1,self.w + while xi > 0 do + local sum = self[ym1][xm1] + self[ym1][x] + self[ym1][xp1] + + self[y][xm1] + self[y][xp1] + + self[yp1][xm1] + self[yp1][x] + self[yp1][xp1] + next[y][x] = ((sum==2) and self[y][x]) or ((sum==3) and 1) or 0 + xm1,x,xp1,xi = x,xp1,xp1+1,xi-1 + end + ym1,y,yp1,yi = y,yp1,yp1+1,yi-1 + end +end + +-- output the array to screen +function _CELLS:draw() + local out="" -- accumulate to reduce flicker + for y=1,self.h do + for x=1,self.w do + out=out..(((self[y][x]>0) and ALIVE) or DEAD) + end + out=out.."\n" + end + write(out) +end + +-- constructor +function CELLS(w,h) + local c = ARRAY2D(w,h) + c.spawn = _CELLS.spawn + c.evolve = _CELLS.evolve + c.draw = _CELLS.draw + return c +end + +-- +-- shapes suitable for use with spawn() above +-- +HEART = { 1,0,1,1,0,1,1,1,1; w=3,h=3 } +GLIDER = { 0,0,1,1,0,1,0,1,1; w=3,h=3 } +EXPLODE = { 0,1,0,1,1,1,1,0,1,0,1,0; w=3,h=4 } +FISH = { 0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0; w=5,h=4 } +BUTTERFLY = { 1,0,0,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1; w=5,h=5 } + +-- the main routine +function LIFE(w,h) + -- create two arrays + local thisgen = CELLS(w,h) + local nextgen = CELLS(w,h) + + -- create some life + -- about 1000 generations of fun, then a glider steady-state + thisgen:spawn(GLIDER,5,4) + thisgen:spawn(EXPLODE,25,10) + thisgen:spawn(FISH,4,12) + + -- run until break + local gen=1 + write("\027[2J") -- ANSI clear screen + while 1 do + thisgen:evolve(nextgen) + thisgen,nextgen = nextgen,thisgen + write("\027[H") -- ANSI home cursor + thisgen:draw() + write("Life - generation ",gen,"\n") + gen=gen+1 + if gen>2000 then break end + --delay() -- no delay + end +end + +LIFE(40,20) diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/luac.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/luac.lua new file mode 100644 index 0000000..b009ae9 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/luac.lua @@ -0,0 +1,7 @@ +-- bare-bones luac in Lua +-- usage: lua luac.lua file.lua + +assert(arg[1]~=nil and arg[2]==nil,"usage: lua luac.lua file.lua") +f=assert(io.open("luac.out","wb")) +f:write(string.dump(assert(loadfile(arg[1])))) +io.close(f) diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/printf.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/printf.lua new file mode 100644 index 0000000..66dfda6 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/printf.lua @@ -0,0 +1,7 @@ +-- an implementation of printf + +function printf(...) + io.write(string.format(unpack(arg))) +end + +printf("Hello %s from %s on %s\n",os.getenv"USER" or "there",_VERSION,os.date()) diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/readonly.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/readonly.lua new file mode 100644 index 0000000..85c0b4e --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/readonly.lua @@ -0,0 +1,12 @@ +-- make global variables readonly + +local f=function (t,i) error("cannot redefine global variable `"..i.."'",2) end +local g={} +local G=getfenv() +setmetatable(g,{__index=G,__newindex=f}) +setfenv(1,g) + +-- an example +rawset(g,"x",3) +x=2 +y=1 -- cannot redefine `y' diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/sieve.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/sieve.lua new file mode 100644 index 0000000..0871bb2 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/sieve.lua @@ -0,0 +1,29 @@ +-- the sieve of of Eratosthenes programmed with coroutines +-- typical usage: lua -e N=1000 sieve.lua | column + +-- generate all the numbers from 2 to n +function gen (n) + return coroutine.wrap(function () + for i=2,n do coroutine.yield(i) end + end) +end + +-- filter the numbers generated by `g', removing multiples of `p' +function filter (p, g) + return coroutine.wrap(function () + while 1 do + local n = g() + if n == nil then return end + if math.mod(n, p) ~= 0 then coroutine.yield(n) end + end + end) +end + +N=N or 1000 -- from command line +x = gen(N) -- generate primes up to N +while 1 do + local n = x() -- pick a number until done + if n == nil then break end + print(n) -- must be a prime number + x = filter(n, x) -- now remove its multiples +end diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/sort.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/sort.lua new file mode 100644 index 0000000..0bcb15f --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/sort.lua @@ -0,0 +1,66 @@ +-- two implementations of a sort function +-- this is an example only. Lua has now a built-in function "sort" + +-- extracted from Programming Pearls, page 110 +function qsort(x,l,u,f) + if ly end) + show("after reverse selection sort",x) + qsort(x,1,n,function (x,y) return x>> ",string.rep(" ",level)) + if t~=nil and t.currentline>=0 then io.write(t.short_src,":",t.currentline," ") end + t=debug.getinfo(2) + if event=="call" then + level=level+1 + else + level=level-1 if level<0 then level=0 end + end + if t.what=="main" then + if event=="call" then + io.write("begin ",t.short_src) + else + io.write("end ",t.short_src) + end + elseif t.what=="Lua" then +-- table.foreach(t,print) + io.write(event," ",t.name or "(Lua)"," <",t.linedefined,":",t.short_src,">") + else + io.write(event," ",t.name or "(C)"," [",t.what,"] ") + end + io.write("\n") +end + +debug.sethook(hook,"cr") +level=0 diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/trace-globals.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/trace-globals.lua new file mode 100644 index 0000000..295e670 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/trace-globals.lua @@ -0,0 +1,38 @@ +-- trace assigments to global variables + +do + -- a tostring that quotes strings. note the use of the original tostring. + local _tostring=tostring + local tostring=function(a) + if type(a)=="string" then + return string.format("%q",a) + else + return _tostring(a) + end + end + + local log=function (name,old,new) + local t=debug.getinfo(3,"Sl") + local line=t.currentline + io.write(t.short_src) + if line>=0 then io.write(":",line) end + io.write(": ",name," is now ",tostring(new)," (was ",tostring(old),")","\n") + end + + local g={} + local set=function (t,name,value) + log(name,g[name],value) + g[name]=value + end + setmetatable(getfenv(),{__index=g,__newindex=set}) +end + +-- an example + +a=1 +b=2 +a=10 +b=20 +b=nil +b=200 +print(a,b,c) diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/undefined.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/undefined.lua new file mode 100644 index 0000000..efe5f24 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/undefined.lua @@ -0,0 +1,9 @@ +-- catch "undefined" global variables + +local f=function (t,i) error("undefined global variable `"..i.."'",2) end +setmetatable(getfenv(),{__index=f}) + +-- an example +a=1 +c=3 +print(a,b,c) -- `b' is undefined diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/xd.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/xd.lua new file mode 100644 index 0000000..32331dc --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/xd.lua @@ -0,0 +1,14 @@ +-- hex dump +-- usage: lua xd.lua < file + +local offset=0 + +while 1 do + local s=io.read(16) + if s==nil then return end + io.write(string.format("%08X ",offset)) + string.gsub(s,"(.)",function (c) io.write(string.format("%02X ",string.byte(c))) end) + io.write(string.rep(" ",3*(16-string.len(s)))) + io.write(" ",string.gsub(s,"%c","."),"\n") + offset=offset+16 +end diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/bisect.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/bisect.lua new file mode 100644 index 0000000..f91e69b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/bisect.lua @@ -0,0 +1,27 @@ +-- bisection method for solving non-linear equations + +delta=1e-6 -- tolerance + +function bisect(f,a,b,fa,fb) + local c=(a+b)/2 + io.write(n," c=",c," a=",a," b=",b,"\n") + if c==a or c==b or math.abs(a-b) posted to lua-l +-- modified to use ANSI terminal escape sequences +-- modified to use for instead of while + +local write=io.write + +ALIVE="¥" DEAD="þ" +ALIVE="O" DEAD="-" + +function delay() -- NOTE: SYSTEM-DEPENDENT, adjust as necessary + for i=1,10000 do end + -- local i=os.clock()+1 while(os.clock() 0 do + local xm1,x,xp1,xi=self.w-1,self.w,1,self.w + while xi > 0 do + local sum = self[ym1][xm1] + self[ym1][x] + self[ym1][xp1] + + self[y][xm1] + self[y][xp1] + + self[yp1][xm1] + self[yp1][x] + self[yp1][xp1] + next[y][x] = ((sum==2) and self[y][x]) or ((sum==3) and 1) or 0 + xm1,x,xp1,xi = x,xp1,xp1+1,xi-1 + end + ym1,y,yp1,yi = y,yp1,yp1+1,yi-1 + end +end + +-- output the array to screen +function _CELLS:draw() + local out="" -- accumulate to reduce flicker + for y=1,self.h do + for x=1,self.w do + out=out..(((self[y][x]>0) and ALIVE) or DEAD) + end + out=out.."\n" + end + write(out) +end + +-- constructor +function CELLS(w,h) + local c = ARRAY2D(w,h) + c.spawn = _CELLS.spawn + c.evolve = _CELLS.evolve + c.draw = _CELLS.draw + return c +end + +-- +-- shapes suitable for use with spawn() above +-- +HEART = { 1,0,1,1,0,1,1,1,1; w=3,h=3 } +GLIDER = { 0,0,1,1,0,1,0,1,1; w=3,h=3 } +EXPLODE = { 0,1,0,1,1,1,1,0,1,0,1,0; w=3,h=4 } +FISH = { 0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0; w=5,h=4 } +BUTTERFLY = { 1,0,0,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1; w=5,h=5 } + +-- the main routine +function LIFE(w,h) + -- create two arrays + local thisgen = CELLS(w,h) + local nextgen = CELLS(w,h) + + -- create some life + -- about 1000 generations of fun, then a glider steady-state + thisgen:spawn(GLIDER,5,4) + thisgen:spawn(EXPLODE,25,10) + thisgen:spawn(FISH,4,12) + + -- run until break + local gen=1 + write("\027[2J") -- ANSI clear screen + while 1 do + thisgen:evolve(nextgen) + thisgen,nextgen = nextgen,thisgen + write("\027[H") -- ANSI home cursor + thisgen:draw() + write("Life - generation ",gen,"\n") + gen=gen+1 + if gen>2000 then break end + --delay() -- no delay + end +end + +LIFE(40,20) diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/luac.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/luac.lua new file mode 100644 index 0000000..96a0a97 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/luac.lua @@ -0,0 +1,7 @@ +-- bare-bones luac in Lua +-- usage: lua luac.lua file.lua + +assert(arg[1]~=nil and arg[2]==nil,"usage: lua luac.lua file.lua") +f=assert(io.open("luac.out","wb")) +assert(f:write(string.dump(assert(loadfile(arg[1]))))) +assert(f:close()) diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/printf.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/printf.lua new file mode 100644 index 0000000..58c63ff --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/printf.lua @@ -0,0 +1,7 @@ +-- an implementation of printf + +function printf(...) + io.write(string.format(...)) +end + +printf("Hello %s from %s on %s\n",os.getenv"USER" or "there",_VERSION,os.date()) diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/readonly.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/readonly.lua new file mode 100644 index 0000000..85c0b4e --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/readonly.lua @@ -0,0 +1,12 @@ +-- make global variables readonly + +local f=function (t,i) error("cannot redefine global variable `"..i.."'",2) end +local g={} +local G=getfenv() +setmetatable(g,{__index=G,__newindex=f}) +setfenv(1,g) + +-- an example +rawset(g,"x",3) +x=2 +y=1 -- cannot redefine `y' diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/sieve.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/sieve.lua new file mode 100644 index 0000000..0871bb2 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/sieve.lua @@ -0,0 +1,29 @@ +-- the sieve of of Eratosthenes programmed with coroutines +-- typical usage: lua -e N=1000 sieve.lua | column + +-- generate all the numbers from 2 to n +function gen (n) + return coroutine.wrap(function () + for i=2,n do coroutine.yield(i) end + end) +end + +-- filter the numbers generated by `g', removing multiples of `p' +function filter (p, g) + return coroutine.wrap(function () + while 1 do + local n = g() + if n == nil then return end + if math.mod(n, p) ~= 0 then coroutine.yield(n) end + end + end) +end + +N=N or 1000 -- from command line +x = gen(N) -- generate primes up to N +while 1 do + local n = x() -- pick a number until done + if n == nil then break end + print(n) -- must be a prime number + x = filter(n, x) -- now remove its multiples +end diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/sort.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/sort.lua new file mode 100644 index 0000000..0bcb15f --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/sort.lua @@ -0,0 +1,66 @@ +-- two implementations of a sort function +-- this is an example only. Lua has now a built-in function "sort" + +-- extracted from Programming Pearls, page 110 +function qsort(x,l,u,f) + if ly end) + show("after reverse selection sort",x) + qsort(x,1,n,function (x,y) return x>> ",string.rep(" ",level)) + if t~=nil and t.currentline>=0 then io.write(t.short_src,":",t.currentline," ") end + t=debug.getinfo(2) + if event=="call" then + level=level+1 + else + level=level-1 if level<0 then level=0 end + end + if t.what=="main" then + if event=="call" then + io.write("begin ",t.short_src) + else + io.write("end ",t.short_src) + end + elseif t.what=="Lua" then +-- table.foreach(t,print) + io.write(event," ",t.name or "(Lua)"," <",t.linedefined,":",t.short_src,">") + else + io.write(event," ",t.name or "(C)"," [",t.what,"] ") + end + io.write("\n") +end + +debug.sethook(hook,"cr") +level=0 diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/trace-globals.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/trace-globals.lua new file mode 100644 index 0000000..295e670 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/trace-globals.lua @@ -0,0 +1,38 @@ +-- trace assigments to global variables + +do + -- a tostring that quotes strings. note the use of the original tostring. + local _tostring=tostring + local tostring=function(a) + if type(a)=="string" then + return string.format("%q",a) + else + return _tostring(a) + end + end + + local log=function (name,old,new) + local t=debug.getinfo(3,"Sl") + local line=t.currentline + io.write(t.short_src) + if line>=0 then io.write(":",line) end + io.write(": ",name," is now ",tostring(new)," (was ",tostring(old),")","\n") + end + + local g={} + local set=function (t,name,value) + log(name,g[name],value) + g[name]=value + end + setmetatable(getfenv(),{__index=g,__newindex=set}) +end + +-- an example + +a=1 +b=2 +a=10 +b=20 +b=nil +b=200 +print(a,b,c) diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/xd.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/xd.lua new file mode 100644 index 0000000..ebc3eff --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/xd.lua @@ -0,0 +1,14 @@ +-- hex dump +-- usage: lua xd.lua < file + +local offset=0 +while true do + local s=io.read(16) + if s==nil then return end + io.write(string.format("%08X ",offset)) + string.gsub(s,"(.)", + function (c) io.write(string.format("%02X ",string.byte(c))) end) + io.write(string.rep(" ",3*(16-string.len(s)))) + io.write(" ",string.gsub(s,"%c","."),"\n") + offset=offset+16 +end diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/README b/LuaSL/testLua/yueliang-0.4.1/test_lua/README new file mode 100644 index 0000000..07d9eb2 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/README @@ -0,0 +1,65 @@ +test_scripts-5.*.lua +---------------------- + +The scripts test_scripts*.lua are for exercising the frontends. Such +testing is non-exhaustive, but useful all the same. + +The files in the 5.0 directory are the sample scripts from the Lua 5.0.x +test directory. Ditto for the 5.1 directory. See the COPYRIGHT_Lua5 for +the copyright notice. + +For example, to run the 5.0.x script tester: + + >lua test_scripts-5.0.lua + +Or, if you have both Lua 5.0.x and Lua 5.1.x, you can prepare two +binaries and run them like this: + + >lua5.0 test_scripts-5.0.lua + >lua5.1 test_scripts-5.1.lua + +If the compilation result is exact, "CORRECT" is printed, otherwise both +binary chunks are written to the current directory as bc1.out and +bc2.out. You can use a disassembly tool like ChunkSpy to generate +listings for both files, then they can be compared with a visual diff +tool. ChunkSpy 0.9.8 supports 5.0.x and 5.1.x. + +For testing additional files, add the argument "ALL" like this: + + >lua test_scripts-5.0.lua ALL + +This will pull in additional personal script files for testing. But in +order to do so, you'd have to adjust the files files-other-*.txt. + +Current status: + +Frontend version File set Result +--------------------------------------------------------------------- +Yueliang 5.0.3 files-lua-5.0.txt ALL CORRECT + files-yueliang-5.0.txt ALL CORRECT +Yueliang 5.1.2 files-lua-5.1.txt ALL CORRECT + files-yueliang-5.1.txt ALL CORRECT +--------------------------------------------------------------------- + +test_parser-5.x.lua +------------------- + +The script files test_parser-5.0.lua and test_parser-5.1.lua contains +many test cases for both parsers. There are a lot of failure cases as +well as pass cases in order to exercise the parsers well, though the +test list is not exhaustive. + + test_parser-5.0.lua 503 test cases + test_parser-5.1.lua 524 test cases + +For the actual test scripts, see test_lparser2.lua in the respective +test directories of each front end. The 5.0.x front end of Yueliang +passed all the tests in test_parser-5.0.lua without any failures, while +testing of the 5.1.x front end using test_parser-5.1.lua led to one +bug found and fixed. + +For Lua 5.0.2, see Yueliang 0.1.3, which was the last release of Lua +5.0.2 material. + +For Lua 5.1.1, see Yueliang 0.2.1, which was the last release of Lua +5.1.1 material. diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/files-lua-5.0.txt b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-lua-5.0.txt new file mode 100644 index 0000000..d6b0c3c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-lua-5.0.txt @@ -0,0 +1,21 @@ +# these are the sample scripts found in Lua 5.0.x +5.0/bisect.lua +5.0/cf.lua +5.0/echo.lua +5.0/env.lua +5.0/factorial.lua +5.0/fib.lua +5.0/fibfor.lua +5.0/globals.lua +5.0/hello.lua +5.0/life.lua +5.0/luac.lua +5.0/printf.lua +5.0/readonly.lua +5.0/sieve.lua +5.0/sort.lua +5.0/table.lua +5.0/trace-calls.lua +5.0/trace-globals.lua +5.0/undefined.lua +5.0/xd.lua diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/files-lua-5.1.txt b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-lua-5.1.txt new file mode 100644 index 0000000..a11d670 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-lua-5.1.txt @@ -0,0 +1,20 @@ +# these are the sample scripts found in Lua 5.1.x +5.1/bisect.lua +5.1/cf.lua +5.1/echo.lua +5.1/env.lua +5.1/factorial.lua +5.1/fib.lua +5.1/fibfor.lua +5.1/globals.lua +5.1/hello.lua +5.1/life.lua +5.1/luac.lua +5.1/printf.lua +5.1/readonly.lua +5.1/sieve.lua +5.1/sort.lua +5.1/table.lua +5.1/trace-calls.lua +5.1/trace-globals.lua +5.1/xd.lua diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/files-other-5.0.txt b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-other-5.0.txt new file mode 100644 index 0000000..a661bc5 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-other-5.0.txt @@ -0,0 +1,21 @@ +# these are other 5.0.x scripts found in my project directories +# WARNING currently out of date... + +../../SciTELuaExporters/SciTE_ExportBase.lua +../../SciTELuaExporters/SciTE_ExporterABW.lua +../../SciTELuaExporters/SciTE_ExporterHTML.lua +../../SciTELuaExporters/SciTE_ExporterHTMLPlus.lua +../../SciTELuaExporters/SciTE_ExporterODT.lua +../../SciTELuaExporters/SciTE_ExporterPDF.lua +../../SciTELuaExporters/SciTE_ExporterPDFPlus.lua +../../SciTELuaExporters/SciTE_ExporterRTF.lua +../../SciTELuaExporters/SciTE_ExporterSXW.lua +../../SciTELuaExporters/SciTE_ExporterTeX.lua +../../SciTELuaExporters/SciTE_ExporterTemplate.lua +../../SciTELuaExporters/SciTE_ExporterXML.lua +../../LuaSrcDiet/LuaSrcDiet.lua +../../LuaSrcDiet/LuaSrcDiet_.lua +../../ChunkBake/ChunkBake.lua +../../ChunkBake/misc/TestRig.lua +../../ChunkSpy/5.0.2/ChunkSpy.lua +../../ChunkSpy/5.1-work4/ChunkSpy.lua diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/files-other-5.1.txt b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-other-5.1.txt new file mode 100644 index 0000000..fa5827d --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-other-5.1.txt @@ -0,0 +1,3 @@ +# these are other 5.1.x scripts found in my project directories +# WARNING currently out of date... + diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/files-yueliang-5.0.txt b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-yueliang-5.0.txt new file mode 100644 index 0000000..72e1da9 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-yueliang-5.0.txt @@ -0,0 +1,34 @@ +# these are yueliang files for 5.0.x + +test_scripts-5.0.lua + +../orig-5.0.3/lzio.lua +../orig-5.0.3/ldump.lua +../orig-5.0.3/lopcodes.lua +../orig-5.0.3/llex.lua +../orig-5.0.3/lparser.lua +../orig-5.0.3/lcode.lua +../orig-5.0.3/luac.lua + +../orig-5.0.3/test/test_lzio.lua +../orig-5.0.3/test/test_ldump.lua +../orig-5.0.3/test/test_llex.lua +../orig-5.0.3/test/test_lparser.lua +../orig-5.0.3/test/test_number.lua +../orig-5.0.3/test/bench_llex.lua +../orig-5.0.3/tools/call_graph.lua +../orig-5.0.3/tools/sample_expr.lua + +../nat-5.0.3/lzio_mk2.lua +../nat-5.0.3/lzio_mk4.lua +../nat-5.0.3/llex_mk2.lua +../nat-5.0.3/llex_mk3.lua +../nat-5.0.3/llex_mk4.lua + +../nat-5.0.3/test/test_lzio_mk2.lua +../nat-5.0.3/test/test_llex_mk2.lua +../nat-5.0.3/test/test_llex_mk3.lua +../nat-5.0.3/test/test_llex_mk4.lua +../nat-5.0.3/test/bench_llex_mk2.lua +../nat-5.0.3/test/bench_llex_mk3.lua +../nat-5.0.3/test/bench_llex_mk4.lua diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/files-yueliang-5.1.txt b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-yueliang-5.1.txt new file mode 100644 index 0000000..6a112d9 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/files-yueliang-5.1.txt @@ -0,0 +1,19 @@ +# these are yueliang files for 5.1.x + +test_scripts-5.1.lua + +../orig-5.1.3/lzio.lua +../orig-5.1.3/ldump.lua +../orig-5.1.3/lopcodes.lua +../orig-5.1.3/llex.lua +../orig-5.1.3/lparser.lua +../orig-5.1.3/lcode.lua +../orig-5.1.3/luac.lua + +../orig-5.1.3/test/test_lzio.lua +../orig-5.1.3/test/test_ldump.lua +../orig-5.1.3/test/test_llex.lua +../orig-5.1.3/test/test_lparser.lua +../orig-5.1.3/test/test_number.lua +../orig-5.1.3/test/bench_llex.lua + diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/test_parser-5.0.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/test_parser-5.0.lua new file mode 100644 index 0000000..b563ed3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/test_parser-5.0.lua @@ -0,0 +1,761 @@ +--[[-------------------------------------------------------------------- + + test_parser-5.0.lua + Lua 5.0.x parser test cases + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * there is no intention of properly specifying a grammar; the notes +-- are meant to reflect the structure of lparser so that it is easy +-- to locate and modify lparser if so desired +-- * some test may have invalid expressions but will compile, this +-- is because the chunk hasn't been executed yet +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- lparser parsing structure, the Lua 5.0.x version... +----------------------------------------------------------------------]] + -------------------------------------------------------------------- + -- chunk -> { stat [';'] } + -------------------------------------------------------------------- + -- stat -> DO block END + -- block -> chunk + -------------------------------------------------------------------- + -- stat -> breakstat + -- breakstat -> BREAK + -- * must have a loop to break + -- * must be last statement in a block + -------------------------------------------------------------------- + -- stat -> retstat + -- retstat -> RETURN explist + -- * must be last statement in a block + -------------------------------------------------------------------- + -- stat -> exprstat + -- exprstat -> primaryexp + -- (-> func | assignment) + -- * if LHS is VCALL then func, otherwise assignment + -- * for func, LHS is VCALL if funcargs in expression + -------------------------------------------------------------------- + -- stat -> funcstat + -- funcstat -> FUNCTION funcname body + -- funcname -> NAME {'.' NAME} [':' NAME] + -------------------------------------------------------------------- + -- body -> '(' parlist ')' chunk END + -- parlist -> [ param { ',' param } ] + -- param -> NAME + -- * DOTS must be the last parameter in a parlist + -------------------------------------------------------------------- + -- stat -> LOCAL localstat + -- LOCAL localstat -> LOCAL NAME {',' NAME} ['=' explist1] + -- explist1 -> expr { ',' expr } + -------------------------------------------------------------------- + -- stat -> LOCAL FUNCTION localfunc + -- LOCAL FUNCTION localfunc -> LOCAL FUNCTION NAME body + -------------------------------------------------------------------- + -- stat -> ifstat + -- ifstat -> IF cond THEN block + -- {ELSEIF cond THEN block} + -- [ELSE block] END + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- + -- stat -> forstat + -- forstat -> fornum | forlist + -- forlist -> NAME {,NAME} IN explist1 forbody END + -- fornum -> NAME = exp1,exp1[,exp1] forbody END + -- forbody -> DO block + -- block -> chunk + -------------------------------------------------------------------- + -- stat -> whilestat + -- whilestat -> WHILE cond DO block END + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- + -- stat -> repeatstat + -- repeatstat -> REPEAT block UNTIL cond + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- + -- assignment -> ',' primaryexp assignment + -- | '=' explist1 + -- explist1 -> expr { ',' expr } + -- * for assignment, LHS must be LOCAL, UPVAL, GLOBAL or INDEXED + -------------------------------------------------------------------- + -- primaryexp -> prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + -- prefixexp -> NAME | '(' expr ')' + -- funcargs -> '(' [ explist1 ] ')' | constructor | STRING + -- * funcargs turn an expr into a function call + -------------------------------------------------------------------- + -- expr -> subexpr + -- subexpr -> (UNOPR subexpr | simpleexp) { BINOPR subexpr } + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE + -- | constructor | FUNCTION body | primaryexp + -------------------------------------------------------------------- + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- fieldsep -> ',' | ';' + -- field -> recfield | listfield + -- recfield -> ( NAME | '[' exp1 ']' ) = exp1 + -- listfield -> expr + -------------------------------------------------------------------- + +--[[-------------------------------------------------------------------- +-- parser test cases, Lua 5.0.x +-- * uncomment string delimiter to enable syntax highlighting... +-- * anything that matches "^%s*%-%-" is a comment +-- * headings to display are "^%s*TESTS:%s*(.*)$" +-- * FAIL test cases should match "%s*%-%-%s*FAIL%s*$" +----------------------------------------------------------------------]] +tests_source = [[ + -------------------------------------------------------------------- + TESTS: empty chunks + -------------------------------------------------------------------- + -- chunk -> { stat [';'] } + -------------------------------------------------------------------- + +; -- FAIL + -------------------------------------------------------------------- + TESTS: optional semicolon, simple local statements + -------------------------------------------------------------------- + -- stat -> LOCAL localstat + -- LOCAL localstat -> LOCAL NAME {',' NAME} ['=' explist1] + -- explist1 -> expr { ',' expr } + -------------------------------------------------------------------- +local -- FAIL +local; -- FAIL +local = -- FAIL +local end -- FAIL +local a +local a; +local a, b, c +local a; local b local c; +local a = 1 +local a local b = a +local a, b = 1, 2 +local a, b, c = 1, 2, 3 +local a, b, c = 1 +local a = 1, 2, 3 +local a, local -- FAIL +local 1 -- FAIL +local "foo" -- FAIL +local a = local -- FAIL +local a, b, = -- FAIL +local a, b = 1, local -- FAIL +local a, b = , local -- FAIL + -------------------------------------------------------------------- + TESTS: simple DO blocks + -------------------------------------------------------------------- + -- stat -> DO block END + -- block -> chunk + -------------------------------------------------------------------- +do -- FAIL +end -- FAIL +do end +do ; end -- FAIL +do 1 end -- FAIL +do "foo" end -- FAIL +do local a, b end +do local a local b end +do local a; local b; end +do local a = 1 end +do do end end +do do end; end +do do do end end end +do do do end; end; end +do do do return end end end +do end do -- FAIL +do end end -- FAIL +do return end +do return return end -- FAIL +do break end -- FAIL + -------------------------------------------------------------------- + TESTS: simple WHILE loops + -------------------------------------------------------------------- + -- stat -> whilestat + -- whilestat -> WHILE cond DO block END + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- +while -- FAIL +while do -- FAIL +while = -- FAIL +while 1 do -- FAIL +while 1 do end +while 1 do local a end +while 1 do local a local b end +while 1 do local a; local b; end +while 1 do 2 end -- FAIL +while 1 do "foo" end -- FAIL +while true do end +while 1 do ; end -- FAIL +while 1 do while -- FAIL +while 1 end -- FAIL +while 1 2 do -- FAIL +while 1 = 2 do -- FAIL +while 1 do return end +while 1 do return return end -- FAIL +while 1 do do end end +while 1 do do return end end +while 1 do break end +while 1 do break break end -- FAIL +while 1 do do break end end + -------------------------------------------------------------------- + TESTS: simple REPEAT loops + -------------------------------------------------------------------- + -- stat -> repeatstat + -- repeatstat -> REPEAT block UNTIL cond + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- +repeat -- FAIL +repeat until -- FAIL +repeat until 0 +repeat until false +repeat until local -- FAIL +repeat end -- FAIL +repeat 1 -- FAIL +repeat = -- FAIL +repeat local a until 1 +repeat local a local b until 0 +repeat local a; local b; until 0 +repeat ; until 1 -- FAIL +repeat 2 until 1 -- FAIL +repeat "foo" until 1 -- FAIL +repeat return until 0 +repeat return return until 0 -- FAIL +repeat break until 0 +repeat break break until 0 -- FAIL +repeat do end until 0 +repeat do return end until 0 +repeat do break end until 0 + -------------------------------------------------------------------- + TESTS: simple FOR loops + -------------------------------------------------------------------- + -- stat -> forstat + -- forstat -> fornum | forlist + -- forlist -> NAME {,NAME} IN explist1 forbody END + -- fornum -> NAME = exp1,exp1[,exp1] forbody END + -- forbody -> DO block + -- block -> chunk + -------------------------------------------------------------------- +for -- FAIL +for do -- FAIL +for end -- FAIL +for 1 -- FAIL +for a -- FAIL +for true -- FAIL +for a, in -- FAIL +for a in -- FAIL +for a do -- FAIL +for a in do -- FAIL +for a in b do -- FAIL +for a in b end -- FAIL +for a in b, do -- FAIL +for a in b do end +for a in b do local a local b end +for a in b do local a; local b; end +for a in b do 1 end -- FAIL +for a in b do "foo" end -- FAIL +for a b in -- FAIL +for a, b, c in p do end +for a, b, c in p, q, r do end +for a in 1 do end +for a in true do end +for a in "foo" do end +for a in b do break end +for a in b do break break end -- FAIL +for a in b do return end +for a in b do return return end -- FAIL +for a in b do do end end +for a in b do do break end end +for a in b do do return end end +for = -- FAIL +for a = -- FAIL +for a, b = -- FAIL +for a = do -- FAIL +for a = 1, do -- FAIL +for a = p, q, do -- FAIL +for a = p q do -- FAIL +for a = b do end -- FAIL +for a = 1, 2, 3, 4 do end -- FAIL +for a = p, q do end +for a = 1, 2 do end +for a = 1, 2 do local a local b end +for a = 1, 2 do local a; local b; end +for a = 1, 2 do 3 end -- FAIL +for a = 1, 2 do "foo" end -- FAIL +for a = p, q, r do end +for a = 1, 2, 3 do end +for a = p, q do break end +for a = p, q do break break end -- FAIL +for a = 1, 2 do return end +for a = 1, 2 do return return end -- FAIL +for a = p, q do do end end +for a = p, q do do break end end +for a = p, q do do return end end + -------------------------------------------------------------------- + TESTS: break statement + -------------------------------------------------------------------- + -- stat -> breakstat + -- breakstat -> BREAK + -- * must have a loop to break + -- * must be last statement in a block + -------------------------------------------------------------------- +break -- FAIL + -------------------------------------------------------------------- + TESTS: return statement + -------------------------------------------------------------------- + -- stat -> retstat + -- retstat -> RETURN explist + -- * must be last statement in a block + -------------------------------------------------------------------- +return +return; +return return -- FAIL +return 1 +return local -- FAIL +return "foo" +return 1, -- FAIL +return 1,2,3 +return a,b,c,d +return 1,2; + -------------------------------------------------------------------- + TESTS: conditional statements + -------------------------------------------------------------------- + -- stat -> ifstat + -- ifstat -> IF cond THEN block + -- {ELSEIF cond THEN block} + -- [ELSE block] END + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- +if -- FAIL +elseif -- FAIL +else -- FAIL +then -- FAIL +if then -- FAIL +if 1 -- FAIL +if 1 then -- FAIL +if 1 else -- FAIL +if 1 then else -- FAIL +if 1 then elseif -- FAIL +if 1 then end +if 1 then local a end +if 1 then local a local b end +if 1 then local a; local b; end +if 1 then else end +if 1 then local a else local b end +if 1 then local a; else local b; end +if 1 then elseif 2 -- FAIL +if 1 then elseif 2 then -- FAIL +if 1 then elseif 2 then end +if 1 then local a elseif 2 then local b end +if 1 then local a; elseif 2 then local b; end +if 1 then elseif 2 then else end +if 1 then else if 2 then end end +if 1 then else if 2 then end -- FAIL +if 1 then break end -- FAIL +if 1 then return end +if 1 then return return end -- FAIL +if 1 then end; if 1 then end; + -------------------------------------------------------------------- + TESTS: function statements + -------------------------------------------------------------------- + -- stat -> funcstat + -- funcstat -> FUNCTION funcname body + -- funcname -> NAME {'.' NAME} [':' NAME] + -------------------------------------------------------------------- + -- body -> '(' parlist ')' chunk END + -- parlist -> [ param { ',' param } ] + -- param -> NAME + -- * DOTS must be the last parameter in a parlist + -------------------------------------------------------------------- +function -- FAIL +function 1 -- FAIL +function end -- FAIL +function a -- FAIL +function a end -- FAIL +function a( end -- FAIL +function a() end +function a(1 -- FAIL +function a("foo" -- FAIL +function a(p -- FAIL +function a(p,) -- FAIL +function a(p q -- FAIL +function a(p) end +function a(p,q,) end -- FAIL +function a(p,q,r) end +function a(p,q,1 -- FAIL +function a(p) do -- FAIL +function a(p) 1 end -- FAIL +function a(p) return end +function a(p) break end -- FAIL +function a(p) return return end -- FAIL +function a(p) do end end +function a.( -- FAIL +function a.1 -- FAIL +function a.b() end +function a.b, -- FAIL +function a.b.( -- FAIL +function a.b.c.d() end +function a: -- FAIL +function a:1 -- FAIL +function a:b() end +function a:b: -- FAIL +function a:b. -- FAIL +function a.b.c:d() end +function a(...) end +function a(..., -- FAIL +function a(p,...) end +function a(p,q,r,...) end +function a() local a local b end +function a() local a; local b; end +function a() end; function a() end; + -------------------------------------------------------------------- + TESTS: local function statements + -------------------------------------------------------------------- + -- stat -> LOCAL FUNCTION localfunc + -- LOCAL FUNCTION localfunc -> LOCAL FUNCTION NAME body + -------------------------------------------------------------------- +local function -- FAIL +local function 1 -- FAIL +local function end -- FAIL +local function a -- FAIL +local function a end -- FAIL +local function a( end -- FAIL +local function a() end +local function a(1 -- FAIL +local function a("foo" -- FAIL +local function a(p -- FAIL +local function a(p,) -- FAIL +local function a(p q -- FAIL +local function a(p) end +local function a(p,q,) end -- FAIL +local function a(p,q,r) end +local function a(p,q,1 -- FAIL +local function a(p) do -- FAIL +local function a(p) 1 end -- FAIL +local function a(p) return end +local function a(p) break end -- FAIL +local function a(p) return return end -- FAIL +local function a(p) do end end +local function a. -- FAIL +local function a: -- FAIL +local function a(...) end +local function a(..., -- FAIL +local function a(p,...) end +local function a(p,q,r,...) end +local function a() local a local b end +local function a() local a; local b; end +local function a() end; local function a() end; + -------------------------------------------------------------------- + -- stat -> exprstat + -- exprstat -> primaryexp + -- (-> func | assignment) + -- * if LHS is VCALL then func, otherwise assignment + -- * for func, LHS is VCALL if funcargs in expression + -------------------------------------------------------------------- + TESTS: assignments + -------------------------------------------------------------------- + -- assignment -> ',' primaryexp assignment + -- | '=' explist1 + -- explist1 -> expr { ',' expr } + -- * for assignment, LHS must be LOCAL, UPVAL, GLOBAL or INDEXED + -------------------------------------------------------------------- +a -- FAIL +a, -- FAIL +a,b,c -- FAIL +a,b = -- FAIL +a = 1 +a = 1,2,3 +a,b,c = 1 +a,b,c = 1,2,3 +a.b = 1 +a.b.c = 1 +a[b] = 1 +a[b][c] = 1 +a.b[c] = 1 +a[b].c = 1 +0 = -- FAIL +"foo" = -- FAIL +true = -- FAIL +(a) = -- FAIL +{} = -- FAIL +a:b() = -- FAIL +a() = -- FAIL +a.b:c() = -- FAIL +a[b]() = -- FAIL +a = a b -- FAIL +a = 1 2 -- FAIL +a = a = 1 -- FAIL + -------------------------------------------------------------------- + TESTS: function calls + -------------------------------------------------------------------- + -- primaryexp -> prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + -- prefixexp -> NAME | '(' expr ')' + -- funcargs -> '(' [ explist1 ] ')' | constructor | STRING + -- * funcargs turn an expr into a function call + -------------------------------------------------------------------- +a( -- FAIL +a() +a(1) +a(1,) -- FAIL +a(1,2,3) +1() -- FAIL +a()() +a.b() +a[b]() +a.1 -- FAIL +a.b -- FAIL +a[b] -- FAIL +a.b.( -- FAIL +a.b.c() +a[b][c]() +a[b].c() +a.b[c]() +a:b() +a:b -- FAIL +a:1 -- FAIL +a.b:c() +a[b]:c() +a:b: -- FAIL +a:b():c() +a:b().c[d]:e() +a:b()[c].d:e() +(a)() +()() -- FAIL +(1)() +("foo")() +(true)() +(a)()() +(a.b)() +(a[b])() +(a).b() +(a)[b]() +(a):b() +(a).b[c]:d() +(a)[b].c:d() +(a):b():c() +(a):b().c[d]:e() +(a):b()[c].d:e() + -------------------------------------------------------------------- + TESTS: more function calls + -------------------------------------------------------------------- +a"foo" +a[[foo]] +a.b"foo" +a[b]"foo" +a:b"foo" +a{} +a.b{} +a[b]{} +a:b{} +a()"foo" +a"foo"() +a"foo".b() +a"foo"[b]() +a"foo":c() +a"foo""bar" +a"foo"{} +(a):b"foo".c[d]:e"bar" +(a):b"foo"[c].d:e"bar" +a(){} +a{}() +a{}.b() +a{}[b]() +a{}:c() +a{}"foo" +a{}{} +(a):b{}.c[d]:e{} +(a):b{}[c].d:e{} + -------------------------------------------------------------------- + TESTS: simple expressions + -------------------------------------------------------------------- + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE + -- | constructor | FUNCTION body | primaryexp + -------------------------------------------------------------------- +a = -- FAIL +a = a +a = nil +a = false +a = 1 +a = "foo" +a = [[foo]] +a = {} +a = (a) +a = (nil) +a = (true) +a = (1) +a = ("foo") +a = ([[foo]]) +a = ({}) +a = a.b +a = a.b. -- FAIL +a = a.b.c +a = a:b -- FAIL +a = a[b] +a = a[1] +a = a["foo"] +a = a[b][c] +a = a.b[c] +a = a[b].c +a = (a)[b] +a = (a).c +a = () -- FAIL +a = a() +a = a.b() +a = a[b]() +a = a:b() +a = (a)() +a = (a).b() +a = (a)[b]() +a = (a):b() +a = a"foo" +a = a{} +a = function -- FAIL +a = function 1 -- FAIL +a = function a -- FAIL +a = function end -- FAIL +a = function( -- FAIL +a = function() end +a = function(1 -- FAIL +a = function(p) end +a = function(p,) -- FAIL +a = function(p q -- FAIL +a = function(p,q,r) end +a = function(p,q,1 -- FAIL +a = function(...) end +a = function(..., -- FAIL +a = function(p,...) end +a = function(p,q,r,...) end + -------------------------------------------------------------------- + TESTS: operators + -------------------------------------------------------------------- + -- expr -> subexpr + -- subexpr -> (UNOPR subexpr | simpleexp) { BINOPR subexpr } + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE + -- | constructor | FUNCTION body | primaryexp + -------------------------------------------------------------------- +a = -10 +a = -"foo" +a = -a +a = -nil +a = -true +a = -{} +a = -function() end +a = -a() +a = -(a) +a = - -- FAIL +a = not 10 +a = not "foo" +a = not a +a = not nil +a = not true +a = not {} +a = not function() end +a = not a() +a = not (a) +a = not -- FAIL +a = 1 + 2; a = 1 - 2 +a = 1 * 2; a = 1 / 2 +a = 1 ^ 2; a = 1 .. 2 +a = 1 + -- FAIL +a = 1 .. -- FAIL +a = 1 * / -- FAIL +a = 1 + -2; a = 1 - -2 +a = 1 * - -- FAIL +a = 1 * not 2; a = 1 / not 2 +a = 1 / not -- FAIL +a = 1 + 2 - 3 * 4 / 5 ^ 6 +a = ((1 + 2) - 3) * (4 / (5 ^ 6)) +a = (1 + (2 - (3 * (4 / (5 ^ ((6))))))) +a = ((1 -- FAIL +a = ((1 + 2) -- FAIL +a = 1) -- FAIL +a = a + b - c +a = "foo" + "bar" +a = "foo".."bar".."baz" +a = true + false - nil +a = {} * {} +a = function() end / function() end +a = a() ^ b() + -------------------------------------------------------------------- + TESTS: more operators + -------------------------------------------------------------------- +a = 1 == 2; a = 1 ~= 2 +a = 1 < 2; a = 1 <= 2 +a = 1 > 2; a = 1 >= 2 +a = 1 < 2 < 3 +a = 1 >= 2 >= 3 +a = 1 == -- FAIL +a = ~= 2 -- FAIL +a = "foo" == "bar" +a = "foo" > "bar" +a = a ~= b +a = true == false +a = 1 and 2; a = 1 or 2 +a = 1 and -- FAIL +a = or 1 -- FAIL +a = 1 and 2 and 3 +a = 1 or 2 or 3 +a = 1 and 2 or 3 +a = a and b or c +a = a() and (b)() or c.d +a = "foo" and "bar" +a = true or false +a = {} and {} or {} +a = (1) and ("foo") or (nil) +a = function() end == function() end +a = function() end or function() end + -------------------------------------------------------------------- + TESTS: constructors + -------------------------------------------------------------------- + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- fieldsep -> ',' | ';' + -- field -> recfield | listfield + -- recfield -> ( NAME | '[' exp1 ']' ) = exp1 + -- listfield -> expr + -------------------------------------------------------------------- +a = { -- FAIL +a = {} +a = {,} -- FAIL +a = {;} +a = {,,} -- FAIL +a = {;;} -- FAIL +a = {{ -- FAIL +a = {{{}}} +a = {{},{},{{}},} +a = { 1 } +a = { 1, } +a = { 1; } +a = { 1, 2 } +a = { a, b, c, } +a = { true; false, nil; } +a = { a.b, a[b]; a:c(), } +a = { 1 + 2, a > b, "a" or "b" } +a = { a=1, } +a = { a=1, b="foo", c=nil } +a = { a -- FAIL +a = { a= -- FAIL +a = { a=, -- FAIL +a = { a=; -- FAIL +a = { 1, a="foo" -- FAIL +a = { 1, a="foo"; b={}, d=true; } +a = { [ -- FAIL +a = { [1 -- FAIL +a = { [1] -- FAIL +a = { [a]= -- FAIL +a = { ["foo"]="bar" } +a = { [1]=a, [2]=b, } +a = { true, a=1; ["foo"]="bar", } +]] + +-- end of script diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/test_parser-5.1.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/test_parser-5.1.lua new file mode 100644 index 0000000..0809652 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/test_parser-5.1.lua @@ -0,0 +1,783 @@ +--[[-------------------------------------------------------------------- + + test_parser-5.1.lua + Lua 5.1.x parser test cases + This file is part of Yueliang. + + Copyright (c) 2006 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- Notes: +-- * there is no intention of properly specifying a grammar; the notes +-- are meant to reflect the structure of lparser so that it is easy +-- to locate and modify lparser if so desired +-- * some test may have invalid expressions but will compile, this +-- is because the chunk hasn't been executed yet +-- +-- Changed in 5.1.x: +-- * added ..., %, # cases +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- lparser parsing structure, the Lua 5.1.x version... +----------------------------------------------------------------------]] + -------------------------------------------------------------------- + -- chunk -> { stat [';'] } + -------------------------------------------------------------------- + -- stat -> DO block END + -- block -> chunk + -------------------------------------------------------------------- + -- stat -> breakstat + -- breakstat -> BREAK + -- * must have a loop to break + -- * must be last statement in a block + -------------------------------------------------------------------- + -- stat -> retstat + -- retstat -> RETURN explist + -- * must be last statement in a block + -------------------------------------------------------------------- + -- stat -> exprstat + -- exprstat -> primaryexp + -- (-> func | assignment) + -- * if LHS is VCALL then func, otherwise assignment + -- * for func, LHS is VCALL if funcargs in expression + -------------------------------------------------------------------- + -- stat -> funcstat + -- funcstat -> FUNCTION funcname body + -- funcname -> NAME {'.' NAME} [':' NAME] + -------------------------------------------------------------------- + -- body -> '(' parlist ')' chunk END + -- parlist -> [ param { ',' param } ] + -- param -> NAME + -- * DOTS must be the last parameter in a parlist + -------------------------------------------------------------------- + -- stat -> LOCAL localstat + -- LOCAL localstat -> LOCAL NAME {',' NAME} ['=' explist1] + -- explist1 -> expr { ',' expr } + -------------------------------------------------------------------- + -- stat -> LOCAL FUNCTION localfunc + -- LOCAL FUNCTION localfunc -> LOCAL FUNCTION NAME body + -------------------------------------------------------------------- + -- stat -> ifstat + -- ifstat -> IF cond THEN block + -- {ELSEIF cond THEN block} + -- [ELSE block] END + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- + -- stat -> forstat + -- forstat -> fornum | forlist + -- forlist -> NAME {,NAME} IN explist1 forbody END + -- fornum -> NAME = exp1,exp1[,exp1] forbody END + -- forbody -> DO block + -- block -> chunk + -------------------------------------------------------------------- + -- stat -> whilestat + -- whilestat -> WHILE cond DO block END + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- + -- stat -> repeatstat + -- repeatstat -> REPEAT chunk UNTIL cond + -- cond -> expr + -------------------------------------------------------------------- + -- assignment -> ',' primaryexp assignment + -- | '=' explist1 + -- explist1 -> expr { ',' expr } + -- * for assignment, LHS must be LOCAL, UPVAL, GLOBAL or INDEXED + -------------------------------------------------------------------- + -- primaryexp -> prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + -- prefixexp -> NAME | '(' expr ')' + -- funcargs -> '(' [ explist1 ] ')' | constructor | STRING + -- * funcargs turn an expr into a function call + -------------------------------------------------------------------- + -- expr -> subexpr + -- subexpr -> (UNOPR subexpr | simpleexp) { BINOPR subexpr } + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... + -- | constructor | FUNCTION body | primaryexp + -------------------------------------------------------------------- + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- fieldsep -> ',' | ';' + -- field -> recfield | listfield + -- recfield -> ( NAME | '[' exp1 ']' ) = exp1 + -- listfield -> expr + -------------------------------------------------------------------- + +--[[-------------------------------------------------------------------- +-- parser test cases, Lua 5.1.x +-- * uncomment string delimiter to enable syntax highlighting... +-- * anything that matches "^%s*%-%-" is a comment +-- * headings to display are "^%s*TESTS:%s*(.*)$" +-- * FAIL test cases should match "%s*%-%-%s*FAIL%s*$" +----------------------------------------------------------------------]] +tests_source = [=[ + -------------------------------------------------------------------- + TESTS: empty chunks + -------------------------------------------------------------------- + -- chunk -> { stat [';'] } + -------------------------------------------------------------------- + +; -- FAIL + -------------------------------------------------------------------- + TESTS: optional semicolon, simple local statements + -------------------------------------------------------------------- + -- stat -> LOCAL localstat + -- LOCAL localstat -> LOCAL NAME {',' NAME} ['=' explist1] + -- explist1 -> expr { ',' expr } + -------------------------------------------------------------------- +local -- FAIL +local; -- FAIL +local = -- FAIL +local end -- FAIL +local a +local a; +local a, b, c +local a; local b local c; +local a = 1 +local a local b = a +local a, b = 1, 2 +local a, b, c = 1, 2, 3 +local a, b, c = 1 +local a = 1, 2, 3 +local a, local -- FAIL +local 1 -- FAIL +local "foo" -- FAIL +local a = local -- FAIL +local a, b, = -- FAIL +local a, b = 1, local -- FAIL +local a, b = , local -- FAIL + -------------------------------------------------------------------- + TESTS: simple DO blocks + -------------------------------------------------------------------- + -- stat -> DO block END + -- block -> chunk + -------------------------------------------------------------------- +do -- FAIL +end -- FAIL +do end +do ; end -- FAIL +do 1 end -- FAIL +do "foo" end -- FAIL +do local a, b end +do local a local b end +do local a; local b; end +do local a = 1 end +do do end end +do do end; end +do do do end end end +do do do end; end; end +do do do return end end end +do end do -- FAIL +do end end -- FAIL +do return end +do return return end -- FAIL +do break end -- FAIL + -------------------------------------------------------------------- + TESTS: simple WHILE loops + -------------------------------------------------------------------- + -- stat -> whilestat + -- whilestat -> WHILE cond DO block END + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- +while -- FAIL +while do -- FAIL +while = -- FAIL +while 1 do -- FAIL +while 1 do end +while 1 do local a end +while 1 do local a local b end +while 1 do local a; local b; end +while 1 do 2 end -- FAIL +while 1 do "foo" end -- FAIL +while true do end +while 1 do ; end -- FAIL +while 1 do while -- FAIL +while 1 end -- FAIL +while 1 2 do -- FAIL +while 1 = 2 do -- FAIL +while 1 do return end +while 1 do return return end -- FAIL +while 1 do do end end +while 1 do do return end end +while 1 do break end +while 1 do break break end -- FAIL +while 1 do do break end end + -------------------------------------------------------------------- + TESTS: simple REPEAT loops + -------------------------------------------------------------------- + -- stat -> repeatstat + -- repeatstat -> REPEAT chunk UNTIL cond + -- cond -> expr + -------------------------------------------------------------------- +repeat -- FAIL +repeat until -- FAIL +repeat until 0 +repeat until false +repeat until local -- FAIL +repeat end -- FAIL +repeat 1 -- FAIL +repeat = -- FAIL +repeat local a until 1 +repeat local a local b until 0 +repeat local a; local b; until 0 +repeat ; until 1 -- FAIL +repeat 2 until 1 -- FAIL +repeat "foo" until 1 -- FAIL +repeat return until 0 +repeat return return until 0 -- FAIL +repeat break until 0 +repeat break break until 0 -- FAIL +repeat do end until 0 +repeat do return end until 0 +repeat do break end until 0 + -------------------------------------------------------------------- + TESTS: simple FOR loops + -------------------------------------------------------------------- + -- stat -> forstat + -- forstat -> fornum | forlist + -- forlist -> NAME {,NAME} IN explist1 forbody END + -- fornum -> NAME = exp1,exp1[,exp1] forbody END + -- forbody -> DO block + -- block -> chunk + -------------------------------------------------------------------- +for -- FAIL +for do -- FAIL +for end -- FAIL +for 1 -- FAIL +for a -- FAIL +for true -- FAIL +for a, in -- FAIL +for a in -- FAIL +for a do -- FAIL +for a in do -- FAIL +for a in b do -- FAIL +for a in b end -- FAIL +for a in b, do -- FAIL +for a in b do end +for a in b do local a local b end +for a in b do local a; local b; end +for a in b do 1 end -- FAIL +for a in b do "foo" end -- FAIL +for a b in -- FAIL +for a, b, c in p do end +for a, b, c in p, q, r do end +for a in 1 do end +for a in true do end +for a in "foo" do end +for a in b do break end +for a in b do break break end -- FAIL +for a in b do return end +for a in b do return return end -- FAIL +for a in b do do end end +for a in b do do break end end +for a in b do do return end end +for = -- FAIL +for a = -- FAIL +for a, b = -- FAIL +for a = do -- FAIL +for a = 1, do -- FAIL +for a = p, q, do -- FAIL +for a = p q do -- FAIL +for a = b do end -- FAIL +for a = 1, 2, 3, 4 do end -- FAIL +for a = p, q do end +for a = 1, 2 do end +for a = 1, 2 do local a local b end +for a = 1, 2 do local a; local b; end +for a = 1, 2 do 3 end -- FAIL +for a = 1, 2 do "foo" end -- FAIL +for a = p, q, r do end +for a = 1, 2, 3 do end +for a = p, q do break end +for a = p, q do break break end -- FAIL +for a = 1, 2 do return end +for a = 1, 2 do return return end -- FAIL +for a = p, q do do end end +for a = p, q do do break end end +for a = p, q do do return end end + -------------------------------------------------------------------- + TESTS: break statement + -------------------------------------------------------------------- + -- stat -> breakstat + -- breakstat -> BREAK + -- * must have a loop to break + -- * must be last statement in a block + -------------------------------------------------------------------- +break -- FAIL + -------------------------------------------------------------------- + TESTS: return statement + -------------------------------------------------------------------- + -- stat -> retstat + -- retstat -> RETURN explist + -- * must be last statement in a block + -------------------------------------------------------------------- +return +return; +return return -- FAIL +return 1 +return local -- FAIL +return "foo" +return 1, -- FAIL +return 1,2,3 +return a,b,c,d +return 1,2; +return ... +return 1,a,... + -------------------------------------------------------------------- + TESTS: conditional statements + -------------------------------------------------------------------- + -- stat -> ifstat + -- ifstat -> IF cond THEN block + -- {ELSEIF cond THEN block} + -- [ELSE block] END + -- block -> chunk + -- cond -> expr + -------------------------------------------------------------------- +if -- FAIL +elseif -- FAIL +else -- FAIL +then -- FAIL +if then -- FAIL +if 1 -- FAIL +if 1 then -- FAIL +if 1 else -- FAIL +if 1 then else -- FAIL +if 1 then elseif -- FAIL +if 1 then end +if 1 then local a end +if 1 then local a local b end +if 1 then local a; local b; end +if 1 then else end +if 1 then local a else local b end +if 1 then local a; else local b; end +if 1 then elseif 2 -- FAIL +if 1 then elseif 2 then -- FAIL +if 1 then elseif 2 then end +if 1 then local a elseif 2 then local b end +if 1 then local a; elseif 2 then local b; end +if 1 then elseif 2 then else end +if 1 then else if 2 then end end +if 1 then else if 2 then end -- FAIL +if 1 then break end -- FAIL +if 1 then return end +if 1 then return return end -- FAIL +if 1 then end; if 1 then end; + -------------------------------------------------------------------- + TESTS: function statements + -------------------------------------------------------------------- + -- stat -> funcstat + -- funcstat -> FUNCTION funcname body + -- funcname -> NAME {'.' NAME} [':' NAME] + -------------------------------------------------------------------- + -- body -> '(' parlist ')' chunk END + -- parlist -> [ param { ',' param } ] + -- param -> NAME + -- * DOTS must be the last parameter in a parlist + -------------------------------------------------------------------- +function -- FAIL +function 1 -- FAIL +function end -- FAIL +function a -- FAIL +function a end -- FAIL +function a( end -- FAIL +function a() end +function a(1 -- FAIL +function a("foo" -- FAIL +function a(p -- FAIL +function a(p,) -- FAIL +function a(p q -- FAIL +function a(p) end +function a(p,q,) end -- FAIL +function a(p,q,r) end +function a(p,q,1 -- FAIL +function a(p) do -- FAIL +function a(p) 1 end -- FAIL +function a(p) return end +function a(p) break end -- FAIL +function a(p) return return end -- FAIL +function a(p) do end end +function a.( -- FAIL +function a.1 -- FAIL +function a.b() end +function a.b, -- FAIL +function a.b.( -- FAIL +function a.b.c.d() end +function a: -- FAIL +function a:1 -- FAIL +function a:b() end +function a:b: -- FAIL +function a:b. -- FAIL +function a.b.c:d() end +function a(...) end +function a(..., -- FAIL +function a(p,...) end +function a(p,q,r,...) end +function a() local a local b end +function a() local a; local b; end +function a() end; function a() end; + -------------------------------------------------------------------- + TESTS: local function statements + -------------------------------------------------------------------- + -- stat -> LOCAL FUNCTION localfunc + -- LOCAL FUNCTION localfunc -> LOCAL FUNCTION NAME body + -------------------------------------------------------------------- +local function -- FAIL +local function 1 -- FAIL +local function end -- FAIL +local function a -- FAIL +local function a end -- FAIL +local function a( end -- FAIL +local function a() end +local function a(1 -- FAIL +local function a("foo" -- FAIL +local function a(p -- FAIL +local function a(p,) -- FAIL +local function a(p q -- FAIL +local function a(p) end +local function a(p,q,) end -- FAIL +local function a(p,q,r) end +local function a(p,q,1 -- FAIL +local function a(p) do -- FAIL +local function a(p) 1 end -- FAIL +local function a(p) return end +local function a(p) break end -- FAIL +local function a(p) return return end -- FAIL +local function a(p) do end end +local function a. -- FAIL +local function a: -- FAIL +local function a(...) end +local function a(..., -- FAIL +local function a(p,...) end +local function a(p,q,r,...) end +local function a() local a local b end +local function a() local a; local b; end +local function a() end; local function a() end; + -------------------------------------------------------------------- + -- stat -> exprstat + -- exprstat -> primaryexp + -- (-> func | assignment) + -- * if LHS is VCALL then func, otherwise assignment + -- * for func, LHS is VCALL if funcargs in expression + -------------------------------------------------------------------- + TESTS: assignments + -------------------------------------------------------------------- + -- assignment -> ',' primaryexp assignment + -- | '=' explist1 + -- explist1 -> expr { ',' expr } + -- * for assignment, LHS must be LOCAL, UPVAL, GLOBAL or INDEXED + -------------------------------------------------------------------- +a -- FAIL +a, -- FAIL +a,b,c -- FAIL +a,b = -- FAIL +a = 1 +a = 1,2,3 +a,b,c = 1 +a,b,c = 1,2,3 +a.b = 1 +a.b.c = 1 +a[b] = 1 +a[b][c] = 1 +a.b[c] = 1 +a[b].c = 1 +0 = -- FAIL +"foo" = -- FAIL +true = -- FAIL +(a) = -- FAIL +{} = -- FAIL +a:b() = -- FAIL +a() = -- FAIL +a.b:c() = -- FAIL +a[b]() = -- FAIL +a = a b -- FAIL +a = 1 2 -- FAIL +a = a = 1 -- FAIL + -------------------------------------------------------------------- + TESTS: function calls + -------------------------------------------------------------------- + -- primaryexp -> prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } + -- prefixexp -> NAME | '(' expr ')' + -- funcargs -> '(' [ explist1 ] ')' | constructor | STRING + -- * funcargs turn an expr into a function call + -------------------------------------------------------------------- +a( -- FAIL +a() +a(1) +a(1,) -- FAIL +a(1,2,3) +1() -- FAIL +a()() +a.b() +a[b]() +a.1 -- FAIL +a.b -- FAIL +a[b] -- FAIL +a.b.( -- FAIL +a.b.c() +a[b][c]() +a[b].c() +a.b[c]() +a:b() +a:b -- FAIL +a:1 -- FAIL +a.b:c() +a[b]:c() +a:b: -- FAIL +a:b():c() +a:b().c[d]:e() +a:b()[c].d:e() +(a)() +()() -- FAIL +(1)() +("foo")() +(true)() +(a)()() +(a.b)() +(a[b])() +(a).b() +(a)[b]() +(a):b() +(a).b[c]:d() +(a)[b].c:d() +(a):b():c() +(a):b().c[d]:e() +(a):b()[c].d:e() + -------------------------------------------------------------------- + TESTS: more function calls + -------------------------------------------------------------------- +a"foo" +a[[foo]] +a.b"foo" +a[b]"foo" +a:b"foo" +a{} +a.b{} +a[b]{} +a:b{} +a()"foo" +a"foo"() +a"foo".b() +a"foo"[b]() +a"foo":c() +a"foo""bar" +a"foo"{} +(a):b"foo".c[d]:e"bar" +(a):b"foo"[c].d:e"bar" +a(){} +a{}() +a{}.b() +a{}[b]() +a{}:c() +a{}"foo" +a{}{} +(a):b{}.c[d]:e{} +(a):b{}[c].d:e{} + -------------------------------------------------------------------- + TESTS: simple expressions + -------------------------------------------------------------------- + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... + -- | constructor | FUNCTION body | primaryexp + -------------------------------------------------------------------- +a = -- FAIL +a = a +a = nil +a = false +a = 1 +a = "foo" +a = [[foo]] +a = {} +a = (a) +a = (nil) +a = (true) +a = (1) +a = ("foo") +a = ([[foo]]) +a = ({}) +a = a.b +a = a.b. -- FAIL +a = a.b.c +a = a:b -- FAIL +a = a[b] +a = a[1] +a = a["foo"] +a = a[b][c] +a = a.b[c] +a = a[b].c +a = (a)[b] +a = (a).c +a = () -- FAIL +a = a() +a = a.b() +a = a[b]() +a = a:b() +a = (a)() +a = (a).b() +a = (a)[b]() +a = (a):b() +a = a"foo" +a = a{} +a = function -- FAIL +a = function 1 -- FAIL +a = function a -- FAIL +a = function end -- FAIL +a = function( -- FAIL +a = function() end +a = function(1 -- FAIL +a = function(p) end +a = function(p,) -- FAIL +a = function(p q -- FAIL +a = function(p,q,r) end +a = function(p,q,1 -- FAIL +a = function(...) end +a = function(..., -- FAIL +a = function(p,...) end +a = function(p,q,r,...) end +a = ... +a = a, b, ... +a = (...) +a = ..., 1, 2 +a = function() return ... end -- FAIL + -------------------------------------------------------------------- + TESTS: operators + -------------------------------------------------------------------- + -- expr -> subexpr + -- subexpr -> (UNOPR subexpr | simpleexp) { BINOPR subexpr } + -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... + -- | constructor | FUNCTION body | primaryexp + -------------------------------------------------------------------- +a = -10 +a = -"foo" +a = -a +a = -nil +a = -true +a = -{} +a = -function() end +a = -a() +a = -(a) +a = - -- FAIL +a = not 10 +a = not "foo" +a = not a +a = not nil +a = not true +a = not {} +a = not function() end +a = not a() +a = not (a) +a = not -- FAIL +a = #10 +a = #"foo" +a = #a +a = #nil +a = #true +a = #{} +a = #function() end +a = #a() +a = #(a) +a = # -- FAIL +a = 1 + 2; a = 1 - 2 +a = 1 * 2; a = 1 / 2 +a = 1 ^ 2; a = 1 % 2 +a = 1 .. 2 +a = 1 + -- FAIL +a = 1 .. -- FAIL +a = 1 * / -- FAIL +a = 1 + -2; a = 1 - -2 +a = 1 * - -- FAIL +a = 1 * not 2; a = 1 / not 2 +a = 1 / not -- FAIL +a = 1 * #"foo"; a = 1 / #"foo" +a = 1 / # -- FAIL +a = 1 + 2 - 3 * 4 / 5 % 6 ^ 7 +a = ((1 + 2) - 3) * (4 / (5 % 6 ^ 7)) +a = (1 + (2 - (3 * (4 / (5 % 6 ^ ((7))))))) +a = ((1 -- FAIL +a = ((1 + 2) -- FAIL +a = 1) -- FAIL +a = a + b - c +a = "foo" + "bar" +a = "foo".."bar".."baz" +a = true + false - nil +a = {} * {} +a = function() end / function() end +a = a() ^ b() +a = ... % ... + -------------------------------------------------------------------- + TESTS: more operators + -------------------------------------------------------------------- +a = 1 == 2; a = 1 ~= 2 +a = 1 < 2; a = 1 <= 2 +a = 1 > 2; a = 1 >= 2 +a = 1 < 2 < 3 +a = 1 >= 2 >= 3 +a = 1 == -- FAIL +a = ~= 2 -- FAIL +a = "foo" == "bar" +a = "foo" > "bar" +a = a ~= b +a = true == false +a = 1 and 2; a = 1 or 2 +a = 1 and -- FAIL +a = or 1 -- FAIL +a = 1 and 2 and 3 +a = 1 or 2 or 3 +a = 1 and 2 or 3 +a = a and b or c +a = a() and (b)() or c.d +a = "foo" and "bar" +a = true or false +a = {} and {} or {} +a = (1) and ("foo") or (nil) +a = function() end == function() end +a = function() end or function() end + -------------------------------------------------------------------- + TESTS: constructors + -------------------------------------------------------------------- + -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' + -- fieldsep -> ',' | ';' + -- field -> recfield | listfield + -- recfield -> ( NAME | '[' exp1 ']' ) = exp1 + -- listfield -> expr + -------------------------------------------------------------------- +a = { -- FAIL +a = {} +a = {,} -- FAIL +a = {;} -- FAIL +a = {,,} -- FAIL +a = {;;} -- FAIL +a = {{ -- FAIL +a = {{{}}} +a = {{},{},{{}},} +a = { 1 } +a = { 1, } +a = { 1; } +a = { 1, 2 } +a = { a, b, c, } +a = { true; false, nil; } +a = { a.b, a[b]; a:c(), } +a = { 1 + 2, a > b, "a" or "b" } +a = { a=1, } +a = { a=1, b="foo", c=nil } +a = { a -- FAIL +a = { a= -- FAIL +a = { a=, -- FAIL +a = { a=; -- FAIL +a = { 1, a="foo" -- FAIL +a = { 1, a="foo"; b={}, d=true; } +a = { [ -- FAIL +a = { [1 -- FAIL +a = { [1] -- FAIL +a = { [a]= -- FAIL +a = { ["foo"]="bar" } +a = { [1]=a, [2]=b, } +a = { true, a=1; ["foo"]="bar", } +]=] + +-- end of script diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/test_scripts-5.0.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/test_scripts-5.0.lua new file mode 100644 index 0000000..53a3ae3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/test_scripts-5.0.lua @@ -0,0 +1,158 @@ +--[[-------------------------------------------------------------------- + + test_scripts-5.0.lua + Compile and compare Lua files + This file is part of Yueliang. + + Copyright (c) 2005-2007 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- NOTE +-- * use the argument ALL to pull in additional personal Lua scripts +-- for testing, e.g. lua test_scripts.lua ALL +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- reads in a list of files to crunch from a text file +------------------------------------------------------------------------ + +local function loadlist(fname, flist) + local inf = io.open(fname, "r") + if not inf then error("cannot open "..fname.." for reading") end + while true do + local d = inf:read("*l") + if not d then break end + if string.find(d, "^%s*$") or string.find(d, "^#") then + -- comments and empty lines are ignored + else + table.insert(flist, d) + end + end + inf:close() +end + +------------------------------------------------------------------------ +-- read in list of files to test +------------------------------------------------------------------------ + +local files = {} + +loadlist("files-lua-5.0.txt", files) +loadlist("files-yueliang-5.0.txt", files) + +-- pull in personal scripts to test if user specifies "ALL" +if arg[1] == "ALL" then + loadlist("files-other-5.0.txt", files) +end + +-- if you want to specify files in this script itself (not recommended) +-- you can add them using the following +--[[ +for v in string.gfind([[ +]], "[^%s]+") do + table.insert(files, v) +end +--]] + +total = 0 -- sum of sizes +fsize = 0 -- current file size + +------------------------------------------------------------------------ +-- initialize +------------------------------------------------------------------------ + +require("../orig-5.0.3/lzio") +require("../orig-5.0.3/llex") +require("../orig-5.0.3/lopcodes") +require("../orig-5.0.3/ldump") +require("../orig-5.0.3/lcode") +require("../orig-5.0.3/lparser") + +function lua_assert(test) + if not test then error("assertion failed!") end +end + +luaX:init() + +io.stdout:write("\n\n") + +------------------------------------------------------------------------ +-- * basic comparison for now; do it properly later +------------------------------------------------------------------------ + +local LuaState = {} + +------------------------------------------------------------------------ +-- dump binary chunks to a file if something goes wrong +------------------------------------------------------------------------ +local function Dump(data, filename) + h = io.open(filename, "wb") + if not h then error("failed to open "..filename.." for writing") end + h:write(data) + h:close() +end + +------------------------------------------------------------------------ +-- create custom chunk reader (sums up file sizes) +------------------------------------------------------------------------ +function make_getF(filename) + local h = io.open(filename, "r") + if not h then return nil end + fsize = h:seek("end") + h:seek("set") + total = total + fsize + return function() -- chunk reader anonymous function here + if not h then return nil end + local buff = h:read(512) + if not buff then h:close() end + return buff + end +end + +------------------------------------------------------------------------ +-- attempt to compile Lua source files +------------------------------------------------------------------------ +for i, filename in ipairs(files) do + -- compile a source file + local zio = luaZ:init(make_getF(filename), nil, "@"..filename) + if not zio then + error("could not initialize zio stream for "..filename) + end + io.stdout:write(filename.."("..fsize.."): ") + local Func = luaY:parser(LuaState, zio, nil) + local Writer, Buff = luaU:make_setS() + luaU:dump(LuaState, Func, Writer, Buff) + local bc1 = Buff.data -- Yueliang's output + + local f = loadfile(filename) + local bc2 = string.dump(f) -- Lua's output + + -- compare outputs + if string.len(bc1) ~= string.len(bc2) then + Dump(bc1, "bc1.out") + Dump(bc2, "bc2.out") + error("binary chunk sizes different") + elseif bc1 ~= bc2 then + Dump(bc1, "bc1.out") + Dump(bc2, "bc2.out") + error("binary chunks different") + else + io.stdout:write("CORRECT\n") + end + local x, y = gcinfo() + -- memory usage isn't really a problem for the straight port + -- string handling in Lua that follows the original C closely is more + -- of a problem, but this will be fixed elsewhere, not in this tree + --io.stdout:write("gcinfo: "..x.." "..y.."\n") +end + +-- summaries here +io.stdout:write("\nTotal file sizes: "..total.."\n") + +-- end diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/test_scripts-5.1.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/test_scripts-5.1.lua new file mode 100644 index 0000000..4d84055 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/test_scripts-5.1.lua @@ -0,0 +1,158 @@ +--[[-------------------------------------------------------------------- + + test_scripts-5.1.lua + Compile and compare Lua files + This file is part of Yueliang. + + Copyright (c) 2005-2007 Kein-Hong Man + The COPYRIGHT file describes the conditions + under which this software may be distributed. + + See the ChangeLog for more information. + +----------------------------------------------------------------------]] + +--[[-------------------------------------------------------------------- +-- NOTE +-- * use the argument ALL to pull in additional personal Lua scripts +-- for testing, e.g. lua test_scripts.lua ALL +----------------------------------------------------------------------]] + +------------------------------------------------------------------------ +-- reads in a list of files to crunch from a text file +------------------------------------------------------------------------ + +local function loadlist(fname, flist) + local inf = io.open(fname, "r") + if not inf then error("cannot open "..fname.." for reading") end + while true do + local d = inf:read("*l") + if not d then break end + if string.match(d, "^%s*$") or string.match(d, "^#") then + -- comments and empty lines are ignored + else + flist[#flist+1] = d + end + end + inf:close() +end + +------------------------------------------------------------------------ +-- read in list of files to test +------------------------------------------------------------------------ + +local files = {} + +loadlist("files-lua-5.1.txt", files) +loadlist("files-yueliang-5.1.txt", files) + +-- pull in personal scripts to test if user specifies "ALL" +if arg[1] == "ALL" then + loadlist("files-other-5.1.txt", files) +end + +-- if you want to specify files in this script itself (not recommended) +-- you can add them using the following +--[=[ +for v in string.gmatch([[ +]], "[^%s]+") do + table.insert(files, v) +end +--]=] + +total = 0 -- sum of sizes +fsize = 0 -- current file size + +------------------------------------------------------------------------ +-- initialize +------------------------------------------------------------------------ + +dofile("../orig-5.1.2/lzio.lua") +dofile("../orig-5.1.2/llex.lua") +dofile("../orig-5.1.2/lopcodes.lua") +dofile("../orig-5.1.2/ldump.lua") +dofile("../orig-5.1.2/lcode.lua") +dofile("../orig-5.1.2/lparser.lua") + +function lua_assert(test) + if not test then error("assertion failed!") end +end + +luaX:init() + +io.stdout:write("\n\n") + +------------------------------------------------------------------------ +-- * basic comparison for now; do it properly later +------------------------------------------------------------------------ + +local LuaState = {} + +------------------------------------------------------------------------ +-- dump binary chunks to a file if something goes wrong +------------------------------------------------------------------------ +local function Dump(data, filename) + h = io.open(filename, "wb") + if not h then error("failed to open "..filename.." for writing") end + h:write(data) + h:close() +end + +------------------------------------------------------------------------ +-- create custom chunk reader (sums up file sizes) +------------------------------------------------------------------------ +function make_getF(filename) + local h = io.open(filename, "r") + if not h then return nil end + fsize = h:seek("end") + h:seek("set") + total = total + fsize + return function() -- chunk reader anonymous function here + if not h then return nil end + local buff = h:read(512) + if not buff then h:close() end + return buff + end +end + +------------------------------------------------------------------------ +-- attempt to compile Lua source files +------------------------------------------------------------------------ +for i, filename in ipairs(files) do + -- compile a source file + local zio = luaZ:init(make_getF(filename), nil) + if not zio then + error("could not initialize zio stream for "..filename) + end + io.stdout:write(filename.."("..fsize.."): ") + local Func = luaY:parser(LuaState, zio, nil, "@"..filename) + local Writer, Buff = luaU:make_setS() + luaU:dump(LuaState, Func, Writer, Buff) + local bc1 = Buff.data -- Yueliang's output + + local f = loadfile(filename) + local bc2 = string.dump(f) -- Lua's output + + -- compare outputs + if #bc1 ~= #bc2 then + Dump(bc1, "bc1.out") + Dump(bc2, "bc2.out") + error("binary chunk sizes different") + elseif bc1 ~= bc2 then + Dump(bc1, "bc1.out") + Dump(bc2, "bc2.out") + error("binary chunks different") + else + io.stdout:write("CORRECT\n") + end + local x = collectgarbage("count") + -- memory usage isn't really a problem for the straight port + -- string handling in Lua that follows the original C closely is more + -- of a problem, but this will be fixed elsewhere, not in this tree + --io.stdout:write("collectgarbage: "..x.."\n") +end + +-- summaries here +io.stdout:write("\nTotal file sizes: "..total.."\n") + +-- end -- cgit v1.1