diff options
author | David Walter Seikel | 2012-01-23 21:58:02 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-23 21:58:02 +1000 |
commit | 2d1df4714e2736dbde7855ddcd76b4c1de822fa5 (patch) | |
tree | c80e4622631c92dbe8dd6375d187702d084c2f2b /LuaSL/testLua/yueliang-0.4.1 | |
parent | Remove the conflict, and the comment. lol (diff) | |
download | SledjHamr-2d1df4714e2736dbde7855ddcd76b4c1de822fa5.zip SledjHamr-2d1df4714e2736dbde7855ddcd76b4c1de822fa5.tar.gz SledjHamr-2d1df4714e2736dbde7855ddcd76b4c1de822fa5.tar.bz2 SledjHamr-2d1df4714e2736dbde7855ddcd76b4c1de822fa5.tar.xz |
Added a big bunch of example lua scripts for testing the speed of lua compiling.
Diffstat (limited to '')
180 files changed, 29784 insertions, 0 deletions
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 @@ | |||
1 | Yueliang License | ||
2 | ---------------- | ||
3 | |||
4 | Yueliang is licensed under the terms of the MIT license reproduced | ||
5 | below. This means that Yueliang is free software and can be used | ||
6 | for both academic and commercial purposes at absolutely no cost. | ||
7 | |||
8 | Yueliang is based on Lua 5 code. See COPYRIGHT_Lua5 (Lua 5.0.3) and | ||
9 | COPYRIGHT_Lua51 (Lua 5.1.3) for Lua 5 license information. | ||
10 | |||
11 | For details and rationale, see http://www.lua.org/license.html . | ||
12 | |||
13 | =============================================================================== | ||
14 | |||
15 | Yueliang Copyright (C) 2005-2008 Kein-Hong Man <khman@users.sf.net> | ||
16 | Lua 5.0.3 Copyright (C) 2003-2006 Tecgraf, PUC-Rio. | ||
17 | Lua 5.1.3 Copyright (C) 1994-2008 Lua.org, PUC-Rio. | ||
18 | |||
19 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
20 | of this software and associated documentation files (the "Software"), to deal | ||
21 | in the Software without restriction, including without limitation the rights | ||
22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
23 | copies of the Software, and to permit persons to whom the Software is | ||
24 | furnished to do so, subject to the following conditions: | ||
25 | |||
26 | The above copyright notice and this permission notice shall be included in | ||
27 | all copies or substantial portions of the Software. | ||
28 | |||
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
35 | THE SOFTWARE. | ||
36 | |||
37 | =============================================================================== | ||
38 | |||
39 | (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 @@ | |||
1 | Lua License | ||
2 | ----------- | ||
3 | |||
4 | Lua is licensed under the terms of the MIT license reproduced below. | ||
5 | This means that Lua is free software and can be used for both academic | ||
6 | and commercial purposes at absolutely no cost. | ||
7 | |||
8 | For details and rationale, see http://www.lua.org/license.html . | ||
9 | |||
10 | =============================================================================== | ||
11 | |||
12 | Copyright (C) 2003-2006 Tecgraf, PUC-Rio. | ||
13 | |||
14 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
15 | of this software and associated documentation files (the "Software"), to deal | ||
16 | in the Software without restriction, including without limitation the rights | ||
17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
18 | copies of the Software, and to permit persons to whom the Software is | ||
19 | furnished to do so, subject to the following conditions: | ||
20 | |||
21 | The above copyright notice and this permission notice shall be included in | ||
22 | all copies or substantial portions of the Software. | ||
23 | |||
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
30 | THE SOFTWARE. | ||
31 | |||
32 | =============================================================================== | ||
33 | |||
34 | (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 @@ | |||
1 | Lua License | ||
2 | ----------- | ||
3 | |||
4 | Lua is licensed under the terms of the MIT license reproduced below. | ||
5 | This means that Lua is free software and can be used for both academic | ||
6 | and commercial purposes at absolutely no cost. | ||
7 | |||
8 | For details and rationale, see http://www.lua.org/license.html . | ||
9 | |||
10 | =============================================================================== | ||
11 | |||
12 | Copyright (C) 1994-2008 Lua.org, PUC-Rio. | ||
13 | |||
14 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
15 | of this software and associated documentation files (the "Software"), to deal | ||
16 | in the Software without restriction, including without limitation the rights | ||
17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
18 | copies of the Software, and to permit persons to whom the Software is | ||
19 | furnished to do so, subject to the following conditions: | ||
20 | |||
21 | The above copyright notice and this permission notice shall be included in | ||
22 | all copies or substantial portions of the Software. | ||
23 | |||
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
30 | THE SOFTWARE. | ||
31 | |||
32 | =============================================================================== | ||
33 | |||
34 | (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 @@ | |||
1 | yueliang changelog | ||
2 | ------------------ | ||
3 | |||
4 | 2008-05-31 Kein-Hong Man <khman@users.sf.net> | ||
5 | |||
6 | * nat-5.0.3/README: updated notes | ||
7 | * nat-5.1.3/README: updated notes | ||
8 | * Manifest: updated | ||
9 | * README: updated | ||
10 | * Version: 0.4.1 | ||
11 | |||
12 | 2008-05-31 Kein-Hong Man <khman@users.sf.net> | ||
13 | |||
14 | * test/test_lparser_mk3_2.lua: added better parser tester that | ||
15 | covers whole grammar, all tests passes | ||
16 | * test/test_lparser_mk3_2.lua: added better parser tester that | ||
17 | covers whole grammar, all tests passes | ||
18 | * nat-5.0.3/test/bench_llex_mk2.lua, nat-5.0.3/test/bench_llex_mk3.lua, | ||
19 | nat-5.0.3/test/bench_llex_mk4.lua, nat-5.0.3/test/test_lzio_mk2.lua, | ||
20 | nat-5.0.3/test/test_lparser_mk3.lua, nat-5.0.3/test/test_lparser_mk3b.lua, | ||
21 | nat-5.0.3/test/test_llex_mk2.lua, nat-5.0.3/test/test_llex_mk3.lua, | ||
22 | nat-5.0.3/test/test_llex_mk4.lua: | ||
23 | adjusted require() call to loose .lua extension, better? | ||
24 | * nat-5.0.3/README: updated info | ||
25 | * orig-5.0.3/test/test_ldump.lua, orig-5.0.3/test/test_llex.lua, | ||
26 | orig-5.0.3/test/bench_llex.lua, orig-5.0.3/test/test_lparser.lua, | ||
27 | orig-5.0.3/test/test_number.lua, orig-5.0.3/test/test_lparser2.lua, | ||
28 | orig-5.0.3/test/test_lzio.lua, test_lua/test_scripts-5.0.lua: | ||
29 | adjusted require() call to loose .lua extension, better? | ||
30 | * orig-5.0.3/test/test_llex.lua: fixed minor change in test case | ||
31 | output, probably something changed between 5.0.2 and 5.0.3 | ||
32 | * nat-5.1.3/test/test_lparser_mk2_2.lua: added better parser tester | ||
33 | that covers whole grammar, all tests passes | ||
34 | |||
35 | 2008-05-29 Kein-Hong Man <khman@users.sf.net> | ||
36 | |||
37 | * nat-5.1.3/lparser_mk2.lua: bug, binopr_* missing '%' operator | ||
38 | |||
39 | 2008-05-28 Kein-Hong Man <khman@users.sf.net> | ||
40 | |||
41 | * nat-5.1.3/lparser_mk2.lua: bug, unopr[] missing '#' operator | ||
42 | |||
43 | 2008-05-23 Kein-Hong Man <khman@users.sf.net> | ||
44 | |||
45 | * orig-5.0.3/test/test_llex.lua: removed duplicate test entry | ||
46 | * orig-5.1.3/test/test_llex.lua: removed duplicate test entry | ||
47 | * nat-5.0.3/test/test_llex_mk2.lua: removed duplicate test entry | ||
48 | * nat-5.0.3/test/test_llex_mk3.lua: removed duplicate test entry | ||
49 | * nat-5.0.3/test/test_llex_mk4.lua: removed duplicate test entry | ||
50 | * nat-5.1.3/test/test_llex_mk2.lua: removed duplicate test entry | ||
51 | |||
52 | 2008-05-22 Kein-Hong Man <khman@users.sf.net> | ||
53 | |||
54 | * nat-5.1.3/lparser_mk2.lua: finish debugging, all test sample | ||
55 | appear to work | ||
56 | * nat-5.1.3/test/test_lparser_mk2.lua: added test script, works | ||
57 | * nat-5.1.3/test/parser_log/sample_*.lua: added parser output | ||
58 | log message samples | ||
59 | * nat-5.1.3/README: updated notes | ||
60 | * Manifest: updated | ||
61 | * README: updated | ||
62 | * OlderNews: updated | ||
63 | * Version: 0.4.0 | ||
64 | |||
65 | 2008-05-22 Kein-Hong Man <khman@users.sf.net> | ||
66 | |||
67 | * nat-5.1.3/lparser_mk2.lua (init): mistake in naming llex.llex | ||
68 | * nat-5.1.3/lparser_mk2.lua (str_checkname): forgot to remove | ||
69 | original C parameter 'ls' in call to check() | ||
70 | * nat-5.1.3/lparser_mk2.lua (constructor): missed name change | ||
71 | from luaX to llex | ||
72 | * nat-5.1.3/lparser_mk2.lua: added a local _G for *_stat lookups | ||
73 | * nat-5.1.3/lparser_mk2.lua (test_then_block): v parm not needed | ||
74 | * nat-5.1.3/lparser_mk2.lua (cond): v parm not needed, added | ||
75 | a local v creation before calling expr() in body, removed not | ||
76 | needed v creation in functions that call cond() | ||
77 | * nat-5.1.3/lparser_mk2.lua (simpleexp): check_condition() for | ||
78 | fs.is_vararg, wrong sense | ||
79 | * nat-5.1.3/lparser_mk2.lua: reset top_fs each time initialized; | ||
80 | added forward references for local functions | ||
81 | |||
82 | 2008-05-20 Kein-Hong Man <khman@users.sf.net> | ||
83 | |||
84 | * nat-5.1.3/lparser_mk2.lua: new file, bits and pieces for | ||
85 | native 5.1.x parser, ongoing | ||
86 | * nat-5.1.3/lparser_mk2.lua: completed initial coding, | ||
87 | untested | ||
88 | |||
89 | 2008-05-20 Kein-Hong Man <khman@users.sf.net> | ||
90 | |||
91 | * nat-5.0.3/README: updated with caveats about line ending | ||
92 | normalization in strings and long strings | ||
93 | * nat-5.1.3/README: updated notes | ||
94 | * README: updated | ||
95 | * Version: 0.3.2 | ||
96 | |||
97 | 2008-05-20 Kein-Hong Man <khman@users.sf.net> | ||
98 | |||
99 | * nat-5.1.3/test/test_llex_mk2.lua: native 5.1.x lexer tester | ||
100 | * nat-5.1.3/test/test_llex_mk2.lua: deleted deprecated tests | ||
101 | * nat-5.1.3/llex_mk2.lua: adjusted require call | ||
102 | * nat-5.1.3/llex_mk2.lua: made sourceid handling more robust | ||
103 | * nat-5.1.3/llex_mk2.lua (llex): mistake in porting code from | ||
104 | 5.0.x native lexer -- variable kept as q when it was renamed p | ||
105 | * nat-5.1.3/llex_mk2.lua (read_long_string): missing reassign | ||
106 | main value I of lexing position for ']' negative test | ||
107 | * nat-5.1.3/llex_mk2.lua (read_long_string): missing add string | ||
108 | segment to buffer for ']' negative test | ||
109 | * nat-5.1.3/llex_mk2.lua (read_string): fixed \xxx sequence | ||
110 | conversion from number to string, forgot how old code worked | ||
111 | * nat-5.1.3/llex_mk2.lua: works | ||
112 | * nat-5.1.3/test/test_llex_mk2.lua: all tests run | ||
113 | * nat-5.1.3/README: updated | ||
114 | |||
115 | 2008-05-19 Kein-Hong Man <khman@users.sf.net> | ||
116 | |||
117 | * nat-5.1.3/: created for 5.1.x lexer/parser work | ||
118 | * nat-5.1.3/test: created for test scripts | ||
119 | * nat-5.1.3/llex_mk2.lua: preliminary native lexer for Lua 5.1.x | ||
120 | complete (except for next() and lookahead()), untested | ||
121 | * nat-5.1.3/README: added | ||
122 | |||
123 | 2008-05-19 Kein-Hong Man <khman@users.sf.net> | ||
124 | |||
125 | * orig-5.0.3/lparser.lua: added comments for calls | ||
126 | * nat-5.0.3/lparser_mk3b.lua: new native parser, same as | ||
127 | lparser_mk3.lua except with variable management code added | ||
128 | * nat-5.0.3/test/test_lparser_mk3b.lua: new test script, | ||
129 | started testing variable management code | ||
130 | * nat-5.0.3/lparser_mk3b.lua (luaY:new_localvar, luaY:searchvar): | ||
131 | fixed var lookup bug due to fs.bl=nil at function top level | ||
132 | * nat-5.0.3/lparser_mk3b.lua (luaY:singlevaraux): fixed bug due | ||
133 | to wrong name used, 'v' instead of the correct 'var' | ||
134 | * nat-5.0.3/lparser_mk3b.lua: fixed extra 'ls' parms that ought | ||
135 | to be removed, when adding code to manage variables; copied from | ||
136 | lparser.lua without thinking | ||
137 | * nat-5.0.3/test/parser_log/sample_b_*.lua: added log samples | ||
138 | * nat-5.0.3/README: updated | ||
139 | * Manifest: updated for parser log samples | ||
140 | * README: updated | ||
141 | * OlderNews: updated | ||
142 | * Version: 0.3.1 | ||
143 | |||
144 | 2008-04-13 Kein-Hong Man <khman@users.sf.net> | ||
145 | |||
146 | * nat-5.0.3/test/parser_log/: new subdirectory for log samples | ||
147 | * nat-5.0.3/test/parser_log/sample_*.lua: added log samples | ||
148 | * nat-5.0.3/README: updated | ||
149 | * Manifest: updated for parser log samples | ||
150 | * test_lua/files-yueliang-5.1.txt: updated directory name change | ||
151 | * README: updated | ||
152 | * Version: 0.3.0 | ||
153 | |||
154 | 2008-04-13 Kein-Hong Man <khman@users.sf.net> | ||
155 | |||
156 | * nat-5.0.3/test/test_lparser_mk3.lua: if_stat tests, | ||
157 | return_stat tests, while_stat tests, repeat_stat tests | ||
158 | * nat-5.0.3/lparser_mk3.lua: logging for if_stat, | ||
159 | return_stat, while_stat, repeat_stat, and comment tweaks | ||
160 | * nat-5.0.3/test/test_lparser_mk3.lua: tests for break_stat, | ||
161 | for_stat, local_stat, function_stat, anonymous functions, | ||
162 | table constructors | ||
163 | * nat-5.0.3/lparser_mk3.lua: logging written for break_stat, | ||
164 | for_stat, local_stat, function_stat, anonymous functions, | ||
165 | table constructors | ||
166 | * nat-5.0.3/lparser_mk3.lua (luaY:localfunc): missing struct b | ||
167 | * nat-5.0.3/lparser_mk3.lua: everything seems to work | ||
168 | |||
169 | 2008-04-12 Kein-Hong Man <khman@users.sf.net> | ||
170 | |||
171 | * nat-5.0.3/test/test_lparser_mk3.lua: basic expr tests | ||
172 | * nat-5.0.3/lparser_mk3.lua: logging for expressions mostly | ||
173 | done, fixed bugs in luaY:subexpr caused by simplification of | ||
174 | orig-5.0.3 sources, seems okay now | ||
175 | * nat-5.0.3/README: updated | ||
176 | * Manifest: updated | ||
177 | * README: updated | ||
178 | * Version: 0.2.4 | ||
179 | |||
180 | 2008-04-12 Kein-Hong Man <khman@users.sf.net> | ||
181 | |||
182 | * nat-5.0.3/test/test_lparser_mk3.lua: added log message | ||
183 | dumper function, added test script exerciser | ||
184 | * nat-5.0.3/lparser_mk3.lua (luaY:open_func): tweaked to | ||
185 | allow early logging | ||
186 | * nat-5.0.3/lparser_mk3.lua: added some logging messages | ||
187 | * nat-5.0.3/test/test_lparser_mk3.lua: added output indenter | ||
188 | * nat-5.0.3/lparser_mk3.lua (luaY:syntaxerror): bug, ref | ||
189 | to self.tok when it should be tok | ||
190 | * nat-5.0.3/lparser_mk3.lua: more logging messages, tests | ||
191 | |||
192 | 2008-04-12 Kein-Hong Man <khman@users.sf.net> | ||
193 | |||
194 | * nat-5.0.3/lparser_mk3.lua: removed old attempt at | ||
195 | writing a native parser skeleton | ||
196 | * nat-5.0.3/lparser_mk3.lua: added preliminary new | ||
197 | native 5.0.3 parser skeleton | ||
198 | * nat-5.0.3/test/test_lparser_mk3.lua: renamed from | ||
199 | test_lparser.lua to match mk numbering | ||
200 | * nat-5.0.3/lparser_mk3.lua (luaY:next): missing 'end' | ||
201 | * nat-5.0.3/test/test_lparser_mk3.lua: runs, no die | ||
202 | |||
203 | 2008-04-10 Kein-Hong Man <khman@users.sf.net> | ||
204 | |||
205 | * nat-5.0.3/test/test_lparser.lua: new, preliminary native | ||
206 | parser test code | ||
207 | * nat-5.0.3/lparser_mk3.lua: fixed regex for binary | ||
208 | operator priority string | ||
209 | * nat-5.0.3/lparser_mk3.lua: renamed variable clash | ||
210 | with function peek -> peek_tok, added missing init | ||
211 | * nat-5.0.3/lparser_mk3.lua: function name clash, | ||
212 | one changed to localstat -> localdeclstat | ||
213 | * nat-5.0.3/test/test_lparser.lua: passed simple string | ||
214 | * nat-5.0.3/test/sample.lua: added test file | ||
215 | * nat-5.0.3/test/test_lparser.lua: added longer test, fail | ||
216 | * nat-5.0.3/lparser_mk3.lua (luaY:subexpr): inconsistent | ||
217 | call parameters, might prefer to rewrite whole thing | ||
218 | |||
219 | 2008-04-09 Kein-Hong Man <khman@users.sf.net> | ||
220 | |||
221 | * orig-5.1.2/lcode.lua (luaK:prefix): 5.1.3 fix | ||
222 | * orig-5.1.2/lparser.lua (luaY:assignment): 5.1.3 fix | ||
223 | * orig-5.1.3: renamed from orig-5.1.2, updated names | ||
224 | * orig-5.1.3/README: updated | ||
225 | * COPYRIGHT, COPYRIGHT_Lua51: updated year | ||
226 | * README: updated | ||
227 | * Version: 0.2.3 | ||
228 | |||
229 | 2007-11-21 Kein-Hong Man <khman@users.sf.net> | ||
230 | |||
231 | * orig-5.1.1/lparser.lua (luaY:listfield): 5.1.2 fixes | ||
232 | * orig-5.1.1/lcode.lua (luaK:infix, luaK:codearith, | ||
233 | luaK:_nil): 5.1.2 fixes | ||
234 | * orig-5.1.2: renamed from orig-5.1.1, updated names | ||
235 | * COPYRIGHT, COPYRIGHT_Lua51: updated | ||
236 | * README: updated | ||
237 | * test_lua/files-*, README: directory name adjustment | ||
238 | * test_lua/5.0, 5.1: renamed from 5.0.3, 5.1.1 | ||
239 | * test_lua: renamed files, adjusted directory references | ||
240 | * Version: 0.2.2 | ||
241 | |||
242 | 2006-11-28 Kein-Hong Man <khman@users.sf.net> | ||
243 | |||
244 | * orig-5.0.3/test/test_lparser2.lua: added option to dump | ||
245 | all error messages for failure cases, to check whether test | ||
246 | cases trip the parser where intended | ||
247 | * orig-5.1.1/test/test_lparser2.lua: ditto | ||
248 | |||
249 | 2006-11-27 Kein-Hong Man <khman@users.sf.net> | ||
250 | |||
251 | * test_lua/README: updated | ||
252 | * orig-5.0.3/README: updated | ||
253 | * orig-5.1.1/README: updated | ||
254 | * Manifest: updated | ||
255 | * README: updated | ||
256 | * COPYRIGHT: updated version number | ||
257 | * Version: 0.2.1 | ||
258 | |||
259 | 2006-11-27 Kein-Hong Man <khman@users.sf.net> | ||
260 | |||
261 | * test_lua/test_parser-5.1.lua: parser test case file | ||
262 | for Lua 5.1.x | ||
263 | * orig-5.1.1/test/test_lparser2.lua: added a parser tester | ||
264 | for the 5.1.1 front end, fixed one bug, 524 tests passed | ||
265 | * orig-5.1.1/lparser.lua (luaY:simpleexp): fixed test | ||
266 | on fs.f.is_vararg, numerical not boolean | ||
267 | |||
268 | 2006-11-27 Kein-Hong Man <khman@users.sf.net> | ||
269 | |||
270 | * nat-5.0.3/lparser_mk3.lua: updated expression type | ||
271 | information passing, needed to detect VCALLs | ||
272 | * test_lua/test_parser-5.0.lua: preliminary parser test | ||
273 | case file for Lua 5.0.x | ||
274 | * test_lua/test_parser-5.0.lua: fixed use of [==[! | ||
275 | * test_lua/test_parser-5.0.lua: updated test cases after | ||
276 | verifying with native Lua | ||
277 | * orig-5.0.3/test/test_lparser2.lua: added a parser tester | ||
278 | for the 5.0.3 front end, 503 tests passed | ||
279 | * nat-5.0.3/README: updated with info on lparser_mk3.lua | ||
280 | |||
281 | 2006-11-23 Kein-Hong Man <khman@users.sf.net> | ||
282 | |||
283 | * orig-5.0.3/lparser.lua: fixed comment typo | ||
284 | * orig-5.1.1/lparser.lua: fixed comment typo | ||
285 | * nat-5.0.3/lparser_mk3.lua: preliminary parser skeleton | ||
286 | |||
287 | 2006-11-22 Kein-Hong Man <khman@users.sf.net> | ||
288 | |||
289 | * test_lua/README: updated with test status | ||
290 | * test_lua/files-yueliang-5.0.3.txt: updated filenames | ||
291 | * test_lua/files-yueliang-5.1.1.txt: added for 5.1.1 | ||
292 | * test_lua/files-lua-5.1.1.txt: added for 5.1.1 | ||
293 | * test_lua/files-other-5.1.1.txt: added for 5.1.1 | ||
294 | * test_lua/test_scripts: to accomodate 5.1.1 material, | ||
295 | renamed to test_lua/test_scripts-5.0.3.lua | ||
296 | * test_lua/test_scripts-5.1.1.lua: added, after debugging, | ||
297 | all files compiled successfully | ||
298 | * Manifest: updated | ||
299 | * README: updated | ||
300 | * Version: 0.2.0 | ||
301 | |||
302 | 2006-11-22 Kein-Hong Man <khman@users.sf.net> | ||
303 | |||
304 | * orig-5.1.1/lparser.lua (luaY:parlist): missing 'self', | ||
305 | (luaY:test_then_block): missing 'self', | ||
306 | (luaY:yindex) check should be checknext, | ||
307 | (luaY:adjustlocalvars) nvars should be loop index i | ||
308 | * orig-5.1.1/lcode.lua (luaK:addk): redo fs.h[] code, | ||
309 | (luaK:nilK) forgot to change from old name nil_constant | ||
310 | (luaK:posfix) copyexp() added to copy expdesc structs | ||
311 | (luaK:patchlistaux) incorrectly placed loop iterator | ||
312 | * orig-5.1.1/lparser.lua: | ||
313 | (luaY:breakstat) luaK:concat returns a value! | ||
314 | (luaY:new_localvarliteral) forgot to correct parameter | ||
315 | (luaY:ifstat) luaK:concat returns a value! | ||
316 | (luaY:whilestat) typo, "whileint" | ||
317 | (luaY:simpleexp) missing 'self' for VARARG_NEEDSARG | ||
318 | (luaY:repeatstat) type, "zself" | ||
319 | (luaY:repeatstat) failed to clear away old code | ||
320 | * orig-5.1.1/lcode.lua: (luaK:constfolding): missing 'self' | ||
321 | (luaK:isnumeral) incorrect type of NO_JUMP | ||
322 | (luaK:need_value) missing interator converting for loop | ||
323 | * orig-5.1.1/llex.lua (luaX:next): must be copy-by-value | ||
324 | (luaK:patchtestreg) cannot replace an inst table | ||
325 | * orig-5.1.1/ldump.lua (luaU:DumpConstants): typo for | ||
326 | constant name, LUA_BOOLEAN -> LUA_TBOOLEAN | ||
327 | |||
328 | 2006-11-22 Kein-Hong Man <khman@users.sf.net> | ||
329 | |||
330 | * orig-5.1.1/test/bench_llex.lua: added performance | ||
331 | tester for Lua 5.1.1 lexer | ||
332 | * orig-5.1.1/README: added preliminary performance data | ||
333 | * orig-5.1.1/lparser.lua: debugging, | ||
334 | (luaY:checklimit) missing 'end' | ||
335 | (luaY:repeatstat) extra 'end' | ||
336 | (luaY:parser) added nCcalls initialization for LuaState | ||
337 | (luaY:exprstat) should be luaK:getcode | ||
338 | * orig-5.1.1/llex.lua: debugging, luaX:lex renamed to | ||
339 | luaX:llex to follow Lua 5.1.1 | ||
340 | * orig-5.1.1/test/test_llex.lua: luaX:lex -> luaX:llex | ||
341 | * orig-5.1.1/test/bench_llex.lua: luaX:lex -> luaX:llex | ||
342 | * orig-5.1.1/lcode.lua: debugging, | ||
343 | (luaK:addK) adjusted value storage, removed setnvalue call | ||
344 | (luaK:codeABC) luaP instead of self, 2 cases | ||
345 | * orig-5.1.1/lopcodes.lua: fixed string parameter type for | ||
346 | instruction information lookup functions, | ||
347 | (luaP:ISK) fixed MSB bit testing to denote constants | ||
348 | (luaP:Instruction) fixed instruction encoding into bytes | ||
349 | |||
350 | 2006-11-21 Kein-Hong Man <khman@users.sf.net> | ||
351 | |||
352 | * orig-5.0.3/lcode.lua: noted failed assert, adjusted | ||
353 | names of set*value lobject.h macros | ||
354 | * README: noted two cases needing following up: a failed | ||
355 | assert (see above) and a missing luaG_checkcode() | ||
356 | * orig-5.1.1/lopcodes.lua: added luaP:CREATE_Inst(c) for | ||
357 | luaK:setlist, implementation of OP_SETLIST | ||
358 | * orig-5.1.1/lcode.lua: added preliminary ported file | ||
359 | |||
360 | 2006-11-21 Kein-Hong Man <khman@users.sf.net> | ||
361 | |||
362 | * orig-5.1.1/lparser.lua: added preliminary ported file | ||
363 | * orig-5.1.1/lparser.lua: fixed syntax porting bugs (3): | ||
364 | (luaY:hasmultret): || changed to or in return statement | ||
365 | (luaY:indexupvalue): || changed to or in assert statement | ||
366 | (luaY:singlevaraux): missing return before return value | ||
367 | |||
368 | 2006-11-17 Kein-Hong Man <khman@users.sf.net> | ||
369 | |||
370 | * Manifest: updated | ||
371 | * README: updated | ||
372 | * Version: 0.1.4 | ||
373 | |||
374 | 2006-11-17 Kein-Hong Man <khman@users.sf.net> | ||
375 | |||
376 | * orig-5.1.1/ldump.lua: removed string.len in 2 places | ||
377 | * orig-5.0.3/lopcodes.lua: (luaP:DecodeInst) comments | ||
378 | adjusted, a regexp changed elsewhere | ||
379 | * orig-5.1.1/ldump.lua: fixed porting bug (function name) | ||
380 | * orig-5.1.1/test/test_ldump.lua: tested binary dumper | ||
381 | * orig-5.1.1/test/test_llex.lua: tested lexer, developed | ||
382 | new test cases to cover changes in Lua 5.1.x | ||
383 | * orig-5.1.1/llex.lua: fixed bugs in lexer in order to | ||
384 | run test cases successfully | ||
385 | (luaX:token2str) variable c should be token | ||
386 | (luaX:lexerror) incorrect call to luaX:chunkid | ||
387 | (luaX:read_numeral) scanning bug, %w captures EOZ too | ||
388 | (luaX:read_long_string) LUA_COMPAT_LSTR is in self | ||
389 | (luaX:lex) incorrect variable used in keyword lookup | ||
390 | * orig-5.0.3/lopcodes.lua: changed a gfind to gmatch | ||
391 | * test_llex*.lua: some tweaks to printout statement | ||
392 | |||
393 | 2006-11-17 Kein-Hong Man <khman@users.sf.net> | ||
394 | |||
395 | * orig-5.1.1/ldump.lua: added binary chunk dumper | ||
396 | * orig-5.1.1/README: added preliminary information | ||
397 | * orig-5.1.1/test/test_lzio.lua: tested chunk reader | ||
398 | * orig-5.1.1/test/test_number.lua: tested number conversion | ||
399 | * test_number.lua: added FLT_MIN, FLT_MAX test values for | ||
400 | completeness, in case conversion to float is needed | ||
401 | |||
402 | 2006-11-16 Kein-Hong Man <khman@users.sf.net> | ||
403 | |||
404 | * test_lua/5.0.2: directory renamed to test_lua/5.0.3 | ||
405 | * test_lua: front end test script and associated files | ||
406 | updated for 5.0.3 | ||
407 | * orig-5.0.2: directory renamed to orig-5.0.3, some | ||
408 | references to 5.0.2 changed | ||
409 | * nat-5.0.2: directory renamed to nat-5.0.3, some | ||
410 | references to 5.0.2 changed | ||
411 | * orig-5.1: directory renamed to orig-5.1.1, some | ||
412 | references to 5.1 changed | ||
413 | |||
414 | 2006-11-16 Kein-Hong Man <khman@users.sf.net> | ||
415 | |||
416 | * orig-5.0.2/lcode.lua: updating to Lua 5.0.3, this is the | ||
417 | only front end file in orig-5.0.2 that has changed; | ||
418 | (luaK:need_value): body changed | ||
419 | (luaK:removevalues): new function, used in luaK:codenot | ||
420 | (luaK:patchlistaux): definition and body changed | ||
421 | (luaK:dischargejpc): body changed (due to luaK:patchlistaux) | ||
422 | (luaK:patchlist): body changed (due to luaK:patchlistaux) | ||
423 | (luaK:exp2reg): body changed (due to luaK:patchlistaux) | ||
424 | (luaK:jumponcond): body changed | ||
425 | (luaK:codenot): body changed (added luaK:removevalues) | ||
426 | |||
427 | 2006-11-16 Kein-Hong Man <khman@users.sf.net> | ||
428 | |||
429 | * test_lua: moved 5.0.2 sample scripts to its own directory | ||
430 | * test_lua/test_scripts.lua: adjusted file paths of sample | ||
431 | files used for parser testing | ||
432 | * test_lua/test_scripts.lua: changed file list specification | ||
433 | to load several separate files for better flexibility and | ||
434 | easier maintenance | ||
435 | * test_lua/files-lua-5.0.2.txt: added sample file list | ||
436 | * test_lua/files-other-5.0.2.txt: added sample file list | ||
437 | * test_lua/files-yueliang-5.0.2.txt: added sample file list | ||
438 | * test_lua/README: updated | ||
439 | * Manifest: updated | ||
440 | |||
441 | 2006-11-13 Kein-Hong Man <khman@users.sf.net> | ||
442 | |||
443 | * orig-5.0.2/lcode.lua: added function comments | ||
444 | |||
445 | 2006-11-13 Kein-Hong Man <khman@users.sf.net> | ||
446 | |||
447 | * orig-5.0.2/test/bench_llex.lua: simple lexer benchmark | ||
448 | * nat-5.0.2/test/bench_llex_mk2.lua: adapted for mk2 lexer | ||
449 | * nat-5.0.2/test/bench_llex_mk3.lua: adapted for mk3 lexer | ||
450 | * nat-5.0.2/test/bench_llex_mk4.lua: adapted for mk4 lexer | ||
451 | * nat-5.0.2/README: added lexer benchmark results | ||
452 | |||
453 | 2006-11-11 Kein-Hong Man <khman@users.sf.net> | ||
454 | |||
455 | * Manifest: updated | ||
456 | * README: updated | ||
457 | * Version: 0.1.3 | ||
458 | |||
459 | 2006-11-11 Kein-Hong Man <khman@users.sf.net> | ||
460 | |||
461 | * nat-5.0.2/llex_mk3.lua: further size optimization work on | ||
462 | new lexer, down to 3286 bytes (stripped) | ||
463 | * nat-5.0.2/llex_mk3.lua: fixed bug in short comment handling | ||
464 | * nat-5.0.2/README: added information for native lexers | ||
465 | * nat-5.0.2/llex_mk4.lua: line-based native lexer, see size | ||
466 | performance data in README | ||
467 | * nat-5.0.2/lzio_mk4.lua: line-based stream reader function | ||
468 | * nat-5.0.2/test/test_llex_mk4.lua: adapted version of test | ||
469 | cases, all tests passed | ||
470 | |||
471 | 2006-11-10 Kein-Hong Man <khman@users.sf.net> | ||
472 | |||
473 | * orig-5.0.2/lparser.lua: added comments for parser | ||
474 | functions, one or more visual tweaks, no code changes | ||
475 | |||
476 | 2006-11-09 Kein-Hong Man <khman@users.sf.net> | ||
477 | |||
478 | * nat-5.0.2/llex_mk3.lua: new minimal size lexer, but takes | ||
479 | in all the source code at once, 3346 bytes (stripped) | ||
480 | * nat-5.0.2/test/test_llex_mk3.lua: adapted version of test | ||
481 | cases, all tests passed | ||
482 | |||
483 | 2006-11-08 Kein-Hong Man <khman@users.sf.net> | ||
484 | |||
485 | * nat-5.0.2/lzio_mk2.lua: renamed from lzio.lua | ||
486 | * nat-5.0.2/test/test_lzio_mk2.lua: renamed from test_lzio.lua | ||
487 | * nat-5.0.2/llex_mk2.lua: renamed from llex.lua | ||
488 | * nat-5.0.2/test/test_llex_mk2.lua: renamed from test_llex.lua | ||
489 | |||
490 | 2006-03-27 Kein-Hong Man <khman@users.sf.net> | ||
491 | |||
492 | * nat-5.0.2/llex.lua: optimizations to reduce file size, | ||
493 | size down to 4003 bytes (stripped) from 4155 bytes | ||
494 | |||
495 | 2006-03-27 Kein-Hong Man <khman@users.sf.net> | ||
496 | |||
497 | * orig-5.1: lzio.lua: minor formatting change | ||
498 | * orig-5.0.2/test/test_llex.lua: fix filename spec | ||
499 | * nat-5.0.2/lzio.lua: new simplified 'native' version | ||
500 | * nat-5.0.2/test/test_lzio.lua: test for the above | ||
501 | * nat-5.0.2/llex.lua: new simplified 'native' version | ||
502 | * nat-5.0.2/test/test_llex.lua: test for the above | ||
503 | |||
504 | 2006-03-25 Kein-Hong Man <khman@users.sf.net> | ||
505 | |||
506 | * orig-5.0.2/llex.lua: typo fix | ||
507 | * orig-5.1/llex.lua: Lua 5.1 lexer | ||
508 | * Manifest: updated | ||
509 | |||
510 | 2006-03-23 Kein-Hong Man <khman@users.sf.net> | ||
511 | |||
512 | * orig-5.0.2/tools/call_graph.lua: added display of contents | ||
513 | of expdesc structures | ||
514 | |||
515 | 2006-03-23 Kein-Hong Man <khman@users.sf.net> | ||
516 | |||
517 | * orig-5.1: new directory for 5.1 front-end | ||
518 | * orig-5.1/lzio.lua: Lua 5.1 input stream reader | ||
519 | * COPYRIGHT: updated with Lua 5.1 information | ||
520 | * COPYRIGHT_Lua51: added for Lua 5.1 | ||
521 | * Manifest: updated | ||
522 | * orig-5.0.2/lzio.lua: updated comments | ||
523 | * orig-5.1/lzio.lua (luaZ:fill): fixed porting bug | ||
524 | |||
525 | 2005-05-04 Kein-Hong Man <khman@users.sf.net> | ||
526 | |||
527 | * orig-5.0.2/tools/sample_expr.lua: a Lua-style expression | ||
528 | parsing interactive demonstrator | ||
529 | * orig-5.0.2/tools/sample_expr.lua: fixed parsing bugs, | ||
530 | (1) unop subexpr, (2) assign to op before testing for binop | ||
531 | * orig-5.0.2/lparser.lua: fixed some comments which have | ||
532 | incorrect description of Lua syntax | ||
533 | |||
534 | 2005-04-18 Kein-Hong Man <khman@users.sf.net> | ||
535 | |||
536 | * Version: 0.1.2 | ||
537 | |||
538 | 2005-04-17 Kein-Hong Man <khman@users.sf.net> | ||
539 | |||
540 | * orig-5.0.2/lparser.lua: added descriptive comments for some | ||
541 | expression parsing functions | ||
542 | * orig-5.0.2/test/test_number.lua: test cases for number | ||
543 | conversion functions in ldump.lua | ||
544 | * test_lua/test_scripts.lua: updated with some new test entries | ||
545 | * orig-5.0.2/ldump.lua (luaU:from_double): added support for | ||
546 | +/- infinity | ||
547 | |||
548 | 2005-04-14 Kein-Hong Man <khman@users.sf.net> | ||
549 | |||
550 | * moved project to a Subversion repository | ||
551 | |||
552 | 2005-03-24 Kein-Hong Man <khman@users.sf.net> | ||
553 | |||
554 | * orig-5.0.2/lopcodes.lua: added luaP:DecodeInst to decode | ||
555 | instruction from a 4-char string | ||
556 | * orig-5.0.2/lopcodes.lua (getOpMode, testOpMode): add 'self.' | ||
557 | |||
558 | 2005-03-22 Kein-Hong Man <khman@users.sf.net> | ||
559 | |||
560 | * orig-5.0.2/tools/call_graph.lua: added comments, check for | ||
561 | namespace collision when selecting new name for orig function | ||
562 | * test_lua/test_scripts.lua: added comments, some test files | ||
563 | |||
564 | 2005-03-21 Kein-Hong Man <khman@users.sf.net> | ||
565 | |||
566 | * orig-5.0.2/tools/call_graph.lua: added allow/deny of specific | ||
567 | functions, display of return values | ||
568 | * orig-5.0.2/tools/calls.log: sample output | ||
569 | * Version: 0.1.1 | ||
570 | |||
571 | 2005-03-20 Kein-Hong Man <khman@users.sf.net> | ||
572 | |||
573 | * orig-5.0.2/tools/call_graph.lua: added script to generate | ||
574 | a call graph from selected modules | ||
575 | |||
576 | 2005-03-19 Kein-Hong Man <khman@users.sf.net> | ||
577 | |||
578 | * README: added some size statistics for comparison | ||
579 | * test_lua/README: updated description | ||
580 | * orig-5.0.2/README: added notes | ||
581 | * orig-5.0.2/lzio.lua: fixed bug when calling zgetc after | ||
582 | EOF for a file chunk reader (Thanks to Adam429) | ||
583 | * orig-5.0.2/test/test_lzio.lua: added manual test for above | ||
584 | |||
585 | 2005-03-17 Kein-Hong Man <khman@users.sf.net> | ||
586 | |||
587 | * orig-5.0.2/lparser.lua (indexupvalue): struct expdesc copy | ||
588 | * orig-5.0.2/luac.lua: simple luac; can compile luac.lua | ||
589 | * orig-5.0.2/lparser.lua (assignment, constructor): missing | ||
590 | 'self:' | ||
591 | * test_lua: added sample Lua scripts from Lua 5.0.2 | ||
592 | * test_lua/README: add source attribution for example scripts | ||
593 | * orig-5.0.2/lcode.lua (arith_opc): typo OP_MULT -> OP_MUL | ||
594 | * orig-5.0.2/ldump.lua (DumpString): fixed handling for "" | ||
595 | * orig-5.0.2/ldump.lua (DumpFunction): fixed f.source handling | ||
596 | * orig-5.0.2/lcode.lua (jump, codebinop): 'luaK:' -> 'self:' | ||
597 | * orig-5.0.2/lcode.lua (need_value, exp2reg): comparison of | ||
598 | boolean cond with 0/1 C field, changed back to all 0/1 | ||
599 | * orig-5.0.2/lzio.lua (init): test for nil reader argument | ||
600 | * test_lua/test_scripts.lua: Lua 5.0.2 examples all compiles | ||
601 | correctly, as does Yueliang files | ||
602 | * orig-5.0.2/lzio.lua (make_getF): changed file mode to "r" | ||
603 | so that chunk reader behaves like luac for \r\n-style files | ||
604 | * test_lua/test_scripts.lua: added Lua code from LuaSrcDiet, | ||
605 | SciTELuaExporters, ChunkBake, ChunkSpy, all works | ||
606 | * README: preliminary documentation | ||
607 | * some pre-release cosmetic changes | ||
608 | * initial public release | ||
609 | * Version: 0.1.0 | ||
610 | |||
611 | 2005-03-16 Kein-Hong Man <khman@users.sf.net> | ||
612 | |||
613 | * orig-5.0.2/test/test_lparser.lua: basic parser/codegen test | ||
614 | * orig-5.0.2/lparser.lua: added FuncState.actvar = {} init | ||
615 | * orig-5.0.2/lcode.lua (ttisnumber): handle nil entries | ||
616 | * orig-5.0.2/lopcodes.lua (getOpMode): string opcode parm | ||
617 | * orig-5.0.2/lcode.lua (exp2reg): missing 'self:' prefixes | ||
618 | * orig-5.0.2/lopcodes.lua (CREATE_ABC, CREATE_ABx): convert | ||
619 | string opcode representation to number when storing in field OP | ||
620 | * orig-5.0.2/lcode.lua (setsvalue, setnvalue, sethvalue): | ||
621 | missing second argument cause addk to fail | ||
622 | * orig-5.0.2/lparser.lua (check_match): missing 'self:' | ||
623 | * orig-5.0.2/test/test_lparser.lua: two simple tests successful | ||
624 | * orig-5.0.2/lcode.lua (exp2val, exp2anyreg, invertjump): | ||
625 | missing 'self:' | ||
626 | * orig-5.0.2/lparser.lua (parlist, subexpr): missing 'self:' | ||
627 | * orig-5.0.2/lopcodes.lua (testOpMode): string opcode parm | ||
628 | * orig-5.0.2/lparser.lua (subexpr): convert string operator name | ||
629 | to BinOpr number when looking up binop operator priority | ||
630 | * orig-5.0.2/lparser.lua (adjustlocalvars): wrong loop index | ||
631 | * orig-5.0.2/lcode.lua (addk): fixed constant lookup | ||
632 | |||
633 | 2005-03-15 Kein-Hong Man <khman@users.sf.net> | ||
634 | |||
635 | * orig-5.0.2/lcode.lua: completed porting (untested) | ||
636 | * orig-5.0.2/ldump.lua: completed porting (untested) | ||
637 | * orig-5.0.2/test/test_ldump.lua: added chunk writer tests | ||
638 | * orig-5.0.2/test/test_ldump.lua: basic test writing binary | ||
639 | chunk from a simple function prototype table successful | ||
640 | |||
641 | 2005-03-14 Kein-Hong Man <khman@users.sf.net> | ||
642 | |||
643 | * orig-5.0.2/lparser.lua: updated representation of constants | ||
644 | * orig-5.0.2/lopcodes.lua: completed porting (untested) | ||
645 | * orig-5.0.2/test_lzio.lua: moved to orig-5.0.2/test subdir | ||
646 | * orig-5.0.2/test_llex.lua: moved to orig-5.0.2/test subdir | ||
647 | |||
648 | 2005-03-13 Kein-Hong Man <khman@users.sf.net> | ||
649 | |||
650 | * orig-5.0.2/lparser.lua: completed porting (untested), | ||
651 | can't be tested without lcode/ldump | ||
652 | |||
653 | 2005-03-11 Kein-Hong Man <khman@users.sf.net> | ||
654 | |||
655 | * orig-5.0.2/test_llex.lua: added manual test for llex.lua | ||
656 | * orig-5.0.2/llex.lua: code review; put Token parameter to | ||
657 | replace seminfo pointer in luaX:lex and related functions | ||
658 | * orig-5.0.2/llex.lua (chunkid): fixed buffer handling bug | ||
659 | * orig-5.0.2/llex.lua (read_string): escaped \n index bug | ||
660 | * orig-5.0.2/test_llex.lua: adjusted calling code to properly | ||
661 | use Token struct t in LS same as in original lparser.c calls | ||
662 | * orig-5.0.2/llex.lua (token2str): put back an assert as comment | ||
663 | * orig-5.0.2/llex.lua (readname): bug reading name up to EOZ | ||
664 | * orig-5.0.2/llex.lua (read_string): forgot c = self:next(LS) | ||
665 | * orig-5.0.2/llex.lua (readname): %w (alnum) instead of %a | ||
666 | * orig-5.0.2/llex.lua (lex): string.byte(c) for ctrl char msg | ||
667 | * orig-5.0.2/test_llex.lua: added automatic testing, all test | ||
668 | cases work after bug fixes (see above entries) to llex.lua | ||
669 | * orig-5.0.2/llex.lua: complete | ||
670 | |||
671 | 2005-03-10 Kein-Hong Man <khman@users.sf.net> | ||
672 | |||
673 | * orig-5.0.2/llex.lua: completed porting | ||
674 | |||
675 | 2005-03-09 Kein-Hong Man <khman@users.sf.net> | ||
676 | |||
677 | * started work on porting files (llex|lparser|lcode).(h|c) | ||
678 | * orig-5.0.2/lzio.lua: done parts needed for llex.lua, manually | ||
679 | tested with both string and file chunk readers | ||
680 | * 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 @@ | |||
1 | Changelog | ||
2 | Manifest | ||
3 | README | ||
4 | OlderNews | ||
5 | COPYRIGHT | ||
6 | COPYRIGHT_Lua5 | ||
7 | COPYRIGHT_Lua51 | ||
8 | orig-5.0.3/README | ||
9 | orig-5.0.3/lzio.lua | ||
10 | orig-5.0.3/ldump.lua | ||
11 | orig-5.0.3/lopcodes.lua | ||
12 | orig-5.0.3/llex.lua | ||
13 | orig-5.0.3/lparser.lua | ||
14 | orig-5.0.3/lcode.lua | ||
15 | orig-5.0.3/luac.lua | ||
16 | orig-5.0.3/test/test_number.lua | ||
17 | orig-5.0.3/test/test_lzio.lua | ||
18 | orig-5.0.3/test/test_ldump.lua | ||
19 | orig-5.0.3/test/test_llex.lua | ||
20 | orig-5.0.3/test/test_lparser.lua | ||
21 | orig-5.0.3/test/test_lparser2.lua | ||
22 | orig-5.0.3/test/sample.lua | ||
23 | orig-5.0.3/test/bench_llex.lua | ||
24 | orig-5.0.3/tools/call_graph.lua | ||
25 | orig-5.0.3/tools/calls.log | ||
26 | orig-5.0.3/tools/sample_expr.lua | ||
27 | orig-5.1.3/README | ||
28 | orig-5.1.3/lzio.lua | ||
29 | orig-5.1.3/ldump.lua | ||
30 | orig-5.1.3/lopcodes.lua | ||
31 | orig-5.1.3/llex.lua | ||
32 | orig-5.1.3/lparser.lua | ||
33 | orig-5.1.3/lcode.lua | ||
34 | orig-5.1.3/luac.lua | ||
35 | orig-5.1.3/test/test_number.lua | ||
36 | orig-5.1.3/test/test_lzio.lua | ||
37 | orig-5.1.3/test/test_ldump.lua | ||
38 | orig-5.1.3/test/test_llex.lua | ||
39 | orig-5.1.3/test/bench_llex.lua | ||
40 | orig-5.1.3/test/test_lparser.lua | ||
41 | orig-5.1.3/test/test_lparser2.lua | ||
42 | orig-5.1.3/test/sample.lua | ||
43 | nat-5.0.3/README | ||
44 | nat-5.0.3/lzio_mk2.lua | ||
45 | nat-5.0.3/lzio_mk4.lua | ||
46 | nat-5.0.3/llex_mk2.lua | ||
47 | nat-5.0.3/llex_mk3.lua | ||
48 | nat-5.0.3/llex_mk4.lua | ||
49 | nat-5.0.3/lparser_mk3.lua | ||
50 | nat-5.0.3/lparser_mk3b.lua | ||
51 | nat-5.0.3/test/test_lzio_mk2.lua | ||
52 | nat-5.0.3/test/test_llex_mk2.lua | ||
53 | nat-5.0.3/test/test_llex_mk3.lua | ||
54 | nat-5.0.3/test/test_llex_mk4.lua | ||
55 | nat-5.0.3/test/bench_llex_mk2.lua | ||
56 | nat-5.0.3/test/bench_llex_mk3.lua | ||
57 | nat-5.0.3/test/bench_llex_mk4.lua | ||
58 | nat-5.0.3/test/test_lparser_mk3.lua | ||
59 | nat-5.0.3/test/test_lparser_mk3_2.lua | ||
60 | nat-5.0.3/test/test_lparser_mk3b.lua | ||
61 | nat-5.0.3/test/test_lparser_mk3b_2.lua | ||
62 | nat-5.0.3/test/sample.lua | ||
63 | nat-5.0.3/test/parser_log/sample_01.lua | ||
64 | nat-5.0.3/test/parser_log/sample_02.lua | ||
65 | nat-5.0.3/test/parser_log/sample_03.lua | ||
66 | nat-5.0.3/test/parser_log/sample_04.lua | ||
67 | nat-5.0.3/test/parser_log/sample_05.lua | ||
68 | nat-5.0.3/test/parser_log/sample_06.lua | ||
69 | nat-5.0.3/test/parser_log/sample_07.lua | ||
70 | nat-5.0.3/test/parser_log/sample_08.lua | ||
71 | nat-5.0.3/test/parser_log/sample_09.lua | ||
72 | nat-5.0.3/test/parser_log/sample_10.lua | ||
73 | nat-5.0.3/test/parser_log/sample_11.lua | ||
74 | nat-5.0.3/test/parser_log/sample_12.lua | ||
75 | nat-5.0.3/test/parser_log/sample_13.lua | ||
76 | nat-5.0.3/test/parser_log/sample_14.lua | ||
77 | nat-5.0.3/test/parser_log/sample_15.lua | ||
78 | nat-5.0.3/test/parser_log/sample_16.lua | ||
79 | nat-5.0.3/test/parser_log/sample_17.lua | ||
80 | nat-5.0.3/test/parser_log/sample_b_01.lua | ||
81 | nat-5.0.3/test/parser_log/sample_b_02.lua | ||
82 | nat-5.0.3/test/parser_log/sample_b_03.lua | ||
83 | nat-5.0.3/test/parser_log/sample_b_04.lua | ||
84 | nat-5.0.3/test/parser_log/sample_b_05.lua | ||
85 | nat-5.0.3/test/parser_log/sample_b_06.lua | ||
86 | nat-5.0.3/test/parser_log/sample_b_07.lua | ||
87 | nat-5.0.3/test/parser_log/sample_b_08.lua | ||
88 | nat-5.0.3/test/parser_log/sample_b_09.lua | ||
89 | nat-5.0.3/test/parser_log/sample_b_10.lua | ||
90 | nat-5.0.3/test/parser_log/sample_b_11.lua | ||
91 | nat-5.0.3/test/parser_log/sample_b_12.lua | ||
92 | nat-5.0.3/test/parser_log/sample_b_13.lua | ||
93 | nat-5.0.3/test/parser_log/sample_b_14.lua | ||
94 | nat-5.1.3/README | ||
95 | nat-5.1.3/llex_mk2.lua | ||
96 | nat-5.1.3/lparser_mk2.lua | ||
97 | nat-5.1.3/test/test_llex_mk2.lua | ||
98 | nat-5.1.3/test/test_lparser_mk2.lua | ||
99 | nat-5.1.3/test/test_lparser_mk2_2.lua | ||
100 | nat-5.1.3/test/parser_log/sample_01.lua | ||
101 | nat-5.1.3/test/parser_log/sample_02.lua | ||
102 | nat-5.1.3/test/parser_log/sample_03.lua | ||
103 | nat-5.1.3/test/parser_log/sample_04.lua | ||
104 | nat-5.1.3/test/parser_log/sample_05.lua | ||
105 | nat-5.1.3/test/parser_log/sample_06.lua | ||
106 | nat-5.1.3/test/parser_log/sample_07.lua | ||
107 | nat-5.1.3/test/parser_log/sample_08.lua | ||
108 | nat-5.1.3/test/parser_log/sample_09.lua | ||
109 | nat-5.1.3/test/parser_log/sample_10.lua | ||
110 | nat-5.1.3/test/parser_log/sample_11.lua | ||
111 | nat-5.1.3/test/parser_log/sample_12.lua | ||
112 | nat-5.1.3/test/parser_log/sample_13.lua | ||
113 | nat-5.1.3/test/parser_log/sample_14.lua | ||
114 | nat-5.1.3/test/parser_log/sample_15.lua | ||
115 | nat-5.1.3/test/parser_log/sample_16.lua | ||
116 | nat-5.1.3/test/parser_log/sample_17.lua | ||
117 | nat-5.1.3/test/parser_log/sample_18.lua | ||
118 | nat-5.1.3/test/parser_log/sample_19.lua | ||
119 | nat-5.1.3/test/parser_log/sample_20.lua | ||
120 | nat-5.1.3/test/parser_log/sample_21.lua | ||
121 | nat-5.1.3/test/parser_log/sample_22.lua | ||
122 | nat-5.1.3/test/parser_log/sample_23.lua | ||
123 | nat-5.1.3/test/parser_log/sample_24.lua | ||
124 | nat-5.1.3/test/parser_log/sample_25.lua | ||
125 | nat-5.1.3/test/parser_log/sample_26.lua | ||
126 | nat-5.1.3/test/parser_log/sample_27.lua | ||
127 | nat-5.1.3/test/parser_log/sample_28.lua | ||
128 | nat-5.1.3/test/parser_log/sample_29.lua | ||
129 | nat-5.1.3/test/parser_log/sample_30.lua | ||
130 | nat-5.1.3/test/parser_log/sample_31.lua | ||
131 | test_lua/README | ||
132 | test_lua/test_scripts-5.0.lua | ||
133 | test_lua/test_scripts-5.1.lua | ||
134 | test_lua/test_parser-5.0.lua | ||
135 | test_lua/test_parser-5.1.lua | ||
136 | test_lua/files-lua-5.0.txt | ||
137 | test_lua/files-other-5.0.txt | ||
138 | test_lua/files-yueliang-5.0.txt | ||
139 | test_lua/files-lua-5.1.txt | ||
140 | test_lua/files-other-5.1.txt | ||
141 | test_lua/files-yueliang-5.1.txt | ||
142 | test_lua/5.0/bisect.lua | ||
143 | test_lua/5.0/cf.lua | ||
144 | test_lua/5.0/echo.lua | ||
145 | test_lua/5.0/env.lua | ||
146 | test_lua/5.0/factorial.lua | ||
147 | test_lua/5.0/fib.lua | ||
148 | test_lua/5.0/fibfor.lua | ||
149 | test_lua/5.0/globals.lua | ||
150 | test_lua/5.0/hello.lua | ||
151 | test_lua/5.0/life.lua | ||
152 | test_lua/5.0/luac.lua | ||
153 | test_lua/5.0/printf.lua | ||
154 | test_lua/5.0/readonly.lua | ||
155 | test_lua/5.0/sieve.lua | ||
156 | test_lua/5.0/sort.lua | ||
157 | test_lua/5.0/table.lua | ||
158 | test_lua/5.0/trace-calls.lua | ||
159 | test_lua/5.0/trace-globals.lua | ||
160 | test_lua/5.0/undefined.lua | ||
161 | test_lua/5.0/xd.lua | ||
162 | test_lua/5.1/fib.lua | ||
163 | test_lua/5.1/printf.lua | ||
164 | test_lua/5.1/hello.lua | ||
165 | test_lua/5.1/factorial.lua | ||
166 | test_lua/5.1/fibfor.lua | ||
167 | test_lua/5.1/bisect.lua | ||
168 | test_lua/5.1/sieve.lua | ||
169 | test_lua/5.1/xd.lua | ||
170 | test_lua/5.1/readonly.lua | ||
171 | test_lua/5.1/echo.lua | ||
172 | test_lua/5.1/life.lua | ||
173 | test_lua/5.1/trace-globals.lua | ||
174 | test_lua/5.1/globals.lua | ||
175 | test_lua/5.1/luac.lua | ||
176 | test_lua/5.1/sort.lua | ||
177 | test_lua/5.1/table.lua | ||
178 | test_lua/5.1/env.lua | ||
179 | test_lua/5.1/cf.lua | ||
180 | 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 @@ | |||
1 | OLDER NEWS | ||
2 | |||
3 | Major changes for version 0.2.4 (details in the ChangeLog): | ||
4 | * Completely reworked native parser skeleton for 5.0.3 | ||
5 | (Partially working, test snippets and logging messages being written | ||
6 | in order to verify it. This is a test run limited to a parser | ||
7 | skeleton before doing a full native implementation for 5.1.x) | ||
8 | |||
9 | Major changes for version 0.2.3 (details in the ChangeLog): | ||
10 | * Updated front end to 5.1.3 | ||
11 | |||
12 | Major changes for version 0.2.2 (details in the ChangeLog): | ||
13 | * Updated front end to 5.1.2 | ||
14 | |||
15 | Major changes for version 0.2.1 (details in the ChangeLog): | ||
16 | * Added a parser test suite for both 5.0.3 and 5.1.1 front ends | ||
17 | * One bug fixed for the 5.1.1 front end | ||
18 | |||
19 | Major changes for version 0.2.0 (details in the ChangeLog): | ||
20 | * Yueliang can generate Lua 5.1.1 binary chunks now | ||
21 | |||
22 | Major changes for version 0.1.4 (details in the ChangeLog): | ||
23 | * updated 5.0.2 material to 5.0.3, front end test script | ||
24 | * updated 5.1 material to 5.1.1, added ldump.lua, lopcodes.lua, | ||
25 | and some test scripts, lexer debugged | ||
26 | |||
27 | Major changes for version 0.1.3 (details in the ChangeLog): | ||
28 | * added a Lua-style expression parsing demonstrator | ||
29 | * added lexer for Lua 5.1 | ||
30 | * native versions of Lua 5.0.2 lexer in the nat-5.0.2 directory | ||
31 | * 0.1.3 will be the last version of Yueliang for Lua 5.0.2 | ||
32 | |||
33 | Major changes for version 0.1.2 (details in the ChangeLog): | ||
34 | * added test cases for number conversion functions in ldump.lua | ||
35 | (recognizes +/- infinity now) | ||
36 | |||
37 | Major changes for version 0.1.1 (details in the ChangeLog): | ||
38 | * added a script to generate a call graph or hierarchy | ||
39 | |||
40 | Major changes for version 0.1.0 (details in the ChangeLog): | ||
41 | * initial release: lexer/parser/code generator works, and binary | ||
42 | chunks can be produced | ||
43 | |||
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 @@ | |||
1 | |||
2 | Yueliang | ||
3 | Lua implemented in Lua | ||
4 | |||
5 | Copyright (c) 2005-2008 Kein-Hong Man <khman@users.sf.net> | ||
6 | The COPYRIGHT file describes the conditions under which this | ||
7 | software may be distributed (basically a Lua 5-style license.) | ||
8 | |||
9 | Website: http://yueliang.luaforge.net/ | ||
10 | Project page: http://luaforge.net/projects/yueliang/ | ||
11 | |||
12 | -- | ||
13 | |||
14 | INTRODUCTION | ||
15 | |||
16 | The goal of Yueliang is to implement Lua 5 in Lua 5. Such a codebase, if | ||
17 | well documented, can be a useful prototyping and educational tool. | ||
18 | Initially, the focus is on the front side of Lua, i.e. the lexical | ||
19 | analyzer, the parser and the code generator, in order to generate binary | ||
20 | chunks. Yueliang currently produces the exact binary chunk as the | ||
21 | original Lua 5 itself for Lua 5.0.3 and Lua 5.1.3. Yueliang is moon in | ||
22 | Mandarin. | ||
23 | |||
24 | A port of the back side (the VM) is being considered, but note that | ||
25 | there is a recent project on LuaForge called LuLu that does just this. | ||
26 | |||
27 | Note: the codebase is currently a no-brainer port of Lua's front side C | ||
28 | source code to Lua code, and the C heritage is retained as much as | ||
29 | possible to allow for easy comparison. Due to certain implementation | ||
30 | methods, processing might be slow (especially if the source file causes | ||
31 | a lot of string processing.) The initial version is not meant to be | ||
32 | fast. Even unused arguments are retained. Asserts are currently enabled. | ||
33 | While the Lua code itself is portable, portions of the code is | ||
34 | hard-coded to generate output for an x86-type platform (32-bit ints, | ||
35 | doubles, little-endian.) | ||
36 | |||
37 | See the test_lua directory for an automatic tester, test_scripts*.lua. | ||
38 | Only the lexer currently has a basic test suite. Performance for the | ||
39 | no-brainer port of the Lua 5.0.2 front end in Yueliang 0.1.0 is 28 | ||
40 | seconds on an Athlon 2500+, or about 29.5KB/sec. (Native C is virtually | ||
41 | instantaneous, so a comparison is pointless, really.) I think a test | ||
42 | suite for the parser will be better than running it on random files. See | ||
43 | below for a list of todos. | ||
44 | |||
45 | For versions of Yueliang corresponding to older minor releases of Lua, | ||
46 | for example Lua 5.0.2 or Lua 5.1.1, please look at the README files in | ||
47 | each of the orig-5.* directory for information on the last version of | ||
48 | Yueliang corresponding to the particular Lua release. | ||
49 | |||
50 | -- | ||
51 | |||
52 | NOTES | ||
53 | |||
54 | * there is a failed assert in luaK:addk for both versions of lcode.lua, | ||
55 | the assert is currently incorrectly written | ||
56 | * luaG_checkcode() in both versions of lparser.lua has currently not | ||
57 | been implemented (better put in the runtime backend?) | ||
58 | * need to check compliance of lexers with recognizing characters beyond | ||
59 | normal ASCII (accented characters) when used in identifiers | ||
60 | |||
61 | -- | ||
62 | |||
63 | WHAT'S NEW | ||
64 | |||
65 | Major changes for version 0.4.1 (details in the ChangeLog): | ||
66 | * Tested native 5.0.x and 5.1.x parsers with lots of test cases | ||
67 | * Fixed two bugs in native 5.1.x parser, # and % operator handling | ||
68 | |||
69 | Major changes for version 0.4.0 (details in the ChangeLog): | ||
70 | * A working native parser skeleton for Lua 5.1.x, plus code | ||
71 | to deal with variable classification | ||
72 | * Sample parser log files covering all of the grammar | ||
73 | |||
74 | Major changes for version 0.3.2 (details in the ChangeLog): | ||
75 | * A working native lexer for Lua 5.1.x | ||
76 | |||
77 | Major changes for version 0.3.1 (details in the ChangeLog): | ||
78 | * Mark 2 of the native parser skeleton for 5.0.3 which does | ||
79 | variable classification into locals, upvalues or globals | ||
80 | * Sample parser log files exercising variable classification | ||
81 | |||
82 | Major changes for version 0.3.0 (details in the ChangeLog): | ||
83 | * Native parser skeleton for 5.0.3 mostly works | ||
84 | * Sample parser log files covering all of the grammar | ||
85 | |||
86 | Older items can be found in OlderNews | ||
87 | |||
88 | -- | ||
89 | |||
90 | SOME SIZE STATS | ||
91 | |||
92 | Here are some 0.1.0 size statistics (note that embedding the sources is | ||
93 | redundant or pretty useless, as you will need an already present front | ||
94 | end to process the source code!) for the 6 files main in orig-5.0.3 | ||
95 | minus luac.lua: | ||
96 | |||
97 | Size Zipped | ||
98 | Original sources* 130162 29546 | ||
99 | with LuaSrcDiet* 48308 13841 | ||
100 | luac 108174 32238 | ||
101 | luac -s 64930 21867 | ||
102 | |||
103 | *note: embedding these would be a little pointless | ||
104 | |||
105 | There are some more size stats in the README file in the nat-5.0.3 | ||
106 | directory, for native lexers. | ||
107 | |||
108 | -- | ||
109 | |||
110 | IMPLEMENTATION PLAN | ||
111 | |||
112 | Here are some ideas, in no particular order or priority, with no | ||
113 | particular implementation time frame: | ||
114 | |||
115 | (a) A straight no-brainer port of Lua's front side C source code to | ||
116 | Lua code, no optimization or heavy rewriting is done (MOSTLY DONE) | ||
117 | (b) A test suite for the lexer (MOSTLY DONE) | ||
118 | (c) A test suite for the: | ||
119 | (i) parser (MOSTLY DONE) | ||
120 | (ii) code generator (CAN ADAPT LUA'S TEST SUITE) | ||
121 | (d) Documentation for Lua code generation (STUDYING) | ||
122 | (e) A straight no-brainer port of Lua's back side C source code to | ||
123 | Lua code, no optimization or heavy rewriting is done (ON HIATUS) | ||
124 | *** NOTE: there is a Lua-on-Lua project called LuLu on LuaForge | ||
125 | (f) A test suite for the VM (CAN ADAPT LUA'S TEST SUITE) | ||
126 | (g) Partial rewrites of Yueliang. (NATIVE LEXERS AND PARSERS DONE | ||
127 | FOR BOTH 5.0 AND 5.1) | ||
128 | (h) Addition of features to Yueliang. | ||
129 | |||
130 | -- | ||
131 | |||
132 | ACKNOWLEDGEMENTS | ||
133 | |||
134 | Yueliang is a straight port of Lua 5 code, so I have included the Lua | ||
135 | 5.0.x copyright as well the Lua 5.1.x copyright files. | ||
136 | |||
137 | Thanks to the LuaForge people for hosting this. | ||
138 | Developed on SciTE http://www.scintilla.org/. Two thumbs up. | ||
139 | |||
140 | -- | ||
141 | |||
142 | FEEDBACK | ||
143 | |||
144 | Feedback and contributions are welcome. Your name will be acknowledged, | ||
145 | as long as you are willing to comply with COPYRIGHT. If your material is | ||
146 | self-contained, you can retain a copyright notice for those material in | ||
147 | your own name, as long as you use the same Lua 5/MIT-style copyright. | ||
148 | |||
149 | I am on dial-up, so I might not be able to reply immediately. My | ||
150 | alternative e-mail address is: keinhong AT gmail DOT com | ||
151 | |||
152 | Enjoy!! | ||
153 | |||
154 | Kein-Hong Man (esq.) | ||
155 | Kuala Lumpur | ||
156 | 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 @@ | |||
1 | nat-5.0.3 | ||
2 | |||
3 | This directory contains versions of front end files that are rewritten | ||
4 | to be more "native" to Lua. These files should be considered as | ||
5 | exercises in exploring ways to write the front end, for example, to | ||
6 | write a front end that is optimized for size, etc. See also file size | ||
7 | data further below. | ||
8 | |||
9 | The following are the different versions available (mk2 == "mark 2", | ||
10 | this is commonly used in the UK, e.g. for aeroplanes during WWII): | ||
11 | |||
12 | Lexers | ||
13 | ------ | ||
14 | |||
15 | WARNING: Theses lexer may or may not exhibit exact behaviour when lexing | ||
16 | strings or long strings with embedded CRLF newlines. The CRLF sequence | ||
17 | may be translated into LF (the reference manual is unclear on this.) The | ||
18 | user is advised to stick to LF line endings exclusively. | ||
19 | |||
20 | llex_mk2 Rewritten from original ported code to become more | ||
21 | Lua-like. Still uses a stream-based input interface. | ||
22 | MK2 still scans using a per-character function that | ||
23 | is pretty inefficient. | ||
24 | |||
25 | Status: TESTED | ||
26 | |||
27 | llex_mk3 A rewritten version of MK2 that needs input to be | ||
28 | entered as a single string. Unless an application's | ||
29 | need is very unusual, this should not be a problem. | ||
30 | It will not work for per-line interaction, though. | ||
31 | MK3 no longer needs stream input functions. This | ||
32 | version is also heavily optimized for size. MK3 scans | ||
33 | using find functions and doesn't create many strings. | ||
34 | |||
35 | Status: TESTED | ||
36 | |||
37 | llex_mk4 A rewritten version of MK3 that is line-oriented. | ||
38 | This allows a command-line version that works in the | ||
39 | usual way to be written. | ||
40 | |||
41 | Status: TESTED | ||
42 | |||
43 | The following is a comparison of file sizes (as of 20061111): | ||
44 | |||
45 | lzio llex TOTAL Speed (2) | ||
46 | (bytes) (bytes) (bytes) (KB/s) | ||
47 | ---------------------------------------------- | ||
48 | Binary (Mingw) 416 5312 5728 N/A | ||
49 | ---------------------------------------------- | ||
50 | (in orig-5.0.3:) | ||
51 | ---------------------------------------------- | ||
52 | normal 2219 12639 14585 404.9 | ||
53 | stripped 1292 7618 8910 | ||
54 | ---------------------------------------------- | ||
55 | (in nat-5.0.3:) | ||
56 | ---------------------------------------------- | ||
57 | mk2 1995 7628 9623 469.5 | ||
58 | mk2-stripped 1195 4003 5298 | ||
59 | ---------------------------------------------- | ||
60 | mk3 (1) - 6552 6552 1870.8 | ||
61 | mk3-stripped - 3286 3286 | ||
62 | ---------------------------------------------- | ||
63 | mk4 1337 6956 8293 802.9 | ||
64 | mk4-stripped 798 3457 4225 | ||
65 | ---------------------------------------------- | ||
66 | |||
67 | (1) mk3 does not have a file input streaming function | ||
68 | |||
69 | (2) Speed was benchmarked using a Sempron 3000+. Benchmark scripts are | ||
70 | in the test directories. Best of first three figures quoted. This is a | ||
71 | measurement of raw lexer speed, i.e. tokens are read but no processing | ||
72 | is done. All files are read in entirely before running the lexer. | ||
73 | |||
74 | The performance of the orig-5.0.3 parser is probably a whole magnitude | ||
75 | less than the orig-5.0.3 lexer performance. | ||
76 | |||
77 | Parsers | ||
78 | ------- | ||
79 | |||
80 | lparser_mk3 Written for the simplified lexer interface of llex_mk3+. | ||
81 | (Should be compatible with llex_mk4 too, but untested.) | ||
82 | This is a lexer skeleton, stripped of codegen code. See | ||
83 | the comments in the source code for more information. | ||
84 | Without logging messages and comments, it's under 600 LOC. | ||
85 | |||
86 | Sample output of the parser message logger can be found | ||
87 | in the test/parser_log subdirectory. | ||
88 | |||
89 | Tested with test_parser-5.0.lua, the Lua 5.0.x parser test | ||
90 | cases in the test_lua/ directory, appears to be fine. | ||
91 | |||
92 | Status: SNIPPETS APPEAR TO WORK | ||
93 | |||
94 | lparser_mk3b As above, with variable management code added. In order | ||
95 | to use the parser usefully, variable management code is | ||
96 | a big step forward, allowing the parser to differentiate | ||
97 | locals, upvalues and globals. The number of added lines | ||
98 | is around 100 LOC. A binary chunk of lparser_mk3b | ||
99 | (stripped) is 18076 bytes. | ||
100 | |||
101 | Sample output of the parser message logger can be found | ||
102 | in the test/parser_log subdirectory. | ||
103 | |||
104 | Tested with test_parser-5.0.lua, the Lua 5.0.x parser test | ||
105 | cases in the test_lua/ directory, appears to be fine. | ||
106 | |||
107 | Status: SNIPPETS APPEAR TO WORK | ||
108 | |||
109 | There will be no further development beyond lparser_mk3b. Further work | ||
110 | will focus on a 5.1.x equivalent, for which both a parser skeleton and a | ||
111 | parser with full code generation using nicely commented code is planned. | ||
112 | |||
113 | Other notes: | ||
114 | ------------ | ||
115 | |||
116 | For Lua 5.0.2, see Yueliang 0.1.3, which was the last release of Lua | ||
117 | 5.0.2 material. | ||
118 | |||
119 | Test scripts for the lexer should probably be consolidated, but it's a | ||
120 | little difficult because not all lexers give the same error messages or | ||
121 | use the same token names or format. | ||
122 | |||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | llex.lua | ||
4 | Lua 5 lexical analyzer in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * parser to implement luaX_syntaxerror, call errorline with 2 parms | ||
18 | ----------------------------------------------------------------------]] | ||
19 | |||
20 | --[[-------------------------------------------------------------------- | ||
21 | -- local lex_init = require("llex.lua") | ||
22 | -- local llex = lex_init(z, source) | ||
23 | -- llex:chunkid() | ||
24 | -- * returns formatted name of chunk id | ||
25 | -- llex:errorline(s, token, line) | ||
26 | -- * throws an error with a formatted message | ||
27 | -- llex:lex() | ||
28 | -- * returns next lexical element (token, seminfo) | ||
29 | ----------------------------------------------------------------------]] | ||
30 | |||
31 | return | ||
32 | function(z, source) | ||
33 | --[[-------------------------------------------------------------------- | ||
34 | -- lexer initialization | ||
35 | ----------------------------------------------------------------------]] | ||
36 | -------------------------------------------------------------------- | ||
37 | -- initialize variables | ||
38 | -------------------------------------------------------------------- | ||
39 | local string = string | ||
40 | local EOF = "<eof>" | ||
41 | local z = z | ||
42 | local luaX = {source = source, lineno = 1,} | ||
43 | local curr, buff | ||
44 | -------------------------------------------------------------------- | ||
45 | -- initialize keyword list | ||
46 | -------------------------------------------------------------------- | ||
47 | local kw = {} | ||
48 | for v in string.gfind([[ | ||
49 | and break do else elseif end false for function if in | ||
50 | local nil not or repeat return then true until while]], "%S+") do | ||
51 | kw[v] = true | ||
52 | end | ||
53 | --[[-------------------------------------------------------------------- | ||
54 | -- support functions | ||
55 | ----------------------------------------------------------------------]] | ||
56 | -------------------------------------------------------------------- | ||
57 | -- returns a chunk name or id | ||
58 | -------------------------------------------------------------------- | ||
59 | function luaX:chunkid() | ||
60 | local sub = string.sub | ||
61 | local first = sub(source, 1, 1) | ||
62 | if first == "=" or first == "@" then | ||
63 | return sub(source, 2) -- remove first char | ||
64 | end | ||
65 | return "[string]" | ||
66 | end | ||
67 | -------------------------------------------------------------------- | ||
68 | -- formats error message and throws error | ||
69 | -------------------------------------------------------------------- | ||
70 | function luaX:errorline(s, token, line) | ||
71 | if not line then line = self.lineno end | ||
72 | error(string.format("%s:%d: %s near '%s'", self:chunkid(), line, s, token)) | ||
73 | end | ||
74 | -------------------------------------------------------------------- | ||
75 | -- throws a lexer error | ||
76 | -------------------------------------------------------------------- | ||
77 | local function lexerror(s, token) | ||
78 | if not token then token = buff end | ||
79 | luaX:errorline(s, token) | ||
80 | end | ||
81 | -------------------------------------------------------------------- | ||
82 | -- gets the next character and returns it | ||
83 | -------------------------------------------------------------------- | ||
84 | local function nextc() | ||
85 | local c = z:getc() | ||
86 | curr = c | ||
87 | return c | ||
88 | end | ||
89 | -------------------------------------------------------------------- | ||
90 | -- save current character into token buffer, grabs next character | ||
91 | -- * save(c) merged into this and elsewhere to save space | ||
92 | -------------------------------------------------------------------- | ||
93 | local function save_next() | ||
94 | buff = buff..curr | ||
95 | return nextc() | ||
96 | end | ||
97 | -------------------------------------------------------------------- | ||
98 | -- move on to next line | ||
99 | -------------------------------------------------------------------- | ||
100 | local function nextline() | ||
101 | local luaX = luaX | ||
102 | nextc() -- skip '\n' | ||
103 | luaX.lineno = luaX.lineno + 1 | ||
104 | end | ||
105 | --[[-------------------------------------------------------------------- | ||
106 | -- reads a number (LUA_NUMBER) | ||
107 | ----------------------------------------------------------------------]] | ||
108 | local function read_numeral(comma) | ||
109 | buff = "" | ||
110 | local find = string.find | ||
111 | if comma then buff = "." end | ||
112 | ------------------------------------------------------------------ | ||
113 | while find(curr, "%d") do save_next() end | ||
114 | if curr == "." then | ||
115 | if save_next() == "." then | ||
116 | save_next() | ||
117 | lexerror("ambiguous syntax (dots follows digits)") | ||
118 | end | ||
119 | end | ||
120 | ------------------------------------------------------------------ | ||
121 | while find(curr, "%d") do save_next() end | ||
122 | if find(curr, "^[eE]$") then | ||
123 | save_next() -- read 'E' and optional exponent sign | ||
124 | if find(curr, "^[+-]$") then save_next() end | ||
125 | while find(curr, "%d") do save_next() end | ||
126 | end | ||
127 | c = tonumber(buff) | ||
128 | if c then return c end | ||
129 | lexerror("malformed number") | ||
130 | end | ||
131 | --[[-------------------------------------------------------------------- | ||
132 | -- reads a long string or long comment | ||
133 | ----------------------------------------------------------------------]] | ||
134 | local function read_long(is_str) | ||
135 | local cont = 0 | ||
136 | buff = "" | ||
137 | nextc() -- pass the '[[' | ||
138 | if curr == "\n" then -- string starts with a newline? | ||
139 | nextline() -- skip it | ||
140 | end | ||
141 | while true do | ||
142 | local c = curr | ||
143 | ---------------------------------------------------------------- | ||
144 | if c == "EOZ" then | ||
145 | lexerror(is_str and "unfinished long string" or | ||
146 | "unfinished long comment", EOF) | ||
147 | ---------------------------------------------------------------- | ||
148 | elseif c == "[" then | ||
149 | if save_next() == "[" then | ||
150 | cont = cont + 1; save_next() | ||
151 | end | ||
152 | ---------------------------------------------------------------- | ||
153 | elseif c == "]" then | ||
154 | if save_next() == "]" then | ||
155 | if cont == 0 then break end | ||
156 | cont = cont - 1; save_next() | ||
157 | end | ||
158 | ---------------------------------------------------------------- | ||
159 | elseif c == "\n" then | ||
160 | buff = buff.."\n"; nextline() | ||
161 | if not is_str then buff = "" end -- avoid wasting space | ||
162 | ---------------------------------------------------------------- | ||
163 | else | ||
164 | save_next() | ||
165 | ---------------------------------------------------------------- | ||
166 | end--if c | ||
167 | end--while | ||
168 | nextc() -- skip second ']' | ||
169 | return string.sub(buff, 1, -2) | ||
170 | end | ||
171 | --[[-------------------------------------------------------------------- | ||
172 | -- reads a string | ||
173 | ----------------------------------------------------------------------]] | ||
174 | local function read_string(del) | ||
175 | local find = string.find | ||
176 | buff = "" | ||
177 | save_next() -- save delimiter | ||
178 | while curr ~= del do | ||
179 | local c = curr | ||
180 | ---------------------------------------------------------------- | ||
181 | -- end-of-file, newline | ||
182 | ---------------------------------------------------------------- | ||
183 | if c == "EOZ" then | ||
184 | lexerror("unfinished string", EOF) | ||
185 | elseif c == "\n" then | ||
186 | lexerror("unfinished string") | ||
187 | ---------------------------------------------------------------- | ||
188 | -- escapes | ||
189 | ---------------------------------------------------------------- | ||
190 | elseif c == "\\" then | ||
191 | c = nextc() -- do not save the '\' | ||
192 | if c ~= "EOZ" then -- will raise an error next loop iteration | ||
193 | local d = find("\nabfnrtv", c, 1, 1) | ||
194 | if d then | ||
195 | buff = buff..string.sub("\n\a\b\f\n\r\t\v", d, d) | ||
196 | if d == 1 then nextline() else nextc() end | ||
197 | elseif find(c, "%D") then | ||
198 | save_next() -- handles \\, \", \', and \? | ||
199 | else -- \xxx | ||
200 | c, d = 0, 0 | ||
201 | repeat | ||
202 | c = 10 * c + curr; d = d + 1; nextc() | ||
203 | until d >= 3 or find(curr, "%D") | ||
204 | if c > 255 then -- UCHAR_MAX | ||
205 | lexerror("escape sequence too large") | ||
206 | end | ||
207 | buff = buff..string.char(c) | ||
208 | end | ||
209 | end | ||
210 | ---------------------------------------------------------------- | ||
211 | -- a regular character | ||
212 | ---------------------------------------------------------------- | ||
213 | else | ||
214 | save_next() | ||
215 | ---------------------------------------------------------------- | ||
216 | end--if c | ||
217 | end--while | ||
218 | nextc() -- skip delimiter | ||
219 | return string.sub(buff, 2) | ||
220 | end | ||
221 | --[[-------------------------------------------------------------------- | ||
222 | -- main lexer function | ||
223 | ----------------------------------------------------------------------]] | ||
224 | function luaX:lex() | ||
225 | local find = string.find | ||
226 | while true do | ||
227 | local c = curr | ||
228 | ---------------------------------------------------------------- | ||
229 | -- operators, numbers | ||
230 | ---------------------------------------------------------------- | ||
231 | local d = find("=<>~\"'-[.\n", c, 1, 1) | ||
232 | if d then | ||
233 | ------------------------------------------------------------ | ||
234 | if d <= 4 then -- "=<>~" (relational operators) | ||
235 | if nextc() ~= "=" then return c end | ||
236 | nextc(); return c.."=" | ||
237 | ------------------------------------------------------------ | ||
238 | elseif d <= 6 then -- "\"" or "'" (string) | ||
239 | return "<string>", read_string(c) | ||
240 | ------------------------------------------------------------ | ||
241 | elseif c == "-" then -- "-" ("-", comment, or long comment) | ||
242 | if nextc() ~= "-" then return "-" end | ||
243 | c = nextc() -- otherwise it is a comment | ||
244 | if c == "[" and nextc() == "[" then | ||
245 | read_long() -- long comment | ||
246 | else -- short comment | ||
247 | while c ~= "\n" and c ~= "EOZ" do c = nextc() end | ||
248 | end | ||
249 | ------------------------------------------------------------ | ||
250 | elseif c == "[" then -- "[" ("[" or long string) | ||
251 | if nextc() ~= "[" then return c end | ||
252 | return "<string>", read_long(true) | ||
253 | ------------------------------------------------------------ | ||
254 | elseif c == "." then -- "." (".", concatenation, or dots) | ||
255 | buff = "" | ||
256 | c = save_next() | ||
257 | if c == "." then -- interpret 2 or 3 dots | ||
258 | if save_next() == "." then save_next() end | ||
259 | return buff | ||
260 | end | ||
261 | if find(c, "%d") then | ||
262 | return "<number>", read_numeral(true) | ||
263 | end | ||
264 | return "." | ||
265 | ------------------------------------------------------------ | ||
266 | else-- c == "\n" then -- "\n" (newline) | ||
267 | nextline() | ||
268 | ------------------------------------------------------------ | ||
269 | end--if d/c | ||
270 | ---------------------------------------------------------------- | ||
271 | -- number, end-of-file, identifier or reserved word | ||
272 | ---------------------------------------------------------------- | ||
273 | elseif find(c, "%d") then -- number | ||
274 | return "<number>", read_numeral(false) | ||
275 | ---------------------------------------------------------------- | ||
276 | elseif find(c, "[_%a]") then -- reads a name | ||
277 | if c == "EOZ" then return EOF end -- end-of-file | ||
278 | buff = "" | ||
279 | repeat | ||
280 | c = save_next() | ||
281 | until c == "EOZ" or find(c, "[^_%w]") | ||
282 | c = buff | ||
283 | if kw[c] then return c end -- reserved word | ||
284 | return "<name>", c | ||
285 | ---------------------------------------------------------------- | ||
286 | -- whitespace, other characters, control characters | ||
287 | ---------------------------------------------------------------- | ||
288 | elseif find(c, "%s") then -- whitespace | ||
289 | nextc() | ||
290 | ---------------------------------------------------------------- | ||
291 | elseif find(c, "%c") then -- control characters | ||
292 | lexerror("invalid control char", "char("..string.byte(c)..")") | ||
293 | ---------------------------------------------------------------- | ||
294 | else -- single-char tokens (+ - / etc.) | ||
295 | nextc(); return c | ||
296 | ---------------------------------------------------------------- | ||
297 | end--if d/c | ||
298 | end--while | ||
299 | end | ||
300 | --[[-------------------------------------------------------------------- | ||
301 | -- initial processing (shbang handling) | ||
302 | ----------------------------------------------------------------------]] | ||
303 | nextc() -- read first char | ||
304 | if cur == "#" then -- skip first line | ||
305 | repeat nextc() until curr == "\n" or curr == "EOZ" | ||
306 | end | ||
307 | return luaX | ||
308 | --[[------------------------------------------------------------------]] | ||
309 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | llex.lua | ||
4 | Lua 5 lexical analyzer in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * takes in the entire source at once | ||
18 | -- * code is heavily optimized for size | ||
19 | -- | ||
20 | -- local lex_init = require("llex.lua") | ||
21 | -- local llex = lex_init(z, source) | ||
22 | -- llex:chunkid() | ||
23 | -- * returns formatted name of chunk id | ||
24 | -- llex:errorline(s, line) | ||
25 | -- * throws an error with a formatted message | ||
26 | -- llex:lex() | ||
27 | -- * returns next lexical element (token, seminfo) | ||
28 | -- llex.ln | ||
29 | -- * line number | ||
30 | ----------------------------------------------------------------------]] | ||
31 | |||
32 | return | ||
33 | function(z, source) | ||
34 | -------------------------------------------------------------------- | ||
35 | -- initialize variables | ||
36 | -- * I is the upvalue, i is the local version for space/efficiency | ||
37 | -------------------------------------------------------------------- | ||
38 | local string = string | ||
39 | local find, sub = string.find, string.sub | ||
40 | local EOF = "<eof>" | ||
41 | local luaX = { ln = 1 } | ||
42 | local I = 1 | ||
43 | -------------------------------------------------------------------- | ||
44 | -- initialize keyword list | ||
45 | -------------------------------------------------------------------- | ||
46 | local kw = {} | ||
47 | for v in string.gfind([[ | ||
48 | and break do else elseif end false for function if in | ||
49 | local nil not or repeat return then true until while]], "%S+") do | ||
50 | kw[v] = true | ||
51 | end | ||
52 | -------------------------------------------------------------------- | ||
53 | -- returns a chunk name or id | ||
54 | -------------------------------------------------------------------- | ||
55 | function luaX:chunkid() | ||
56 | if find(source, "^[=@]") then | ||
57 | return sub(source, 2) -- remove first char | ||
58 | end | ||
59 | return "[string]" | ||
60 | end | ||
61 | -------------------------------------------------------------------- | ||
62 | -- formats error message and throws error | ||
63 | -- * a simplified version, does not report what token was responsible | ||
64 | -------------------------------------------------------------------- | ||
65 | function luaX:errorline(s, line) | ||
66 | error(string.format("%s:%d: %s", self:chunkid(), line or self.ln, s)) | ||
67 | end | ||
68 | ---------------------------------------------------------------------- | ||
69 | -- reads a long string or long comment | ||
70 | ---------------------------------------------------------------------- | ||
71 | local function read_long(i, is_str) | ||
72 | local luaX = luaX | ||
73 | local string = string | ||
74 | local cont = 1 | ||
75 | if sub(z, i, i) == "\n" then | ||
76 | i = i + 1 | ||
77 | luaX.ln = luaX.ln + 1 | ||
78 | end | ||
79 | local j = i | ||
80 | while true do | ||
81 | local p, q, r = find(z, "([\n%[%]])", i) -- (long range) | ||
82 | if not p then | ||
83 | luaX:errorline(is_str and "unfinished long string" or | ||
84 | "unfinished long comment") | ||
85 | end | ||
86 | i = p + 1 | ||
87 | if r == "\n" then | ||
88 | luaX.ln = luaX.ln + 1 | ||
89 | elseif sub(z, i, i) == r then -- only [[ or ]] | ||
90 | i = i + 1 | ||
91 | if r == "[" then | ||
92 | cont = cont + 1 | ||
93 | else-- r == "]" then | ||
94 | if cont == 1 then break end -- last ]] found | ||
95 | cont = cont - 1 | ||
96 | end | ||
97 | end | ||
98 | end--while | ||
99 | I = i | ||
100 | return sub(z, j, i - 3) | ||
101 | end | ||
102 | ---------------------------------------------------------------------- | ||
103 | -- reads a string | ||
104 | ---------------------------------------------------------------------- | ||
105 | local function read_string(i, del) | ||
106 | local luaX = luaX | ||
107 | local string = string | ||
108 | local buff = "" | ||
109 | while true do | ||
110 | local p, q, r = find(z, "([\n\\\"\'])", i) -- (long range) | ||
111 | if p then | ||
112 | if r == "\n" then | ||
113 | luaX:errorline("unfinished string") | ||
114 | end | ||
115 | buff = buff..sub(z, i, p - 1) -- normal portions | ||
116 | i = p | ||
117 | if r == "\\" then -- handle escapes | ||
118 | i = i + 1 | ||
119 | r = sub(z, i, i) | ||
120 | if r == "" then break end -- (error) | ||
121 | p = find("\nabfnrtv", r, 1, 1) | ||
122 | ------------------------------------------------------ | ||
123 | if p then -- special escapes | ||
124 | r = sub("\n\a\b\f\n\r\t\v", p, p) | ||
125 | if p == 1 then luaX.ln = luaX.ln + 1 end | ||
126 | i = i + 1 | ||
127 | ------------------------------------------------------ | ||
128 | elseif find(r, "%D") then -- other non-digits | ||
129 | i = i + 1 | ||
130 | ------------------------------------------------------ | ||
131 | else -- \xxx sequence | ||
132 | local p, q, s = find(z, "^(%d%d?%d?)", i) | ||
133 | i = q + 1 | ||
134 | if s + 1 > 256 then -- UCHAR_MAX | ||
135 | luaX:errorline("escape sequence too large") | ||
136 | end | ||
137 | r = string.char(s) | ||
138 | ------------------------------------------------------ | ||
139 | end--if p | ||
140 | else | ||
141 | i = i + 1 | ||
142 | if r == del then | ||
143 | I = i | ||
144 | return buff -- ending delimiter | ||
145 | end | ||
146 | end--if r | ||
147 | buff = buff..r | ||
148 | else | ||
149 | break -- (error) | ||
150 | end--if p | ||
151 | end--while | ||
152 | luaX:errorline("unfinished string") | ||
153 | end | ||
154 | ---------------------------------------------------------------------- | ||
155 | -- main lexer function | ||
156 | ---------------------------------------------------------------------- | ||
157 | function luaX:lex() | ||
158 | local string = string | ||
159 | local find, len = find, string.len | ||
160 | while true do--outer | ||
161 | local i = I | ||
162 | -- inner loop allows break to be used to nicely section tests | ||
163 | while true do--inner | ||
164 | ---------------------------------------------------------------- | ||
165 | local p, _, r = find(z, "^([_%a][_%w]*)", i) | ||
166 | if p then | ||
167 | I = i + len(r) | ||
168 | if kw[r] then return r end -- keyword | ||
169 | return "<name>", r -- identifier | ||
170 | end | ||
171 | ---------------------------------------------------------------- | ||
172 | local p, q, r = find(z, "^(%.?)%d", i) | ||
173 | if p then -- numeral | ||
174 | if r == "." then i = i + 1 end | ||
175 | local _, n, r, s = find(z, "^%d*(%.?%.?)%d*([eE]?)", i) | ||
176 | q = n | ||
177 | i = q + 1 | ||
178 | if len(r) == 2 then | ||
179 | self:errorline("ambiguous syntax (dots follows digits)") | ||
180 | end | ||
181 | if len(s) == 1 then -- optional exponent | ||
182 | local _, n = find(z, "^[%+%-]?%d*", i) -- optional sign | ||
183 | q = n | ||
184 | i = q + 1 | ||
185 | end | ||
186 | r = tonumber(sub(z, p, q)) | ||
187 | I = i | ||
188 | if not r then self:errorline("malformed number") end | ||
189 | return "<number>", r | ||
190 | end | ||
191 | ---------------------------------------------------------------- | ||
192 | local p, q, r = find(z, "^(%s)[ \t]*", i) | ||
193 | if p then | ||
194 | if r == "\n" then -- newline | ||
195 | self.ln = self.ln + 1 | ||
196 | I = i + 1 | ||
197 | else | ||
198 | I = q + 1 -- whitespace | ||
199 | end | ||
200 | break -- (continue) | ||
201 | end | ||
202 | ---------------------------------------------------------------- | ||
203 | local p, _, r = find(z, "^(%p)", i) -- symbols/punctuation | ||
204 | if p then | ||
205 | local q = find("-[\"\'.=<>~", r, 1, 1) | ||
206 | if q then -- further processing for more complex symbols | ||
207 | ---------------------------------------------------- | ||
208 | if q <= 2 then | ||
209 | if q == 1 then -- minus | ||
210 | if find(z, "^%-%-", i) then | ||
211 | i = i + 2 | ||
212 | if find(z, "^%[%[", i) then -- long comment | ||
213 | read_long(i + 2) | ||
214 | else -- short comment | ||
215 | I = find(z, "\n", i) or (len(z) + 1) | ||
216 | end | ||
217 | break -- (continue) | ||
218 | end | ||
219 | -- (fall through for "-") | ||
220 | elseif q == 2 then -- [ or long string | ||
221 | if find(z, "^%[%[", i) then | ||
222 | return "<string>", read_long(i + 2, true) | ||
223 | end | ||
224 | -- (fall through for "[") | ||
225 | end | ||
226 | ---------------------------------------------------- | ||
227 | elseif q <= 5 then | ||
228 | if q < 5 then -- strings | ||
229 | return "<string>", read_string(i + 1, r) | ||
230 | end | ||
231 | local _, _, s = find(z, "^(%.%.?%.?)", i) -- dots | ||
232 | r = s | ||
233 | -- (fall through) | ||
234 | ---------------------------------------------------- | ||
235 | else -- relational/logic | ||
236 | local _, _, s = find(z, "^(%p=?)", i) | ||
237 | r = s | ||
238 | -- (fall through) | ||
239 | end | ||
240 | end | ||
241 | I = i + len(r); return r -- for other symbols, fall through | ||
242 | end | ||
243 | ---------------------------------------------------------------- | ||
244 | local r = sub(z, i, i) | ||
245 | if r ~= "" then | ||
246 | if find(r, "%c") then -- invalid control char | ||
247 | self:errorline("invalid control char("..string.byte(r)..")") | ||
248 | end | ||
249 | I = i + 1; return r -- other single-char tokens | ||
250 | end | ||
251 | return EOF -- end of stream | ||
252 | ---------------------------------------------------------------- | ||
253 | end--while inner | ||
254 | end--while outer | ||
255 | end | ||
256 | -------------------------------------------------------------------- | ||
257 | -- initial processing (shbang handling) | ||
258 | -------------------------------------------------------------------- | ||
259 | local p, q, r = find(z, "^#[^\n]*(\n?)") | ||
260 | if p then -- skip first line | ||
261 | I = q + 1 | ||
262 | if r == "\n" then luaX.ln = luaX.ln + 1 end | ||
263 | end | ||
264 | return luaX | ||
265 | -------------------------------------------------------------------- | ||
266 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | llex.lua | ||
4 | Lua 5 lexical analyzer in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * a line-oriented version of mk3 | ||
18 | -- | ||
19 | -- local lex_init = require("llex.lua") | ||
20 | -- local llex = lex_init(z, source) | ||
21 | -- llex:chunkid() | ||
22 | -- * returns formatted name of chunk id | ||
23 | -- llex:errorline(s, line) | ||
24 | -- * throws an error with a formatted message | ||
25 | -- llex:lex() | ||
26 | -- * returns next lexical element (token, seminfo) | ||
27 | -- llex.ln | ||
28 | -- * line number | ||
29 | ----------------------------------------------------------------------]] | ||
30 | |||
31 | return | ||
32 | function(zio, source) | ||
33 | -------------------------------------------------------------------- | ||
34 | -- initialize variables | ||
35 | -- * I is the upvalue, i is the local version for space/efficiency | ||
36 | -------------------------------------------------------------------- | ||
37 | local string = string | ||
38 | local find, sub = string.find, string.sub | ||
39 | local EOF = "<eof>" | ||
40 | local luaX = { ln = 0 } | ||
41 | local I, z | ||
42 | -------------------------------------------------------------------- | ||
43 | -- initialize keyword list | ||
44 | -------------------------------------------------------------------- | ||
45 | local kw = {} | ||
46 | for v in string.gfind([[ | ||
47 | and break do else elseif end false for function if in | ||
48 | local nil not or repeat return then true until while]], "%S+") do | ||
49 | kw[v] = true | ||
50 | end | ||
51 | -------------------------------------------------------------------- | ||
52 | -- returns a chunk name or id | ||
53 | -------------------------------------------------------------------- | ||
54 | function luaX:chunkid() | ||
55 | if find(source, "^[=@]") then | ||
56 | return sub(source, 2) -- remove first char | ||
57 | end | ||
58 | return "[string]" | ||
59 | end | ||
60 | -------------------------------------------------------------------- | ||
61 | -- formats error message and throws error | ||
62 | -- * a simplified version, does not report what token was responsible | ||
63 | -------------------------------------------------------------------- | ||
64 | function luaX:errorline(s, line) | ||
65 | error(string.format("%s:%d: %s", self:chunkid(), line or self.ln, s)) | ||
66 | end | ||
67 | -------------------------------------------------------------------- | ||
68 | -- move on to next line | ||
69 | -------------------------------------------------------------------- | ||
70 | local function nextln() | ||
71 | local luaX = luaX | ||
72 | luaX.ln = luaX.ln + 1 | ||
73 | z = zio:getln() | ||
74 | I = 1 | ||
75 | end | ||
76 | ---------------------------------------------------------------------- | ||
77 | -- reads a long string or long comment | ||
78 | ---------------------------------------------------------------------- | ||
79 | local function read_long(i, is_str) | ||
80 | local luaX = luaX | ||
81 | local string = string | ||
82 | local buff = "" | ||
83 | local cont = 1 | ||
84 | if sub(z, i, i) == "\n" then | ||
85 | nextln(); i = 1 | ||
86 | end | ||
87 | while true do | ||
88 | local p, q, r = find(z, "([\n%[%]])", i) -- (long range) | ||
89 | if not p then | ||
90 | luaX:errorline(is_str and "unfinished long string" or | ||
91 | "unfinished long comment") | ||
92 | end | ||
93 | buff = buff..string.sub(z, i, p - 1) -- add a portion | ||
94 | i = p + 1 | ||
95 | if sub(z, i, i) == r then -- only [[ or ]] | ||
96 | i = i + 1 | ||
97 | if r == "[" then | ||
98 | cont = cont + 1 | ||
99 | else-- r == "]" then | ||
100 | if cont == 1 then break end -- last ]] found | ||
101 | cont = cont - 1 | ||
102 | end | ||
103 | buff = buff..r..r | ||
104 | else -- [ or ] or \n | ||
105 | buff = buff..r | ||
106 | if r == "\n" then | ||
107 | nextln(); i = 1 | ||
108 | end | ||
109 | end | ||
110 | end--while | ||
111 | I = i | ||
112 | return buff | ||
113 | end | ||
114 | ---------------------------------------------------------------------- | ||
115 | -- reads a string | ||
116 | ---------------------------------------------------------------------- | ||
117 | local function read_string(i, del) | ||
118 | local luaX = luaX | ||
119 | local string = string | ||
120 | local buff = "" | ||
121 | while true do | ||
122 | local p, q, r = find(z, "([\n\\\"\'])", i) -- (long range) | ||
123 | if p then | ||
124 | if r == "\n" then | ||
125 | luaX:errorline("unfinished string") | ||
126 | end | ||
127 | buff = buff..sub(z, i, p - 1) -- normal portions | ||
128 | i = p | ||
129 | if r == "\\" then -- handle escapes | ||
130 | i = i + 1 | ||
131 | r = sub(z, i, i) | ||
132 | if r == "" then break end -- (error) | ||
133 | p = find("\nabfnrtv", r, 1, 1) | ||
134 | ------------------------------------------------------ | ||
135 | if p then -- special escapes | ||
136 | r = sub("\n\a\b\f\n\r\t\v", p, p) | ||
137 | if p == 1 then | ||
138 | nextln(); i = 1 | ||
139 | else | ||
140 | i = i + 1 | ||
141 | end | ||
142 | ------------------------------------------------------ | ||
143 | elseif find(r, "%D") then -- other non-digits | ||
144 | i = i + 1 | ||
145 | ------------------------------------------------------ | ||
146 | else -- \xxx sequence | ||
147 | local p, q, s = find(z, "^(%d%d?%d?)", i) | ||
148 | i = q + 1 | ||
149 | if s + 1 > 256 then -- UCHAR_MAX | ||
150 | luaX:errorline("escape sequence too large") | ||
151 | end | ||
152 | r = string.char(s) | ||
153 | ------------------------------------------------------ | ||
154 | end--if p | ||
155 | else | ||
156 | i = i + 1 | ||
157 | if r == del then | ||
158 | I = i | ||
159 | return buff -- ending delimiter | ||
160 | end | ||
161 | end--if r | ||
162 | buff = buff..r | ||
163 | else | ||
164 | break -- (error) | ||
165 | end--if p | ||
166 | end--while | ||
167 | luaX:errorline("unfinished string") | ||
168 | end | ||
169 | ---------------------------------------------------------------------- | ||
170 | -- main lexer function | ||
171 | ---------------------------------------------------------------------- | ||
172 | function luaX:lex() | ||
173 | local string = string | ||
174 | local find, len = find, string.len | ||
175 | while true do--outer | ||
176 | local i = I | ||
177 | -- inner loop allows break to be used to nicely section tests | ||
178 | while true do--inner | ||
179 | ---------------------------------------------------------------- | ||
180 | local p, _, r = find(z, "^([_%a][_%w]*)", i) | ||
181 | if p then | ||
182 | I = i + len(r) | ||
183 | if kw[r] then return r end -- keyword | ||
184 | return "<name>", r -- identifier | ||
185 | end | ||
186 | ---------------------------------------------------------------- | ||
187 | local p, q, r = find(z, "^(%.?)%d", i) | ||
188 | if p then -- numeral | ||
189 | if r == "." then i = i + 1 end | ||
190 | local _, n, r, s = find(z, "^%d*(%.?%.?)%d*([eE]?)", i) | ||
191 | q = n | ||
192 | i = q + 1 | ||
193 | if len(r) == 2 then | ||
194 | self:errorline("ambiguous syntax (dots follows digits)") | ||
195 | end | ||
196 | if len(s) == 1 then -- optional exponent | ||
197 | local _, n = find(z, "^[%+%-]?%d*", i) -- optional sign | ||
198 | q = n | ||
199 | i = q + 1 | ||
200 | end | ||
201 | r = tonumber(sub(z, p, q)) | ||
202 | I = i | ||
203 | if not r then self:errorline("malformed number") end | ||
204 | return "<number>", r | ||
205 | end | ||
206 | ---------------------------------------------------------------- | ||
207 | local p, q, r = find(z, "^(%s)[ \t]*", i) | ||
208 | if p then | ||
209 | if r == "\n" then -- newline | ||
210 | nextln() | ||
211 | else | ||
212 | I = q + 1 -- whitespace | ||
213 | end | ||
214 | break -- (continue) | ||
215 | end | ||
216 | ---------------------------------------------------------------- | ||
217 | local p, _, r = find(z, "^(%p)", i) -- symbols/punctuation | ||
218 | if p then | ||
219 | local q = find("-[\"\'.=<>~", r, 1, 1) | ||
220 | if q then -- further processing for more complex symbols | ||
221 | ---------------------------------------------------- | ||
222 | if q <= 2 then | ||
223 | if q == 1 then -- minus | ||
224 | if find(z, "^%-%-", i) then | ||
225 | i = i + 2 | ||
226 | if find(z, "^%[%[", i) then -- long comment | ||
227 | read_long(i + 2) | ||
228 | else -- short comment | ||
229 | if find(z, "\n", i) then | ||
230 | nextln() | ||
231 | else | ||
232 | I = len(z) + 1 | ||
233 | end | ||
234 | end | ||
235 | break -- (continue) | ||
236 | end | ||
237 | -- (fall through for "-") | ||
238 | elseif q == 2 then -- [ or long string | ||
239 | if find(z, "^%[%[", i) then | ||
240 | return "<string>", read_long(i + 2, true) | ||
241 | end | ||
242 | -- (fall through for "[") | ||
243 | end | ||
244 | ---------------------------------------------------- | ||
245 | elseif q <= 5 then | ||
246 | if q < 5 then -- strings | ||
247 | return "<string>", read_string(i + 1, r) | ||
248 | end | ||
249 | local _, _, s = find(z, "^(%.%.?%.?)", i) -- dots | ||
250 | r = s | ||
251 | -- (fall through) | ||
252 | ---------------------------------------------------- | ||
253 | else -- relational/logic | ||
254 | local _, _, s = find(z, "^(%p=?)", i) | ||
255 | r = s | ||
256 | -- (fall through) | ||
257 | end | ||
258 | end | ||
259 | I = i + len(r); return r -- for other symbols, fall through | ||
260 | end | ||
261 | ---------------------------------------------------------------- | ||
262 | local r = sub(z, i, i) | ||
263 | if r ~= "" then | ||
264 | if find(r, "%c") then -- invalid control char | ||
265 | self:errorline("invalid control char("..string.byte(r)..")") | ||
266 | end | ||
267 | I = i + 1; return r -- other single-char tokens | ||
268 | end | ||
269 | return EOF -- end of stream | ||
270 | ---------------------------------------------------------------- | ||
271 | end--while inner | ||
272 | end--while outer | ||
273 | end | ||
274 | -------------------------------------------------------------------- | ||
275 | -- initial processing (shbang handling) | ||
276 | -------------------------------------------------------------------- | ||
277 | nextln() | ||
278 | local p, q, r = find(z, "^#[^\n]*(\n?)") | ||
279 | if p then -- skip first line | ||
280 | I = q + 1 | ||
281 | if r == "\n" then nextln() end | ||
282 | end | ||
283 | return luaX | ||
284 | -------------------------------------------------------------------- | ||
285 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lparser.lua | ||
4 | Lua 5 parser in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * this is a Lua 5.0.x parser skeleton, for llex_mk3.lua lexer | ||
18 | -- * written as a module factory with recognizable lparser.c roots | ||
19 | -- * builds some data, performs logging for educational purposes | ||
20 | -- * target is to have relatively efficient and clear code | ||
21 | -- * needs one parameter, a lexer module that implements: | ||
22 | -- luaX:lex() - returns appropriate [token, semantic info] pairs | ||
23 | -- luaX.ln - current line number | ||
24 | -- luaX:errorline(s, [line]) - dies with error message | ||
25 | -- | ||
26 | -- Usage example: | ||
27 | -- lex_init = require("llex_mk3.lua") | ||
28 | -- parser_init = require("lparser_mk3.lua") | ||
29 | -- local luaX = lex_init(chunk, "=string") | ||
30 | -- local luaY = parser_init(luaX) | ||
31 | -- local fs = luaY:parser() | ||
32 | -- | ||
33 | -- Development notes: | ||
34 | -- * see test_parser-5.0.lua for grammar elements based on lparser.c | ||
35 | -- * lparser has a few extra items to help parsing/syntax checking | ||
36 | -- (a) line number (error reporting), lookahead token storage | ||
37 | -- (b) per-prototype states needs a storage list | ||
38 | -- (c) 'break' needs a per-block flag in a stack | ||
39 | -- (d) 'kind' (v.k) testing needed in expr_stat() and assignment() | ||
40 | -- for disambiguation, thus v.k manipulation is retained | ||
41 | -- (e) one line # var (lastln) for ambiguous (split line) function | ||
42 | -- call checking | ||
43 | -- (f) most line number function call args retained for future use | ||
44 | -- (g) Lua 4 compatibility code completely removed | ||
45 | -- (h) no variable management code! singlevar() always returns VLOCAL | ||
46 | -- * parsing starts from the end of this file in luaY:parser() | ||
47 | -- | ||
48 | ----------------------------------------------------------------------]] | ||
49 | |||
50 | return | ||
51 | function(luaX) | ||
52 | --[[-------------------------------------------------------------------- | ||
53 | -- structures and data initialization | ||
54 | ----------------------------------------------------------------------]] | ||
55 | |||
56 | local line -- start line # for error messages | ||
57 | local lastln -- last line # for ambiguous syntax chk | ||
58 | local tok, seminfo -- token, semantic info pair | ||
59 | local peek_tok, peek_sem -- ditto, for lookahead | ||
60 | local fs -- function state | ||
61 | local top_fs = {} -- top-level function state | ||
62 | local luaY = {} | ||
63 | -------------------------------------------------------------------- | ||
64 | local block_follow = {} -- lookahead check in chunk(), returnstat() | ||
65 | for v in string.gfind("else elseif end until <eof>", "%S+") do | ||
66 | block_follow[v] = true | ||
67 | end | ||
68 | -------------------------------------------------------------------- | ||
69 | local stat_call = {} -- lookup for calls in stat() | ||
70 | for v in string.gfind("if while do for repeat function local return break", "%S+") do | ||
71 | stat_call[v] = v.."_stat" | ||
72 | end | ||
73 | -------------------------------------------------------------------- | ||
74 | local binopr_left = {} -- binary operators, left priority | ||
75 | local binopr_right = {} -- binary operators, right priority | ||
76 | for op, lt, rt in string.gfind([[ | ||
77 | {+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{^ 10 9}{.. 5 4} | ||
78 | {~= 3 3}{== 3 3}{< 3 3}{<= 3 3}{> 3 3}{>= 3 3} | ||
79 | {and 2 2}{or 1 1} | ||
80 | ]], "{(%S+)%s(%d+)%s(%d+)}") do | ||
81 | binopr_left[op] = lt + 0 | ||
82 | binopr_right[op] = rt + 0 | ||
83 | end | ||
84 | local unopr = { ["not"] = true, ["-"] = true, } -- unary operators | ||
85 | |||
86 | --[[-------------------------------------------------------------------- | ||
87 | -- logging: this logging function is for educational purposes | ||
88 | -- * logged data can be retrieved from the returned data structure | ||
89 | -- * or, replace self:log() instances with your custom code... | ||
90 | ----------------------------------------------------------------------]] | ||
91 | |||
92 | function luaY:log(msg) | ||
93 | local log = top_fs.log | ||
94 | if not log then log = {}; top_fs.log = log end | ||
95 | table.insert(top_fs.log, msg) | ||
96 | end | ||
97 | |||
98 | --[[-------------------------------------------------------------------- | ||
99 | -- support functions | ||
100 | ----------------------------------------------------------------------]] | ||
101 | |||
102 | -------------------------------------------------------------------- | ||
103 | -- reads in next token | ||
104 | -------------------------------------------------------------------- | ||
105 | function luaY:next() | ||
106 | lastln = luaX.ln | ||
107 | if peek_tok then -- is there a look-ahead token? if yes, use it | ||
108 | tok, seminfo = peek_tok, peek_sem | ||
109 | peek_tok = nil | ||
110 | else | ||
111 | tok, seminfo = luaX:lex() -- read next token | ||
112 | end | ||
113 | end | ||
114 | -------------------------------------------------------------------- | ||
115 | -- peek at next token (single lookahead for table constructor) | ||
116 | -------------------------------------------------------------------- | ||
117 | function luaY:lookahead() | ||
118 | peek_tok, peek_sem = luaX:lex() | ||
119 | return peek_tok | ||
120 | end | ||
121 | |||
122 | ------------------------------------------------------------------------ | ||
123 | -- throws a syntax error | ||
124 | ------------------------------------------------------------------------ | ||
125 | function luaY:syntaxerror(msg) | ||
126 | local tok = tok | ||
127 | if tok ~= "<number>" and tok ~= "<string>" then | ||
128 | if tok == "<name>" then tok = seminfo end | ||
129 | tok = "'"..tok.."'" | ||
130 | end | ||
131 | luaX:errorline(msg.." near "..tok) | ||
132 | end | ||
133 | -------------------------------------------------------------------- | ||
134 | -- throws a syntax error if token expected is not there | ||
135 | -------------------------------------------------------------------- | ||
136 | function luaY:error_expected(token) | ||
137 | self:syntaxerror("'"..token.."' expected") | ||
138 | end | ||
139 | |||
140 | -------------------------------------------------------------------- | ||
141 | -- verifies token conditions are met or else throw error | ||
142 | -------------------------------------------------------------------- | ||
143 | function luaY:check_match(what, who, where) | ||
144 | if not self:testnext(what) then | ||
145 | if where == luaX.ln then | ||
146 | self:error_expected(what) | ||
147 | else | ||
148 | self:syntaxerror("'"..what.."' expected (to close '"..who.."' at line "..where..")") | ||
149 | end | ||
150 | end | ||
151 | end | ||
152 | -------------------------------------------------------------------- | ||
153 | -- tests for a token, returns outcome | ||
154 | -- * return value changed to boolean | ||
155 | -------------------------------------------------------------------- | ||
156 | function luaY:testnext(c) | ||
157 | if tok == c then self:next(); return true end | ||
158 | end | ||
159 | -------------------------------------------------------------------- | ||
160 | -- throws error if condition not matched | ||
161 | -------------------------------------------------------------------- | ||
162 | function luaY:check_condition(c, msg) | ||
163 | if not c then self:syntaxerror(msg) end | ||
164 | end | ||
165 | -------------------------------------------------------------------- | ||
166 | -- check for existence of a token, throws error if not found | ||
167 | -------------------------------------------------------------------- | ||
168 | function luaY:check(c) | ||
169 | if not self:testnext(c) then self:error_expected(c) end | ||
170 | end | ||
171 | |||
172 | -------------------------------------------------------------------- | ||
173 | -- expect that token is a name, return the name | ||
174 | -------------------------------------------------------------------- | ||
175 | function luaY:str_checkname() | ||
176 | self:check_condition(tok == "<name>", "<name> expected") | ||
177 | local ts = seminfo | ||
178 | self:next() | ||
179 | self:log(" str_checkname: '"..ts.."'") | ||
180 | return ts | ||
181 | end | ||
182 | -------------------------------------------------------------------- | ||
183 | -- adds given string s in string pool, sets e as VK | ||
184 | -------------------------------------------------------------------- | ||
185 | function luaY:codestring(e, s) | ||
186 | e.k = "VK" | ||
187 | self:log(" codestring: "..string.format("%q", s)) | ||
188 | end | ||
189 | -------------------------------------------------------------------- | ||
190 | -- consume a name token, adds it to string pool | ||
191 | -------------------------------------------------------------------- | ||
192 | function luaY:checkname(e) | ||
193 | self:log(" checkname:") | ||
194 | self:codestring(e, self:str_checkname()) | ||
195 | end | ||
196 | |||
197 | --[[-------------------------------------------------------------------- | ||
198 | -- state management functions with open/close pairs | ||
199 | ----------------------------------------------------------------------]] | ||
200 | |||
201 | -------------------------------------------------------------------- | ||
202 | -- enters a code unit, initializes elements | ||
203 | -------------------------------------------------------------------- | ||
204 | function luaY:enterblock(isbreakable) | ||
205 | local bl = {} -- per-block state | ||
206 | bl.isbreakable = isbreakable | ||
207 | bl.prev = fs.bl | ||
208 | fs.bl = bl | ||
209 | self:log(">> enterblock(isbreakable="..tostring(isbreakable)..")") | ||
210 | end | ||
211 | -------------------------------------------------------------------- | ||
212 | -- leaves a code unit, close any upvalues | ||
213 | -------------------------------------------------------------------- | ||
214 | function luaY:leaveblock() | ||
215 | local bl = fs.bl | ||
216 | fs.bl = bl.prev | ||
217 | self:log("<< leaveblock") | ||
218 | end | ||
219 | -------------------------------------------------------------------- | ||
220 | -- opening of a function | ||
221 | -------------------------------------------------------------------- | ||
222 | function luaY:open_func() | ||
223 | local new_fs -- per-function state | ||
224 | if not fs then -- top_fs is created early | ||
225 | new_fs = top_fs | ||
226 | else | ||
227 | new_fs = {} | ||
228 | end | ||
229 | new_fs.prev = fs -- linked list of function states | ||
230 | new_fs.bl = nil | ||
231 | fs = new_fs | ||
232 | self:log(">> open_func") | ||
233 | end | ||
234 | -------------------------------------------------------------------- | ||
235 | -- closing of a function | ||
236 | -------------------------------------------------------------------- | ||
237 | function luaY:close_func() | ||
238 | fs = fs.prev | ||
239 | self:log("<< close_func") | ||
240 | end | ||
241 | |||
242 | --[[-------------------------------------------------------------------- | ||
243 | -- variable (global|local|upvalue) handling | ||
244 | -- * does nothing for now, always returns "VLOCAL" | ||
245 | ----------------------------------------------------------------------]] | ||
246 | |||
247 | -------------------------------------------------------------------- | ||
248 | -- consume a name token, creates a variable (global|local|upvalue) | ||
249 | -- * used in prefixexp(), funcname() | ||
250 | -------------------------------------------------------------------- | ||
251 | function luaY:singlevar(v) | ||
252 | local varname = self:str_checkname() | ||
253 | v.k = "VLOCAL" | ||
254 | self:log(" singlevar: name='"..varname.."'") | ||
255 | end | ||
256 | |||
257 | --[[-------------------------------------------------------------------- | ||
258 | -- other parsing functions | ||
259 | -- * for table constructor, parameter list, argument list | ||
260 | ----------------------------------------------------------------------]] | ||
261 | |||
262 | -------------------------------------------------------------------- | ||
263 | -- parse a function name suffix, for function call specifications | ||
264 | -- * used in primaryexp(), funcname() | ||
265 | -------------------------------------------------------------------- | ||
266 | function luaY:field(v) | ||
267 | -- field -> ['.' | ':'] NAME | ||
268 | local key = {} | ||
269 | self:log(" field: operator="..tok) | ||
270 | self:next() -- skip the dot or colon | ||
271 | self:checkname(key) | ||
272 | v.k = "VINDEXED" | ||
273 | end | ||
274 | -------------------------------------------------------------------- | ||
275 | -- parse a table indexing suffix, for constructors, expressions | ||
276 | -- * used in recfield(), primaryexp() | ||
277 | -------------------------------------------------------------------- | ||
278 | function luaY:index(v) | ||
279 | -- index -> '[' expr ']' | ||
280 | self:log(">> index: begin '['") | ||
281 | self:next() -- skip the '[' | ||
282 | self:expr(v) | ||
283 | self:check("]") | ||
284 | self:log("<< index: end ']'") | ||
285 | end | ||
286 | -------------------------------------------------------------------- | ||
287 | -- parse a table record (hash) field | ||
288 | -- * used in constructor() | ||
289 | -------------------------------------------------------------------- | ||
290 | function luaY:recfield(cc) | ||
291 | -- recfield -> (NAME | '['exp1']') = exp1 | ||
292 | local key, val = {}, {} | ||
293 | if tok == "<name>" then | ||
294 | self:log("recfield: name") | ||
295 | self:checkname(key) | ||
296 | else-- tok == '[' | ||
297 | self:log("recfield: [ exp1 ]") | ||
298 | self:index(key) | ||
299 | end | ||
300 | self:check("=") | ||
301 | self:expr(val) | ||
302 | end | ||
303 | -------------------------------------------------------------------- | ||
304 | -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) | ||
305 | -- * note: retained in this skeleton because it modifies cc.v.k | ||
306 | -- * used in constructor() | ||
307 | -------------------------------------------------------------------- | ||
308 | function luaY:closelistfield(cc) | ||
309 | if cc.v.k == "VVOID" then return end -- there is no list item | ||
310 | cc.v.k = "VVOID" | ||
311 | end | ||
312 | -------------------------------------------------------------------- | ||
313 | -- parse a table list (array) field | ||
314 | -- * used in constructor() | ||
315 | -------------------------------------------------------------------- | ||
316 | function luaY:listfield(cc) | ||
317 | self:log("listfield: expr") | ||
318 | self:expr(cc.v) | ||
319 | end | ||
320 | -------------------------------------------------------------------- | ||
321 | -- parse a table constructor | ||
322 | -- * used in funcargs(), simpleexp() | ||
323 | -------------------------------------------------------------------- | ||
324 | function luaY:constructor(t) | ||
325 | -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' | ||
326 | -- field -> recfield | listfield | ||
327 | -- fieldsep -> ',' | ';' | ||
328 | self:log(">> constructor: begin") | ||
329 | local line = luaX.ln | ||
330 | local cc = {} | ||
331 | cc.v = {} | ||
332 | cc.t = t | ||
333 | t.k = "VRELOCABLE" | ||
334 | cc.v.k = "VVOID" | ||
335 | self:check("{") | ||
336 | repeat | ||
337 | self:testnext(";") -- compatibility only | ||
338 | if tok == "}" then break end | ||
339 | -- closelistfield(cc) here | ||
340 | local c = tok | ||
341 | if c == "<name>" then -- may be listfields or recfields | ||
342 | if self:lookahead() ~= "=" then -- look ahead: expression? | ||
343 | self:listfield(cc) | ||
344 | else | ||
345 | self:recfield(cc) | ||
346 | end | ||
347 | elseif c == "[" then -- constructor_item -> recfield | ||
348 | self:recfield(cc) | ||
349 | else -- constructor_part -> listfield | ||
350 | self:listfield(cc) | ||
351 | end | ||
352 | until not self:testnext(",") and not self:testnext(";") | ||
353 | self:check_match("}", "{", line) | ||
354 | -- lastlistfield(cc) here | ||
355 | self:log("<< constructor: end") | ||
356 | end | ||
357 | -------------------------------------------------------------------- | ||
358 | -- parse the arguments (parameters) of a function declaration | ||
359 | -- * used in body() | ||
360 | -------------------------------------------------------------------- | ||
361 | function luaY:parlist() | ||
362 | -- parlist -> [ param { ',' param } ] | ||
363 | self:log(">> parlist: begin") | ||
364 | local dots = false | ||
365 | if tok ~= ")" then -- is 'parlist' not empty? | ||
366 | repeat | ||
367 | local c = tok | ||
368 | if c == "..." then | ||
369 | self:log("parlist: ... (dots)") | ||
370 | dots = true | ||
371 | self:next() | ||
372 | elseif c == "<name>" then | ||
373 | local str = self:str_checkname() | ||
374 | else | ||
375 | self:syntaxerror("<name> or '...' expected") | ||
376 | end | ||
377 | until dots or not self:testnext(",") | ||
378 | end | ||
379 | self:log("<< parlist: end") | ||
380 | end | ||
381 | -------------------------------------------------------------------- | ||
382 | -- parse the parameters of a function call | ||
383 | -- * contrast with parlist(), used in function declarations | ||
384 | -- * used in primaryexp() | ||
385 | -------------------------------------------------------------------- | ||
386 | function luaY:funcargs(f) | ||
387 | local args = {} | ||
388 | local line = luaX.ln | ||
389 | local c = tok | ||
390 | if c == "(" then -- funcargs -> '(' [ explist1 ] ')' | ||
391 | self:log(">> funcargs: begin '('") | ||
392 | if line ~= lastln then | ||
393 | self:syntaxerror("ambiguous syntax (function call x new statement)") | ||
394 | end | ||
395 | self:next() | ||
396 | if tok == ")" then -- arg list is empty? | ||
397 | args.k = "VVOID" | ||
398 | else | ||
399 | self:explist1(args) | ||
400 | end | ||
401 | self:check_match(")", "(", line) | ||
402 | elseif c == "{" then -- funcargs -> constructor | ||
403 | self:log(">> funcargs: begin '{'") | ||
404 | self:constructor(args) | ||
405 | elseif c == "<string>" then -- funcargs -> STRING | ||
406 | self:log(">> funcargs: begin <string>") | ||
407 | self:codestring(args, seminfo) | ||
408 | self:next() -- must use 'seminfo' before 'next' | ||
409 | else | ||
410 | self:syntaxerror("function arguments expected") | ||
411 | return | ||
412 | end--if c | ||
413 | f.k = "VCALL" | ||
414 | self:log("<< funcargs: end -- expr is a VCALL") | ||
415 | end | ||
416 | |||
417 | --[[-------------------------------------------------------------------- | ||
418 | -- mostly expression functions | ||
419 | ----------------------------------------------------------------------]] | ||
420 | |||
421 | -------------------------------------------------------------------- | ||
422 | -- parses an expression in parentheses or a single variable | ||
423 | -- * used in primaryexp() | ||
424 | -------------------------------------------------------------------- | ||
425 | function luaY:prefixexp(v) | ||
426 | -- prefixexp -> NAME | '(' expr ')' | ||
427 | local c = tok | ||
428 | if c == "(" then | ||
429 | self:log(">> prefixexp: begin ( expr ) ") | ||
430 | local line = self.ln | ||
431 | self:next() | ||
432 | self:expr(v) | ||
433 | self:check_match(")", "(", line) | ||
434 | self:log("<< prefixexp: end ( expr ) ") | ||
435 | elseif c == "<name>" then | ||
436 | self:log("prefixexp: <name>") | ||
437 | self:singlevar(v) | ||
438 | else | ||
439 | self:syntaxerror("unexpected symbol") | ||
440 | end--if c | ||
441 | end | ||
442 | -------------------------------------------------------------------- | ||
443 | -- parses a prefixexp (an expression in parentheses or a single | ||
444 | -- variable) or a function call specification | ||
445 | -- * used in simpleexp(), assignment(), expr_stat() | ||
446 | -------------------------------------------------------------------- | ||
447 | function luaY:primaryexp(v) | ||
448 | -- primaryexp -> | ||
449 | -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } | ||
450 | self:prefixexp(v) | ||
451 | while true do | ||
452 | local c = tok | ||
453 | if c == "." then -- field | ||
454 | self:log("primaryexp: '.' field") | ||
455 | self:field(v) | ||
456 | elseif c == "[" then -- '[' exp1 ']' | ||
457 | self:log("primaryexp: [ exp1 ]") | ||
458 | local key = {} | ||
459 | self:index(key) | ||
460 | elseif c == ":" then -- ':' NAME funcargs | ||
461 | self:log("primaryexp: :<name> funcargs") | ||
462 | local key = {} | ||
463 | self:next() | ||
464 | self:checkname(key) | ||
465 | self:funcargs(v) | ||
466 | elseif c == "(" or c == "<string>" or c == "{" then -- funcargs | ||
467 | self:log("primaryexp: "..c.." funcargs") | ||
468 | self:funcargs(v) | ||
469 | else | ||
470 | return | ||
471 | end--if c | ||
472 | end--while | ||
473 | end | ||
474 | -------------------------------------------------------------------- | ||
475 | -- parses general expression types, constants handled here | ||
476 | -- * used in subexpr() | ||
477 | -------------------------------------------------------------------- | ||
478 | function luaY:simpleexp(v) | ||
479 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | constructor | ||
480 | -- | FUNCTION body | primaryexp | ||
481 | local c = tok | ||
482 | if c == "<number>" then | ||
483 | self:log("simpleexp: <number>="..seminfo) | ||
484 | v.k = "VK" | ||
485 | self:next() -- must use 'seminfo' before 'next' | ||
486 | elseif c == "<string>" then | ||
487 | self:log("simpleexp: <string>="..seminfo) | ||
488 | self:codestring(v, seminfo) | ||
489 | self:next() -- must use 'seminfo' before 'next' | ||
490 | elseif c == "nil" then | ||
491 | self:log("simpleexp: nil") | ||
492 | v.k = "VNIL" | ||
493 | self:next() | ||
494 | elseif c == "true" then | ||
495 | self:log("simpleexp: true") | ||
496 | v.k = "VTRUE" | ||
497 | self:next() | ||
498 | elseif c == "false" then | ||
499 | self:log("simpleexp: false") | ||
500 | v.k = "VFALSE" | ||
501 | self:next() | ||
502 | elseif c == "{" then -- constructor | ||
503 | self:log("simpleexp: constructor") | ||
504 | self:constructor(v) | ||
505 | elseif c == "function" then | ||
506 | self:log("simpleexp: function") | ||
507 | self:next() | ||
508 | self:body(v, false, luaX.ln) | ||
509 | else | ||
510 | self:primaryexp(v) | ||
511 | end--if c | ||
512 | end | ||
513 | ------------------------------------------------------------------------ | ||
514 | -- Parse subexpressions. Includes handling of unary operators and binary | ||
515 | -- operators. A subexpr is given the rhs priority level of the operator | ||
516 | -- immediately left of it, if any (limit is -1 if none,) and if a binop | ||
517 | -- is found, limit is compared with the lhs priority level of the binop | ||
518 | -- in order to determine which executes first. | ||
519 | -- * recursively called | ||
520 | -- * used in expr() | ||
521 | ------------------------------------------------------------------------ | ||
522 | function luaY:subexpr(v, limit) | ||
523 | -- subexpr -> (simpleexp | unop subexpr) { binop subexpr } | ||
524 | -- * where 'binop' is any binary operator with a priority | ||
525 | -- higher than 'limit' | ||
526 | local op = tok | ||
527 | local uop = unopr[op] | ||
528 | if uop then | ||
529 | self:log(" subexpr: uop='"..op.."'") | ||
530 | self:next() | ||
531 | self:subexpr(v, 8) -- UNARY_PRIORITY | ||
532 | else | ||
533 | self:simpleexp(v) | ||
534 | end | ||
535 | -- expand while operators have priorities higher than 'limit' | ||
536 | op = tok | ||
537 | local binop = binopr_left[op] | ||
538 | while binop and binop > limit do | ||
539 | local v2 = {} | ||
540 | self:log(">> subexpr: binop='"..op.."'") | ||
541 | self:next() | ||
542 | -- read sub-expression with higher priority | ||
543 | local nextop = self:subexpr(v2, binopr_right[op]) | ||
544 | self:log("<< subexpr: -- evaluate") | ||
545 | op = nextop | ||
546 | binop = binopr_left[op] | ||
547 | end | ||
548 | return op -- return first untreated operator | ||
549 | end | ||
550 | -------------------------------------------------------------------- | ||
551 | -- Expression parsing starts here. Function subexpr is entered with the | ||
552 | -- left operator (which is non-existent) priority of -1, which is lower | ||
553 | -- than all actual operators. Expr information is returned in parm v. | ||
554 | -- * used in cond(), explist1(), index(), recfield(), listfield(), | ||
555 | -- prefixexp(), while_stat(), exp1() | ||
556 | -------------------------------------------------------------------- | ||
557 | function luaY:expr(v) | ||
558 | -- expr -> subexpr | ||
559 | self:log("expr:") | ||
560 | self:subexpr(v, -1) | ||
561 | end | ||
562 | |||
563 | --[[-------------------------------------------------------------------- | ||
564 | -- third level parsing functions | ||
565 | ----------------------------------------------------------------------]] | ||
566 | |||
567 | -------------------------------------------------------------------- | ||
568 | -- parse a variable assignment sequence | ||
569 | -- * recursively called | ||
570 | -- * used in expr_stat() | ||
571 | -------------------------------------------------------------------- | ||
572 | function luaY:assignment(v) | ||
573 | local e = {} | ||
574 | local c = v.v.k | ||
575 | self:check_condition(c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" | ||
576 | or c == "VINDEXED", "syntax error") | ||
577 | if self:testnext(",") then -- assignment -> ',' primaryexp assignment | ||
578 | local nv = {} -- expdesc | ||
579 | nv.v = {} | ||
580 | self:log("assignment: ',' -- next LHS element") | ||
581 | self:primaryexp(nv.v) | ||
582 | -- lparser.c deals with some register usage conflict here | ||
583 | self:assignment(nv) | ||
584 | else -- assignment -> '=' explist1 | ||
585 | self:check("=") | ||
586 | self:log("assignment: '=' -- RHS elements follows") | ||
587 | self:explist1(e) | ||
588 | return -- avoid default | ||
589 | end | ||
590 | e.k = "VNONRELOC" | ||
591 | end | ||
592 | -------------------------------------------------------------------- | ||
593 | -- parse a for loop body for both versions of the for loop | ||
594 | -- * used in fornum(), forlist() | ||
595 | -------------------------------------------------------------------- | ||
596 | function luaY:forbody(line, isnum) | ||
597 | self:check("do") | ||
598 | self:enterblock(true) -- loop block | ||
599 | self:block() | ||
600 | self:leaveblock() | ||
601 | end | ||
602 | -------------------------------------------------------------------- | ||
603 | -- parse a numerical for loop, calls forbody() | ||
604 | -- * used in for_stat() | ||
605 | -------------------------------------------------------------------- | ||
606 | function luaY:fornum(line) | ||
607 | -- fornum -> NAME = exp1, exp1 [, exp1] DO body | ||
608 | self:log(">> fornum: begin") | ||
609 | self:check("=") | ||
610 | self:log("fornum: index start") | ||
611 | self:exp1() -- initial value | ||
612 | self:check(",") | ||
613 | self:log("fornum: index stop") | ||
614 | self:exp1() -- limit | ||
615 | if self:testnext(",") then | ||
616 | self:log("fornum: index step") | ||
617 | self:exp1() -- optional step | ||
618 | else | ||
619 | -- default step = 1 | ||
620 | end | ||
621 | self:log("fornum: body") | ||
622 | self:forbody(line, true) | ||
623 | self:log("<< fornum: end") | ||
624 | end | ||
625 | -------------------------------------------------------------------- | ||
626 | -- parse a generic for loop, calls forbody() | ||
627 | -- * used in for_stat() | ||
628 | -------------------------------------------------------------------- | ||
629 | function luaY:forlist() | ||
630 | -- forlist -> NAME {, NAME} IN explist1 DO body | ||
631 | self:log(">> forlist: begin") | ||
632 | local e = {} | ||
633 | while self:testnext(",") do | ||
634 | self:str_checkname() | ||
635 | end | ||
636 | self:check("in") | ||
637 | local line = line | ||
638 | self:log("forlist: explist1") | ||
639 | self:explist1(e) | ||
640 | self:log("forlist: body") | ||
641 | self:forbody(line, false) | ||
642 | self:log("<< forlist: end") | ||
643 | end | ||
644 | -------------------------------------------------------------------- | ||
645 | -- parse a function name specification | ||
646 | -- * used in func_stat() | ||
647 | -------------------------------------------------------------------- | ||
648 | function luaY:funcname(v) | ||
649 | -- funcname -> NAME {field} [':' NAME] | ||
650 | self:log(">> funcname: begin") | ||
651 | local needself = false | ||
652 | self:singlevar(v) | ||
653 | while tok == "." do | ||
654 | self:log("funcname: -- '.' field") | ||
655 | self:field(v) | ||
656 | end | ||
657 | if tok == ":" then | ||
658 | self:log("funcname: -- ':' field") | ||
659 | needself = true | ||
660 | self:field(v) | ||
661 | end | ||
662 | self:log("<< funcname: end") | ||
663 | return needself | ||
664 | end | ||
665 | -------------------------------------------------------------------- | ||
666 | -- parse the single expressions needed in numerical for loops | ||
667 | -- * used in fornum() | ||
668 | -------------------------------------------------------------------- | ||
669 | function luaY:exp1() | ||
670 | -- exp1 -> expr | ||
671 | local e = {} | ||
672 | self:log(">> exp1: begin") | ||
673 | self:expr(e) | ||
674 | self:log("<< exp1: end") | ||
675 | end | ||
676 | -------------------------------------------------------------------- | ||
677 | -- parse condition in a repeat statement or an if control structure | ||
678 | -- * used in repeat_stat(), test_then_block() | ||
679 | -------------------------------------------------------------------- | ||
680 | function luaY:cond(v) | ||
681 | -- cond -> expr | ||
682 | self:log(">> cond: begin") | ||
683 | self:expr(v) -- read condition | ||
684 | self:log("<< cond: end") | ||
685 | end | ||
686 | -------------------------------------------------------------------- | ||
687 | -- parse part of an if control structure, including the condition | ||
688 | -- * used in if_stat() | ||
689 | -------------------------------------------------------------------- | ||
690 | function luaY:test_then_block(v) | ||
691 | -- test_then_block -> [IF | ELSEIF] cond THEN block | ||
692 | self:next() -- skip IF or ELSEIF | ||
693 | self:log("test_then_block: test condition") | ||
694 | self:cond(v) | ||
695 | self:check("then") | ||
696 | self:log("test_then_block: then block") | ||
697 | self:block() -- 'then' part | ||
698 | end | ||
699 | -------------------------------------------------------------------- | ||
700 | -- parse a local function statement | ||
701 | -- * used in local_stat() | ||
702 | -------------------------------------------------------------------- | ||
703 | function luaY:localfunc() | ||
704 | -- localfunc -> NAME body | ||
705 | local v, b = {} | ||
706 | self:log("localfunc: begin") | ||
707 | local str = self:str_checkname() | ||
708 | v.k = "VLOCAL" | ||
709 | self:log("localfunc: body") | ||
710 | self:body(b, false, luaX.ln) | ||
711 | self:log("localfunc: end") | ||
712 | end | ||
713 | -------------------------------------------------------------------- | ||
714 | -- parse a local variable declaration statement | ||
715 | -- * used in local_stat() | ||
716 | -------------------------------------------------------------------- | ||
717 | function luaY:localstat() | ||
718 | -- localstat -> NAME {',' NAME} ['=' explist1] | ||
719 | self:log(">> localstat: begin") | ||
720 | local e = {} | ||
721 | repeat | ||
722 | local str = self:str_checkname() | ||
723 | until not self:testnext(",") | ||
724 | if self:testnext("=") then | ||
725 | self:log("localstat: -- assignment") | ||
726 | self:explist1(e) | ||
727 | else | ||
728 | e.k = "VVOID" | ||
729 | end | ||
730 | self:log("<< localstat: end") | ||
731 | end | ||
732 | -------------------------------------------------------------------- | ||
733 | -- parse a list of comma-separated expressions | ||
734 | -- * used in return_stat(), localstat(), funcargs(), assignment(), | ||
735 | -- forlist() | ||
736 | -------------------------------------------------------------------- | ||
737 | function luaY:explist1(e) | ||
738 | -- explist1 -> expr { ',' expr } | ||
739 | self:log(">> explist1: begin") | ||
740 | self:expr(e) | ||
741 | while self:testnext(",") do | ||
742 | self:log("explist1: ',' -- continuation") | ||
743 | self:expr(e) | ||
744 | end | ||
745 | self:log("<< explist1: end") | ||
746 | end | ||
747 | -------------------------------------------------------------------- | ||
748 | -- parse function declaration body | ||
749 | -- * used in simpleexp(), localfunc(), func_stat() | ||
750 | -------------------------------------------------------------------- | ||
751 | function luaY:body(e, needself, line) | ||
752 | -- body -> '(' parlist ')' chunk END | ||
753 | self:open_func() | ||
754 | self:log("body: begin") | ||
755 | self:check("(") | ||
756 | if needself then | ||
757 | -- handle 'self' processing here | ||
758 | end | ||
759 | self:log("body: parlist") | ||
760 | self:parlist() | ||
761 | self:check(")") | ||
762 | self:log("body: chunk") | ||
763 | self:chunk() | ||
764 | self:check_match("end", "function", line) | ||
765 | self:log("body: end") | ||
766 | self:close_func() | ||
767 | end | ||
768 | -------------------------------------------------------------------- | ||
769 | -- parse a code block or unit | ||
770 | -- * used in do_stat(), while_stat(), repeat_stat(), forbody(), | ||
771 | -- test_then_block(), if_stat() | ||
772 | -------------------------------------------------------------------- | ||
773 | function luaY:block() | ||
774 | -- block -> chunk | ||
775 | self:log("block: begin") | ||
776 | self:enterblock(false) | ||
777 | self:chunk() | ||
778 | self:leaveblock() | ||
779 | self:log("block: end") | ||
780 | end | ||
781 | |||
782 | --[[-------------------------------------------------------------------- | ||
783 | -- second level parsing functions, all with '_stat' suffix | ||
784 | -- * stat() -> *_stat() | ||
785 | ----------------------------------------------------------------------]] | ||
786 | |||
787 | -------------------------------------------------------------------- | ||
788 | -- initial parsing for a for loop, calls fornum() or forlist() | ||
789 | -- * used in stat() | ||
790 | -------------------------------------------------------------------- | ||
791 | function luaY:for_stat() | ||
792 | -- stat -> for_stat -> fornum | forlist | ||
793 | local line = line | ||
794 | self:log("for_stat: begin") | ||
795 | self:enterblock(false) -- block to control variable scope | ||
796 | self:next() -- skip 'for' | ||
797 | local str = self:str_checkname() -- first variable name | ||
798 | local c = tok | ||
799 | if c == "=" then | ||
800 | self:log("for_stat: numerical loop") | ||
801 | self:fornum(line) | ||
802 | elseif c == "," or c == "in" then | ||
803 | self:log("for_stat: list-based loop") | ||
804 | self:forlist() | ||
805 | else | ||
806 | self:syntaxerror("'=' or 'in' expected") | ||
807 | end | ||
808 | self:check_match("end", "for", line) | ||
809 | self:leaveblock() | ||
810 | self:log("for_stat: end") | ||
811 | end | ||
812 | -------------------------------------------------------------------- | ||
813 | -- parse a while-do control structure, body processed by block() | ||
814 | -- * used in stat() | ||
815 | -------------------------------------------------------------------- | ||
816 | function luaY:while_stat() | ||
817 | -- stat -> while_stat -> WHILE cond DO block END | ||
818 | local line = line | ||
819 | local v = {} | ||
820 | self:next() -- skip WHILE | ||
821 | self:log("while_stat: begin/condition") | ||
822 | self:expr(v) -- parse condition | ||
823 | self:enterblock(true) | ||
824 | self:check("do") | ||
825 | self:log("while_stat: block") | ||
826 | self:block() | ||
827 | self:check_match("end", "while", line) | ||
828 | self:leaveblock() | ||
829 | self:log("while_stat: end") | ||
830 | end | ||
831 | -------------------------------------------------------------------- | ||
832 | -- parse a repeat-until control structure, body parsed by block() | ||
833 | -- * used in stat() | ||
834 | -------------------------------------------------------------------- | ||
835 | function luaY:repeat_stat() | ||
836 | -- stat -> repeat_stat -> REPEAT block UNTIL cond | ||
837 | local line = line | ||
838 | local v = {} | ||
839 | self:log("repeat_stat: begin") | ||
840 | self:enterblock(true) | ||
841 | self:next() | ||
842 | self:block() | ||
843 | self:check_match("until", "repeat", line) | ||
844 | self:log("repeat_stat: condition") | ||
845 | self:cond(v) | ||
846 | self:leaveblock() | ||
847 | self:log("repeat_stat: end") | ||
848 | end | ||
849 | -------------------------------------------------------------------- | ||
850 | -- parse an if control structure | ||
851 | -- * used in stat() | ||
852 | -------------------------------------------------------------------- | ||
853 | function luaY:if_stat() | ||
854 | -- stat -> if_stat -> IF cond THEN block | ||
855 | -- {ELSEIF cond THEN block} [ELSE block] END | ||
856 | local line = line | ||
857 | local v = {} | ||
858 | self:log("if_stat: if...then") | ||
859 | self:test_then_block(v) -- IF cond THEN block | ||
860 | while tok == "elseif" do | ||
861 | self:log("if_stat: elseif...then") | ||
862 | self:test_then_block(v) -- ELSEIF cond THEN block | ||
863 | end | ||
864 | if tok == "else" then | ||
865 | self:log("if_stat: else...") | ||
866 | self:next() -- skip ELSE | ||
867 | self:block() -- 'else' part | ||
868 | end | ||
869 | self:check_match("end", "if", line) | ||
870 | self:log("if_stat: end") | ||
871 | end | ||
872 | -------------------------------------------------------------------- | ||
873 | -- parse a return statement | ||
874 | -- * used in stat() | ||
875 | -------------------------------------------------------------------- | ||
876 | function luaY:return_stat() | ||
877 | -- stat -> return_stat -> RETURN explist | ||
878 | local e = {} | ||
879 | self:next() -- skip RETURN | ||
880 | local c = tok | ||
881 | if block_follow[c] or c == ";" then | ||
882 | -- return no values | ||
883 | self:log("return_stat: no return values") | ||
884 | else | ||
885 | self:log("return_stat: begin") | ||
886 | self:explist1(e) -- optional return values | ||
887 | self:log("return_stat: end") | ||
888 | end | ||
889 | end | ||
890 | -------------------------------------------------------------------- | ||
891 | -- parse a break statement | ||
892 | -- * used in stat() | ||
893 | -------------------------------------------------------------------- | ||
894 | function luaY:break_stat() | ||
895 | -- stat -> break_stat -> BREAK | ||
896 | local bl = fs.bl | ||
897 | self:next() -- skip BREAK | ||
898 | while bl and not bl.isbreakable do -- find a breakable block | ||
899 | bl = bl.prev | ||
900 | end | ||
901 | if not bl then | ||
902 | self:syntaxerror("no loop to break") | ||
903 | end | ||
904 | self:log("break_stat: -- break out of loop") | ||
905 | end | ||
906 | -------------------------------------------------------------------- | ||
907 | -- parse a function call with no returns or an assignment statement | ||
908 | -- * the struct with .prev is used for name searching in lparse.c, | ||
909 | -- so it is retained for now; present in assignment() also | ||
910 | -- * used in stat() | ||
911 | -------------------------------------------------------------------- | ||
912 | function luaY:expr_stat() | ||
913 | -- stat -> expr_stat -> func | assignment | ||
914 | local v = {} | ||
915 | v.v = {} | ||
916 | self:primaryexp(v.v) | ||
917 | if v.v.k == "VCALL" then -- stat -> func | ||
918 | -- call statement uses no results | ||
919 | self:log("expr_stat: function call k='"..v.v.k.."'") | ||
920 | else -- stat -> assignment | ||
921 | self:log("expr_stat: assignment k='"..v.v.k.."'") | ||
922 | v.prev = nil | ||
923 | self:assignment(v) | ||
924 | end | ||
925 | end | ||
926 | -------------------------------------------------------------------- | ||
927 | -- parse a function statement | ||
928 | -- * used in stat() | ||
929 | -------------------------------------------------------------------- | ||
930 | function luaY:function_stat() | ||
931 | -- stat -> function_stat -> FUNCTION funcname body | ||
932 | local line = line | ||
933 | local v, b = {}, {} | ||
934 | self:log("function_stat: begin") | ||
935 | self:next() -- skip FUNCTION | ||
936 | local needself = self:funcname(v) | ||
937 | self:log("function_stat: body needself='"..tostring(needself).."'") | ||
938 | self:body(b, needself, line) | ||
939 | self:log("function_stat: end") | ||
940 | end | ||
941 | -------------------------------------------------------------------- | ||
942 | -- parse a simple block enclosed by a DO..END pair | ||
943 | -- * used in stat() | ||
944 | -------------------------------------------------------------------- | ||
945 | function luaY:do_stat() | ||
946 | -- stat -> do_stat -> DO block END | ||
947 | self:next() -- skip DO | ||
948 | self:log("do_stat: begin") | ||
949 | self:block() | ||
950 | self:log("do_stat: end") | ||
951 | self:check_match("end", "do", line) | ||
952 | end | ||
953 | -------------------------------------------------------------------- | ||
954 | -- parse a statement starting with LOCAL | ||
955 | -- * used in stat() | ||
956 | -------------------------------------------------------------------- | ||
957 | function luaY:local_stat() | ||
958 | -- stat -> local_stat -> LOCAL FUNCTION localfunc | ||
959 | -- -> LOCAL localstat | ||
960 | self:next() -- skip LOCAL | ||
961 | if self:testnext("function") then -- local function? | ||
962 | self:log("local_stat: local function") | ||
963 | self:localfunc() | ||
964 | else | ||
965 | self:log("local_stat: local statement") | ||
966 | self:localstat() | ||
967 | end | ||
968 | end | ||
969 | |||
970 | --[[-------------------------------------------------------------------- | ||
971 | -- main function, top level parsing functions | ||
972 | -- * [entry] -> parser() -> chunk() -> stat() | ||
973 | ----------------------------------------------------------------------]] | ||
974 | |||
975 | -------------------------------------------------------------------- | ||
976 | -- initial parsing for statements, calls '_stat' suffixed functions | ||
977 | -- * used in chunk() | ||
978 | -------------------------------------------------------------------- | ||
979 | function luaY:stat() | ||
980 | line = luaX.ln | ||
981 | local c = tok | ||
982 | local fn = stat_call[c] | ||
983 | -- handles: if while do for repeat function local return break | ||
984 | if fn then | ||
985 | self:log("-- STATEMENT: begin '"..c.."' line="..line) | ||
986 | self[fn](self) | ||
987 | self:log("-- STATEMENT: end '"..c.."'") | ||
988 | -- return or break must be last statement | ||
989 | if c == "return" or c == "break" then return true end | ||
990 | else | ||
991 | self:log("-- STATEMENT: begin 'expr' line="..line) | ||
992 | self:expr_stat() | ||
993 | self:log("-- STATEMENT: end 'expr'") | ||
994 | end | ||
995 | self:log("") | ||
996 | return false | ||
997 | end | ||
998 | -------------------------------------------------------------------- | ||
999 | -- parse a chunk, which consists of a bunch of statements | ||
1000 | -- * used in parser(), body(), block() | ||
1001 | -------------------------------------------------------------------- | ||
1002 | function luaY:chunk() | ||
1003 | -- chunk -> { stat [';'] } | ||
1004 | self:log("chunk:") | ||
1005 | local islast = false | ||
1006 | while not islast and not block_follow[tok] do | ||
1007 | islast = self:stat() | ||
1008 | self:testnext(";") | ||
1009 | end | ||
1010 | end | ||
1011 | -------------------------------------------------------------------- | ||
1012 | -- performs parsing, returns parsed data structure | ||
1013 | -------------------------------------------------------------------- | ||
1014 | function luaY:parser() | ||
1015 | self:log("-- TOP: begin") | ||
1016 | self:open_func() | ||
1017 | self:log("") | ||
1018 | self:next() -- read first token | ||
1019 | self:chunk() | ||
1020 | self:check_condition(tok == "<eof>", "<eof> expected") | ||
1021 | self:close_func() | ||
1022 | self:log("-- TOP: end") | ||
1023 | return top_fs | ||
1024 | end | ||
1025 | -------------------------------------------------------------------- | ||
1026 | return luaY -- return actual module to user, done | ||
1027 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lparser.lua | ||
4 | Lua 5 parser in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * this is a Lua 5.0.x parser skeleton, for llex_mk3.lua lexer | ||
18 | -- * written as a module factory with recognizable lparser.c roots | ||
19 | -- * builds some data, performs logging for educational purposes | ||
20 | -- * target is to have relatively efficient and clear code | ||
21 | -- * needs one parameter, a lexer module that implements: | ||
22 | -- luaX:lex() - returns appropriate [token, semantic info] pairs | ||
23 | -- luaX.ln - current line number | ||
24 | -- luaX:errorline(s, [line]) - dies with error message | ||
25 | -- | ||
26 | -- Usage example: | ||
27 | -- lex_init = require("llex_mk3.lua") | ||
28 | -- parser_init = require("lparser_mk3.lua") | ||
29 | -- local luaX = lex_init(chunk, "=string") | ||
30 | -- local luaY = parser_init(luaX) | ||
31 | -- local fs = luaY:parser() | ||
32 | -- | ||
33 | -- Development notes: | ||
34 | -- * see test_parser-5.0.lua for grammar elements based on lparser.c | ||
35 | -- * lparser has a few extra items to help parsing/syntax checking | ||
36 | -- (a) line number (error reporting), lookahead token storage | ||
37 | -- (b) per-prototype states needs a storage list | ||
38 | -- (c) 'break' needs a per-block flag in a stack | ||
39 | -- (d) 'kind' (v.k) testing needed in expr_stat() and assignment() | ||
40 | -- for disambiguation, thus v.k manipulation is retained | ||
41 | -- (e) one line # var (lastln) for ambiguous (split line) function | ||
42 | -- call checking | ||
43 | -- (f) most line number function call args retained for future use | ||
44 | -- (g) Lua 4 compatibility code completely removed | ||
45 | -- (h) minimal variable management code to differentiate each type | ||
46 | -- * parsing starts from the end of this file in luaY:parser() | ||
47 | -- | ||
48 | ----------------------------------------------------------------------]] | ||
49 | |||
50 | return | ||
51 | function(luaX) | ||
52 | --[[-------------------------------------------------------------------- | ||
53 | -- structures and data initialization | ||
54 | ----------------------------------------------------------------------]] | ||
55 | |||
56 | local line -- start line # for error messages | ||
57 | local lastln -- last line # for ambiguous syntax chk | ||
58 | local tok, seminfo -- token, semantic info pair | ||
59 | local peek_tok, peek_sem -- ditto, for lookahead | ||
60 | local fs -- function state | ||
61 | local top_fs = {} -- top-level function state | ||
62 | local luaY = {} | ||
63 | -------------------------------------------------------------------- | ||
64 | local block_follow = {} -- lookahead check in chunk(), returnstat() | ||
65 | for v in string.gfind("else elseif end until <eof>", "%S+") do | ||
66 | block_follow[v] = true | ||
67 | end | ||
68 | -------------------------------------------------------------------- | ||
69 | local stat_call = {} -- lookup for calls in stat() | ||
70 | for v in string.gfind("if while do for repeat function local return break", "%S+") do | ||
71 | stat_call[v] = v.."_stat" | ||
72 | end | ||
73 | -------------------------------------------------------------------- | ||
74 | local binopr_left = {} -- binary operators, left priority | ||
75 | local binopr_right = {} -- binary operators, right priority | ||
76 | for op, lt, rt in string.gfind([[ | ||
77 | {+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{^ 10 9}{.. 5 4} | ||
78 | {~= 3 3}{== 3 3}{< 3 3}{<= 3 3}{> 3 3}{>= 3 3} | ||
79 | {and 2 2}{or 1 1} | ||
80 | ]], "{(%S+)%s(%d+)%s(%d+)}") do | ||
81 | binopr_left[op] = lt + 0 | ||
82 | binopr_right[op] = rt + 0 | ||
83 | end | ||
84 | local unopr = { ["not"] = true, ["-"] = true, } -- unary operators | ||
85 | |||
86 | --[[-------------------------------------------------------------------- | ||
87 | -- logging: this logging function is for educational purposes | ||
88 | -- * logged data can be retrieved from the returned data structure | ||
89 | -- * or, replace self:log() instances with your custom code... | ||
90 | ----------------------------------------------------------------------]] | ||
91 | |||
92 | function luaY:log(msg) | ||
93 | local log = top_fs.log | ||
94 | if not log then log = {}; top_fs.log = log end | ||
95 | table.insert(top_fs.log, msg) | ||
96 | end | ||
97 | |||
98 | --[[-------------------------------------------------------------------- | ||
99 | -- support functions | ||
100 | ----------------------------------------------------------------------]] | ||
101 | |||
102 | -------------------------------------------------------------------- | ||
103 | -- reads in next token | ||
104 | -------------------------------------------------------------------- | ||
105 | function luaY:next() | ||
106 | lastln = luaX.ln | ||
107 | if peek_tok then -- is there a look-ahead token? if yes, use it | ||
108 | tok, seminfo = peek_tok, peek_sem | ||
109 | peek_tok = nil | ||
110 | else | ||
111 | tok, seminfo = luaX:lex() -- read next token | ||
112 | end | ||
113 | end | ||
114 | -------------------------------------------------------------------- | ||
115 | -- peek at next token (single lookahead for table constructor) | ||
116 | -------------------------------------------------------------------- | ||
117 | function luaY:lookahead() | ||
118 | peek_tok, peek_sem = luaX:lex() | ||
119 | return peek_tok | ||
120 | end | ||
121 | |||
122 | ------------------------------------------------------------------------ | ||
123 | -- throws a syntax error | ||
124 | ------------------------------------------------------------------------ | ||
125 | function luaY:syntaxerror(msg) | ||
126 | local tok = tok | ||
127 | if tok ~= "<number>" and tok ~= "<string>" then | ||
128 | if tok == "<name>" then tok = seminfo end | ||
129 | tok = "'"..tok.."'" | ||
130 | end | ||
131 | luaX:errorline(msg.." near "..tok) | ||
132 | end | ||
133 | -------------------------------------------------------------------- | ||
134 | -- throws a syntax error if token expected is not there | ||
135 | -------------------------------------------------------------------- | ||
136 | function luaY:error_expected(token) | ||
137 | self:syntaxerror("'"..token.."' expected") | ||
138 | end | ||
139 | |||
140 | -------------------------------------------------------------------- | ||
141 | -- verifies token conditions are met or else throw error | ||
142 | -------------------------------------------------------------------- | ||
143 | function luaY:check_match(what, who, where) | ||
144 | if not self:testnext(what) then | ||
145 | if where == luaX.ln then | ||
146 | self:error_expected(what) | ||
147 | else | ||
148 | self:syntaxerror("'"..what.."' expected (to close '"..who.."' at line "..where..")") | ||
149 | end | ||
150 | end | ||
151 | end | ||
152 | -------------------------------------------------------------------- | ||
153 | -- tests for a token, returns outcome | ||
154 | -- * return value changed to boolean | ||
155 | -------------------------------------------------------------------- | ||
156 | function luaY:testnext(c) | ||
157 | if tok == c then self:next(); return true end | ||
158 | end | ||
159 | -------------------------------------------------------------------- | ||
160 | -- throws error if condition not matched | ||
161 | -------------------------------------------------------------------- | ||
162 | function luaY:check_condition(c, msg) | ||
163 | if not c then self:syntaxerror(msg) end | ||
164 | end | ||
165 | -------------------------------------------------------------------- | ||
166 | -- check for existence of a token, throws error if not found | ||
167 | -------------------------------------------------------------------- | ||
168 | function luaY:check(c) | ||
169 | if not self:testnext(c) then self:error_expected(c) end | ||
170 | end | ||
171 | |||
172 | -------------------------------------------------------------------- | ||
173 | -- expect that token is a name, return the name | ||
174 | -------------------------------------------------------------------- | ||
175 | function luaY:str_checkname() | ||
176 | self:check_condition(tok == "<name>", "<name> expected") | ||
177 | local ts = seminfo | ||
178 | self:next() | ||
179 | self:log(" str_checkname: '"..ts.."'") | ||
180 | return ts | ||
181 | end | ||
182 | -------------------------------------------------------------------- | ||
183 | -- adds given string s in string pool, sets e as VK | ||
184 | -------------------------------------------------------------------- | ||
185 | function luaY:codestring(e, s) | ||
186 | e.k = "VK" | ||
187 | self:log(" codestring: "..string.format("%q", s)) | ||
188 | end | ||
189 | -------------------------------------------------------------------- | ||
190 | -- consume a name token, adds it to string pool | ||
191 | -------------------------------------------------------------------- | ||
192 | function luaY:checkname(e) | ||
193 | self:log(" checkname:") | ||
194 | self:codestring(e, self:str_checkname()) | ||
195 | end | ||
196 | |||
197 | --[[-------------------------------------------------------------------- | ||
198 | -- state management functions with open/close pairs | ||
199 | ----------------------------------------------------------------------]] | ||
200 | |||
201 | -------------------------------------------------------------------- | ||
202 | -- enters a code unit, initializes elements | ||
203 | -------------------------------------------------------------------- | ||
204 | function luaY:enterblock(isbreakable) | ||
205 | local bl = {} -- per-block state | ||
206 | bl.isbreakable = isbreakable | ||
207 | bl.prev = fs.bl | ||
208 | bl.locallist = {} | ||
209 | fs.bl = bl | ||
210 | self:log(">> enterblock(isbreakable="..tostring(isbreakable)..")") | ||
211 | end | ||
212 | -------------------------------------------------------------------- | ||
213 | -- leaves a code unit, close any upvalues | ||
214 | -------------------------------------------------------------------- | ||
215 | function luaY:leaveblock() | ||
216 | local bl = fs.bl | ||
217 | fs.bl = bl.prev | ||
218 | self:log("<< leaveblock") | ||
219 | end | ||
220 | -------------------------------------------------------------------- | ||
221 | -- opening of a function | ||
222 | -------------------------------------------------------------------- | ||
223 | function luaY:open_func() | ||
224 | local new_fs -- per-function state | ||
225 | if not fs then -- top_fs is created early | ||
226 | new_fs = top_fs | ||
227 | else | ||
228 | new_fs = {} | ||
229 | end | ||
230 | new_fs.prev = fs -- linked list of function states | ||
231 | new_fs.bl = nil | ||
232 | new_fs.locallist = {} | ||
233 | fs = new_fs | ||
234 | self:log(">> open_func") | ||
235 | end | ||
236 | -------------------------------------------------------------------- | ||
237 | -- closing of a function | ||
238 | -------------------------------------------------------------------- | ||
239 | function luaY:close_func() | ||
240 | fs = fs.prev | ||
241 | self:log("<< close_func") | ||
242 | end | ||
243 | |||
244 | --[[-------------------------------------------------------------------- | ||
245 | -- variable (global|local|upvalue) handling | ||
246 | -- * a pure parser does not really need this, but if we want to produce | ||
247 | -- useful output, might as well write minimal code to manage this... | ||
248 | -- * entry point is singlevar() for variable lookups | ||
249 | -- * three entry points for local variable creation, in order to keep | ||
250 | -- to original C calls, but the extra arguments such as positioning | ||
251 | -- are removed as we are not allocating registers -- we are only | ||
252 | -- doing simple classification | ||
253 | -- * lookup tables (bl.locallist) are maintained awkwardly in the basic | ||
254 | -- block data structures, PLUS the function data structure (this is | ||
255 | -- an inelegant hack, since bl is nil for the top level of a function) | ||
256 | ----------------------------------------------------------------------]] | ||
257 | |||
258 | -------------------------------------------------------------------- | ||
259 | -- register a local variable, set in active variable list | ||
260 | -- * used in new_localvarstr(), parlist(), fornum(), forlist(), | ||
261 | -- localfunc(), localstat() | ||
262 | -------------------------------------------------------------------- | ||
263 | function luaY:new_localvar(name) | ||
264 | local bl = fs.bl | ||
265 | local locallist | ||
266 | if bl then | ||
267 | locallist = bl.locallist | ||
268 | else | ||
269 | locallist = fs.locallist | ||
270 | end | ||
271 | locallist[name] = true | ||
272 | self:log(" new_localvar: '"..name.."'") | ||
273 | end | ||
274 | -------------------------------------------------------------------- | ||
275 | -- creates a new local variable given a name | ||
276 | -- * used in fornum(), forlist() for loop variables; in create_local() | ||
277 | -------------------------------------------------------------------- | ||
278 | function luaY:new_localvarstr(name) | ||
279 | self:new_localvar(name) | ||
280 | end | ||
281 | -------------------------------------------------------------------- | ||
282 | -- creates a single local variable and activates it | ||
283 | -- * used only in code_params() for "arg", body() for "self" | ||
284 | -------------------------------------------------------------------- | ||
285 | function luaY:create_local(name) | ||
286 | self:new_localvarstr(name) | ||
287 | end | ||
288 | |||
289 | -------------------------------------------------------------------- | ||
290 | -- search the local variable namespace of the given fs for a match | ||
291 | -- * a simple lookup only, no active variable list kept, so no useful | ||
292 | -- index value can be returned by this function | ||
293 | -- * used only in singlevaraux() | ||
294 | -------------------------------------------------------------------- | ||
295 | function luaY:searchvar(fs, n) | ||
296 | local bl = fs.bl | ||
297 | if bl then | ||
298 | locallist = bl.locallist | ||
299 | while locallist do | ||
300 | if locallist[n] then return 1 end -- found | ||
301 | bl = bl.prev | ||
302 | locallist = bl and bl.locallist | ||
303 | end | ||
304 | end | ||
305 | locallist = fs.locallist | ||
306 | if locallist[n] then return 1 end -- found | ||
307 | return -1 -- not found | ||
308 | end | ||
309 | -------------------------------------------------------------------- | ||
310 | -- handle locals, globals and upvalues and related processing | ||
311 | -- * search mechanism is recursive, calls itself to search parents | ||
312 | -- * used only in singlevar() | ||
313 | -------------------------------------------------------------------- | ||
314 | function luaY:singlevaraux(fs, n, var, base) | ||
315 | if fs == nil then -- no more levels? | ||
316 | var.k = "VGLOBAL" -- default is global variable | ||
317 | else | ||
318 | local v = self:searchvar(fs, n) -- look up at current level | ||
319 | if v >= 0 then | ||
320 | var.k = "VLOCAL" | ||
321 | else -- not found at current level; try upper one | ||
322 | self:singlevaraux(fs.prev, n, var, 0) | ||
323 | if var.k == "VGLOBAL" then | ||
324 | -- handle global var processing here | ||
325 | else -- LOCAL or UPVAL | ||
326 | var.k = "VUPVAL" | ||
327 | end | ||
328 | end--if v | ||
329 | end--if fs | ||
330 | end | ||
331 | -------------------------------------------------------------------- | ||
332 | -- consume a name token, creates a variable (global|local|upvalue) | ||
333 | -- * used in prefixexp(), funcname() | ||
334 | -------------------------------------------------------------------- | ||
335 | function luaY:singlevar(v) | ||
336 | local varname = self:str_checkname() | ||
337 | self:singlevaraux(fs, varname, v, 1) | ||
338 | self:log(" singlevar(kind): '"..v.k.."'") | ||
339 | end | ||
340 | |||
341 | --[[-------------------------------------------------------------------- | ||
342 | -- other parsing functions | ||
343 | -- * for table constructor, parameter list, argument list | ||
344 | ----------------------------------------------------------------------]] | ||
345 | |||
346 | -------------------------------------------------------------------- | ||
347 | -- parse a function name suffix, for function call specifications | ||
348 | -- * used in primaryexp(), funcname() | ||
349 | -------------------------------------------------------------------- | ||
350 | function luaY:field(v) | ||
351 | -- field -> ['.' | ':'] NAME | ||
352 | local key = {} | ||
353 | self:log(" field: operator="..tok) | ||
354 | self:next() -- skip the dot or colon | ||
355 | self:checkname(key) | ||
356 | v.k = "VINDEXED" | ||
357 | end | ||
358 | -------------------------------------------------------------------- | ||
359 | -- parse a table indexing suffix, for constructors, expressions | ||
360 | -- * used in recfield(), primaryexp() | ||
361 | -------------------------------------------------------------------- | ||
362 | function luaY:index(v) | ||
363 | -- index -> '[' expr ']' | ||
364 | self:log(">> index: begin '['") | ||
365 | self:next() -- skip the '[' | ||
366 | self:expr(v) | ||
367 | self:check("]") | ||
368 | self:log("<< index: end ']'") | ||
369 | end | ||
370 | -------------------------------------------------------------------- | ||
371 | -- parse a table record (hash) field | ||
372 | -- * used in constructor() | ||
373 | -------------------------------------------------------------------- | ||
374 | function luaY:recfield(cc) | ||
375 | -- recfield -> (NAME | '['exp1']') = exp1 | ||
376 | local key, val = {}, {} | ||
377 | if tok == "<name>" then | ||
378 | self:log("recfield: name") | ||
379 | self:checkname(key) | ||
380 | else-- tok == '[' | ||
381 | self:log("recfield: [ exp1 ]") | ||
382 | self:index(key) | ||
383 | end | ||
384 | self:check("=") | ||
385 | self:expr(val) | ||
386 | end | ||
387 | -------------------------------------------------------------------- | ||
388 | -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) | ||
389 | -- * note: retained in this skeleton because it modifies cc.v.k | ||
390 | -- * used in constructor() | ||
391 | -------------------------------------------------------------------- | ||
392 | function luaY:closelistfield(cc) | ||
393 | if cc.v.k == "VVOID" then return end -- there is no list item | ||
394 | cc.v.k = "VVOID" | ||
395 | end | ||
396 | -------------------------------------------------------------------- | ||
397 | -- parse a table list (array) field | ||
398 | -- * used in constructor() | ||
399 | -------------------------------------------------------------------- | ||
400 | function luaY:listfield(cc) | ||
401 | self:log("listfield: expr") | ||
402 | self:expr(cc.v) | ||
403 | end | ||
404 | -------------------------------------------------------------------- | ||
405 | -- parse a table constructor | ||
406 | -- * used in funcargs(), simpleexp() | ||
407 | -------------------------------------------------------------------- | ||
408 | function luaY:constructor(t) | ||
409 | -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' | ||
410 | -- field -> recfield | listfield | ||
411 | -- fieldsep -> ',' | ';' | ||
412 | self:log(">> constructor: begin") | ||
413 | local line = luaX.ln | ||
414 | local cc = {} | ||
415 | cc.v = {} | ||
416 | cc.t = t | ||
417 | t.k = "VRELOCABLE" | ||
418 | cc.v.k = "VVOID" | ||
419 | self:check("{") | ||
420 | repeat | ||
421 | self:testnext(";") -- compatibility only | ||
422 | if tok == "}" then break end | ||
423 | -- closelistfield(cc) here | ||
424 | local c = tok | ||
425 | if c == "<name>" then -- may be listfields or recfields | ||
426 | if self:lookahead() ~= "=" then -- look ahead: expression? | ||
427 | self:listfield(cc) | ||
428 | else | ||
429 | self:recfield(cc) | ||
430 | end | ||
431 | elseif c == "[" then -- constructor_item -> recfield | ||
432 | self:recfield(cc) | ||
433 | else -- constructor_part -> listfield | ||
434 | self:listfield(cc) | ||
435 | end | ||
436 | until not self:testnext(",") and not self:testnext(";") | ||
437 | self:check_match("}", "{", line) | ||
438 | -- lastlistfield(cc) here | ||
439 | self:log("<< constructor: end") | ||
440 | end | ||
441 | -------------------------------------------------------------------- | ||
442 | -- parse the arguments (parameters) of a function declaration | ||
443 | -- * used in body() | ||
444 | -------------------------------------------------------------------- | ||
445 | function luaY:parlist() | ||
446 | -- parlist -> [ param { ',' param } ] | ||
447 | self:log(">> parlist: begin") | ||
448 | local dots = false | ||
449 | if tok ~= ")" then -- is 'parlist' not empty? | ||
450 | repeat | ||
451 | local c = tok | ||
452 | if c == "..." then | ||
453 | self:log("parlist: ... (dots)") | ||
454 | dots = true | ||
455 | self:next() | ||
456 | elseif c == "<name>" then | ||
457 | self:new_localvar(self:str_checkname()) | ||
458 | else | ||
459 | self:syntaxerror("<name> or '...' expected") | ||
460 | end | ||
461 | until dots or not self:testnext(",") | ||
462 | end | ||
463 | -- was code_params() | ||
464 | if dots then | ||
465 | self:create_local("arg") | ||
466 | end | ||
467 | self:log("<< parlist: end") | ||
468 | end | ||
469 | -------------------------------------------------------------------- | ||
470 | -- parse the parameters of a function call | ||
471 | -- * contrast with parlist(), used in function declarations | ||
472 | -- * used in primaryexp() | ||
473 | -------------------------------------------------------------------- | ||
474 | function luaY:funcargs(f) | ||
475 | local args = {} | ||
476 | local line = luaX.ln | ||
477 | local c = tok | ||
478 | if c == "(" then -- funcargs -> '(' [ explist1 ] ')' | ||
479 | self:log(">> funcargs: begin '('") | ||
480 | if line ~= lastln then | ||
481 | self:syntaxerror("ambiguous syntax (function call x new statement)") | ||
482 | end | ||
483 | self:next() | ||
484 | if tok == ")" then -- arg list is empty? | ||
485 | args.k = "VVOID" | ||
486 | else | ||
487 | self:explist1(args) | ||
488 | end | ||
489 | self:check_match(")", "(", line) | ||
490 | elseif c == "{" then -- funcargs -> constructor | ||
491 | self:log(">> funcargs: begin '{'") | ||
492 | self:constructor(args) | ||
493 | elseif c == "<string>" then -- funcargs -> STRING | ||
494 | self:log(">> funcargs: begin <string>") | ||
495 | self:codestring(args, seminfo) | ||
496 | self:next() -- must use 'seminfo' before 'next' | ||
497 | else | ||
498 | self:syntaxerror("function arguments expected") | ||
499 | return | ||
500 | end--if c | ||
501 | f.k = "VCALL" | ||
502 | self:log("<< funcargs: end -- expr is a VCALL") | ||
503 | end | ||
504 | |||
505 | --[[-------------------------------------------------------------------- | ||
506 | -- mostly expression functions | ||
507 | ----------------------------------------------------------------------]] | ||
508 | |||
509 | -------------------------------------------------------------------- | ||
510 | -- parses an expression in parentheses or a single variable | ||
511 | -- * used in primaryexp() | ||
512 | -------------------------------------------------------------------- | ||
513 | function luaY:prefixexp(v) | ||
514 | -- prefixexp -> NAME | '(' expr ')' | ||
515 | local c = tok | ||
516 | if c == "(" then | ||
517 | self:log(">> prefixexp: begin ( expr ) ") | ||
518 | local line = self.ln | ||
519 | self:next() | ||
520 | self:expr(v) | ||
521 | self:check_match(")", "(", line) | ||
522 | self:log("<< prefixexp: end ( expr ) ") | ||
523 | elseif c == "<name>" then | ||
524 | self:log("prefixexp: <name>") | ||
525 | self:singlevar(v) | ||
526 | else | ||
527 | self:syntaxerror("unexpected symbol") | ||
528 | end--if c | ||
529 | end | ||
530 | -------------------------------------------------------------------- | ||
531 | -- parses a prefixexp (an expression in parentheses or a single | ||
532 | -- variable) or a function call specification | ||
533 | -- * used in simpleexp(), assignment(), expr_stat() | ||
534 | -------------------------------------------------------------------- | ||
535 | function luaY:primaryexp(v) | ||
536 | -- primaryexp -> | ||
537 | -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } | ||
538 | self:prefixexp(v) | ||
539 | while true do | ||
540 | local c = tok | ||
541 | if c == "." then -- field | ||
542 | self:log("primaryexp: '.' field") | ||
543 | self:field(v) | ||
544 | elseif c == "[" then -- '[' exp1 ']' | ||
545 | self:log("primaryexp: [ exp1 ]") | ||
546 | local key = {} | ||
547 | self:index(key) | ||
548 | elseif c == ":" then -- ':' NAME funcargs | ||
549 | self:log("primaryexp: :<name> funcargs") | ||
550 | local key = {} | ||
551 | self:next() | ||
552 | self:checkname(key) | ||
553 | self:funcargs(v) | ||
554 | elseif c == "(" or c == "<string>" or c == "{" then -- funcargs | ||
555 | self:log("primaryexp: "..c.." funcargs") | ||
556 | self:funcargs(v) | ||
557 | else | ||
558 | return | ||
559 | end--if c | ||
560 | end--while | ||
561 | end | ||
562 | -------------------------------------------------------------------- | ||
563 | -- parses general expression types, constants handled here | ||
564 | -- * used in subexpr() | ||
565 | -------------------------------------------------------------------- | ||
566 | function luaY:simpleexp(v) | ||
567 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | constructor | ||
568 | -- | FUNCTION body | primaryexp | ||
569 | local c = tok | ||
570 | if c == "<number>" then | ||
571 | self:log("simpleexp: <number>="..seminfo) | ||
572 | v.k = "VK" | ||
573 | self:next() -- must use 'seminfo' before 'next' | ||
574 | elseif c == "<string>" then | ||
575 | self:log("simpleexp: <string>="..seminfo) | ||
576 | self:codestring(v, seminfo) | ||
577 | self:next() -- must use 'seminfo' before 'next' | ||
578 | elseif c == "nil" then | ||
579 | self:log("simpleexp: nil") | ||
580 | v.k = "VNIL" | ||
581 | self:next() | ||
582 | elseif c == "true" then | ||
583 | self:log("simpleexp: true") | ||
584 | v.k = "VTRUE" | ||
585 | self:next() | ||
586 | elseif c == "false" then | ||
587 | self:log("simpleexp: false") | ||
588 | v.k = "VFALSE" | ||
589 | self:next() | ||
590 | elseif c == "{" then -- constructor | ||
591 | self:log("simpleexp: constructor") | ||
592 | self:constructor(v) | ||
593 | elseif c == "function" then | ||
594 | self:log("simpleexp: function") | ||
595 | self:next() | ||
596 | self:body(v, false, luaX.ln) | ||
597 | else | ||
598 | self:primaryexp(v) | ||
599 | end--if c | ||
600 | end | ||
601 | ------------------------------------------------------------------------ | ||
602 | -- Parse subexpressions. Includes handling of unary operators and binary | ||
603 | -- operators. A subexpr is given the rhs priority level of the operator | ||
604 | -- immediately left of it, if any (limit is -1 if none,) and if a binop | ||
605 | -- is found, limit is compared with the lhs priority level of the binop | ||
606 | -- in order to determine which executes first. | ||
607 | -- * recursively called | ||
608 | -- * used in expr() | ||
609 | ------------------------------------------------------------------------ | ||
610 | function luaY:subexpr(v, limit) | ||
611 | -- subexpr -> (simpleexp | unop subexpr) { binop subexpr } | ||
612 | -- * where 'binop' is any binary operator with a priority | ||
613 | -- higher than 'limit' | ||
614 | local op = tok | ||
615 | local uop = unopr[op] | ||
616 | if uop then | ||
617 | self:log(" subexpr: uop='"..op.."'") | ||
618 | self:next() | ||
619 | self:subexpr(v, 8) -- UNARY_PRIORITY | ||
620 | else | ||
621 | self:simpleexp(v) | ||
622 | end | ||
623 | -- expand while operators have priorities higher than 'limit' | ||
624 | op = tok | ||
625 | local binop = binopr_left[op] | ||
626 | while binop and binop > limit do | ||
627 | local v2 = {} | ||
628 | self:log(">> subexpr: binop='"..op.."'") | ||
629 | self:next() | ||
630 | -- read sub-expression with higher priority | ||
631 | local nextop = self:subexpr(v2, binopr_right[op]) | ||
632 | self:log("<< subexpr: -- evaluate") | ||
633 | op = nextop | ||
634 | binop = binopr_left[op] | ||
635 | end | ||
636 | return op -- return first untreated operator | ||
637 | end | ||
638 | -------------------------------------------------------------------- | ||
639 | -- Expression parsing starts here. Function subexpr is entered with the | ||
640 | -- left operator (which is non-existent) priority of -1, which is lower | ||
641 | -- than all actual operators. Expr information is returned in parm v. | ||
642 | -- * used in cond(), explist1(), index(), recfield(), listfield(), | ||
643 | -- prefixexp(), while_stat(), exp1() | ||
644 | -------------------------------------------------------------------- | ||
645 | function luaY:expr(v) | ||
646 | -- expr -> subexpr | ||
647 | self:log("expr:") | ||
648 | self:subexpr(v, -1) | ||
649 | end | ||
650 | |||
651 | --[[-------------------------------------------------------------------- | ||
652 | -- third level parsing functions | ||
653 | ----------------------------------------------------------------------]] | ||
654 | |||
655 | -------------------------------------------------------------------- | ||
656 | -- parse a variable assignment sequence | ||
657 | -- * recursively called | ||
658 | -- * used in expr_stat() | ||
659 | -------------------------------------------------------------------- | ||
660 | function luaY:assignment(v) | ||
661 | local e = {} | ||
662 | local c = v.v.k | ||
663 | self:check_condition(c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" | ||
664 | or c == "VINDEXED", "syntax error") | ||
665 | if self:testnext(",") then -- assignment -> ',' primaryexp assignment | ||
666 | local nv = {} -- expdesc | ||
667 | nv.v = {} | ||
668 | self:log("assignment: ',' -- next LHS element") | ||
669 | self:primaryexp(nv.v) | ||
670 | -- lparser.c deals with some register usage conflict here | ||
671 | self:assignment(nv) | ||
672 | else -- assignment -> '=' explist1 | ||
673 | self:check("=") | ||
674 | self:log("assignment: '=' -- RHS elements follows") | ||
675 | self:explist1(e) | ||
676 | return -- avoid default | ||
677 | end | ||
678 | e.k = "VNONRELOC" | ||
679 | end | ||
680 | -------------------------------------------------------------------- | ||
681 | -- parse a for loop body for both versions of the for loop | ||
682 | -- * used in fornum(), forlist() | ||
683 | -------------------------------------------------------------------- | ||
684 | function luaY:forbody(line, isnum) | ||
685 | self:check("do") | ||
686 | self:enterblock(true) -- loop block | ||
687 | self:block() | ||
688 | self:leaveblock() | ||
689 | end | ||
690 | -------------------------------------------------------------------- | ||
691 | -- parse a numerical for loop, calls forbody() | ||
692 | -- * used in for_stat() | ||
693 | -------------------------------------------------------------------- | ||
694 | function luaY:fornum(varname, line) | ||
695 | -- fornum -> NAME = exp1, exp1 [, exp1] DO body | ||
696 | self:new_localvar(varname) | ||
697 | self:new_localvarstr("(for limit)") | ||
698 | self:new_localvarstr("(for step)") | ||
699 | self:log(">> fornum: begin") | ||
700 | self:check("=") | ||
701 | self:log("fornum: index start") | ||
702 | self:exp1() -- initial value | ||
703 | self:check(",") | ||
704 | self:log("fornum: index stop") | ||
705 | self:exp1() -- limit | ||
706 | if self:testnext(",") then | ||
707 | self:log("fornum: index step") | ||
708 | self:exp1() -- optional step | ||
709 | else | ||
710 | -- default step = 1 | ||
711 | end | ||
712 | self:log("fornum: body") | ||
713 | self:forbody(line, true) | ||
714 | self:log("<< fornum: end") | ||
715 | end | ||
716 | -------------------------------------------------------------------- | ||
717 | -- parse a generic for loop, calls forbody() | ||
718 | -- * used in for_stat() | ||
719 | -------------------------------------------------------------------- | ||
720 | function luaY:forlist(indexname) | ||
721 | -- forlist -> NAME {, NAME} IN explist1 DO body | ||
722 | self:log(">> forlist: begin") | ||
723 | local e = {} | ||
724 | self:new_localvarstr("(for generator)") | ||
725 | self:new_localvarstr("(for state)") | ||
726 | self:new_localvar(indexname) | ||
727 | while self:testnext(",") do | ||
728 | self:new_localvar(self:str_checkname()) | ||
729 | end | ||
730 | self:check("in") | ||
731 | local line = line | ||
732 | self:log("forlist: explist1") | ||
733 | self:explist1(e) | ||
734 | self:log("forlist: body") | ||
735 | self:forbody(line, false) | ||
736 | self:log("<< forlist: end") | ||
737 | end | ||
738 | -------------------------------------------------------------------- | ||
739 | -- parse a function name specification | ||
740 | -- * used in func_stat() | ||
741 | -------------------------------------------------------------------- | ||
742 | function luaY:funcname(v) | ||
743 | -- funcname -> NAME {field} [':' NAME] | ||
744 | self:log(">> funcname: begin") | ||
745 | local needself = false | ||
746 | self:singlevar(v) | ||
747 | while tok == "." do | ||
748 | self:log("funcname: -- '.' field") | ||
749 | self:field(v) | ||
750 | end | ||
751 | if tok == ":" then | ||
752 | self:log("funcname: -- ':' field") | ||
753 | needself = true | ||
754 | self:field(v) | ||
755 | end | ||
756 | self:log("<< funcname: end") | ||
757 | return needself | ||
758 | end | ||
759 | -------------------------------------------------------------------- | ||
760 | -- parse the single expressions needed in numerical for loops | ||
761 | -- * used in fornum() | ||
762 | -------------------------------------------------------------------- | ||
763 | function luaY:exp1() | ||
764 | -- exp1 -> expr | ||
765 | local e = {} | ||
766 | self:log(">> exp1: begin") | ||
767 | self:expr(e) | ||
768 | self:log("<< exp1: end") | ||
769 | end | ||
770 | -------------------------------------------------------------------- | ||
771 | -- parse condition in a repeat statement or an if control structure | ||
772 | -- * used in repeat_stat(), test_then_block() | ||
773 | -------------------------------------------------------------------- | ||
774 | function luaY:cond(v) | ||
775 | -- cond -> expr | ||
776 | self:log(">> cond: begin") | ||
777 | self:expr(v) -- read condition | ||
778 | self:log("<< cond: end") | ||
779 | end | ||
780 | -------------------------------------------------------------------- | ||
781 | -- parse part of an if control structure, including the condition | ||
782 | -- * used in if_stat() | ||
783 | -------------------------------------------------------------------- | ||
784 | function luaY:test_then_block(v) | ||
785 | -- test_then_block -> [IF | ELSEIF] cond THEN block | ||
786 | self:next() -- skip IF or ELSEIF | ||
787 | self:log("test_then_block: test condition") | ||
788 | self:cond(v) | ||
789 | self:check("then") | ||
790 | self:log("test_then_block: then block") | ||
791 | self:block() -- 'then' part | ||
792 | end | ||
793 | -------------------------------------------------------------------- | ||
794 | -- parse a local function statement | ||
795 | -- * used in local_stat() | ||
796 | -------------------------------------------------------------------- | ||
797 | function luaY:localfunc() | ||
798 | -- localfunc -> NAME body | ||
799 | local v, b = {} | ||
800 | self:log("localfunc: begin") | ||
801 | self:new_localvar(self:str_checkname()) | ||
802 | v.k = "VLOCAL" | ||
803 | self:log("localfunc: body") | ||
804 | self:body(b, false, luaX.ln) | ||
805 | self:log("localfunc: end") | ||
806 | end | ||
807 | -------------------------------------------------------------------- | ||
808 | -- parse a local variable declaration statement | ||
809 | -- * used in local_stat() | ||
810 | -------------------------------------------------------------------- | ||
811 | function luaY:localstat() | ||
812 | -- localstat -> NAME {',' NAME} ['=' explist1] | ||
813 | self:log(">> localstat: begin") | ||
814 | local e = {} | ||
815 | repeat | ||
816 | self:new_localvar(self:str_checkname()) | ||
817 | until not self:testnext(",") | ||
818 | if self:testnext("=") then | ||
819 | self:log("localstat: -- assignment") | ||
820 | self:explist1(e) | ||
821 | else | ||
822 | e.k = "VVOID" | ||
823 | end | ||
824 | self:log("<< localstat: end") | ||
825 | end | ||
826 | -------------------------------------------------------------------- | ||
827 | -- parse a list of comma-separated expressions | ||
828 | -- * used in return_stat(), localstat(), funcargs(), assignment(), | ||
829 | -- forlist() | ||
830 | -------------------------------------------------------------------- | ||
831 | function luaY:explist1(e) | ||
832 | -- explist1 -> expr { ',' expr } | ||
833 | self:log(">> explist1: begin") | ||
834 | self:expr(e) | ||
835 | while self:testnext(",") do | ||
836 | self:log("explist1: ',' -- continuation") | ||
837 | self:expr(e) | ||
838 | end | ||
839 | self:log("<< explist1: end") | ||
840 | end | ||
841 | -------------------------------------------------------------------- | ||
842 | -- parse function declaration body | ||
843 | -- * used in simpleexp(), localfunc(), func_stat() | ||
844 | -------------------------------------------------------------------- | ||
845 | function luaY:body(e, needself, line) | ||
846 | -- body -> '(' parlist ')' chunk END | ||
847 | self:open_func() | ||
848 | self:log("body: begin") | ||
849 | self:check("(") | ||
850 | if needself then | ||
851 | self:create_local("self") | ||
852 | end | ||
853 | self:log("body: parlist") | ||
854 | self:parlist() | ||
855 | self:check(")") | ||
856 | self:log("body: chunk") | ||
857 | self:chunk() | ||
858 | self:check_match("end", "function", line) | ||
859 | self:log("body: end") | ||
860 | self:close_func() | ||
861 | end | ||
862 | -------------------------------------------------------------------- | ||
863 | -- parse a code block or unit | ||
864 | -- * used in do_stat(), while_stat(), repeat_stat(), forbody(), | ||
865 | -- test_then_block(), if_stat() | ||
866 | -------------------------------------------------------------------- | ||
867 | function luaY:block() | ||
868 | -- block -> chunk | ||
869 | self:log("block: begin") | ||
870 | self:enterblock(false) | ||
871 | self:chunk() | ||
872 | self:leaveblock() | ||
873 | self:log("block: end") | ||
874 | end | ||
875 | |||
876 | --[[-------------------------------------------------------------------- | ||
877 | -- second level parsing functions, all with '_stat' suffix | ||
878 | -- * stat() -> *_stat() | ||
879 | ----------------------------------------------------------------------]] | ||
880 | |||
881 | -------------------------------------------------------------------- | ||
882 | -- initial parsing for a for loop, calls fornum() or forlist() | ||
883 | -- * used in stat() | ||
884 | -------------------------------------------------------------------- | ||
885 | function luaY:for_stat() | ||
886 | -- stat -> for_stat -> fornum | forlist | ||
887 | local line = line | ||
888 | self:log("for_stat: begin") | ||
889 | self:enterblock(false) -- block to control variable scope | ||
890 | self:next() -- skip 'for' | ||
891 | local varname = self:str_checkname() -- first variable name | ||
892 | local c = tok | ||
893 | if c == "=" then | ||
894 | self:log("for_stat: numerical loop") | ||
895 | self:fornum(varname, line) | ||
896 | elseif c == "," or c == "in" then | ||
897 | self:log("for_stat: list-based loop") | ||
898 | self:forlist(varname) | ||
899 | else | ||
900 | self:syntaxerror("'=' or 'in' expected") | ||
901 | end | ||
902 | self:check_match("end", "for", line) | ||
903 | self:leaveblock() | ||
904 | self:log("for_stat: end") | ||
905 | end | ||
906 | -------------------------------------------------------------------- | ||
907 | -- parse a while-do control structure, body processed by block() | ||
908 | -- * used in stat() | ||
909 | -------------------------------------------------------------------- | ||
910 | function luaY:while_stat() | ||
911 | -- stat -> while_stat -> WHILE cond DO block END | ||
912 | local line = line | ||
913 | local v = {} | ||
914 | self:next() -- skip WHILE | ||
915 | self:log("while_stat: begin/condition") | ||
916 | self:expr(v) -- parse condition | ||
917 | self:enterblock(true) | ||
918 | self:check("do") | ||
919 | self:log("while_stat: block") | ||
920 | self:block() | ||
921 | self:check_match("end", "while", line) | ||
922 | self:leaveblock() | ||
923 | self:log("while_stat: end") | ||
924 | end | ||
925 | -------------------------------------------------------------------- | ||
926 | -- parse a repeat-until control structure, body parsed by block() | ||
927 | -- * used in stat() | ||
928 | -------------------------------------------------------------------- | ||
929 | function luaY:repeat_stat() | ||
930 | -- stat -> repeat_stat -> REPEAT block UNTIL cond | ||
931 | local line = line | ||
932 | local v = {} | ||
933 | self:log("repeat_stat: begin") | ||
934 | self:enterblock(true) | ||
935 | self:next() | ||
936 | self:block() | ||
937 | self:check_match("until", "repeat", line) | ||
938 | self:log("repeat_stat: condition") | ||
939 | self:cond(v) | ||
940 | self:leaveblock() | ||
941 | self:log("repeat_stat: end") | ||
942 | end | ||
943 | -------------------------------------------------------------------- | ||
944 | -- parse an if control structure | ||
945 | -- * used in stat() | ||
946 | -------------------------------------------------------------------- | ||
947 | function luaY:if_stat() | ||
948 | -- stat -> if_stat -> IF cond THEN block | ||
949 | -- {ELSEIF cond THEN block} [ELSE block] END | ||
950 | local line = line | ||
951 | local v = {} | ||
952 | self:log("if_stat: if...then") | ||
953 | self:test_then_block(v) -- IF cond THEN block | ||
954 | while tok == "elseif" do | ||
955 | self:log("if_stat: elseif...then") | ||
956 | self:test_then_block(v) -- ELSEIF cond THEN block | ||
957 | end | ||
958 | if tok == "else" then | ||
959 | self:log("if_stat: else...") | ||
960 | self:next() -- skip ELSE | ||
961 | self:block() -- 'else' part | ||
962 | end | ||
963 | self:check_match("end", "if", line) | ||
964 | self:log("if_stat: end") | ||
965 | end | ||
966 | -------------------------------------------------------------------- | ||
967 | -- parse a return statement | ||
968 | -- * used in stat() | ||
969 | -------------------------------------------------------------------- | ||
970 | function luaY:return_stat() | ||
971 | -- stat -> return_stat -> RETURN explist | ||
972 | local e = {} | ||
973 | self:next() -- skip RETURN | ||
974 | local c = tok | ||
975 | if block_follow[c] or c == ";" then | ||
976 | -- return no values | ||
977 | self:log("return_stat: no return values") | ||
978 | else | ||
979 | self:log("return_stat: begin") | ||
980 | self:explist1(e) -- optional return values | ||
981 | self:log("return_stat: end") | ||
982 | end | ||
983 | end | ||
984 | -------------------------------------------------------------------- | ||
985 | -- parse a break statement | ||
986 | -- * used in stat() | ||
987 | -------------------------------------------------------------------- | ||
988 | function luaY:break_stat() | ||
989 | -- stat -> break_stat -> BREAK | ||
990 | local bl = fs.bl | ||
991 | self:next() -- skip BREAK | ||
992 | while bl and not bl.isbreakable do -- find a breakable block | ||
993 | bl = bl.prev | ||
994 | end | ||
995 | if not bl then | ||
996 | self:syntaxerror("no loop to break") | ||
997 | end | ||
998 | self:log("break_stat: -- break out of loop") | ||
999 | end | ||
1000 | -------------------------------------------------------------------- | ||
1001 | -- parse a function call with no returns or an assignment statement | ||
1002 | -- * the struct with .prev is used for name searching in lparse.c, | ||
1003 | -- so it is retained for now; present in assignment() also | ||
1004 | -- * used in stat() | ||
1005 | -------------------------------------------------------------------- | ||
1006 | function luaY:expr_stat() | ||
1007 | -- stat -> expr_stat -> func | assignment | ||
1008 | local v = {} | ||
1009 | v.v = {} | ||
1010 | self:primaryexp(v.v) | ||
1011 | if v.v.k == "VCALL" then -- stat -> func | ||
1012 | -- call statement uses no results | ||
1013 | self:log("expr_stat: function call k='"..v.v.k.."'") | ||
1014 | else -- stat -> assignment | ||
1015 | self:log("expr_stat: assignment k='"..v.v.k.."'") | ||
1016 | v.prev = nil | ||
1017 | self:assignment(v) | ||
1018 | end | ||
1019 | end | ||
1020 | -------------------------------------------------------------------- | ||
1021 | -- parse a function statement | ||
1022 | -- * used in stat() | ||
1023 | -------------------------------------------------------------------- | ||
1024 | function luaY:function_stat() | ||
1025 | -- stat -> function_stat -> FUNCTION funcname body | ||
1026 | local line = line | ||
1027 | local v, b = {}, {} | ||
1028 | self:log("function_stat: begin") | ||
1029 | self:next() -- skip FUNCTION | ||
1030 | local needself = self:funcname(v) | ||
1031 | self:log("function_stat: body needself='"..tostring(needself).."'") | ||
1032 | self:body(b, needself, line) | ||
1033 | self:log("function_stat: end") | ||
1034 | end | ||
1035 | -------------------------------------------------------------------- | ||
1036 | -- parse a simple block enclosed by a DO..END pair | ||
1037 | -- * used in stat() | ||
1038 | -------------------------------------------------------------------- | ||
1039 | function luaY:do_stat() | ||
1040 | -- stat -> do_stat -> DO block END | ||
1041 | self:next() -- skip DO | ||
1042 | self:log("do_stat: begin") | ||
1043 | self:block() | ||
1044 | self:log("do_stat: end") | ||
1045 | self:check_match("end", "do", line) | ||
1046 | end | ||
1047 | -------------------------------------------------------------------- | ||
1048 | -- parse a statement starting with LOCAL | ||
1049 | -- * used in stat() | ||
1050 | -------------------------------------------------------------------- | ||
1051 | function luaY:local_stat() | ||
1052 | -- stat -> local_stat -> LOCAL FUNCTION localfunc | ||
1053 | -- -> LOCAL localstat | ||
1054 | self:next() -- skip LOCAL | ||
1055 | if self:testnext("function") then -- local function? | ||
1056 | self:log("local_stat: local function") | ||
1057 | self:localfunc() | ||
1058 | else | ||
1059 | self:log("local_stat: local statement") | ||
1060 | self:localstat() | ||
1061 | end | ||
1062 | end | ||
1063 | |||
1064 | --[[-------------------------------------------------------------------- | ||
1065 | -- main function, top level parsing functions | ||
1066 | -- * [entry] -> parser() -> chunk() -> stat() | ||
1067 | ----------------------------------------------------------------------]] | ||
1068 | |||
1069 | -------------------------------------------------------------------- | ||
1070 | -- initial parsing for statements, calls '_stat' suffixed functions | ||
1071 | -- * used in chunk() | ||
1072 | -------------------------------------------------------------------- | ||
1073 | function luaY:stat() | ||
1074 | line = luaX.ln | ||
1075 | local c = tok | ||
1076 | local fn = stat_call[c] | ||
1077 | -- handles: if while do for repeat function local return break | ||
1078 | if fn then | ||
1079 | self:log("-- STATEMENT: begin '"..c.."' line="..line) | ||
1080 | self[fn](self) | ||
1081 | self:log("-- STATEMENT: end '"..c.."'") | ||
1082 | -- return or break must be last statement | ||
1083 | if c == "return" or c == "break" then return true end | ||
1084 | else | ||
1085 | self:log("-- STATEMENT: begin 'expr' line="..line) | ||
1086 | self:expr_stat() | ||
1087 | self:log("-- STATEMENT: end 'expr'") | ||
1088 | end | ||
1089 | self:log("") | ||
1090 | return false | ||
1091 | end | ||
1092 | -------------------------------------------------------------------- | ||
1093 | -- parse a chunk, which consists of a bunch of statements | ||
1094 | -- * used in parser(), body(), block() | ||
1095 | -------------------------------------------------------------------- | ||
1096 | function luaY:chunk() | ||
1097 | -- chunk -> { stat [';'] } | ||
1098 | self:log("chunk:") | ||
1099 | local islast = false | ||
1100 | while not islast and not block_follow[tok] do | ||
1101 | islast = self:stat() | ||
1102 | self:testnext(";") | ||
1103 | end | ||
1104 | end | ||
1105 | -------------------------------------------------------------------- | ||
1106 | -- performs parsing, returns parsed data structure | ||
1107 | -------------------------------------------------------------------- | ||
1108 | function luaY:parser() | ||
1109 | self:log("-- TOP: begin") | ||
1110 | self:open_func() | ||
1111 | self:log("") | ||
1112 | self:next() -- read first token | ||
1113 | self:chunk() | ||
1114 | self:check_condition(tok == "<eof>", "<eof> expected") | ||
1115 | self:close_func() | ||
1116 | self:log("-- TOP: end") | ||
1117 | return top_fs | ||
1118 | end | ||
1119 | -------------------------------------------------------------------- | ||
1120 | return luaY -- return actual module to user, done | ||
1121 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lzio.lua | ||
4 | Lua 5 buffered streams in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * | ||
18 | ----------------------------------------------------------------------]] | ||
19 | |||
20 | --[[-------------------------------------------------------------------- | ||
21 | -- local zio_init = require("lzio.lua") | ||
22 | -- local z = zio_init("@<filename>") | ||
23 | -- local z = zio_init("<string>") | ||
24 | -- z:getc() | ||
25 | -- * get next character from input stream | ||
26 | -- z:fill() | ||
27 | -- * fills an empty stream buffer | ||
28 | -- z.name | ||
29 | -- * name of the chunk, "@<filename>" or "=string" | ||
30 | ----------------------------------------------------------------------]] | ||
31 | |||
32 | --[[-------------------------------------------------------------------- | ||
33 | -- Format of z structure (ZIO) | ||
34 | -- z.n -- bytes still unread | ||
35 | -- z.p -- last read position in buffer | ||
36 | -- z.reader -- chunk reader function | ||
37 | -- z.data -- data buffer | ||
38 | -- z.name -- name of stream | ||
39 | ----------------------------------------------------------------------]] | ||
40 | |||
41 | return | ||
42 | function(buff) | ||
43 | --[[-------------------------------------------------------------------- | ||
44 | -- initialize reader | ||
45 | -- * reader should return a string, or nil if nothing else to parse | ||
46 | ----------------------------------------------------------------------]] | ||
47 | local reader | ||
48 | local z = {} | ||
49 | if string.sub(buff, 1, 1) == "@" then | ||
50 | ---------------------------------------------------------------- | ||
51 | -- create a chunk reader function from a source file | ||
52 | ---------------------------------------------------------------- | ||
53 | z.name = buff | ||
54 | local BUFFERSIZE = 512 | ||
55 | local h = io.open(string.sub(buff, 2), "r") | ||
56 | if not h then return nil end | ||
57 | reader = function() | ||
58 | if not h or io.type(h) == "closed file" then return nil end | ||
59 | local buff = h:read(BUFFERSIZE) | ||
60 | if not buff then h:close(); h = nil end | ||
61 | return buff | ||
62 | end | ||
63 | else | ||
64 | ---------------------------------------------------------------- | ||
65 | -- create a chunk reader function from a source string | ||
66 | ---------------------------------------------------------------- | ||
67 | z.name = "=string" | ||
68 | reader = function() | ||
69 | if not buff then return nil end | ||
70 | local data = buff | ||
71 | buff = nil | ||
72 | return data | ||
73 | end | ||
74 | end | ||
75 | --[[-------------------------------------------------------------------- | ||
76 | -- fills an empty stream buffer, returns first character | ||
77 | ----------------------------------------------------------------------]] | ||
78 | function z:fill() | ||
79 | local data = z.reader() | ||
80 | z.data = data | ||
81 | if not data or data == "" then return "EOZ" end | ||
82 | z.n, z.p = string.len(data) - 1, 1 | ||
83 | return string.sub(data, 1, 1) | ||
84 | end | ||
85 | --[[-------------------------------------------------------------------- | ||
86 | -- get next character, fills buffer if characters needed | ||
87 | ----------------------------------------------------------------------]] | ||
88 | function z:getc() | ||
89 | local n, p = z.n, z.p + 1 | ||
90 | if n > 0 then | ||
91 | z.n, z.p = n - 1, p | ||
92 | return string.sub(z.data, p, p) | ||
93 | else | ||
94 | return self:fill() | ||
95 | end | ||
96 | end | ||
97 | --[[-------------------------------------------------------------------- | ||
98 | -- initialize input stream object | ||
99 | ----------------------------------------------------------------------]] | ||
100 | if not reader then return end | ||
101 | z.reader = reader | ||
102 | z.data = "" | ||
103 | z.n, z.p = 0, 0 | ||
104 | return z | ||
105 | --[[------------------------------------------------------------------]] | ||
106 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lzio.lua | ||
4 | Lua 5 buffered streams in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * this is a line-based input streamer for the MK4 lexer | ||
18 | -- * all EOL (end-of-line) characters are translated to "\n" | ||
19 | -- * if last line in a file does not have an EOL character, this | ||
20 | -- streamer adds one, the ambiguity is due to "*l" stripping | ||
21 | -- * EOF uses an empty string to simplify testing in lexer | ||
22 | ----------------------------------------------------------------------]] | ||
23 | |||
24 | --[[-------------------------------------------------------------------- | ||
25 | -- local zio_init = require("lzio.lua") | ||
26 | -- local z = zio_init("@<filename>") | ||
27 | -- local z = zio_init("<string>") | ||
28 | -- z:getln() | ||
29 | -- * get next line from input stream | ||
30 | -- z.name | ||
31 | -- * name of the chunk, "@<filename>" or "=string" | ||
32 | ----------------------------------------------------------------------]] | ||
33 | |||
34 | --[[-------------------------------------------------------------------- | ||
35 | -- Format of z structure (ZIO) | ||
36 | -- z.getln -- chunk reader function, reads line-by-line | ||
37 | -- z.name -- name of stream | ||
38 | ----------------------------------------------------------------------]] | ||
39 | |||
40 | return | ||
41 | function(buff) | ||
42 | --[[-------------------------------------------------------------------- | ||
43 | -- initialize reader | ||
44 | -- * reader should return a string with an EOL character, or an empty | ||
45 | -- string if there is nothing else to parse | ||
46 | ----------------------------------------------------------------------]] | ||
47 | local reader | ||
48 | local z = {} | ||
49 | if string.sub(buff, 1, 1) == "@" then | ||
50 | ---------------------------------------------------------------- | ||
51 | -- create a chunk reader function from a source file | ||
52 | ---------------------------------------------------------------- | ||
53 | z.name = buff | ||
54 | local h = io.open(string.sub(buff, 2), "r") | ||
55 | if not h then return nil end | ||
56 | reader = function() | ||
57 | if not h or io.type(h) == "closed file" then return nil end | ||
58 | local data = h:read("*l") | ||
59 | if not data then h:close(); return "" end | ||
60 | return data.."\n" | ||
61 | end | ||
62 | else | ||
63 | ---------------------------------------------------------------- | ||
64 | -- create a chunk reader function from a source string | ||
65 | ---------------------------------------------------------------- | ||
66 | z.name = "=string" | ||
67 | reader = function() | ||
68 | if not buff then return nil end | ||
69 | local p, q, data, eol = string.find(buff, "([^\r\n]*)(\r?\n?)") | ||
70 | buff = string.sub(buff, q + 1) | ||
71 | if data == "" and eol == "" then return "" end | ||
72 | return data..eol | ||
73 | end | ||
74 | end | ||
75 | --[[-------------------------------------------------------------------- | ||
76 | -- initialize input stream object | ||
77 | ----------------------------------------------------------------------]] | ||
78 | if not reader then return end | ||
79 | z.getln = reader | ||
80 | return z | ||
81 | --[[------------------------------------------------------------------]] | ||
82 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | bench_llex.lua | ||
4 | Benchmark test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | local zio_init = require("../lzio_mk2") | ||
16 | local lex_init = require("../llex_mk2") | ||
17 | |||
18 | ------------------------------------------------------------------------ | ||
19 | -- load in a standard set of sample files | ||
20 | -- * file set is 5.0.3 front end set sans luac.lua | ||
21 | ------------------------------------------------------------------------ | ||
22 | |||
23 | local fileset, totalsize = {}, 0 | ||
24 | for fn in string.gfind([[ | ||
25 | ../../orig-5.0.3/lcode.lua | ||
26 | ../../orig-5.0.3/ldump.lua | ||
27 | ../../orig-5.0.3/llex.lua | ||
28 | ../../orig-5.0.3/lopcodes.lua | ||
29 | ../../orig-5.0.3/lparser.lua | ||
30 | ../../orig-5.0.3/lzio.lua | ||
31 | ]], "%S+") do | ||
32 | table.insert(fileset, fn) | ||
33 | end | ||
34 | |||
35 | for i = 1, table.getn(fileset) do | ||
36 | local fn = fileset[i] | ||
37 | local inf = io.open(fn, "rb") | ||
38 | if not inf then | ||
39 | error("failed to open "..fn.." for reading") | ||
40 | end | ||
41 | local data = inf:read("*a") | ||
42 | local data_sz = string.len(data) | ||
43 | inf:close() | ||
44 | if not data or data_sz == 0 then | ||
45 | error("failed to read data from "..fn.." or file is zero-length") | ||
46 | end | ||
47 | totalsize = totalsize + data_sz | ||
48 | fileset[i] = data | ||
49 | end | ||
50 | |||
51 | ------------------------------------------------------------------------ | ||
52 | -- benchmark tester | ||
53 | ------------------------------------------------------------------------ | ||
54 | |||
55 | local DURATION = 5 -- how long the benchmark should run | ||
56 | |||
57 | local time = os.time | ||
58 | local lexedsize = 0 | ||
59 | local tnow, elapsed = time(), 0 | ||
60 | |||
61 | while time() == tnow do end -- wait for second to click over | ||
62 | tnow = time() | ||
63 | |||
64 | while true do | ||
65 | for i = 1, table.getn(fileset) do | ||
66 | ------------------------------------------------------------ | ||
67 | local chunk = fileset[i] | ||
68 | local z = zio_init(chunk) | ||
69 | local luaX = lex_init(z, "=string") | ||
70 | while true do | ||
71 | local tok, seminfo = luaX:lex() | ||
72 | if tok == "<eof>" then break end | ||
73 | end | ||
74 | ------------------------------------------------------------ | ||
75 | lexedsize = lexedsize + string.len(chunk) | ||
76 | if time() > tnow then | ||
77 | tnow = time() | ||
78 | elapsed = elapsed + 1 | ||
79 | if elapsed >= DURATION then | ||
80 | -- report performance of lexer | ||
81 | lexedsize = lexedsize / 1024 | ||
82 | local speed = lexedsize / DURATION | ||
83 | print("Lexer performance:") | ||
84 | print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) | ||
85 | print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) | ||
86 | -- repeat until user breaks program | ||
87 | elapsed = 0 | ||
88 | end | ||
89 | end | ||
90 | ------------------------------------------------------------ | ||
91 | end--for | ||
92 | end--while | ||
93 | |||
94 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | bench_llex.lua | ||
4 | Benchmark test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | local lex_init = require("../llex_mk3") | ||
16 | |||
17 | ------------------------------------------------------------------------ | ||
18 | -- load in a standard set of sample files | ||
19 | -- * file set is 5.0.3 front end set sans luac.lua | ||
20 | ------------------------------------------------------------------------ | ||
21 | |||
22 | local fileset, totalsize = {}, 0 | ||
23 | for fn in string.gfind([[ | ||
24 | ../../orig-5.0.3/lcode.lua | ||
25 | ../../orig-5.0.3/ldump.lua | ||
26 | ../../orig-5.0.3/llex.lua | ||
27 | ../../orig-5.0.3/lopcodes.lua | ||
28 | ../../orig-5.0.3/lparser.lua | ||
29 | ../../orig-5.0.3/lzio.lua | ||
30 | ]], "%S+") do | ||
31 | table.insert(fileset, fn) | ||
32 | end | ||
33 | |||
34 | for i = 1, table.getn(fileset) do | ||
35 | local fn = fileset[i] | ||
36 | local inf = io.open(fn, "rb") | ||
37 | if not inf then | ||
38 | error("failed to open "..fn.." for reading") | ||
39 | end | ||
40 | local data = inf:read("*a") | ||
41 | local data_sz = string.len(data) | ||
42 | inf:close() | ||
43 | if not data or data_sz == 0 then | ||
44 | error("failed to read data from "..fn.." or file is zero-length") | ||
45 | end | ||
46 | totalsize = totalsize + data_sz | ||
47 | fileset[i] = data | ||
48 | end | ||
49 | |||
50 | ------------------------------------------------------------------------ | ||
51 | -- benchmark tester | ||
52 | ------------------------------------------------------------------------ | ||
53 | |||
54 | local DURATION = 5 -- how long the benchmark should run | ||
55 | |||
56 | local time = os.time | ||
57 | local lexedsize = 0 | ||
58 | local tnow, elapsed = time(), 0 | ||
59 | |||
60 | while time() == tnow do end -- wait for second to click over | ||
61 | tnow = time() | ||
62 | |||
63 | while true do | ||
64 | for i = 1, table.getn(fileset) do | ||
65 | ------------------------------------------------------------ | ||
66 | local chunk = fileset[i] | ||
67 | local luaX = lex_init(chunk, "=string") | ||
68 | while true do | ||
69 | local tok, seminfo = luaX:lex() | ||
70 | if tok == "<eof>" then break end | ||
71 | end | ||
72 | ------------------------------------------------------------ | ||
73 | lexedsize = lexedsize + string.len(chunk) | ||
74 | if time() > tnow then | ||
75 | tnow = time() | ||
76 | elapsed = elapsed + 1 | ||
77 | if elapsed >= DURATION then | ||
78 | -- report performance of lexer | ||
79 | lexedsize = lexedsize / 1024 | ||
80 | local speed = lexedsize / DURATION | ||
81 | print("Lexer performance:") | ||
82 | print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) | ||
83 | print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) | ||
84 | -- repeat until user breaks program | ||
85 | elapsed = 0 | ||
86 | end | ||
87 | end | ||
88 | ------------------------------------------------------------ | ||
89 | end--for | ||
90 | end--while | ||
91 | |||
92 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | bench_llex.lua | ||
4 | Benchmark test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | local zio_init = require("../lzio_mk4") | ||
16 | local lex_init = require("../llex_mk4") | ||
17 | |||
18 | ------------------------------------------------------------------------ | ||
19 | -- load in a standard set of sample files | ||
20 | -- * file set is 5.0.3 front end set sans luac.lua | ||
21 | ------------------------------------------------------------------------ | ||
22 | |||
23 | local fileset, totalsize = {}, 0 | ||
24 | for fn in string.gfind([[ | ||
25 | ../../orig-5.0.3/lcode.lua | ||
26 | ../../orig-5.0.3/ldump.lua | ||
27 | ../../orig-5.0.3/llex.lua | ||
28 | ../../orig-5.0.3/lopcodes.lua | ||
29 | ../../orig-5.0.3/lparser.lua | ||
30 | ../../orig-5.0.3/lzio.lua | ||
31 | ]], "%S+") do | ||
32 | table.insert(fileset, fn) | ||
33 | end | ||
34 | |||
35 | for i = 1, table.getn(fileset) do | ||
36 | local fn = fileset[i] | ||
37 | local inf = io.open(fn, "rb") | ||
38 | if not inf then | ||
39 | error("failed to open "..fn.." for reading") | ||
40 | end | ||
41 | local data = inf:read("*a") | ||
42 | local data_sz = string.len(data) | ||
43 | inf:close() | ||
44 | if not data or data_sz == 0 then | ||
45 | error("failed to read data from "..fn.." or file is zero-length") | ||
46 | end | ||
47 | totalsize = totalsize + data_sz | ||
48 | fileset[i] = data | ||
49 | end | ||
50 | |||
51 | ------------------------------------------------------------------------ | ||
52 | -- benchmark tester | ||
53 | ------------------------------------------------------------------------ | ||
54 | |||
55 | local DURATION = 5 -- how long the benchmark should run | ||
56 | |||
57 | local time = os.time | ||
58 | local lexedsize = 0 | ||
59 | local tnow, elapsed = time(), 0 | ||
60 | |||
61 | while time() == tnow do end -- wait for second to click over | ||
62 | tnow = time() | ||
63 | |||
64 | while true do | ||
65 | for i = 1, table.getn(fileset) do | ||
66 | ------------------------------------------------------------ | ||
67 | local chunk = fileset[i] | ||
68 | local z = zio_init(chunk) | ||
69 | local luaX = lex_init(z, "=string") | ||
70 | while true do | ||
71 | local tok, seminfo = luaX:lex() | ||
72 | if tok == "<eof>" then break end | ||
73 | end | ||
74 | ------------------------------------------------------------ | ||
75 | lexedsize = lexedsize + string.len(chunk) | ||
76 | if time() > tnow then | ||
77 | tnow = time() | ||
78 | elapsed = elapsed + 1 | ||
79 | if elapsed >= DURATION then | ||
80 | -- report performance of lexer | ||
81 | lexedsize = lexedsize / 1024 | ||
82 | local speed = lexedsize / DURATION | ||
83 | print("Lexer performance:") | ||
84 | print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) | ||
85 | print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) | ||
86 | -- repeat until user breaks program | ||
87 | elapsed = 0 | ||
88 | end | ||
89 | end | ||
90 | ------------------------------------------------------------ | ||
91 | end--for | ||
92 | end--while | ||
93 | |||
94 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | -- END OF SOURCE -- | ||
3 | |||
4 | -- TOP: begin | ||
5 | open_func | ||
6 | |||
7 | chunk: | ||
8 | close_func | ||
9 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | -- foobar | ||
3 | -- END OF SOURCE -- | ||
4 | |||
5 | -- TOP: begin | ||
6 | open_func | ||
7 | |||
8 | chunk: | ||
9 | close_func | ||
10 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do | ||
3 | end | ||
4 | -- END OF SOURCE -- | ||
5 | |||
6 | -- TOP: begin | ||
7 | open_func | ||
8 | |||
9 | chunk: | ||
10 | -- STATEMENT: begin 'do' line=1 | ||
11 | do_stat: begin | ||
12 | block: begin | ||
13 | enterblock(isbreakable=false) | ||
14 | chunk: | ||
15 | leaveblock | ||
16 | block: end | ||
17 | do_stat: end | ||
18 | -- STATEMENT: end 'do' | ||
19 | |||
20 | close_func | ||
21 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do end | ||
3 | do end | ||
4 | -- END OF SOURCE -- | ||
5 | |||
6 | -- TOP: begin | ||
7 | open_func | ||
8 | |||
9 | chunk: | ||
10 | -- STATEMENT: begin 'do' line=1 | ||
11 | do_stat: begin | ||
12 | block: begin | ||
13 | enterblock(isbreakable=false) | ||
14 | chunk: | ||
15 | leaveblock | ||
16 | block: end | ||
17 | do_stat: end | ||
18 | -- STATEMENT: end 'do' | ||
19 | |||
20 | -- STATEMENT: begin 'do' line=2 | ||
21 | do_stat: begin | ||
22 | block: begin | ||
23 | enterblock(isbreakable=false) | ||
24 | chunk: | ||
25 | leaveblock | ||
26 | block: end | ||
27 | do_stat: end | ||
28 | -- STATEMENT: end 'do' | ||
29 | |||
30 | close_func | ||
31 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | foo() | ||
3 | foo{} | ||
4 | foo"" | ||
5 | foo:bar() | ||
6 | foo=false | ||
7 | foo.bar=true | ||
8 | foo[true]=nil | ||
9 | foo,bar=1,"a" | ||
10 | -- END OF SOURCE -- | ||
11 | |||
12 | -- TOP: begin | ||
13 | open_func | ||
14 | |||
15 | chunk: | ||
16 | -- STATEMENT: begin 'expr' line=1 | ||
17 | prefixexp: <name> | ||
18 | str_checkname: 'foo' | ||
19 | singlevar: name='foo' | ||
20 | primaryexp: ( funcargs | ||
21 | funcargs: begin '(' | ||
22 | funcargs: end -- expr is a VCALL | ||
23 | expr_stat: function call k='VCALL' | ||
24 | -- STATEMENT: end 'expr' | ||
25 | |||
26 | -- STATEMENT: begin 'expr' line=2 | ||
27 | prefixexp: <name> | ||
28 | str_checkname: 'foo' | ||
29 | singlevar: name='foo' | ||
30 | primaryexp: { funcargs | ||
31 | funcargs: begin '{' | ||
32 | constructor: begin | ||
33 | constructor: end | ||
34 | funcargs: end -- expr is a VCALL | ||
35 | expr_stat: function call k='VCALL' | ||
36 | -- STATEMENT: end 'expr' | ||
37 | |||
38 | -- STATEMENT: begin 'expr' line=3 | ||
39 | prefixexp: <name> | ||
40 | str_checkname: 'foo' | ||
41 | singlevar: name='foo' | ||
42 | primaryexp: <string> funcargs | ||
43 | funcargs: begin <string> | ||
44 | codestring: "" | ||
45 | funcargs: end -- expr is a VCALL | ||
46 | expr_stat: function call k='VCALL' | ||
47 | -- STATEMENT: end 'expr' | ||
48 | |||
49 | -- STATEMENT: begin 'expr' line=4 | ||
50 | prefixexp: <name> | ||
51 | str_checkname: 'foo' | ||
52 | singlevar: name='foo' | ||
53 | primaryexp: :<name> funcargs | ||
54 | checkname: | ||
55 | str_checkname: 'bar' | ||
56 | codestring: "bar" | ||
57 | funcargs: begin '(' | ||
58 | funcargs: end -- expr is a VCALL | ||
59 | expr_stat: function call k='VCALL' | ||
60 | -- STATEMENT: end 'expr' | ||
61 | |||
62 | -- STATEMENT: begin 'expr' line=5 | ||
63 | prefixexp: <name> | ||
64 | str_checkname: 'foo' | ||
65 | singlevar: name='foo' | ||
66 | expr_stat: assignment k='VLOCAL' | ||
67 | assignment: '=' -- RHS elements follows | ||
68 | explist1: begin | ||
69 | expr: | ||
70 | simpleexp: false | ||
71 | explist1: end | ||
72 | -- STATEMENT: end 'expr' | ||
73 | |||
74 | -- STATEMENT: begin 'expr' line=6 | ||
75 | prefixexp: <name> | ||
76 | str_checkname: 'foo' | ||
77 | singlevar: name='foo' | ||
78 | primaryexp: '.' field | ||
79 | field: operator=. | ||
80 | checkname: | ||
81 | str_checkname: 'bar' | ||
82 | codestring: "bar" | ||
83 | expr_stat: assignment k='VINDEXED' | ||
84 | assignment: '=' -- RHS elements follows | ||
85 | explist1: begin | ||
86 | expr: | ||
87 | simpleexp: true | ||
88 | explist1: end | ||
89 | -- STATEMENT: end 'expr' | ||
90 | |||
91 | -- STATEMENT: begin 'expr' line=7 | ||
92 | prefixexp: <name> | ||
93 | str_checkname: 'foo' | ||
94 | singlevar: name='foo' | ||
95 | primaryexp: [ exp1 ] | ||
96 | index: begin '[' | ||
97 | expr: | ||
98 | simpleexp: true | ||
99 | index: end ']' | ||
100 | expr_stat: assignment k='VLOCAL' | ||
101 | assignment: '=' -- RHS elements follows | ||
102 | explist1: begin | ||
103 | expr: | ||
104 | simpleexp: nil | ||
105 | explist1: end | ||
106 | -- STATEMENT: end 'expr' | ||
107 | |||
108 | -- STATEMENT: begin 'expr' line=8 | ||
109 | prefixexp: <name> | ||
110 | str_checkname: 'foo' | ||
111 | singlevar: name='foo' | ||
112 | expr_stat: assignment k='VLOCAL' | ||
113 | assignment: ',' -- next LHS element | ||
114 | prefixexp: <name> | ||
115 | str_checkname: 'bar' | ||
116 | singlevar: name='bar' | ||
117 | assignment: '=' -- RHS elements follows | ||
118 | explist1: begin | ||
119 | expr: | ||
120 | simpleexp: <number>=1 | ||
121 | explist1: ',' -- continuation | ||
122 | expr: | ||
123 | simpleexp: <string>=a | ||
124 | codestring: "a" | ||
125 | explist1: end | ||
126 | -- STATEMENT: end 'expr' | ||
127 | |||
128 | close_func | ||
129 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | foo=true | ||
3 | foo=false | ||
4 | foo=nil | ||
5 | foo=1.23e45 | ||
6 | foo=-1 | ||
7 | foo=(0) | ||
8 | foo=1+2 | ||
9 | foo=1+2*3-4/5 | ||
10 | -- END OF SOURCE -- | ||
11 | |||
12 | -- TOP: begin | ||
13 | open_func | ||
14 | |||
15 | chunk: | ||
16 | -- STATEMENT: begin 'expr' line=1 | ||
17 | prefixexp: <name> | ||
18 | str_checkname: 'foo' | ||
19 | singlevar: name='foo' | ||
20 | expr_stat: assignment k='VLOCAL' | ||
21 | assignment: '=' -- RHS elements follows | ||
22 | explist1: begin | ||
23 | expr: | ||
24 | simpleexp: true | ||
25 | explist1: end | ||
26 | -- STATEMENT: end 'expr' | ||
27 | |||
28 | -- STATEMENT: begin 'expr' line=2 | ||
29 | prefixexp: <name> | ||
30 | str_checkname: 'foo' | ||
31 | singlevar: name='foo' | ||
32 | expr_stat: assignment k='VLOCAL' | ||
33 | assignment: '=' -- RHS elements follows | ||
34 | explist1: begin | ||
35 | expr: | ||
36 | simpleexp: false | ||
37 | explist1: end | ||
38 | -- STATEMENT: end 'expr' | ||
39 | |||
40 | -- STATEMENT: begin 'expr' line=3 | ||
41 | prefixexp: <name> | ||
42 | str_checkname: 'foo' | ||
43 | singlevar: name='foo' | ||
44 | expr_stat: assignment k='VLOCAL' | ||
45 | assignment: '=' -- RHS elements follows | ||
46 | explist1: begin | ||
47 | expr: | ||
48 | simpleexp: nil | ||
49 | explist1: end | ||
50 | -- STATEMENT: end 'expr' | ||
51 | |||
52 | -- STATEMENT: begin 'expr' line=4 | ||
53 | prefixexp: <name> | ||
54 | str_checkname: 'foo' | ||
55 | singlevar: name='foo' | ||
56 | expr_stat: assignment k='VLOCAL' | ||
57 | assignment: '=' -- RHS elements follows | ||
58 | explist1: begin | ||
59 | expr: | ||
60 | simpleexp: <number>=1.23e+45 | ||
61 | explist1: end | ||
62 | -- STATEMENT: end 'expr' | ||
63 | |||
64 | -- STATEMENT: begin 'expr' line=5 | ||
65 | prefixexp: <name> | ||
66 | str_checkname: 'foo' | ||
67 | singlevar: name='foo' | ||
68 | expr_stat: assignment k='VLOCAL' | ||
69 | assignment: '=' -- RHS elements follows | ||
70 | explist1: begin | ||
71 | expr: | ||
72 | subexpr: uop='-' | ||
73 | simpleexp: <number>=1 | ||
74 | explist1: end | ||
75 | -- STATEMENT: end 'expr' | ||
76 | |||
77 | -- STATEMENT: begin 'expr' line=6 | ||
78 | prefixexp: <name> | ||
79 | str_checkname: 'foo' | ||
80 | singlevar: name='foo' | ||
81 | expr_stat: assignment k='VLOCAL' | ||
82 | assignment: '=' -- RHS elements follows | ||
83 | explist1: begin | ||
84 | expr: | ||
85 | prefixexp: begin ( expr ) | ||
86 | expr: | ||
87 | simpleexp: <number>=0 | ||
88 | prefixexp: end ( expr ) | ||
89 | explist1: end | ||
90 | -- STATEMENT: end 'expr' | ||
91 | |||
92 | -- STATEMENT: begin 'expr' line=7 | ||
93 | prefixexp: <name> | ||
94 | str_checkname: 'foo' | ||
95 | singlevar: name='foo' | ||
96 | expr_stat: assignment k='VLOCAL' | ||
97 | assignment: '=' -- RHS elements follows | ||
98 | explist1: begin | ||
99 | expr: | ||
100 | simpleexp: <number>=1 | ||
101 | subexpr: binop='+' | ||
102 | simpleexp: <number>=2 | ||
103 | subexpr: -- evaluate | ||
104 | explist1: end | ||
105 | -- STATEMENT: end 'expr' | ||
106 | |||
107 | -- STATEMENT: begin 'expr' line=8 | ||
108 | prefixexp: <name> | ||
109 | str_checkname: 'foo' | ||
110 | singlevar: name='foo' | ||
111 | expr_stat: assignment k='VLOCAL' | ||
112 | assignment: '=' -- RHS elements follows | ||
113 | explist1: begin | ||
114 | expr: | ||
115 | simpleexp: <number>=1 | ||
116 | subexpr: binop='+' | ||
117 | simpleexp: <number>=2 | ||
118 | subexpr: binop='*' | ||
119 | simpleexp: <number>=3 | ||
120 | subexpr: -- evaluate | ||
121 | subexpr: -- evaluate | ||
122 | subexpr: binop='-' | ||
123 | simpleexp: <number>=4 | ||
124 | subexpr: binop='/' | ||
125 | simpleexp: <number>=5 | ||
126 | subexpr: -- evaluate | ||
127 | subexpr: -- evaluate | ||
128 | explist1: end | ||
129 | -- STATEMENT: end 'expr' | ||
130 | |||
131 | close_func | ||
132 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | if foo then foo=1 end | ||
3 | if foo then foo=1 else foo=0 end | ||
4 | if foo then foo=1 elseif not foo then foo=0 end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'if' line=1 | ||
12 | if_stat: if...then | ||
13 | test_then_block: test condition | ||
14 | cond: begin | ||
15 | expr: | ||
16 | prefixexp: <name> | ||
17 | str_checkname: 'foo' | ||
18 | singlevar: name='foo' | ||
19 | cond: end | ||
20 | test_then_block: then block | ||
21 | block: begin | ||
22 | enterblock(isbreakable=false) | ||
23 | chunk: | ||
24 | -- STATEMENT: begin 'expr' line=1 | ||
25 | prefixexp: <name> | ||
26 | str_checkname: 'foo' | ||
27 | singlevar: name='foo' | ||
28 | expr_stat: assignment k='VLOCAL' | ||
29 | assignment: '=' -- RHS elements follows | ||
30 | explist1: begin | ||
31 | expr: | ||
32 | simpleexp: <number>=1 | ||
33 | explist1: end | ||
34 | -- STATEMENT: end 'expr' | ||
35 | |||
36 | leaveblock | ||
37 | block: end | ||
38 | if_stat: end | ||
39 | -- STATEMENT: end 'if' | ||
40 | |||
41 | -- STATEMENT: begin 'if' line=2 | ||
42 | if_stat: if...then | ||
43 | test_then_block: test condition | ||
44 | cond: begin | ||
45 | expr: | ||
46 | prefixexp: <name> | ||
47 | str_checkname: 'foo' | ||
48 | singlevar: name='foo' | ||
49 | cond: end | ||
50 | test_then_block: then block | ||
51 | block: begin | ||
52 | enterblock(isbreakable=false) | ||
53 | chunk: | ||
54 | -- STATEMENT: begin 'expr' line=2 | ||
55 | prefixexp: <name> | ||
56 | str_checkname: 'foo' | ||
57 | singlevar: name='foo' | ||
58 | expr_stat: assignment k='VLOCAL' | ||
59 | assignment: '=' -- RHS elements follows | ||
60 | explist1: begin | ||
61 | expr: | ||
62 | simpleexp: <number>=1 | ||
63 | explist1: end | ||
64 | -- STATEMENT: end 'expr' | ||
65 | |||
66 | leaveblock | ||
67 | block: end | ||
68 | if_stat: else... | ||
69 | block: begin | ||
70 | enterblock(isbreakable=false) | ||
71 | chunk: | ||
72 | -- STATEMENT: begin 'expr' line=2 | ||
73 | prefixexp: <name> | ||
74 | str_checkname: 'foo' | ||
75 | singlevar: name='foo' | ||
76 | expr_stat: assignment k='VLOCAL' | ||
77 | assignment: '=' -- RHS elements follows | ||
78 | explist1: begin | ||
79 | expr: | ||
80 | simpleexp: <number>=0 | ||
81 | explist1: end | ||
82 | -- STATEMENT: end 'expr' | ||
83 | |||
84 | leaveblock | ||
85 | block: end | ||
86 | if_stat: end | ||
87 | -- STATEMENT: end 'if' | ||
88 | |||
89 | -- STATEMENT: begin 'if' line=3 | ||
90 | if_stat: if...then | ||
91 | test_then_block: test condition | ||
92 | cond: begin | ||
93 | expr: | ||
94 | prefixexp: <name> | ||
95 | str_checkname: 'foo' | ||
96 | singlevar: name='foo' | ||
97 | cond: end | ||
98 | test_then_block: then block | ||
99 | block: begin | ||
100 | enterblock(isbreakable=false) | ||
101 | chunk: | ||
102 | -- STATEMENT: begin 'expr' line=3 | ||
103 | prefixexp: <name> | ||
104 | str_checkname: 'foo' | ||
105 | singlevar: name='foo' | ||
106 | expr_stat: assignment k='VLOCAL' | ||
107 | assignment: '=' -- RHS elements follows | ||
108 | explist1: begin | ||
109 | expr: | ||
110 | simpleexp: <number>=1 | ||
111 | explist1: end | ||
112 | -- STATEMENT: end 'expr' | ||
113 | |||
114 | leaveblock | ||
115 | block: end | ||
116 | if_stat: elseif...then | ||
117 | test_then_block: test condition | ||
118 | cond: begin | ||
119 | expr: | ||
120 | subexpr: uop='not' | ||
121 | prefixexp: <name> | ||
122 | str_checkname: 'foo' | ||
123 | singlevar: name='foo' | ||
124 | cond: end | ||
125 | test_then_block: then block | ||
126 | block: begin | ||
127 | enterblock(isbreakable=false) | ||
128 | chunk: | ||
129 | -- STATEMENT: begin 'expr' line=3 | ||
130 | prefixexp: <name> | ||
131 | str_checkname: 'foo' | ||
132 | singlevar: name='foo' | ||
133 | expr_stat: assignment k='VLOCAL' | ||
134 | assignment: '=' -- RHS elements follows | ||
135 | explist1: begin | ||
136 | expr: | ||
137 | simpleexp: <number>=0 | ||
138 | explist1: end | ||
139 | -- STATEMENT: end 'expr' | ||
140 | |||
141 | leaveblock | ||
142 | block: end | ||
143 | if_stat: end | ||
144 | -- STATEMENT: end 'if' | ||
145 | |||
146 | close_func | ||
147 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do return end | ||
3 | do return 123 end | ||
4 | do return "foo","bar" end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'do' line=1 | ||
12 | do_stat: begin | ||
13 | block: begin | ||
14 | enterblock(isbreakable=false) | ||
15 | chunk: | ||
16 | -- STATEMENT: begin 'return' line=1 | ||
17 | return_stat: no return values | ||
18 | -- STATEMENT: end 'return' | ||
19 | leaveblock | ||
20 | block: end | ||
21 | do_stat: end | ||
22 | -- STATEMENT: end 'do' | ||
23 | |||
24 | -- STATEMENT: begin 'do' line=2 | ||
25 | do_stat: begin | ||
26 | block: begin | ||
27 | enterblock(isbreakable=false) | ||
28 | chunk: | ||
29 | -- STATEMENT: begin 'return' line=2 | ||
30 | return_stat: begin | ||
31 | explist1: begin | ||
32 | expr: | ||
33 | simpleexp: <number>=123 | ||
34 | explist1: end | ||
35 | return_stat: end | ||
36 | -- STATEMENT: end 'return' | ||
37 | leaveblock | ||
38 | block: end | ||
39 | do_stat: end | ||
40 | -- STATEMENT: end 'do' | ||
41 | |||
42 | -- STATEMENT: begin 'do' line=3 | ||
43 | do_stat: begin | ||
44 | block: begin | ||
45 | enterblock(isbreakable=false) | ||
46 | chunk: | ||
47 | -- STATEMENT: begin 'return' line=3 | ||
48 | return_stat: begin | ||
49 | explist1: begin | ||
50 | expr: | ||
51 | simpleexp: <string>=foo | ||
52 | codestring: "foo" | ||
53 | explist1: ',' -- continuation | ||
54 | expr: | ||
55 | simpleexp: <string>=bar | ||
56 | codestring: "bar" | ||
57 | explist1: end | ||
58 | return_stat: end | ||
59 | -- STATEMENT: end 'return' | ||
60 | leaveblock | ||
61 | block: end | ||
62 | do_stat: end | ||
63 | -- STATEMENT: end 'do' | ||
64 | |||
65 | close_func | ||
66 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | while true do foo=not foo end | ||
3 | while foo~=42 do foo=foo-1 end | ||
4 | while true do break end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'while' line=1 | ||
12 | while_stat: begin/condition | ||
13 | expr: | ||
14 | simpleexp: true | ||
15 | enterblock(isbreakable=true) | ||
16 | while_stat: block | ||
17 | block: begin | ||
18 | enterblock(isbreakable=false) | ||
19 | chunk: | ||
20 | -- STATEMENT: begin 'expr' line=1 | ||
21 | prefixexp: <name> | ||
22 | str_checkname: 'foo' | ||
23 | singlevar: name='foo' | ||
24 | expr_stat: assignment k='VLOCAL' | ||
25 | assignment: '=' -- RHS elements follows | ||
26 | explist1: begin | ||
27 | expr: | ||
28 | subexpr: uop='not' | ||
29 | prefixexp: <name> | ||
30 | str_checkname: 'foo' | ||
31 | singlevar: name='foo' | ||
32 | explist1: end | ||
33 | -- STATEMENT: end 'expr' | ||
34 | |||
35 | leaveblock | ||
36 | block: end | ||
37 | leaveblock | ||
38 | while_stat: end | ||
39 | -- STATEMENT: end 'while' | ||
40 | |||
41 | -- STATEMENT: begin 'while' line=2 | ||
42 | while_stat: begin/condition | ||
43 | expr: | ||
44 | prefixexp: <name> | ||
45 | str_checkname: 'foo' | ||
46 | singlevar: name='foo' | ||
47 | subexpr: binop='~=' | ||
48 | simpleexp: <number>=42 | ||
49 | subexpr: -- evaluate | ||
50 | enterblock(isbreakable=true) | ||
51 | while_stat: block | ||
52 | block: begin | ||
53 | enterblock(isbreakable=false) | ||
54 | chunk: | ||
55 | -- STATEMENT: begin 'expr' line=2 | ||
56 | prefixexp: <name> | ||
57 | str_checkname: 'foo' | ||
58 | singlevar: name='foo' | ||
59 | expr_stat: assignment k='VLOCAL' | ||
60 | assignment: '=' -- RHS elements follows | ||
61 | explist1: begin | ||
62 | expr: | ||
63 | prefixexp: <name> | ||
64 | str_checkname: 'foo' | ||
65 | singlevar: name='foo' | ||
66 | subexpr: binop='-' | ||
67 | simpleexp: <number>=1 | ||
68 | subexpr: -- evaluate | ||
69 | explist1: end | ||
70 | -- STATEMENT: end 'expr' | ||
71 | |||
72 | leaveblock | ||
73 | block: end | ||
74 | leaveblock | ||
75 | while_stat: end | ||
76 | -- STATEMENT: end 'while' | ||
77 | |||
78 | -- STATEMENT: begin 'while' line=3 | ||
79 | while_stat: begin/condition | ||
80 | expr: | ||
81 | simpleexp: true | ||
82 | enterblock(isbreakable=true) | ||
83 | while_stat: block | ||
84 | block: begin | ||
85 | enterblock(isbreakable=false) | ||
86 | chunk: | ||
87 | -- STATEMENT: begin 'break' line=3 | ||
88 | break_stat: -- break out of loop | ||
89 | -- STATEMENT: end 'break' | ||
90 | leaveblock | ||
91 | block: end | ||
92 | leaveblock | ||
93 | while_stat: end | ||
94 | -- STATEMENT: end 'while' | ||
95 | |||
96 | close_func | ||
97 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | repeat foo=foo.."bar" until false | ||
3 | repeat foo=foo/2 until foo<1 | ||
4 | repeat break until false | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'repeat' line=1 | ||
12 | repeat_stat: begin | ||
13 | enterblock(isbreakable=true) | ||
14 | block: begin | ||
15 | enterblock(isbreakable=false) | ||
16 | chunk: | ||
17 | -- STATEMENT: begin 'expr' line=1 | ||
18 | prefixexp: <name> | ||
19 | str_checkname: 'foo' | ||
20 | singlevar: name='foo' | ||
21 | expr_stat: assignment k='VLOCAL' | ||
22 | assignment: '=' -- RHS elements follows | ||
23 | explist1: begin | ||
24 | expr: | ||
25 | prefixexp: <name> | ||
26 | str_checkname: 'foo' | ||
27 | singlevar: name='foo' | ||
28 | subexpr: binop='..' | ||
29 | simpleexp: <string>=bar | ||
30 | codestring: "bar" | ||
31 | subexpr: -- evaluate | ||
32 | explist1: end | ||
33 | -- STATEMENT: end 'expr' | ||
34 | |||
35 | leaveblock | ||
36 | block: end | ||
37 | repeat_stat: condition | ||
38 | cond: begin | ||
39 | expr: | ||
40 | simpleexp: false | ||
41 | cond: end | ||
42 | leaveblock | ||
43 | repeat_stat: end | ||
44 | -- STATEMENT: end 'repeat' | ||
45 | |||
46 | -- STATEMENT: begin 'repeat' line=2 | ||
47 | repeat_stat: begin | ||
48 | enterblock(isbreakable=true) | ||
49 | block: begin | ||
50 | enterblock(isbreakable=false) | ||
51 | chunk: | ||
52 | -- STATEMENT: begin 'expr' line=2 | ||
53 | prefixexp: <name> | ||
54 | str_checkname: 'foo' | ||
55 | singlevar: name='foo' | ||
56 | expr_stat: assignment k='VLOCAL' | ||
57 | assignment: '=' -- RHS elements follows | ||
58 | explist1: begin | ||
59 | expr: | ||
60 | prefixexp: <name> | ||
61 | str_checkname: 'foo' | ||
62 | singlevar: name='foo' | ||
63 | subexpr: binop='/' | ||
64 | simpleexp: <number>=2 | ||
65 | subexpr: -- evaluate | ||
66 | explist1: end | ||
67 | -- STATEMENT: end 'expr' | ||
68 | |||
69 | leaveblock | ||
70 | block: end | ||
71 | repeat_stat: condition | ||
72 | cond: begin | ||
73 | expr: | ||
74 | prefixexp: <name> | ||
75 | str_checkname: 'foo' | ||
76 | singlevar: name='foo' | ||
77 | subexpr: binop='<' | ||
78 | simpleexp: <number>=1 | ||
79 | subexpr: -- evaluate | ||
80 | cond: end | ||
81 | leaveblock | ||
82 | repeat_stat: end | ||
83 | -- STATEMENT: end 'repeat' | ||
84 | |||
85 | -- STATEMENT: begin 'repeat' line=3 | ||
86 | repeat_stat: begin | ||
87 | enterblock(isbreakable=true) | ||
88 | block: begin | ||
89 | enterblock(isbreakable=false) | ||
90 | chunk: | ||
91 | -- STATEMENT: begin 'break' line=3 | ||
92 | break_stat: -- break out of loop | ||
93 | -- STATEMENT: end 'break' | ||
94 | leaveblock | ||
95 | block: end | ||
96 | repeat_stat: condition | ||
97 | cond: begin | ||
98 | expr: | ||
99 | simpleexp: false | ||
100 | cond: end | ||
101 | leaveblock | ||
102 | repeat_stat: end | ||
103 | -- STATEMENT: end 'repeat' | ||
104 | |||
105 | close_func | ||
106 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | for i=1,10 do foo=i end | ||
3 | for i=1,10,2 do break end | ||
4 | for i in foo do bar=0 end | ||
5 | for i,j in foo,bar do baz=0 end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'for' line=1 | ||
13 | for_stat: begin | ||
14 | enterblock(isbreakable=false) | ||
15 | str_checkname: 'i' | ||
16 | for_stat: numerical loop | ||
17 | fornum: begin | ||
18 | fornum: index start | ||
19 | exp1: begin | ||
20 | expr: | ||
21 | simpleexp: <number>=1 | ||
22 | exp1: end | ||
23 | fornum: index stop | ||
24 | exp1: begin | ||
25 | expr: | ||
26 | simpleexp: <number>=10 | ||
27 | exp1: end | ||
28 | fornum: body | ||
29 | enterblock(isbreakable=true) | ||
30 | block: begin | ||
31 | enterblock(isbreakable=false) | ||
32 | chunk: | ||
33 | -- STATEMENT: begin 'expr' line=1 | ||
34 | prefixexp: <name> | ||
35 | str_checkname: 'foo' | ||
36 | singlevar: name='foo' | ||
37 | expr_stat: assignment k='VLOCAL' | ||
38 | assignment: '=' -- RHS elements follows | ||
39 | explist1: begin | ||
40 | expr: | ||
41 | prefixexp: <name> | ||
42 | str_checkname: 'i' | ||
43 | singlevar: name='i' | ||
44 | explist1: end | ||
45 | -- STATEMENT: end 'expr' | ||
46 | |||
47 | leaveblock | ||
48 | block: end | ||
49 | leaveblock | ||
50 | fornum: end | ||
51 | leaveblock | ||
52 | for_stat: end | ||
53 | -- STATEMENT: end 'for' | ||
54 | |||
55 | -- STATEMENT: begin 'for' line=2 | ||
56 | for_stat: begin | ||
57 | enterblock(isbreakable=false) | ||
58 | str_checkname: 'i' | ||
59 | for_stat: numerical loop | ||
60 | fornum: begin | ||
61 | fornum: index start | ||
62 | exp1: begin | ||
63 | expr: | ||
64 | simpleexp: <number>=1 | ||
65 | exp1: end | ||
66 | fornum: index stop | ||
67 | exp1: begin | ||
68 | expr: | ||
69 | simpleexp: <number>=10 | ||
70 | exp1: end | ||
71 | fornum: index step | ||
72 | exp1: begin | ||
73 | expr: | ||
74 | simpleexp: <number>=2 | ||
75 | exp1: end | ||
76 | fornum: body | ||
77 | enterblock(isbreakable=true) | ||
78 | block: begin | ||
79 | enterblock(isbreakable=false) | ||
80 | chunk: | ||
81 | -- STATEMENT: begin 'break' line=2 | ||
82 | break_stat: -- break out of loop | ||
83 | -- STATEMENT: end 'break' | ||
84 | leaveblock | ||
85 | block: end | ||
86 | leaveblock | ||
87 | fornum: end | ||
88 | leaveblock | ||
89 | for_stat: end | ||
90 | -- STATEMENT: end 'for' | ||
91 | |||
92 | -- STATEMENT: begin 'for' line=3 | ||
93 | for_stat: begin | ||
94 | enterblock(isbreakable=false) | ||
95 | str_checkname: 'i' | ||
96 | for_stat: list-based loop | ||
97 | forlist: begin | ||
98 | forlist: explist1 | ||
99 | explist1: begin | ||
100 | expr: | ||
101 | prefixexp: <name> | ||
102 | str_checkname: 'foo' | ||
103 | singlevar: name='foo' | ||
104 | explist1: end | ||
105 | forlist: body | ||
106 | enterblock(isbreakable=true) | ||
107 | block: begin | ||
108 | enterblock(isbreakable=false) | ||
109 | chunk: | ||
110 | -- STATEMENT: begin 'expr' line=3 | ||
111 | prefixexp: <name> | ||
112 | str_checkname: 'bar' | ||
113 | singlevar: name='bar' | ||
114 | expr_stat: assignment k='VLOCAL' | ||
115 | assignment: '=' -- RHS elements follows | ||
116 | explist1: begin | ||
117 | expr: | ||
118 | simpleexp: <number>=0 | ||
119 | explist1: end | ||
120 | -- STATEMENT: end 'expr' | ||
121 | |||
122 | leaveblock | ||
123 | block: end | ||
124 | leaveblock | ||
125 | forlist: end | ||
126 | leaveblock | ||
127 | for_stat: end | ||
128 | -- STATEMENT: end 'for' | ||
129 | |||
130 | -- STATEMENT: begin 'for' line=4 | ||
131 | for_stat: begin | ||
132 | enterblock(isbreakable=false) | ||
133 | str_checkname: 'i' | ||
134 | for_stat: list-based loop | ||
135 | forlist: begin | ||
136 | str_checkname: 'j' | ||
137 | forlist: explist1 | ||
138 | explist1: begin | ||
139 | expr: | ||
140 | prefixexp: <name> | ||
141 | str_checkname: 'foo' | ||
142 | singlevar: name='foo' | ||
143 | explist1: ',' -- continuation | ||
144 | expr: | ||
145 | prefixexp: <name> | ||
146 | str_checkname: 'bar' | ||
147 | singlevar: name='bar' | ||
148 | explist1: end | ||
149 | forlist: body | ||
150 | enterblock(isbreakable=true) | ||
151 | block: begin | ||
152 | enterblock(isbreakable=false) | ||
153 | chunk: | ||
154 | -- STATEMENT: begin 'expr' line=4 | ||
155 | prefixexp: <name> | ||
156 | str_checkname: 'baz' | ||
157 | singlevar: name='baz' | ||
158 | expr_stat: assignment k='VLOCAL' | ||
159 | assignment: '=' -- RHS elements follows | ||
160 | explist1: begin | ||
161 | expr: | ||
162 | simpleexp: <number>=0 | ||
163 | explist1: end | ||
164 | -- STATEMENT: end 'expr' | ||
165 | |||
166 | leaveblock | ||
167 | block: end | ||
168 | leaveblock | ||
169 | forlist: end | ||
170 | leaveblock | ||
171 | for_stat: end | ||
172 | -- STATEMENT: end 'for' | ||
173 | |||
174 | close_func | ||
175 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local foo | ||
3 | local foo,bar,baz | ||
4 | local foo,bar="foo","bar" | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'local' line=1 | ||
12 | local_stat: local statement | ||
13 | localstat: begin | ||
14 | str_checkname: 'foo' | ||
15 | localstat: end | ||
16 | -- STATEMENT: end 'local' | ||
17 | |||
18 | -- STATEMENT: begin 'local' line=2 | ||
19 | local_stat: local statement | ||
20 | localstat: begin | ||
21 | str_checkname: 'foo' | ||
22 | str_checkname: 'bar' | ||
23 | str_checkname: 'baz' | ||
24 | localstat: end | ||
25 | -- STATEMENT: end 'local' | ||
26 | |||
27 | -- STATEMENT: begin 'local' line=3 | ||
28 | local_stat: local statement | ||
29 | localstat: begin | ||
30 | str_checkname: 'foo' | ||
31 | str_checkname: 'bar' | ||
32 | localstat: -- assignment | ||
33 | explist1: begin | ||
34 | expr: | ||
35 | simpleexp: <string>=foo | ||
36 | codestring: "foo" | ||
37 | explist1: ',' -- continuation | ||
38 | expr: | ||
39 | simpleexp: <string>=bar | ||
40 | codestring: "bar" | ||
41 | explist1: end | ||
42 | localstat: end | ||
43 | -- STATEMENT: end 'local' | ||
44 | |||
45 | close_func | ||
46 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local function foo() return end | ||
3 | local function foo(a) return end | ||
4 | local function foo(x,y,z) return end | ||
5 | local function foo(x,...) return end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'local' line=1 | ||
13 | local_stat: local function | ||
14 | localfunc: begin | ||
15 | str_checkname: 'foo' | ||
16 | localfunc: body | ||
17 | open_func | ||
18 | body: begin | ||
19 | body: parlist | ||
20 | parlist: begin | ||
21 | parlist: end | ||
22 | body: chunk | ||
23 | chunk: | ||
24 | -- STATEMENT: begin 'return' line=1 | ||
25 | return_stat: no return values | ||
26 | -- STATEMENT: end 'return' | ||
27 | body: end | ||
28 | close_func | ||
29 | localfunc: end | ||
30 | -- STATEMENT: end 'local' | ||
31 | |||
32 | -- STATEMENT: begin 'local' line=2 | ||
33 | local_stat: local function | ||
34 | localfunc: begin | ||
35 | str_checkname: 'foo' | ||
36 | localfunc: body | ||
37 | open_func | ||
38 | body: begin | ||
39 | body: parlist | ||
40 | parlist: begin | ||
41 | str_checkname: 'a' | ||
42 | parlist: end | ||
43 | body: chunk | ||
44 | chunk: | ||
45 | -- STATEMENT: begin 'return' line=2 | ||
46 | return_stat: no return values | ||
47 | -- STATEMENT: end 'return' | ||
48 | body: end | ||
49 | close_func | ||
50 | localfunc: end | ||
51 | -- STATEMENT: end 'local' | ||
52 | |||
53 | -- STATEMENT: begin 'local' line=3 | ||
54 | local_stat: local function | ||
55 | localfunc: begin | ||
56 | str_checkname: 'foo' | ||
57 | localfunc: body | ||
58 | open_func | ||
59 | body: begin | ||
60 | body: parlist | ||
61 | parlist: begin | ||
62 | str_checkname: 'x' | ||
63 | str_checkname: 'y' | ||
64 | str_checkname: 'z' | ||
65 | parlist: end | ||
66 | body: chunk | ||
67 | chunk: | ||
68 | -- STATEMENT: begin 'return' line=3 | ||
69 | return_stat: no return values | ||
70 | -- STATEMENT: end 'return' | ||
71 | body: end | ||
72 | close_func | ||
73 | localfunc: end | ||
74 | -- STATEMENT: end 'local' | ||
75 | |||
76 | -- STATEMENT: begin 'local' line=4 | ||
77 | local_stat: local function | ||
78 | localfunc: begin | ||
79 | str_checkname: 'foo' | ||
80 | localfunc: body | ||
81 | open_func | ||
82 | body: begin | ||
83 | body: parlist | ||
84 | parlist: begin | ||
85 | str_checkname: 'x' | ||
86 | parlist: ... (dots) | ||
87 | parlist: end | ||
88 | body: chunk | ||
89 | chunk: | ||
90 | -- STATEMENT: begin 'return' line=4 | ||
91 | return_stat: no return values | ||
92 | -- STATEMENT: end 'return' | ||
93 | body: end | ||
94 | close_func | ||
95 | localfunc: end | ||
96 | -- STATEMENT: end 'local' | ||
97 | |||
98 | close_func | ||
99 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo() return end | ||
3 | function foo(a) return end | ||
4 | function foo(x,y,z) return end | ||
5 | function foo(x,...) return end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'function' line=1 | ||
13 | function_stat: begin | ||
14 | funcname: begin | ||
15 | str_checkname: 'foo' | ||
16 | singlevar: name='foo' | ||
17 | funcname: end | ||
18 | function_stat: body needself='false' | ||
19 | open_func | ||
20 | body: begin | ||
21 | body: parlist | ||
22 | parlist: begin | ||
23 | parlist: end | ||
24 | body: chunk | ||
25 | chunk: | ||
26 | -- STATEMENT: begin 'return' line=1 | ||
27 | return_stat: no return values | ||
28 | -- STATEMENT: end 'return' | ||
29 | body: end | ||
30 | close_func | ||
31 | function_stat: end | ||
32 | -- STATEMENT: end 'function' | ||
33 | |||
34 | -- STATEMENT: begin 'function' line=2 | ||
35 | function_stat: begin | ||
36 | funcname: begin | ||
37 | str_checkname: 'foo' | ||
38 | singlevar: name='foo' | ||
39 | funcname: end | ||
40 | function_stat: body needself='false' | ||
41 | open_func | ||
42 | body: begin | ||
43 | body: parlist | ||
44 | parlist: begin | ||
45 | str_checkname: 'a' | ||
46 | parlist: end | ||
47 | body: chunk | ||
48 | chunk: | ||
49 | -- STATEMENT: begin 'return' line=2 | ||
50 | return_stat: no return values | ||
51 | -- STATEMENT: end 'return' | ||
52 | body: end | ||
53 | close_func | ||
54 | function_stat: end | ||
55 | -- STATEMENT: end 'function' | ||
56 | |||
57 | -- STATEMENT: begin 'function' line=3 | ||
58 | function_stat: begin | ||
59 | funcname: begin | ||
60 | str_checkname: 'foo' | ||
61 | singlevar: name='foo' | ||
62 | funcname: end | ||
63 | function_stat: body needself='false' | ||
64 | open_func | ||
65 | body: begin | ||
66 | body: parlist | ||
67 | parlist: begin | ||
68 | str_checkname: 'x' | ||
69 | str_checkname: 'y' | ||
70 | str_checkname: 'z' | ||
71 | parlist: end | ||
72 | body: chunk | ||
73 | chunk: | ||
74 | -- STATEMENT: begin 'return' line=3 | ||
75 | return_stat: no return values | ||
76 | -- STATEMENT: end 'return' | ||
77 | body: end | ||
78 | close_func | ||
79 | function_stat: end | ||
80 | -- STATEMENT: end 'function' | ||
81 | |||
82 | -- STATEMENT: begin 'function' line=4 | ||
83 | function_stat: begin | ||
84 | funcname: begin | ||
85 | str_checkname: 'foo' | ||
86 | singlevar: name='foo' | ||
87 | funcname: end | ||
88 | function_stat: body needself='false' | ||
89 | open_func | ||
90 | body: begin | ||
91 | body: parlist | ||
92 | parlist: begin | ||
93 | str_checkname: 'x' | ||
94 | parlist: ... (dots) | ||
95 | parlist: end | ||
96 | body: chunk | ||
97 | chunk: | ||
98 | -- STATEMENT: begin 'return' line=4 | ||
99 | return_stat: no return values | ||
100 | -- STATEMENT: end 'return' | ||
101 | body: end | ||
102 | close_func | ||
103 | function_stat: end | ||
104 | -- STATEMENT: end 'function' | ||
105 | |||
106 | close_func | ||
107 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo.bar(p) return end | ||
3 | function foo.bar.baz(p) return end | ||
4 | function foo:bar(p) return end | ||
5 | function foo.bar.baz(p) return end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'function' line=1 | ||
13 | function_stat: begin | ||
14 | funcname: begin | ||
15 | str_checkname: 'foo' | ||
16 | singlevar: name='foo' | ||
17 | funcname: -- '.' field | ||
18 | field: operator=. | ||
19 | checkname: | ||
20 | str_checkname: 'bar' | ||
21 | codestring: "bar" | ||
22 | funcname: end | ||
23 | function_stat: body needself='false' | ||
24 | open_func | ||
25 | body: begin | ||
26 | body: parlist | ||
27 | parlist: begin | ||
28 | str_checkname: 'p' | ||
29 | parlist: end | ||
30 | body: chunk | ||
31 | chunk: | ||
32 | -- STATEMENT: begin 'return' line=1 | ||
33 | return_stat: no return values | ||
34 | -- STATEMENT: end 'return' | ||
35 | body: end | ||
36 | close_func | ||
37 | function_stat: end | ||
38 | -- STATEMENT: end 'function' | ||
39 | |||
40 | -- STATEMENT: begin 'function' line=2 | ||
41 | function_stat: begin | ||
42 | funcname: begin | ||
43 | str_checkname: 'foo' | ||
44 | singlevar: name='foo' | ||
45 | funcname: -- '.' field | ||
46 | field: operator=. | ||
47 | checkname: | ||
48 | str_checkname: 'bar' | ||
49 | codestring: "bar" | ||
50 | funcname: -- '.' field | ||
51 | field: operator=. | ||
52 | checkname: | ||
53 | str_checkname: 'baz' | ||
54 | codestring: "baz" | ||
55 | funcname: end | ||
56 | function_stat: body needself='false' | ||
57 | open_func | ||
58 | body: begin | ||
59 | body: parlist | ||
60 | parlist: begin | ||
61 | str_checkname: 'p' | ||
62 | parlist: end | ||
63 | body: chunk | ||
64 | chunk: | ||
65 | -- STATEMENT: begin 'return' line=2 | ||
66 | return_stat: no return values | ||
67 | -- STATEMENT: end 'return' | ||
68 | body: end | ||
69 | close_func | ||
70 | function_stat: end | ||
71 | -- STATEMENT: end 'function' | ||
72 | |||
73 | -- STATEMENT: begin 'function' line=3 | ||
74 | function_stat: begin | ||
75 | funcname: begin | ||
76 | str_checkname: 'foo' | ||
77 | singlevar: name='foo' | ||
78 | funcname: -- ':' field | ||
79 | field: operator=: | ||
80 | checkname: | ||
81 | str_checkname: 'bar' | ||
82 | codestring: "bar" | ||
83 | funcname: end | ||
84 | function_stat: body needself='true' | ||
85 | open_func | ||
86 | body: begin | ||
87 | body: parlist | ||
88 | parlist: begin | ||
89 | str_checkname: 'p' | ||
90 | parlist: end | ||
91 | body: chunk | ||
92 | chunk: | ||
93 | -- STATEMENT: begin 'return' line=3 | ||
94 | return_stat: no return values | ||
95 | -- STATEMENT: end 'return' | ||
96 | body: end | ||
97 | close_func | ||
98 | function_stat: end | ||
99 | -- STATEMENT: end 'function' | ||
100 | |||
101 | -- STATEMENT: begin 'function' line=4 | ||
102 | function_stat: begin | ||
103 | funcname: begin | ||
104 | str_checkname: 'foo' | ||
105 | singlevar: name='foo' | ||
106 | funcname: -- '.' field | ||
107 | field: operator=. | ||
108 | checkname: | ||
109 | str_checkname: 'bar' | ||
110 | codestring: "bar" | ||
111 | funcname: -- '.' field | ||
112 | field: operator=. | ||
113 | checkname: | ||
114 | str_checkname: 'baz' | ||
115 | codestring: "baz" | ||
116 | funcname: end | ||
117 | function_stat: body needself='false' | ||
118 | open_func | ||
119 | body: begin | ||
120 | body: parlist | ||
121 | parlist: begin | ||
122 | str_checkname: 'p' | ||
123 | parlist: end | ||
124 | body: chunk | ||
125 | chunk: | ||
126 | -- STATEMENT: begin 'return' line=4 | ||
127 | return_stat: no return values | ||
128 | -- STATEMENT: end 'return' | ||
129 | body: end | ||
130 | close_func | ||
131 | function_stat: end | ||
132 | -- STATEMENT: end 'function' | ||
133 | |||
134 | close_func | ||
135 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | foo = function() return end | ||
3 | foo = function(x,y) return end | ||
4 | foo = function(...) return end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'expr' line=1 | ||
12 | prefixexp: <name> | ||
13 | str_checkname: 'foo' | ||
14 | singlevar: name='foo' | ||
15 | expr_stat: assignment k='VLOCAL' | ||
16 | assignment: '=' -- RHS elements follows | ||
17 | explist1: begin | ||
18 | expr: | ||
19 | simpleexp: function | ||
20 | open_func | ||
21 | body: begin | ||
22 | body: parlist | ||
23 | parlist: begin | ||
24 | parlist: end | ||
25 | body: chunk | ||
26 | chunk: | ||
27 | -- STATEMENT: begin 'return' line=1 | ||
28 | return_stat: no return values | ||
29 | -- STATEMENT: end 'return' | ||
30 | body: end | ||
31 | close_func | ||
32 | explist1: end | ||
33 | -- STATEMENT: end 'expr' | ||
34 | |||
35 | -- STATEMENT: begin 'expr' line=2 | ||
36 | prefixexp: <name> | ||
37 | str_checkname: 'foo' | ||
38 | singlevar: name='foo' | ||
39 | expr_stat: assignment k='VLOCAL' | ||
40 | assignment: '=' -- RHS elements follows | ||
41 | explist1: begin | ||
42 | expr: | ||
43 | simpleexp: function | ||
44 | open_func | ||
45 | body: begin | ||
46 | body: parlist | ||
47 | parlist: begin | ||
48 | str_checkname: 'x' | ||
49 | str_checkname: 'y' | ||
50 | parlist: end | ||
51 | body: chunk | ||
52 | chunk: | ||
53 | -- STATEMENT: begin 'return' line=2 | ||
54 | return_stat: no return values | ||
55 | -- STATEMENT: end 'return' | ||
56 | body: end | ||
57 | close_func | ||
58 | explist1: end | ||
59 | -- STATEMENT: end 'expr' | ||
60 | |||
61 | -- STATEMENT: begin 'expr' line=3 | ||
62 | prefixexp: <name> | ||
63 | str_checkname: 'foo' | ||
64 | singlevar: name='foo' | ||
65 | expr_stat: assignment k='VLOCAL' | ||
66 | assignment: '=' -- RHS elements follows | ||
67 | explist1: begin | ||
68 | expr: | ||
69 | simpleexp: function | ||
70 | open_func | ||
71 | body: begin | ||
72 | body: parlist | ||
73 | parlist: begin | ||
74 | parlist: ... (dots) | ||
75 | parlist: end | ||
76 | body: chunk | ||
77 | chunk: | ||
78 | -- STATEMENT: begin 'return' line=3 | ||
79 | return_stat: no return values | ||
80 | -- STATEMENT: end 'return' | ||
81 | body: end | ||
82 | close_func | ||
83 | explist1: end | ||
84 | -- STATEMENT: end 'expr' | ||
85 | |||
86 | close_func | ||
87 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | foo = {} | ||
3 | foo = { 1,2,3; "foo"; } | ||
4 | foo = { bar=77, baz=88, } | ||
5 | foo = { ["bar"]=77, ["baz"]=88, } | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'expr' line=1 | ||
13 | prefixexp: <name> | ||
14 | str_checkname: 'foo' | ||
15 | singlevar: name='foo' | ||
16 | expr_stat: assignment k='VLOCAL' | ||
17 | assignment: '=' -- RHS elements follows | ||
18 | explist1: begin | ||
19 | expr: | ||
20 | simpleexp: constructor | ||
21 | constructor: begin | ||
22 | constructor: end | ||
23 | explist1: end | ||
24 | -- STATEMENT: end 'expr' | ||
25 | |||
26 | -- STATEMENT: begin 'expr' line=2 | ||
27 | prefixexp: <name> | ||
28 | str_checkname: 'foo' | ||
29 | singlevar: name='foo' | ||
30 | expr_stat: assignment k='VLOCAL' | ||
31 | assignment: '=' -- RHS elements follows | ||
32 | explist1: begin | ||
33 | expr: | ||
34 | simpleexp: constructor | ||
35 | constructor: begin | ||
36 | listfield: expr | ||
37 | expr: | ||
38 | simpleexp: <number>=1 | ||
39 | listfield: expr | ||
40 | expr: | ||
41 | simpleexp: <number>=2 | ||
42 | listfield: expr | ||
43 | expr: | ||
44 | simpleexp: <number>=3 | ||
45 | listfield: expr | ||
46 | expr: | ||
47 | simpleexp: <string>=foo | ||
48 | codestring: "foo" | ||
49 | constructor: end | ||
50 | explist1: end | ||
51 | -- STATEMENT: end 'expr' | ||
52 | |||
53 | -- STATEMENT: begin 'expr' line=3 | ||
54 | prefixexp: <name> | ||
55 | str_checkname: 'foo' | ||
56 | singlevar: name='foo' | ||
57 | expr_stat: assignment k='VLOCAL' | ||
58 | assignment: '=' -- RHS elements follows | ||
59 | explist1: begin | ||
60 | expr: | ||
61 | simpleexp: constructor | ||
62 | constructor: begin | ||
63 | recfield: name | ||
64 | checkname: | ||
65 | str_checkname: 'bar' | ||
66 | codestring: "bar" | ||
67 | expr: | ||
68 | simpleexp: <number>=77 | ||
69 | recfield: name | ||
70 | checkname: | ||
71 | str_checkname: 'baz' | ||
72 | codestring: "baz" | ||
73 | expr: | ||
74 | simpleexp: <number>=88 | ||
75 | constructor: end | ||
76 | explist1: end | ||
77 | -- STATEMENT: end 'expr' | ||
78 | |||
79 | -- STATEMENT: begin 'expr' line=4 | ||
80 | prefixexp: <name> | ||
81 | str_checkname: 'foo' | ||
82 | singlevar: name='foo' | ||
83 | expr_stat: assignment k='VLOCAL' | ||
84 | assignment: '=' -- RHS elements follows | ||
85 | explist1: begin | ||
86 | expr: | ||
87 | simpleexp: constructor | ||
88 | constructor: begin | ||
89 | recfield: [ exp1 ] | ||
90 | index: begin '[' | ||
91 | expr: | ||
92 | simpleexp: <string>=bar | ||
93 | codestring: "bar" | ||
94 | index: end ']' | ||
95 | expr: | ||
96 | simpleexp: <number>=77 | ||
97 | recfield: [ exp1 ] | ||
98 | index: begin '[' | ||
99 | expr: | ||
100 | simpleexp: <string>=baz | ||
101 | codestring: "baz" | ||
102 | index: end ']' | ||
103 | expr: | ||
104 | simpleexp: <number>=88 | ||
105 | constructor: end | ||
106 | explist1: end | ||
107 | -- STATEMENT: end 'expr' | ||
108 | |||
109 | close_func | ||
110 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | print(a) | ||
3 | -- END OF SOURCE -- | ||
4 | |||
5 | -- TOP: begin | ||
6 | open_func | ||
7 | |||
8 | chunk: | ||
9 | -- STATEMENT: begin 'expr' line=1 | ||
10 | prefixexp: <name> | ||
11 | str_checkname: 'print' | ||
12 | singlevar(kind): 'VGLOBAL' | ||
13 | primaryexp: ( funcargs | ||
14 | funcargs: begin '(' | ||
15 | explist1: begin | ||
16 | expr: | ||
17 | prefixexp: <name> | ||
18 | str_checkname: 'a' | ||
19 | singlevar(kind): 'VGLOBAL' | ||
20 | explist1: end | ||
21 | funcargs: end -- expr is a VCALL | ||
22 | expr_stat: function call k='VCALL' | ||
23 | -- STATEMENT: end 'expr' | ||
24 | |||
25 | close_func | ||
26 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local a | ||
3 | print(a) | ||
4 | -- END OF SOURCE -- | ||
5 | |||
6 | -- TOP: begin | ||
7 | open_func | ||
8 | |||
9 | chunk: | ||
10 | -- STATEMENT: begin 'local' line=1 | ||
11 | local_stat: local statement | ||
12 | localstat: begin | ||
13 | str_checkname: 'a' | ||
14 | new_localvar: 'a' | ||
15 | localstat: end | ||
16 | -- STATEMENT: end 'local' | ||
17 | |||
18 | -- STATEMENT: begin 'expr' line=2 | ||
19 | prefixexp: <name> | ||
20 | str_checkname: 'print' | ||
21 | singlevar(kind): 'VGLOBAL' | ||
22 | primaryexp: ( funcargs | ||
23 | funcargs: begin '(' | ||
24 | explist1: begin | ||
25 | expr: | ||
26 | prefixexp: <name> | ||
27 | str_checkname: 'a' | ||
28 | singlevar(kind): 'VLOCAL' | ||
29 | explist1: end | ||
30 | funcargs: end -- expr is a VCALL | ||
31 | expr_stat: function call k='VCALL' | ||
32 | -- STATEMENT: end 'expr' | ||
33 | |||
34 | close_func | ||
35 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do | ||
3 | local a | ||
4 | print(a) | ||
5 | end | ||
6 | print(a) | ||
7 | -- END OF SOURCE -- | ||
8 | |||
9 | -- TOP: begin | ||
10 | open_func | ||
11 | |||
12 | chunk: | ||
13 | -- STATEMENT: begin 'do' line=1 | ||
14 | do_stat: begin | ||
15 | block: begin | ||
16 | enterblock(isbreakable=false) | ||
17 | chunk: | ||
18 | -- STATEMENT: begin 'local' line=2 | ||
19 | local_stat: local statement | ||
20 | localstat: begin | ||
21 | str_checkname: 'a' | ||
22 | new_localvar: 'a' | ||
23 | localstat: end | ||
24 | -- STATEMENT: end 'local' | ||
25 | |||
26 | -- STATEMENT: begin 'expr' line=3 | ||
27 | prefixexp: <name> | ||
28 | str_checkname: 'print' | ||
29 | singlevar(kind): 'VGLOBAL' | ||
30 | primaryexp: ( funcargs | ||
31 | funcargs: begin '(' | ||
32 | explist1: begin | ||
33 | expr: | ||
34 | prefixexp: <name> | ||
35 | str_checkname: 'a' | ||
36 | singlevar(kind): 'VLOCAL' | ||
37 | explist1: end | ||
38 | funcargs: end -- expr is a VCALL | ||
39 | expr_stat: function call k='VCALL' | ||
40 | -- STATEMENT: end 'expr' | ||
41 | |||
42 | leaveblock | ||
43 | block: end | ||
44 | do_stat: end | ||
45 | -- STATEMENT: end 'do' | ||
46 | |||
47 | -- STATEMENT: begin 'expr' line=5 | ||
48 | prefixexp: <name> | ||
49 | str_checkname: 'print' | ||
50 | singlevar(kind): 'VGLOBAL' | ||
51 | primaryexp: ( funcargs | ||
52 | funcargs: begin '(' | ||
53 | explist1: begin | ||
54 | expr: | ||
55 | prefixexp: <name> | ||
56 | str_checkname: 'a' | ||
57 | singlevar(kind): 'VGLOBAL' | ||
58 | explist1: end | ||
59 | funcargs: end -- expr is a VCALL | ||
60 | expr_stat: function call k='VCALL' | ||
61 | -- STATEMENT: end 'expr' | ||
62 | |||
63 | close_func | ||
64 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local a,b,c | ||
3 | do | ||
4 | local b | ||
5 | print(b) | ||
6 | end | ||
7 | print(b) | ||
8 | -- END OF SOURCE -- | ||
9 | |||
10 | -- TOP: begin | ||
11 | open_func | ||
12 | |||
13 | chunk: | ||
14 | -- STATEMENT: begin 'local' line=1 | ||
15 | local_stat: local statement | ||
16 | localstat: begin | ||
17 | str_checkname: 'a' | ||
18 | new_localvar: 'a' | ||
19 | str_checkname: 'b' | ||
20 | new_localvar: 'b' | ||
21 | str_checkname: 'c' | ||
22 | new_localvar: 'c' | ||
23 | localstat: end | ||
24 | -- STATEMENT: end 'local' | ||
25 | |||
26 | -- STATEMENT: begin 'do' line=2 | ||
27 | do_stat: begin | ||
28 | block: begin | ||
29 | enterblock(isbreakable=false) | ||
30 | chunk: | ||
31 | -- STATEMENT: begin 'local' line=3 | ||
32 | local_stat: local statement | ||
33 | localstat: begin | ||
34 | str_checkname: 'b' | ||
35 | new_localvar: 'b' | ||
36 | localstat: end | ||
37 | -- STATEMENT: end 'local' | ||
38 | |||
39 | -- STATEMENT: begin 'expr' line=4 | ||
40 | prefixexp: <name> | ||
41 | str_checkname: 'print' | ||
42 | singlevar(kind): 'VGLOBAL' | ||
43 | primaryexp: ( funcargs | ||
44 | funcargs: begin '(' | ||
45 | explist1: begin | ||
46 | expr: | ||
47 | prefixexp: <name> | ||
48 | str_checkname: 'b' | ||
49 | singlevar(kind): 'VLOCAL' | ||
50 | explist1: end | ||
51 | funcargs: end -- expr is a VCALL | ||
52 | expr_stat: function call k='VCALL' | ||
53 | -- STATEMENT: end 'expr' | ||
54 | |||
55 | leaveblock | ||
56 | block: end | ||
57 | do_stat: end | ||
58 | -- STATEMENT: end 'do' | ||
59 | |||
60 | -- STATEMENT: begin 'expr' line=6 | ||
61 | prefixexp: <name> | ||
62 | str_checkname: 'print' | ||
63 | singlevar(kind): 'VGLOBAL' | ||
64 | primaryexp: ( funcargs | ||
65 | funcargs: begin '(' | ||
66 | explist1: begin | ||
67 | expr: | ||
68 | prefixexp: <name> | ||
69 | str_checkname: 'b' | ||
70 | singlevar(kind): 'VLOCAL' | ||
71 | explist1: end | ||
72 | funcargs: end -- expr is a VCALL | ||
73 | expr_stat: function call k='VCALL' | ||
74 | -- STATEMENT: end 'expr' | ||
75 | |||
76 | close_func | ||
77 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local function foo() end | ||
3 | bar = foo | ||
4 | -- END OF SOURCE -- | ||
5 | |||
6 | -- TOP: begin | ||
7 | open_func | ||
8 | |||
9 | chunk: | ||
10 | -- STATEMENT: begin 'local' line=1 | ||
11 | local_stat: local function | ||
12 | localfunc: begin | ||
13 | str_checkname: 'foo' | ||
14 | new_localvar: 'foo' | ||
15 | localfunc: body | ||
16 | open_func | ||
17 | body: begin | ||
18 | body: parlist | ||
19 | parlist: begin | ||
20 | parlist: end | ||
21 | body: chunk | ||
22 | chunk: | ||
23 | body: end | ||
24 | close_func | ||
25 | localfunc: end | ||
26 | -- STATEMENT: end 'local' | ||
27 | |||
28 | -- STATEMENT: begin 'expr' line=2 | ||
29 | prefixexp: <name> | ||
30 | str_checkname: 'bar' | ||
31 | singlevar(kind): 'VGLOBAL' | ||
32 | expr_stat: assignment k='VGLOBAL' | ||
33 | assignment: '=' -- RHS elements follows | ||
34 | explist1: begin | ||
35 | expr: | ||
36 | prefixexp: <name> | ||
37 | str_checkname: 'foo' | ||
38 | singlevar(kind): 'VLOCAL' | ||
39 | explist1: end | ||
40 | -- STATEMENT: end 'expr' | ||
41 | |||
42 | close_func | ||
43 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do | ||
3 | local function foo() end | ||
4 | bar = foo | ||
5 | end | ||
6 | baz = foo | ||
7 | -- END OF SOURCE -- | ||
8 | |||
9 | -- TOP: begin | ||
10 | open_func | ||
11 | |||
12 | chunk: | ||
13 | -- STATEMENT: begin 'do' line=1 | ||
14 | do_stat: begin | ||
15 | block: begin | ||
16 | enterblock(isbreakable=false) | ||
17 | chunk: | ||
18 | -- STATEMENT: begin 'local' line=2 | ||
19 | local_stat: local function | ||
20 | localfunc: begin | ||
21 | str_checkname: 'foo' | ||
22 | new_localvar: 'foo' | ||
23 | localfunc: body | ||
24 | open_func | ||
25 | body: begin | ||
26 | body: parlist | ||
27 | parlist: begin | ||
28 | parlist: end | ||
29 | body: chunk | ||
30 | chunk: | ||
31 | body: end | ||
32 | close_func | ||
33 | localfunc: end | ||
34 | -- STATEMENT: end 'local' | ||
35 | |||
36 | -- STATEMENT: begin 'expr' line=3 | ||
37 | prefixexp: <name> | ||
38 | str_checkname: 'bar' | ||
39 | singlevar(kind): 'VGLOBAL' | ||
40 | expr_stat: assignment k='VGLOBAL' | ||
41 | assignment: '=' -- RHS elements follows | ||
42 | explist1: begin | ||
43 | expr: | ||
44 | prefixexp: <name> | ||
45 | str_checkname: 'foo' | ||
46 | singlevar(kind): 'VLOCAL' | ||
47 | explist1: end | ||
48 | -- STATEMENT: end 'expr' | ||
49 | |||
50 | leaveblock | ||
51 | block: end | ||
52 | do_stat: end | ||
53 | -- STATEMENT: end 'do' | ||
54 | |||
55 | -- STATEMENT: begin 'expr' line=5 | ||
56 | prefixexp: <name> | ||
57 | str_checkname: 'baz' | ||
58 | singlevar(kind): 'VGLOBAL' | ||
59 | expr_stat: assignment k='VGLOBAL' | ||
60 | assignment: '=' -- RHS elements follows | ||
61 | explist1: begin | ||
62 | expr: | ||
63 | prefixexp: <name> | ||
64 | str_checkname: 'foo' | ||
65 | singlevar(kind): 'VGLOBAL' | ||
66 | explist1: end | ||
67 | -- STATEMENT: end 'expr' | ||
68 | |||
69 | close_func | ||
70 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local foo | ||
3 | local function bar() | ||
4 | baz = nil | ||
5 | foo = bar() | ||
6 | end | ||
7 | foo = bar | ||
8 | -- END OF SOURCE -- | ||
9 | |||
10 | -- TOP: begin | ||
11 | open_func | ||
12 | |||
13 | chunk: | ||
14 | -- STATEMENT: begin 'local' line=1 | ||
15 | local_stat: local statement | ||
16 | localstat: begin | ||
17 | str_checkname: 'foo' | ||
18 | new_localvar: 'foo' | ||
19 | localstat: end | ||
20 | -- STATEMENT: end 'local' | ||
21 | |||
22 | -- STATEMENT: begin 'local' line=2 | ||
23 | local_stat: local function | ||
24 | localfunc: begin | ||
25 | str_checkname: 'bar' | ||
26 | new_localvar: 'bar' | ||
27 | localfunc: body | ||
28 | open_func | ||
29 | body: begin | ||
30 | body: parlist | ||
31 | parlist: begin | ||
32 | parlist: end | ||
33 | body: chunk | ||
34 | chunk: | ||
35 | -- STATEMENT: begin 'expr' line=3 | ||
36 | prefixexp: <name> | ||
37 | str_checkname: 'baz' | ||
38 | singlevar(kind): 'VGLOBAL' | ||
39 | expr_stat: assignment k='VGLOBAL' | ||
40 | assignment: '=' -- RHS elements follows | ||
41 | explist1: begin | ||
42 | expr: | ||
43 | simpleexp: nil | ||
44 | explist1: end | ||
45 | -- STATEMENT: end 'expr' | ||
46 | |||
47 | -- STATEMENT: begin 'expr' line=4 | ||
48 | prefixexp: <name> | ||
49 | str_checkname: 'foo' | ||
50 | singlevar(kind): 'VUPVAL' | ||
51 | expr_stat: assignment k='VUPVAL' | ||
52 | assignment: '=' -- RHS elements follows | ||
53 | explist1: begin | ||
54 | expr: | ||
55 | prefixexp: <name> | ||
56 | str_checkname: 'bar' | ||
57 | singlevar(kind): 'VUPVAL' | ||
58 | primaryexp: ( funcargs | ||
59 | funcargs: begin '(' | ||
60 | funcargs: end -- expr is a VCALL | ||
61 | explist1: end | ||
62 | -- STATEMENT: end 'expr' | ||
63 | |||
64 | body: end | ||
65 | close_func | ||
66 | localfunc: end | ||
67 | -- STATEMENT: end 'local' | ||
68 | |||
69 | -- STATEMENT: begin 'expr' line=6 | ||
70 | prefixexp: <name> | ||
71 | str_checkname: 'foo' | ||
72 | singlevar(kind): 'VLOCAL' | ||
73 | expr_stat: assignment k='VLOCAL' | ||
74 | assignment: '=' -- RHS elements follows | ||
75 | explist1: begin | ||
76 | expr: | ||
77 | prefixexp: <name> | ||
78 | str_checkname: 'bar' | ||
79 | singlevar(kind): 'VLOCAL' | ||
80 | explist1: end | ||
81 | -- STATEMENT: end 'expr' | ||
82 | |||
83 | close_func | ||
84 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local foo | ||
3 | local function bar() | ||
4 | local function baz() | ||
5 | local foo, bar | ||
6 | foo = bar | ||
7 | foo = baz | ||
8 | end | ||
9 | foo = bar | ||
10 | foo = baz | ||
11 | end | ||
12 | foo = bar | ||
13 | foo = baz | ||
14 | -- END OF SOURCE -- | ||
15 | |||
16 | -- TOP: begin | ||
17 | open_func | ||
18 | |||
19 | chunk: | ||
20 | -- STATEMENT: begin 'local' line=1 | ||
21 | local_stat: local statement | ||
22 | localstat: begin | ||
23 | str_checkname: 'foo' | ||
24 | new_localvar: 'foo' | ||
25 | localstat: end | ||
26 | -- STATEMENT: end 'local' | ||
27 | |||
28 | -- STATEMENT: begin 'local' line=2 | ||
29 | local_stat: local function | ||
30 | localfunc: begin | ||
31 | str_checkname: 'bar' | ||
32 | new_localvar: 'bar' | ||
33 | localfunc: body | ||
34 | open_func | ||
35 | body: begin | ||
36 | body: parlist | ||
37 | parlist: begin | ||
38 | parlist: end | ||
39 | body: chunk | ||
40 | chunk: | ||
41 | -- STATEMENT: begin 'local' line=3 | ||
42 | local_stat: local function | ||
43 | localfunc: begin | ||
44 | str_checkname: 'baz' | ||
45 | new_localvar: 'baz' | ||
46 | localfunc: body | ||
47 | open_func | ||
48 | body: begin | ||
49 | body: parlist | ||
50 | parlist: begin | ||
51 | parlist: end | ||
52 | body: chunk | ||
53 | chunk: | ||
54 | -- STATEMENT: begin 'local' line=4 | ||
55 | local_stat: local statement | ||
56 | localstat: begin | ||
57 | str_checkname: 'foo' | ||
58 | new_localvar: 'foo' | ||
59 | str_checkname: 'bar' | ||
60 | new_localvar: 'bar' | ||
61 | localstat: end | ||
62 | -- STATEMENT: end 'local' | ||
63 | |||
64 | -- STATEMENT: begin 'expr' line=5 | ||
65 | prefixexp: <name> | ||
66 | str_checkname: 'foo' | ||
67 | singlevar(kind): 'VLOCAL' | ||
68 | expr_stat: assignment k='VLOCAL' | ||
69 | assignment: '=' -- RHS elements follows | ||
70 | explist1: begin | ||
71 | expr: | ||
72 | prefixexp: <name> | ||
73 | str_checkname: 'bar' | ||
74 | singlevar(kind): 'VLOCAL' | ||
75 | explist1: end | ||
76 | -- STATEMENT: end 'expr' | ||
77 | |||
78 | -- STATEMENT: begin 'expr' line=6 | ||
79 | prefixexp: <name> | ||
80 | str_checkname: 'foo' | ||
81 | singlevar(kind): 'VLOCAL' | ||
82 | expr_stat: assignment k='VLOCAL' | ||
83 | assignment: '=' -- RHS elements follows | ||
84 | explist1: begin | ||
85 | expr: | ||
86 | prefixexp: <name> | ||
87 | str_checkname: 'baz' | ||
88 | singlevar(kind): 'VUPVAL' | ||
89 | explist1: end | ||
90 | -- STATEMENT: end 'expr' | ||
91 | |||
92 | body: end | ||
93 | close_func | ||
94 | localfunc: end | ||
95 | -- STATEMENT: end 'local' | ||
96 | |||
97 | -- STATEMENT: begin 'expr' line=8 | ||
98 | prefixexp: <name> | ||
99 | str_checkname: 'foo' | ||
100 | singlevar(kind): 'VUPVAL' | ||
101 | expr_stat: assignment k='VUPVAL' | ||
102 | assignment: '=' -- RHS elements follows | ||
103 | explist1: begin | ||
104 | expr: | ||
105 | prefixexp: <name> | ||
106 | str_checkname: 'bar' | ||
107 | singlevar(kind): 'VUPVAL' | ||
108 | explist1: end | ||
109 | -- STATEMENT: end 'expr' | ||
110 | |||
111 | -- STATEMENT: begin 'expr' line=9 | ||
112 | prefixexp: <name> | ||
113 | str_checkname: 'foo' | ||
114 | singlevar(kind): 'VUPVAL' | ||
115 | expr_stat: assignment k='VUPVAL' | ||
116 | assignment: '=' -- RHS elements follows | ||
117 | explist1: begin | ||
118 | expr: | ||
119 | prefixexp: <name> | ||
120 | str_checkname: 'baz' | ||
121 | singlevar(kind): 'VLOCAL' | ||
122 | explist1: end | ||
123 | -- STATEMENT: end 'expr' | ||
124 | |||
125 | body: end | ||
126 | close_func | ||
127 | localfunc: end | ||
128 | -- STATEMENT: end 'local' | ||
129 | |||
130 | -- STATEMENT: begin 'expr' line=11 | ||
131 | prefixexp: <name> | ||
132 | str_checkname: 'foo' | ||
133 | singlevar(kind): 'VLOCAL' | ||
134 | expr_stat: assignment k='VLOCAL' | ||
135 | assignment: '=' -- RHS elements follows | ||
136 | explist1: begin | ||
137 | expr: | ||
138 | prefixexp: <name> | ||
139 | str_checkname: 'bar' | ||
140 | singlevar(kind): 'VLOCAL' | ||
141 | explist1: end | ||
142 | -- STATEMENT: end 'expr' | ||
143 | |||
144 | -- STATEMENT: begin 'expr' line=12 | ||
145 | prefixexp: <name> | ||
146 | str_checkname: 'foo' | ||
147 | singlevar(kind): 'VLOCAL' | ||
148 | expr_stat: assignment k='VLOCAL' | ||
149 | assignment: '=' -- RHS elements follows | ||
150 | explist1: begin | ||
151 | expr: | ||
152 | prefixexp: <name> | ||
153 | str_checkname: 'baz' | ||
154 | singlevar(kind): 'VGLOBAL' | ||
155 | explist1: end | ||
156 | -- STATEMENT: end 'expr' | ||
157 | |||
158 | close_func | ||
159 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo:bar() | ||
3 | print(self) | ||
4 | end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'function' line=1 | ||
12 | function_stat: begin | ||
13 | funcname: begin | ||
14 | str_checkname: 'foo' | ||
15 | singlevar(kind): 'VGLOBAL' | ||
16 | funcname: -- ':' field | ||
17 | field: operator=: | ||
18 | checkname: | ||
19 | str_checkname: 'bar' | ||
20 | codestring: "bar" | ||
21 | funcname: end | ||
22 | function_stat: body needself='true' | ||
23 | open_func | ||
24 | body: begin | ||
25 | new_localvar: 'self' | ||
26 | body: parlist | ||
27 | parlist: begin | ||
28 | parlist: end | ||
29 | body: chunk | ||
30 | chunk: | ||
31 | -- STATEMENT: begin 'expr' line=2 | ||
32 | prefixexp: <name> | ||
33 | str_checkname: 'print' | ||
34 | singlevar(kind): 'VGLOBAL' | ||
35 | primaryexp: ( funcargs | ||
36 | funcargs: begin '(' | ||
37 | explist1: begin | ||
38 | expr: | ||
39 | prefixexp: <name> | ||
40 | str_checkname: 'self' | ||
41 | singlevar(kind): 'VLOCAL' | ||
42 | explist1: end | ||
43 | funcargs: end -- expr is a VCALL | ||
44 | expr_stat: function call k='VCALL' | ||
45 | -- STATEMENT: end 'expr' | ||
46 | |||
47 | body: end | ||
48 | close_func | ||
49 | function_stat: end | ||
50 | -- STATEMENT: end 'function' | ||
51 | |||
52 | close_func | ||
53 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo(...) | ||
3 | print(arg) | ||
4 | end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'function' line=1 | ||
12 | function_stat: begin | ||
13 | funcname: begin | ||
14 | str_checkname: 'foo' | ||
15 | singlevar(kind): 'VGLOBAL' | ||
16 | funcname: end | ||
17 | function_stat: body needself='false' | ||
18 | open_func | ||
19 | body: begin | ||
20 | body: parlist | ||
21 | parlist: begin | ||
22 | parlist: ... (dots) | ||
23 | new_localvar: 'arg' | ||
24 | parlist: end | ||
25 | body: chunk | ||
26 | chunk: | ||
27 | -- STATEMENT: begin 'expr' line=2 | ||
28 | prefixexp: <name> | ||
29 | str_checkname: 'print' | ||
30 | singlevar(kind): 'VGLOBAL' | ||
31 | primaryexp: ( funcargs | ||
32 | funcargs: begin '(' | ||
33 | explist1: begin | ||
34 | expr: | ||
35 | prefixexp: <name> | ||
36 | str_checkname: 'arg' | ||
37 | singlevar(kind): 'VLOCAL' | ||
38 | explist1: end | ||
39 | funcargs: end -- expr is a VCALL | ||
40 | expr_stat: function call k='VCALL' | ||
41 | -- STATEMENT: end 'expr' | ||
42 | |||
43 | body: end | ||
44 | close_func | ||
45 | function_stat: end | ||
46 | -- STATEMENT: end 'function' | ||
47 | |||
48 | close_func | ||
49 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local c,d | ||
3 | function foo(a,b,c) | ||
4 | print(a,c,d,e) | ||
5 | end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'local' line=1 | ||
13 | local_stat: local statement | ||
14 | localstat: begin | ||
15 | str_checkname: 'c' | ||
16 | new_localvar: 'c' | ||
17 | str_checkname: 'd' | ||
18 | new_localvar: 'd' | ||
19 | localstat: end | ||
20 | -- STATEMENT: end 'local' | ||
21 | |||
22 | -- STATEMENT: begin 'function' line=2 | ||
23 | function_stat: begin | ||
24 | funcname: begin | ||
25 | str_checkname: 'foo' | ||
26 | singlevar(kind): 'VGLOBAL' | ||
27 | funcname: end | ||
28 | function_stat: body needself='false' | ||
29 | open_func | ||
30 | body: begin | ||
31 | body: parlist | ||
32 | parlist: begin | ||
33 | str_checkname: 'a' | ||
34 | new_localvar: 'a' | ||
35 | str_checkname: 'b' | ||
36 | new_localvar: 'b' | ||
37 | str_checkname: 'c' | ||
38 | new_localvar: 'c' | ||
39 | parlist: end | ||
40 | body: chunk | ||
41 | chunk: | ||
42 | -- STATEMENT: begin 'expr' line=3 | ||
43 | prefixexp: <name> | ||
44 | str_checkname: 'print' | ||
45 | singlevar(kind): 'VGLOBAL' | ||
46 | primaryexp: ( funcargs | ||
47 | funcargs: begin '(' | ||
48 | explist1: begin | ||
49 | expr: | ||
50 | prefixexp: <name> | ||
51 | str_checkname: 'a' | ||
52 | singlevar(kind): 'VLOCAL' | ||
53 | explist1: ',' -- continuation | ||
54 | expr: | ||
55 | prefixexp: <name> | ||
56 | str_checkname: 'c' | ||
57 | singlevar(kind): 'VLOCAL' | ||
58 | explist1: ',' -- continuation | ||
59 | expr: | ||
60 | prefixexp: <name> | ||
61 | str_checkname: 'd' | ||
62 | singlevar(kind): 'VUPVAL' | ||
63 | explist1: ',' -- continuation | ||
64 | expr: | ||
65 | prefixexp: <name> | ||
66 | str_checkname: 'e' | ||
67 | singlevar(kind): 'VGLOBAL' | ||
68 | explist1: end | ||
69 | funcargs: end -- expr is a VCALL | ||
70 | expr_stat: function call k='VCALL' | ||
71 | -- STATEMENT: end 'expr' | ||
72 | |||
73 | body: end | ||
74 | close_func | ||
75 | function_stat: end | ||
76 | -- STATEMENT: end 'function' | ||
77 | |||
78 | close_func | ||
79 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo(a,b) | ||
3 | local bar = function(c,d) | ||
4 | print(a,b,c,d) | ||
5 | end | ||
6 | end | ||
7 | -- END OF SOURCE -- | ||
8 | |||
9 | -- TOP: begin | ||
10 | open_func | ||
11 | |||
12 | chunk: | ||
13 | -- STATEMENT: begin 'function' line=1 | ||
14 | function_stat: begin | ||
15 | funcname: begin | ||
16 | str_checkname: 'foo' | ||
17 | singlevar(kind): 'VGLOBAL' | ||
18 | funcname: end | ||
19 | function_stat: body needself='false' | ||
20 | open_func | ||
21 | body: begin | ||
22 | body: parlist | ||
23 | parlist: begin | ||
24 | str_checkname: 'a' | ||
25 | new_localvar: 'a' | ||
26 | str_checkname: 'b' | ||
27 | new_localvar: 'b' | ||
28 | parlist: end | ||
29 | body: chunk | ||
30 | chunk: | ||
31 | -- STATEMENT: begin 'local' line=2 | ||
32 | local_stat: local statement | ||
33 | localstat: begin | ||
34 | str_checkname: 'bar' | ||
35 | new_localvar: 'bar' | ||
36 | localstat: -- assignment | ||
37 | explist1: begin | ||
38 | expr: | ||
39 | simpleexp: function | ||
40 | open_func | ||
41 | body: begin | ||
42 | body: parlist | ||
43 | parlist: begin | ||
44 | str_checkname: 'c' | ||
45 | new_localvar: 'c' | ||
46 | str_checkname: 'd' | ||
47 | new_localvar: 'd' | ||
48 | parlist: end | ||
49 | body: chunk | ||
50 | chunk: | ||
51 | -- STATEMENT: begin 'expr' line=3 | ||
52 | prefixexp: <name> | ||
53 | str_checkname: 'print' | ||
54 | singlevar(kind): 'VGLOBAL' | ||
55 | primaryexp: ( funcargs | ||
56 | funcargs: begin '(' | ||
57 | explist1: begin | ||
58 | expr: | ||
59 | prefixexp: <name> | ||
60 | str_checkname: 'a' | ||
61 | singlevar(kind): 'VUPVAL' | ||
62 | explist1: ',' -- continuation | ||
63 | expr: | ||
64 | prefixexp: <name> | ||
65 | str_checkname: 'b' | ||
66 | singlevar(kind): 'VUPVAL' | ||
67 | explist1: ',' -- continuation | ||
68 | expr: | ||
69 | prefixexp: <name> | ||
70 | str_checkname: 'c' | ||
71 | singlevar(kind): 'VLOCAL' | ||
72 | explist1: ',' -- continuation | ||
73 | expr: | ||
74 | prefixexp: <name> | ||
75 | str_checkname: 'd' | ||
76 | singlevar(kind): 'VLOCAL' | ||
77 | explist1: end | ||
78 | funcargs: end -- expr is a VCALL | ||
79 | expr_stat: function call k='VCALL' | ||
80 | -- STATEMENT: end 'expr' | ||
81 | |||
82 | body: end | ||
83 | close_func | ||
84 | explist1: end | ||
85 | localstat: end | ||
86 | -- STATEMENT: end 'local' | ||
87 | |||
88 | body: end | ||
89 | close_func | ||
90 | function_stat: end | ||
91 | -- STATEMENT: end 'function' | ||
92 | |||
93 | close_func | ||
94 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | for i = 1,10 do | ||
3 | print(i) | ||
4 | end | ||
5 | for i = 1,10,-2 do | ||
6 | print(i) | ||
7 | end | ||
8 | -- END OF SOURCE -- | ||
9 | |||
10 | -- TOP: begin | ||
11 | open_func | ||
12 | |||
13 | chunk: | ||
14 | -- STATEMENT: begin 'for' line=1 | ||
15 | for_stat: begin | ||
16 | enterblock(isbreakable=false) | ||
17 | str_checkname: 'i' | ||
18 | for_stat: numerical loop | ||
19 | new_localvar: 'i' | ||
20 | new_localvar: '(for limit)' | ||
21 | new_localvar: '(for step)' | ||
22 | fornum: begin | ||
23 | fornum: index start | ||
24 | exp1: begin | ||
25 | expr: | ||
26 | simpleexp: <number>=1 | ||
27 | exp1: end | ||
28 | fornum: index stop | ||
29 | exp1: begin | ||
30 | expr: | ||
31 | simpleexp: <number>=10 | ||
32 | exp1: end | ||
33 | fornum: body | ||
34 | enterblock(isbreakable=true) | ||
35 | block: begin | ||
36 | enterblock(isbreakable=false) | ||
37 | chunk: | ||
38 | -- STATEMENT: begin 'expr' line=2 | ||
39 | prefixexp: <name> | ||
40 | str_checkname: 'print' | ||
41 | singlevar(kind): 'VGLOBAL' | ||
42 | primaryexp: ( funcargs | ||
43 | funcargs: begin '(' | ||
44 | explist1: begin | ||
45 | expr: | ||
46 | prefixexp: <name> | ||
47 | str_checkname: 'i' | ||
48 | singlevar(kind): 'VLOCAL' | ||
49 | explist1: end | ||
50 | funcargs: end -- expr is a VCALL | ||
51 | expr_stat: function call k='VCALL' | ||
52 | -- STATEMENT: end 'expr' | ||
53 | |||
54 | leaveblock | ||
55 | block: end | ||
56 | leaveblock | ||
57 | fornum: end | ||
58 | leaveblock | ||
59 | for_stat: end | ||
60 | -- STATEMENT: end 'for' | ||
61 | |||
62 | -- STATEMENT: begin 'for' line=4 | ||
63 | for_stat: begin | ||
64 | enterblock(isbreakable=false) | ||
65 | str_checkname: 'i' | ||
66 | for_stat: numerical loop | ||
67 | new_localvar: 'i' | ||
68 | new_localvar: '(for limit)' | ||
69 | new_localvar: '(for step)' | ||
70 | fornum: begin | ||
71 | fornum: index start | ||
72 | exp1: begin | ||
73 | expr: | ||
74 | simpleexp: <number>=1 | ||
75 | exp1: end | ||
76 | fornum: index stop | ||
77 | exp1: begin | ||
78 | expr: | ||
79 | simpleexp: <number>=10 | ||
80 | exp1: end | ||
81 | fornum: index step | ||
82 | exp1: begin | ||
83 | expr: | ||
84 | subexpr: uop='-' | ||
85 | simpleexp: <number>=2 | ||
86 | exp1: end | ||
87 | fornum: body | ||
88 | enterblock(isbreakable=true) | ||
89 | block: begin | ||
90 | enterblock(isbreakable=false) | ||
91 | chunk: | ||
92 | -- STATEMENT: begin 'expr' line=5 | ||
93 | prefixexp: <name> | ||
94 | str_checkname: 'print' | ||
95 | singlevar(kind): 'VGLOBAL' | ||
96 | primaryexp: ( funcargs | ||
97 | funcargs: begin '(' | ||
98 | explist1: begin | ||
99 | expr: | ||
100 | prefixexp: <name> | ||
101 | str_checkname: 'i' | ||
102 | singlevar(kind): 'VLOCAL' | ||
103 | explist1: end | ||
104 | funcargs: end -- expr is a VCALL | ||
105 | expr_stat: function call k='VCALL' | ||
106 | -- STATEMENT: end 'expr' | ||
107 | |||
108 | leaveblock | ||
109 | block: end | ||
110 | leaveblock | ||
111 | fornum: end | ||
112 | leaveblock | ||
113 | for_stat: end | ||
114 | -- STATEMENT: end 'for' | ||
115 | |||
116 | close_func | ||
117 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | for foo in bar() do | ||
3 | print(foo) | ||
4 | end | ||
5 | for foo,bar,baz in spring() do | ||
6 | print(foo,bar,baz) | ||
7 | end | ||
8 | -- END OF SOURCE -- | ||
9 | |||
10 | -- TOP: begin | ||
11 | open_func | ||
12 | |||
13 | chunk: | ||
14 | -- STATEMENT: begin 'for' line=1 | ||
15 | for_stat: begin | ||
16 | enterblock(isbreakable=false) | ||
17 | str_checkname: 'foo' | ||
18 | for_stat: list-based loop | ||
19 | forlist: begin | ||
20 | new_localvar: '(for generator)' | ||
21 | new_localvar: '(for state)' | ||
22 | new_localvar: 'foo' | ||
23 | forlist: explist1 | ||
24 | explist1: begin | ||
25 | expr: | ||
26 | prefixexp: <name> | ||
27 | str_checkname: 'bar' | ||
28 | singlevar(kind): 'VGLOBAL' | ||
29 | primaryexp: ( funcargs | ||
30 | funcargs: begin '(' | ||
31 | funcargs: end -- expr is a VCALL | ||
32 | explist1: end | ||
33 | forlist: body | ||
34 | enterblock(isbreakable=true) | ||
35 | block: begin | ||
36 | enterblock(isbreakable=false) | ||
37 | chunk: | ||
38 | -- STATEMENT: begin 'expr' line=2 | ||
39 | prefixexp: <name> | ||
40 | str_checkname: 'print' | ||
41 | singlevar(kind): 'VGLOBAL' | ||
42 | primaryexp: ( funcargs | ||
43 | funcargs: begin '(' | ||
44 | explist1: begin | ||
45 | expr: | ||
46 | prefixexp: <name> | ||
47 | str_checkname: 'foo' | ||
48 | singlevar(kind): 'VLOCAL' | ||
49 | explist1: end | ||
50 | funcargs: end -- expr is a VCALL | ||
51 | expr_stat: function call k='VCALL' | ||
52 | -- STATEMENT: end 'expr' | ||
53 | |||
54 | leaveblock | ||
55 | block: end | ||
56 | leaveblock | ||
57 | forlist: end | ||
58 | leaveblock | ||
59 | for_stat: end | ||
60 | -- STATEMENT: end 'for' | ||
61 | |||
62 | -- STATEMENT: begin 'for' line=4 | ||
63 | for_stat: begin | ||
64 | enterblock(isbreakable=false) | ||
65 | str_checkname: 'foo' | ||
66 | for_stat: list-based loop | ||
67 | forlist: begin | ||
68 | new_localvar: '(for generator)' | ||
69 | new_localvar: '(for state)' | ||
70 | new_localvar: 'foo' | ||
71 | str_checkname: 'bar' | ||
72 | new_localvar: 'bar' | ||
73 | str_checkname: 'baz' | ||
74 | new_localvar: 'baz' | ||
75 | forlist: explist1 | ||
76 | explist1: begin | ||
77 | expr: | ||
78 | prefixexp: <name> | ||
79 | str_checkname: 'spring' | ||
80 | singlevar(kind): 'VGLOBAL' | ||
81 | primaryexp: ( funcargs | ||
82 | funcargs: begin '(' | ||
83 | funcargs: end -- expr is a VCALL | ||
84 | explist1: end | ||
85 | forlist: body | ||
86 | enterblock(isbreakable=true) | ||
87 | block: begin | ||
88 | enterblock(isbreakable=false) | ||
89 | chunk: | ||
90 | -- STATEMENT: begin 'expr' line=5 | ||
91 | prefixexp: <name> | ||
92 | str_checkname: 'print' | ||
93 | singlevar(kind): 'VGLOBAL' | ||
94 | primaryexp: ( funcargs | ||
95 | funcargs: begin '(' | ||
96 | explist1: begin | ||
97 | expr: | ||
98 | prefixexp: <name> | ||
99 | str_checkname: 'foo' | ||
100 | singlevar(kind): 'VLOCAL' | ||
101 | explist1: ',' -- continuation | ||
102 | expr: | ||
103 | prefixexp: <name> | ||
104 | str_checkname: 'bar' | ||
105 | singlevar(kind): 'VLOCAL' | ||
106 | explist1: ',' -- continuation | ||
107 | expr: | ||
108 | prefixexp: <name> | ||
109 | str_checkname: 'baz' | ||
110 | singlevar(kind): 'VLOCAL' | ||
111 | explist1: end | ||
112 | funcargs: end -- expr is a VCALL | ||
113 | expr_stat: function call k='VCALL' | ||
114 | -- STATEMENT: end 'expr' | ||
115 | |||
116 | leaveblock | ||
117 | block: end | ||
118 | leaveblock | ||
119 | forlist: end | ||
120 | leaveblock | ||
121 | for_stat: end | ||
122 | -- STATEMENT: end 'for' | ||
123 | |||
124 | close_func | ||
125 | -- 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 @@ | |||
1 | local a = 47 | ||
2 | local b = "hello, world!" | ||
3 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_llex.lua | ||
4 | Test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- if BRIEF is not set to false, auto-test will silently succeed | ||
17 | ------------------------------------------------------------------------ | ||
18 | BRIEF = true -- if set to true, messages are less verbose | ||
19 | |||
20 | local zio_init = require("../lzio_mk2") | ||
21 | local lex_init = require("../llex_mk2") | ||
22 | |||
23 | ------------------------------------------------------------------------ | ||
24 | -- simple manual tests | ||
25 | ------------------------------------------------------------------------ | ||
26 | |||
27 | --[[ | ||
28 | local function dump(z, source) | ||
29 | local luaX = lex_init(z, source) | ||
30 | while true do | ||
31 | local tok, seminfo = luaX:lex() | ||
32 | if tok == "<name>" then | ||
33 | seminfo = " "..seminfo | ||
34 | elseif tok == "<number>" then | ||
35 | seminfo = " "..seminfo | ||
36 | elseif tok == "<string>" then | ||
37 | seminfo = " '"..seminfo.."'" | ||
38 | else | ||
39 | seminfo = "" | ||
40 | end | ||
41 | io.stdout:write(tok..seminfo.."\n") | ||
42 | if tok == "<eof>" then break end | ||
43 | end | ||
44 | end | ||
45 | |||
46 | local function try_string(chunk) | ||
47 | dump(zio_init(chunk), "=string") | ||
48 | end | ||
49 | local function try_file(filename) | ||
50 | local f = "@"..filename | ||
51 | dump(zio_init(f), f) | ||
52 | end | ||
53 | |||
54 | z = try_string("local c = z:getc()") | ||
55 | z = try_file("test_lzio_mk2.lua") | ||
56 | z = try_file("test_llex_mk2.lua") | ||
57 | os.exit() | ||
58 | --]] | ||
59 | |||
60 | ------------------------------------------------------------------------ | ||
61 | -- auto-testing of simple test cases to validate lexer behaviour: | ||
62 | -- * NOTE coverage has not been checked; not comprehensive | ||
63 | -- * only test cases with non-empty comments are processed | ||
64 | -- * if no result, then the output is displayed for manual decision | ||
65 | -- (output may be used to set expected success or fail text) | ||
66 | -- * cases expected to be successful may be a partial match | ||
67 | -- * cases expected to fail may also be a partial match | ||
68 | ------------------------------------------------------------------------ | ||
69 | |||
70 | -- [[ | ||
71 | local function auto_test() | ||
72 | local PASS, FAIL = true, false | ||
73 | ------------------------------------------------------------------ | ||
74 | -- table of test cases | ||
75 | ------------------------------------------------------------------ | ||
76 | local test_cases = | ||
77 | { | ||
78 | ------------------------------------------------------------- | ||
79 | --{ "comment", -- comment about the test | ||
80 | -- "chunk", -- chunk to test | ||
81 | -- PASS, -- PASS or FAIL outcome | ||
82 | -- "output", -- output to compare against | ||
83 | --}, | ||
84 | ------------------------------------------------------------- | ||
85 | { "empty chunk string, test EOS", | ||
86 | "", | ||
87 | PASS, "1 <eof>", | ||
88 | }, | ||
89 | ------------------------------------------------------------- | ||
90 | { "line number counting", | ||
91 | "\n\n\r\n", | ||
92 | PASS, "4 <eof>", | ||
93 | }, | ||
94 | ------------------------------------------------------------- | ||
95 | { "various whitespaces", | ||
96 | " \n\t\t\n \t \t \n\n", | ||
97 | PASS, "5 <eof>", | ||
98 | }, | ||
99 | ------------------------------------------------------------- | ||
100 | { "short comment ending in EOS", | ||
101 | "-- moo moo", | ||
102 | PASS, "1 <eof>", | ||
103 | }, | ||
104 | ------------------------------------------------------------- | ||
105 | { "short comment ending in newline", | ||
106 | "-- moo moo\n", | ||
107 | PASS, "2 <eof>", | ||
108 | }, | ||
109 | ------------------------------------------------------------- | ||
110 | { "several lines of short comments", | ||
111 | "--moo\n-- moo moo\n\n--\tmoo\n", | ||
112 | PASS, "5 <eof>", | ||
113 | }, | ||
114 | ------------------------------------------------------------- | ||
115 | { "basic block comment", | ||
116 | "--[[bovine]]", | ||
117 | PASS, "1 <eof>", | ||
118 | }, | ||
119 | ------------------------------------------------------------- | ||
120 | { "unterminated block comment 1", | ||
121 | "--[[bovine", | ||
122 | FAIL, ":1: unfinished long comment near '<eof>'", | ||
123 | }, | ||
124 | ------------------------------------------------------------- | ||
125 | { "unterminated block comment 2", | ||
126 | "--[[bovine]", | ||
127 | FAIL, ":1: unfinished long comment near '<eof>'", | ||
128 | }, | ||
129 | ------------------------------------------------------------- | ||
130 | { "unterminated block comment 3", | ||
131 | "--[[bovine\nmoo moo\nwoof", | ||
132 | FAIL, ":3: unfinished long comment near '<eof>'", | ||
133 | }, | ||
134 | ------------------------------------------------------------- | ||
135 | { "basic long string", | ||
136 | "\n[[bovine]]\n", | ||
137 | PASS, "2 <string> = bovine\n3 <eof>", | ||
138 | }, | ||
139 | ------------------------------------------------------------- | ||
140 | { "first newline consumed in long string", | ||
141 | "[[\nmoo]]", | ||
142 | PASS, "2 <string> = moo\n2 <eof>", | ||
143 | }, | ||
144 | ------------------------------------------------------------- | ||
145 | { "multiline long string", | ||
146 | "[[moo\nmoo moo\n]]", | ||
147 | PASS, "3 <string> = moo\nmoo moo\n\n3 <eof>", | ||
148 | }, | ||
149 | ------------------------------------------------------------- | ||
150 | { "unterminated long string 1", | ||
151 | "\n[[\nbovine", | ||
152 | FAIL, ":3: unfinished long string near '<eof>'", | ||
153 | }, | ||
154 | ------------------------------------------------------------- | ||
155 | { "unterminated long string 2", | ||
156 | "[[bovine]", | ||
157 | FAIL, ":1: unfinished long string near '<eof>'", | ||
158 | }, | ||
159 | ------------------------------------------------------------- | ||
160 | { "unterminated long string 3", | ||
161 | "[[[[ \n", | ||
162 | FAIL, ":2: unfinished long string near '<eof>'", | ||
163 | }, | ||
164 | ------------------------------------------------------------- | ||
165 | { "nested long string 1", | ||
166 | "[[moo[[moo]]moo]]", | ||
167 | PASS, "moo[[moo]]moo", | ||
168 | }, | ||
169 | ------------------------------------------------------------- | ||
170 | { "nested long string 2", | ||
171 | "[[moo[[moo[[[[]]]]moo]]moo]]", | ||
172 | PASS, "moo[[moo[[[[]]]]moo]]moo", | ||
173 | }, | ||
174 | ------------------------------------------------------------- | ||
175 | { "nested long string 3", | ||
176 | "[[[[[[]]]][[[[]]]]]]", | ||
177 | PASS, "[[[[]]]][[[[]]]]", | ||
178 | }, | ||
179 | ------------------------------------------------------------- | ||
180 | { "brackets in long strings 1", | ||
181 | "[[moo[moo]]", | ||
182 | PASS, "moo[moo", | ||
183 | }, | ||
184 | ------------------------------------------------------------- | ||
185 | { "brackets in long strings 2", | ||
186 | "[[moo[[moo]moo]]moo]]", | ||
187 | PASS, "moo[[moo]moo]]moo", | ||
188 | }, | ||
189 | ------------------------------------------------------------- | ||
190 | { "unprocessed escapes in long strings", | ||
191 | [[ [[\a\b\f\n\r\t\v\123]] ]], | ||
192 | PASS, [[\a\b\f\n\r\t\v\123]], | ||
193 | }, | ||
194 | ------------------------------------------------------------- | ||
195 | { "unbalanced long string", | ||
196 | "[[moo]]moo]]", | ||
197 | PASS, "1 <string> = moo\n1 <name> = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 <eof>", | ||
198 | }, | ||
199 | ------------------------------------------------------------- | ||
200 | { "keywords 1", | ||
201 | "and break do else", | ||
202 | PASS, "1 and\n1 break\n1 do\n1 else\n1 <eof>", | ||
203 | }, | ||
204 | ------------------------------------------------------------- | ||
205 | { "keywords 2", | ||
206 | "elseif end false for", | ||
207 | PASS, "1 elseif\n1 end\n1 false\n1 for\n1 <eof>", | ||
208 | }, | ||
209 | ------------------------------------------------------------- | ||
210 | { "keywords 3", | ||
211 | "function if in local nil", | ||
212 | PASS, "1 function\n1 if\n1 in\n1 local\n1 nil\n1 <eof>", | ||
213 | }, | ||
214 | ------------------------------------------------------------- | ||
215 | { "keywords 4", | ||
216 | "not or repeat return", | ||
217 | PASS, "1 not\n1 or\n1 repeat\n1 return\n1 <eof>", | ||
218 | }, | ||
219 | ------------------------------------------------------------- | ||
220 | { "keywords 5", | ||
221 | "then true until while", | ||
222 | PASS, "1 then\n1 true\n1 until\n1 while\n1 <eof>", | ||
223 | }, | ||
224 | ------------------------------------------------------------- | ||
225 | { "concat and dots", | ||
226 | ".. ...", | ||
227 | PASS, "1 ..\n1 ...\n1 <eof>", | ||
228 | }, | ||
229 | ------------------------------------------------------------- | ||
230 | { "shbang handling 1", | ||
231 | "#blahblah", | ||
232 | PASS, "1 <eof>", | ||
233 | }, | ||
234 | ------------------------------------------------------------- | ||
235 | { "shbang handling 2", | ||
236 | "#blahblah\nmoo moo\n", | ||
237 | PASS, "2 <name> = moo\n2 <name> = moo\n3 <eof>", | ||
238 | }, | ||
239 | ------------------------------------------------------------- | ||
240 | { "empty string", | ||
241 | [['']], | ||
242 | PASS, "1 <string> = \n1 <eof>", | ||
243 | }, | ||
244 | ------------------------------------------------------------- | ||
245 | { "single-quoted string", | ||
246 | [['bovine']], | ||
247 | PASS, "1 <string> = bovine\n1 <eof>", | ||
248 | }, | ||
249 | ------------------------------------------------------------- | ||
250 | { "double-quoted string", | ||
251 | [["bovine"]], | ||
252 | PASS, "1 <string> = bovine\n1 <eof>", | ||
253 | }, | ||
254 | ------------------------------------------------------------- | ||
255 | { "unterminated string 1", | ||
256 | [['moo ]], | ||
257 | FAIL, ":1: unfinished string near '<eof>'", | ||
258 | }, | ||
259 | ------------------------------------------------------------- | ||
260 | { "unterminated string 2", | ||
261 | [["moo \n]], | ||
262 | FAIL, ":1: unfinished string near '<eof>'", | ||
263 | }, | ||
264 | ------------------------------------------------------------- | ||
265 | { "escaped newline in string, line number counted", | ||
266 | "\"moo\\\nmoo\\\nmoo\"", | ||
267 | PASS, "3 <string> = moo\nmoo\nmoo\n3 <eof>", | ||
268 | }, | ||
269 | ------------------------------------------------------------- | ||
270 | { "escaped characters in string 1", | ||
271 | [["moo\amoo"]], | ||
272 | PASS, "1 <string> = moo\amoo", | ||
273 | }, | ||
274 | ------------------------------------------------------------- | ||
275 | { "escaped characters in string 2", | ||
276 | [["moo\bmoo"]], | ||
277 | PASS, "1 <string> = moo\bmoo", | ||
278 | }, | ||
279 | ------------------------------------------------------------- | ||
280 | { "escaped characters in string 3", | ||
281 | [["moo\f\n\r\t\vmoo"]], | ||
282 | PASS, "1 <string> = moo\f\n\r\t\vmoo", | ||
283 | }, | ||
284 | ------------------------------------------------------------- | ||
285 | { "escaped characters in string 4", | ||
286 | [["\\ \" \' \? \[ \]"]], | ||
287 | PASS, "1 <string> = \\ \" \' \? \[ \]", | ||
288 | }, | ||
289 | ------------------------------------------------------------- | ||
290 | { "escaped characters in string 5", | ||
291 | [["\z \k \: \;"]], | ||
292 | PASS, "1 <string> = z k : ;", | ||
293 | }, | ||
294 | ------------------------------------------------------------- | ||
295 | { "escaped characters in string 6", | ||
296 | [["\8 \65 \160 \180K \097097"]], | ||
297 | PASS, "1 <string> = \8 \65 \160 \180K \097097\n", | ||
298 | }, | ||
299 | ------------------------------------------------------------- | ||
300 | { "escaped characters in string 7", | ||
301 | [["\666"]], | ||
302 | FAIL, ":1: escape sequence too large near '\"'", | ||
303 | }, | ||
304 | ------------------------------------------------------------- | ||
305 | { "simple numbers", | ||
306 | "123 123+", | ||
307 | PASS, "1 <number> = 123\n1 <number> = 123\n1 CHAR = '+'\n1 <eof>", | ||
308 | }, | ||
309 | ------------------------------------------------------------- | ||
310 | { "longer numbers", | ||
311 | "1234567890 12345678901234567890", | ||
312 | PASS, "1 <number> = 1234567890\n1 <number> = 1.2345678901235e+19\n", | ||
313 | }, | ||
314 | ------------------------------------------------------------- | ||
315 | { "fractional numbers", | ||
316 | ".123 .12345678901234567890", | ||
317 | PASS, "1 <number> = 0.123\n1 <number> = 0.12345678901235\n", | ||
318 | }, | ||
319 | ------------------------------------------------------------- | ||
320 | { "more numbers with decimal points", | ||
321 | "12345.67890 1.1.", | ||
322 | PASS, "1 <number> = 12345.6789\n1 <number> = 1.1\n1 CHAR = '.'\n", | ||
323 | }, | ||
324 | ------------------------------------------------------------- | ||
325 | { "double decimal points", | ||
326 | ".1.1", | ||
327 | FAIL, ":1: malformed number near '.1.1'", | ||
328 | }, | ||
329 | ------------------------------------------------------------- | ||
330 | { "double dots within numbers", | ||
331 | "1..1", | ||
332 | FAIL, ":1: ambiguous syntax (dots follows digits) near '1..'", | ||
333 | }, | ||
334 | ------------------------------------------------------------- | ||
335 | { "incomplete exponential numbers", | ||
336 | "123e", | ||
337 | FAIL, ":1: malformed number near '123e'", | ||
338 | }, | ||
339 | ------------------------------------------------------------- | ||
340 | { "exponential numbers 1", | ||
341 | "1234e5 1234e5.", | ||
342 | PASS, "1 <number> = 123400000\n1 <number> = 123400000\n1 CHAR = '.'", | ||
343 | }, | ||
344 | ------------------------------------------------------------- | ||
345 | { "exponential numbers 2", | ||
346 | "1234e56 1.23e123", | ||
347 | PASS, "1 <number> = 1.234e+59\n1 <number> = 1.23e+123\n", | ||
348 | }, | ||
349 | ------------------------------------------------------------- | ||
350 | { "exponential numbers 3", | ||
351 | "12.34e+", | ||
352 | FAIL, ":1: malformed number near '12.34e+'", | ||
353 | }, | ||
354 | ------------------------------------------------------------- | ||
355 | { "exponential numbers 4", | ||
356 | "12.34e+5 123.4e-5 1234.E+5", | ||
357 | PASS, "1 <number> = 1234000\n1 <number> = 0.001234\n1 <number> = 123400000\n", | ||
358 | }, | ||
359 | ------------------------------------------------------------- | ||
360 | { "single character symbols 1", | ||
361 | "= > < ~", | ||
362 | PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n", | ||
363 | }, | ||
364 | ------------------------------------------------------------- | ||
365 | { "double character symbols", | ||
366 | "== >= <= ~=", | ||
367 | PASS, "1 ==\n1 >=\n1 <=\n1 ~=\n", | ||
368 | }, | ||
369 | ------------------------------------------------------------- | ||
370 | { "simple identifiers", | ||
371 | "abc ABC", | ||
372 | PASS, "1 <name> = abc\n1 <name> = ABC\n1 <eof>", | ||
373 | }, | ||
374 | ------------------------------------------------------------- | ||
375 | { "more identifiers", | ||
376 | "_abc _ABC", | ||
377 | PASS, "1 <name> = _abc\n1 <name> = _ABC\n1 <eof>", | ||
378 | }, | ||
379 | ------------------------------------------------------------- | ||
380 | { "still more identifiers", | ||
381 | "_aB_ _123", | ||
382 | PASS, "1 <name> = _aB_\n1 <name> = _123\n1 <eof>", | ||
383 | }, | ||
384 | ------------------------------------------------------------- | ||
385 | { "invalid control character", | ||
386 | "\4", | ||
387 | FAIL, ":1: invalid control char near 'char(4)'", | ||
388 | }, | ||
389 | ------------------------------------------------------------- | ||
390 | { "single character symbols 2", | ||
391 | "` ! @ $ %", | ||
392 | PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", | ||
393 | }, | ||
394 | ------------------------------------------------------------- | ||
395 | { "single character symbols 3", | ||
396 | "^ & * ( )", | ||
397 | PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", | ||
398 | }, | ||
399 | ------------------------------------------------------------- | ||
400 | { "single character symbols 4", | ||
401 | "_ - + \\ |", | ||
402 | PASS, "1 <name> = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", | ||
403 | }, | ||
404 | ------------------------------------------------------------- | ||
405 | { "single character symbols 5", | ||
406 | "{ } [ ] :", | ||
407 | PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", | ||
408 | }, | ||
409 | ------------------------------------------------------------- | ||
410 | { "single character symbols 6", | ||
411 | "; , . / ?", | ||
412 | PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", | ||
413 | }, | ||
414 | ------------------------------------------------------------- | ||
415 | } | ||
416 | ------------------------------------------------------------------ | ||
417 | -- perform a test case | ||
418 | ------------------------------------------------------------------ | ||
419 | function do_test_case(count, test_case) | ||
420 | if comment == "" then return end -- skip empty entries | ||
421 | local comment, chunk, outcome, matcher = unpack(test_case) | ||
422 | local result = PASS | ||
423 | local output = "" | ||
424 | -- initialize lexer | ||
425 | local z = zio_init(chunk) | ||
426 | local luaX = lex_init(z, "=test") | ||
427 | -- lexer test loop | ||
428 | local status, token, seminfo | ||
429 | repeat | ||
430 | -- protected call | ||
431 | status, token, seminfo = pcall(luaX.lex, luaX) | ||
432 | output = output..luaX.lineno.." " | ||
433 | if status then | ||
434 | -- successful call | ||
435 | if string.len(token) > 1 then | ||
436 | if token == "<name>" | ||
437 | or token == "<number>" | ||
438 | or token == "<string>" then | ||
439 | token = token.." = "..seminfo | ||
440 | end | ||
441 | elseif string.byte(token) >= 32 then -- displayable chars | ||
442 | token = "CHAR = '"..token.."'" | ||
443 | else -- control characters | ||
444 | token = "CHAR = (".. string.byte(token)..")" | ||
445 | end | ||
446 | output = output..token.."\n" | ||
447 | else | ||
448 | -- failed call | ||
449 | output = output..token -- token is the error message | ||
450 | result = FAIL | ||
451 | break | ||
452 | end | ||
453 | until token == "<eof>" | ||
454 | -- decision making and reporting | ||
455 | local head = "Test "..count..": "..comment | ||
456 | if matcher == "" then | ||
457 | -- nothing to check against, display for manual check | ||
458 | print(head.."\nMANUAL please check manually".. | ||
459 | "\n--chunk---------------------------------\n"..chunk.. | ||
460 | "\n--actual--------------------------------\n"..output.. | ||
461 | "\n\n") | ||
462 | return | ||
463 | else | ||
464 | if outcome == PASS then | ||
465 | -- success expected, may be a partial match | ||
466 | if string.find(output, matcher, 1, 1) and result == PASS then | ||
467 | if not BRIEF then print(head.."\nOK expected success\n") end | ||
468 | return | ||
469 | end | ||
470 | else | ||
471 | -- failure expected, may be a partial match | ||
472 | if string.find(output, matcher, 1, 1) and result == FAIL then | ||
473 | if not BRIEF then print(head.."\nOK expected failure\n") end | ||
474 | return | ||
475 | end | ||
476 | end | ||
477 | -- failed because of unmatched string or boolean result | ||
478 | local function passfail(status) | ||
479 | if status == PASS then return "PASS" else return "FAIL" end | ||
480 | end | ||
481 | print(head.." *FAILED*".. | ||
482 | "\noutcome="..passfail(outcome).. | ||
483 | "\nactual= "..passfail(result).. | ||
484 | "\n--chunk---------------------------------\n"..chunk.. | ||
485 | "\n--expected------------------------------\n"..matcher.. | ||
486 | "\n--actual--------------------------------\n"..output.. | ||
487 | "\n\n") | ||
488 | end | ||
489 | end | ||
490 | ------------------------------------------------------------------ | ||
491 | -- perform auto testing | ||
492 | ------------------------------------------------------------------ | ||
493 | for i,test_case in ipairs(test_cases) do | ||
494 | do_test_case(i, test_case) | ||
495 | end | ||
496 | end | ||
497 | |||
498 | auto_test() | ||
499 | --]] | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_llex.lua | ||
4 | Test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- if BRIEF is not set to false, auto-test will silently succeed | ||
17 | ------------------------------------------------------------------------ | ||
18 | BRIEF = true -- if set to true, messages are less verbose | ||
19 | |||
20 | local lex_init = require("../llex_mk3") | ||
21 | |||
22 | ------------------------------------------------------------------------ | ||
23 | -- simple manual tests | ||
24 | ------------------------------------------------------------------------ | ||
25 | |||
26 | --[[ | ||
27 | local function dump(z, source) | ||
28 | local luaX = lex_init(z, source) | ||
29 | while true do | ||
30 | local tok, seminfo = luaX:lex() | ||
31 | if tok == "<name>" then | ||
32 | seminfo = " "..seminfo | ||
33 | elseif tok == "<number>" then | ||
34 | seminfo = " "..seminfo | ||
35 | elseif tok == "<string>" then | ||
36 | seminfo = " '"..seminfo.."'" | ||
37 | else | ||
38 | seminfo = "" | ||
39 | end | ||
40 | io.stdout:write(tok..seminfo.."\n") | ||
41 | if tok == "<eof>" then break end | ||
42 | end | ||
43 | end | ||
44 | |||
45 | local function try_string(chunk) | ||
46 | dump(chunk, "=string") | ||
47 | end | ||
48 | local function try_file(filename) | ||
49 | local inf = io.open(filename, "r") | ||
50 | if not inf then error("file not found") end | ||
51 | local data = inf:read("*a") | ||
52 | inf:close() | ||
53 | dump(data, "@"..filename) | ||
54 | end | ||
55 | |||
56 | z = try_string("local c = z:getc()") | ||
57 | z = try_file("test_lzio_mk2.lua") | ||
58 | z = try_file("test_llex_mk2.lua") | ||
59 | os.exit() | ||
60 | --]] | ||
61 | |||
62 | ------------------------------------------------------------------------ | ||
63 | -- auto-testing of simple test cases to validate lexer behaviour: | ||
64 | -- * NOTE coverage has not been checked; not comprehensive | ||
65 | -- * only test cases with non-empty comments are processed | ||
66 | -- * if no result, then the output is displayed for manual decision | ||
67 | -- (output may be used to set expected success or fail text) | ||
68 | -- * cases expected to be successful may be a partial match | ||
69 | -- * cases expected to fail may also be a partial match | ||
70 | ------------------------------------------------------------------------ | ||
71 | |||
72 | -- [[ | ||
73 | local function auto_test() | ||
74 | local PASS, FAIL = true, false | ||
75 | ------------------------------------------------------------------ | ||
76 | -- table of test cases | ||
77 | ------------------------------------------------------------------ | ||
78 | local test_cases = | ||
79 | { | ||
80 | ------------------------------------------------------------- | ||
81 | --{ "comment", -- comment about the test | ||
82 | -- "chunk", -- chunk to test | ||
83 | -- PASS, -- PASS or FAIL outcome | ||
84 | -- "output", -- output to compare against | ||
85 | --}, | ||
86 | ------------------------------------------------------------- | ||
87 | { "empty chunk string, test EOS", | ||
88 | "", | ||
89 | PASS, "1 <eof>", | ||
90 | }, | ||
91 | ------------------------------------------------------------- | ||
92 | { "line number counting", | ||
93 | "\n\n\r\n", | ||
94 | PASS, "4 <eof>", | ||
95 | }, | ||
96 | ------------------------------------------------------------- | ||
97 | { "various whitespaces", | ||
98 | " \n\t\t\n \t \t \n\n", | ||
99 | PASS, "5 <eof>", | ||
100 | }, | ||
101 | ------------------------------------------------------------- | ||
102 | { "short comment ending in EOS", | ||
103 | "-- moo moo", | ||
104 | PASS, "1 <eof>", | ||
105 | }, | ||
106 | ------------------------------------------------------------- | ||
107 | { "short comment ending in newline", | ||
108 | "-- moo moo\n", | ||
109 | PASS, "2 <eof>", | ||
110 | }, | ||
111 | ------------------------------------------------------------- | ||
112 | { "several lines of short comments", | ||
113 | "--moo\n-- moo moo\n\n--\tmoo\n", | ||
114 | PASS, "5 <eof>", | ||
115 | }, | ||
116 | ------------------------------------------------------------- | ||
117 | { "basic block comment", | ||
118 | "--[[bovine]]", | ||
119 | PASS, "1 <eof>", | ||
120 | }, | ||
121 | ------------------------------------------------------------- | ||
122 | { "unterminated block comment 1", | ||
123 | "--[[bovine", | ||
124 | FAIL, ":1: unfinished long comment", | ||
125 | }, | ||
126 | ------------------------------------------------------------- | ||
127 | { "unterminated block comment 2", | ||
128 | "--[[bovine]", | ||
129 | FAIL, ":1: unfinished long comment", | ||
130 | }, | ||
131 | ------------------------------------------------------------- | ||
132 | { "unterminated block comment 3", | ||
133 | "--[[bovine\nmoo moo\nwoof", | ||
134 | FAIL, ":3: unfinished long comment", | ||
135 | }, | ||
136 | ------------------------------------------------------------- | ||
137 | { "basic long string", | ||
138 | "\n[[bovine]]\n", | ||
139 | PASS, "2 <string> = bovine\n3 <eof>", | ||
140 | }, | ||
141 | ------------------------------------------------------------- | ||
142 | { "first newline consumed in long string", | ||
143 | "[[\nmoo]]", | ||
144 | PASS, "2 <string> = moo\n2 <eof>", | ||
145 | }, | ||
146 | ------------------------------------------------------------- | ||
147 | { "multiline long string", | ||
148 | "[[moo\nmoo moo\n]]", | ||
149 | PASS, "3 <string> = moo\nmoo moo\n\n3 <eof>", | ||
150 | }, | ||
151 | ------------------------------------------------------------- | ||
152 | { "unterminated long string 1", | ||
153 | "\n[[\nbovine", | ||
154 | FAIL, ":3: unfinished long string", | ||
155 | }, | ||
156 | ------------------------------------------------------------- | ||
157 | { "unterminated long string 2", | ||
158 | "[[bovine]", | ||
159 | FAIL, ":1: unfinished long string", | ||
160 | }, | ||
161 | ------------------------------------------------------------- | ||
162 | { "unterminated long string 3", | ||
163 | "[[[[ \n", | ||
164 | FAIL, ":2: unfinished long string", | ||
165 | }, | ||
166 | ------------------------------------------------------------- | ||
167 | { "nested long string 1", | ||
168 | "[[moo[[moo]]moo]]", | ||
169 | PASS, "moo[[moo]]moo", | ||
170 | }, | ||
171 | ------------------------------------------------------------- | ||
172 | { "nested long string 2", | ||
173 | "[[moo[[moo[[[[]]]]moo]]moo]]", | ||
174 | PASS, "moo[[moo[[[[]]]]moo]]moo", | ||
175 | }, | ||
176 | ------------------------------------------------------------- | ||
177 | { "nested long string 3", | ||
178 | "[[[[[[]]]][[[[]]]]]]", | ||
179 | PASS, "[[[[]]]][[[[]]]]", | ||
180 | }, | ||
181 | ------------------------------------------------------------- | ||
182 | { "brackets in long strings 1", | ||
183 | "[[moo[moo]]", | ||
184 | PASS, "moo[moo", | ||
185 | }, | ||
186 | ------------------------------------------------------------- | ||
187 | { "brackets in long strings 2", | ||
188 | "[[moo[[moo]moo]]moo]]", | ||
189 | PASS, "moo[[moo]moo]]moo", | ||
190 | }, | ||
191 | ------------------------------------------------------------- | ||
192 | { "unprocessed escapes in long strings", | ||
193 | [[ [[\a\b\f\n\r\t\v\123]] ]], | ||
194 | PASS, [[\a\b\f\n\r\t\v\123]], | ||
195 | }, | ||
196 | ------------------------------------------------------------- | ||
197 | { "unbalanced long string", | ||
198 | "[[moo]]moo]]", | ||
199 | PASS, "1 <string> = moo\n1 <name> = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 <eof>", | ||
200 | }, | ||
201 | ------------------------------------------------------------- | ||
202 | { "keywords 1", | ||
203 | "and break do else", | ||
204 | PASS, "1 and\n1 break\n1 do\n1 else\n1 <eof>", | ||
205 | }, | ||
206 | ------------------------------------------------------------- | ||
207 | { "keywords 2", | ||
208 | "elseif end false for", | ||
209 | PASS, "1 elseif\n1 end\n1 false\n1 for\n1 <eof>", | ||
210 | }, | ||
211 | ------------------------------------------------------------- | ||
212 | { "keywords 3", | ||
213 | "function if in local nil", | ||
214 | PASS, "1 function\n1 if\n1 in\n1 local\n1 nil\n1 <eof>", | ||
215 | }, | ||
216 | ------------------------------------------------------------- | ||
217 | { "keywords 4", | ||
218 | "not or repeat return", | ||
219 | PASS, "1 not\n1 or\n1 repeat\n1 return\n1 <eof>", | ||
220 | }, | ||
221 | ------------------------------------------------------------- | ||
222 | { "keywords 5", | ||
223 | "then true until while", | ||
224 | PASS, "1 then\n1 true\n1 until\n1 while\n1 <eof>", | ||
225 | }, | ||
226 | ------------------------------------------------------------- | ||
227 | { "concat and dots", | ||
228 | ".. ...", | ||
229 | PASS, "1 ..\n1 ...\n1 <eof>", | ||
230 | }, | ||
231 | ------------------------------------------------------------- | ||
232 | { "shbang handling 1", | ||
233 | "#blahblah", | ||
234 | PASS, "1 <eof>", | ||
235 | }, | ||
236 | ------------------------------------------------------------- | ||
237 | { "shbang handling 2", | ||
238 | "#blahblah\nmoo moo\n", | ||
239 | PASS, "2 <name> = moo\n2 <name> = moo\n3 <eof>", | ||
240 | }, | ||
241 | ------------------------------------------------------------- | ||
242 | { "empty string", | ||
243 | [['']], | ||
244 | PASS, "1 <string> = \n1 <eof>", | ||
245 | }, | ||
246 | ------------------------------------------------------------- | ||
247 | { "single-quoted string", | ||
248 | [['bovine']], | ||
249 | PASS, "1 <string> = bovine\n1 <eof>", | ||
250 | }, | ||
251 | ------------------------------------------------------------- | ||
252 | { "double-quoted string", | ||
253 | [["bovine"]], | ||
254 | PASS, "1 <string> = bovine\n1 <eof>", | ||
255 | }, | ||
256 | ------------------------------------------------------------- | ||
257 | { "unterminated string 1", | ||
258 | [['moo ]], | ||
259 | FAIL, ":1: unfinished string", | ||
260 | }, | ||
261 | ------------------------------------------------------------- | ||
262 | { "unterminated string 2", | ||
263 | [["moo \n]], | ||
264 | FAIL, ":1: unfinished string", | ||
265 | }, | ||
266 | ------------------------------------------------------------- | ||
267 | { "escaped newline in string, line number counted", | ||
268 | "\"moo\\\nmoo\\\nmoo\"", | ||
269 | PASS, "3 <string> = moo\nmoo\nmoo\n3 <eof>", | ||
270 | }, | ||
271 | ------------------------------------------------------------- | ||
272 | { "escaped characters in string 1", | ||
273 | [["moo\amoo"]], | ||
274 | PASS, "1 <string> = moo\amoo", | ||
275 | }, | ||
276 | ------------------------------------------------------------- | ||
277 | { "escaped characters in string 2", | ||
278 | [["moo\bmoo"]], | ||
279 | PASS, "1 <string> = moo\bmoo", | ||
280 | }, | ||
281 | ------------------------------------------------------------- | ||
282 | { "escaped characters in string 3", | ||
283 | [["moo\f\n\r\t\vmoo"]], | ||
284 | PASS, "1 <string> = moo\f\n\r\t\vmoo", | ||
285 | }, | ||
286 | ------------------------------------------------------------- | ||
287 | { "escaped characters in string 4", | ||
288 | [["\\ \" \' \? \[ \]"]], | ||
289 | PASS, "1 <string> = \\ \" \' \? \[ \]", | ||
290 | }, | ||
291 | ------------------------------------------------------------- | ||
292 | { "escaped characters in string 5", | ||
293 | [["\z \k \: \;"]], | ||
294 | PASS, "1 <string> = z k : ;", | ||
295 | }, | ||
296 | ------------------------------------------------------------- | ||
297 | { "escaped characters in string 6", | ||
298 | [["\8 \65 \160 \180K \097097"]], | ||
299 | PASS, "1 <string> = \8 \65 \160 \180K \097097\n", | ||
300 | }, | ||
301 | ------------------------------------------------------------- | ||
302 | { "escaped characters in string 7", | ||
303 | [["\666"]], | ||
304 | FAIL, ":1: escape sequence too large", | ||
305 | }, | ||
306 | ------------------------------------------------------------- | ||
307 | { "simple numbers", | ||
308 | "123 123+", | ||
309 | PASS, "1 <number> = 123\n1 <number> = 123\n1 CHAR = '+'\n1 <eof>", | ||
310 | }, | ||
311 | ------------------------------------------------------------- | ||
312 | { "longer numbers", | ||
313 | "1234567890 12345678901234567890", | ||
314 | PASS, "1 <number> = 1234567890\n1 <number> = 1.2345678901235e+19\n", | ||
315 | }, | ||
316 | ------------------------------------------------------------- | ||
317 | { "fractional numbers", | ||
318 | ".123 .12345678901234567890", | ||
319 | PASS, "1 <number> = 0.123\n1 <number> = 0.12345678901235\n", | ||
320 | }, | ||
321 | ------------------------------------------------------------- | ||
322 | { "more numbers with decimal points", | ||
323 | "12345.67890 1.1.", | ||
324 | PASS, "1 <number> = 12345.6789\n1 <number> = 1.1\n1 CHAR = '.'\n", | ||
325 | }, | ||
326 | ------------------------------------------------------------- | ||
327 | { "double decimal points", | ||
328 | ".1.1", | ||
329 | FAIL, ":1: malformed number", | ||
330 | }, | ||
331 | ------------------------------------------------------------- | ||
332 | { "double dots within numbers", | ||
333 | "1..1", | ||
334 | FAIL, ":1: ambiguous syntax (dots follows digits)", | ||
335 | }, | ||
336 | ------------------------------------------------------------- | ||
337 | { "incomplete exponential numbers", | ||
338 | "123e", | ||
339 | FAIL, ":1: malformed number", | ||
340 | }, | ||
341 | ------------------------------------------------------------- | ||
342 | { "exponential numbers 1", | ||
343 | "1234e5 1234e5.", | ||
344 | PASS, "1 <number> = 123400000\n1 <number> = 123400000\n1 CHAR = '.'", | ||
345 | }, | ||
346 | ------------------------------------------------------------- | ||
347 | { "exponential numbers 2", | ||
348 | "1234e56 1.23e123", | ||
349 | PASS, "1 <number> = 1.234e+59\n1 <number> = 1.23e+123\n", | ||
350 | }, | ||
351 | ------------------------------------------------------------- | ||
352 | { "exponential numbers 3", | ||
353 | "12.34e+", | ||
354 | FAIL, ":1: malformed number", | ||
355 | }, | ||
356 | ------------------------------------------------------------- | ||
357 | { "exponential numbers 4", | ||
358 | "12.34e+5 123.4e-5 1234.E+5", | ||
359 | PASS, "1 <number> = 1234000\n1 <number> = 0.001234\n1 <number> = 123400000\n", | ||
360 | }, | ||
361 | ------------------------------------------------------------- | ||
362 | { "single character symbols 1", | ||
363 | "= > < ~", | ||
364 | PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n", | ||
365 | }, | ||
366 | ------------------------------------------------------------- | ||
367 | { "double character symbols", | ||
368 | "== >= <= ~=", | ||
369 | PASS, "1 ==\n1 >=\n1 <=\n1 ~=\n", | ||
370 | }, | ||
371 | ------------------------------------------------------------- | ||
372 | { "simple identifiers", | ||
373 | "abc ABC", | ||
374 | PASS, "1 <name> = abc\n1 <name> = ABC\n1 <eof>", | ||
375 | }, | ||
376 | ------------------------------------------------------------- | ||
377 | { "more identifiers", | ||
378 | "_abc _ABC", | ||
379 | PASS, "1 <name> = _abc\n1 <name> = _ABC\n1 <eof>", | ||
380 | }, | ||
381 | ------------------------------------------------------------- | ||
382 | { "still more identifiers", | ||
383 | "_aB_ _123", | ||
384 | PASS, "1 <name> = _aB_\n1 <name> = _123\n1 <eof>", | ||
385 | }, | ||
386 | ------------------------------------------------------------- | ||
387 | { "invalid control character", | ||
388 | "\4", | ||
389 | FAIL, ":1: invalid control char", | ||
390 | }, | ||
391 | ------------------------------------------------------------- | ||
392 | { "single character symbols 2", | ||
393 | "` ! @ $ %", | ||
394 | PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", | ||
395 | }, | ||
396 | ------------------------------------------------------------- | ||
397 | { "single character symbols 3", | ||
398 | "^ & * ( )", | ||
399 | PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", | ||
400 | }, | ||
401 | ------------------------------------------------------------- | ||
402 | { "single character symbols 4", | ||
403 | "_ - + \\ |", | ||
404 | PASS, "1 <name> = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", | ||
405 | }, | ||
406 | ------------------------------------------------------------- | ||
407 | { "single character symbols 5", | ||
408 | "{ } [ ] :", | ||
409 | PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", | ||
410 | }, | ||
411 | ------------------------------------------------------------- | ||
412 | { "single character symbols 6", | ||
413 | "; , . / ?", | ||
414 | PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", | ||
415 | }, | ||
416 | ------------------------------------------------------------- | ||
417 | } | ||
418 | ------------------------------------------------------------------ | ||
419 | -- perform a test case | ||
420 | ------------------------------------------------------------------ | ||
421 | function do_test_case(count, test_case) | ||
422 | if comment == "" then return end -- skip empty entries | ||
423 | local comment, chunk, outcome, matcher = unpack(test_case) | ||
424 | local result = PASS | ||
425 | local output = "" | ||
426 | -- initialize lexer | ||
427 | local luaX = lex_init(chunk, "=test") | ||
428 | -- lexer test loop | ||
429 | local status, token, seminfo | ||
430 | repeat | ||
431 | -- protected call | ||
432 | status, token, seminfo = pcall(luaX.lex, luaX) | ||
433 | output = output..luaX.ln.." " | ||
434 | if status then | ||
435 | -- successful call | ||
436 | if string.len(token) > 1 then | ||
437 | if token == "<name>" | ||
438 | or token == "<number>" | ||
439 | or token == "<string>" then | ||
440 | token = token.." = "..seminfo | ||
441 | end | ||
442 | elseif string.byte(token) >= 32 then -- displayable chars | ||
443 | token = "CHAR = '"..token.."'" | ||
444 | else -- control characters | ||
445 | token = "CHAR = (".. string.byte(token)..")" | ||
446 | end | ||
447 | output = output..token.."\n" | ||
448 | else | ||
449 | -- failed call | ||
450 | output = output..token -- token is the error message | ||
451 | result = FAIL | ||
452 | break | ||
453 | end | ||
454 | until token == "<eof>" | ||
455 | -- decision making and reporting | ||
456 | local head = "Test "..count..": "..comment | ||
457 | if matcher == "" then | ||
458 | -- nothing to check against, display for manual check | ||
459 | print(head.."\nMANUAL please check manually".. | ||
460 | "\n--chunk---------------------------------\n"..chunk.. | ||
461 | "\n--actual--------------------------------\n"..output.. | ||
462 | "\n\n") | ||
463 | return | ||
464 | else | ||
465 | if outcome == PASS then | ||
466 | -- success expected, may be a partial match | ||
467 | if string.find(output, matcher, 1, 1) and result == PASS then | ||
468 | if not BRIEF then print(head.."\nOK expected success\n") end | ||
469 | return | ||
470 | end | ||
471 | else | ||
472 | -- failure expected, may be a partial match | ||
473 | if string.find(output, matcher, 1, 1) and result == FAIL then | ||
474 | if not BRIEF then print(head.."\nOK expected failure\n") end | ||
475 | return | ||
476 | end | ||
477 | end | ||
478 | -- failed because of unmatched string or boolean result | ||
479 | local function passfail(status) | ||
480 | if status == PASS then return "PASS" else return "FAIL" end | ||
481 | end | ||
482 | print(head.." *FAILED*".. | ||
483 | "\noutcome="..passfail(outcome).. | ||
484 | "\nactual= "..passfail(result).. | ||
485 | "\n--chunk---------------------------------\n"..chunk.. | ||
486 | "\n--expected------------------------------\n"..matcher.. | ||
487 | "\n--actual--------------------------------\n"..output.. | ||
488 | "\n\n") | ||
489 | end | ||
490 | end | ||
491 | ------------------------------------------------------------------ | ||
492 | -- perform auto testing | ||
493 | ------------------------------------------------------------------ | ||
494 | for i,test_case in ipairs(test_cases) do | ||
495 | do_test_case(i, test_case) | ||
496 | end | ||
497 | end | ||
498 | |||
499 | auto_test() | ||
500 | --]] | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_llex.lua | ||
4 | Test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- if BRIEF is not set to false, auto-test will silently succeed | ||
17 | ------------------------------------------------------------------------ | ||
18 | BRIEF = true -- if set to true, messages are less verbose | ||
19 | |||
20 | local zio_init = require("../lzio_mk4") | ||
21 | local lex_init = require("../llex_mk4") | ||
22 | |||
23 | ------------------------------------------------------------------------ | ||
24 | -- simple manual tests | ||
25 | ------------------------------------------------------------------------ | ||
26 | |||
27 | --[[ | ||
28 | local function dump(z, source) | ||
29 | local luaX = lex_init(z, source) | ||
30 | while true do | ||
31 | local tok, seminfo = luaX:lex() | ||
32 | if tok == "<name>" then | ||
33 | seminfo = " "..seminfo | ||
34 | elseif tok == "<number>" then | ||
35 | seminfo = " "..seminfo | ||
36 | elseif tok == "<string>" then | ||
37 | seminfo = " '"..seminfo.."'" | ||
38 | else | ||
39 | seminfo = "" | ||
40 | end | ||
41 | io.stdout:write(tok..seminfo.."\n") | ||
42 | if tok == "<eof>" then break end | ||
43 | end | ||
44 | end | ||
45 | |||
46 | local function try_string(chunk) | ||
47 | dump(zio_init(chunk), "=string") | ||
48 | end | ||
49 | local function try_file(filename) | ||
50 | local f = "@"..filename | ||
51 | dump(zio_init(f), f) | ||
52 | end | ||
53 | |||
54 | z = try_string("local c = z:getc()") | ||
55 | z = try_file("test_lzio_mk2.lua") | ||
56 | z = try_file("test_llex_mk2.lua") | ||
57 | os.exit() | ||
58 | --]] | ||
59 | |||
60 | ------------------------------------------------------------------------ | ||
61 | -- auto-testing of simple test cases to validate lexer behaviour: | ||
62 | -- * NOTE coverage has not been checked; not comprehensive | ||
63 | -- * only test cases with non-empty comments are processed | ||
64 | -- * if no result, then the output is displayed for manual decision | ||
65 | -- (output may be used to set expected success or fail text) | ||
66 | -- * cases expected to be successful may be a partial match | ||
67 | -- * cases expected to fail may also be a partial match | ||
68 | ------------------------------------------------------------------------ | ||
69 | |||
70 | -- [[ | ||
71 | local function auto_test() | ||
72 | local PASS, FAIL = true, false | ||
73 | ------------------------------------------------------------------ | ||
74 | -- table of test cases | ||
75 | ------------------------------------------------------------------ | ||
76 | local test_cases = | ||
77 | { | ||
78 | ------------------------------------------------------------- | ||
79 | --{ "comment", -- comment about the test | ||
80 | -- "chunk", -- chunk to test | ||
81 | -- PASS, -- PASS or FAIL outcome | ||
82 | -- "output", -- output to compare against | ||
83 | --}, | ||
84 | ------------------------------------------------------------- | ||
85 | { "empty chunk string, test EOS", | ||
86 | "", | ||
87 | PASS, "1 <eof>", | ||
88 | }, | ||
89 | ------------------------------------------------------------- | ||
90 | { "line number counting", | ||
91 | "\n\n\r\n", | ||
92 | PASS, "4 <eof>", | ||
93 | }, | ||
94 | ------------------------------------------------------------- | ||
95 | { "various whitespaces", | ||
96 | " \n\t\t\n \t \t \n\n", | ||
97 | PASS, "5 <eof>", | ||
98 | }, | ||
99 | ------------------------------------------------------------- | ||
100 | { "short comment ending in EOS", | ||
101 | "-- moo moo", | ||
102 | PASS, "1 <eof>", | ||
103 | }, | ||
104 | ------------------------------------------------------------- | ||
105 | { "short comment ending in newline", | ||
106 | "-- moo moo\n", | ||
107 | PASS, "2 <eof>", | ||
108 | }, | ||
109 | ------------------------------------------------------------- | ||
110 | { "several lines of short comments", | ||
111 | "--moo\n-- moo moo\n\n--\tmoo\n", | ||
112 | PASS, "5 <eof>", | ||
113 | }, | ||
114 | ------------------------------------------------------------- | ||
115 | { "basic block comment", | ||
116 | "--[[bovine]]", | ||
117 | PASS, "1 <eof>", | ||
118 | }, | ||
119 | ------------------------------------------------------------- | ||
120 | { "unterminated block comment 1", | ||
121 | "--[[bovine", | ||
122 | FAIL, ":1: unfinished long comment", | ||
123 | }, | ||
124 | ------------------------------------------------------------- | ||
125 | { "unterminated block comment 2", | ||
126 | "--[[bovine]", | ||
127 | FAIL, ":1: unfinished long comment", | ||
128 | }, | ||
129 | ------------------------------------------------------------- | ||
130 | { "unterminated block comment 3", | ||
131 | "--[[bovine\nmoo moo\nwoof", | ||
132 | FAIL, ":3: unfinished long comment", | ||
133 | }, | ||
134 | ------------------------------------------------------------- | ||
135 | { "basic long string", | ||
136 | "\n[[bovine]]\n", | ||
137 | PASS, "2 <string> = bovine\n3 <eof>", | ||
138 | }, | ||
139 | ------------------------------------------------------------- | ||
140 | { "first newline consumed in long string", | ||
141 | "[[\nmoo]]", | ||
142 | PASS, "2 <string> = moo\n2 <eof>", | ||
143 | }, | ||
144 | ------------------------------------------------------------- | ||
145 | { "multiline long string", | ||
146 | "[[moo\nmoo moo\n]]", | ||
147 | PASS, "3 <string> = moo\nmoo moo\n\n3 <eof>", | ||
148 | }, | ||
149 | ------------------------------------------------------------- | ||
150 | { "unterminated long string 1", | ||
151 | "\n[[\nbovine", | ||
152 | FAIL, ":3: unfinished long string", | ||
153 | }, | ||
154 | ------------------------------------------------------------- | ||
155 | { "unterminated long string 2", | ||
156 | "[[bovine]", | ||
157 | FAIL, ":1: unfinished long string", | ||
158 | }, | ||
159 | ------------------------------------------------------------- | ||
160 | { "unterminated long string 3", | ||
161 | "[[[[ \n", | ||
162 | FAIL, ":2: unfinished long string", | ||
163 | }, | ||
164 | ------------------------------------------------------------- | ||
165 | { "nested long string 1", | ||
166 | "[[moo[[moo]]moo]]", | ||
167 | PASS, "moo[[moo]]moo", | ||
168 | }, | ||
169 | ------------------------------------------------------------- | ||
170 | { "nested long string 2", | ||
171 | "[[moo[[moo[[[[]]]]moo]]moo]]", | ||
172 | PASS, "moo[[moo[[[[]]]]moo]]moo", | ||
173 | }, | ||
174 | ------------------------------------------------------------- | ||
175 | { "nested long string 3", | ||
176 | "[[[[[[]]]][[[[]]]]]]", | ||
177 | PASS, "[[[[]]]][[[[]]]]", | ||
178 | }, | ||
179 | ------------------------------------------------------------- | ||
180 | { "brackets in long strings 1", | ||
181 | "[[moo[moo]]", | ||
182 | PASS, "moo[moo", | ||
183 | }, | ||
184 | ------------------------------------------------------------- | ||
185 | { "brackets in long strings 2", | ||
186 | "[[moo[[moo]moo]]moo]]", | ||
187 | PASS, "moo[[moo]moo]]moo", | ||
188 | }, | ||
189 | ------------------------------------------------------------- | ||
190 | { "unprocessed escapes in long strings", | ||
191 | [[ [[\a\b\f\n\r\t\v\123]] ]], | ||
192 | PASS, [[\a\b\f\n\r\t\v\123]], | ||
193 | }, | ||
194 | ------------------------------------------------------------- | ||
195 | { "unbalanced long string", | ||
196 | "[[moo]]moo]]", | ||
197 | PASS, "1 <string> = moo\n1 <name> = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 <eof>", | ||
198 | }, | ||
199 | ------------------------------------------------------------- | ||
200 | { "keywords 1", | ||
201 | "and break do else", | ||
202 | PASS, "1 and\n1 break\n1 do\n1 else\n1 <eof>", | ||
203 | }, | ||
204 | ------------------------------------------------------------- | ||
205 | { "keywords 2", | ||
206 | "elseif end false for", | ||
207 | PASS, "1 elseif\n1 end\n1 false\n1 for\n1 <eof>", | ||
208 | }, | ||
209 | ------------------------------------------------------------- | ||
210 | { "keywords 3", | ||
211 | "function if in local nil", | ||
212 | PASS, "1 function\n1 if\n1 in\n1 local\n1 nil\n1 <eof>", | ||
213 | }, | ||
214 | ------------------------------------------------------------- | ||
215 | { "keywords 4", | ||
216 | "not or repeat return", | ||
217 | PASS, "1 not\n1 or\n1 repeat\n1 return\n1 <eof>", | ||
218 | }, | ||
219 | ------------------------------------------------------------- | ||
220 | { "keywords 5", | ||
221 | "then true until while", | ||
222 | PASS, "1 then\n1 true\n1 until\n1 while\n1 <eof>", | ||
223 | }, | ||
224 | ------------------------------------------------------------- | ||
225 | { "concat and dots", | ||
226 | ".. ...", | ||
227 | PASS, "1 ..\n1 ...\n1 <eof>", | ||
228 | }, | ||
229 | ------------------------------------------------------------- | ||
230 | { "shbang handling 1", | ||
231 | "#blahblah", | ||
232 | PASS, "1 <eof>", | ||
233 | }, | ||
234 | ------------------------------------------------------------- | ||
235 | { "shbang handling 2", | ||
236 | "#blahblah\nmoo moo\n", | ||
237 | PASS, "2 <name> = moo\n2 <name> = moo\n3 <eof>", | ||
238 | }, | ||
239 | ------------------------------------------------------------- | ||
240 | { "empty string", | ||
241 | [['']], | ||
242 | PASS, "1 <string> = \n1 <eof>", | ||
243 | }, | ||
244 | ------------------------------------------------------------- | ||
245 | { "single-quoted string", | ||
246 | [['bovine']], | ||
247 | PASS, "1 <string> = bovine\n1 <eof>", | ||
248 | }, | ||
249 | ------------------------------------------------------------- | ||
250 | { "double-quoted string", | ||
251 | [["bovine"]], | ||
252 | PASS, "1 <string> = bovine\n1 <eof>", | ||
253 | }, | ||
254 | ------------------------------------------------------------- | ||
255 | { "unterminated string 1", | ||
256 | [['moo ]], | ||
257 | FAIL, ":1: unfinished string", | ||
258 | }, | ||
259 | ------------------------------------------------------------- | ||
260 | { "unterminated string 2", | ||
261 | [["moo \n]], | ||
262 | FAIL, ":1: unfinished string", | ||
263 | }, | ||
264 | ------------------------------------------------------------- | ||
265 | { "escaped newline in string, line number counted", | ||
266 | "\"moo\\\nmoo\\\nmoo\"", | ||
267 | PASS, "3 <string> = moo\nmoo\nmoo\n3 <eof>", | ||
268 | }, | ||
269 | ------------------------------------------------------------- | ||
270 | { "escaped characters in string 1", | ||
271 | [["moo\amoo"]], | ||
272 | PASS, "1 <string> = moo\amoo", | ||
273 | }, | ||
274 | ------------------------------------------------------------- | ||
275 | { "escaped characters in string 2", | ||
276 | [["moo\bmoo"]], | ||
277 | PASS, "1 <string> = moo\bmoo", | ||
278 | }, | ||
279 | ------------------------------------------------------------- | ||
280 | { "escaped characters in string 3", | ||
281 | [["moo\f\n\r\t\vmoo"]], | ||
282 | PASS, "1 <string> = moo\f\n\r\t\vmoo", | ||
283 | }, | ||
284 | ------------------------------------------------------------- | ||
285 | { "escaped characters in string 4", | ||
286 | [["\\ \" \' \? \[ \]"]], | ||
287 | PASS, "1 <string> = \\ \" \' \? \[ \]", | ||
288 | }, | ||
289 | ------------------------------------------------------------- | ||
290 | { "escaped characters in string 5", | ||
291 | [["\z \k \: \;"]], | ||
292 | PASS, "1 <string> = z k : ;", | ||
293 | }, | ||
294 | ------------------------------------------------------------- | ||
295 | { "escaped characters in string 6", | ||
296 | [["\8 \65 \160 \180K \097097"]], | ||
297 | PASS, "1 <string> = \8 \65 \160 \180K \097097\n", | ||
298 | }, | ||
299 | ------------------------------------------------------------- | ||
300 | { "escaped characters in string 7", | ||
301 | [["\666"]], | ||
302 | FAIL, ":1: escape sequence too large", | ||
303 | }, | ||
304 | ------------------------------------------------------------- | ||
305 | { "simple numbers", | ||
306 | "123 123+", | ||
307 | PASS, "1 <number> = 123\n1 <number> = 123\n1 CHAR = '+'\n1 <eof>", | ||
308 | }, | ||
309 | ------------------------------------------------------------- | ||
310 | { "longer numbers", | ||
311 | "1234567890 12345678901234567890", | ||
312 | PASS, "1 <number> = 1234567890\n1 <number> = 1.2345678901235e+19\n", | ||
313 | }, | ||
314 | ------------------------------------------------------------- | ||
315 | { "fractional numbers", | ||
316 | ".123 .12345678901234567890", | ||
317 | PASS, "1 <number> = 0.123\n1 <number> = 0.12345678901235\n", | ||
318 | }, | ||
319 | ------------------------------------------------------------- | ||
320 | { "more numbers with decimal points", | ||
321 | "12345.67890 1.1.", | ||
322 | PASS, "1 <number> = 12345.6789\n1 <number> = 1.1\n1 CHAR = '.'\n", | ||
323 | }, | ||
324 | ------------------------------------------------------------- | ||
325 | { "double decimal points", | ||
326 | ".1.1", | ||
327 | FAIL, ":1: malformed number", | ||
328 | }, | ||
329 | ------------------------------------------------------------- | ||
330 | { "double dots within numbers", | ||
331 | "1..1", | ||
332 | FAIL, ":1: ambiguous syntax (dots follows digits)", | ||
333 | }, | ||
334 | ------------------------------------------------------------- | ||
335 | { "incomplete exponential numbers", | ||
336 | "123e", | ||
337 | FAIL, ":1: malformed number", | ||
338 | }, | ||
339 | ------------------------------------------------------------- | ||
340 | { "exponential numbers 1", | ||
341 | "1234e5 1234e5.", | ||
342 | PASS, "1 <number> = 123400000\n1 <number> = 123400000\n1 CHAR = '.'", | ||
343 | }, | ||
344 | ------------------------------------------------------------- | ||
345 | { "exponential numbers 2", | ||
346 | "1234e56 1.23e123", | ||
347 | PASS, "1 <number> = 1.234e+59\n1 <number> = 1.23e+123\n", | ||
348 | }, | ||
349 | ------------------------------------------------------------- | ||
350 | { "exponential numbers 3", | ||
351 | "12.34e+", | ||
352 | FAIL, ":1: malformed number", | ||
353 | }, | ||
354 | ------------------------------------------------------------- | ||
355 | { "exponential numbers 4", | ||
356 | "12.34e+5 123.4e-5 1234.E+5", | ||
357 | PASS, "1 <number> = 1234000\n1 <number> = 0.001234\n1 <number> = 123400000\n", | ||
358 | }, | ||
359 | ------------------------------------------------------------- | ||
360 | { "single character symbols 1", | ||
361 | "= > < ~", | ||
362 | PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n", | ||
363 | }, | ||
364 | ------------------------------------------------------------- | ||
365 | { "double character symbols", | ||
366 | "== >= <= ~=", | ||
367 | PASS, "1 ==\n1 >=\n1 <=\n1 ~=\n", | ||
368 | }, | ||
369 | ------------------------------------------------------------- | ||
370 | { "simple identifiers", | ||
371 | "abc ABC", | ||
372 | PASS, "1 <name> = abc\n1 <name> = ABC\n1 <eof>", | ||
373 | }, | ||
374 | ------------------------------------------------------------- | ||
375 | { "more identifiers", | ||
376 | "_abc _ABC", | ||
377 | PASS, "1 <name> = _abc\n1 <name> = _ABC\n1 <eof>", | ||
378 | }, | ||
379 | ------------------------------------------------------------- | ||
380 | { "still more identifiers", | ||
381 | "_aB_ _123", | ||
382 | PASS, "1 <name> = _aB_\n1 <name> = _123\n1 <eof>", | ||
383 | }, | ||
384 | ------------------------------------------------------------- | ||
385 | { "invalid control character", | ||
386 | "\4", | ||
387 | FAIL, ":1: invalid control char", | ||
388 | }, | ||
389 | ------------------------------------------------------------- | ||
390 | { "single character symbols 2", | ||
391 | "` ! @ $ %", | ||
392 | PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", | ||
393 | }, | ||
394 | ------------------------------------------------------------- | ||
395 | { "single character symbols 3", | ||
396 | "^ & * ( )", | ||
397 | PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", | ||
398 | }, | ||
399 | ------------------------------------------------------------- | ||
400 | { "single character symbols 4", | ||
401 | "_ - + \\ |", | ||
402 | PASS, "1 <name> = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", | ||
403 | }, | ||
404 | ------------------------------------------------------------- | ||
405 | { "single character symbols 5", | ||
406 | "{ } [ ] :", | ||
407 | PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", | ||
408 | }, | ||
409 | ------------------------------------------------------------- | ||
410 | { "single character symbols 6", | ||
411 | "; , . / ?", | ||
412 | PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", | ||
413 | }, | ||
414 | ------------------------------------------------------------- | ||
415 | } | ||
416 | ------------------------------------------------------------------ | ||
417 | -- perform a test case | ||
418 | ------------------------------------------------------------------ | ||
419 | function do_test_case(count, test_case) | ||
420 | if comment == "" then return end -- skip empty entries | ||
421 | local comment, chunk, outcome, matcher = unpack(test_case) | ||
422 | local result = PASS | ||
423 | local output = "" | ||
424 | -- initialize lexer | ||
425 | local z = zio_init(chunk) | ||
426 | local luaX = lex_init(z, "=test") | ||
427 | -- lexer test loop | ||
428 | local status, token, seminfo | ||
429 | repeat | ||
430 | -- protected call | ||
431 | status, token, seminfo = pcall(luaX.lex, luaX) | ||
432 | output = output..luaX.ln.." " | ||
433 | if status then | ||
434 | -- successful call | ||
435 | if string.len(token) > 1 then | ||
436 | if token == "<name>" | ||
437 | or token == "<number>" | ||
438 | or token == "<string>" then | ||
439 | token = token.." = "..seminfo | ||
440 | end | ||
441 | elseif string.byte(token) >= 32 then -- displayable chars | ||
442 | token = "CHAR = '"..token.."'" | ||
443 | else -- control characters | ||
444 | token = "CHAR = (".. string.byte(token)..")" | ||
445 | end | ||
446 | output = output..token.."\n" | ||
447 | else | ||
448 | -- failed call | ||
449 | output = output..token -- token is the error message | ||
450 | result = FAIL | ||
451 | break | ||
452 | end | ||
453 | until token == "<eof>" | ||
454 | -- decision making and reporting | ||
455 | local head = "Test "..count..": "..comment | ||
456 | if matcher == "" then | ||
457 | -- nothing to check against, display for manual check | ||
458 | print(head.."\nMANUAL please check manually".. | ||
459 | "\n--chunk---------------------------------\n"..chunk.. | ||
460 | "\n--actual--------------------------------\n"..output.. | ||
461 | "\n\n") | ||
462 | return | ||
463 | else | ||
464 | if outcome == PASS then | ||
465 | -- success expected, may be a partial match | ||
466 | if string.find(output, matcher, 1, 1) and result == PASS then | ||
467 | if not BRIEF then print(head.."\nOK expected success\n") end | ||
468 | return | ||
469 | end | ||
470 | else | ||
471 | -- failure expected, may be a partial match | ||
472 | if string.find(output, matcher, 1, 1) and result == FAIL then | ||
473 | if not BRIEF then print(head.."\nOK expected failure\n") end | ||
474 | return | ||
475 | end | ||
476 | end | ||
477 | -- failed because of unmatched string or boolean result | ||
478 | local function passfail(status) | ||
479 | if status == PASS then return "PASS" else return "FAIL" end | ||
480 | end | ||
481 | print(head.." *FAILED*".. | ||
482 | "\noutcome="..passfail(outcome).. | ||
483 | "\nactual= "..passfail(result).. | ||
484 | "\n--chunk---------------------------------\n"..chunk.. | ||
485 | "\n--expected------------------------------\n"..matcher.. | ||
486 | "\n--actual--------------------------------\n"..output.. | ||
487 | "\n\n") | ||
488 | end | ||
489 | end | ||
490 | ------------------------------------------------------------------ | ||
491 | -- perform auto testing | ||
492 | ------------------------------------------------------------------ | ||
493 | for i,test_case in ipairs(test_cases) do | ||
494 | do_test_case(i, test_case) | ||
495 | end | ||
496 | end | ||
497 | |||
498 | auto_test() | ||
499 | --]] | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser_mk3.lua | ||
4 | Test for lparser_mk3.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- test the whole kaboodle | ||
17 | ------------------------------------------------------------------------ | ||
18 | |||
19 | local lex_init = require("../llex_mk3") | ||
20 | local parser_init = require("../lparser_mk3") | ||
21 | |||
22 | ------------------------------------------------------------------------ | ||
23 | -- dump contents of log table | ||
24 | ------------------------------------------------------------------------ | ||
25 | |||
26 | local function dump_log(fs) | ||
27 | local log = fs.log | ||
28 | for i = 1, table.getn(log) do | ||
29 | print(log[i]) | ||
30 | end | ||
31 | end | ||
32 | |||
33 | ------------------------------------------------------------------------ | ||
34 | -- try 1 | ||
35 | ------------------------------------------------------------------------ | ||
36 | |||
37 | local luaX = lex_init("local a = 1", "=string") | ||
38 | local luaY = parser_init(luaX) | ||
39 | |||
40 | -- nothing is returned, so hope there is an error if problem occurs | ||
41 | local fs = luaY:parser() | ||
42 | --dump_log(fs) | ||
43 | |||
44 | ------------------------------------------------------------------------ | ||
45 | -- try 2 | ||
46 | ------------------------------------------------------------------------ | ||
47 | |||
48 | -- llex_mk3.lua cannot load files by itself | ||
49 | local INF = io.open("sample.lua", "rb") | ||
50 | if not INF then error("failed to load test file") end | ||
51 | local sample = INF:read("*a") | ||
52 | INF:close() | ||
53 | |||
54 | luaX = lex_init(sample, "@sample.lua") | ||
55 | luaY = parser_init(luaX) | ||
56 | |||
57 | -- nothing is returned, so hope there is an error if problem occurs | ||
58 | local fs = luaY:parser() | ||
59 | --dump_log(fs) | ||
60 | |||
61 | ------------------------------------------------------------------------ | ||
62 | -- automatic dumper of output log data | ||
63 | ------------------------------------------------------------------------ | ||
64 | |||
65 | local test_case = { | ||
66 | -- 1 | ||
67 | [[ | ||
68 | ]], | ||
69 | -- 2 | ||
70 | [[ | ||
71 | -- foobar | ||
72 | ]], | ||
73 | -- 3 | ||
74 | [[ | ||
75 | do | ||
76 | end | ||
77 | ]], | ||
78 | -- 4 | ||
79 | [[ | ||
80 | do end | ||
81 | do end | ||
82 | ]], | ||
83 | -- 5 | ||
84 | [[ | ||
85 | foo() | ||
86 | foo{} | ||
87 | foo"" | ||
88 | foo:bar() | ||
89 | foo=false | ||
90 | foo.bar=true | ||
91 | foo[true]=nil | ||
92 | foo,bar=1,"a" | ||
93 | ]], | ||
94 | -- 6 | ||
95 | [[ | ||
96 | foo=true | ||
97 | foo=false | ||
98 | foo=nil | ||
99 | foo=1.23e45 | ||
100 | foo=-1 | ||
101 | foo=(0) | ||
102 | foo=1+2 | ||
103 | foo=1+2*3-4/5 | ||
104 | ]], | ||
105 | -- 7 | ||
106 | [[ | ||
107 | if foo then foo=1 end | ||
108 | if foo then foo=1 else foo=0 end | ||
109 | if foo then foo=1 elseif not foo then foo=0 end | ||
110 | ]], | ||
111 | -- 8 | ||
112 | [[ | ||
113 | do return end | ||
114 | do return 123 end | ||
115 | do return "foo","bar" end | ||
116 | ]], | ||
117 | -- 9 | ||
118 | [[ | ||
119 | while true do foo=not foo end | ||
120 | while foo~=42 do foo=foo-1 end | ||
121 | while true do break end | ||
122 | ]], | ||
123 | -- 10 | ||
124 | [[ | ||
125 | repeat foo=foo.."bar" until false | ||
126 | repeat foo=foo/2 until foo<1 | ||
127 | repeat break until false | ||
128 | ]], | ||
129 | -- 11 | ||
130 | [[ | ||
131 | for i=1,10 do foo=i end | ||
132 | for i=1,10,2 do break end | ||
133 | for i in foo do bar=0 end | ||
134 | for i,j in foo,bar do baz=0 end | ||
135 | ]], | ||
136 | -- 12 | ||
137 | [[ | ||
138 | local foo | ||
139 | local foo,bar,baz | ||
140 | local foo,bar="foo","bar" | ||
141 | ]], | ||
142 | -- 13 | ||
143 | [[ | ||
144 | local function foo() return end | ||
145 | local function foo(a) return end | ||
146 | local function foo(x,y,z) return end | ||
147 | local function foo(x,...) return end | ||
148 | ]], | ||
149 | -- 14 | ||
150 | [[ | ||
151 | function foo() return end | ||
152 | function foo(a) return end | ||
153 | function foo(x,y,z) return end | ||
154 | function foo(x,...) return end | ||
155 | ]], | ||
156 | -- 15 | ||
157 | [[ | ||
158 | function foo.bar(p) return end | ||
159 | function foo.bar.baz(p) return end | ||
160 | function foo:bar(p) return end | ||
161 | function foo.bar.baz(p) return end | ||
162 | ]], | ||
163 | -- 16 | ||
164 | [[ | ||
165 | foo = function() return end | ||
166 | foo = function(x,y) return end | ||
167 | foo = function(...) return end | ||
168 | ]], | ||
169 | -- 17 | ||
170 | [[ | ||
171 | foo = {} | ||
172 | foo = { 1,2,3; "foo"; } | ||
173 | foo = { bar=77, baz=88, } | ||
174 | foo = { ["bar"]=77, ["baz"]=88, } | ||
175 | ]], | ||
176 | } | ||
177 | |||
178 | -- helps to skip old stuff during development of snippets | ||
179 | local do_beg, do_end = 1, table.getn(test_case) | ||
180 | |||
181 | -- loop for all example snippets | ||
182 | for i = do_beg, do_end do | ||
183 | local fname = "parser_log/sample_"..string.format("%02d", i)..".lua" | ||
184 | local src = test_case[i] | ||
185 | local OUTF = io.open(fname, "wb") | ||
186 | if not OUTF then error("failed to write to file '"..fname.."'") end | ||
187 | -- write out actual source for comparison | ||
188 | OUTF:write( | ||
189 | "-- START OF SOURCE --\n".. | ||
190 | src.. | ||
191 | "-- END OF SOURCE --\n".. | ||
192 | "\n" | ||
193 | ) | ||
194 | -- attempt to parse | ||
195 | local luaX = lex_init(src, "=string") | ||
196 | local luaY = parser_init(luaX) | ||
197 | local fs = luaY:parser() | ||
198 | -- grab logged messages and write | ||
199 | local log = fs.log | ||
200 | local indent = 0 | ||
201 | for i = 1, table.getn(log) do | ||
202 | local ln = log[i] | ||
203 | -- handle indentation | ||
204 | local tag = string.sub(ln, 1, 2) | ||
205 | if tag == ">>" or tag == "<<" then | ||
206 | ln = string.sub(ln, 4) | ||
207 | end | ||
208 | if tag == ">>" then | ||
209 | indent = indent + 1 | ||
210 | end | ||
211 | OUTF:write(string.rep(" ", indent)..ln.."\n") | ||
212 | if tag == "<<" then | ||
213 | indent = indent - 1 | ||
214 | end | ||
215 | end | ||
216 | -- we're done | ||
217 | OUTF:close() | ||
218 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser_mk3_2.lua | ||
4 | Test for lparser_mk3.lua, using the test case file | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006-2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * unlike the equivalent in the orig-5.0.3/ directory, this version | ||
18 | -- tests only parsing, lparser_mk3 cannot generate binary chunks | ||
19 | -- * the test cases are in the test_lua directory (test_parser-5.0.lua) | ||
20 | ----------------------------------------------------------------------]] | ||
21 | |||
22 | -- * true if you want an output of all failure cases in native Lua, | ||
23 | -- for checking whether test cases fail where you intend them to | ||
24 | local DEBUG_FAILS = false | ||
25 | |||
26 | ------------------------------------------------------------------------ | ||
27 | -- test the whole kaboodle | ||
28 | ------------------------------------------------------------------------ | ||
29 | |||
30 | local lex_init = require("../llex_mk3") | ||
31 | local parser_init = require("../lparser_mk3") | ||
32 | |||
33 | ------------------------------------------------------------------------ | ||
34 | -- load test cases | ||
35 | ------------------------------------------------------------------------ | ||
36 | |||
37 | require("../../test_lua/test_parser-5.0") | ||
38 | |||
39 | local test, expect, heading = {}, {}, {} | ||
40 | local total, total_pass, total_fail = 0, 0, 0 | ||
41 | |||
42 | for ln in string.gfind(tests_source, "([^\n]*)\n") do | ||
43 | if string.find(ln, "^%s*%-%-") then | ||
44 | -- comment, ignore | ||
45 | else | ||
46 | local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") | ||
47 | if m then | ||
48 | heading[total + 1] = head -- informational heading | ||
49 | else | ||
50 | total = total + 1 | ||
51 | local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") | ||
52 | if n then -- FAIL test case | ||
53 | ln = string.sub(ln, 1, n - 1) -- remove comment | ||
54 | expect[total] = "FAIL" | ||
55 | total_fail = total_fail + 1 | ||
56 | else -- PASS test case | ||
57 | expect[total] = "PASS" | ||
58 | total_pass = total_pass + 1 | ||
59 | end--n | ||
60 | test[total] = ln | ||
61 | end--m | ||
62 | end--ln | ||
63 | end--for | ||
64 | |||
65 | print("Tests loaded: "..total.." (total), " | ||
66 | ..total_pass.." (passes), " | ||
67 | ..total_fail.." (fails)") | ||
68 | |||
69 | ------------------------------------------------------------------------ | ||
70 | -- verify test cases using native Lua | ||
71 | ------------------------------------------------------------------------ | ||
72 | |||
73 | local last_head = "TESTS: no heading yet" | ||
74 | for i = 1, total do | ||
75 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
76 | -- show progress | ||
77 | if head then | ||
78 | last_head = head | ||
79 | if DEBUG_FAILS then print("\n"..head.."\n") end | ||
80 | end | ||
81 | ------------------------------------------------------------------ | ||
82 | -- perform test | ||
83 | local f, err = loadstring(test_case) | ||
84 | -- look at outcome | ||
85 | ------------------------------------------------------------------ | ||
86 | if f then-- actual PASS | ||
87 | if expected == "FAIL" then | ||
88 | print("\nVerified as PASS but expected to FAIL".. | ||
89 | "\n-------------------------------------") | ||
90 | print("Lastest heading: "..last_head) | ||
91 | print("TEST: "..test_case) | ||
92 | os.exit() | ||
93 | end | ||
94 | ------------------------------------------------------------------ | ||
95 | else-- actual FAIL | ||
96 | if expected == "PASS" then | ||
97 | print("\nVerified as FAIL but expected to PASS".. | ||
98 | "\n-------------------------------------") | ||
99 | print("Lastest heading: "..last_head) | ||
100 | print("TEST: "..test_case) | ||
101 | print("ERROR: "..err) | ||
102 | os.exit() | ||
103 | end | ||
104 | if DEBUG_FAILS then | ||
105 | print("TEST: "..test_case) | ||
106 | print("ERROR: "..err.."\n") | ||
107 | end | ||
108 | ------------------------------------------------------------------ | ||
109 | end--f | ||
110 | end--for | ||
111 | |||
112 | print("Test cases verified using native Lua, no anomalies.") | ||
113 | |||
114 | ------------------------------------------------------------------------ | ||
115 | -- test using Yueliang front end | ||
116 | ------------------------------------------------------------------------ | ||
117 | |||
118 | local last_head = "TESTS: no heading yet" | ||
119 | for i = 1, total do | ||
120 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
121 | -- show progress | ||
122 | if head then last_head = head end | ||
123 | ------------------------------------------------------------------ | ||
124 | -- perform test | ||
125 | luaX = lex_init(test_case, "=test_sample") | ||
126 | luaY = parser_init(luaX) | ||
127 | |||
128 | local status, func = pcall(luaY.parser, luaY) | ||
129 | -- look at outcome | ||
130 | ------------------------------------------------------------------ | ||
131 | if status then-- actual PASS | ||
132 | if expected == "FAIL" then | ||
133 | print("\nTested as PASS but expected to FAIL".. | ||
134 | "\n-----------------------------------") | ||
135 | print("Lastest heading: "..last_head) | ||
136 | print("TEST: "..test_case) | ||
137 | os.exit() | ||
138 | end | ||
139 | ------------------------------------------------------------------ | ||
140 | else-- actual FAIL | ||
141 | if expected == "PASS" then | ||
142 | print("\nTested as FAIL but expected to PASS".. | ||
143 | "\n-----------------------------------") | ||
144 | print("Lastest heading: "..last_head) | ||
145 | print("TEST: "..test_case) | ||
146 | os.exit() | ||
147 | else | ||
148 | io.stdout:write("-") | ||
149 | end | ||
150 | ------------------------------------------------------------------ | ||
151 | end--status | ||
152 | io.stdout:write("\rTesting ["..i.."]...") | ||
153 | end--for | ||
154 | print(" done.") | ||
155 | |||
156 | print("Test cases run on Yueliang, no anomalies.") | ||
157 | |||
158 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser_mk3b.lua | ||
4 | Test for lparser_mk3b.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- test the whole kaboodle | ||
17 | ------------------------------------------------------------------------ | ||
18 | |||
19 | local lex_init = require("../llex_mk3") | ||
20 | local parser_init = require("../lparser_mk3b") | ||
21 | |||
22 | ------------------------------------------------------------------------ | ||
23 | -- dump contents of log table | ||
24 | ------------------------------------------------------------------------ | ||
25 | |||
26 | local function dump_log(fs) | ||
27 | local log = fs.log | ||
28 | for i = 1, table.getn(log) do | ||
29 | print(log[i]) | ||
30 | end | ||
31 | end | ||
32 | |||
33 | ------------------------------------------------------------------------ | ||
34 | -- automatic dumper of output log data | ||
35 | ------------------------------------------------------------------------ | ||
36 | |||
37 | local test_case = { | ||
38 | -- 1 | ||
39 | [[ | ||
40 | print(a) | ||
41 | ]], | ||
42 | -- 2 | ||
43 | [[ | ||
44 | local a | ||
45 | print(a) | ||
46 | ]], | ||
47 | -- 3 | ||
48 | [[ | ||
49 | do | ||
50 | local a | ||
51 | print(a) | ||
52 | end | ||
53 | print(a) | ||
54 | ]], | ||
55 | -- 4 | ||
56 | [[ | ||
57 | local a,b,c | ||
58 | do | ||
59 | local b | ||
60 | print(b) | ||
61 | end | ||
62 | print(b) | ||
63 | ]], | ||
64 | -- 5 | ||
65 | [[ | ||
66 | local function foo() end | ||
67 | bar = foo | ||
68 | ]], | ||
69 | -- 6 | ||
70 | [[ | ||
71 | do | ||
72 | local function foo() end | ||
73 | bar = foo | ||
74 | end | ||
75 | baz = foo | ||
76 | ]], | ||
77 | -- 7 | ||
78 | [[ | ||
79 | local foo | ||
80 | local function bar() | ||
81 | baz = nil | ||
82 | foo = bar() | ||
83 | end | ||
84 | foo = bar | ||
85 | ]], | ||
86 | -- 8 | ||
87 | [[ | ||
88 | local foo | ||
89 | local function bar() | ||
90 | local function baz() | ||
91 | local foo, bar | ||
92 | foo = bar | ||
93 | foo = baz | ||
94 | end | ||
95 | foo = bar | ||
96 | foo = baz | ||
97 | end | ||
98 | foo = bar | ||
99 | foo = baz | ||
100 | ]], | ||
101 | -- 9 | ||
102 | [[ | ||
103 | function foo:bar() | ||
104 | print(self) | ||
105 | end | ||
106 | ]], | ||
107 | -- 10 | ||
108 | [[ | ||
109 | function foo(...) | ||
110 | print(arg) | ||
111 | end | ||
112 | ]], | ||
113 | -- 11 | ||
114 | [[ | ||
115 | local c,d | ||
116 | function foo(a,b,c) | ||
117 | print(a,c,d,e) | ||
118 | end | ||
119 | ]], | ||
120 | -- 11 | ||
121 | [[ | ||
122 | function foo(a,b) | ||
123 | local bar = function(c,d) | ||
124 | print(a,b,c,d) | ||
125 | end | ||
126 | end | ||
127 | ]], | ||
128 | -- 12 | ||
129 | [[ | ||
130 | for i = 1,10 do | ||
131 | print(i) | ||
132 | end | ||
133 | for i = 1,10,-2 do | ||
134 | print(i) | ||
135 | end | ||
136 | ]], | ||
137 | -- 13 | ||
138 | [[ | ||
139 | for foo in bar() do | ||
140 | print(foo) | ||
141 | end | ||
142 | for foo,bar,baz in spring() do | ||
143 | print(foo,bar,baz) | ||
144 | end | ||
145 | ]], | ||
146 | } | ||
147 | |||
148 | -- helps to skip old stuff during development of snippets | ||
149 | local do_beg, do_end = 1, table.getn(test_case) | ||
150 | |||
151 | -- loop for all example snippets | ||
152 | for i = do_beg, do_end do | ||
153 | local fname = "parser_log/sample_b_"..string.format("%02d", i)..".lua" | ||
154 | local src = test_case[i] | ||
155 | local OUTF = io.open(fname, "wb") | ||
156 | if not OUTF then error("failed to write to file '"..fname.."'") end | ||
157 | -- write out actual source for comparison | ||
158 | OUTF:write( | ||
159 | "-- START OF SOURCE --\n".. | ||
160 | src.. | ||
161 | "-- END OF SOURCE --\n".. | ||
162 | "\n" | ||
163 | ) | ||
164 | -- attempt to parse | ||
165 | local luaX = lex_init(src, "=string") | ||
166 | local luaY = parser_init(luaX) | ||
167 | local fs = luaY:parser() | ||
168 | -- grab logged messages and write | ||
169 | local log = fs.log | ||
170 | local indent = 0 | ||
171 | for i = 1, table.getn(log) do | ||
172 | local ln = log[i] | ||
173 | -- handle indentation | ||
174 | local tag = string.sub(ln, 1, 2) | ||
175 | if tag == ">>" or tag == "<<" then | ||
176 | ln = string.sub(ln, 4) | ||
177 | end | ||
178 | if tag == ">>" then | ||
179 | indent = indent + 1 | ||
180 | end | ||
181 | OUTF:write(string.rep(" ", indent)..ln.."\n") | ||
182 | if tag == "<<" then | ||
183 | indent = indent - 1 | ||
184 | end | ||
185 | end | ||
186 | -- we're done | ||
187 | OUTF:close() | ||
188 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser_mk3b_2.lua | ||
4 | Test for lparser_mk3b.lua, using the test case file | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006-2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * unlike the equivalent in the orig-5.0.3/ directory, this version | ||
18 | -- tests only parsing, lparser_mk3 cannot generate binary chunks | ||
19 | -- * the test cases are in the test_lua directory (test_parser-5.0.lua) | ||
20 | ----------------------------------------------------------------------]] | ||
21 | |||
22 | -- * true if you want an output of all failure cases in native Lua, | ||
23 | -- for checking whether test cases fail where you intend them to | ||
24 | local DEBUG_FAILS = false | ||
25 | |||
26 | ------------------------------------------------------------------------ | ||
27 | -- test the whole kaboodle | ||
28 | ------------------------------------------------------------------------ | ||
29 | |||
30 | local lex_init = require("../llex_mk3") | ||
31 | local parser_init = require("../lparser_mk3b") | ||
32 | |||
33 | ------------------------------------------------------------------------ | ||
34 | -- load test cases | ||
35 | ------------------------------------------------------------------------ | ||
36 | |||
37 | require("../../test_lua/test_parser-5.0") | ||
38 | |||
39 | local test, expect, heading = {}, {}, {} | ||
40 | local total, total_pass, total_fail = 0, 0, 0 | ||
41 | |||
42 | for ln in string.gfind(tests_source, "([^\n]*)\n") do | ||
43 | if string.find(ln, "^%s*%-%-") then | ||
44 | -- comment, ignore | ||
45 | else | ||
46 | local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") | ||
47 | if m then | ||
48 | heading[total + 1] = head -- informational heading | ||
49 | else | ||
50 | total = total + 1 | ||
51 | local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") | ||
52 | if n then -- FAIL test case | ||
53 | ln = string.sub(ln, 1, n - 1) -- remove comment | ||
54 | expect[total] = "FAIL" | ||
55 | total_fail = total_fail + 1 | ||
56 | else -- PASS test case | ||
57 | expect[total] = "PASS" | ||
58 | total_pass = total_pass + 1 | ||
59 | end--n | ||
60 | test[total] = ln | ||
61 | end--m | ||
62 | end--ln | ||
63 | end--for | ||
64 | |||
65 | print("Tests loaded: "..total.." (total), " | ||
66 | ..total_pass.." (passes), " | ||
67 | ..total_fail.." (fails)") | ||
68 | |||
69 | ------------------------------------------------------------------------ | ||
70 | -- verify test cases using native Lua | ||
71 | ------------------------------------------------------------------------ | ||
72 | |||
73 | local last_head = "TESTS: no heading yet" | ||
74 | for i = 1, total do | ||
75 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
76 | -- show progress | ||
77 | if head then | ||
78 | last_head = head | ||
79 | if DEBUG_FAILS then print("\n"..head.."\n") end | ||
80 | end | ||
81 | ------------------------------------------------------------------ | ||
82 | -- perform test | ||
83 | local f, err = loadstring(test_case) | ||
84 | -- look at outcome | ||
85 | ------------------------------------------------------------------ | ||
86 | if f then-- actual PASS | ||
87 | if expected == "FAIL" then | ||
88 | print("\nVerified as PASS but expected to FAIL".. | ||
89 | "\n-------------------------------------") | ||
90 | print("Lastest heading: "..last_head) | ||
91 | print("TEST: "..test_case) | ||
92 | os.exit() | ||
93 | end | ||
94 | ------------------------------------------------------------------ | ||
95 | else-- actual FAIL | ||
96 | if expected == "PASS" then | ||
97 | print("\nVerified as FAIL but expected to PASS".. | ||
98 | "\n-------------------------------------") | ||
99 | print("Lastest heading: "..last_head) | ||
100 | print("TEST: "..test_case) | ||
101 | print("ERROR: "..err) | ||
102 | os.exit() | ||
103 | end | ||
104 | if DEBUG_FAILS then | ||
105 | print("TEST: "..test_case) | ||
106 | print("ERROR: "..err.."\n") | ||
107 | end | ||
108 | ------------------------------------------------------------------ | ||
109 | end--f | ||
110 | end--for | ||
111 | |||
112 | print("Test cases verified using native Lua, no anomalies.") | ||
113 | |||
114 | ------------------------------------------------------------------------ | ||
115 | -- test using Yueliang front end | ||
116 | ------------------------------------------------------------------------ | ||
117 | |||
118 | local last_head = "TESTS: no heading yet" | ||
119 | for i = 1, total do | ||
120 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
121 | -- show progress | ||
122 | if head then last_head = head end | ||
123 | ------------------------------------------------------------------ | ||
124 | -- perform test | ||
125 | luaX = lex_init(test_case, "=test_sample") | ||
126 | luaY = parser_init(luaX) | ||
127 | |||
128 | local status, func = pcall(luaY.parser, luaY) | ||
129 | -- look at outcome | ||
130 | ------------------------------------------------------------------ | ||
131 | if status then-- actual PASS | ||
132 | if expected == "FAIL" then | ||
133 | print("\nTested as PASS but expected to FAIL".. | ||
134 | "\n-----------------------------------") | ||
135 | print("Lastest heading: "..last_head) | ||
136 | print("TEST: "..test_case) | ||
137 | os.exit() | ||
138 | end | ||
139 | ------------------------------------------------------------------ | ||
140 | else-- actual FAIL | ||
141 | if expected == "PASS" then | ||
142 | print("\nTested as FAIL but expected to PASS".. | ||
143 | "\n-----------------------------------") | ||
144 | print("Lastest heading: "..last_head) | ||
145 | print("TEST: "..test_case) | ||
146 | os.exit() | ||
147 | else | ||
148 | io.stdout:write("-") | ||
149 | end | ||
150 | ------------------------------------------------------------------ | ||
151 | end--status | ||
152 | io.stdout:write("\rTesting ["..i.."]...") | ||
153 | end--for | ||
154 | print(" done.") | ||
155 | |||
156 | print("Test cases run on Yueliang, no anomalies.") | ||
157 | |||
158 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lzio.lua | ||
4 | Test for lzio.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | -- manual test for lzio.lua lua-style chunk reader | ||
16 | |||
17 | local zio_init = require("../lzio_mk2") | ||
18 | |||
19 | local z | ||
20 | function dump(z) | ||
21 | while true do | ||
22 | local c = z:getc() | ||
23 | io.stdout:write("("..c..")") | ||
24 | if c == "EOZ" then break end | ||
25 | end | ||
26 | io.stdout:write("\n") | ||
27 | end | ||
28 | |||
29 | -- z = zio_init("@<filename>") for a file | ||
30 | -- z = zio_init("<string>") for a string | ||
31 | |||
32 | -- [[ | ||
33 | z = zio_init("hello, world!") | ||
34 | dump(z) | ||
35 | z = zio_init("line1\nline2\n") | ||
36 | dump(z) | ||
37 | z = zio_init("@test_lzio_mk2.lua") | ||
38 | dump(z) | ||
39 | --]] | ||
40 | |||
41 | -- test read beyond end of file | ||
42 | -- bug reported by Adam429 | ||
43 | --[[ | ||
44 | z = zio_init("@test_lzio_mk2.lua") | ||
45 | while true do | ||
46 | local c = z:getc() | ||
47 | io.stdout:write("("..c..")") | ||
48 | if c == "EOZ" then break end | ||
49 | end | ||
50 | print(z:getc()) | ||
51 | print(z:getc()) | ||
52 | io.stdout:write("\n") | ||
53 | --]] | ||
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 @@ | |||
1 | nat-5.1.3 | ||
2 | |||
3 | This directory contains versions of front end files that are rewritten | ||
4 | to be more "native" to Lua. These files should be considered as | ||
5 | exercises in exploring ways to write the front end, for example, to | ||
6 | write a front end that is optimized for size, etc. See also file size | ||
7 | data further below. | ||
8 | |||
9 | The following are the different versions available (mk2 == "mark 2", | ||
10 | this is commonly used in the UK, e.g. for aeroplanes during WWII): | ||
11 | |||
12 | Lexers | ||
13 | ------ | ||
14 | |||
15 | NOTE: These lexers should behave mostly identically to the original C | ||
16 | lexer. Locale support for non-standard decimal points is missing. Also, | ||
17 | all strings and long strings have line endings normalized to LF. | ||
18 | |||
19 | llex_mk2 Rewritten from original ported code to become more | ||
20 | Lua-like. Needs input to be entered as a single string. | ||
21 | Unless an application's need is very unusual, this | ||
22 | should not be a problem. It will not work for per-line | ||
23 | interaction, though. This version is also somewhat | ||
24 | optimized for size; its stripped binary chunk size is | ||
25 | 3716 bytes. | ||
26 | |||
27 | Status: TESTED | ||
28 | |||
29 | Parsers | ||
30 | ------- | ||
31 | |||
32 | lparser_mk2 Written for the simplified lexer interface of llex_mk2. | ||
33 | This is a lexer skeleton, stripped of codegen code. Has | ||
34 | a minimum of variable management code added, and tracks | ||
35 | the is_vararg flag of a function. See the comments in | ||
36 | the source code for more information. Without logging | ||
37 | messages and comments, it should be under 600 LOC. A | ||
38 | binary chunk of lparser_mk2 (stripped) is 15783 bytes. | ||
39 | |||
40 | Sample output of the parser message logger can be found | ||
41 | in the test/parser_log subdirectory. | ||
42 | |||
43 | Tested with test_parser-5.1.lua, the Lua 5.1.x parser test | ||
44 | cases in the test_lua/ directory, appears to be fine. | ||
45 | |||
46 | Compared to the 5.0.x parser skeleton, the main changes | ||
47 | are: (a) 'arg' not implemented, so it appears as a global, | ||
48 | and (b) '...' recognized as the last function parameter. | ||
49 | |||
50 | Status: SNIPPETS APPEAR TO WORK | ||
51 | |||
52 | Other notes: | ||
53 | ------------ | ||
54 | |||
55 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | llex.lua | ||
4 | Lua 5.1 lexical analyzer in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * takes in the entire source at once | ||
18 | -- * greatly simplified chunkid, error handling | ||
19 | -- * NO shbang handling (it's done elsewhere in Lua 5.1) | ||
20 | -- * NO localized decimal point replacement magic | ||
21 | -- * NO limit to number of lines (MAX_INT = 2147483645) | ||
22 | -- * NO support for compatible long strings (LUA_COMPAT_LSTR) | ||
23 | -- * NO next(), lookahead() because I want next() to set tok and | ||
24 | -- seminfo that are locals, and that can only be done easily in | ||
25 | -- lparser, not llex. lastline would be handled in lparser too. | ||
26 | -- | ||
27 | -- Usage example: | ||
28 | -- local llex = require("llex_mk2") | ||
29 | -- llex.init(source_code, source_code_name) | ||
30 | -- repeat | ||
31 | -- local token, seminfo = llex.llex() | ||
32 | -- until token == "<eof>" | ||
33 | -- | ||
34 | ----------------------------------------------------------------------]] | ||
35 | |||
36 | local base = _G | ||
37 | local string = require "string" | ||
38 | module "llex" | ||
39 | |||
40 | ---------------------------------------------------------------------- | ||
41 | -- initialize keyword list | ||
42 | ---------------------------------------------------------------------- | ||
43 | local kw = {} | ||
44 | for v in string.gmatch([[ | ||
45 | and break do else elseif end false for function if in | ||
46 | local nil not or repeat return then true until while]], "%S+") do | ||
47 | kw[v] = true | ||
48 | end | ||
49 | |||
50 | ---------------------------------------------------------------------- | ||
51 | -- initialize lexer for given source _z and source name _sourceid | ||
52 | ---------------------------------------------------------------------- | ||
53 | local z, sourceid, I | ||
54 | local find = string.find | ||
55 | local match = string.match | ||
56 | local sub = string.sub | ||
57 | |||
58 | function init(_z, _sourceid) | ||
59 | z = _z -- source | ||
60 | sourceid = _sourceid -- name of source | ||
61 | I = 1 -- lexer's position in source | ||
62 | ln = 1 -- line number | ||
63 | end | ||
64 | |||
65 | ---------------------------------------------------------------------- | ||
66 | -- returns a chunk name or id, no truncation for long names | ||
67 | ---------------------------------------------------------------------- | ||
68 | function chunkid() | ||
69 | if sourceid and match(sourceid, "^[=@]") then | ||
70 | return sub(sourceid, 2) -- remove first char | ||
71 | end | ||
72 | return "[string]" | ||
73 | end | ||
74 | |||
75 | ---------------------------------------------------------------------- | ||
76 | -- formats error message and throws error | ||
77 | -- * a simplified version, does not report what token was responsible | ||
78 | ---------------------------------------------------------------------- | ||
79 | function errorline(s, line) | ||
80 | base.error(string.format("%s:%d: %s", chunkid(), line or ln, s)) | ||
81 | end | ||
82 | |||
83 | ---------------------------------------------------------------------- | ||
84 | -- handles line number incrementation and end-of-line characters | ||
85 | ---------------------------------------------------------------------- | ||
86 | |||
87 | local function inclinenumber(i) | ||
88 | local sub = sub | ||
89 | local old = sub(z, i, i) | ||
90 | i = i + 1 -- skip '\n' or '\r' | ||
91 | local c = sub(z, i, i) | ||
92 | if (c == "\n" or c == "\r") and (c ~= old) then | ||
93 | i = i + 1 -- skip '\n\r' or '\r\n' | ||
94 | end | ||
95 | ln = ln + 1 | ||
96 | I = i | ||
97 | return i | ||
98 | end | ||
99 | |||
100 | ------------------------------------------------------------------------ | ||
101 | -- count separators ("=") in a long string delimiter | ||
102 | ------------------------------------------------------------------------ | ||
103 | local function skip_sep(i) | ||
104 | local sub = sub | ||
105 | local s = sub(z, i, i) | ||
106 | i = i + 1 | ||
107 | local count = #match(z, "=*", i) -- note, take the length | ||
108 | i = i + count | ||
109 | I = i | ||
110 | return (sub(z, i, i) == s) and count or (-count) - 1 | ||
111 | end | ||
112 | |||
113 | ---------------------------------------------------------------------- | ||
114 | -- reads a long string or long comment | ||
115 | ---------------------------------------------------------------------- | ||
116 | |||
117 | local function read_long_string(is_str, sep) | ||
118 | local i = I + 1 -- skip 2nd '[' | ||
119 | local sub = sub | ||
120 | local buff = "" | ||
121 | local c = sub(z, i, i) | ||
122 | if c == "\r" or c == "\n" then -- string starts with a newline? | ||
123 | i = inclinenumber(i) -- skip it | ||
124 | end | ||
125 | local j = i | ||
126 | while true do | ||
127 | local p, q, r = find(z, "([\r\n%]])", i) -- (long range) | ||
128 | if not p then | ||
129 | errorline(is_str and "unfinished long string" or | ||
130 | "unfinished long comment") | ||
131 | end | ||
132 | if is_str then | ||
133 | buff = buff..sub(z, i, p - 1) -- save string portions | ||
134 | end | ||
135 | i = p | ||
136 | if r == "]" then -- delimiter test | ||
137 | if skip_sep(i) == sep then | ||
138 | i = I + 1 -- skip 2nd ']' | ||
139 | break | ||
140 | end | ||
141 | buff = buff..sub(z, i, I - 1) | ||
142 | i = I | ||
143 | else -- newline | ||
144 | buff = buff.."\n" | ||
145 | i = inclinenumber(i) | ||
146 | end | ||
147 | end--while | ||
148 | I = i | ||
149 | return buff | ||
150 | end | ||
151 | |||
152 | ---------------------------------------------------------------------- | ||
153 | -- reads a string | ||
154 | ---------------------------------------------------------------------- | ||
155 | local function read_string(del) | ||
156 | local i = I | ||
157 | local find = find | ||
158 | local sub = sub | ||
159 | local buff = "" | ||
160 | while true do | ||
161 | local p, q, r = find(z, "([\n\r\\\"\'])", i) -- (long range) | ||
162 | if p then | ||
163 | if r == "\n" or r == "\r" then | ||
164 | errorline("unfinished string") | ||
165 | end | ||
166 | buff = buff..sub(z, i, p - 1) -- normal portions | ||
167 | i = p | ||
168 | if r == "\\" then -- handle escapes | ||
169 | i = i + 1 | ||
170 | r = sub(z, i, i) | ||
171 | if r == "" then break end -- (EOZ error) | ||
172 | p = find("abfnrtv\n\r", r, 1, true) | ||
173 | ------------------------------------------------------ | ||
174 | if p then -- special escapes | ||
175 | if p > 7 then | ||
176 | r = "\n" | ||
177 | i = inclinenumber(i) | ||
178 | else | ||
179 | r = sub("\a\b\f\n\r\t\v", p, p) | ||
180 | i = i + 1 | ||
181 | end | ||
182 | ------------------------------------------------------ | ||
183 | elseif find(r, "%D") then -- other non-digits | ||
184 | i = i + 1 | ||
185 | ------------------------------------------------------ | ||
186 | else -- \xxx sequence | ||
187 | local p, q, s = find(z, "^(%d%d?%d?)", i) | ||
188 | i = q + 1 | ||
189 | if s + 1 > 256 then -- UCHAR_MAX | ||
190 | errorline("escape sequence too large") | ||
191 | end | ||
192 | r = string.char(s) | ||
193 | ------------------------------------------------------ | ||
194 | end--if p | ||
195 | else | ||
196 | i = i + 1 | ||
197 | if r == del then -- ending delimiter | ||
198 | I = i; return buff -- return string | ||
199 | end | ||
200 | end--if r | ||
201 | buff = buff..r -- handled escapes falls through to here | ||
202 | else | ||
203 | break -- (error) | ||
204 | end--if p | ||
205 | end--while | ||
206 | errorline("unfinished string") | ||
207 | end | ||
208 | |||
209 | ------------------------------------------------------------------------ | ||
210 | -- main lexer function | ||
211 | ------------------------------------------------------------------------ | ||
212 | function llex() | ||
213 | local find = find | ||
214 | local match = match | ||
215 | while true do--outer | ||
216 | local i = I | ||
217 | -- inner loop allows break to be used to nicely section tests | ||
218 | while true do--inner | ||
219 | ---------------------------------------------------------------- | ||
220 | local p, _, r = find(z, "^([_%a][_%w]*)", i) | ||
221 | if p then | ||
222 | I = i + #r | ||
223 | if kw[r] then return r end -- reserved word (keyword) | ||
224 | return "<name>", r -- identifier | ||
225 | end | ||
226 | ---------------------------------------------------------------- | ||
227 | local p, _, r = find(z, "^(%.?)%d", i) | ||
228 | if p then -- numeral | ||
229 | if r == "." then i = i + 1 end | ||
230 | local _, q, r = find(z, "^%d*[%.%d]*([eE]?)", i) | ||
231 | i = q + 1 | ||
232 | if #r == 1 then -- optional exponent | ||
233 | if match(z, "^[%+%-]", i) then -- optional sign | ||
234 | i = i + 1 | ||
235 | end | ||
236 | end | ||
237 | local _, q = find(z, "^[_%w]*", i) | ||
238 | I = q + 1 | ||
239 | local v = base.tonumber(sub(z, p, q)) -- handles hex also | ||
240 | if not v then errorline("malformed number") end | ||
241 | return "<number>", v | ||
242 | end | ||
243 | ---------------------------------------------------------------- | ||
244 | local p, q, r = find(z, "^(%s)[ \t]*", i) | ||
245 | if p then | ||
246 | if r == "\n" or r == "\r" then -- newline | ||
247 | inclinenumber(i) | ||
248 | else | ||
249 | I = q + 1 -- whitespace | ||
250 | end | ||
251 | break -- (continue) | ||
252 | end | ||
253 | ---------------------------------------------------------------- | ||
254 | local r = match(z, "^%p", i) | ||
255 | if r then | ||
256 | local p = find("-[\"\'.=<>~", r, 1, true) | ||
257 | if p then | ||
258 | -- two-level if block for punctuation/symbols | ||
259 | -------------------------------------------------------- | ||
260 | if p <= 2 then | ||
261 | if p == 1 then -- minus | ||
262 | local c = match(z, "^%-%-(%[?)", i) | ||
263 | if c then | ||
264 | i = i + 2 | ||
265 | local sep = -1 | ||
266 | if c == "[" then | ||
267 | sep = skip_sep(i) | ||
268 | end | ||
269 | if sep >= 0 then -- long comment | ||
270 | read_long_string(false, sep) | ||
271 | else -- short comment | ||
272 | I = find(z, "[\n\r]", i) or (#z + 1) | ||
273 | end | ||
274 | break -- (continue) | ||
275 | end | ||
276 | -- (fall through for "-") | ||
277 | else -- [ or long string | ||
278 | local sep = skip_sep(i) | ||
279 | if sep >= 0 then | ||
280 | return "<string>", read_long_string(true, sep) | ||
281 | elseif sep == -1 then | ||
282 | return "[" | ||
283 | else | ||
284 | errorline("invalid long string delimiter") | ||
285 | end | ||
286 | end | ||
287 | -------------------------------------------------------- | ||
288 | elseif p <= 5 then | ||
289 | if p < 5 then -- strings | ||
290 | I = i + 1 | ||
291 | return "<string>", read_string(r) | ||
292 | end | ||
293 | r = match(z, "^%.%.?%.?", i) -- .|..|... dots | ||
294 | -- (fall through) | ||
295 | -------------------------------------------------------- | ||
296 | else -- relational | ||
297 | r = match(z, "^%p=?", i) | ||
298 | -- (fall through) | ||
299 | end | ||
300 | end | ||
301 | I = i + #r; return r -- for other symbols, fall through | ||
302 | end | ||
303 | ---------------------------------------------------------------- | ||
304 | local r = sub(z, i, i) | ||
305 | if r ~= "" then | ||
306 | I = i + 1; return r -- other single-char tokens | ||
307 | end | ||
308 | return "<eof>" -- end of stream | ||
309 | ---------------------------------------------------------------- | ||
310 | end--while inner | ||
311 | end--while outer | ||
312 | end | ||
313 | |||
314 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lparser.lua | ||
4 | Lua 5.1 parser in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * this is a Lua 5.1.x parser skeleton, for the llex_mk2.lua lexer | ||
18 | -- * builds some data, performs logging for educational purposes | ||
19 | -- * target is to have relatively efficient and clear code | ||
20 | -- * NO parsing limitations, since it is only a parser skeleton. Some | ||
21 | -- limits set in the default sources (in luaconf.h) are: | ||
22 | -- LUAI_MAXVARS = 200 | ||
23 | -- LUAI_MAXUPVALUES = 60 | ||
24 | -- LUAI_MAXCCALLS = 200 | ||
25 | -- * NO support for 'arg' vararg functions (LUA_COMPAT_VARARG) | ||
26 | -- * init(llex) needs one parameter, a lexer module that implements: | ||
27 | -- llex.lex() - returns appropriate [token, semantic info] pairs | ||
28 | -- llex.ln - current line number | ||
29 | -- llex.errorline(s, [line]) - dies with error message | ||
30 | -- | ||
31 | -- Usage example: | ||
32 | -- local llex = require("llex_mk2") | ||
33 | -- local lparser = require("lparser_mk2") | ||
34 | -- llex.init(source_code, source_code_name) | ||
35 | -- lparser.init(llex) | ||
36 | -- local fs = lparser.parser() | ||
37 | -- | ||
38 | -- Development notes: | ||
39 | -- * see test_parser-5.1.lua for grammar elements based on lparser.c | ||
40 | -- * next() (renamed to nextt) and lookahead() has been moved from llex; | ||
41 | -- it's more convenient to keep tok, seminfo as local variables here | ||
42 | -- * syntaxerror() is from llex, easier to keep here since little token | ||
43 | -- translation needed in preparation of error message | ||
44 | -- * lparser has a few extra items to help parsing/syntax checking | ||
45 | -- (a) line number (error reporting), lookahead token storage | ||
46 | -- * (b) per-prototype states needs a storage list | ||
47 | -- * (c) 'break' needs a per-block flag in a stack | ||
48 | -- * (d) 'kind' (v.k) testing needed in expr_stat() and assignment() | ||
49 | -- for disambiguation, thus v.k manipulation is retained | ||
50 | -- * (e) one line # var (lastln) for ambiguous (split line) function | ||
51 | -- call checking | ||
52 | -- * (f) LUA_COMPAT_VARARG compatibility code completely removed | ||
53 | -- * (g) minimal variable management code to differentiate each type | ||
54 | -- * parsing starts from the end of this file in parser() | ||
55 | ----------------------------------------------------------------------]] | ||
56 | |||
57 | local base = _G | ||
58 | local string = require "string" | ||
59 | module "lparser" | ||
60 | local _G = base.getfenv() | ||
61 | |||
62 | --[[-------------------------------------------------------------------- | ||
63 | -- variable and data structure initialization | ||
64 | ----------------------------------------------------------------------]] | ||
65 | |||
66 | ---------------------------------------------------------------------- | ||
67 | -- initialization: main variables | ||
68 | ---------------------------------------------------------------------- | ||
69 | |||
70 | local llex, llex_lex -- references lexer module, function | ||
71 | local line -- start line # for error messages | ||
72 | local lastln -- last line # for ambiguous syntax chk | ||
73 | local tok, seminfo -- token, semantic info pair | ||
74 | local peek_tok, peek_sem -- ditto, for lookahead | ||
75 | local fs -- current function state | ||
76 | local top_fs -- top-level function state | ||
77 | |||
78 | -- forward references for local functions | ||
79 | local explist1, expr, block, exp1, body | ||
80 | |||
81 | ---------------------------------------------------------------------- | ||
82 | -- initialization: data structures | ||
83 | ---------------------------------------------------------------------- | ||
84 | |||
85 | local gmatch = string.gmatch | ||
86 | |||
87 | local block_follow = {} -- lookahead check in chunk(), returnstat() | ||
88 | for v in gmatch("else elseif end until <eof>", "%S+") do | ||
89 | block_follow[v] = true | ||
90 | end | ||
91 | |||
92 | local stat_call = {} -- lookup for calls in stat() | ||
93 | for v in gmatch("if while do for repeat function local return break", "%S+") do | ||
94 | stat_call[v] = v.."_stat" | ||
95 | end | ||
96 | |||
97 | local binopr_left = {} -- binary operators, left priority | ||
98 | local binopr_right = {} -- binary operators, right priority | ||
99 | for op, lt, rt in gmatch([[ | ||
100 | {+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{% 7 7} | ||
101 | {^ 10 9}{.. 5 4} | ||
102 | {~= 3 3}{== 3 3} | ||
103 | {< 3 3}{<= 3 3}{> 3 3}{>= 3 3} | ||
104 | {and 2 2}{or 1 1} | ||
105 | ]], "{(%S+)%s(%d+)%s(%d+)}") do | ||
106 | binopr_left[op] = lt + 0 | ||
107 | binopr_right[op] = rt + 0 | ||
108 | end | ||
109 | |||
110 | local unopr = { ["not"] = true, ["-"] = true, | ||
111 | ["#"] = true, } -- unary operators | ||
112 | local UNARY_PRIORITY = 8 -- priority for unary operators | ||
113 | |||
114 | --[[-------------------------------------------------------------------- | ||
115 | -- logging: this logging function is for educational purposes | ||
116 | -- * logged data can be retrieved from the returned data structure | ||
117 | ----------------------------------------------------------------------]] | ||
118 | |||
119 | local function log(msg) | ||
120 | local log = top_fs.log | ||
121 | if not log then -- initialize message table | ||
122 | log = {}; top_fs.log = log | ||
123 | end | ||
124 | log[#log + 1] = msg | ||
125 | end | ||
126 | |||
127 | --[[-------------------------------------------------------------------- | ||
128 | -- support functions | ||
129 | ----------------------------------------------------------------------]] | ||
130 | |||
131 | ---------------------------------------------------------------------- | ||
132 | -- handles incoming token, semantic information pairs; these two | ||
133 | -- functions are from llex, they are put here because keeping the | ||
134 | -- tok, seminfo variables here as locals is more convenient | ||
135 | -- * NOTE: 'nextt' is named 'next' originally | ||
136 | ---------------------------------------------------------------------- | ||
137 | |||
138 | -- reads in next token | ||
139 | local function nextt() | ||
140 | lastln = llex.ln | ||
141 | if peek_tok then -- is there a look-ahead token? if yes, use it | ||
142 | tok, seminfo = peek_tok, peek_sem | ||
143 | peek_tok = nil | ||
144 | else | ||
145 | tok, seminfo = llex_lex() -- read next token | ||
146 | end | ||
147 | end | ||
148 | |||
149 | -- peek at next token (single lookahead for table constructor) | ||
150 | local function lookahead() | ||
151 | peek_tok, peek_sem = llex_lex() | ||
152 | return peek_tok | ||
153 | end | ||
154 | |||
155 | ---------------------------------------------------------------------- | ||
156 | -- throws a syntax error, or if token expected is not there | ||
157 | ---------------------------------------------------------------------- | ||
158 | |||
159 | local function syntaxerror(msg) | ||
160 | local tok = tok | ||
161 | if tok ~= "<number>" and tok ~= "<string>" then | ||
162 | if tok == "<name>" then tok = seminfo end | ||
163 | tok = "'"..tok.."'" | ||
164 | end | ||
165 | llex.errorline(msg.." near "..tok) | ||
166 | end | ||
167 | |||
168 | local function error_expected(token) | ||
169 | syntaxerror("'"..token.."' expected") | ||
170 | end | ||
171 | |||
172 | ---------------------------------------------------------------------- | ||
173 | -- tests for a token, returns outcome | ||
174 | -- * return value changed to boolean | ||
175 | ---------------------------------------------------------------------- | ||
176 | |||
177 | local function testnext(c) | ||
178 | if tok == c then nextt(); return true end | ||
179 | end | ||
180 | |||
181 | ---------------------------------------------------------------------- | ||
182 | -- check for existence of a token, throws error if not found | ||
183 | ---------------------------------------------------------------------- | ||
184 | |||
185 | local function check(c) | ||
186 | if tok ~= c then error_expected(c) end | ||
187 | end | ||
188 | |||
189 | ---------------------------------------------------------------------- | ||
190 | -- verify existence of a token, then skip it | ||
191 | ---------------------------------------------------------------------- | ||
192 | |||
193 | local function checknext(c) | ||
194 | check(c); nextt() | ||
195 | end | ||
196 | |||
197 | ---------------------------------------------------------------------- | ||
198 | -- throws error if condition not matched | ||
199 | ---------------------------------------------------------------------- | ||
200 | |||
201 | local function check_condition(c, msg) | ||
202 | if not c then syntaxerror(msg) end | ||
203 | end | ||
204 | |||
205 | ---------------------------------------------------------------------- | ||
206 | -- verifies token conditions are met or else throw error | ||
207 | ---------------------------------------------------------------------- | ||
208 | |||
209 | local function check_match(what, who, where) | ||
210 | if not testnext(what) then | ||
211 | if where == llex.ln then | ||
212 | error_expected(what) | ||
213 | else | ||
214 | syntaxerror("'"..what.."' expected (to close '"..who.."' at line "..where..")") | ||
215 | end | ||
216 | end | ||
217 | end | ||
218 | |||
219 | ---------------------------------------------------------------------- | ||
220 | -- expect that token is a name, return the name | ||
221 | ---------------------------------------------------------------------- | ||
222 | |||
223 | local function str_checkname() | ||
224 | check("<name>") | ||
225 | local ts = seminfo | ||
226 | nextt() | ||
227 | log(" str_checkname: '"..ts.."'") | ||
228 | return ts | ||
229 | end | ||
230 | |||
231 | ---------------------------------------------------------------------- | ||
232 | -- adds given string s in string pool, sets e as VK | ||
233 | ---------------------------------------------------------------------- | ||
234 | |||
235 | local function codestring(e, s) | ||
236 | e.k = "VK" | ||
237 | log(" codestring: "..string.format("%q", s)) | ||
238 | end | ||
239 | |||
240 | ---------------------------------------------------------------------- | ||
241 | -- consume a name token, adds it to string pool | ||
242 | ---------------------------------------------------------------------- | ||
243 | |||
244 | local function checkname(e) | ||
245 | log(" checkname:") | ||
246 | codestring(e, str_checkname()) | ||
247 | end | ||
248 | |||
249 | --[[-------------------------------------------------------------------- | ||
250 | -- state management functions with open/close pairs | ||
251 | ----------------------------------------------------------------------]] | ||
252 | |||
253 | ---------------------------------------------------------------------- | ||
254 | -- enters a code unit, initializes elements | ||
255 | ---------------------------------------------------------------------- | ||
256 | |||
257 | local function enterblock(isbreakable) | ||
258 | local bl = {} -- per-block state | ||
259 | bl.isbreakable = isbreakable | ||
260 | bl.prev = fs.bl | ||
261 | bl.locallist = {} | ||
262 | fs.bl = bl | ||
263 | log(">> enterblock(isbreakable="..base.tostring(isbreakable)..")") | ||
264 | end | ||
265 | |||
266 | ---------------------------------------------------------------------- | ||
267 | -- leaves a code unit, close any upvalues | ||
268 | ---------------------------------------------------------------------- | ||
269 | |||
270 | local function leaveblock() | ||
271 | local bl = fs.bl | ||
272 | fs.bl = bl.prev | ||
273 | log("<< leaveblock") | ||
274 | end | ||
275 | |||
276 | ---------------------------------------------------------------------- | ||
277 | -- opening of a function | ||
278 | -- * top_fs is only for anchoring the top fs, so that parser() can | ||
279 | -- return it to the caller function along with useful output | ||
280 | -- * used in parser() and body() | ||
281 | ---------------------------------------------------------------------- | ||
282 | |||
283 | local function open_func() | ||
284 | local new_fs -- per-function state | ||
285 | if not fs then -- top_fs is created early | ||
286 | new_fs = top_fs | ||
287 | else | ||
288 | new_fs = {} | ||
289 | end | ||
290 | new_fs.prev = fs -- linked list of function states | ||
291 | new_fs.bl = nil | ||
292 | new_fs.locallist = {} | ||
293 | fs = new_fs | ||
294 | log(">> open_func") | ||
295 | end | ||
296 | |||
297 | ---------------------------------------------------------------------- | ||
298 | -- closing of a function | ||
299 | -- * used in parser() and body() | ||
300 | ---------------------------------------------------------------------- | ||
301 | |||
302 | local function close_func() | ||
303 | fs = fs.prev | ||
304 | log("<< close_func") | ||
305 | end | ||
306 | |||
307 | --[[-------------------------------------------------------------------- | ||
308 | -- variable (global|local|upvalue) handling | ||
309 | -- * a pure parser does not really need this, but if we want to produce | ||
310 | -- useful output, might as well write minimal code to manage this... | ||
311 | -- * entry point is singlevar() for variable lookups | ||
312 | -- * three entry points for local variable creation, in order to keep | ||
313 | -- to original C calls, but the extra arguments such as positioning | ||
314 | -- are removed as we are not allocating registers -- we are only | ||
315 | -- doing simple classification | ||
316 | -- * lookup tables (bl.locallist) are maintained awkwardly in the basic | ||
317 | -- block data structures, PLUS the function data structure (this is | ||
318 | -- an inelegant hack, since bl is nil for the top level of a function) | ||
319 | ----------------------------------------------------------------------]] | ||
320 | |||
321 | ---------------------------------------------------------------------- | ||
322 | -- register a local variable, set in active variable list | ||
323 | -- * code for a simple lookup only | ||
324 | -- * used in new_localvarliteral(), parlist(), fornum(), forlist(), | ||
325 | -- localfunc(), localstat() | ||
326 | ---------------------------------------------------------------------- | ||
327 | |||
328 | local function new_localvar(name) | ||
329 | local bl = fs.bl | ||
330 | local locallist | ||
331 | if bl then | ||
332 | locallist = bl.locallist | ||
333 | else | ||
334 | locallist = fs.locallist | ||
335 | end | ||
336 | locallist[name] = true | ||
337 | log(" new_localvar: '"..name.."'") | ||
338 | end | ||
339 | |||
340 | ---------------------------------------------------------------------- | ||
341 | -- creates a new local variable given a name | ||
342 | -- * used in fornum(), forlist(), parlist(), body() | ||
343 | ---------------------------------------------------------------------- | ||
344 | |||
345 | local function new_localvarliteral(name) | ||
346 | new_localvar(name) | ||
347 | end | ||
348 | |||
349 | ---------------------------------------------------------------------- | ||
350 | -- search the local variable namespace of the given fs for a match | ||
351 | -- * a simple lookup only, no active variable list kept, so no useful | ||
352 | -- index value can be returned by this function | ||
353 | -- * used only in singlevaraux() | ||
354 | ---------------------------------------------------------------------- | ||
355 | |||
356 | local function searchvar(fs, n) | ||
357 | local bl = fs.bl | ||
358 | if bl then | ||
359 | locallist = bl.locallist | ||
360 | while locallist do | ||
361 | if locallist[n] then return 1 end -- found | ||
362 | bl = bl.prev | ||
363 | locallist = bl and bl.locallist | ||
364 | end | ||
365 | end | ||
366 | locallist = fs.locallist | ||
367 | if locallist[n] then return 1 end -- found | ||
368 | return -1 -- not found | ||
369 | end | ||
370 | |||
371 | ---------------------------------------------------------------------- | ||
372 | -- handle locals, globals and upvalues and related processing | ||
373 | -- * search mechanism is recursive, calls itself to search parents | ||
374 | -- * used only in singlevar() | ||
375 | ---------------------------------------------------------------------- | ||
376 | |||
377 | local function singlevaraux(fs, n, var, base) | ||
378 | if fs == nil then -- no more levels? | ||
379 | var.k = "VGLOBAL" -- default is global variable | ||
380 | return "VGLOBAL" | ||
381 | else | ||
382 | local v = searchvar(fs, n) -- look up at current level | ||
383 | if v >= 0 then | ||
384 | var.k = "VLOCAL" | ||
385 | -- codegen may need to deal with upvalue here | ||
386 | return "VLOCAL" | ||
387 | else -- not found at current level; try upper one | ||
388 | if singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then | ||
389 | return "VGLOBAL" | ||
390 | end | ||
391 | -- else was LOCAL or UPVAL, handle here | ||
392 | var.k = "VUPVAL" -- upvalue in this level | ||
393 | return "VUPVAL" | ||
394 | end--if v | ||
395 | end--if fs | ||
396 | end | ||
397 | |||
398 | ---------------------------------------------------------------------- | ||
399 | -- consume a name token, creates a variable (global|local|upvalue) | ||
400 | -- * used in prefixexp(), funcname() | ||
401 | ---------------------------------------------------------------------- | ||
402 | |||
403 | local function singlevar(v) | ||
404 | local varname = str_checkname() | ||
405 | singlevaraux(fs, varname, v, 1) | ||
406 | log(" singlevar(kind): '"..v.k.."'") | ||
407 | end | ||
408 | |||
409 | --[[-------------------------------------------------------------------- | ||
410 | -- other parsing functions | ||
411 | -- * for table constructor, parameter list, argument list | ||
412 | ----------------------------------------------------------------------]] | ||
413 | |||
414 | ---------------------------------------------------------------------- | ||
415 | -- parse a function name suffix, for function call specifications | ||
416 | -- * used in primaryexp(), funcname() | ||
417 | ---------------------------------------------------------------------- | ||
418 | |||
419 | local function field(v) | ||
420 | -- field -> ['.' | ':'] NAME | ||
421 | local key = {} | ||
422 | log(" field: operator="..tok) | ||
423 | nextt() -- skip the dot or colon | ||
424 | checkname(key) | ||
425 | v.k = "VINDEXED" | ||
426 | end | ||
427 | |||
428 | ---------------------------------------------------------------------- | ||
429 | -- parse a table indexing suffix, for constructors, expressions | ||
430 | -- * used in recfield(), primaryexp() | ||
431 | ---------------------------------------------------------------------- | ||
432 | |||
433 | local function yindex(v) | ||
434 | -- index -> '[' expr ']' | ||
435 | log(">> index: begin '['") | ||
436 | nextt() -- skip the '[' | ||
437 | expr(v) | ||
438 | checknext("]") | ||
439 | log("<< index: end ']'") | ||
440 | end | ||
441 | |||
442 | ---------------------------------------------------------------------- | ||
443 | -- parse a table record (hash) field | ||
444 | -- * used in constructor() | ||
445 | ---------------------------------------------------------------------- | ||
446 | |||
447 | local function recfield(cc) | ||
448 | -- recfield -> (NAME | '['exp1']') = exp1 | ||
449 | local key, val = {}, {} | ||
450 | if tok == "<name>" then | ||
451 | log("recfield: name") | ||
452 | checkname(key) | ||
453 | else-- tok == '[' | ||
454 | log("recfield: [ exp1 ]") | ||
455 | yindex(key) | ||
456 | end | ||
457 | checknext("=") | ||
458 | expr(val) | ||
459 | end | ||
460 | |||
461 | ---------------------------------------------------------------------- | ||
462 | -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) | ||
463 | -- * note: retained in this skeleton because it modifies cc.v.k | ||
464 | -- * used in constructor() | ||
465 | ---------------------------------------------------------------------- | ||
466 | |||
467 | local function closelistfield(cc) | ||
468 | if cc.v.k == "VVOID" then return end -- there is no list item | ||
469 | cc.v.k = "VVOID" | ||
470 | end | ||
471 | |||
472 | ---------------------------------------------------------------------- | ||
473 | -- parse a table list (array) field | ||
474 | -- * used in constructor() | ||
475 | ---------------------------------------------------------------------- | ||
476 | |||
477 | local function listfield(cc) | ||
478 | log("listfield: expr") | ||
479 | expr(cc.v) | ||
480 | end | ||
481 | |||
482 | ---------------------------------------------------------------------- | ||
483 | -- parse a table constructor | ||
484 | -- * used in funcargs(), simpleexp() | ||
485 | ---------------------------------------------------------------------- | ||
486 | |||
487 | local function constructor(t) | ||
488 | -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' | ||
489 | -- field -> recfield | listfield | ||
490 | -- fieldsep -> ',' | ';' | ||
491 | log(">> constructor: begin") | ||
492 | local line = llex.ln | ||
493 | local cc = {} | ||
494 | cc.v = {} | ||
495 | cc.t = t | ||
496 | t.k = "VRELOCABLE" | ||
497 | cc.v.k = "VVOID" | ||
498 | checknext("{") | ||
499 | repeat | ||
500 | if tok == "}" then break end | ||
501 | -- closelistfield(cc) here | ||
502 | local c = tok | ||
503 | if c == "<name>" then -- may be listfields or recfields | ||
504 | if lookahead() ~= "=" then -- look ahead: expression? | ||
505 | listfield(cc) | ||
506 | else | ||
507 | recfield(cc) | ||
508 | end | ||
509 | elseif c == "[" then -- constructor_item -> recfield | ||
510 | recfield(cc) | ||
511 | else -- constructor_part -> listfield | ||
512 | listfield(cc) | ||
513 | end | ||
514 | until not testnext(",") and not testnext(";") | ||
515 | check_match("}", "{", line) | ||
516 | -- lastlistfield(cc) here | ||
517 | log("<< constructor: end") | ||
518 | end | ||
519 | |||
520 | ---------------------------------------------------------------------- | ||
521 | -- parse the arguments (parameters) of a function declaration | ||
522 | -- * used in body() | ||
523 | ---------------------------------------------------------------------- | ||
524 | |||
525 | local function parlist() | ||
526 | -- parlist -> [ param { ',' param } ] | ||
527 | log(">> parlist: begin") | ||
528 | if tok ~= ")" then -- is 'parlist' not empty? | ||
529 | repeat | ||
530 | local c = tok | ||
531 | if c == "<name>" then -- param -> NAME | ||
532 | new_localvar(str_checkname()) | ||
533 | elseif c == "..." then | ||
534 | log("parlist: ... (dots)") | ||
535 | nextt() | ||
536 | fs.is_vararg = true | ||
537 | else | ||
538 | syntaxerror("<name> or '...' expected") | ||
539 | end | ||
540 | until fs.is_vararg or not testnext(",") | ||
541 | end--if | ||
542 | log("<< parlist: end") | ||
543 | end | ||
544 | |||
545 | ---------------------------------------------------------------------- | ||
546 | -- parse the parameters of a function call | ||
547 | -- * contrast with parlist(), used in function declarations | ||
548 | -- * used in primaryexp() | ||
549 | ---------------------------------------------------------------------- | ||
550 | |||
551 | local function funcargs(f) | ||
552 | local args = {} | ||
553 | local line = llex.ln | ||
554 | local c = tok | ||
555 | if c == "(" then -- funcargs -> '(' [ explist1 ] ')' | ||
556 | log(">> funcargs: begin '('") | ||
557 | if line ~= lastln then | ||
558 | syntaxerror("ambiguous syntax (function call x new statement)") | ||
559 | end | ||
560 | nextt() | ||
561 | if tok == ")" then -- arg list is empty? | ||
562 | args.k = "VVOID" | ||
563 | else | ||
564 | explist1(args) | ||
565 | end | ||
566 | check_match(")", "(", line) | ||
567 | elseif c == "{" then -- funcargs -> constructor | ||
568 | log(">> funcargs: begin '{'") | ||
569 | constructor(args) | ||
570 | elseif c == "<string>" then -- funcargs -> STRING | ||
571 | log(">> funcargs: begin <string>") | ||
572 | codestring(args, seminfo) | ||
573 | nextt() -- must use 'seminfo' before 'next' | ||
574 | else | ||
575 | syntaxerror("function arguments expected") | ||
576 | return | ||
577 | end--if c | ||
578 | f.k = "VCALL" | ||
579 | log("<< funcargs: end -- expr is a VCALL") | ||
580 | end | ||
581 | |||
582 | --[[-------------------------------------------------------------------- | ||
583 | -- mostly expression functions | ||
584 | ----------------------------------------------------------------------]] | ||
585 | |||
586 | ---------------------------------------------------------------------- | ||
587 | -- parses an expression in parentheses or a single variable | ||
588 | -- * used in primaryexp() | ||
589 | ---------------------------------------------------------------------- | ||
590 | |||
591 | local function prefixexp(v) | ||
592 | -- prefixexp -> NAME | '(' expr ')' | ||
593 | local c = tok | ||
594 | if c == "(" then | ||
595 | log(">> prefixexp: begin ( expr ) ") | ||
596 | local line = llex.ln | ||
597 | nextt() | ||
598 | expr(v) | ||
599 | check_match(")", "(", line) | ||
600 | log("<< prefixexp: end ( expr ) ") | ||
601 | elseif c == "<name>" then | ||
602 | log("prefixexp: <name>") | ||
603 | singlevar(v) | ||
604 | else | ||
605 | syntaxerror("unexpected symbol") | ||
606 | end--if c | ||
607 | end | ||
608 | |||
609 | ---------------------------------------------------------------------- | ||
610 | -- parses a prefixexp (an expression in parentheses or a single | ||
611 | -- variable) or a function call specification | ||
612 | -- * used in simpleexp(), assignment(), expr_stat() | ||
613 | ---------------------------------------------------------------------- | ||
614 | |||
615 | local function primaryexp(v) | ||
616 | -- primaryexp -> | ||
617 | -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } | ||
618 | prefixexp(v) | ||
619 | while true do | ||
620 | local c = tok | ||
621 | if c == "." then -- field | ||
622 | log("primaryexp: '.' field") | ||
623 | field(v) | ||
624 | elseif c == "[" then -- '[' exp1 ']' | ||
625 | log("primaryexp: [ exp1 ]") | ||
626 | local key = {} | ||
627 | yindex(key) | ||
628 | elseif c == ":" then -- ':' NAME funcargs | ||
629 | log("primaryexp: :<name> funcargs") | ||
630 | local key = {} | ||
631 | nextt() | ||
632 | checkname(key) | ||
633 | funcargs(v) | ||
634 | elseif c == "(" or c == "<string>" or c == "{" then -- funcargs | ||
635 | log("primaryexp: "..c.." funcargs") | ||
636 | funcargs(v) | ||
637 | else | ||
638 | return | ||
639 | end--if c | ||
640 | end--while | ||
641 | end | ||
642 | |||
643 | ---------------------------------------------------------------------- | ||
644 | -- parses general expression types, constants handled here | ||
645 | -- * used in subexpr() | ||
646 | ---------------------------------------------------------------------- | ||
647 | |||
648 | local function simpleexp(v) | ||
649 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | | ||
650 | -- constructor | FUNCTION body | primaryexp | ||
651 | local c = tok | ||
652 | if c == "<number>" then | ||
653 | log("simpleexp: <number>="..seminfo) | ||
654 | v.k = "VKNUM" | ||
655 | elseif c == "<string>" then | ||
656 | log("simpleexp: <string>="..seminfo) | ||
657 | codestring(v, seminfo) | ||
658 | elseif c == "nil" then | ||
659 | log("simpleexp: nil") | ||
660 | v.k = "VNIL" | ||
661 | elseif c == "true" then | ||
662 | log("simpleexp: true") | ||
663 | v.k = "VTRUE" | ||
664 | elseif c == "false" then | ||
665 | log("simpleexp: false") | ||
666 | v.k = "VFALSE" | ||
667 | elseif c == "..." then -- vararg | ||
668 | check_condition(fs.is_vararg == true, | ||
669 | "cannot use '...' outside a vararg function"); | ||
670 | log("simpleexp: ...") | ||
671 | v.k = "VVARARG" | ||
672 | elseif c == "{" then -- constructor | ||
673 | log("simpleexp: constructor") | ||
674 | constructor(v) | ||
675 | return | ||
676 | elseif c == "function" then | ||
677 | log("simpleexp: function") | ||
678 | nextt() | ||
679 | body(v, false, llex.ln) | ||
680 | return | ||
681 | else | ||
682 | primaryexp(v) | ||
683 | return | ||
684 | end--if c | ||
685 | nextt() | ||
686 | end | ||
687 | |||
688 | ------------------------------------------------------------------------ | ||
689 | -- Parse subexpressions. Includes handling of unary operators and binary | ||
690 | -- operators. A subexpr is given the rhs priority level of the operator | ||
691 | -- immediately left of it, if any (limit is -1 if none,) and if a binop | ||
692 | -- is found, limit is compared with the lhs priority level of the binop | ||
693 | -- in order to determine which executes first. | ||
694 | -- * recursively called | ||
695 | -- * used in expr() | ||
696 | ------------------------------------------------------------------------ | ||
697 | |||
698 | local function subexpr(v, limit) | ||
699 | -- subexpr -> (simpleexp | unop subexpr) { binop subexpr } | ||
700 | -- * where 'binop' is any binary operator with a priority | ||
701 | -- higher than 'limit' | ||
702 | local op = tok | ||
703 | local uop = unopr[op] | ||
704 | if uop then | ||
705 | log(" subexpr: uop='"..op.."'") | ||
706 | nextt() | ||
707 | subexpr(v, UNARY_PRIORITY) | ||
708 | else | ||
709 | simpleexp(v) | ||
710 | end | ||
711 | -- expand while operators have priorities higher than 'limit' | ||
712 | op = tok | ||
713 | local binop = binopr_left[op] | ||
714 | while binop and binop > limit do | ||
715 | local v2 = {} | ||
716 | log(">> subexpr: binop='"..op.."'") | ||
717 | nextt() | ||
718 | -- read sub-expression with higher priority | ||
719 | local nextop = subexpr(v2, binopr_right[op]) | ||
720 | log("<< subexpr: -- evaluate") | ||
721 | op = nextop | ||
722 | binop = binopr_left[op] | ||
723 | end | ||
724 | return op -- return first untreated operator | ||
725 | end | ||
726 | |||
727 | ---------------------------------------------------------------------- | ||
728 | -- Expression parsing starts here. Function subexpr is entered with the | ||
729 | -- left operator (which is non-existent) priority of -1, which is lower | ||
730 | -- than all actual operators. Expr information is returned in parm v. | ||
731 | -- * used in cond(), explist1(), index(), recfield(), listfield(), | ||
732 | -- prefixexp(), while_stat(), exp1() | ||
733 | ---------------------------------------------------------------------- | ||
734 | |||
735 | -- this is a forward-referenced local | ||
736 | function expr(v) | ||
737 | -- expr -> subexpr | ||
738 | log("expr:") | ||
739 | subexpr(v, 0) | ||
740 | end | ||
741 | |||
742 | --[[-------------------------------------------------------------------- | ||
743 | -- third level parsing functions | ||
744 | ----------------------------------------------------------------------]] | ||
745 | |||
746 | ------------------------------------------------------------------------ | ||
747 | -- parse a variable assignment sequence | ||
748 | -- * recursively called | ||
749 | -- * used in expr_stat() | ||
750 | ------------------------------------------------------------------------ | ||
751 | |||
752 | local function assignment(v) | ||
753 | local e = {} | ||
754 | local c = v.v.k | ||
755 | check_condition(c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" | ||
756 | or c == "VINDEXED", "syntax error") | ||
757 | if testnext(",") then -- assignment -> ',' primaryexp assignment | ||
758 | local nv = {} -- expdesc | ||
759 | nv.v = {} | ||
760 | log("assignment: ',' -- next LHS element") | ||
761 | primaryexp(nv.v) | ||
762 | -- lparser.c deals with some register usage conflict here | ||
763 | assignment(nv) | ||
764 | else -- assignment -> '=' explist1 | ||
765 | checknext("=") | ||
766 | log("assignment: '=' -- RHS elements follows") | ||
767 | explist1(e) | ||
768 | return -- avoid default | ||
769 | end | ||
770 | e.k = "VNONRELOC" | ||
771 | end | ||
772 | |||
773 | ---------------------------------------------------------------------- | ||
774 | -- parse a for loop body for both versions of the for loop | ||
775 | -- * used in fornum(), forlist() | ||
776 | ---------------------------------------------------------------------- | ||
777 | |||
778 | local function forbody(isnum) | ||
779 | -- forbody -> DO block | ||
780 | checknext("do") | ||
781 | enterblock(false) -- scope for declared variables | ||
782 | block() | ||
783 | leaveblock() -- end of scope for declared variables | ||
784 | end | ||
785 | |||
786 | ---------------------------------------------------------------------- | ||
787 | -- parse a numerical for loop, calls forbody() | ||
788 | -- * used in for_stat() | ||
789 | ---------------------------------------------------------------------- | ||
790 | |||
791 | local function fornum(varname) | ||
792 | -- fornum -> NAME = exp1, exp1 [, exp1] DO body | ||
793 | local line = line | ||
794 | new_localvarliteral("(for index)") | ||
795 | new_localvarliteral("(for limit)") | ||
796 | new_localvarliteral("(for step)") | ||
797 | new_localvar(varname) | ||
798 | log(">> fornum: begin") | ||
799 | checknext("=") | ||
800 | log("fornum: index start") | ||
801 | exp1() -- initial value | ||
802 | checknext(",") | ||
803 | log("fornum: index stop") | ||
804 | exp1() -- limit | ||
805 | if testnext(",") then | ||
806 | log("fornum: index step") | ||
807 | exp1() -- optional step | ||
808 | else | ||
809 | -- default step = 1 | ||
810 | end | ||
811 | log("fornum: body") | ||
812 | forbody(true) | ||
813 | log("<< fornum: end") | ||
814 | end | ||
815 | |||
816 | ---------------------------------------------------------------------- | ||
817 | -- parse a generic for loop, calls forbody() | ||
818 | -- * used in for_stat() | ||
819 | ---------------------------------------------------------------------- | ||
820 | |||
821 | local function forlist(indexname) | ||
822 | -- forlist -> NAME {, NAME} IN explist1 DO body | ||
823 | log(">> forlist: begin") | ||
824 | local e = {} | ||
825 | -- create control variables | ||
826 | new_localvarliteral("(for generator)") | ||
827 | new_localvarliteral("(for state)") | ||
828 | new_localvarliteral("(for control)") | ||
829 | -- create declared variables | ||
830 | new_localvar(indexname) | ||
831 | while testnext(",") do | ||
832 | new_localvar(str_checkname()) | ||
833 | end | ||
834 | checknext("in") | ||
835 | local line = line | ||
836 | log("forlist: explist1") | ||
837 | explist1(e) | ||
838 | log("forlist: body") | ||
839 | forbody(false) | ||
840 | log("<< forlist: end") | ||
841 | end | ||
842 | |||
843 | ---------------------------------------------------------------------- | ||
844 | -- parse a function name specification | ||
845 | -- * used in func_stat() | ||
846 | ---------------------------------------------------------------------- | ||
847 | |||
848 | local function funcname(v) | ||
849 | -- funcname -> NAME {field} [':' NAME] | ||
850 | log(">> funcname: begin") | ||
851 | local needself = false | ||
852 | singlevar(v) | ||
853 | while tok == "." do | ||
854 | log("funcname: -- '.' field") | ||
855 | field(v) | ||
856 | end | ||
857 | if tok == ":" then | ||
858 | log("funcname: -- ':' field") | ||
859 | needself = true | ||
860 | field(v) | ||
861 | end | ||
862 | log("<< funcname: end") | ||
863 | return needself | ||
864 | end | ||
865 | |||
866 | ---------------------------------------------------------------------- | ||
867 | -- parse the single expressions needed in numerical for loops | ||
868 | -- * used in fornum() | ||
869 | ---------------------------------------------------------------------- | ||
870 | |||
871 | -- this is a forward-referenced local | ||
872 | function exp1() | ||
873 | -- exp1 -> expr | ||
874 | local e = {} | ||
875 | log(">> exp1: begin") | ||
876 | expr(e) | ||
877 | log("<< exp1: end") | ||
878 | end | ||
879 | |||
880 | ---------------------------------------------------------------------- | ||
881 | -- parse condition in a repeat statement or an if control structure | ||
882 | -- * used in repeat_stat(), test_then_block() | ||
883 | ---------------------------------------------------------------------- | ||
884 | |||
885 | local function cond() | ||
886 | -- cond -> expr | ||
887 | log(">> cond: begin") | ||
888 | local v = {} | ||
889 | expr(v) -- read condition | ||
890 | log("<< cond: end") | ||
891 | end | ||
892 | |||
893 | ---------------------------------------------------------------------- | ||
894 | -- parse part of an if control structure, including the condition | ||
895 | -- * used in if_stat() | ||
896 | ---------------------------------------------------------------------- | ||
897 | |||
898 | local function test_then_block() | ||
899 | -- test_then_block -> [IF | ELSEIF] cond THEN block | ||
900 | nextt() -- skip IF or ELSEIF | ||
901 | log("test_then_block: test condition") | ||
902 | cond() | ||
903 | checknext("then") | ||
904 | log("test_then_block: then block") | ||
905 | block() -- 'then' part | ||
906 | end | ||
907 | |||
908 | ---------------------------------------------------------------------- | ||
909 | -- parse a local function statement | ||
910 | -- * used in local_stat() | ||
911 | ---------------------------------------------------------------------- | ||
912 | |||
913 | local function localfunc() | ||
914 | -- localfunc -> NAME body | ||
915 | local v, b = {} | ||
916 | log("localfunc: begin") | ||
917 | new_localvar(str_checkname()) | ||
918 | v.k = "VLOCAL" | ||
919 | log("localfunc: body") | ||
920 | body(b, false, llex.ln) | ||
921 | log("localfunc: end") | ||
922 | end | ||
923 | |||
924 | ---------------------------------------------------------------------- | ||
925 | -- parse a local variable declaration statement | ||
926 | -- * used in local_stat() | ||
927 | ---------------------------------------------------------------------- | ||
928 | |||
929 | local function localstat() | ||
930 | -- localstat -> NAME {',' NAME} ['=' explist1] | ||
931 | log(">> localstat: begin") | ||
932 | local e = {} | ||
933 | repeat | ||
934 | new_localvar(str_checkname()) | ||
935 | until not testnext(",") | ||
936 | if testnext("=") then | ||
937 | log("localstat: -- assignment") | ||
938 | explist1(e) | ||
939 | else | ||
940 | e.k = "VVOID" | ||
941 | end | ||
942 | log("<< localstat: end") | ||
943 | end | ||
944 | |||
945 | ---------------------------------------------------------------------- | ||
946 | -- parse a list of comma-separated expressions | ||
947 | -- * used in return_stat(), localstat(), funcargs(), assignment(), | ||
948 | -- forlist() | ||
949 | ---------------------------------------------------------------------- | ||
950 | |||
951 | -- this is a forward-referenced local | ||
952 | function explist1(e) | ||
953 | -- explist1 -> expr { ',' expr } | ||
954 | log(">> explist1: begin") | ||
955 | expr(e) | ||
956 | while testnext(",") do | ||
957 | log("explist1: ',' -- continuation") | ||
958 | expr(e) | ||
959 | end | ||
960 | log("<< explist1: end") | ||
961 | end | ||
962 | |||
963 | ---------------------------------------------------------------------- | ||
964 | -- parse function declaration body | ||
965 | -- * used in simpleexp(), localfunc(), func_stat() | ||
966 | ---------------------------------------------------------------------- | ||
967 | |||
968 | -- this is a forward-referenced local | ||
969 | function body(e, needself, line) | ||
970 | -- body -> '(' parlist ')' chunk END | ||
971 | open_func() | ||
972 | log("body: begin") | ||
973 | checknext("(") | ||
974 | if needself then | ||
975 | new_localvarliteral("self") | ||
976 | end | ||
977 | log("body: parlist") | ||
978 | parlist() | ||
979 | checknext(")") | ||
980 | log("body: chunk") | ||
981 | chunk() | ||
982 | check_match("end", "function", line) | ||
983 | log("body: end") | ||
984 | close_func() | ||
985 | end | ||
986 | |||
987 | ---------------------------------------------------------------------- | ||
988 | -- parse a code block or unit | ||
989 | -- * used in do_stat(), while_stat(), forbody(), test_then_block(), | ||
990 | -- if_stat() | ||
991 | ---------------------------------------------------------------------- | ||
992 | |||
993 | -- this is a forward-referenced local | ||
994 | function block() | ||
995 | -- block -> chunk | ||
996 | log("block: begin") | ||
997 | enterblock(false) | ||
998 | chunk() | ||
999 | leaveblock() | ||
1000 | log("block: end") | ||
1001 | end | ||
1002 | |||
1003 | --[[-------------------------------------------------------------------- | ||
1004 | -- second level parsing functions, all with '_stat' suffix | ||
1005 | -- * since they are called via a table lookup, they cannot be local | ||
1006 | -- functions (a lookup table of local functions might be smaller...) | ||
1007 | -- * stat() -> *_stat() | ||
1008 | ----------------------------------------------------------------------]] | ||
1009 | |||
1010 | ---------------------------------------------------------------------- | ||
1011 | -- initial parsing for a for loop, calls fornum() or forlist() | ||
1012 | -- * removed 'line' parameter (used to set debug information only) | ||
1013 | -- * used in stat() | ||
1014 | ---------------------------------------------------------------------- | ||
1015 | |||
1016 | function for_stat() | ||
1017 | -- stat -> for_stat -> FOR (fornum | forlist) END | ||
1018 | local line = line | ||
1019 | log("for_stat: begin") | ||
1020 | enterblock(true) -- scope for loop and control variables | ||
1021 | nextt() -- skip 'for' | ||
1022 | local varname = str_checkname() -- first variable name | ||
1023 | local c = tok | ||
1024 | if c == "=" then | ||
1025 | log("for_stat: numerical loop") | ||
1026 | fornum(varname) | ||
1027 | elseif c == "," or c == "in" then | ||
1028 | log("for_stat: list-based loop") | ||
1029 | forlist(varname) | ||
1030 | else | ||
1031 | syntaxerror("'=' or 'in' expected") | ||
1032 | end | ||
1033 | check_match("end", "for", line) | ||
1034 | leaveblock() -- loop scope (`break' jumps to this point) | ||
1035 | log("for_stat: end") | ||
1036 | end | ||
1037 | |||
1038 | ---------------------------------------------------------------------- | ||
1039 | -- parse a while-do control structure, body processed by block() | ||
1040 | -- * used in stat() | ||
1041 | ---------------------------------------------------------------------- | ||
1042 | |||
1043 | function while_stat() | ||
1044 | -- stat -> while_stat -> WHILE cond DO block END | ||
1045 | local line = line | ||
1046 | nextt() -- skip WHILE | ||
1047 | log("while_stat: begin/condition") | ||
1048 | cond() -- parse condition | ||
1049 | enterblock(true) | ||
1050 | checknext("do") | ||
1051 | log("while_stat: block") | ||
1052 | block() | ||
1053 | check_match("end", "while", line) | ||
1054 | leaveblock() | ||
1055 | log("while_stat: end") | ||
1056 | end | ||
1057 | |||
1058 | ---------------------------------------------------------------------- | ||
1059 | -- parse a repeat-until control structure, body parsed by chunk() | ||
1060 | -- * originally, repeatstat() calls breakstat() too if there is an | ||
1061 | -- upvalue in the scope block; nothing is actually lexed, it is | ||
1062 | -- actually the common code in breakstat() for closing of upvalues | ||
1063 | -- * used in stat() | ||
1064 | ---------------------------------------------------------------------- | ||
1065 | |||
1066 | function repeat_stat() | ||
1067 | -- stat -> repeat_stat -> REPEAT block UNTIL cond | ||
1068 | local line = line | ||
1069 | log("repeat_stat: begin") | ||
1070 | enterblock(true) -- loop block | ||
1071 | enterblock(false) -- scope block | ||
1072 | nextt() -- skip REPEAT | ||
1073 | chunk() | ||
1074 | check_match("until", "repeat", line) | ||
1075 | log("repeat_stat: condition") | ||
1076 | cond() | ||
1077 | -- close upvalues at scope level below | ||
1078 | leaveblock() -- finish scope | ||
1079 | leaveblock() -- finish loop | ||
1080 | log("repeat_stat: end") | ||
1081 | end | ||
1082 | |||
1083 | ---------------------------------------------------------------------- | ||
1084 | -- parse an if control structure | ||
1085 | -- * used in stat() | ||
1086 | ---------------------------------------------------------------------- | ||
1087 | |||
1088 | function if_stat() | ||
1089 | -- stat -> if_stat -> IF cond THEN block | ||
1090 | -- {ELSEIF cond THEN block} [ELSE block] END | ||
1091 | local line = line | ||
1092 | local v = {} | ||
1093 | log("if_stat: if...then") | ||
1094 | test_then_block() -- IF cond THEN block | ||
1095 | while tok == "elseif" do | ||
1096 | log("if_stat: elseif...then") | ||
1097 | test_then_block() -- ELSEIF cond THEN block | ||
1098 | end | ||
1099 | if tok == "else" then | ||
1100 | log("if_stat: else...") | ||
1101 | nextt() -- skip ELSE | ||
1102 | block() -- 'else' part | ||
1103 | end | ||
1104 | check_match("end", "if", line) | ||
1105 | log("if_stat: end") | ||
1106 | end | ||
1107 | |||
1108 | ---------------------------------------------------------------------- | ||
1109 | -- parse a return statement | ||
1110 | -- * used in stat() | ||
1111 | ---------------------------------------------------------------------- | ||
1112 | |||
1113 | function return_stat() | ||
1114 | -- stat -> return_stat -> RETURN explist | ||
1115 | local e = {} | ||
1116 | nextt() -- skip RETURN | ||
1117 | local c = tok | ||
1118 | if block_follow[c] or c == ";" then | ||
1119 | -- return no values | ||
1120 | log("return_stat: no return values") | ||
1121 | else | ||
1122 | log("return_stat: begin") | ||
1123 | explist1(e) -- optional return values | ||
1124 | log("return_stat: end") | ||
1125 | end | ||
1126 | end | ||
1127 | |||
1128 | ---------------------------------------------------------------------- | ||
1129 | -- parse a break statement | ||
1130 | -- * used in stat() | ||
1131 | ---------------------------------------------------------------------- | ||
1132 | |||
1133 | function break_stat() | ||
1134 | -- stat -> break_stat -> BREAK | ||
1135 | local bl = fs.bl | ||
1136 | nextt() -- skip BREAK | ||
1137 | while bl and not bl.isbreakable do -- find a breakable block | ||
1138 | bl = bl.prev | ||
1139 | end | ||
1140 | if not bl then | ||
1141 | syntaxerror("no loop to break") | ||
1142 | end | ||
1143 | log("break_stat: -- break out of loop") | ||
1144 | end | ||
1145 | |||
1146 | ---------------------------------------------------------------------- | ||
1147 | -- parse a function call with no returns or an assignment statement | ||
1148 | -- * the struct with .prev is used for name searching in lparse.c, | ||
1149 | -- so it is retained for now; present in assignment() also | ||
1150 | -- * used in stat() | ||
1151 | ---------------------------------------------------------------------- | ||
1152 | |||
1153 | function expr_stat() | ||
1154 | -- stat -> expr_stat -> func | assignment | ||
1155 | local v = {} | ||
1156 | v.v = {} | ||
1157 | primaryexp(v.v) | ||
1158 | if v.v.k == "VCALL" then -- stat -> func | ||
1159 | -- call statement uses no results | ||
1160 | log("expr_stat: function call k='"..v.v.k.."'") | ||
1161 | else -- stat -> assignment | ||
1162 | log("expr_stat: assignment k='"..v.v.k.."'") | ||
1163 | v.prev = nil | ||
1164 | assignment(v) | ||
1165 | end | ||
1166 | end | ||
1167 | |||
1168 | ---------------------------------------------------------------------- | ||
1169 | -- parse a function statement | ||
1170 | -- * used in stat() | ||
1171 | ---------------------------------------------------------------------- | ||
1172 | |||
1173 | function function_stat() | ||
1174 | -- stat -> function_stat -> FUNCTION funcname body | ||
1175 | local line = line | ||
1176 | local v, b = {}, {} | ||
1177 | log("function_stat: begin") | ||
1178 | nextt() -- skip FUNCTION | ||
1179 | local needself = funcname(v) | ||
1180 | log("function_stat: body needself='"..base.tostring(needself).."'") | ||
1181 | body(b, needself, line) | ||
1182 | log("function_stat: end") | ||
1183 | end | ||
1184 | |||
1185 | ---------------------------------------------------------------------- | ||
1186 | -- parse a simple block enclosed by a DO..END pair | ||
1187 | -- * used in stat() | ||
1188 | ---------------------------------------------------------------------- | ||
1189 | |||
1190 | function do_stat() | ||
1191 | -- stat -> do_stat -> DO block END | ||
1192 | local line = line | ||
1193 | nextt() -- skip DO | ||
1194 | log("do_stat: begin") | ||
1195 | block() | ||
1196 | log("do_stat: end") | ||
1197 | check_match("end", "do", line) | ||
1198 | end | ||
1199 | |||
1200 | ---------------------------------------------------------------------- | ||
1201 | -- parse a statement starting with LOCAL | ||
1202 | -- * used in stat() | ||
1203 | ---------------------------------------------------------------------- | ||
1204 | |||
1205 | function local_stat() | ||
1206 | -- stat -> local_stat -> LOCAL FUNCTION localfunc | ||
1207 | -- -> LOCAL localstat | ||
1208 | nextt() -- skip LOCAL | ||
1209 | if testnext("function") then -- local function? | ||
1210 | log("local_stat: local function") | ||
1211 | localfunc() | ||
1212 | else | ||
1213 | log("local_stat: local statement") | ||
1214 | localstat() | ||
1215 | end | ||
1216 | end | ||
1217 | |||
1218 | --[[-------------------------------------------------------------------- | ||
1219 | -- main functions, top level parsing functions | ||
1220 | -- * accessible functions are: init(lexer), parser() | ||
1221 | -- * [entry] -> parser() -> chunk() -> stat() | ||
1222 | ----------------------------------------------------------------------]] | ||
1223 | |||
1224 | ---------------------------------------------------------------------- | ||
1225 | -- initial parsing for statements, calls '_stat' suffixed functions | ||
1226 | -- * used in chunk() | ||
1227 | ---------------------------------------------------------------------- | ||
1228 | |||
1229 | local function stat() | ||
1230 | -- stat -> if_stat while_stat do_stat for_stat repeat_stat | ||
1231 | -- function_stat local_stat return_stat break_stat | ||
1232 | -- expr_stat | ||
1233 | line = llex.ln -- may be needed for error messages | ||
1234 | local c = tok | ||
1235 | local fn = stat_call[c] | ||
1236 | -- handles: if while do for repeat function local return break | ||
1237 | if fn then | ||
1238 | log("-- STATEMENT: begin '"..c.."' line="..line) | ||
1239 | _G[fn]() | ||
1240 | log("-- STATEMENT: end '"..c.."'") | ||
1241 | -- return or break must be last statement | ||
1242 | if c == "return" or c == "break" then return true end | ||
1243 | else | ||
1244 | log("-- STATEMENT: begin 'expr' line="..line) | ||
1245 | expr_stat() | ||
1246 | log("-- STATEMENT: end 'expr'") | ||
1247 | end | ||
1248 | log("") | ||
1249 | return false | ||
1250 | end | ||
1251 | |||
1252 | ---------------------------------------------------------------------- | ||
1253 | -- parse a chunk, which consists of a bunch of statements | ||
1254 | -- * used in parser(), body(), block(), repeat_stat() | ||
1255 | ---------------------------------------------------------------------- | ||
1256 | |||
1257 | function chunk() | ||
1258 | -- chunk -> { stat [';'] } | ||
1259 | log("chunk:") | ||
1260 | local islast = false | ||
1261 | while not islast and not block_follow[tok] do | ||
1262 | islast = stat() | ||
1263 | testnext(";") | ||
1264 | end | ||
1265 | end | ||
1266 | |||
1267 | ---------------------------------------------------------------------- | ||
1268 | -- performs parsing, returns parsed data structure | ||
1269 | ---------------------------------------------------------------------- | ||
1270 | |||
1271 | function parser() | ||
1272 | log("-- TOP: begin") | ||
1273 | open_func() | ||
1274 | fs.is_vararg = true -- main func. is always vararg | ||
1275 | log("") | ||
1276 | nextt() -- read first token | ||
1277 | chunk() | ||
1278 | check("<eof>") | ||
1279 | close_func() | ||
1280 | log("-- TOP: end") | ||
1281 | return top_fs | ||
1282 | end | ||
1283 | |||
1284 | ---------------------------------------------------------------------- | ||
1285 | -- initialization function | ||
1286 | ---------------------------------------------------------------------- | ||
1287 | |||
1288 | function init(lexer) | ||
1289 | llex = lexer -- set lexer (assume user-initialized) | ||
1290 | llex_lex = llex.llex | ||
1291 | top_fs = {} -- reset top level function state | ||
1292 | end | ||
1293 | |||
1294 | 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | -- END OF SOURCE -- | ||
3 | |||
4 | -- TOP: begin | ||
5 | open_func | ||
6 | |||
7 | chunk: | ||
8 | close_func | ||
9 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | -- foobar | ||
3 | -- END OF SOURCE -- | ||
4 | |||
5 | -- TOP: begin | ||
6 | open_func | ||
7 | |||
8 | chunk: | ||
9 | close_func | ||
10 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do | ||
3 | end | ||
4 | -- END OF SOURCE -- | ||
5 | |||
6 | -- TOP: begin | ||
7 | open_func | ||
8 | |||
9 | chunk: | ||
10 | -- STATEMENT: begin 'do' line=1 | ||
11 | do_stat: begin | ||
12 | block: begin | ||
13 | enterblock(isbreakable=false) | ||
14 | chunk: | ||
15 | leaveblock | ||
16 | block: end | ||
17 | do_stat: end | ||
18 | -- STATEMENT: end 'do' | ||
19 | |||
20 | close_func | ||
21 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do end | ||
3 | do end | ||
4 | -- END OF SOURCE -- | ||
5 | |||
6 | -- TOP: begin | ||
7 | open_func | ||
8 | |||
9 | chunk: | ||
10 | -- STATEMENT: begin 'do' line=1 | ||
11 | do_stat: begin | ||
12 | block: begin | ||
13 | enterblock(isbreakable=false) | ||
14 | chunk: | ||
15 | leaveblock | ||
16 | block: end | ||
17 | do_stat: end | ||
18 | -- STATEMENT: end 'do' | ||
19 | |||
20 | -- STATEMENT: begin 'do' line=2 | ||
21 | do_stat: begin | ||
22 | block: begin | ||
23 | enterblock(isbreakable=false) | ||
24 | chunk: | ||
25 | leaveblock | ||
26 | block: end | ||
27 | do_stat: end | ||
28 | -- STATEMENT: end 'do' | ||
29 | |||
30 | close_func | ||
31 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | foo() | ||
3 | foo{} | ||
4 | foo"" | ||
5 | foo:bar() | ||
6 | foo=false | ||
7 | foo.bar=true | ||
8 | foo[true]=nil | ||
9 | foo,bar=1,"a" | ||
10 | -- END OF SOURCE -- | ||
11 | |||
12 | -- TOP: begin | ||
13 | open_func | ||
14 | |||
15 | chunk: | ||
16 | -- STATEMENT: begin 'expr' line=1 | ||
17 | prefixexp: <name> | ||
18 | str_checkname: 'foo' | ||
19 | singlevar(kind): 'VGLOBAL' | ||
20 | primaryexp: ( funcargs | ||
21 | funcargs: begin '(' | ||
22 | funcargs: end -- expr is a VCALL | ||
23 | expr_stat: function call k='VCALL' | ||
24 | -- STATEMENT: end 'expr' | ||
25 | |||
26 | -- STATEMENT: begin 'expr' line=2 | ||
27 | prefixexp: <name> | ||
28 | str_checkname: 'foo' | ||
29 | singlevar(kind): 'VGLOBAL' | ||
30 | primaryexp: { funcargs | ||
31 | funcargs: begin '{' | ||
32 | constructor: begin | ||
33 | constructor: end | ||
34 | funcargs: end -- expr is a VCALL | ||
35 | expr_stat: function call k='VCALL' | ||
36 | -- STATEMENT: end 'expr' | ||
37 | |||
38 | -- STATEMENT: begin 'expr' line=3 | ||
39 | prefixexp: <name> | ||
40 | str_checkname: 'foo' | ||
41 | singlevar(kind): 'VGLOBAL' | ||
42 | primaryexp: <string> funcargs | ||
43 | funcargs: begin <string> | ||
44 | codestring: "" | ||
45 | funcargs: end -- expr is a VCALL | ||
46 | expr_stat: function call k='VCALL' | ||
47 | -- STATEMENT: end 'expr' | ||
48 | |||
49 | -- STATEMENT: begin 'expr' line=4 | ||
50 | prefixexp: <name> | ||
51 | str_checkname: 'foo' | ||
52 | singlevar(kind): 'VGLOBAL' | ||
53 | primaryexp: :<name> funcargs | ||
54 | checkname: | ||
55 | str_checkname: 'bar' | ||
56 | codestring: "bar" | ||
57 | funcargs: begin '(' | ||
58 | funcargs: end -- expr is a VCALL | ||
59 | expr_stat: function call k='VCALL' | ||
60 | -- STATEMENT: end 'expr' | ||
61 | |||
62 | -- STATEMENT: begin 'expr' line=5 | ||
63 | prefixexp: <name> | ||
64 | str_checkname: 'foo' | ||
65 | singlevar(kind): 'VGLOBAL' | ||
66 | expr_stat: assignment k='VGLOBAL' | ||
67 | assignment: '=' -- RHS elements follows | ||
68 | explist1: begin | ||
69 | expr: | ||
70 | simpleexp: false | ||
71 | explist1: end | ||
72 | -- STATEMENT: end 'expr' | ||
73 | |||
74 | -- STATEMENT: begin 'expr' line=6 | ||
75 | prefixexp: <name> | ||
76 | str_checkname: 'foo' | ||
77 | singlevar(kind): 'VGLOBAL' | ||
78 | primaryexp: '.' field | ||
79 | field: operator=. | ||
80 | checkname: | ||
81 | str_checkname: 'bar' | ||
82 | codestring: "bar" | ||
83 | expr_stat: assignment k='VINDEXED' | ||
84 | assignment: '=' -- RHS elements follows | ||
85 | explist1: begin | ||
86 | expr: | ||
87 | simpleexp: true | ||
88 | explist1: end | ||
89 | -- STATEMENT: end 'expr' | ||
90 | |||
91 | -- STATEMENT: begin 'expr' line=7 | ||
92 | prefixexp: <name> | ||
93 | str_checkname: 'foo' | ||
94 | singlevar(kind): 'VGLOBAL' | ||
95 | primaryexp: [ exp1 ] | ||
96 | index: begin '[' | ||
97 | expr: | ||
98 | simpleexp: true | ||
99 | index: end ']' | ||
100 | expr_stat: assignment k='VGLOBAL' | ||
101 | assignment: '=' -- RHS elements follows | ||
102 | explist1: begin | ||
103 | expr: | ||
104 | simpleexp: nil | ||
105 | explist1: end | ||
106 | -- STATEMENT: end 'expr' | ||
107 | |||
108 | -- STATEMENT: begin 'expr' line=8 | ||
109 | prefixexp: <name> | ||
110 | str_checkname: 'foo' | ||
111 | singlevar(kind): 'VGLOBAL' | ||
112 | expr_stat: assignment k='VGLOBAL' | ||
113 | assignment: ',' -- next LHS element | ||
114 | prefixexp: <name> | ||
115 | str_checkname: 'bar' | ||
116 | singlevar(kind): 'VGLOBAL' | ||
117 | assignment: '=' -- RHS elements follows | ||
118 | explist1: begin | ||
119 | expr: | ||
120 | simpleexp: <number>=1 | ||
121 | explist1: ',' -- continuation | ||
122 | expr: | ||
123 | simpleexp: <string>=a | ||
124 | codestring: "a" | ||
125 | explist1: end | ||
126 | -- STATEMENT: end 'expr' | ||
127 | |||
128 | close_func | ||
129 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | foo=true | ||
3 | foo=false | ||
4 | foo=nil | ||
5 | foo=1.23e45 | ||
6 | foo=-1 | ||
7 | foo=(0) | ||
8 | foo=1+2 | ||
9 | foo=1+2*3-4/5 | ||
10 | -- END OF SOURCE -- | ||
11 | |||
12 | -- TOP: begin | ||
13 | open_func | ||
14 | |||
15 | chunk: | ||
16 | -- STATEMENT: begin 'expr' line=1 | ||
17 | prefixexp: <name> | ||
18 | str_checkname: 'foo' | ||
19 | singlevar(kind): 'VGLOBAL' | ||
20 | expr_stat: assignment k='VGLOBAL' | ||
21 | assignment: '=' -- RHS elements follows | ||
22 | explist1: begin | ||
23 | expr: | ||
24 | simpleexp: true | ||
25 | explist1: end | ||
26 | -- STATEMENT: end 'expr' | ||
27 | |||
28 | -- STATEMENT: begin 'expr' line=2 | ||
29 | prefixexp: <name> | ||
30 | str_checkname: 'foo' | ||
31 | singlevar(kind): 'VGLOBAL' | ||
32 | expr_stat: assignment k='VGLOBAL' | ||
33 | assignment: '=' -- RHS elements follows | ||
34 | explist1: begin | ||
35 | expr: | ||
36 | simpleexp: false | ||
37 | explist1: end | ||
38 | -- STATEMENT: end 'expr' | ||
39 | |||
40 | -- STATEMENT: begin 'expr' line=3 | ||
41 | prefixexp: <name> | ||
42 | str_checkname: 'foo' | ||
43 | singlevar(kind): 'VGLOBAL' | ||
44 | expr_stat: assignment k='VGLOBAL' | ||
45 | assignment: '=' -- RHS elements follows | ||
46 | explist1: begin | ||
47 | expr: | ||
48 | simpleexp: nil | ||
49 | explist1: end | ||
50 | -- STATEMENT: end 'expr' | ||
51 | |||
52 | -- STATEMENT: begin 'expr' line=4 | ||
53 | prefixexp: <name> | ||
54 | str_checkname: 'foo' | ||
55 | singlevar(kind): 'VGLOBAL' | ||
56 | expr_stat: assignment k='VGLOBAL' | ||
57 | assignment: '=' -- RHS elements follows | ||
58 | explist1: begin | ||
59 | expr: | ||
60 | simpleexp: <number>=1.23e+45 | ||
61 | explist1: end | ||
62 | -- STATEMENT: end 'expr' | ||
63 | |||
64 | -- STATEMENT: begin 'expr' line=5 | ||
65 | prefixexp: <name> | ||
66 | str_checkname: 'foo' | ||
67 | singlevar(kind): 'VGLOBAL' | ||
68 | expr_stat: assignment k='VGLOBAL' | ||
69 | assignment: '=' -- RHS elements follows | ||
70 | explist1: begin | ||
71 | expr: | ||
72 | subexpr: uop='-' | ||
73 | simpleexp: <number>=1 | ||
74 | explist1: end | ||
75 | -- STATEMENT: end 'expr' | ||
76 | |||
77 | -- STATEMENT: begin 'expr' line=6 | ||
78 | prefixexp: <name> | ||
79 | str_checkname: 'foo' | ||
80 | singlevar(kind): 'VGLOBAL' | ||
81 | expr_stat: assignment k='VGLOBAL' | ||
82 | assignment: '=' -- RHS elements follows | ||
83 | explist1: begin | ||
84 | expr: | ||
85 | prefixexp: begin ( expr ) | ||
86 | expr: | ||
87 | simpleexp: <number>=0 | ||
88 | prefixexp: end ( expr ) | ||
89 | explist1: end | ||
90 | -- STATEMENT: end 'expr' | ||
91 | |||
92 | -- STATEMENT: begin 'expr' line=7 | ||
93 | prefixexp: <name> | ||
94 | str_checkname: 'foo' | ||
95 | singlevar(kind): 'VGLOBAL' | ||
96 | expr_stat: assignment k='VGLOBAL' | ||
97 | assignment: '=' -- RHS elements follows | ||
98 | explist1: begin | ||
99 | expr: | ||
100 | simpleexp: <number>=1 | ||
101 | subexpr: binop='+' | ||
102 | simpleexp: <number>=2 | ||
103 | subexpr: -- evaluate | ||
104 | explist1: end | ||
105 | -- STATEMENT: end 'expr' | ||
106 | |||
107 | -- STATEMENT: begin 'expr' line=8 | ||
108 | prefixexp: <name> | ||
109 | str_checkname: 'foo' | ||
110 | singlevar(kind): 'VGLOBAL' | ||
111 | expr_stat: assignment k='VGLOBAL' | ||
112 | assignment: '=' -- RHS elements follows | ||
113 | explist1: begin | ||
114 | expr: | ||
115 | simpleexp: <number>=1 | ||
116 | subexpr: binop='+' | ||
117 | simpleexp: <number>=2 | ||
118 | subexpr: binop='*' | ||
119 | simpleexp: <number>=3 | ||
120 | subexpr: -- evaluate | ||
121 | subexpr: -- evaluate | ||
122 | subexpr: binop='-' | ||
123 | simpleexp: <number>=4 | ||
124 | subexpr: binop='/' | ||
125 | simpleexp: <number>=5 | ||
126 | subexpr: -- evaluate | ||
127 | subexpr: -- evaluate | ||
128 | explist1: end | ||
129 | -- STATEMENT: end 'expr' | ||
130 | |||
131 | close_func | ||
132 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | if foo then foo=1 end | ||
3 | if foo then foo=1 else foo=0 end | ||
4 | if foo then foo=1 elseif not foo then foo=0 end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'if' line=1 | ||
12 | if_stat: if...then | ||
13 | test_then_block: test condition | ||
14 | cond: begin | ||
15 | expr: | ||
16 | prefixexp: <name> | ||
17 | str_checkname: 'foo' | ||
18 | singlevar(kind): 'VGLOBAL' | ||
19 | cond: end | ||
20 | test_then_block: then block | ||
21 | block: begin | ||
22 | enterblock(isbreakable=false) | ||
23 | chunk: | ||
24 | -- STATEMENT: begin 'expr' line=1 | ||
25 | prefixexp: <name> | ||
26 | str_checkname: 'foo' | ||
27 | singlevar(kind): 'VGLOBAL' | ||
28 | expr_stat: assignment k='VGLOBAL' | ||
29 | assignment: '=' -- RHS elements follows | ||
30 | explist1: begin | ||
31 | expr: | ||
32 | simpleexp: <number>=1 | ||
33 | explist1: end | ||
34 | -- STATEMENT: end 'expr' | ||
35 | |||
36 | leaveblock | ||
37 | block: end | ||
38 | if_stat: end | ||
39 | -- STATEMENT: end 'if' | ||
40 | |||
41 | -- STATEMENT: begin 'if' line=2 | ||
42 | if_stat: if...then | ||
43 | test_then_block: test condition | ||
44 | cond: begin | ||
45 | expr: | ||
46 | prefixexp: <name> | ||
47 | str_checkname: 'foo' | ||
48 | singlevar(kind): 'VGLOBAL' | ||
49 | cond: end | ||
50 | test_then_block: then block | ||
51 | block: begin | ||
52 | enterblock(isbreakable=false) | ||
53 | chunk: | ||
54 | -- STATEMENT: begin 'expr' line=2 | ||
55 | prefixexp: <name> | ||
56 | str_checkname: 'foo' | ||
57 | singlevar(kind): 'VGLOBAL' | ||
58 | expr_stat: assignment k='VGLOBAL' | ||
59 | assignment: '=' -- RHS elements follows | ||
60 | explist1: begin | ||
61 | expr: | ||
62 | simpleexp: <number>=1 | ||
63 | explist1: end | ||
64 | -- STATEMENT: end 'expr' | ||
65 | |||
66 | leaveblock | ||
67 | block: end | ||
68 | if_stat: else... | ||
69 | block: begin | ||
70 | enterblock(isbreakable=false) | ||
71 | chunk: | ||
72 | -- STATEMENT: begin 'expr' line=2 | ||
73 | prefixexp: <name> | ||
74 | str_checkname: 'foo' | ||
75 | singlevar(kind): 'VGLOBAL' | ||
76 | expr_stat: assignment k='VGLOBAL' | ||
77 | assignment: '=' -- RHS elements follows | ||
78 | explist1: begin | ||
79 | expr: | ||
80 | simpleexp: <number>=0 | ||
81 | explist1: end | ||
82 | -- STATEMENT: end 'expr' | ||
83 | |||
84 | leaveblock | ||
85 | block: end | ||
86 | if_stat: end | ||
87 | -- STATEMENT: end 'if' | ||
88 | |||
89 | -- STATEMENT: begin 'if' line=3 | ||
90 | if_stat: if...then | ||
91 | test_then_block: test condition | ||
92 | cond: begin | ||
93 | expr: | ||
94 | prefixexp: <name> | ||
95 | str_checkname: 'foo' | ||
96 | singlevar(kind): 'VGLOBAL' | ||
97 | cond: end | ||
98 | test_then_block: then block | ||
99 | block: begin | ||
100 | enterblock(isbreakable=false) | ||
101 | chunk: | ||
102 | -- STATEMENT: begin 'expr' line=3 | ||
103 | prefixexp: <name> | ||
104 | str_checkname: 'foo' | ||
105 | singlevar(kind): 'VGLOBAL' | ||
106 | expr_stat: assignment k='VGLOBAL' | ||
107 | assignment: '=' -- RHS elements follows | ||
108 | explist1: begin | ||
109 | expr: | ||
110 | simpleexp: <number>=1 | ||
111 | explist1: end | ||
112 | -- STATEMENT: end 'expr' | ||
113 | |||
114 | leaveblock | ||
115 | block: end | ||
116 | if_stat: elseif...then | ||
117 | test_then_block: test condition | ||
118 | cond: begin | ||
119 | expr: | ||
120 | subexpr: uop='not' | ||
121 | prefixexp: <name> | ||
122 | str_checkname: 'foo' | ||
123 | singlevar(kind): 'VGLOBAL' | ||
124 | cond: end | ||
125 | test_then_block: then block | ||
126 | block: begin | ||
127 | enterblock(isbreakable=false) | ||
128 | chunk: | ||
129 | -- STATEMENT: begin 'expr' line=3 | ||
130 | prefixexp: <name> | ||
131 | str_checkname: 'foo' | ||
132 | singlevar(kind): 'VGLOBAL' | ||
133 | expr_stat: assignment k='VGLOBAL' | ||
134 | assignment: '=' -- RHS elements follows | ||
135 | explist1: begin | ||
136 | expr: | ||
137 | simpleexp: <number>=0 | ||
138 | explist1: end | ||
139 | -- STATEMENT: end 'expr' | ||
140 | |||
141 | leaveblock | ||
142 | block: end | ||
143 | if_stat: end | ||
144 | -- STATEMENT: end 'if' | ||
145 | |||
146 | close_func | ||
147 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do return end | ||
3 | do return 123 end | ||
4 | do return "foo","bar" end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'do' line=1 | ||
12 | do_stat: begin | ||
13 | block: begin | ||
14 | enterblock(isbreakable=false) | ||
15 | chunk: | ||
16 | -- STATEMENT: begin 'return' line=1 | ||
17 | return_stat: no return values | ||
18 | -- STATEMENT: end 'return' | ||
19 | leaveblock | ||
20 | block: end | ||
21 | do_stat: end | ||
22 | -- STATEMENT: end 'do' | ||
23 | |||
24 | -- STATEMENT: begin 'do' line=2 | ||
25 | do_stat: begin | ||
26 | block: begin | ||
27 | enterblock(isbreakable=false) | ||
28 | chunk: | ||
29 | -- STATEMENT: begin 'return' line=2 | ||
30 | return_stat: begin | ||
31 | explist1: begin | ||
32 | expr: | ||
33 | simpleexp: <number>=123 | ||
34 | explist1: end | ||
35 | return_stat: end | ||
36 | -- STATEMENT: end 'return' | ||
37 | leaveblock | ||
38 | block: end | ||
39 | do_stat: end | ||
40 | -- STATEMENT: end 'do' | ||
41 | |||
42 | -- STATEMENT: begin 'do' line=3 | ||
43 | do_stat: begin | ||
44 | block: begin | ||
45 | enterblock(isbreakable=false) | ||
46 | chunk: | ||
47 | -- STATEMENT: begin 'return' line=3 | ||
48 | return_stat: begin | ||
49 | explist1: begin | ||
50 | expr: | ||
51 | simpleexp: <string>=foo | ||
52 | codestring: "foo" | ||
53 | explist1: ',' -- continuation | ||
54 | expr: | ||
55 | simpleexp: <string>=bar | ||
56 | codestring: "bar" | ||
57 | explist1: end | ||
58 | return_stat: end | ||
59 | -- STATEMENT: end 'return' | ||
60 | leaveblock | ||
61 | block: end | ||
62 | do_stat: end | ||
63 | -- STATEMENT: end 'do' | ||
64 | |||
65 | close_func | ||
66 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | while true do foo=not foo end | ||
3 | while foo~=42 do foo=foo-1 end | ||
4 | while true do break end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'while' line=1 | ||
12 | while_stat: begin/condition | ||
13 | cond: begin | ||
14 | expr: | ||
15 | simpleexp: true | ||
16 | cond: end | ||
17 | enterblock(isbreakable=true) | ||
18 | while_stat: block | ||
19 | block: begin | ||
20 | enterblock(isbreakable=false) | ||
21 | chunk: | ||
22 | -- STATEMENT: begin 'expr' line=1 | ||
23 | prefixexp: <name> | ||
24 | str_checkname: 'foo' | ||
25 | singlevar(kind): 'VGLOBAL' | ||
26 | expr_stat: assignment k='VGLOBAL' | ||
27 | assignment: '=' -- RHS elements follows | ||
28 | explist1: begin | ||
29 | expr: | ||
30 | subexpr: uop='not' | ||
31 | prefixexp: <name> | ||
32 | str_checkname: 'foo' | ||
33 | singlevar(kind): 'VGLOBAL' | ||
34 | explist1: end | ||
35 | -- STATEMENT: end 'expr' | ||
36 | |||
37 | leaveblock | ||
38 | block: end | ||
39 | leaveblock | ||
40 | while_stat: end | ||
41 | -- STATEMENT: end 'while' | ||
42 | |||
43 | -- STATEMENT: begin 'while' line=2 | ||
44 | while_stat: begin/condition | ||
45 | cond: begin | ||
46 | expr: | ||
47 | prefixexp: <name> | ||
48 | str_checkname: 'foo' | ||
49 | singlevar(kind): 'VGLOBAL' | ||
50 | subexpr: binop='~=' | ||
51 | simpleexp: <number>=42 | ||
52 | subexpr: -- evaluate | ||
53 | cond: end | ||
54 | enterblock(isbreakable=true) | ||
55 | while_stat: block | ||
56 | block: begin | ||
57 | enterblock(isbreakable=false) | ||
58 | chunk: | ||
59 | -- STATEMENT: begin 'expr' line=2 | ||
60 | prefixexp: <name> | ||
61 | str_checkname: 'foo' | ||
62 | singlevar(kind): 'VGLOBAL' | ||
63 | expr_stat: assignment k='VGLOBAL' | ||
64 | assignment: '=' -- RHS elements follows | ||
65 | explist1: begin | ||
66 | expr: | ||
67 | prefixexp: <name> | ||
68 | str_checkname: 'foo' | ||
69 | singlevar(kind): 'VGLOBAL' | ||
70 | subexpr: binop='-' | ||
71 | simpleexp: <number>=1 | ||
72 | subexpr: -- evaluate | ||
73 | explist1: end | ||
74 | -- STATEMENT: end 'expr' | ||
75 | |||
76 | leaveblock | ||
77 | block: end | ||
78 | leaveblock | ||
79 | while_stat: end | ||
80 | -- STATEMENT: end 'while' | ||
81 | |||
82 | -- STATEMENT: begin 'while' line=3 | ||
83 | while_stat: begin/condition | ||
84 | cond: begin | ||
85 | expr: | ||
86 | simpleexp: true | ||
87 | cond: end | ||
88 | enterblock(isbreakable=true) | ||
89 | while_stat: block | ||
90 | block: begin | ||
91 | enterblock(isbreakable=false) | ||
92 | chunk: | ||
93 | -- STATEMENT: begin 'break' line=3 | ||
94 | break_stat: -- break out of loop | ||
95 | -- STATEMENT: end 'break' | ||
96 | leaveblock | ||
97 | block: end | ||
98 | leaveblock | ||
99 | while_stat: end | ||
100 | -- STATEMENT: end 'while' | ||
101 | |||
102 | close_func | ||
103 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | repeat foo=foo.."bar" until false | ||
3 | repeat foo=foo/2 until foo<1 | ||
4 | repeat break until false | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'repeat' line=1 | ||
12 | repeat_stat: begin | ||
13 | enterblock(isbreakable=true) | ||
14 | enterblock(isbreakable=false) | ||
15 | chunk: | ||
16 | -- STATEMENT: begin 'expr' line=1 | ||
17 | prefixexp: <name> | ||
18 | str_checkname: 'foo' | ||
19 | singlevar(kind): 'VGLOBAL' | ||
20 | expr_stat: assignment k='VGLOBAL' | ||
21 | assignment: '=' -- RHS elements follows | ||
22 | explist1: begin | ||
23 | expr: | ||
24 | prefixexp: <name> | ||
25 | str_checkname: 'foo' | ||
26 | singlevar(kind): 'VGLOBAL' | ||
27 | subexpr: binop='..' | ||
28 | simpleexp: <string>=bar | ||
29 | codestring: "bar" | ||
30 | subexpr: -- evaluate | ||
31 | explist1: end | ||
32 | -- STATEMENT: end 'expr' | ||
33 | |||
34 | repeat_stat: condition | ||
35 | cond: begin | ||
36 | expr: | ||
37 | simpleexp: false | ||
38 | cond: end | ||
39 | leaveblock | ||
40 | leaveblock | ||
41 | repeat_stat: end | ||
42 | -- STATEMENT: end 'repeat' | ||
43 | |||
44 | -- STATEMENT: begin 'repeat' line=2 | ||
45 | repeat_stat: begin | ||
46 | enterblock(isbreakable=true) | ||
47 | enterblock(isbreakable=false) | ||
48 | chunk: | ||
49 | -- STATEMENT: begin 'expr' line=2 | ||
50 | prefixexp: <name> | ||
51 | str_checkname: 'foo' | ||
52 | singlevar(kind): 'VGLOBAL' | ||
53 | expr_stat: assignment k='VGLOBAL' | ||
54 | assignment: '=' -- RHS elements follows | ||
55 | explist1: begin | ||
56 | expr: | ||
57 | prefixexp: <name> | ||
58 | str_checkname: 'foo' | ||
59 | singlevar(kind): 'VGLOBAL' | ||
60 | subexpr: binop='/' | ||
61 | simpleexp: <number>=2 | ||
62 | subexpr: -- evaluate | ||
63 | explist1: end | ||
64 | -- STATEMENT: end 'expr' | ||
65 | |||
66 | repeat_stat: condition | ||
67 | cond: begin | ||
68 | expr: | ||
69 | prefixexp: <name> | ||
70 | str_checkname: 'foo' | ||
71 | singlevar(kind): 'VGLOBAL' | ||
72 | subexpr: binop='<' | ||
73 | simpleexp: <number>=1 | ||
74 | subexpr: -- evaluate | ||
75 | cond: end | ||
76 | leaveblock | ||
77 | leaveblock | ||
78 | repeat_stat: end | ||
79 | -- STATEMENT: end 'repeat' | ||
80 | |||
81 | -- STATEMENT: begin 'repeat' line=3 | ||
82 | repeat_stat: begin | ||
83 | enterblock(isbreakable=true) | ||
84 | enterblock(isbreakable=false) | ||
85 | chunk: | ||
86 | -- STATEMENT: begin 'break' line=3 | ||
87 | break_stat: -- break out of loop | ||
88 | -- STATEMENT: end 'break' | ||
89 | repeat_stat: condition | ||
90 | cond: begin | ||
91 | expr: | ||
92 | simpleexp: false | ||
93 | cond: end | ||
94 | leaveblock | ||
95 | leaveblock | ||
96 | repeat_stat: end | ||
97 | -- STATEMENT: end 'repeat' | ||
98 | |||
99 | close_func | ||
100 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | for i=1,10 do foo=i end | ||
3 | for i=1,10,2 do break end | ||
4 | for i in foo do bar=0 end | ||
5 | for i,j in foo,bar do baz=0 end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'for' line=1 | ||
13 | for_stat: begin | ||
14 | enterblock(isbreakable=true) | ||
15 | str_checkname: 'i' | ||
16 | for_stat: numerical loop | ||
17 | new_localvar: '(for index)' | ||
18 | new_localvar: '(for limit)' | ||
19 | new_localvar: '(for step)' | ||
20 | new_localvar: 'i' | ||
21 | fornum: begin | ||
22 | fornum: index start | ||
23 | exp1: begin | ||
24 | expr: | ||
25 | simpleexp: <number>=1 | ||
26 | exp1: end | ||
27 | fornum: index stop | ||
28 | exp1: begin | ||
29 | expr: | ||
30 | simpleexp: <number>=10 | ||
31 | exp1: end | ||
32 | fornum: body | ||
33 | enterblock(isbreakable=false) | ||
34 | block: begin | ||
35 | enterblock(isbreakable=false) | ||
36 | chunk: | ||
37 | -- STATEMENT: begin 'expr' line=1 | ||
38 | prefixexp: <name> | ||
39 | str_checkname: 'foo' | ||
40 | singlevar(kind): 'VGLOBAL' | ||
41 | expr_stat: assignment k='VGLOBAL' | ||
42 | assignment: '=' -- RHS elements follows | ||
43 | explist1: begin | ||
44 | expr: | ||
45 | prefixexp: <name> | ||
46 | str_checkname: 'i' | ||
47 | singlevar(kind): 'VLOCAL' | ||
48 | explist1: end | ||
49 | -- STATEMENT: end 'expr' | ||
50 | |||
51 | leaveblock | ||
52 | block: end | ||
53 | leaveblock | ||
54 | fornum: end | ||
55 | leaveblock | ||
56 | for_stat: end | ||
57 | -- STATEMENT: end 'for' | ||
58 | |||
59 | -- STATEMENT: begin 'for' line=2 | ||
60 | for_stat: begin | ||
61 | enterblock(isbreakable=true) | ||
62 | str_checkname: 'i' | ||
63 | for_stat: numerical loop | ||
64 | new_localvar: '(for index)' | ||
65 | new_localvar: '(for limit)' | ||
66 | new_localvar: '(for step)' | ||
67 | new_localvar: 'i' | ||
68 | fornum: begin | ||
69 | fornum: index start | ||
70 | exp1: begin | ||
71 | expr: | ||
72 | simpleexp: <number>=1 | ||
73 | exp1: end | ||
74 | fornum: index stop | ||
75 | exp1: begin | ||
76 | expr: | ||
77 | simpleexp: <number>=10 | ||
78 | exp1: end | ||
79 | fornum: index step | ||
80 | exp1: begin | ||
81 | expr: | ||
82 | simpleexp: <number>=2 | ||
83 | exp1: end | ||
84 | fornum: body | ||
85 | enterblock(isbreakable=false) | ||
86 | block: begin | ||
87 | enterblock(isbreakable=false) | ||
88 | chunk: | ||
89 | -- STATEMENT: begin 'break' line=2 | ||
90 | break_stat: -- break out of loop | ||
91 | -- STATEMENT: end 'break' | ||
92 | leaveblock | ||
93 | block: end | ||
94 | leaveblock | ||
95 | fornum: end | ||
96 | leaveblock | ||
97 | for_stat: end | ||
98 | -- STATEMENT: end 'for' | ||
99 | |||
100 | -- STATEMENT: begin 'for' line=3 | ||
101 | for_stat: begin | ||
102 | enterblock(isbreakable=true) | ||
103 | str_checkname: 'i' | ||
104 | for_stat: list-based loop | ||
105 | forlist: begin | ||
106 | new_localvar: '(for generator)' | ||
107 | new_localvar: '(for state)' | ||
108 | new_localvar: '(for control)' | ||
109 | new_localvar: 'i' | ||
110 | forlist: explist1 | ||
111 | explist1: begin | ||
112 | expr: | ||
113 | prefixexp: <name> | ||
114 | str_checkname: 'foo' | ||
115 | singlevar(kind): 'VGLOBAL' | ||
116 | explist1: end | ||
117 | forlist: body | ||
118 | enterblock(isbreakable=false) | ||
119 | block: begin | ||
120 | enterblock(isbreakable=false) | ||
121 | chunk: | ||
122 | -- STATEMENT: begin 'expr' line=3 | ||
123 | prefixexp: <name> | ||
124 | str_checkname: 'bar' | ||
125 | singlevar(kind): 'VGLOBAL' | ||
126 | expr_stat: assignment k='VGLOBAL' | ||
127 | assignment: '=' -- RHS elements follows | ||
128 | explist1: begin | ||
129 | expr: | ||
130 | simpleexp: <number>=0 | ||
131 | explist1: end | ||
132 | -- STATEMENT: end 'expr' | ||
133 | |||
134 | leaveblock | ||
135 | block: end | ||
136 | leaveblock | ||
137 | forlist: end | ||
138 | leaveblock | ||
139 | for_stat: end | ||
140 | -- STATEMENT: end 'for' | ||
141 | |||
142 | -- STATEMENT: begin 'for' line=4 | ||
143 | for_stat: begin | ||
144 | enterblock(isbreakable=true) | ||
145 | str_checkname: 'i' | ||
146 | for_stat: list-based loop | ||
147 | forlist: begin | ||
148 | new_localvar: '(for generator)' | ||
149 | new_localvar: '(for state)' | ||
150 | new_localvar: '(for control)' | ||
151 | new_localvar: 'i' | ||
152 | str_checkname: 'j' | ||
153 | new_localvar: 'j' | ||
154 | forlist: explist1 | ||
155 | explist1: begin | ||
156 | expr: | ||
157 | prefixexp: <name> | ||
158 | str_checkname: 'foo' | ||
159 | singlevar(kind): 'VGLOBAL' | ||
160 | explist1: ',' -- continuation | ||
161 | expr: | ||
162 | prefixexp: <name> | ||
163 | str_checkname: 'bar' | ||
164 | singlevar(kind): 'VGLOBAL' | ||
165 | explist1: end | ||
166 | forlist: body | ||
167 | enterblock(isbreakable=false) | ||
168 | block: begin | ||
169 | enterblock(isbreakable=false) | ||
170 | chunk: | ||
171 | -- STATEMENT: begin 'expr' line=4 | ||
172 | prefixexp: <name> | ||
173 | str_checkname: 'baz' | ||
174 | singlevar(kind): 'VGLOBAL' | ||
175 | expr_stat: assignment k='VGLOBAL' | ||
176 | assignment: '=' -- RHS elements follows | ||
177 | explist1: begin | ||
178 | expr: | ||
179 | simpleexp: <number>=0 | ||
180 | explist1: end | ||
181 | -- STATEMENT: end 'expr' | ||
182 | |||
183 | leaveblock | ||
184 | block: end | ||
185 | leaveblock | ||
186 | forlist: end | ||
187 | leaveblock | ||
188 | for_stat: end | ||
189 | -- STATEMENT: end 'for' | ||
190 | |||
191 | close_func | ||
192 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local foo | ||
3 | local foo,bar,baz | ||
4 | local foo,bar="foo","bar" | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'local' line=1 | ||
12 | local_stat: local statement | ||
13 | localstat: begin | ||
14 | str_checkname: 'foo' | ||
15 | new_localvar: 'foo' | ||
16 | localstat: end | ||
17 | -- STATEMENT: end 'local' | ||
18 | |||
19 | -- STATEMENT: begin 'local' line=2 | ||
20 | local_stat: local statement | ||
21 | localstat: begin | ||
22 | str_checkname: 'foo' | ||
23 | new_localvar: 'foo' | ||
24 | str_checkname: 'bar' | ||
25 | new_localvar: 'bar' | ||
26 | str_checkname: 'baz' | ||
27 | new_localvar: 'baz' | ||
28 | localstat: end | ||
29 | -- STATEMENT: end 'local' | ||
30 | |||
31 | -- STATEMENT: begin 'local' line=3 | ||
32 | local_stat: local statement | ||
33 | localstat: begin | ||
34 | str_checkname: 'foo' | ||
35 | new_localvar: 'foo' | ||
36 | str_checkname: 'bar' | ||
37 | new_localvar: 'bar' | ||
38 | localstat: -- assignment | ||
39 | explist1: begin | ||
40 | expr: | ||
41 | simpleexp: <string>=foo | ||
42 | codestring: "foo" | ||
43 | explist1: ',' -- continuation | ||
44 | expr: | ||
45 | simpleexp: <string>=bar | ||
46 | codestring: "bar" | ||
47 | explist1: end | ||
48 | localstat: end | ||
49 | -- STATEMENT: end 'local' | ||
50 | |||
51 | close_func | ||
52 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local function foo() return end | ||
3 | local function foo(a) return end | ||
4 | local function foo(x,y,z) return end | ||
5 | local function foo(x,...) return end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'local' line=1 | ||
13 | local_stat: local function | ||
14 | localfunc: begin | ||
15 | str_checkname: 'foo' | ||
16 | new_localvar: 'foo' | ||
17 | localfunc: body | ||
18 | open_func | ||
19 | body: begin | ||
20 | body: parlist | ||
21 | parlist: begin | ||
22 | parlist: end | ||
23 | body: chunk | ||
24 | chunk: | ||
25 | -- STATEMENT: begin 'return' line=1 | ||
26 | return_stat: no return values | ||
27 | -- STATEMENT: end 'return' | ||
28 | body: end | ||
29 | close_func | ||
30 | localfunc: end | ||
31 | -- STATEMENT: end 'local' | ||
32 | |||
33 | -- STATEMENT: begin 'local' line=2 | ||
34 | local_stat: local function | ||
35 | localfunc: begin | ||
36 | str_checkname: 'foo' | ||
37 | new_localvar: 'foo' | ||
38 | localfunc: body | ||
39 | open_func | ||
40 | body: begin | ||
41 | body: parlist | ||
42 | parlist: begin | ||
43 | str_checkname: 'a' | ||
44 | new_localvar: 'a' | ||
45 | parlist: end | ||
46 | body: chunk | ||
47 | chunk: | ||
48 | -- STATEMENT: begin 'return' line=2 | ||
49 | return_stat: no return values | ||
50 | -- STATEMENT: end 'return' | ||
51 | body: end | ||
52 | close_func | ||
53 | localfunc: end | ||
54 | -- STATEMENT: end 'local' | ||
55 | |||
56 | -- STATEMENT: begin 'local' line=3 | ||
57 | local_stat: local function | ||
58 | localfunc: begin | ||
59 | str_checkname: 'foo' | ||
60 | new_localvar: 'foo' | ||
61 | localfunc: body | ||
62 | open_func | ||
63 | body: begin | ||
64 | body: parlist | ||
65 | parlist: begin | ||
66 | str_checkname: 'x' | ||
67 | new_localvar: 'x' | ||
68 | str_checkname: 'y' | ||
69 | new_localvar: 'y' | ||
70 | str_checkname: 'z' | ||
71 | new_localvar: 'z' | ||
72 | parlist: end | ||
73 | body: chunk | ||
74 | chunk: | ||
75 | -- STATEMENT: begin 'return' line=3 | ||
76 | return_stat: no return values | ||
77 | -- STATEMENT: end 'return' | ||
78 | body: end | ||
79 | close_func | ||
80 | localfunc: end | ||
81 | -- STATEMENT: end 'local' | ||
82 | |||
83 | -- STATEMENT: begin 'local' line=4 | ||
84 | local_stat: local function | ||
85 | localfunc: begin | ||
86 | str_checkname: 'foo' | ||
87 | new_localvar: 'foo' | ||
88 | localfunc: body | ||
89 | open_func | ||
90 | body: begin | ||
91 | body: parlist | ||
92 | parlist: begin | ||
93 | str_checkname: 'x' | ||
94 | new_localvar: 'x' | ||
95 | parlist: ... (dots) | ||
96 | parlist: end | ||
97 | body: chunk | ||
98 | chunk: | ||
99 | -- STATEMENT: begin 'return' line=4 | ||
100 | return_stat: no return values | ||
101 | -- STATEMENT: end 'return' | ||
102 | body: end | ||
103 | close_func | ||
104 | localfunc: end | ||
105 | -- STATEMENT: end 'local' | ||
106 | |||
107 | close_func | ||
108 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo() return end | ||
3 | function foo(a) return end | ||
4 | function foo(x,y,z) return end | ||
5 | function foo(x,...) return end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'function' line=1 | ||
13 | function_stat: begin | ||
14 | funcname: begin | ||
15 | str_checkname: 'foo' | ||
16 | singlevar(kind): 'VGLOBAL' | ||
17 | funcname: end | ||
18 | function_stat: body needself='false' | ||
19 | open_func | ||
20 | body: begin | ||
21 | body: parlist | ||
22 | parlist: begin | ||
23 | parlist: end | ||
24 | body: chunk | ||
25 | chunk: | ||
26 | -- STATEMENT: begin 'return' line=1 | ||
27 | return_stat: no return values | ||
28 | -- STATEMENT: end 'return' | ||
29 | body: end | ||
30 | close_func | ||
31 | function_stat: end | ||
32 | -- STATEMENT: end 'function' | ||
33 | |||
34 | -- STATEMENT: begin 'function' line=2 | ||
35 | function_stat: begin | ||
36 | funcname: begin | ||
37 | str_checkname: 'foo' | ||
38 | singlevar(kind): 'VGLOBAL' | ||
39 | funcname: end | ||
40 | function_stat: body needself='false' | ||
41 | open_func | ||
42 | body: begin | ||
43 | body: parlist | ||
44 | parlist: begin | ||
45 | str_checkname: 'a' | ||
46 | new_localvar: 'a' | ||
47 | parlist: end | ||
48 | body: chunk | ||
49 | chunk: | ||
50 | -- STATEMENT: begin 'return' line=2 | ||
51 | return_stat: no return values | ||
52 | -- STATEMENT: end 'return' | ||
53 | body: end | ||
54 | close_func | ||
55 | function_stat: end | ||
56 | -- STATEMENT: end 'function' | ||
57 | |||
58 | -- STATEMENT: begin 'function' line=3 | ||
59 | function_stat: begin | ||
60 | funcname: begin | ||
61 | str_checkname: 'foo' | ||
62 | singlevar(kind): 'VGLOBAL' | ||
63 | funcname: end | ||
64 | function_stat: body needself='false' | ||
65 | open_func | ||
66 | body: begin | ||
67 | body: parlist | ||
68 | parlist: begin | ||
69 | str_checkname: 'x' | ||
70 | new_localvar: 'x' | ||
71 | str_checkname: 'y' | ||
72 | new_localvar: 'y' | ||
73 | str_checkname: 'z' | ||
74 | new_localvar: 'z' | ||
75 | parlist: end | ||
76 | body: chunk | ||
77 | chunk: | ||
78 | -- STATEMENT: begin 'return' line=3 | ||
79 | return_stat: no return values | ||
80 | -- STATEMENT: end 'return' | ||
81 | body: end | ||
82 | close_func | ||
83 | function_stat: end | ||
84 | -- STATEMENT: end 'function' | ||
85 | |||
86 | -- STATEMENT: begin 'function' line=4 | ||
87 | function_stat: begin | ||
88 | funcname: begin | ||
89 | str_checkname: 'foo' | ||
90 | singlevar(kind): 'VGLOBAL' | ||
91 | funcname: end | ||
92 | function_stat: body needself='false' | ||
93 | open_func | ||
94 | body: begin | ||
95 | body: parlist | ||
96 | parlist: begin | ||
97 | str_checkname: 'x' | ||
98 | new_localvar: 'x' | ||
99 | parlist: ... (dots) | ||
100 | parlist: end | ||
101 | body: chunk | ||
102 | chunk: | ||
103 | -- STATEMENT: begin 'return' line=4 | ||
104 | return_stat: no return values | ||
105 | -- STATEMENT: end 'return' | ||
106 | body: end | ||
107 | close_func | ||
108 | function_stat: end | ||
109 | -- STATEMENT: end 'function' | ||
110 | |||
111 | close_func | ||
112 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo.bar(p) return end | ||
3 | function foo.bar.baz(p) return end | ||
4 | function foo:bar(p) return end | ||
5 | function foo.bar.baz(p) return end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'function' line=1 | ||
13 | function_stat: begin | ||
14 | funcname: begin | ||
15 | str_checkname: 'foo' | ||
16 | singlevar(kind): 'VGLOBAL' | ||
17 | funcname: -- '.' field | ||
18 | field: operator=. | ||
19 | checkname: | ||
20 | str_checkname: 'bar' | ||
21 | codestring: "bar" | ||
22 | funcname: end | ||
23 | function_stat: body needself='false' | ||
24 | open_func | ||
25 | body: begin | ||
26 | body: parlist | ||
27 | parlist: begin | ||
28 | str_checkname: 'p' | ||
29 | new_localvar: 'p' | ||
30 | parlist: end | ||
31 | body: chunk | ||
32 | chunk: | ||
33 | -- STATEMENT: begin 'return' line=1 | ||
34 | return_stat: no return values | ||
35 | -- STATEMENT: end 'return' | ||
36 | body: end | ||
37 | close_func | ||
38 | function_stat: end | ||
39 | -- STATEMENT: end 'function' | ||
40 | |||
41 | -- STATEMENT: begin 'function' line=2 | ||
42 | function_stat: begin | ||
43 | funcname: begin | ||
44 | str_checkname: 'foo' | ||
45 | singlevar(kind): 'VGLOBAL' | ||
46 | funcname: -- '.' field | ||
47 | field: operator=. | ||
48 | checkname: | ||
49 | str_checkname: 'bar' | ||
50 | codestring: "bar" | ||
51 | funcname: -- '.' field | ||
52 | field: operator=. | ||
53 | checkname: | ||
54 | str_checkname: 'baz' | ||
55 | codestring: "baz" | ||
56 | funcname: end | ||
57 | function_stat: body needself='false' | ||
58 | open_func | ||
59 | body: begin | ||
60 | body: parlist | ||
61 | parlist: begin | ||
62 | str_checkname: 'p' | ||
63 | new_localvar: 'p' | ||
64 | parlist: end | ||
65 | body: chunk | ||
66 | chunk: | ||
67 | -- STATEMENT: begin 'return' line=2 | ||
68 | return_stat: no return values | ||
69 | -- STATEMENT: end 'return' | ||
70 | body: end | ||
71 | close_func | ||
72 | function_stat: end | ||
73 | -- STATEMENT: end 'function' | ||
74 | |||
75 | -- STATEMENT: begin 'function' line=3 | ||
76 | function_stat: begin | ||
77 | funcname: begin | ||
78 | str_checkname: 'foo' | ||
79 | singlevar(kind): 'VGLOBAL' | ||
80 | funcname: -- ':' field | ||
81 | field: operator=: | ||
82 | checkname: | ||
83 | str_checkname: 'bar' | ||
84 | codestring: "bar" | ||
85 | funcname: end | ||
86 | function_stat: body needself='true' | ||
87 | open_func | ||
88 | body: begin | ||
89 | new_localvar: 'self' | ||
90 | body: parlist | ||
91 | parlist: begin | ||
92 | str_checkname: 'p' | ||
93 | new_localvar: 'p' | ||
94 | parlist: end | ||
95 | body: chunk | ||
96 | chunk: | ||
97 | -- STATEMENT: begin 'return' line=3 | ||
98 | return_stat: no return values | ||
99 | -- STATEMENT: end 'return' | ||
100 | body: end | ||
101 | close_func | ||
102 | function_stat: end | ||
103 | -- STATEMENT: end 'function' | ||
104 | |||
105 | -- STATEMENT: begin 'function' line=4 | ||
106 | function_stat: begin | ||
107 | funcname: begin | ||
108 | str_checkname: 'foo' | ||
109 | singlevar(kind): 'VGLOBAL' | ||
110 | funcname: -- '.' field | ||
111 | field: operator=. | ||
112 | checkname: | ||
113 | str_checkname: 'bar' | ||
114 | codestring: "bar" | ||
115 | funcname: -- '.' field | ||
116 | field: operator=. | ||
117 | checkname: | ||
118 | str_checkname: 'baz' | ||
119 | codestring: "baz" | ||
120 | funcname: end | ||
121 | function_stat: body needself='false' | ||
122 | open_func | ||
123 | body: begin | ||
124 | body: parlist | ||
125 | parlist: begin | ||
126 | str_checkname: 'p' | ||
127 | new_localvar: 'p' | ||
128 | parlist: end | ||
129 | body: chunk | ||
130 | chunk: | ||
131 | -- STATEMENT: begin 'return' line=4 | ||
132 | return_stat: no return values | ||
133 | -- STATEMENT: end 'return' | ||
134 | body: end | ||
135 | close_func | ||
136 | function_stat: end | ||
137 | -- STATEMENT: end 'function' | ||
138 | |||
139 | close_func | ||
140 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | foo = function() return end | ||
3 | foo = function(x,y) return end | ||
4 | foo = function(...) return end | ||
5 | foo = function(...) local bar = ... return end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'expr' line=1 | ||
13 | prefixexp: <name> | ||
14 | str_checkname: 'foo' | ||
15 | singlevar(kind): 'VGLOBAL' | ||
16 | expr_stat: assignment k='VGLOBAL' | ||
17 | assignment: '=' -- RHS elements follows | ||
18 | explist1: begin | ||
19 | expr: | ||
20 | simpleexp: function | ||
21 | open_func | ||
22 | body: begin | ||
23 | body: parlist | ||
24 | parlist: begin | ||
25 | parlist: end | ||
26 | body: chunk | ||
27 | chunk: | ||
28 | -- STATEMENT: begin 'return' line=1 | ||
29 | return_stat: no return values | ||
30 | -- STATEMENT: end 'return' | ||
31 | body: end | ||
32 | close_func | ||
33 | explist1: end | ||
34 | -- STATEMENT: end 'expr' | ||
35 | |||
36 | -- STATEMENT: begin 'expr' line=2 | ||
37 | prefixexp: <name> | ||
38 | str_checkname: 'foo' | ||
39 | singlevar(kind): 'VGLOBAL' | ||
40 | expr_stat: assignment k='VGLOBAL' | ||
41 | assignment: '=' -- RHS elements follows | ||
42 | explist1: begin | ||
43 | expr: | ||
44 | simpleexp: function | ||
45 | open_func | ||
46 | body: begin | ||
47 | body: parlist | ||
48 | parlist: begin | ||
49 | str_checkname: 'x' | ||
50 | new_localvar: 'x' | ||
51 | str_checkname: 'y' | ||
52 | new_localvar: 'y' | ||
53 | parlist: end | ||
54 | body: chunk | ||
55 | chunk: | ||
56 | -- STATEMENT: begin 'return' line=2 | ||
57 | return_stat: no return values | ||
58 | -- STATEMENT: end 'return' | ||
59 | body: end | ||
60 | close_func | ||
61 | explist1: end | ||
62 | -- STATEMENT: end 'expr' | ||
63 | |||
64 | -- STATEMENT: begin 'expr' line=3 | ||
65 | prefixexp: <name> | ||
66 | str_checkname: 'foo' | ||
67 | singlevar(kind): 'VGLOBAL' | ||
68 | expr_stat: assignment k='VGLOBAL' | ||
69 | assignment: '=' -- RHS elements follows | ||
70 | explist1: begin | ||
71 | expr: | ||
72 | simpleexp: function | ||
73 | open_func | ||
74 | body: begin | ||
75 | body: parlist | ||
76 | parlist: begin | ||
77 | parlist: ... (dots) | ||
78 | parlist: end | ||
79 | body: chunk | ||
80 | chunk: | ||
81 | -- STATEMENT: begin 'return' line=3 | ||
82 | return_stat: no return values | ||
83 | -- STATEMENT: end 'return' | ||
84 | body: end | ||
85 | close_func | ||
86 | explist1: end | ||
87 | -- STATEMENT: end 'expr' | ||
88 | |||
89 | -- STATEMENT: begin 'expr' line=4 | ||
90 | prefixexp: <name> | ||
91 | str_checkname: 'foo' | ||
92 | singlevar(kind): 'VGLOBAL' | ||
93 | expr_stat: assignment k='VGLOBAL' | ||
94 | assignment: '=' -- RHS elements follows | ||
95 | explist1: begin | ||
96 | expr: | ||
97 | simpleexp: function | ||
98 | open_func | ||
99 | body: begin | ||
100 | body: parlist | ||
101 | parlist: begin | ||
102 | parlist: ... (dots) | ||
103 | parlist: end | ||
104 | body: chunk | ||
105 | chunk: | ||
106 | -- STATEMENT: begin 'local' line=4 | ||
107 | local_stat: local statement | ||
108 | localstat: begin | ||
109 | str_checkname: 'bar' | ||
110 | new_localvar: 'bar' | ||
111 | localstat: -- assignment | ||
112 | explist1: begin | ||
113 | expr: | ||
114 | simpleexp: ... | ||
115 | explist1: end | ||
116 | localstat: end | ||
117 | -- STATEMENT: end 'local' | ||
118 | |||
119 | -- STATEMENT: begin 'return' line=4 | ||
120 | return_stat: no return values | ||
121 | -- STATEMENT: end 'return' | ||
122 | body: end | ||
123 | close_func | ||
124 | explist1: end | ||
125 | -- STATEMENT: end 'expr' | ||
126 | |||
127 | close_func | ||
128 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | foo = {} | ||
3 | foo = { 1,2,3; "foo"; } | ||
4 | foo = { bar=77, baz=88, } | ||
5 | foo = { ["bar"]=77, ["baz"]=88, } | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'expr' line=1 | ||
13 | prefixexp: <name> | ||
14 | str_checkname: 'foo' | ||
15 | singlevar(kind): 'VGLOBAL' | ||
16 | expr_stat: assignment k='VGLOBAL' | ||
17 | assignment: '=' -- RHS elements follows | ||
18 | explist1: begin | ||
19 | expr: | ||
20 | simpleexp: constructor | ||
21 | constructor: begin | ||
22 | constructor: end | ||
23 | explist1: end | ||
24 | -- STATEMENT: end 'expr' | ||
25 | |||
26 | -- STATEMENT: begin 'expr' line=2 | ||
27 | prefixexp: <name> | ||
28 | str_checkname: 'foo' | ||
29 | singlevar(kind): 'VGLOBAL' | ||
30 | expr_stat: assignment k='VGLOBAL' | ||
31 | assignment: '=' -- RHS elements follows | ||
32 | explist1: begin | ||
33 | expr: | ||
34 | simpleexp: constructor | ||
35 | constructor: begin | ||
36 | listfield: expr | ||
37 | expr: | ||
38 | simpleexp: <number>=1 | ||
39 | listfield: expr | ||
40 | expr: | ||
41 | simpleexp: <number>=2 | ||
42 | listfield: expr | ||
43 | expr: | ||
44 | simpleexp: <number>=3 | ||
45 | listfield: expr | ||
46 | expr: | ||
47 | simpleexp: <string>=foo | ||
48 | codestring: "foo" | ||
49 | constructor: end | ||
50 | explist1: end | ||
51 | -- STATEMENT: end 'expr' | ||
52 | |||
53 | -- STATEMENT: begin 'expr' line=3 | ||
54 | prefixexp: <name> | ||
55 | str_checkname: 'foo' | ||
56 | singlevar(kind): 'VGLOBAL' | ||
57 | expr_stat: assignment k='VGLOBAL' | ||
58 | assignment: '=' -- RHS elements follows | ||
59 | explist1: begin | ||
60 | expr: | ||
61 | simpleexp: constructor | ||
62 | constructor: begin | ||
63 | recfield: name | ||
64 | checkname: | ||
65 | str_checkname: 'bar' | ||
66 | codestring: "bar" | ||
67 | expr: | ||
68 | simpleexp: <number>=77 | ||
69 | recfield: name | ||
70 | checkname: | ||
71 | str_checkname: 'baz' | ||
72 | codestring: "baz" | ||
73 | expr: | ||
74 | simpleexp: <number>=88 | ||
75 | constructor: end | ||
76 | explist1: end | ||
77 | -- STATEMENT: end 'expr' | ||
78 | |||
79 | -- STATEMENT: begin 'expr' line=4 | ||
80 | prefixexp: <name> | ||
81 | str_checkname: 'foo' | ||
82 | singlevar(kind): 'VGLOBAL' | ||
83 | expr_stat: assignment k='VGLOBAL' | ||
84 | assignment: '=' -- RHS elements follows | ||
85 | explist1: begin | ||
86 | expr: | ||
87 | simpleexp: constructor | ||
88 | constructor: begin | ||
89 | recfield: [ exp1 ] | ||
90 | index: begin '[' | ||
91 | expr: | ||
92 | simpleexp: <string>=bar | ||
93 | codestring: "bar" | ||
94 | index: end ']' | ||
95 | expr: | ||
96 | simpleexp: <number>=77 | ||
97 | recfield: [ exp1 ] | ||
98 | index: begin '[' | ||
99 | expr: | ||
100 | simpleexp: <string>=baz | ||
101 | codestring: "baz" | ||
102 | index: end ']' | ||
103 | expr: | ||
104 | simpleexp: <number>=88 | ||
105 | constructor: end | ||
106 | explist1: end | ||
107 | -- STATEMENT: end 'expr' | ||
108 | |||
109 | close_func | ||
110 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | print(a) | ||
3 | -- END OF SOURCE -- | ||
4 | |||
5 | -- TOP: begin | ||
6 | open_func | ||
7 | |||
8 | chunk: | ||
9 | -- STATEMENT: begin 'expr' line=1 | ||
10 | prefixexp: <name> | ||
11 | str_checkname: 'print' | ||
12 | singlevar(kind): 'VGLOBAL' | ||
13 | primaryexp: ( funcargs | ||
14 | funcargs: begin '(' | ||
15 | explist1: begin | ||
16 | expr: | ||
17 | prefixexp: <name> | ||
18 | str_checkname: 'a' | ||
19 | singlevar(kind): 'VGLOBAL' | ||
20 | explist1: end | ||
21 | funcargs: end -- expr is a VCALL | ||
22 | expr_stat: function call k='VCALL' | ||
23 | -- STATEMENT: end 'expr' | ||
24 | |||
25 | close_func | ||
26 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local a | ||
3 | print(a) | ||
4 | -- END OF SOURCE -- | ||
5 | |||
6 | -- TOP: begin | ||
7 | open_func | ||
8 | |||
9 | chunk: | ||
10 | -- STATEMENT: begin 'local' line=1 | ||
11 | local_stat: local statement | ||
12 | localstat: begin | ||
13 | str_checkname: 'a' | ||
14 | new_localvar: 'a' | ||
15 | localstat: end | ||
16 | -- STATEMENT: end 'local' | ||
17 | |||
18 | -- STATEMENT: begin 'expr' line=2 | ||
19 | prefixexp: <name> | ||
20 | str_checkname: 'print' | ||
21 | singlevar(kind): 'VGLOBAL' | ||
22 | primaryexp: ( funcargs | ||
23 | funcargs: begin '(' | ||
24 | explist1: begin | ||
25 | expr: | ||
26 | prefixexp: <name> | ||
27 | str_checkname: 'a' | ||
28 | singlevar(kind): 'VLOCAL' | ||
29 | explist1: end | ||
30 | funcargs: end -- expr is a VCALL | ||
31 | expr_stat: function call k='VCALL' | ||
32 | -- STATEMENT: end 'expr' | ||
33 | |||
34 | close_func | ||
35 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do | ||
3 | local a | ||
4 | print(a) | ||
5 | end | ||
6 | print(a) | ||
7 | -- END OF SOURCE -- | ||
8 | |||
9 | -- TOP: begin | ||
10 | open_func | ||
11 | |||
12 | chunk: | ||
13 | -- STATEMENT: begin 'do' line=1 | ||
14 | do_stat: begin | ||
15 | block: begin | ||
16 | enterblock(isbreakable=false) | ||
17 | chunk: | ||
18 | -- STATEMENT: begin 'local' line=2 | ||
19 | local_stat: local statement | ||
20 | localstat: begin | ||
21 | str_checkname: 'a' | ||
22 | new_localvar: 'a' | ||
23 | localstat: end | ||
24 | -- STATEMENT: end 'local' | ||
25 | |||
26 | -- STATEMENT: begin 'expr' line=3 | ||
27 | prefixexp: <name> | ||
28 | str_checkname: 'print' | ||
29 | singlevar(kind): 'VGLOBAL' | ||
30 | primaryexp: ( funcargs | ||
31 | funcargs: begin '(' | ||
32 | explist1: begin | ||
33 | expr: | ||
34 | prefixexp: <name> | ||
35 | str_checkname: 'a' | ||
36 | singlevar(kind): 'VLOCAL' | ||
37 | explist1: end | ||
38 | funcargs: end -- expr is a VCALL | ||
39 | expr_stat: function call k='VCALL' | ||
40 | -- STATEMENT: end 'expr' | ||
41 | |||
42 | leaveblock | ||
43 | block: end | ||
44 | do_stat: end | ||
45 | -- STATEMENT: end 'do' | ||
46 | |||
47 | -- STATEMENT: begin 'expr' line=5 | ||
48 | prefixexp: <name> | ||
49 | str_checkname: 'print' | ||
50 | singlevar(kind): 'VGLOBAL' | ||
51 | primaryexp: ( funcargs | ||
52 | funcargs: begin '(' | ||
53 | explist1: begin | ||
54 | expr: | ||
55 | prefixexp: <name> | ||
56 | str_checkname: 'a' | ||
57 | singlevar(kind): 'VGLOBAL' | ||
58 | explist1: end | ||
59 | funcargs: end -- expr is a VCALL | ||
60 | expr_stat: function call k='VCALL' | ||
61 | -- STATEMENT: end 'expr' | ||
62 | |||
63 | close_func | ||
64 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local a,b,c | ||
3 | do | ||
4 | local b | ||
5 | print(b) | ||
6 | end | ||
7 | print(b) | ||
8 | -- END OF SOURCE -- | ||
9 | |||
10 | -- TOP: begin | ||
11 | open_func | ||
12 | |||
13 | chunk: | ||
14 | -- STATEMENT: begin 'local' line=1 | ||
15 | local_stat: local statement | ||
16 | localstat: begin | ||
17 | str_checkname: 'a' | ||
18 | new_localvar: 'a' | ||
19 | str_checkname: 'b' | ||
20 | new_localvar: 'b' | ||
21 | str_checkname: 'c' | ||
22 | new_localvar: 'c' | ||
23 | localstat: end | ||
24 | -- STATEMENT: end 'local' | ||
25 | |||
26 | -- STATEMENT: begin 'do' line=2 | ||
27 | do_stat: begin | ||
28 | block: begin | ||
29 | enterblock(isbreakable=false) | ||
30 | chunk: | ||
31 | -- STATEMENT: begin 'local' line=3 | ||
32 | local_stat: local statement | ||
33 | localstat: begin | ||
34 | str_checkname: 'b' | ||
35 | new_localvar: 'b' | ||
36 | localstat: end | ||
37 | -- STATEMENT: end 'local' | ||
38 | |||
39 | -- STATEMENT: begin 'expr' line=4 | ||
40 | prefixexp: <name> | ||
41 | str_checkname: 'print' | ||
42 | singlevar(kind): 'VGLOBAL' | ||
43 | primaryexp: ( funcargs | ||
44 | funcargs: begin '(' | ||
45 | explist1: begin | ||
46 | expr: | ||
47 | prefixexp: <name> | ||
48 | str_checkname: 'b' | ||
49 | singlevar(kind): 'VLOCAL' | ||
50 | explist1: end | ||
51 | funcargs: end -- expr is a VCALL | ||
52 | expr_stat: function call k='VCALL' | ||
53 | -- STATEMENT: end 'expr' | ||
54 | |||
55 | leaveblock | ||
56 | block: end | ||
57 | do_stat: end | ||
58 | -- STATEMENT: end 'do' | ||
59 | |||
60 | -- STATEMENT: begin 'expr' line=6 | ||
61 | prefixexp: <name> | ||
62 | str_checkname: 'print' | ||
63 | singlevar(kind): 'VGLOBAL' | ||
64 | primaryexp: ( funcargs | ||
65 | funcargs: begin '(' | ||
66 | explist1: begin | ||
67 | expr: | ||
68 | prefixexp: <name> | ||
69 | str_checkname: 'b' | ||
70 | singlevar(kind): 'VLOCAL' | ||
71 | explist1: end | ||
72 | funcargs: end -- expr is a VCALL | ||
73 | expr_stat: function call k='VCALL' | ||
74 | -- STATEMENT: end 'expr' | ||
75 | |||
76 | close_func | ||
77 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local function foo() end | ||
3 | bar = foo | ||
4 | -- END OF SOURCE -- | ||
5 | |||
6 | -- TOP: begin | ||
7 | open_func | ||
8 | |||
9 | chunk: | ||
10 | -- STATEMENT: begin 'local' line=1 | ||
11 | local_stat: local function | ||
12 | localfunc: begin | ||
13 | str_checkname: 'foo' | ||
14 | new_localvar: 'foo' | ||
15 | localfunc: body | ||
16 | open_func | ||
17 | body: begin | ||
18 | body: parlist | ||
19 | parlist: begin | ||
20 | parlist: end | ||
21 | body: chunk | ||
22 | chunk: | ||
23 | body: end | ||
24 | close_func | ||
25 | localfunc: end | ||
26 | -- STATEMENT: end 'local' | ||
27 | |||
28 | -- STATEMENT: begin 'expr' line=2 | ||
29 | prefixexp: <name> | ||
30 | str_checkname: 'bar' | ||
31 | singlevar(kind): 'VGLOBAL' | ||
32 | expr_stat: assignment k='VGLOBAL' | ||
33 | assignment: '=' -- RHS elements follows | ||
34 | explist1: begin | ||
35 | expr: | ||
36 | prefixexp: <name> | ||
37 | str_checkname: 'foo' | ||
38 | singlevar(kind): 'VLOCAL' | ||
39 | explist1: end | ||
40 | -- STATEMENT: end 'expr' | ||
41 | |||
42 | close_func | ||
43 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | do | ||
3 | local function foo() end | ||
4 | bar = foo | ||
5 | end | ||
6 | baz = foo | ||
7 | -- END OF SOURCE -- | ||
8 | |||
9 | -- TOP: begin | ||
10 | open_func | ||
11 | |||
12 | chunk: | ||
13 | -- STATEMENT: begin 'do' line=1 | ||
14 | do_stat: begin | ||
15 | block: begin | ||
16 | enterblock(isbreakable=false) | ||
17 | chunk: | ||
18 | -- STATEMENT: begin 'local' line=2 | ||
19 | local_stat: local function | ||
20 | localfunc: begin | ||
21 | str_checkname: 'foo' | ||
22 | new_localvar: 'foo' | ||
23 | localfunc: body | ||
24 | open_func | ||
25 | body: begin | ||
26 | body: parlist | ||
27 | parlist: begin | ||
28 | parlist: end | ||
29 | body: chunk | ||
30 | chunk: | ||
31 | body: end | ||
32 | close_func | ||
33 | localfunc: end | ||
34 | -- STATEMENT: end 'local' | ||
35 | |||
36 | -- STATEMENT: begin 'expr' line=3 | ||
37 | prefixexp: <name> | ||
38 | str_checkname: 'bar' | ||
39 | singlevar(kind): 'VGLOBAL' | ||
40 | expr_stat: assignment k='VGLOBAL' | ||
41 | assignment: '=' -- RHS elements follows | ||
42 | explist1: begin | ||
43 | expr: | ||
44 | prefixexp: <name> | ||
45 | str_checkname: 'foo' | ||
46 | singlevar(kind): 'VLOCAL' | ||
47 | explist1: end | ||
48 | -- STATEMENT: end 'expr' | ||
49 | |||
50 | leaveblock | ||
51 | block: end | ||
52 | do_stat: end | ||
53 | -- STATEMENT: end 'do' | ||
54 | |||
55 | -- STATEMENT: begin 'expr' line=5 | ||
56 | prefixexp: <name> | ||
57 | str_checkname: 'baz' | ||
58 | singlevar(kind): 'VGLOBAL' | ||
59 | expr_stat: assignment k='VGLOBAL' | ||
60 | assignment: '=' -- RHS elements follows | ||
61 | explist1: begin | ||
62 | expr: | ||
63 | prefixexp: <name> | ||
64 | str_checkname: 'foo' | ||
65 | singlevar(kind): 'VGLOBAL' | ||
66 | explist1: end | ||
67 | -- STATEMENT: end 'expr' | ||
68 | |||
69 | close_func | ||
70 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local foo | ||
3 | local function bar() | ||
4 | baz = nil | ||
5 | foo = bar() | ||
6 | end | ||
7 | foo = bar | ||
8 | -- END OF SOURCE -- | ||
9 | |||
10 | -- TOP: begin | ||
11 | open_func | ||
12 | |||
13 | chunk: | ||
14 | -- STATEMENT: begin 'local' line=1 | ||
15 | local_stat: local statement | ||
16 | localstat: begin | ||
17 | str_checkname: 'foo' | ||
18 | new_localvar: 'foo' | ||
19 | localstat: end | ||
20 | -- STATEMENT: end 'local' | ||
21 | |||
22 | -- STATEMENT: begin 'local' line=2 | ||
23 | local_stat: local function | ||
24 | localfunc: begin | ||
25 | str_checkname: 'bar' | ||
26 | new_localvar: 'bar' | ||
27 | localfunc: body | ||
28 | open_func | ||
29 | body: begin | ||
30 | body: parlist | ||
31 | parlist: begin | ||
32 | parlist: end | ||
33 | body: chunk | ||
34 | chunk: | ||
35 | -- STATEMENT: begin 'expr' line=3 | ||
36 | prefixexp: <name> | ||
37 | str_checkname: 'baz' | ||
38 | singlevar(kind): 'VGLOBAL' | ||
39 | expr_stat: assignment k='VGLOBAL' | ||
40 | assignment: '=' -- RHS elements follows | ||
41 | explist1: begin | ||
42 | expr: | ||
43 | simpleexp: nil | ||
44 | explist1: end | ||
45 | -- STATEMENT: end 'expr' | ||
46 | |||
47 | -- STATEMENT: begin 'expr' line=4 | ||
48 | prefixexp: <name> | ||
49 | str_checkname: 'foo' | ||
50 | singlevar(kind): 'VUPVAL' | ||
51 | expr_stat: assignment k='VUPVAL' | ||
52 | assignment: '=' -- RHS elements follows | ||
53 | explist1: begin | ||
54 | expr: | ||
55 | prefixexp: <name> | ||
56 | str_checkname: 'bar' | ||
57 | singlevar(kind): 'VUPVAL' | ||
58 | primaryexp: ( funcargs | ||
59 | funcargs: begin '(' | ||
60 | funcargs: end -- expr is a VCALL | ||
61 | explist1: end | ||
62 | -- STATEMENT: end 'expr' | ||
63 | |||
64 | body: end | ||
65 | close_func | ||
66 | localfunc: end | ||
67 | -- STATEMENT: end 'local' | ||
68 | |||
69 | -- STATEMENT: begin 'expr' line=6 | ||
70 | prefixexp: <name> | ||
71 | str_checkname: 'foo' | ||
72 | singlevar(kind): 'VLOCAL' | ||
73 | expr_stat: assignment k='VLOCAL' | ||
74 | assignment: '=' -- RHS elements follows | ||
75 | explist1: begin | ||
76 | expr: | ||
77 | prefixexp: <name> | ||
78 | str_checkname: 'bar' | ||
79 | singlevar(kind): 'VLOCAL' | ||
80 | explist1: end | ||
81 | -- STATEMENT: end 'expr' | ||
82 | |||
83 | close_func | ||
84 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local foo | ||
3 | local function bar() | ||
4 | local function baz() | ||
5 | local foo, bar | ||
6 | foo = bar | ||
7 | foo = baz | ||
8 | end | ||
9 | foo = bar | ||
10 | foo = baz | ||
11 | end | ||
12 | foo = bar | ||
13 | foo = baz | ||
14 | -- END OF SOURCE -- | ||
15 | |||
16 | -- TOP: begin | ||
17 | open_func | ||
18 | |||
19 | chunk: | ||
20 | -- STATEMENT: begin 'local' line=1 | ||
21 | local_stat: local statement | ||
22 | localstat: begin | ||
23 | str_checkname: 'foo' | ||
24 | new_localvar: 'foo' | ||
25 | localstat: end | ||
26 | -- STATEMENT: end 'local' | ||
27 | |||
28 | -- STATEMENT: begin 'local' line=2 | ||
29 | local_stat: local function | ||
30 | localfunc: begin | ||
31 | str_checkname: 'bar' | ||
32 | new_localvar: 'bar' | ||
33 | localfunc: body | ||
34 | open_func | ||
35 | body: begin | ||
36 | body: parlist | ||
37 | parlist: begin | ||
38 | parlist: end | ||
39 | body: chunk | ||
40 | chunk: | ||
41 | -- STATEMENT: begin 'local' line=3 | ||
42 | local_stat: local function | ||
43 | localfunc: begin | ||
44 | str_checkname: 'baz' | ||
45 | new_localvar: 'baz' | ||
46 | localfunc: body | ||
47 | open_func | ||
48 | body: begin | ||
49 | body: parlist | ||
50 | parlist: begin | ||
51 | parlist: end | ||
52 | body: chunk | ||
53 | chunk: | ||
54 | -- STATEMENT: begin 'local' line=4 | ||
55 | local_stat: local statement | ||
56 | localstat: begin | ||
57 | str_checkname: 'foo' | ||
58 | new_localvar: 'foo' | ||
59 | str_checkname: 'bar' | ||
60 | new_localvar: 'bar' | ||
61 | localstat: end | ||
62 | -- STATEMENT: end 'local' | ||
63 | |||
64 | -- STATEMENT: begin 'expr' line=5 | ||
65 | prefixexp: <name> | ||
66 | str_checkname: 'foo' | ||
67 | singlevar(kind): 'VLOCAL' | ||
68 | expr_stat: assignment k='VLOCAL' | ||
69 | assignment: '=' -- RHS elements follows | ||
70 | explist1: begin | ||
71 | expr: | ||
72 | prefixexp: <name> | ||
73 | str_checkname: 'bar' | ||
74 | singlevar(kind): 'VLOCAL' | ||
75 | explist1: end | ||
76 | -- STATEMENT: end 'expr' | ||
77 | |||
78 | -- STATEMENT: begin 'expr' line=6 | ||
79 | prefixexp: <name> | ||
80 | str_checkname: 'foo' | ||
81 | singlevar(kind): 'VLOCAL' | ||
82 | expr_stat: assignment k='VLOCAL' | ||
83 | assignment: '=' -- RHS elements follows | ||
84 | explist1: begin | ||
85 | expr: | ||
86 | prefixexp: <name> | ||
87 | str_checkname: 'baz' | ||
88 | singlevar(kind): 'VUPVAL' | ||
89 | explist1: end | ||
90 | -- STATEMENT: end 'expr' | ||
91 | |||
92 | body: end | ||
93 | close_func | ||
94 | localfunc: end | ||
95 | -- STATEMENT: end 'local' | ||
96 | |||
97 | -- STATEMENT: begin 'expr' line=8 | ||
98 | prefixexp: <name> | ||
99 | str_checkname: 'foo' | ||
100 | singlevar(kind): 'VUPVAL' | ||
101 | expr_stat: assignment k='VUPVAL' | ||
102 | assignment: '=' -- RHS elements follows | ||
103 | explist1: begin | ||
104 | expr: | ||
105 | prefixexp: <name> | ||
106 | str_checkname: 'bar' | ||
107 | singlevar(kind): 'VUPVAL' | ||
108 | explist1: end | ||
109 | -- STATEMENT: end 'expr' | ||
110 | |||
111 | -- STATEMENT: begin 'expr' line=9 | ||
112 | prefixexp: <name> | ||
113 | str_checkname: 'foo' | ||
114 | singlevar(kind): 'VUPVAL' | ||
115 | expr_stat: assignment k='VUPVAL' | ||
116 | assignment: '=' -- RHS elements follows | ||
117 | explist1: begin | ||
118 | expr: | ||
119 | prefixexp: <name> | ||
120 | str_checkname: 'baz' | ||
121 | singlevar(kind): 'VLOCAL' | ||
122 | explist1: end | ||
123 | -- STATEMENT: end 'expr' | ||
124 | |||
125 | body: end | ||
126 | close_func | ||
127 | localfunc: end | ||
128 | -- STATEMENT: end 'local' | ||
129 | |||
130 | -- STATEMENT: begin 'expr' line=11 | ||
131 | prefixexp: <name> | ||
132 | str_checkname: 'foo' | ||
133 | singlevar(kind): 'VLOCAL' | ||
134 | expr_stat: assignment k='VLOCAL' | ||
135 | assignment: '=' -- RHS elements follows | ||
136 | explist1: begin | ||
137 | expr: | ||
138 | prefixexp: <name> | ||
139 | str_checkname: 'bar' | ||
140 | singlevar(kind): 'VLOCAL' | ||
141 | explist1: end | ||
142 | -- STATEMENT: end 'expr' | ||
143 | |||
144 | -- STATEMENT: begin 'expr' line=12 | ||
145 | prefixexp: <name> | ||
146 | str_checkname: 'foo' | ||
147 | singlevar(kind): 'VLOCAL' | ||
148 | expr_stat: assignment k='VLOCAL' | ||
149 | assignment: '=' -- RHS elements follows | ||
150 | explist1: begin | ||
151 | expr: | ||
152 | prefixexp: <name> | ||
153 | str_checkname: 'baz' | ||
154 | singlevar(kind): 'VGLOBAL' | ||
155 | explist1: end | ||
156 | -- STATEMENT: end 'expr' | ||
157 | |||
158 | close_func | ||
159 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo:bar() | ||
3 | print(self) | ||
4 | end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'function' line=1 | ||
12 | function_stat: begin | ||
13 | funcname: begin | ||
14 | str_checkname: 'foo' | ||
15 | singlevar(kind): 'VGLOBAL' | ||
16 | funcname: -- ':' field | ||
17 | field: operator=: | ||
18 | checkname: | ||
19 | str_checkname: 'bar' | ||
20 | codestring: "bar" | ||
21 | funcname: end | ||
22 | function_stat: body needself='true' | ||
23 | open_func | ||
24 | body: begin | ||
25 | new_localvar: 'self' | ||
26 | body: parlist | ||
27 | parlist: begin | ||
28 | parlist: end | ||
29 | body: chunk | ||
30 | chunk: | ||
31 | -- STATEMENT: begin 'expr' line=2 | ||
32 | prefixexp: <name> | ||
33 | str_checkname: 'print' | ||
34 | singlevar(kind): 'VGLOBAL' | ||
35 | primaryexp: ( funcargs | ||
36 | funcargs: begin '(' | ||
37 | explist1: begin | ||
38 | expr: | ||
39 | prefixexp: <name> | ||
40 | str_checkname: 'self' | ||
41 | singlevar(kind): 'VLOCAL' | ||
42 | explist1: end | ||
43 | funcargs: end -- expr is a VCALL | ||
44 | expr_stat: function call k='VCALL' | ||
45 | -- STATEMENT: end 'expr' | ||
46 | |||
47 | body: end | ||
48 | close_func | ||
49 | function_stat: end | ||
50 | -- STATEMENT: end 'function' | ||
51 | |||
52 | close_func | ||
53 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo(...) | ||
3 | print(arg) | ||
4 | end | ||
5 | -- END OF SOURCE -- | ||
6 | |||
7 | -- TOP: begin | ||
8 | open_func | ||
9 | |||
10 | chunk: | ||
11 | -- STATEMENT: begin 'function' line=1 | ||
12 | function_stat: begin | ||
13 | funcname: begin | ||
14 | str_checkname: 'foo' | ||
15 | singlevar(kind): 'VGLOBAL' | ||
16 | funcname: end | ||
17 | function_stat: body needself='false' | ||
18 | open_func | ||
19 | body: begin | ||
20 | body: parlist | ||
21 | parlist: begin | ||
22 | parlist: ... (dots) | ||
23 | parlist: end | ||
24 | body: chunk | ||
25 | chunk: | ||
26 | -- STATEMENT: begin 'expr' line=2 | ||
27 | prefixexp: <name> | ||
28 | str_checkname: 'print' | ||
29 | singlevar(kind): 'VGLOBAL' | ||
30 | primaryexp: ( funcargs | ||
31 | funcargs: begin '(' | ||
32 | explist1: begin | ||
33 | expr: | ||
34 | prefixexp: <name> | ||
35 | str_checkname: 'arg' | ||
36 | singlevar(kind): 'VGLOBAL' | ||
37 | explist1: end | ||
38 | funcargs: end -- expr is a VCALL | ||
39 | expr_stat: function call k='VCALL' | ||
40 | -- STATEMENT: end 'expr' | ||
41 | |||
42 | body: end | ||
43 | close_func | ||
44 | function_stat: end | ||
45 | -- STATEMENT: end 'function' | ||
46 | |||
47 | close_func | ||
48 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | local c,d | ||
3 | function foo(a,b,c) | ||
4 | print(a,c,d,e) | ||
5 | end | ||
6 | -- END OF SOURCE -- | ||
7 | |||
8 | -- TOP: begin | ||
9 | open_func | ||
10 | |||
11 | chunk: | ||
12 | -- STATEMENT: begin 'local' line=1 | ||
13 | local_stat: local statement | ||
14 | localstat: begin | ||
15 | str_checkname: 'c' | ||
16 | new_localvar: 'c' | ||
17 | str_checkname: 'd' | ||
18 | new_localvar: 'd' | ||
19 | localstat: end | ||
20 | -- STATEMENT: end 'local' | ||
21 | |||
22 | -- STATEMENT: begin 'function' line=2 | ||
23 | function_stat: begin | ||
24 | funcname: begin | ||
25 | str_checkname: 'foo' | ||
26 | singlevar(kind): 'VGLOBAL' | ||
27 | funcname: end | ||
28 | function_stat: body needself='false' | ||
29 | open_func | ||
30 | body: begin | ||
31 | body: parlist | ||
32 | parlist: begin | ||
33 | str_checkname: 'a' | ||
34 | new_localvar: 'a' | ||
35 | str_checkname: 'b' | ||
36 | new_localvar: 'b' | ||
37 | str_checkname: 'c' | ||
38 | new_localvar: 'c' | ||
39 | parlist: end | ||
40 | body: chunk | ||
41 | chunk: | ||
42 | -- STATEMENT: begin 'expr' line=3 | ||
43 | prefixexp: <name> | ||
44 | str_checkname: 'print' | ||
45 | singlevar(kind): 'VGLOBAL' | ||
46 | primaryexp: ( funcargs | ||
47 | funcargs: begin '(' | ||
48 | explist1: begin | ||
49 | expr: | ||
50 | prefixexp: <name> | ||
51 | str_checkname: 'a' | ||
52 | singlevar(kind): 'VLOCAL' | ||
53 | explist1: ',' -- continuation | ||
54 | expr: | ||
55 | prefixexp: <name> | ||
56 | str_checkname: 'c' | ||
57 | singlevar(kind): 'VLOCAL' | ||
58 | explist1: ',' -- continuation | ||
59 | expr: | ||
60 | prefixexp: <name> | ||
61 | str_checkname: 'd' | ||
62 | singlevar(kind): 'VUPVAL' | ||
63 | explist1: ',' -- continuation | ||
64 | expr: | ||
65 | prefixexp: <name> | ||
66 | str_checkname: 'e' | ||
67 | singlevar(kind): 'VGLOBAL' | ||
68 | explist1: end | ||
69 | funcargs: end -- expr is a VCALL | ||
70 | expr_stat: function call k='VCALL' | ||
71 | -- STATEMENT: end 'expr' | ||
72 | |||
73 | body: end | ||
74 | close_func | ||
75 | function_stat: end | ||
76 | -- STATEMENT: end 'function' | ||
77 | |||
78 | close_func | ||
79 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | function foo(a,b) | ||
3 | local bar = function(c,d) | ||
4 | print(a,b,c,d) | ||
5 | end | ||
6 | end | ||
7 | -- END OF SOURCE -- | ||
8 | |||
9 | -- TOP: begin | ||
10 | open_func | ||
11 | |||
12 | chunk: | ||
13 | -- STATEMENT: begin 'function' line=1 | ||
14 | function_stat: begin | ||
15 | funcname: begin | ||
16 | str_checkname: 'foo' | ||
17 | singlevar(kind): 'VGLOBAL' | ||
18 | funcname: end | ||
19 | function_stat: body needself='false' | ||
20 | open_func | ||
21 | body: begin | ||
22 | body: parlist | ||
23 | parlist: begin | ||
24 | str_checkname: 'a' | ||
25 | new_localvar: 'a' | ||
26 | str_checkname: 'b' | ||
27 | new_localvar: 'b' | ||
28 | parlist: end | ||
29 | body: chunk | ||
30 | chunk: | ||
31 | -- STATEMENT: begin 'local' line=2 | ||
32 | local_stat: local statement | ||
33 | localstat: begin | ||
34 | str_checkname: 'bar' | ||
35 | new_localvar: 'bar' | ||
36 | localstat: -- assignment | ||
37 | explist1: begin | ||
38 | expr: | ||
39 | simpleexp: function | ||
40 | open_func | ||
41 | body: begin | ||
42 | body: parlist | ||
43 | parlist: begin | ||
44 | str_checkname: 'c' | ||
45 | new_localvar: 'c' | ||
46 | str_checkname: 'd' | ||
47 | new_localvar: 'd' | ||
48 | parlist: end | ||
49 | body: chunk | ||
50 | chunk: | ||
51 | -- STATEMENT: begin 'expr' line=3 | ||
52 | prefixexp: <name> | ||
53 | str_checkname: 'print' | ||
54 | singlevar(kind): 'VGLOBAL' | ||
55 | primaryexp: ( funcargs | ||
56 | funcargs: begin '(' | ||
57 | explist1: begin | ||
58 | expr: | ||
59 | prefixexp: <name> | ||
60 | str_checkname: 'a' | ||
61 | singlevar(kind): 'VUPVAL' | ||
62 | explist1: ',' -- continuation | ||
63 | expr: | ||
64 | prefixexp: <name> | ||
65 | str_checkname: 'b' | ||
66 | singlevar(kind): 'VUPVAL' | ||
67 | explist1: ',' -- continuation | ||
68 | expr: | ||
69 | prefixexp: <name> | ||
70 | str_checkname: 'c' | ||
71 | singlevar(kind): 'VLOCAL' | ||
72 | explist1: ',' -- continuation | ||
73 | expr: | ||
74 | prefixexp: <name> | ||
75 | str_checkname: 'd' | ||
76 | singlevar(kind): 'VLOCAL' | ||
77 | explist1: end | ||
78 | funcargs: end -- expr is a VCALL | ||
79 | expr_stat: function call k='VCALL' | ||
80 | -- STATEMENT: end 'expr' | ||
81 | |||
82 | body: end | ||
83 | close_func | ||
84 | explist1: end | ||
85 | localstat: end | ||
86 | -- STATEMENT: end 'local' | ||
87 | |||
88 | body: end | ||
89 | close_func | ||
90 | function_stat: end | ||
91 | -- STATEMENT: end 'function' | ||
92 | |||
93 | close_func | ||
94 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | for i = 1,10 do | ||
3 | print(i) | ||
4 | end | ||
5 | for i = 1,10,-2 do | ||
6 | print(i) | ||
7 | end | ||
8 | -- END OF SOURCE -- | ||
9 | |||
10 | -- TOP: begin | ||
11 | open_func | ||
12 | |||
13 | chunk: | ||
14 | -- STATEMENT: begin 'for' line=1 | ||
15 | for_stat: begin | ||
16 | enterblock(isbreakable=true) | ||
17 | str_checkname: 'i' | ||
18 | for_stat: numerical loop | ||
19 | new_localvar: '(for index)' | ||
20 | new_localvar: '(for limit)' | ||
21 | new_localvar: '(for step)' | ||
22 | new_localvar: 'i' | ||
23 | fornum: begin | ||
24 | fornum: index start | ||
25 | exp1: begin | ||
26 | expr: | ||
27 | simpleexp: <number>=1 | ||
28 | exp1: end | ||
29 | fornum: index stop | ||
30 | exp1: begin | ||
31 | expr: | ||
32 | simpleexp: <number>=10 | ||
33 | exp1: end | ||
34 | fornum: body | ||
35 | enterblock(isbreakable=false) | ||
36 | block: begin | ||
37 | enterblock(isbreakable=false) | ||
38 | chunk: | ||
39 | -- STATEMENT: begin 'expr' line=2 | ||
40 | prefixexp: <name> | ||
41 | str_checkname: 'print' | ||
42 | singlevar(kind): 'VGLOBAL' | ||
43 | primaryexp: ( funcargs | ||
44 | funcargs: begin '(' | ||
45 | explist1: begin | ||
46 | expr: | ||
47 | prefixexp: <name> | ||
48 | str_checkname: 'i' | ||
49 | singlevar(kind): 'VLOCAL' | ||
50 | explist1: end | ||
51 | funcargs: end -- expr is a VCALL | ||
52 | expr_stat: function call k='VCALL' | ||
53 | -- STATEMENT: end 'expr' | ||
54 | |||
55 | leaveblock | ||
56 | block: end | ||
57 | leaveblock | ||
58 | fornum: end | ||
59 | leaveblock | ||
60 | for_stat: end | ||
61 | -- STATEMENT: end 'for' | ||
62 | |||
63 | -- STATEMENT: begin 'for' line=4 | ||
64 | for_stat: begin | ||
65 | enterblock(isbreakable=true) | ||
66 | str_checkname: 'i' | ||
67 | for_stat: numerical loop | ||
68 | new_localvar: '(for index)' | ||
69 | new_localvar: '(for limit)' | ||
70 | new_localvar: '(for step)' | ||
71 | new_localvar: 'i' | ||
72 | fornum: begin | ||
73 | fornum: index start | ||
74 | exp1: begin | ||
75 | expr: | ||
76 | simpleexp: <number>=1 | ||
77 | exp1: end | ||
78 | fornum: index stop | ||
79 | exp1: begin | ||
80 | expr: | ||
81 | simpleexp: <number>=10 | ||
82 | exp1: end | ||
83 | fornum: index step | ||
84 | exp1: begin | ||
85 | expr: | ||
86 | subexpr: uop='-' | ||
87 | simpleexp: <number>=2 | ||
88 | exp1: end | ||
89 | fornum: body | ||
90 | enterblock(isbreakable=false) | ||
91 | block: begin | ||
92 | enterblock(isbreakable=false) | ||
93 | chunk: | ||
94 | -- STATEMENT: begin 'expr' line=5 | ||
95 | prefixexp: <name> | ||
96 | str_checkname: 'print' | ||
97 | singlevar(kind): 'VGLOBAL' | ||
98 | primaryexp: ( funcargs | ||
99 | funcargs: begin '(' | ||
100 | explist1: begin | ||
101 | expr: | ||
102 | prefixexp: <name> | ||
103 | str_checkname: 'i' | ||
104 | singlevar(kind): 'VLOCAL' | ||
105 | explist1: end | ||
106 | funcargs: end -- expr is a VCALL | ||
107 | expr_stat: function call k='VCALL' | ||
108 | -- STATEMENT: end 'expr' | ||
109 | |||
110 | leaveblock | ||
111 | block: end | ||
112 | leaveblock | ||
113 | fornum: end | ||
114 | leaveblock | ||
115 | for_stat: end | ||
116 | -- STATEMENT: end 'for' | ||
117 | |||
118 | close_func | ||
119 | -- 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 @@ | |||
1 | -- START OF SOURCE -- | ||
2 | for foo in bar() do | ||
3 | print(foo) | ||
4 | end | ||
5 | for foo,bar,baz in spring() do | ||
6 | print(foo,bar,baz) | ||
7 | end | ||
8 | -- END OF SOURCE -- | ||
9 | |||
10 | -- TOP: begin | ||
11 | open_func | ||
12 | |||
13 | chunk: | ||
14 | -- STATEMENT: begin 'for' line=1 | ||
15 | for_stat: begin | ||
16 | enterblock(isbreakable=true) | ||
17 | str_checkname: 'foo' | ||
18 | for_stat: list-based loop | ||
19 | forlist: begin | ||
20 | new_localvar: '(for generator)' | ||
21 | new_localvar: '(for state)' | ||
22 | new_localvar: '(for control)' | ||
23 | new_localvar: 'foo' | ||
24 | forlist: explist1 | ||
25 | explist1: begin | ||
26 | expr: | ||
27 | prefixexp: <name> | ||
28 | str_checkname: 'bar' | ||
29 | singlevar(kind): 'VGLOBAL' | ||
30 | primaryexp: ( funcargs | ||
31 | funcargs: begin '(' | ||
32 | funcargs: end -- expr is a VCALL | ||
33 | explist1: end | ||
34 | forlist: body | ||
35 | enterblock(isbreakable=false) | ||
36 | block: begin | ||
37 | enterblock(isbreakable=false) | ||
38 | chunk: | ||
39 | -- STATEMENT: begin 'expr' line=2 | ||
40 | prefixexp: <name> | ||
41 | str_checkname: 'print' | ||
42 | singlevar(kind): 'VGLOBAL' | ||
43 | primaryexp: ( funcargs | ||
44 | funcargs: begin '(' | ||
45 | explist1: begin | ||
46 | expr: | ||
47 | prefixexp: <name> | ||
48 | str_checkname: 'foo' | ||
49 | singlevar(kind): 'VLOCAL' | ||
50 | explist1: end | ||
51 | funcargs: end -- expr is a VCALL | ||
52 | expr_stat: function call k='VCALL' | ||
53 | -- STATEMENT: end 'expr' | ||
54 | |||
55 | leaveblock | ||
56 | block: end | ||
57 | leaveblock | ||
58 | forlist: end | ||
59 | leaveblock | ||
60 | for_stat: end | ||
61 | -- STATEMENT: end 'for' | ||
62 | |||
63 | -- STATEMENT: begin 'for' line=4 | ||
64 | for_stat: begin | ||
65 | enterblock(isbreakable=true) | ||
66 | str_checkname: 'foo' | ||
67 | for_stat: list-based loop | ||
68 | forlist: begin | ||
69 | new_localvar: '(for generator)' | ||
70 | new_localvar: '(for state)' | ||
71 | new_localvar: '(for control)' | ||
72 | new_localvar: 'foo' | ||
73 | str_checkname: 'bar' | ||
74 | new_localvar: 'bar' | ||
75 | str_checkname: 'baz' | ||
76 | new_localvar: 'baz' | ||
77 | forlist: explist1 | ||
78 | explist1: begin | ||
79 | expr: | ||
80 | prefixexp: <name> | ||
81 | str_checkname: 'spring' | ||
82 | singlevar(kind): 'VGLOBAL' | ||
83 | primaryexp: ( funcargs | ||
84 | funcargs: begin '(' | ||
85 | funcargs: end -- expr is a VCALL | ||
86 | explist1: end | ||
87 | forlist: body | ||
88 | enterblock(isbreakable=false) | ||
89 | block: begin | ||
90 | enterblock(isbreakable=false) | ||
91 | chunk: | ||
92 | -- STATEMENT: begin 'expr' line=5 | ||
93 | prefixexp: <name> | ||
94 | str_checkname: 'print' | ||
95 | singlevar(kind): 'VGLOBAL' | ||
96 | primaryexp: ( funcargs | ||
97 | funcargs: begin '(' | ||
98 | explist1: begin | ||
99 | expr: | ||
100 | prefixexp: <name> | ||
101 | str_checkname: 'foo' | ||
102 | singlevar(kind): 'VLOCAL' | ||
103 | explist1: ',' -- continuation | ||
104 | expr: | ||
105 | prefixexp: <name> | ||
106 | str_checkname: 'bar' | ||
107 | singlevar(kind): 'VLOCAL' | ||
108 | explist1: ',' -- continuation | ||
109 | expr: | ||
110 | prefixexp: <name> | ||
111 | str_checkname: 'baz' | ||
112 | singlevar(kind): 'VLOCAL' | ||
113 | explist1: end | ||
114 | funcargs: end -- expr is a VCALL | ||
115 | expr_stat: function call k='VCALL' | ||
116 | -- STATEMENT: end 'expr' | ||
117 | |||
118 | leaveblock | ||
119 | block: end | ||
120 | leaveblock | ||
121 | forlist: end | ||
122 | leaveblock | ||
123 | for_stat: end | ||
124 | -- STATEMENT: end 'for' | ||
125 | |||
126 | close_func | ||
127 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_llex_mk2.lua | ||
4 | Test for llex_mk2.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- if BRIEF is not set to false, auto-test will silently succeed | ||
17 | ------------------------------------------------------------------------ | ||
18 | BRIEF = true -- if set to true, messages are less verbose | ||
19 | |||
20 | package.path = "../?.lua;"..package.path | ||
21 | local llex = require "llex_mk2" | ||
22 | |||
23 | ------------------------------------------------------------------------ | ||
24 | -- simple manual tests | ||
25 | ------------------------------------------------------------------------ | ||
26 | |||
27 | --[[ | ||
28 | local function dump(z) | ||
29 | llex.init(z) | ||
30 | while true do | ||
31 | local token, seminfo = llex.llex() | ||
32 | if token == "<name>" then | ||
33 | seminfo = " "..seminfo | ||
34 | elseif token == "<number>" then | ||
35 | seminfo = " "..seminfo | ||
36 | elseif token == "<string>" then | ||
37 | seminfo = " '"..seminfo.."'" | ||
38 | else | ||
39 | seminfo = "" | ||
40 | end | ||
41 | io.stdout:write(token..seminfo.."\n") | ||
42 | if token == "<eof>" then break end | ||
43 | end | ||
44 | end | ||
45 | |||
46 | dump("local c = luaZ:zgetc(z)") | ||
47 | os.exit() | ||
48 | --]] | ||
49 | |||
50 | ------------------------------------------------------------------------ | ||
51 | -- auto-testing of simple test cases to validate lexer behaviour: | ||
52 | -- * NOTE coverage has not been checked; not comprehensive | ||
53 | -- * only test cases with non-empty comments are processed | ||
54 | -- * if no result, then the output is displayed for manual decision | ||
55 | -- (output may be used to set expected success or fail text) | ||
56 | -- * cases expected to be successful may be a partial match | ||
57 | -- * cases expected to fail may also be a partial match | ||
58 | ------------------------------------------------------------------------ | ||
59 | |||
60 | -- [=====[ | ||
61 | local function auto_test() | ||
62 | local PASS, FAIL = true, false | ||
63 | ------------------------------------------------------------------ | ||
64 | -- table of test cases | ||
65 | ------------------------------------------------------------------ | ||
66 | local test_cases = | ||
67 | { | ||
68 | ------------------------------------------------------------- | ||
69 | --{ "comment", -- comment about the test | ||
70 | -- "chunk", -- chunk to test | ||
71 | -- PASS, -- PASS or FAIL outcome | ||
72 | -- "output", -- output to compare against | ||
73 | --}, | ||
74 | ------------------------------------------------------------- | ||
75 | { "empty chunk string, test EOS", | ||
76 | "", | ||
77 | PASS, "1 <eof>", | ||
78 | }, | ||
79 | ------------------------------------------------------------- | ||
80 | { "line number counting", | ||
81 | "\n\n\r\n", | ||
82 | PASS, "4 <eof>", | ||
83 | }, | ||
84 | ------------------------------------------------------------- | ||
85 | { "various whitespaces", | ||
86 | " \n\t\t\n \t \t \n\n", | ||
87 | PASS, "5 <eof>", | ||
88 | }, | ||
89 | ------------------------------------------------------------- | ||
90 | { "short comment ending in EOS", | ||
91 | "-- moo moo", | ||
92 | PASS, "1 <eof>", | ||
93 | }, | ||
94 | ------------------------------------------------------------- | ||
95 | { "short comment ending in newline", | ||
96 | "-- moo moo\n", | ||
97 | PASS, "2 <eof>", | ||
98 | }, | ||
99 | ------------------------------------------------------------- | ||
100 | { "several lines of short comments", | ||
101 | "--moo\n-- moo moo\n\n--\tmoo\n", | ||
102 | PASS, "5 <eof>", | ||
103 | }, | ||
104 | ------------------------------------------------------------- | ||
105 | { "basic block comment 1", | ||
106 | "--[[bovine]]", | ||
107 | PASS, "1 <eof>", | ||
108 | }, | ||
109 | ------------------------------------------------------------- | ||
110 | { "basic block comment 2", | ||
111 | "--[=[bovine]=]", | ||
112 | PASS, "1 <eof>", | ||
113 | }, | ||
114 | ------------------------------------------------------------- | ||
115 | { "basic block comment 3", | ||
116 | "--[====[-[[bovine]]-]====]", | ||
117 | PASS, "1 <eof>", | ||
118 | }, | ||
119 | ------------------------------------------------------------- | ||
120 | { "unterminated block comment 1", | ||
121 | "--[[bovine", | ||
122 | FAIL, ":1: unfinished long comment", | ||
123 | }, | ||
124 | ------------------------------------------------------------- | ||
125 | { "unterminated block comment 2", | ||
126 | "--[==[bovine", | ||
127 | FAIL, ":1: unfinished long comment", | ||
128 | }, | ||
129 | ------------------------------------------------------------- | ||
130 | { "unterminated block comment 3", | ||
131 | "--[[bovine]", | ||
132 | FAIL, ":1: unfinished long comment", | ||
133 | }, | ||
134 | ------------------------------------------------------------- | ||
135 | { "unterminated block comment 4", | ||
136 | "--[[bovine\nmoo moo\nwoof", | ||
137 | FAIL, ":3: unfinished long comment", | ||
138 | }, | ||
139 | ------------------------------------------------------------- | ||
140 | { "basic long string 1", | ||
141 | "\n[[bovine]]\n", | ||
142 | PASS, "2 <string> = bovine\n3 <eof>", | ||
143 | }, | ||
144 | ------------------------------------------------------------- | ||
145 | { "basic long string 2", | ||
146 | "\n[=[bovine]=]\n", | ||
147 | PASS, "2 <string> = bovine\n3 <eof>", | ||
148 | }, | ||
149 | ------------------------------------------------------------- | ||
150 | { "first newline consumed in long string", | ||
151 | "[[\nmoo]]", | ||
152 | PASS, "2 <string> = moo\n2 <eof>", | ||
153 | }, | ||
154 | ------------------------------------------------------------- | ||
155 | { "multiline long string 1", | ||
156 | "[[moo\nmoo moo\n]]", | ||
157 | PASS, "3 <string> = moo\nmoo moo\n\n3 <eof>", | ||
158 | }, | ||
159 | ------------------------------------------------------------- | ||
160 | { "multiline long string 2", | ||
161 | "[===[moo\n[=[moo moo]=]\n]===]", | ||
162 | PASS, "3 <string> = moo\n[=[moo moo]=]\n\n3 <eof>", | ||
163 | }, | ||
164 | ------------------------------------------------------------- | ||
165 | { "unterminated long string 1", | ||
166 | "\n[[\nbovine", | ||
167 | FAIL, ":3: unfinished long string", | ||
168 | }, | ||
169 | ------------------------------------------------------------- | ||
170 | { "unterminated long string 2", | ||
171 | "[[bovine]", | ||
172 | FAIL, ":1: unfinished long string", | ||
173 | }, | ||
174 | ------------------------------------------------------------- | ||
175 | { "unterminated long string 2", | ||
176 | "[==[bovine]==", | ||
177 | FAIL, ":1: unfinished long string", | ||
178 | }, | ||
179 | ------------------------------------------------------------- | ||
180 | { "complex long string 1", | ||
181 | "[=[moo[[moo]]moo]=]", | ||
182 | PASS, "moo[[moo]]moo", | ||
183 | }, | ||
184 | ------------------------------------------------------------- | ||
185 | { "complex long string 2", | ||
186 | "[=[moo[[moo[[[[]]]]moo]]moo]=]", | ||
187 | PASS, "moo[[moo[[[[]]]]moo]]moo", | ||
188 | }, | ||
189 | ------------------------------------------------------------- | ||
190 | { "complex long string 3", | ||
191 | "[=[[[[[]]]][[[[]]]]]=]", | ||
192 | PASS, "[[[[]]]][[[[]]]]", | ||
193 | }, | ||
194 | ------------------------------------------------------------- | ||
195 | -- NOTE: this native lexer does not support compatible long | ||
196 | -- strings (LUA_COMPAT_LSTR) | ||
197 | ------------------------------------------------------------- | ||
198 | --{ "deprecated long string 1", | ||
199 | -- "[[moo[[moo]]moo]]", | ||
200 | -- FAIL, ":1: nesting of [[...]] is deprecated near '['", | ||
201 | --}, | ||
202 | --------------------------------------------------------------- | ||
203 | --{ "deprecated long string 2", | ||
204 | -- "[[[[ \n", | ||
205 | -- FAIL, ":1: nesting of [[...]] is deprecated near '['", | ||
206 | --}, | ||
207 | --------------------------------------------------------------- | ||
208 | --{ "deprecated long string 3", | ||
209 | -- "[[moo[[moo[[[[]]]]moo]]moo]]", | ||
210 | -- FAIL, ":1: nesting of [[...]] is deprecated near '['", | ||
211 | --}, | ||
212 | --------------------------------------------------------------- | ||
213 | --{ "deprecated long string 4", | ||
214 | -- "[[[[[[]]]][[[[]]]]]]", | ||
215 | -- FAIL, ":1: nesting of [[...]] is deprecated near '['", | ||
216 | --}, | ||
217 | ------------------------------------------------------------- | ||
218 | { "brackets in long strings 1", | ||
219 | "[[moo[moo]]", | ||
220 | PASS, "moo[moo", | ||
221 | }, | ||
222 | ------------------------------------------------------------- | ||
223 | { "brackets in long strings 2", | ||
224 | "[=[moo[[moo]moo]]moo]=]", | ||
225 | PASS, "moo[[moo]moo]]moo", | ||
226 | }, | ||
227 | ------------------------------------------------------------- | ||
228 | { "unprocessed escapes in long strings", | ||
229 | [[ [=[\a\b\f\n\r\t\v\123]=] ]], | ||
230 | PASS, [[\a\b\f\n\r\t\v\123]], | ||
231 | }, | ||
232 | ------------------------------------------------------------- | ||
233 | { "unbalanced long string", | ||
234 | "[[moo]]moo]]", | ||
235 | PASS, "1 <string> = moo\n1 <name> = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 <eof>", | ||
236 | }, | ||
237 | ------------------------------------------------------------- | ||
238 | { "keywords 1", | ||
239 | "and break do else", | ||
240 | PASS, "1 and\n1 break\n1 do\n1 else\n1 <eof>", | ||
241 | }, | ||
242 | ------------------------------------------------------------- | ||
243 | { "keywords 2", | ||
244 | "elseif end false for", | ||
245 | PASS, "1 elseif\n1 end\n1 false\n1 for\n1 <eof>", | ||
246 | }, | ||
247 | ------------------------------------------------------------- | ||
248 | { "keywords 3", | ||
249 | "function if in local nil", | ||
250 | PASS, "1 function\n1 if\n1 in\n1 local\n1 nil\n1 <eof>", | ||
251 | }, | ||
252 | ------------------------------------------------------------- | ||
253 | { "keywords 4", | ||
254 | "not or repeat return", | ||
255 | PASS, "1 not\n1 or\n1 repeat\n1 return\n1 <eof>", | ||
256 | }, | ||
257 | ------------------------------------------------------------- | ||
258 | { "keywords 5", | ||
259 | "then true until while", | ||
260 | PASS, "1 then\n1 true\n1 until\n1 while\n1 <eof>", | ||
261 | }, | ||
262 | ------------------------------------------------------------- | ||
263 | { "concat and dots", | ||
264 | ".. ...", | ||
265 | PASS, "1 ..\n1 ...\n1 <eof>", | ||
266 | }, | ||
267 | ------------------------------------------------------------- | ||
268 | -- NOTE: in Lua 5.1.x, shbang handling is no longer performed | ||
269 | -- in the lexer; it is now done in lauxlib.c (luaL_loadfile) | ||
270 | -- so the following cannot be performed by the lexer... | ||
271 | ------------------------------------------------------------- | ||
272 | --{ "shbang handling 1", | ||
273 | -- "#blahblah", | ||
274 | -- PASS, "1 <eof>", | ||
275 | --}, | ||
276 | ------------------------------------------------------------- | ||
277 | --{ "shbang handling 2", | ||
278 | -- "#blahblah\nmoo moo\n", | ||
279 | -- PASS, "2 <name> = moo\n2 <name> = moo\n3 <eof>", | ||
280 | --}, | ||
281 | ------------------------------------------------------------- | ||
282 | { "empty string", | ||
283 | [['']], | ||
284 | PASS, "1 <string> = \n1 <eof>", | ||
285 | }, | ||
286 | ------------------------------------------------------------- | ||
287 | { "single-quoted string", | ||
288 | [['bovine']], | ||
289 | PASS, "1 <string> = bovine\n1 <eof>", | ||
290 | }, | ||
291 | ------------------------------------------------------------- | ||
292 | { "double-quoted string", | ||
293 | [["bovine"]], | ||
294 | PASS, "1 <string> = bovine\n1 <eof>", | ||
295 | }, | ||
296 | ------------------------------------------------------------- | ||
297 | { "unterminated string 1", | ||
298 | [['moo ]], | ||
299 | FAIL, ":1: unfinished string", | ||
300 | }, | ||
301 | ------------------------------------------------------------- | ||
302 | { "unterminated string 2", | ||
303 | [["moo \n]], | ||
304 | FAIL, ":1: unfinished string", | ||
305 | }, | ||
306 | ------------------------------------------------------------- | ||
307 | { "escaped newline in string, line number counted", | ||
308 | "\"moo\\\nmoo\\\nmoo\"", | ||
309 | PASS, "3 <string> = moo\nmoo\nmoo\n3 <eof>", | ||
310 | }, | ||
311 | ------------------------------------------------------------- | ||
312 | { "escaped characters in string 1", | ||
313 | [["moo\amoo"]], | ||
314 | PASS, "1 <string> = moo\amoo", | ||
315 | }, | ||
316 | ------------------------------------------------------------- | ||
317 | { "escaped characters in string 2", | ||
318 | [["moo\bmoo"]], | ||
319 | PASS, "1 <string> = moo\bmoo", | ||
320 | }, | ||
321 | ------------------------------------------------------------- | ||
322 | { "escaped characters in string 3", | ||
323 | [["moo\f\n\r\t\vmoo"]], | ||
324 | PASS, "1 <string> = moo\f\n\r\t\vmoo", | ||
325 | }, | ||
326 | ------------------------------------------------------------- | ||
327 | { "escaped characters in string 4", | ||
328 | [["\\ \" \' \? \[ \]"]], | ||
329 | PASS, "1 <string> = \\ \" \' \? \[ \]", | ||
330 | }, | ||
331 | ------------------------------------------------------------- | ||
332 | { "escaped characters in string 5", | ||
333 | [["\z \k \: \;"]], | ||
334 | PASS, "1 <string> = z k : ;", | ||
335 | }, | ||
336 | ------------------------------------------------------------- | ||
337 | { "escaped characters in string 6", | ||
338 | [["\8 \65 \160 \180K \097097"]], | ||
339 | PASS, "1 <string> = \8 \65 \160 \180K \097097\n", | ||
340 | }, | ||
341 | ------------------------------------------------------------- | ||
342 | { "escaped characters in string 7", | ||
343 | [["\666"]], | ||
344 | FAIL, ":1: escape sequence too large", | ||
345 | }, | ||
346 | ------------------------------------------------------------- | ||
347 | { "simple numbers", | ||
348 | "123 123+", | ||
349 | PASS, "1 <number> = 123\n1 <number> = 123\n1 CHAR = '+'\n1 <eof>", | ||
350 | }, | ||
351 | ------------------------------------------------------------- | ||
352 | { "longer numbers", | ||
353 | "1234567890 12345678901234567890", | ||
354 | PASS, "1 <number> = 1234567890\n1 <number> = 1.2345678901235e+19\n", | ||
355 | }, | ||
356 | ------------------------------------------------------------- | ||
357 | { "fractional numbers", | ||
358 | ".123 .12345678901234567890", | ||
359 | PASS, "1 <number> = 0.123\n1 <number> = 0.12345678901235\n", | ||
360 | }, | ||
361 | ------------------------------------------------------------- | ||
362 | { "more numbers with decimal points", | ||
363 | "12345.67890", | ||
364 | PASS, "1 <number> = 12345.6789\n", | ||
365 | }, | ||
366 | ------------------------------------------------------------- | ||
367 | { "malformed number with decimal points", | ||
368 | "1.1.", | ||
369 | FAIL, ":1: malformed number", | ||
370 | }, | ||
371 | ------------------------------------------------------------- | ||
372 | { "double decimal points", | ||
373 | ".1.1", | ||
374 | FAIL, ":1: malformed number", | ||
375 | }, | ||
376 | ------------------------------------------------------------- | ||
377 | { "double dots within numbers", | ||
378 | "1..1", | ||
379 | FAIL, ":1: malformed number", | ||
380 | }, | ||
381 | ------------------------------------------------------------- | ||
382 | { "incomplete exponential numbers", | ||
383 | "123e", | ||
384 | FAIL, ":1: malformed number", | ||
385 | }, | ||
386 | ------------------------------------------------------------- | ||
387 | { "exponential numbers 1", | ||
388 | "1234e5 1234e5.", | ||
389 | PASS, "1 <number> = 123400000\n1 <number> = 123400000\n1 CHAR = '.'", | ||
390 | }, | ||
391 | ------------------------------------------------------------- | ||
392 | { "exponential numbers 2", | ||
393 | "1234e56 1.23e123", | ||
394 | PASS, "1 <number> = 1.234e+59\n1 <number> = 1.23e+123\n", | ||
395 | }, | ||
396 | ------------------------------------------------------------- | ||
397 | { "exponential numbers 3", | ||
398 | "12.34e+", | ||
399 | FAIL, ":1: malformed number", | ||
400 | }, | ||
401 | ------------------------------------------------------------- | ||
402 | { "exponential numbers 4", | ||
403 | "12.34e+5 123.4e-5 1234.E+5", | ||
404 | PASS, "1 <number> = 1234000\n1 <number> = 0.001234\n1 <number> = 123400000\n", | ||
405 | }, | ||
406 | ------------------------------------------------------------- | ||
407 | { "hexadecimal numbers", | ||
408 | "0x00FF 0X1234 0xDEADBEEF", | ||
409 | PASS, "1 <number> = 255\n1 <number> = 4660\n1 <number> = 3735928559\n", | ||
410 | }, | ||
411 | ------------------------------------------------------------- | ||
412 | { "invalid hexadecimal numbers 1", | ||
413 | "0xFOO", | ||
414 | FAIL, ":1: malformed number", | ||
415 | }, | ||
416 | ------------------------------------------------------------- | ||
417 | { "invalid hexadecimal numbers 2", | ||
418 | "0.BAR", | ||
419 | FAIL, ":1: malformed number", | ||
420 | }, | ||
421 | ------------------------------------------------------------- | ||
422 | { "invalid hexadecimal numbers 3", | ||
423 | "0BAZ", | ||
424 | FAIL, ":1: malformed number", | ||
425 | }, | ||
426 | ------------------------------------------------------------- | ||
427 | { "single character symbols 1", | ||
428 | "= > < ~ #", | ||
429 | PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n1 CHAR = '#'\n", | ||
430 | }, | ||
431 | ------------------------------------------------------------- | ||
432 | { "double character symbols", | ||
433 | "== >= <= ~=", | ||
434 | PASS, "1 ==\n1 >=\n1 <=\n1 ~=\n", | ||
435 | }, | ||
436 | ------------------------------------------------------------- | ||
437 | { "simple identifiers", | ||
438 | "abc ABC", | ||
439 | PASS, "1 <name> = abc\n1 <name> = ABC\n1 <eof>", | ||
440 | }, | ||
441 | ------------------------------------------------------------- | ||
442 | { "more identifiers", | ||
443 | "_abc _ABC", | ||
444 | PASS, "1 <name> = _abc\n1 <name> = _ABC\n1 <eof>", | ||
445 | }, | ||
446 | ------------------------------------------------------------- | ||
447 | { "still more identifiers", | ||
448 | "_aB_ _123", | ||
449 | PASS, "1 <name> = _aB_\n1 <name> = _123\n1 <eof>", | ||
450 | }, | ||
451 | ------------------------------------------------------------- | ||
452 | -- NOTE: in Lua 5.1.x, this test is no longer performed | ||
453 | ------------------------------------------------------------- | ||
454 | --{ "invalid control character", | ||
455 | -- "\4", | ||
456 | -- FAIL, ":1: invalid control char near 'char(4)'", | ||
457 | --}, | ||
458 | ------------------------------------------------------------- | ||
459 | { "single character symbols 2", | ||
460 | "` ! @ $ %", | ||
461 | PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", | ||
462 | }, | ||
463 | ------------------------------------------------------------- | ||
464 | { "single character symbols 3", | ||
465 | "^ & * ( )", | ||
466 | PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", | ||
467 | }, | ||
468 | ------------------------------------------------------------- | ||
469 | { "single character symbols 4", | ||
470 | "_ - + \\ |", | ||
471 | PASS, "1 <name> = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", | ||
472 | }, | ||
473 | ------------------------------------------------------------- | ||
474 | { "single character symbols 5", | ||
475 | "{ } [ ] :", | ||
476 | PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", | ||
477 | }, | ||
478 | ------------------------------------------------------------- | ||
479 | { "single character symbols 6", | ||
480 | "; , . / ?", | ||
481 | PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", | ||
482 | }, | ||
483 | ------------------------------------------------------------- | ||
484 | } | ||
485 | ------------------------------------------------------------------ | ||
486 | -- perform a test case | ||
487 | ------------------------------------------------------------------ | ||
488 | function do_test_case(count, test_case) | ||
489 | if comment == "" then return end -- skip empty entries | ||
490 | local comment, chunk, outcome, matcher = unpack(test_case) | ||
491 | local result = PASS | ||
492 | local output = "" | ||
493 | -- initialize lexer | ||
494 | llex.init(chunk, "=test") | ||
495 | -- lexer test loop | ||
496 | repeat | ||
497 | -- protected call | ||
498 | local status, token, seminfo = pcall(llex.llex) | ||
499 | output = output..llex.ln.." " | ||
500 | if status then | ||
501 | -- successful call | ||
502 | if #token > 1 then | ||
503 | if token == "<name>" | ||
504 | or token == "<number>" | ||
505 | or token == "<string>" then | ||
506 | token = token.." = "..seminfo | ||
507 | end | ||
508 | elseif string.byte(token) >= 32 then -- displayable chars | ||
509 | token = "CHAR = '"..token.."'" | ||
510 | else -- control characters | ||
511 | token = "CHAR = (".. string.byte(token)..")" | ||
512 | end | ||
513 | output = output..token.."\n" | ||
514 | else | ||
515 | -- failed call | ||
516 | output = output..token -- token is the error message | ||
517 | result = FAIL | ||
518 | break | ||
519 | end | ||
520 | until token == "<eof>" | ||
521 | -- decision making and reporting | ||
522 | local head = "Test "..count..": "..comment | ||
523 | if matcher == "" then | ||
524 | -- nothing to check against, display for manual check | ||
525 | print(head.."\nMANUAL please check manually".. | ||
526 | "\n--chunk---------------------------------\n"..chunk.. | ||
527 | "\n--actual--------------------------------\n"..output.. | ||
528 | "\n\n") | ||
529 | return | ||
530 | else | ||
531 | if outcome == PASS then | ||
532 | -- success expected, may be a partial match | ||
533 | if string.find(output, matcher, 1, 1) and result == PASS then | ||
534 | if not BRIEF then print(head.."\nOK expected success\n") end | ||
535 | return | ||
536 | end | ||
537 | else | ||
538 | -- failure expected, may be a partial match | ||
539 | if string.find(output, matcher, 1, 1) and result == FAIL then | ||
540 | if not BRIEF then print(head.."\nOK expected failure\n") end | ||
541 | return | ||
542 | end | ||
543 | end | ||
544 | -- failed because of unmatched string or boolean result | ||
545 | local function passfail(status) | ||
546 | if status == PASS then return "PASS" else return "FAIL" end | ||
547 | end | ||
548 | print(head.." *FAILED*".. | ||
549 | "\noutcome="..passfail(outcome).. | ||
550 | "\nactual= "..passfail(result).. | ||
551 | "\n--chunk---------------------------------\n"..chunk.. | ||
552 | "\n--expected------------------------------\n"..matcher.. | ||
553 | "\n--actual--------------------------------\n"..output.. | ||
554 | "\n\n") | ||
555 | end | ||
556 | end | ||
557 | ------------------------------------------------------------------ | ||
558 | -- perform auto testing | ||
559 | ------------------------------------------------------------------ | ||
560 | for i,test_case in ipairs(test_cases) do | ||
561 | do_test_case(i, test_case) | ||
562 | end | ||
563 | end | ||
564 | |||
565 | auto_test() | ||
566 | --]=====] | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser_mk2.lua | ||
4 | Test for lparser_mk2.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- test the whole kaboodle | ||
17 | ------------------------------------------------------------------------ | ||
18 | |||
19 | package.path = "../?.lua;"..package.path | ||
20 | local llex = require "llex_mk2" | ||
21 | local lparser = require "lparser_mk2" | ||
22 | |||
23 | ------------------------------------------------------------------------ | ||
24 | -- dump contents of log table | ||
25 | ------------------------------------------------------------------------ | ||
26 | |||
27 | local function dump_log(fs) | ||
28 | local log = fs.log | ||
29 | for i = 1, #log do | ||
30 | print(log[i]) | ||
31 | end | ||
32 | end | ||
33 | |||
34 | ------------------------------------------------------------------------ | ||
35 | -- try 1 | ||
36 | ------------------------------------------------------------------------ | ||
37 | |||
38 | --[=[ | ||
39 | llex.init("local a = 1", "=string") | ||
40 | lparser.init(llex) | ||
41 | -- nothing is returned, so hope there is an error if problem occurs | ||
42 | local fs = lparser.parser() | ||
43 | dump_log(fs) | ||
44 | --]=] | ||
45 | |||
46 | ------------------------------------------------------------------------ | ||
47 | -- try 2 | ||
48 | ------------------------------------------------------------------------ | ||
49 | |||
50 | -- a slightly larger sample | ||
51 | --[=[ | ||
52 | llex.init([[ | ||
53 | local a = 47 | ||
54 | local b = "hello, world!" | ||
55 | print(a, b) | ||
56 | ]], "@sample.lua") | ||
57 | lparser.init(llex) | ||
58 | -- nothing is returned, so hope there is an error if problem occurs | ||
59 | local fs = lparser.parser() | ||
60 | dump_log(fs) | ||
61 | --]=] | ||
62 | |||
63 | ------------------------------------------------------------------------ | ||
64 | -- automatic dumper of output log data | ||
65 | ------------------------------------------------------------------------ | ||
66 | |||
67 | local test_case = { | ||
68 | -- 1 attempts to exercise most parts, extent of coverage not known | ||
69 | [[ | ||
70 | ]], | ||
71 | -- 2 | ||
72 | [[ | ||
73 | -- foobar | ||
74 | ]], | ||
75 | -- 3 | ||
76 | [[ | ||
77 | do | ||
78 | end | ||
79 | ]], | ||
80 | -- 4 | ||
81 | [[ | ||
82 | do end | ||
83 | do end | ||
84 | ]], | ||
85 | -- 5 | ||
86 | [[ | ||
87 | foo() | ||
88 | foo{} | ||
89 | foo"" | ||
90 | foo:bar() | ||
91 | foo=false | ||
92 | foo.bar=true | ||
93 | foo[true]=nil | ||
94 | foo,bar=1,"a" | ||
95 | ]], | ||
96 | -- 6 | ||
97 | [[ | ||
98 | foo=true | ||
99 | foo=false | ||
100 | foo=nil | ||
101 | foo=1.23e45 | ||
102 | foo=-1 | ||
103 | foo=(0) | ||
104 | foo=1+2 | ||
105 | foo=1+2*3-4/5 | ||
106 | ]], | ||
107 | -- 7 | ||
108 | [[ | ||
109 | if foo then foo=1 end | ||
110 | if foo then foo=1 else foo=0 end | ||
111 | if foo then foo=1 elseif not foo then foo=0 end | ||
112 | ]], | ||
113 | -- 8 | ||
114 | [[ | ||
115 | do return end | ||
116 | do return 123 end | ||
117 | do return "foo","bar" end | ||
118 | ]], | ||
119 | -- 9 | ||
120 | [[ | ||
121 | while true do foo=not foo end | ||
122 | while foo~=42 do foo=foo-1 end | ||
123 | while true do break end | ||
124 | ]], | ||
125 | -- 10 | ||
126 | [[ | ||
127 | repeat foo=foo.."bar" until false | ||
128 | repeat foo=foo/2 until foo<1 | ||
129 | repeat break until false | ||
130 | ]], | ||
131 | -- 11 | ||
132 | [[ | ||
133 | for i=1,10 do foo=i end | ||
134 | for i=1,10,2 do break end | ||
135 | for i in foo do bar=0 end | ||
136 | for i,j in foo,bar do baz=0 end | ||
137 | ]], | ||
138 | -- 12 | ||
139 | [[ | ||
140 | local foo | ||
141 | local foo,bar,baz | ||
142 | local foo,bar="foo","bar" | ||
143 | ]], | ||
144 | -- 13 | ||
145 | [[ | ||
146 | local function foo() return end | ||
147 | local function foo(a) return end | ||
148 | local function foo(x,y,z) return end | ||
149 | local function foo(x,...) return end | ||
150 | ]], | ||
151 | -- 14 | ||
152 | [[ | ||
153 | function foo() return end | ||
154 | function foo(a) return end | ||
155 | function foo(x,y,z) return end | ||
156 | function foo(x,...) return end | ||
157 | ]], | ||
158 | -- 15 | ||
159 | [[ | ||
160 | function foo.bar(p) return end | ||
161 | function foo.bar.baz(p) return end | ||
162 | function foo:bar(p) return end | ||
163 | function foo.bar.baz(p) return end | ||
164 | ]], | ||
165 | -- 16 | ||
166 | [[ | ||
167 | foo = function() return end | ||
168 | foo = function(x,y) return end | ||
169 | foo = function(...) return end | ||
170 | foo = function(...) local bar = ... return end | ||
171 | ]], | ||
172 | -- 17 | ||
173 | [[ | ||
174 | foo = {} | ||
175 | foo = { 1,2,3; "foo"; } | ||
176 | foo = { bar=77, baz=88, } | ||
177 | foo = { ["bar"]=77, ["baz"]=88, } | ||
178 | ]], | ||
179 | -- 18 simple tests for variable management follows | ||
180 | [[ | ||
181 | print(a) | ||
182 | ]], | ||
183 | -- 19 | ||
184 | [[ | ||
185 | local a | ||
186 | print(a) | ||
187 | ]], | ||
188 | -- 20 | ||
189 | [[ | ||
190 | do | ||
191 | local a | ||
192 | print(a) | ||
193 | end | ||
194 | print(a) | ||
195 | ]], | ||
196 | -- 21 | ||
197 | [[ | ||
198 | local a,b,c | ||
199 | do | ||
200 | local b | ||
201 | print(b) | ||
202 | end | ||
203 | print(b) | ||
204 | ]], | ||
205 | -- 22 | ||
206 | [[ | ||
207 | local function foo() end | ||
208 | bar = foo | ||
209 | ]], | ||
210 | -- 23 | ||
211 | [[ | ||
212 | do | ||
213 | local function foo() end | ||
214 | bar = foo | ||
215 | end | ||
216 | baz = foo | ||
217 | ]], | ||
218 | -- 24 | ||
219 | [[ | ||
220 | local foo | ||
221 | local function bar() | ||
222 | baz = nil | ||
223 | foo = bar() | ||
224 | end | ||
225 | foo = bar | ||
226 | ]], | ||
227 | -- 25 | ||
228 | [[ | ||
229 | local foo | ||
230 | local function bar() | ||
231 | local function baz() | ||
232 | local foo, bar | ||
233 | foo = bar | ||
234 | foo = baz | ||
235 | end | ||
236 | foo = bar | ||
237 | foo = baz | ||
238 | end | ||
239 | foo = bar | ||
240 | foo = baz | ||
241 | ]], | ||
242 | -- 26 | ||
243 | [[ | ||
244 | function foo:bar() | ||
245 | print(self) | ||
246 | end | ||
247 | ]], | ||
248 | -- 27 | ||
249 | [[ | ||
250 | function foo(...) | ||
251 | print(arg) | ||
252 | end | ||
253 | ]], | ||
254 | -- 28 | ||
255 | [[ | ||
256 | local c,d | ||
257 | function foo(a,b,c) | ||
258 | print(a,c,d,e) | ||
259 | end | ||
260 | ]], | ||
261 | -- 29 | ||
262 | [[ | ||
263 | function foo(a,b) | ||
264 | local bar = function(c,d) | ||
265 | print(a,b,c,d) | ||
266 | end | ||
267 | end | ||
268 | ]], | ||
269 | -- 30 | ||
270 | [[ | ||
271 | for i = 1,10 do | ||
272 | print(i) | ||
273 | end | ||
274 | for i = 1,10,-2 do | ||
275 | print(i) | ||
276 | end | ||
277 | ]], | ||
278 | -- 31 | ||
279 | [[ | ||
280 | for foo in bar() do | ||
281 | print(foo) | ||
282 | end | ||
283 | for foo,bar,baz in spring() do | ||
284 | print(foo,bar,baz) | ||
285 | end | ||
286 | ]], | ||
287 | } | ||
288 | |||
289 | -- helps to skip old stuff during development of snippets | ||
290 | local do_beg, do_end = 1, #test_case | ||
291 | |||
292 | -- loop for all example snippets | ||
293 | for i = do_beg, do_end do | ||
294 | local fname = "parser_log/sample_"..string.format("%02d", i)..".lua" | ||
295 | local src = test_case[i] | ||
296 | local OUTF = io.open(fname, "wb") | ||
297 | if not OUTF then error("failed to write to file '"..fname.."'") end | ||
298 | -- write out actual source for comparison | ||
299 | OUTF:write( | ||
300 | "-- START OF SOURCE --\n".. | ||
301 | src.. | ||
302 | "-- END OF SOURCE --\n".. | ||
303 | "\n" | ||
304 | ) | ||
305 | -- attempt to parse | ||
306 | llex.init(src, "=string") | ||
307 | lparser.init(llex) | ||
308 | local fs = lparser.parser() | ||
309 | -- grab logged messages and write | ||
310 | local log = fs.log | ||
311 | local indent = 0 | ||
312 | for i = 1, #log do | ||
313 | local ln = log[i] | ||
314 | -- handle indentation | ||
315 | local tag = string.sub(ln, 1, 2) | ||
316 | if tag == ">>" or tag == "<<" then | ||
317 | ln = string.sub(ln, 4) | ||
318 | end | ||
319 | if tag == ">>" then | ||
320 | indent = indent + 1 | ||
321 | end | ||
322 | OUTF:write(string.rep(" ", indent)..ln.."\n") | ||
323 | if tag == "<<" then | ||
324 | indent = indent - 1 | ||
325 | end | ||
326 | end | ||
327 | -- we're done | ||
328 | OUTF:close() | ||
329 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser_mk2_2.lua | ||
4 | Test for lparser_mk2.lua, using the test case file | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006-2008 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * unlike the equivalent in the orig-5.1.3/ directory, this version | ||
18 | -- tests only parsing, lparser_mk3 cannot generate binary chunks | ||
19 | -- * the test cases are in the test_lua directory (test_parser-5.1.lua) | ||
20 | ----------------------------------------------------------------------]] | ||
21 | |||
22 | -- * true if you want an output of all failure cases in native Lua, | ||
23 | -- for checking whether test cases fail where you intend them to | ||
24 | local DEBUG_FAILS = false | ||
25 | |||
26 | ------------------------------------------------------------------------ | ||
27 | -- test the whole kaboodle | ||
28 | ------------------------------------------------------------------------ | ||
29 | |||
30 | package.path = "../?.lua;"..package.path | ||
31 | local llex = require "llex_mk2" | ||
32 | local lparser = require "lparser_mk2" | ||
33 | |||
34 | ------------------------------------------------------------------------ | ||
35 | -- load test cases | ||
36 | ------------------------------------------------------------------------ | ||
37 | |||
38 | dofile("../../test_lua/test_parser-5.1.lua") | ||
39 | |||
40 | local test, expect, heading = {}, {}, {} | ||
41 | local total, total_pass, total_fail = 0, 0, 0 | ||
42 | |||
43 | for ln in string.gfind(tests_source, "([^\n]*)\n") do | ||
44 | if string.find(ln, "^%s*%-%-") then | ||
45 | -- comment, ignore | ||
46 | else | ||
47 | local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") | ||
48 | if m then | ||
49 | heading[total + 1] = head -- informational heading | ||
50 | else | ||
51 | total = total + 1 | ||
52 | local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") | ||
53 | if n then -- FAIL test case | ||
54 | ln = string.sub(ln, 1, n - 1) -- remove comment | ||
55 | expect[total] = "FAIL" | ||
56 | total_fail = total_fail + 1 | ||
57 | else -- PASS test case | ||
58 | expect[total] = "PASS" | ||
59 | total_pass = total_pass + 1 | ||
60 | end--n | ||
61 | test[total] = ln | ||
62 | end--m | ||
63 | end--ln | ||
64 | end--for | ||
65 | |||
66 | print("Tests loaded: "..total.." (total), " | ||
67 | ..total_pass.." (passes), " | ||
68 | ..total_fail.." (fails)") | ||
69 | |||
70 | ------------------------------------------------------------------------ | ||
71 | -- verify test cases using native Lua | ||
72 | ------------------------------------------------------------------------ | ||
73 | |||
74 | local last_head = "TESTS: no heading yet" | ||
75 | for i = 1, total do | ||
76 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
77 | -- show progress | ||
78 | if head then | ||
79 | last_head = head | ||
80 | if DEBUG_FAILS then print("\n"..head.."\n") end | ||
81 | end | ||
82 | ------------------------------------------------------------------ | ||
83 | -- perform test | ||
84 | local f, err = loadstring(test_case) | ||
85 | -- look at outcome | ||
86 | ------------------------------------------------------------------ | ||
87 | if f then-- actual PASS | ||
88 | if expected == "FAIL" then | ||
89 | print("\nVerified as PASS but expected to FAIL".. | ||
90 | "\n-------------------------------------") | ||
91 | print("Lastest heading: "..last_head) | ||
92 | print("TEST: "..test_case) | ||
93 | os.exit() | ||
94 | end | ||
95 | ------------------------------------------------------------------ | ||
96 | else-- actual FAIL | ||
97 | if expected == "PASS" then | ||
98 | print("\nVerified as FAIL but expected to PASS".. | ||
99 | "\n-------------------------------------") | ||
100 | print("Lastest heading: "..last_head) | ||
101 | print("TEST: "..test_case) | ||
102 | print("ERROR: "..err) | ||
103 | os.exit() | ||
104 | end | ||
105 | if DEBUG_FAILS then | ||
106 | print("TEST: "..test_case) | ||
107 | print("ERROR: "..err.."\n") | ||
108 | end | ||
109 | ------------------------------------------------------------------ | ||
110 | end--f | ||
111 | end--for | ||
112 | |||
113 | print("Test cases verified using native Lua, no anomalies.") | ||
114 | |||
115 | ------------------------------------------------------------------------ | ||
116 | -- test using Yueliang front end | ||
117 | ------------------------------------------------------------------------ | ||
118 | |||
119 | local last_head = "TESTS: no heading yet" | ||
120 | for i = 1, total do | ||
121 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
122 | -- show progress | ||
123 | if head then last_head = head end | ||
124 | ------------------------------------------------------------------ | ||
125 | -- perform test | ||
126 | llex.init(test_case, "=test_sample") | ||
127 | lparser.init(llex) | ||
128 | |||
129 | local status, func = pcall(lparser.parser) | ||
130 | -- look at outcome | ||
131 | ------------------------------------------------------------------ | ||
132 | if status then-- actual PASS | ||
133 | if expected == "FAIL" then | ||
134 | print("\nTested as PASS but expected to FAIL".. | ||
135 | "\n-----------------------------------") | ||
136 | print("Lastest heading: "..last_head) | ||
137 | print("TEST: "..test_case) | ||
138 | os.exit() | ||
139 | end | ||
140 | ------------------------------------------------------------------ | ||
141 | else-- actual FAIL | ||
142 | if expected == "PASS" then | ||
143 | print("\nTested as FAIL but expected to PASS".. | ||
144 | "\n-----------------------------------") | ||
145 | print("Lastest heading: "..last_head) | ||
146 | print("TEST: "..test_case) | ||
147 | os.exit() | ||
148 | else | ||
149 | io.stdout:write("-") | ||
150 | end | ||
151 | ------------------------------------------------------------------ | ||
152 | end--status | ||
153 | io.stdout:write("\rTesting ["..i.."]...") | ||
154 | end--for | ||
155 | print(" done.") | ||
156 | |||
157 | print("Test cases run on Yueliang, no anomalies.") | ||
158 | |||
159 | -- 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 @@ | |||
1 | orig-5.0.3 | ||
2 | |||
3 | This is a straightforward port of the Lua 5.0.3 front end (lexical | ||
4 | analyzer, parser, code generator, binary chunk dumper.) | ||
5 | |||
6 | The front end files are: | ||
7 | |||
8 | lopcodes.lua opcode definition | ||
9 | lzio.lua input streams | ||
10 | llex.lua lexical analyzer | ||
11 | lparser.lua parser | ||
12 | lcode.lua code generator | ||
13 | ldump.lua binary chunk dumper | ||
14 | |||
15 | Status: operational, passes all current tests (non-exhaustive) | ||
16 | |||
17 | Major test scripts are: | ||
18 | |||
19 | test/test_llex.lua exercises test cases | ||
20 | test/test_lparser2.lua exercises test cases | ||
21 | |||
22 | luac.lua is a clone of Lua 5.0.3's luac.lua, except that it generates a | ||
23 | binary chunk using Yueliang's front end implementation. | ||
24 | |||
25 | Note that performance is not a consideration. The code tries to stay | ||
26 | faithful to its C roots, so that if you were to do anything using this | ||
27 | codebase, backporting the changes to C will be easy. As such, this | ||
28 | codebase is meant for learning or prototyping purposes. | ||
29 | |||
30 | Many parameters are unused, because call arguments are retained as far | ||
31 | as possible. Changes and deletions are described wherever possible, but | ||
32 | documentation of changes is not comprehensive. | ||
33 | |||
34 | These files will stay faithful to the equivalent C files or modules in | ||
35 | Lua 5.0.3. For rewrites or new features, a new directory will be created | ||
36 | and a different set of files maintained. For Lua 5.1, a new directory | ||
37 | will be created. | ||
38 | |||
39 | The test directory has several primitive test scripts. Much better | ||
40 | testing is planned. Eventually, the codebase will be validated using | ||
41 | automated tests, so that any changes that breaks the system can be | ||
42 | caught easily. | ||
43 | |||
44 | The tools directory has a call graph generator, showing what gets | ||
45 | called. Specific modules and functions can be monitored, and some | ||
46 | parameters and return values are shown. This is a demonstration of the | ||
47 | flexibility and ease of manipulation of using a relatively inefficient | ||
48 | global table scheme. | ||
49 | |||
50 | For Lua 5.0.2, see Yueliang 0.1.3, which was the last release of Lua | ||
51 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lcode.lua | ||
4 | Lua 5 code generator in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * one function manipulate a pointer argument with a simple data type | ||
18 | -- (can't be emulated by a table, ambiguous), now returns that value: | ||
19 | -- luaK:concat(fs, l1, l2) | ||
20 | -- * some function parameters changed to boolean, additional code | ||
21 | -- translates boolean back to 1/0 for instruction fields | ||
22 | -- * Added: | ||
23 | -- luaK:ttisnumber(o) (from lobject.h) | ||
24 | -- luaK:nvalue(o) (from lobject.h) | ||
25 | -- luaK:setnilvalue(o) (from lobject.h) | ||
26 | -- luaK:setsvalue(o, x) (from lobject.h) | ||
27 | -- luaK:setnvalue(o, x) (from lobject.h) | ||
28 | -- luaK:sethvalue(o, x) (from lobject.h) | ||
29 | ----------------------------------------------------------------------]] | ||
30 | |||
31 | -- requires luaP, luaX, luaY | ||
32 | luaK = {} | ||
33 | |||
34 | ------------------------------------------------------------------------ | ||
35 | -- Marks the end of a patch list. It is an invalid value both as an absolute | ||
36 | -- address, and as a list link (would link an element to itself). | ||
37 | ------------------------------------------------------------------------ | ||
38 | luaK.NO_JUMP = -1 | ||
39 | |||
40 | ------------------------------------------------------------------------ | ||
41 | -- grep "ORDER OPR" if you change these enums | ||
42 | ------------------------------------------------------------------------ | ||
43 | luaK.BinOpr = { | ||
44 | OPR_ADD = 0, OPR_SUB = 1, OPR_MULT = 2, OPR_DIV = 3, OPR_POW = 4, | ||
45 | OPR_CONCAT = 5, | ||
46 | OPR_NE = 6, OPR_EQ = 7, | ||
47 | OPR_LT = 8, OPR_LE = 9, OPR_GT = 10, OPR_GE = 11, | ||
48 | OPR_AND = 12, OPR_OR = 13, | ||
49 | OPR_NOBINOPR = 14, | ||
50 | } | ||
51 | |||
52 | ------------------------------------------------------------------------ | ||
53 | -- emulation of TObject macros (these are from lobject.h) | ||
54 | -- * TObject is a table since lcode passes references around | ||
55 | -- * tt member field removed, using Lua's type() instead | ||
56 | ------------------------------------------------------------------------ | ||
57 | function luaK:ttisnumber(o) | ||
58 | if o then return type(o.value) == "number" else return false end | ||
59 | end | ||
60 | function luaK:nvalue(o) return o.value end | ||
61 | function luaK:setnilvalue(o) o.value = nil end | ||
62 | function luaK:setsvalue(o, x) o.value = x end | ||
63 | luaK.setnvalue = luaK.setsvalue | ||
64 | luaK.sethvalue = luaK.setsvalue | ||
65 | |||
66 | ------------------------------------------------------------------------ | ||
67 | -- * binopistest appears to be unused | ||
68 | -- * UnOpr is used by luaK:prefix's op argument | ||
69 | ------------------------------------------------------------------------ | ||
70 | function luaK:binopistest(op) | ||
71 | return self.BinOpr[op] >= self.BinOpr["OPR_NE"] | ||
72 | end | ||
73 | |||
74 | luaK.UnOpr = { | ||
75 | OPR_MINUS = 0, OPR_NOT = 1, OPR_NOUNOPR = 2 | ||
76 | } | ||
77 | |||
78 | ------------------------------------------------------------------------ | ||
79 | -- returns the instruction object for given e (expdesc) | ||
80 | ------------------------------------------------------------------------ | ||
81 | function luaK:getcode(fs, e) | ||
82 | return fs.f.code[e.info] | ||
83 | end | ||
84 | |||
85 | ------------------------------------------------------------------------ | ||
86 | -- codes an instruction with a signed Bx (sBx) field | ||
87 | ------------------------------------------------------------------------ | ||
88 | function luaK:codeAsBx(fs, o, A, sBx) | ||
89 | return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx) | ||
90 | end | ||
91 | |||
92 | ------------------------------------------------------------------------ | ||
93 | -- there is a jump if patch lists are not identical | ||
94 | -- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val() | ||
95 | ------------------------------------------------------------------------ | ||
96 | function luaK:hasjumps(e) | ||
97 | return e.t ~= e.f | ||
98 | end | ||
99 | |||
100 | ------------------------------------------------------------------------ | ||
101 | -- codes loading of nil, optimization done if consecutive locations | ||
102 | -- * used only in discharge2reg() | ||
103 | ------------------------------------------------------------------------ | ||
104 | function luaK:_nil(fs, from, n) | ||
105 | if fs.pc > fs.lasttarget then -- no jumps to current position? | ||
106 | local previous = fs.f.code[fs.pc - 1] | ||
107 | if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then | ||
108 | local pfrom = luaP:GETARG_A(previous) | ||
109 | local pto = luaP:GETARG_B(previous) | ||
110 | if pfrom <= from and from <= pto + 1 then -- can connect both? | ||
111 | if from + n - 1 > pto then | ||
112 | luaP:SETARG_B(previous, from + n - 1) | ||
113 | end | ||
114 | return | ||
115 | end | ||
116 | end | ||
117 | end | ||
118 | self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization | ||
119 | end | ||
120 | |||
121 | ------------------------------------------------------------------------ | ||
122 | -- | ||
123 | -- * used in multiple locations | ||
124 | ------------------------------------------------------------------------ | ||
125 | function luaK:jump(fs) | ||
126 | local jpc = fs.jpc -- save list of jumps to here | ||
127 | fs.jpc = self.NO_JUMP | ||
128 | local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP) | ||
129 | return self:concat(fs, j, jpc) -- keep them on hold | ||
130 | end | ||
131 | |||
132 | ------------------------------------------------------------------------ | ||
133 | -- | ||
134 | -- * used in luaK:jumponcond(), luaK:codebinop() | ||
135 | ------------------------------------------------------------------------ | ||
136 | function luaK:condjump(fs, op, A, B, C) | ||
137 | self:codeABC(fs, op, A, B, C) | ||
138 | return self:jump(fs) | ||
139 | end | ||
140 | |||
141 | ------------------------------------------------------------------------ | ||
142 | -- | ||
143 | -- * used in luaK:patchlistaux(), luaK:concat() | ||
144 | ------------------------------------------------------------------------ | ||
145 | function luaK:fixjump(fs, pc, dest) | ||
146 | local jmp = fs.f.code[pc] | ||
147 | local offset = dest - (pc + 1) | ||
148 | lua_assert(dest ~= self.NO_JUMP) | ||
149 | if math.abs(offset) > luaP.MAXARG_sBx then | ||
150 | luaX:syntaxerror(fs.ls, "control structure too long") | ||
151 | end | ||
152 | luaP:SETARG_sBx(jmp, offset) | ||
153 | end | ||
154 | |||
155 | ------------------------------------------------------------------------ | ||
156 | -- returns current 'pc' and marks it as a jump target (to avoid wrong | ||
157 | -- optimizations with consecutive instructions not in the same basic block). | ||
158 | -- * used in multiple locations | ||
159 | -- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL | ||
160 | ------------------------------------------------------------------------ | ||
161 | function luaK:getlabel(fs) | ||
162 | fs.lasttarget = fs.pc | ||
163 | return fs.pc | ||
164 | end | ||
165 | |||
166 | ------------------------------------------------------------------------ | ||
167 | -- | ||
168 | -- * used in luaK:need_value(), luaK:patchlistaux(), luaK:concat() | ||
169 | ------------------------------------------------------------------------ | ||
170 | function luaK:getjump(fs, pc) | ||
171 | local offset = luaP:GETARG_sBx(fs.f.code[pc]) | ||
172 | if offset == self.NO_JUMP then -- point to itself represents end of list | ||
173 | return self.NO_JUMP -- end of list | ||
174 | else | ||
175 | return (pc + 1) + offset -- turn offset into absolute position | ||
176 | end | ||
177 | end | ||
178 | |||
179 | ------------------------------------------------------------------------ | ||
180 | -- | ||
181 | -- * used in luaK:need_value(), luaK:patchlistaux(), luaK:invertjump() | ||
182 | ------------------------------------------------------------------------ | ||
183 | function luaK:getjumpcontrol(fs, pc) | ||
184 | local pi = fs.f.code[pc] | ||
185 | local ppi = fs.f.code[pc - 1] | ||
186 | if pc >= 1 and luaP:testOpMode(luaP:GET_OPCODE(ppi), "OpModeT") then | ||
187 | return ppi | ||
188 | else | ||
189 | return pi | ||
190 | end | ||
191 | end | ||
192 | |||
193 | ------------------------------------------------------------------------ | ||
194 | -- check whether list has any jump that do not produce a value | ||
195 | -- (or produce an inverted value) | ||
196 | -- * used only in luaK:exp2reg() | ||
197 | ------------------------------------------------------------------------ | ||
198 | function luaK:need_value(fs, list, cond) | ||
199 | while list ~= self.NO_JUMP do | ||
200 | local i = self:getjumpcontrol(fs, list) | ||
201 | if luaP:GET_OPCODE(i) ~= "OP_TEST" or | ||
202 | luaP:GETARG_A(i) ~= luaP.NO_REG or | ||
203 | luaP:GETARG_C(i) ~= cond then | ||
204 | return true | ||
205 | end | ||
206 | list = self:getjump(fs, list) | ||
207 | end | ||
208 | return false -- not found | ||
209 | end | ||
210 | |||
211 | ------------------------------------------------------------------------ | ||
212 | -- | ||
213 | -- * used only in luaK:patchlistaux() | ||
214 | ------------------------------------------------------------------------ | ||
215 | function luaK:patchtestreg(i, reg) | ||
216 | if reg == luaP.NO_REG then reg = luaP:GETARG_B(i) end | ||
217 | luaP:SETARG_A(i, reg) | ||
218 | end | ||
219 | |||
220 | ------------------------------------------------------------------------ | ||
221 | -- | ||
222 | -- * used only in luaK:codenot() | ||
223 | ------------------------------------------------------------------------ | ||
224 | |||
225 | function luaK:removevalues(fs, list) | ||
226 | while list ~= self.NO_JUMP do | ||
227 | local i = self:getjumpcontrol(fs, list) | ||
228 | if luaP:GET_OPCODE(i) == "OP_TEST" then | ||
229 | self:patchtestreg(i, luaP.NO_REG) | ||
230 | end | ||
231 | list = self:getjump(fs, list) | ||
232 | end | ||
233 | end | ||
234 | |||
235 | ------------------------------------------------------------------------ | ||
236 | -- | ||
237 | -- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg() | ||
238 | ------------------------------------------------------------------------ | ||
239 | function luaK:patchlistaux(fs, list, vtarget, reg, dtarget) | ||
240 | while list ~= self.NO_JUMP do | ||
241 | local _next = self:getjump(fs, list) | ||
242 | local i = self:getjumpcontrol(fs, list) | ||
243 | if luaP:GET_OPCODE(i) == "OP_TEST" and luaP:GETARG_A(i) == luaP.NO_REG then | ||
244 | self:patchtestreg(i, reg) | ||
245 | self:fixjump(fs, list, vtarget) | ||
246 | else | ||
247 | self:fixjump(fs, list, dtarget) -- jump to default target | ||
248 | end | ||
249 | list = _next | ||
250 | end | ||
251 | end | ||
252 | |||
253 | ------------------------------------------------------------------------ | ||
254 | -- | ||
255 | -- * used only in luaK:code() | ||
256 | ------------------------------------------------------------------------ | ||
257 | function luaK:dischargejpc(fs) | ||
258 | self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc) | ||
259 | fs.jpc = self.NO_JUMP | ||
260 | end | ||
261 | |||
262 | ------------------------------------------------------------------------ | ||
263 | -- | ||
264 | -- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody() | ||
265 | ------------------------------------------------------------------------ | ||
266 | function luaK:patchlist(fs, list, target) | ||
267 | if target == fs.pc then | ||
268 | self:patchtohere(fs, list) | ||
269 | else | ||
270 | lua_assert(target < fs.pc) | ||
271 | self:patchlistaux(fs, list, target, luaP.NO_REG, target) | ||
272 | end | ||
273 | end | ||
274 | |||
275 | ------------------------------------------------------------------------ | ||
276 | -- | ||
277 | -- * used in multiple locations | ||
278 | ------------------------------------------------------------------------ | ||
279 | function luaK:patchtohere(fs, list) | ||
280 | self:getlabel(fs) | ||
281 | fs.jpc = self:concat(fs, fs.jpc, list) | ||
282 | end | ||
283 | |||
284 | ------------------------------------------------------------------------ | ||
285 | -- * l1 was a pointer, now l1 is returned and callee assigns the value | ||
286 | -- * used in multiple locations | ||
287 | ------------------------------------------------------------------------ | ||
288 | function luaK:concat(fs, l1, l2) | ||
289 | if l2 == self.NO_JUMP then return l1 -- unchanged | ||
290 | elseif l1 == self.NO_JUMP then | ||
291 | return l2 -- changed | ||
292 | else | ||
293 | local list = l1 | ||
294 | local _next = self:getjump(fs, list) | ||
295 | while _next ~= self.NO_JUMP do -- find last element | ||
296 | list = _next | ||
297 | _next = self:getjump(fs, list) | ||
298 | end | ||
299 | self:fixjump(fs, list, l2) | ||
300 | end | ||
301 | return l1 -- unchanged | ||
302 | end | ||
303 | |||
304 | ------------------------------------------------------------------------ | ||
305 | -- | ||
306 | -- * used in luaK:reserveregs(), (lparser) luaY:forlist() | ||
307 | ------------------------------------------------------------------------ | ||
308 | function luaK:checkstack(fs, n) | ||
309 | local newstack = fs.freereg + n | ||
310 | if newstack > fs.f.maxstacksize then | ||
311 | if newstack >= luaY.MAXSTACK then | ||
312 | luaX:syntaxerror(fs.ls, "function or expression too complex") | ||
313 | end | ||
314 | fs.f.maxstacksize = newstack | ||
315 | end | ||
316 | end | ||
317 | |||
318 | ------------------------------------------------------------------------ | ||
319 | -- | ||
320 | -- * used in multiple locations | ||
321 | ------------------------------------------------------------------------ | ||
322 | function luaK:reserveregs(fs, n) | ||
323 | self:checkstack(fs, n) | ||
324 | fs.freereg = fs.freereg + n | ||
325 | end | ||
326 | |||
327 | ------------------------------------------------------------------------ | ||
328 | -- | ||
329 | -- * used in luaK:freeexp(), luaK:dischargevars() | ||
330 | ------------------------------------------------------------------------ | ||
331 | function luaK:freereg(fs, reg) | ||
332 | if reg >= fs.nactvar and reg < luaY.MAXSTACK then | ||
333 | fs.freereg = fs.freereg - 1 | ||
334 | lua_assert(reg == fs.freereg) | ||
335 | end | ||
336 | end | ||
337 | |||
338 | ------------------------------------------------------------------------ | ||
339 | -- | ||
340 | -- * used in multiple locations | ||
341 | ------------------------------------------------------------------------ | ||
342 | function luaK:freeexp(fs, e) | ||
343 | if e.k == "VNONRELOC" then | ||
344 | self:freereg(fs, e.info) | ||
345 | end | ||
346 | end | ||
347 | |||
348 | ------------------------------------------------------------------------ | ||
349 | -- * luaH_get, luaH_set deleted; direct table access used instead | ||
350 | -- * luaO_rawequalObj deleted in first assert | ||
351 | -- * setobj2n deleted in assignment of v to f.k table | ||
352 | -- * used in luaK:stringK(), luaK:numberK(), luaK:nil_constant() | ||
353 | ------------------------------------------------------------------------ | ||
354 | function luaK:addk(fs, k, v) | ||
355 | local idx = fs.h[k.value] | ||
356 | if self:ttisnumber(idx) then | ||
357 | --TODO this assert currently FAILS, probably something wrong... | ||
358 | --lua_assert(fs.f.k[self:nvalue(idx)] == v) | ||
359 | return self:nvalue(idx) | ||
360 | else -- constant not found; create a new entry | ||
361 | local f = fs.f | ||
362 | luaY:growvector(fs.L, f.k, fs.nk, f.sizek, nil, | ||
363 | luaP.MAXARG_Bx, "constant table overflow") | ||
364 | f.k[fs.nk] = v -- setobj2n deleted | ||
365 | fs.h[k.value] = {} | ||
366 | self:setnvalue(fs.h[k.value], fs.nk) | ||
367 | local nk = fs.nk | ||
368 | fs.nk = fs.nk + 1 | ||
369 | return nk | ||
370 | end | ||
371 | end | ||
372 | |||
373 | ------------------------------------------------------------------------ | ||
374 | -- creates and sets a string object | ||
375 | -- * used in (lparser) luaY:codestring(), luaY:singlevaraux() | ||
376 | ------------------------------------------------------------------------ | ||
377 | function luaK:stringK(fs, s) | ||
378 | local o = {} -- TObject | ||
379 | self:setsvalue(o, s) | ||
380 | return self:addk(fs, o, o) | ||
381 | end | ||
382 | |||
383 | ------------------------------------------------------------------------ | ||
384 | -- creates and sets a number object | ||
385 | -- * used in luaK:prefix() for negative (or negation of) numbers | ||
386 | -- * used in (lparser) luaY:simpleexp(), luaY:fornum() | ||
387 | ------------------------------------------------------------------------ | ||
388 | function luaK:numberK(fs, r) | ||
389 | local o = {} -- TObject | ||
390 | self:setnvalue(o, r) | ||
391 | return self:addk(fs, o, o) | ||
392 | end | ||
393 | |||
394 | ------------------------------------------------------------------------ | ||
395 | -- | ||
396 | -- * used only in luaK:exp2RK() | ||
397 | ------------------------------------------------------------------------ | ||
398 | function luaK:nil_constant(fs) | ||
399 | local k, v = {}, {} -- TObject | ||
400 | self:setnilvalue(v) | ||
401 | self:sethvalue(k, fs.h) -- cannot use nil as key; instead use table itself | ||
402 | return self:addk(fs, k, v) | ||
403 | end | ||
404 | |||
405 | ------------------------------------------------------------------------ | ||
406 | -- | ||
407 | -- * used in luaK:dischargevars() | ||
408 | -- * used in (lparser) luaY:adjust_assign(), luaY:lastlistfield(), | ||
409 | -- luaY:funcargs(), luaY:assignment(), luaY:exprstat(), luaY:retstat() | ||
410 | ------------------------------------------------------------------------ | ||
411 | function luaK:setcallreturns(fs, e, nresults) | ||
412 | if e.k == "VCALL" then -- expression is an open function call? | ||
413 | luaP:SETARG_C(self:getcode(fs, e), nresults + 1) | ||
414 | if nresults == 1 then -- 'regular' expression? | ||
415 | e.k = "VNONRELOC" | ||
416 | e.info = luaP:GETARG_A(self:getcode(fs, e)) | ||
417 | end | ||
418 | end | ||
419 | end | ||
420 | |||
421 | ------------------------------------------------------------------------ | ||
422 | -- | ||
423 | -- * used in multiple locations | ||
424 | ------------------------------------------------------------------------ | ||
425 | function luaK:dischargevars(fs, e) | ||
426 | local k = e.k | ||
427 | if k == "VLOCAL" then | ||
428 | e.k = "VNONRELOC" | ||
429 | elseif k == "VUPVAL" then | ||
430 | e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0) | ||
431 | e.k = "VRELOCABLE" | ||
432 | elseif k == "VGLOBAL" then | ||
433 | e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info) | ||
434 | e.k = "VRELOCABLE" | ||
435 | elseif k == "VINDEXED" then | ||
436 | self:freereg(fs, e.aux) | ||
437 | self:freereg(fs, e.info) | ||
438 | e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux) | ||
439 | e.k = "VRELOCABLE" | ||
440 | elseif k == "VCALL" then | ||
441 | self:setcallreturns(fs, e, 1) | ||
442 | else | ||
443 | -- there is one value available (somewhere) | ||
444 | end | ||
445 | end | ||
446 | |||
447 | ------------------------------------------------------------------------ | ||
448 | -- | ||
449 | -- * used only in luaK:exp2reg() | ||
450 | ------------------------------------------------------------------------ | ||
451 | function luaK:code_label(fs, A, b, jump) | ||
452 | self:getlabel(fs) -- those instructions may be jump targets | ||
453 | return self:codeABC(fs, "OP_LOADBOOL", A, b, jump) | ||
454 | end | ||
455 | |||
456 | ------------------------------------------------------------------------ | ||
457 | -- | ||
458 | -- * used in luaK:discharge2anyreg(), luaK:exp2reg() | ||
459 | ------------------------------------------------------------------------ | ||
460 | function luaK:discharge2reg(fs, e, reg) | ||
461 | self:dischargevars(fs, e) | ||
462 | local k = e.k | ||
463 | if k == "VNIL" then | ||
464 | self:_nil(fs, reg, 1) | ||
465 | elseif k == "VFALSE" or k == "VTRUE" then | ||
466 | self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0) | ||
467 | elseif k == "VK" then | ||
468 | self:codeABx(fs, "OP_LOADK", reg, e.info) | ||
469 | elseif k == "VRELOCABLE" then | ||
470 | local pc = self:getcode(fs, e) | ||
471 | luaP:SETARG_A(pc, reg) | ||
472 | elseif k == "VNONRELOC" then | ||
473 | if reg ~= e.info then | ||
474 | self:codeABC(fs, "OP_MOVE", reg, e.info, 0) | ||
475 | end | ||
476 | else | ||
477 | lua_assert(e.k == "VVOID" or e.k == "VJMP") | ||
478 | return -- nothing to do... | ||
479 | end | ||
480 | e.info = reg | ||
481 | e.k = "VNONRELOC" | ||
482 | end | ||
483 | |||
484 | ------------------------------------------------------------------------ | ||
485 | -- | ||
486 | -- * used in luaK:jumponcond(), luaK:codenot() | ||
487 | ------------------------------------------------------------------------ | ||
488 | function luaK:discharge2anyreg(fs, e) | ||
489 | if e.k ~= "VNONRELOC" then | ||
490 | self:reserveregs(fs, 1) | ||
491 | self:discharge2reg(fs, e, fs.freereg - 1) | ||
492 | end | ||
493 | end | ||
494 | |||
495 | ------------------------------------------------------------------------ | ||
496 | -- | ||
497 | -- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar() | ||
498 | ------------------------------------------------------------------------ | ||
499 | function luaK:exp2reg(fs, e, reg) | ||
500 | self:discharge2reg(fs, e, reg) | ||
501 | if e.k == "VJMP" then | ||
502 | e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list | ||
503 | end | ||
504 | if self:hasjumps(e) then | ||
505 | local final -- position after whole expression | ||
506 | local p_f = self.NO_JUMP -- position of an eventual LOAD false | ||
507 | local p_t = self.NO_JUMP -- position of an eventual LOAD true | ||
508 | if self:need_value(fs, e.t, 1) or self:need_value(fs, e.f, 0) then | ||
509 | local fj = self.NO_JUMP -- first jump (over LOAD ops.) | ||
510 | if e.k ~= "VJMP" then | ||
511 | fj = self:jump(fs) | ||
512 | end | ||
513 | p_f = self:code_label(fs, reg, 0, 1) | ||
514 | p_t = self:code_label(fs, reg, 1, 0) | ||
515 | self:patchtohere(fs, fj) | ||
516 | end | ||
517 | final = self:getlabel(fs) | ||
518 | self:patchlistaux(fs, e.f, final, reg, p_f) | ||
519 | self:patchlistaux(fs, e.t, final, reg, p_t) | ||
520 | end | ||
521 | e.f, e.t = self.NO_JUMP, self.NO_JUMP | ||
522 | e.info = reg | ||
523 | e.k = "VNONRELOC" | ||
524 | end | ||
525 | |||
526 | ------------------------------------------------------------------------ | ||
527 | -- | ||
528 | -- * used in multiple locations | ||
529 | ------------------------------------------------------------------------ | ||
530 | function luaK:exp2nextreg(fs, e) | ||
531 | self:dischargevars(fs, e) | ||
532 | self:freeexp(fs, e) | ||
533 | self:reserveregs(fs, 1) | ||
534 | self:exp2reg(fs, e, fs.freereg - 1) | ||
535 | end | ||
536 | |||
537 | ------------------------------------------------------------------------ | ||
538 | -- | ||
539 | -- * used in multiple locations | ||
540 | ------------------------------------------------------------------------ | ||
541 | function luaK:exp2anyreg(fs, e) | ||
542 | self:dischargevars(fs, e) | ||
543 | if e.k == "VNONRELOC" then | ||
544 | if not self:hasjumps(e) then -- exp is already in a register | ||
545 | return e.info | ||
546 | end | ||
547 | if e.info >= fs.nactvar then -- reg. is not a local? | ||
548 | self:exp2reg(fs, e, e.info) -- put value on it | ||
549 | return e.info | ||
550 | end | ||
551 | end | ||
552 | self:exp2nextreg(fs, e) -- default | ||
553 | return e.info | ||
554 | end | ||
555 | |||
556 | ------------------------------------------------------------------------ | ||
557 | -- | ||
558 | -- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix() | ||
559 | -- * used in (lparser) luaY:index() | ||
560 | ------------------------------------------------------------------------ | ||
561 | function luaK:exp2val(fs, e) | ||
562 | if self:hasjumps(e) then | ||
563 | self:exp2anyreg(fs, e) | ||
564 | else | ||
565 | self:dischargevars(fs, e) | ||
566 | end | ||
567 | end | ||
568 | |||
569 | ------------------------------------------------------------------------ | ||
570 | -- | ||
571 | -- * used in multiple locations | ||
572 | ------------------------------------------------------------------------ | ||
573 | function luaK:exp2RK(fs, e) | ||
574 | self:exp2val(fs, e) | ||
575 | local k = e.k | ||
576 | if k == "VNIL" then | ||
577 | if fs.nk + luaY.MAXSTACK <= luaP.MAXARG_C then -- constant fit in argC? | ||
578 | e.info = self:nil_constant(fs) | ||
579 | e.k = "VK" | ||
580 | return e.info + luaY.MAXSTACK | ||
581 | end | ||
582 | elseif k == "VK" then | ||
583 | if e.info + luaY.MAXSTACK <= luaP.MAXARG_C then -- constant fit in argC? | ||
584 | return e.info + luaY.MAXSTACK | ||
585 | end | ||
586 | end | ||
587 | -- not a constant in the right range: put it in a register | ||
588 | return self:exp2anyreg(fs, e) | ||
589 | end | ||
590 | |||
591 | ------------------------------------------------------------------------ | ||
592 | -- | ||
593 | -- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat() | ||
594 | ------------------------------------------------------------------------ | ||
595 | function luaK:storevar(fs, var, exp) | ||
596 | local k = var.k | ||
597 | if k == "VLOCAL" then | ||
598 | self:freeexp(fs, exp) | ||
599 | self:exp2reg(fs, exp, var.info) | ||
600 | return | ||
601 | elseif k == "VUPVAL" then | ||
602 | local e = self:exp2anyreg(fs, exp) | ||
603 | self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0) | ||
604 | elseif k == "VGLOBAL" then | ||
605 | local e = self:exp2anyreg(fs, exp) | ||
606 | self:codeABx(fs, "OP_SETGLOBAL", e, var.info) | ||
607 | elseif k == "VINDEXED" then | ||
608 | local e = self:exp2RK(fs, exp) | ||
609 | self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e) | ||
610 | else | ||
611 | lua_assert(0) -- invalid var kind to store | ||
612 | end | ||
613 | self:freeexp(fs, exp) | ||
614 | end | ||
615 | |||
616 | ------------------------------------------------------------------------ | ||
617 | -- | ||
618 | -- * used only in (lparser) luaY:primaryexp() | ||
619 | ------------------------------------------------------------------------ | ||
620 | function luaK:_self(fs, e, key) | ||
621 | self:exp2anyreg(fs, e) | ||
622 | self:freeexp(fs, e) | ||
623 | local func = fs.freereg | ||
624 | self:reserveregs(fs, 2) | ||
625 | self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key)) | ||
626 | self:freeexp(fs, key) | ||
627 | e.info = func | ||
628 | e.k = "VNONRELOC" | ||
629 | end | ||
630 | |||
631 | ------------------------------------------------------------------------ | ||
632 | -- | ||
633 | -- * used in luaK:goiftrue(), luaK:codenot() | ||
634 | ------------------------------------------------------------------------ | ||
635 | function luaK:invertjump(fs, e) | ||
636 | local pc = self:getjumpcontrol(fs, e.info) | ||
637 | lua_assert(luaP:testOpMode(luaP:GET_OPCODE(pc), "OpModeT") and | ||
638 | luaP:GET_OPCODE(pc) ~= "OP_TEST") | ||
639 | luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0) | ||
640 | end | ||
641 | |||
642 | ------------------------------------------------------------------------ | ||
643 | -- | ||
644 | -- * used in luaK:goiftrue(), luaK:goiffalse() | ||
645 | ------------------------------------------------------------------------ | ||
646 | function luaK:jumponcond(fs, e, cond) | ||
647 | if e.k == "VRELOCABLE" then | ||
648 | local ie = self:getcode(fs, e) | ||
649 | if luaP:GET_OPCODE(ie) == "OP_NOT" then | ||
650 | fs.pc = fs.pc - 1 -- remove previous OP_NOT | ||
651 | return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), luaP:GETARG_B(ie), | ||
652 | cond and 0 or 1) | ||
653 | end | ||
654 | -- else go through | ||
655 | end | ||
656 | self:discharge2anyreg(fs, e) | ||
657 | self:freeexp(fs, e) | ||
658 | return self:condjump(fs, "OP_TEST", luaP.NO_REG, e.info, cond and 1 or 0) | ||
659 | end | ||
660 | |||
661 | ------------------------------------------------------------------------ | ||
662 | -- | ||
663 | -- * used in luaK:infix(), (lparser) luaY:cond() | ||
664 | ------------------------------------------------------------------------ | ||
665 | function luaK:goiftrue(fs, e) | ||
666 | local pc -- pc of last jump | ||
667 | self:dischargevars(fs, e) | ||
668 | local k = e.k | ||
669 | if k == "VK" or k == "VTRUE" then | ||
670 | pc = self.NO_JUMP -- always true; do nothing | ||
671 | elseif k == "VFALSE" then | ||
672 | pc = self:jump(fs) -- always jump | ||
673 | elseif k == "VJMP" then | ||
674 | self:invertjump(fs, e) | ||
675 | pc = e.info | ||
676 | else | ||
677 | pc = self:jumponcond(fs, e, false) | ||
678 | end | ||
679 | e.f = self:concat(fs, e.f, pc) -- insert last jump in 'f' list | ||
680 | end | ||
681 | |||
682 | ------------------------------------------------------------------------ | ||
683 | -- | ||
684 | -- * used in luaK:infix(), (lparser) luaY:whilestat() | ||
685 | ------------------------------------------------------------------------ | ||
686 | function luaK:goiffalse(fs, e) | ||
687 | local pc -- pc of last jump | ||
688 | self:dischargevars(fs, e) | ||
689 | local k = e.k | ||
690 | if k == "VNIL" or k == "VFALSE"then | ||
691 | pc = self.NO_JUMP -- always false; do nothing | ||
692 | elseif k == "VTRUE" then | ||
693 | pc = self:jump(fs) -- always jump | ||
694 | elseif k == "VJMP" then | ||
695 | pc = e.info | ||
696 | else | ||
697 | pc = self:jumponcond(fs, e, true) | ||
698 | end | ||
699 | e.t = self:concat(fs, e.t, pc) -- insert last jump in 't' list | ||
700 | end | ||
701 | |||
702 | ------------------------------------------------------------------------ | ||
703 | -- | ||
704 | -- * used only in luaK:prefix() | ||
705 | ------------------------------------------------------------------------ | ||
706 | function luaK:codenot(fs, e) | ||
707 | self:dischargevars(fs, e) | ||
708 | local k = e.k | ||
709 | if k == "VNIL" or k == "VFALSE" then | ||
710 | e.k = "VTRUE" | ||
711 | elseif k == "VK" or k == "VTRUE" then | ||
712 | e.k = "VFALSE" | ||
713 | elseif k == "VJMP" then | ||
714 | self:invertjump(fs, e) | ||
715 | elseif k == "VRELOCABLE" or k == "VNONRELOC" then | ||
716 | self:discharge2anyreg(fs, e) | ||
717 | self:freeexp(fs, e) | ||
718 | e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0) | ||
719 | e.k = "VRELOCABLE" | ||
720 | else | ||
721 | lua_assert(0) -- cannot happen | ||
722 | end | ||
723 | -- interchange true and false lists | ||
724 | e.f, e.t = e.t, e.f | ||
725 | self:removevalues(fs, e.f) | ||
726 | self:removevalues(fs, e.t) | ||
727 | end | ||
728 | |||
729 | ------------------------------------------------------------------------ | ||
730 | -- | ||
731 | -- * used in (lparser) luaY:field(), luaY:primaryexp() | ||
732 | ------------------------------------------------------------------------ | ||
733 | function luaK:indexed(fs, t, k) | ||
734 | t.aux = self:exp2RK(fs, k) | ||
735 | t.k = "VINDEXED" | ||
736 | end | ||
737 | |||
738 | ------------------------------------------------------------------------ | ||
739 | -- | ||
740 | -- * used only in (lparser) luaY:subexpr() | ||
741 | ------------------------------------------------------------------------ | ||
742 | function luaK:prefix(fs, op, e) | ||
743 | if op == "OPR_MINUS" then | ||
744 | self:exp2val(fs, e) | ||
745 | if e.k == "VK" and self:ttisnumber(fs.f.k[e.info]) then | ||
746 | e.info = self:numberK(fs, -self:nvalue(fs.f.k[e.info])) | ||
747 | else | ||
748 | self:exp2anyreg(fs, e) | ||
749 | self:freeexp(fs, e) | ||
750 | e.info = self:codeABC(fs, "OP_UNM", 0, e.info, 0) | ||
751 | e.k = "VRELOCABLE" | ||
752 | end | ||
753 | else -- op == NOT | ||
754 | self:codenot(fs, e) | ||
755 | end | ||
756 | end | ||
757 | |||
758 | ------------------------------------------------------------------------ | ||
759 | -- | ||
760 | -- * used only in (lparser) luaY:subexpr() | ||
761 | ------------------------------------------------------------------------ | ||
762 | function luaK:infix(fs, op, v) | ||
763 | if op == "OPR_AND" then | ||
764 | self:goiftrue(fs, v) | ||
765 | self:patchtohere(fs, v.t) | ||
766 | v.t = self.NO_JUMP | ||
767 | elseif op == "OPR_OR" then | ||
768 | self:goiffalse(fs, v) | ||
769 | self:patchtohere(fs, v.f) | ||
770 | v.f = self.NO_JUMP | ||
771 | elseif op == "OPR_CONCAT" then | ||
772 | self:exp2nextreg(fs, v) -- operand must be on the 'stack' | ||
773 | else | ||
774 | self:exp2RK(fs, v) | ||
775 | end | ||
776 | end | ||
777 | |||
778 | ------------------------------------------------------------------------ | ||
779 | -- | ||
780 | -- grep "ORDER OPR" if you change these enums | ||
781 | -- * used only in luaK:posfix() | ||
782 | ------------------------------------------------------------------------ | ||
783 | luaK.arith_opc = { -- done as a table lookup instead of a calc | ||
784 | OPR_ADD = "OP_ADD", | ||
785 | OPR_SUB = "OP_SUB", | ||
786 | OPR_MULT = "OP_MUL", | ||
787 | OPR_DIV = "OP_DIV", | ||
788 | OPR_POW = "OP_POW", | ||
789 | } | ||
790 | luaK.test_opc = { -- was ops[] in the codebinop function | ||
791 | OPR_NE = "OP_EQ", | ||
792 | OPR_EQ = "OP_EQ", | ||
793 | OPR_LT = "OP_LT", | ||
794 | OPR_LE = "OP_LE", | ||
795 | OPR_GT = "OP_LT", | ||
796 | OPR_GE = "OP_LE", | ||
797 | } | ||
798 | function luaK:codebinop(fs, res, op, o1, o2) | ||
799 | if self.BinOpr[op] <= self.BinOpr["OPR_POW"] then -- arithmetic operator? | ||
800 | local opc = self.arith_opc[op] -- ORDER OP | ||
801 | res.info = self:codeABC(fs, opc, 0, o1, o2) | ||
802 | res.k = "VRELOCABLE" | ||
803 | else -- test operator | ||
804 | local cond = true | ||
805 | if self.BinOpr[op] >= self.BinOpr["OPR_GT"] then -- '>' or '>='? | ||
806 | -- exchange args and replace by '<' or '<=' | ||
807 | o1, o2 = o2, o1 -- o1 <==> o2 | ||
808 | elseif op == "OPR_NE" then | ||
809 | cond = false | ||
810 | end | ||
811 | res.info = self:condjump(fs, self.test_opc[op], cond and 1 or 0, o1, o2) | ||
812 | res.k = "VJMP" | ||
813 | end | ||
814 | end | ||
815 | |||
816 | ------------------------------------------------------------------------ | ||
817 | -- | ||
818 | -- * used only in (lparser) luaY:subexpr() | ||
819 | ------------------------------------------------------------------------ | ||
820 | function luaK:posfix(fs, op, e1, e2) | ||
821 | if op == "OPR_AND" then | ||
822 | lua_assert(e1.t == self.NO_JUMP) -- list must be closed | ||
823 | self:dischargevars(fs, e2) | ||
824 | e1.f = self:concat(fs, e1.f, e2.f) | ||
825 | e1.k = e2.k; e1.info = e2.info; e1.aux = e2.aux; e1.t = e2.t | ||
826 | elseif op == "OPR_OR" then | ||
827 | lua_assert(e1.f == self.NO_JUMP) -- list must be closed | ||
828 | self:dischargevars(fs, e2) | ||
829 | e1.t = self:concat(fs, e1.t, e2.t) | ||
830 | e1.k = e2.k; e1.info = e2.info; e1.aux = e2.aux; e1.f = e2.f | ||
831 | elseif op == "OPR_CONCAT" then | ||
832 | self:exp2val(fs, e2) | ||
833 | if e2.k == "VRELOCABLE" | ||
834 | and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then | ||
835 | lua_assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1) | ||
836 | self:freeexp(fs, e1) | ||
837 | luaP:SETARG_B(self:getcode(fs, e2), e1.info) | ||
838 | e1.k = e2.k; e1.info = e2.info | ||
839 | else | ||
840 | self:exp2nextreg(fs, e2) | ||
841 | self:freeexp(fs, e2) | ||
842 | self:freeexp(fs, e1) | ||
843 | e1.info = self:codeABC(fs, "OP_CONCAT", 0, e1.info, e2.info) | ||
844 | e1.k = "VRELOCABLE" | ||
845 | end | ||
846 | else | ||
847 | local o1 = self:exp2RK(fs, e1) | ||
848 | local o2 = self:exp2RK(fs, e2) | ||
849 | self:freeexp(fs, e2) | ||
850 | self:freeexp(fs, e1) | ||
851 | self:codebinop(fs, e1, op, o1, o2) | ||
852 | end | ||
853 | end | ||
854 | |||
855 | ------------------------------------------------------------------------ | ||
856 | -- adjusts debug information for last instruction written, in order to | ||
857 | -- change the line where item comes into existence | ||
858 | -- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat() | ||
859 | ------------------------------------------------------------------------ | ||
860 | function luaK:fixline(fs, line) | ||
861 | fs.f.lineinfo[fs.pc - 1] = line | ||
862 | end | ||
863 | |||
864 | ------------------------------------------------------------------------ | ||
865 | -- general function to write an instruction into the instruction buffer, | ||
866 | -- sets debug information too | ||
867 | -- * used in luaK:codeABC(), luaK:codeABx() | ||
868 | -- * called directly by (lparser) luaY:whilestat() | ||
869 | ------------------------------------------------------------------------ | ||
870 | function luaK:code(fs, i, line) | ||
871 | local f = fs.f | ||
872 | self:dischargejpc(fs) -- 'pc' will change | ||
873 | -- put new instruction in code array | ||
874 | luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil, | ||
875 | luaY.MAX_INT, "code size overflow") | ||
876 | f.code[fs.pc] = i | ||
877 | -- save corresponding line information | ||
878 | luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil, | ||
879 | luaY.MAX_INT, "code size overflow") | ||
880 | f.lineinfo[fs.pc] = line | ||
881 | local pc = fs.pc | ||
882 | fs.pc = fs.pc + 1 | ||
883 | return pc | ||
884 | end | ||
885 | |||
886 | ------------------------------------------------------------------------ | ||
887 | -- writes an instruction of type ABC | ||
888 | -- * calls luaK:code() | ||
889 | ------------------------------------------------------------------------ | ||
890 | function luaK:codeABC(fs, o, a, b, c) | ||
891 | lua_assert(luaP:getOpMode(o) == "iABC") | ||
892 | return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline) | ||
893 | end | ||
894 | |||
895 | ------------------------------------------------------------------------ | ||
896 | -- writes an instruction of type ABx | ||
897 | -- * calls luaK:code(), called by luaK:codeAsBx() | ||
898 | ------------------------------------------------------------------------ | ||
899 | function luaK:codeABx(fs, o, a, bc) | ||
900 | lua_assert(luaP:getOpMode(o) == "iABx" or luaP:getOpMode(o) == "iAsBx") | ||
901 | return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline) | ||
902 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | ldump.lua | ||
4 | Save bytecodes in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * LUA_NUMBER (double), byte order (little endian) and some other | ||
18 | -- header values hard-coded; see other notes below... | ||
19 | -- * One significant difference is that instructions are still in table | ||
20 | -- form (with OP/A/B/C/Bx fields) and luaP:Instruction() is needed to | ||
21 | -- convert them into 4-char strings | ||
22 | -- * Deleted: | ||
23 | -- luaU:DumpVector: folded into DumpLines, DumpCode | ||
24 | -- * Added: | ||
25 | -- luaU:endianness() (from lundump.c) | ||
26 | -- luaU:make_setS: create a chunk writer that writes to a string | ||
27 | -- luaU:make_setF: create a chunk writer that writes to a file | ||
28 | -- (lua.h contains a typedef for a Chunkwriter pointer, and | ||
29 | -- a Lua-based implementation exists, writer() in lstrlib.c) | ||
30 | -- luaU:from_double(x): encode double value for writing | ||
31 | -- luaU:from_int(x): encode integer value for writing | ||
32 | -- (error checking is limited for these conversion functions) | ||
33 | -- (double conversion does not support denormals or NaNs) | ||
34 | -- luaU:ttype(o) (from lobject.h) | ||
35 | ----------------------------------------------------------------------]] | ||
36 | |||
37 | --requires luaP | ||
38 | luaU = {} | ||
39 | |||
40 | -- constants used by dumper | ||
41 | luaU.LUA_TNUMBER = 3 -- (all in lua.h) | ||
42 | luaU.LUA_TSTRING = 4 | ||
43 | luaU.LUA_TNIL = 0 | ||
44 | luaU.LUA_TNONE = -1 | ||
45 | |||
46 | -- definitions for headers of binary files | ||
47 | luaU.LUA_SIGNATURE = "\27Lua" -- binary files start with "<esc>Lua" | ||
48 | luaU.VERSION = 80 -- 0x50; last format change was in 5.0 | ||
49 | luaU.VERSION0 = 80 -- 0x50; last major change was in 5.0 | ||
50 | |||
51 | -- a multiple of PI for testing native format | ||
52 | -- multiplying by 1E7 gives non-trivial integer values | ||
53 | luaU.TEST_NUMBER = 3.14159265358979323846E7 | ||
54 | |||
55 | --[[-------------------------------------------------------------------- | ||
56 | -- Additional functions to handle chunk writing | ||
57 | -- * to use make_setS and make_setF, see test_ldump.lua elsewhere | ||
58 | ----------------------------------------------------------------------]] | ||
59 | |||
60 | ------------------------------------------------------------------------ | ||
61 | -- works like the lobject.h version except that TObject used in these | ||
62 | -- scripts only has a 'value' field, no 'tt' field (native types used) | ||
63 | ------------------------------------------------------------------------ | ||
64 | function luaU:ttype(o) | ||
65 | local tt = type(o.value) | ||
66 | if tt == "number" then return self.LUA_TNUMBER | ||
67 | elseif tt == "string" then return self.LUA_TSTRING | ||
68 | elseif tt == "nil" then return self.LUA_TNIL | ||
69 | else | ||
70 | return self.LUA_TNONE -- the rest should not appear | ||
71 | end | ||
72 | end | ||
73 | |||
74 | ------------------------------------------------------------------------ | ||
75 | -- create a chunk writer that writes to a string | ||
76 | -- * returns the writer function and a table containing the string | ||
77 | -- * to get the final result, look in buff.data | ||
78 | ------------------------------------------------------------------------ | ||
79 | function luaU:make_setS() | ||
80 | local buff = {} | ||
81 | buff.data = "" | ||
82 | local writer = | ||
83 | function(s, buff) -- chunk writer | ||
84 | if not s then return end | ||
85 | buff.data = buff.data..s | ||
86 | end | ||
87 | return writer, buff | ||
88 | end | ||
89 | |||
90 | ------------------------------------------------------------------------ | ||
91 | -- create a chunk writer that writes to a file | ||
92 | -- * returns the writer function and a table containing the file handle | ||
93 | -- * if a nil is passed, then writer should close the open file | ||
94 | ------------------------------------------------------------------------ | ||
95 | function luaU:make_setF(filename) | ||
96 | local buff = {} | ||
97 | buff.h = io.open(filename, "wb") | ||
98 | if not buff.h then return nil end | ||
99 | local writer = | ||
100 | function(s, buff) -- chunk writer | ||
101 | if not buff.h then return end | ||
102 | if not s then buff.h:close(); return end | ||
103 | buff.h:write(s) | ||
104 | end | ||
105 | return writer, buff | ||
106 | end | ||
107 | |||
108 | ----------------------------------------------------------------------- | ||
109 | -- converts a IEEE754 double number to an 8-byte little-endian string | ||
110 | -- * luaU:from_double() and luaU:from_int() are from ChunkBake project | ||
111 | -- * supports +/- Infinity, but not denormals or NaNs | ||
112 | ----------------------------------------------------------------------- | ||
113 | function luaU:from_double(x) | ||
114 | local function grab_byte(v) | ||
115 | return math.floor(v / 256), | ||
116 | string.char(math.mod(math.floor(v), 256)) | ||
117 | end | ||
118 | local sign = 0 | ||
119 | if x < 0 then sign = 1; x = -x end | ||
120 | local mantissa, exponent = math.frexp(x) | ||
121 | if x == 0 then -- zero | ||
122 | mantissa, exponent = 0, 0 | ||
123 | elseif x == 1/0 then | ||
124 | mantissa, exponent = 0, 2047 | ||
125 | else | ||
126 | mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, 53) | ||
127 | exponent = exponent + 1022 | ||
128 | end | ||
129 | local v, byte = "" -- convert to bytes | ||
130 | x = mantissa | ||
131 | for i = 1,6 do | ||
132 | x, byte = grab_byte(x); v = v..byte -- 47:0 | ||
133 | end | ||
134 | x, byte = grab_byte(exponent * 16 + x); v = v..byte -- 55:48 | ||
135 | x, byte = grab_byte(sign * 128 + x); v = v..byte -- 63:56 | ||
136 | return v | ||
137 | end | ||
138 | |||
139 | ----------------------------------------------------------------------- | ||
140 | -- converts a number to a little-endian 32-bit integer string | ||
141 | -- * input value assumed to not overflow, can be signed/unsigned | ||
142 | ----------------------------------------------------------------------- | ||
143 | function luaU:from_int(x) | ||
144 | local v = "" | ||
145 | x = math.floor(x) | ||
146 | if x >= 0 then | ||
147 | for i = 1, 4 do | ||
148 | v = v..string.char(math.mod(x, 256)); x = math.floor(x / 256) | ||
149 | end | ||
150 | else-- x < 0 | ||
151 | x = -x | ||
152 | local carry = 1 | ||
153 | for i = 1, 4 do | ||
154 | local c = 255 - math.mod(x, 256) + carry | ||
155 | if c == 256 then c = 0; carry = 1 else carry = 0 end | ||
156 | v = v..string.char(c); x = math.floor(x / 256) | ||
157 | end | ||
158 | end | ||
159 | return v | ||
160 | end | ||
161 | |||
162 | --[[-------------------------------------------------------------------- | ||
163 | -- Functions to make a binary chunk | ||
164 | -- * many functions have the size parameter removed, since output is | ||
165 | -- in the form of a string and some sizes are implicit or hard-coded | ||
166 | -- * luaU:DumpVector has been deleted (used in DumpCode & DumpLines) | ||
167 | ----------------------------------------------------------------------]] | ||
168 | |||
169 | ------------------------------------------------------------------------ | ||
170 | -- dump a block of literal bytes | ||
171 | ------------------------------------------------------------------------ | ||
172 | function luaU:DumpLiteral(s, D) self:DumpBlock(s, D) end | ||
173 | |||
174 | --[[-------------------------------------------------------------------- | ||
175 | -- struct DumpState: | ||
176 | -- L -- lua_State (not used in this script) | ||
177 | -- write -- lua_Chunkwriter (chunk writer function) | ||
178 | -- data -- void* (chunk writer context or data already written) | ||
179 | ----------------------------------------------------------------------]] | ||
180 | |||
181 | ------------------------------------------------------------------------ | ||
182 | -- dumps a block of bytes | ||
183 | -- * lua_unlock(D.L), lua_lock(D.L) deleted | ||
184 | ------------------------------------------------------------------------ | ||
185 | function luaU:DumpBlock(b, D) D.write(b, D.data) end | ||
186 | |||
187 | ------------------------------------------------------------------------ | ||
188 | -- dumps a single byte | ||
189 | ------------------------------------------------------------------------ | ||
190 | function luaU:DumpByte(y, D) | ||
191 | self:DumpBlock(string.char(y), D) | ||
192 | end | ||
193 | |||
194 | ------------------------------------------------------------------------ | ||
195 | -- dumps a 32-bit signed integer (for int) | ||
196 | ------------------------------------------------------------------------ | ||
197 | function luaU:DumpInt(x, D) | ||
198 | self:DumpBlock(self:from_int(x), D) | ||
199 | end | ||
200 | |||
201 | ------------------------------------------------------------------------ | ||
202 | -- dumps a 32-bit unsigned integer (for size_t) | ||
203 | ------------------------------------------------------------------------ | ||
204 | function luaU:DumpSize(x, D) | ||
205 | self:DumpBlock(self:from_int(x), D) | ||
206 | end | ||
207 | |||
208 | ------------------------------------------------------------------------ | ||
209 | -- dumps a LUA_NUMBER (hard-coded as a double) | ||
210 | ------------------------------------------------------------------------ | ||
211 | function luaU:DumpNumber(x, D) | ||
212 | self:DumpBlock(self:from_double(x), D) | ||
213 | end | ||
214 | |||
215 | ------------------------------------------------------------------------ | ||
216 | -- dumps a Lua string | ||
217 | ------------------------------------------------------------------------ | ||
218 | function luaU:DumpString(s, D) | ||
219 | if s == nil then | ||
220 | self:DumpSize(0, D) | ||
221 | else | ||
222 | s = s.."\0" -- include trailing '\0' | ||
223 | self:DumpSize(string.len(s), D) | ||
224 | self:DumpBlock(s, D) | ||
225 | end | ||
226 | end | ||
227 | |||
228 | ------------------------------------------------------------------------ | ||
229 | -- dumps instruction block from function prototype | ||
230 | ------------------------------------------------------------------------ | ||
231 | function luaU:DumpCode(f, D) | ||
232 | local n = f.sizecode | ||
233 | self:DumpInt(n, D) | ||
234 | --was DumpVector | ||
235 | for i = 0, n - 1 do | ||
236 | self:DumpBlock(luaP:Instruction(f.code[i]), D) | ||
237 | end | ||
238 | end | ||
239 | |||
240 | ------------------------------------------------------------------------ | ||
241 | -- dumps local variable names from function prototype | ||
242 | ------------------------------------------------------------------------ | ||
243 | function luaU:DumpLocals(f, D) | ||
244 | local n = f.sizelocvars | ||
245 | self:DumpInt(n, D) | ||
246 | for i = 0, n - 1 do | ||
247 | self:DumpString(f.locvars[i].varname, D) | ||
248 | self:DumpInt(f.locvars[i].startpc, D) | ||
249 | self:DumpInt(f.locvars[i].endpc, D) | ||
250 | end | ||
251 | end | ||
252 | |||
253 | ------------------------------------------------------------------------ | ||
254 | -- dumps line information from function prototype | ||
255 | ------------------------------------------------------------------------ | ||
256 | function luaU:DumpLines(f, D) | ||
257 | local n = f.sizelineinfo | ||
258 | self:DumpInt(n, D) | ||
259 | --was DumpVector | ||
260 | for i = 0, n - 1 do | ||
261 | self:DumpInt(f.lineinfo[i], D) -- was DumpBlock | ||
262 | end | ||
263 | end | ||
264 | |||
265 | ------------------------------------------------------------------------ | ||
266 | -- dump upvalue names from function prototype | ||
267 | ------------------------------------------------------------------------ | ||
268 | function luaU:DumpUpvalues(f, D) | ||
269 | local n = f.sizeupvalues | ||
270 | self:DumpInt(n, D) | ||
271 | for i = 0, n - 1 do | ||
272 | self:DumpString(f.upvalues[i], D) | ||
273 | end | ||
274 | end | ||
275 | |||
276 | ------------------------------------------------------------------------ | ||
277 | -- dump constant pool from function prototype | ||
278 | -- * nvalue(o) and tsvalue(o) macros removed | ||
279 | ------------------------------------------------------------------------ | ||
280 | function luaU:DumpConstants(f, D) | ||
281 | local n = f.sizek | ||
282 | self:DumpInt(n, D) | ||
283 | for i = 0, n - 1 do | ||
284 | local o = f.k[i] -- TObject | ||
285 | local tt = self:ttype(o) | ||
286 | self:DumpByte(tt, D) | ||
287 | if tt == self.LUA_TNUMBER then | ||
288 | self:DumpNumber(o.value, D) | ||
289 | elseif tt == self.LUA_TSTRING then | ||
290 | self:DumpString(o.value, D) | ||
291 | elseif tt == self.LUA_TNIL then | ||
292 | else | ||
293 | --lua_assert(0) -- cannot happen | ||
294 | end | ||
295 | end | ||
296 | n = f.sizep | ||
297 | self:DumpInt(n, D) | ||
298 | for i = 0, n - 1 do | ||
299 | self:DumpFunction(f.p[i], f.source, D) | ||
300 | end | ||
301 | end | ||
302 | |||
303 | ------------------------------------------------------------------------ | ||
304 | -- dump child function prototypes from function prototype | ||
305 | ------------------------------------------------------------------------ | ||
306 | function luaU:DumpFunction(f, p, D) | ||
307 | local source = f.source | ||
308 | if source == p then source = nil end | ||
309 | self:DumpString(source, D) | ||
310 | self:DumpInt(f.lineDefined, D) | ||
311 | self:DumpByte(f.nups, D) | ||
312 | self:DumpByte(f.numparams, D) | ||
313 | self:DumpByte(f.is_vararg, D) | ||
314 | self:DumpByte(f.maxstacksize, D) | ||
315 | self:DumpLines(f, D) | ||
316 | self:DumpLocals(f, D) | ||
317 | self:DumpUpvalues(f, D) | ||
318 | self:DumpConstants(f, D) | ||
319 | self:DumpCode(f, D) | ||
320 | end | ||
321 | |||
322 | ------------------------------------------------------------------------ | ||
323 | -- dump Lua header section (some sizes hard-coded) | ||
324 | ------------------------------------------------------------------------ | ||
325 | function luaU:DumpHeader(D) | ||
326 | self:DumpLiteral(self.LUA_SIGNATURE, D) | ||
327 | self:DumpByte(self.VERSION, D) | ||
328 | self:DumpByte(self:endianness(), D) | ||
329 | self:DumpByte(4, D) -- sizeof(int) | ||
330 | self:DumpByte(4, D) -- sizeof(size_t) | ||
331 | self:DumpByte(4, D) -- sizeof(Instruction) | ||
332 | self:DumpByte(luaP.SIZE_OP, D) | ||
333 | self:DumpByte(luaP.SIZE_A, D) | ||
334 | self:DumpByte(luaP.SIZE_B, D) | ||
335 | self:DumpByte(luaP.SIZE_C, D) | ||
336 | self:DumpByte(8, D) -- sizeof(lua_Number) | ||
337 | self:DumpNumber(self.TEST_NUMBER, D) | ||
338 | end | ||
339 | |||
340 | ------------------------------------------------------------------------ | ||
341 | -- dump function as precompiled chunk | ||
342 | -- * w, data are created from make_setS, make_setF | ||
343 | ------------------------------------------------------------------------ | ||
344 | function luaU:dump(L, Main, w, data) | ||
345 | local D = {} -- DumpState | ||
346 | D.L = L | ||
347 | D.write = w | ||
348 | D.data = data | ||
349 | self:DumpHeader(D) | ||
350 | self:DumpFunction(Main, nil, D) | ||
351 | -- added: for a chunk writer writing to a file, this final call with | ||
352 | -- nil data is to indicate to the writer to close the file | ||
353 | D.write(nil, D.data) | ||
354 | end | ||
355 | |||
356 | ------------------------------------------------------------------------ | ||
357 | -- find byte order (from lundump.c) | ||
358 | -- * hard-coded to little-endian | ||
359 | ------------------------------------------------------------------------ | ||
360 | function luaU:endianness() | ||
361 | return 1 | ||
362 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | llex.lua | ||
4 | Lua 5 lexical analyzer in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * intended to 'imitate' llex.c code; performance is not a concern | ||
18 | -- * tokens are strings; code structure largely retained | ||
19 | -- * deleted stuff (compared to llex.c) are noted, comments retained | ||
20 | -- * Added: | ||
21 | -- luaX:chunkid (from lobject.c) | ||
22 | -- * To use the lexer: | ||
23 | -- (1) luaX:init() to initialize the lexer | ||
24 | -- (2) luaX:setinput() to set the input stream to lex, get LS | ||
25 | -- (3) call luaX:lex() to get tokens, until "TK_EOS": | ||
26 | -- LS.t.token = luaX:lex(LS, LS.t) | ||
27 | -- * since EOZ is returned as a string, be careful when regexp testing | ||
28 | ----------------------------------------------------------------------]] | ||
29 | |||
30 | luaX = {} | ||
31 | |||
32 | -- FIRST_RESERVED is not required as tokens are manipulated as strings | ||
33 | -- TOKEN_LEN deleted; maximum length of a reserved word | ||
34 | |||
35 | ------------------------------------------------------------------------ | ||
36 | -- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED | ||
37 | ------------------------------------------------------------------------ | ||
38 | |||
39 | -- terminal symbols denoted by reserved words: TK_AND to TK_WHILE | ||
40 | -- other terminal symbols: TK_NAME to TK_EOS | ||
41 | luaX.RESERVED = [[ | ||
42 | TK_AND and | ||
43 | TK_BREAK break | ||
44 | TK_DO do | ||
45 | TK_ELSE else | ||
46 | TK_ELSEIF elseif | ||
47 | TK_END end | ||
48 | TK_FALSE false | ||
49 | TK_FOR for | ||
50 | TK_FUNCTION function | ||
51 | TK_IF if | ||
52 | TK_IN in | ||
53 | TK_LOCAL local | ||
54 | TK_NIL nil | ||
55 | TK_NOT not | ||
56 | TK_OR or | ||
57 | TK_REPEAT repeat | ||
58 | TK_RETURN return | ||
59 | TK_THEN then | ||
60 | TK_TRUE true | ||
61 | TK_UNTIL until | ||
62 | TK_WHILE while | ||
63 | TK_NAME *name | ||
64 | TK_CONCAT .. | ||
65 | TK_DOTS ... | ||
66 | TK_EQ == | ||
67 | TK_GE >= | ||
68 | TK_LE <= | ||
69 | TK_NE ~= | ||
70 | TK_NUMBER *number | ||
71 | TK_STRING *string | ||
72 | TK_EOS <eof>]] | ||
73 | |||
74 | -- NUM_RESERVED is not required; number of reserved words | ||
75 | |||
76 | --[[-------------------------------------------------------------------- | ||
77 | -- Instead of passing seminfo, the Token struct (e.g. LS.t) is passed | ||
78 | -- so that lexer functions can use its table element, LS.t.seminfo | ||
79 | -- | ||
80 | -- Token (struct of LS.t and LS.lookahead): | ||
81 | -- token -- token symbol | ||
82 | -- seminfo -- semantics information | ||
83 | -- | ||
84 | -- LexState (struct of LS; LS is initialized by luaX:setinput): | ||
85 | -- current -- current character | ||
86 | -- linenumber -- input line counter | ||
87 | -- lastline -- line of last token 'consumed' | ||
88 | -- t -- current token (table: struct Token) | ||
89 | -- lookahead -- look ahead token (table: struct Token) | ||
90 | -- fs -- 'FuncState' is private to the parser | ||
91 | -- L -- LuaState | ||
92 | -- z -- input stream | ||
93 | -- buff -- buffer for tokens | ||
94 | -- source -- current source name | ||
95 | -- nestlevel -- level of nested non-terminals | ||
96 | ----------------------------------------------------------------------]] | ||
97 | |||
98 | -- token2string is now a hash; see luaX:init | ||
99 | |||
100 | ------------------------------------------------------------------------ | ||
101 | -- initialize lexer | ||
102 | ------------------------------------------------------------------------ | ||
103 | function luaX:init() | ||
104 | self.token2string = {} | ||
105 | self.string2token = {} | ||
106 | for v in string.gfind(self.RESERVED, "[^\n]+") do | ||
107 | local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)") | ||
108 | self.token2string[tok] = str | ||
109 | self.string2token[str] = tok | ||
110 | end | ||
111 | end | ||
112 | |||
113 | luaX.MAXSRC = 80 | ||
114 | |||
115 | ------------------------------------------------------------------------ | ||
116 | -- returns a suitably-formatted chunk name or id | ||
117 | -- * from lobject.c, used in llex.c and ldebug.c | ||
118 | -- * the result, out, is returned (was first argument) | ||
119 | ------------------------------------------------------------------------ | ||
120 | function luaX:chunkid(source, bufflen) | ||
121 | local out | ||
122 | local first = string.sub(source, 1, 1) | ||
123 | if first == "=" then | ||
124 | out = string.sub(source, 2, bufflen) -- remove first char | ||
125 | else -- out = "source", or "...source" | ||
126 | if first == "@" then | ||
127 | source = string.sub(source, 2) -- skip the '@' | ||
128 | bufflen = bufflen - string.len(" `...' ") | ||
129 | local l = string.len(source) | ||
130 | out = "" | ||
131 | if l > bufflen then | ||
132 | source = string.sub(source, 1 + l - bufflen) -- get last part of file name | ||
133 | out = out.."..." | ||
134 | end | ||
135 | out = out..source | ||
136 | else -- out = [string "string"] | ||
137 | local len = string.find(source, "\n", 1, 1) -- stop at first newline | ||
138 | len = len and (len - 1) or string.len(source) | ||
139 | bufflen = bufflen - string.len(" [string \"...\"] ") | ||
140 | if len > bufflen then len = bufflen end | ||
141 | out = "[string \"" | ||
142 | if len < string.len(source) then -- must truncate? | ||
143 | out = out..string.sub(source, 1, len).."..." | ||
144 | else | ||
145 | out = out..source | ||
146 | end | ||
147 | out = out.."\"]" | ||
148 | end | ||
149 | end | ||
150 | return out | ||
151 | end | ||
152 | |||
153 | --[[-------------------------------------------------------------------- | ||
154 | -- Support functions for lexer | ||
155 | -- * all lexer errors eventually reaches errorline: | ||
156 | checklimit -> syntaxerror -> error -> errorline | ||
157 | lexerror -> error -> errorline | ||
158 | ----------------------------------------------------------------------]] | ||
159 | |||
160 | ------------------------------------------------------------------------ | ||
161 | -- limit check, syntax error if fails (also called by parser) | ||
162 | ------------------------------------------------------------------------ | ||
163 | function luaX:checklimit(ls, val, limit, msg) | ||
164 | if val > limit then | ||
165 | msg = string.format("too many %s (limit=%d)", msg, limit) | ||
166 | self:syntaxerror(ls, msg) | ||
167 | end | ||
168 | end | ||
169 | |||
170 | ------------------------------------------------------------------------ | ||
171 | -- formats error message and throws error (also called by parser) | ||
172 | ------------------------------------------------------------------------ | ||
173 | function luaX:errorline(ls, s, token, line) | ||
174 | local buff = self:chunkid(ls.source, self.MAXSRC) | ||
175 | error(string.format("%s:%d: %s near `%s'", buff, line, s, token)) | ||
176 | end | ||
177 | |||
178 | ------------------------------------------------------------------------ | ||
179 | -- throws an error, adds line number | ||
180 | ------------------------------------------------------------------------ | ||
181 | function luaX:error(ls, s, token) | ||
182 | self:errorline(ls, s, token, ls.linenumber) | ||
183 | end | ||
184 | |||
185 | ------------------------------------------------------------------------ | ||
186 | -- throws a syntax error (mainly called by parser) | ||
187 | -- * ls.t.token has to be set by the function calling luaX:lex | ||
188 | -- (see next() and lookahead() in lparser.c) | ||
189 | ------------------------------------------------------------------------ | ||
190 | function luaX:syntaxerror(ls, msg) | ||
191 | local lasttoken | ||
192 | local tok = ls.t.token | ||
193 | if tok == "TK_NAME" then | ||
194 | lasttoken = ls.t.seminfo | ||
195 | elseif tok == "TK_STRING" or tok == "TK_NUMBER" then | ||
196 | lasttoken = ls.buff | ||
197 | else | ||
198 | lasttoken = self:token2str(ls.t.token) | ||
199 | end | ||
200 | self:error(ls, msg, lasttoken) | ||
201 | end | ||
202 | |||
203 | ------------------------------------------------------------------------ | ||
204 | -- look up token and return keyword if found (also called by parser) | ||
205 | ------------------------------------------------------------------------ | ||
206 | function luaX:token2str(ls, token) | ||
207 | if string.sub(token, 1, 3) ~= "TK_" then | ||
208 | return token | ||
209 | else | ||
210 | --lua_assert(string.len(token) == 1) | ||
211 | return self.token2string[token] | ||
212 | end | ||
213 | end | ||
214 | |||
215 | ------------------------------------------------------------------------ | ||
216 | -- throws a lexer error | ||
217 | ------------------------------------------------------------------------ | ||
218 | function luaX:lexerror(ls, s, token) | ||
219 | if token == "TK_EOS" then | ||
220 | self:error(ls, s, self:token2str(ls, token)) | ||
221 | else | ||
222 | self:error(ls, s, ls.buff) | ||
223 | end | ||
224 | end | ||
225 | |||
226 | ------------------------------------------------------------------------ | ||
227 | -- move on to next line | ||
228 | ------------------------------------------------------------------------ | ||
229 | function luaX:inclinenumber(LS) | ||
230 | self:next(LS) -- skip '\n' | ||
231 | LS.linenumber = LS.linenumber + 1 | ||
232 | self:checklimit(LS, LS.linenumber, self.MAX_INT, "lines in a chunk") | ||
233 | end | ||
234 | |||
235 | luaX.MAX_INT = 2147483645 -- INT_MAX-2 for 32-bit systems (llimits.h) | ||
236 | |||
237 | ------------------------------------------------------------------------ | ||
238 | -- initializes an input stream for lexing | ||
239 | -- * if LS (the lexer state) is passed as a table, then it is filled in, | ||
240 | -- otherwise it has to be retrieved as a return value | ||
241 | ------------------------------------------------------------------------ | ||
242 | function luaX:setinput(L, LS, z, source) | ||
243 | if not LS then LS = {} end -- create struct | ||
244 | if not LS.lookahead then LS.lookahead = {} end | ||
245 | if not LS.t then LS.t = {} end | ||
246 | LS.L = L | ||
247 | LS.lookahead.token = "TK_EOS" -- no look-ahead token | ||
248 | LS.z = z | ||
249 | LS.fs = nil | ||
250 | LS.linenumber = 1 | ||
251 | LS.lastline = 1 | ||
252 | LS.source = source | ||
253 | self:next(LS) -- read first char | ||
254 | if LS.current == "#" then | ||
255 | repeat -- skip first line | ||
256 | self:next(LS) | ||
257 | until LS.current == "\n" or LS.current == "EOZ" | ||
258 | end | ||
259 | return LS | ||
260 | end | ||
261 | |||
262 | --[[-------------------------------------------------------------------- | ||
263 | -- LEXICAL ANALYZER | ||
264 | ----------------------------------------------------------------------]] | ||
265 | |||
266 | -- NOTE the following buffer handling stuff are no longer required: | ||
267 | -- use buffer to store names, literal strings and numbers | ||
268 | -- EXTRABUFF deleted; extra space to allocate when growing buffer | ||
269 | -- MAXNOCHECK deleted; maximum number of chars that can be read without checking buffer size | ||
270 | -- checkbuffer(LS, len) deleted | ||
271 | |||
272 | ------------------------------------------------------------------------ | ||
273 | -- gets the next character and returns it | ||
274 | ------------------------------------------------------------------------ | ||
275 | function luaX:next(LS) | ||
276 | local c = luaZ:zgetc(LS.z) | ||
277 | LS.current = c | ||
278 | return c | ||
279 | end | ||
280 | |||
281 | ------------------------------------------------------------------------ | ||
282 | -- saves the given character into the token buffer | ||
283 | ------------------------------------------------------------------------ | ||
284 | function luaX:save(LS, c) | ||
285 | LS.buff = LS.buff..c | ||
286 | end | ||
287 | |||
288 | ------------------------------------------------------------------------ | ||
289 | -- save current character into token buffer, grabs next character | ||
290 | ------------------------------------------------------------------------ | ||
291 | function luaX:save_and_next(LS) | ||
292 | self:save(LS, LS.current) | ||
293 | return self:next(LS) | ||
294 | end | ||
295 | |||
296 | ------------------------------------------------------------------------ | ||
297 | -- reads a name | ||
298 | -- * originally returns the string length | ||
299 | ------------------------------------------------------------------------ | ||
300 | function luaX:readname(LS) | ||
301 | LS.buff = "" | ||
302 | repeat | ||
303 | self:save_and_next(LS) | ||
304 | until LS.current == "EOZ" or not string.find(LS.current, "[_%w]") | ||
305 | return LS.buff | ||
306 | end | ||
307 | |||
308 | ------------------------------------------------------------------------ | ||
309 | -- reads a number (LUA_NUMBER) | ||
310 | ------------------------------------------------------------------------ | ||
311 | function luaX:read_numeral(LS, comma, Token) | ||
312 | LS.buff = "" | ||
313 | if comma then self:save(LS, '.') end | ||
314 | while string.find(LS.current, "%d") do | ||
315 | self:save_and_next(LS) | ||
316 | end | ||
317 | if LS.current == "." then | ||
318 | self:save_and_next(LS) | ||
319 | if LS.current == "." then | ||
320 | self:save_and_next(LS) | ||
321 | self:lexerror(LS, | ||
322 | "ambiguous syntax (decimal point x string concatenation)", | ||
323 | "TK_NUMBER") | ||
324 | end | ||
325 | end | ||
326 | while string.find(LS.current, "%d") do | ||
327 | self:save_and_next(LS) | ||
328 | end | ||
329 | if LS.current == "e" or LS.current == "E" then | ||
330 | self:save_and_next(LS) -- read 'E' | ||
331 | if LS.current == "+" or LS.current == "-" then | ||
332 | self:save_and_next(LS) -- optional exponent sign | ||
333 | end | ||
334 | while string.find(LS.current, "%d") do | ||
335 | self:save_and_next(LS) | ||
336 | end | ||
337 | end | ||
338 | local seminfo = tonumber(LS.buff) | ||
339 | if not seminfo then | ||
340 | self:lexerror(LS, "malformed number", "TK_NUMBER") | ||
341 | end | ||
342 | Token.seminfo = seminfo | ||
343 | end | ||
344 | |||
345 | ------------------------------------------------------------------------ | ||
346 | -- reads a long string or long comment | ||
347 | ------------------------------------------------------------------------ | ||
348 | function luaX:read_long_string(LS, Token) | ||
349 | local cont = 0 | ||
350 | LS.buff = "" | ||
351 | self:save(LS, "[") -- save first '[' | ||
352 | self:save_and_next(LS) -- pass the second '[' | ||
353 | if LS.current == "\n" then -- string starts with a newline? | ||
354 | self:inclinenumber(LS) -- skip it | ||
355 | end | ||
356 | while true do | ||
357 | local c = LS.current | ||
358 | if c == "EOZ" then | ||
359 | self:lexerror(LS, Token and "unfinished long string" or | ||
360 | "unfinished long comment", "TK_EOS") | ||
361 | elseif c == "[" then | ||
362 | self:save_and_next(LS) | ||
363 | if LS.current == "[" then | ||
364 | cont = cont + 1 | ||
365 | self:save_and_next(LS) | ||
366 | end | ||
367 | elseif c == "]" then | ||
368 | self:save_and_next(LS) | ||
369 | if LS.current == "]" then | ||
370 | if cont == 0 then break end | ||
371 | cont = cont - 1 | ||
372 | self:save_and_next(LS) | ||
373 | end | ||
374 | elseif c == "\n" then | ||
375 | self:save(LS, "\n") | ||
376 | self:inclinenumber(LS) | ||
377 | if not Token then LS.buff = "" end -- reset buffer to avoid wasting space | ||
378 | else | ||
379 | self:save_and_next(LS) | ||
380 | end--if c | ||
381 | end--while | ||
382 | self:save_and_next(LS) -- skip the second ']' | ||
383 | if Token then | ||
384 | Token.seminfo = string.sub(LS.buff, 3, -3) | ||
385 | end | ||
386 | end | ||
387 | |||
388 | ------------------------------------------------------------------------ | ||
389 | -- reads a string | ||
390 | ------------------------------------------------------------------------ | ||
391 | function luaX:read_string(LS, del, Token) | ||
392 | LS.buff = "" | ||
393 | self:save_and_next(LS) | ||
394 | while LS.current ~= del do | ||
395 | local c = LS.current | ||
396 | if c == "EOZ" then | ||
397 | self:lexerror(LS, "unfinished string", "TK_EOS") | ||
398 | elseif c == "\n" then | ||
399 | self:lexerror(LS, "unfinished string", "TK_STRING") | ||
400 | elseif c == "\\" then | ||
401 | c = self:next(LS) -- do not save the '\' | ||
402 | if c ~= "EOZ" then -- will raise an error next loop | ||
403 | -- escapes handling greatly simplified here: | ||
404 | local i = string.find("abfnrtv\n", c, 1, 1) | ||
405 | if i then | ||
406 | self:save(LS, string.sub("\a\b\f\n\r\t\v\n", i, i)) | ||
407 | if i == 8 then self:inclinenumber(LS) else self:next(LS) end | ||
408 | elseif not string.find(c, "%d") then | ||
409 | self:save_and_next(LS) -- handles \\, \", \', and \? | ||
410 | else -- \xxx | ||
411 | c, i = 0, 0 | ||
412 | repeat | ||
413 | c = 10 * c + LS.current | ||
414 | self:next(LS) | ||
415 | i = i + 1 | ||
416 | until i >= 3 or not string.find(LS.current, "%d") | ||
417 | if c > 255 then -- UCHAR_MAX | ||
418 | self:lexerror(LS, "escape sequence too large", "TK_STRING") | ||
419 | end | ||
420 | self:save(LS, string.char(c)) | ||
421 | end | ||
422 | end | ||
423 | else | ||
424 | self:save_and_next(LS) | ||
425 | end--if c | ||
426 | end--while | ||
427 | self:save_and_next(LS) -- skip delimiter | ||
428 | Token.seminfo = string.sub(LS.buff, 2, -2) | ||
429 | end | ||
430 | |||
431 | ------------------------------------------------------------------------ | ||
432 | -- main lexer function | ||
433 | ------------------------------------------------------------------------ | ||
434 | function luaX:lex(LS, Token) | ||
435 | while true do | ||
436 | local c = LS.current | ||
437 | ---------------------------------------------------------------- | ||
438 | if c == "\n" then | ||
439 | self:inclinenumber(LS) | ||
440 | ---------------------------------------------------------------- | ||
441 | elseif c == "-" then | ||
442 | c = self:next(LS) | ||
443 | if c ~= "-" then return "-" end | ||
444 | -- else is a comment | ||
445 | c = self:next(LS) | ||
446 | if c == "[" and self:next(LS) == "[" then | ||
447 | self:read_long_string(LS) -- long comment | ||
448 | else -- short comment | ||
449 | c = LS.current | ||
450 | while c ~= "\n" and c ~= "EOZ" do | ||
451 | c = self:next(LS) | ||
452 | end | ||
453 | end | ||
454 | ---------------------------------------------------------------- | ||
455 | elseif c == "[" then | ||
456 | c = self:next(LS) | ||
457 | if c ~= "[" then return "[" | ||
458 | else | ||
459 | self:read_long_string(LS, Token) | ||
460 | return "TK_STRING" | ||
461 | end | ||
462 | ---------------------------------------------------------------- | ||
463 | elseif c == "=" then | ||
464 | c = self:next(LS) | ||
465 | if c ~= "=" then return "=" | ||
466 | else self:next(LS); return "TK_EQ" end | ||
467 | ---------------------------------------------------------------- | ||
468 | elseif c == "<" then | ||
469 | c = self:next(LS) | ||
470 | if c ~= "=" then return "<" | ||
471 | else self:next(LS); return "TK_LE" end | ||
472 | ---------------------------------------------------------------- | ||
473 | elseif c == ">" then | ||
474 | c = self:next(LS) | ||
475 | if c ~= "=" then return ">" | ||
476 | else self:next(LS); return "TK_GE" end | ||
477 | ---------------------------------------------------------------- | ||
478 | elseif c == "~" then | ||
479 | c = self:next(LS) | ||
480 | if c ~= "=" then return "~" | ||
481 | else self:next(LS); return "TK_NE" end | ||
482 | ---------------------------------------------------------------- | ||
483 | elseif c == "\"" or c == "'" then | ||
484 | self:read_string(LS, c, Token) | ||
485 | return "TK_STRING" | ||
486 | ---------------------------------------------------------------- | ||
487 | elseif c == "." then | ||
488 | c = self:next(LS) | ||
489 | if c == "." then | ||
490 | c = self:next(LS) | ||
491 | if c == "." then | ||
492 | self:next(LS) | ||
493 | return "TK_DOTS" -- ... | ||
494 | else | ||
495 | return "TK_CONCAT" -- .. | ||
496 | end | ||
497 | elseif not string.find(c, "%d") then | ||
498 | return '.' | ||
499 | else | ||
500 | self:read_numeral(LS, true, Token) | ||
501 | return "TK_NUMBER" | ||
502 | end | ||
503 | ---------------------------------------------------------------- | ||
504 | elseif c == "EOZ" then | ||
505 | return "TK_EOS" | ||
506 | ---------------------------------------------------------------- | ||
507 | else -- default | ||
508 | if string.find(c, "%s") then | ||
509 | self:next(LS) | ||
510 | elseif string.find(c, "%d") then | ||
511 | self:read_numeral(LS, false, Token) | ||
512 | return "TK_NUMBER" | ||
513 | elseif string.find(c, "[_%a]") then | ||
514 | -- identifier or reserved word | ||
515 | local l = self:readname(LS) | ||
516 | local tok = self.string2token[l] | ||
517 | if tok then return tok end -- reserved word? | ||
518 | Token.seminfo = l | ||
519 | return "TK_NAME" | ||
520 | else | ||
521 | if string.find(c, "%c") then | ||
522 | self:error(LS, "invalid control char", | ||
523 | string.format("char(%d)", string.byte(c))) | ||
524 | end | ||
525 | self:next(LS) | ||
526 | return c -- single-char tokens (+ - / ...) | ||
527 | end | ||
528 | ---------------------------------------------------------------- | ||
529 | end--if c | ||
530 | end--while | ||
531 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lopcodes.lua | ||
4 | Lua 5 virtual machine opcodes in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * an Instruction is a table with OP, A, B, C, Bx elements; this | ||
18 | -- should allow instruction handling to work with doubles and ints | ||
19 | -- * Added: | ||
20 | -- luaP:Instruction(i): convert field elements to a 4-char string | ||
21 | -- luaP:DecodeInst(x): convert 4-char string into field elements | ||
22 | -- * WARNING luaP:Instruction outputs instructions encoded in little- | ||
23 | -- endian form and field size and positions are hard-coded | ||
24 | ----------------------------------------------------------------------]] | ||
25 | |||
26 | luaP = {} | ||
27 | |||
28 | --[[ | ||
29 | =========================================================================== | ||
30 | We assume that instructions are unsigned numbers. | ||
31 | All instructions have an opcode in the first 6 bits. | ||
32 | Instructions can have the following fields: | ||
33 | 'A' : 8 bits | ||
34 | 'B' : 9 bits | ||
35 | 'C' : 9 bits | ||
36 | 'Bx' : 18 bits ('B' and 'C' together) | ||
37 | 'sBx' : signed Bx | ||
38 | |||
39 | A signed argument is represented in excess K; that is, the number | ||
40 | value is the unsigned value minus K. K is exactly the maximum value | ||
41 | for that argument (so that -max is represented by 0, and +max is | ||
42 | represented by 2*max), which is half the maximum for the corresponding | ||
43 | unsigned argument. | ||
44 | =========================================================================== | ||
45 | --]] | ||
46 | |||
47 | luaP.OpMode = {"iABC", "iABx", "iAsBx"} -- basic instruction format | ||
48 | |||
49 | ------------------------------------------------------------------------ | ||
50 | -- size and position of opcode arguments. | ||
51 | -- * WARNING size and position is hard-coded elsewhere in this script | ||
52 | ------------------------------------------------------------------------ | ||
53 | luaP.SIZE_C = 9 | ||
54 | luaP.SIZE_B = 9 | ||
55 | luaP.SIZE_Bx = luaP.SIZE_C + luaP.SIZE_B | ||
56 | luaP.SIZE_A = 8 | ||
57 | |||
58 | luaP.SIZE_OP = 6 | ||
59 | |||
60 | luaP.POS_C = luaP.SIZE_OP | ||
61 | luaP.POS_B = luaP.POS_C + luaP.SIZE_C | ||
62 | luaP.POS_Bx = luaP.POS_C | ||
63 | luaP.POS_A = luaP.POS_B + luaP.SIZE_B | ||
64 | |||
65 | ------------------------------------------------------------------------ | ||
66 | -- limits for opcode arguments. | ||
67 | -- we use (signed) int to manipulate most arguments, | ||
68 | -- so they must fit in BITS_INT-1 bits (-1 for sign) | ||
69 | ------------------------------------------------------------------------ | ||
70 | -- removed "#if SIZE_Bx < BITS_INT-1" test, assume this script is | ||
71 | -- running on a Lua VM with double or int as LUA_NUMBER | ||
72 | |||
73 | luaP.MAXARG_Bx = math.ldexp(1, luaP.SIZE_Bx) - 1 | ||
74 | luaP.MAXARG_sBx = math.floor(luaP.MAXARG_Bx / 2) -- 'sBx' is signed | ||
75 | |||
76 | luaP.MAXARG_A = math.ldexp(1, luaP.SIZE_A) - 1 | ||
77 | luaP.MAXARG_B = math.ldexp(1, luaP.SIZE_B) - 1 | ||
78 | luaP.MAXARG_C = math.ldexp(1, luaP.SIZE_C) - 1 | ||
79 | |||
80 | -- creates a mask with 'n' 1 bits at position 'p' | ||
81 | -- MASK1(n,p) deleted | ||
82 | -- creates a mask with 'n' 0 bits at position 'p' | ||
83 | -- MASK0(n,p) deleted | ||
84 | |||
85 | --[[-------------------------------------------------------------------- | ||
86 | Visual representation for reference: | ||
87 | |||
88 | 31 | | | 0 bit position | ||
89 | +-----+-----+-----+----------+ | ||
90 | | A | B | C | Opcode | iABC format | ||
91 | +-----+-----+-----+----------+ | ||
92 | - 8 - 9 - 9 - 6 - field sizes | ||
93 | +-----+-----+-----+----------+ | ||
94 | | A | [s]Bx | Opcode | iABx | iAsBx format | ||
95 | +-----+-----+-----+----------+ | ||
96 | ----------------------------------------------------------------------]] | ||
97 | |||
98 | ------------------------------------------------------------------------ | ||
99 | -- the following macros help to manipulate instructions | ||
100 | -- * changed to a table object representation, very clean compared to | ||
101 | -- the [nightmare] alternatives of using a number or a string | ||
102 | ------------------------------------------------------------------------ | ||
103 | |||
104 | -- these accept or return opcodes in the form of string names | ||
105 | function luaP:GET_OPCODE(i) return self.ROpCode[i.OP] end | ||
106 | function luaP:SET_OPCODE(i, o) i.OP = self.OpCode[o] end | ||
107 | |||
108 | function luaP:GETARG_A(i) return i.A end | ||
109 | function luaP:SETARG_A(i, u) i.A = u end | ||
110 | |||
111 | function luaP:GETARG_B(i) return i.B end | ||
112 | function luaP:SETARG_B(i, b) i.B = b end | ||
113 | |||
114 | function luaP:GETARG_C(i) return i.C end | ||
115 | function luaP:SETARG_C(i, b) i.C = b end | ||
116 | |||
117 | function luaP:GETARG_Bx(i) return i.Bx end | ||
118 | function luaP:SETARG_Bx(i, b) i.Bx = b end | ||
119 | |||
120 | function luaP:GETARG_sBx(i) return i.Bx - self.MAXARG_sBx end | ||
121 | function luaP:SETARG_sBx(i, b) i.Bx = b + self.MAXARG_sBx end | ||
122 | |||
123 | function luaP:CREATE_ABC(o,a,b,c) | ||
124 | return {OP = self.OpCode[o], A = a, B = b, C = c} | ||
125 | end | ||
126 | |||
127 | function luaP:CREATE_ABx(o,a,bc) | ||
128 | return {OP = self.OpCode[o], A = a, Bx = bc} | ||
129 | end | ||
130 | |||
131 | ------------------------------------------------------------------------ | ||
132 | -- returns a 4-char string little-endian encoded form of an instruction | ||
133 | ------------------------------------------------------------------------ | ||
134 | function luaP:Instruction(i) | ||
135 | local I, c0, c1, c2, c3 | ||
136 | if i.Bx then | ||
137 | -- change to OP/A/B/C format | ||
138 | i.C = math.mod(i.Bx, 512) | ||
139 | i.B = math.floor(i.Bx / 512) | ||
140 | end | ||
141 | I = i.C * 64 + i.OP | ||
142 | c0 = math.mod(I, 256) | ||
143 | I = i.B * 128 + math.floor(I / 256) -- 7 bits of C left | ||
144 | c1 = math.mod(I, 256) | ||
145 | I = math.floor(I / 256) -- 8 bits of B left | ||
146 | c2 = math.mod(I, 256) | ||
147 | c3 = math.mod(i.A, 256) | ||
148 | return string.char(c0, c1, c2, c3) | ||
149 | end | ||
150 | |||
151 | ------------------------------------------------------------------------ | ||
152 | -- decodes a 4-char little-endian string into an instruction struct | ||
153 | ------------------------------------------------------------------------ | ||
154 | function luaP:DecodeInst(x) | ||
155 | local i = {} | ||
156 | local I = string.byte(x, 1) | ||
157 | local op = math.mod(I, 64) | ||
158 | i.OP = op | ||
159 | I = string.byte(x, 2) * 4 + math.floor(I / 64) -- 2 bits of c0 left | ||
160 | i.C = math.mod(I, 512) | ||
161 | i.B = string.byte(x, 3) * 2 + math.floor(I / 128) -- 1 bit of c2 left | ||
162 | i.A = string.byte(x, 4) | ||
163 | local opmode = self.OpMode[tonumber(string.sub(self.opmodes[op + 1], 7, 7))] | ||
164 | if opmode ~= "iABC" then | ||
165 | i.Bx = i.B * 512 + i.C | ||
166 | end | ||
167 | return i | ||
168 | end | ||
169 | |||
170 | ------------------------------------------------------------------------ | ||
171 | -- invalid register that fits in 8 bits | ||
172 | ------------------------------------------------------------------------ | ||
173 | luaP.NO_REG = luaP.MAXARG_A | ||
174 | |||
175 | ------------------------------------------------------------------------ | ||
176 | -- R(x) - register | ||
177 | -- Kst(x) - constant (in constant table) | ||
178 | -- RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK) | ||
179 | ------------------------------------------------------------------------ | ||
180 | |||
181 | ------------------------------------------------------------------------ | ||
182 | -- grep "ORDER OP" if you change these enums | ||
183 | ------------------------------------------------------------------------ | ||
184 | |||
185 | --[[-------------------------------------------------------------------- | ||
186 | Lua virtual machine opcodes (enum OpCode): | ||
187 | ------------------------------------------------------------------------ | ||
188 | name args description | ||
189 | ------------------------------------------------------------------------ | ||
190 | OP_MOVE A B R(A) := R(B) | ||
191 | OP_LOADK A Bx R(A) := Kst(Bx) | ||
192 | OP_LOADBOOL A B C R(A) := (Bool)B; if (C) PC++ | ||
193 | OP_LOADNIL A B R(A) := ... := R(B) := nil | ||
194 | OP_GETUPVAL A B R(A) := UpValue[B] | ||
195 | OP_GETGLOBAL A Bx R(A) := Gbl[Kst(Bx)] | ||
196 | OP_GETTABLE A B C R(A) := R(B)[RK(C)] | ||
197 | OP_SETGLOBAL A Bx Gbl[Kst(Bx)] := R(A) | ||
198 | OP_SETUPVAL A B UpValue[B] := R(A) | ||
199 | OP_SETTABLE A B C R(A)[RK(B)] := RK(C) | ||
200 | OP_NEWTABLE A B C R(A) := {} (size = B,C) | ||
201 | OP_SELF A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] | ||
202 | OP_ADD A B C R(A) := RK(B) + RK(C) | ||
203 | OP_SUB A B C R(A) := RK(B) - RK(C) | ||
204 | OP_MUL A B C R(A) := RK(B) * RK(C) | ||
205 | OP_DIV A B C R(A) := RK(B) / RK(C) | ||
206 | OP_POW A B C R(A) := RK(B) ^ RK(C) | ||
207 | OP_UNM A B R(A) := -R(B) | ||
208 | OP_NOT A B R(A) := not R(B) | ||
209 | OP_CONCAT A B C R(A) := R(B).. ... ..R(C) | ||
210 | OP_JMP sBx PC += sBx | ||
211 | OP_EQ A B C if ((RK(B) == RK(C)) ~= A) then pc++ | ||
212 | OP_LT A B C if ((RK(B) < RK(C)) ~= A) then pc++ | ||
213 | OP_LE A B C if ((RK(B) <= RK(C)) ~= A) then pc++ | ||
214 | OP_TEST A B C if (R(B) <=> C) then R(A) := R(B) else pc++ | ||
215 | OP_CALL A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) | ||
216 | OP_TAILCALL A B C return R(A)(R(A+1), ... ,R(A+B-1)) | ||
217 | OP_RETURN A B return R(A), ... ,R(A+B-2) (see note) | ||
218 | OP_FORLOOP A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx | ||
219 | OP_TFORLOOP A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); | ||
220 | if R(A+2) ~= nil then pc++ | ||
221 | OP_TFORPREP A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next; | ||
222 | PC += sBx | ||
223 | OP_SETLIST A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 | ||
224 | OP_SETLISTO A Bx (see note) | ||
225 | OP_CLOSE A close all variables in the stack up to (>=) R(A) | ||
226 | OP_CLOSURE A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) | ||
227 | ----------------------------------------------------------------------]] | ||
228 | |||
229 | luaP.opnames = {} -- opcode names | ||
230 | luaP.OpCode = {} -- lookup name -> number | ||
231 | luaP.ROpCode = {} -- lookup number -> name | ||
232 | |||
233 | -- ORDER OP | ||
234 | local i = 0 | ||
235 | for v in string.gfind([[ | ||
236 | MOVE LOADK LOADBOOL LOADNIL GETUPVAL | ||
237 | GETGLOBAL GETTABLE SETGLOBAL SETUPVAL SETTABLE | ||
238 | NEWTABLE SELF ADD SUB MUL | ||
239 | DIV POW UNM NOT CONCAT | ||
240 | JMP EQ LT LE TEST | ||
241 | CALL TAILCALL RETURN FORLOOP TFORLOOP | ||
242 | TFORPREP SETLIST SETLISTO CLOSE CLOSURE | ||
243 | ]], "%S+") do | ||
244 | local n = "OP_"..v | ||
245 | luaP.opnames[i] = v | ||
246 | luaP.OpCode[n] = i | ||
247 | luaP.ROpCode[i] = n | ||
248 | i = i + 1 | ||
249 | end | ||
250 | luaP.NUM_OPCODES = i | ||
251 | |||
252 | --[[ | ||
253 | =========================================================================== | ||
254 | Notes: | ||
255 | (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, | ||
256 | and can be 0: OP_CALL then sets 'top' to last_result+1, so | ||
257 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use 'top'. | ||
258 | |||
259 | (2) In OP_RETURN, if (B == 0) then return up to 'top' | ||
260 | |||
261 | (3) For comparisons, B specifies what conditions the test should accept. | ||
262 | |||
263 | (4) All 'skips' (pc++) assume that next instruction is a jump | ||
264 | |||
265 | (5) OP_SETLISTO is used when the last item in a table constructor is a | ||
266 | function, so the number of elements set is up to top of stack | ||
267 | =========================================================================== | ||
268 | --]] | ||
269 | |||
270 | ------------------------------------------------------------------------ | ||
271 | -- masks for instruction properties | ||
272 | ------------------------------------------------------------------------ | ||
273 | -- was enum OpModeMask: | ||
274 | luaP.OpModeBreg = 2 -- B is a register | ||
275 | luaP.OpModeBrk = 3 -- B is a register/constant | ||
276 | luaP.OpModeCrk = 4 -- C is a register/constant | ||
277 | luaP.OpModesetA = 5 -- instruction set register A | ||
278 | luaP.OpModeK = 6 -- Bx is a constant | ||
279 | luaP.OpModeT = 1 -- operator is a test | ||
280 | |||
281 | ------------------------------------------------------------------------ | ||
282 | -- get opcode mode, e.g. "iABC" | ||
283 | ------------------------------------------------------------------------ | ||
284 | function luaP:getOpMode(m) | ||
285 | return self.OpMode[tonumber(string.sub(self.opmodes[self.OpCode[m] + 1], 7, 7))] | ||
286 | end | ||
287 | |||
288 | ------------------------------------------------------------------------ | ||
289 | -- test an instruction property flag | ||
290 | -- * b is a string, e.g. "OpModeBreg" | ||
291 | ------------------------------------------------------------------------ | ||
292 | function luaP:testOpMode(m, b) | ||
293 | return (string.sub(self.opmodes[self.OpCode[m] + 1], self[b], self[b]) == "1") | ||
294 | end | ||
295 | |||
296 | -- number of list items to accumulate before a SETLIST instruction | ||
297 | -- (must be a power of 2) | ||
298 | -- * used in lparser, lvm, ldebug, ltests | ||
299 | luaP.LFIELDS_PER_FLUSH = 32 | ||
300 | |||
301 | -- luaP_opnames[] is set above, as the luaP.opnames table | ||
302 | -- opmode(t,b,bk,ck,sa,k,m) deleted | ||
303 | |||
304 | --[[-------------------------------------------------------------------- | ||
305 | Legend for luaP:opmodes: | ||
306 | T -> T B -> B mode -> m, where iABC = 1 | ||
307 | Bk -> b Ck -> C iABx = 2 | ||
308 | sA -> A K -> K iAsBx = 3 | ||
309 | ----------------------------------------------------------------------]] | ||
310 | |||
311 | -- ORDER OP | ||
312 | luaP.opmodes = { | ||
313 | -- TBbCAKm opcode | ||
314 | "0100101", -- OP_MOVE | ||
315 | "0000112", -- OP_LOADK | ||
316 | "0000101", -- OP_LOADBOOL | ||
317 | "0100101", -- OP_LOADNIL | ||
318 | "0000101", -- OP_GETUPVAL | ||
319 | "0000112", -- OP_GETGLOBAL | ||
320 | "0101101", -- OP_GETTABLE | ||
321 | "0000012", -- OP_SETGLOBAL | ||
322 | "0000001", -- OP_SETUPVAL | ||
323 | "0011001", -- OP_SETTABLE | ||
324 | "0000101", -- OP_NEWTABLE | ||
325 | "0101101", -- OP_SELF | ||
326 | "0011101", -- OP_ADD | ||
327 | "0011101", -- OP_SUB | ||
328 | "0011101", -- OP_MUL | ||
329 | "0011101", -- OP_DIV | ||
330 | "0011101", -- OP_POW | ||
331 | "0100101", -- OP_UNM | ||
332 | "0100101", -- OP_NOT | ||
333 | "0101101", -- OP_CONCAT | ||
334 | "0000003", -- OP_JMP | ||
335 | "1011001", -- OP_EQ | ||
336 | "1011001", -- OP_LT | ||
337 | "1011001", -- OP_LE | ||
338 | "1100101", -- OP_TEST | ||
339 | "0000001", -- OP_CALL | ||
340 | "0000001", -- OP_TAILCALL | ||
341 | "0000001", -- OP_RETURN | ||
342 | "0000003", -- OP_FORLOOP | ||
343 | "1000001", -- OP_TFORLOOP | ||
344 | "0000003", -- OP_TFORPREP | ||
345 | "0000002", -- OP_SETLIST | ||
346 | "0000002", -- OP_SETLISTO | ||
347 | "0000001", -- OP_CLOSE | ||
348 | "0000102", -- OP_CLOSURE | ||
349 | } | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lparser.lua | ||
4 | Lua 5 parser in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * LUA_COMPATUPSYNTAX option changed into a comment block | ||
18 | -- * Added: | ||
19 | -- some constants, see below | ||
20 | -- luaY:newproto (from lfunc.c) -- called by lparser, lundump, luac | ||
21 | -- luaY:int2fb (from lobject.c) -- called by lparser, ltests | ||
22 | -- luaY:log2 (from lobject.c) -- called by lparser, ltests, ltable | ||
23 | -- luaY:growvector (from lmem.h) -- skeleton only, limit checking | ||
24 | -- * Unimplemented: | ||
25 | -- luaG_checkcode() in lua_assert is not currently implemented | ||
26 | ----------------------------------------------------------------------]] | ||
27 | |||
28 | --requires luaP, luaX, luaK | ||
29 | luaY = {} | ||
30 | |||
31 | ------------------------------------------------------------------------ | ||
32 | -- constants used by parser | ||
33 | -- * MAX_INT duplicated in luaX.MAX_INT | ||
34 | ------------------------------------------------------------------------ | ||
35 | luaY.MAX_INT = 2147483645 -- INT_MAX-2 for 32-bit systems (llimits.h) | ||
36 | luaY.MAXVARS = 200 -- (llimits.h) | ||
37 | luaY.MAXUPVALUES = 32 -- (llimits.h) | ||
38 | luaY.MAXPARAMS = 100 -- (llimits.h) | ||
39 | luaY.LUA_MAXPARSERLEVEL = 200 -- (llimits.h) | ||
40 | luaY.LUA_MULTRET = -1 -- (lua.h) | ||
41 | luaY.MAXSTACK = 250 -- (llimits.h, used in lcode.lua) | ||
42 | |||
43 | ------------------------------------------------------------------------ | ||
44 | -- Expression descriptor | ||
45 | ------------------------------------------------------------------------ | ||
46 | |||
47 | --[[-------------------------------------------------------------------- | ||
48 | -- * expkind changed to string constants; luaY:assignment was the only | ||
49 | -- function to use a relational operator with this enumeration | ||
50 | -- VVOID -- no value | ||
51 | -- VNIL -- no value | ||
52 | -- VTRUE -- no value | ||
53 | -- VFALSE -- no value | ||
54 | -- VK -- info = index of constant in 'k' | ||
55 | -- VLOCAL -- info = local register | ||
56 | -- VUPVAL, -- info = index of upvalue in 'upvalues' | ||
57 | -- VGLOBAL -- info = index of table; aux = index of global name in 'k' | ||
58 | -- VINDEXED -- info = table register; aux = index register (or 'k') | ||
59 | -- VJMP -- info = instruction pc | ||
60 | -- VRELOCABLE -- info = instruction pc | ||
61 | -- VNONRELOC -- info = result register | ||
62 | -- VCALL -- info = result register | ||
63 | ----------------------------------------------------------------------]] | ||
64 | |||
65 | --[[-------------------------------------------------------------------- | ||
66 | -- struct expdesc: | ||
67 | -- k -- (enum: expkind) | ||
68 | -- info, aux | ||
69 | -- t -- patch list of 'exit when true' | ||
70 | -- f -- patch list of 'exit when false' | ||
71 | ----------------------------------------------------------------------]] | ||
72 | |||
73 | --[[-------------------------------------------------------------------- | ||
74 | -- state needed to generate code for a given function | ||
75 | -- struct FuncState: | ||
76 | -- f -- current function header (table: Proto) | ||
77 | -- h -- table to find (and reuse) elements in 'k' (table: Table) | ||
78 | -- prev -- enclosing function (table: FuncState) | ||
79 | -- ls -- lexical state (table: LexState) | ||
80 | -- L -- copy of the Lua state (table: lua_State) | ||
81 | -- bl -- chain of current blocks (table: BlockCnt) | ||
82 | -- pc -- next position to code (equivalent to 'ncode') | ||
83 | -- lasttarget -- 'pc' of last 'jump target' | ||
84 | -- jpc -- list of pending jumps to 'pc' | ||
85 | -- freereg -- first free register | ||
86 | -- nk -- number of elements in 'k' | ||
87 | -- np -- number of elements in 'p' | ||
88 | -- nlocvars -- number of elements in 'locvars' | ||
89 | -- nactvar -- number of active local variables | ||
90 | -- upvalues[MAXUPVALUES] -- upvalues (table: expdesc) | ||
91 | -- actvar[MAXVARS] -- declared-variable stack | ||
92 | ----------------------------------------------------------------------]] | ||
93 | |||
94 | ------------------------------------------------------------------------ | ||
95 | -- converts an integer to a "floating point byte", represented as | ||
96 | -- (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm) | ||
97 | ------------------------------------------------------------------------ | ||
98 | |||
99 | function luaY:int2fb(x) | ||
100 | local m = 0 -- mantissa | ||
101 | while x >= 8 do | ||
102 | x = math.floor((x + 1) / 2) | ||
103 | m = m + 1 | ||
104 | end | ||
105 | return m * 8 + x | ||
106 | end | ||
107 | |||
108 | ------------------------------------------------------------------------ | ||
109 | -- calculates log value for encoding the hash portion's size | ||
110 | -- * there are 2 implementations: the shorter one uses math.frexp | ||
111 | -- while the other one is based on the original code, so pick one... | ||
112 | -- * since LUA_NUMBER is assumed to be a double elsewhere, the | ||
113 | -- shorter version works fine | ||
114 | ------------------------------------------------------------------------ | ||
115 | --[[ | ||
116 | function luaY:log2(x) | ||
117 | -- this is based on the original lua0_log2 in lobject.c | ||
118 | local log_8 = { -- index starts from 1 | ||
119 | 0, | ||
120 | 1,1, | ||
121 | 2,2,2,2, | ||
122 | 3,3,3,3,3,3,3,3, | ||
123 | 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, | ||
124 | 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, | ||
125 | 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, | ||
126 | 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, | ||
127 | 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, | ||
128 | 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, | ||
129 | 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, | ||
130 | 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 | ||
131 | } | ||
132 | if x >= 65536 then | ||
133 | if x >= 16777216 then | ||
134 | return log_8[math.mod(math.floor(x / 16777216), 256)] + 24 | ||
135 | else | ||
136 | return log_8[math.mod(math.floor(x / 65536), 256)] + 16 | ||
137 | end | ||
138 | else | ||
139 | if x >= 256 then | ||
140 | return log_8[math.mod(math.floor(x / 256), 256)] + 8 | ||
141 | elseif x > 0 then | ||
142 | return log_8[math.mod(x, 256)] | ||
143 | end | ||
144 | return -1 -- special 'log' for 0 | ||
145 | end | ||
146 | end | ||
147 | --]] | ||
148 | -- [[ | ||
149 | function luaY:log2(x) | ||
150 | -- math result is always one more than lua0_log2() | ||
151 | local mn, ex = math.frexp(x) | ||
152 | return ex - 1 | ||
153 | end | ||
154 | --]] | ||
155 | |||
156 | ------------------------------------------------------------------------ | ||
157 | -- this is a stripped-down luaM_growvector (from lmem.h) which is a | ||
158 | -- macro based on luaM_growaux (in lmem.c); all this function does is | ||
159 | -- reproduce the size limit checking logic of the original function | ||
160 | -- so that error behaviour is identical; all arguments preserved for | ||
161 | -- convenience, even those which are unused | ||
162 | -- * set the t field to nil, since this originally does a sizeof(t) | ||
163 | -- * size (originally a pointer) is never updated, their final values | ||
164 | -- are set by luaY:close_func(), so overall things should still work | ||
165 | ------------------------------------------------------------------------ | ||
166 | function luaY:growvector(L, v, nelems, size, t, limit, e) | ||
167 | local MINSIZEARRAY = 4 -- defined in lmem.c | ||
168 | -- still have at least MINSIZEARRAY free places | ||
169 | if nelems >= limit - MINSIZEARRAY then | ||
170 | luaX:syntaxerror(ls, e) | ||
171 | end | ||
172 | end | ||
173 | |||
174 | -- getlocvar(fs, i) has been placed with functions for locals, changed | ||
175 | -- into a function | ||
176 | |||
177 | ------------------------------------------------------------------------ | ||
178 | -- tracks and limits parsing depth, assert check at end of parsing | ||
179 | ------------------------------------------------------------------------ | ||
180 | function luaY:enterlevel(ls) | ||
181 | ls.nestlevel = ls.nestlevel + 1 | ||
182 | if ls.nestlevel > self.LUA_MAXPARSERLEVEL then | ||
183 | luaX:syntaxerror(ls, "too many syntax levels") | ||
184 | end | ||
185 | end | ||
186 | |||
187 | ------------------------------------------------------------------------ | ||
188 | -- tracks parsing depth, a pair with luaY:enterlevel() | ||
189 | ------------------------------------------------------------------------ | ||
190 | function luaY:leavelevel(ls) | ||
191 | ls.nestlevel = ls.nestlevel - 1 | ||
192 | end | ||
193 | |||
194 | ------------------------------------------------------------------------ | ||
195 | -- nodes for block list (list of active blocks) | ||
196 | ------------------------------------------------------------------------ | ||
197 | --[[-------------------------------------------------------------------- | ||
198 | -- struct BlockCnt: | ||
199 | -- previous -- chain (table: struct BlockCnt) | ||
200 | -- breaklist -- list of jumps out of this loop | ||
201 | -- nactvar -- # active local variables outside the breakable structure | ||
202 | -- upval -- true if some variable in the block is an upvalue (boolean) | ||
203 | -- isbreakable -- true if 'block' is a loop (boolean) | ||
204 | ----------------------------------------------------------------------]] | ||
205 | |||
206 | ------------------------------------------------------------------------ | ||
207 | -- prototypes for recursive non-terminal functions | ||
208 | ------------------------------------------------------------------------ | ||
209 | -- prototypes deleted; not required in Lua | ||
210 | |||
211 | ------------------------------------------------------------------------ | ||
212 | -- reads in next token | ||
213 | -- * luaX:lex fills in ls.t.seminfo too, lookahead is handled | ||
214 | ------------------------------------------------------------------------ | ||
215 | function luaY:next(ls) | ||
216 | ls.lastline = ls.linenumber | ||
217 | if ls.lookahead.token ~= "TK_EOS" then -- is there a look-ahead token? | ||
218 | ls.t.token = ls.lookahead.token -- use this one | ||
219 | ls.t.seminfo = ls.lookahead.seminfo | ||
220 | ls.lookahead.token = "TK_EOS" -- and discharge it | ||
221 | else | ||
222 | ls.t.token = luaX:lex(ls, ls.t) -- read next token | ||
223 | end | ||
224 | end | ||
225 | |||
226 | ------------------------------------------------------------------------ | ||
227 | -- peek at next token (single lookahead only) | ||
228 | ------------------------------------------------------------------------ | ||
229 | function luaY:lookahead(ls) | ||
230 | lua_assert(ls.lookahead.token == "TK_EOS") | ||
231 | ls.lookahead.token = luaX:lex(ls, ls.lookahead) | ||
232 | end | ||
233 | |||
234 | ------------------------------------------------------------------------ | ||
235 | -- throws a syntax error if token expected is not there | ||
236 | ------------------------------------------------------------------------ | ||
237 | function luaY:error_expected(ls, token) | ||
238 | luaX:syntaxerror(ls, | ||
239 | string.format("`%s' expected", luaX:token2str(ls, token))) | ||
240 | end | ||
241 | |||
242 | ------------------------------------------------------------------------ | ||
243 | -- tests for a token, returns outcome | ||
244 | -- * return value changed to boolean | ||
245 | ------------------------------------------------------------------------ | ||
246 | function luaY:testnext(ls, c) | ||
247 | if ls.t.token == c then | ||
248 | self:next(ls) | ||
249 | return true | ||
250 | else | ||
251 | return false | ||
252 | end | ||
253 | end | ||
254 | |||
255 | ------------------------------------------------------------------------ | ||
256 | -- check for existence of a token, throws error if not found | ||
257 | ------------------------------------------------------------------------ | ||
258 | function luaY:check(ls, c) | ||
259 | if not self:testnext(ls, c) then | ||
260 | self:error_expected(ls, c) | ||
261 | end | ||
262 | end | ||
263 | |||
264 | ------------------------------------------------------------------------ | ||
265 | -- throws error if condition not matched | ||
266 | ------------------------------------------------------------------------ | ||
267 | function luaY:check_condition(ls, c, msg) | ||
268 | if not c then luaX:syntaxerror(ls, msg) end | ||
269 | end | ||
270 | |||
271 | ------------------------------------------------------------------------ | ||
272 | -- verifies token conditions are met or else throw error | ||
273 | ------------------------------------------------------------------------ | ||
274 | function luaY:check_match(ls, what, who, where) | ||
275 | if not self:testnext(ls, what) then | ||
276 | if where == ls.linenumber then | ||
277 | self:error_expected(ls, what) | ||
278 | else | ||
279 | luaX:syntaxerror(ls, string.format( | ||
280 | "`%s' expected (to close `%s' at line %d)", | ||
281 | luaX:token2str(ls, what), luaX:token2str(ls, who), where)) | ||
282 | end | ||
283 | end | ||
284 | end | ||
285 | |||
286 | ------------------------------------------------------------------------ | ||
287 | -- expect that token is a name, return the name | ||
288 | ------------------------------------------------------------------------ | ||
289 | function luaY:str_checkname(ls) | ||
290 | self:check_condition(ls, ls.t.token == "TK_NAME", "<name> expected") | ||
291 | local ts = ls.t.seminfo | ||
292 | self:next(ls) | ||
293 | return ts | ||
294 | end | ||
295 | |||
296 | ------------------------------------------------------------------------ | ||
297 | -- initialize a struct expdesc, expression description data structure | ||
298 | ------------------------------------------------------------------------ | ||
299 | function luaY:init_exp(e, k, i) | ||
300 | e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP | ||
301 | e.k = k | ||
302 | e.info = i | ||
303 | end | ||
304 | |||
305 | ------------------------------------------------------------------------ | ||
306 | -- adds given string s in string pool, sets e as VK | ||
307 | ------------------------------------------------------------------------ | ||
308 | function luaY:codestring(ls, e, s) | ||
309 | self:init_exp(e, "VK", luaK:stringK(ls.fs, s)) | ||
310 | end | ||
311 | |||
312 | ------------------------------------------------------------------------ | ||
313 | -- consume a name token, adds it to string pool, sets e as VK | ||
314 | ------------------------------------------------------------------------ | ||
315 | function luaY:checkname(ls, e) | ||
316 | self:codestring(ls, e, self:str_checkname(ls)) | ||
317 | end | ||
318 | |||
319 | ------------------------------------------------------------------------ | ||
320 | -- returns local variable entry struct for a function | ||
321 | ------------------------------------------------------------------------ | ||
322 | function luaY:getlocvar(fs, i) | ||
323 | return fs.f.locvars[ fs.actvar[i] ] | ||
324 | end | ||
325 | |||
326 | ------------------------------------------------------------------------ | ||
327 | -- creates struct entry for a local variable | ||
328 | -- * used by new_localvar() only | ||
329 | ------------------------------------------------------------------------ | ||
330 | function luaY:registerlocalvar(ls, varname) | ||
331 | local fs = ls.fs | ||
332 | local f = fs.f | ||
333 | self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars, | ||
334 | nil, self.MAX_INT, "") | ||
335 | f.locvars[fs.nlocvars] = {} -- LocVar | ||
336 | f.locvars[fs.nlocvars].varname = varname | ||
337 | local nlocvars = fs.nlocvars | ||
338 | fs.nlocvars = fs.nlocvars + 1 | ||
339 | return nlocvars | ||
340 | end | ||
341 | |||
342 | ------------------------------------------------------------------------ | ||
343 | -- register a local variable, set in active variable list | ||
344 | -- * used in new_localvarstr(), parlist(), fornum(), forlist(), | ||
345 | -- localfunc(), localstat() | ||
346 | ------------------------------------------------------------------------ | ||
347 | function luaY:new_localvar(ls, name, n) | ||
348 | local fs = ls.fs | ||
349 | luaX:checklimit(ls, fs.nactvar + n + 1, self.MAXVARS, "local variables") | ||
350 | fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name) | ||
351 | end | ||
352 | |||
353 | ------------------------------------------------------------------------ | ||
354 | -- adds nvars number of new local variables, set debug information | ||
355 | -- * used in create_local(), code_params(), forbody(), localfunc(), | ||
356 | -- localstat() | ||
357 | ------------------------------------------------------------------------ | ||
358 | function luaY:adjustlocalvars(ls, nvars) | ||
359 | local fs = ls.fs | ||
360 | fs.nactvar = fs.nactvar + nvars | ||
361 | for i = 1, nvars do | ||
362 | self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc | ||
363 | end | ||
364 | end | ||
365 | |||
366 | ------------------------------------------------------------------------ | ||
367 | -- removes a number of locals, set debug information | ||
368 | -- * used in leaveblock(), close_func() | ||
369 | ------------------------------------------------------------------------ | ||
370 | function luaY:removevars(ls, tolevel) | ||
371 | local fs = ls.fs | ||
372 | while fs.nactvar > tolevel do | ||
373 | fs.nactvar = fs.nactvar - 1 | ||
374 | self:getlocvar(fs, fs.nactvar).endpc = fs.pc | ||
375 | end | ||
376 | end | ||
377 | |||
378 | ------------------------------------------------------------------------ | ||
379 | -- creates a new local variable given a name and an offset from nactvar | ||
380 | -- * used in fornum(), forlist() for loop variables; in create_local() | ||
381 | ------------------------------------------------------------------------ | ||
382 | function luaY:new_localvarstr(ls, name, n) | ||
383 | self:new_localvar(ls, name, n) | ||
384 | end | ||
385 | |||
386 | ------------------------------------------------------------------------ | ||
387 | -- creates a single local variable and activates it | ||
388 | -- * used only in code_params() for "arg", body() for "self" | ||
389 | ------------------------------------------------------------------------ | ||
390 | function luaY:create_local(ls, name) | ||
391 | self:new_localvarstr(ls, name, 0) | ||
392 | self:adjustlocalvars(ls, 1) | ||
393 | end | ||
394 | |||
395 | ------------------------------------------------------------------------ | ||
396 | -- returns an existing upvalue index based on the given name, or | ||
397 | -- creates a new upvalue struct entry and returns the new index | ||
398 | -- * used only in singlevaraux() | ||
399 | ------------------------------------------------------------------------ | ||
400 | function luaY:indexupvalue(fs, name, v) | ||
401 | local f = fs.f | ||
402 | for i = 0, f.nups - 1 do | ||
403 | if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then | ||
404 | lua_assert(fs.f.upvalues[i] == name) | ||
405 | return i | ||
406 | end | ||
407 | end | ||
408 | -- new one | ||
409 | luaX:checklimit(fs.ls, f.nups + 1, self.MAXUPVALUES, "upvalues") | ||
410 | self:growvector(fs.L, fs.f.upvalues, f.nups, fs.f.sizeupvalues, | ||
411 | nil, self.MAX_INT, "") | ||
412 | fs.f.upvalues[f.nups] = name | ||
413 | -- this is a partial copy; only k & info fields used | ||
414 | fs.upvalues[f.nups] = { k = v.k, info = v.info } | ||
415 | local nups = f.nups | ||
416 | f.nups = f.nups + 1 | ||
417 | return nups | ||
418 | end | ||
419 | |||
420 | ------------------------------------------------------------------------ | ||
421 | -- search the local variable namespace of the given fs for a match | ||
422 | -- * used only in singlevaraux() | ||
423 | ------------------------------------------------------------------------ | ||
424 | function luaY:searchvar(fs, n) | ||
425 | for i = fs.nactvar - 1, 0, -1 do | ||
426 | if n == self:getlocvar(fs, i).varname then | ||
427 | return i | ||
428 | end | ||
429 | end | ||
430 | return -1 -- not found | ||
431 | end | ||
432 | |||
433 | ------------------------------------------------------------------------ | ||
434 | -- * mark upvalue flags in function states up to a given level | ||
435 | -- * used only in singlevaraux() | ||
436 | ------------------------------------------------------------------------ | ||
437 | function luaY:markupval(fs, level) | ||
438 | local bl = fs.bl | ||
439 | while bl and bl.nactvar > level do bl = bl.previous end | ||
440 | if bl then bl.upval = true end | ||
441 | end | ||
442 | |||
443 | ------------------------------------------------------------------------ | ||
444 | -- handle locals, globals and upvalues and related processing | ||
445 | -- * search mechanism is recursive, calls itself to search parents | ||
446 | -- * used only in singlevar() | ||
447 | ------------------------------------------------------------------------ | ||
448 | function luaY:singlevaraux(fs, n, var, base) | ||
449 | if fs == nil then -- no more levels? | ||
450 | self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable | ||
451 | else | ||
452 | local v = self:searchvar(fs, n) -- look up at current level | ||
453 | if v >= 0 then | ||
454 | self:init_exp(var, "VLOCAL", v) | ||
455 | if base == 0 then | ||
456 | self:markupval(fs, v) -- local will be used as an upval | ||
457 | end | ||
458 | else -- not found at current level; try upper one | ||
459 | self:singlevaraux(fs.prev, n, var, 0) | ||
460 | if var.k == "VGLOBAL" then | ||
461 | if base ~= 0 then | ||
462 | var.info = luaK:stringK(fs, n) -- info points to global name | ||
463 | end | ||
464 | else -- LOCAL or UPVAL | ||
465 | var.info = self:indexupvalue(fs, n, var) | ||
466 | var.k = "VUPVAL" -- upvalue in this level | ||
467 | end | ||
468 | end--if v | ||
469 | end--if fs | ||
470 | end | ||
471 | |||
472 | ------------------------------------------------------------------------ | ||
473 | -- consume a name token, creates a variable (global|local|upvalue) | ||
474 | -- * used in prefixexp(), funcname() | ||
475 | ------------------------------------------------------------------------ | ||
476 | function luaY:singlevar(ls, var, base) | ||
477 | local varname = self:str_checkname(ls) | ||
478 | self:singlevaraux(ls.fs, varname, var, base) | ||
479 | return varname | ||
480 | end | ||
481 | |||
482 | ------------------------------------------------------------------------ | ||
483 | -- adjust RHS to match LHS in an assignment | ||
484 | -- * used in assignment(), forlist(), localstat() | ||
485 | ------------------------------------------------------------------------ | ||
486 | function luaY:adjust_assign(ls, nvars, nexps, e) | ||
487 | local fs = ls.fs | ||
488 | local extra = nvars - nexps | ||
489 | if e.k == "VCALL" then | ||
490 | extra = extra + 1 -- includes call itself | ||
491 | if extra <= 0 then extra = 0 | ||
492 | else luaK:reserveregs(fs, extra - 1) end | ||
493 | luaK:setcallreturns(fs, e, extra) -- call provides the difference | ||
494 | else | ||
495 | if e.k ~= "VVOID" then luaK:exp2nextreg(fs, e) end -- close last expression | ||
496 | if extra > 0 then | ||
497 | local reg = fs.freereg | ||
498 | luaK:reserveregs(fs, extra) | ||
499 | luaK:_nil(fs, reg, extra) | ||
500 | end | ||
501 | end | ||
502 | end | ||
503 | |||
504 | ------------------------------------------------------------------------ | ||
505 | -- perform initialization for a parameter list, adds arg if needed | ||
506 | -- * used only in parlist() | ||
507 | ------------------------------------------------------------------------ | ||
508 | function luaY:code_params(ls, nparams, dots) | ||
509 | local fs = ls.fs | ||
510 | self:adjustlocalvars(ls, nparams) | ||
511 | luaX:checklimit(ls, fs.nactvar, self.MAXPARAMS, "parameters") | ||
512 | fs.f.numparams = fs.nactvar | ||
513 | fs.f.is_vararg = dots and 1 or 0 | ||
514 | if dots then | ||
515 | self:create_local(ls, "arg") | ||
516 | end | ||
517 | luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters | ||
518 | end | ||
519 | |||
520 | ------------------------------------------------------------------------ | ||
521 | -- enters a code unit, initializes elements | ||
522 | ------------------------------------------------------------------------ | ||
523 | function luaY:enterblock(fs, bl, isbreakable) | ||
524 | bl.breaklist = luaK.NO_JUMP | ||
525 | bl.isbreakable = isbreakable | ||
526 | bl.nactvar = fs.nactvar | ||
527 | bl.upval = false | ||
528 | bl.previous = fs.bl | ||
529 | fs.bl = bl | ||
530 | lua_assert(fs.freereg == fs.nactvar) | ||
531 | end | ||
532 | |||
533 | ------------------------------------------------------------------------ | ||
534 | -- leaves a code unit, close any upvalues | ||
535 | ------------------------------------------------------------------------ | ||
536 | function luaY:leaveblock(fs) | ||
537 | local bl = fs.bl | ||
538 | fs.bl = bl.previous | ||
539 | self:removevars(fs.ls, bl.nactvar) | ||
540 | if bl.upval then | ||
541 | luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) | ||
542 | end | ||
543 | lua_assert(bl.nactvar == fs.nactvar) | ||
544 | fs.freereg = fs.nactvar -- free registers | ||
545 | luaK:patchtohere(fs, bl.breaklist) | ||
546 | end | ||
547 | |||
548 | ------------------------------------------------------------------------ | ||
549 | -- implement the instantiation of a function prototype, append list of | ||
550 | -- upvalues after the instantiation instruction | ||
551 | -- * used only in body() | ||
552 | ------------------------------------------------------------------------ | ||
553 | function luaY:pushclosure(ls, func, v) | ||
554 | local fs = ls.fs | ||
555 | local f = fs.f | ||
556 | self:growvector(ls.L, f.p, fs.np, f.sizep, nil, | ||
557 | luaP.MAXARG_Bx, "constant table overflow") | ||
558 | f.p[fs.np] = func.f | ||
559 | fs.np = fs.np + 1 | ||
560 | self:init_exp(v, "VRELOCABLE", luaK:codeABx(fs, "OP_CLOSURE", 0, fs.np - 1)) | ||
561 | for i = 0, func.f.nups - 1 do | ||
562 | local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL" | ||
563 | luaK:codeABC(fs, o, 0, func.upvalues[i].info, 0) | ||
564 | end | ||
565 | end | ||
566 | |||
567 | ------------------------------------------------------------------------ | ||
568 | -- initialize a new function prototype structure | ||
569 | ------------------------------------------------------------------------ | ||
570 | function luaY:newproto(L) | ||
571 | local f = {} -- Proto | ||
572 | -- luaC_link deleted | ||
573 | f.k = {} | ||
574 | f.sizek = 0 | ||
575 | f.p = {} | ||
576 | f.sizep = 0 | ||
577 | f.code = {} | ||
578 | f.sizecode = 0 | ||
579 | f.sizelineinfo = 0 | ||
580 | f.sizeupvalues = 0 | ||
581 | f.nups = 0 | ||
582 | f.upvalues = {} | ||
583 | f.numparams = 0 | ||
584 | f.is_vararg = 0 | ||
585 | f.maxstacksize = 0 | ||
586 | f.lineinfo = {} | ||
587 | f.sizelocvars = 0 | ||
588 | f.locvars = {} | ||
589 | f.lineDefined = 0 | ||
590 | f.source = nil | ||
591 | return f | ||
592 | end | ||
593 | |||
594 | ------------------------------------------------------------------------ | ||
595 | -- opening of a function | ||
596 | ------------------------------------------------------------------------ | ||
597 | function luaY:open_func(ls, fs) | ||
598 | local f = self:newproto(ls.L) | ||
599 | fs.f = f | ||
600 | fs.prev = ls.fs -- linked list of funcstates | ||
601 | fs.ls = ls | ||
602 | fs.L = ls.L | ||
603 | ls.fs = fs | ||
604 | fs.pc = 0 | ||
605 | fs.lasttarget = 0 | ||
606 | fs.jpc = luaK.NO_JUMP | ||
607 | fs.freereg = 0 | ||
608 | fs.nk = 0 | ||
609 | fs.h = {} -- constant table; was luaH_new call | ||
610 | fs.np = 0 | ||
611 | fs.nlocvars = 0 | ||
612 | fs.nactvar = 0 | ||
613 | fs.bl = nil | ||
614 | f.source = ls.source | ||
615 | f.maxstacksize = 2 -- registers 0/1 are always valid | ||
616 | end | ||
617 | |||
618 | ------------------------------------------------------------------------ | ||
619 | -- closing of a function | ||
620 | ------------------------------------------------------------------------ | ||
621 | function luaY:close_func(ls) | ||
622 | local L = ls.L | ||
623 | local fs = ls.fs | ||
624 | local f = fs.f | ||
625 | self:removevars(ls, 0) | ||
626 | luaK:codeABC(fs, "OP_RETURN", 0, 1, 0) -- final return | ||
627 | -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p, | ||
628 | -- f->locvars, f->upvalues; not required for Lua table arrays | ||
629 | f.sizecode = fs.pc | ||
630 | f.sizelineinfo = fs.pc | ||
631 | f.sizek = fs.nk | ||
632 | f.sizep = fs.np | ||
633 | f.sizelocvars = fs.nlocvars | ||
634 | f.sizeupvalues = f.nups | ||
635 | --lua_assert(luaG_checkcode(f)) -- currently not implemented | ||
636 | lua_assert(fs.bl == nil) | ||
637 | ls.fs = fs.prev | ||
638 | end | ||
639 | |||
640 | ------------------------------------------------------------------------ | ||
641 | -- parser initialization function | ||
642 | -- * note additional sub-tables needed for LexState, FuncState | ||
643 | ------------------------------------------------------------------------ | ||
644 | function luaY:parser(L, z, buff) | ||
645 | local lexstate = {} -- LexState | ||
646 | lexstate.t = {} | ||
647 | lexstate.lookahead = {} | ||
648 | local funcstate = {} -- FuncState | ||
649 | funcstate.upvalues = {} | ||
650 | funcstate.actvar = {} | ||
651 | lexstate.buff = buff | ||
652 | lexstate.nestlevel = 0 | ||
653 | luaX:setinput(L, lexstate, z, z.name) | ||
654 | self:open_func(lexstate, funcstate) | ||
655 | self:next(lexstate) -- read first token | ||
656 | self:chunk(lexstate) | ||
657 | self:check_condition(lexstate, lexstate.t.token == "TK_EOS", "<eof> expected") | ||
658 | self:close_func(lexstate) | ||
659 | lua_assert(funcstate.prev == nil) | ||
660 | lua_assert(funcstate.f.nups == 0) | ||
661 | lua_assert(lexstate.nestlevel == 0) | ||
662 | return funcstate.f | ||
663 | end | ||
664 | |||
665 | --[[-------------------------------------------------------------------- | ||
666 | -- GRAMMAR RULES | ||
667 | ----------------------------------------------------------------------]] | ||
668 | |||
669 | ------------------------------------------------------------------------ | ||
670 | -- parse a function name suffix, for function call specifications | ||
671 | -- * used in primaryexp(), funcname() | ||
672 | ------------------------------------------------------------------------ | ||
673 | function luaY:field(ls, v) | ||
674 | -- field -> ['.' | ':'] NAME | ||
675 | local fs = ls.fs | ||
676 | local key = {} -- expdesc | ||
677 | luaK:exp2anyreg(fs, v) | ||
678 | self:next(ls) -- skip the dot or colon | ||
679 | self:checkname(ls, key) | ||
680 | luaK:indexed(fs, v, key) | ||
681 | end | ||
682 | |||
683 | ------------------------------------------------------------------------ | ||
684 | -- parse a table indexing suffix, for constructors, expressions | ||
685 | -- * used in recfield(), primaryexp() | ||
686 | ------------------------------------------------------------------------ | ||
687 | function luaY:index(ls, v) | ||
688 | -- index -> '[' expr ']' | ||
689 | self:next(ls) -- skip the '[' | ||
690 | self:expr(ls, v) | ||
691 | luaK:exp2val(ls.fs, v) | ||
692 | self:check(ls, "]") | ||
693 | end | ||
694 | |||
695 | --[[-------------------------------------------------------------------- | ||
696 | -- Rules for Constructors | ||
697 | ----------------------------------------------------------------------]] | ||
698 | |||
699 | --[[-------------------------------------------------------------------- | ||
700 | -- struct ConsControl: | ||
701 | -- v -- last list item read (table: struct expdesc) | ||
702 | -- t -- table descriptor (table: struct expdesc) | ||
703 | -- nh -- total number of 'record' elements | ||
704 | -- na -- total number of array elements | ||
705 | -- tostore -- number of array elements pending to be stored | ||
706 | ----------------------------------------------------------------------]] | ||
707 | |||
708 | ------------------------------------------------------------------------ | ||
709 | -- parse a table record (hash) field | ||
710 | -- * used in constructor() | ||
711 | ------------------------------------------------------------------------ | ||
712 | function luaY:recfield(ls, cc) | ||
713 | -- recfield -> (NAME | '['exp1']') = exp1 | ||
714 | local fs = ls.fs | ||
715 | local reg = ls.fs.freereg | ||
716 | local key, val = {}, {} -- expdesc | ||
717 | if ls.t.token == "TK_NAME" then | ||
718 | luaX:checklimit(ls, cc.nh, self.MAX_INT, "items in a constructor") | ||
719 | cc.nh = cc.nh + 1 | ||
720 | self:checkname(ls, key) | ||
721 | else -- ls->t.token == '[' | ||
722 | self:index(ls, key) | ||
723 | end | ||
724 | self:check(ls, "=") | ||
725 | luaK:exp2RK(fs, key) | ||
726 | self:expr(ls, val) | ||
727 | luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, luaK:exp2RK(fs, key), | ||
728 | luaK:exp2RK(fs, val)) | ||
729 | fs.freereg = reg -- free registers | ||
730 | end | ||
731 | |||
732 | ------------------------------------------------------------------------ | ||
733 | -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) | ||
734 | -- * used in constructor() | ||
735 | ------------------------------------------------------------------------ | ||
736 | function luaY:closelistfield(fs, cc) | ||
737 | if cc.v.k == "VVOID" then return end -- there is no list item | ||
738 | luaK:exp2nextreg(fs, cc.v) | ||
739 | cc.v.k = "VVOID" | ||
740 | if cc.tostore == luaP.LFIELDS_PER_FLUSH then | ||
741 | luaK:codeABx(fs, "OP_SETLIST", cc.t.info, cc.na - 1) -- flush | ||
742 | cc.tostore = 0 -- no more items pending | ||
743 | fs.freereg = cc.t.info + 1 -- free registers | ||
744 | end | ||
745 | end | ||
746 | |||
747 | ------------------------------------------------------------------------ | ||
748 | -- emit a set list instruction at the end of parsing list constructor | ||
749 | -- * used in constructor() | ||
750 | ------------------------------------------------------------------------ | ||
751 | function luaY:lastlistfield(fs, cc) | ||
752 | if cc.tostore == 0 then return end | ||
753 | if cc.v.k == "VCALL" then | ||
754 | luaK:setcallreturns(fs, cc.v, self.LUA_MULTRET) | ||
755 | luaK:codeABx(fs, "OP_SETLISTO", cc.t.info, cc.na - 1) | ||
756 | else | ||
757 | if cc.v.k ~= "VVOID" then | ||
758 | luaK:exp2nextreg(fs, cc.v) | ||
759 | end | ||
760 | luaK:codeABx(fs, "OP_SETLIST", cc.t.info, cc.na - 1) | ||
761 | end | ||
762 | fs.freereg = cc.t.info + 1 -- free registers | ||
763 | end | ||
764 | |||
765 | ------------------------------------------------------------------------ | ||
766 | -- parse a table list (array) field | ||
767 | -- * used in constructor() | ||
768 | ------------------------------------------------------------------------ | ||
769 | function luaY:listfield(ls, cc) | ||
770 | self:expr(ls, cc.v) | ||
771 | luaX:checklimit(ls, cc.na, luaP.MAXARG_Bx, "items in a constructor") | ||
772 | cc.na = cc.na + 1 | ||
773 | cc.tostore = cc.tostore + 1 | ||
774 | end | ||
775 | |||
776 | ------------------------------------------------------------------------ | ||
777 | -- parse a table constructor | ||
778 | -- * used in funcargs(), simpleexp() | ||
779 | ------------------------------------------------------------------------ | ||
780 | function luaY:constructor(ls, t) | ||
781 | -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' | ||
782 | -- field -> recfield | listfield | ||
783 | -- fieldsep -> ',' | ';' | ||
784 | local fs = ls.fs | ||
785 | local line = ls.linenumber | ||
786 | local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0) | ||
787 | local cc = {} -- ConsControl | ||
788 | cc.v = {} | ||
789 | cc.na, cc.nh, cc.tostore = 0, 0, 0 | ||
790 | cc.t = t | ||
791 | self:init_exp(t, "VRELOCABLE", pc) | ||
792 | self:init_exp(cc.v, "VVOID", 0) -- no value (yet) | ||
793 | luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc) | ||
794 | self:check(ls, "{") | ||
795 | repeat | ||
796 | lua_assert(cc.v.k == "VVOID" or cc.tostore > 0) | ||
797 | self:testnext(ls, ";") -- compatibility only | ||
798 | if ls.t.token == "}" then break end | ||
799 | self:closelistfield(fs, cc) | ||
800 | local c = ls.t.token | ||
801 | if c == "TK_NAME" then -- may be listfields or recfields | ||
802 | self:lookahead(ls) | ||
803 | if ls.lookahead.token ~= "=" then -- expression? | ||
804 | self:listfield(ls, cc) | ||
805 | else | ||
806 | self:recfield(ls, cc) | ||
807 | end | ||
808 | elseif c == "[" then -- constructor_item -> recfield | ||
809 | self:recfield(ls, cc) | ||
810 | else -- constructor_part -> listfield | ||
811 | self:listfield(ls, cc) | ||
812 | end | ||
813 | until not self:testnext(ls, ",") and not self:testnext(ls, ";") | ||
814 | self:check_match(ls, "}", "{", line) | ||
815 | self:lastlistfield(fs, cc) | ||
816 | luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size | ||
817 | luaP:SETARG_C(fs.f.code[pc], self:log2(cc.nh) + 1) -- set initial table size | ||
818 | end | ||
819 | |||
820 | ------------------------------------------------------------------------ | ||
821 | -- parse the arguments (parameters) of a function declaration | ||
822 | -- * used in body() | ||
823 | ------------------------------------------------------------------------ | ||
824 | function luaY:parlist(ls) | ||
825 | -- parlist -> [ param { ',' param } ] | ||
826 | local nparams = 0 | ||
827 | local dots = false | ||
828 | if ls.t.token ~= ")" then -- is 'parlist' not empty? | ||
829 | repeat | ||
830 | local c = ls.t.token | ||
831 | if c == "TK_DOTS" then | ||
832 | dots = true | ||
833 | self:next(ls) | ||
834 | elseif c == "TK_NAME" then | ||
835 | self:new_localvar(ls, self:str_checkname(ls), nparams) | ||
836 | nparams = nparams + 1 | ||
837 | else | ||
838 | luaX:syntaxerror(ls, "<name> or `...' expected") | ||
839 | end | ||
840 | until dots or not self:testnext(ls, ",") | ||
841 | end | ||
842 | self:code_params(ls, nparams, dots) | ||
843 | end | ||
844 | |||
845 | ------------------------------------------------------------------------ | ||
846 | -- parse function declaration body | ||
847 | -- * used in simpleexp(), localfunc(), funcstat() | ||
848 | ------------------------------------------------------------------------ | ||
849 | function luaY:body(ls, e, needself, line) | ||
850 | -- body -> '(' parlist ')' chunk END | ||
851 | local new_fs = {} -- FuncState | ||
852 | new_fs.upvalues = {} | ||
853 | new_fs.actvar = {} | ||
854 | self:open_func(ls, new_fs) | ||
855 | new_fs.f.lineDefined = line | ||
856 | self:check(ls, "(") | ||
857 | if needself then | ||
858 | self:create_local(ls, "self") | ||
859 | end | ||
860 | self:parlist(ls) | ||
861 | self:check(ls, ")") | ||
862 | self:chunk(ls) | ||
863 | self:check_match(ls, "TK_END", "TK_FUNCTION", line) | ||
864 | self:close_func(ls) | ||
865 | self:pushclosure(ls, new_fs, e) | ||
866 | end | ||
867 | |||
868 | ------------------------------------------------------------------------ | ||
869 | -- parse a list of comma-separated expressions | ||
870 | -- * used is multiple locations | ||
871 | ------------------------------------------------------------------------ | ||
872 | function luaY:explist1(ls, v) | ||
873 | -- explist1 -> expr { ',' expr } | ||
874 | local n = 1 -- at least one expression | ||
875 | self:expr(ls, v) | ||
876 | while self:testnext(ls, ",") do | ||
877 | luaK:exp2nextreg(ls.fs, v) | ||
878 | self:expr(ls, v) | ||
879 | n = n + 1 | ||
880 | end | ||
881 | return n | ||
882 | end | ||
883 | |||
884 | ------------------------------------------------------------------------ | ||
885 | -- parse the parameters of a function call | ||
886 | -- * contrast with parlist(), used in function declarations | ||
887 | -- * used in primaryexp() | ||
888 | ------------------------------------------------------------------------ | ||
889 | function luaY:funcargs(ls, f) | ||
890 | local fs = ls.fs | ||
891 | local args = {} -- expdesc | ||
892 | local nparams | ||
893 | local line = ls.linenumber | ||
894 | local c = ls.t.token | ||
895 | if c == "(" then -- funcargs -> '(' [ explist1 ] ')' | ||
896 | if line ~= ls.lastline then | ||
897 | luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)") | ||
898 | end | ||
899 | self:next(ls) | ||
900 | if ls.t.token == ")" then -- arg list is empty? | ||
901 | args.k = "VVOID" | ||
902 | else | ||
903 | self:explist1(ls, args) | ||
904 | luaK:setcallreturns(fs, args, self.LUA_MULTRET) | ||
905 | end | ||
906 | self:check_match(ls, ")", "(", line) | ||
907 | elseif c == "{" then -- funcargs -> constructor | ||
908 | self:constructor(ls, args) | ||
909 | elseif c == "TK_STRING" then -- funcargs -> STRING | ||
910 | self:codestring(ls, args, ls.t.seminfo) | ||
911 | self:next(ls) -- must use 'seminfo' before 'next' | ||
912 | else | ||
913 | luaX:syntaxerror(ls, "function arguments expected") | ||
914 | return | ||
915 | end | ||
916 | lua_assert(f.k == "VNONRELOC") | ||
917 | local base = f.info -- base register for call | ||
918 | if args.k == "VCALL" then | ||
919 | nparams = self.LUA_MULTRET -- open call | ||
920 | else | ||
921 | if args.k ~= "VVOID" then | ||
922 | luaK:exp2nextreg(fs, args) -- close last argument | ||
923 | end | ||
924 | nparams = fs.freereg - (base + 1) | ||
925 | end | ||
926 | self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2)) | ||
927 | luaK:fixline(fs, line) | ||
928 | fs.freereg = base + 1 -- call remove function and arguments and leaves | ||
929 | -- (unless changed) one result | ||
930 | end | ||
931 | |||
932 | --[[-------------------------------------------------------------------- | ||
933 | -- Expression parsing | ||
934 | ----------------------------------------------------------------------]] | ||
935 | |||
936 | ------------------------------------------------------------------------ | ||
937 | -- parses an expression in parentheses or a single variable | ||
938 | -- * used in primaryexp() | ||
939 | ------------------------------------------------------------------------ | ||
940 | function luaY:prefixexp(ls, v) | ||
941 | -- prefixexp -> NAME | '(' expr ')' | ||
942 | local c = ls.t.token | ||
943 | if c == "(" then | ||
944 | local line = ls.linenumber | ||
945 | self:next(ls) | ||
946 | self:expr(ls, v) | ||
947 | self:check_match(ls, ")", "(", line) | ||
948 | luaK:dischargevars(ls.fs, v) | ||
949 | elseif c == "TK_NAME" then | ||
950 | self:singlevar(ls, v, 1) | ||
951 | -- LUA_COMPATUPSYNTAX | ||
952 | --[[ | ||
953 | elseif c == "%" then -- for compatibility only | ||
954 | local line = ls.linenumber | ||
955 | self:next(ls) -- skip '%' | ||
956 | local varname = self:singlevar(ls, v, 1) | ||
957 | if v.k ~= "VUPVAL" then | ||
958 | luaX:errorline(ls, "global upvalues are obsolete", varname, line) | ||
959 | end | ||
960 | --]] | ||
961 | else | ||
962 | luaX:syntaxerror(ls, "unexpected symbol") | ||
963 | end--if c | ||
964 | return | ||
965 | end | ||
966 | |||
967 | ------------------------------------------------------------------------ | ||
968 | -- parses a prefixexp (an expression in parentheses or a single variable) | ||
969 | -- or a function call specification | ||
970 | -- * used in simpleexp(), assignment(), exprstat() | ||
971 | ------------------------------------------------------------------------ | ||
972 | function luaY:primaryexp(ls, v) | ||
973 | -- primaryexp -> | ||
974 | -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } | ||
975 | local fs = ls.fs | ||
976 | self:prefixexp(ls, v) | ||
977 | while true do | ||
978 | local c = ls.t.token | ||
979 | if c == "." then -- field | ||
980 | self:field(ls, v) | ||
981 | elseif c == "[" then -- '[' exp1 ']' | ||
982 | local key = {} -- expdesc | ||
983 | luaK:exp2anyreg(fs, v) | ||
984 | self:index(ls, key) | ||
985 | luaK:indexed(fs, v, key) | ||
986 | elseif c == ":" then -- ':' NAME funcargs | ||
987 | local key = {} -- expdesc | ||
988 | self:next(ls) | ||
989 | self:checkname(ls, key) | ||
990 | luaK:_self(fs, v, key) | ||
991 | self:funcargs(ls, v) | ||
992 | elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs | ||
993 | luaK:exp2nextreg(fs, v) | ||
994 | self:funcargs(ls, v) | ||
995 | else | ||
996 | return | ||
997 | end--if c | ||
998 | end--while | ||
999 | end | ||
1000 | |||
1001 | ------------------------------------------------------------------------ | ||
1002 | -- parses general expression types, constants handled here | ||
1003 | -- * used in subexpr() | ||
1004 | ------------------------------------------------------------------------ | ||
1005 | function luaY:simpleexp(ls, v) | ||
1006 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | constructor | ||
1007 | -- | FUNCTION body | primaryexp | ||
1008 | local c = ls.t.token | ||
1009 | if c == "TK_NUMBER" then | ||
1010 | self:init_exp(v, "VK", luaK:numberK(ls.fs, ls.t.seminfo)) | ||
1011 | self:next(ls) -- must use 'seminfo' before 'next' | ||
1012 | elseif c == "TK_STRING" then | ||
1013 | self:codestring(ls, v, ls.t.seminfo) | ||
1014 | self:next(ls) -- must use 'seminfo' before 'next' | ||
1015 | elseif c == "TK_NIL" then | ||
1016 | self:init_exp(v, "VNIL", 0) | ||
1017 | self:next(ls) | ||
1018 | elseif c == "TK_TRUE" then | ||
1019 | self:init_exp(v, "VTRUE", 0) | ||
1020 | self:next(ls) | ||
1021 | elseif c == "TK_FALSE" then | ||
1022 | self:init_exp(v, "VFALSE", 0) | ||
1023 | self:next(ls) | ||
1024 | elseif c == "{" then -- constructor | ||
1025 | self:constructor(ls, v) | ||
1026 | elseif c == "TK_FUNCTION" then | ||
1027 | self:next(ls) | ||
1028 | self:body(ls, v, false, ls.linenumber) | ||
1029 | else | ||
1030 | self:primaryexp(ls, v) | ||
1031 | end--if c | ||
1032 | end | ||
1033 | |||
1034 | ------------------------------------------------------------------------ | ||
1035 | -- Translates unary operators tokens if found, otherwise returns | ||
1036 | -- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr(). | ||
1037 | -- * used in subexpr() | ||
1038 | ------------------------------------------------------------------------ | ||
1039 | function luaY:getunopr(op) | ||
1040 | if op == "TK_NOT" then | ||
1041 | return "OPR_NOT" | ||
1042 | elseif op == "-" then | ||
1043 | return "OPR_MINUS" | ||
1044 | else | ||
1045 | return "OPR_NOUNOPR" | ||
1046 | end | ||
1047 | end | ||
1048 | |||
1049 | ------------------------------------------------------------------------ | ||
1050 | -- Translates binary operator tokens if found, otherwise returns | ||
1051 | -- OPR_NOBINOPR. Code generation uses OPR_* style tokens. | ||
1052 | -- * used in subexpr() | ||
1053 | ------------------------------------------------------------------------ | ||
1054 | luaY.getbinopr_table = { | ||
1055 | ["+"] = "OPR_ADD", | ||
1056 | ["-"] = "OPR_SUB", | ||
1057 | ["*"] = "OPR_MULT", | ||
1058 | ["/"] = "OPR_DIV", | ||
1059 | ["^"] = "OPR_POW", | ||
1060 | ["TK_CONCAT"] = "OPR_CONCAT", | ||
1061 | ["TK_NE"] = "OPR_NE", | ||
1062 | ["TK_EQ"] = "OPR_EQ", | ||
1063 | ["<"] = "OPR_LT", | ||
1064 | ["TK_LE"] = "OPR_LE", | ||
1065 | [">"] = "OPR_GT", | ||
1066 | ["TK_GE"] = "OPR_GE", | ||
1067 | ["TK_AND"] = "OPR_AND", | ||
1068 | ["TK_OR"] = "OPR_OR", | ||
1069 | } | ||
1070 | function luaY:getbinopr(op) | ||
1071 | local opr = self.getbinopr_table[op] | ||
1072 | if opr then return opr else return "OPR_NOBINOPR" end | ||
1073 | end | ||
1074 | |||
1075 | ------------------------------------------------------------------------ | ||
1076 | -- the following priority table consists of pairs of left/right values | ||
1077 | -- for binary operators (was a static const struct); grep for ORDER OPR | ||
1078 | ------------------------------------------------------------------------ | ||
1079 | luaY.priority = { | ||
1080 | {6, 6}, {6, 6}, {7, 7}, {7, 7}, -- arithmetic | ||
1081 | {10, 9}, {5, 4}, -- power and concat (right associative) | ||
1082 | {3, 3}, {3, 3}, -- equality | ||
1083 | {3, 3}, {3, 3}, {3, 3}, {3, 3}, -- order | ||
1084 | {2, 2}, {1, 1} -- logical (and/or) | ||
1085 | } | ||
1086 | |||
1087 | luaY.UNARY_PRIORITY = 8 -- priority for unary operators | ||
1088 | |||
1089 | ------------------------------------------------------------------------ | ||
1090 | -- subexpr -> (simpleexp | unop subexpr) { binop subexpr } | ||
1091 | -- where 'binop' is any binary operator with a priority higher than 'limit' | ||
1092 | ------------------------------------------------------------------------ | ||
1093 | |||
1094 | ------------------------------------------------------------------------ | ||
1095 | -- * for priority lookups with self.priority[], 1=left and 2=right | ||
1096 | -- | ||
1097 | -- Parse subexpressions. Includes handling of unary operators and binary | ||
1098 | -- operators. A subexpr is given the rhs priority level of the operator | ||
1099 | -- immediately left of it, if any (limit is -1 if none,) and if a binop | ||
1100 | -- is found, limit is compared with the lhs priority level of the binop | ||
1101 | -- in order to determine which executes first. | ||
1102 | -- | ||
1103 | -- * recursively called | ||
1104 | -- * used in expr() | ||
1105 | ------------------------------------------------------------------------ | ||
1106 | function luaY:subexpr(ls, v, limit) | ||
1107 | self:enterlevel(ls) | ||
1108 | local uop = self:getunopr(ls.t.token) | ||
1109 | if uop ~= "OPR_NOUNOPR" then | ||
1110 | self:next(ls) | ||
1111 | self:subexpr(ls, v, self.UNARY_PRIORITY) | ||
1112 | luaK:prefix(ls.fs, uop, v) | ||
1113 | else | ||
1114 | self:simpleexp(ls, v) | ||
1115 | end | ||
1116 | -- expand while operators have priorities higher than 'limit' | ||
1117 | local op = self:getbinopr(ls.t.token) | ||
1118 | while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do | ||
1119 | local v2 = {} -- expdesc | ||
1120 | self:next(ls) | ||
1121 | luaK:infix(ls.fs, op, v) | ||
1122 | -- read sub-expression with higher priority | ||
1123 | local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2]) | ||
1124 | luaK:posfix(ls.fs, op, v, v2) | ||
1125 | op = nextop | ||
1126 | end | ||
1127 | self:leavelevel(ls) | ||
1128 | return op -- return first untreated operator | ||
1129 | end | ||
1130 | |||
1131 | ------------------------------------------------------------------------ | ||
1132 | -- Expression parsing starts here. Function subexpr is entered with the | ||
1133 | -- left operator (which is non-existent) priority of -1, which is lower | ||
1134 | -- than all actual operators. Expr information is returned in parm v. | ||
1135 | -- * used in multiple locations | ||
1136 | ------------------------------------------------------------------------ | ||
1137 | function luaY:expr(ls, v) | ||
1138 | self:subexpr(ls, v, -1) | ||
1139 | end | ||
1140 | |||
1141 | --[[-------------------------------------------------------------------- | ||
1142 | -- Rules for Statements | ||
1143 | ----------------------------------------------------------------------]] | ||
1144 | |||
1145 | ------------------------------------------------------------------------ | ||
1146 | -- checks next token, used as a look-ahead | ||
1147 | -- * returns boolean instead of 0|1 | ||
1148 | -- * used in retstat(), chunk() | ||
1149 | ------------------------------------------------------------------------ | ||
1150 | function luaY:block_follow(token) | ||
1151 | if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END" | ||
1152 | or token == "TK_UNTIL" or token == "TK_EOS" then | ||
1153 | return true | ||
1154 | else | ||
1155 | return false | ||
1156 | end | ||
1157 | end | ||
1158 | |||
1159 | ------------------------------------------------------------------------ | ||
1160 | -- parse a code block or unit | ||
1161 | -- * used in multiple functions | ||
1162 | ------------------------------------------------------------------------ | ||
1163 | function luaY:block(ls) | ||
1164 | -- block -> chunk | ||
1165 | local fs = ls.fs | ||
1166 | local bl = {} -- BlockCnt | ||
1167 | self:enterblock(fs, bl, false) | ||
1168 | self:chunk(ls) | ||
1169 | lua_assert(bl.breaklist == luaK.NO_JUMP) | ||
1170 | self:leaveblock(fs) | ||
1171 | end | ||
1172 | |||
1173 | ------------------------------------------------------------------------ | ||
1174 | -- structure to chain all variables in the left-hand side of an | ||
1175 | -- assignment | ||
1176 | ------------------------------------------------------------------------ | ||
1177 | --[[-------------------------------------------------------------------- | ||
1178 | -- struct LHS_assign: | ||
1179 | -- prev -- (table: struct LHS_assign) | ||
1180 | -- v -- variable (global, local, upvalue, or indexed) (table: expdesc) | ||
1181 | ----------------------------------------------------------------------]] | ||
1182 | |||
1183 | ------------------------------------------------------------------------ | ||
1184 | -- check whether, in an assignment to a local variable, the local variable | ||
1185 | -- is needed in a previous assignment (to a table). If so, save original | ||
1186 | -- local value in a safe place and use this safe copy in the previous | ||
1187 | -- assignment. | ||
1188 | -- * used in assignment() | ||
1189 | ------------------------------------------------------------------------ | ||
1190 | function luaY:check_conflict(ls, lh, v) | ||
1191 | local fs = ls.fs | ||
1192 | local extra = fs.freereg -- eventual position to save local variable | ||
1193 | local conflict = false | ||
1194 | while lh do | ||
1195 | if lh.v.k == "VINDEXED" then | ||
1196 | if lh.v.info == v.info then -- conflict? | ||
1197 | conflict = true | ||
1198 | lh.v.info = extra -- previous assignment will use safe copy | ||
1199 | end | ||
1200 | if lh.v.aux == v.info then -- conflict? | ||
1201 | conflict = true | ||
1202 | lh.v.aux = extra -- previous assignment will use safe copy | ||
1203 | end | ||
1204 | end | ||
1205 | lh = lh.prev | ||
1206 | end | ||
1207 | if conflict then | ||
1208 | luaK:codeABC(fs, "OP_MOVE", fs.freereg, v.info, 0) -- make copy | ||
1209 | luaK:reserveregs(fs, 1) | ||
1210 | end | ||
1211 | end | ||
1212 | |||
1213 | ------------------------------------------------------------------------ | ||
1214 | -- parse a variable assignment sequence | ||
1215 | -- * recursively called | ||
1216 | -- * used in exprstat() | ||
1217 | ------------------------------------------------------------------------ | ||
1218 | function luaY:assignment(ls, lh, nvars) | ||
1219 | local e = {} -- expdesc | ||
1220 | -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED | ||
1221 | local c = lh.v.k | ||
1222 | self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" | ||
1223 | or c == "VINDEXED", "syntax error") | ||
1224 | if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment | ||
1225 | local nv = {} -- LHS_assign | ||
1226 | nv.v = {} | ||
1227 | nv.prev = lh | ||
1228 | self:primaryexp(ls, nv.v) | ||
1229 | if nv.v.k == "VLOCAL" then | ||
1230 | self:check_conflict(ls, lh, nv.v) | ||
1231 | end | ||
1232 | self:assignment(ls, nv, nvars + 1) | ||
1233 | else -- assignment -> '=' explist1 | ||
1234 | self:check(ls, "=") | ||
1235 | local nexps = self:explist1(ls, e) | ||
1236 | if nexps ~= nvars then | ||
1237 | self:adjust_assign(ls, nvars, nexps, e) | ||
1238 | if nexps > nvars then | ||
1239 | ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values | ||
1240 | end | ||
1241 | else | ||
1242 | luaK:setcallreturns(ls.fs, e, 1) -- close last expression | ||
1243 | luaK:storevar(ls.fs, lh.v, e) | ||
1244 | return -- avoid default | ||
1245 | end | ||
1246 | end | ||
1247 | self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment | ||
1248 | luaK:storevar(ls.fs, lh.v, e) | ||
1249 | end | ||
1250 | |||
1251 | ------------------------------------------------------------------------ | ||
1252 | -- parse condition in a repeat statement or an if control structure | ||
1253 | -- * used in repeatstat(), test_then_block() | ||
1254 | ------------------------------------------------------------------------ | ||
1255 | function luaY:cond(ls, v) | ||
1256 | -- cond -> exp | ||
1257 | self:expr(ls, v) -- read condition | ||
1258 | if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here | ||
1259 | luaK:goiftrue(ls.fs, v) | ||
1260 | luaK:patchtohere(ls.fs, v.t) | ||
1261 | end | ||
1262 | |||
1263 | ------------------------------------------------------------------------ | ||
1264 | -- The while statement optimizes its code by coding the condition | ||
1265 | -- after its body (and thus avoiding one jump in the loop). | ||
1266 | ------------------------------------------------------------------------ | ||
1267 | |||
1268 | ------------------------------------------------------------------------ | ||
1269 | -- maximum size of expressions for optimizing 'while' code | ||
1270 | ------------------------------------------------------------------------ | ||
1271 | if not luaY.MAXEXPWHILE then | ||
1272 | luaY.MAXEXPWHILE = 100 | ||
1273 | end | ||
1274 | |||
1275 | ------------------------------------------------------------------------ | ||
1276 | -- the call 'luaK_goiffalse' may grow the size of an expression by | ||
1277 | -- at most this: | ||
1278 | ------------------------------------------------------------------------ | ||
1279 | luaY.EXTRAEXP = 5 | ||
1280 | |||
1281 | ------------------------------------------------------------------------ | ||
1282 | -- parse a while-do control structure, body processed by block() | ||
1283 | -- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by | ||
1284 | -- the function's implementation can be removed | ||
1285 | -- * used in statements() | ||
1286 | ------------------------------------------------------------------------ | ||
1287 | function luaY:whilestat(ls, line) | ||
1288 | -- whilestat -> WHILE cond DO block END | ||
1289 | -- array size of [MAXEXPWHILE + EXTRAEXP] no longer required | ||
1290 | local codeexp = {} -- Instruction | ||
1291 | local fs = ls.fs | ||
1292 | local v = {} -- expdesc | ||
1293 | local bl = {} -- BlockCnt | ||
1294 | self:next(ls) -- skip WHILE | ||
1295 | local whileinit = luaK:jump(fs) -- jump to condition (which will be moved) | ||
1296 | local expinit = luaK:getlabel(fs) | ||
1297 | self:expr(ls, v) -- parse condition | ||
1298 | if v.k == "VK" then v.k = "VTRUE" end -- 'trues' are all equal here | ||
1299 | local lineexp = ls.linenumber | ||
1300 | luaK:goiffalse(fs, v) | ||
1301 | v.f = luaK:concat(fs, v.f, fs.jpc) | ||
1302 | fs.jpc = luaK.NO_JUMP | ||
1303 | local sizeexp = fs.pc - expinit -- size of expression code | ||
1304 | if sizeexp > self.MAXEXPWHILE then | ||
1305 | luaX:syntaxerror(ls, "`while' condition too complex") | ||
1306 | end | ||
1307 | for i = 0, sizeexp - 1 do -- save 'exp' code | ||
1308 | codeexp[i] = fs.f.code[expinit + i] | ||
1309 | end | ||
1310 | fs.pc = expinit -- remove 'exp' code | ||
1311 | self:enterblock(fs, bl, true) | ||
1312 | self:check(ls, "TK_DO") | ||
1313 | local blockinit = luaK:getlabel(fs) | ||
1314 | self:block(ls) | ||
1315 | luaK:patchtohere(fs, whileinit) -- initial jump jumps to here | ||
1316 | -- move 'exp' back to code | ||
1317 | if v.t ~= luaK.NO_JUMP then v.t = v.t + fs.pc - expinit end | ||
1318 | if v.f ~= luaK.NO_JUMP then v.f = v.f + fs.pc - expinit end | ||
1319 | for i = 0, sizeexp - 1 do | ||
1320 | luaK:code(fs, codeexp[i], lineexp) | ||
1321 | end | ||
1322 | self:check_match(ls, "TK_END", "TK_WHILE", line) | ||
1323 | self:leaveblock(fs) | ||
1324 | luaK:patchlist(fs, v.t, blockinit) -- true conditions go back to loop | ||
1325 | luaK:patchtohere(fs, v.f) -- false conditions finish the loop | ||
1326 | end | ||
1327 | |||
1328 | ------------------------------------------------------------------------ | ||
1329 | -- parse a repeat-until control structure, body parsed by block() | ||
1330 | -- * used in statements() | ||
1331 | ------------------------------------------------------------------------ | ||
1332 | function luaY:repeatstat(ls, line) | ||
1333 | -- repeatstat -> REPEAT block UNTIL cond | ||
1334 | local fs = ls.fs | ||
1335 | local repeat_init = luaK:getlabel(fs) | ||
1336 | local v = {} -- expdesc | ||
1337 | local bl = {} -- BlockCnt | ||
1338 | self:enterblock(fs, bl, true) | ||
1339 | self:next(ls) | ||
1340 | self:block(ls) | ||
1341 | self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line) | ||
1342 | self:cond(ls, v) | ||
1343 | luaK:patchlist(fs, v.f, repeat_init) | ||
1344 | self:leaveblock(fs) | ||
1345 | end | ||
1346 | |||
1347 | ------------------------------------------------------------------------ | ||
1348 | -- parse the single expressions needed in numerical for loops | ||
1349 | -- * used in fornum() | ||
1350 | ------------------------------------------------------------------------ | ||
1351 | function luaY:exp1(ls) | ||
1352 | local e = {} -- expdesc | ||
1353 | self:expr(ls, e) | ||
1354 | local k = e.k | ||
1355 | luaK:exp2nextreg(ls.fs, e) | ||
1356 | return k | ||
1357 | end | ||
1358 | |||
1359 | ------------------------------------------------------------------------ | ||
1360 | -- parse a for loop body for both versions of the for loop | ||
1361 | -- * used in fornum(), forlist() | ||
1362 | ------------------------------------------------------------------------ | ||
1363 | function luaY:forbody(ls, base, line, nvars, isnum) | ||
1364 | local bl = {} -- BlockCnt | ||
1365 | local fs = ls.fs | ||
1366 | self:adjustlocalvars(ls, nvars) -- scope for all variables | ||
1367 | self:check(ls, "TK_DO") | ||
1368 | self:enterblock(fs, bl, true) -- loop block | ||
1369 | local prep = luaK:getlabel(fs) | ||
1370 | self:block(ls) | ||
1371 | luaK:patchtohere(fs, prep - 1) | ||
1372 | local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP) | ||
1373 | or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars - 3) | ||
1374 | luaK:fixline(fs, line) -- pretend that 'OP_FOR' starts the loop | ||
1375 | luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep) | ||
1376 | self:leaveblock(fs) | ||
1377 | end | ||
1378 | |||
1379 | ------------------------------------------------------------------------ | ||
1380 | -- parse a numerical for loop, calls forbody() | ||
1381 | -- * used in forstat() | ||
1382 | ------------------------------------------------------------------------ | ||
1383 | function luaY:fornum(ls, varname, line) | ||
1384 | -- fornum -> NAME = exp1,exp1[,exp1] DO body | ||
1385 | local fs = ls.fs | ||
1386 | local base = fs.freereg | ||
1387 | self:new_localvar(ls, varname, 0) | ||
1388 | self:new_localvarstr(ls, "(for limit)", 1) | ||
1389 | self:new_localvarstr(ls, "(for step)", 2) | ||
1390 | self:check(ls, "=") | ||
1391 | self:exp1(ls) -- initial value | ||
1392 | self:check(ls, ",") | ||
1393 | self:exp1(ls) -- limit | ||
1394 | if self:testnext(ls, ",") then | ||
1395 | self:exp1(ls) -- optional step | ||
1396 | else -- default step = 1 | ||
1397 | luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1)) | ||
1398 | luaK:reserveregs(fs, 1) | ||
1399 | end | ||
1400 | luaK:codeABC(fs, "OP_SUB", fs.freereg - 3, fs.freereg - 3, fs.freereg - 1) | ||
1401 | luaK:jump(fs) | ||
1402 | self:forbody(ls, base, line, 3, true) | ||
1403 | end | ||
1404 | |||
1405 | ------------------------------------------------------------------------ | ||
1406 | -- parse a generic for loop, calls forbody() | ||
1407 | -- * used in forstat() | ||
1408 | ------------------------------------------------------------------------ | ||
1409 | function luaY:forlist(ls, indexname) | ||
1410 | -- forlist -> NAME {,NAME} IN explist1 DO body | ||
1411 | local fs = ls.fs | ||
1412 | local e = {} -- expdesc | ||
1413 | local nvars = 0 | ||
1414 | local base = fs.freereg | ||
1415 | self:new_localvarstr(ls, "(for generator)", nvars) | ||
1416 | nvars = nvars + 1 | ||
1417 | self:new_localvarstr(ls, "(for state)", nvars) | ||
1418 | nvars = nvars + 1 | ||
1419 | self:new_localvar(ls, indexname, nvars) | ||
1420 | nvars = nvars + 1 | ||
1421 | while self:testnext(ls, ",") do | ||
1422 | self:new_localvar(ls, self:str_checkname(ls), nvars) | ||
1423 | nvars = nvars + 1 | ||
1424 | end | ||
1425 | self:check(ls, "TK_IN") | ||
1426 | local line = ls.linenumber | ||
1427 | self:adjust_assign(ls, nvars, self:explist1(ls, e), e) | ||
1428 | luaK:checkstack(fs, 3) -- extra space to call generator | ||
1429 | luaK:codeAsBx(fs, "OP_TFORPREP", base, luaK.NO_JUMP) | ||
1430 | self:forbody(ls, base, line, nvars, false) | ||
1431 | end | ||
1432 | |||
1433 | ------------------------------------------------------------------------ | ||
1434 | -- initial parsing for a for loop, calls fornum() or forlist() | ||
1435 | -- * used in statements() | ||
1436 | ------------------------------------------------------------------------ | ||
1437 | function luaY:forstat(ls, line) | ||
1438 | -- forstat -> fornum | forlist | ||
1439 | local fs = ls.fs | ||
1440 | local bl = {} -- BlockCnt | ||
1441 | self:enterblock(fs, bl, false) -- block to control variable scope | ||
1442 | self:next(ls) -- skip 'for' | ||
1443 | local varname = self:str_checkname(ls) -- first variable name | ||
1444 | local c = ls.t.token | ||
1445 | if c == "=" then | ||
1446 | self:fornum(ls, varname, line) | ||
1447 | elseif c == "," or c == "TK_IN" then | ||
1448 | self:forlist(ls, varname) | ||
1449 | else | ||
1450 | luaX:syntaxerror(ls, "`=' or `in' expected") | ||
1451 | end | ||
1452 | self:check_match(ls, "TK_END", "TK_FOR", line) | ||
1453 | self:leaveblock(fs) | ||
1454 | end | ||
1455 | |||
1456 | ------------------------------------------------------------------------ | ||
1457 | -- parse part of an if control structure, including the condition | ||
1458 | -- * used in ifstat() | ||
1459 | ------------------------------------------------------------------------ | ||
1460 | function luaY:test_then_block(ls, v) | ||
1461 | -- test_then_block -> [IF | ELSEIF] cond THEN block | ||
1462 | self:next(ls) -- skip IF or ELSEIF | ||
1463 | self:cond(ls, v) | ||
1464 | self:check(ls, "TK_THEN") | ||
1465 | self:block(ls) -- 'then' part | ||
1466 | end | ||
1467 | |||
1468 | ------------------------------------------------------------------------ | ||
1469 | -- parse an if control structure | ||
1470 | -- * used in statements() | ||
1471 | ------------------------------------------------------------------------ | ||
1472 | function luaY:ifstat(ls, line) | ||
1473 | -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END | ||
1474 | local fs = ls.fs | ||
1475 | local v = {} -- expdesc | ||
1476 | local escapelist = luaK.NO_JUMP | ||
1477 | self:test_then_block(ls, v) -- IF cond THEN block | ||
1478 | while ls.t.token == "TK_ELSEIF" do | ||
1479 | escapelist = luaK:concat(fs, escapelist, luaK:jump(fs)) | ||
1480 | luaK:patchtohere(fs, v.f) | ||
1481 | self:test_then_block(ls, v) -- ELSEIF cond THEN block | ||
1482 | end | ||
1483 | if ls.t.token == "TK_ELSE" then | ||
1484 | escapelist = luaK:concat(fs, escapelist, luaK:jump(fs)) | ||
1485 | luaK:patchtohere(fs, v.f) | ||
1486 | self:next(ls) -- skip ELSE (after patch, for correct line info) | ||
1487 | self:block(ls) -- 'else' part | ||
1488 | else | ||
1489 | escapelist = luaK:concat(fs, escapelist, v.f) | ||
1490 | end | ||
1491 | luaK:patchtohere(fs, escapelist) | ||
1492 | self:check_match(ls, "TK_END", "TK_IF", line) | ||
1493 | end | ||
1494 | |||
1495 | ------------------------------------------------------------------------ | ||
1496 | -- parse a local function statement | ||
1497 | -- * used in statements() | ||
1498 | ------------------------------------------------------------------------ | ||
1499 | function luaY:localfunc(ls) | ||
1500 | local v, b = {}, {} -- expdesc | ||
1501 | local fs = ls.fs | ||
1502 | self:new_localvar(ls, self:str_checkname(ls), 0) | ||
1503 | self:init_exp(v, "VLOCAL", fs.freereg) | ||
1504 | luaK:reserveregs(fs, 1) | ||
1505 | self:adjustlocalvars(ls, 1) | ||
1506 | self:body(ls, b, false, ls.linenumber) | ||
1507 | luaK:storevar(fs, v, b) | ||
1508 | -- debug information will only see the variable after this point! | ||
1509 | self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc | ||
1510 | end | ||
1511 | |||
1512 | ------------------------------------------------------------------------ | ||
1513 | -- parse a local variable declaration statement | ||
1514 | -- * used in statements() | ||
1515 | ------------------------------------------------------------------------ | ||
1516 | function luaY:localstat(ls) | ||
1517 | -- stat -> LOCAL NAME {',' NAME} ['=' explist1] | ||
1518 | local nvars = 0 | ||
1519 | local nexps | ||
1520 | local e = {} -- expdesc | ||
1521 | repeat | ||
1522 | self:new_localvar(ls, self:str_checkname(ls), nvars) | ||
1523 | nvars = nvars + 1 | ||
1524 | until not self:testnext(ls, ",") | ||
1525 | if self:testnext(ls, "=") then | ||
1526 | nexps = self:explist1(ls, e) | ||
1527 | else | ||
1528 | e.k = "VVOID" | ||
1529 | nexps = 0 | ||
1530 | end | ||
1531 | self:adjust_assign(ls, nvars, nexps, e) | ||
1532 | self:adjustlocalvars(ls, nvars) | ||
1533 | end | ||
1534 | |||
1535 | ------------------------------------------------------------------------ | ||
1536 | -- parse a function name specification | ||
1537 | -- * used in funcstat() | ||
1538 | ------------------------------------------------------------------------ | ||
1539 | function luaY:funcname(ls, v) | ||
1540 | -- funcname -> NAME {field} [':' NAME] | ||
1541 | local needself = false | ||
1542 | self:singlevar(ls, v, 1) | ||
1543 | while ls.t.token == "." do | ||
1544 | self:field(ls, v) | ||
1545 | end | ||
1546 | if ls.t.token == ":" then | ||
1547 | needself = true | ||
1548 | self:field(ls, v) | ||
1549 | end | ||
1550 | return needself | ||
1551 | end | ||
1552 | |||
1553 | ------------------------------------------------------------------------ | ||
1554 | -- parse a function statement | ||
1555 | -- * used in statements() | ||
1556 | ------------------------------------------------------------------------ | ||
1557 | function luaY:funcstat(ls, line) | ||
1558 | -- funcstat -> FUNCTION funcname body | ||
1559 | local v, b = {}, {} -- expdesc | ||
1560 | self:next(ls) -- skip FUNCTION | ||
1561 | local needself = self:funcname(ls, v) | ||
1562 | self:body(ls, b, needself, line) | ||
1563 | luaK:storevar(ls.fs, v, b) | ||
1564 | luaK:fixline(ls.fs, line) -- definition 'happens' in the first line | ||
1565 | end | ||
1566 | |||
1567 | ------------------------------------------------------------------------ | ||
1568 | -- parse a function call with no returns or an assignment statement | ||
1569 | -- * used in statements() | ||
1570 | ------------------------------------------------------------------------ | ||
1571 | function luaY:exprstat(ls) | ||
1572 | -- stat -> func | assignment | ||
1573 | local fs = ls.fs | ||
1574 | local v = {} -- LHS_assign | ||
1575 | v.v = {} | ||
1576 | self:primaryexp(ls, v.v) | ||
1577 | if v.v.k == "VCALL" then -- stat -> func | ||
1578 | luaK:setcallreturns(fs, v.v, 0) -- call statement uses no results | ||
1579 | else -- stat -> assignment | ||
1580 | v.prev = nil | ||
1581 | self:assignment(ls, v, 1) | ||
1582 | end | ||
1583 | end | ||
1584 | |||
1585 | ------------------------------------------------------------------------ | ||
1586 | -- parse a return statement | ||
1587 | -- * used in statements() | ||
1588 | ------------------------------------------------------------------------ | ||
1589 | function luaY:retstat(ls) | ||
1590 | -- stat -> RETURN explist | ||
1591 | local fs = ls.fs | ||
1592 | local e = {} -- expdesc | ||
1593 | local first, nret -- registers with returned values | ||
1594 | self:next(ls) -- skip RETURN | ||
1595 | if self:block_follow(ls.t.token) or ls.t.token == ";" then | ||
1596 | first, nret = 0, 0 -- return no values | ||
1597 | else | ||
1598 | nret = self:explist1(ls, e) -- optional return values | ||
1599 | if e.k == "VCALL" then | ||
1600 | luaK:setcallreturns(fs, e, self.LUA_MULTRET) | ||
1601 | if nret == 1 then -- tail call? | ||
1602 | luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL") | ||
1603 | lua_assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar) | ||
1604 | end | ||
1605 | first = fs.nactvar | ||
1606 | nret = self.LUA_MULTRET -- return all values | ||
1607 | else | ||
1608 | if nret == 1 then -- only one single value? | ||
1609 | first = luaK:exp2anyreg(fs, e) | ||
1610 | else | ||
1611 | luaK:exp2nextreg(fs, e) -- values must go to the 'stack' | ||
1612 | first = fs.nactvar -- return all 'active' values | ||
1613 | lua_assert(nret == fs.freereg - first) | ||
1614 | end | ||
1615 | end--if | ||
1616 | end--if | ||
1617 | luaK:codeABC(fs, "OP_RETURN", first, nret + 1, 0) | ||
1618 | end | ||
1619 | |||
1620 | ------------------------------------------------------------------------ | ||
1621 | -- parse a break statement | ||
1622 | -- * used in statements() | ||
1623 | ------------------------------------------------------------------------ | ||
1624 | function luaY:breakstat(ls) | ||
1625 | -- stat -> BREAK | ||
1626 | local fs = ls.fs | ||
1627 | local bl = fs.bl | ||
1628 | local upval = false | ||
1629 | self:next(ls) -- skip BREAK | ||
1630 | while bl and not bl.isbreakable do | ||
1631 | if bl.upval then upval = true end | ||
1632 | bl = bl.previous | ||
1633 | end | ||
1634 | if not bl then | ||
1635 | luaX:syntaxerror(ls, "no loop to break") | ||
1636 | end | ||
1637 | if upval then | ||
1638 | luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) | ||
1639 | end | ||
1640 | bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs)) | ||
1641 | end | ||
1642 | |||
1643 | ------------------------------------------------------------------------ | ||
1644 | -- initial parsing for statements, calls a lot of functions | ||
1645 | -- * returns boolean instead of 0|1 | ||
1646 | -- * used in chunk() | ||
1647 | ------------------------------------------------------------------------ | ||
1648 | function luaY:statement(ls) | ||
1649 | local line = ls.linenumber -- may be needed for error messages | ||
1650 | local c = ls.t.token | ||
1651 | if c == "TK_IF" then -- stat -> ifstat | ||
1652 | self:ifstat(ls, line) | ||
1653 | return false | ||
1654 | elseif c == "TK_WHILE" then -- stat -> whilestat | ||
1655 | self:whilestat(ls, line) | ||
1656 | return false | ||
1657 | elseif c == "TK_DO" then -- stat -> DO block END | ||
1658 | self:next(ls) -- skip DO | ||
1659 | self:block(ls) | ||
1660 | self:check_match(ls, "TK_END", "TK_DO", line) | ||
1661 | return false | ||
1662 | elseif c == "TK_FOR" then -- stat -> forstat | ||
1663 | self:forstat(ls, line) | ||
1664 | return false | ||
1665 | elseif c == "TK_REPEAT" then -- stat -> repeatstat | ||
1666 | self:repeatstat(ls, line) | ||
1667 | return false | ||
1668 | elseif c == "TK_FUNCTION" then -- stat -> funcstat | ||
1669 | self:funcstat(ls, line) | ||
1670 | return false | ||
1671 | elseif c == "TK_LOCAL" then -- stat -> localstat | ||
1672 | self:next(ls) -- skip LOCAL | ||
1673 | if self:testnext(ls, "TK_FUNCTION") then -- local function? | ||
1674 | self:localfunc(ls) | ||
1675 | else | ||
1676 | self:localstat(ls) | ||
1677 | end | ||
1678 | return false | ||
1679 | elseif c == "TK_RETURN" then -- stat -> retstat | ||
1680 | self:retstat(ls) | ||
1681 | return true -- must be last statement | ||
1682 | elseif c == "TK_BREAK" then -- stat -> breakstat | ||
1683 | self:breakstat(ls) | ||
1684 | return true -- must be last statement | ||
1685 | else | ||
1686 | self:exprstat(ls) | ||
1687 | return false -- to avoid warnings | ||
1688 | end--if c | ||
1689 | end | ||
1690 | |||
1691 | ------------------------------------------------------------------------ | ||
1692 | -- parse a chunk, which consists of a bunch of statements | ||
1693 | -- * used in parser(), body(), block() | ||
1694 | ------------------------------------------------------------------------ | ||
1695 | function luaY:chunk(ls) | ||
1696 | -- chunk -> { stat [';'] } | ||
1697 | local islast = false | ||
1698 | self:enterlevel(ls) | ||
1699 | while not islast and not self:block_follow(ls.t.token) do | ||
1700 | islast = self:statement(ls) | ||
1701 | self:testnext(ls, ";") | ||
1702 | lua_assert(ls.fs.freereg >= ls.fs.nactvar) | ||
1703 | ls.fs.freereg = ls.fs.nactvar -- free registers | ||
1704 | end | ||
1705 | self:leavelevel(ls) | ||
1706 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | luac.lua | ||
4 | Primitive luac in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * based on luac.lua in the test directory of the 5.0.3 distribution | ||
18 | -- * usage: lua luac.lua file.lua | ||
19 | ----------------------------------------------------------------------]] | ||
20 | |||
21 | ------------------------------------------------------------------------ | ||
22 | -- load and initialize the required modules | ||
23 | ------------------------------------------------------------------------ | ||
24 | require("lzio.lua") | ||
25 | require("llex.lua") | ||
26 | require("lopcodes.lua") | ||
27 | require("ldump.lua") | ||
28 | require("lcode.lua") | ||
29 | require("lparser.lua") | ||
30 | |||
31 | luaX:init() -- required by llex | ||
32 | local LuaState = {} -- dummy, not actually used, but retained since | ||
33 | -- the intention is to complete a straight port | ||
34 | |||
35 | ------------------------------------------------------------------------ | ||
36 | -- interfacing to yueliang | ||
37 | ------------------------------------------------------------------------ | ||
38 | |||
39 | -- currently asserts are enabled because the codebase hasn't been tested | ||
40 | -- much (if you don't want asserts, just comment them out) | ||
41 | function lua_assert(test) | ||
42 | if not test then error("assertion failed!") end | ||
43 | end | ||
44 | |||
45 | function yloadfile(filename) | ||
46 | -- luaZ:make_getF returns a file chunk reader | ||
47 | -- luaZ:init returns a zio input stream | ||
48 | local zio = luaZ:init(luaZ:make_getF(filename), nil, "@"..filename) | ||
49 | if not zio then return end | ||
50 | -- luaY:parser parses the input stream | ||
51 | -- func is the function prototype in tabular form; in C, func can | ||
52 | -- now be used directly by the VM, this can't be done in Lua | ||
53 | local func = luaY:parser(LuaState, zio, nil) | ||
54 | -- luaU:make_setS returns a string chunk writer | ||
55 | local writer, buff = luaU:make_setS() | ||
56 | -- luaU:dump builds a binary chunk | ||
57 | luaU:dump(LuaState, func, writer, buff) | ||
58 | -- a string.dump equivalent in returned | ||
59 | return buff.data | ||
60 | end | ||
61 | |||
62 | ------------------------------------------------------------------------ | ||
63 | -- command line interface | ||
64 | ------------------------------------------------------------------------ | ||
65 | |||
66 | assert(arg[1] ~= nil and arg[2] == nil, "usage: lua luac.lua file.lua") | ||
67 | local f = assert(io.open("luac.out","wb")) | ||
68 | f:write(assert(yloadfile(arg[1]))) | ||
69 | io.close(f) | ||
70 | |||
71 | --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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lzio.lua | ||
4 | Lua 5 buffered streams in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * EOZ is implemented as a string, "EOZ" | ||
18 | -- * Format of z structure (ZIO) | ||
19 | -- z.n -- bytes still unread | ||
20 | -- z.p -- last read position in buffer | ||
21 | -- z.reader -- chunk reader function | ||
22 | -- z.data -- additional data | ||
23 | -- z.name -- name of stream | ||
24 | -- * Current position, p, is now last read index instead of a pointer | ||
25 | -- | ||
26 | -- Not implemented: | ||
27 | -- * luaZ_lookahead: used only in lapi.c:lua_load to detect binary chunk | ||
28 | -- * luaZ_read: used only in lundump.c:ezread to read +1 bytes | ||
29 | -- * luaZ_openspace: dropped; let Lua handle buffers as strings | ||
30 | -- * luaZ buffer macros: dropped; unused for now | ||
31 | -- | ||
32 | -- Alternatives: | ||
33 | -- * zname(z) is z.name | ||
34 | -- | ||
35 | -- Added: | ||
36 | -- (both of the following are vaguely adapted from lauxlib.c) | ||
37 | -- * luaZ:make_getS: create Chunkreader from a string | ||
38 | -- * luaZ:make_getF: create Chunkreader that reads from a file | ||
39 | ----------------------------------------------------------------------]] | ||
40 | |||
41 | luaZ = {} | ||
42 | |||
43 | ------------------------------------------------------------------------ | ||
44 | -- * reader() should return a string, or nil if nothing else to parse. | ||
45 | -- Unlike Chunkreaders, there are no arguments like additional data | ||
46 | -- * Chunkreaders are handled in lauxlib.h, see luaL_load(file|buffer) | ||
47 | -- * Original Chunkreader: | ||
48 | -- const char * (*lua_Chunkreader) (lua_State *L, void *ud, size_t *sz); | ||
49 | -- * This Lua chunk reader implementation: | ||
50 | -- returns string or nil, no arguments to function | ||
51 | ------------------------------------------------------------------------ | ||
52 | |||
53 | ------------------------------------------------------------------------ | ||
54 | -- create a chunk reader from a source string | ||
55 | ------------------------------------------------------------------------ | ||
56 | function luaZ:make_getS(buff) | ||
57 | local b = buff | ||
58 | return function() -- chunk reader anonymous function here | ||
59 | if not b then return nil end | ||
60 | local data = b | ||
61 | b = nil | ||
62 | return data | ||
63 | end | ||
64 | end | ||
65 | |||
66 | ------------------------------------------------------------------------ | ||
67 | -- create a chunk reader from a source file | ||
68 | ------------------------------------------------------------------------ | ||
69 | function luaZ:make_getF(filename) | ||
70 | local LUAL_BUFFERSIZE = 512 | ||
71 | local h = io.open(filename, "r") | ||
72 | if not h then return nil end | ||
73 | return function() -- chunk reader anonymous function here | ||
74 | if not h or io.type(h) == "closed file" then return nil end | ||
75 | local buff = h:read(LUAL_BUFFERSIZE) | ||
76 | if not buff then h:close(); h = nil end | ||
77 | return buff | ||
78 | end | ||
79 | end | ||
80 | |||
81 | ------------------------------------------------------------------------ | ||
82 | -- creates a zio input stream | ||
83 | -- returns the ZIO structure, z | ||
84 | ------------------------------------------------------------------------ | ||
85 | function luaZ:init(reader, data, name) | ||
86 | if not reader then return end | ||
87 | local z = {} | ||
88 | z.reader = reader | ||
89 | z.data = data or "" | ||
90 | z.name = name | ||
91 | -- set up additional data for reading | ||
92 | if not data or data == "" then z.n = 0 else z.n = string.len(data) end | ||
93 | z.p = 0 | ||
94 | return z | ||
95 | end | ||
96 | |||
97 | ------------------------------------------------------------------------ | ||
98 | -- fill up input buffer | ||
99 | ------------------------------------------------------------------------ | ||
100 | function luaZ:fill(z) | ||
101 | local data = z.reader() | ||
102 | z.data = data | ||
103 | if not data or data == "" then return "EOZ" end | ||
104 | z.n = string.len(data) - 1 | ||
105 | z.p = 1 | ||
106 | return string.sub(data, 1, 1) | ||
107 | end | ||
108 | |||
109 | ------------------------------------------------------------------------ | ||
110 | -- get next character from the input stream | ||
111 | ------------------------------------------------------------------------ | ||
112 | function luaZ:zgetc(z) | ||
113 | if z.n > 0 then | ||
114 | z.n = z.n - 1 | ||
115 | z.p = z.p + 1 | ||
116 | return string.sub(z.data, z.p, z.p) | ||
117 | else | ||
118 | return self:fill(z) | ||
119 | end | ||
120 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | bench_llex.lua | ||
4 | Benchmark test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | require("../lzio") | ||
16 | require("../llex") | ||
17 | luaX:init() | ||
18 | |||
19 | ------------------------------------------------------------------------ | ||
20 | -- load in a standard set of sample files | ||
21 | -- * file set is 5.0.3 front end set sans luac.lua | ||
22 | ------------------------------------------------------------------------ | ||
23 | |||
24 | local fileset, totalsize = {}, 0 | ||
25 | for fn in string.gfind([[ | ||
26 | ../lcode.lua | ||
27 | ../ldump.lua | ||
28 | ../llex.lua | ||
29 | ../lopcodes.lua | ||
30 | ../lparser.lua | ||
31 | ../lzio.lua | ||
32 | ]], "%S+") do | ||
33 | table.insert(fileset, fn) | ||
34 | end | ||
35 | |||
36 | for i = 1, table.getn(fileset) do | ||
37 | local fn = fileset[i] | ||
38 | local inf = io.open(fn, "rb") | ||
39 | if not inf then | ||
40 | error("failed to open "..fn.." for reading") | ||
41 | end | ||
42 | local data = inf:read("*a") | ||
43 | local data_sz = string.len(data) | ||
44 | inf:close() | ||
45 | if not data or data_sz == 0 then | ||
46 | error("failed to read data from "..fn.." or file is zero-length") | ||
47 | end | ||
48 | totalsize = totalsize + data_sz | ||
49 | fileset[i] = data | ||
50 | end | ||
51 | |||
52 | ------------------------------------------------------------------------ | ||
53 | -- benchmark tester | ||
54 | ------------------------------------------------------------------------ | ||
55 | |||
56 | local DURATION = 5 -- how long the benchmark should run | ||
57 | |||
58 | local L = {} -- LuaState | ||
59 | local LS = {} -- LexState | ||
60 | |||
61 | local time = os.time | ||
62 | local lexedsize = 0 | ||
63 | local tnow, elapsed = time(), 0 | ||
64 | |||
65 | while time() == tnow do end -- wait for second to click over | ||
66 | tnow = time() | ||
67 | |||
68 | while true do | ||
69 | for i = 1, table.getn(fileset) do | ||
70 | ------------------------------------------------------------ | ||
71 | local chunk = fileset[i] | ||
72 | local z = luaZ:init(luaZ:make_getS(chunk), nil, "=string") | ||
73 | luaX:setinput(L, LS, z, z.name) | ||
74 | while true do | ||
75 | LS.t.token = luaX:lex(LS, LS.t) | ||
76 | local tok, seminfo = LS.t.token, LS.t.seminfo | ||
77 | if tok == "TK_EOS" then break end | ||
78 | end | ||
79 | ------------------------------------------------------------ | ||
80 | lexedsize = lexedsize + string.len(chunk) | ||
81 | if time() > tnow then | ||
82 | tnow = time() | ||
83 | elapsed = elapsed + 1 | ||
84 | if elapsed >= DURATION then | ||
85 | -- report performance of lexer | ||
86 | lexedsize = lexedsize / 1024 | ||
87 | local speed = lexedsize / DURATION | ||
88 | print("Lexer performance:") | ||
89 | print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) | ||
90 | print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) | ||
91 | -- repeat until user breaks program | ||
92 | elapsed = 0 | ||
93 | end | ||
94 | end | ||
95 | ------------------------------------------------------------ | ||
96 | end--for | ||
97 | end--while | ||
98 | |||
99 | -- 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 @@ | |||
1 | local a = 47 | ||
2 | local b = "hello, world!" | ||
3 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_ldump.lua | ||
4 | Test for ldump.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- test dump chunkwriter style | ||
17 | ------------------------------------------------------------------------ | ||
18 | |||
19 | require("../lopcodes") | ||
20 | require("../ldump") | ||
21 | |||
22 | -- Original typedef: | ||
23 | --int (*lua_Chunkwriter) (lua_State *L, const void* p, size_t sz, void* ud); | ||
24 | |||
25 | local MyWriter, MyBuff = luaU:make_setS() | ||
26 | if not MyWriter then | ||
27 | error("failed to initialize using make_setS") | ||
28 | end | ||
29 | MyWriter("hello, ", MyBuff) | ||
30 | MyWriter("world!", MyBuff) | ||
31 | print(MyBuff.data) | ||
32 | |||
33 | local MyWriter, MyBuff = luaU:make_setF("try.txt") | ||
34 | if not MyWriter then | ||
35 | error("failed to initialize using make_setF") | ||
36 | end | ||
37 | MyWriter("hello, ", MyBuff) | ||
38 | MyWriter("world!", MyBuff) | ||
39 | MyWriter(nil, MyBuff) | ||
40 | |||
41 | ------------------------------------------------------------------------ | ||
42 | -- test output of a function prototype | ||
43 | -- * data can be copied from a ChunkSpy listing output | ||
44 | ------------------------------------------------------------------------ | ||
45 | -- local a = 47 | ||
46 | -- local b = "hello, world!" | ||
47 | -- print(a, b) | ||
48 | ------------------------------------------------------------------------ | ||
49 | |||
50 | local F = {} | ||
51 | F.source = "sample.lua" | ||
52 | F.lineDefined = 0 | ||
53 | F.nups = 0 | ||
54 | F.numparams = 0 | ||
55 | F.is_vararg = 0 | ||
56 | F.maxstacksize = 5 | ||
57 | F.sizelineinfo = 7 | ||
58 | F.lineinfo = {} | ||
59 | F.lineinfo[0] = 1 | ||
60 | F.lineinfo[1] = 2 | ||
61 | F.lineinfo[2] = 3 | ||
62 | F.lineinfo[3] = 3 | ||
63 | F.lineinfo[4] = 3 | ||
64 | F.lineinfo[5] = 3 | ||
65 | F.lineinfo[6] = 3 | ||
66 | F.sizelocvars = 2 | ||
67 | F.locvars = {} | ||
68 | F.locvars[0] = { varname = "a", startpc = 1, endpc = 6 } | ||
69 | F.locvars[1] = { varname = "b", startpc = 2, endpc = 6 } | ||
70 | F.sizeupvalues = 0 | ||
71 | F.upvalues = {} | ||
72 | F.sizek = 3 | ||
73 | F.k = {} | ||
74 | F.k[0] = { value = 47 } | ||
75 | F.k[1] = { value = "hello, world!" } | ||
76 | F.k[2] = { value = "print" } | ||
77 | F.sizep = 0 | ||
78 | F.p = {} | ||
79 | F.sizecode = 7 | ||
80 | F.code = {} | ||
81 | F.code[0] = { OP = 1, A = 0, Bx = 0 } | ||
82 | F.code[1] = { OP = 1, A = 1, Bx = 1 } | ||
83 | F.code[2] = { OP = 5, A = 2, Bx = 2 } | ||
84 | F.code[3] = { OP = 0, A = 3, B = 0, C = 0 } | ||
85 | F.code[4] = { OP = 0, A = 4, B = 1, C = 0 } | ||
86 | F.code[5] = { OP = 25, A = 2, B = 3, C = 1 } | ||
87 | F.code[6] = { OP = 27, A = 0, B = 1, C = 0 } | ||
88 | |||
89 | local L = {} | ||
90 | --[[ | ||
91 | local Writer, Buff = luaU:make_setS() | ||
92 | luaU:dump(L, F, Writer, Buff) | ||
93 | for i = 1, string.len(Buff.data) do | ||
94 | io.stdout:write(string.byte(string.sub(Buff.data, i, i)).." ") | ||
95 | end | ||
96 | --]] | ||
97 | local Writer, Buff = luaU:make_setF("try.out") | ||
98 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_llex.lua | ||
4 | Test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- if BRIEF is not set to false, auto-test will silently succeed | ||
17 | ------------------------------------------------------------------------ | ||
18 | BRIEF = true -- if set to true, messages are less verbose | ||
19 | |||
20 | require("../lzio") | ||
21 | require("../llex") | ||
22 | luaX:init() | ||
23 | |||
24 | ------------------------------------------------------------------------ | ||
25 | -- simple manual tests | ||
26 | ------------------------------------------------------------------------ | ||
27 | |||
28 | --[[ | ||
29 | local L = {} -- LuaState | ||
30 | local LS = {} -- LexState | ||
31 | |||
32 | local function dump(z) | ||
33 | luaX:setinput(L, LS, z, z.name) | ||
34 | while true do | ||
35 | LS.t.token = luaX:lex(LS, LS.t) | ||
36 | local tok, seminfo = LS.t.token, LS.t.seminfo | ||
37 | if tok == "TK_NAME" then | ||
38 | seminfo = " "..seminfo | ||
39 | elseif tok == "TK_NUMBER" then | ||
40 | seminfo = " "..seminfo | ||
41 | elseif tok == "TK_STRING" then | ||
42 | seminfo = " '"..seminfo.."'" | ||
43 | else | ||
44 | seminfo = "" | ||
45 | end | ||
46 | io.stdout:write(tok..seminfo.."\n") | ||
47 | if tok == "TK_EOS" then break end | ||
48 | end | ||
49 | end | ||
50 | |||
51 | local function try_string(chunk) | ||
52 | dump(luaZ:init(luaZ:make_getS(chunk), nil, "=string")) | ||
53 | end | ||
54 | local function try_file(filename) | ||
55 | dump(luaZ:init(luaZ:make_getF(filename), nil, filename)) | ||
56 | end | ||
57 | |||
58 | z = try_string("local c = luaZ:zgetc(z)") | ||
59 | z = try_file("test_lzio.lua") | ||
60 | z = try_file("test_llex.lua") | ||
61 | os.exit() | ||
62 | --]] | ||
63 | |||
64 | ------------------------------------------------------------------------ | ||
65 | -- auto-testing of simple test cases to validate lexer behaviour: | ||
66 | -- * NOTE coverage has not been checked; not comprehensive | ||
67 | -- * only test cases with non-empty comments are processed | ||
68 | -- * if no result, then the output is displayed for manual decision | ||
69 | -- (output may be used to set expected success or fail text) | ||
70 | -- * cases expected to be successful may be a partial match | ||
71 | -- * cases expected to fail may also be a partial match | ||
72 | ------------------------------------------------------------------------ | ||
73 | |||
74 | -- [[ | ||
75 | local function auto_test() | ||
76 | local PASS, FAIL = true, false | ||
77 | ------------------------------------------------------------------ | ||
78 | -- table of test cases | ||
79 | ------------------------------------------------------------------ | ||
80 | local test_cases = | ||
81 | { | ||
82 | ------------------------------------------------------------- | ||
83 | --{ "comment", -- comment about the test | ||
84 | -- "chunk", -- chunk to test | ||
85 | -- PASS, -- PASS or FAIL outcome | ||
86 | -- "output", -- output to compare against | ||
87 | --}, | ||
88 | ------------------------------------------------------------- | ||
89 | { "empty chunk string, test EOS", | ||
90 | "", | ||
91 | PASS, "1 TK_EOS", | ||
92 | }, | ||
93 | ------------------------------------------------------------- | ||
94 | { "line number counting", | ||
95 | "\n\n\r\n", | ||
96 | PASS, "4 TK_EOS", | ||
97 | }, | ||
98 | ------------------------------------------------------------- | ||
99 | { "various whitespaces", | ||
100 | " \n\t\t\n \t \t \n\n", | ||
101 | PASS, "5 TK_EOS", | ||
102 | }, | ||
103 | ------------------------------------------------------------- | ||
104 | { "short comment ending in EOS", | ||
105 | "-- moo moo", | ||
106 | PASS, "1 TK_EOS", | ||
107 | }, | ||
108 | ------------------------------------------------------------- | ||
109 | { "short comment ending in newline", | ||
110 | "-- moo moo\n", | ||
111 | PASS, "2 TK_EOS", | ||
112 | }, | ||
113 | ------------------------------------------------------------- | ||
114 | { "several lines of short comments", | ||
115 | "--moo\n-- moo moo\n\n--\tmoo\n", | ||
116 | PASS, "5 TK_EOS", | ||
117 | }, | ||
118 | ------------------------------------------------------------- | ||
119 | { "basic block comment", | ||
120 | "--[[bovine]]", | ||
121 | PASS, "1 TK_EOS", | ||
122 | }, | ||
123 | ------------------------------------------------------------- | ||
124 | { "unterminated block comment 1", | ||
125 | "--[[bovine", | ||
126 | FAIL, ":1: unfinished long comment near `<eof>'", | ||
127 | }, | ||
128 | ------------------------------------------------------------- | ||
129 | { "unterminated block comment 2", | ||
130 | "--[[bovine]", | ||
131 | FAIL, ":1: unfinished long comment near `<eof>'", | ||
132 | }, | ||
133 | ------------------------------------------------------------- | ||
134 | { "unterminated block comment 3", | ||
135 | "--[[bovine\nmoo moo\nwoof", | ||
136 | FAIL, ":3: unfinished long comment near `<eof>'", | ||
137 | }, | ||
138 | ------------------------------------------------------------- | ||
139 | { "basic long string", | ||
140 | "\n[[bovine]]\n", | ||
141 | PASS, "2 TK_STRING = bovine\n3 TK_EOS", | ||
142 | }, | ||
143 | ------------------------------------------------------------- | ||
144 | { "first newline consumed in long string", | ||
145 | "[[\nmoo]]", | ||
146 | PASS, "2 TK_STRING = moo\n2 TK_EOS", | ||
147 | }, | ||
148 | ------------------------------------------------------------- | ||
149 | { "multiline long string", | ||
150 | "[[moo\nmoo moo\n]]", | ||
151 | PASS, "3 TK_STRING = moo\nmoo moo\n\n3 TK_EOS", | ||
152 | }, | ||
153 | ------------------------------------------------------------- | ||
154 | { "unterminated long string 1", | ||
155 | "\n[[\nbovine", | ||
156 | FAIL, ":3: unfinished long string near `<eof>'", | ||
157 | }, | ||
158 | ------------------------------------------------------------- | ||
159 | { "unterminated long string 2", | ||
160 | "[[bovine]", | ||
161 | FAIL, ":1: unfinished long string near `<eof>'", | ||
162 | }, | ||
163 | ------------------------------------------------------------- | ||
164 | { "unterminated long string 3", | ||
165 | "[[[[ \n", | ||
166 | FAIL, ":2: unfinished long string near `<eof>'", | ||
167 | }, | ||
168 | ------------------------------------------------------------- | ||
169 | { "nested long string 1", | ||
170 | "[[moo[[moo]]moo]]", | ||
171 | PASS, "moo[[moo]]moo", | ||
172 | }, | ||
173 | ------------------------------------------------------------- | ||
174 | { "nested long string 2", | ||
175 | "[[moo[[moo[[[[]]]]moo]]moo]]", | ||
176 | PASS, "moo[[moo[[[[]]]]moo]]moo", | ||
177 | }, | ||
178 | ------------------------------------------------------------- | ||
179 | { "nested long string 3", | ||
180 | "[[[[[[]]]][[[[]]]]]]", | ||
181 | PASS, "[[[[]]]][[[[]]]]", | ||
182 | }, | ||
183 | ------------------------------------------------------------- | ||
184 | { "brackets in long strings 1", | ||
185 | "[[moo[moo]]", | ||
186 | PASS, "moo[moo", | ||
187 | }, | ||
188 | ------------------------------------------------------------- | ||
189 | { "brackets in long strings 2", | ||
190 | "[[moo[[moo]moo]]moo]]", | ||
191 | PASS, "moo[[moo]moo]]moo", | ||
192 | }, | ||
193 | ------------------------------------------------------------- | ||
194 | { "unprocessed escapes in long strings", | ||
195 | [[ [[\a\b\f\n\r\t\v\123]] ]], | ||
196 | PASS, [[\a\b\f\n\r\t\v\123]], | ||
197 | }, | ||
198 | ------------------------------------------------------------- | ||
199 | { "unbalanced long string", | ||
200 | "[[moo]]moo]]", | ||
201 | PASS, "1 TK_STRING = moo\n1 TK_NAME = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 TK_EOS", | ||
202 | }, | ||
203 | ------------------------------------------------------------- | ||
204 | { "keywords 1", | ||
205 | "and break do else", | ||
206 | PASS, "1 TK_AND\n1 TK_BREAK\n1 TK_DO\n1 TK_ELSE\n1 TK_EOS", | ||
207 | }, | ||
208 | ------------------------------------------------------------- | ||
209 | { "keywords 2", | ||
210 | "elseif end false for", | ||
211 | PASS, "1 TK_ELSEIF\n1 TK_END\n1 TK_FALSE\n1 TK_FOR\n1 TK_EOS", | ||
212 | }, | ||
213 | ------------------------------------------------------------- | ||
214 | { "keywords 3", | ||
215 | "function if in local nil", | ||
216 | PASS, "1 TK_FUNCTION\n1 TK_IF\n1 TK_IN\n1 TK_LOCAL\n1 TK_NIL\n1 TK_EOS", | ||
217 | }, | ||
218 | ------------------------------------------------------------- | ||
219 | { "keywords 4", | ||
220 | "not or repeat return", | ||
221 | PASS, "1 TK_NOT\n1 TK_OR\n1 TK_REPEAT\n1 TK_RETURN\n1 TK_EOS", | ||
222 | }, | ||
223 | ------------------------------------------------------------- | ||
224 | { "keywords 5", | ||
225 | "then true until while", | ||
226 | PASS, "1 TK_THEN\n1 TK_TRUE\n1 TK_UNTIL\n1 TK_WHILE\n1 TK_EOS", | ||
227 | }, | ||
228 | ------------------------------------------------------------- | ||
229 | { "concat and dots", | ||
230 | ".. ...", | ||
231 | PASS, "1 TK_CONCAT\n1 TK_DOTS\n1 TK_EOS", | ||
232 | }, | ||
233 | ------------------------------------------------------------- | ||
234 | { "shbang handling 1", | ||
235 | "#blahblah", | ||
236 | PASS, "1 TK_EOS", | ||
237 | }, | ||
238 | ------------------------------------------------------------- | ||
239 | { "shbang handling 2", | ||
240 | "#blahblah\nmoo moo\n", | ||
241 | PASS, "2 TK_NAME = moo\n2 TK_NAME = moo\n3 TK_EOS", | ||
242 | }, | ||
243 | ------------------------------------------------------------- | ||
244 | { "empty string", | ||
245 | [['']], | ||
246 | PASS, "1 TK_STRING = \n1 TK_EOS", | ||
247 | }, | ||
248 | ------------------------------------------------------------- | ||
249 | { "single-quoted string", | ||
250 | [['bovine']], | ||
251 | PASS, "1 TK_STRING = bovine\n1 TK_EOS", | ||
252 | }, | ||
253 | ------------------------------------------------------------- | ||
254 | { "double-quoted string", | ||
255 | [["bovine"]], | ||
256 | PASS, "1 TK_STRING = bovine\n1 TK_EOS", | ||
257 | }, | ||
258 | ------------------------------------------------------------- | ||
259 | { "unterminated string 1", | ||
260 | [['moo ]], | ||
261 | FAIL, ":1: unfinished string near `<eof>'", | ||
262 | }, | ||
263 | ------------------------------------------------------------- | ||
264 | { "unterminated string 2", | ||
265 | [["moo \n]], | ||
266 | FAIL, ":1: unfinished string near `<eof>'", | ||
267 | }, | ||
268 | ------------------------------------------------------------- | ||
269 | { "escaped newline in string, line number counted", | ||
270 | "\"moo\\\nmoo\\\nmoo\"", | ||
271 | PASS, "3 TK_STRING = moo\nmoo\nmoo\n3 TK_EOS", | ||
272 | }, | ||
273 | ------------------------------------------------------------- | ||
274 | { "escaped characters in string 1", | ||
275 | [["moo\amoo"]], | ||
276 | PASS, "1 TK_STRING = moo\amoo", | ||
277 | }, | ||
278 | ------------------------------------------------------------- | ||
279 | { "escaped characters in string 2", | ||
280 | [["moo\bmoo"]], | ||
281 | PASS, "1 TK_STRING = moo\bmoo", | ||
282 | }, | ||
283 | ------------------------------------------------------------- | ||
284 | { "escaped characters in string 3", | ||
285 | [["moo\f\n\r\t\vmoo"]], | ||
286 | PASS, "1 TK_STRING = moo\f\n\r\t\vmoo", | ||
287 | }, | ||
288 | ------------------------------------------------------------- | ||
289 | { "escaped characters in string 4", | ||
290 | [["\\ \" \' \? \[ \]"]], | ||
291 | PASS, "1 TK_STRING = \\ \" \' \? \[ \]", | ||
292 | }, | ||
293 | ------------------------------------------------------------- | ||
294 | { "escaped characters in string 5", | ||
295 | [["\z \k \: \;"]], | ||
296 | PASS, "1 TK_STRING = z k : ;", | ||
297 | }, | ||
298 | ------------------------------------------------------------- | ||
299 | { "escaped characters in string 6", | ||
300 | [["\8 \65 \160 \180K \097097"]], | ||
301 | PASS, "1 TK_STRING = \8 \65 \160 \180K \097097\n", | ||
302 | }, | ||
303 | ------------------------------------------------------------- | ||
304 | { "escaped characters in string 7", | ||
305 | [["\666"]], | ||
306 | FAIL, ":1: escape sequence too large near `\"'", | ||
307 | }, | ||
308 | ------------------------------------------------------------- | ||
309 | { "simple numbers", | ||
310 | "123 123+", | ||
311 | PASS, "1 TK_NUMBER = 123\n1 TK_NUMBER = 123\n1 CHAR = '+'\n1 TK_EOS", | ||
312 | }, | ||
313 | ------------------------------------------------------------- | ||
314 | { "longer numbers", | ||
315 | "1234567890 12345678901234567890", | ||
316 | PASS, "1 TK_NUMBER = 1234567890\n1 TK_NUMBER = 1.2345678901235e+19\n", | ||
317 | }, | ||
318 | ------------------------------------------------------------- | ||
319 | { "fractional numbers", | ||
320 | ".123 .12345678901234567890", | ||
321 | PASS, "1 TK_NUMBER = 0.123\n1 TK_NUMBER = 0.12345678901235\n", | ||
322 | }, | ||
323 | ------------------------------------------------------------- | ||
324 | { "more numbers with decimal points", | ||
325 | "12345.67890 1.1.", | ||
326 | PASS, "1 TK_NUMBER = 12345.6789\n1 TK_NUMBER = 1.1\n1 CHAR = '.'\n", | ||
327 | }, | ||
328 | ------------------------------------------------------------- | ||
329 | { "double decimal points", | ||
330 | ".1.1", | ||
331 | FAIL, ":1: malformed number near `.1.1'", | ||
332 | }, | ||
333 | ------------------------------------------------------------- | ||
334 | { "double dots within numbers", | ||
335 | "1..1", | ||
336 | FAIL, ":1: ambiguous syntax (decimal point x string concatenation) near `1..'", | ||
337 | }, | ||
338 | ------------------------------------------------------------- | ||
339 | { "incomplete exponential numbers", | ||
340 | "123e", | ||
341 | FAIL, ":1: malformed number near `123e'", | ||
342 | }, | ||
343 | ------------------------------------------------------------- | ||
344 | { "exponential numbers 1", | ||
345 | "1234e5 1234e5.", | ||
346 | PASS, "1 TK_NUMBER = 123400000\n1 TK_NUMBER = 123400000\n1 CHAR = '.'", | ||
347 | }, | ||
348 | ------------------------------------------------------------- | ||
349 | { "exponential numbers 2", | ||
350 | "1234e56 1.23e123", | ||
351 | PASS, "1 TK_NUMBER = 1.234e+59\n1 TK_NUMBER = 1.23e+123\n", | ||
352 | }, | ||
353 | ------------------------------------------------------------- | ||
354 | { "exponential numbers 3", | ||
355 | "12.34e+", | ||
356 | FAIL, ":1: malformed number near `12.34e+'", | ||
357 | }, | ||
358 | ------------------------------------------------------------- | ||
359 | { "exponential numbers 4", | ||
360 | "12.34e+5 123.4e-5 1234.E+5", | ||
361 | PASS, "1 TK_NUMBER = 1234000\n1 TK_NUMBER = 0.001234\n1 TK_NUMBER = 123400000\n", | ||
362 | }, | ||
363 | ------------------------------------------------------------- | ||
364 | { "single character symbols 1", | ||
365 | "= > < ~", | ||
366 | PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n", | ||
367 | }, | ||
368 | ------------------------------------------------------------- | ||
369 | { "double character symbols", | ||
370 | "== >= <= ~=", | ||
371 | PASS, "1 TK_EQ\n1 TK_GE\n1 TK_LE\n1 TK_NE\n", | ||
372 | }, | ||
373 | ------------------------------------------------------------- | ||
374 | { "simple identifiers", | ||
375 | "abc ABC", | ||
376 | PASS, "1 TK_NAME = abc\n1 TK_NAME = ABC\n1 TK_EOS", | ||
377 | }, | ||
378 | ------------------------------------------------------------- | ||
379 | { "more identifiers", | ||
380 | "_abc _ABC", | ||
381 | PASS, "1 TK_NAME = _abc\n1 TK_NAME = _ABC\n1 TK_EOS", | ||
382 | }, | ||
383 | ------------------------------------------------------------- | ||
384 | { "still more identifiers", | ||
385 | "_aB_ _123", | ||
386 | PASS, "1 TK_NAME = _aB_\n1 TK_NAME = _123\n1 TK_EOS", | ||
387 | }, | ||
388 | ------------------------------------------------------------- | ||
389 | { "invalid control character", | ||
390 | "\4", | ||
391 | FAIL, ":1: invalid control char near `char(4)'", | ||
392 | }, | ||
393 | ------------------------------------------------------------- | ||
394 | { "single character symbols 2", | ||
395 | "` ! @ $ %", | ||
396 | PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", | ||
397 | }, | ||
398 | ------------------------------------------------------------- | ||
399 | { "single character symbols 3", | ||
400 | "^ & * ( )", | ||
401 | PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", | ||
402 | }, | ||
403 | ------------------------------------------------------------- | ||
404 | { "single character symbols 4", | ||
405 | "_ - + \\ |", | ||
406 | PASS, "1 TK_NAME = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", | ||
407 | }, | ||
408 | ------------------------------------------------------------- | ||
409 | { "single character symbols 5", | ||
410 | "{ } [ ] :", | ||
411 | PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", | ||
412 | }, | ||
413 | ------------------------------------------------------------- | ||
414 | { "single character symbols 6", | ||
415 | "; , . / ?", | ||
416 | PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", | ||
417 | }, | ||
418 | ------------------------------------------------------------- | ||
419 | } | ||
420 | ------------------------------------------------------------------ | ||
421 | -- perform a test case | ||
422 | ------------------------------------------------------------------ | ||
423 | function do_test_case(count, test_case) | ||
424 | if comment == "" then return end -- skip empty entries | ||
425 | local comment, chunk, outcome, matcher = unpack(test_case) | ||
426 | local result = PASS | ||
427 | local output = "" | ||
428 | -- initialize lexer | ||
429 | local L, LS = {}, {} | ||
430 | local z = luaZ:init(luaZ:make_getS(chunk), nil, "=test") | ||
431 | luaX:setinput(L, LS, z, z.name) | ||
432 | -- lexer test loop | ||
433 | repeat | ||
434 | -- protected call | ||
435 | local status, token = pcall(luaX.lex, luaX, LS, LS.t) | ||
436 | LS.t.token = token | ||
437 | output = output..LS.linenumber.." " | ||
438 | if status then | ||
439 | -- successful call | ||
440 | if string.len(token) > 1 then | ||
441 | if token == "TK_NAME" | ||
442 | or token == "TK_NUMBER" | ||
443 | or token == "TK_STRING" then | ||
444 | token = token.." = "..LS.t.seminfo | ||
445 | end | ||
446 | elseif string.byte(token) >= 32 then -- displayable chars | ||
447 | token = "CHAR = '"..token.."'" | ||
448 | else -- control characters | ||
449 | token = "CHAR = (".. string.byte(token)..")" | ||
450 | end | ||
451 | output = output..token.."\n" | ||
452 | else | ||
453 | -- failed call | ||
454 | output = output..token -- token is the error message | ||
455 | result = FAIL | ||
456 | break | ||
457 | end | ||
458 | until LS.t.token == "TK_EOS" | ||
459 | -- decision making and reporting | ||
460 | local head = "Test "..count..": "..comment | ||
461 | if matcher == "" then | ||
462 | -- nothing to check against, display for manual check | ||
463 | print(head.."\nMANUAL please check manually".. | ||
464 | "\n--chunk---------------------------------\n"..chunk.. | ||
465 | "\n--actual--------------------------------\n"..output.. | ||
466 | "\n\n") | ||
467 | return | ||
468 | else | ||
469 | if outcome == PASS then | ||
470 | -- success expected, may be a partial match | ||
471 | if string.find(output, matcher, 1, 1) and result == PASS then | ||
472 | if not BRIEF then print(head.."\nOK expected success\n") end | ||
473 | return | ||
474 | end | ||
475 | else | ||
476 | -- failure expected, may be a partial match | ||
477 | if string.find(output, matcher, 1, 1) and result == FAIL then | ||
478 | if not BRIEF then print(head.."\nOK expected failure\n") end | ||
479 | return | ||
480 | end | ||
481 | end | ||
482 | -- failed because of unmatched string or boolean result | ||
483 | local function passfail(status) | ||
484 | if status == PASS then return "PASS" else return "FAIL" end | ||
485 | end | ||
486 | print(head.." *FAILED*".. | ||
487 | "\noutcome="..passfail(outcome).. | ||
488 | "\nactual= "..passfail(result).. | ||
489 | "\n--chunk---------------------------------\n"..chunk.. | ||
490 | "\n--expected------------------------------\n"..matcher.. | ||
491 | "\n--actual--------------------------------\n"..output.. | ||
492 | "\n\n") | ||
493 | end | ||
494 | end | ||
495 | ------------------------------------------------------------------ | ||
496 | -- perform auto testing | ||
497 | ------------------------------------------------------------------ | ||
498 | for i,test_case in ipairs(test_cases) do | ||
499 | do_test_case(i, test_case) | ||
500 | end | ||
501 | end | ||
502 | |||
503 | auto_test() | ||
504 | --]] | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser.lua | ||
4 | Test for lparser.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- test the whole kaboodle | ||
17 | ------------------------------------------------------------------------ | ||
18 | |||
19 | require("../lzio") | ||
20 | require("../llex") | ||
21 | require("../lopcodes") | ||
22 | require("../ldump") | ||
23 | require("../lcode") | ||
24 | require("../lparser") | ||
25 | |||
26 | function lua_assert(test) | ||
27 | if not test then error("assertion failed!") end | ||
28 | end | ||
29 | |||
30 | luaX:init() | ||
31 | |||
32 | ------------------------------------------------------------------------ | ||
33 | -- try 1 | ||
34 | ------------------------------------------------------------------------ | ||
35 | |||
36 | local zio = luaZ:init(luaZ:make_getS("local a = 1"), nil, "=string") | ||
37 | local LuaState = {} | ||
38 | local Func = luaY:parser(LuaState, zio, nil) | ||
39 | |||
40 | --[[ | ||
41 | for i, v in Func do | ||
42 | if type(v) == "string" or type(v) == "number" then | ||
43 | print(i, v) | ||
44 | elseif type(v) == "table" then | ||
45 | print(i, "TABLE") | ||
46 | end | ||
47 | end | ||
48 | --]] | ||
49 | |||
50 | local Writer, Buff = luaU:make_setF("parse1.out") | ||
51 | luaU:dump(LuaState, Func, Writer, Buff) | ||
52 | |||
53 | ------------------------------------------------------------------------ | ||
54 | -- try 2 | ||
55 | ------------------------------------------------------------------------ | ||
56 | |||
57 | zio = luaZ:init(luaZ:make_getF("sample.lua"), nil, "@sample.lua") | ||
58 | Func = luaY:parser(LuaState, zio, nil) | ||
59 | Writer, Buff = luaU:make_setF("parse2.out") | ||
60 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser2.lua | ||
4 | Test for lparser.lua, using the test case file | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * the test cases are in the test_lua directory (test_parser-5.0.lua) | ||
18 | ----------------------------------------------------------------------]] | ||
19 | |||
20 | -- * true if you want an output of all failure cases in native Lua, | ||
21 | -- for checking whether test cases fail where you intend them to | ||
22 | local DEBUG_FAILS = false | ||
23 | |||
24 | ------------------------------------------------------------------------ | ||
25 | -- test the whole kaboodle | ||
26 | ------------------------------------------------------------------------ | ||
27 | |||
28 | require("../lzio") | ||
29 | require("../llex") | ||
30 | require("../lopcodes") | ||
31 | require("../ldump") | ||
32 | require("../lcode") | ||
33 | require("../lparser") | ||
34 | |||
35 | function lua_assert(test) | ||
36 | if not test then error("assertion failed!") end | ||
37 | end | ||
38 | |||
39 | luaX:init() | ||
40 | |||
41 | ------------------------------------------------------------------------ | ||
42 | -- load test cases | ||
43 | ------------------------------------------------------------------------ | ||
44 | |||
45 | require("../../test_lua/test_parser-5.0") | ||
46 | |||
47 | local test, expect, heading = {}, {}, {} | ||
48 | local total, total_pass, total_fail = 0, 0, 0 | ||
49 | |||
50 | for ln in string.gfind(tests_source, "([^\n]*)\n") do | ||
51 | if string.find(ln, "^%s*%-%-") then | ||
52 | -- comment, ignore | ||
53 | else | ||
54 | local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") | ||
55 | if m then | ||
56 | heading[total + 1] = head -- informational heading | ||
57 | else | ||
58 | total = total + 1 | ||
59 | local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") | ||
60 | if n then -- FAIL test case | ||
61 | ln = string.sub(ln, 1, n - 1) -- remove comment | ||
62 | expect[total] = "FAIL" | ||
63 | total_fail = total_fail + 1 | ||
64 | else -- PASS test case | ||
65 | expect[total] = "PASS" | ||
66 | total_pass = total_pass + 1 | ||
67 | end--n | ||
68 | test[total] = ln | ||
69 | end--m | ||
70 | end--ln | ||
71 | end--for | ||
72 | |||
73 | print("Tests loaded: "..total.." (total), " | ||
74 | ..total_pass.." (passes), " | ||
75 | ..total_fail.." (fails)") | ||
76 | |||
77 | ------------------------------------------------------------------------ | ||
78 | -- verify test cases using native Lua | ||
79 | ------------------------------------------------------------------------ | ||
80 | |||
81 | local last_head = "TESTS: no heading yet" | ||
82 | for i = 1, total do | ||
83 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
84 | -- show progress | ||
85 | if head then | ||
86 | last_head = head | ||
87 | if DEBUG_FAILS then print("\n"..head.."\n") end | ||
88 | end | ||
89 | ------------------------------------------------------------------ | ||
90 | -- perform test | ||
91 | local f, err = loadstring(test_case) | ||
92 | -- look at outcome | ||
93 | ------------------------------------------------------------------ | ||
94 | if f then-- actual PASS | ||
95 | if expected == "FAIL" then | ||
96 | print("\nVerified as PASS but expected to FAIL".. | ||
97 | "\n-------------------------------------") | ||
98 | print("Lastest heading: "..last_head) | ||
99 | print("TEST: "..test_case) | ||
100 | os.exit() | ||
101 | end | ||
102 | ------------------------------------------------------------------ | ||
103 | else-- actual FAIL | ||
104 | if expected == "PASS" then | ||
105 | print("\nVerified as FAIL but expected to PASS".. | ||
106 | "\n-------------------------------------") | ||
107 | print("Lastest heading: "..last_head) | ||
108 | print("TEST: "..test_case) | ||
109 | print("ERROR: "..err) | ||
110 | os.exit() | ||
111 | end | ||
112 | if DEBUG_FAILS then | ||
113 | print("TEST: "..test_case) | ||
114 | print("ERROR: "..err.."\n") | ||
115 | end | ||
116 | ------------------------------------------------------------------ | ||
117 | end--f | ||
118 | end--for | ||
119 | |||
120 | print("Test cases verified using native Lua, no anomalies.") | ||
121 | |||
122 | ------------------------------------------------------------------------ | ||
123 | -- dump binary chunks to a file if something goes wrong | ||
124 | ------------------------------------------------------------------------ | ||
125 | local function Dump(data, filename) | ||
126 | h = io.open(filename, "wb") | ||
127 | if not h then error("failed to open "..filename.." for writing") end | ||
128 | h:write(data) | ||
129 | h:close() | ||
130 | end | ||
131 | |||
132 | ------------------------------------------------------------------------ | ||
133 | -- test using Yueliang front end | ||
134 | ------------------------------------------------------------------------ | ||
135 | |||
136 | local last_head = "TESTS: no heading yet" | ||
137 | for i = 1, total do | ||
138 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
139 | -- show progress | ||
140 | if head then last_head = head end | ||
141 | ------------------------------------------------------------------ | ||
142 | -- perform test | ||
143 | local LuaState = {} | ||
144 | local zio = luaZ:init(luaZ:make_getS(test_case), nil, "test") | ||
145 | local status, func = pcall(luaY.parser, luaY, LuaState, zio, nil) | ||
146 | -- look at outcome | ||
147 | ------------------------------------------------------------------ | ||
148 | if status then-- actual PASS | ||
149 | if expected == "PASS" then | ||
150 | -- actual PASS and expected PASS, so check binary chunks | ||
151 | local writer, buff = luaU:make_setS() | ||
152 | luaU:dump(LuaState, func, writer, buff) | ||
153 | local bc1 = buff.data -- Yueliang's output | ||
154 | local f = loadstring(test_case, "test") | ||
155 | local bc2 = string.dump(f) -- Lua's output | ||
156 | local die | ||
157 | -- compare outputs | ||
158 | if string.len(bc1) ~= string.len(bc2) then | ||
159 | Dump(bc1, "bc1.out") | ||
160 | Dump(bc2, "bc2.out") | ||
161 | die = "binary chunk sizes different" | ||
162 | elseif bc1 ~= bc2 then | ||
163 | Dump(bc1, "bc1.out") | ||
164 | Dump(bc2, "bc2.out") | ||
165 | die = "binary chunks different" | ||
166 | else | ||
167 | -- everything checks out! | ||
168 | end | ||
169 | if die then | ||
170 | print("\nTested PASS and expected to PASS, but chunks different".. | ||
171 | "\n------------------------------------------------------") | ||
172 | print("Reason: "..die) | ||
173 | print("Lastest heading: "..last_head) | ||
174 | print("TEST: "..test_case) | ||
175 | os.exit() | ||
176 | end | ||
177 | else-- expected FAIL | ||
178 | print("\nTested as PASS but expected to FAIL".. | ||
179 | "\n-----------------------------------") | ||
180 | print("Lastest heading: "..last_head) | ||
181 | print("TEST: "..test_case) | ||
182 | os.exit() | ||
183 | end | ||
184 | ------------------------------------------------------------------ | ||
185 | else-- actual FAIL | ||
186 | if expected == "PASS" then | ||
187 | print("\nTested as FAIL but expected to PASS".. | ||
188 | "\n-----------------------------------") | ||
189 | print("Lastest heading: "..last_head) | ||
190 | print("TEST: "..test_case) | ||
191 | print("ERROR: "..err) | ||
192 | os.exit() | ||
193 | end | ||
194 | ------------------------------------------------------------------ | ||
195 | end--status | ||
196 | io.stdout:write("\rTesting ["..i.."]...") | ||
197 | end--for | ||
198 | print(" done.") | ||
199 | |||
200 | print("Test cases run on Yueliang, no anomalies.") | ||
201 | |||
202 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lzio.lua | ||
4 | Test for lzio.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | -- manual test for lzio.lua lua-style chunk reader | ||
16 | |||
17 | require("../lzio") | ||
18 | |||
19 | local z | ||
20 | function dump(z) | ||
21 | while true do | ||
22 | local c = luaZ:zgetc(z) | ||
23 | io.stdout:write("("..c..")") | ||
24 | if c == "EOZ" then break end | ||
25 | end | ||
26 | io.stdout:write("\n") | ||
27 | end | ||
28 | |||
29 | -- luaZ:make_getS or luaZ:make_getF creates a chunk reader | ||
30 | -- luaZ:init makes a zio stream | ||
31 | |||
32 | -- [[ | ||
33 | z = luaZ:init(luaZ:make_getS("hello, world!"), nil, "=string") | ||
34 | dump(z) | ||
35 | z = luaZ:init(luaZ:make_getS(", world!"), "hello", "=string") | ||
36 | dump(z) | ||
37 | z = luaZ:init(luaZ:make_getS("line1\nline2\n"), "", "=string") | ||
38 | dump(z) | ||
39 | z = luaZ:init(luaZ:make_getF("test_lzio.lua"), nil, "=string") | ||
40 | dump(z) | ||
41 | --]] | ||
42 | |||
43 | -- test read beyond end of file | ||
44 | -- bug reported by Adam429 | ||
45 | --[[ | ||
46 | z = luaZ:init(luaZ:make_getF("test_lzio.lua"), nil, "=string") | ||
47 | while true do | ||
48 | local c = luaZ:zgetc(z) | ||
49 | io.stdout:write("("..c..")") | ||
50 | if c == "EOZ" then break end | ||
51 | end | ||
52 | print(luaZ:zgetc(z)) | ||
53 | print(luaZ:zgetc(z)) | ||
54 | io.stdout:write("\n") | ||
55 | --]] | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_number.lua | ||
4 | Test for Lua-based number conversion functions in ldump.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * luaU:from_int(value) does not have overflow checks, but this | ||
18 | -- can presumably be put in for debugging purposes. | ||
19 | -- * TODO: double conversion does not support denormals or NaNs | ||
20 | -- * apparently 0/0 == 0/0 is false (Lua 5.0.2 on Win32/Mingw), so | ||
21 | -- can't use to check for NaNs | ||
22 | ----------------------------------------------------------------------]] | ||
23 | |||
24 | require("../ldump") | ||
25 | |||
26 | ------------------------------------------------------------------------ | ||
27 | -- convert hex string representation to a byte string | ||
28 | -- * must have an even number of hex digits | ||
29 | ------------------------------------------------------------------------ | ||
30 | local function from_hexstring(s) | ||
31 | local bs = "" | ||
32 | for i = 1, string.len(s), 2 do | ||
33 | local asc = tonumber(string.sub(s, i, i + 1), 16) | ||
34 | bs = bs..string.char(asc) | ||
35 | end | ||
36 | return bs | ||
37 | end | ||
38 | |||
39 | ------------------------------------------------------------------------ | ||
40 | -- convert a byte string to a hex string representation | ||
41 | -- * big-endian, easier to grok | ||
42 | ------------------------------------------------------------------------ | ||
43 | local function to_hexstring(s) | ||
44 | local hs = "" | ||
45 | for i = string.len(s), 1, -1 do | ||
46 | local c = string.byte(string.sub(s, i, i)) | ||
47 | hs = hs..string.format("%02X", c) | ||
48 | end | ||
49 | return hs | ||
50 | end | ||
51 | |||
52 | ------------------------------------------------------------------------ | ||
53 | -- tests for 32-bit signed/unsigned integer | ||
54 | ------------------------------------------------------------------------ | ||
55 | local function test_int(value, expected) | ||
56 | local actual = to_hexstring(luaU:from_int(value)) | ||
57 | if not expected or expected == "" then | ||
58 | print(value..": "..actual) | ||
59 | elseif actual ~= expected then | ||
60 | print(value..": FAILED!\n".. | ||
61 | "Converted: "..actual.."\n".. | ||
62 | "Expected: "..expected) | ||
63 | return true | ||
64 | end | ||
65 | return false | ||
66 | end | ||
67 | |||
68 | local table_int = { | ||
69 | ["0"] = "00000000", | ||
70 | ["1"] = "00000001", | ||
71 | ["256"] = "00000100", | ||
72 | ["-256"] = "FFFFFF00", | ||
73 | ["-1"] = "FFFFFFFF", | ||
74 | ["2147483647"] = "7FFFFFFF", -- LONG_MAX | ||
75 | ["-2147483648"] = "80000000", -- LONG_MIN | ||
76 | ["4294967295"] = "FFFFFFFF", -- ULONG_MAX | ||
77 | --[""] = "", | ||
78 | } | ||
79 | |||
80 | local success = true | ||
81 | print("Testing luaU:from_int():") | ||
82 | for i, v in pairs(table_int) do | ||
83 | local test_value = tonumber(i) | ||
84 | local expected = v | ||
85 | if test_int(test_value, expected) then | ||
86 | success = false | ||
87 | end | ||
88 | end | ||
89 | if success then | ||
90 | print("All test numbers passed okay.\n") | ||
91 | else | ||
92 | print("There were one or more failures.\n") | ||
93 | end | ||
94 | |||
95 | ------------------------------------------------------------------------ | ||
96 | -- tests for IEEE 754 64-bit double | ||
97 | ------------------------------------------------------------------------ | ||
98 | |||
99 | local function test_double(value, expected) | ||
100 | local actual = to_hexstring(luaU:from_double(value)) | ||
101 | if not expected or expected == "" then | ||
102 | print(value..": "..actual) | ||
103 | elseif actual ~= expected then | ||
104 | print(value..": FAILED!\n".. | ||
105 | "Converted: "..actual.."\n".. | ||
106 | "Expected: "..expected) | ||
107 | return true | ||
108 | end | ||
109 | return false | ||
110 | end | ||
111 | |||
112 | -- special values, see testing loop for actual lookup | ||
113 | Infinity = 1/0 | ||
114 | Infinity_neg = -1/0 | ||
115 | |||
116 | -- can't seem to do a comparison test with NaN, so leave them | ||
117 | -- (need to check the IEEE standard on this...) | ||
118 | NaN = 0/0 | ||
119 | NaN_neg = -0/0 | ||
120 | --["NaN"] = "", -- 7FF8000000000000 (djgpp) | ||
121 | --["NaN_neg"] = "", -- FFF8000000000000 (djgpp) | ||
122 | |||
123 | local table_double = { | ||
124 | -- 0 for exponent, 0 for mantissa | ||
125 | ["0"] = "0000000000000000", | ||
126 | -- 3FF is bias of 1023, so (-1)^0 * (1+0) * 2^0 | ||
127 | ["1"] = "3FF0000000000000", | ||
128 | -- BFF has sign bit on, so (-1)^1 * (1+0) * 2^0 | ||
129 | ["-1"] = "BFF0000000000000", | ||
130 | -- 3FC is bias of 1020, so (-1)^0 * (1+0) * 2^-3 | ||
131 | ["0.125"] = "3FC0000000000000", | ||
132 | ["0.250"] = "3FD0000000000000", | ||
133 | ["0.500"] = "3FE0000000000000", | ||
134 | -- 40F is bias of 1039, so (-1)^0 * (1+0) * 2^16 | ||
135 | ["65536"] = "40F0000000000000", | ||
136 | -- 7FF is bias of 2047, 0 for mantissa | ||
137 | ["Infinity"] = "7FF0000000000000", | ||
138 | -- FFF has sign bit on, 0 for mantissa | ||
139 | ["Infinity_neg"] = "FFF0000000000000", | ||
140 | -- DBL_MIN, exponent=001 ( 1), mantissa=0000000000000 | ||
141 | ["2.2250738585072014e-308"] = "0010000000000000", | ||
142 | -- DBL_MAX, exponent=7FE (2046), mantissa=FFFFFFFFFFFFF | ||
143 | ["1.7976931348623157e+308"] = "7FEFFFFFFFFFFFFF", | ||
144 | --[[ | ||
145 | -- * the following is for float numbers only * | ||
146 | -- FLT_MIN, exponent=01 ( 1), mantissa=000000 | ||
147 | -- altervative value for FLT_MIN: 1.17549435e-38F | ||
148 | ["1.1754943508222875081e-38"] = "00800000", | ||
149 | -- FLT_MAX, exponent=FE (254), mantissa=7FFFFF | ||
150 | -- altervative value for FLT_MAX: 3.402823466e+38F | ||
151 | ["3.4028234663852885982e+38"] = "7F7FFFFF", | ||
152 | --]] | ||
153 | --[""] = "", | ||
154 | } | ||
155 | |||
156 | local success = true | ||
157 | print("Testing luaU:from_double():") | ||
158 | for i, v in pairs(table_double) do | ||
159 | local test_value | ||
160 | if not string.find(i, "%d") then | ||
161 | test_value = _G[i] | ||
162 | else | ||
163 | test_value = tonumber(i) | ||
164 | end | ||
165 | local expected = v | ||
166 | if test_double(test_value, expected) then | ||
167 | success = false | ||
168 | end | ||
169 | end | ||
170 | if success then | ||
171 | print("All test numbers passed okay.\n") | ||
172 | else | ||
173 | print("There were one or more failures.\n") | ||
174 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | call_graph.lua | ||
4 | Call graph generator. | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * the call tracer wraps function calls in tables to do its work | ||
18 | -- * not very elegant as the namespace of the table/module is affected | ||
19 | -- * tracing using the debugger is probably much more powerful... | ||
20 | -- * use of braces {} allows editors to match braces in the output | ||
21 | -- and do folding, if such facilities are available; for example, the | ||
22 | -- output looks better if Lua syntax highlighting is used on SciTE | ||
23 | ----------------------------------------------------------------------]] | ||
24 | |||
25 | ------------------------------------------------------------------------ | ||
26 | -- options | ||
27 | ------------------------------------------------------------------------ | ||
28 | |||
29 | local SHOW_EXPDESC = true -- show expdesc struct data | ||
30 | |||
31 | ------------------------------------------------------------------------ | ||
32 | -- load and initialize modules | ||
33 | ------------------------------------------------------------------------ | ||
34 | require("../lzio.lua") | ||
35 | require("../llex.lua") | ||
36 | require("../lopcodes.lua") | ||
37 | require("../ldump.lua") | ||
38 | require("../lcode.lua") | ||
39 | require("../lparser.lua") | ||
40 | |||
41 | function lua_assert(test) | ||
42 | if not test then error("assertion failed!") end | ||
43 | end | ||
44 | luaX:init() | ||
45 | local LuaState = {} | ||
46 | |||
47 | ------------------------------------------------------------------------ | ||
48 | -- call graph generator | ||
49 | -- * (1) logging functions, (2) the wrapper initializer itself | ||
50 | ------------------------------------------------------------------------ | ||
51 | |||
52 | llog = {} | ||
53 | |||
54 | ------------------------------------------------------------------------ | ||
55 | -- initialize log file; the usual mode is append; can use stdout/stderr | ||
56 | ------------------------------------------------------------------------ | ||
57 | function llog:init(filename) | ||
58 | if filename == "stdout" then self.h = io.stdout | ||
59 | elseif filename == "stderr" then self.h = io.stderr | ||
60 | else | ||
61 | self.h = io.open(filename, "ab") | ||
62 | if not self.h then | ||
63 | error("can't open log file "..filename.."for writing") | ||
64 | end | ||
65 | end | ||
66 | self.h:write("\n-- start of log --\n\n") | ||
67 | end | ||
68 | |||
69 | ------------------------------------------------------------------------ | ||
70 | -- cleanly closes log file | ||
71 | ------------------------------------------------------------------------ | ||
72 | function llog:exit() | ||
73 | self.h:write("\n-- end of log --\n\n") | ||
74 | if self.h ~= io.stdout and self.h ~= io.stderr then | ||
75 | self.h:close() | ||
76 | end | ||
77 | end | ||
78 | |||
79 | ------------------------------------------------------------------------ | ||
80 | -- logs a message at a particular call depth | ||
81 | ------------------------------------------------------------------------ | ||
82 | function llog:msg(msg, level) | ||
83 | if level then msg = string.rep(" ", level)..msg end | ||
84 | self.h:write(msg) | ||
85 | self.h:flush() | ||
86 | end | ||
87 | |||
88 | ------------------------------------------------------------------------ | ||
89 | -- set up wrapper functions to do tracing on a per-module basis | ||
90 | ------------------------------------------------------------------------ | ||
91 | function llog:calltrace(parms) | ||
92 | ------------------------------------------------------------------ | ||
93 | -- process parameters | ||
94 | ------------------------------------------------------------------ | ||
95 | local module = parms.module | ||
96 | local modulename = parms.modulename | ||
97 | if type(module) ~= "table" then | ||
98 | error("module table parameter required") | ||
99 | elseif not modulename then | ||
100 | error("module name parameter required") | ||
101 | end | ||
102 | ------------------------------------------------------------------ | ||
103 | -- use either allow or deny list | ||
104 | ------------------------------------------------------------------ | ||
105 | local allow = parms.allow or {} | ||
106 | local deny = parms.deny or {} | ||
107 | if table.getn(allow) > 0 and table.getn(deny) > 0 then | ||
108 | error("can't apply both allow and deny lists at the same time") | ||
109 | end | ||
110 | ------------------------------------------------------------------ | ||
111 | -- select functions to wrap | ||
112 | ------------------------------------------------------------------ | ||
113 | local flist = {} | ||
114 | for i, f in pairs(module) do | ||
115 | local wrapthis | ||
116 | if table.getn(allow) > 0 then -- allow some only | ||
117 | wrapthis = false | ||
118 | for j, v in ipairs(allow) do | ||
119 | if i == v then wrapthis = true; break end | ||
120 | end | ||
121 | elseif table.getn(deny) > 0 then -- deny some only | ||
122 | wrapthis = true | ||
123 | for j, v in ipairs(deny) do | ||
124 | if i == v then wrapthis = false; break end | ||
125 | end | ||
126 | else -- default include | ||
127 | wrapthis = true | ||
128 | end | ||
129 | if wrapthis then flist[i] = f end | ||
130 | end | ||
131 | ------------------------------------------------------------------ | ||
132 | -- wrapped function(s) in a module for tracing | ||
133 | ------------------------------------------------------------------ | ||
134 | llog.level = 0 -- nesting level | ||
135 | for i, f in pairs(flist) do | ||
136 | local ModuleName = modulename..":" | ||
137 | local OldName, OldFunc = i, f | ||
138 | if type(OldFunc) == "function" then | ||
139 | local NewName = "__"..OldName | ||
140 | while module[NewName] ~= nil do -- avoid collisions | ||
141 | NewName = "_"..NewName | ||
142 | end | ||
143 | module[NewName] = OldFunc | ||
144 | module[OldName] = | ||
145 | ---------------------------------------------------------- | ||
146 | -- wrapper function for a module's function | ||
147 | -- old function XYZ is renamed __XYZ | ||
148 | ---------------------------------------------------------- | ||
149 | function(self, ...) | ||
150 | local parms = " (" | ||
151 | local exps = {} | ||
152 | -- look for expdesc structs, identify FuncState structs too | ||
153 | local function checkexpdesc(v) | ||
154 | local typ = type(v) | ||
155 | if typ == "table" then | ||
156 | if v.code then return "func" | ||
157 | elseif v.L then return "ls" | ||
158 | elseif v.seminfo then return "token" | ||
159 | elseif v.k then | ||
160 | table.insert(exps, v) | ||
161 | return "exp"..table.getn(exps) | ||
162 | end | ||
163 | end | ||
164 | return typ | ||
165 | end | ||
166 | -- format parameters for printing | ||
167 | for i,v in ipairs(arg) do | ||
168 | if type(v) == "number" then parms = parms..v.."," | ||
169 | elseif type(v) == "string" then parms = parms.."'"..v.."'," | ||
170 | elseif type(v) == "boolean" then parms = parms..tostring(v).."," | ||
171 | elseif SHOW_EXPDESC then parms = parms..checkexpdesc(v).."," | ||
172 | else parms = parms..type(v).."," | ||
173 | end | ||
174 | end | ||
175 | if table.getn(arg) > 0 then -- chop last comma | ||
176 | parms = string.sub(parms, 1, -2) | ||
177 | end | ||
178 | -- up level | ||
179 | llog:msg(ModuleName..OldName..parms..") {\n", llog.level) | ||
180 | llog.level = llog.level + 1 | ||
181 | -- display contents of expdesc | ||
182 | if SHOW_EXPDESC and table.getn(exps) > 0 then | ||
183 | for i,v in ipairs(exps) do | ||
184 | parms = "k:'"..v.k.."'," | ||
185 | if v.info then parms = parms.."info:"..v.info.."," end | ||
186 | if v.aux then parms = parms.."aux:"..v.aux.."," end | ||
187 | if v.t then parms = parms.."t:"..v.t.."," end | ||
188 | if v.f then parms = parms.."f:"..v.f.."," end | ||
189 | parms = string.sub(parms, 1, -2) | ||
190 | llog:msg("exp"..i.."("..parms..")\n", llog.level) | ||
191 | end | ||
192 | end | ||
193 | -- original function called here... | ||
194 | local retval = {self[NewName](self, unpack(arg))} | ||
195 | -- format return values | ||
196 | local rets = " = " | ||
197 | for i,v in ipairs(retval) do | ||
198 | if type(v) == "number" then rets = rets..v.."," | ||
199 | elseif type(v) == "string" then rets = rets.."'"..v.."'," | ||
200 | elseif type(v) == "boolean" then rets = rets..tostring(v).."," | ||
201 | else rets = rets..type(v).."," | ||
202 | end | ||
203 | end | ||
204 | if table.getn(retval) > 0 then -- chop last comma | ||
205 | rets = string.sub(rets, 1, -2) | ||
206 | else | ||
207 | rets = "" | ||
208 | end | ||
209 | -- down level | ||
210 | llog.level = llog.level - 1 | ||
211 | llog:msg("} "..ModuleName..OldName..rets.."\n", llog.level) | ||
212 | return unpack(retval) | ||
213 | end--function | ||
214 | ---------------------------------------------------------- | ||
215 | --print("patched "..OldName) | ||
216 | end--if | ||
217 | end--for | ||
218 | end | ||
219 | |||
220 | ------------------------------------------------------------------------ | ||
221 | -- testing here | ||
222 | -- * allow/deny works a bit like a somewhat similar Apache syntax | ||
223 | -- * e.g. to show only function 'lex' and 'save' -> allow={"lex","save",} | ||
224 | -- to not show function 'save_and_next' -> deny={"save_and_next",} | ||
225 | -- * you can't do both allow and deny at the same time | ||
226 | ------------------------------------------------------------------------ | ||
227 | |||
228 | -- select the file or stream to output to | ||
229 | --llog:init("calls.log") | ||
230 | llog:init("stdout") | ||
231 | |||
232 | -- select modules to trace | ||
233 | llog:calltrace{module=luaX, modulename="luaX", allow={"lex"} } | ||
234 | -- here we trace only the main lex() function, to avoid showing | ||
235 | -- too many lexer calls; we want to focus on luaY and luaK | ||
236 | llog:calltrace{module=luaY, modulename="luaY", deny={"growvector"} } | ||
237 | -- growvector() is just a limit checker in Yueliang, so drop it | ||
238 | -- to simplify the output log | ||
239 | llog:calltrace{module=luaK, modulename="luaK"} | ||
240 | --llog:calltrace{module=luaU, modulename="luaU"} | ||
241 | |||
242 | -- select input stream | ||
243 | local zio = luaZ:init(luaZ:make_getS("local a = 1"), nil, "=string") | ||
244 | --local zio = luaZ:init(luaZ:make_getF("sample.lua"), nil, "@sample.lua") | ||
245 | |||
246 | -- compile the source | ||
247 | local Func = luaY:parser(LuaState, zio, nil) | ||
248 | |||
249 | -- write binary chunk | ||
250 | local Writer, Buff = luaU:make_setF("call_graph.out") | ||
251 | luaU:dump(LuaState, Func, Writer, Buff) | ||
252 | |||
253 | llog:exit() | ||
254 | --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 @@ | |||
1 | |||
2 | -- start of log -- | ||
3 | |||
4 | luaY:parser (table,table) { | ||
5 | luaY:open_func (table,table) { | ||
6 | luaY:newproto (table) { | ||
7 | } luaY:newproto = table | ||
8 | } luaY:open_func | ||
9 | luaY:next (table) { | ||
10 | luaX:lex (table,table) { | ||
11 | } luaX:lex = 'TK_LOCAL' | ||
12 | } luaY:next | ||
13 | luaY:chunk (table) { | ||
14 | luaY:enterlevel (table) { | ||
15 | } luaY:enterlevel | ||
16 | luaY:block_follow ('TK_LOCAL') { | ||
17 | } luaY:block_follow = false | ||
18 | luaY:statement (table) { | ||
19 | luaY:next (table) { | ||
20 | luaX:lex (table,table) { | ||
21 | } luaX:lex = 'TK_NAME' | ||
22 | } luaY:next | ||
23 | luaY:testnext (table,'TK_FUNCTION') { | ||
24 | } luaY:testnext = false | ||
25 | luaY:localstat (table) { | ||
26 | luaY:str_checkname (table) { | ||
27 | luaY:check_condition (table,true,'<name> expected') { | ||
28 | } luaY:check_condition | ||
29 | luaY:next (table) { | ||
30 | luaX:lex (table,table) { | ||
31 | } luaX:lex = '=' | ||
32 | } luaY:next | ||
33 | } luaY:str_checkname = 'a' | ||
34 | luaY:new_localvar (table,'a',0) { | ||
35 | luaY:registerlocalvar (table,'a') { | ||
36 | luaY:growvector (table,table,0,0) { | ||
37 | } luaY:growvector | ||
38 | } luaY:registerlocalvar = 0 | ||
39 | } luaY:new_localvar | ||
40 | luaY:testnext (table,',') { | ||
41 | } luaY:testnext = false | ||
42 | luaY:testnext (table,'=') { | ||
43 | luaY:next (table) { | ||
44 | luaX:lex (table,table) { | ||
45 | } luaX:lex = 'TK_NUMBER' | ||
46 | } luaY:next | ||
47 | } luaY:testnext = true | ||
48 | luaY:explist1 (table,table) { | ||
49 | luaY:expr (table,table) { | ||
50 | luaY:subexpr (table,table,-1) { | ||
51 | luaY:enterlevel (table) { | ||
52 | } luaY:enterlevel | ||
53 | luaY:getunopr ('TK_NUMBER') { | ||
54 | } luaY:getunopr = 'OPR_NOUNOPR' | ||
55 | luaY:simpleexp (table,table) { | ||
56 | luaK:numberK (table,1) { | ||
57 | luaK:setnvalue (table,1) { | ||
58 | } luaK:setnvalue | ||
59 | luaK:addk (table,table,table) { | ||
60 | luaK:ttisnumber ) { | ||
61 | } luaK:ttisnumber = false | ||
62 | luaY:growvector (table,table,0,0) { | ||
63 | } luaY:growvector | ||
64 | luaK:setnvalue (table,0) { | ||
65 | } luaK:setnvalue | ||
66 | } luaK:addk = 0 | ||
67 | } luaK:numberK = 0 | ||
68 | luaY:init_exp (table,'VK',0) { | ||
69 | } luaY:init_exp | ||
70 | luaY:next (table) { | ||
71 | luaX:lex (table,table) { | ||
72 | } luaX:lex = 'TK_EOS' | ||
73 | } luaY:next | ||
74 | } luaY:simpleexp | ||
75 | luaY:getbinopr ('TK_EOS') { | ||
76 | } luaY:getbinopr = 'OPR_NOBINOPR' | ||
77 | luaY:leavelevel (table) { | ||
78 | } luaY:leavelevel | ||
79 | } luaY:subexpr = 'OPR_NOBINOPR' | ||
80 | } luaY:expr | ||
81 | luaY:testnext (table,',') { | ||
82 | } luaY:testnext = false | ||
83 | } luaY:explist1 = 1 | ||
84 | luaY:adjust_assign (table,1,1,table) { | ||
85 | luaK:exp2nextreg (table,table) { | ||
86 | luaK:dischargevars (table,table) { | ||
87 | } luaK:dischargevars | ||
88 | luaK:freeexp (table,table) { | ||
89 | } luaK:freeexp | ||
90 | luaK:reserveregs (table,1) { | ||
91 | luaK:checkstack (table,1) { | ||
92 | } luaK:checkstack | ||
93 | } luaK:reserveregs | ||
94 | luaK:exp2reg (table,table,0) { | ||
95 | luaK:discharge2reg (table,table,0) { | ||
96 | luaK:dischargevars (table,table) { | ||
97 | } luaK:dischargevars | ||
98 | luaK:codeABx (table,'OP_LOADK',0,0) { | ||
99 | luaK:code (table,table,1) { | ||
100 | luaK:dischargejpc (table) { | ||
101 | luaK:patchlistaux (table,-1,0,255,0,255,0) { | ||
102 | } luaK:patchlistaux | ||
103 | } luaK:dischargejpc | ||
104 | luaY:growvector (table,table,0,0) { | ||
105 | } luaY:growvector | ||
106 | luaY:growvector (table,table,0,0) { | ||
107 | } luaY:growvector | ||
108 | } luaK:code = 0 | ||
109 | } luaK:codeABx = 0 | ||
110 | } luaK:discharge2reg | ||
111 | luaK:hasjumps (table) { | ||
112 | } luaK:hasjumps = false | ||
113 | } luaK:exp2reg | ||
114 | } luaK:exp2nextreg | ||
115 | } luaY:adjust_assign | ||
116 | luaY:adjustlocalvars (table,1) { | ||
117 | luaY:getlocvar (table,0) { | ||
118 | } luaY:getlocvar = table | ||
119 | } luaY:adjustlocalvars | ||
120 | } luaY:localstat | ||
121 | } luaY:statement = false | ||
122 | luaY:testnext (table,';') { | ||
123 | } luaY:testnext = false | ||
124 | luaY:block_follow ('TK_EOS') { | ||
125 | } luaY:block_follow = true | ||
126 | luaY:leavelevel (table) { | ||
127 | } luaY:leavelevel | ||
128 | } luaY:chunk | ||
129 | luaY:check_condition (table,true,'<eof> expected') { | ||
130 | } luaY:check_condition | ||
131 | luaY:close_func (table) { | ||
132 | luaY:removevars (table,0) { | ||
133 | luaY:getlocvar (table,0) { | ||
134 | } luaY:getlocvar = table | ||
135 | } luaY:removevars | ||
136 | luaK:codeABC (table,'OP_RETURN',0,1,0) { | ||
137 | luaK:code (table,table,1) { | ||
138 | luaK:dischargejpc (table) { | ||
139 | luaK:patchlistaux (table,-1,1,255,1,255,1) { | ||
140 | } luaK:patchlistaux | ||
141 | } luaK:dischargejpc | ||
142 | luaY:growvector (table,table,1,0) { | ||
143 | } luaY:growvector | ||
144 | luaY:growvector (table,table,1,0) { | ||
145 | } luaY:growvector | ||
146 | } luaK:code = 1 | ||
147 | } luaK:codeABC = 1 | ||
148 | } luaY:close_func | ||
149 | } luaY:parser = table | ||
150 | |||
151 | -- end of log -- | ||
152 | |||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | sample_expr.lua | ||
4 | Stand-alone expression parsing demonstrator. | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * this is an interactive demonstrator for implementing expression | ||
18 | -- parsing in ChunkBake, a Lua assembler | ||
19 | -- * evaluation is immediate, and a result is immediately generated | ||
20 | ----------------------------------------------------------------------]] | ||
21 | |||
22 | require("../lzio.lua") | ||
23 | require("../llex.lua") | ||
24 | luaX:init() | ||
25 | |||
26 | ------------------------------------------------------------------------ | ||
27 | -- expression parser | ||
28 | ------------------------------------------------------------------------ | ||
29 | |||
30 | expr = {} | ||
31 | |||
32 | expr.unop = { | ||
33 | ["TK_NOT"] = true, | ||
34 | ["-"] = true, | ||
35 | } | ||
36 | expr.binop = { | ||
37 | ["^"] = 10, | ||
38 | ["*"] = 7, | ||
39 | ["/"] = 7, | ||
40 | ["+"] = 6, | ||
41 | ["-"] = 6, | ||
42 | ["TK_CONCAT"] = 5, | ||
43 | ["TK_NE"] = 3, | ||
44 | ["TK_EQ"] = 3, | ||
45 | ["<"] = 3, | ||
46 | ["TK_LE"] = 3, | ||
47 | [">"] = 3, | ||
48 | ["TK_GE"] = 3, | ||
49 | ["TK_AND"] = 2, | ||
50 | ["TK_OR"] = 1, | ||
51 | } | ||
52 | expr.binop_r = { | ||
53 | ["^"] = 9, | ||
54 | ["*"] = 7, | ||
55 | ["/"] = 7, | ||
56 | ["+"] = 6, | ||
57 | ["-"] = 6, | ||
58 | ["TK_CONCAT"] = 4, | ||
59 | ["TK_NE"] = 3, | ||
60 | ["TK_EQ"] = 3, | ||
61 | ["<"] = 3, | ||
62 | ["TK_LE"] = 3, | ||
63 | [">"] = 3, | ||
64 | ["TK_GE"] = 3, | ||
65 | ["TK_AND"] = 2, | ||
66 | ["TK_OR"] = 1, | ||
67 | } | ||
68 | |||
69 | function expr:parse(str) | ||
70 | self.LS = {} | ||
71 | self.L = {} | ||
72 | self.z = luaZ:init(luaZ:make_getS(str), nil, "=string") | ||
73 | luaX:setinput(self.L, self.LS, self.z, self.z.name) | ||
74 | self:token() | ||
75 | local v = self:expr() | ||
76 | if self.tok ~= "TK_EOS" then | ||
77 | io.stderr:write("parse error: some tokens unparsed\n") | ||
78 | end | ||
79 | return v | ||
80 | end | ||
81 | |||
82 | function expr:token() | ||
83 | self.tok = luaX:lex(self.LS, self.LS.t) | ||
84 | self.seminfo = self.LS.t.seminfo | ||
85 | return self.tok | ||
86 | end | ||
87 | |||
88 | function expr:simpleexpr() | ||
89 | local tok = self.tok | ||
90 | if tok == "TK_NIL" then | ||
91 | self:token() | ||
92 | return nil | ||
93 | elseif tok == "TK_TRUE" then | ||
94 | self:token() | ||
95 | return true | ||
96 | elseif tok == "TK_FALSE" then | ||
97 | self:token() | ||
98 | return false | ||
99 | elseif tok == "TK_NUMBER" or tok == "TK_STRING" then | ||
100 | self:token() | ||
101 | return self.seminfo | ||
102 | elseif tok == "(" then | ||
103 | self:token() | ||
104 | local v = self:expr() | ||
105 | if self.tok ~= ")" then | ||
106 | io.stderr:write("parse error: expecting ')' to delimit\n") | ||
107 | else | ||
108 | self:token() | ||
109 | return v | ||
110 | end | ||
111 | end | ||
112 | self:token() | ||
113 | io.stderr:write("parse error: "..tok.." encountered, substituting nil\n") | ||
114 | return nil | ||
115 | end | ||
116 | |||
117 | function expr:subexpr(prev_op) | ||
118 | local v, op | ||
119 | if self.unop[self.tok] then | ||
120 | op = self.tok | ||
121 | self:token() | ||
122 | v = self:subexpr(8) | ||
123 | if op == "TK_NOT" then | ||
124 | v = not v | ||
125 | else-- op == "-" then | ||
126 | v = -v | ||
127 | end | ||
128 | else | ||
129 | v = self:simpleexpr() | ||
130 | end | ||
131 | op = self.tok | ||
132 | if self.binop[op] then | ||
133 | while self.binop[op] and self.binop[op] > prev_op do | ||
134 | self:token() | ||
135 | local v2, next_op = self:subexpr(self.binop_r[op]) | ||
136 | if op == "^" then | ||
137 | v = v ^ v2 | ||
138 | elseif op == "*" then | ||
139 | v = v * v2 | ||
140 | elseif op == "/" then | ||
141 | v = v / v2 | ||
142 | elseif op == "+" then | ||
143 | v = v + v2 | ||
144 | elseif op == "-" then | ||
145 | v = v - v2 | ||
146 | elseif op == "TK_CONCAT" then | ||
147 | v = v .. v2 | ||
148 | elseif op == "TK_NE" then | ||
149 | v = v ~= v2 | ||
150 | elseif op == "TK_EQ" then | ||
151 | v = v == v2 | ||
152 | elseif op == "<" then | ||
153 | v = v < v2 | ||
154 | elseif op == "TK_LE" then | ||
155 | v = v <= v2 | ||
156 | elseif op == ">" then | ||
157 | v = v > v2 | ||
158 | elseif op == "TK_GE" then | ||
159 | v = v >= v2 | ||
160 | elseif op == "TK_AND" then | ||
161 | v = v and v2 | ||
162 | else-- op == "TK_OR" then | ||
163 | v = v or v2 | ||
164 | end | ||
165 | op = next_op | ||
166 | end | ||
167 | end | ||
168 | return v, op | ||
169 | end | ||
170 | |||
171 | function expr:expr() | ||
172 | return self:subexpr(-1) | ||
173 | end | ||
174 | |||
175 | ------------------------------------------------------------------------ | ||
176 | -- interactive test code | ||
177 | ------------------------------------------------------------------------ | ||
178 | |||
179 | io.stdout:write([[ | ||
180 | Lua-style expression parsing demonstrator. | ||
181 | Type 'exit' or 'quit' at the prompt to terminate session. | ||
182 | ]]) | ||
183 | local done = false | ||
184 | while not done do | ||
185 | io.stdout:write(":>") | ||
186 | io.stdout:flush() | ||
187 | local l = io.stdin:read("*l") | ||
188 | if l == nil or (l == "exit" or l == "quit" and not prevline) then | ||
189 | done = true | ||
190 | else | ||
191 | local v = tostring(expr:parse(l)) | ||
192 | io.stdout:write(v, "\n") | ||
193 | end | ||
194 | end--while | ||
195 | --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 @@ | |||
1 | orig-5.1.3 | ||
2 | |||
3 | This is a straightforward port of the Lua 5.1.3 front end (lexical | ||
4 | analyzer, parser, code generator, binary chunk dumper.) | ||
5 | |||
6 | The front end files are: | ||
7 | |||
8 | lopcodes.lua opcode definition | ||
9 | lzio.lua input streams | ||
10 | llex.lua lexical analyzer | ||
11 | lparser.lua parser | ||
12 | lcode.lua code generator | ||
13 | ldump.lua binary chunk dumper | ||
14 | |||
15 | Status: operational, passes all current tests (non-exhaustive) | ||
16 | |||
17 | Major test scripts are: | ||
18 | |||
19 | test/test_llex.lua exercises test cases | ||
20 | test/test_lparser2.lua exercises test cases | ||
21 | |||
22 | luac.lua is a clone of Lua 5.1.3's luac.lua, except that it generates a | ||
23 | binary chunk using Yueliang's front end implementation. | ||
24 | |||
25 | See the README file in orig-5.0.3 for a discussion. | ||
26 | |||
27 | The following is some performance data. Note that absolutely nothing has | ||
28 | been done to optimize the code; it is meant to mirror the original C as | ||
29 | an educational tool. | ||
30 | |||
31 | lzio llex TOTAL Speed (1) | ||
32 | (bytes) (bytes) (bytes) (KB/s) | ||
33 | ---------------------------------------------- | ||
34 | (in orig-5.0.3:) | ||
35 | ---------------------------------------------- | ||
36 | normal 2219 12639 14585 404.9 | ||
37 | stripped 1292 7618 8910 | ||
38 | ---------------------------------------------- | ||
39 | (in orig-5.0.3:) | ||
40 | ---------------------------------------------- | ||
41 | normal - - - 389.7 | ||
42 | stripped - - - | ||
43 | ---------------------------------------------- | ||
44 | |||
45 | (1) Speed was benchmarked using a Sempron 3000+. Benchmark scripts are | ||
46 | in the test directories. Best of first three figures quoted. This is a | ||
47 | measurement of raw lexer speed, i.e. tokens are read but no processing | ||
48 | is done. All files are read in entirely before running the lexer. | ||
49 | |||
50 | For Lua 5.1.1, see Yueliang 0.2.1, which was the last release of Lua | ||
51 | 5.1.1 material. | ||
52 | |||
53 | For Lua 5.1.2, see Yueliang 0.2.2, which was the last release of Lua | ||
54 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lcode.lua | ||
4 | Lua 5 code generator in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * one function manipulate a pointer argument with a simple data type | ||
18 | -- (can't be emulated by a table, ambiguous), now returns that value: | ||
19 | -- luaK:concat(fs, l1, l2) | ||
20 | -- * luaM_growvector uses the faux luaY:growvector, for limit checking | ||
21 | -- * some function parameters changed to boolean, additional code | ||
22 | -- translates boolean back to 1/0 for instruction fields | ||
23 | -- | ||
24 | -- Not implemented: | ||
25 | -- * NOTE there is a failed assert in luaK:addk, a porting problem | ||
26 | -- | ||
27 | -- Added: | ||
28 | -- * constant MAXSTACK from llimits.h | ||
29 | -- * luaK:ttisnumber(o) (from lobject.h) | ||
30 | -- * luaK:nvalue(o) (from lobject.h) | ||
31 | -- * luaK:setnilvalue(o) (from lobject.h) | ||
32 | -- * luaK:setnvalue(o, x) (from lobject.h) | ||
33 | -- * luaK:setbvalue(o, x) (from lobject.h) | ||
34 | -- * luaK:sethvalue(o, x) (from lobject.h), parameter L deleted | ||
35 | -- * luaK:setsvalue(o, x) (from lobject.h), parameter L deleted | ||
36 | -- * luaK:numadd, luaK:numsub, luaK:nummul, luaK:numdiv, luaK:nummod, | ||
37 | -- luaK:numpow, luaK:numunm, luaK:numisnan (from luaconf.h) | ||
38 | -- * copyexp(e1, e2) added in luaK:posfix to copy expdesc struct | ||
39 | -- | ||
40 | -- Changed in 5.1.x: | ||
41 | -- * enum BinOpr has a new entry, OPR_MOD | ||
42 | -- * enum UnOpr has a new entry, OPR_LEN | ||
43 | -- * binopistest, unused in 5.0.x, has been deleted | ||
44 | -- * macro setmultret is new | ||
45 | -- * functions isnumeral, luaK_ret, boolK are new | ||
46 | -- * funcion nilK was named nil_constant in 5.0.x | ||
47 | -- * function interface changed: need_value, patchtestreg, concat | ||
48 | -- * TObject now a TValue | ||
49 | -- * functions luaK_setreturns, luaK_setoneret are new | ||
50 | -- * function luaK:setcallreturns deleted, to be replaced by: | ||
51 | -- luaK:setmultret, luaK:ret, luaK:setreturns, luaK:setoneret | ||
52 | -- * functions constfolding, codearith, codecomp are new | ||
53 | -- * luaK:codebinop has been deleted | ||
54 | -- * function luaK_setlist is new | ||
55 | -- * OPR_MULT renamed to OPR_MUL | ||
56 | ----------------------------------------------------------------------]] | ||
57 | |||
58 | -- requires luaP, luaX, luaY | ||
59 | luaK = {} | ||
60 | |||
61 | ------------------------------------------------------------------------ | ||
62 | -- constants used by code generator | ||
63 | ------------------------------------------------------------------------ | ||
64 | -- maximum stack for a Lua function | ||
65 | luaK.MAXSTACK = 250 -- (from llimits.h) | ||
66 | |||
67 | --[[-------------------------------------------------------------------- | ||
68 | -- other functions | ||
69 | ----------------------------------------------------------------------]] | ||
70 | |||
71 | ------------------------------------------------------------------------ | ||
72 | -- emulation of TValue macros (these are from lobject.h) | ||
73 | -- * TValue is a table since lcode passes references around | ||
74 | -- * tt member field removed, using Lua's type() instead | ||
75 | -- * for setsvalue, sethvalue, parameter L (deleted here) in lobject.h | ||
76 | -- is used in an assert for testing, see checkliveness(g,obj) | ||
77 | ------------------------------------------------------------------------ | ||
78 | function luaK:ttisnumber(o) | ||
79 | if o then return type(o.value) == "number" else return false end | ||
80 | end | ||
81 | function luaK:nvalue(o) return o.value end | ||
82 | function luaK:setnilvalue(o) o.value = nil end | ||
83 | function luaK:setsvalue(o, x) o.value = x end | ||
84 | luaK.setnvalue = luaK.setsvalue | ||
85 | luaK.sethvalue = luaK.setsvalue | ||
86 | luaK.setbvalue = luaK.setsvalue | ||
87 | |||
88 | ------------------------------------------------------------------------ | ||
89 | -- The luai_num* macros define the primitive operations over numbers. | ||
90 | -- * this is not the entire set of primitive operations from luaconf.h | ||
91 | -- * used in luaK:constfolding() | ||
92 | ------------------------------------------------------------------------ | ||
93 | function luaK:numadd(a, b) return a + b end | ||
94 | function luaK:numsub(a, b) return a - b end | ||
95 | function luaK:nummul(a, b) return a * b end | ||
96 | function luaK:numdiv(a, b) return a / b end | ||
97 | function luaK:nummod(a, b) return a % b end | ||
98 | -- ((a) - floor((a)/(b))*(b)) /* actual, for reference */ | ||
99 | function luaK:numpow(a, b) return a ^ b end | ||
100 | function luaK:numunm(a) return -a end | ||
101 | function luaK:numisnan(a) return not a == a end | ||
102 | -- a NaN cannot equal another NaN | ||
103 | |||
104 | --[[-------------------------------------------------------------------- | ||
105 | -- code generator functions | ||
106 | ----------------------------------------------------------------------]] | ||
107 | |||
108 | ------------------------------------------------------------------------ | ||
109 | -- Marks the end of a patch list. It is an invalid value both as an absolute | ||
110 | -- address, and as a list link (would link an element to itself). | ||
111 | ------------------------------------------------------------------------ | ||
112 | luaK.NO_JUMP = -1 | ||
113 | |||
114 | ------------------------------------------------------------------------ | ||
115 | -- grep "ORDER OPR" if you change these enums | ||
116 | ------------------------------------------------------------------------ | ||
117 | luaK.BinOpr = { | ||
118 | OPR_ADD = 0, OPR_SUB = 1, OPR_MUL = 2, OPR_DIV = 3, OPR_MOD = 4, OPR_POW = 5, | ||
119 | OPR_CONCAT = 6, | ||
120 | OPR_NE = 7, OPR_EQ = 8, | ||
121 | OPR_LT = 9, OPR_LE = 10, OPR_GT = 11, OPR_GE = 12, | ||
122 | OPR_AND = 13, OPR_OR = 14, | ||
123 | OPR_NOBINOPR = 15, | ||
124 | } | ||
125 | |||
126 | -- * UnOpr is used by luaK:prefix's op argument, but not directly used | ||
127 | -- because the function receives the symbols as strings, e.g. "OPR_NOT" | ||
128 | luaK.UnOpr = { | ||
129 | OPR_MINUS = 0, OPR_NOT = 1, OPR_LEN = 2, OPR_NOUNOPR = 3 | ||
130 | } | ||
131 | |||
132 | ------------------------------------------------------------------------ | ||
133 | -- returns the instruction object for given e (expdesc), was a macro | ||
134 | ------------------------------------------------------------------------ | ||
135 | function luaK:getcode(fs, e) | ||
136 | return fs.f.code[e.info] | ||
137 | end | ||
138 | |||
139 | ------------------------------------------------------------------------ | ||
140 | -- codes an instruction with a signed Bx (sBx) field, was a macro | ||
141 | -- * used in luaK:jump(), (lparser) luaY:forbody() | ||
142 | ------------------------------------------------------------------------ | ||
143 | function luaK:codeAsBx(fs, o, A, sBx) | ||
144 | return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx) | ||
145 | end | ||
146 | |||
147 | ------------------------------------------------------------------------ | ||
148 | -- set the expdesc e instruction for multiple returns, was a macro | ||
149 | ------------------------------------------------------------------------ | ||
150 | function luaK:setmultret(fs, e) | ||
151 | self:setreturns(fs, e, luaY.LUA_MULTRET) | ||
152 | end | ||
153 | |||
154 | ------------------------------------------------------------------------ | ||
155 | -- there is a jump if patch lists are not identical, was a macro | ||
156 | -- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val() | ||
157 | ------------------------------------------------------------------------ | ||
158 | function luaK:hasjumps(e) | ||
159 | return e.t ~= e.f | ||
160 | end | ||
161 | |||
162 | ------------------------------------------------------------------------ | ||
163 | -- true if the expression is a constant number (for constant folding) | ||
164 | -- * used in constfolding(), infix() | ||
165 | ------------------------------------------------------------------------ | ||
166 | function luaK:isnumeral(e) | ||
167 | return e.k == "VKNUM" and e.t == self.NO_JUMP and e.f == self.NO_JUMP | ||
168 | end | ||
169 | |||
170 | ------------------------------------------------------------------------ | ||
171 | -- codes loading of nil, optimization done if consecutive locations | ||
172 | -- * used in luaK:discharge2reg(), (lparser) luaY:adjust_assign() | ||
173 | ------------------------------------------------------------------------ | ||
174 | function luaK:_nil(fs, from, n) | ||
175 | if fs.pc > fs.lasttarget then -- no jumps to current position? | ||
176 | if fs.pc == 0 then -- function start? | ||
177 | if from >= fs.nactvar then | ||
178 | return -- positions are already clean | ||
179 | end | ||
180 | else | ||
181 | local previous = fs.f.code[fs.pc - 1] | ||
182 | if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then | ||
183 | local pfrom = luaP:GETARG_A(previous) | ||
184 | local pto = luaP:GETARG_B(previous) | ||
185 | if pfrom <= from and from <= pto + 1 then -- can connect both? | ||
186 | if from + n - 1 > pto then | ||
187 | luaP:SETARG_B(previous, from + n - 1) | ||
188 | end | ||
189 | return | ||
190 | end | ||
191 | end | ||
192 | end | ||
193 | end | ||
194 | self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization | ||
195 | end | ||
196 | |||
197 | ------------------------------------------------------------------------ | ||
198 | -- | ||
199 | -- * used in multiple locations | ||
200 | ------------------------------------------------------------------------ | ||
201 | function luaK:jump(fs) | ||
202 | local jpc = fs.jpc -- save list of jumps to here | ||
203 | fs.jpc = self.NO_JUMP | ||
204 | local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP) | ||
205 | j = self:concat(fs, j, jpc) -- keep them on hold | ||
206 | return j | ||
207 | end | ||
208 | |||
209 | ------------------------------------------------------------------------ | ||
210 | -- codes a RETURN instruction | ||
211 | -- * used in luaY:close_func(), luaY:retstat() | ||
212 | ------------------------------------------------------------------------ | ||
213 | function luaK:ret(fs, first, nret) | ||
214 | self:codeABC(fs, "OP_RETURN", first, nret + 1, 0) | ||
215 | end | ||
216 | |||
217 | ------------------------------------------------------------------------ | ||
218 | -- | ||
219 | -- * used in luaK:jumponcond(), luaK:codecomp() | ||
220 | ------------------------------------------------------------------------ | ||
221 | function luaK:condjump(fs, op, A, B, C) | ||
222 | self:codeABC(fs, op, A, B, C) | ||
223 | return self:jump(fs) | ||
224 | end | ||
225 | |||
226 | ------------------------------------------------------------------------ | ||
227 | -- | ||
228 | -- * used in luaK:patchlistaux(), luaK:concat() | ||
229 | ------------------------------------------------------------------------ | ||
230 | function luaK:fixjump(fs, pc, dest) | ||
231 | local jmp = fs.f.code[pc] | ||
232 | local offset = dest - (pc + 1) | ||
233 | lua_assert(dest ~= self.NO_JUMP) | ||
234 | if math.abs(offset) > luaP.MAXARG_sBx then | ||
235 | luaX:syntaxerror(fs.ls, "control structure too long") | ||
236 | end | ||
237 | luaP:SETARG_sBx(jmp, offset) | ||
238 | end | ||
239 | |||
240 | ------------------------------------------------------------------------ | ||
241 | -- returns current 'pc' and marks it as a jump target (to avoid wrong | ||
242 | -- optimizations with consecutive instructions not in the same basic block). | ||
243 | -- * used in multiple locations | ||
244 | -- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL | ||
245 | ------------------------------------------------------------------------ | ||
246 | function luaK:getlabel(fs) | ||
247 | fs.lasttarget = fs.pc | ||
248 | return fs.pc | ||
249 | end | ||
250 | |||
251 | ------------------------------------------------------------------------ | ||
252 | -- | ||
253 | -- * used in luaK:need_value(), luaK:removevalues(), luaK:patchlistaux(), | ||
254 | -- luaK:concat() | ||
255 | ------------------------------------------------------------------------ | ||
256 | function luaK:getjump(fs, pc) | ||
257 | local offset = luaP:GETARG_sBx(fs.f.code[pc]) | ||
258 | if offset == self.NO_JUMP then -- point to itself represents end of list | ||
259 | return self.NO_JUMP -- end of list | ||
260 | else | ||
261 | return (pc + 1) + offset -- turn offset into absolute position | ||
262 | end | ||
263 | end | ||
264 | |||
265 | ------------------------------------------------------------------------ | ||
266 | -- | ||
267 | -- * used in luaK:need_value(), luaK:patchtestreg(), luaK:invertjump() | ||
268 | ------------------------------------------------------------------------ | ||
269 | function luaK:getjumpcontrol(fs, pc) | ||
270 | local pi = fs.f.code[pc] | ||
271 | local ppi = fs.f.code[pc - 1] | ||
272 | if pc >= 1 and luaP:testTMode(luaP:GET_OPCODE(ppi)) ~= 0 then | ||
273 | return ppi | ||
274 | else | ||
275 | return pi | ||
276 | end | ||
277 | end | ||
278 | |||
279 | ------------------------------------------------------------------------ | ||
280 | -- check whether list has any jump that do not produce a value | ||
281 | -- (or produce an inverted value) | ||
282 | -- * return value changed to boolean | ||
283 | -- * used only in luaK:exp2reg() | ||
284 | ------------------------------------------------------------------------ | ||
285 | function luaK:need_value(fs, list) | ||
286 | while list ~= self.NO_JUMP do | ||
287 | local i = self:getjumpcontrol(fs, list) | ||
288 | if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then return true end | ||
289 | list = self:getjump(fs, list) | ||
290 | end | ||
291 | return false -- not found | ||
292 | end | ||
293 | |||
294 | ------------------------------------------------------------------------ | ||
295 | -- | ||
296 | -- * used in luaK:removevalues(), luaK:patchlistaux() | ||
297 | ------------------------------------------------------------------------ | ||
298 | function luaK:patchtestreg(fs, node, reg) | ||
299 | local i = self:getjumpcontrol(fs, node) | ||
300 | if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then | ||
301 | return false -- cannot patch other instructions | ||
302 | end | ||
303 | if reg ~= luaP.NO_REG and reg ~= luaP:GETARG_B(i) then | ||
304 | luaP:SETARG_A(i, reg) | ||
305 | else -- no register to put value or register already has the value | ||
306 | -- due to use of a table as i, i cannot be replaced by another table | ||
307 | -- so the following is required; there is no change to ARG_C | ||
308 | luaP:SET_OPCODE(i, "OP_TEST") | ||
309 | local b = luaP:GETARG_B(i) | ||
310 | luaP:SETARG_A(i, b) | ||
311 | luaP:SETARG_B(i, 0) | ||
312 | -- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); /* C */ | ||
313 | end | ||
314 | return true | ||
315 | end | ||
316 | |||
317 | ------------------------------------------------------------------------ | ||
318 | -- | ||
319 | -- * used only in luaK:codenot() | ||
320 | ------------------------------------------------------------------------ | ||
321 | function luaK:removevalues(fs, list) | ||
322 | while list ~= self.NO_JUMP do | ||
323 | self:patchtestreg(fs, list, luaP.NO_REG) | ||
324 | list = self:getjump(fs, list) | ||
325 | end | ||
326 | end | ||
327 | |||
328 | ------------------------------------------------------------------------ | ||
329 | -- | ||
330 | -- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg() | ||
331 | ------------------------------------------------------------------------ | ||
332 | function luaK:patchlistaux(fs, list, vtarget, reg, dtarget) | ||
333 | while list ~= self.NO_JUMP do | ||
334 | local _next = self:getjump(fs, list) | ||
335 | if self:patchtestreg(fs, list, reg) then | ||
336 | self:fixjump(fs, list, vtarget) | ||
337 | else | ||
338 | self:fixjump(fs, list, dtarget) -- jump to default target | ||
339 | end | ||
340 | list = _next | ||
341 | end | ||
342 | end | ||
343 | |||
344 | ------------------------------------------------------------------------ | ||
345 | -- | ||
346 | -- * used only in luaK:code() | ||
347 | ------------------------------------------------------------------------ | ||
348 | function luaK:dischargejpc(fs) | ||
349 | self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc) | ||
350 | fs.jpc = self.NO_JUMP | ||
351 | end | ||
352 | |||
353 | ------------------------------------------------------------------------ | ||
354 | -- | ||
355 | -- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody() | ||
356 | ------------------------------------------------------------------------ | ||
357 | function luaK:patchlist(fs, list, target) | ||
358 | if target == fs.pc then | ||
359 | self:patchtohere(fs, list) | ||
360 | else | ||
361 | lua_assert(target < fs.pc) | ||
362 | self:patchlistaux(fs, list, target, luaP.NO_REG, target) | ||
363 | end | ||
364 | end | ||
365 | |||
366 | ------------------------------------------------------------------------ | ||
367 | -- | ||
368 | -- * used in multiple locations | ||
369 | ------------------------------------------------------------------------ | ||
370 | function luaK:patchtohere(fs, list) | ||
371 | self:getlabel(fs) | ||
372 | fs.jpc = self:concat(fs, fs.jpc, list) | ||
373 | end | ||
374 | |||
375 | ------------------------------------------------------------------------ | ||
376 | -- * l1 was a pointer, now l1 is returned and callee assigns the value | ||
377 | -- * used in multiple locations | ||
378 | ------------------------------------------------------------------------ | ||
379 | function luaK:concat(fs, l1, l2) | ||
380 | if l2 == self.NO_JUMP then return l1 | ||
381 | elseif l1 == self.NO_JUMP then | ||
382 | return l2 | ||
383 | else | ||
384 | local list = l1 | ||
385 | local _next = self:getjump(fs, list) | ||
386 | while _next ~= self.NO_JUMP do -- find last element | ||
387 | list = _next | ||
388 | _next = self:getjump(fs, list) | ||
389 | end | ||
390 | self:fixjump(fs, list, l2) | ||
391 | end | ||
392 | return l1 | ||
393 | end | ||
394 | |||
395 | ------------------------------------------------------------------------ | ||
396 | -- | ||
397 | -- * used in luaK:reserveregs(), (lparser) luaY:forlist() | ||
398 | ------------------------------------------------------------------------ | ||
399 | function luaK:checkstack(fs, n) | ||
400 | local newstack = fs.freereg + n | ||
401 | if newstack > fs.f.maxstacksize then | ||
402 | if newstack >= self.MAXSTACK then | ||
403 | luaX:syntaxerror(fs.ls, "function or expression too complex") | ||
404 | end | ||
405 | fs.f.maxstacksize = newstack | ||
406 | end | ||
407 | end | ||
408 | |||
409 | ------------------------------------------------------------------------ | ||
410 | -- | ||
411 | -- * used in multiple locations | ||
412 | ------------------------------------------------------------------------ | ||
413 | function luaK:reserveregs(fs, n) | ||
414 | self:checkstack(fs, n) | ||
415 | fs.freereg = fs.freereg + n | ||
416 | end | ||
417 | |||
418 | ------------------------------------------------------------------------ | ||
419 | -- | ||
420 | -- * used in luaK:freeexp(), luaK:dischargevars() | ||
421 | ------------------------------------------------------------------------ | ||
422 | function luaK:freereg(fs, reg) | ||
423 | if not luaP:ISK(reg) and reg >= fs.nactvar then | ||
424 | fs.freereg = fs.freereg - 1 | ||
425 | lua_assert(reg == fs.freereg) | ||
426 | end | ||
427 | end | ||
428 | |||
429 | ------------------------------------------------------------------------ | ||
430 | -- | ||
431 | -- * used in multiple locations | ||
432 | ------------------------------------------------------------------------ | ||
433 | function luaK:freeexp(fs, e) | ||
434 | if e.k == "VNONRELOC" then | ||
435 | self:freereg(fs, e.info) | ||
436 | end | ||
437 | end | ||
438 | |||
439 | ------------------------------------------------------------------------ | ||
440 | -- * TODO NOTE implementation is not 100% correct, since the assert fails | ||
441 | -- * luaH_set, setobj deleted; direct table access used instead | ||
442 | -- * used in luaK:stringK(), luaK:numberK(), luaK:boolK(), luaK:nilK() | ||
443 | ------------------------------------------------------------------------ | ||
444 | function luaK:addk(fs, k, v) | ||
445 | local L = fs.L | ||
446 | local idx = fs.h[k.value] | ||
447 | --TValue *idx = luaH_set(L, fs->h, k); /* C */ | ||
448 | local f = fs.f | ||
449 | if self:ttisnumber(idx) then | ||
450 | --TODO this assert currently FAILS (last tested for 5.0.2) | ||
451 | --lua_assert(fs.f.k[self:nvalue(idx)] == v) | ||
452 | --lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); /* C */ | ||
453 | return self:nvalue(idx) | ||
454 | else -- constant not found; create a new entry | ||
455 | idx = {} | ||
456 | self:setnvalue(idx, fs.nk) | ||
457 | fs.h[k.value] = idx | ||
458 | -- setnvalue(idx, cast_num(fs->nk)); /* C */ | ||
459 | luaY:growvector(L, f.k, fs.nk, f.sizek, nil, | ||
460 | luaP.MAXARG_Bx, "constant table overflow") | ||
461 | -- loop to initialize empty f.k positions not required | ||
462 | f.k[fs.nk] = v | ||
463 | -- setobj(L, &f->k[fs->nk], v); /* C */ | ||
464 | -- luaC_barrier(L, f, v); /* GC */ | ||
465 | local nk = fs.nk | ||
466 | fs.nk = fs.nk + 1 | ||
467 | return nk | ||
468 | end | ||
469 | |||
470 | end | ||
471 | |||
472 | ------------------------------------------------------------------------ | ||
473 | -- creates and sets a string object | ||
474 | -- * used in (lparser) luaY:codestring(), luaY:singlevar() | ||
475 | ------------------------------------------------------------------------ | ||
476 | function luaK:stringK(fs, s) | ||
477 | local o = {} -- TValue | ||
478 | self:setsvalue(o, s) | ||
479 | return self:addk(fs, o, o) | ||
480 | end | ||
481 | |||
482 | ------------------------------------------------------------------------ | ||
483 | -- creates and sets a number object | ||
484 | -- * used in luaK:prefix() for negative (or negation of) numbers | ||
485 | -- * used in (lparser) luaY:simpleexp(), luaY:fornum() | ||
486 | ------------------------------------------------------------------------ | ||
487 | function luaK:numberK(fs, r) | ||
488 | local o = {} -- TValue | ||
489 | self:setnvalue(o, r) | ||
490 | return self:addk(fs, o, o) | ||
491 | end | ||
492 | |||
493 | ------------------------------------------------------------------------ | ||
494 | -- creates and sets a boolean object | ||
495 | -- * used only in luaK:exp2RK() | ||
496 | ------------------------------------------------------------------------ | ||
497 | function luaK:boolK(fs, b) | ||
498 | local o = {} -- TValue | ||
499 | self:setbvalue(o, b) | ||
500 | return self:addk(fs, o, o) | ||
501 | end | ||
502 | |||
503 | ------------------------------------------------------------------------ | ||
504 | -- creates and sets a nil object | ||
505 | -- * used only in luaK:exp2RK() | ||
506 | ------------------------------------------------------------------------ | ||
507 | function luaK:nilK(fs) | ||
508 | local k, v = {}, {} -- TValue | ||
509 | self:setnilvalue(v) | ||
510 | -- cannot use nil as key; instead use table itself to represent nil | ||
511 | self:sethvalue(k, fs.h) | ||
512 | return self:addk(fs, k, v) | ||
513 | end | ||
514 | |||
515 | ------------------------------------------------------------------------ | ||
516 | -- | ||
517 | -- * used in luaK:setmultret(), (lparser) luaY:adjust_assign() | ||
518 | ------------------------------------------------------------------------ | ||
519 | function luaK:setreturns(fs, e, nresults) | ||
520 | if e.k == "VCALL" then -- expression is an open function call? | ||
521 | luaP:SETARG_C(self:getcode(fs, e), nresults + 1) | ||
522 | elseif e.k == "VVARARG" then | ||
523 | luaP:SETARG_B(self:getcode(fs, e), nresults + 1); | ||
524 | luaP:SETARG_A(self:getcode(fs, e), fs.freereg); | ||
525 | luaK:reserveregs(fs, 1) | ||
526 | end | ||
527 | end | ||
528 | |||
529 | ------------------------------------------------------------------------ | ||
530 | -- | ||
531 | -- * used in luaK:dischargevars(), (lparser) luaY:assignment() | ||
532 | ------------------------------------------------------------------------ | ||
533 | function luaK:setoneret(fs, e) | ||
534 | if e.k == "VCALL" then -- expression is an open function call? | ||
535 | e.k = "VNONRELOC" | ||
536 | e.info = luaP:GETARG_A(self:getcode(fs, e)) | ||
537 | elseif e.k == "VVARARG" then | ||
538 | luaP:SETARG_B(self:getcode(fs, e), 2) | ||
539 | e.k = "VRELOCABLE" -- can relocate its simple result | ||
540 | end | ||
541 | end | ||
542 | |||
543 | ------------------------------------------------------------------------ | ||
544 | -- | ||
545 | -- * used in multiple locations | ||
546 | ------------------------------------------------------------------------ | ||
547 | function luaK:dischargevars(fs, e) | ||
548 | local k = e.k | ||
549 | if k == "VLOCAL" then | ||
550 | e.k = "VNONRELOC" | ||
551 | elseif k == "VUPVAL" then | ||
552 | e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0) | ||
553 | e.k = "VRELOCABLE" | ||
554 | elseif k == "VGLOBAL" then | ||
555 | e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info) | ||
556 | e.k = "VRELOCABLE" | ||
557 | elseif k == "VINDEXED" then | ||
558 | self:freereg(fs, e.aux) | ||
559 | self:freereg(fs, e.info) | ||
560 | e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux) | ||
561 | e.k = "VRELOCABLE" | ||
562 | elseif k == "VVARARG" or k == "VCALL" then | ||
563 | self:setoneret(fs, e) | ||
564 | else | ||
565 | -- there is one value available (somewhere) | ||
566 | end | ||
567 | end | ||
568 | |||
569 | ------------------------------------------------------------------------ | ||
570 | -- | ||
571 | -- * used only in luaK:exp2reg() | ||
572 | ------------------------------------------------------------------------ | ||
573 | function luaK:code_label(fs, A, b, jump) | ||
574 | self:getlabel(fs) -- those instructions may be jump targets | ||
575 | return self:codeABC(fs, "OP_LOADBOOL", A, b, jump) | ||
576 | end | ||
577 | |||
578 | ------------------------------------------------------------------------ | ||
579 | -- | ||
580 | -- * used in luaK:discharge2anyreg(), luaK:exp2reg() | ||
581 | ------------------------------------------------------------------------ | ||
582 | function luaK:discharge2reg(fs, e, reg) | ||
583 | self:dischargevars(fs, e) | ||
584 | local k = e.k | ||
585 | if k == "VNIL" then | ||
586 | self:_nil(fs, reg, 1) | ||
587 | elseif k == "VFALSE" or k == "VTRUE" then | ||
588 | self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0) | ||
589 | elseif k == "VK" then | ||
590 | self:codeABx(fs, "OP_LOADK", reg, e.info) | ||
591 | elseif k == "VKNUM" then | ||
592 | self:codeABx(fs, "OP_LOADK", reg, self:numberK(fs, e.nval)) | ||
593 | elseif k == "VRELOCABLE" then | ||
594 | local pc = self:getcode(fs, e) | ||
595 | luaP:SETARG_A(pc, reg) | ||
596 | elseif k == "VNONRELOC" then | ||
597 | if reg ~= e.info then | ||
598 | self:codeABC(fs, "OP_MOVE", reg, e.info, 0) | ||
599 | end | ||
600 | else | ||
601 | lua_assert(e.k == "VVOID" or e.k == "VJMP") | ||
602 | return -- nothing to do... | ||
603 | end | ||
604 | e.info = reg | ||
605 | e.k = "VNONRELOC" | ||
606 | end | ||
607 | |||
608 | ------------------------------------------------------------------------ | ||
609 | -- | ||
610 | -- * used in luaK:jumponcond(), luaK:codenot() | ||
611 | ------------------------------------------------------------------------ | ||
612 | function luaK:discharge2anyreg(fs, e) | ||
613 | if e.k ~= "VNONRELOC" then | ||
614 | self:reserveregs(fs, 1) | ||
615 | self:discharge2reg(fs, e, fs.freereg - 1) | ||
616 | end | ||
617 | end | ||
618 | |||
619 | ------------------------------------------------------------------------ | ||
620 | -- | ||
621 | -- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar() | ||
622 | ------------------------------------------------------------------------ | ||
623 | function luaK:exp2reg(fs, e, reg) | ||
624 | self:discharge2reg(fs, e, reg) | ||
625 | if e.k == "VJMP" then | ||
626 | e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list | ||
627 | end | ||
628 | if self:hasjumps(e) then | ||
629 | local final -- position after whole expression | ||
630 | local p_f = self.NO_JUMP -- position of an eventual LOAD false | ||
631 | local p_t = self.NO_JUMP -- position of an eventual LOAD true | ||
632 | if self:need_value(fs, e.t) or self:need_value(fs, e.f) then | ||
633 | local fj = (e.k == "VJMP") and self.NO_JUMP or self:jump(fs) | ||
634 | p_f = self:code_label(fs, reg, 0, 1) | ||
635 | p_t = self:code_label(fs, reg, 1, 0) | ||
636 | self:patchtohere(fs, fj) | ||
637 | end | ||
638 | final = self:getlabel(fs) | ||
639 | self:patchlistaux(fs, e.f, final, reg, p_f) | ||
640 | self:patchlistaux(fs, e.t, final, reg, p_t) | ||
641 | end | ||
642 | e.f, e.t = self.NO_JUMP, self.NO_JUMP | ||
643 | e.info = reg | ||
644 | e.k = "VNONRELOC" | ||
645 | end | ||
646 | |||
647 | ------------------------------------------------------------------------ | ||
648 | -- | ||
649 | -- * used in multiple locations | ||
650 | ------------------------------------------------------------------------ | ||
651 | function luaK:exp2nextreg(fs, e) | ||
652 | self:dischargevars(fs, e) | ||
653 | self:freeexp(fs, e) | ||
654 | self:reserveregs(fs, 1) | ||
655 | self:exp2reg(fs, e, fs.freereg - 1) | ||
656 | end | ||
657 | |||
658 | ------------------------------------------------------------------------ | ||
659 | -- | ||
660 | -- * used in multiple locations | ||
661 | ------------------------------------------------------------------------ | ||
662 | function luaK:exp2anyreg(fs, e) | ||
663 | self:dischargevars(fs, e) | ||
664 | if e.k == "VNONRELOC" then | ||
665 | if not self:hasjumps(e) then -- exp is already in a register | ||
666 | return e.info | ||
667 | end | ||
668 | if e.info >= fs.nactvar then -- reg. is not a local? | ||
669 | self:exp2reg(fs, e, e.info) -- put value on it | ||
670 | return e.info | ||
671 | end | ||
672 | end | ||
673 | self:exp2nextreg(fs, e) -- default | ||
674 | return e.info | ||
675 | end | ||
676 | |||
677 | ------------------------------------------------------------------------ | ||
678 | -- | ||
679 | -- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix() | ||
680 | -- * used in (lparser) luaY:yindex() | ||
681 | ------------------------------------------------------------------------ | ||
682 | function luaK:exp2val(fs, e) | ||
683 | if self:hasjumps(e) then | ||
684 | self:exp2anyreg(fs, e) | ||
685 | else | ||
686 | self:dischargevars(fs, e) | ||
687 | end | ||
688 | end | ||
689 | |||
690 | ------------------------------------------------------------------------ | ||
691 | -- | ||
692 | -- * used in multiple locations | ||
693 | ------------------------------------------------------------------------ | ||
694 | function luaK:exp2RK(fs, e) | ||
695 | self:exp2val(fs, e) | ||
696 | local k = e.k | ||
697 | if k == "VKNUM" or k == "VTRUE" or k == "VFALSE" or k == "VNIL" then | ||
698 | if fs.nk <= luaP.MAXINDEXRK then -- constant fit in RK operand? | ||
699 | -- converted from a 2-deep ternary operator expression | ||
700 | if e.k == "VNIL" then | ||
701 | e.info = self:nilK(fs) | ||
702 | else | ||
703 | e.info = (e.k == "VKNUM") and self:numberK(fs, e.nval) | ||
704 | or self:boolK(fs, e.k == "VTRUE") | ||
705 | end | ||
706 | e.k = "VK" | ||
707 | return luaP:RKASK(e.info) | ||
708 | end | ||
709 | elseif k == "VK" then | ||
710 | if e.info <= luaP.MAXINDEXRK then -- constant fit in argC? | ||
711 | return luaP:RKASK(e.info) | ||
712 | end | ||
713 | else | ||
714 | -- default | ||
715 | end | ||
716 | -- not a constant in the right range: put it in a register | ||
717 | return self:exp2anyreg(fs, e) | ||
718 | end | ||
719 | |||
720 | ------------------------------------------------------------------------ | ||
721 | -- | ||
722 | -- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat() | ||
723 | ------------------------------------------------------------------------ | ||
724 | function luaK:storevar(fs, var, ex) | ||
725 | local k = var.k | ||
726 | if k == "VLOCAL" then | ||
727 | self:freeexp(fs, ex) | ||
728 | self:exp2reg(fs, ex, var.info) | ||
729 | return | ||
730 | elseif k == "VUPVAL" then | ||
731 | local e = self:exp2anyreg(fs, ex) | ||
732 | self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0) | ||
733 | elseif k == "VGLOBAL" then | ||
734 | local e = self:exp2anyreg(fs, ex) | ||
735 | self:codeABx(fs, "OP_SETGLOBAL", e, var.info) | ||
736 | elseif k == "VINDEXED" then | ||
737 | local e = self:exp2RK(fs, ex) | ||
738 | self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e) | ||
739 | else | ||
740 | lua_assert(0) -- invalid var kind to store | ||
741 | end | ||
742 | self:freeexp(fs, ex) | ||
743 | end | ||
744 | |||
745 | ------------------------------------------------------------------------ | ||
746 | -- | ||
747 | -- * used only in (lparser) luaY:primaryexp() | ||
748 | ------------------------------------------------------------------------ | ||
749 | function luaK:_self(fs, e, key) | ||
750 | self:exp2anyreg(fs, e) | ||
751 | self:freeexp(fs, e) | ||
752 | local func = fs.freereg | ||
753 | self:reserveregs(fs, 2) | ||
754 | self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key)) | ||
755 | self:freeexp(fs, key) | ||
756 | e.info = func | ||
757 | e.k = "VNONRELOC" | ||
758 | end | ||
759 | |||
760 | ------------------------------------------------------------------------ | ||
761 | -- | ||
762 | -- * used in luaK:goiftrue(), luaK:codenot() | ||
763 | ------------------------------------------------------------------------ | ||
764 | function luaK:invertjump(fs, e) | ||
765 | local pc = self:getjumpcontrol(fs, e.info) | ||
766 | lua_assert(luaP:testTMode(luaP:GET_OPCODE(pc)) ~= 0 and | ||
767 | luaP:GET_OPCODE(pc) ~= "OP_TESTSET" and | ||
768 | luaP:GET_OPCODE(pc) ~= "OP_TEST") | ||
769 | luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0) | ||
770 | end | ||
771 | |||
772 | ------------------------------------------------------------------------ | ||
773 | -- | ||
774 | -- * used in luaK:goiftrue(), luaK:goiffalse() | ||
775 | ------------------------------------------------------------------------ | ||
776 | function luaK:jumponcond(fs, e, cond) | ||
777 | if e.k == "VRELOCABLE" then | ||
778 | local ie = self:getcode(fs, e) | ||
779 | if luaP:GET_OPCODE(ie) == "OP_NOT" then | ||
780 | fs.pc = fs.pc - 1 -- remove previous OP_NOT | ||
781 | return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), 0, cond and 0 or 1) | ||
782 | end | ||
783 | -- else go through | ||
784 | end | ||
785 | self:discharge2anyreg(fs, e) | ||
786 | self:freeexp(fs, e) | ||
787 | return self:condjump(fs, "OP_TESTSET", luaP.NO_REG, e.info, cond and 1 or 0) | ||
788 | end | ||
789 | |||
790 | ------------------------------------------------------------------------ | ||
791 | -- | ||
792 | -- * used in luaK:infix(), (lparser) luaY:cond() | ||
793 | ------------------------------------------------------------------------ | ||
794 | function luaK:goiftrue(fs, e) | ||
795 | local pc -- pc of last jump | ||
796 | self:dischargevars(fs, e) | ||
797 | local k = e.k | ||
798 | if k == "VK" or k == "VKNUM" or k == "VTRUE" then | ||
799 | pc = self.NO_JUMP -- always true; do nothing | ||
800 | elseif k == "VFALSE" then | ||
801 | pc = self:jump(fs) -- always jump | ||
802 | elseif k == "VJMP" then | ||
803 | self:invertjump(fs, e) | ||
804 | pc = e.info | ||
805 | else | ||
806 | pc = self:jumponcond(fs, e, false) | ||
807 | end | ||
808 | e.f = self:concat(fs, e.f, pc) -- insert last jump in `f' list | ||
809 | self:patchtohere(fs, e.t) | ||
810 | e.t = self.NO_JUMP | ||
811 | end | ||
812 | |||
813 | ------------------------------------------------------------------------ | ||
814 | -- | ||
815 | -- * used in luaK:infix() | ||
816 | ------------------------------------------------------------------------ | ||
817 | function luaK:goiffalse(fs, e) | ||
818 | local pc -- pc of last jump | ||
819 | self:dischargevars(fs, e) | ||
820 | local k = e.k | ||
821 | if k == "VNIL" or k == "VFALSE"then | ||
822 | pc = self.NO_JUMP -- always false; do nothing | ||
823 | elseif k == "VTRUE" then | ||
824 | pc = self:jump(fs) -- always jump | ||
825 | elseif k == "VJMP" then | ||
826 | pc = e.info | ||
827 | else | ||
828 | pc = self:jumponcond(fs, e, true) | ||
829 | end | ||
830 | e.t = self:concat(fs, e.t, pc) -- insert last jump in `t' list | ||
831 | self:patchtohere(fs, e.f) | ||
832 | e.f = self.NO_JUMP | ||
833 | end | ||
834 | |||
835 | ------------------------------------------------------------------------ | ||
836 | -- | ||
837 | -- * used only in luaK:prefix() | ||
838 | ------------------------------------------------------------------------ | ||
839 | function luaK:codenot(fs, e) | ||
840 | self:dischargevars(fs, e) | ||
841 | local k = e.k | ||
842 | if k == "VNIL" or k == "VFALSE" then | ||
843 | e.k = "VTRUE" | ||
844 | elseif k == "VK" or k == "VKNUM" or k == "VTRUE" then | ||
845 | e.k = "VFALSE" | ||
846 | elseif k == "VJMP" then | ||
847 | self:invertjump(fs, e) | ||
848 | elseif k == "VRELOCABLE" or k == "VNONRELOC" then | ||
849 | self:discharge2anyreg(fs, e) | ||
850 | self:freeexp(fs, e) | ||
851 | e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0) | ||
852 | e.k = "VRELOCABLE" | ||
853 | else | ||
854 | lua_assert(0) -- cannot happen | ||
855 | end | ||
856 | -- interchange true and false lists | ||
857 | e.f, e.t = e.t, e.f | ||
858 | self:removevalues(fs, e.f) | ||
859 | self:removevalues(fs, e.t) | ||
860 | end | ||
861 | |||
862 | ------------------------------------------------------------------------ | ||
863 | -- | ||
864 | -- * used in (lparser) luaY:field(), luaY:primaryexp() | ||
865 | ------------------------------------------------------------------------ | ||
866 | function luaK:indexed(fs, t, k) | ||
867 | t.aux = self:exp2RK(fs, k) | ||
868 | t.k = "VINDEXED" | ||
869 | end | ||
870 | |||
871 | ------------------------------------------------------------------------ | ||
872 | -- | ||
873 | -- * used only in luaK:codearith() | ||
874 | ------------------------------------------------------------------------ | ||
875 | function luaK:constfolding(op, e1, e2) | ||
876 | local r | ||
877 | if not self:isnumeral(e1) or not self:isnumeral(e2) then return false end | ||
878 | local v1 = e1.nval | ||
879 | local v2 = e2.nval | ||
880 | if op == "OP_ADD" then | ||
881 | r = self:numadd(v1, v2) | ||
882 | elseif op == "OP_SUB" then | ||
883 | r = self:numsub(v1, v2) | ||
884 | elseif op == "OP_MUL" then | ||
885 | r = self:nummul(v1, v2) | ||
886 | elseif op == "OP_DIV" then | ||
887 | if v2 == 0 then return false end -- do not attempt to divide by 0 | ||
888 | r = self:numdiv(v1, v2) | ||
889 | elseif op == "OP_MOD" then | ||
890 | if v2 == 0 then return false end -- do not attempt to divide by 0 | ||
891 | r = self:nummod(v1, v2) | ||
892 | elseif op == "OP_POW" then | ||
893 | r = self:numpow(v1, v2) | ||
894 | elseif op == "OP_UNM" then | ||
895 | r = self:numunm(v1) | ||
896 | elseif op == "OP_LEN" then | ||
897 | return false -- no constant folding for 'len' | ||
898 | else | ||
899 | lua_assert(0) | ||
900 | r = 0 | ||
901 | end | ||
902 | if self:numisnan(r) then return false end -- do not attempt to produce NaN | ||
903 | e1.nval = r | ||
904 | return true | ||
905 | end | ||
906 | |||
907 | ------------------------------------------------------------------------ | ||
908 | -- | ||
909 | -- * used in luaK:prefix(), luaK:posfix() | ||
910 | ------------------------------------------------------------------------ | ||
911 | function luaK:codearith(fs, op, e1, e2) | ||
912 | if self:constfolding(op, e1, e2) then | ||
913 | return | ||
914 | else | ||
915 | local o2 = (op ~= "OP_UNM" and op ~= "OP_LEN") and self:exp2RK(fs, e2) or 0 | ||
916 | local o1 = self:exp2RK(fs, e1) | ||
917 | if o1 > o2 then | ||
918 | self:freeexp(fs, e1) | ||
919 | self:freeexp(fs, e2) | ||
920 | else | ||
921 | self:freeexp(fs, e2) | ||
922 | self:freeexp(fs, e1) | ||
923 | end | ||
924 | e1.info = self:codeABC(fs, op, 0, o1, o2) | ||
925 | e1.k = "VRELOCABLE" | ||
926 | end | ||
927 | end | ||
928 | |||
929 | ------------------------------------------------------------------------ | ||
930 | -- | ||
931 | -- * used only in luaK:posfix() | ||
932 | ------------------------------------------------------------------------ | ||
933 | function luaK:codecomp(fs, op, cond, e1, e2) | ||
934 | local o1 = self:exp2RK(fs, e1) | ||
935 | local o2 = self:exp2RK(fs, e2) | ||
936 | self:freeexp(fs, e2) | ||
937 | self:freeexp(fs, e1) | ||
938 | if cond == 0 and op ~= "OP_EQ" then | ||
939 | -- exchange args to replace by `<' or `<=' | ||
940 | o1, o2 = o2, o1 -- o1 <==> o2 | ||
941 | cond = 1 | ||
942 | end | ||
943 | e1.info = self:condjump(fs, op, cond, o1, o2) | ||
944 | e1.k = "VJMP" | ||
945 | end | ||
946 | |||
947 | ------------------------------------------------------------------------ | ||
948 | -- | ||
949 | -- * used only in (lparser) luaY:subexpr() | ||
950 | ------------------------------------------------------------------------ | ||
951 | function luaK:prefix(fs, op, e) | ||
952 | local e2 = {} -- expdesc | ||
953 | e2.t, e2.f = self.NO_JUMP, self.NO_JUMP | ||
954 | e2.k = "VKNUM" | ||
955 | e2.nval = 0 | ||
956 | if op == "OPR_MINUS" then | ||
957 | if not self:isnumeral(e) then | ||
958 | self:exp2anyreg(fs, e) -- cannot operate on non-numeric constants | ||
959 | end | ||
960 | self:codearith(fs, "OP_UNM", e, e2) | ||
961 | elseif op == "OPR_NOT" then | ||
962 | self:codenot(fs, e) | ||
963 | elseif op == "OPR_LEN" then | ||
964 | self:exp2anyreg(fs, e) -- cannot operate on constants | ||
965 | self:codearith(fs, "OP_LEN", e, e2) | ||
966 | else | ||
967 | lua_assert(0) | ||
968 | end | ||
969 | end | ||
970 | |||
971 | ------------------------------------------------------------------------ | ||
972 | -- | ||
973 | -- * used only in (lparser) luaY:subexpr() | ||
974 | ------------------------------------------------------------------------ | ||
975 | function luaK:infix(fs, op, v) | ||
976 | if op == "OPR_AND" then | ||
977 | self:goiftrue(fs, v) | ||
978 | elseif op == "OPR_OR" then | ||
979 | self:goiffalse(fs, v) | ||
980 | elseif op == "OPR_CONCAT" then | ||
981 | self:exp2nextreg(fs, v) -- operand must be on the 'stack' | ||
982 | elseif op == "OPR_ADD" or op == "OPR_SUB" or | ||
983 | op == "OPR_MUL" or op == "OPR_DIV" or | ||
984 | op == "OPR_MOD" or op == "OPR_POW" then | ||
985 | if not self:isnumeral(v) then self:exp2RK(fs, v) end | ||
986 | else | ||
987 | self:exp2RK(fs, v) | ||
988 | end | ||
989 | end | ||
990 | |||
991 | ------------------------------------------------------------------------ | ||
992 | -- | ||
993 | -- * used only in (lparser) luaY:subexpr() | ||
994 | ------------------------------------------------------------------------ | ||
995 | -- table lookups to simplify testing | ||
996 | luaK.arith_op = { | ||
997 | OPR_ADD = "OP_ADD", OPR_SUB = "OP_SUB", OPR_MUL = "OP_MUL", | ||
998 | OPR_DIV = "OP_DIV", OPR_MOD = "OP_MOD", OPR_POW = "OP_POW", | ||
999 | } | ||
1000 | luaK.comp_op = { | ||
1001 | OPR_EQ = "OP_EQ", OPR_NE = "OP_EQ", OPR_LT = "OP_LT", | ||
1002 | OPR_LE = "OP_LE", OPR_GT = "OP_LT", OPR_GE = "OP_LE", | ||
1003 | } | ||
1004 | luaK.comp_cond = { | ||
1005 | OPR_EQ = 1, OPR_NE = 0, OPR_LT = 1, | ||
1006 | OPR_LE = 1, OPR_GT = 0, OPR_GE = 0, | ||
1007 | } | ||
1008 | function luaK:posfix(fs, op, e1, e2) | ||
1009 | -- needed because e1 = e2 doesn't copy values... | ||
1010 | -- * in 5.0.x, only k/info/aux/t/f copied, t for AND, f for OR | ||
1011 | -- but here, all elements are copied for completeness' sake | ||
1012 | local function copyexp(e1, e2) | ||
1013 | e1.k = e2.k | ||
1014 | e1.info = e2.info; e1.aux = e2.aux | ||
1015 | e1.nval = e2.nval | ||
1016 | e1.t = e2.t; e1.f = e2.f | ||
1017 | end | ||
1018 | if op == "OPR_AND" then | ||
1019 | lua_assert(e1.t == self.NO_JUMP) -- list must be closed | ||
1020 | self:dischargevars(fs, e2) | ||
1021 | e2.f = self:concat(fs, e2.f, e1.f) | ||
1022 | copyexp(e1, e2) | ||
1023 | elseif op == "OPR_OR" then | ||
1024 | lua_assert(e1.f == self.NO_JUMP) -- list must be closed | ||
1025 | self:dischargevars(fs, e2) | ||
1026 | e2.t = self:concat(fs, e2.t, e1.t) | ||
1027 | copyexp(e1, e2) | ||
1028 | elseif op == "OPR_CONCAT" then | ||
1029 | self:exp2val(fs, e2) | ||
1030 | if e2.k == "VRELOCABLE" and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then | ||
1031 | lua_assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1) | ||
1032 | self:freeexp(fs, e1) | ||
1033 | luaP:SETARG_B(self:getcode(fs, e2), e1.info) | ||
1034 | e1.k = "VRELOCABLE" | ||
1035 | e1.info = e2.info | ||
1036 | else | ||
1037 | self:exp2nextreg(fs, e2) -- operand must be on the 'stack' | ||
1038 | self:codearith(fs, "OP_CONCAT", e1, e2) | ||
1039 | end | ||
1040 | else | ||
1041 | -- the following uses a table lookup in place of conditionals | ||
1042 | local arith = self.arith_op[op] | ||
1043 | if arith then | ||
1044 | self:codearith(fs, arith, e1, e2) | ||
1045 | else | ||
1046 | local comp = self.comp_op[op] | ||
1047 | if comp then | ||
1048 | self:codecomp(fs, comp, self.comp_cond[op], e1, e2) | ||
1049 | else | ||
1050 | lua_assert(0) | ||
1051 | end | ||
1052 | end--if arith | ||
1053 | end--if op | ||
1054 | end | ||
1055 | |||
1056 | ------------------------------------------------------------------------ | ||
1057 | -- adjusts debug information for last instruction written, in order to | ||
1058 | -- change the line where item comes into existence | ||
1059 | -- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat() | ||
1060 | ------------------------------------------------------------------------ | ||
1061 | function luaK:fixline(fs, line) | ||
1062 | fs.f.lineinfo[fs.pc - 1] = line | ||
1063 | end | ||
1064 | |||
1065 | ------------------------------------------------------------------------ | ||
1066 | -- general function to write an instruction into the instruction buffer, | ||
1067 | -- sets debug information too | ||
1068 | -- * used in luaK:codeABC(), luaK:codeABx() | ||
1069 | -- * called directly by (lparser) luaY:whilestat() | ||
1070 | ------------------------------------------------------------------------ | ||
1071 | function luaK:code(fs, i, line) | ||
1072 | local f = fs.f | ||
1073 | self:dischargejpc(fs) -- 'pc' will change | ||
1074 | -- put new instruction in code array | ||
1075 | luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil, | ||
1076 | luaY.MAX_INT, "code size overflow") | ||
1077 | f.code[fs.pc] = i | ||
1078 | -- save corresponding line information | ||
1079 | luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil, | ||
1080 | luaY.MAX_INT, "code size overflow") | ||
1081 | f.lineinfo[fs.pc] = line | ||
1082 | local pc = fs.pc | ||
1083 | fs.pc = fs.pc + 1 | ||
1084 | return pc | ||
1085 | end | ||
1086 | |||
1087 | ------------------------------------------------------------------------ | ||
1088 | -- writes an instruction of type ABC | ||
1089 | -- * calls luaK:code() | ||
1090 | ------------------------------------------------------------------------ | ||
1091 | function luaK:codeABC(fs, o, a, b, c) | ||
1092 | lua_assert(luaP:getOpMode(o) == luaP.OpMode.iABC) | ||
1093 | lua_assert(luaP:getBMode(o) ~= luaP.OpArgMask.OpArgN or b == 0) | ||
1094 | lua_assert(luaP:getCMode(o) ~= luaP.OpArgMask.OpArgN or c == 0) | ||
1095 | return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline) | ||
1096 | end | ||
1097 | |||
1098 | ------------------------------------------------------------------------ | ||
1099 | -- writes an instruction of type ABx | ||
1100 | -- * calls luaK:code(), called by luaK:codeAsBx() | ||
1101 | ------------------------------------------------------------------------ | ||
1102 | function luaK:codeABx(fs, o, a, bc) | ||
1103 | lua_assert(luaP:getOpMode(o) == luaP.OpMode.iABx or | ||
1104 | luaP:getOpMode(o) == luaP.OpMode.iAsBx) | ||
1105 | lua_assert(luaP:getCMode(o) == luaP.OpArgMask.OpArgN) | ||
1106 | return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline) | ||
1107 | end | ||
1108 | |||
1109 | ------------------------------------------------------------------------ | ||
1110 | -- | ||
1111 | -- * used in (lparser) luaY:closelistfield(), luaY:lastlistfield() | ||
1112 | ------------------------------------------------------------------------ | ||
1113 | function luaK:setlist(fs, base, nelems, tostore) | ||
1114 | local c = math.floor((nelems - 1)/luaP.LFIELDS_PER_FLUSH) + 1 | ||
1115 | local b = (tostore == luaY.LUA_MULTRET) and 0 or tostore | ||
1116 | lua_assert(tostore ~= 0) | ||
1117 | if c <= luaP.MAXARG_C then | ||
1118 | self:codeABC(fs, "OP_SETLIST", base, b, c) | ||
1119 | else | ||
1120 | self:codeABC(fs, "OP_SETLIST", base, b, 0) | ||
1121 | self:code(fs, luaP:CREATE_Inst(c), fs.ls.lastline) | ||
1122 | end | ||
1123 | fs.freereg = base + 1 -- free registers with list values | ||
1124 | end | ||
1125 | |||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | ldump.lua | ||
4 | Save precompiled Lua chunks | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * WARNING! byte order (little endian) and data type sizes for header | ||
18 | -- signature values hard-coded; see luaU:header | ||
19 | -- * chunk writer generators are included, see below | ||
20 | -- * one significant difference is that instructions are still in table | ||
21 | -- form (with OP/A/B/C/Bx fields) and luaP:Instruction() is needed to | ||
22 | -- convert them into 4-char strings | ||
23 | -- | ||
24 | -- Not implemented: | ||
25 | -- * DumpVar, DumpMem has been removed | ||
26 | -- * DumpVector folded into folded into DumpDebug, DumpCode | ||
27 | -- | ||
28 | -- Added: | ||
29 | -- * for convenience, the following two functions have been added: | ||
30 | -- luaU:make_setS: create a chunk writer that writes to a string | ||
31 | -- luaU:make_setF: create a chunk writer that writes to a file | ||
32 | -- (lua.h contains a typedef for lua_Writer/lua_Chunkwriter, and | ||
33 | -- a Lua-based implementation exists, writer() in lstrlib.c) | ||
34 | -- * luaU:ttype(o) (from lobject.h) | ||
35 | -- * for converting number types to its binary equivalent: | ||
36 | -- luaU:from_double(x): encode double value for writing | ||
37 | -- luaU:from_int(x): encode integer value for writing | ||
38 | -- (error checking is limited for these conversion functions) | ||
39 | -- (double conversion does not support denormals or NaNs) | ||
40 | -- | ||
41 | -- Changed in 5.1.x: | ||
42 | -- * the dumper was mostly rewritten in Lua 5.1.x, so notes on the | ||
43 | -- differences between 5.0.x and 5.1.x is limited | ||
44 | -- * LUAC_VERSION bumped to 0x51, LUAC_FORMAT added | ||
45 | -- * developer is expected to adjust LUAC_FORMAT in order to identify | ||
46 | -- non-standard binary chunk formats | ||
47 | -- * header signature code is smaller, has been simplified, and is | ||
48 | -- tested as a single unit; its logic is shared with the undumper | ||
49 | -- * no more endian conversion, invalid endianness mean rejection | ||
50 | -- * opcode field sizes are no longer exposed in the header | ||
51 | -- * code moved to front of a prototype, followed by constants | ||
52 | -- * debug information moved to the end of the binary chunk, and the | ||
53 | -- relevant functions folded into a single function | ||
54 | -- * luaU:dump returns a writer status code | ||
55 | -- * chunk writer now implements status code because dumper uses it | ||
56 | -- * luaU:endianness removed | ||
57 | ----------------------------------------------------------------------]] | ||
58 | |||
59 | --requires luaP | ||
60 | luaU = {} | ||
61 | |||
62 | -- mark for precompiled code ('<esc>Lua') (from lua.h) | ||
63 | luaU.LUA_SIGNATURE = "\27Lua" | ||
64 | |||
65 | -- constants used by dumper (from lua.h) | ||
66 | luaU.LUA_TNUMBER = 3 | ||
67 | luaU.LUA_TSTRING = 4 | ||
68 | luaU.LUA_TNIL = 0 | ||
69 | luaU.LUA_TBOOLEAN = 1 | ||
70 | luaU.LUA_TNONE = -1 | ||
71 | |||
72 | -- constants for header of binary files (from lundump.h) | ||
73 | luaU.LUAC_VERSION = 0x51 -- this is Lua 5.1 | ||
74 | luaU.LUAC_FORMAT = 0 -- this is the official format | ||
75 | luaU.LUAC_HEADERSIZE = 12 -- size of header of binary files | ||
76 | |||
77 | --[[-------------------------------------------------------------------- | ||
78 | -- Additional functions to handle chunk writing | ||
79 | -- * to use make_setS and make_setF, see test_ldump.lua elsewhere | ||
80 | ----------------------------------------------------------------------]] | ||
81 | |||
82 | ------------------------------------------------------------------------ | ||
83 | -- create a chunk writer that writes to a string | ||
84 | -- * returns the writer function and a table containing the string | ||
85 | -- * to get the final result, look in buff.data | ||
86 | ------------------------------------------------------------------------ | ||
87 | function luaU:make_setS() | ||
88 | local buff = {} | ||
89 | buff.data = "" | ||
90 | local writer = | ||
91 | function(s, buff) -- chunk writer | ||
92 | if not s then return 0 end | ||
93 | buff.data = buff.data..s | ||
94 | return 0 | ||
95 | end | ||
96 | return writer, buff | ||
97 | end | ||
98 | |||
99 | ------------------------------------------------------------------------ | ||
100 | -- create a chunk writer that writes to a file | ||
101 | -- * returns the writer function and a table containing the file handle | ||
102 | -- * if a nil is passed, then writer should close the open file | ||
103 | ------------------------------------------------------------------------ | ||
104 | function luaU:make_setF(filename) | ||
105 | local buff = {} | ||
106 | buff.h = io.open(filename, "wb") | ||
107 | if not buff.h then return nil end | ||
108 | local writer = | ||
109 | function(s, buff) -- chunk writer | ||
110 | if not buff.h then return 0 end | ||
111 | if not s then | ||
112 | if buff.h:close() then return 0 end | ||
113 | else | ||
114 | if buff.h:write(s) then return 0 end | ||
115 | end | ||
116 | return 1 | ||
117 | end | ||
118 | return writer, buff | ||
119 | end | ||
120 | |||
121 | ------------------------------------------------------------------------ | ||
122 | -- works like the lobject.h version except that TObject used in these | ||
123 | -- scripts only has a 'value' field, no 'tt' field (native types used) | ||
124 | ------------------------------------------------------------------------ | ||
125 | function luaU:ttype(o) | ||
126 | local tt = type(o.value) | ||
127 | if tt == "number" then return self.LUA_TNUMBER | ||
128 | elseif tt == "string" then return self.LUA_TSTRING | ||
129 | elseif tt == "nil" then return self.LUA_TNIL | ||
130 | elseif tt == "boolean" then return self.LUA_TBOOLEAN | ||
131 | else | ||
132 | return self.LUA_TNONE -- the rest should not appear | ||
133 | end | ||
134 | end | ||
135 | |||
136 | ----------------------------------------------------------------------- | ||
137 | -- converts a IEEE754 double number to an 8-byte little-endian string | ||
138 | -- * luaU:from_double() and luaU:from_int() are adapted from ChunkBake | ||
139 | -- * supports +/- Infinity, but not denormals or NaNs | ||
140 | ----------------------------------------------------------------------- | ||
141 | function luaU:from_double(x) | ||
142 | local function grab_byte(v) | ||
143 | local c = v % 256 | ||
144 | return (v - c) / 256, string.char(c) | ||
145 | end | ||
146 | local sign = 0 | ||
147 | if x < 0 then sign = 1; x = -x end | ||
148 | local mantissa, exponent = math.frexp(x) | ||
149 | if x == 0 then -- zero | ||
150 | mantissa, exponent = 0, 0 | ||
151 | elseif x == 1/0 then | ||
152 | mantissa, exponent = 0, 2047 | ||
153 | else | ||
154 | mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, 53) | ||
155 | exponent = exponent + 1022 | ||
156 | end | ||
157 | local v, byte = "" -- convert to bytes | ||
158 | x = math.floor(mantissa) | ||
159 | for i = 1,6 do | ||
160 | x, byte = grab_byte(x); v = v..byte -- 47:0 | ||
161 | end | ||
162 | x, byte = grab_byte(exponent * 16 + x); v = v..byte -- 55:48 | ||
163 | x, byte = grab_byte(sign * 128 + x); v = v..byte -- 63:56 | ||
164 | return v | ||
165 | end | ||
166 | |||
167 | ----------------------------------------------------------------------- | ||
168 | -- converts a number to a little-endian 32-bit integer string | ||
169 | -- * input value assumed to not overflow, can be signed/unsigned | ||
170 | ----------------------------------------------------------------------- | ||
171 | function luaU:from_int(x) | ||
172 | local v = "" | ||
173 | x = math.floor(x) | ||
174 | if x < 0 then x = 4294967296 + x end -- ULONG_MAX+1 | ||
175 | for i = 1, 4 do | ||
176 | local c = x % 256 | ||
177 | v = v..string.char(c); x = math.floor(x / 256) | ||
178 | end | ||
179 | return v | ||
180 | end | ||
181 | |||
182 | --[[-------------------------------------------------------------------- | ||
183 | -- Functions to make a binary chunk | ||
184 | -- * many functions have the size parameter removed, since output is | ||
185 | -- in the form of a string and some sizes are implicit or hard-coded | ||
186 | ----------------------------------------------------------------------]] | ||
187 | |||
188 | --[[-------------------------------------------------------------------- | ||
189 | -- struct DumpState: | ||
190 | -- L -- lua_State (not used in this script) | ||
191 | -- writer -- lua_Writer (chunk writer function) | ||
192 | -- data -- void* (chunk writer context or data already written) | ||
193 | -- strip -- if true, don't write any debug information | ||
194 | -- status -- if non-zero, an error has occured | ||
195 | ----------------------------------------------------------------------]] | ||
196 | |||
197 | ------------------------------------------------------------------------ | ||
198 | -- dumps a block of bytes | ||
199 | -- * lua_unlock(D.L), lua_lock(D.L) unused | ||
200 | ------------------------------------------------------------------------ | ||
201 | function luaU:DumpBlock(b, D) | ||
202 | if D.status == 0 then | ||
203 | -- lua_unlock(D->L); | ||
204 | D.status = D.write(b, D.data) | ||
205 | -- lua_lock(D->L); | ||
206 | end | ||
207 | end | ||
208 | |||
209 | ------------------------------------------------------------------------ | ||
210 | -- dumps a char | ||
211 | ------------------------------------------------------------------------ | ||
212 | function luaU:DumpChar(y, D) | ||
213 | self:DumpBlock(string.char(y), D) | ||
214 | end | ||
215 | |||
216 | ------------------------------------------------------------------------ | ||
217 | -- dumps a 32-bit signed or unsigned integer (for int) (hard-coded) | ||
218 | ------------------------------------------------------------------------ | ||
219 | function luaU:DumpInt(x, D) | ||
220 | self:DumpBlock(self:from_int(x), D) | ||
221 | end | ||
222 | |||
223 | ------------------------------------------------------------------------ | ||
224 | -- dumps a lua_Number (hard-coded as a double) | ||
225 | ------------------------------------------------------------------------ | ||
226 | function luaU:DumpNumber(x, D) | ||
227 | self:DumpBlock(self:from_double(x), D) | ||
228 | end | ||
229 | |||
230 | ------------------------------------------------------------------------ | ||
231 | -- dumps a Lua string (size type is hard-coded) | ||
232 | ------------------------------------------------------------------------ | ||
233 | function luaU:DumpString(s, D) | ||
234 | if s == nil then | ||
235 | self:DumpInt(0, D) | ||
236 | else | ||
237 | s = s.."\0" -- include trailing '\0' | ||
238 | self:DumpInt(#s, D) | ||
239 | self:DumpBlock(s, D) | ||
240 | end | ||
241 | end | ||
242 | |||
243 | ------------------------------------------------------------------------ | ||
244 | -- dumps instruction block from function prototype | ||
245 | ------------------------------------------------------------------------ | ||
246 | function luaU:DumpCode(f, D) | ||
247 | local n = f.sizecode | ||
248 | --was DumpVector | ||
249 | self:DumpInt(n, D) | ||
250 | for i = 0, n - 1 do | ||
251 | self:DumpBlock(luaP:Instruction(f.code[i]), D) | ||
252 | end | ||
253 | end | ||
254 | |||
255 | ------------------------------------------------------------------------ | ||
256 | -- dump constant pool from function prototype | ||
257 | -- * bvalue(o), nvalue(o) and rawtsvalue(o) macros removed | ||
258 | ------------------------------------------------------------------------ | ||
259 | function luaU:DumpConstants(f, D) | ||
260 | local n = f.sizek | ||
261 | self:DumpInt(n, D) | ||
262 | for i = 0, n - 1 do | ||
263 | local o = f.k[i] -- TValue | ||
264 | local tt = self:ttype(o) | ||
265 | self:DumpChar(tt, D) | ||
266 | if tt == self.LUA_TNIL then | ||
267 | elseif tt == self.LUA_TBOOLEAN then | ||
268 | self:DumpChar(o.value and 1 or 0, D) | ||
269 | elseif tt == self.LUA_TNUMBER then | ||
270 | self:DumpNumber(o.value, D) | ||
271 | elseif tt == self.LUA_TSTRING then | ||
272 | self:DumpString(o.value, D) | ||
273 | else | ||
274 | --lua_assert(0) -- cannot happen | ||
275 | end | ||
276 | end | ||
277 | n = f.sizep | ||
278 | self:DumpInt(n, D) | ||
279 | for i = 0, n - 1 do | ||
280 | self:DumpFunction(f.p[i], f.source, D) | ||
281 | end | ||
282 | end | ||
283 | |||
284 | ------------------------------------------------------------------------ | ||
285 | -- dump debug information | ||
286 | ------------------------------------------------------------------------ | ||
287 | function luaU:DumpDebug(f, D) | ||
288 | local n | ||
289 | n = D.strip and 0 or f.sizelineinfo -- dump line information | ||
290 | --was DumpVector | ||
291 | self:DumpInt(n, D) | ||
292 | for i = 0, n - 1 do | ||
293 | self:DumpInt(f.lineinfo[i], D) | ||
294 | end | ||
295 | n = D.strip and 0 or f.sizelocvars -- dump local information | ||
296 | self:DumpInt(n, D) | ||
297 | for i = 0, n - 1 do | ||
298 | self:DumpString(f.locvars[i].varname, D) | ||
299 | self:DumpInt(f.locvars[i].startpc, D) | ||
300 | self:DumpInt(f.locvars[i].endpc, D) | ||
301 | end | ||
302 | n = D.strip and 0 or f.sizeupvalues -- dump upvalue information | ||
303 | self:DumpInt(n, D) | ||
304 | for i = 0, n - 1 do | ||
305 | self:DumpString(f.upvalues[i], D) | ||
306 | end | ||
307 | end | ||
308 | |||
309 | ------------------------------------------------------------------------ | ||
310 | -- dump child function prototypes from function prototype | ||
311 | ------------------------------------------------------------------------ | ||
312 | function luaU:DumpFunction(f, p, D) | ||
313 | local source = f.source | ||
314 | if source == p or D.strip then source = nil end | ||
315 | self:DumpString(source, D) | ||
316 | self:DumpInt(f.lineDefined, D) | ||
317 | self:DumpInt(f.lastlinedefined, D) | ||
318 | self:DumpChar(f.nups, D) | ||
319 | self:DumpChar(f.numparams, D) | ||
320 | self:DumpChar(f.is_vararg, D) | ||
321 | self:DumpChar(f.maxstacksize, D) | ||
322 | self:DumpCode(f, D) | ||
323 | self:DumpConstants(f, D) | ||
324 | self:DumpDebug(f, D) | ||
325 | end | ||
326 | |||
327 | ------------------------------------------------------------------------ | ||
328 | -- dump Lua header section (some sizes hard-coded) | ||
329 | ------------------------------------------------------------------------ | ||
330 | function luaU:DumpHeader(D) | ||
331 | local h = self:header() | ||
332 | assert(#h == self.LUAC_HEADERSIZE) -- fixed buffer now an assert | ||
333 | self:DumpBlock(h, D) | ||
334 | end | ||
335 | |||
336 | ------------------------------------------------------------------------ | ||
337 | -- make header (from lundump.c) | ||
338 | -- returns the header string | ||
339 | ------------------------------------------------------------------------ | ||
340 | function luaU:header() | ||
341 | local x = 1 | ||
342 | return self.LUA_SIGNATURE.. | ||
343 | string.char( | ||
344 | self.LUAC_VERSION, | ||
345 | self.LUAC_FORMAT, | ||
346 | x, -- endianness (1=little) | ||
347 | 4, -- sizeof(int) | ||
348 | 4, -- sizeof(size_t) | ||
349 | 4, -- sizeof(Instruction) | ||
350 | 8, -- sizeof(lua_Number) | ||
351 | 0) -- is lua_Number integral? | ||
352 | end | ||
353 | |||
354 | ------------------------------------------------------------------------ | ||
355 | -- dump Lua function as precompiled chunk | ||
356 | -- (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) | ||
357 | -- * w, data are created from make_setS, make_setF | ||
358 | ------------------------------------------------------------------------ | ||
359 | function luaU:dump(L, f, w, data, strip) | ||
360 | local D = {} -- DumpState | ||
361 | D.L = L | ||
362 | D.write = w | ||
363 | D.data = data | ||
364 | D.strip = strip | ||
365 | D.status = 0 | ||
366 | self:DumpHeader(D) | ||
367 | self:DumpFunction(f, nil, D) | ||
368 | -- added: for a chunk writer writing to a file, this final call with | ||
369 | -- nil data is to indicate to the writer to close the file | ||
370 | D.write(nil, D.data) | ||
371 | return D.status | ||
372 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | llex.lua | ||
4 | Lua lexical analyzer in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * intended to 'imitate' llex.c code; performance is not a concern | ||
18 | -- * tokens are strings; code structure largely retained | ||
19 | -- * deleted stuff (compared to llex.c) are noted, comments retained | ||
20 | -- * nextc() returns the currently read character to simplify coding | ||
21 | -- here; next() in llex.c does not return anything | ||
22 | -- * compatibility code is marked with "--#" comments | ||
23 | -- | ||
24 | -- Added: | ||
25 | -- * luaX:chunkid (function luaO_chunkid from lobject.c) | ||
26 | -- * luaX:str2d (function luaO_str2d from lobject.c) | ||
27 | -- * luaX.LUA_QS used in luaX:lexerror (from luaconf.h) | ||
28 | -- * luaX.LUA_COMPAT_LSTR in luaX:read_long_string (from luaconf.h) | ||
29 | -- * luaX.MAX_INT used in luaX:inclinenumber (from llimits.h) | ||
30 | -- | ||
31 | -- To use the lexer: | ||
32 | -- (1) luaX:init() to initialize the lexer | ||
33 | -- (2) luaX:setinput() to set the input stream to lex | ||
34 | -- (3) call luaX:next() or luaX:luaX:lookahead() to get tokens, | ||
35 | -- until "TK_EOS": luaX:next() | ||
36 | -- * since EOZ is returned as a string, be careful when regexp testing | ||
37 | -- | ||
38 | -- Not implemented: | ||
39 | -- * luaX_newstring: not required by this Lua implementation | ||
40 | -- * buffer MAX_SIZET size limit (from llimits.h) test not implemented | ||
41 | -- in the interest of performance | ||
42 | -- * locale-aware number handling is largely redundant as Lua's | ||
43 | -- tonumber() function is already capable of this | ||
44 | -- | ||
45 | -- Changed in 5.1.x: | ||
46 | -- * TK_NAME token order moved down | ||
47 | -- * string representation for TK_NAME, TK_NUMBER, TK_STRING changed | ||
48 | -- * token struct renamed to lower case (LS -> ls) | ||
49 | -- * LexState struct: removed nestlevel, added decpoint | ||
50 | -- * error message functions have been greatly simplified | ||
51 | -- * token2string renamed to luaX_tokens, exposed in llex.h | ||
52 | -- * lexer now handles all kinds of newlines, including CRLF | ||
53 | -- * shbang first line handling removed from luaX:setinput; | ||
54 | -- it is now done in lauxlib.c (luaL_loadfile) | ||
55 | -- * next(ls) macro renamed to nextc(ls) due to new luaX_next function | ||
56 | -- * EXTRABUFF and MAXNOCHECK removed due to lexer changes | ||
57 | -- * checkbuffer(ls, len) macro deleted | ||
58 | -- * luaX:read_numeral now has 3 support functions: luaX:trydecpoint, | ||
59 | -- luaX:buffreplace and (luaO_str2d from lobject.c) luaX:str2d | ||
60 | -- * luaX:read_numeral is now more promiscuous in slurping characters; | ||
61 | -- hexadecimal numbers was added, locale-aware decimal points too | ||
62 | -- * luaX:skip_sep is new; used by luaX:read_long_string | ||
63 | -- * luaX:read_long_string handles new-style long blocks, with some | ||
64 | -- optional compatibility code | ||
65 | -- * luaX:llex: parts changed to support new-style long blocks | ||
66 | -- * luaX:llex: readname functionality has been folded in | ||
67 | -- * luaX:llex: removed test for control characters | ||
68 | ----------------------------------------------------------------------]] | ||
69 | |||
70 | luaX = {} | ||
71 | |||
72 | -- FIRST_RESERVED is not required as tokens are manipulated as strings | ||
73 | -- TOKEN_LEN deleted; maximum length of a reserved word not needed | ||
74 | |||
75 | ------------------------------------------------------------------------ | ||
76 | -- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED | ||
77 | ------------------------------------------------------------------------ | ||
78 | |||
79 | -- terminal symbols denoted by reserved words: TK_AND to TK_WHILE | ||
80 | -- other terminal symbols: TK_NAME to TK_EOS | ||
81 | luaX.RESERVED = [[ | ||
82 | TK_AND and | ||
83 | TK_BREAK break | ||
84 | TK_DO do | ||
85 | TK_ELSE else | ||
86 | TK_ELSEIF elseif | ||
87 | TK_END end | ||
88 | TK_FALSE false | ||
89 | TK_FOR for | ||
90 | TK_FUNCTION function | ||
91 | TK_IF if | ||
92 | TK_IN in | ||
93 | TK_LOCAL local | ||
94 | TK_NIL nil | ||
95 | TK_NOT not | ||
96 | TK_OR or | ||
97 | TK_REPEAT repeat | ||
98 | TK_RETURN return | ||
99 | TK_THEN then | ||
100 | TK_TRUE true | ||
101 | TK_UNTIL until | ||
102 | TK_WHILE while | ||
103 | TK_CONCAT .. | ||
104 | TK_DOTS ... | ||
105 | TK_EQ == | ||
106 | TK_GE >= | ||
107 | TK_LE <= | ||
108 | TK_NE ~= | ||
109 | TK_NAME <name> | ||
110 | TK_NUMBER <number> | ||
111 | TK_STRING <string> | ||
112 | TK_EOS <eof>]] | ||
113 | |||
114 | -- NUM_RESERVED is not required; number of reserved words | ||
115 | |||
116 | --[[-------------------------------------------------------------------- | ||
117 | -- Instead of passing seminfo, the Token struct (e.g. ls.t) is passed | ||
118 | -- so that lexer functions can use its table element, ls.t.seminfo | ||
119 | -- | ||
120 | -- SemInfo (struct no longer needed, a mixed-type value is used) | ||
121 | -- | ||
122 | -- Token (struct of ls.t and ls.lookahead): | ||
123 | -- token -- token symbol | ||
124 | -- seminfo -- semantics information | ||
125 | -- | ||
126 | -- LexState (struct of ls; ls is initialized by luaX:setinput): | ||
127 | -- current -- current character (charint) | ||
128 | -- linenumber -- input line counter | ||
129 | -- lastline -- line of last token 'consumed' | ||
130 | -- t -- current token (table: struct Token) | ||
131 | -- lookahead -- look ahead token (table: struct Token) | ||
132 | -- fs -- 'FuncState' is private to the parser | ||
133 | -- L -- LuaState | ||
134 | -- z -- input stream | ||
135 | -- buff -- buffer for tokens | ||
136 | -- source -- current source name | ||
137 | -- decpoint -- locale decimal point | ||
138 | -- nestlevel -- level of nested non-terminals | ||
139 | ----------------------------------------------------------------------]] | ||
140 | |||
141 | -- luaX.tokens (was luaX_tokens) is now a hash; see luaX:init | ||
142 | |||
143 | luaX.MAXSRC = 80 | ||
144 | luaX.MAX_INT = 2147483645 -- constants from elsewhere (see above) | ||
145 | luaX.LUA_QS = "'%s'" | ||
146 | luaX.LUA_COMPAT_LSTR = 1 | ||
147 | --luaX.MAX_SIZET = 4294967293 | ||
148 | |||
149 | ------------------------------------------------------------------------ | ||
150 | -- initialize lexer | ||
151 | -- * original luaX_init has code to create and register token strings | ||
152 | -- * luaX.tokens: TK_* -> token | ||
153 | -- * luaX.enums: token -> TK_* (used in luaX:llex) | ||
154 | ------------------------------------------------------------------------ | ||
155 | function luaX:init() | ||
156 | local tokens, enums = {}, {} | ||
157 | for v in string.gmatch(self.RESERVED, "[^\n]+") do | ||
158 | local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)") | ||
159 | tokens[tok] = str | ||
160 | enums[str] = tok | ||
161 | end | ||
162 | self.tokens = tokens | ||
163 | self.enums = enums | ||
164 | end | ||
165 | |||
166 | ------------------------------------------------------------------------ | ||
167 | -- returns a suitably-formatted chunk name or id | ||
168 | -- * from lobject.c, used in llex.c and ldebug.c | ||
169 | -- * the result, out, is returned (was first argument) | ||
170 | ------------------------------------------------------------------------ | ||
171 | function luaX:chunkid(source, bufflen) | ||
172 | local out | ||
173 | local first = string.sub(source, 1, 1) | ||
174 | if first == "=" then | ||
175 | out = string.sub(source, 2, bufflen) -- remove first char | ||
176 | else -- out = "source", or "...source" | ||
177 | if first == "@" then | ||
178 | source = string.sub(source, 2) -- skip the '@' | ||
179 | bufflen = bufflen - #" '...' " | ||
180 | local l = #source | ||
181 | out = "" | ||
182 | if l > bufflen then | ||
183 | source = string.sub(source, 1 + l - bufflen) -- get last part of file name | ||
184 | out = out.."..." | ||
185 | end | ||
186 | out = out..source | ||
187 | else -- out = [string "string"] | ||
188 | local len = string.find(source, "[\n\r]") -- stop at first newline | ||
189 | len = len and (len - 1) or #source | ||
190 | bufflen = bufflen - #(" [string \"...\"] ") | ||
191 | if len > bufflen then len = bufflen end | ||
192 | out = "[string \"" | ||
193 | if len < #source then -- must truncate? | ||
194 | out = out..string.sub(source, 1, len).."..." | ||
195 | else | ||
196 | out = out..source | ||
197 | end | ||
198 | out = out.."\"]" | ||
199 | end | ||
200 | end | ||
201 | return out | ||
202 | end | ||
203 | |||
204 | --[[-------------------------------------------------------------------- | ||
205 | -- Support functions for lexer | ||
206 | -- * all lexer errors eventually reaches lexerror: | ||
207 | syntaxerror -> lexerror | ||
208 | ----------------------------------------------------------------------]] | ||
209 | |||
210 | ------------------------------------------------------------------------ | ||
211 | -- look up token and return keyword if found (also called by parser) | ||
212 | ------------------------------------------------------------------------ | ||
213 | function luaX:token2str(ls, token) | ||
214 | if string.sub(token, 1, 3) ~= "TK_" then | ||
215 | if string.find(token, "%c") then | ||
216 | return string.format("char(%d)", string.byte(token)) | ||
217 | end | ||
218 | return token | ||
219 | else | ||
220 | return self.tokens[token] | ||
221 | end | ||
222 | end | ||
223 | |||
224 | ------------------------------------------------------------------------ | ||
225 | -- throws a lexer error | ||
226 | -- * txtToken has been made local to luaX:lexerror | ||
227 | -- * can't communicate LUA_ERRSYNTAX, so it is unimplemented | ||
228 | ------------------------------------------------------------------------ | ||
229 | function luaX:lexerror(ls, msg, token) | ||
230 | local function txtToken(ls, token) | ||
231 | if token == "TK_NAME" or | ||
232 | token == "TK_STRING" or | ||
233 | token == "TK_NUMBER" then | ||
234 | return ls.buff | ||
235 | else | ||
236 | return self:token2str(ls, token) | ||
237 | end | ||
238 | end | ||
239 | local buff = self:chunkid(ls.source, self.MAXSRC) | ||
240 | local msg = string.format("%s:%d: %s", buff, ls.linenumber, msg) | ||
241 | if token then | ||
242 | msg = string.format("%s near "..self.LUA_QS, msg, txtToken(ls, token)) | ||
243 | end | ||
244 | -- luaD_throw(ls->L, LUA_ERRSYNTAX) | ||
245 | error(msg) | ||
246 | end | ||
247 | |||
248 | ------------------------------------------------------------------------ | ||
249 | -- throws a syntax error (mainly called by parser) | ||
250 | -- * ls.t.token has to be set by the function calling luaX:llex | ||
251 | -- (see luaX:next and luaX:lookahead elsewhere in this file) | ||
252 | ------------------------------------------------------------------------ | ||
253 | function luaX:syntaxerror(ls, msg) | ||
254 | self:lexerror(ls, msg, ls.t.token) | ||
255 | end | ||
256 | |||
257 | ------------------------------------------------------------------------ | ||
258 | -- move on to next line | ||
259 | ------------------------------------------------------------------------ | ||
260 | function luaX:currIsNewline(ls) | ||
261 | return ls.current == "\n" or ls.current == "\r" | ||
262 | end | ||
263 | |||
264 | function luaX:inclinenumber(ls) | ||
265 | local old = ls.current | ||
266 | -- lua_assert(currIsNewline(ls)) | ||
267 | self:nextc(ls) -- skip '\n' or '\r' | ||
268 | if self:currIsNewline(ls) and ls.current ~= old then | ||
269 | self:nextc(ls) -- skip '\n\r' or '\r\n' | ||
270 | end | ||
271 | ls.linenumber = ls.linenumber + 1 | ||
272 | if ls.linenumber >= self.MAX_INT then | ||
273 | self:syntaxerror(ls, "chunk has too many lines") | ||
274 | end | ||
275 | end | ||
276 | |||
277 | ------------------------------------------------------------------------ | ||
278 | -- initializes an input stream for lexing | ||
279 | -- * if ls (the lexer state) is passed as a table, then it is filled in, | ||
280 | -- otherwise it has to be retrieved as a return value | ||
281 | -- * LUA_MINBUFFER not used; buffer handling not required any more | ||
282 | ------------------------------------------------------------------------ | ||
283 | function luaX:setinput(L, ls, z, source) | ||
284 | if not ls then ls = {} end -- create struct | ||
285 | if not ls.lookahead then ls.lookahead = {} end | ||
286 | if not ls.t then ls.t = {} end | ||
287 | ls.decpoint = "." | ||
288 | ls.L = L | ||
289 | ls.lookahead.token = "TK_EOS" -- no look-ahead token | ||
290 | ls.z = z | ||
291 | ls.fs = nil | ||
292 | ls.linenumber = 1 | ||
293 | ls.lastline = 1 | ||
294 | ls.source = source | ||
295 | self:nextc(ls) -- read first char | ||
296 | end | ||
297 | |||
298 | --[[-------------------------------------------------------------------- | ||
299 | -- LEXICAL ANALYZER | ||
300 | ----------------------------------------------------------------------]] | ||
301 | |||
302 | ------------------------------------------------------------------------ | ||
303 | -- checks if current character read is found in the set 'set' | ||
304 | ------------------------------------------------------------------------ | ||
305 | function luaX:check_next(ls, set) | ||
306 | if not string.find(set, ls.current, 1, 1) then | ||
307 | return false | ||
308 | end | ||
309 | self:save_and_next(ls) | ||
310 | return true | ||
311 | end | ||
312 | |||
313 | ------------------------------------------------------------------------ | ||
314 | -- retrieve next token, checking the lookahead buffer if necessary | ||
315 | -- * note that the macro next(ls) in llex.c is now luaX:nextc | ||
316 | -- * utilized used in lparser.c (various places) | ||
317 | ------------------------------------------------------------------------ | ||
318 | function luaX:next(ls) | ||
319 | ls.lastline = ls.linenumber | ||
320 | if ls.lookahead.token ~= "TK_EOS" then -- is there a look-ahead token? | ||
321 | -- this must be copy-by-value | ||
322 | ls.t.seminfo = ls.lookahead.seminfo -- use this one | ||
323 | ls.t.token = ls.lookahead.token | ||
324 | ls.lookahead.token = "TK_EOS" -- and discharge it | ||
325 | else | ||
326 | ls.t.token = self:llex(ls, ls.t) -- read next token | ||
327 | end | ||
328 | end | ||
329 | |||
330 | ------------------------------------------------------------------------ | ||
331 | -- fill in the lookahead buffer | ||
332 | -- * utilized used in lparser.c:constructor | ||
333 | ------------------------------------------------------------------------ | ||
334 | function luaX:lookahead(ls) | ||
335 | -- lua_assert(ls.lookahead.token == "TK_EOS") | ||
336 | ls.lookahead.token = self:llex(ls, ls.lookahead) | ||
337 | end | ||
338 | |||
339 | ------------------------------------------------------------------------ | ||
340 | -- gets the next character and returns it | ||
341 | -- * this is the next() macro in llex.c; see notes at the beginning | ||
342 | ------------------------------------------------------------------------ | ||
343 | function luaX:nextc(ls) | ||
344 | local c = luaZ:zgetc(ls.z) | ||
345 | ls.current = c | ||
346 | return c | ||
347 | end | ||
348 | |||
349 | ------------------------------------------------------------------------ | ||
350 | -- saves the given character into the token buffer | ||
351 | -- * buffer handling code removed, not used in this implementation | ||
352 | -- * test for maximum token buffer length not used, makes things faster | ||
353 | ------------------------------------------------------------------------ | ||
354 | |||
355 | function luaX:save(ls, c) | ||
356 | local buff = ls.buff | ||
357 | -- if you want to use this, please uncomment luaX.MAX_SIZET further up | ||
358 | --if #buff > self.MAX_SIZET then | ||
359 | -- self:lexerror(ls, "lexical element too long") | ||
360 | --end | ||
361 | ls.buff = buff..c | ||
362 | end | ||
363 | |||
364 | ------------------------------------------------------------------------ | ||
365 | -- save current character into token buffer, grabs next character | ||
366 | -- * like luaX:nextc, returns the character read for convenience | ||
367 | ------------------------------------------------------------------------ | ||
368 | function luaX:save_and_next(ls) | ||
369 | self:save(ls, ls.current) | ||
370 | return self:nextc(ls) | ||
371 | end | ||
372 | |||
373 | ------------------------------------------------------------------------ | ||
374 | -- LUA_NUMBER | ||
375 | -- * luaX:read_numeral is the main lexer function to read a number | ||
376 | -- * luaX:str2d, luaX:buffreplace, luaX:trydecpoint are support functions | ||
377 | ------------------------------------------------------------------------ | ||
378 | |||
379 | ------------------------------------------------------------------------ | ||
380 | -- string to number converter (was luaO_str2d from lobject.c) | ||
381 | -- * returns the number, nil if fails (originally returns a boolean) | ||
382 | -- * conversion function originally lua_str2number(s,p), a macro which | ||
383 | -- maps to the strtod() function by default (from luaconf.h) | ||
384 | ------------------------------------------------------------------------ | ||
385 | function luaX:str2d(s) | ||
386 | local result = tonumber(s) | ||
387 | if result then return result end | ||
388 | -- conversion failed | ||
389 | if string.lower(string.sub(s, 1, 2)) == "0x" then -- maybe an hexadecimal constant? | ||
390 | result = tonumber(s, 16) | ||
391 | if result then return result end -- most common case | ||
392 | -- Was: invalid trailing characters? | ||
393 | -- In C, this function then skips over trailing spaces. | ||
394 | -- true is returned if nothing else is found except for spaces. | ||
395 | -- If there is still something else, then it returns a false. | ||
396 | -- All this is not necessary using Lua's tonumber. | ||
397 | end | ||
398 | return nil | ||
399 | end | ||
400 | |||
401 | ------------------------------------------------------------------------ | ||
402 | -- single-character replacement, for locale-aware decimal points | ||
403 | ------------------------------------------------------------------------ | ||
404 | function luaX:buffreplace(ls, from, to) | ||
405 | local result, buff = "", ls.buff | ||
406 | for p = 1, #buff do | ||
407 | local c = string.sub(buff, p, p) | ||
408 | if c == from then c = to end | ||
409 | result = result..c | ||
410 | end | ||
411 | ls.buff = result | ||
412 | end | ||
413 | |||
414 | ------------------------------------------------------------------------ | ||
415 | -- Attempt to convert a number by translating '.' decimal points to | ||
416 | -- the decimal point character used by the current locale. This is not | ||
417 | -- needed in Yueliang as Lua's tonumber() is already locale-aware. | ||
418 | -- Instead, the code is here in case the user implements localeconv(). | ||
419 | ------------------------------------------------------------------------ | ||
420 | function luaX:trydecpoint(ls, Token) | ||
421 | -- format error: try to update decimal point separator | ||
422 | local old = ls.decpoint | ||
423 | -- translate the following to Lua if you implement localeconv(): | ||
424 | -- struct lconv *cv = localeconv(); | ||
425 | -- ls->decpoint = (cv ? cv->decimal_point[0] : '.'); | ||
426 | self:buffreplace(ls, old, ls.decpoint) -- try updated decimal separator | ||
427 | local seminfo = self:str2d(ls.buff) | ||
428 | Token.seminfo = seminfo | ||
429 | if not seminfo then | ||
430 | -- format error with correct decimal point: no more options | ||
431 | self:buffreplace(ls, ls.decpoint, ".") -- undo change (for error message) | ||
432 | self:lexerror(ls, "malformed number", "TK_NUMBER") | ||
433 | end | ||
434 | end | ||
435 | |||
436 | ------------------------------------------------------------------------ | ||
437 | -- main number conversion function | ||
438 | -- * "^%w$" needed in the scan in order to detect "EOZ" | ||
439 | ------------------------------------------------------------------------ | ||
440 | function luaX:read_numeral(ls, Token) | ||
441 | -- lua_assert(string.find(ls.current, "%d")) | ||
442 | repeat | ||
443 | self:save_and_next(ls) | ||
444 | until string.find(ls.current, "%D") and ls.current ~= "." | ||
445 | if self:check_next(ls, "Ee") then -- 'E'? | ||
446 | self:check_next(ls, "+-") -- optional exponent sign | ||
447 | end | ||
448 | while string.find(ls.current, "^%w$") or ls.current == "_" do | ||
449 | self:save_and_next(ls) | ||
450 | end | ||
451 | self:buffreplace(ls, ".", ls.decpoint) -- follow locale for decimal point | ||
452 | local seminfo = self:str2d(ls.buff) | ||
453 | Token.seminfo = seminfo | ||
454 | if not seminfo then -- format error? | ||
455 | self:trydecpoint(ls, Token) -- try to update decimal point separator | ||
456 | end | ||
457 | end | ||
458 | |||
459 | ------------------------------------------------------------------------ | ||
460 | -- count separators ("=") in a long string delimiter | ||
461 | -- * used by luaX:read_long_string | ||
462 | ------------------------------------------------------------------------ | ||
463 | function luaX:skip_sep(ls) | ||
464 | local count = 0 | ||
465 | local s = ls.current | ||
466 | -- lua_assert(s == "[" or s == "]") | ||
467 | self:save_and_next(ls) | ||
468 | while ls.current == "=" do | ||
469 | self:save_and_next(ls) | ||
470 | count = count + 1 | ||
471 | end | ||
472 | return (ls.current == s) and count or (-count) - 1 | ||
473 | end | ||
474 | |||
475 | ------------------------------------------------------------------------ | ||
476 | -- reads a long string or long comment | ||
477 | ------------------------------------------------------------------------ | ||
478 | function luaX:read_long_string(ls, Token, sep) | ||
479 | local cont = 0 | ||
480 | self:save_and_next(ls) -- skip 2nd '[' | ||
481 | if self:currIsNewline(ls) then -- string starts with a newline? | ||
482 | self:inclinenumber(ls) -- skip it | ||
483 | end | ||
484 | while true do | ||
485 | local c = ls.current | ||
486 | if c == "EOZ" then | ||
487 | self:lexerror(ls, Token and "unfinished long string" or | ||
488 | "unfinished long comment", "TK_EOS") | ||
489 | elseif c == "[" then | ||
490 | --# compatibility code start | ||
491 | if self.LUA_COMPAT_LSTR then | ||
492 | if self:skip_sep(ls) == sep then | ||
493 | self:save_and_next(ls) -- skip 2nd '[' | ||
494 | cont = cont + 1 | ||
495 | --# compatibility code start | ||
496 | if self.LUA_COMPAT_LSTR == 1 then | ||
497 | if sep == 0 then | ||
498 | self:lexerror(ls, "nesting of [[...]] is deprecated", "[") | ||
499 | end | ||
500 | end | ||
501 | --# compatibility code end | ||
502 | end | ||
503 | end | ||
504 | --# compatibility code end | ||
505 | elseif c == "]" then | ||
506 | if self:skip_sep(ls) == sep then | ||
507 | self:save_and_next(ls) -- skip 2nd ']' | ||
508 | --# compatibility code start | ||
509 | if self.LUA_COMPAT_LSTR and self.LUA_COMPAT_LSTR == 2 then | ||
510 | cont = cont - 1 | ||
511 | if sep == 0 and cont >= 0 then break end | ||
512 | end | ||
513 | --# compatibility code end | ||
514 | break | ||
515 | end | ||
516 | elseif self:currIsNewline(ls) then | ||
517 | self:save(ls, "\n") | ||
518 | self:inclinenumber(ls) | ||
519 | if not Token then ls.buff = "" end -- avoid wasting space | ||
520 | else -- default | ||
521 | if Token then | ||
522 | self:save_and_next(ls) | ||
523 | else | ||
524 | self:nextc(ls) | ||
525 | end | ||
526 | end--if c | ||
527 | end--while | ||
528 | if Token then | ||
529 | local p = 3 + sep | ||
530 | Token.seminfo = string.sub(ls.buff, p, -p) | ||
531 | end | ||
532 | end | ||
533 | |||
534 | ------------------------------------------------------------------------ | ||
535 | -- reads a string | ||
536 | -- * has been restructured significantly compared to the original C code | ||
537 | ------------------------------------------------------------------------ | ||
538 | |||
539 | function luaX:read_string(ls, del, Token) | ||
540 | self:save_and_next(ls) | ||
541 | while ls.current ~= del do | ||
542 | local c = ls.current | ||
543 | if c == "EOZ" then | ||
544 | self:lexerror(ls, "unfinished string", "TK_EOS") | ||
545 | elseif self:currIsNewline(ls) then | ||
546 | self:lexerror(ls, "unfinished string", "TK_STRING") | ||
547 | elseif c == "\\" then | ||
548 | c = self:nextc(ls) -- do not save the '\' | ||
549 | if self:currIsNewline(ls) then -- go through | ||
550 | self:save(ls, "\n") | ||
551 | self:inclinenumber(ls) | ||
552 | elseif c ~= "EOZ" then -- will raise an error next loop | ||
553 | -- escapes handling greatly simplified here: | ||
554 | local i = string.find("abfnrtv", c, 1, 1) | ||
555 | if i then | ||
556 | self:save(ls, string.sub("\a\b\f\n\r\t\v", i, i)) | ||
557 | self:nextc(ls) | ||
558 | elseif not string.find(c, "%d") then | ||
559 | self:save_and_next(ls) -- handles \\, \", \', and \? | ||
560 | else -- \xxx | ||
561 | c, i = 0, 0 | ||
562 | repeat | ||
563 | c = 10 * c + ls.current | ||
564 | self:nextc(ls) | ||
565 | i = i + 1 | ||
566 | until i >= 3 or not string.find(ls.current, "%d") | ||
567 | if c > 255 then -- UCHAR_MAX | ||
568 | self:lexerror(ls, "escape sequence too large", "TK_STRING") | ||
569 | end | ||
570 | self:save(ls, string.char(c)) | ||
571 | end | ||
572 | end | ||
573 | else | ||
574 | self:save_and_next(ls) | ||
575 | end--if c | ||
576 | end--while | ||
577 | self:save_and_next(ls) -- skip delimiter | ||
578 | Token.seminfo = string.sub(ls.buff, 2, -2) | ||
579 | end | ||
580 | |||
581 | ------------------------------------------------------------------------ | ||
582 | -- main lexer function | ||
583 | ------------------------------------------------------------------------ | ||
584 | function luaX:llex(ls, Token) | ||
585 | ls.buff = "" | ||
586 | while true do | ||
587 | local c = ls.current | ||
588 | ---------------------------------------------------------------- | ||
589 | if self:currIsNewline(ls) then | ||
590 | self:inclinenumber(ls) | ||
591 | ---------------------------------------------------------------- | ||
592 | elseif c == "-" then | ||
593 | c = self:nextc(ls) | ||
594 | if c ~= "-" then return "-" end | ||
595 | -- else is a comment | ||
596 | local sep = -1 | ||
597 | if self:nextc(ls) == '[' then | ||
598 | sep = self:skip_sep(ls) | ||
599 | ls.buff = "" -- 'skip_sep' may dirty the buffer | ||
600 | end | ||
601 | if sep >= 0 then | ||
602 | self:read_long_string(ls, nil, sep) -- long comment | ||
603 | ls.buff = "" | ||
604 | else -- else short comment | ||
605 | while not self:currIsNewline(ls) and ls.current ~= "EOZ" do | ||
606 | self:nextc(ls) | ||
607 | end | ||
608 | end | ||
609 | ---------------------------------------------------------------- | ||
610 | elseif c == "[" then | ||
611 | local sep = self:skip_sep(ls) | ||
612 | if sep >= 0 then | ||
613 | self:read_long_string(ls, Token, sep) | ||
614 | return "TK_STRING" | ||
615 | elseif sep == -1 then | ||
616 | return "[" | ||
617 | else | ||
618 | self:lexerror(ls, "invalid long string delimiter", "TK_STRING") | ||
619 | end | ||
620 | ---------------------------------------------------------------- | ||
621 | elseif c == "=" then | ||
622 | c = self:nextc(ls) | ||
623 | if c ~= "=" then return "=" | ||
624 | else self:nextc(ls); return "TK_EQ" end | ||
625 | ---------------------------------------------------------------- | ||
626 | elseif c == "<" then | ||
627 | c = self:nextc(ls) | ||
628 | if c ~= "=" then return "<" | ||
629 | else self:nextc(ls); return "TK_LE" end | ||
630 | ---------------------------------------------------------------- | ||
631 | elseif c == ">" then | ||
632 | c = self:nextc(ls) | ||
633 | if c ~= "=" then return ">" | ||
634 | else self:nextc(ls); return "TK_GE" end | ||
635 | ---------------------------------------------------------------- | ||
636 | elseif c == "~" then | ||
637 | c = self:nextc(ls) | ||
638 | if c ~= "=" then return "~" | ||
639 | else self:nextc(ls); return "TK_NE" end | ||
640 | ---------------------------------------------------------------- | ||
641 | elseif c == "\"" or c == "'" then | ||
642 | self:read_string(ls, c, Token) | ||
643 | return "TK_STRING" | ||
644 | ---------------------------------------------------------------- | ||
645 | elseif c == "." then | ||
646 | c = self:save_and_next(ls) | ||
647 | if self:check_next(ls, ".") then | ||
648 | if self:check_next(ls, ".") then | ||
649 | return "TK_DOTS" -- ... | ||
650 | else return "TK_CONCAT" -- .. | ||
651 | end | ||
652 | elseif not string.find(c, "%d") then | ||
653 | return "." | ||
654 | else | ||
655 | self:read_numeral(ls, Token) | ||
656 | return "TK_NUMBER" | ||
657 | end | ||
658 | ---------------------------------------------------------------- | ||
659 | elseif c == "EOZ" then | ||
660 | return "TK_EOS" | ||
661 | ---------------------------------------------------------------- | ||
662 | else -- default | ||
663 | if string.find(c, "%s") then | ||
664 | -- lua_assert(self:currIsNewline(ls)) | ||
665 | self:nextc(ls) | ||
666 | elseif string.find(c, "%d") then | ||
667 | self:read_numeral(ls, Token) | ||
668 | return "TK_NUMBER" | ||
669 | elseif string.find(c, "[_%a]") then | ||
670 | -- identifier or reserved word | ||
671 | repeat | ||
672 | c = self:save_and_next(ls) | ||
673 | until c == "EOZ" or not string.find(c, "[_%w]") | ||
674 | local ts = ls.buff | ||
675 | local tok = self.enums[ts] | ||
676 | if tok then return tok end -- reserved word? | ||
677 | Token.seminfo = ts | ||
678 | return "TK_NAME" | ||
679 | else | ||
680 | self:nextc(ls) | ||
681 | return c -- single-char tokens (+ - / ...) | ||
682 | end | ||
683 | ---------------------------------------------------------------- | ||
684 | end--if c | ||
685 | end--while | ||
686 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lopcodes.lua | ||
4 | Lua 5 virtual machine opcodes in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * an Instruction is a table with OP, A, B, C, Bx elements; this | ||
18 | -- makes the code easy to follow and should allow instruction handling | ||
19 | -- to work with doubles and ints | ||
20 | -- * WARNING luaP:Instruction outputs instructions encoded in little- | ||
21 | -- endian form and field size and positions are hard-coded | ||
22 | -- | ||
23 | -- Not implemented: | ||
24 | -- * | ||
25 | -- | ||
26 | -- Added: | ||
27 | -- * luaP:CREATE_Inst(c): create an inst from a number (for OP_SETLIST) | ||
28 | -- * luaP:Instruction(i): convert field elements to a 4-char string | ||
29 | -- * luaP:DecodeInst(x): convert 4-char string into field elements | ||
30 | -- | ||
31 | -- Changed in 5.1.x: | ||
32 | -- * POS_OP added, instruction field positions changed | ||
33 | -- * some symbol names may have changed, e.g. LUAI_BITSINT | ||
34 | -- * new operators for RK indices: BITRK, ISK(x), INDEXK(r), RKASK(x) | ||
35 | -- * OP_MOD, OP_LEN is new | ||
36 | -- * OP_TEST is now OP_TESTSET, OP_TEST is new | ||
37 | -- * OP_FORLOOP, OP_TFORLOOP adjusted, OP_FORPREP is new | ||
38 | -- * OP_TFORPREP deleted | ||
39 | -- * OP_SETLIST and OP_SETLISTO merged and extended | ||
40 | -- * OP_VARARG is new | ||
41 | -- * many changes to implementation of OpMode data | ||
42 | ----------------------------------------------------------------------]] | ||
43 | |||
44 | luaP = {} | ||
45 | |||
46 | --[[ | ||
47 | =========================================================================== | ||
48 | We assume that instructions are unsigned numbers. | ||
49 | All instructions have an opcode in the first 6 bits. | ||
50 | Instructions can have the following fields: | ||
51 | 'A' : 8 bits | ||
52 | 'B' : 9 bits | ||
53 | 'C' : 9 bits | ||
54 | 'Bx' : 18 bits ('B' and 'C' together) | ||
55 | 'sBx' : signed Bx | ||
56 | |||
57 | A signed argument is represented in excess K; that is, the number | ||
58 | value is the unsigned value minus K. K is exactly the maximum value | ||
59 | for that argument (so that -max is represented by 0, and +max is | ||
60 | represented by 2*max), which is half the maximum for the corresponding | ||
61 | unsigned argument. | ||
62 | =========================================================================== | ||
63 | --]] | ||
64 | |||
65 | luaP.OpMode = { iABC = 0, iABx = 1, iAsBx = 2 } -- basic instruction format | ||
66 | |||
67 | ------------------------------------------------------------------------ | ||
68 | -- size and position of opcode arguments. | ||
69 | -- * WARNING size and position is hard-coded elsewhere in this script | ||
70 | ------------------------------------------------------------------------ | ||
71 | luaP.SIZE_C = 9 | ||
72 | luaP.SIZE_B = 9 | ||
73 | luaP.SIZE_Bx = luaP.SIZE_C + luaP.SIZE_B | ||
74 | luaP.SIZE_A = 8 | ||
75 | |||
76 | luaP.SIZE_OP = 6 | ||
77 | |||
78 | luaP.POS_OP = 0 | ||
79 | luaP.POS_A = luaP.POS_OP + luaP.SIZE_OP | ||
80 | luaP.POS_C = luaP.POS_A + luaP.SIZE_A | ||
81 | luaP.POS_B = luaP.POS_C + luaP.SIZE_C | ||
82 | luaP.POS_Bx = luaP.POS_C | ||
83 | |||
84 | ------------------------------------------------------------------------ | ||
85 | -- limits for opcode arguments. | ||
86 | -- we use (signed) int to manipulate most arguments, | ||
87 | -- so they must fit in LUAI_BITSINT-1 bits (-1 for sign) | ||
88 | ------------------------------------------------------------------------ | ||
89 | -- removed "#if SIZE_Bx < BITS_INT-1" test, assume this script is | ||
90 | -- running on a Lua VM with double or int as LUA_NUMBER | ||
91 | |||
92 | luaP.MAXARG_Bx = math.ldexp(1, luaP.SIZE_Bx) - 1 | ||
93 | luaP.MAXARG_sBx = math.floor(luaP.MAXARG_Bx / 2) -- 'sBx' is signed | ||
94 | |||
95 | luaP.MAXARG_A = math.ldexp(1, luaP.SIZE_A) - 1 | ||
96 | luaP.MAXARG_B = math.ldexp(1, luaP.SIZE_B) - 1 | ||
97 | luaP.MAXARG_C = math.ldexp(1, luaP.SIZE_C) - 1 | ||
98 | |||
99 | -- creates a mask with 'n' 1 bits at position 'p' | ||
100 | -- MASK1(n,p) deleted, not required | ||
101 | -- creates a mask with 'n' 0 bits at position 'p' | ||
102 | -- MASK0(n,p) deleted, not required | ||
103 | |||
104 | --[[-------------------------------------------------------------------- | ||
105 | Visual representation for reference: | ||
106 | |||
107 | 31 | | | 0 bit position | ||
108 | +-----+-----+-----+----------+ | ||
109 | | B | C | A | Opcode | iABC format | ||
110 | +-----+-----+-----+----------+ | ||
111 | - 9 - 9 - 8 - 6 - field sizes | ||
112 | +-----+-----+-----+----------+ | ||
113 | | [s]Bx | A | Opcode | iABx | iAsBx format | ||
114 | +-----+-----+-----+----------+ | ||
115 | |||
116 | ----------------------------------------------------------------------]] | ||
117 | |||
118 | ------------------------------------------------------------------------ | ||
119 | -- the following macros help to manipulate instructions | ||
120 | -- * changed to a table object representation, very clean compared to | ||
121 | -- the [nightmare] alternatives of using a number or a string | ||
122 | -- * Bx is a separate element from B and C, since there is never a need | ||
123 | -- to split Bx in the parser or code generator | ||
124 | ------------------------------------------------------------------------ | ||
125 | |||
126 | -- these accept or return opcodes in the form of string names | ||
127 | function luaP:GET_OPCODE(i) return self.ROpCode[i.OP] end | ||
128 | function luaP:SET_OPCODE(i, o) i.OP = self.OpCode[o] end | ||
129 | |||
130 | function luaP:GETARG_A(i) return i.A end | ||
131 | function luaP:SETARG_A(i, u) i.A = u end | ||
132 | |||
133 | function luaP:GETARG_B(i) return i.B end | ||
134 | function luaP:SETARG_B(i, b) i.B = b end | ||
135 | |||
136 | function luaP:GETARG_C(i) return i.C end | ||
137 | function luaP:SETARG_C(i, b) i.C = b end | ||
138 | |||
139 | function luaP:GETARG_Bx(i) return i.Bx end | ||
140 | function luaP:SETARG_Bx(i, b) i.Bx = b end | ||
141 | |||
142 | function luaP:GETARG_sBx(i) return i.Bx - self.MAXARG_sBx end | ||
143 | function luaP:SETARG_sBx(i, b) i.Bx = b + self.MAXARG_sBx end | ||
144 | |||
145 | function luaP:CREATE_ABC(o,a,b,c) | ||
146 | return {OP = self.OpCode[o], A = a, B = b, C = c} | ||
147 | end | ||
148 | |||
149 | function luaP:CREATE_ABx(o,a,bc) | ||
150 | return {OP = self.OpCode[o], A = a, Bx = bc} | ||
151 | end | ||
152 | |||
153 | ------------------------------------------------------------------------ | ||
154 | -- create an instruction from a number (for OP_SETLIST) | ||
155 | ------------------------------------------------------------------------ | ||
156 | function luaP:CREATE_Inst(c) | ||
157 | local o = c % 64 | ||
158 | c = (c - o) / 64 | ||
159 | local a = c % 256 | ||
160 | c = (c - a) / 256 | ||
161 | return self:CREATE_ABx(o, a, c) | ||
162 | end | ||
163 | |||
164 | ------------------------------------------------------------------------ | ||
165 | -- returns a 4-char string little-endian encoded form of an instruction | ||
166 | ------------------------------------------------------------------------ | ||
167 | function luaP:Instruction(i) | ||
168 | if i.Bx then | ||
169 | -- change to OP/A/B/C format | ||
170 | i.C = i.Bx % 512 | ||
171 | i.B = (i.Bx - i.C) / 512 | ||
172 | end | ||
173 | local I = i.A * 64 + i.OP | ||
174 | local c0 = I % 256 | ||
175 | I = i.C * 64 + (I - c0) / 256 -- 6 bits of A left | ||
176 | local c1 = I % 256 | ||
177 | I = i.B * 128 + (I - c1) / 256 -- 7 bits of C left | ||
178 | local c2 = I % 256 | ||
179 | local c3 = (I - c2) / 256 | ||
180 | return string.char(c0, c1, c2, c3) | ||
181 | end | ||
182 | |||
183 | ------------------------------------------------------------------------ | ||
184 | -- decodes a 4-char little-endian string into an instruction struct | ||
185 | ------------------------------------------------------------------------ | ||
186 | function luaP:DecodeInst(x) | ||
187 | local byte = string.byte | ||
188 | local i = {} | ||
189 | local I = byte(x, 1) | ||
190 | local op = I % 64 | ||
191 | i.OP = op | ||
192 | I = byte(x, 2) * 4 + (I - op) / 64 -- 2 bits of c0 left | ||
193 | local a = I % 256 | ||
194 | i.A = a | ||
195 | I = byte(x, 3) * 4 + (I - a) / 256 -- 2 bits of c1 left | ||
196 | local c = I % 512 | ||
197 | i.C = c | ||
198 | i.B = byte(x, 4) * 2 + (I - c) / 512 -- 1 bits of c2 left | ||
199 | local opmode = self.OpMode[tonumber(string.sub(self.opmodes[op + 1], 7, 7))] | ||
200 | if opmode ~= "iABC" then | ||
201 | i.Bx = i.B * 512 + i.C | ||
202 | end | ||
203 | return i | ||
204 | end | ||
205 | |||
206 | ------------------------------------------------------------------------ | ||
207 | -- Macros to operate RK indices | ||
208 | -- * these use arithmetic instead of bit ops | ||
209 | ------------------------------------------------------------------------ | ||
210 | |||
211 | -- this bit 1 means constant (0 means register) | ||
212 | luaP.BITRK = math.ldexp(1, luaP.SIZE_B - 1) | ||
213 | |||
214 | -- test whether value is a constant | ||
215 | function luaP:ISK(x) return x >= self.BITRK end | ||
216 | |||
217 | -- gets the index of the constant | ||
218 | function luaP:INDEXK(r) return x - self.BITRK end | ||
219 | |||
220 | luaP.MAXINDEXRK = luaP.BITRK - 1 | ||
221 | |||
222 | -- code a constant index as a RK value | ||
223 | function luaP:RKASK(x) return x + self.BITRK end | ||
224 | |||
225 | ------------------------------------------------------------------------ | ||
226 | -- invalid register that fits in 8 bits | ||
227 | ------------------------------------------------------------------------ | ||
228 | luaP.NO_REG = luaP.MAXARG_A | ||
229 | |||
230 | ------------------------------------------------------------------------ | ||
231 | -- R(x) - register | ||
232 | -- Kst(x) - constant (in constant table) | ||
233 | -- RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x) | ||
234 | ------------------------------------------------------------------------ | ||
235 | |||
236 | ------------------------------------------------------------------------ | ||
237 | -- grep "ORDER OP" if you change these enums | ||
238 | ------------------------------------------------------------------------ | ||
239 | |||
240 | --[[-------------------------------------------------------------------- | ||
241 | Lua virtual machine opcodes (enum OpCode): | ||
242 | ------------------------------------------------------------------------ | ||
243 | name args description | ||
244 | ------------------------------------------------------------------------ | ||
245 | OP_MOVE A B R(A) := R(B) | ||
246 | OP_LOADK A Bx R(A) := Kst(Bx) | ||
247 | OP_LOADBOOL A B C R(A) := (Bool)B; if (C) pc++ | ||
248 | OP_LOADNIL A B R(A) := ... := R(B) := nil | ||
249 | OP_GETUPVAL A B R(A) := UpValue[B] | ||
250 | OP_GETGLOBAL A Bx R(A) := Gbl[Kst(Bx)] | ||
251 | OP_GETTABLE A B C R(A) := R(B)[RK(C)] | ||
252 | OP_SETGLOBAL A Bx Gbl[Kst(Bx)] := R(A) | ||
253 | OP_SETUPVAL A B UpValue[B] := R(A) | ||
254 | OP_SETTABLE A B C R(A)[RK(B)] := RK(C) | ||
255 | OP_NEWTABLE A B C R(A) := {} (size = B,C) | ||
256 | OP_SELF A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] | ||
257 | OP_ADD A B C R(A) := RK(B) + RK(C) | ||
258 | OP_SUB A B C R(A) := RK(B) - RK(C) | ||
259 | OP_MUL A B C R(A) := RK(B) * RK(C) | ||
260 | OP_DIV A B C R(A) := RK(B) / RK(C) | ||
261 | OP_MOD A B C R(A) := RK(B) % RK(C) | ||
262 | OP_POW A B C R(A) := RK(B) ^ RK(C) | ||
263 | OP_UNM A B R(A) := -R(B) | ||
264 | OP_NOT A B R(A) := not R(B) | ||
265 | OP_LEN A B R(A) := length of R(B) | ||
266 | OP_CONCAT A B C R(A) := R(B).. ... ..R(C) | ||
267 | OP_JMP sBx pc+=sBx | ||
268 | OP_EQ A B C if ((RK(B) == RK(C)) ~= A) then pc++ | ||
269 | OP_LT A B C if ((RK(B) < RK(C)) ~= A) then pc++ | ||
270 | OP_LE A B C if ((RK(B) <= RK(C)) ~= A) then pc++ | ||
271 | OP_TEST A C if not (R(A) <=> C) then pc++ | ||
272 | OP_TESTSET A B C if (R(B) <=> C) then R(A) := R(B) else pc++ | ||
273 | OP_CALL A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) | ||
274 | OP_TAILCALL A B C return R(A)(R(A+1), ... ,R(A+B-1)) | ||
275 | OP_RETURN A B return R(A), ... ,R(A+B-2) (see note) | ||
276 | OP_FORLOOP A sBx R(A)+=R(A+2); | ||
277 | if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) } | ||
278 | OP_FORPREP A sBx R(A)-=R(A+2); pc+=sBx | ||
279 | OP_TFORLOOP A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); | ||
280 | if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ | ||
281 | OP_SETLIST A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B | ||
282 | OP_CLOSE A close all variables in the stack up to (>=) R(A) | ||
283 | OP_CLOSURE A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) | ||
284 | OP_VARARG A B R(A), R(A+1), ..., R(A+B-1) = vararg | ||
285 | ----------------------------------------------------------------------]] | ||
286 | |||
287 | luaP.opnames = {} -- opcode names | ||
288 | luaP.OpCode = {} -- lookup name -> number | ||
289 | luaP.ROpCode = {} -- lookup number -> name | ||
290 | |||
291 | ------------------------------------------------------------------------ | ||
292 | -- ORDER OP | ||
293 | ------------------------------------------------------------------------ | ||
294 | local i = 0 | ||
295 | for v in string.gmatch([[ | ||
296 | MOVE LOADK LOADBOOL LOADNIL GETUPVAL | ||
297 | GETGLOBAL GETTABLE SETGLOBAL SETUPVAL SETTABLE | ||
298 | NEWTABLE SELF ADD SUB MUL | ||
299 | DIV MOD POW UNM NOT | ||
300 | LEN CONCAT JMP EQ LT | ||
301 | LE TEST TESTSET CALL TAILCALL | ||
302 | RETURN FORLOOP FORPREP TFORLOOP SETLIST | ||
303 | CLOSE CLOSURE VARARG | ||
304 | ]], "%S+") do | ||
305 | local n = "OP_"..v | ||
306 | luaP.opnames[i] = v | ||
307 | luaP.OpCode[n] = i | ||
308 | luaP.ROpCode[i] = n | ||
309 | i = i + 1 | ||
310 | end | ||
311 | luaP.NUM_OPCODES = i | ||
312 | |||
313 | --[[ | ||
314 | =========================================================================== | ||
315 | Notes: | ||
316 | (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, | ||
317 | and can be 0: OP_CALL then sets 'top' to last_result+1, so | ||
318 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use 'top'. | ||
319 | (*) In OP_VARARG, if (B == 0) then use actual number of varargs and | ||
320 | set top (like in OP_CALL with C == 0). | ||
321 | (*) In OP_RETURN, if (B == 0) then return up to 'top' | ||
322 | (*) In OP_SETLIST, if (B == 0) then B = 'top'; | ||
323 | if (C == 0) then next 'instruction' is real C | ||
324 | (*) For comparisons, A specifies what condition the test should accept | ||
325 | (true or false). | ||
326 | (*) All 'skips' (pc++) assume that next instruction is a jump | ||
327 | =========================================================================== | ||
328 | --]] | ||
329 | |||
330 | --[[-------------------------------------------------------------------- | ||
331 | masks for instruction properties. The format is: | ||
332 | bits 0-1: op mode | ||
333 | bits 2-3: C arg mode | ||
334 | bits 4-5: B arg mode | ||
335 | bit 6: instruction set register A | ||
336 | bit 7: operator is a test | ||
337 | |||
338 | for OpArgMask: | ||
339 | OpArgN - argument is not used | ||
340 | OpArgU - argument is used | ||
341 | OpArgR - argument is a register or a jump offset | ||
342 | OpArgK - argument is a constant or register/constant | ||
343 | ----------------------------------------------------------------------]] | ||
344 | |||
345 | -- was enum OpArgMask | ||
346 | luaP.OpArgMask = { OpArgN = 0, OpArgU = 1, OpArgR = 2, OpArgK = 3 } | ||
347 | |||
348 | ------------------------------------------------------------------------ | ||
349 | -- e.g. to compare with symbols, luaP:getOpMode(...) == luaP.OpCode.iABC | ||
350 | -- * accepts opcode parameter as strings, e.g. "OP_MOVE" | ||
351 | ------------------------------------------------------------------------ | ||
352 | |||
353 | function luaP:getOpMode(m) | ||
354 | return self.opmodes[self.OpCode[m]] % 4 | ||
355 | end | ||
356 | |||
357 | function luaP:getBMode(m) | ||
358 | return math.floor(self.opmodes[self.OpCode[m]] / 16) % 4 | ||
359 | end | ||
360 | |||
361 | function luaP:getCMode(m) | ||
362 | return math.floor(self.opmodes[self.OpCode[m]] / 4) % 4 | ||
363 | end | ||
364 | |||
365 | function luaP:testAMode(m) | ||
366 | return math.floor(self.opmodes[self.OpCode[m]] / 64) % 2 | ||
367 | end | ||
368 | |||
369 | function luaP:testTMode(m) | ||
370 | return math.floor(self.opmodes[self.OpCode[m]] / 128) | ||
371 | end | ||
372 | |||
373 | -- luaP_opnames[] is set above, as the luaP.opnames table | ||
374 | |||
375 | -- number of list items to accumulate before a SETLIST instruction | ||
376 | luaP.LFIELDS_PER_FLUSH = 50 | ||
377 | |||
378 | ------------------------------------------------------------------------ | ||
379 | -- build instruction properties array | ||
380 | -- * deliberately coded to look like the C equivalent | ||
381 | ------------------------------------------------------------------------ | ||
382 | local function opmode(t, a, b, c, m) | ||
383 | local luaP = luaP | ||
384 | return t * 128 + a * 64 + | ||
385 | luaP.OpArgMask[b] * 16 + luaP.OpArgMask[c] * 4 + luaP.OpMode[m] | ||
386 | end | ||
387 | |||
388 | -- ORDER OP | ||
389 | luaP.opmodes = { | ||
390 | -- T A B C mode opcode | ||
391 | opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_LOADK | ||
392 | opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_LOADBOOL | ||
393 | opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LOADNIL | ||
394 | opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_GETUPVAL | ||
395 | opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_GETGLOBAL | ||
396 | opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_GETTABLE | ||
397 | opmode(0, 0, "OpArgK", "OpArgN", "iABx"), -- OP_SETGLOBAL | ||
398 | opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_SETUPVAL | ||
399 | opmode(0, 0, "OpArgK", "OpArgK", "iABC"), -- OP_SETTABLE | ||
400 | opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_NEWTABLE | ||
401 | opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_SELF | ||
402 | opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_ADD | ||
403 | opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_SUB | ||
404 | opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MUL | ||
405 | opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_DIV | ||
406 | opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MOD | ||
407 | opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_POW | ||
408 | opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_UNM | ||
409 | opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_NOT | ||
410 | opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LEN | ||
411 | opmode(0, 1, "OpArgR", "OpArgR", "iABC"), -- OP_CONCAT | ||
412 | opmode(0, 0, "OpArgR", "OpArgN", "iAsBx"), -- OP_JMP | ||
413 | opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_EQ | ||
414 | opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LT | ||
415 | opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LE | ||
416 | opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TEST | ||
417 | opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TESTSET | ||
418 | opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_CALL | ||
419 | opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_TAILCALL | ||
420 | opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_RETURN | ||
421 | opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORLOOP | ||
422 | opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORPREP | ||
423 | opmode(1, 0, "OpArgN", "OpArgU", "iABC"), -- OP_TFORLOOP | ||
424 | opmode(0, 0, "OpArgU", "OpArgU", "iABC"), -- OP_SETLIST | ||
425 | opmode(0, 0, "OpArgN", "OpArgN", "iABC"), -- OP_CLOSE | ||
426 | opmode(0, 1, "OpArgU", "OpArgN", "iABx"), -- OP_CLOSURE | ||
427 | opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_VARARG | ||
428 | } | ||
429 | -- an awkward way to set a zero-indexed table... | ||
430 | luaP.opmodes[0] = | ||
431 | opmode(0, 1, "OpArgR", "OpArgN", "iABC") -- OP_MOVE | ||
432 | |||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lparser.lua | ||
4 | Lua 5 parser in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * some unused C code that were not converted are kept as comments | ||
18 | -- * LUA_COMPAT_VARARG option changed into a comment block | ||
19 | -- * for value/size specific code added, look for 'NOTE: ' | ||
20 | -- | ||
21 | -- Not implemented: | ||
22 | -- * luaX_newstring not needed by this Lua implementation | ||
23 | -- * luaG_checkcode() in lua_assert is not currently implemented | ||
24 | -- | ||
25 | -- Added: | ||
26 | -- * some constants added from various header files | ||
27 | -- * luaY.LUA_QS used in error_expected, check_match (from luaconf.h) | ||
28 | -- * luaY:LUA_QL needed for error messages (from luaconf.h) | ||
29 | -- * luaY:growvector (from lmem.h) -- skeleton only, limit checking | ||
30 | -- * luaY.SHRT_MAX (from <limits.h>) for registerlocalvar | ||
31 | -- * luaY:newproto (from lfunc.c) | ||
32 | -- * luaY:int2fb (from lobject.c) | ||
33 | -- * NOTE: HASARG_MASK, for implementing a VARARG_HASARG bit operation | ||
34 | -- * NOTE: value-specific code for VARARG_NEEDSARG to replace a bitop | ||
35 | -- | ||
36 | -- Changed in 5.1.x: | ||
37 | -- * various code changes are not detailed... | ||
38 | -- * names of constants may have changed, e.g. added a LUAI_ prefix | ||
39 | -- * struct expkind: added VKNUM, VVARARG; VCALL's info changed? | ||
40 | -- * struct expdesc: added nval | ||
41 | -- * struct FuncState: upvalues data type changed to upvaldesc | ||
42 | -- * macro hasmultret is new | ||
43 | -- * function checklimit moved to parser from lexer | ||
44 | -- * functions anchor_token, errorlimit, checknext are new | ||
45 | -- * checknext is new, equivalent to 5.0.x's check, see check too | ||
46 | -- * luaY:next and luaY:lookahead moved to lexer | ||
47 | -- * break keyword no longer skipped in luaY:breakstat | ||
48 | -- * function new_localvarstr replaced by new_localvarliteral | ||
49 | -- * registerlocalvar limits local variables to SHRT_MAX | ||
50 | -- * create_local deleted, new_localvarliteral used instead | ||
51 | -- * constant LUAI_MAXUPVALUES increased to 60 | ||
52 | -- * constants MAXPARAMS, LUA_MAXPARSERLEVEL, MAXSTACK removed | ||
53 | -- * function interface changed: singlevaraux, singlevar | ||
54 | -- * enterlevel and leavelevel uses nCcalls to track call depth | ||
55 | -- * added a name argument to main entry function, luaY:parser | ||
56 | -- * function luaY_index changed to yindex | ||
57 | -- * luaY:int2fb()'s table size encoding format has been changed | ||
58 | -- * luaY:log2() no longer needed for table constructors | ||
59 | -- * function code_params deleted, functionality folded in parlist | ||
60 | -- * vararg flags handling (is_vararg) changes; also see VARARG_* | ||
61 | -- * LUA_COMPATUPSYNTAX section for old-style upvalues removed | ||
62 | -- * repeatstat() calls chunk() instead of block() | ||
63 | -- * function interface changed: cond, test_then_block | ||
64 | -- * while statement implementation considerably simplified; MAXEXPWHILE | ||
65 | -- and EXTRAEXP no longer required, no limits to the complexity of a | ||
66 | -- while condition | ||
67 | -- * repeat, forbody statement implementation has major changes, | ||
68 | -- mostly due to new scoping behaviour of local variables | ||
69 | -- * OPR_MULT renamed to OPR_MUL | ||
70 | ----------------------------------------------------------------------]] | ||
71 | |||
72 | --requires luaP, luaX, luaK | ||
73 | luaY = {} | ||
74 | |||
75 | --[[-------------------------------------------------------------------- | ||
76 | -- Expression descriptor | ||
77 | -- * expkind changed to string constants; luaY:assignment was the only | ||
78 | -- function to use a relational operator with this enumeration | ||
79 | -- VVOID -- no value | ||
80 | -- VNIL -- no value | ||
81 | -- VTRUE -- no value | ||
82 | -- VFALSE -- no value | ||
83 | -- VK -- info = index of constant in 'k' | ||
84 | -- VKNUM -- nval = numerical value | ||
85 | -- VLOCAL -- info = local register | ||
86 | -- VUPVAL, -- info = index of upvalue in 'upvalues' | ||
87 | -- VGLOBAL -- info = index of table; aux = index of global name in 'k' | ||
88 | -- VINDEXED -- info = table register; aux = index register (or 'k') | ||
89 | -- VJMP -- info = instruction pc | ||
90 | -- VRELOCABLE -- info = instruction pc | ||
91 | -- VNONRELOC -- info = result register | ||
92 | -- VCALL -- info = instruction pc | ||
93 | -- VVARARG -- info = instruction pc | ||
94 | } ----------------------------------------------------------------------]] | ||
95 | |||
96 | --[[-------------------------------------------------------------------- | ||
97 | -- * expdesc in Lua 5.1.x has a union u and another struct s; this Lua | ||
98 | -- implementation ignores all instances of u and s usage | ||
99 | -- struct expdesc: | ||
100 | -- k -- (enum: expkind) | ||
101 | -- info, aux -- (int, int) | ||
102 | -- nval -- (lua_Number) | ||
103 | -- t -- patch list of 'exit when true' | ||
104 | -- f -- patch list of 'exit when false' | ||
105 | ----------------------------------------------------------------------]] | ||
106 | |||
107 | --[[-------------------------------------------------------------------- | ||
108 | -- struct upvaldesc: | ||
109 | -- k -- (lu_byte) | ||
110 | -- info -- (lu_byte) | ||
111 | ----------------------------------------------------------------------]] | ||
112 | |||
113 | --[[-------------------------------------------------------------------- | ||
114 | -- state needed to generate code for a given function | ||
115 | -- struct FuncState: | ||
116 | -- f -- current function header (table: Proto) | ||
117 | -- h -- table to find (and reuse) elements in 'k' (table: Table) | ||
118 | -- prev -- enclosing function (table: FuncState) | ||
119 | -- ls -- lexical state (table: LexState) | ||
120 | -- L -- copy of the Lua state (table: lua_State) | ||
121 | -- bl -- chain of current blocks (table: BlockCnt) | ||
122 | -- pc -- next position to code (equivalent to 'ncode') | ||
123 | -- lasttarget -- 'pc' of last 'jump target' | ||
124 | -- jpc -- list of pending jumps to 'pc' | ||
125 | -- freereg -- first free register | ||
126 | -- nk -- number of elements in 'k' | ||
127 | -- np -- number of elements in 'p' | ||
128 | -- nlocvars -- number of elements in 'locvars' | ||
129 | -- nactvar -- number of active local variables | ||
130 | -- upvalues[LUAI_MAXUPVALUES] -- upvalues (table: upvaldesc) | ||
131 | -- actvar[LUAI_MAXVARS] -- declared-variable stack | ||
132 | ----------------------------------------------------------------------]] | ||
133 | |||
134 | ------------------------------------------------------------------------ | ||
135 | -- constants used by parser | ||
136 | -- * picks up duplicate values from luaX if required | ||
137 | ------------------------------------------------------------------------ | ||
138 | luaY.LUA_QS = luaX.LUA_QS or "'%s'" -- (from luaconf.h) | ||
139 | |||
140 | luaY.SHRT_MAX = 32767 -- (from <limits.h>) | ||
141 | luaY.LUAI_MAXVARS = 200 -- (luaconf.h) | ||
142 | luaY.LUAI_MAXUPVALUES = 60 -- (luaconf.h) | ||
143 | luaY.MAX_INT = luaX.MAX_INT or 2147483645 -- (from llimits.h) | ||
144 | -- * INT_MAX-2 for 32-bit systems | ||
145 | luaY.LUAI_MAXCCALLS = 200 -- (from luaconf.h) | ||
146 | |||
147 | luaY.VARARG_HASARG = 1 -- (from lobject.h) | ||
148 | -- NOTE: HASARG_MASK is value-specific | ||
149 | luaY.HASARG_MASK = 2 -- this was added for a bitop in parlist() | ||
150 | luaY.VARARG_ISVARARG = 2 | ||
151 | -- NOTE: there is some value-specific code that involves VARARG_NEEDSARG | ||
152 | luaY.VARARG_NEEDSARG = 4 | ||
153 | |||
154 | luaY.LUA_MULTRET = -1 -- (lua.h) | ||
155 | |||
156 | --[[-------------------------------------------------------------------- | ||
157 | -- other functions | ||
158 | ----------------------------------------------------------------------]] | ||
159 | |||
160 | ------------------------------------------------------------------------ | ||
161 | -- LUA_QL describes how error messages quote program elements. | ||
162 | -- CHANGE it if you want a different appearance. (from luaconf.h) | ||
163 | ------------------------------------------------------------------------ | ||
164 | function luaY:LUA_QL(x) | ||
165 | return "'"..x.."'" | ||
166 | end | ||
167 | |||
168 | ------------------------------------------------------------------------ | ||
169 | -- this is a stripped-down luaM_growvector (from lmem.h) which is a | ||
170 | -- macro based on luaM_growaux (in lmem.c); all the following does is | ||
171 | -- reproduce the size limit checking logic of the original function | ||
172 | -- so that error behaviour is identical; all arguments preserved for | ||
173 | -- convenience, even those which are unused | ||
174 | -- * set the t field to nil, since this originally does a sizeof(t) | ||
175 | -- * size (originally a pointer) is never updated, their final values | ||
176 | -- are set by luaY:close_func(), so overall things should still work | ||
177 | ------------------------------------------------------------------------ | ||
178 | function luaY:growvector(L, v, nelems, size, t, limit, e) | ||
179 | if nelems >= limit then | ||
180 | error(e) -- was luaG_runerror | ||
181 | end | ||
182 | end | ||
183 | |||
184 | ------------------------------------------------------------------------ | ||
185 | -- initialize a new function prototype structure (from lfunc.c) | ||
186 | -- * used only in open_func() | ||
187 | ------------------------------------------------------------------------ | ||
188 | function luaY:newproto(L) | ||
189 | local f = {} -- Proto | ||
190 | -- luaC_link(L, obj2gco(f), LUA_TPROTO); /* GC */ | ||
191 | f.k = {} | ||
192 | f.sizek = 0 | ||
193 | f.p = {} | ||
194 | f.sizep = 0 | ||
195 | f.code = {} | ||
196 | f.sizecode = 0 | ||
197 | f.sizelineinfo = 0 | ||
198 | f.sizeupvalues = 0 | ||
199 | f.nups = 0 | ||
200 | f.upvalues = {} | ||
201 | f.numparams = 0 | ||
202 | f.is_vararg = 0 | ||
203 | f.maxstacksize = 0 | ||
204 | f.lineinfo = {} | ||
205 | f.sizelocvars = 0 | ||
206 | f.locvars = {} | ||
207 | f.lineDefined = 0 | ||
208 | f.lastlinedefined = 0 | ||
209 | f.source = nil | ||
210 | return f | ||
211 | end | ||
212 | |||
213 | ------------------------------------------------------------------------ | ||
214 | -- converts an integer to a "floating point byte", represented as | ||
215 | -- (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if | ||
216 | -- eeeee != 0 and (xxx) otherwise. | ||
217 | ------------------------------------------------------------------------ | ||
218 | function luaY:int2fb(x) | ||
219 | local e = 0 -- exponent | ||
220 | while x >= 16 do | ||
221 | x = math.floor((x + 1) / 2) | ||
222 | e = e + 1 | ||
223 | end | ||
224 | if x < 8 then | ||
225 | return x | ||
226 | else | ||
227 | return ((e + 1) * 8) + (x - 8) | ||
228 | end | ||
229 | end | ||
230 | |||
231 | --[[-------------------------------------------------------------------- | ||
232 | -- parser functions | ||
233 | ----------------------------------------------------------------------]] | ||
234 | |||
235 | ------------------------------------------------------------------------ | ||
236 | -- true of the kind of expression produces multiple return values | ||
237 | ------------------------------------------------------------------------ | ||
238 | function luaY:hasmultret(k) | ||
239 | return k == "VCALL" or k == "VVARARG" | ||
240 | end | ||
241 | |||
242 | ------------------------------------------------------------------------ | ||
243 | -- convenience function to access active local i, returns entry | ||
244 | ------------------------------------------------------------------------ | ||
245 | function luaY:getlocvar(fs, i) | ||
246 | return fs.f.locvars[ fs.actvar[i] ] | ||
247 | end | ||
248 | |||
249 | ------------------------------------------------------------------------ | ||
250 | -- check a limit, string m provided as an error message | ||
251 | ------------------------------------------------------------------------ | ||
252 | function luaY:checklimit(fs, v, l, m) | ||
253 | if v > l then self:errorlimit(fs, l, m) end | ||
254 | end | ||
255 | |||
256 | --[[-------------------------------------------------------------------- | ||
257 | -- nodes for block list (list of active blocks) | ||
258 | -- struct BlockCnt: | ||
259 | -- previous -- chain (table: BlockCnt) | ||
260 | -- breaklist -- list of jumps out of this loop | ||
261 | -- nactvar -- # active local variables outside the breakable structure | ||
262 | -- upval -- true if some variable in the block is an upvalue (boolean) | ||
263 | -- isbreakable -- true if 'block' is a loop (boolean) | ||
264 | ----------------------------------------------------------------------]] | ||
265 | |||
266 | ------------------------------------------------------------------------ | ||
267 | -- prototypes for recursive non-terminal functions | ||
268 | ------------------------------------------------------------------------ | ||
269 | -- prototypes deleted; not required in Lua | ||
270 | |||
271 | ------------------------------------------------------------------------ | ||
272 | -- reanchor if last token is has a constant string, see close_func() | ||
273 | -- * used only in close_func() | ||
274 | ------------------------------------------------------------------------ | ||
275 | function luaY:anchor_token(ls) | ||
276 | if ls.t.token == "TK_NAME" or ls.t.token == "TK_STRING" then | ||
277 | -- not relevant to Lua implementation of parser | ||
278 | -- local ts = ls.t.seminfo | ||
279 | -- luaX_newstring(ls, getstr(ts), ts->tsv.len); /* C */ | ||
280 | end | ||
281 | end | ||
282 | |||
283 | ------------------------------------------------------------------------ | ||
284 | -- throws a syntax error if token expected is not there | ||
285 | ------------------------------------------------------------------------ | ||
286 | function luaY:error_expected(ls, token) | ||
287 | luaX:syntaxerror(ls, | ||
288 | string.format(self.LUA_QS.." expected", luaX:token2str(ls, token))) | ||
289 | end | ||
290 | |||
291 | ------------------------------------------------------------------------ | ||
292 | -- prepares error message for display, for limits exceeded | ||
293 | -- * used only in checklimit() | ||
294 | ------------------------------------------------------------------------ | ||
295 | function luaY:errorlimit(fs, limit, what) | ||
296 | local msg = (fs.f.linedefined == 0) and | ||
297 | string.format("main function has more than %d %s", limit, what) or | ||
298 | string.format("function at line %d has more than %d %s", | ||
299 | fs.f.linedefined, limit, what) | ||
300 | luaX:lexerror(fs.ls, msg, 0) | ||
301 | end | ||
302 | |||
303 | ------------------------------------------------------------------------ | ||
304 | -- tests for a token, returns outcome | ||
305 | -- * return value changed to boolean | ||
306 | ------------------------------------------------------------------------ | ||
307 | function luaY:testnext(ls, c) | ||
308 | if ls.t.token == c then | ||
309 | luaX:next(ls) | ||
310 | return true | ||
311 | else | ||
312 | return false | ||
313 | end | ||
314 | end | ||
315 | |||
316 | ------------------------------------------------------------------------ | ||
317 | -- check for existence of a token, throws error if not found | ||
318 | ------------------------------------------------------------------------ | ||
319 | function luaY:check(ls, c) | ||
320 | if ls.t.token ~= c then | ||
321 | self:error_expected(ls, c) | ||
322 | end | ||
323 | end | ||
324 | |||
325 | ------------------------------------------------------------------------ | ||
326 | -- verify existence of a token, then skip it | ||
327 | ------------------------------------------------------------------------ | ||
328 | function luaY:checknext(ls, c) | ||
329 | self:check(ls, c) | ||
330 | luaX:next(ls) | ||
331 | end | ||
332 | |||
333 | ------------------------------------------------------------------------ | ||
334 | -- throws error if condition not matched | ||
335 | ------------------------------------------------------------------------ | ||
336 | function luaY:check_condition(ls, c, msg) | ||
337 | if not c then luaX:syntaxerror(ls, msg) end | ||
338 | end | ||
339 | |||
340 | ------------------------------------------------------------------------ | ||
341 | -- verifies token conditions are met or else throw error | ||
342 | ------------------------------------------------------------------------ | ||
343 | function luaY:check_match(ls, what, who, where) | ||
344 | if not self:testnext(ls, what) then | ||
345 | if where == ls.linenumber then | ||
346 | self:error_expected(ls, what) | ||
347 | else | ||
348 | luaX:syntaxerror(ls, string.format( | ||
349 | self.LUA_QS.." expected (to close "..self.LUA_QS.." at line %d)", | ||
350 | luaX:token2str(ls, what), luaX:token2str(ls, who), where)) | ||
351 | end | ||
352 | end | ||
353 | end | ||
354 | |||
355 | ------------------------------------------------------------------------ | ||
356 | -- expect that token is a name, return the name | ||
357 | ------------------------------------------------------------------------ | ||
358 | function luaY:str_checkname(ls) | ||
359 | self:check(ls, "TK_NAME") | ||
360 | local ts = ls.t.seminfo | ||
361 | luaX:next(ls) | ||
362 | return ts | ||
363 | end | ||
364 | |||
365 | ------------------------------------------------------------------------ | ||
366 | -- initialize a struct expdesc, expression description data structure | ||
367 | ------------------------------------------------------------------------ | ||
368 | function luaY:init_exp(e, k, i) | ||
369 | e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP | ||
370 | e.k = k | ||
371 | e.info = i | ||
372 | end | ||
373 | |||
374 | ------------------------------------------------------------------------ | ||
375 | -- adds given string s in string pool, sets e as VK | ||
376 | ------------------------------------------------------------------------ | ||
377 | function luaY:codestring(ls, e, s) | ||
378 | self:init_exp(e, "VK", luaK:stringK(ls.fs, s)) | ||
379 | end | ||
380 | |||
381 | ------------------------------------------------------------------------ | ||
382 | -- consume a name token, adds it to string pool, sets e as VK | ||
383 | ------------------------------------------------------------------------ | ||
384 | function luaY:checkname(ls, e) | ||
385 | self:codestring(ls, e, self:str_checkname(ls)) | ||
386 | end | ||
387 | |||
388 | ------------------------------------------------------------------------ | ||
389 | -- creates struct entry for a local variable | ||
390 | -- * used only in new_localvar() | ||
391 | ------------------------------------------------------------------------ | ||
392 | function luaY:registerlocalvar(ls, varname) | ||
393 | local fs = ls.fs | ||
394 | local f = fs.f | ||
395 | self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars, | ||
396 | nil, self.SHRT_MAX, "too many local variables") | ||
397 | -- loop to initialize empty f.locvar positions not required | ||
398 | f.locvars[fs.nlocvars] = {} -- LocVar | ||
399 | f.locvars[fs.nlocvars].varname = varname | ||
400 | -- luaC_objbarrier(ls.L, f, varname) /* GC */ | ||
401 | local nlocvars = fs.nlocvars | ||
402 | fs.nlocvars = fs.nlocvars + 1 | ||
403 | return nlocvars | ||
404 | end | ||
405 | |||
406 | ------------------------------------------------------------------------ | ||
407 | -- creates a new local variable given a name and an offset from nactvar | ||
408 | -- * used in fornum(), forlist(), parlist(), body() | ||
409 | ------------------------------------------------------------------------ | ||
410 | function luaY:new_localvarliteral(ls, v, n) | ||
411 | self:new_localvar(ls, v, n) | ||
412 | end | ||
413 | |||
414 | ------------------------------------------------------------------------ | ||
415 | -- register a local variable, set in active variable list | ||
416 | ------------------------------------------------------------------------ | ||
417 | function luaY:new_localvar(ls, name, n) | ||
418 | local fs = ls.fs | ||
419 | self:checklimit(fs, fs.nactvar + n + 1, self.LUAI_MAXVARS, "local variables") | ||
420 | fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name) | ||
421 | end | ||
422 | |||
423 | ------------------------------------------------------------------------ | ||
424 | -- adds nvars number of new local variables, set debug information | ||
425 | ------------------------------------------------------------------------ | ||
426 | function luaY:adjustlocalvars(ls, nvars) | ||
427 | local fs = ls.fs | ||
428 | fs.nactvar = fs.nactvar + nvars | ||
429 | for i = nvars, 1, -1 do | ||
430 | self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc | ||
431 | end | ||
432 | end | ||
433 | |||
434 | ------------------------------------------------------------------------ | ||
435 | -- removes a number of locals, set debug information | ||
436 | ------------------------------------------------------------------------ | ||
437 | function luaY:removevars(ls, tolevel) | ||
438 | local fs = ls.fs | ||
439 | while fs.nactvar > tolevel do | ||
440 | fs.nactvar = fs.nactvar - 1 | ||
441 | self:getlocvar(fs, fs.nactvar).endpc = fs.pc | ||
442 | end | ||
443 | end | ||
444 | |||
445 | ------------------------------------------------------------------------ | ||
446 | -- returns an existing upvalue index based on the given name, or | ||
447 | -- creates a new upvalue struct entry and returns the new index | ||
448 | -- * used only in singlevaraux() | ||
449 | ------------------------------------------------------------------------ | ||
450 | function luaY:indexupvalue(fs, name, v) | ||
451 | local f = fs.f | ||
452 | for i = 0, f.nups - 1 do | ||
453 | if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then | ||
454 | lua_assert(f.upvalues[i] == name) | ||
455 | return i | ||
456 | end | ||
457 | end | ||
458 | -- new one | ||
459 | self:checklimit(fs, f.nups + 1, self.LUAI_MAXUPVALUES, "upvalues") | ||
460 | self:growvector(fs.L, f.upvalues, f.nups, f.sizeupvalues, | ||
461 | nil, self.MAX_INT, "") | ||
462 | -- loop to initialize empty f.upvalues positions not required | ||
463 | f.upvalues[f.nups] = name | ||
464 | -- luaC_objbarrier(fs->L, f, name); /* GC */ | ||
465 | lua_assert(v.k == "VLOCAL" or v.k == "VUPVAL") | ||
466 | -- this is a partial copy; only k & info fields used | ||
467 | fs.upvalues[f.nups] = { k = v.k, info = v.info } | ||
468 | local nups = f.nups | ||
469 | f.nups = f.nups + 1 | ||
470 | return nups | ||
471 | end | ||
472 | |||
473 | ------------------------------------------------------------------------ | ||
474 | -- search the local variable namespace of the given fs for a match | ||
475 | -- * used only in singlevaraux() | ||
476 | ------------------------------------------------------------------------ | ||
477 | function luaY:searchvar(fs, n) | ||
478 | for i = fs.nactvar - 1, 0, -1 do | ||
479 | if n == self:getlocvar(fs, i).varname then | ||
480 | return i | ||
481 | end | ||
482 | end | ||
483 | return -1 -- not found | ||
484 | end | ||
485 | |||
486 | ------------------------------------------------------------------------ | ||
487 | -- * mark upvalue flags in function states up to a given level | ||
488 | -- * used only in singlevaraux() | ||
489 | ------------------------------------------------------------------------ | ||
490 | function luaY:markupval(fs, level) | ||
491 | local bl = fs.bl | ||
492 | while bl and bl.nactvar > level do bl = bl.previous end | ||
493 | if bl then bl.upval = true end | ||
494 | end | ||
495 | |||
496 | ------------------------------------------------------------------------ | ||
497 | -- handle locals, globals and upvalues and related processing | ||
498 | -- * search mechanism is recursive, calls itself to search parents | ||
499 | -- * used only in singlevar() | ||
500 | ------------------------------------------------------------------------ | ||
501 | function luaY:singlevaraux(fs, n, var, base) | ||
502 | if fs == nil then -- no more levels? | ||
503 | self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable | ||
504 | return "VGLOBAL" | ||
505 | else | ||
506 | local v = self:searchvar(fs, n) -- look up at current level | ||
507 | if v >= 0 then | ||
508 | self:init_exp(var, "VLOCAL", v) | ||
509 | if base == 0 then | ||
510 | self:markupval(fs, v) -- local will be used as an upval | ||
511 | end | ||
512 | return "VLOCAL" | ||
513 | else -- not found at current level; try upper one | ||
514 | if self:singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then | ||
515 | return "VGLOBAL" | ||
516 | end | ||
517 | var.info = self:indexupvalue(fs, n, var) -- else was LOCAL or UPVAL | ||
518 | var.k = "VUPVAL" -- upvalue in this level | ||
519 | return "VUPVAL" | ||
520 | end--if v | ||
521 | end--if fs | ||
522 | end | ||
523 | |||
524 | ------------------------------------------------------------------------ | ||
525 | -- consume a name token, creates a variable (global|local|upvalue) | ||
526 | -- * used in prefixexp(), funcname() | ||
527 | ------------------------------------------------------------------------ | ||
528 | function luaY:singlevar(ls, var) | ||
529 | local varname = self:str_checkname(ls) | ||
530 | local fs = ls.fs | ||
531 | if self:singlevaraux(fs, varname, var, 1) == "VGLOBAL" then | ||
532 | var.info = luaK:stringK(fs, varname) -- info points to global name | ||
533 | end | ||
534 | end | ||
535 | |||
536 | ------------------------------------------------------------------------ | ||
537 | -- adjust RHS to match LHS in an assignment | ||
538 | -- * used in assignment(), forlist(), localstat() | ||
539 | ------------------------------------------------------------------------ | ||
540 | function luaY:adjust_assign(ls, nvars, nexps, e) | ||
541 | local fs = ls.fs | ||
542 | local extra = nvars - nexps | ||
543 | if self:hasmultret(e.k) then | ||
544 | extra = extra + 1 -- includes call itself | ||
545 | if extra <= 0 then extra = 0 end | ||
546 | luaK:setreturns(fs, e, extra) -- last exp. provides the difference | ||
547 | if extra > 1 then luaK:reserveregs(fs, extra - 1) end | ||
548 | else | ||
549 | if e.k ~= "VVOID" then luaK:exp2nextreg(fs, e) end -- close last expression | ||
550 | if extra > 0 then | ||
551 | local reg = fs.freereg | ||
552 | luaK:reserveregs(fs, extra) | ||
553 | luaK:_nil(fs, reg, extra) | ||
554 | end | ||
555 | end | ||
556 | end | ||
557 | |||
558 | ------------------------------------------------------------------------ | ||
559 | -- tracks and limits parsing depth, assert check at end of parsing | ||
560 | ------------------------------------------------------------------------ | ||
561 | function luaY:enterlevel(ls) | ||
562 | ls.L.nCcalls = ls.L.nCcalls + 1 | ||
563 | if ls.L.nCcalls > self.LUAI_MAXCCALLS then | ||
564 | luaX:lexerror(ls, "chunk has too many syntax levels", 0) | ||
565 | end | ||
566 | end | ||
567 | |||
568 | ------------------------------------------------------------------------ | ||
569 | -- tracks parsing depth, a pair with luaY:enterlevel() | ||
570 | ------------------------------------------------------------------------ | ||
571 | function luaY:leavelevel(ls) | ||
572 | ls.L.nCcalls = ls.L.nCcalls - 1 | ||
573 | end | ||
574 | |||
575 | ------------------------------------------------------------------------ | ||
576 | -- enters a code unit, initializes elements | ||
577 | ------------------------------------------------------------------------ | ||
578 | function luaY:enterblock(fs, bl, isbreakable) | ||
579 | bl.breaklist = luaK.NO_JUMP | ||
580 | bl.isbreakable = isbreakable | ||
581 | bl.nactvar = fs.nactvar | ||
582 | bl.upval = false | ||
583 | bl.previous = fs.bl | ||
584 | fs.bl = bl | ||
585 | lua_assert(fs.freereg == fs.nactvar) | ||
586 | end | ||
587 | |||
588 | ------------------------------------------------------------------------ | ||
589 | -- leaves a code unit, close any upvalues | ||
590 | ------------------------------------------------------------------------ | ||
591 | function luaY:leaveblock(fs) | ||
592 | local bl = fs.bl | ||
593 | fs.bl = bl.previous | ||
594 | self:removevars(fs.ls, bl.nactvar) | ||
595 | if bl.upval then | ||
596 | luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) | ||
597 | end | ||
598 | -- a block either controls scope or breaks (never both) | ||
599 | lua_assert(not bl.isbreakable or not bl.upval) | ||
600 | lua_assert(bl.nactvar == fs.nactvar) | ||
601 | fs.freereg = fs.nactvar -- free registers | ||
602 | luaK:patchtohere(fs, bl.breaklist) | ||
603 | end | ||
604 | |||
605 | ------------------------------------------------------------------------ | ||
606 | -- implement the instantiation of a function prototype, append list of | ||
607 | -- upvalues after the instantiation instruction | ||
608 | -- * used only in body() | ||
609 | ------------------------------------------------------------------------ | ||
610 | function luaY:pushclosure(ls, func, v) | ||
611 | local fs = ls.fs | ||
612 | local f = fs.f | ||
613 | self:growvector(ls.L, f.p, fs.np, f.sizep, nil, | ||
614 | luaP.MAXARG_Bx, "constant table overflow") | ||
615 | -- loop to initialize empty f.p positions not required | ||
616 | f.p[fs.np] = func.f | ||
617 | fs.np = fs.np + 1 | ||
618 | -- luaC_objbarrier(ls->L, f, func->f); /* C */ | ||
619 | self:init_exp(v, "VRELOCABLE", luaK:codeABx(fs, "OP_CLOSURE", 0, fs.np - 1)) | ||
620 | for i = 0, func.f.nups - 1 do | ||
621 | local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL" | ||
622 | luaK:codeABC(fs, o, 0, func.upvalues[i].info, 0) | ||
623 | end | ||
624 | end | ||
625 | |||
626 | ------------------------------------------------------------------------ | ||
627 | -- opening of a function | ||
628 | ------------------------------------------------------------------------ | ||
629 | function luaY:open_func(ls, fs) | ||
630 | local L = ls.L | ||
631 | local f = self:newproto(ls.L) | ||
632 | fs.f = f | ||
633 | fs.prev = ls.fs -- linked list of funcstates | ||
634 | fs.ls = ls | ||
635 | fs.L = L | ||
636 | ls.fs = fs | ||
637 | fs.pc = 0 | ||
638 | fs.lasttarget = -1 | ||
639 | fs.jpc = luaK.NO_JUMP | ||
640 | fs.freereg = 0 | ||
641 | fs.nk = 0 | ||
642 | fs.np = 0 | ||
643 | fs.nlocvars = 0 | ||
644 | fs.nactvar = 0 | ||
645 | fs.bl = nil | ||
646 | f.source = ls.source | ||
647 | f.maxstacksize = 2 -- registers 0/1 are always valid | ||
648 | fs.h = {} -- constant table; was luaH_new call | ||
649 | -- anchor table of constants and prototype (to avoid being collected) | ||
650 | -- sethvalue2s(L, L->top, fs->h); incr_top(L); /* C */ | ||
651 | -- setptvalue2s(L, L->top, f); incr_top(L); | ||
652 | end | ||
653 | |||
654 | ------------------------------------------------------------------------ | ||
655 | -- closing of a function | ||
656 | ------------------------------------------------------------------------ | ||
657 | function luaY:close_func(ls) | ||
658 | local L = ls.L | ||
659 | local fs = ls.fs | ||
660 | local f = fs.f | ||
661 | self:removevars(ls, 0) | ||
662 | luaK:ret(fs, 0, 0) -- final return | ||
663 | -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p, | ||
664 | -- f->locvars, f->upvalues; not required for Lua table arrays | ||
665 | f.sizecode = fs.pc | ||
666 | f.sizelineinfo = fs.pc | ||
667 | f.sizek = fs.nk | ||
668 | f.sizep = fs.np | ||
669 | f.sizelocvars = fs.nlocvars | ||
670 | f.sizeupvalues = f.nups | ||
671 | --lua_assert(luaG_checkcode(f)) -- currently not implemented | ||
672 | lua_assert(fs.bl == nil) | ||
673 | ls.fs = fs.prev | ||
674 | -- the following is not required for this implementation; kept here | ||
675 | -- for completeness | ||
676 | -- L->top -= 2; /* remove table and prototype from the stack */ | ||
677 | -- last token read was anchored in defunct function; must reanchor it | ||
678 | if fs then self:anchor_token(ls) end | ||
679 | end | ||
680 | |||
681 | ------------------------------------------------------------------------ | ||
682 | -- parser initialization function | ||
683 | -- * note additional sub-tables needed for LexState, FuncState | ||
684 | ------------------------------------------------------------------------ | ||
685 | function luaY:parser(L, z, buff, name) | ||
686 | local lexstate = {} -- LexState | ||
687 | lexstate.t = {} | ||
688 | lexstate.lookahead = {} | ||
689 | local funcstate = {} -- FuncState | ||
690 | funcstate.upvalues = {} | ||
691 | funcstate.actvar = {} | ||
692 | -- the following nCcalls initialization added for convenience | ||
693 | L.nCcalls = 0 | ||
694 | lexstate.buff = buff | ||
695 | luaX:setinput(L, lexstate, z, name) | ||
696 | self:open_func(lexstate, funcstate) | ||
697 | funcstate.f.is_vararg = self.VARARG_ISVARARG -- main func. is always vararg | ||
698 | luaX:next(lexstate) -- read first token | ||
699 | self:chunk(lexstate) | ||
700 | self:check(lexstate, "TK_EOS") | ||
701 | self:close_func(lexstate) | ||
702 | lua_assert(funcstate.prev == nil) | ||
703 | lua_assert(funcstate.f.nups == 0) | ||
704 | lua_assert(lexstate.fs == nil) | ||
705 | return funcstate.f | ||
706 | end | ||
707 | |||
708 | --[[-------------------------------------------------------------------- | ||
709 | -- GRAMMAR RULES | ||
710 | ----------------------------------------------------------------------]] | ||
711 | |||
712 | ------------------------------------------------------------------------ | ||
713 | -- parse a function name suffix, for function call specifications | ||
714 | -- * used in primaryexp(), funcname() | ||
715 | ------------------------------------------------------------------------ | ||
716 | function luaY:field(ls, v) | ||
717 | -- field -> ['.' | ':'] NAME | ||
718 | local fs = ls.fs | ||
719 | local key = {} -- expdesc | ||
720 | luaK:exp2anyreg(fs, v) | ||
721 | luaX:next(ls) -- skip the dot or colon | ||
722 | self:checkname(ls, key) | ||
723 | luaK:indexed(fs, v, key) | ||
724 | end | ||
725 | |||
726 | ------------------------------------------------------------------------ | ||
727 | -- parse a table indexing suffix, for constructors, expressions | ||
728 | -- * used in recfield(), primaryexp() | ||
729 | ------------------------------------------------------------------------ | ||
730 | function luaY:yindex(ls, v) | ||
731 | -- index -> '[' expr ']' | ||
732 | luaX:next(ls) -- skip the '[' | ||
733 | self:expr(ls, v) | ||
734 | luaK:exp2val(ls.fs, v) | ||
735 | self:checknext(ls, "]") | ||
736 | end | ||
737 | |||
738 | --[[-------------------------------------------------------------------- | ||
739 | -- Rules for Constructors | ||
740 | ----------------------------------------------------------------------]] | ||
741 | |||
742 | --[[-------------------------------------------------------------------- | ||
743 | -- struct ConsControl: | ||
744 | -- v -- last list item read (table: struct expdesc) | ||
745 | -- t -- table descriptor (table: struct expdesc) | ||
746 | -- nh -- total number of 'record' elements | ||
747 | -- na -- total number of array elements | ||
748 | -- tostore -- number of array elements pending to be stored | ||
749 | ----------------------------------------------------------------------]] | ||
750 | |||
751 | ------------------------------------------------------------------------ | ||
752 | -- parse a table record (hash) field | ||
753 | -- * used in constructor() | ||
754 | ------------------------------------------------------------------------ | ||
755 | function luaY:recfield(ls, cc) | ||
756 | -- recfield -> (NAME | '['exp1']') = exp1 | ||
757 | local fs = ls.fs | ||
758 | local reg = ls.fs.freereg | ||
759 | local key, val = {}, {} -- expdesc | ||
760 | if ls.t.token == "TK_NAME" then | ||
761 | self:checklimit(fs, cc.nh, self.MAX_INT, "items in a constructor") | ||
762 | self:checkname(ls, key) | ||
763 | else -- ls->t.token == '[' | ||
764 | self:yindex(ls, key) | ||
765 | end | ||
766 | cc.nh = cc.nh + 1 | ||
767 | self:checknext(ls, "=") | ||
768 | local rkkey = luaK:exp2RK(fs, key) | ||
769 | self:expr(ls, val) | ||
770 | luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, rkkey, luaK:exp2RK(fs, val)) | ||
771 | fs.freereg = reg -- free registers | ||
772 | end | ||
773 | |||
774 | ------------------------------------------------------------------------ | ||
775 | -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH) | ||
776 | -- * used in constructor() | ||
777 | ------------------------------------------------------------------------ | ||
778 | function luaY:closelistfield(fs, cc) | ||
779 | if cc.v.k == "VVOID" then return end -- there is no list item | ||
780 | luaK:exp2nextreg(fs, cc.v) | ||
781 | cc.v.k = "VVOID" | ||
782 | if cc.tostore == luaP.LFIELDS_PER_FLUSH then | ||
783 | luaK:setlist(fs, cc.t.info, cc.na, cc.tostore) -- flush | ||
784 | cc.tostore = 0 -- no more items pending | ||
785 | end | ||
786 | end | ||
787 | |||
788 | ------------------------------------------------------------------------ | ||
789 | -- emit a set list instruction at the end of parsing list constructor | ||
790 | -- * used in constructor() | ||
791 | ------------------------------------------------------------------------ | ||
792 | function luaY:lastlistfield(fs, cc) | ||
793 | if cc.tostore == 0 then return end | ||
794 | if self:hasmultret(cc.v.k) then | ||
795 | luaK:setmultret(fs, cc.v) | ||
796 | luaK:setlist(fs, cc.t.info, cc.na, self.LUA_MULTRET) | ||
797 | cc.na = cc.na - 1 -- do not count last expression (unknown number of elements) | ||
798 | else | ||
799 | if cc.v.k ~= "VVOID" then | ||
800 | luaK:exp2nextreg(fs, cc.v) | ||
801 | end | ||
802 | luaK:setlist(fs, cc.t.info, cc.na, cc.tostore) | ||
803 | end | ||
804 | end | ||
805 | |||
806 | ------------------------------------------------------------------------ | ||
807 | -- parse a table list (array) field | ||
808 | -- * used in constructor() | ||
809 | ------------------------------------------------------------------------ | ||
810 | function luaY:listfield(ls, cc) | ||
811 | self:expr(ls, cc.v) | ||
812 | self:checklimit(ls.fs, cc.na, self.MAX_INT, "items in a constructor") | ||
813 | cc.na = cc.na + 1 | ||
814 | cc.tostore = cc.tostore + 1 | ||
815 | end | ||
816 | |||
817 | ------------------------------------------------------------------------ | ||
818 | -- parse a table constructor | ||
819 | -- * used in funcargs(), simpleexp() | ||
820 | ------------------------------------------------------------------------ | ||
821 | function luaY:constructor(ls, t) | ||
822 | -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' | ||
823 | -- field -> recfield | listfield | ||
824 | -- fieldsep -> ',' | ';' | ||
825 | local fs = ls.fs | ||
826 | local line = ls.linenumber | ||
827 | local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0) | ||
828 | local cc = {} -- ConsControl | ||
829 | cc.v = {} | ||
830 | cc.na, cc.nh, cc.tostore = 0, 0, 0 | ||
831 | cc.t = t | ||
832 | self:init_exp(t, "VRELOCABLE", pc) | ||
833 | self:init_exp(cc.v, "VVOID", 0) -- no value (yet) | ||
834 | luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc) | ||
835 | self:checknext(ls, "{") | ||
836 | repeat | ||
837 | lua_assert(cc.v.k == "VVOID" or cc.tostore > 0) | ||
838 | if ls.t.token == "}" then break end | ||
839 | self:closelistfield(fs, cc) | ||
840 | local c = ls.t.token | ||
841 | |||
842 | if c == "TK_NAME" then -- may be listfields or recfields | ||
843 | luaX:lookahead(ls) | ||
844 | if ls.lookahead.token ~= "=" then -- expression? | ||
845 | self:listfield(ls, cc) | ||
846 | else | ||
847 | self:recfield(ls, cc) | ||
848 | end | ||
849 | elseif c == "[" then -- constructor_item -> recfield | ||
850 | self:recfield(ls, cc) | ||
851 | else -- constructor_part -> listfield | ||
852 | self:listfield(ls, cc) | ||
853 | end | ||
854 | until not self:testnext(ls, ",") and not self:testnext(ls, ";") | ||
855 | self:check_match(ls, "}", "{", line) | ||
856 | self:lastlistfield(fs, cc) | ||
857 | luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size | ||
858 | luaP:SETARG_C(fs.f.code[pc], self:int2fb(cc.nh)) -- set initial table size | ||
859 | end | ||
860 | |||
861 | -- }====================================================================== | ||
862 | |||
863 | ------------------------------------------------------------------------ | ||
864 | -- parse the arguments (parameters) of a function declaration | ||
865 | -- * used in body() | ||
866 | ------------------------------------------------------------------------ | ||
867 | function luaY:parlist(ls) | ||
868 | -- parlist -> [ param { ',' param } ] | ||
869 | local fs = ls.fs | ||
870 | local f = fs.f | ||
871 | local nparams = 0 | ||
872 | f.is_vararg = 0 | ||
873 | if ls.t.token ~= ")" then -- is 'parlist' not empty? | ||
874 | repeat | ||
875 | local c = ls.t.token | ||
876 | if c == "TK_NAME" then -- param -> NAME | ||
877 | self:new_localvar(ls, self:str_checkname(ls), nparams) | ||
878 | nparams = nparams + 1 | ||
879 | elseif c == "TK_DOTS" then -- param -> `...' | ||
880 | luaX:next(ls) | ||
881 | -- [[ | ||
882 | -- #if defined(LUA_COMPAT_VARARG) | ||
883 | -- use `arg' as default name | ||
884 | self:new_localvarliteral(ls, "arg", nparams) | ||
885 | nparams = nparams + 1 | ||
886 | f.is_vararg = self.VARARG_HASARG + self.VARARG_NEEDSARG | ||
887 | -- #endif | ||
888 | --]] | ||
889 | f.is_vararg = f.is_vararg + self.VARARG_ISVARARG | ||
890 | else | ||
891 | luaX:syntaxerror(ls, "<name> or "..self:LUA_QL("...").." expected") | ||
892 | end | ||
893 | until f.is_vararg ~= 0 or not self:testnext(ls, ",") | ||
894 | end--if | ||
895 | self:adjustlocalvars(ls, nparams) | ||
896 | -- NOTE: the following works only when HASARG_MASK is 2! | ||
897 | f.numparams = fs.nactvar - (f.is_vararg % self.HASARG_MASK) | ||
898 | luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters | ||
899 | end | ||
900 | |||
901 | ------------------------------------------------------------------------ | ||
902 | -- parse function declaration body | ||
903 | -- * used in simpleexp(), localfunc(), funcstat() | ||
904 | ------------------------------------------------------------------------ | ||
905 | function luaY:body(ls, e, needself, line) | ||
906 | -- body -> '(' parlist ')' chunk END | ||
907 | local new_fs = {} -- FuncState | ||
908 | new_fs.upvalues = {} | ||
909 | new_fs.actvar = {} | ||
910 | self:open_func(ls, new_fs) | ||
911 | new_fs.f.lineDefined = line | ||
912 | self:checknext(ls, "(") | ||
913 | if needself then | ||
914 | self:new_localvarliteral(ls, "self", 0) | ||
915 | self:adjustlocalvars(ls, 1) | ||
916 | end | ||
917 | self:parlist(ls) | ||
918 | self:checknext(ls, ")") | ||
919 | self:chunk(ls) | ||
920 | new_fs.f.lastlinedefined = ls.linenumber | ||
921 | self:check_match(ls, "TK_END", "TK_FUNCTION", line) | ||
922 | self:close_func(ls) | ||
923 | self:pushclosure(ls, new_fs, e) | ||
924 | end | ||
925 | |||
926 | ------------------------------------------------------------------------ | ||
927 | -- parse a list of comma-separated expressions | ||
928 | -- * used is multiple locations | ||
929 | ------------------------------------------------------------------------ | ||
930 | function luaY:explist1(ls, v) | ||
931 | -- explist1 -> expr { ',' expr } | ||
932 | local n = 1 -- at least one expression | ||
933 | self:expr(ls, v) | ||
934 | while self:testnext(ls, ",") do | ||
935 | luaK:exp2nextreg(ls.fs, v) | ||
936 | self:expr(ls, v) | ||
937 | n = n + 1 | ||
938 | end | ||
939 | return n | ||
940 | end | ||
941 | |||
942 | ------------------------------------------------------------------------ | ||
943 | -- parse the parameters of a function call | ||
944 | -- * contrast with parlist(), used in function declarations | ||
945 | -- * used in primaryexp() | ||
946 | ------------------------------------------------------------------------ | ||
947 | function luaY:funcargs(ls, f) | ||
948 | local fs = ls.fs | ||
949 | local args = {} -- expdesc | ||
950 | local nparams | ||
951 | local line = ls.linenumber | ||
952 | local c = ls.t.token | ||
953 | if c == "(" then -- funcargs -> '(' [ explist1 ] ')' | ||
954 | if line ~= ls.lastline then | ||
955 | luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)") | ||
956 | end | ||
957 | luaX:next(ls) | ||
958 | if ls.t.token == ")" then -- arg list is empty? | ||
959 | args.k = "VVOID" | ||
960 | else | ||
961 | self:explist1(ls, args) | ||
962 | luaK:setmultret(fs, args) | ||
963 | end | ||
964 | self:check_match(ls, ")", "(", line) | ||
965 | elseif c == "{" then -- funcargs -> constructor | ||
966 | self:constructor(ls, args) | ||
967 | elseif c == "TK_STRING" then -- funcargs -> STRING | ||
968 | self:codestring(ls, args, ls.t.seminfo) | ||
969 | luaX:next(ls) -- must use 'seminfo' before 'next' | ||
970 | else | ||
971 | luaX:syntaxerror(ls, "function arguments expected") | ||
972 | return | ||
973 | end | ||
974 | lua_assert(f.k == "VNONRELOC") | ||
975 | local base = f.info -- base register for call | ||
976 | if self:hasmultret(args.k) then | ||
977 | nparams = self.LUA_MULTRET -- open call | ||
978 | else | ||
979 | if args.k ~= "VVOID" then | ||
980 | luaK:exp2nextreg(fs, args) -- close last argument | ||
981 | end | ||
982 | nparams = fs.freereg - (base + 1) | ||
983 | end | ||
984 | self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2)) | ||
985 | luaK:fixline(fs, line) | ||
986 | fs.freereg = base + 1 -- call remove function and arguments and leaves | ||
987 | -- (unless changed) one result | ||
988 | end | ||
989 | |||
990 | --[[-------------------------------------------------------------------- | ||
991 | -- Expression parsing | ||
992 | ----------------------------------------------------------------------]] | ||
993 | |||
994 | ------------------------------------------------------------------------ | ||
995 | -- parses an expression in parentheses or a single variable | ||
996 | -- * used in primaryexp() | ||
997 | ------------------------------------------------------------------------ | ||
998 | function luaY:prefixexp(ls, v) | ||
999 | -- prefixexp -> NAME | '(' expr ')' | ||
1000 | local c = ls.t.token | ||
1001 | if c == "(" then | ||
1002 | local line = ls.linenumber | ||
1003 | luaX:next(ls) | ||
1004 | self:expr(ls, v) | ||
1005 | self:check_match(ls, ")", "(", line) | ||
1006 | luaK:dischargevars(ls.fs, v) | ||
1007 | elseif c == "TK_NAME" then | ||
1008 | self:singlevar(ls, v) | ||
1009 | else | ||
1010 | luaX:syntaxerror(ls, "unexpected symbol") | ||
1011 | end--if c | ||
1012 | return | ||
1013 | end | ||
1014 | |||
1015 | ------------------------------------------------------------------------ | ||
1016 | -- parses a prefixexp (an expression in parentheses or a single variable) | ||
1017 | -- or a function call specification | ||
1018 | -- * used in simpleexp(), assignment(), exprstat() | ||
1019 | ------------------------------------------------------------------------ | ||
1020 | function luaY:primaryexp(ls, v) | ||
1021 | -- primaryexp -> | ||
1022 | -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } | ||
1023 | local fs = ls.fs | ||
1024 | self:prefixexp(ls, v) | ||
1025 | while true do | ||
1026 | local c = ls.t.token | ||
1027 | if c == "." then -- field | ||
1028 | self:field(ls, v) | ||
1029 | elseif c == "[" then -- '[' exp1 ']' | ||
1030 | local key = {} -- expdesc | ||
1031 | luaK:exp2anyreg(fs, v) | ||
1032 | self:yindex(ls, key) | ||
1033 | luaK:indexed(fs, v, key) | ||
1034 | elseif c == ":" then -- ':' NAME funcargs | ||
1035 | local key = {} -- expdesc | ||
1036 | luaX:next(ls) | ||
1037 | self:checkname(ls, key) | ||
1038 | luaK:_self(fs, v, key) | ||
1039 | self:funcargs(ls, v) | ||
1040 | elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs | ||
1041 | luaK:exp2nextreg(fs, v) | ||
1042 | self:funcargs(ls, v) | ||
1043 | else | ||
1044 | return | ||
1045 | end--if c | ||
1046 | end--while | ||
1047 | end | ||
1048 | |||
1049 | ------------------------------------------------------------------------ | ||
1050 | -- parses general expression types, constants handled here | ||
1051 | -- * used in subexpr() | ||
1052 | ------------------------------------------------------------------------ | ||
1053 | function luaY:simpleexp(ls, v) | ||
1054 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | | ||
1055 | -- constructor | FUNCTION body | primaryexp | ||
1056 | local c = ls.t.token | ||
1057 | if c == "TK_NUMBER" then | ||
1058 | self:init_exp(v, "VKNUM", 0) | ||
1059 | v.nval = ls.t.seminfo | ||
1060 | elseif c == "TK_STRING" then | ||
1061 | self:codestring(ls, v, ls.t.seminfo) | ||
1062 | elseif c == "TK_NIL" then | ||
1063 | self:init_exp(v, "VNIL", 0) | ||
1064 | elseif c == "TK_TRUE" then | ||
1065 | self:init_exp(v, "VTRUE", 0) | ||
1066 | elseif c == "TK_FALSE" then | ||
1067 | self:init_exp(v, "VFALSE", 0) | ||
1068 | elseif c == "TK_DOTS" then -- vararg | ||
1069 | local fs = ls.fs | ||
1070 | self:check_condition(ls, fs.f.is_vararg ~= 0, | ||
1071 | "cannot use "..self:LUA_QL("...").." outside a vararg function"); | ||
1072 | -- NOTE: the following substitutes for a bitop, but is value-specific | ||
1073 | local is_vararg = fs.f.is_vararg | ||
1074 | if is_vararg >= self.VARARG_NEEDSARG then | ||
1075 | fs.f.is_vararg = is_vararg - self.VARARG_NEEDSARG -- don't need 'arg' | ||
1076 | end | ||
1077 | self:init_exp(v, "VVARARG", luaK:codeABC(fs, "OP_VARARG", 0, 1, 0)) | ||
1078 | elseif c == "{" then -- constructor | ||
1079 | self:constructor(ls, v) | ||
1080 | return | ||
1081 | elseif c == "TK_FUNCTION" then | ||
1082 | luaX:next(ls) | ||
1083 | self:body(ls, v, false, ls.linenumber) | ||
1084 | return | ||
1085 | else | ||
1086 | self:primaryexp(ls, v) | ||
1087 | return | ||
1088 | end--if c | ||
1089 | luaX:next(ls) | ||
1090 | end | ||
1091 | |||
1092 | ------------------------------------------------------------------------ | ||
1093 | -- Translates unary operators tokens if found, otherwise returns | ||
1094 | -- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr(). | ||
1095 | -- * used in subexpr() | ||
1096 | ------------------------------------------------------------------------ | ||
1097 | function luaY:getunopr(op) | ||
1098 | if op == "TK_NOT" then | ||
1099 | return "OPR_NOT" | ||
1100 | elseif op == "-" then | ||
1101 | return "OPR_MINUS" | ||
1102 | elseif op == "#" then | ||
1103 | return "OPR_LEN" | ||
1104 | else | ||
1105 | return "OPR_NOUNOPR" | ||
1106 | end | ||
1107 | end | ||
1108 | |||
1109 | ------------------------------------------------------------------------ | ||
1110 | -- Translates binary operator tokens if found, otherwise returns | ||
1111 | -- OPR_NOBINOPR. Code generation uses OPR_* style tokens. | ||
1112 | -- * used in subexpr() | ||
1113 | ------------------------------------------------------------------------ | ||
1114 | luaY.getbinopr_table = { | ||
1115 | ["+"] = "OPR_ADD", | ||
1116 | ["-"] = "OPR_SUB", | ||
1117 | ["*"] = "OPR_MUL", | ||
1118 | ["/"] = "OPR_DIV", | ||
1119 | ["%"] = "OPR_MOD", | ||
1120 | ["^"] = "OPR_POW", | ||
1121 | ["TK_CONCAT"] = "OPR_CONCAT", | ||
1122 | ["TK_NE"] = "OPR_NE", | ||
1123 | ["TK_EQ"] = "OPR_EQ", | ||
1124 | ["<"] = "OPR_LT", | ||
1125 | ["TK_LE"] = "OPR_LE", | ||
1126 | [">"] = "OPR_GT", | ||
1127 | ["TK_GE"] = "OPR_GE", | ||
1128 | ["TK_AND"] = "OPR_AND", | ||
1129 | ["TK_OR"] = "OPR_OR", | ||
1130 | } | ||
1131 | function luaY:getbinopr(op) | ||
1132 | local opr = self.getbinopr_table[op] | ||
1133 | if opr then return opr else return "OPR_NOBINOPR" end | ||
1134 | end | ||
1135 | |||
1136 | ------------------------------------------------------------------------ | ||
1137 | -- the following priority table consists of pairs of left/right values | ||
1138 | -- for binary operators (was a static const struct); grep for ORDER OPR | ||
1139 | -- * the following struct is replaced: | ||
1140 | -- static const struct { | ||
1141 | -- lu_byte left; /* left priority for each binary operator */ | ||
1142 | -- lu_byte right; /* right priority */ | ||
1143 | -- } priority[] = { /* ORDER OPR */ | ||
1144 | ------------------------------------------------------------------------ | ||
1145 | luaY.priority = { | ||
1146 | {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, -- `+' `-' `/' `%' | ||
1147 | {10, 9}, {5, 4}, -- power and concat (right associative) | ||
1148 | {3, 3}, {3, 3}, -- equality | ||
1149 | {3, 3}, {3, 3}, {3, 3}, {3, 3}, -- order | ||
1150 | {2, 2}, {1, 1} -- logical (and/or) | ||
1151 | } | ||
1152 | |||
1153 | luaY.UNARY_PRIORITY = 8 -- priority for unary operators | ||
1154 | |||
1155 | ------------------------------------------------------------------------ | ||
1156 | -- Parse subexpressions. Includes handling of unary operators and binary | ||
1157 | -- operators. A subexpr is given the rhs priority level of the operator | ||
1158 | -- immediately left of it, if any (limit is -1 if none,) and if a binop | ||
1159 | -- is found, limit is compared with the lhs priority level of the binop | ||
1160 | -- in order to determine which executes first. | ||
1161 | ------------------------------------------------------------------------ | ||
1162 | |||
1163 | ------------------------------------------------------------------------ | ||
1164 | -- subexpr -> (simpleexp | unop subexpr) { binop subexpr } | ||
1165 | -- where 'binop' is any binary operator with a priority higher than 'limit' | ||
1166 | -- * for priority lookups with self.priority[], 1=left and 2=right | ||
1167 | -- * recursively called | ||
1168 | -- * used in expr() | ||
1169 | ------------------------------------------------------------------------ | ||
1170 | function luaY:subexpr(ls, v, limit) | ||
1171 | self:enterlevel(ls) | ||
1172 | local uop = self:getunopr(ls.t.token) | ||
1173 | if uop ~= "OPR_NOUNOPR" then | ||
1174 | luaX:next(ls) | ||
1175 | self:subexpr(ls, v, self.UNARY_PRIORITY) | ||
1176 | luaK:prefix(ls.fs, uop, v) | ||
1177 | else | ||
1178 | self:simpleexp(ls, v) | ||
1179 | end | ||
1180 | -- expand while operators have priorities higher than 'limit' | ||
1181 | local op = self:getbinopr(ls.t.token) | ||
1182 | while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do | ||
1183 | local v2 = {} -- expdesc | ||
1184 | luaX:next(ls) | ||
1185 | luaK:infix(ls.fs, op, v) | ||
1186 | -- read sub-expression with higher priority | ||
1187 | local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2]) | ||
1188 | luaK:posfix(ls.fs, op, v, v2) | ||
1189 | op = nextop | ||
1190 | end | ||
1191 | self:leavelevel(ls) | ||
1192 | return op -- return first untreated operator | ||
1193 | end | ||
1194 | |||
1195 | ------------------------------------------------------------------------ | ||
1196 | -- Expression parsing starts here. Function subexpr is entered with the | ||
1197 | -- left operator (which is non-existent) priority of -1, which is lower | ||
1198 | -- than all actual operators. Expr information is returned in parm v. | ||
1199 | -- * used in multiple locations | ||
1200 | ------------------------------------------------------------------------ | ||
1201 | function luaY:expr(ls, v) | ||
1202 | self:subexpr(ls, v, 0) | ||
1203 | end | ||
1204 | |||
1205 | -- }==================================================================== | ||
1206 | |||
1207 | --[[-------------------------------------------------------------------- | ||
1208 | -- Rules for Statements | ||
1209 | ----------------------------------------------------------------------]] | ||
1210 | |||
1211 | ------------------------------------------------------------------------ | ||
1212 | -- checks next token, used as a look-ahead | ||
1213 | -- * returns boolean instead of 0|1 | ||
1214 | -- * used in retstat(), chunk() | ||
1215 | ------------------------------------------------------------------------ | ||
1216 | function luaY:block_follow(token) | ||
1217 | if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END" | ||
1218 | or token == "TK_UNTIL" or token == "TK_EOS" then | ||
1219 | return true | ||
1220 | else | ||
1221 | return false | ||
1222 | end | ||
1223 | end | ||
1224 | |||
1225 | ------------------------------------------------------------------------ | ||
1226 | -- parse a code block or unit | ||
1227 | -- * used in multiple functions | ||
1228 | ------------------------------------------------------------------------ | ||
1229 | function luaY:block(ls) | ||
1230 | -- block -> chunk | ||
1231 | local fs = ls.fs | ||
1232 | local bl = {} -- BlockCnt | ||
1233 | self:enterblock(fs, bl, false) | ||
1234 | self:chunk(ls) | ||
1235 | lua_assert(bl.breaklist == luaK.NO_JUMP) | ||
1236 | self:leaveblock(fs) | ||
1237 | end | ||
1238 | |||
1239 | ------------------------------------------------------------------------ | ||
1240 | -- structure to chain all variables in the left-hand side of an | ||
1241 | -- assignment | ||
1242 | -- struct LHS_assign: | ||
1243 | -- prev -- (table: struct LHS_assign) | ||
1244 | -- v -- variable (global, local, upvalue, or indexed) (table: expdesc) | ||
1245 | ------------------------------------------------------------------------ | ||
1246 | |||
1247 | ------------------------------------------------------------------------ | ||
1248 | -- check whether, in an assignment to a local variable, the local variable | ||
1249 | -- is needed in a previous assignment (to a table). If so, save original | ||
1250 | -- local value in a safe place and use this safe copy in the previous | ||
1251 | -- assignment. | ||
1252 | -- * used in assignment() | ||
1253 | ------------------------------------------------------------------------ | ||
1254 | function luaY:check_conflict(ls, lh, v) | ||
1255 | local fs = ls.fs | ||
1256 | local extra = fs.freereg -- eventual position to save local variable | ||
1257 | local conflict = false | ||
1258 | while lh do | ||
1259 | if lh.v.k == "VINDEXED" then | ||
1260 | if lh.v.info == v.info then -- conflict? | ||
1261 | conflict = true | ||
1262 | lh.v.info = extra -- previous assignment will use safe copy | ||
1263 | end | ||
1264 | if lh.v.aux == v.info then -- conflict? | ||
1265 | conflict = true | ||
1266 | lh.v.aux = extra -- previous assignment will use safe copy | ||
1267 | end | ||
1268 | end | ||
1269 | lh = lh.prev | ||
1270 | end | ||
1271 | if conflict then | ||
1272 | luaK:codeABC(fs, "OP_MOVE", fs.freereg, v.info, 0) -- make copy | ||
1273 | luaK:reserveregs(fs, 1) | ||
1274 | end | ||
1275 | end | ||
1276 | |||
1277 | ------------------------------------------------------------------------ | ||
1278 | -- parse a variable assignment sequence | ||
1279 | -- * recursively called | ||
1280 | -- * used in exprstat() | ||
1281 | ------------------------------------------------------------------------ | ||
1282 | function luaY:assignment(ls, lh, nvars) | ||
1283 | local e = {} -- expdesc | ||
1284 | -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED | ||
1285 | local c = lh.v.k | ||
1286 | self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" | ||
1287 | or c == "VINDEXED", "syntax error") | ||
1288 | if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment | ||
1289 | local nv = {} -- LHS_assign | ||
1290 | nv.v = {} | ||
1291 | nv.prev = lh | ||
1292 | self:primaryexp(ls, nv.v) | ||
1293 | if nv.v.k == "VLOCAL" then | ||
1294 | self:check_conflict(ls, lh, nv.v) | ||
1295 | end | ||
1296 | self:checklimit(ls.fs, nvars, self.LUAI_MAXCCALLS - ls.L.nCcalls, | ||
1297 | "variables in assignment") | ||
1298 | self:assignment(ls, nv, nvars + 1) | ||
1299 | else -- assignment -> '=' explist1 | ||
1300 | self:checknext(ls, "=") | ||
1301 | local nexps = self:explist1(ls, e) | ||
1302 | if nexps ~= nvars then | ||
1303 | self:adjust_assign(ls, nvars, nexps, e) | ||
1304 | if nexps > nvars then | ||
1305 | ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values | ||
1306 | end | ||
1307 | else | ||
1308 | luaK:setoneret(ls.fs, e) -- close last expression | ||
1309 | luaK:storevar(ls.fs, lh.v, e) | ||
1310 | return -- avoid default | ||
1311 | end | ||
1312 | end | ||
1313 | self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment | ||
1314 | luaK:storevar(ls.fs, lh.v, e) | ||
1315 | end | ||
1316 | |||
1317 | ------------------------------------------------------------------------ | ||
1318 | -- parse condition in a repeat statement or an if control structure | ||
1319 | -- * used in repeatstat(), test_then_block() | ||
1320 | ------------------------------------------------------------------------ | ||
1321 | function luaY:cond(ls) | ||
1322 | -- cond -> exp | ||
1323 | local v = {} -- expdesc | ||
1324 | self:expr(ls, v) -- read condition | ||
1325 | if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here | ||
1326 | luaK:goiftrue(ls.fs, v) | ||
1327 | return v.f | ||
1328 | end | ||
1329 | |||
1330 | ------------------------------------------------------------------------ | ||
1331 | -- parse a break statement | ||
1332 | -- * used in statements() | ||
1333 | ------------------------------------------------------------------------ | ||
1334 | function luaY:breakstat(ls) | ||
1335 | -- stat -> BREAK | ||
1336 | local fs = ls.fs | ||
1337 | local bl = fs.bl | ||
1338 | local upval = false | ||
1339 | while bl and not bl.isbreakable do | ||
1340 | if bl.upval then upval = true end | ||
1341 | bl = bl.previous | ||
1342 | end | ||
1343 | if not bl then | ||
1344 | luaX:syntaxerror(ls, "no loop to break") | ||
1345 | end | ||
1346 | if upval then | ||
1347 | luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0) | ||
1348 | end | ||
1349 | bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs)) | ||
1350 | end | ||
1351 | |||
1352 | ------------------------------------------------------------------------ | ||
1353 | -- parse a while-do control structure, body processed by block() | ||
1354 | -- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by | ||
1355 | -- the function's implementation can be removed | ||
1356 | -- * used in statements() | ||
1357 | ------------------------------------------------------------------------ | ||
1358 | function luaY:whilestat(ls, line) | ||
1359 | -- whilestat -> WHILE cond DO block END | ||
1360 | local fs = ls.fs | ||
1361 | local bl = {} -- BlockCnt | ||
1362 | luaX:next(ls) -- skip WHILE | ||
1363 | local whileinit = luaK:getlabel(fs) | ||
1364 | local condexit = self:cond(ls) | ||
1365 | self:enterblock(fs, bl, true) | ||
1366 | self:checknext(ls, "TK_DO") | ||
1367 | self:block(ls) | ||
1368 | luaK:patchlist(fs, luaK:jump(fs), whileinit) | ||
1369 | self:check_match(ls, "TK_END", "TK_WHILE", line) | ||
1370 | self:leaveblock(fs) | ||
1371 | luaK:patchtohere(fs, condexit) -- false conditions finish the loop | ||
1372 | end | ||
1373 | |||
1374 | ------------------------------------------------------------------------ | ||
1375 | -- parse a repeat-until control structure, body parsed by chunk() | ||
1376 | -- * used in statements() | ||
1377 | ------------------------------------------------------------------------ | ||
1378 | function luaY:repeatstat(ls, line) | ||
1379 | -- repeatstat -> REPEAT block UNTIL cond | ||
1380 | local fs = ls.fs | ||
1381 | local repeat_init = luaK:getlabel(fs) | ||
1382 | local bl1, bl2 = {}, {} -- BlockCnt | ||
1383 | self:enterblock(fs, bl1, true) -- loop block | ||
1384 | self:enterblock(fs, bl2, false) -- scope block | ||
1385 | luaX:next(ls) -- skip REPEAT | ||
1386 | self:chunk(ls) | ||
1387 | self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line) | ||
1388 | local condexit = self:cond(ls) -- read condition (inside scope block) | ||
1389 | if not bl2.upval then -- no upvalues? | ||
1390 | self:leaveblock(fs) -- finish scope | ||
1391 | luaK:patchlist(ls.fs, condexit, repeat_init) -- close the loop | ||
1392 | else -- complete semantics when there are upvalues | ||
1393 | self:breakstat(ls) -- if condition then break | ||
1394 | luaK:patchtohere(ls.fs, condexit) -- else... | ||
1395 | self:leaveblock(fs) -- finish scope... | ||
1396 | luaK:patchlist(ls.fs, luaK:jump(fs), repeat_init) -- and repeat | ||
1397 | end | ||
1398 | self:leaveblock(fs) -- finish loop | ||
1399 | end | ||
1400 | |||
1401 | ------------------------------------------------------------------------ | ||
1402 | -- parse the single expressions needed in numerical for loops | ||
1403 | -- * used in fornum() | ||
1404 | ------------------------------------------------------------------------ | ||
1405 | function luaY:exp1(ls) | ||
1406 | local e = {} -- expdesc | ||
1407 | self:expr(ls, e) | ||
1408 | local k = e.k | ||
1409 | luaK:exp2nextreg(ls.fs, e) | ||
1410 | return k | ||
1411 | end | ||
1412 | |||
1413 | ------------------------------------------------------------------------ | ||
1414 | -- parse a for loop body for both versions of the for loop | ||
1415 | -- * used in fornum(), forlist() | ||
1416 | ------------------------------------------------------------------------ | ||
1417 | function luaY:forbody(ls, base, line, nvars, isnum) | ||
1418 | -- forbody -> DO block | ||
1419 | local bl = {} -- BlockCnt | ||
1420 | local fs = ls.fs | ||
1421 | self:adjustlocalvars(ls, 3) -- control variables | ||
1422 | self:checknext(ls, "TK_DO") | ||
1423 | local prep = isnum and luaK:codeAsBx(fs, "OP_FORPREP", base, luaK.NO_JUMP) | ||
1424 | or luaK:jump(fs) | ||
1425 | self:enterblock(fs, bl, false) -- scope for declared variables | ||
1426 | self:adjustlocalvars(ls, nvars) | ||
1427 | luaK:reserveregs(fs, nvars) | ||
1428 | self:block(ls) | ||
1429 | self:leaveblock(fs) -- end of scope for declared variables | ||
1430 | luaK:patchtohere(fs, prep) | ||
1431 | local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP) | ||
1432 | or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars) | ||
1433 | luaK:fixline(fs, line) -- pretend that `OP_FOR' starts the loop | ||
1434 | luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep + 1) | ||
1435 | end | ||
1436 | |||
1437 | ------------------------------------------------------------------------ | ||
1438 | -- parse a numerical for loop, calls forbody() | ||
1439 | -- * used in forstat() | ||
1440 | ------------------------------------------------------------------------ | ||
1441 | function luaY:fornum(ls, varname, line) | ||
1442 | -- fornum -> NAME = exp1,exp1[,exp1] forbody | ||
1443 | local fs = ls.fs | ||
1444 | local base = fs.freereg | ||
1445 | self:new_localvarliteral(ls, "(for index)", 0) | ||
1446 | self:new_localvarliteral(ls, "(for limit)", 1) | ||
1447 | self:new_localvarliteral(ls, "(for step)", 2) | ||
1448 | self:new_localvar(ls, varname, 3) | ||
1449 | self:checknext(ls, '=') | ||
1450 | self:exp1(ls) -- initial value | ||
1451 | self:checknext(ls, ",") | ||
1452 | self:exp1(ls) -- limit | ||
1453 | if self:testnext(ls, ",") then | ||
1454 | self:exp1(ls) -- optional step | ||
1455 | else -- default step = 1 | ||
1456 | luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1)) | ||
1457 | luaK:reserveregs(fs, 1) | ||
1458 | end | ||
1459 | self:forbody(ls, base, line, 1, true) | ||
1460 | end | ||
1461 | |||
1462 | ------------------------------------------------------------------------ | ||
1463 | -- parse a generic for loop, calls forbody() | ||
1464 | -- * used in forstat() | ||
1465 | ------------------------------------------------------------------------ | ||
1466 | function luaY:forlist(ls, indexname) | ||
1467 | -- forlist -> NAME {,NAME} IN explist1 forbody | ||
1468 | local fs = ls.fs | ||
1469 | local e = {} -- expdesc | ||
1470 | local nvars = 0 | ||
1471 | local base = fs.freereg | ||
1472 | -- create control variables | ||
1473 | self:new_localvarliteral(ls, "(for generator)", nvars) | ||
1474 | nvars = nvars + 1 | ||
1475 | self:new_localvarliteral(ls, "(for state)", nvars) | ||
1476 | nvars = nvars + 1 | ||
1477 | self:new_localvarliteral(ls, "(for control)", nvars) | ||
1478 | nvars = nvars + 1 | ||
1479 | -- create declared variables | ||
1480 | self:new_localvar(ls, indexname, nvars) | ||
1481 | nvars = nvars + 1 | ||
1482 | while self:testnext(ls, ",") do | ||
1483 | self:new_localvar(ls, self:str_checkname(ls), nvars) | ||
1484 | nvars = nvars + 1 | ||
1485 | end | ||
1486 | self:checknext(ls, "TK_IN") | ||
1487 | local line = ls.linenumber | ||
1488 | self:adjust_assign(ls, 3, self:explist1(ls, e), e) | ||
1489 | luaK:checkstack(fs, 3) -- extra space to call generator | ||
1490 | self:forbody(ls, base, line, nvars - 3, false) | ||
1491 | end | ||
1492 | |||
1493 | ------------------------------------------------------------------------ | ||
1494 | -- initial parsing for a for loop, calls fornum() or forlist() | ||
1495 | -- * used in statements() | ||
1496 | ------------------------------------------------------------------------ | ||
1497 | function luaY:forstat(ls, line) | ||
1498 | -- forstat -> FOR (fornum | forlist) END | ||
1499 | local fs = ls.fs | ||
1500 | local bl = {} -- BlockCnt | ||
1501 | self:enterblock(fs, bl, true) -- scope for loop and control variables | ||
1502 | luaX:next(ls) -- skip `for' | ||
1503 | local varname = self:str_checkname(ls) -- first variable name | ||
1504 | local c = ls.t.token | ||
1505 | if c == "=" then | ||
1506 | self:fornum(ls, varname, line) | ||
1507 | elseif c == "," or c == "TK_IN" then | ||
1508 | self:forlist(ls, varname) | ||
1509 | else | ||
1510 | luaX:syntaxerror(ls, self:LUA_QL("=").." or "..self:LUA_QL("in").." expected") | ||
1511 | end | ||
1512 | self:check_match(ls, "TK_END", "TK_FOR", line) | ||
1513 | self:leaveblock(fs) -- loop scope (`break' jumps to this point) | ||
1514 | end | ||
1515 | |||
1516 | ------------------------------------------------------------------------ | ||
1517 | -- parse part of an if control structure, including the condition | ||
1518 | -- * used in ifstat() | ||
1519 | ------------------------------------------------------------------------ | ||
1520 | function luaY:test_then_block(ls) | ||
1521 | -- test_then_block -> [IF | ELSEIF] cond THEN block | ||
1522 | luaX:next(ls) -- skip IF or ELSEIF | ||
1523 | local condexit = self:cond(ls) | ||
1524 | self:checknext(ls, "TK_THEN") | ||
1525 | self:block(ls) -- `then' part | ||
1526 | return condexit | ||
1527 | end | ||
1528 | |||
1529 | ------------------------------------------------------------------------ | ||
1530 | -- parse an if control structure | ||
1531 | -- * used in statements() | ||
1532 | ------------------------------------------------------------------------ | ||
1533 | function luaY:ifstat(ls, line) | ||
1534 | -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END | ||
1535 | local fs = ls.fs | ||
1536 | local escapelist = luaK.NO_JUMP | ||
1537 | local flist = self:test_then_block(ls) -- IF cond THEN block | ||
1538 | while ls.t.token == "TK_ELSEIF" do | ||
1539 | escapelist = luaK:concat(fs, escapelist, luaK:jump(fs)) | ||
1540 | luaK:patchtohere(fs, flist) | ||
1541 | flist = self:test_then_block(ls) -- ELSEIF cond THEN block | ||
1542 | end | ||
1543 | if ls.t.token == "TK_ELSE" then | ||
1544 | escapelist = luaK:concat(fs, escapelist, luaK:jump(fs)) | ||
1545 | luaK:patchtohere(fs, flist) | ||
1546 | luaX:next(ls) -- skip ELSE (after patch, for correct line info) | ||
1547 | self:block(ls) -- 'else' part | ||
1548 | else | ||
1549 | escapelist = luaK:concat(fs, escapelist, flist) | ||
1550 | end | ||
1551 | luaK:patchtohere(fs, escapelist) | ||
1552 | self:check_match(ls, "TK_END", "TK_IF", line) | ||
1553 | end | ||
1554 | |||
1555 | ------------------------------------------------------------------------ | ||
1556 | -- parse a local function statement | ||
1557 | -- * used in statements() | ||
1558 | ------------------------------------------------------------------------ | ||
1559 | function luaY:localfunc(ls) | ||
1560 | local v, b = {}, {} -- expdesc | ||
1561 | local fs = ls.fs | ||
1562 | self:new_localvar(ls, self:str_checkname(ls), 0) | ||
1563 | self:init_exp(v, "VLOCAL", fs.freereg) | ||
1564 | luaK:reserveregs(fs, 1) | ||
1565 | self:adjustlocalvars(ls, 1) | ||
1566 | self:body(ls, b, false, ls.linenumber) | ||
1567 | luaK:storevar(fs, v, b) | ||
1568 | -- debug information will only see the variable after this point! | ||
1569 | self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc | ||
1570 | end | ||
1571 | |||
1572 | ------------------------------------------------------------------------ | ||
1573 | -- parse a local variable declaration statement | ||
1574 | -- * used in statements() | ||
1575 | ------------------------------------------------------------------------ | ||
1576 | function luaY:localstat(ls) | ||
1577 | -- stat -> LOCAL NAME {',' NAME} ['=' explist1] | ||
1578 | local nvars = 0 | ||
1579 | local nexps | ||
1580 | local e = {} -- expdesc | ||
1581 | repeat | ||
1582 | self:new_localvar(ls, self:str_checkname(ls), nvars) | ||
1583 | nvars = nvars + 1 | ||
1584 | until not self:testnext(ls, ",") | ||
1585 | if self:testnext(ls, "=") then | ||
1586 | nexps = self:explist1(ls, e) | ||
1587 | else | ||
1588 | e.k = "VVOID" | ||
1589 | nexps = 0 | ||
1590 | end | ||
1591 | self:adjust_assign(ls, nvars, nexps, e) | ||
1592 | self:adjustlocalvars(ls, nvars) | ||
1593 | end | ||
1594 | |||
1595 | ------------------------------------------------------------------------ | ||
1596 | -- parse a function name specification | ||
1597 | -- * used in funcstat() | ||
1598 | ------------------------------------------------------------------------ | ||
1599 | function luaY:funcname(ls, v) | ||
1600 | -- funcname -> NAME {field} [':' NAME] | ||
1601 | local needself = false | ||
1602 | self:singlevar(ls, v) | ||
1603 | while ls.t.token == "." do | ||
1604 | self:field(ls, v) | ||
1605 | end | ||
1606 | if ls.t.token == ":" then | ||
1607 | needself = true | ||
1608 | self:field(ls, v) | ||
1609 | end | ||
1610 | return needself | ||
1611 | end | ||
1612 | |||
1613 | ------------------------------------------------------------------------ | ||
1614 | -- parse a function statement | ||
1615 | -- * used in statements() | ||
1616 | ------------------------------------------------------------------------ | ||
1617 | function luaY:funcstat(ls, line) | ||
1618 | -- funcstat -> FUNCTION funcname body | ||
1619 | local v, b = {}, {} -- expdesc | ||
1620 | luaX:next(ls) -- skip FUNCTION | ||
1621 | local needself = self:funcname(ls, v) | ||
1622 | self:body(ls, b, needself, line) | ||
1623 | luaK:storevar(ls.fs, v, b) | ||
1624 | luaK:fixline(ls.fs, line) -- definition 'happens' in the first line | ||
1625 | end | ||
1626 | |||
1627 | ------------------------------------------------------------------------ | ||
1628 | -- parse a function call with no returns or an assignment statement | ||
1629 | -- * used in statements() | ||
1630 | ------------------------------------------------------------------------ | ||
1631 | function luaY:exprstat(ls) | ||
1632 | -- stat -> func | assignment | ||
1633 | local fs = ls.fs | ||
1634 | local v = {} -- LHS_assign | ||
1635 | v.v = {} | ||
1636 | self:primaryexp(ls, v.v) | ||
1637 | if v.v.k == "VCALL" then -- stat -> func | ||
1638 | luaP:SETARG_C(luaK:getcode(fs, v.v), 1) -- call statement uses no results | ||
1639 | else -- stat -> assignment | ||
1640 | v.prev = nil | ||
1641 | self:assignment(ls, v, 1) | ||
1642 | end | ||
1643 | end | ||
1644 | |||
1645 | ------------------------------------------------------------------------ | ||
1646 | -- parse a return statement | ||
1647 | -- * used in statements() | ||
1648 | ------------------------------------------------------------------------ | ||
1649 | function luaY:retstat(ls) | ||
1650 | -- stat -> RETURN explist | ||
1651 | local fs = ls.fs | ||
1652 | local e = {} -- expdesc | ||
1653 | local first, nret -- registers with returned values | ||
1654 | luaX:next(ls) -- skip RETURN | ||
1655 | if self:block_follow(ls.t.token) or ls.t.token == ";" then | ||
1656 | first, nret = 0, 0 -- return no values | ||
1657 | else | ||
1658 | nret = self:explist1(ls, e) -- optional return values | ||
1659 | if self:hasmultret(e.k) then | ||
1660 | luaK:setmultret(fs, e) | ||
1661 | if e.k == "VCALL" and nret == 1 then -- tail call? | ||
1662 | luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL") | ||
1663 | lua_assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar) | ||
1664 | end | ||
1665 | first = fs.nactvar | ||
1666 | nret = self.LUA_MULTRET -- return all values | ||
1667 | else | ||
1668 | if nret == 1 then -- only one single value? | ||
1669 | first = luaK:exp2anyreg(fs, e) | ||
1670 | else | ||
1671 | luaK:exp2nextreg(fs, e) -- values must go to the 'stack' | ||
1672 | first = fs.nactvar -- return all 'active' values | ||
1673 | lua_assert(nret == fs.freereg - first) | ||
1674 | end | ||
1675 | end--if | ||
1676 | end--if | ||
1677 | luaK:ret(fs, first, nret) | ||
1678 | end | ||
1679 | |||
1680 | ------------------------------------------------------------------------ | ||
1681 | -- initial parsing for statements, calls a lot of functions | ||
1682 | -- * returns boolean instead of 0|1 | ||
1683 | -- * used in chunk() | ||
1684 | ------------------------------------------------------------------------ | ||
1685 | function luaY:statement(ls) | ||
1686 | local line = ls.linenumber -- may be needed for error messages | ||
1687 | local c = ls.t.token | ||
1688 | if c == "TK_IF" then -- stat -> ifstat | ||
1689 | self:ifstat(ls, line) | ||
1690 | return false | ||
1691 | elseif c == "TK_WHILE" then -- stat -> whilestat | ||
1692 | self:whilestat(ls, line) | ||
1693 | return false | ||
1694 | elseif c == "TK_DO" then -- stat -> DO block END | ||
1695 | luaX:next(ls) -- skip DO | ||
1696 | self:block(ls) | ||
1697 | self:check_match(ls, "TK_END", "TK_DO", line) | ||
1698 | return false | ||
1699 | elseif c == "TK_FOR" then -- stat -> forstat | ||
1700 | self:forstat(ls, line) | ||
1701 | return false | ||
1702 | elseif c == "TK_REPEAT" then -- stat -> repeatstat | ||
1703 | self:repeatstat(ls, line) | ||
1704 | return false | ||
1705 | elseif c == "TK_FUNCTION" then -- stat -> funcstat | ||
1706 | self:funcstat(ls, line) | ||
1707 | return false | ||
1708 | elseif c == "TK_LOCAL" then -- stat -> localstat | ||
1709 | luaX:next(ls) -- skip LOCAL | ||
1710 | if self:testnext(ls, "TK_FUNCTION") then -- local function? | ||
1711 | self:localfunc(ls) | ||
1712 | else | ||
1713 | self:localstat(ls) | ||
1714 | end | ||
1715 | return false | ||
1716 | elseif c == "TK_RETURN" then -- stat -> retstat | ||
1717 | self:retstat(ls) | ||
1718 | return true -- must be last statement | ||
1719 | elseif c == "TK_BREAK" then -- stat -> breakstat | ||
1720 | luaX:next(ls) -- skip BREAK | ||
1721 | self:breakstat(ls) | ||
1722 | return true -- must be last statement | ||
1723 | else | ||
1724 | self:exprstat(ls) | ||
1725 | return false -- to avoid warnings | ||
1726 | end--if c | ||
1727 | end | ||
1728 | |||
1729 | ------------------------------------------------------------------------ | ||
1730 | -- parse a chunk, which consists of a bunch of statements | ||
1731 | -- * used in parser(), body(), block(), repeatstat() | ||
1732 | ------------------------------------------------------------------------ | ||
1733 | function luaY:chunk(ls) | ||
1734 | -- chunk -> { stat [';'] } | ||
1735 | local islast = false | ||
1736 | self:enterlevel(ls) | ||
1737 | while not islast and not self:block_follow(ls.t.token) do | ||
1738 | islast = self:statement(ls) | ||
1739 | self:testnext(ls, ";") | ||
1740 | lua_assert(ls.fs.f.maxstacksize >= ls.fs.freereg and | ||
1741 | ls.fs.freereg >= ls.fs.nactvar) | ||
1742 | ls.fs.freereg = ls.fs.nactvar -- free registers | ||
1743 | end | ||
1744 | self:leavelevel(ls) | ||
1745 | end | ||
1746 | |||
1747 | -- }====================================================================== | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | luac.lua | ||
4 | Primitive luac in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * based on luac.lua in the test directory of the 5.1.2 distribution | ||
18 | -- * usage: lua luac.lua file.lua | ||
19 | ----------------------------------------------------------------------]] | ||
20 | |||
21 | ------------------------------------------------------------------------ | ||
22 | -- load and initialize the required modules | ||
23 | ------------------------------------------------------------------------ | ||
24 | dofile("lzio.lua") | ||
25 | dofile("llex.lua") | ||
26 | dofile("lopcodes.lua") | ||
27 | dofile("ldump.lua") | ||
28 | dofile("lcode.lua") | ||
29 | dofile("lparser.lua") | ||
30 | |||
31 | luaX:init() -- required by llex | ||
32 | local LuaState = {} -- dummy, not actually used, but retained since | ||
33 | -- the intention is to complete a straight port | ||
34 | |||
35 | ------------------------------------------------------------------------ | ||
36 | -- interfacing to yueliang | ||
37 | ------------------------------------------------------------------------ | ||
38 | |||
39 | -- currently asserts are enabled because the codebase hasn't been tested | ||
40 | -- much (if you don't want asserts, just comment them out) | ||
41 | function lua_assert(test) | ||
42 | if not test then error("assertion failed!") end | ||
43 | end | ||
44 | |||
45 | function yloadfile(filename) | ||
46 | -- luaZ:make_getF returns a file chunk reader | ||
47 | -- luaZ:init returns a zio input stream | ||
48 | local zio = luaZ:init(luaZ:make_getF(filename), nil) | ||
49 | if not zio then return end | ||
50 | -- luaY:parser parses the input stream | ||
51 | -- func is the function prototype in tabular form; in C, func can | ||
52 | -- now be used directly by the VM, this can't be done in Lua | ||
53 | local func = luaY:parser(LuaState, zio, nil, "@"..filename) | ||
54 | -- luaU:make_setS returns a string chunk writer | ||
55 | local writer, buff = luaU:make_setS() | ||
56 | -- luaU:dump builds a binary chunk | ||
57 | luaU:dump(LuaState, func, writer, buff) | ||
58 | -- a string.dump equivalent in returned | ||
59 | return buff.data | ||
60 | end | ||
61 | |||
62 | ------------------------------------------------------------------------ | ||
63 | -- command line interface | ||
64 | ------------------------------------------------------------------------ | ||
65 | |||
66 | assert(arg[1] ~= nil and arg[2] == nil, "usage: lua luac.lua file.lua") | ||
67 | local f = assert(io.open("luac.out","wb")) | ||
68 | assert(f:write(assert(yloadfile(arg[1])))) | ||
69 | assert(io.close(f)) | ||
70 | |||
71 | --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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | lzio.lua | ||
4 | Lua buffered streams in Lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * EOZ is implemented as a string, "EOZ" | ||
18 | -- * Format of z structure (ZIO) | ||
19 | -- z.n -- bytes still unread | ||
20 | -- z.p -- last read position position in buffer | ||
21 | -- z.reader -- chunk reader function | ||
22 | -- z.data -- additional data | ||
23 | -- * Current position, p, is now last read index instead of a pointer | ||
24 | -- | ||
25 | -- Not implemented: | ||
26 | -- * luaZ_lookahead: used only in lapi.c:lua_load to detect binary chunk | ||
27 | -- * luaZ_read: used only in lundump.c:ezread to read +1 bytes | ||
28 | -- * luaZ_openspace: dropped; let Lua handle buffers as strings (used in | ||
29 | -- lundump.c:LoadString & lvm.c:luaV_concat) | ||
30 | -- * luaZ buffer macros: dropped; buffers are handled as strings | ||
31 | -- * lauxlib.c:getF reader implementation has an extraline flag to | ||
32 | -- skip over a shbang (#!) line, this is not implemented here | ||
33 | -- | ||
34 | -- Added: | ||
35 | -- (both of the following are vaguely adapted from lauxlib.c) | ||
36 | -- * luaZ:make_getS: create Reader from a string | ||
37 | -- * luaZ:make_getF: create Reader that reads from a file | ||
38 | -- | ||
39 | -- Changed in 5.1.x: | ||
40 | -- * Chunkreader renamed to Reader (ditto with Chunkwriter) | ||
41 | -- * Zio struct: no more name string, added Lua state for reader | ||
42 | -- (however, Yueliang readers do not require a Lua state) | ||
43 | ----------------------------------------------------------------------]] | ||
44 | |||
45 | luaZ = {} | ||
46 | |||
47 | ------------------------------------------------------------------------ | ||
48 | -- * reader() should return a string, or nil if nothing else to parse. | ||
49 | -- Additional data can be set only during stream initialization | ||
50 | -- * Readers are handled in lauxlib.c, see luaL_load(file|buffer|string) | ||
51 | -- * LUAL_BUFFERSIZE=BUFSIZ=512 in make_getF() (located in luaconf.h) | ||
52 | -- * Original Reader typedef: | ||
53 | -- const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); | ||
54 | -- * This Lua chunk reader implementation: | ||
55 | -- returns string or nil, no arguments to function | ||
56 | ------------------------------------------------------------------------ | ||
57 | |||
58 | ------------------------------------------------------------------------ | ||
59 | -- create a chunk reader from a source string | ||
60 | ------------------------------------------------------------------------ | ||
61 | function luaZ:make_getS(buff) | ||
62 | local b = buff | ||
63 | return function() -- chunk reader anonymous function here | ||
64 | if not b then return nil end | ||
65 | local data = b | ||
66 | b = nil | ||
67 | return data | ||
68 | end | ||
69 | end | ||
70 | |||
71 | ------------------------------------------------------------------------ | ||
72 | -- create a chunk reader from a source file | ||
73 | ------------------------------------------------------------------------ | ||
74 | function luaZ:make_getF(filename) | ||
75 | local LUAL_BUFFERSIZE = 512 | ||
76 | local h = io.open(filename, "r") | ||
77 | if not h then return nil end | ||
78 | return function() -- chunk reader anonymous function here | ||
79 | if not h or io.type(h) == "closed file" then return nil end | ||
80 | local buff = h:read(LUAL_BUFFERSIZE) | ||
81 | if not buff then h:close(); h = nil end | ||
82 | return buff | ||
83 | end | ||
84 | end | ||
85 | |||
86 | ------------------------------------------------------------------------ | ||
87 | -- creates a zio input stream | ||
88 | -- returns the ZIO structure, z | ||
89 | ------------------------------------------------------------------------ | ||
90 | function luaZ:init(reader, data) | ||
91 | if not reader then return end | ||
92 | local z = {} | ||
93 | z.reader = reader | ||
94 | z.data = data or "" | ||
95 | z.name = name | ||
96 | -- set up additional data for reading | ||
97 | if not data or data == "" then z.n = 0 else z.n = #data end | ||
98 | z.p = 0 | ||
99 | return z | ||
100 | end | ||
101 | |||
102 | ------------------------------------------------------------------------ | ||
103 | -- fill up input buffer | ||
104 | ------------------------------------------------------------------------ | ||
105 | function luaZ:fill(z) | ||
106 | local buff = z.reader() | ||
107 | z.data = buff | ||
108 | if not buff or buff == "" then return "EOZ" end | ||
109 | z.n, z.p = #buff - 1, 1 | ||
110 | return string.sub(buff, 1, 1) | ||
111 | end | ||
112 | |||
113 | ------------------------------------------------------------------------ | ||
114 | -- get next character from the input stream | ||
115 | -- * local n, p are used to optimize code generation | ||
116 | ------------------------------------------------------------------------ | ||
117 | function luaZ:zgetc(z) | ||
118 | local n, p = z.n, z.p + 1 | ||
119 | if n > 0 then | ||
120 | z.n, z.p = n - 1, p | ||
121 | return string.sub(z.data, p, p) | ||
122 | else | ||
123 | return self:fill(z) | ||
124 | end | ||
125 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | bench_llex.lua | ||
4 | Benchmark test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | dofile("../lzio.lua") | ||
16 | dofile("../llex.lua") | ||
17 | luaX:init() | ||
18 | |||
19 | ------------------------------------------------------------------------ | ||
20 | -- load in a standard set of sample files | ||
21 | -- * file set is 5.0.3 front end set sans luac.lua | ||
22 | ------------------------------------------------------------------------ | ||
23 | |||
24 | local fileset, totalsize = {}, 0 | ||
25 | for fn in string.gmatch([[ | ||
26 | ../../orig-5.0.3/lcode.lua | ||
27 | ../../orig-5.0.3/ldump.lua | ||
28 | ../../orig-5.0.3/llex.lua | ||
29 | ../../orig-5.0.3/lopcodes.lua | ||
30 | ../../orig-5.0.3/lparser.lua | ||
31 | ../../orig-5.0.3/lzio.lua | ||
32 | ]], "%S+") do | ||
33 | fileset[#fileset+1] = fn | ||
34 | end | ||
35 | |||
36 | for i = 1, #fileset do | ||
37 | local fn = fileset[i] | ||
38 | local inf = io.open(fn, "rb") | ||
39 | if not inf then | ||
40 | error("failed to open "..fn.." for reading") | ||
41 | end | ||
42 | local data = inf:read("*a") | ||
43 | local data_sz = #data | ||
44 | inf:close() | ||
45 | if not data or data_sz == 0 then | ||
46 | error("failed to read data from "..fn.." or file is zero-length") | ||
47 | end | ||
48 | totalsize = totalsize + data_sz | ||
49 | fileset[i] = data | ||
50 | end | ||
51 | |||
52 | ------------------------------------------------------------------------ | ||
53 | -- benchmark tester | ||
54 | ------------------------------------------------------------------------ | ||
55 | |||
56 | local DURATION = 5 -- how long the benchmark should run | ||
57 | |||
58 | local L = {} -- LuaState | ||
59 | local LS = {} -- LexState | ||
60 | |||
61 | local time = os.time | ||
62 | local lexedsize = 0 | ||
63 | local tnow, elapsed = time(), 0 | ||
64 | |||
65 | while time() == tnow do end -- wait for second to click over | ||
66 | tnow = time() | ||
67 | |||
68 | while true do | ||
69 | for i = 1, #fileset do | ||
70 | ------------------------------------------------------------ | ||
71 | local chunk = fileset[i] | ||
72 | local z = luaZ:init(luaZ:make_getS(chunk), nil) | ||
73 | luaX:setinput(L, LS, z, "=string") | ||
74 | while true do | ||
75 | LS.t.token = luaX:llex(LS, LS.t) | ||
76 | local tok, seminfo = LS.t.token, LS.t.seminfo | ||
77 | if tok == "TK_EOS" then break end | ||
78 | end | ||
79 | ------------------------------------------------------------ | ||
80 | lexedsize = lexedsize + #chunk | ||
81 | if time() > tnow then | ||
82 | tnow = time() | ||
83 | elapsed = elapsed + 1 | ||
84 | if elapsed >= DURATION then | ||
85 | -- report performance of lexer | ||
86 | lexedsize = lexedsize / 1024 | ||
87 | local speed = lexedsize / DURATION | ||
88 | print("Lexer performance:") | ||
89 | print("Size of data lexed (KB): "..string.format("%.1f", lexedsize)) | ||
90 | print("Speed of lexer (KB/s): "..string.format("%.1f", speed)) | ||
91 | -- repeat until user breaks program | ||
92 | elapsed = 0 | ||
93 | end | ||
94 | end | ||
95 | ------------------------------------------------------------ | ||
96 | end--for | ||
97 | end--while | ||
98 | |||
99 | -- 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 @@ | |||
1 | local a = 47 | ||
2 | local b = "hello, world!" | ||
3 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_ldump.lua | ||
4 | Test for ldump.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- test dump chunkwriter style | ||
17 | ------------------------------------------------------------------------ | ||
18 | |||
19 | dofile("../lopcodes.lua") | ||
20 | dofile("../ldump.lua") | ||
21 | |||
22 | -- Original typedef: | ||
23 | --int (*lua_Chunkwriter) (lua_State *L, const void* p, size_t sz, void* ud); | ||
24 | |||
25 | local MyWriter, MyBuff = luaU:make_setS() | ||
26 | if not MyWriter then | ||
27 | error("failed to initialize using make_setS") | ||
28 | end | ||
29 | MyWriter("hello, ", MyBuff) | ||
30 | MyWriter("world!", MyBuff) | ||
31 | print(MyBuff.data) | ||
32 | |||
33 | local MyWriter, MyBuff = luaU:make_setF("try.txt") | ||
34 | if not MyWriter then | ||
35 | error("failed to initialize using make_setF") | ||
36 | end | ||
37 | MyWriter("hello, ", MyBuff) | ||
38 | MyWriter("world!", MyBuff) | ||
39 | MyWriter(nil, MyBuff) | ||
40 | |||
41 | ------------------------------------------------------------------------ | ||
42 | -- test output of a function prototype | ||
43 | -- * data can be copied from a ChunkSpy listing output | ||
44 | ------------------------------------------------------------------------ | ||
45 | -- local a = 47 | ||
46 | -- local b = "hello, world!" | ||
47 | -- print(a, b) | ||
48 | ------------------------------------------------------------------------ | ||
49 | |||
50 | local F = {} | ||
51 | F.source = "sample.lua" | ||
52 | F.lineDefined = 0 | ||
53 | F.lastlinedefined = 0 | ||
54 | F.nups = 0 | ||
55 | F.numparams = 0 | ||
56 | F.is_vararg = 2 | ||
57 | F.maxstacksize = 5 | ||
58 | F.sizecode = 7 | ||
59 | F.code = {} | ||
60 | F.code[0] = { OP = 1, A = 0, Bx = 0 } | ||
61 | F.code[1] = { OP = 1, A = 1, Bx = 1 } | ||
62 | F.code[2] = { OP = 5, A = 2, Bx = 2 } | ||
63 | F.code[3] = { OP = 0, A = 3, B = 0, C = 0 } | ||
64 | F.code[4] = { OP = 0, A = 4, B = 1, C = 0 } | ||
65 | F.code[5] = { OP = 28, A = 2, B = 3, C = 1 } | ||
66 | F.code[6] = { OP = 30, A = 0, B = 1, C = 0 } | ||
67 | F.sizek = 3 | ||
68 | F.k = {} | ||
69 | F.k[0] = { value = 47 } | ||
70 | F.k[1] = { value = "hello, world!" } | ||
71 | F.k[2] = { value = "print" } | ||
72 | F.sizep = 0 | ||
73 | F.p = {} | ||
74 | F.sizelineinfo = 7 | ||
75 | F.lineinfo = {} | ||
76 | F.lineinfo[0] = 1 | ||
77 | F.lineinfo[1] = 2 | ||
78 | F.lineinfo[2] = 3 | ||
79 | F.lineinfo[3] = 3 | ||
80 | F.lineinfo[4] = 3 | ||
81 | F.lineinfo[5] = 3 | ||
82 | F.lineinfo[6] = 3 | ||
83 | F.sizelocvars = 2 | ||
84 | F.locvars = {} | ||
85 | F.locvars[0] = { varname = "a", startpc = 1, endpc = 6 } | ||
86 | F.locvars[1] = { varname = "b", startpc = 2, endpc = 6 } | ||
87 | F.sizeupvalues = 0 | ||
88 | F.upvalues = {} | ||
89 | |||
90 | local L = {} | ||
91 | --[[ | ||
92 | local Writer, Buff = luaU:make_setS() | ||
93 | luaU:dump(L, F, Writer, Buff) | ||
94 | for i = 1, string.len(Buff.data) do | ||
95 | io.stdout:write(string.byte(string.sub(Buff.data, i, i)).." ") | ||
96 | end | ||
97 | --]] | ||
98 | local Writer, Buff = luaU:make_setF("try.out") | ||
99 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_llex.lua | ||
4 | Test for llex.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- if BRIEF is not set to false, auto-test will silently succeed | ||
17 | ------------------------------------------------------------------------ | ||
18 | BRIEF = true -- if set to true, messages are less verbose | ||
19 | |||
20 | dofile("../lzio.lua") | ||
21 | dofile("../llex.lua") | ||
22 | luaX:init() | ||
23 | |||
24 | ------------------------------------------------------------------------ | ||
25 | -- simple manual tests | ||
26 | ------------------------------------------------------------------------ | ||
27 | |||
28 | --[[ | ||
29 | local L = {} -- LuaState | ||
30 | local LS = {} -- LexState | ||
31 | |||
32 | local function dump(z) | ||
33 | luaX:setinput(L, LS, z, z.name) | ||
34 | while true do | ||
35 | LS.t.token = luaX:lex(LS, LS.t) | ||
36 | local tok, seminfo = LS.t.token, LS.t.seminfo | ||
37 | if tok == "TK_NAME" then | ||
38 | seminfo = " "..seminfo | ||
39 | elseif tok == "TK_NUMBER" then | ||
40 | seminfo = " "..seminfo | ||
41 | elseif tok == "TK_STRING" then | ||
42 | seminfo = " '"..seminfo.."'" | ||
43 | else | ||
44 | seminfo = "" | ||
45 | end | ||
46 | io.stdout:write(tok..seminfo.."\n") | ||
47 | if tok == "TK_EOS" then break end | ||
48 | end | ||
49 | end | ||
50 | |||
51 | local function try_string(chunk) | ||
52 | dump(luaZ:init(luaZ:make_getS(chunk), nil, "=string")) | ||
53 | end | ||
54 | local function try_file(filename) | ||
55 | dump(luaZ:init(luaZ:make_getF(filename), nil, filename)) | ||
56 | end | ||
57 | |||
58 | z = try_string("local c = luaZ:zgetc(z)") | ||
59 | z = try_file("test_lzio.lua") | ||
60 | z = try_file("test_llex.lua") | ||
61 | os.exit() | ||
62 | --]] | ||
63 | |||
64 | ------------------------------------------------------------------------ | ||
65 | -- auto-testing of simple test cases to validate lexer behaviour: | ||
66 | -- * NOTE coverage has not been checked; not comprehensive | ||
67 | -- * only test cases with non-empty comments are processed | ||
68 | -- * if no result, then the output is displayed for manual decision | ||
69 | -- (output may be used to set expected success or fail text) | ||
70 | -- * cases expected to be successful may be a partial match | ||
71 | -- * cases expected to fail may also be a partial match | ||
72 | ------------------------------------------------------------------------ | ||
73 | |||
74 | -- [[ | ||
75 | local function auto_test() | ||
76 | local PASS, FAIL = true, false | ||
77 | ------------------------------------------------------------------ | ||
78 | -- table of test cases | ||
79 | ------------------------------------------------------------------ | ||
80 | local test_cases = | ||
81 | { | ||
82 | ------------------------------------------------------------- | ||
83 | --{ "comment", -- comment about the test | ||
84 | -- "chunk", -- chunk to test | ||
85 | -- PASS, -- PASS or FAIL outcome | ||
86 | -- "output", -- output to compare against | ||
87 | --}, | ||
88 | ------------------------------------------------------------- | ||
89 | { "empty chunk string, test EOS", | ||
90 | "", | ||
91 | PASS, "1 TK_EOS", | ||
92 | }, | ||
93 | ------------------------------------------------------------- | ||
94 | { "line number counting", | ||
95 | "\n\n\r\n", | ||
96 | PASS, "4 TK_EOS", | ||
97 | }, | ||
98 | ------------------------------------------------------------- | ||
99 | { "various whitespaces", | ||
100 | " \n\t\t\n \t \t \n\n", | ||
101 | PASS, "5 TK_EOS", | ||
102 | }, | ||
103 | ------------------------------------------------------------- | ||
104 | { "short comment ending in EOS", | ||
105 | "-- moo moo", | ||
106 | PASS, "1 TK_EOS", | ||
107 | }, | ||
108 | ------------------------------------------------------------- | ||
109 | { "short comment ending in newline", | ||
110 | "-- moo moo\n", | ||
111 | PASS, "2 TK_EOS", | ||
112 | }, | ||
113 | ------------------------------------------------------------- | ||
114 | { "several lines of short comments", | ||
115 | "--moo\n-- moo moo\n\n--\tmoo\n", | ||
116 | PASS, "5 TK_EOS", | ||
117 | }, | ||
118 | ------------------------------------------------------------- | ||
119 | { "basic block comment 1", | ||
120 | "--[[bovine]]", | ||
121 | PASS, "1 TK_EOS", | ||
122 | }, | ||
123 | ------------------------------------------------------------- | ||
124 | { "basic block comment 2", | ||
125 | "--[=[bovine]=]", | ||
126 | PASS, "1 TK_EOS", | ||
127 | }, | ||
128 | ------------------------------------------------------------- | ||
129 | { "basic block comment 3", | ||
130 | "--[====[-[[bovine]]-]====]", | ||
131 | PASS, "1 TK_EOS", | ||
132 | }, | ||
133 | ------------------------------------------------------------- | ||
134 | { "unterminated block comment 1", | ||
135 | "--[[bovine", | ||
136 | FAIL, ":1: unfinished long comment near '<eof>'", | ||
137 | }, | ||
138 | ------------------------------------------------------------- | ||
139 | { "unterminated block comment 2", | ||
140 | "--[==[bovine", | ||
141 | FAIL, ":1: unfinished long comment near '<eof>'", | ||
142 | }, | ||
143 | ------------------------------------------------------------- | ||
144 | { "unterminated block comment 3", | ||
145 | "--[[bovine]", | ||
146 | FAIL, ":1: unfinished long comment near '<eof>'", | ||
147 | }, | ||
148 | ------------------------------------------------------------- | ||
149 | { "unterminated block comment 4", | ||
150 | "--[[bovine\nmoo moo\nwoof", | ||
151 | FAIL, ":3: unfinished long comment near '<eof>'", | ||
152 | }, | ||
153 | ------------------------------------------------------------- | ||
154 | { "basic long string 1", | ||
155 | "\n[[bovine]]\n", | ||
156 | PASS, "2 TK_STRING = bovine\n3 TK_EOS", | ||
157 | }, | ||
158 | ------------------------------------------------------------- | ||
159 | { "basic long string 2", | ||
160 | "\n[=[bovine]=]\n", | ||
161 | PASS, "2 TK_STRING = bovine\n3 TK_EOS", | ||
162 | }, | ||
163 | ------------------------------------------------------------- | ||
164 | { "first newline consumed in long string", | ||
165 | "[[\nmoo]]", | ||
166 | PASS, "2 TK_STRING = moo\n2 TK_EOS", | ||
167 | }, | ||
168 | ------------------------------------------------------------- | ||
169 | { "multiline long string 1", | ||
170 | "[[moo\nmoo moo\n]]", | ||
171 | PASS, "3 TK_STRING = moo\nmoo moo\n\n3 TK_EOS", | ||
172 | }, | ||
173 | ------------------------------------------------------------- | ||
174 | { "multiline long string 2", | ||
175 | "[===[moo\n[=[moo moo]=]\n]===]", | ||
176 | PASS, "3 TK_STRING = moo\n[=[moo moo]=]\n\n3 TK_EOS", | ||
177 | }, | ||
178 | ------------------------------------------------------------- | ||
179 | { "unterminated long string 1", | ||
180 | "\n[[\nbovine", | ||
181 | FAIL, ":3: unfinished long string near '<eof>'", | ||
182 | }, | ||
183 | ------------------------------------------------------------- | ||
184 | { "unterminated long string 2", | ||
185 | "[[bovine]", | ||
186 | FAIL, ":1: unfinished long string near '<eof>'", | ||
187 | }, | ||
188 | ------------------------------------------------------------- | ||
189 | { "unterminated long string 2", | ||
190 | "[==[bovine]==", | ||
191 | FAIL, ":1: unfinished long string near '<eof>'", | ||
192 | }, | ||
193 | ------------------------------------------------------------- | ||
194 | { "complex long string 1", | ||
195 | "[=[moo[[moo]]moo]=]", | ||
196 | PASS, "moo[[moo]]moo", | ||
197 | }, | ||
198 | ------------------------------------------------------------- | ||
199 | { "complex long string 2", | ||
200 | "[=[moo[[moo[[[[]]]]moo]]moo]=]", | ||
201 | PASS, "moo[[moo[[[[]]]]moo]]moo", | ||
202 | }, | ||
203 | ------------------------------------------------------------- | ||
204 | { "complex long string 3", | ||
205 | "[=[[[[[]]]][[[[]]]]]=]", | ||
206 | PASS, "[[[[]]]][[[[]]]]", | ||
207 | }, | ||
208 | ------------------------------------------------------------- | ||
209 | { "deprecated long string 1", | ||
210 | "[[moo[[moo]]moo]]", | ||
211 | FAIL, ":1: nesting of [[...]] is deprecated near '['", | ||
212 | }, | ||
213 | ------------------------------------------------------------- | ||
214 | { "deprecated long string 2", | ||
215 | "[[[[ \n", | ||
216 | FAIL, ":1: nesting of [[...]] is deprecated near '['", | ||
217 | }, | ||
218 | ------------------------------------------------------------- | ||
219 | { "deprecated long string 3", | ||
220 | "[[moo[[moo[[[[]]]]moo]]moo]]", | ||
221 | FAIL, ":1: nesting of [[...]] is deprecated near '['", | ||
222 | }, | ||
223 | ------------------------------------------------------------- | ||
224 | { "deprecated long string 4", | ||
225 | "[[[[[[]]]][[[[]]]]]]", | ||
226 | FAIL, ":1: nesting of [[...]] is deprecated near '['", | ||
227 | }, | ||
228 | ------------------------------------------------------------- | ||
229 | { "brackets in long strings 1", | ||
230 | "[[moo[moo]]", | ||
231 | PASS, "moo[moo", | ||
232 | }, | ||
233 | ------------------------------------------------------------- | ||
234 | { "brackets in long strings 2", | ||
235 | "[=[moo[[moo]moo]]moo]=]", | ||
236 | PASS, "moo[[moo]moo]]moo", | ||
237 | }, | ||
238 | ------------------------------------------------------------- | ||
239 | { "unprocessed escapes in long strings", | ||
240 | [[ [=[\a\b\f\n\r\t\v\123]=] ]], | ||
241 | PASS, [[\a\b\f\n\r\t\v\123]], | ||
242 | }, | ||
243 | ------------------------------------------------------------- | ||
244 | { "unbalanced long string", | ||
245 | "[[moo]]moo]]", | ||
246 | PASS, "1 TK_STRING = moo\n1 TK_NAME = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 TK_EOS", | ||
247 | }, | ||
248 | ------------------------------------------------------------- | ||
249 | { "keywords 1", | ||
250 | "and break do else", | ||
251 | PASS, "1 TK_AND\n1 TK_BREAK\n1 TK_DO\n1 TK_ELSE\n1 TK_EOS", | ||
252 | }, | ||
253 | ------------------------------------------------------------- | ||
254 | { "keywords 2", | ||
255 | "elseif end false for", | ||
256 | PASS, "1 TK_ELSEIF\n1 TK_END\n1 TK_FALSE\n1 TK_FOR\n1 TK_EOS", | ||
257 | }, | ||
258 | ------------------------------------------------------------- | ||
259 | { "keywords 3", | ||
260 | "function if in local nil", | ||
261 | PASS, "1 TK_FUNCTION\n1 TK_IF\n1 TK_IN\n1 TK_LOCAL\n1 TK_NIL\n1 TK_EOS", | ||
262 | }, | ||
263 | ------------------------------------------------------------- | ||
264 | { "keywords 4", | ||
265 | "not or repeat return", | ||
266 | PASS, "1 TK_NOT\n1 TK_OR\n1 TK_REPEAT\n1 TK_RETURN\n1 TK_EOS", | ||
267 | }, | ||
268 | ------------------------------------------------------------- | ||
269 | { "keywords 5", | ||
270 | "then true until while", | ||
271 | PASS, "1 TK_THEN\n1 TK_TRUE\n1 TK_UNTIL\n1 TK_WHILE\n1 TK_EOS", | ||
272 | }, | ||
273 | ------------------------------------------------------------- | ||
274 | { "concat and dots", | ||
275 | ".. ...", | ||
276 | PASS, "1 TK_CONCAT\n1 TK_DOTS\n1 TK_EOS", | ||
277 | }, | ||
278 | ------------------------------------------------------------- | ||
279 | -- NOTE: in Lua 5.1.x, shbang handling is no longer performed | ||
280 | -- in the lexer; it is now done in lauxlib.c (luaL_loadfile) | ||
281 | -- so the following cannot be performed by the lexer... | ||
282 | ------------------------------------------------------------- | ||
283 | --{ "shbang handling 1", | ||
284 | -- "#blahblah", | ||
285 | -- PASS, "1 TK_EOS", | ||
286 | --}, | ||
287 | ------------------------------------------------------------- | ||
288 | --{ "shbang handling 2", | ||
289 | -- "#blahblah\nmoo moo\n", | ||
290 | -- PASS, "2 TK_NAME = moo\n2 TK_NAME = moo\n3 TK_EOS", | ||
291 | --}, | ||
292 | ------------------------------------------------------------- | ||
293 | { "empty string", | ||
294 | [['']], | ||
295 | PASS, "1 TK_STRING = \n1 TK_EOS", | ||
296 | }, | ||
297 | ------------------------------------------------------------- | ||
298 | { "single-quoted string", | ||
299 | [['bovine']], | ||
300 | PASS, "1 TK_STRING = bovine\n1 TK_EOS", | ||
301 | }, | ||
302 | ------------------------------------------------------------- | ||
303 | { "double-quoted string", | ||
304 | [["bovine"]], | ||
305 | PASS, "1 TK_STRING = bovine\n1 TK_EOS", | ||
306 | }, | ||
307 | ------------------------------------------------------------- | ||
308 | { "unterminated string 1", | ||
309 | [['moo ]], | ||
310 | FAIL, ":1: unfinished string near '<eof>'", | ||
311 | }, | ||
312 | ------------------------------------------------------------- | ||
313 | { "unterminated string 2", | ||
314 | [["moo \n]], | ||
315 | FAIL, ":1: unfinished string near '<eof>'", | ||
316 | }, | ||
317 | ------------------------------------------------------------- | ||
318 | { "escaped newline in string, line number counted", | ||
319 | "\"moo\\\nmoo\\\nmoo\"", | ||
320 | PASS, "3 TK_STRING = moo\nmoo\nmoo\n3 TK_EOS", | ||
321 | }, | ||
322 | ------------------------------------------------------------- | ||
323 | { "escaped characters in string 1", | ||
324 | [["moo\amoo"]], | ||
325 | PASS, "1 TK_STRING = moo\amoo", | ||
326 | }, | ||
327 | ------------------------------------------------------------- | ||
328 | { "escaped characters in string 2", | ||
329 | [["moo\bmoo"]], | ||
330 | PASS, "1 TK_STRING = moo\bmoo", | ||
331 | }, | ||
332 | ------------------------------------------------------------- | ||
333 | { "escaped characters in string 3", | ||
334 | [["moo\f\n\r\t\vmoo"]], | ||
335 | PASS, "1 TK_STRING = moo\f\n\r\t\vmoo", | ||
336 | }, | ||
337 | ------------------------------------------------------------- | ||
338 | { "escaped characters in string 4", | ||
339 | [["\\ \" \' \? \[ \]"]], | ||
340 | PASS, "1 TK_STRING = \\ \" \' \? \[ \]", | ||
341 | }, | ||
342 | ------------------------------------------------------------- | ||
343 | { "escaped characters in string 5", | ||
344 | [["\z \k \: \;"]], | ||
345 | PASS, "1 TK_STRING = z k : ;", | ||
346 | }, | ||
347 | ------------------------------------------------------------- | ||
348 | { "escaped characters in string 6", | ||
349 | [["\8 \65 \160 \180K \097097"]], | ||
350 | PASS, "1 TK_STRING = \8 \65 \160 \180K \097097\n", | ||
351 | }, | ||
352 | ------------------------------------------------------------- | ||
353 | { "escaped characters in string 7", | ||
354 | [["\666"]], | ||
355 | FAIL, ":1: escape sequence too large near '\"'", | ||
356 | }, | ||
357 | ------------------------------------------------------------- | ||
358 | { "simple numbers", | ||
359 | "123 123+", | ||
360 | PASS, "1 TK_NUMBER = 123\n1 TK_NUMBER = 123\n1 CHAR = '+'\n1 TK_EOS", | ||
361 | }, | ||
362 | ------------------------------------------------------------- | ||
363 | { "longer numbers", | ||
364 | "1234567890 12345678901234567890", | ||
365 | PASS, "1 TK_NUMBER = 1234567890\n1 TK_NUMBER = 1.2345678901235e+19\n", | ||
366 | }, | ||
367 | ------------------------------------------------------------- | ||
368 | { "fractional numbers", | ||
369 | ".123 .12345678901234567890", | ||
370 | PASS, "1 TK_NUMBER = 0.123\n1 TK_NUMBER = 0.12345678901235\n", | ||
371 | }, | ||
372 | ------------------------------------------------------------- | ||
373 | { "more numbers with decimal points", | ||
374 | "12345.67890", | ||
375 | PASS, "1 TK_NUMBER = 12345.6789\n", | ||
376 | }, | ||
377 | ------------------------------------------------------------- | ||
378 | { "malformed number with decimal points", | ||
379 | "1.1.", | ||
380 | FAIL, ":1: malformed number near '1.1.'", | ||
381 | }, | ||
382 | ------------------------------------------------------------- | ||
383 | { "double decimal points", | ||
384 | ".1.1", | ||
385 | FAIL, ":1: malformed number near '.1.1'", | ||
386 | }, | ||
387 | ------------------------------------------------------------- | ||
388 | { "double dots within numbers", | ||
389 | "1..1", | ||
390 | FAIL, ":1: malformed number near '1..1'", | ||
391 | }, | ||
392 | ------------------------------------------------------------- | ||
393 | { "incomplete exponential numbers", | ||
394 | "123e", | ||
395 | FAIL, ":1: malformed number near '123e'", | ||
396 | }, | ||
397 | ------------------------------------------------------------- | ||
398 | { "exponential numbers 1", | ||
399 | "1234e5 1234e5.", | ||
400 | PASS, "1 TK_NUMBER = 123400000\n1 TK_NUMBER = 123400000\n1 CHAR = '.'", | ||
401 | }, | ||
402 | ------------------------------------------------------------- | ||
403 | { "exponential numbers 2", | ||
404 | "1234e56 1.23e123", | ||
405 | PASS, "1 TK_NUMBER = 1.234e+59\n1 TK_NUMBER = 1.23e+123\n", | ||
406 | }, | ||
407 | ------------------------------------------------------------- | ||
408 | { "exponential numbers 3", | ||
409 | "12.34e+", | ||
410 | FAIL, ":1: malformed number near '12.34e+'", | ||
411 | }, | ||
412 | ------------------------------------------------------------- | ||
413 | { "exponential numbers 4", | ||
414 | "12.34e+5 123.4e-5 1234.E+5", | ||
415 | PASS, "1 TK_NUMBER = 1234000\n1 TK_NUMBER = 0.001234\n1 TK_NUMBER = 123400000\n", | ||
416 | }, | ||
417 | ------------------------------------------------------------- | ||
418 | { "hexadecimal numbers", | ||
419 | "0x00FF 0X1234 0xDEADBEEF", | ||
420 | PASS, "1 TK_NUMBER = 255\n1 TK_NUMBER = 4660\n1 TK_NUMBER = 3735928559\n", | ||
421 | }, | ||
422 | ------------------------------------------------------------- | ||
423 | { "invalid hexadecimal numbers 1", | ||
424 | "0xFOO", | ||
425 | FAIL, ":1: malformed number near '0xFOO'", | ||
426 | }, | ||
427 | ------------------------------------------------------------- | ||
428 | { "invalid hexadecimal numbers 2", | ||
429 | "0.BAR", | ||
430 | FAIL, ":1: malformed number near '0.BAR'", | ||
431 | }, | ||
432 | ------------------------------------------------------------- | ||
433 | { "invalid hexadecimal numbers 3", | ||
434 | "0BAZ", | ||
435 | FAIL, ":1: malformed number near '0BAZ'", | ||
436 | }, | ||
437 | ------------------------------------------------------------- | ||
438 | { "single character symbols 1", | ||
439 | "= > < ~ #", | ||
440 | PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n1 CHAR = '#'\n", | ||
441 | }, | ||
442 | ------------------------------------------------------------- | ||
443 | { "double character symbols", | ||
444 | "== >= <= ~=", | ||
445 | PASS, "1 TK_EQ\n1 TK_GE\n1 TK_LE\n1 TK_NE\n", | ||
446 | }, | ||
447 | ------------------------------------------------------------- | ||
448 | { "simple identifiers", | ||
449 | "abc ABC", | ||
450 | PASS, "1 TK_NAME = abc\n1 TK_NAME = ABC\n1 TK_EOS", | ||
451 | }, | ||
452 | ------------------------------------------------------------- | ||
453 | { "more identifiers", | ||
454 | "_abc _ABC", | ||
455 | PASS, "1 TK_NAME = _abc\n1 TK_NAME = _ABC\n1 TK_EOS", | ||
456 | }, | ||
457 | ------------------------------------------------------------- | ||
458 | { "still more identifiers", | ||
459 | "_aB_ _123", | ||
460 | PASS, "1 TK_NAME = _aB_\n1 TK_NAME = _123\n1 TK_EOS", | ||
461 | }, | ||
462 | ------------------------------------------------------------- | ||
463 | -- NOTE: in Lua 5.1.x, this test is no longer performed | ||
464 | ------------------------------------------------------------- | ||
465 | --{ "invalid control character", | ||
466 | -- "\4", | ||
467 | -- FAIL, ":1: invalid control char near 'char(4)'", | ||
468 | --}, | ||
469 | ------------------------------------------------------------- | ||
470 | { "single character symbols 2", | ||
471 | "` ! @ $ %", | ||
472 | PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n", | ||
473 | }, | ||
474 | ------------------------------------------------------------- | ||
475 | { "single character symbols 3", | ||
476 | "^ & * ( )", | ||
477 | PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n", | ||
478 | }, | ||
479 | ------------------------------------------------------------- | ||
480 | { "single character symbols 4", | ||
481 | "_ - + \\ |", | ||
482 | PASS, "1 TK_NAME = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n", | ||
483 | }, | ||
484 | ------------------------------------------------------------- | ||
485 | { "single character symbols 5", | ||
486 | "{ } [ ] :", | ||
487 | PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n", | ||
488 | }, | ||
489 | ------------------------------------------------------------- | ||
490 | { "single character symbols 6", | ||
491 | "; , . / ?", | ||
492 | PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n", | ||
493 | }, | ||
494 | ------------------------------------------------------------- | ||
495 | } | ||
496 | ------------------------------------------------------------------ | ||
497 | -- perform a test case | ||
498 | ------------------------------------------------------------------ | ||
499 | function do_test_case(count, test_case) | ||
500 | if comment == "" then return end -- skip empty entries | ||
501 | local comment, chunk, outcome, matcher = unpack(test_case) | ||
502 | local result = PASS | ||
503 | local output = "" | ||
504 | -- initialize lexer | ||
505 | local L, LS = {}, {} | ||
506 | local z = luaZ:init(luaZ:make_getS(chunk), nil) | ||
507 | luaX:setinput(L, LS, z, "=test") | ||
508 | -- lexer test loop | ||
509 | repeat | ||
510 | -- protected call | ||
511 | local status, token = pcall(luaX.llex, luaX, LS, LS.t) | ||
512 | LS.t.token = token | ||
513 | output = output..LS.linenumber.." " | ||
514 | if status then | ||
515 | -- successful call | ||
516 | if string.len(token) > 1 then | ||
517 | if token == "TK_NAME" | ||
518 | or token == "TK_NUMBER" | ||
519 | or token == "TK_STRING" then | ||
520 | token = token.." = "..LS.t.seminfo | ||
521 | end | ||
522 | elseif string.byte(token) >= 32 then -- displayable chars | ||
523 | token = "CHAR = '"..token.."'" | ||
524 | else -- control characters | ||
525 | token = "CHAR = (".. string.byte(token)..")" | ||
526 | end | ||
527 | output = output..token.."\n" | ||
528 | else | ||
529 | -- failed call | ||
530 | output = output..token -- token is the error message | ||
531 | result = FAIL | ||
532 | break | ||
533 | end | ||
534 | until LS.t.token == "TK_EOS" | ||
535 | -- decision making and reporting | ||
536 | local head = "Test "..count..": "..comment | ||
537 | if matcher == "" then | ||
538 | -- nothing to check against, display for manual check | ||
539 | print(head.."\nMANUAL please check manually".. | ||
540 | "\n--chunk---------------------------------\n"..chunk.. | ||
541 | "\n--actual--------------------------------\n"..output.. | ||
542 | "\n\n") | ||
543 | return | ||
544 | else | ||
545 | if outcome == PASS then | ||
546 | -- success expected, may be a partial match | ||
547 | if string.find(output, matcher, 1, 1) and result == PASS then | ||
548 | if not BRIEF then print(head.."\nOK expected success\n") end | ||
549 | return | ||
550 | end | ||
551 | else | ||
552 | -- failure expected, may be a partial match | ||
553 | if string.find(output, matcher, 1, 1) and result == FAIL then | ||
554 | if not BRIEF then print(head.."\nOK expected failure\n") end | ||
555 | return | ||
556 | end | ||
557 | end | ||
558 | -- failed because of unmatched string or boolean result | ||
559 | local function passfail(status) | ||
560 | if status == PASS then return "PASS" else return "FAIL" end | ||
561 | end | ||
562 | print(head.." *FAILED*".. | ||
563 | "\noutcome="..passfail(outcome).. | ||
564 | "\nactual= "..passfail(result).. | ||
565 | "\n--chunk---------------------------------\n"..chunk.. | ||
566 | "\n--expected------------------------------\n"..matcher.. | ||
567 | "\n--actual--------------------------------\n"..output.. | ||
568 | "\n\n") | ||
569 | end | ||
570 | end | ||
571 | ------------------------------------------------------------------ | ||
572 | -- perform auto testing | ||
573 | ------------------------------------------------------------------ | ||
574 | for i,test_case in ipairs(test_cases) do | ||
575 | do_test_case(i, test_case) | ||
576 | end | ||
577 | end | ||
578 | |||
579 | auto_test() | ||
580 | --]] | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser.lua | ||
4 | Test for lparser.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | ------------------------------------------------------------------------ | ||
16 | -- test the whole kaboodle | ||
17 | ------------------------------------------------------------------------ | ||
18 | |||
19 | dofile("../lzio.lua") | ||
20 | dofile("../llex.lua") | ||
21 | dofile("../lopcodes.lua") | ||
22 | dofile("../ldump.lua") | ||
23 | dofile("../lcode.lua") | ||
24 | dofile("../lparser.lua") | ||
25 | |||
26 | function lua_assert(test) | ||
27 | if not test then error("assertion failed!") end | ||
28 | end | ||
29 | |||
30 | luaX:init() | ||
31 | |||
32 | ------------------------------------------------------------------------ | ||
33 | -- try 1 | ||
34 | ------------------------------------------------------------------------ | ||
35 | local zio = luaZ:init(luaZ:make_getS("local a = 1"), nil) | ||
36 | local LuaState = {} | ||
37 | local Func = luaY:parser(LuaState, zio, nil, "=string") | ||
38 | |||
39 | --[[ | ||
40 | for i, v in Func do | ||
41 | if type(v) == "string" or type(v) == "number" then | ||
42 | print(i, v) | ||
43 | elseif type(v) == "table" then | ||
44 | print(i, "TABLE") | ||
45 | end | ||
46 | end | ||
47 | --]] | ||
48 | |||
49 | local Writer, Buff = luaU:make_setF("parse1.out") | ||
50 | luaU:dump(LuaState, Func, Writer, Buff) | ||
51 | |||
52 | ------------------------------------------------------------------------ | ||
53 | -- try 2 | ||
54 | ------------------------------------------------------------------------ | ||
55 | |||
56 | zio = luaZ:init(luaZ:make_getF("sample.lua"), nil) | ||
57 | Func = luaY:parser(LuaState, zio, nil, "@sample.lua") | ||
58 | Writer, Buff = luaU:make_setF("parse2.out") | ||
59 | 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lparser2.lua | ||
4 | Test for lparser.lua, using the test case file | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * the test cases are in the test_lua directory (test_parser-5.1.lua) | ||
18 | ----------------------------------------------------------------------]] | ||
19 | |||
20 | -- * true if you want an output of all failure cases in native Lua, | ||
21 | -- for checking whether test cases fail where you intend them to | ||
22 | local DEBUG_FAILS = false | ||
23 | |||
24 | ------------------------------------------------------------------------ | ||
25 | -- test the whole kaboodle | ||
26 | ------------------------------------------------------------------------ | ||
27 | |||
28 | dofile("../lzio.lua") | ||
29 | dofile("../llex.lua") | ||
30 | dofile("../lopcodes.lua") | ||
31 | dofile("../ldump.lua") | ||
32 | dofile("../lcode.lua") | ||
33 | dofile("../lparser.lua") | ||
34 | |||
35 | function lua_assert(test) | ||
36 | if not test then error("assertion failed!") end | ||
37 | end | ||
38 | |||
39 | luaX:init() | ||
40 | |||
41 | ------------------------------------------------------------------------ | ||
42 | -- load test cases | ||
43 | ------------------------------------------------------------------------ | ||
44 | |||
45 | dofile("../../test_lua/test_parser-5.1.lua") | ||
46 | |||
47 | local test, expect, heading = {}, {}, {} | ||
48 | local total, total_pass, total_fail = 0, 0, 0 | ||
49 | |||
50 | for ln in string.gmatch(tests_source, "([^\n]*)\n") do | ||
51 | if string.find(ln, "^%s*%-%-") then | ||
52 | -- comment, ignore | ||
53 | else | ||
54 | local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$") | ||
55 | if m then | ||
56 | heading[total + 1] = head -- informational heading | ||
57 | else | ||
58 | total = total + 1 | ||
59 | local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$") | ||
60 | if n then -- FAIL test case | ||
61 | ln = string.sub(ln, 1, n - 1) -- remove comment | ||
62 | expect[total] = "FAIL" | ||
63 | total_fail = total_fail + 1 | ||
64 | else -- PASS test case | ||
65 | expect[total] = "PASS" | ||
66 | total_pass = total_pass + 1 | ||
67 | end--n | ||
68 | test[total] = ln | ||
69 | end--m | ||
70 | end--ln | ||
71 | end--for | ||
72 | |||
73 | print("Tests loaded: "..total.." (total), " | ||
74 | ..total_pass.." (passes), " | ||
75 | ..total_fail.." (fails)") | ||
76 | |||
77 | ------------------------------------------------------------------------ | ||
78 | -- verify test cases using native Lua | ||
79 | ------------------------------------------------------------------------ | ||
80 | |||
81 | local last_head = "TESTS: no heading yet" | ||
82 | for i = 1, total do | ||
83 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
84 | -- show progress | ||
85 | if head then | ||
86 | last_head = head | ||
87 | if DEBUG_FAILS then print("\n"..head.."\n") end | ||
88 | end | ||
89 | ------------------------------------------------------------------ | ||
90 | -- perform test | ||
91 | local f, err = loadstring(test_case) | ||
92 | -- look at outcome | ||
93 | ------------------------------------------------------------------ | ||
94 | if f then-- actual PASS | ||
95 | if expected == "FAIL" then | ||
96 | print("\nVerified as PASS but expected to FAIL".. | ||
97 | "\n-------------------------------------") | ||
98 | print("Lastest heading: "..last_head) | ||
99 | print("TEST: "..test_case) | ||
100 | os.exit() | ||
101 | end | ||
102 | ------------------------------------------------------------------ | ||
103 | else-- actual FAIL | ||
104 | if expected == "PASS" then | ||
105 | print("\nVerified as FAIL but expected to PASS".. | ||
106 | "\n-------------------------------------") | ||
107 | print("Lastest heading: "..last_head) | ||
108 | print("TEST: "..test_case) | ||
109 | print("ERROR: "..err) | ||
110 | os.exit() | ||
111 | end | ||
112 | if DEBUG_FAILS then | ||
113 | print("TEST: "..test_case) | ||
114 | print("ERROR: "..err.."\n") | ||
115 | end | ||
116 | ------------------------------------------------------------------ | ||
117 | end--f | ||
118 | end--for | ||
119 | |||
120 | print("Test cases verified using native Lua, no anomalies.") | ||
121 | |||
122 | ------------------------------------------------------------------------ | ||
123 | -- dump binary chunks to a file if something goes wrong | ||
124 | ------------------------------------------------------------------------ | ||
125 | local function Dump(data, filename) | ||
126 | h = io.open(filename, "wb") | ||
127 | if not h then error("failed to open "..filename.." for writing") end | ||
128 | h:write(data) | ||
129 | h:close() | ||
130 | end | ||
131 | |||
132 | ------------------------------------------------------------------------ | ||
133 | -- test using Yueliang front end | ||
134 | ------------------------------------------------------------------------ | ||
135 | |||
136 | local last_head = "TESTS: no heading yet" | ||
137 | for i = 1, total do | ||
138 | local test_case, expected, head = test[i], expect[i], heading[i] | ||
139 | -- show progress | ||
140 | if head then last_head = head end | ||
141 | ------------------------------------------------------------------ | ||
142 | -- perform test | ||
143 | local LuaState = {} | ||
144 | local zio = luaZ:init(luaZ:make_getS(test_case), nil) | ||
145 | local status, func = pcall(luaY.parser, luaY, LuaState, zio, nil, "test") | ||
146 | -- look at outcome | ||
147 | ------------------------------------------------------------------ | ||
148 | if status then-- actual PASS | ||
149 | if expected == "PASS" then | ||
150 | -- actual PASS and expected PASS, so check binary chunks | ||
151 | local writer, buff = luaU:make_setS() | ||
152 | luaU:dump(LuaState, func, writer, buff) | ||
153 | local bc1 = buff.data -- Yueliang's output | ||
154 | local f = loadstring(test_case, "test") | ||
155 | local bc2 = string.dump(f) -- Lua's output | ||
156 | local die | ||
157 | -- compare outputs | ||
158 | if #bc1 ~= #bc2 then | ||
159 | Dump(bc1, "bc1.out") | ||
160 | Dump(bc2, "bc2.out") | ||
161 | die = "binary chunk sizes different" | ||
162 | elseif bc1 ~= bc2 then | ||
163 | Dump(bc1, "bc1.out") | ||
164 | Dump(bc2, "bc2.out") | ||
165 | die = "binary chunks different" | ||
166 | else | ||
167 | -- everything checks out! | ||
168 | end | ||
169 | if die then | ||
170 | print("\nTested PASS and expected to PASS, but chunks different".. | ||
171 | "\n------------------------------------------------------") | ||
172 | print("Reason: "..die) | ||
173 | print("Lastest heading: "..last_head) | ||
174 | print("TEST: "..test_case) | ||
175 | os.exit() | ||
176 | end | ||
177 | else-- expected FAIL | ||
178 | print("\nTested as PASS but expected to FAIL".. | ||
179 | "\n-----------------------------------") | ||
180 | print("Lastest heading: "..last_head) | ||
181 | print("TEST: "..test_case) | ||
182 | os.exit() | ||
183 | end | ||
184 | ------------------------------------------------------------------ | ||
185 | else-- actual FAIL | ||
186 | if expected == "PASS" then | ||
187 | print("\nTested as FAIL but expected to PASS".. | ||
188 | "\n-----------------------------------") | ||
189 | print("Lastest heading: "..last_head) | ||
190 | print("TEST: "..test_case) | ||
191 | print("ERROR: "..err) | ||
192 | os.exit() | ||
193 | end | ||
194 | ------------------------------------------------------------------ | ||
195 | end--status | ||
196 | io.stdout:write("\rTesting ["..i.."]...") | ||
197 | end--for | ||
198 | print(" done.") | ||
199 | |||
200 | print("Test cases run on Yueliang, no anomalies.") | ||
201 | |||
202 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_lzio.lua | ||
4 | Test for lzio.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | -- manual test for lzio.lua lua-style chunk reader | ||
16 | |||
17 | dofile("../lzio.lua") | ||
18 | |||
19 | local z | ||
20 | function dump(z) | ||
21 | while true do | ||
22 | local c = luaZ:zgetc(z) | ||
23 | io.stdout:write("("..c..")") | ||
24 | if c == "EOZ" then break end | ||
25 | end | ||
26 | io.stdout:write("\n") | ||
27 | end | ||
28 | |||
29 | -- luaZ:make_getS or luaZ:make_getF creates a chunk reader | ||
30 | -- luaZ:init makes a zio stream | ||
31 | |||
32 | -- [[ | ||
33 | z = luaZ:init(luaZ:make_getS("hello, world!"), nil, "=string") | ||
34 | dump(z) | ||
35 | z = luaZ:init(luaZ:make_getS(", world!"), "hello", "=string") | ||
36 | dump(z) | ||
37 | z = luaZ:init(luaZ:make_getS("line1\nline2\n"), "", "=string") | ||
38 | dump(z) | ||
39 | z = luaZ:init(luaZ:make_getF("test_lzio.lua"), nil, "=string") | ||
40 | dump(z) | ||
41 | --]] | ||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_number.lua | ||
4 | Test for Lua-based number conversion functions in ldump.lua | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * luaU:from_int(value) does not have overflow checks, but this | ||
18 | -- can presumably be put in for debugging purposes. | ||
19 | -- * TODO: double conversion does not support denormals or NaNs | ||
20 | -- * apparently 0/0 == 0/0 is false (Lua 5.0.2 on Win32/Mingw), so | ||
21 | -- can't use to check for NaNs | ||
22 | ----------------------------------------------------------------------]] | ||
23 | |||
24 | dofile("../ldump.lua") | ||
25 | |||
26 | ------------------------------------------------------------------------ | ||
27 | -- convert hex string representation to a byte string | ||
28 | -- * must have an even number of hex digits | ||
29 | ------------------------------------------------------------------------ | ||
30 | local function from_hexstring(s) | ||
31 | local bs = "" | ||
32 | for i = 1, string.len(s), 2 do | ||
33 | local asc = tonumber(string.sub(s, i, i + 1), 16) | ||
34 | bs = bs..string.char(asc) | ||
35 | end | ||
36 | return bs | ||
37 | end | ||
38 | |||
39 | ------------------------------------------------------------------------ | ||
40 | -- convert a byte string to a hex string representation | ||
41 | -- * big-endian, easier to grok | ||
42 | ------------------------------------------------------------------------ | ||
43 | local function to_hexstring(s) | ||
44 | local hs = "" | ||
45 | for i = string.len(s), 1, -1 do | ||
46 | local c = string.byte(string.sub(s, i, i)) | ||
47 | hs = hs..string.format("%02X", c) | ||
48 | end | ||
49 | return hs | ||
50 | end | ||
51 | |||
52 | ------------------------------------------------------------------------ | ||
53 | -- tests for 32-bit signed/unsigned integer | ||
54 | ------------------------------------------------------------------------ | ||
55 | local function test_int(value, expected) | ||
56 | local actual = to_hexstring(luaU:from_int(value)) | ||
57 | if not expected or expected == "" then | ||
58 | print(value..": "..actual) | ||
59 | elseif actual ~= expected then | ||
60 | print(value..": FAILED!\n".. | ||
61 | "Converted: "..actual.."\n".. | ||
62 | "Expected: "..expected) | ||
63 | return true | ||
64 | end | ||
65 | return false | ||
66 | end | ||
67 | |||
68 | local table_int = { | ||
69 | ["0"] = "00000000", | ||
70 | ["1"] = "00000001", | ||
71 | ["256"] = "00000100", | ||
72 | ["-256"] = "FFFFFF00", | ||
73 | ["-1"] = "FFFFFFFF", | ||
74 | ["2147483647"] = "7FFFFFFF", -- LONG_MAX | ||
75 | ["-2147483648"] = "80000000", -- LONG_MIN | ||
76 | ["4294967295"] = "FFFFFFFF", -- ULONG_MAX | ||
77 | --[""] = "", | ||
78 | } | ||
79 | |||
80 | local success = true | ||
81 | print("Testing luaU:from_int():") | ||
82 | for i, v in pairs(table_int) do | ||
83 | local test_value = tonumber(i) | ||
84 | local expected = v | ||
85 | if test_int(test_value, expected) then | ||
86 | success = false | ||
87 | end | ||
88 | end | ||
89 | if success then | ||
90 | print("All test numbers passed okay.\n") | ||
91 | else | ||
92 | print("There were one or more failures.\n") | ||
93 | end | ||
94 | |||
95 | ------------------------------------------------------------------------ | ||
96 | -- tests for IEEE 754 64-bit double | ||
97 | ------------------------------------------------------------------------ | ||
98 | |||
99 | local function test_double(value, expected) | ||
100 | local actual = to_hexstring(luaU:from_double(value)) | ||
101 | if not expected or expected == "" then | ||
102 | print(value..": "..actual) | ||
103 | elseif actual ~= expected then | ||
104 | print(value..": FAILED!\n".. | ||
105 | "Converted: "..actual.."\n".. | ||
106 | "Expected: "..expected) | ||
107 | return true | ||
108 | end | ||
109 | return false | ||
110 | end | ||
111 | |||
112 | -- special values, see testing loop for actual lookup | ||
113 | Infinity = 1/0 | ||
114 | Infinity_neg = -1/0 | ||
115 | |||
116 | -- can't seem to do a comparison test with NaN, so leave them | ||
117 | -- (need to check the IEEE standard on this...) | ||
118 | NaN = 0/0 | ||
119 | NaN_neg = -0/0 | ||
120 | --["NaN"] = "", -- 7FF8000000000000 (djgpp) | ||
121 | --["NaN_neg"] = "", -- FFF8000000000000 (djgpp) | ||
122 | |||
123 | local table_double = { | ||
124 | -- 0 for exponent, 0 for mantissa | ||
125 | ["0"] = "0000000000000000", | ||
126 | -- 3FF is bias of 1023, so (-1)^0 * (1+0) * 2^0 | ||
127 | ["1"] = "3FF0000000000000", | ||
128 | -- BFF has sign bit on, so (-1)^1 * (1+0) * 2^0 | ||
129 | ["-1"] = "BFF0000000000000", | ||
130 | -- 3FC is bias of 1020, so (-1)^0 * (1+0) * 2^-3 | ||
131 | ["0.125"] = "3FC0000000000000", | ||
132 | ["0.250"] = "3FD0000000000000", | ||
133 | ["0.500"] = "3FE0000000000000", | ||
134 | -- 40F is bias of 1039, so (-1)^0 * (1+0) * 2^16 | ||
135 | ["65536"] = "40F0000000000000", | ||
136 | -- 7FF is bias of 2047, 0 for mantissa | ||
137 | ["Infinity"] = "7FF0000000000000", | ||
138 | -- FFF has sign bit on, 0 for mantissa | ||
139 | ["Infinity_neg"] = "FFF0000000000000", | ||
140 | -- DBL_MIN, exponent=001 ( 1), mantissa=0000000000000 | ||
141 | ["2.2250738585072014e-308"] = "0010000000000000", | ||
142 | -- DBL_MAX, exponent=7FE (2046), mantissa=FFFFFFFFFFFFF | ||
143 | ["1.7976931348623157e+308"] = "7FEFFFFFFFFFFFFF", | ||
144 | --[[ | ||
145 | -- * the following is for float numbers only * | ||
146 | -- FLT_MIN, exponent=01 ( 1), mantissa=000000 | ||
147 | -- altervative value for FLT_MIN: 1.17549435e-38F | ||
148 | ["1.1754943508222875081e-38"] = "00800000", | ||
149 | -- FLT_MAX, exponent=FE (254), mantissa=7FFFFF | ||
150 | -- altervative value for FLT_MAX: 3.402823466e+38F | ||
151 | ["3.4028234663852885982e+38"] = "7F7FFFFF", | ||
152 | --]] | ||
153 | --[""] = "", | ||
154 | } | ||
155 | |||
156 | local success = true | ||
157 | print("Testing luaU:from_double():") | ||
158 | for i, v in pairs(table_double) do | ||
159 | local test_value | ||
160 | if not string.find(i, "%d") then | ||
161 | test_value = _G[i] | ||
162 | else | ||
163 | test_value = tonumber(i) | ||
164 | end | ||
165 | local expected = v | ||
166 | if test_double(test_value, expected) then | ||
167 | success = false | ||
168 | end | ||
169 | end | ||
170 | if success then | ||
171 | print("All test numbers passed okay.\n") | ||
172 | else | ||
173 | print("There were one or more failures.\n") | ||
174 | 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 @@ | |||
1 | -- bisection method for solving non-linear equations | ||
2 | |||
3 | delta=1e-6 -- tolerance | ||
4 | |||
5 | function bisect(f,a,b,fa,fb) | ||
6 | local c=(a+b)/2 | ||
7 | io.write(n," c=",c," a=",a," b=",b,"\n") | ||
8 | if c==a or c==b or math.abs(a-b)<delta then return c,b-a end | ||
9 | n=n+1 | ||
10 | local fc=f(c) | ||
11 | if fa*fc<0 then return bisect(f,a,c,fa,fc) else return bisect(f,c,b,fc,fb) end | ||
12 | end | ||
13 | |||
14 | -- find root of f in the inverval [a,b]. needs f(a)*f(b)<0 | ||
15 | function solve(f,a,b) | ||
16 | n=0 | ||
17 | local z,e=bisect(f,a,b,f(a),f(b)) | ||
18 | io.write(string.format("after %d steps, root is %.17g with error %.1e, f=%.1e\n",n,z,e,f(z))) | ||
19 | end | ||
20 | |||
21 | -- our function | ||
22 | function f(x) | ||
23 | return x*x*x-x-1 | ||
24 | end | ||
25 | |||
26 | -- find zero in [1,2] | ||
27 | solve(f,1,2) | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/cf.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/cf.lua new file mode 100644 index 0000000..8cda54b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/cf.lua | |||
@@ -0,0 +1,16 @@ | |||
1 | -- temperature conversion table (celsius to farenheit) | ||
2 | |||
3 | for c0=-20,50-1,10 do | ||
4 | io.write("C ") | ||
5 | for c=c0,c0+10-1 do | ||
6 | io.write(string.format("%3.0f ",c)) | ||
7 | end | ||
8 | io.write("\n") | ||
9 | |||
10 | io.write("F ") | ||
11 | for c=c0,c0+10-1 do | ||
12 | f=(9/5)*c+32 | ||
13 | io.write(string.format("%3.0f ",f)) | ||
14 | end | ||
15 | io.write("\n\n") | ||
16 | end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/echo.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/echo.lua new file mode 100644 index 0000000..4313439 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/echo.lua | |||
@@ -0,0 +1,5 @@ | |||
1 | -- echo command line arguments | ||
2 | |||
3 | for i=0,table.getn(arg) do | ||
4 | print(i,arg[i]) | ||
5 | end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/env.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/env.lua new file mode 100644 index 0000000..9e62a57 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/env.lua | |||
@@ -0,0 +1,7 @@ | |||
1 | -- read environment variables as if they were global variables | ||
2 | |||
3 | local f=function (t,i) return os.getenv(i) end | ||
4 | setmetatable(getfenv(),{__index=f}) | ||
5 | |||
6 | -- an example | ||
7 | print(a,USER,PATH) | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/factorial.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/factorial.lua new file mode 100644 index 0000000..7c4cf0f --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/factorial.lua | |||
@@ -0,0 +1,32 @@ | |||
1 | -- function closures are powerful | ||
2 | |||
3 | -- traditional fixed-point operator from functional programming | ||
4 | Y = function (g) | ||
5 | local a = function (f) return f(f) end | ||
6 | return a(function (f) | ||
7 | return g(function (x) | ||
8 | local c=f(f) | ||
9 | return c(x) | ||
10 | end) | ||
11 | end) | ||
12 | end | ||
13 | |||
14 | |||
15 | -- factorial without recursion | ||
16 | F = function (f) | ||
17 | return function (n) | ||
18 | if n == 0 then return 1 | ||
19 | else return n*f(n-1) end | ||
20 | end | ||
21 | end | ||
22 | |||
23 | factorial = Y(F) -- factorial is the fixed point of F | ||
24 | |||
25 | -- now test it | ||
26 | function test(x) | ||
27 | io.write(x,"! = ",factorial(x),"\n") | ||
28 | end | ||
29 | |||
30 | for n=0,16 do | ||
31 | test(n) | ||
32 | end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/fib.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/fib.lua new file mode 100644 index 0000000..97a921b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/fib.lua | |||
@@ -0,0 +1,40 @@ | |||
1 | -- fibonacci function with cache | ||
2 | |||
3 | -- very inefficient fibonacci function | ||
4 | function fib(n) | ||
5 | N=N+1 | ||
6 | if n<2 then | ||
7 | return n | ||
8 | else | ||
9 | return fib(n-1)+fib(n-2) | ||
10 | end | ||
11 | end | ||
12 | |||
13 | -- a general-purpose value cache | ||
14 | function cache(f) | ||
15 | local c={} | ||
16 | return function (x) | ||
17 | local y=c[x] | ||
18 | if not y then | ||
19 | y=f(x) | ||
20 | c[x]=y | ||
21 | end | ||
22 | return y | ||
23 | end | ||
24 | end | ||
25 | |||
26 | -- run and time it | ||
27 | function test(s,f) | ||
28 | N=0 | ||
29 | local c=os.clock() | ||
30 | local v=f(n) | ||
31 | local t=os.clock()-c | ||
32 | print(s,n,v,t,N) | ||
33 | end | ||
34 | |||
35 | n=arg[1] or 24 -- for other values, do lua fib.lua XX | ||
36 | n=tonumber(n) | ||
37 | print("","n","value","time","evals") | ||
38 | test("plain",fib) | ||
39 | fib=cache(fib) | ||
40 | test("cached",fib) | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/fibfor.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/fibfor.lua new file mode 100644 index 0000000..19bb34b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/fibfor.lua | |||
@@ -0,0 +1,13 @@ | |||
1 | -- example of for with generator functions | ||
2 | |||
3 | function generatefib (n) | ||
4 | return coroutine.wrap(function () | ||
5 | local a,b = 1, 1 | ||
6 | while a <= n do | ||
7 | coroutine.yield(a) | ||
8 | a, b = b, a+b | ||
9 | end | ||
10 | end, n) | ||
11 | end | ||
12 | |||
13 | for i in generatefib(1000) do print(i) end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/globals.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/globals.lua new file mode 100644 index 0000000..d4c20e1 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/globals.lua | |||
@@ -0,0 +1,13 @@ | |||
1 | -- reads luac listings and reports global variable usage | ||
2 | -- lines where a global is written to are marked with "*" | ||
3 | -- typical usage: luac -p -l file.lua | lua globals.lua | sort | lua table.lua | ||
4 | |||
5 | while 1 do | ||
6 | local s=io.read() | ||
7 | if s==nil then break end | ||
8 | local ok,_,l,op,g=string.find(s,"%[%-?(%d*)%]%s*([GS])ETGLOBAL.-;%s+(.*)$") | ||
9 | if ok then | ||
10 | if op=="S" then op="*" else op="" end | ||
11 | io.write(g,"\t",l,op,"\n") | ||
12 | end | ||
13 | end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/hello.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/hello.lua new file mode 100644 index 0000000..0925498 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/hello.lua | |||
@@ -0,0 +1,3 @@ | |||
1 | -- the first program in every language | ||
2 | |||
3 | io.write("Hello world, from ",_VERSION,"!\n") | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/life.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/life.lua new file mode 100644 index 0000000..911d9fe --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/life.lua | |||
@@ -0,0 +1,111 @@ | |||
1 | -- life.lua | ||
2 | -- original by Dave Bollinger <DBollinger@compuserve.com> posted to lua-l | ||
3 | -- modified to use ANSI terminal escape sequences | ||
4 | -- modified to use for instead of while | ||
5 | |||
6 | local write=io.write | ||
7 | |||
8 | ALIVE="¥" DEAD="þ" | ||
9 | ALIVE="O" DEAD="-" | ||
10 | |||
11 | function delay() -- NOTE: SYSTEM-DEPENDENT, adjust as necessary | ||
12 | for i=1,10000 do end | ||
13 | -- local i=os.clock()+1 while(os.clock()<i) do end | ||
14 | end | ||
15 | |||
16 | function ARRAY2D(w,h) | ||
17 | local t = {w=w,h=h} | ||
18 | for y=1,h do | ||
19 | t[y] = {} | ||
20 | for x=1,w do | ||
21 | t[y][x]=0 | ||
22 | end | ||
23 | end | ||
24 | return t | ||
25 | end | ||
26 | |||
27 | _CELLS = {} | ||
28 | |||
29 | -- give birth to a "shape" within the cell array | ||
30 | function _CELLS:spawn(shape,left,top) | ||
31 | for y=0,shape.h-1 do | ||
32 | for x=0,shape.w-1 do | ||
33 | self[top+y][left+x] = shape[y*shape.w+x+1] | ||
34 | end | ||
35 | end | ||
36 | end | ||
37 | |||
38 | -- run the CA and produce the next generation | ||
39 | function _CELLS:evolve(next) | ||
40 | local ym1,y,yp1,yi=self.h-1,self.h,1,self.h | ||
41 | while yi > 0 do | ||
42 | local xm1,x,xp1,xi=self.w-1,self.w,1,self.w | ||
43 | while xi > 0 do | ||
44 | local sum = self[ym1][xm1] + self[ym1][x] + self[ym1][xp1] + | ||
45 | self[y][xm1] + self[y][xp1] + | ||
46 | self[yp1][xm1] + self[yp1][x] + self[yp1][xp1] | ||
47 | next[y][x] = ((sum==2) and self[y][x]) or ((sum==3) and 1) or 0 | ||
48 | xm1,x,xp1,xi = x,xp1,xp1+1,xi-1 | ||
49 | end | ||
50 | ym1,y,yp1,yi = y,yp1,yp1+1,yi-1 | ||
51 | end | ||
52 | end | ||
53 | |||
54 | -- output the array to screen | ||
55 | function _CELLS:draw() | ||
56 | local out="" -- accumulate to reduce flicker | ||
57 | for y=1,self.h do | ||
58 | for x=1,self.w do | ||
59 | out=out..(((self[y][x]>0) and ALIVE) or DEAD) | ||
60 | end | ||
61 | out=out.."\n" | ||
62 | end | ||
63 | write(out) | ||
64 | end | ||
65 | |||
66 | -- constructor | ||
67 | function CELLS(w,h) | ||
68 | local c = ARRAY2D(w,h) | ||
69 | c.spawn = _CELLS.spawn | ||
70 | c.evolve = _CELLS.evolve | ||
71 | c.draw = _CELLS.draw | ||
72 | return c | ||
73 | end | ||
74 | |||
75 | -- | ||
76 | -- shapes suitable for use with spawn() above | ||
77 | -- | ||
78 | HEART = { 1,0,1,1,0,1,1,1,1; w=3,h=3 } | ||
79 | GLIDER = { 0,0,1,1,0,1,0,1,1; w=3,h=3 } | ||
80 | EXPLODE = { 0,1,0,1,1,1,1,0,1,0,1,0; w=3,h=4 } | ||
81 | 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 } | ||
82 | 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 } | ||
83 | |||
84 | -- the main routine | ||
85 | function LIFE(w,h) | ||
86 | -- create two arrays | ||
87 | local thisgen = CELLS(w,h) | ||
88 | local nextgen = CELLS(w,h) | ||
89 | |||
90 | -- create some life | ||
91 | -- about 1000 generations of fun, then a glider steady-state | ||
92 | thisgen:spawn(GLIDER,5,4) | ||
93 | thisgen:spawn(EXPLODE,25,10) | ||
94 | thisgen:spawn(FISH,4,12) | ||
95 | |||
96 | -- run until break | ||
97 | local gen=1 | ||
98 | write("\027[2J") -- ANSI clear screen | ||
99 | while 1 do | ||
100 | thisgen:evolve(nextgen) | ||
101 | thisgen,nextgen = nextgen,thisgen | ||
102 | write("\027[H") -- ANSI home cursor | ||
103 | thisgen:draw() | ||
104 | write("Life - generation ",gen,"\n") | ||
105 | gen=gen+1 | ||
106 | if gen>2000 then break end | ||
107 | --delay() -- no delay | ||
108 | end | ||
109 | end | ||
110 | |||
111 | 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 @@ | |||
1 | -- bare-bones luac in Lua | ||
2 | -- usage: lua luac.lua file.lua | ||
3 | |||
4 | assert(arg[1]~=nil and arg[2]==nil,"usage: lua luac.lua file.lua") | ||
5 | f=assert(io.open("luac.out","wb")) | ||
6 | f:write(string.dump(assert(loadfile(arg[1])))) | ||
7 | 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 @@ | |||
1 | -- an implementation of printf | ||
2 | |||
3 | function printf(...) | ||
4 | io.write(string.format(unpack(arg))) | ||
5 | end | ||
6 | |||
7 | 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 @@ | |||
1 | -- make global variables readonly | ||
2 | |||
3 | local f=function (t,i) error("cannot redefine global variable `"..i.."'",2) end | ||
4 | local g={} | ||
5 | local G=getfenv() | ||
6 | setmetatable(g,{__index=G,__newindex=f}) | ||
7 | setfenv(1,g) | ||
8 | |||
9 | -- an example | ||
10 | rawset(g,"x",3) | ||
11 | x=2 | ||
12 | 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 @@ | |||
1 | -- the sieve of of Eratosthenes programmed with coroutines | ||
2 | -- typical usage: lua -e N=1000 sieve.lua | column | ||
3 | |||
4 | -- generate all the numbers from 2 to n | ||
5 | function gen (n) | ||
6 | return coroutine.wrap(function () | ||
7 | for i=2,n do coroutine.yield(i) end | ||
8 | end) | ||
9 | end | ||
10 | |||
11 | -- filter the numbers generated by `g', removing multiples of `p' | ||
12 | function filter (p, g) | ||
13 | return coroutine.wrap(function () | ||
14 | while 1 do | ||
15 | local n = g() | ||
16 | if n == nil then return end | ||
17 | if math.mod(n, p) ~= 0 then coroutine.yield(n) end | ||
18 | end | ||
19 | end) | ||
20 | end | ||
21 | |||
22 | N=N or 1000 -- from command line | ||
23 | x = gen(N) -- generate primes up to N | ||
24 | while 1 do | ||
25 | local n = x() -- pick a number until done | ||
26 | if n == nil then break end | ||
27 | print(n) -- must be a prime number | ||
28 | x = filter(n, x) -- now remove its multiples | ||
29 | 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 @@ | |||
1 | -- two implementations of a sort function | ||
2 | -- this is an example only. Lua has now a built-in function "sort" | ||
3 | |||
4 | -- extracted from Programming Pearls, page 110 | ||
5 | function qsort(x,l,u,f) | ||
6 | if l<u then | ||
7 | local m=math.random(u-(l-1))+l-1 -- choose a random pivot in range l..u | ||
8 | x[l],x[m]=x[m],x[l] -- swap pivot to first position | ||
9 | local t=x[l] -- pivot value | ||
10 | m=l | ||
11 | local i=l+1 | ||
12 | while i<=u do | ||
13 | -- invariant: x[l+1..m] < t <= x[m+1..i-1] | ||
14 | if f(x[i],t) then | ||
15 | m=m+1 | ||
16 | x[m],x[i]=x[i],x[m] -- swap x[i] and x[m] | ||
17 | end | ||
18 | i=i+1 | ||
19 | end | ||
20 | x[l],x[m]=x[m],x[l] -- swap pivot to a valid place | ||
21 | -- x[l+1..m-1] < x[m] <= x[m+1..u] | ||
22 | qsort(x,l,m-1,f) | ||
23 | qsort(x,m+1,u,f) | ||
24 | end | ||
25 | end | ||
26 | |||
27 | function selectionsort(x,n,f) | ||
28 | local i=1 | ||
29 | while i<=n do | ||
30 | local m,j=i,i+1 | ||
31 | while j<=n do | ||
32 | if f(x[j],x[m]) then m=j end | ||
33 | j=j+1 | ||
34 | end | ||
35 | x[i],x[m]=x[m],x[i] -- swap x[i] and x[m] | ||
36 | i=i+1 | ||
37 | end | ||
38 | end | ||
39 | |||
40 | function show(m,x) | ||
41 | io.write(m,"\n\t") | ||
42 | local i=1 | ||
43 | while x[i] do | ||
44 | io.write(x[i]) | ||
45 | i=i+1 | ||
46 | if x[i] then io.write(",") end | ||
47 | end | ||
48 | io.write("\n") | ||
49 | end | ||
50 | |||
51 | function testsorts(x) | ||
52 | local n=1 | ||
53 | while x[n] do n=n+1 end; n=n-1 -- count elements | ||
54 | show("original",x) | ||
55 | qsort(x,1,n,function (x,y) return x<y end) | ||
56 | show("after quicksort",x) | ||
57 | selectionsort(x,n,function (x,y) return x>y end) | ||
58 | show("after reverse selection sort",x) | ||
59 | qsort(x,1,n,function (x,y) return x<y end) | ||
60 | show("after quicksort again",x) | ||
61 | end | ||
62 | |||
63 | -- array to be sorted | ||
64 | x={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"} | ||
65 | |||
66 | testsorts(x) | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/table.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/table.lua new file mode 100644 index 0000000..235089c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/table.lua | |||
@@ -0,0 +1,12 @@ | |||
1 | -- make table, grouping all data for the same item | ||
2 | -- input is 2 columns (item, data) | ||
3 | |||
4 | local A | ||
5 | while 1 do | ||
6 | local l=io.read() | ||
7 | if l==nil then break end | ||
8 | local _,_,a,b=string.find(l,'"?([_%w]+)"?%s*(.*)$') | ||
9 | if a~=A then A=a io.write("\n",a,":") end | ||
10 | io.write(" ",b) | ||
11 | end | ||
12 | io.write("\n") | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/trace-calls.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/trace-calls.lua new file mode 100644 index 0000000..63c8b8f --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.0/trace-calls.lua | |||
@@ -0,0 +1,32 @@ | |||
1 | -- trace calls | ||
2 | -- example: lua -ltrace-calls.lua bisect.lua | ||
3 | |||
4 | local level=0 | ||
5 | |||
6 | function hook(event) | ||
7 | local t=debug.getinfo(3) | ||
8 | io.write(level," >>> ",string.rep(" ",level)) | ||
9 | if t~=nil and t.currentline>=0 then io.write(t.short_src,":",t.currentline," ") end | ||
10 | t=debug.getinfo(2) | ||
11 | if event=="call" then | ||
12 | level=level+1 | ||
13 | else | ||
14 | level=level-1 if level<0 then level=0 end | ||
15 | end | ||
16 | if t.what=="main" then | ||
17 | if event=="call" then | ||
18 | io.write("begin ",t.short_src) | ||
19 | else | ||
20 | io.write("end ",t.short_src) | ||
21 | end | ||
22 | elseif t.what=="Lua" then | ||
23 | -- table.foreach(t,print) | ||
24 | io.write(event," ",t.name or "(Lua)"," <",t.linedefined,":",t.short_src,">") | ||
25 | else | ||
26 | io.write(event," ",t.name or "(C)"," [",t.what,"] ") | ||
27 | end | ||
28 | io.write("\n") | ||
29 | end | ||
30 | |||
31 | debug.sethook(hook,"cr") | ||
32 | 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 @@ | |||
1 | -- trace assigments to global variables | ||
2 | |||
3 | do | ||
4 | -- a tostring that quotes strings. note the use of the original tostring. | ||
5 | local _tostring=tostring | ||
6 | local tostring=function(a) | ||
7 | if type(a)=="string" then | ||
8 | return string.format("%q",a) | ||
9 | else | ||
10 | return _tostring(a) | ||
11 | end | ||
12 | end | ||
13 | |||
14 | local log=function (name,old,new) | ||
15 | local t=debug.getinfo(3,"Sl") | ||
16 | local line=t.currentline | ||
17 | io.write(t.short_src) | ||
18 | if line>=0 then io.write(":",line) end | ||
19 | io.write(": ",name," is now ",tostring(new)," (was ",tostring(old),")","\n") | ||
20 | end | ||
21 | |||
22 | local g={} | ||
23 | local set=function (t,name,value) | ||
24 | log(name,g[name],value) | ||
25 | g[name]=value | ||
26 | end | ||
27 | setmetatable(getfenv(),{__index=g,__newindex=set}) | ||
28 | end | ||
29 | |||
30 | -- an example | ||
31 | |||
32 | a=1 | ||
33 | b=2 | ||
34 | a=10 | ||
35 | b=20 | ||
36 | b=nil | ||
37 | b=200 | ||
38 | 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 @@ | |||
1 | -- catch "undefined" global variables | ||
2 | |||
3 | local f=function (t,i) error("undefined global variable `"..i.."'",2) end | ||
4 | setmetatable(getfenv(),{__index=f}) | ||
5 | |||
6 | -- an example | ||
7 | a=1 | ||
8 | c=3 | ||
9 | 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 @@ | |||
1 | -- hex dump | ||
2 | -- usage: lua xd.lua < file | ||
3 | |||
4 | local offset=0 | ||
5 | |||
6 | while 1 do | ||
7 | local s=io.read(16) | ||
8 | if s==nil then return end | ||
9 | io.write(string.format("%08X ",offset)) | ||
10 | string.gsub(s,"(.)",function (c) io.write(string.format("%02X ",string.byte(c))) end) | ||
11 | io.write(string.rep(" ",3*(16-string.len(s)))) | ||
12 | io.write(" ",string.gsub(s,"%c","."),"\n") | ||
13 | offset=offset+16 | ||
14 | 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 @@ | |||
1 | -- bisection method for solving non-linear equations | ||
2 | |||
3 | delta=1e-6 -- tolerance | ||
4 | |||
5 | function bisect(f,a,b,fa,fb) | ||
6 | local c=(a+b)/2 | ||
7 | io.write(n," c=",c," a=",a," b=",b,"\n") | ||
8 | if c==a or c==b or math.abs(a-b)<delta then return c,b-a end | ||
9 | n=n+1 | ||
10 | local fc=f(c) | ||
11 | if fa*fc<0 then return bisect(f,a,c,fa,fc) else return bisect(f,c,b,fc,fb) end | ||
12 | end | ||
13 | |||
14 | -- find root of f in the inverval [a,b]. needs f(a)*f(b)<0 | ||
15 | function solve(f,a,b) | ||
16 | n=0 | ||
17 | local z,e=bisect(f,a,b,f(a),f(b)) | ||
18 | io.write(string.format("after %d steps, root is %.17g with error %.1e, f=%.1e\n",n,z,e,f(z))) | ||
19 | end | ||
20 | |||
21 | -- our function | ||
22 | function f(x) | ||
23 | return x*x*x-x-1 | ||
24 | end | ||
25 | |||
26 | -- find zero in [1,2] | ||
27 | solve(f,1,2) | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/cf.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/cf.lua new file mode 100644 index 0000000..8cda54b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/cf.lua | |||
@@ -0,0 +1,16 @@ | |||
1 | -- temperature conversion table (celsius to farenheit) | ||
2 | |||
3 | for c0=-20,50-1,10 do | ||
4 | io.write("C ") | ||
5 | for c=c0,c0+10-1 do | ||
6 | io.write(string.format("%3.0f ",c)) | ||
7 | end | ||
8 | io.write("\n") | ||
9 | |||
10 | io.write("F ") | ||
11 | for c=c0,c0+10-1 do | ||
12 | f=(9/5)*c+32 | ||
13 | io.write(string.format("%3.0f ",f)) | ||
14 | end | ||
15 | io.write("\n\n") | ||
16 | end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/echo.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/echo.lua new file mode 100644 index 0000000..4313439 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/echo.lua | |||
@@ -0,0 +1,5 @@ | |||
1 | -- echo command line arguments | ||
2 | |||
3 | for i=0,table.getn(arg) do | ||
4 | print(i,arg[i]) | ||
5 | end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/env.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/env.lua new file mode 100644 index 0000000..9e62a57 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/env.lua | |||
@@ -0,0 +1,7 @@ | |||
1 | -- read environment variables as if they were global variables | ||
2 | |||
3 | local f=function (t,i) return os.getenv(i) end | ||
4 | setmetatable(getfenv(),{__index=f}) | ||
5 | |||
6 | -- an example | ||
7 | print(a,USER,PATH) | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/factorial.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/factorial.lua new file mode 100644 index 0000000..7c4cf0f --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/factorial.lua | |||
@@ -0,0 +1,32 @@ | |||
1 | -- function closures are powerful | ||
2 | |||
3 | -- traditional fixed-point operator from functional programming | ||
4 | Y = function (g) | ||
5 | local a = function (f) return f(f) end | ||
6 | return a(function (f) | ||
7 | return g(function (x) | ||
8 | local c=f(f) | ||
9 | return c(x) | ||
10 | end) | ||
11 | end) | ||
12 | end | ||
13 | |||
14 | |||
15 | -- factorial without recursion | ||
16 | F = function (f) | ||
17 | return function (n) | ||
18 | if n == 0 then return 1 | ||
19 | else return n*f(n-1) end | ||
20 | end | ||
21 | end | ||
22 | |||
23 | factorial = Y(F) -- factorial is the fixed point of F | ||
24 | |||
25 | -- now test it | ||
26 | function test(x) | ||
27 | io.write(x,"! = ",factorial(x),"\n") | ||
28 | end | ||
29 | |||
30 | for n=0,16 do | ||
31 | test(n) | ||
32 | end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/fib.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/fib.lua new file mode 100644 index 0000000..97a921b --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/fib.lua | |||
@@ -0,0 +1,40 @@ | |||
1 | -- fibonacci function with cache | ||
2 | |||
3 | -- very inefficient fibonacci function | ||
4 | function fib(n) | ||
5 | N=N+1 | ||
6 | if n<2 then | ||
7 | return n | ||
8 | else | ||
9 | return fib(n-1)+fib(n-2) | ||
10 | end | ||
11 | end | ||
12 | |||
13 | -- a general-purpose value cache | ||
14 | function cache(f) | ||
15 | local c={} | ||
16 | return function (x) | ||
17 | local y=c[x] | ||
18 | if not y then | ||
19 | y=f(x) | ||
20 | c[x]=y | ||
21 | end | ||
22 | return y | ||
23 | end | ||
24 | end | ||
25 | |||
26 | -- run and time it | ||
27 | function test(s,f) | ||
28 | N=0 | ||
29 | local c=os.clock() | ||
30 | local v=f(n) | ||
31 | local t=os.clock()-c | ||
32 | print(s,n,v,t,N) | ||
33 | end | ||
34 | |||
35 | n=arg[1] or 24 -- for other values, do lua fib.lua XX | ||
36 | n=tonumber(n) | ||
37 | print("","n","value","time","evals") | ||
38 | test("plain",fib) | ||
39 | fib=cache(fib) | ||
40 | test("cached",fib) | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/fibfor.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/fibfor.lua new file mode 100644 index 0000000..8bbba39 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/fibfor.lua | |||
@@ -0,0 +1,13 @@ | |||
1 | -- example of for with generator functions | ||
2 | |||
3 | function generatefib (n) | ||
4 | return coroutine.wrap(function () | ||
5 | local a,b = 1, 1 | ||
6 | while a <= n do | ||
7 | coroutine.yield(a) | ||
8 | a, b = b, a+b | ||
9 | end | ||
10 | end) | ||
11 | end | ||
12 | |||
13 | for i in generatefib(1000) do print(i) end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/globals.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/globals.lua new file mode 100644 index 0000000..d4c20e1 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/globals.lua | |||
@@ -0,0 +1,13 @@ | |||
1 | -- reads luac listings and reports global variable usage | ||
2 | -- lines where a global is written to are marked with "*" | ||
3 | -- typical usage: luac -p -l file.lua | lua globals.lua | sort | lua table.lua | ||
4 | |||
5 | while 1 do | ||
6 | local s=io.read() | ||
7 | if s==nil then break end | ||
8 | local ok,_,l,op,g=string.find(s,"%[%-?(%d*)%]%s*([GS])ETGLOBAL.-;%s+(.*)$") | ||
9 | if ok then | ||
10 | if op=="S" then op="*" else op="" end | ||
11 | io.write(g,"\t",l,op,"\n") | ||
12 | end | ||
13 | end | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/hello.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/hello.lua new file mode 100644 index 0000000..0925498 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/hello.lua | |||
@@ -0,0 +1,3 @@ | |||
1 | -- the first program in every language | ||
2 | |||
3 | io.write("Hello world, from ",_VERSION,"!\n") | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/life.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/life.lua new file mode 100644 index 0000000..911d9fe --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/life.lua | |||
@@ -0,0 +1,111 @@ | |||
1 | -- life.lua | ||
2 | -- original by Dave Bollinger <DBollinger@compuserve.com> posted to lua-l | ||
3 | -- modified to use ANSI terminal escape sequences | ||
4 | -- modified to use for instead of while | ||
5 | |||
6 | local write=io.write | ||
7 | |||
8 | ALIVE="¥" DEAD="þ" | ||
9 | ALIVE="O" DEAD="-" | ||
10 | |||
11 | function delay() -- NOTE: SYSTEM-DEPENDENT, adjust as necessary | ||
12 | for i=1,10000 do end | ||
13 | -- local i=os.clock()+1 while(os.clock()<i) do end | ||
14 | end | ||
15 | |||
16 | function ARRAY2D(w,h) | ||
17 | local t = {w=w,h=h} | ||
18 | for y=1,h do | ||
19 | t[y] = {} | ||
20 | for x=1,w do | ||
21 | t[y][x]=0 | ||
22 | end | ||
23 | end | ||
24 | return t | ||
25 | end | ||
26 | |||
27 | _CELLS = {} | ||
28 | |||
29 | -- give birth to a "shape" within the cell array | ||
30 | function _CELLS:spawn(shape,left,top) | ||
31 | for y=0,shape.h-1 do | ||
32 | for x=0,shape.w-1 do | ||
33 | self[top+y][left+x] = shape[y*shape.w+x+1] | ||
34 | end | ||
35 | end | ||
36 | end | ||
37 | |||
38 | -- run the CA and produce the next generation | ||
39 | function _CELLS:evolve(next) | ||
40 | local ym1,y,yp1,yi=self.h-1,self.h,1,self.h | ||
41 | while yi > 0 do | ||
42 | local xm1,x,xp1,xi=self.w-1,self.w,1,self.w | ||
43 | while xi > 0 do | ||
44 | local sum = self[ym1][xm1] + self[ym1][x] + self[ym1][xp1] + | ||
45 | self[y][xm1] + self[y][xp1] + | ||
46 | self[yp1][xm1] + self[yp1][x] + self[yp1][xp1] | ||
47 | next[y][x] = ((sum==2) and self[y][x]) or ((sum==3) and 1) or 0 | ||
48 | xm1,x,xp1,xi = x,xp1,xp1+1,xi-1 | ||
49 | end | ||
50 | ym1,y,yp1,yi = y,yp1,yp1+1,yi-1 | ||
51 | end | ||
52 | end | ||
53 | |||
54 | -- output the array to screen | ||
55 | function _CELLS:draw() | ||
56 | local out="" -- accumulate to reduce flicker | ||
57 | for y=1,self.h do | ||
58 | for x=1,self.w do | ||
59 | out=out..(((self[y][x]>0) and ALIVE) or DEAD) | ||
60 | end | ||
61 | out=out.."\n" | ||
62 | end | ||
63 | write(out) | ||
64 | end | ||
65 | |||
66 | -- constructor | ||
67 | function CELLS(w,h) | ||
68 | local c = ARRAY2D(w,h) | ||
69 | c.spawn = _CELLS.spawn | ||
70 | c.evolve = _CELLS.evolve | ||
71 | c.draw = _CELLS.draw | ||
72 | return c | ||
73 | end | ||
74 | |||
75 | -- | ||
76 | -- shapes suitable for use with spawn() above | ||
77 | -- | ||
78 | HEART = { 1,0,1,1,0,1,1,1,1; w=3,h=3 } | ||
79 | GLIDER = { 0,0,1,1,0,1,0,1,1; w=3,h=3 } | ||
80 | EXPLODE = { 0,1,0,1,1,1,1,0,1,0,1,0; w=3,h=4 } | ||
81 | 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 } | ||
82 | 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 } | ||
83 | |||
84 | -- the main routine | ||
85 | function LIFE(w,h) | ||
86 | -- create two arrays | ||
87 | local thisgen = CELLS(w,h) | ||
88 | local nextgen = CELLS(w,h) | ||
89 | |||
90 | -- create some life | ||
91 | -- about 1000 generations of fun, then a glider steady-state | ||
92 | thisgen:spawn(GLIDER,5,4) | ||
93 | thisgen:spawn(EXPLODE,25,10) | ||
94 | thisgen:spawn(FISH,4,12) | ||
95 | |||
96 | -- run until break | ||
97 | local gen=1 | ||
98 | write("\027[2J") -- ANSI clear screen | ||
99 | while 1 do | ||
100 | thisgen:evolve(nextgen) | ||
101 | thisgen,nextgen = nextgen,thisgen | ||
102 | write("\027[H") -- ANSI home cursor | ||
103 | thisgen:draw() | ||
104 | write("Life - generation ",gen,"\n") | ||
105 | gen=gen+1 | ||
106 | if gen>2000 then break end | ||
107 | --delay() -- no delay | ||
108 | end | ||
109 | end | ||
110 | |||
111 | 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 @@ | |||
1 | -- bare-bones luac in Lua | ||
2 | -- usage: lua luac.lua file.lua | ||
3 | |||
4 | assert(arg[1]~=nil and arg[2]==nil,"usage: lua luac.lua file.lua") | ||
5 | f=assert(io.open("luac.out","wb")) | ||
6 | assert(f:write(string.dump(assert(loadfile(arg[1]))))) | ||
7 | 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 @@ | |||
1 | -- an implementation of printf | ||
2 | |||
3 | function printf(...) | ||
4 | io.write(string.format(...)) | ||
5 | end | ||
6 | |||
7 | 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 @@ | |||
1 | -- make global variables readonly | ||
2 | |||
3 | local f=function (t,i) error("cannot redefine global variable `"..i.."'",2) end | ||
4 | local g={} | ||
5 | local G=getfenv() | ||
6 | setmetatable(g,{__index=G,__newindex=f}) | ||
7 | setfenv(1,g) | ||
8 | |||
9 | -- an example | ||
10 | rawset(g,"x",3) | ||
11 | x=2 | ||
12 | 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 @@ | |||
1 | -- the sieve of of Eratosthenes programmed with coroutines | ||
2 | -- typical usage: lua -e N=1000 sieve.lua | column | ||
3 | |||
4 | -- generate all the numbers from 2 to n | ||
5 | function gen (n) | ||
6 | return coroutine.wrap(function () | ||
7 | for i=2,n do coroutine.yield(i) end | ||
8 | end) | ||
9 | end | ||
10 | |||
11 | -- filter the numbers generated by `g', removing multiples of `p' | ||
12 | function filter (p, g) | ||
13 | return coroutine.wrap(function () | ||
14 | while 1 do | ||
15 | local n = g() | ||
16 | if n == nil then return end | ||
17 | if math.mod(n, p) ~= 0 then coroutine.yield(n) end | ||
18 | end | ||
19 | end) | ||
20 | end | ||
21 | |||
22 | N=N or 1000 -- from command line | ||
23 | x = gen(N) -- generate primes up to N | ||
24 | while 1 do | ||
25 | local n = x() -- pick a number until done | ||
26 | if n == nil then break end | ||
27 | print(n) -- must be a prime number | ||
28 | x = filter(n, x) -- now remove its multiples | ||
29 | 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 @@ | |||
1 | -- two implementations of a sort function | ||
2 | -- this is an example only. Lua has now a built-in function "sort" | ||
3 | |||
4 | -- extracted from Programming Pearls, page 110 | ||
5 | function qsort(x,l,u,f) | ||
6 | if l<u then | ||
7 | local m=math.random(u-(l-1))+l-1 -- choose a random pivot in range l..u | ||
8 | x[l],x[m]=x[m],x[l] -- swap pivot to first position | ||
9 | local t=x[l] -- pivot value | ||
10 | m=l | ||
11 | local i=l+1 | ||
12 | while i<=u do | ||
13 | -- invariant: x[l+1..m] < t <= x[m+1..i-1] | ||
14 | if f(x[i],t) then | ||
15 | m=m+1 | ||
16 | x[m],x[i]=x[i],x[m] -- swap x[i] and x[m] | ||
17 | end | ||
18 | i=i+1 | ||
19 | end | ||
20 | x[l],x[m]=x[m],x[l] -- swap pivot to a valid place | ||
21 | -- x[l+1..m-1] < x[m] <= x[m+1..u] | ||
22 | qsort(x,l,m-1,f) | ||
23 | qsort(x,m+1,u,f) | ||
24 | end | ||
25 | end | ||
26 | |||
27 | function selectionsort(x,n,f) | ||
28 | local i=1 | ||
29 | while i<=n do | ||
30 | local m,j=i,i+1 | ||
31 | while j<=n do | ||
32 | if f(x[j],x[m]) then m=j end | ||
33 | j=j+1 | ||
34 | end | ||
35 | x[i],x[m]=x[m],x[i] -- swap x[i] and x[m] | ||
36 | i=i+1 | ||
37 | end | ||
38 | end | ||
39 | |||
40 | function show(m,x) | ||
41 | io.write(m,"\n\t") | ||
42 | local i=1 | ||
43 | while x[i] do | ||
44 | io.write(x[i]) | ||
45 | i=i+1 | ||
46 | if x[i] then io.write(",") end | ||
47 | end | ||
48 | io.write("\n") | ||
49 | end | ||
50 | |||
51 | function testsorts(x) | ||
52 | local n=1 | ||
53 | while x[n] do n=n+1 end; n=n-1 -- count elements | ||
54 | show("original",x) | ||
55 | qsort(x,1,n,function (x,y) return x<y end) | ||
56 | show("after quicksort",x) | ||
57 | selectionsort(x,n,function (x,y) return x>y end) | ||
58 | show("after reverse selection sort",x) | ||
59 | qsort(x,1,n,function (x,y) return x<y end) | ||
60 | show("after quicksort again",x) | ||
61 | end | ||
62 | |||
63 | -- array to be sorted | ||
64 | x={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"} | ||
65 | |||
66 | testsorts(x) | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/table.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/table.lua new file mode 100644 index 0000000..235089c --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/table.lua | |||
@@ -0,0 +1,12 @@ | |||
1 | -- make table, grouping all data for the same item | ||
2 | -- input is 2 columns (item, data) | ||
3 | |||
4 | local A | ||
5 | while 1 do | ||
6 | local l=io.read() | ||
7 | if l==nil then break end | ||
8 | local _,_,a,b=string.find(l,'"?([_%w]+)"?%s*(.*)$') | ||
9 | if a~=A then A=a io.write("\n",a,":") end | ||
10 | io.write(" ",b) | ||
11 | end | ||
12 | io.write("\n") | ||
diff --git a/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/trace-calls.lua b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/trace-calls.lua new file mode 100644 index 0000000..6d7a7b3 --- /dev/null +++ b/LuaSL/testLua/yueliang-0.4.1/test_lua/5.1/trace-calls.lua | |||
@@ -0,0 +1,32 @@ | |||
1 | -- trace calls | ||
2 | -- example: lua -ltrace-calls bisect.lua | ||
3 | |||
4 | local level=0 | ||
5 | |||
6 | local function hook(event) | ||
7 | local t=debug.getinfo(3) | ||
8 | io.write(level," >>> ",string.rep(" ",level)) | ||
9 | if t~=nil and t.currentline>=0 then io.write(t.short_src,":",t.currentline," ") end | ||
10 | t=debug.getinfo(2) | ||
11 | if event=="call" then | ||
12 | level=level+1 | ||
13 | else | ||
14 | level=level-1 if level<0 then level=0 end | ||
15 | end | ||
16 | if t.what=="main" then | ||
17 | if event=="call" then | ||
18 | io.write("begin ",t.short_src) | ||
19 | else | ||
20 | io.write("end ",t.short_src) | ||
21 | end | ||
22 | elseif t.what=="Lua" then | ||
23 | -- table.foreach(t,print) | ||
24 | io.write(event," ",t.name or "(Lua)"," <",t.linedefined,":",t.short_src,">") | ||
25 | else | ||
26 | io.write(event," ",t.name or "(C)"," [",t.what,"] ") | ||
27 | end | ||
28 | io.write("\n") | ||
29 | end | ||
30 | |||
31 | debug.sethook(hook,"cr") | ||
32 | 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 @@ | |||
1 | -- trace assigments to global variables | ||
2 | |||
3 | do | ||
4 | -- a tostring that quotes strings. note the use of the original tostring. | ||
5 | local _tostring=tostring | ||
6 | local tostring=function(a) | ||
7 | if type(a)=="string" then | ||
8 | return string.format("%q",a) | ||
9 | else | ||
10 | return _tostring(a) | ||
11 | end | ||
12 | end | ||
13 | |||
14 | local log=function (name,old,new) | ||
15 | local t=debug.getinfo(3,"Sl") | ||
16 | local line=t.currentline | ||
17 | io.write(t.short_src) | ||
18 | if line>=0 then io.write(":",line) end | ||
19 | io.write(": ",name," is now ",tostring(new)," (was ",tostring(old),")","\n") | ||
20 | end | ||
21 | |||
22 | local g={} | ||
23 | local set=function (t,name,value) | ||
24 | log(name,g[name],value) | ||
25 | g[name]=value | ||
26 | end | ||
27 | setmetatable(getfenv(),{__index=g,__newindex=set}) | ||
28 | end | ||
29 | |||
30 | -- an example | ||
31 | |||
32 | a=1 | ||
33 | b=2 | ||
34 | a=10 | ||
35 | b=20 | ||
36 | b=nil | ||
37 | b=200 | ||
38 | 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 @@ | |||
1 | -- hex dump | ||
2 | -- usage: lua xd.lua < file | ||
3 | |||
4 | local offset=0 | ||
5 | while true do | ||
6 | local s=io.read(16) | ||
7 | if s==nil then return end | ||
8 | io.write(string.format("%08X ",offset)) | ||
9 | string.gsub(s,"(.)", | ||
10 | function (c) io.write(string.format("%02X ",string.byte(c))) end) | ||
11 | io.write(string.rep(" ",3*(16-string.len(s)))) | ||
12 | io.write(" ",string.gsub(s,"%c","."),"\n") | ||
13 | offset=offset+16 | ||
14 | 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 @@ | |||
1 | test_scripts-5.*.lua | ||
2 | ---------------------- | ||
3 | |||
4 | The scripts test_scripts*.lua are for exercising the frontends. Such | ||
5 | testing is non-exhaustive, but useful all the same. | ||
6 | |||
7 | The files in the 5.0 directory are the sample scripts from the Lua 5.0.x | ||
8 | test directory. Ditto for the 5.1 directory. See the COPYRIGHT_Lua5 for | ||
9 | the copyright notice. | ||
10 | |||
11 | For example, to run the 5.0.x script tester: | ||
12 | |||
13 | >lua test_scripts-5.0.lua | ||
14 | |||
15 | Or, if you have both Lua 5.0.x and Lua 5.1.x, you can prepare two | ||
16 | binaries and run them like this: | ||
17 | |||
18 | >lua5.0 test_scripts-5.0.lua | ||
19 | >lua5.1 test_scripts-5.1.lua | ||
20 | |||
21 | If the compilation result is exact, "CORRECT" is printed, otherwise both | ||
22 | binary chunks are written to the current directory as bc1.out and | ||
23 | bc2.out. You can use a disassembly tool like ChunkSpy to generate | ||
24 | listings for both files, then they can be compared with a visual diff | ||
25 | tool. ChunkSpy 0.9.8 supports 5.0.x and 5.1.x. | ||
26 | |||
27 | For testing additional files, add the argument "ALL" like this: | ||
28 | |||
29 | >lua test_scripts-5.0.lua ALL | ||
30 | |||
31 | This will pull in additional personal script files for testing. But in | ||
32 | order to do so, you'd have to adjust the files files-other-*.txt. | ||
33 | |||
34 | Current status: | ||
35 | |||
36 | Frontend version File set Result | ||
37 | --------------------------------------------------------------------- | ||
38 | Yueliang 5.0.3 files-lua-5.0.txt ALL CORRECT | ||
39 | files-yueliang-5.0.txt ALL CORRECT | ||
40 | Yueliang 5.1.2 files-lua-5.1.txt ALL CORRECT | ||
41 | files-yueliang-5.1.txt ALL CORRECT | ||
42 | --------------------------------------------------------------------- | ||
43 | |||
44 | test_parser-5.x.lua | ||
45 | ------------------- | ||
46 | |||
47 | The script files test_parser-5.0.lua and test_parser-5.1.lua contains | ||
48 | many test cases for both parsers. There are a lot of failure cases as | ||
49 | well as pass cases in order to exercise the parsers well, though the | ||
50 | test list is not exhaustive. | ||
51 | |||
52 | test_parser-5.0.lua 503 test cases | ||
53 | test_parser-5.1.lua 524 test cases | ||
54 | |||
55 | For the actual test scripts, see test_lparser2.lua in the respective | ||
56 | test directories of each front end. The 5.0.x front end of Yueliang | ||
57 | passed all the tests in test_parser-5.0.lua without any failures, while | ||
58 | testing of the 5.1.x front end using test_parser-5.1.lua led to one | ||
59 | bug found and fixed. | ||
60 | |||
61 | For Lua 5.0.2, see Yueliang 0.1.3, which was the last release of Lua | ||
62 | 5.0.2 material. | ||
63 | |||
64 | For Lua 5.1.1, see Yueliang 0.2.1, which was the last release of Lua | ||
65 | 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 @@ | |||
1 | # these are the sample scripts found in Lua 5.0.x | ||
2 | 5.0/bisect.lua | ||
3 | 5.0/cf.lua | ||
4 | 5.0/echo.lua | ||
5 | 5.0/env.lua | ||
6 | 5.0/factorial.lua | ||
7 | 5.0/fib.lua | ||
8 | 5.0/fibfor.lua | ||
9 | 5.0/globals.lua | ||
10 | 5.0/hello.lua | ||
11 | 5.0/life.lua | ||
12 | 5.0/luac.lua | ||
13 | 5.0/printf.lua | ||
14 | 5.0/readonly.lua | ||
15 | 5.0/sieve.lua | ||
16 | 5.0/sort.lua | ||
17 | 5.0/table.lua | ||
18 | 5.0/trace-calls.lua | ||
19 | 5.0/trace-globals.lua | ||
20 | 5.0/undefined.lua | ||
21 | 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 @@ | |||
1 | # these are the sample scripts found in Lua 5.1.x | ||
2 | 5.1/bisect.lua | ||
3 | 5.1/cf.lua | ||
4 | 5.1/echo.lua | ||
5 | 5.1/env.lua | ||
6 | 5.1/factorial.lua | ||
7 | 5.1/fib.lua | ||
8 | 5.1/fibfor.lua | ||
9 | 5.1/globals.lua | ||
10 | 5.1/hello.lua | ||
11 | 5.1/life.lua | ||
12 | 5.1/luac.lua | ||
13 | 5.1/printf.lua | ||
14 | 5.1/readonly.lua | ||
15 | 5.1/sieve.lua | ||
16 | 5.1/sort.lua | ||
17 | 5.1/table.lua | ||
18 | 5.1/trace-calls.lua | ||
19 | 5.1/trace-globals.lua | ||
20 | 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 @@ | |||
1 | # these are other 5.0.x scripts found in my project directories | ||
2 | # WARNING currently out of date... | ||
3 | |||
4 | ../../SciTELuaExporters/SciTE_ExportBase.lua | ||
5 | ../../SciTELuaExporters/SciTE_ExporterABW.lua | ||
6 | ../../SciTELuaExporters/SciTE_ExporterHTML.lua | ||
7 | ../../SciTELuaExporters/SciTE_ExporterHTMLPlus.lua | ||
8 | ../../SciTELuaExporters/SciTE_ExporterODT.lua | ||
9 | ../../SciTELuaExporters/SciTE_ExporterPDF.lua | ||
10 | ../../SciTELuaExporters/SciTE_ExporterPDFPlus.lua | ||
11 | ../../SciTELuaExporters/SciTE_ExporterRTF.lua | ||
12 | ../../SciTELuaExporters/SciTE_ExporterSXW.lua | ||
13 | ../../SciTELuaExporters/SciTE_ExporterTeX.lua | ||
14 | ../../SciTELuaExporters/SciTE_ExporterTemplate.lua | ||
15 | ../../SciTELuaExporters/SciTE_ExporterXML.lua | ||
16 | ../../LuaSrcDiet/LuaSrcDiet.lua | ||
17 | ../../LuaSrcDiet/LuaSrcDiet_.lua | ||
18 | ../../ChunkBake/ChunkBake.lua | ||
19 | ../../ChunkBake/misc/TestRig.lua | ||
20 | ../../ChunkSpy/5.0.2/ChunkSpy.lua | ||
21 | ../../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 @@ | |||
1 | # these are other 5.1.x scripts found in my project directories | ||
2 | # WARNING currently out of date... | ||
3 | |||
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 @@ | |||
1 | # these are yueliang files for 5.0.x | ||
2 | |||
3 | test_scripts-5.0.lua | ||
4 | |||
5 | ../orig-5.0.3/lzio.lua | ||
6 | ../orig-5.0.3/ldump.lua | ||
7 | ../orig-5.0.3/lopcodes.lua | ||
8 | ../orig-5.0.3/llex.lua | ||
9 | ../orig-5.0.3/lparser.lua | ||
10 | ../orig-5.0.3/lcode.lua | ||
11 | ../orig-5.0.3/luac.lua | ||
12 | |||
13 | ../orig-5.0.3/test/test_lzio.lua | ||
14 | ../orig-5.0.3/test/test_ldump.lua | ||
15 | ../orig-5.0.3/test/test_llex.lua | ||
16 | ../orig-5.0.3/test/test_lparser.lua | ||
17 | ../orig-5.0.3/test/test_number.lua | ||
18 | ../orig-5.0.3/test/bench_llex.lua | ||
19 | ../orig-5.0.3/tools/call_graph.lua | ||
20 | ../orig-5.0.3/tools/sample_expr.lua | ||
21 | |||
22 | ../nat-5.0.3/lzio_mk2.lua | ||
23 | ../nat-5.0.3/lzio_mk4.lua | ||
24 | ../nat-5.0.3/llex_mk2.lua | ||
25 | ../nat-5.0.3/llex_mk3.lua | ||
26 | ../nat-5.0.3/llex_mk4.lua | ||
27 | |||
28 | ../nat-5.0.3/test/test_lzio_mk2.lua | ||
29 | ../nat-5.0.3/test/test_llex_mk2.lua | ||
30 | ../nat-5.0.3/test/test_llex_mk3.lua | ||
31 | ../nat-5.0.3/test/test_llex_mk4.lua | ||
32 | ../nat-5.0.3/test/bench_llex_mk2.lua | ||
33 | ../nat-5.0.3/test/bench_llex_mk3.lua | ||
34 | ../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 @@ | |||
1 | # these are yueliang files for 5.1.x | ||
2 | |||
3 | test_scripts-5.1.lua | ||
4 | |||
5 | ../orig-5.1.3/lzio.lua | ||
6 | ../orig-5.1.3/ldump.lua | ||
7 | ../orig-5.1.3/lopcodes.lua | ||
8 | ../orig-5.1.3/llex.lua | ||
9 | ../orig-5.1.3/lparser.lua | ||
10 | ../orig-5.1.3/lcode.lua | ||
11 | ../orig-5.1.3/luac.lua | ||
12 | |||
13 | ../orig-5.1.3/test/test_lzio.lua | ||
14 | ../orig-5.1.3/test/test_ldump.lua | ||
15 | ../orig-5.1.3/test/test_llex.lua | ||
16 | ../orig-5.1.3/test/test_lparser.lua | ||
17 | ../orig-5.1.3/test/test_number.lua | ||
18 | ../orig-5.1.3/test/bench_llex.lua | ||
19 | |||
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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_parser-5.0.lua | ||
4 | Lua 5.0.x parser test cases | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * there is no intention of properly specifying a grammar; the notes | ||
18 | -- are meant to reflect the structure of lparser so that it is easy | ||
19 | -- to locate and modify lparser if so desired | ||
20 | -- * some test may have invalid expressions but will compile, this | ||
21 | -- is because the chunk hasn't been executed yet | ||
22 | ----------------------------------------------------------------------]] | ||
23 | |||
24 | --[[-------------------------------------------------------------------- | ||
25 | -- lparser parsing structure, the Lua 5.0.x version... | ||
26 | ----------------------------------------------------------------------]] | ||
27 | -------------------------------------------------------------------- | ||
28 | -- chunk -> { stat [';'] } | ||
29 | -------------------------------------------------------------------- | ||
30 | -- stat -> DO block END | ||
31 | -- block -> chunk | ||
32 | -------------------------------------------------------------------- | ||
33 | -- stat -> breakstat | ||
34 | -- breakstat -> BREAK | ||
35 | -- * must have a loop to break | ||
36 | -- * must be last statement in a block | ||
37 | -------------------------------------------------------------------- | ||
38 | -- stat -> retstat | ||
39 | -- retstat -> RETURN explist | ||
40 | -- * must be last statement in a block | ||
41 | -------------------------------------------------------------------- | ||
42 | -- stat -> exprstat | ||
43 | -- exprstat -> primaryexp | ||
44 | -- (-> func | assignment) | ||
45 | -- * if LHS is VCALL then func, otherwise assignment | ||
46 | -- * for func, LHS is VCALL if funcargs in expression | ||
47 | -------------------------------------------------------------------- | ||
48 | -- stat -> funcstat | ||
49 | -- funcstat -> FUNCTION funcname body | ||
50 | -- funcname -> NAME {'.' NAME} [':' NAME] | ||
51 | -------------------------------------------------------------------- | ||
52 | -- body -> '(' parlist ')' chunk END | ||
53 | -- parlist -> [ param { ',' param } ] | ||
54 | -- param -> NAME | ||
55 | -- * DOTS must be the last parameter in a parlist | ||
56 | -------------------------------------------------------------------- | ||
57 | -- stat -> LOCAL localstat | ||
58 | -- LOCAL localstat -> LOCAL NAME {',' NAME} ['=' explist1] | ||
59 | -- explist1 -> expr { ',' expr } | ||
60 | -------------------------------------------------------------------- | ||
61 | -- stat -> LOCAL FUNCTION localfunc | ||
62 | -- LOCAL FUNCTION localfunc -> LOCAL FUNCTION NAME body | ||
63 | -------------------------------------------------------------------- | ||
64 | -- stat -> ifstat | ||
65 | -- ifstat -> IF cond THEN block | ||
66 | -- {ELSEIF cond THEN block} | ||
67 | -- [ELSE block] END | ||
68 | -- block -> chunk | ||
69 | -- cond -> expr | ||
70 | -------------------------------------------------------------------- | ||
71 | -- stat -> forstat | ||
72 | -- forstat -> fornum | forlist | ||
73 | -- forlist -> NAME {,NAME} IN explist1 forbody END | ||
74 | -- fornum -> NAME = exp1,exp1[,exp1] forbody END | ||
75 | -- forbody -> DO block | ||
76 | -- block -> chunk | ||
77 | -------------------------------------------------------------------- | ||
78 | -- stat -> whilestat | ||
79 | -- whilestat -> WHILE cond DO block END | ||
80 | -- block -> chunk | ||
81 | -- cond -> expr | ||
82 | -------------------------------------------------------------------- | ||
83 | -- stat -> repeatstat | ||
84 | -- repeatstat -> REPEAT block UNTIL cond | ||
85 | -- block -> chunk | ||
86 | -- cond -> expr | ||
87 | -------------------------------------------------------------------- | ||
88 | -- assignment -> ',' primaryexp assignment | ||
89 | -- | '=' explist1 | ||
90 | -- explist1 -> expr { ',' expr } | ||
91 | -- * for assignment, LHS must be LOCAL, UPVAL, GLOBAL or INDEXED | ||
92 | -------------------------------------------------------------------- | ||
93 | -- primaryexp -> prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } | ||
94 | -- prefixexp -> NAME | '(' expr ')' | ||
95 | -- funcargs -> '(' [ explist1 ] ')' | constructor | STRING | ||
96 | -- * funcargs turn an expr into a function call | ||
97 | -------------------------------------------------------------------- | ||
98 | -- expr -> subexpr | ||
99 | -- subexpr -> (UNOPR subexpr | simpleexp) { BINOPR subexpr } | ||
100 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ||
101 | -- | constructor | FUNCTION body | primaryexp | ||
102 | -------------------------------------------------------------------- | ||
103 | -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' | ||
104 | -- fieldsep -> ',' | ';' | ||
105 | -- field -> recfield | listfield | ||
106 | -- recfield -> ( NAME | '[' exp1 ']' ) = exp1 | ||
107 | -- listfield -> expr | ||
108 | -------------------------------------------------------------------- | ||
109 | |||
110 | --[[-------------------------------------------------------------------- | ||
111 | -- parser test cases, Lua 5.0.x | ||
112 | -- * uncomment string delimiter to enable syntax highlighting... | ||
113 | -- * anything that matches "^%s*%-%-" is a comment | ||
114 | -- * headings to display are "^%s*TESTS:%s*(.*)$" | ||
115 | -- * FAIL test cases should match "%s*%-%-%s*FAIL%s*$" | ||
116 | ----------------------------------------------------------------------]] | ||
117 | tests_source = [[ | ||
118 | -------------------------------------------------------------------- | ||
119 | TESTS: empty chunks | ||
120 | -------------------------------------------------------------------- | ||
121 | -- chunk -> { stat [';'] } | ||
122 | -------------------------------------------------------------------- | ||
123 | |||
124 | ; -- FAIL | ||
125 | -------------------------------------------------------------------- | ||
126 | TESTS: optional semicolon, simple local statements | ||
127 | -------------------------------------------------------------------- | ||
128 | -- stat -> LOCAL localstat | ||
129 | -- LOCAL localstat -> LOCAL NAME {',' NAME} ['=' explist1] | ||
130 | -- explist1 -> expr { ',' expr } | ||
131 | -------------------------------------------------------------------- | ||
132 | local -- FAIL | ||
133 | local; -- FAIL | ||
134 | local = -- FAIL | ||
135 | local end -- FAIL | ||
136 | local a | ||
137 | local a; | ||
138 | local a, b, c | ||
139 | local a; local b local c; | ||
140 | local a = 1 | ||
141 | local a local b = a | ||
142 | local a, b = 1, 2 | ||
143 | local a, b, c = 1, 2, 3 | ||
144 | local a, b, c = 1 | ||
145 | local a = 1, 2, 3 | ||
146 | local a, local -- FAIL | ||
147 | local 1 -- FAIL | ||
148 | local "foo" -- FAIL | ||
149 | local a = local -- FAIL | ||
150 | local a, b, = -- FAIL | ||
151 | local a, b = 1, local -- FAIL | ||
152 | local a, b = , local -- FAIL | ||
153 | -------------------------------------------------------------------- | ||
154 | TESTS: simple DO blocks | ||
155 | -------------------------------------------------------------------- | ||
156 | -- stat -> DO block END | ||
157 | -- block -> chunk | ||
158 | -------------------------------------------------------------------- | ||
159 | do -- FAIL | ||
160 | end -- FAIL | ||
161 | do end | ||
162 | do ; end -- FAIL | ||
163 | do 1 end -- FAIL | ||
164 | do "foo" end -- FAIL | ||
165 | do local a, b end | ||
166 | do local a local b end | ||
167 | do local a; local b; end | ||
168 | do local a = 1 end | ||
169 | do do end end | ||
170 | do do end; end | ||
171 | do do do end end end | ||
172 | do do do end; end; end | ||
173 | do do do return end end end | ||
174 | do end do -- FAIL | ||
175 | do end end -- FAIL | ||
176 | do return end | ||
177 | do return return end -- FAIL | ||
178 | do break end -- FAIL | ||
179 | -------------------------------------------------------------------- | ||
180 | TESTS: simple WHILE loops | ||
181 | -------------------------------------------------------------------- | ||
182 | -- stat -> whilestat | ||
183 | -- whilestat -> WHILE cond DO block END | ||
184 | -- block -> chunk | ||
185 | -- cond -> expr | ||
186 | -------------------------------------------------------------------- | ||
187 | while -- FAIL | ||
188 | while do -- FAIL | ||
189 | while = -- FAIL | ||
190 | while 1 do -- FAIL | ||
191 | while 1 do end | ||
192 | while 1 do local a end | ||
193 | while 1 do local a local b end | ||
194 | while 1 do local a; local b; end | ||
195 | while 1 do 2 end -- FAIL | ||
196 | while 1 do "foo" end -- FAIL | ||
197 | while true do end | ||
198 | while 1 do ; end -- FAIL | ||
199 | while 1 do while -- FAIL | ||
200 | while 1 end -- FAIL | ||
201 | while 1 2 do -- FAIL | ||
202 | while 1 = 2 do -- FAIL | ||
203 | while 1 do return end | ||
204 | while 1 do return return end -- FAIL | ||
205 | while 1 do do end end | ||
206 | while 1 do do return end end | ||
207 | while 1 do break end | ||
208 | while 1 do break break end -- FAIL | ||
209 | while 1 do do break end end | ||
210 | -------------------------------------------------------------------- | ||
211 | TESTS: simple REPEAT loops | ||
212 | -------------------------------------------------------------------- | ||
213 | -- stat -> repeatstat | ||
214 | -- repeatstat -> REPEAT block UNTIL cond | ||
215 | -- block -> chunk | ||
216 | -- cond -> expr | ||
217 | -------------------------------------------------------------------- | ||
218 | repeat -- FAIL | ||
219 | repeat until -- FAIL | ||
220 | repeat until 0 | ||
221 | repeat until false | ||
222 | repeat until local -- FAIL | ||
223 | repeat end -- FAIL | ||
224 | repeat 1 -- FAIL | ||
225 | repeat = -- FAIL | ||
226 | repeat local a until 1 | ||
227 | repeat local a local b until 0 | ||
228 | repeat local a; local b; until 0 | ||
229 | repeat ; until 1 -- FAIL | ||
230 | repeat 2 until 1 -- FAIL | ||
231 | repeat "foo" until 1 -- FAIL | ||
232 | repeat return until 0 | ||
233 | repeat return return until 0 -- FAIL | ||
234 | repeat break until 0 | ||
235 | repeat break break until 0 -- FAIL | ||
236 | repeat do end until 0 | ||
237 | repeat do return end until 0 | ||
238 | repeat do break end until 0 | ||
239 | -------------------------------------------------------------------- | ||
240 | TESTS: simple FOR loops | ||
241 | -------------------------------------------------------------------- | ||
242 | -- stat -> forstat | ||
243 | -- forstat -> fornum | forlist | ||
244 | -- forlist -> NAME {,NAME} IN explist1 forbody END | ||
245 | -- fornum -> NAME = exp1,exp1[,exp1] forbody END | ||
246 | -- forbody -> DO block | ||
247 | -- block -> chunk | ||
248 | -------------------------------------------------------------------- | ||
249 | for -- FAIL | ||
250 | for do -- FAIL | ||
251 | for end -- FAIL | ||
252 | for 1 -- FAIL | ||
253 | for a -- FAIL | ||
254 | for true -- FAIL | ||
255 | for a, in -- FAIL | ||
256 | for a in -- FAIL | ||
257 | for a do -- FAIL | ||
258 | for a in do -- FAIL | ||
259 | for a in b do -- FAIL | ||
260 | for a in b end -- FAIL | ||
261 | for a in b, do -- FAIL | ||
262 | for a in b do end | ||
263 | for a in b do local a local b end | ||
264 | for a in b do local a; local b; end | ||
265 | for a in b do 1 end -- FAIL | ||
266 | for a in b do "foo" end -- FAIL | ||
267 | for a b in -- FAIL | ||
268 | for a, b, c in p do end | ||
269 | for a, b, c in p, q, r do end | ||
270 | for a in 1 do end | ||
271 | for a in true do end | ||
272 | for a in "foo" do end | ||
273 | for a in b do break end | ||
274 | for a in b do break break end -- FAIL | ||
275 | for a in b do return end | ||
276 | for a in b do return return end -- FAIL | ||
277 | for a in b do do end end | ||
278 | for a in b do do break end end | ||
279 | for a in b do do return end end | ||
280 | for = -- FAIL | ||
281 | for a = -- FAIL | ||
282 | for a, b = -- FAIL | ||
283 | for a = do -- FAIL | ||
284 | for a = 1, do -- FAIL | ||
285 | for a = p, q, do -- FAIL | ||
286 | for a = p q do -- FAIL | ||
287 | for a = b do end -- FAIL | ||
288 | for a = 1, 2, 3, 4 do end -- FAIL | ||
289 | for a = p, q do end | ||
290 | for a = 1, 2 do end | ||
291 | for a = 1, 2 do local a local b end | ||
292 | for a = 1, 2 do local a; local b; end | ||
293 | for a = 1, 2 do 3 end -- FAIL | ||
294 | for a = 1, 2 do "foo" end -- FAIL | ||
295 | for a = p, q, r do end | ||
296 | for a = 1, 2, 3 do end | ||
297 | for a = p, q do break end | ||
298 | for a = p, q do break break end -- FAIL | ||
299 | for a = 1, 2 do return end | ||
300 | for a = 1, 2 do return return end -- FAIL | ||
301 | for a = p, q do do end end | ||
302 | for a = p, q do do break end end | ||
303 | for a = p, q do do return end end | ||
304 | -------------------------------------------------------------------- | ||
305 | TESTS: break statement | ||
306 | -------------------------------------------------------------------- | ||
307 | -- stat -> breakstat | ||
308 | -- breakstat -> BREAK | ||
309 | -- * must have a loop to break | ||
310 | -- * must be last statement in a block | ||
311 | -------------------------------------------------------------------- | ||
312 | break -- FAIL | ||
313 | -------------------------------------------------------------------- | ||
314 | TESTS: return statement | ||
315 | -------------------------------------------------------------------- | ||
316 | -- stat -> retstat | ||
317 | -- retstat -> RETURN explist | ||
318 | -- * must be last statement in a block | ||
319 | -------------------------------------------------------------------- | ||
320 | return | ||
321 | return; | ||
322 | return return -- FAIL | ||
323 | return 1 | ||
324 | return local -- FAIL | ||
325 | return "foo" | ||
326 | return 1, -- FAIL | ||
327 | return 1,2,3 | ||
328 | return a,b,c,d | ||
329 | return 1,2; | ||
330 | -------------------------------------------------------------------- | ||
331 | TESTS: conditional statements | ||
332 | -------------------------------------------------------------------- | ||
333 | -- stat -> ifstat | ||
334 | -- ifstat -> IF cond THEN block | ||
335 | -- {ELSEIF cond THEN block} | ||
336 | -- [ELSE block] END | ||
337 | -- block -> chunk | ||
338 | -- cond -> expr | ||
339 | -------------------------------------------------------------------- | ||
340 | if -- FAIL | ||
341 | elseif -- FAIL | ||
342 | else -- FAIL | ||
343 | then -- FAIL | ||
344 | if then -- FAIL | ||
345 | if 1 -- FAIL | ||
346 | if 1 then -- FAIL | ||
347 | if 1 else -- FAIL | ||
348 | if 1 then else -- FAIL | ||
349 | if 1 then elseif -- FAIL | ||
350 | if 1 then end | ||
351 | if 1 then local a end | ||
352 | if 1 then local a local b end | ||
353 | if 1 then local a; local b; end | ||
354 | if 1 then else end | ||
355 | if 1 then local a else local b end | ||
356 | if 1 then local a; else local b; end | ||
357 | if 1 then elseif 2 -- FAIL | ||
358 | if 1 then elseif 2 then -- FAIL | ||
359 | if 1 then elseif 2 then end | ||
360 | if 1 then local a elseif 2 then local b end | ||
361 | if 1 then local a; elseif 2 then local b; end | ||
362 | if 1 then elseif 2 then else end | ||
363 | if 1 then else if 2 then end end | ||
364 | if 1 then else if 2 then end -- FAIL | ||
365 | if 1 then break end -- FAIL | ||
366 | if 1 then return end | ||
367 | if 1 then return return end -- FAIL | ||
368 | if 1 then end; if 1 then end; | ||
369 | -------------------------------------------------------------------- | ||
370 | TESTS: function statements | ||
371 | -------------------------------------------------------------------- | ||
372 | -- stat -> funcstat | ||
373 | -- funcstat -> FUNCTION funcname body | ||
374 | -- funcname -> NAME {'.' NAME} [':' NAME] | ||
375 | -------------------------------------------------------------------- | ||
376 | -- body -> '(' parlist ')' chunk END | ||
377 | -- parlist -> [ param { ',' param } ] | ||
378 | -- param -> NAME | ||
379 | -- * DOTS must be the last parameter in a parlist | ||
380 | -------------------------------------------------------------------- | ||
381 | function -- FAIL | ||
382 | function 1 -- FAIL | ||
383 | function end -- FAIL | ||
384 | function a -- FAIL | ||
385 | function a end -- FAIL | ||
386 | function a( end -- FAIL | ||
387 | function a() end | ||
388 | function a(1 -- FAIL | ||
389 | function a("foo" -- FAIL | ||
390 | function a(p -- FAIL | ||
391 | function a(p,) -- FAIL | ||
392 | function a(p q -- FAIL | ||
393 | function a(p) end | ||
394 | function a(p,q,) end -- FAIL | ||
395 | function a(p,q,r) end | ||
396 | function a(p,q,1 -- FAIL | ||
397 | function a(p) do -- FAIL | ||
398 | function a(p) 1 end -- FAIL | ||
399 | function a(p) return end | ||
400 | function a(p) break end -- FAIL | ||
401 | function a(p) return return end -- FAIL | ||
402 | function a(p) do end end | ||
403 | function a.( -- FAIL | ||
404 | function a.1 -- FAIL | ||
405 | function a.b() end | ||
406 | function a.b, -- FAIL | ||
407 | function a.b.( -- FAIL | ||
408 | function a.b.c.d() end | ||
409 | function a: -- FAIL | ||
410 | function a:1 -- FAIL | ||
411 | function a:b() end | ||
412 | function a:b: -- FAIL | ||
413 | function a:b. -- FAIL | ||
414 | function a.b.c:d() end | ||
415 | function a(...) end | ||
416 | function a(..., -- FAIL | ||
417 | function a(p,...) end | ||
418 | function a(p,q,r,...) end | ||
419 | function a() local a local b end | ||
420 | function a() local a; local b; end | ||
421 | function a() end; function a() end; | ||
422 | -------------------------------------------------------------------- | ||
423 | TESTS: local function statements | ||
424 | -------------------------------------------------------------------- | ||
425 | -- stat -> LOCAL FUNCTION localfunc | ||
426 | -- LOCAL FUNCTION localfunc -> LOCAL FUNCTION NAME body | ||
427 | -------------------------------------------------------------------- | ||
428 | local function -- FAIL | ||
429 | local function 1 -- FAIL | ||
430 | local function end -- FAIL | ||
431 | local function a -- FAIL | ||
432 | local function a end -- FAIL | ||
433 | local function a( end -- FAIL | ||
434 | local function a() end | ||
435 | local function a(1 -- FAIL | ||
436 | local function a("foo" -- FAIL | ||
437 | local function a(p -- FAIL | ||
438 | local function a(p,) -- FAIL | ||
439 | local function a(p q -- FAIL | ||
440 | local function a(p) end | ||
441 | local function a(p,q,) end -- FAIL | ||
442 | local function a(p,q,r) end | ||
443 | local function a(p,q,1 -- FAIL | ||
444 | local function a(p) do -- FAIL | ||
445 | local function a(p) 1 end -- FAIL | ||
446 | local function a(p) return end | ||
447 | local function a(p) break end -- FAIL | ||
448 | local function a(p) return return end -- FAIL | ||
449 | local function a(p) do end end | ||
450 | local function a. -- FAIL | ||
451 | local function a: -- FAIL | ||
452 | local function a(...) end | ||
453 | local function a(..., -- FAIL | ||
454 | local function a(p,...) end | ||
455 | local function a(p,q,r,...) end | ||
456 | local function a() local a local b end | ||
457 | local function a() local a; local b; end | ||
458 | local function a() end; local function a() end; | ||
459 | -------------------------------------------------------------------- | ||
460 | -- stat -> exprstat | ||
461 | -- exprstat -> primaryexp | ||
462 | -- (-> func | assignment) | ||
463 | -- * if LHS is VCALL then func, otherwise assignment | ||
464 | -- * for func, LHS is VCALL if funcargs in expression | ||
465 | -------------------------------------------------------------------- | ||
466 | TESTS: assignments | ||
467 | -------------------------------------------------------------------- | ||
468 | -- assignment -> ',' primaryexp assignment | ||
469 | -- | '=' explist1 | ||
470 | -- explist1 -> expr { ',' expr } | ||
471 | -- * for assignment, LHS must be LOCAL, UPVAL, GLOBAL or INDEXED | ||
472 | -------------------------------------------------------------------- | ||
473 | a -- FAIL | ||
474 | a, -- FAIL | ||
475 | a,b,c -- FAIL | ||
476 | a,b = -- FAIL | ||
477 | a = 1 | ||
478 | a = 1,2,3 | ||
479 | a,b,c = 1 | ||
480 | a,b,c = 1,2,3 | ||
481 | a.b = 1 | ||
482 | a.b.c = 1 | ||
483 | a[b] = 1 | ||
484 | a[b][c] = 1 | ||
485 | a.b[c] = 1 | ||
486 | a[b].c = 1 | ||
487 | 0 = -- FAIL | ||
488 | "foo" = -- FAIL | ||
489 | true = -- FAIL | ||
490 | (a) = -- FAIL | ||
491 | {} = -- FAIL | ||
492 | a:b() = -- FAIL | ||
493 | a() = -- FAIL | ||
494 | a.b:c() = -- FAIL | ||
495 | a[b]() = -- FAIL | ||
496 | a = a b -- FAIL | ||
497 | a = 1 2 -- FAIL | ||
498 | a = a = 1 -- FAIL | ||
499 | -------------------------------------------------------------------- | ||
500 | TESTS: function calls | ||
501 | -------------------------------------------------------------------- | ||
502 | -- primaryexp -> prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } | ||
503 | -- prefixexp -> NAME | '(' expr ')' | ||
504 | -- funcargs -> '(' [ explist1 ] ')' | constructor | STRING | ||
505 | -- * funcargs turn an expr into a function call | ||
506 | -------------------------------------------------------------------- | ||
507 | a( -- FAIL | ||
508 | a() | ||
509 | a(1) | ||
510 | a(1,) -- FAIL | ||
511 | a(1,2,3) | ||
512 | 1() -- FAIL | ||
513 | a()() | ||
514 | a.b() | ||
515 | a[b]() | ||
516 | a.1 -- FAIL | ||
517 | a.b -- FAIL | ||
518 | a[b] -- FAIL | ||
519 | a.b.( -- FAIL | ||
520 | a.b.c() | ||
521 | a[b][c]() | ||
522 | a[b].c() | ||
523 | a.b[c]() | ||
524 | a:b() | ||
525 | a:b -- FAIL | ||
526 | a:1 -- FAIL | ||
527 | a.b:c() | ||
528 | a[b]:c() | ||
529 | a:b: -- FAIL | ||
530 | a:b():c() | ||
531 | a:b().c[d]:e() | ||
532 | a:b()[c].d:e() | ||
533 | (a)() | ||
534 | ()() -- FAIL | ||
535 | (1)() | ||
536 | ("foo")() | ||
537 | (true)() | ||
538 | (a)()() | ||
539 | (a.b)() | ||
540 | (a[b])() | ||
541 | (a).b() | ||
542 | (a)[b]() | ||
543 | (a):b() | ||
544 | (a).b[c]:d() | ||
545 | (a)[b].c:d() | ||
546 | (a):b():c() | ||
547 | (a):b().c[d]:e() | ||
548 | (a):b()[c].d:e() | ||
549 | -------------------------------------------------------------------- | ||
550 | TESTS: more function calls | ||
551 | -------------------------------------------------------------------- | ||
552 | a"foo" | ||
553 | a[[foo]] | ||
554 | a.b"foo" | ||
555 | a[b]"foo" | ||
556 | a:b"foo" | ||
557 | a{} | ||
558 | a.b{} | ||
559 | a[b]{} | ||
560 | a:b{} | ||
561 | a()"foo" | ||
562 | a"foo"() | ||
563 | a"foo".b() | ||
564 | a"foo"[b]() | ||
565 | a"foo":c() | ||
566 | a"foo""bar" | ||
567 | a"foo"{} | ||
568 | (a):b"foo".c[d]:e"bar" | ||
569 | (a):b"foo"[c].d:e"bar" | ||
570 | a(){} | ||
571 | a{}() | ||
572 | a{}.b() | ||
573 | a{}[b]() | ||
574 | a{}:c() | ||
575 | a{}"foo" | ||
576 | a{}{} | ||
577 | (a):b{}.c[d]:e{} | ||
578 | (a):b{}[c].d:e{} | ||
579 | -------------------------------------------------------------------- | ||
580 | TESTS: simple expressions | ||
581 | -------------------------------------------------------------------- | ||
582 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ||
583 | -- | constructor | FUNCTION body | primaryexp | ||
584 | -------------------------------------------------------------------- | ||
585 | a = -- FAIL | ||
586 | a = a | ||
587 | a = nil | ||
588 | a = false | ||
589 | a = 1 | ||
590 | a = "foo" | ||
591 | a = [[foo]] | ||
592 | a = {} | ||
593 | a = (a) | ||
594 | a = (nil) | ||
595 | a = (true) | ||
596 | a = (1) | ||
597 | a = ("foo") | ||
598 | a = ([[foo]]) | ||
599 | a = ({}) | ||
600 | a = a.b | ||
601 | a = a.b. -- FAIL | ||
602 | a = a.b.c | ||
603 | a = a:b -- FAIL | ||
604 | a = a[b] | ||
605 | a = a[1] | ||
606 | a = a["foo"] | ||
607 | a = a[b][c] | ||
608 | a = a.b[c] | ||
609 | a = a[b].c | ||
610 | a = (a)[b] | ||
611 | a = (a).c | ||
612 | a = () -- FAIL | ||
613 | a = a() | ||
614 | a = a.b() | ||
615 | a = a[b]() | ||
616 | a = a:b() | ||
617 | a = (a)() | ||
618 | a = (a).b() | ||
619 | a = (a)[b]() | ||
620 | a = (a):b() | ||
621 | a = a"foo" | ||
622 | a = a{} | ||
623 | a = function -- FAIL | ||
624 | a = function 1 -- FAIL | ||
625 | a = function a -- FAIL | ||
626 | a = function end -- FAIL | ||
627 | a = function( -- FAIL | ||
628 | a = function() end | ||
629 | a = function(1 -- FAIL | ||
630 | a = function(p) end | ||
631 | a = function(p,) -- FAIL | ||
632 | a = function(p q -- FAIL | ||
633 | a = function(p,q,r) end | ||
634 | a = function(p,q,1 -- FAIL | ||
635 | a = function(...) end | ||
636 | a = function(..., -- FAIL | ||
637 | a = function(p,...) end | ||
638 | a = function(p,q,r,...) end | ||
639 | -------------------------------------------------------------------- | ||
640 | TESTS: operators | ||
641 | -------------------------------------------------------------------- | ||
642 | -- expr -> subexpr | ||
643 | -- subexpr -> (UNOPR subexpr | simpleexp) { BINOPR subexpr } | ||
644 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ||
645 | -- | constructor | FUNCTION body | primaryexp | ||
646 | -------------------------------------------------------------------- | ||
647 | a = -10 | ||
648 | a = -"foo" | ||
649 | a = -a | ||
650 | a = -nil | ||
651 | a = -true | ||
652 | a = -{} | ||
653 | a = -function() end | ||
654 | a = -a() | ||
655 | a = -(a) | ||
656 | a = - -- FAIL | ||
657 | a = not 10 | ||
658 | a = not "foo" | ||
659 | a = not a | ||
660 | a = not nil | ||
661 | a = not true | ||
662 | a = not {} | ||
663 | a = not function() end | ||
664 | a = not a() | ||
665 | a = not (a) | ||
666 | a = not -- FAIL | ||
667 | a = 1 + 2; a = 1 - 2 | ||
668 | a = 1 * 2; a = 1 / 2 | ||
669 | a = 1 ^ 2; a = 1 .. 2 | ||
670 | a = 1 + -- FAIL | ||
671 | a = 1 .. -- FAIL | ||
672 | a = 1 * / -- FAIL | ||
673 | a = 1 + -2; a = 1 - -2 | ||
674 | a = 1 * - -- FAIL | ||
675 | a = 1 * not 2; a = 1 / not 2 | ||
676 | a = 1 / not -- FAIL | ||
677 | a = 1 + 2 - 3 * 4 / 5 ^ 6 | ||
678 | a = ((1 + 2) - 3) * (4 / (5 ^ 6)) | ||
679 | a = (1 + (2 - (3 * (4 / (5 ^ ((6))))))) | ||
680 | a = ((1 -- FAIL | ||
681 | a = ((1 + 2) -- FAIL | ||
682 | a = 1) -- FAIL | ||
683 | a = a + b - c | ||
684 | a = "foo" + "bar" | ||
685 | a = "foo".."bar".."baz" | ||
686 | a = true + false - nil | ||
687 | a = {} * {} | ||
688 | a = function() end / function() end | ||
689 | a = a() ^ b() | ||
690 | -------------------------------------------------------------------- | ||
691 | TESTS: more operators | ||
692 | -------------------------------------------------------------------- | ||
693 | a = 1 == 2; a = 1 ~= 2 | ||
694 | a = 1 < 2; a = 1 <= 2 | ||
695 | a = 1 > 2; a = 1 >= 2 | ||
696 | a = 1 < 2 < 3 | ||
697 | a = 1 >= 2 >= 3 | ||
698 | a = 1 == -- FAIL | ||
699 | a = ~= 2 -- FAIL | ||
700 | a = "foo" == "bar" | ||
701 | a = "foo" > "bar" | ||
702 | a = a ~= b | ||
703 | a = true == false | ||
704 | a = 1 and 2; a = 1 or 2 | ||
705 | a = 1 and -- FAIL | ||
706 | a = or 1 -- FAIL | ||
707 | a = 1 and 2 and 3 | ||
708 | a = 1 or 2 or 3 | ||
709 | a = 1 and 2 or 3 | ||
710 | a = a and b or c | ||
711 | a = a() and (b)() or c.d | ||
712 | a = "foo" and "bar" | ||
713 | a = true or false | ||
714 | a = {} and {} or {} | ||
715 | a = (1) and ("foo") or (nil) | ||
716 | a = function() end == function() end | ||
717 | a = function() end or function() end | ||
718 | -------------------------------------------------------------------- | ||
719 | TESTS: constructors | ||
720 | -------------------------------------------------------------------- | ||
721 | -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' | ||
722 | -- fieldsep -> ',' | ';' | ||
723 | -- field -> recfield | listfield | ||
724 | -- recfield -> ( NAME | '[' exp1 ']' ) = exp1 | ||
725 | -- listfield -> expr | ||
726 | -------------------------------------------------------------------- | ||
727 | a = { -- FAIL | ||
728 | a = {} | ||
729 | a = {,} -- FAIL | ||
730 | a = {;} | ||
731 | a = {,,} -- FAIL | ||
732 | a = {;;} -- FAIL | ||
733 | a = {{ -- FAIL | ||
734 | a = {{{}}} | ||
735 | a = {{},{},{{}},} | ||
736 | a = { 1 } | ||
737 | a = { 1, } | ||
738 | a = { 1; } | ||
739 | a = { 1, 2 } | ||
740 | a = { a, b, c, } | ||
741 | a = { true; false, nil; } | ||
742 | a = { a.b, a[b]; a:c(), } | ||
743 | a = { 1 + 2, a > b, "a" or "b" } | ||
744 | a = { a=1, } | ||
745 | a = { a=1, b="foo", c=nil } | ||
746 | a = { a -- FAIL | ||
747 | a = { a= -- FAIL | ||
748 | a = { a=, -- FAIL | ||
749 | a = { a=; -- FAIL | ||
750 | a = { 1, a="foo" -- FAIL | ||
751 | a = { 1, a="foo"; b={}, d=true; } | ||
752 | a = { [ -- FAIL | ||
753 | a = { [1 -- FAIL | ||
754 | a = { [1] -- FAIL | ||
755 | a = { [a]= -- FAIL | ||
756 | a = { ["foo"]="bar" } | ||
757 | a = { [1]=a, [2]=b, } | ||
758 | a = { true, a=1; ["foo"]="bar", } | ||
759 | ]] | ||
760 | |||
761 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_parser-5.1.lua | ||
4 | Lua 5.1.x parser test cases | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- Notes: | ||
17 | -- * there is no intention of properly specifying a grammar; the notes | ||
18 | -- are meant to reflect the structure of lparser so that it is easy | ||
19 | -- to locate and modify lparser if so desired | ||
20 | -- * some test may have invalid expressions but will compile, this | ||
21 | -- is because the chunk hasn't been executed yet | ||
22 | -- | ||
23 | -- Changed in 5.1.x: | ||
24 | -- * added ..., %, # cases | ||
25 | ----------------------------------------------------------------------]] | ||
26 | |||
27 | --[[-------------------------------------------------------------------- | ||
28 | -- lparser parsing structure, the Lua 5.1.x version... | ||
29 | ----------------------------------------------------------------------]] | ||
30 | -------------------------------------------------------------------- | ||
31 | -- chunk -> { stat [';'] } | ||
32 | -------------------------------------------------------------------- | ||
33 | -- stat -> DO block END | ||
34 | -- block -> chunk | ||
35 | -------------------------------------------------------------------- | ||
36 | -- stat -> breakstat | ||
37 | -- breakstat -> BREAK | ||
38 | -- * must have a loop to break | ||
39 | -- * must be last statement in a block | ||
40 | -------------------------------------------------------------------- | ||
41 | -- stat -> retstat | ||
42 | -- retstat -> RETURN explist | ||
43 | -- * must be last statement in a block | ||
44 | -------------------------------------------------------------------- | ||
45 | -- stat -> exprstat | ||
46 | -- exprstat -> primaryexp | ||
47 | -- (-> func | assignment) | ||
48 | -- * if LHS is VCALL then func, otherwise assignment | ||
49 | -- * for func, LHS is VCALL if funcargs in expression | ||
50 | -------------------------------------------------------------------- | ||
51 | -- stat -> funcstat | ||
52 | -- funcstat -> FUNCTION funcname body | ||
53 | -- funcname -> NAME {'.' NAME} [':' NAME] | ||
54 | -------------------------------------------------------------------- | ||
55 | -- body -> '(' parlist ')' chunk END | ||
56 | -- parlist -> [ param { ',' param } ] | ||
57 | -- param -> NAME | ||
58 | -- * DOTS must be the last parameter in a parlist | ||
59 | -------------------------------------------------------------------- | ||
60 | -- stat -> LOCAL localstat | ||
61 | -- LOCAL localstat -> LOCAL NAME {',' NAME} ['=' explist1] | ||
62 | -- explist1 -> expr { ',' expr } | ||
63 | -------------------------------------------------------------------- | ||
64 | -- stat -> LOCAL FUNCTION localfunc | ||
65 | -- LOCAL FUNCTION localfunc -> LOCAL FUNCTION NAME body | ||
66 | -------------------------------------------------------------------- | ||
67 | -- stat -> ifstat | ||
68 | -- ifstat -> IF cond THEN block | ||
69 | -- {ELSEIF cond THEN block} | ||
70 | -- [ELSE block] END | ||
71 | -- block -> chunk | ||
72 | -- cond -> expr | ||
73 | -------------------------------------------------------------------- | ||
74 | -- stat -> forstat | ||
75 | -- forstat -> fornum | forlist | ||
76 | -- forlist -> NAME {,NAME} IN explist1 forbody END | ||
77 | -- fornum -> NAME = exp1,exp1[,exp1] forbody END | ||
78 | -- forbody -> DO block | ||
79 | -- block -> chunk | ||
80 | -------------------------------------------------------------------- | ||
81 | -- stat -> whilestat | ||
82 | -- whilestat -> WHILE cond DO block END | ||
83 | -- block -> chunk | ||
84 | -- cond -> expr | ||
85 | -------------------------------------------------------------------- | ||
86 | -- stat -> repeatstat | ||
87 | -- repeatstat -> REPEAT chunk UNTIL cond | ||
88 | -- cond -> expr | ||
89 | -------------------------------------------------------------------- | ||
90 | -- assignment -> ',' primaryexp assignment | ||
91 | -- | '=' explist1 | ||
92 | -- explist1 -> expr { ',' expr } | ||
93 | -- * for assignment, LHS must be LOCAL, UPVAL, GLOBAL or INDEXED | ||
94 | -------------------------------------------------------------------- | ||
95 | -- primaryexp -> prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } | ||
96 | -- prefixexp -> NAME | '(' expr ')' | ||
97 | -- funcargs -> '(' [ explist1 ] ')' | constructor | STRING | ||
98 | -- * funcargs turn an expr into a function call | ||
99 | -------------------------------------------------------------------- | ||
100 | -- expr -> subexpr | ||
101 | -- subexpr -> (UNOPR subexpr | simpleexp) { BINOPR subexpr } | ||
102 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | ||
103 | -- | constructor | FUNCTION body | primaryexp | ||
104 | -------------------------------------------------------------------- | ||
105 | -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' | ||
106 | -- fieldsep -> ',' | ';' | ||
107 | -- field -> recfield | listfield | ||
108 | -- recfield -> ( NAME | '[' exp1 ']' ) = exp1 | ||
109 | -- listfield -> expr | ||
110 | -------------------------------------------------------------------- | ||
111 | |||
112 | --[[-------------------------------------------------------------------- | ||
113 | -- parser test cases, Lua 5.1.x | ||
114 | -- * uncomment string delimiter to enable syntax highlighting... | ||
115 | -- * anything that matches "^%s*%-%-" is a comment | ||
116 | -- * headings to display are "^%s*TESTS:%s*(.*)$" | ||
117 | -- * FAIL test cases should match "%s*%-%-%s*FAIL%s*$" | ||
118 | ----------------------------------------------------------------------]] | ||
119 | tests_source = [=[ | ||
120 | -------------------------------------------------------------------- | ||
121 | TESTS: empty chunks | ||
122 | -------------------------------------------------------------------- | ||
123 | -- chunk -> { stat [';'] } | ||
124 | -------------------------------------------------------------------- | ||
125 | |||
126 | ; -- FAIL | ||
127 | -------------------------------------------------------------------- | ||
128 | TESTS: optional semicolon, simple local statements | ||
129 | -------------------------------------------------------------------- | ||
130 | -- stat -> LOCAL localstat | ||
131 | -- LOCAL localstat -> LOCAL NAME {',' NAME} ['=' explist1] | ||
132 | -- explist1 -> expr { ',' expr } | ||
133 | -------------------------------------------------------------------- | ||
134 | local -- FAIL | ||
135 | local; -- FAIL | ||
136 | local = -- FAIL | ||
137 | local end -- FAIL | ||
138 | local a | ||
139 | local a; | ||
140 | local a, b, c | ||
141 | local a; local b local c; | ||
142 | local a = 1 | ||
143 | local a local b = a | ||
144 | local a, b = 1, 2 | ||
145 | local a, b, c = 1, 2, 3 | ||
146 | local a, b, c = 1 | ||
147 | local a = 1, 2, 3 | ||
148 | local a, local -- FAIL | ||
149 | local 1 -- FAIL | ||
150 | local "foo" -- FAIL | ||
151 | local a = local -- FAIL | ||
152 | local a, b, = -- FAIL | ||
153 | local a, b = 1, local -- FAIL | ||
154 | local a, b = , local -- FAIL | ||
155 | -------------------------------------------------------------------- | ||
156 | TESTS: simple DO blocks | ||
157 | -------------------------------------------------------------------- | ||
158 | -- stat -> DO block END | ||
159 | -- block -> chunk | ||
160 | -------------------------------------------------------------------- | ||
161 | do -- FAIL | ||
162 | end -- FAIL | ||
163 | do end | ||
164 | do ; end -- FAIL | ||
165 | do 1 end -- FAIL | ||
166 | do "foo" end -- FAIL | ||
167 | do local a, b end | ||
168 | do local a local b end | ||
169 | do local a; local b; end | ||
170 | do local a = 1 end | ||
171 | do do end end | ||
172 | do do end; end | ||
173 | do do do end end end | ||
174 | do do do end; end; end | ||
175 | do do do return end end end | ||
176 | do end do -- FAIL | ||
177 | do end end -- FAIL | ||
178 | do return end | ||
179 | do return return end -- FAIL | ||
180 | do break end -- FAIL | ||
181 | -------------------------------------------------------------------- | ||
182 | TESTS: simple WHILE loops | ||
183 | -------------------------------------------------------------------- | ||
184 | -- stat -> whilestat | ||
185 | -- whilestat -> WHILE cond DO block END | ||
186 | -- block -> chunk | ||
187 | -- cond -> expr | ||
188 | -------------------------------------------------------------------- | ||
189 | while -- FAIL | ||
190 | while do -- FAIL | ||
191 | while = -- FAIL | ||
192 | while 1 do -- FAIL | ||
193 | while 1 do end | ||
194 | while 1 do local a end | ||
195 | while 1 do local a local b end | ||
196 | while 1 do local a; local b; end | ||
197 | while 1 do 2 end -- FAIL | ||
198 | while 1 do "foo" end -- FAIL | ||
199 | while true do end | ||
200 | while 1 do ; end -- FAIL | ||
201 | while 1 do while -- FAIL | ||
202 | while 1 end -- FAIL | ||
203 | while 1 2 do -- FAIL | ||
204 | while 1 = 2 do -- FAIL | ||
205 | while 1 do return end | ||
206 | while 1 do return return end -- FAIL | ||
207 | while 1 do do end end | ||
208 | while 1 do do return end end | ||
209 | while 1 do break end | ||
210 | while 1 do break break end -- FAIL | ||
211 | while 1 do do break end end | ||
212 | -------------------------------------------------------------------- | ||
213 | TESTS: simple REPEAT loops | ||
214 | -------------------------------------------------------------------- | ||
215 | -- stat -> repeatstat | ||
216 | -- repeatstat -> REPEAT chunk UNTIL cond | ||
217 | -- cond -> expr | ||
218 | -------------------------------------------------------------------- | ||
219 | repeat -- FAIL | ||
220 | repeat until -- FAIL | ||
221 | repeat until 0 | ||
222 | repeat until false | ||
223 | repeat until local -- FAIL | ||
224 | repeat end -- FAIL | ||
225 | repeat 1 -- FAIL | ||
226 | repeat = -- FAIL | ||
227 | repeat local a until 1 | ||
228 | repeat local a local b until 0 | ||
229 | repeat local a; local b; until 0 | ||
230 | repeat ; until 1 -- FAIL | ||
231 | repeat 2 until 1 -- FAIL | ||
232 | repeat "foo" until 1 -- FAIL | ||
233 | repeat return until 0 | ||
234 | repeat return return until 0 -- FAIL | ||
235 | repeat break until 0 | ||
236 | repeat break break until 0 -- FAIL | ||
237 | repeat do end until 0 | ||
238 | repeat do return end until 0 | ||
239 | repeat do break end until 0 | ||
240 | -------------------------------------------------------------------- | ||
241 | TESTS: simple FOR loops | ||
242 | -------------------------------------------------------------------- | ||
243 | -- stat -> forstat | ||
244 | -- forstat -> fornum | forlist | ||
245 | -- forlist -> NAME {,NAME} IN explist1 forbody END | ||
246 | -- fornum -> NAME = exp1,exp1[,exp1] forbody END | ||
247 | -- forbody -> DO block | ||
248 | -- block -> chunk | ||
249 | -------------------------------------------------------------------- | ||
250 | for -- FAIL | ||
251 | for do -- FAIL | ||
252 | for end -- FAIL | ||
253 | for 1 -- FAIL | ||
254 | for a -- FAIL | ||
255 | for true -- FAIL | ||
256 | for a, in -- FAIL | ||
257 | for a in -- FAIL | ||
258 | for a do -- FAIL | ||
259 | for a in do -- FAIL | ||
260 | for a in b do -- FAIL | ||
261 | for a in b end -- FAIL | ||
262 | for a in b, do -- FAIL | ||
263 | for a in b do end | ||
264 | for a in b do local a local b end | ||
265 | for a in b do local a; local b; end | ||
266 | for a in b do 1 end -- FAIL | ||
267 | for a in b do "foo" end -- FAIL | ||
268 | for a b in -- FAIL | ||
269 | for a, b, c in p do end | ||
270 | for a, b, c in p, q, r do end | ||
271 | for a in 1 do end | ||
272 | for a in true do end | ||
273 | for a in "foo" do end | ||
274 | for a in b do break end | ||
275 | for a in b do break break end -- FAIL | ||
276 | for a in b do return end | ||
277 | for a in b do return return end -- FAIL | ||
278 | for a in b do do end end | ||
279 | for a in b do do break end end | ||
280 | for a in b do do return end end | ||
281 | for = -- FAIL | ||
282 | for a = -- FAIL | ||
283 | for a, b = -- FAIL | ||
284 | for a = do -- FAIL | ||
285 | for a = 1, do -- FAIL | ||
286 | for a = p, q, do -- FAIL | ||
287 | for a = p q do -- FAIL | ||
288 | for a = b do end -- FAIL | ||
289 | for a = 1, 2, 3, 4 do end -- FAIL | ||
290 | for a = p, q do end | ||
291 | for a = 1, 2 do end | ||
292 | for a = 1, 2 do local a local b end | ||
293 | for a = 1, 2 do local a; local b; end | ||
294 | for a = 1, 2 do 3 end -- FAIL | ||
295 | for a = 1, 2 do "foo" end -- FAIL | ||
296 | for a = p, q, r do end | ||
297 | for a = 1, 2, 3 do end | ||
298 | for a = p, q do break end | ||
299 | for a = p, q do break break end -- FAIL | ||
300 | for a = 1, 2 do return end | ||
301 | for a = 1, 2 do return return end -- FAIL | ||
302 | for a = p, q do do end end | ||
303 | for a = p, q do do break end end | ||
304 | for a = p, q do do return end end | ||
305 | -------------------------------------------------------------------- | ||
306 | TESTS: break statement | ||
307 | -------------------------------------------------------------------- | ||
308 | -- stat -> breakstat | ||
309 | -- breakstat -> BREAK | ||
310 | -- * must have a loop to break | ||
311 | -- * must be last statement in a block | ||
312 | -------------------------------------------------------------------- | ||
313 | break -- FAIL | ||
314 | -------------------------------------------------------------------- | ||
315 | TESTS: return statement | ||
316 | -------------------------------------------------------------------- | ||
317 | -- stat -> retstat | ||
318 | -- retstat -> RETURN explist | ||
319 | -- * must be last statement in a block | ||
320 | -------------------------------------------------------------------- | ||
321 | return | ||
322 | return; | ||
323 | return return -- FAIL | ||
324 | return 1 | ||
325 | return local -- FAIL | ||
326 | return "foo" | ||
327 | return 1, -- FAIL | ||
328 | return 1,2,3 | ||
329 | return a,b,c,d | ||
330 | return 1,2; | ||
331 | return ... | ||
332 | return 1,a,... | ||
333 | -------------------------------------------------------------------- | ||
334 | TESTS: conditional statements | ||
335 | -------------------------------------------------------------------- | ||
336 | -- stat -> ifstat | ||
337 | -- ifstat -> IF cond THEN block | ||
338 | -- {ELSEIF cond THEN block} | ||
339 | -- [ELSE block] END | ||
340 | -- block -> chunk | ||
341 | -- cond -> expr | ||
342 | -------------------------------------------------------------------- | ||
343 | if -- FAIL | ||
344 | elseif -- FAIL | ||
345 | else -- FAIL | ||
346 | then -- FAIL | ||
347 | if then -- FAIL | ||
348 | if 1 -- FAIL | ||
349 | if 1 then -- FAIL | ||
350 | if 1 else -- FAIL | ||
351 | if 1 then else -- FAIL | ||
352 | if 1 then elseif -- FAIL | ||
353 | if 1 then end | ||
354 | if 1 then local a end | ||
355 | if 1 then local a local b end | ||
356 | if 1 then local a; local b; end | ||
357 | if 1 then else end | ||
358 | if 1 then local a else local b end | ||
359 | if 1 then local a; else local b; end | ||
360 | if 1 then elseif 2 -- FAIL | ||
361 | if 1 then elseif 2 then -- FAIL | ||
362 | if 1 then elseif 2 then end | ||
363 | if 1 then local a elseif 2 then local b end | ||
364 | if 1 then local a; elseif 2 then local b; end | ||
365 | if 1 then elseif 2 then else end | ||
366 | if 1 then else if 2 then end end | ||
367 | if 1 then else if 2 then end -- FAIL | ||
368 | if 1 then break end -- FAIL | ||
369 | if 1 then return end | ||
370 | if 1 then return return end -- FAIL | ||
371 | if 1 then end; if 1 then end; | ||
372 | -------------------------------------------------------------------- | ||
373 | TESTS: function statements | ||
374 | -------------------------------------------------------------------- | ||
375 | -- stat -> funcstat | ||
376 | -- funcstat -> FUNCTION funcname body | ||
377 | -- funcname -> NAME {'.' NAME} [':' NAME] | ||
378 | -------------------------------------------------------------------- | ||
379 | -- body -> '(' parlist ')' chunk END | ||
380 | -- parlist -> [ param { ',' param } ] | ||
381 | -- param -> NAME | ||
382 | -- * DOTS must be the last parameter in a parlist | ||
383 | -------------------------------------------------------------------- | ||
384 | function -- FAIL | ||
385 | function 1 -- FAIL | ||
386 | function end -- FAIL | ||
387 | function a -- FAIL | ||
388 | function a end -- FAIL | ||
389 | function a( end -- FAIL | ||
390 | function a() end | ||
391 | function a(1 -- FAIL | ||
392 | function a("foo" -- FAIL | ||
393 | function a(p -- FAIL | ||
394 | function a(p,) -- FAIL | ||
395 | function a(p q -- FAIL | ||
396 | function a(p) end | ||
397 | function a(p,q,) end -- FAIL | ||
398 | function a(p,q,r) end | ||
399 | function a(p,q,1 -- FAIL | ||
400 | function a(p) do -- FAIL | ||
401 | function a(p) 1 end -- FAIL | ||
402 | function a(p) return end | ||
403 | function a(p) break end -- FAIL | ||
404 | function a(p) return return end -- FAIL | ||
405 | function a(p) do end end | ||
406 | function a.( -- FAIL | ||
407 | function a.1 -- FAIL | ||
408 | function a.b() end | ||
409 | function a.b, -- FAIL | ||
410 | function a.b.( -- FAIL | ||
411 | function a.b.c.d() end | ||
412 | function a: -- FAIL | ||
413 | function a:1 -- FAIL | ||
414 | function a:b() end | ||
415 | function a:b: -- FAIL | ||
416 | function a:b. -- FAIL | ||
417 | function a.b.c:d() end | ||
418 | function a(...) end | ||
419 | function a(..., -- FAIL | ||
420 | function a(p,...) end | ||
421 | function a(p,q,r,...) end | ||
422 | function a() local a local b end | ||
423 | function a() local a; local b; end | ||
424 | function a() end; function a() end; | ||
425 | -------------------------------------------------------------------- | ||
426 | TESTS: local function statements | ||
427 | -------------------------------------------------------------------- | ||
428 | -- stat -> LOCAL FUNCTION localfunc | ||
429 | -- LOCAL FUNCTION localfunc -> LOCAL FUNCTION NAME body | ||
430 | -------------------------------------------------------------------- | ||
431 | local function -- FAIL | ||
432 | local function 1 -- FAIL | ||
433 | local function end -- FAIL | ||
434 | local function a -- FAIL | ||
435 | local function a end -- FAIL | ||
436 | local function a( end -- FAIL | ||
437 | local function a() end | ||
438 | local function a(1 -- FAIL | ||
439 | local function a("foo" -- FAIL | ||
440 | local function a(p -- FAIL | ||
441 | local function a(p,) -- FAIL | ||
442 | local function a(p q -- FAIL | ||
443 | local function a(p) end | ||
444 | local function a(p,q,) end -- FAIL | ||
445 | local function a(p,q,r) end | ||
446 | local function a(p,q,1 -- FAIL | ||
447 | local function a(p) do -- FAIL | ||
448 | local function a(p) 1 end -- FAIL | ||
449 | local function a(p) return end | ||
450 | local function a(p) break end -- FAIL | ||
451 | local function a(p) return return end -- FAIL | ||
452 | local function a(p) do end end | ||
453 | local function a. -- FAIL | ||
454 | local function a: -- FAIL | ||
455 | local function a(...) end | ||
456 | local function a(..., -- FAIL | ||
457 | local function a(p,...) end | ||
458 | local function a(p,q,r,...) end | ||
459 | local function a() local a local b end | ||
460 | local function a() local a; local b; end | ||
461 | local function a() end; local function a() end; | ||
462 | -------------------------------------------------------------------- | ||
463 | -- stat -> exprstat | ||
464 | -- exprstat -> primaryexp | ||
465 | -- (-> func | assignment) | ||
466 | -- * if LHS is VCALL then func, otherwise assignment | ||
467 | -- * for func, LHS is VCALL if funcargs in expression | ||
468 | -------------------------------------------------------------------- | ||
469 | TESTS: assignments | ||
470 | -------------------------------------------------------------------- | ||
471 | -- assignment -> ',' primaryexp assignment | ||
472 | -- | '=' explist1 | ||
473 | -- explist1 -> expr { ',' expr } | ||
474 | -- * for assignment, LHS must be LOCAL, UPVAL, GLOBAL or INDEXED | ||
475 | -------------------------------------------------------------------- | ||
476 | a -- FAIL | ||
477 | a, -- FAIL | ||
478 | a,b,c -- FAIL | ||
479 | a,b = -- FAIL | ||
480 | a = 1 | ||
481 | a = 1,2,3 | ||
482 | a,b,c = 1 | ||
483 | a,b,c = 1,2,3 | ||
484 | a.b = 1 | ||
485 | a.b.c = 1 | ||
486 | a[b] = 1 | ||
487 | a[b][c] = 1 | ||
488 | a.b[c] = 1 | ||
489 | a[b].c = 1 | ||
490 | 0 = -- FAIL | ||
491 | "foo" = -- FAIL | ||
492 | true = -- FAIL | ||
493 | (a) = -- FAIL | ||
494 | {} = -- FAIL | ||
495 | a:b() = -- FAIL | ||
496 | a() = -- FAIL | ||
497 | a.b:c() = -- FAIL | ||
498 | a[b]() = -- FAIL | ||
499 | a = a b -- FAIL | ||
500 | a = 1 2 -- FAIL | ||
501 | a = a = 1 -- FAIL | ||
502 | -------------------------------------------------------------------- | ||
503 | TESTS: function calls | ||
504 | -------------------------------------------------------------------- | ||
505 | -- primaryexp -> prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } | ||
506 | -- prefixexp -> NAME | '(' expr ')' | ||
507 | -- funcargs -> '(' [ explist1 ] ')' | constructor | STRING | ||
508 | -- * funcargs turn an expr into a function call | ||
509 | -------------------------------------------------------------------- | ||
510 | a( -- FAIL | ||
511 | a() | ||
512 | a(1) | ||
513 | a(1,) -- FAIL | ||
514 | a(1,2,3) | ||
515 | 1() -- FAIL | ||
516 | a()() | ||
517 | a.b() | ||
518 | a[b]() | ||
519 | a.1 -- FAIL | ||
520 | a.b -- FAIL | ||
521 | a[b] -- FAIL | ||
522 | a.b.( -- FAIL | ||
523 | a.b.c() | ||
524 | a[b][c]() | ||
525 | a[b].c() | ||
526 | a.b[c]() | ||
527 | a:b() | ||
528 | a:b -- FAIL | ||
529 | a:1 -- FAIL | ||
530 | a.b:c() | ||
531 | a[b]:c() | ||
532 | a:b: -- FAIL | ||
533 | a:b():c() | ||
534 | a:b().c[d]:e() | ||
535 | a:b()[c].d:e() | ||
536 | (a)() | ||
537 | ()() -- FAIL | ||
538 | (1)() | ||
539 | ("foo")() | ||
540 | (true)() | ||
541 | (a)()() | ||
542 | (a.b)() | ||
543 | (a[b])() | ||
544 | (a).b() | ||
545 | (a)[b]() | ||
546 | (a):b() | ||
547 | (a).b[c]:d() | ||
548 | (a)[b].c:d() | ||
549 | (a):b():c() | ||
550 | (a):b().c[d]:e() | ||
551 | (a):b()[c].d:e() | ||
552 | -------------------------------------------------------------------- | ||
553 | TESTS: more function calls | ||
554 | -------------------------------------------------------------------- | ||
555 | a"foo" | ||
556 | a[[foo]] | ||
557 | a.b"foo" | ||
558 | a[b]"foo" | ||
559 | a:b"foo" | ||
560 | a{} | ||
561 | a.b{} | ||
562 | a[b]{} | ||
563 | a:b{} | ||
564 | a()"foo" | ||
565 | a"foo"() | ||
566 | a"foo".b() | ||
567 | a"foo"[b]() | ||
568 | a"foo":c() | ||
569 | a"foo""bar" | ||
570 | a"foo"{} | ||
571 | (a):b"foo".c[d]:e"bar" | ||
572 | (a):b"foo"[c].d:e"bar" | ||
573 | a(){} | ||
574 | a{}() | ||
575 | a{}.b() | ||
576 | a{}[b]() | ||
577 | a{}:c() | ||
578 | a{}"foo" | ||
579 | a{}{} | ||
580 | (a):b{}.c[d]:e{} | ||
581 | (a):b{}[c].d:e{} | ||
582 | -------------------------------------------------------------------- | ||
583 | TESTS: simple expressions | ||
584 | -------------------------------------------------------------------- | ||
585 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | ||
586 | -- | constructor | FUNCTION body | primaryexp | ||
587 | -------------------------------------------------------------------- | ||
588 | a = -- FAIL | ||
589 | a = a | ||
590 | a = nil | ||
591 | a = false | ||
592 | a = 1 | ||
593 | a = "foo" | ||
594 | a = [[foo]] | ||
595 | a = {} | ||
596 | a = (a) | ||
597 | a = (nil) | ||
598 | a = (true) | ||
599 | a = (1) | ||
600 | a = ("foo") | ||
601 | a = ([[foo]]) | ||
602 | a = ({}) | ||
603 | a = a.b | ||
604 | a = a.b. -- FAIL | ||
605 | a = a.b.c | ||
606 | a = a:b -- FAIL | ||
607 | a = a[b] | ||
608 | a = a[1] | ||
609 | a = a["foo"] | ||
610 | a = a[b][c] | ||
611 | a = a.b[c] | ||
612 | a = a[b].c | ||
613 | a = (a)[b] | ||
614 | a = (a).c | ||
615 | a = () -- FAIL | ||
616 | a = a() | ||
617 | a = a.b() | ||
618 | a = a[b]() | ||
619 | a = a:b() | ||
620 | a = (a)() | ||
621 | a = (a).b() | ||
622 | a = (a)[b]() | ||
623 | a = (a):b() | ||
624 | a = a"foo" | ||
625 | a = a{} | ||
626 | a = function -- FAIL | ||
627 | a = function 1 -- FAIL | ||
628 | a = function a -- FAIL | ||
629 | a = function end -- FAIL | ||
630 | a = function( -- FAIL | ||
631 | a = function() end | ||
632 | a = function(1 -- FAIL | ||
633 | a = function(p) end | ||
634 | a = function(p,) -- FAIL | ||
635 | a = function(p q -- FAIL | ||
636 | a = function(p,q,r) end | ||
637 | a = function(p,q,1 -- FAIL | ||
638 | a = function(...) end | ||
639 | a = function(..., -- FAIL | ||
640 | a = function(p,...) end | ||
641 | a = function(p,q,r,...) end | ||
642 | a = ... | ||
643 | a = a, b, ... | ||
644 | a = (...) | ||
645 | a = ..., 1, 2 | ||
646 | a = function() return ... end -- FAIL | ||
647 | -------------------------------------------------------------------- | ||
648 | TESTS: operators | ||
649 | -------------------------------------------------------------------- | ||
650 | -- expr -> subexpr | ||
651 | -- subexpr -> (UNOPR subexpr | simpleexp) { BINOPR subexpr } | ||
652 | -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | ||
653 | -- | constructor | FUNCTION body | primaryexp | ||
654 | -------------------------------------------------------------------- | ||
655 | a = -10 | ||
656 | a = -"foo" | ||
657 | a = -a | ||
658 | a = -nil | ||
659 | a = -true | ||
660 | a = -{} | ||
661 | a = -function() end | ||
662 | a = -a() | ||
663 | a = -(a) | ||
664 | a = - -- FAIL | ||
665 | a = not 10 | ||
666 | a = not "foo" | ||
667 | a = not a | ||
668 | a = not nil | ||
669 | a = not true | ||
670 | a = not {} | ||
671 | a = not function() end | ||
672 | a = not a() | ||
673 | a = not (a) | ||
674 | a = not -- FAIL | ||
675 | a = #10 | ||
676 | a = #"foo" | ||
677 | a = #a | ||
678 | a = #nil | ||
679 | a = #true | ||
680 | a = #{} | ||
681 | a = #function() end | ||
682 | a = #a() | ||
683 | a = #(a) | ||
684 | a = # -- FAIL | ||
685 | a = 1 + 2; a = 1 - 2 | ||
686 | a = 1 * 2; a = 1 / 2 | ||
687 | a = 1 ^ 2; a = 1 % 2 | ||
688 | a = 1 .. 2 | ||
689 | a = 1 + -- FAIL | ||
690 | a = 1 .. -- FAIL | ||
691 | a = 1 * / -- FAIL | ||
692 | a = 1 + -2; a = 1 - -2 | ||
693 | a = 1 * - -- FAIL | ||
694 | a = 1 * not 2; a = 1 / not 2 | ||
695 | a = 1 / not -- FAIL | ||
696 | a = 1 * #"foo"; a = 1 / #"foo" | ||
697 | a = 1 / # -- FAIL | ||
698 | a = 1 + 2 - 3 * 4 / 5 % 6 ^ 7 | ||
699 | a = ((1 + 2) - 3) * (4 / (5 % 6 ^ 7)) | ||
700 | a = (1 + (2 - (3 * (4 / (5 % 6 ^ ((7))))))) | ||
701 | a = ((1 -- FAIL | ||
702 | a = ((1 + 2) -- FAIL | ||
703 | a = 1) -- FAIL | ||
704 | a = a + b - c | ||
705 | a = "foo" + "bar" | ||
706 | a = "foo".."bar".."baz" | ||
707 | a = true + false - nil | ||
708 | a = {} * {} | ||
709 | a = function() end / function() end | ||
710 | a = a() ^ b() | ||
711 | a = ... % ... | ||
712 | -------------------------------------------------------------------- | ||
713 | TESTS: more operators | ||
714 | -------------------------------------------------------------------- | ||
715 | a = 1 == 2; a = 1 ~= 2 | ||
716 | a = 1 < 2; a = 1 <= 2 | ||
717 | a = 1 > 2; a = 1 >= 2 | ||
718 | a = 1 < 2 < 3 | ||
719 | a = 1 >= 2 >= 3 | ||
720 | a = 1 == -- FAIL | ||
721 | a = ~= 2 -- FAIL | ||
722 | a = "foo" == "bar" | ||
723 | a = "foo" > "bar" | ||
724 | a = a ~= b | ||
725 | a = true == false | ||
726 | a = 1 and 2; a = 1 or 2 | ||
727 | a = 1 and -- FAIL | ||
728 | a = or 1 -- FAIL | ||
729 | a = 1 and 2 and 3 | ||
730 | a = 1 or 2 or 3 | ||
731 | a = 1 and 2 or 3 | ||
732 | a = a and b or c | ||
733 | a = a() and (b)() or c.d | ||
734 | a = "foo" and "bar" | ||
735 | a = true or false | ||
736 | a = {} and {} or {} | ||
737 | a = (1) and ("foo") or (nil) | ||
738 | a = function() end == function() end | ||
739 | a = function() end or function() end | ||
740 | -------------------------------------------------------------------- | ||
741 | TESTS: constructors | ||
742 | -------------------------------------------------------------------- | ||
743 | -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}' | ||
744 | -- fieldsep -> ',' | ';' | ||
745 | -- field -> recfield | listfield | ||
746 | -- recfield -> ( NAME | '[' exp1 ']' ) = exp1 | ||
747 | -- listfield -> expr | ||
748 | -------------------------------------------------------------------- | ||
749 | a = { -- FAIL | ||
750 | a = {} | ||
751 | a = {,} -- FAIL | ||
752 | a = {;} -- FAIL | ||
753 | a = {,,} -- FAIL | ||
754 | a = {;;} -- FAIL | ||
755 | a = {{ -- FAIL | ||
756 | a = {{{}}} | ||
757 | a = {{},{},{{}},} | ||
758 | a = { 1 } | ||
759 | a = { 1, } | ||
760 | a = { 1; } | ||
761 | a = { 1, 2 } | ||
762 | a = { a, b, c, } | ||
763 | a = { true; false, nil; } | ||
764 | a = { a.b, a[b]; a:c(), } | ||
765 | a = { 1 + 2, a > b, "a" or "b" } | ||
766 | a = { a=1, } | ||
767 | a = { a=1, b="foo", c=nil } | ||
768 | a = { a -- FAIL | ||
769 | a = { a= -- FAIL | ||
770 | a = { a=, -- FAIL | ||
771 | a = { a=; -- FAIL | ||
772 | a = { 1, a="foo" -- FAIL | ||
773 | a = { 1, a="foo"; b={}, d=true; } | ||
774 | a = { [ -- FAIL | ||
775 | a = { [1 -- FAIL | ||
776 | a = { [1] -- FAIL | ||
777 | a = { [a]= -- FAIL | ||
778 | a = { ["foo"]="bar" } | ||
779 | a = { [1]=a, [2]=b, } | ||
780 | a = { true, a=1; ["foo"]="bar", } | ||
781 | ]=] | ||
782 | |||
783 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_scripts-5.0.lua | ||
4 | Compile and compare Lua files | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- NOTE | ||
17 | -- * use the argument ALL to pull in additional personal Lua scripts | ||
18 | -- for testing, e.g. lua test_scripts.lua ALL | ||
19 | ----------------------------------------------------------------------]] | ||
20 | |||
21 | ------------------------------------------------------------------------ | ||
22 | -- reads in a list of files to crunch from a text file | ||
23 | ------------------------------------------------------------------------ | ||
24 | |||
25 | local function loadlist(fname, flist) | ||
26 | local inf = io.open(fname, "r") | ||
27 | if not inf then error("cannot open "..fname.." for reading") end | ||
28 | while true do | ||
29 | local d = inf:read("*l") | ||
30 | if not d then break end | ||
31 | if string.find(d, "^%s*$") or string.find(d, "^#") then | ||
32 | -- comments and empty lines are ignored | ||
33 | else | ||
34 | table.insert(flist, d) | ||
35 | end | ||
36 | end | ||
37 | inf:close() | ||
38 | end | ||
39 | |||
40 | ------------------------------------------------------------------------ | ||
41 | -- read in list of files to test | ||
42 | ------------------------------------------------------------------------ | ||
43 | |||
44 | local files = {} | ||
45 | |||
46 | loadlist("files-lua-5.0.txt", files) | ||
47 | loadlist("files-yueliang-5.0.txt", files) | ||
48 | |||
49 | -- pull in personal scripts to test if user specifies "ALL" | ||
50 | if arg[1] == "ALL" then | ||
51 | loadlist("files-other-5.0.txt", files) | ||
52 | end | ||
53 | |||
54 | -- if you want to specify files in this script itself (not recommended) | ||
55 | -- you can add them using the following | ||
56 | --[[ | ||
57 | for v in string.gfind([[ | ||
58 | ]], "[^%s]+") do | ||
59 | table.insert(files, v) | ||
60 | end | ||
61 | --]] | ||
62 | |||
63 | total = 0 -- sum of sizes | ||
64 | fsize = 0 -- current file size | ||
65 | |||
66 | ------------------------------------------------------------------------ | ||
67 | -- initialize | ||
68 | ------------------------------------------------------------------------ | ||
69 | |||
70 | require("../orig-5.0.3/lzio") | ||
71 | require("../orig-5.0.3/llex") | ||
72 | require("../orig-5.0.3/lopcodes") | ||
73 | require("../orig-5.0.3/ldump") | ||
74 | require("../orig-5.0.3/lcode") | ||
75 | require("../orig-5.0.3/lparser") | ||
76 | |||
77 | function lua_assert(test) | ||
78 | if not test then error("assertion failed!") end | ||
79 | end | ||
80 | |||
81 | luaX:init() | ||
82 | |||
83 | io.stdout:write("\n\n") | ||
84 | |||
85 | ------------------------------------------------------------------------ | ||
86 | -- * basic comparison for now; do it properly later | ||
87 | ------------------------------------------------------------------------ | ||
88 | |||
89 | local LuaState = {} | ||
90 | |||
91 | ------------------------------------------------------------------------ | ||
92 | -- dump binary chunks to a file if something goes wrong | ||
93 | ------------------------------------------------------------------------ | ||
94 | local function Dump(data, filename) | ||
95 | h = io.open(filename, "wb") | ||
96 | if not h then error("failed to open "..filename.." for writing") end | ||
97 | h:write(data) | ||
98 | h:close() | ||
99 | end | ||
100 | |||
101 | ------------------------------------------------------------------------ | ||
102 | -- create custom chunk reader (sums up file sizes) | ||
103 | ------------------------------------------------------------------------ | ||
104 | function make_getF(filename) | ||
105 | local h = io.open(filename, "r") | ||
106 | if not h then return nil end | ||
107 | fsize = h:seek("end") | ||
108 | h:seek("set") | ||
109 | total = total + fsize | ||
110 | return function() -- chunk reader anonymous function here | ||
111 | if not h then return nil end | ||
112 | local buff = h:read(512) | ||
113 | if not buff then h:close() end | ||
114 | return buff | ||
115 | end | ||
116 | end | ||
117 | |||
118 | ------------------------------------------------------------------------ | ||
119 | -- attempt to compile Lua source files | ||
120 | ------------------------------------------------------------------------ | ||
121 | for i, filename in ipairs(files) do | ||
122 | -- compile a source file | ||
123 | local zio = luaZ:init(make_getF(filename), nil, "@"..filename) | ||
124 | if not zio then | ||
125 | error("could not initialize zio stream for "..filename) | ||
126 | end | ||
127 | io.stdout:write(filename.."("..fsize.."): ") | ||
128 | local Func = luaY:parser(LuaState, zio, nil) | ||
129 | local Writer, Buff = luaU:make_setS() | ||
130 | luaU:dump(LuaState, Func, Writer, Buff) | ||
131 | local bc1 = Buff.data -- Yueliang's output | ||
132 | |||
133 | local f = loadfile(filename) | ||
134 | local bc2 = string.dump(f) -- Lua's output | ||
135 | |||
136 | -- compare outputs | ||
137 | if string.len(bc1) ~= string.len(bc2) then | ||
138 | Dump(bc1, "bc1.out") | ||
139 | Dump(bc2, "bc2.out") | ||
140 | error("binary chunk sizes different") | ||
141 | elseif bc1 ~= bc2 then | ||
142 | Dump(bc1, "bc1.out") | ||
143 | Dump(bc2, "bc2.out") | ||
144 | error("binary chunks different") | ||
145 | else | ||
146 | io.stdout:write("CORRECT\n") | ||
147 | end | ||
148 | local x, y = gcinfo() | ||
149 | -- memory usage isn't really a problem for the straight port | ||
150 | -- string handling in Lua that follows the original C closely is more | ||
151 | -- of a problem, but this will be fixed elsewhere, not in this tree | ||
152 | --io.stdout:write("gcinfo: "..x.." "..y.."\n") | ||
153 | end | ||
154 | |||
155 | -- summaries here | ||
156 | io.stdout:write("\nTotal file sizes: "..total.."\n") | ||
157 | |||
158 | -- 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 @@ | |||
1 | --[[-------------------------------------------------------------------- | ||
2 | |||
3 | test_scripts-5.1.lua | ||
4 | Compile and compare Lua files | ||
5 | This file is part of Yueliang. | ||
6 | |||
7 | Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net> | ||
8 | The COPYRIGHT file describes the conditions | ||
9 | under which this software may be distributed. | ||
10 | |||
11 | See the ChangeLog for more information. | ||
12 | |||
13 | ----------------------------------------------------------------------]] | ||
14 | |||
15 | --[[-------------------------------------------------------------------- | ||
16 | -- NOTE | ||
17 | -- * use the argument ALL to pull in additional personal Lua scripts | ||
18 | -- for testing, e.g. lua test_scripts.lua ALL | ||
19 | ----------------------------------------------------------------------]] | ||
20 | |||
21 | ------------------------------------------------------------------------ | ||
22 | -- reads in a list of files to crunch from a text file | ||
23 | ------------------------------------------------------------------------ | ||
24 | |||
25 | local function loadlist(fname, flist) | ||
26 | local inf = io.open(fname, "r") | ||
27 | if not inf then error("cannot open "..fname.." for reading") end | ||
28 | while true do | ||
29 | local d = inf:read("*l") | ||
30 | if not d then break end | ||
31 | if string.match(d, "^%s*$") or string.match(d, "^#") then | ||
32 | -- comments and empty lines are ignored | ||
33 | else | ||
34 | flist[#flist+1] = d | ||
35 | end | ||
36 | end | ||
37 | inf:close() | ||
38 | end | ||
39 | |||
40 | ------------------------------------------------------------------------ | ||
41 | -- read in list of files to test | ||
42 | ------------------------------------------------------------------------ | ||
43 | |||
44 | local files = {} | ||
45 | |||
46 | loadlist("files-lua-5.1.txt", files) | ||
47 | loadlist("files-yueliang-5.1.txt", files) | ||
48 | |||
49 | -- pull in personal scripts to test if user specifies "ALL" | ||
50 | if arg[1] == "ALL" then | ||
51 | loadlist("files-other-5.1.txt", files) | ||
52 | end | ||
53 | |||
54 | -- if you want to specify files in this script itself (not recommended) | ||
55 | -- you can add them using the following | ||
56 | --[=[ | ||
57 | for v in string.gmatch([[ | ||
58 | ]], "[^%s]+") do | ||
59 | table.insert(files, v) | ||
60 | end | ||
61 | --]=] | ||
62 | |||
63 | total = 0 -- sum of sizes | ||
64 | fsize = 0 -- current file size | ||
65 | |||
66 | ------------------------------------------------------------------------ | ||
67 | -- initialize | ||
68 | ------------------------------------------------------------------------ | ||
69 | |||
70 | dofile("../orig-5.1.2/lzio.lua") | ||
71 | dofile("../orig-5.1.2/llex.lua") | ||
72 | dofile("../orig-5.1.2/lopcodes.lua") | ||
73 | dofile("../orig-5.1.2/ldump.lua") | ||
74 | dofile("../orig-5.1.2/lcode.lua") | ||
75 | dofile("../orig-5.1.2/lparser.lua") | ||
76 | |||
77 | function lua_assert(test) | ||
78 | if not test then error("assertion failed!") end | ||
79 | end | ||
80 | |||
81 | luaX:init() | ||
82 | |||
83 | io.stdout:write("\n\n") | ||
84 | |||
85 | ------------------------------------------------------------------------ | ||
86 | -- * basic comparison for now; do it properly later | ||
87 | ------------------------------------------------------------------------ | ||
88 | |||
89 | local LuaState = {} | ||
90 | |||
91 | ------------------------------------------------------------------------ | ||
92 | -- dump binary chunks to a file if something goes wrong | ||
93 | ------------------------------------------------------------------------ | ||
94 | local function Dump(data, filename) | ||
95 | h = io.open(filename, "wb") | ||
96 | if not h then error("failed to open "..filename.." for writing") end | ||
97 | h:write(data) | ||
98 | h:close() | ||
99 | end | ||
100 | |||
101 | ------------------------------------------------------------------------ | ||
102 | -- create custom chunk reader (sums up file sizes) | ||
103 | ------------------------------------------------------------------------ | ||
104 | function make_getF(filename) | ||
105 | local h = io.open(filename, "r") | ||
106 | if not h then return nil end | ||
107 | fsize = h:seek("end") | ||
108 | h:seek("set") | ||
109 | total = total + fsize | ||
110 | return function() -- chunk reader anonymous function here | ||
111 | if not h then return nil end | ||
112 | local buff = h:read(512) | ||
113 | if not buff then h:close() end | ||
114 | return buff | ||
115 | end | ||
116 | end | ||
117 | |||
118 | ------------------------------------------------------------------------ | ||
119 | -- attempt to compile Lua source files | ||
120 | ------------------------------------------------------------------------ | ||
121 | for i, filename in ipairs(files) do | ||
122 | -- compile a source file | ||
123 | local zio = luaZ:init(make_getF(filename), nil) | ||
124 | if not zio then | ||
125 | error("could not initialize zio stream for "..filename) | ||
126 | end | ||
127 | io.stdout:write(filename.."("..fsize.."): ") | ||
128 | local Func = luaY:parser(LuaState, zio, nil, "@"..filename) | ||
129 | local Writer, Buff = luaU:make_setS() | ||
130 | luaU:dump(LuaState, Func, Writer, Buff) | ||
131 | local bc1 = Buff.data -- Yueliang's output | ||
132 | |||
133 | local f = loadfile(filename) | ||
134 | local bc2 = string.dump(f) -- Lua's output | ||
135 | |||
136 | -- compare outputs | ||
137 | if #bc1 ~= #bc2 then | ||
138 | Dump(bc1, "bc1.out") | ||
139 | Dump(bc2, "bc2.out") | ||
140 | error("binary chunk sizes different") | ||
141 | elseif bc1 ~= bc2 then | ||
142 | Dump(bc1, "bc1.out") | ||
143 | Dump(bc2, "bc2.out") | ||
144 | error("binary chunks different") | ||
145 | else | ||
146 | io.stdout:write("CORRECT\n") | ||
147 | end | ||
148 | local x = collectgarbage("count") | ||
149 | -- memory usage isn't really a problem for the straight port | ||
150 | -- string handling in Lua that follows the original C closely is more | ||
151 | -- of a problem, but this will be fixed elsewhere, not in this tree | ||
152 | --io.stdout:write("collectgarbage: "..x.."\n") | ||
153 | end | ||
154 | |||
155 | -- summaries here | ||
156 | io.stdout:write("\nTotal file sizes: "..total.."\n") | ||
157 | |||
158 | -- end | ||