lua-obfuscator 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yml +40 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +18 -14
- package/dist/prometheus/LICENSE +661 -661
- package/dist/prometheus/build.bat +9 -9
- package/dist/prometheus/doc/README.md +11 -11
- package/dist/prometheus/doc/SUMMARY.md +27 -27
- package/dist/prometheus/doc/advanced/using-prometheus-in-your-lua-application.md +31 -31
- package/dist/prometheus/doc/getting-started/command-line-options.md +13 -13
- package/dist/prometheus/doc/getting-started/installation.md +11 -11
- package/dist/prometheus/doc/getting-started/obfuscating-your-first-script.md +50 -50
- package/dist/prometheus/doc/getting-started/presets.md +10 -10
- package/dist/prometheus/doc/getting-started/the-config-object.md +58 -58
- package/dist/prometheus/doc/getting-started/writing-a-custom-config-file.md +56 -56
- package/dist/prometheus/doc/steps/anti-tamper.md +11 -11
- package/dist/prometheus/doc/steps/constantarray.md +71 -71
- package/dist/prometheus/doc/steps/encryptstrings.md +86 -86
- package/dist/prometheus/doc/steps/proxifylocals.md +47 -47
- package/dist/prometheus/doc/steps/splitstrings.md +40 -40
- package/dist/prometheus/doc/steps/vmify.md +9 -9
- package/dist/prometheus/doc/steps/wrapinfunction.md +29 -29
- package/dist/prometheus/readme.md +57 -57
- package/dist/prometheus/readme.txt +4 -4
- package/package.json +5 -1
- package/src/index.ts +81 -75
- package/tsconfig.json +12 -12
- package/src/prometheus/.editorconfig +0 -4
- package/src/prometheus/.gitattributes +0 -2
- package/src/prometheus/.gitbook.yaml +0 -1
- package/src/prometheus/.github/ISSUE_TEMPLATE/bug_report.md +0 -25
- package/src/prometheus/.github/workflows/Build.yml +0 -49
- package/src/prometheus/.github/workflows/Test.yml +0 -19
- package/src/prometheus/LICENSE +0 -661
- package/src/prometheus/benchmark.lua +0 -34
- package/src/prometheus/build.bat +0 -10
- package/src/prometheus/cli.lua +0 -12
- package/src/prometheus/doc/README.md +0 -11
- package/src/prometheus/doc/SUMMARY.md +0 -27
- package/src/prometheus/doc/advanced/using-prometheus-in-your-lua-application.md +0 -31
- package/src/prometheus/doc/getting-started/command-line-options.md +0 -13
- package/src/prometheus/doc/getting-started/installation.md +0 -11
- package/src/prometheus/doc/getting-started/obfuscating-your-first-script.md +0 -50
- package/src/prometheus/doc/getting-started/presets.md +0 -10
- package/src/prometheus/doc/getting-started/the-config-object.md +0 -58
- package/src/prometheus/doc/getting-started/writing-a-custom-config-file.md +0 -56
- package/src/prometheus/doc/steps/anti-tamper.md +0 -11
- package/src/prometheus/doc/steps/constantarray.md +0 -71
- package/src/prometheus/doc/steps/encryptstrings.md +0 -86
- package/src/prometheus/doc/steps/proxifylocals.md +0 -47
- package/src/prometheus/doc/steps/splitstrings.md +0 -40
- package/src/prometheus/doc/steps/vmify.md +0 -9
- package/src/prometheus/doc/steps/wrapinfunction.md +0 -29
- package/src/prometheus/prometheus-main.lua +0 -1
- package/src/prometheus/readme.md +0 -57
- package/src/prometheus/readme.txt +0 -5
- package/src/prometheus/src/cli.lua +0 -154
- package/src/prometheus/src/colors.lua +0 -61
- package/src/prometheus/src/highlightlua.lua +0 -61
- package/src/prometheus/src/logger.lua +0 -62
- package/src/prometheus/src/presets.lua +0 -174
- package/src/prometheus/src/prometheus/ast.lua +0 -792
- package/src/prometheus/src/prometheus/bit.lua +0 -521
- package/src/prometheus/src/prometheus/compiler/compiler.lua +0 -2365
- package/src/prometheus/src/prometheus/enums.lua +0 -106
- package/src/prometheus/src/prometheus/namegenerators/Il.lua +0 -41
- package/src/prometheus/src/prometheus/namegenerators/confuse.lua +0 -169
- package/src/prometheus/src/prometheus/namegenerators/mangled.lua +0 -26
- package/src/prometheus/src/prometheus/namegenerators/mangled_shuffled.lua +0 -35
- package/src/prometheus/src/prometheus/namegenerators/number.lua +0 -11
- package/src/prometheus/src/prometheus/namegenerators.lua +0 -7
- package/src/prometheus/src/prometheus/parser.lua +0 -969
- package/src/prometheus/src/prometheus/pipeline.lua +0 -250
- package/src/prometheus/src/prometheus/randomLiterals.lua +0 -41
- package/src/prometheus/src/prometheus/randomStrings.lua +0 -24
- package/src/prometheus/src/prometheus/scope.lua +0 -332
- package/src/prometheus/src/prometheus/step.lua +0 -79
- package/src/prometheus/src/prometheus/steps/AddVararg.lua +0 -33
- package/src/prometheus/src/prometheus/steps/AntiTamper.lua +0 -194
- package/src/prometheus/src/prometheus/steps/ConstantArray.lua +0 -521
- package/src/prometheus/src/prometheus/steps/EncryptStrings.lua +0 -239
- package/src/prometheus/src/prometheus/steps/NumbersToExpressions.lua +0 -82
- package/src/prometheus/src/prometheus/steps/ProxifyLocals.lua +0 -313
- package/src/prometheus/src/prometheus/steps/SplitStrings.lua +0 -338
- package/src/prometheus/src/prometheus/steps/Vmify.lua +0 -30
- package/src/prometheus/src/prometheus/steps/Watermark.lua +0 -61
- package/src/prometheus/src/prometheus/steps/WatermarkCheck.lua +0 -50
- package/src/prometheus/src/prometheus/steps/WrapInFunction.lua +0 -45
- package/src/prometheus/src/prometheus/steps.lua +0 -12
- package/src/prometheus/src/prometheus/tokenizer.lua +0 -546
- package/src/prometheus/src/prometheus/unparser.lua +0 -866
- package/src/prometheus/src/prometheus/util.lua +0 -297
- package/src/prometheus/src/prometheus/visitast.lua +0 -245
- package/src/prometheus/src/prometheus.lua +0 -71
- package/src/prometheus/tests/closures.lua +0 -12
- package/src/prometheus/tests/fibonacci.lua +0 -10
- package/src/prometheus/tests/loops.lua +0 -8
- package/src/prometheus/tests/primes.lua +0 -18
- package/src/prometheus/tests.lua +0 -149
|
@@ -1,969 +0,0 @@
|
|
|
1
|
-
-- This Script is Part of the Prometheus Obfuscator by Levno_710
|
|
2
|
-
--
|
|
3
|
-
-- parser.lua
|
|
4
|
-
-- Overview:
|
|
5
|
-
-- This Script provides a class for parsing of lua code.
|
|
6
|
-
-- This Parser is Capable of parsing LuaU and Lua5.1
|
|
7
|
-
--
|
|
8
|
-
-- Note that when parsing LuaU "continue" is treated as a Keyword, so no variable may be named "continue" even though this would be valid in LuaU
|
|
9
|
-
--
|
|
10
|
-
-- Settings Object:
|
|
11
|
-
-- luaVersion : The LuaVersion of the Script - Currently Supported : Lua51 and LuaU
|
|
12
|
-
--
|
|
13
|
-
|
|
14
|
-
local Tokenizer = require("prometheus.tokenizer");
|
|
15
|
-
local Enums = require("prometheus.enums");
|
|
16
|
-
local util = require("prometheus.util");
|
|
17
|
-
local Ast = require("prometheus.ast");
|
|
18
|
-
local Scope = require("prometheus.scope");
|
|
19
|
-
local logger = require("logger");
|
|
20
|
-
|
|
21
|
-
local AstKind = Ast.AstKind;
|
|
22
|
-
|
|
23
|
-
local LuaVersion = Enums.LuaVersion;
|
|
24
|
-
local lookupify = util.lookupify;
|
|
25
|
-
local unlookupify = util.unlookupify;
|
|
26
|
-
local escape = util.escape;
|
|
27
|
-
local chararray = util.chararray;
|
|
28
|
-
local keys = util.keys;
|
|
29
|
-
|
|
30
|
-
local TokenKind = Tokenizer.TokenKind;
|
|
31
|
-
|
|
32
|
-
local Parser = {};
|
|
33
|
-
|
|
34
|
-
local ASSIGNMENT_NO_WARN_LOOKUP = lookupify{
|
|
35
|
-
AstKind.NilExpression,
|
|
36
|
-
AstKind.FunctionCallExpression,
|
|
37
|
-
AstKind.PassSelfFunctionCallExpression,
|
|
38
|
-
AstKind.VarargExpression
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
local function generateError(self, message)
|
|
42
|
-
local token;
|
|
43
|
-
if(self.index > self.length) then
|
|
44
|
-
token = self.tokens[self.length];
|
|
45
|
-
elseif(self.index < 1) then
|
|
46
|
-
return "Parsing Error at Position 0:0, " .. message;
|
|
47
|
-
else
|
|
48
|
-
token = self.tokens[self.index];
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
return "Parsing Error at Position " .. tostring(token.line) .. ":" .. tostring(token.linePos) .. ", " .. message;
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
local function generateWarning(token, message)
|
|
55
|
-
return "Warning at Position " .. tostring(token.line) .. ":" .. tostring(token.linePos) .. ", " .. message;
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
function Parser:new(settings)
|
|
59
|
-
local luaVersion = (settings and (settings.luaVersion or settings.LuaVersion)) or LuaVersion.LuaU;
|
|
60
|
-
local parser = {
|
|
61
|
-
luaVersion = luaVersion,
|
|
62
|
-
tokenizer = Tokenizer:new({
|
|
63
|
-
luaVersion = luaVersion
|
|
64
|
-
}),
|
|
65
|
-
tokens = {};
|
|
66
|
-
length = 0;
|
|
67
|
-
index = 0;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
setmetatable(parser, self);
|
|
71
|
-
self.__index = self;
|
|
72
|
-
|
|
73
|
-
return parser;
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
-- Function to peek the n'th token
|
|
77
|
-
local function peek(self, n)
|
|
78
|
-
n = n or 0;
|
|
79
|
-
local i = self.index + n + 1;
|
|
80
|
-
if i > self.length then
|
|
81
|
-
return Tokenizer.EOF_TOKEN;
|
|
82
|
-
end
|
|
83
|
-
return self.tokens[i];
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
-- Function to get the next Token
|
|
87
|
-
local function get(self)
|
|
88
|
-
local i = self.index + 1;
|
|
89
|
-
if i > self.length then
|
|
90
|
-
error(generateError(self, "Unexpected end of Input"));
|
|
91
|
-
end
|
|
92
|
-
self.index = self.index + 1;
|
|
93
|
-
local tk = self.tokens[i];
|
|
94
|
-
|
|
95
|
-
return tk;
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
local function is(self, kind, sourceOrN, n)
|
|
99
|
-
local token = peek(self, n);
|
|
100
|
-
|
|
101
|
-
local source = nil;
|
|
102
|
-
if(type(sourceOrN) == "string") then
|
|
103
|
-
source = sourceOrN;
|
|
104
|
-
else
|
|
105
|
-
n = sourceOrN;
|
|
106
|
-
end
|
|
107
|
-
n = n or 0;
|
|
108
|
-
|
|
109
|
-
if(token.kind == kind) then
|
|
110
|
-
if(source == nil or token.source == source) then
|
|
111
|
-
return true;
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
return false;
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
local function consume(self, kind, source)
|
|
119
|
-
if(is(self, kind, source)) then
|
|
120
|
-
self.index = self.index + 1;
|
|
121
|
-
return true;
|
|
122
|
-
end
|
|
123
|
-
return false;
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
local function expect(self, kind, source)
|
|
127
|
-
if(is(self, kind, source, 0)) then
|
|
128
|
-
return get(self);
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
local token = peek(self);
|
|
132
|
-
if self.disableLog then error() end
|
|
133
|
-
if(source) then
|
|
134
|
-
logger:error(generateError(self, string.format("unexpected token <%s> \"%s\", expected <%s> \"%s\"", token.kind, token.source, kind, source)));
|
|
135
|
-
else
|
|
136
|
-
logger:error(generateError(self, string.format("unexpected token <%s> \"%s\", expected <%s>", token.kind, token.source, kind)));
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
-- Parse the given code to an Abstract Syntax Tree
|
|
141
|
-
function Parser:parse(code)
|
|
142
|
-
self.tokenizer:append(code);
|
|
143
|
-
self.tokens = self.tokenizer:scanAll();
|
|
144
|
-
self.length = #self.tokens;
|
|
145
|
-
|
|
146
|
-
-- Create Global Variable Scope
|
|
147
|
-
local globalScope = Scope:newGlobal();
|
|
148
|
-
|
|
149
|
-
local ast = Ast.TopNode(self:block(globalScope, false), globalScope);
|
|
150
|
-
-- File Must be Over when Top Node is Fully Parsed
|
|
151
|
-
expect(self, TokenKind.Eof);
|
|
152
|
-
|
|
153
|
-
logger:debug("Cleaning up Parser for next Use ...")
|
|
154
|
-
-- Clean Up
|
|
155
|
-
self.tokenizer:reset();
|
|
156
|
-
self.tokens = {};
|
|
157
|
-
self.index = 0;
|
|
158
|
-
self.length = 0;
|
|
159
|
-
|
|
160
|
-
logger:debug("Cleanup Done")
|
|
161
|
-
|
|
162
|
-
return ast;
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
-- Parse a Code Block
|
|
166
|
-
function Parser:block(parentScope, currentLoop, scope)
|
|
167
|
-
scope = scope or Scope:new(parentScope);
|
|
168
|
-
local statements = {};
|
|
169
|
-
|
|
170
|
-
repeat
|
|
171
|
-
local statement, isTerminatingStatement = self:statement(scope, currentLoop);
|
|
172
|
-
table.insert(statements, statement);
|
|
173
|
-
until isTerminatingStatement or not statement
|
|
174
|
-
|
|
175
|
-
-- Consume Eventual Semicolon after terminating return, break or continue
|
|
176
|
-
consume(self, TokenKind.Symbol, ";");
|
|
177
|
-
|
|
178
|
-
return Ast.Block(statements, scope);
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
function Parser:statement(scope, currentLoop)
|
|
182
|
-
-- Skip all semicolons before next real statement
|
|
183
|
-
-- NOP statements are therefore ignored
|
|
184
|
-
while(consume(self, TokenKind.Symbol, ";")) do
|
|
185
|
-
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
-- Break Statement - only valid inside of Loops
|
|
189
|
-
if(consume(self, TokenKind.Keyword, "break")) then
|
|
190
|
-
if(not currentLoop) then
|
|
191
|
-
if self.disableLog then error() end;
|
|
192
|
-
logger:error(generateError(self, "the break Statement is only valid inside of loops"));
|
|
193
|
-
end
|
|
194
|
-
-- Return true as Second value because break must be the last Statement in a block
|
|
195
|
-
return Ast.BreakStatement(currentLoop, scope), true;
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
-- Continue Statement - only valid inside of Loops - only valid in LuaU
|
|
199
|
-
if(self.luaVersion == LuaVersion.LuaU and consume(self, TokenKind.Keyword, "continue")) then
|
|
200
|
-
if(not currentLoop) then
|
|
201
|
-
if self.disableLog then error() end;
|
|
202
|
-
logger:error(generateError(self, "the continue Statement is only valid inside of loops"));
|
|
203
|
-
end
|
|
204
|
-
-- Return true as Second value because continue must be the last Statement in a block
|
|
205
|
-
return Ast.ContinueStatement(currentLoop, scope), true;
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
-- do ... end Statement
|
|
209
|
-
if(consume(self, TokenKind.Keyword, "do")) then
|
|
210
|
-
local body = self:block(scope, currentLoop);
|
|
211
|
-
expect(self, TokenKind.Keyword, "end");
|
|
212
|
-
return Ast.DoStatement(body);
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
-- While Statement
|
|
216
|
-
if(consume(self, TokenKind.Keyword, "while")) then
|
|
217
|
-
local condition = self:expression(scope);
|
|
218
|
-
expect(self, TokenKind.Keyword, "do");
|
|
219
|
-
local stat = Ast.WhileStatement(nil, condition, scope);
|
|
220
|
-
stat.body = self:block(scope, stat);
|
|
221
|
-
expect(self, TokenKind.Keyword, "end");
|
|
222
|
-
return stat;
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
-- Repeat Statement
|
|
226
|
-
if(consume(self, TokenKind.Keyword, "repeat")) then
|
|
227
|
-
local repeatScope = Scope:new(scope);
|
|
228
|
-
local stat = Ast.RepeatStatement(nil, nil, scope);
|
|
229
|
-
stat.body = self:block(nil, stat, repeatScope);
|
|
230
|
-
expect(self, TokenKind.Keyword, "until");
|
|
231
|
-
stat.condition = self:expression(repeatScope);
|
|
232
|
-
return stat;
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
-- Return Statement
|
|
236
|
-
if(consume(self, TokenKind.Keyword, "return")) then
|
|
237
|
-
local args = {};
|
|
238
|
-
if(not is(self, TokenKind.Keyword, "end") and not is(self, TokenKind.Keyword, "elseif") and not is(self, TokenKind.Keyword, "else") and not is(self, TokenKind.Symbol, ";") and not is(self, TokenKind.Eof)) then
|
|
239
|
-
args = self:exprList(scope);
|
|
240
|
-
end
|
|
241
|
-
-- Return true as Second value because return must be the last Statement in a block
|
|
242
|
-
return Ast.ReturnStatement(args), true;
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
-- If Statement
|
|
246
|
-
if(consume(self, TokenKind.Keyword, "if")) then
|
|
247
|
-
local condition = self:expression(scope);
|
|
248
|
-
expect(self, TokenKind.Keyword, "then");
|
|
249
|
-
local body = self:block(scope, currentLoop);
|
|
250
|
-
|
|
251
|
-
local elseifs = {};
|
|
252
|
-
-- Elseifs
|
|
253
|
-
while(consume(self, TokenKind.Keyword, "elseif")) do
|
|
254
|
-
local condition = self:expression(scope);
|
|
255
|
-
expect(self, TokenKind.Keyword, "then");
|
|
256
|
-
local body = self:block(scope, currentLoop);
|
|
257
|
-
|
|
258
|
-
table.insert(elseifs, {
|
|
259
|
-
condition = condition,
|
|
260
|
-
body = body,
|
|
261
|
-
});
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
local elsebody = nil;
|
|
265
|
-
-- Else
|
|
266
|
-
if(consume(self, TokenKind.Keyword, "else")) then
|
|
267
|
-
elsebody = self:block(scope, currentLoop);
|
|
268
|
-
end
|
|
269
|
-
|
|
270
|
-
expect(self, TokenKind.Keyword, "end");
|
|
271
|
-
|
|
272
|
-
return Ast.IfStatement(condition, body, elseifs, elsebody);
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
-- Function Declaration
|
|
276
|
-
if(consume(self, TokenKind.Keyword, "function")) then
|
|
277
|
-
-- TODO: Parse Function Declaration Name
|
|
278
|
-
local obj = self:funcName(scope);
|
|
279
|
-
local baseScope = obj.scope;
|
|
280
|
-
local baseId = obj.id;
|
|
281
|
-
local indices = obj.indices;
|
|
282
|
-
|
|
283
|
-
local funcScope = Scope:new(scope);
|
|
284
|
-
|
|
285
|
-
expect(self, TokenKind.Symbol, "(");
|
|
286
|
-
local args = self:functionArgList(funcScope);
|
|
287
|
-
expect(self, TokenKind.Symbol, ")");
|
|
288
|
-
|
|
289
|
-
if(obj.passSelf) then
|
|
290
|
-
local id = funcScope:addVariable("self", obj.token);
|
|
291
|
-
table.insert(args, 1, Ast.VariableExpression(funcScope, id));
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
local body = self:block(nil, false, funcScope);
|
|
295
|
-
expect(self, TokenKind.Keyword, "end");
|
|
296
|
-
|
|
297
|
-
return Ast.FunctionDeclaration(baseScope, baseId, indices, args, body);
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
-- Local Function or Variable Declaration
|
|
301
|
-
if(consume(self, TokenKind.Keyword, "local")) then
|
|
302
|
-
-- Local Function Declaration
|
|
303
|
-
if(consume(self, TokenKind.Keyword, "function")) then
|
|
304
|
-
local ident = expect(self, TokenKind.Ident);
|
|
305
|
-
local name = ident.value;
|
|
306
|
-
|
|
307
|
-
local id = scope:addVariable(name, ident);
|
|
308
|
-
local funcScope = Scope:new(scope);
|
|
309
|
-
|
|
310
|
-
expect(self, TokenKind.Symbol, "(");
|
|
311
|
-
local args = self:functionArgList(funcScope);
|
|
312
|
-
expect(self, TokenKind.Symbol, ")");
|
|
313
|
-
|
|
314
|
-
local body = self:block(nil, false, funcScope);
|
|
315
|
-
expect(self, TokenKind.Keyword, "end");
|
|
316
|
-
|
|
317
|
-
return Ast.LocalFunctionDeclaration(scope, id, args, body);
|
|
318
|
-
end
|
|
319
|
-
|
|
320
|
-
-- Local Variable Declaration
|
|
321
|
-
local ids = self:nameList(scope);
|
|
322
|
-
local expressions = {};
|
|
323
|
-
if(consume(self, TokenKind.Symbol, "=")) then
|
|
324
|
-
expressions = self:exprList(scope);
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
-- Variables can only be reffered to in the next statement, so the id's are enabled after the expressions have been parsed
|
|
328
|
-
self:enableNameList(scope, ids);
|
|
329
|
-
|
|
330
|
-
if(#expressions > #ids) then
|
|
331
|
-
logger:warn(generateWarning(peek(self, -1), string.format("assigning %d values to %d variable" .. ((#ids > 1 and "s") or ""), #expressions, #ids)));
|
|
332
|
-
elseif(#ids > #expressions and #expressions > 0 and not ASSIGNMENT_NO_WARN_LOOKUP[expressions[#expressions].kind]) then
|
|
333
|
-
logger:warn(generateWarning(peek(self, -1), string.format("assigning %d value" .. ((#expressions > 1 and "s") or "") ..
|
|
334
|
-
" to %d variables initializes extra variables with nil, add a nil value to silence", #expressions, #ids)));
|
|
335
|
-
end
|
|
336
|
-
return Ast.LocalVariableDeclaration(scope, ids, expressions);
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
-- For Statement
|
|
340
|
-
if(consume(self, TokenKind.Keyword, "for")) then
|
|
341
|
-
-- Normal for Statement
|
|
342
|
-
if(is(self, TokenKind.Symbol, "=", 1)) then
|
|
343
|
-
local forScope = Scope:new(scope);
|
|
344
|
-
|
|
345
|
-
local ident = expect(self, TokenKind.Ident);
|
|
346
|
-
local varId = forScope:addDisabledVariable(ident.value, ident);
|
|
347
|
-
|
|
348
|
-
expect(self, TokenKind.Symbol, "=");
|
|
349
|
-
local initialValue = self:expression(scope);
|
|
350
|
-
|
|
351
|
-
expect(self, TokenKind.Symbol, ",");
|
|
352
|
-
local finalValue = self:expression(scope);
|
|
353
|
-
local incrementBy = Ast.NumberExpression(1);
|
|
354
|
-
if(consume(self, TokenKind.Symbol, ",")) then
|
|
355
|
-
incrementBy = self:expression(scope);
|
|
356
|
-
end
|
|
357
|
-
|
|
358
|
-
local stat = Ast.ForStatement(forScope, varId, initialValue, finalValue, incrementBy, nil, scope);
|
|
359
|
-
forScope:enableVariable(varId);
|
|
360
|
-
expect(self, TokenKind.Keyword, "do");
|
|
361
|
-
stat.body = self:block(nil, stat, forScope);
|
|
362
|
-
expect(self, TokenKind.Keyword, "end");
|
|
363
|
-
return stat;
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
-- For ... in ... statement
|
|
367
|
-
local forScope = Scope:new(scope);
|
|
368
|
-
|
|
369
|
-
local ids = self:nameList(forScope);
|
|
370
|
-
expect(self, TokenKind.Keyword, "in");
|
|
371
|
-
local expressions = self:exprList(scope);
|
|
372
|
-
-- Enable Ids after Expression Parsing so that code like this works:
|
|
373
|
-
-- local z = {10,20}
|
|
374
|
-
-- for y,z in ipairs(z) do
|
|
375
|
-
-- print(y, z);
|
|
376
|
-
-- end
|
|
377
|
-
self:enableNameList(forScope, ids);
|
|
378
|
-
expect(self, TokenKind.Keyword, "do");
|
|
379
|
-
local stat = Ast.ForInStatement(forScope, ids, expressions, nil, scope);
|
|
380
|
-
stat.body = self:block(nil, stat, forScope);
|
|
381
|
-
expect(self, TokenKind.Keyword, "end");
|
|
382
|
-
|
|
383
|
-
return stat;
|
|
384
|
-
end
|
|
385
|
-
|
|
386
|
-
local expr = self:primaryExpression(scope);
|
|
387
|
-
-- Variable Assignment or Function Call
|
|
388
|
-
if expr then
|
|
389
|
-
-- Function Call Statement
|
|
390
|
-
if(expr.kind == AstKind.FunctionCallExpression) then
|
|
391
|
-
return Ast.FunctionCallStatement(expr.base, expr.args);
|
|
392
|
-
end
|
|
393
|
-
|
|
394
|
-
-- Function Call Statement passing self
|
|
395
|
-
if(expr.kind == AstKind.PassSelfFunctionCallExpression) then
|
|
396
|
-
return Ast.PassSelfFunctionCallStatement(expr.base, expr.passSelfFunctionName, expr.args);
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
-- Variable Assignment
|
|
400
|
-
if(expr.kind == AstKind.IndexExpression or expr.kind == AstKind.VariableExpression) then
|
|
401
|
-
if(expr.kind == AstKind.IndexExpression) then
|
|
402
|
-
expr.kind = AstKind.AssignmentIndexing
|
|
403
|
-
end
|
|
404
|
-
if(expr.kind == AstKind.VariableExpression) then
|
|
405
|
-
expr.kind = AstKind.AssignmentVariable
|
|
406
|
-
end
|
|
407
|
-
|
|
408
|
-
if(self.luaVersion == LuaVersion.LuaU) then
|
|
409
|
-
-- LuaU Compound Assignment
|
|
410
|
-
if(consume(self, TokenKind.Symbol, "+=")) then
|
|
411
|
-
local rhs = self:expression(scope);
|
|
412
|
-
return Ast.CompoundAddStatement(expr, rhs);
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
if(consume(self, TokenKind.Symbol, "-=")) then
|
|
416
|
-
local rhs = self:expression(scope);
|
|
417
|
-
return Ast.CompoundSubStatement(expr, rhs);
|
|
418
|
-
end
|
|
419
|
-
|
|
420
|
-
if(consume(self, TokenKind.Symbol, "*=")) then
|
|
421
|
-
local rhs = self:expression(scope);
|
|
422
|
-
return Ast.CompoundMulStatement(expr, rhs);
|
|
423
|
-
end
|
|
424
|
-
|
|
425
|
-
if(consume(self, TokenKind.Symbol, "/=")) then
|
|
426
|
-
local rhs = self:expression(scope);
|
|
427
|
-
return Ast.CompoundDivStatement(expr, rhs);
|
|
428
|
-
end
|
|
429
|
-
|
|
430
|
-
if(consume(self, TokenKind.Symbol, "%=")) then
|
|
431
|
-
local rhs = self:expression(scope);
|
|
432
|
-
return Ast.CompoundModStatement(expr, rhs);
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
if(consume(self, TokenKind.Symbol, "^=")) then
|
|
436
|
-
local rhs = self:expression(scope);
|
|
437
|
-
return Ast.CompoundPowStatement(expr, rhs);
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
if(consume(self, TokenKind.Symbol, "..=")) then
|
|
441
|
-
local rhs = self:expression(scope);
|
|
442
|
-
return Ast.CompoundConcatStatement(expr, rhs);
|
|
443
|
-
end
|
|
444
|
-
end
|
|
445
|
-
|
|
446
|
-
local lhs = {
|
|
447
|
-
expr
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
while consume(self, TokenKind.Symbol, ",") do
|
|
451
|
-
expr = self:primaryExpression(scope);
|
|
452
|
-
|
|
453
|
-
if(not expr) then
|
|
454
|
-
if self.disableLog then error() end;
|
|
455
|
-
logger:error(generateError(self, string.format("expected a valid assignment statement lhs part but got nil")));
|
|
456
|
-
end
|
|
457
|
-
|
|
458
|
-
if(expr.kind == AstKind.IndexExpression or expr.kind == AstKind.VariableExpression) then
|
|
459
|
-
if(expr.kind == AstKind.IndexExpression) then
|
|
460
|
-
expr.kind = AstKind.AssignmentIndexing
|
|
461
|
-
end
|
|
462
|
-
if(expr.kind == AstKind.VariableExpression) then
|
|
463
|
-
expr.kind = AstKind.AssignmentVariable
|
|
464
|
-
end
|
|
465
|
-
table.insert(lhs, expr);
|
|
466
|
-
else
|
|
467
|
-
if self.disableLog then error() end;
|
|
468
|
-
logger:error(generateError(self, string.format("expected a valid assignment statement lhs part but got <%s>", expr.kind)));
|
|
469
|
-
end
|
|
470
|
-
end
|
|
471
|
-
|
|
472
|
-
expect(self, TokenKind.Symbol, "=");
|
|
473
|
-
|
|
474
|
-
local rhs = self:exprList(scope);
|
|
475
|
-
|
|
476
|
-
return Ast.AssignmentStatement(lhs, rhs);
|
|
477
|
-
end
|
|
478
|
-
|
|
479
|
-
if self.disableLog then error() end;
|
|
480
|
-
logger:error(generateError(self, "expressions are not valid statements!"));
|
|
481
|
-
end
|
|
482
|
-
|
|
483
|
-
return nil;
|
|
484
|
-
end
|
|
485
|
-
|
|
486
|
-
function Parser:primaryExpression(scope)
|
|
487
|
-
local i = self.index;
|
|
488
|
-
local s = self;
|
|
489
|
-
self.disableLog = true;
|
|
490
|
-
local status, val = pcall(self.expressionFunctionCall, self, scope);
|
|
491
|
-
self.disableLog = false;
|
|
492
|
-
if(status) then
|
|
493
|
-
return val;
|
|
494
|
-
else
|
|
495
|
-
self.index = i;
|
|
496
|
-
return nil;
|
|
497
|
-
end
|
|
498
|
-
end
|
|
499
|
-
|
|
500
|
-
-- List of expressions Seperated by a comma
|
|
501
|
-
function Parser:exprList(scope)
|
|
502
|
-
local expressions = {
|
|
503
|
-
self:expression(scope)
|
|
504
|
-
};
|
|
505
|
-
while(consume(self, TokenKind.Symbol, ",")) do
|
|
506
|
-
table.insert(expressions, self:expression(scope));
|
|
507
|
-
end
|
|
508
|
-
return expressions;
|
|
509
|
-
end
|
|
510
|
-
|
|
511
|
-
-- list of local variable names
|
|
512
|
-
function Parser:nameList(scope)
|
|
513
|
-
local ids = {};
|
|
514
|
-
|
|
515
|
-
local ident = expect(self, TokenKind.Ident);
|
|
516
|
-
local id = scope:addDisabledVariable(ident.value, ident);
|
|
517
|
-
table.insert(ids, id);
|
|
518
|
-
|
|
519
|
-
while(consume(self, TokenKind.Symbol, ",")) do
|
|
520
|
-
ident = expect(self, TokenKind.Ident);
|
|
521
|
-
id = scope:addDisabledVariable(ident.value, ident);
|
|
522
|
-
table.insert(ids, id);
|
|
523
|
-
end
|
|
524
|
-
|
|
525
|
-
return ids;
|
|
526
|
-
end
|
|
527
|
-
|
|
528
|
-
function Parser:enableNameList(scope, list)
|
|
529
|
-
for i, id in ipairs(list) do
|
|
530
|
-
scope:enableVariable(id);
|
|
531
|
-
end
|
|
532
|
-
end
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
-- function name
|
|
536
|
-
function Parser:funcName(scope)
|
|
537
|
-
local ident = expect(self, TokenKind.Ident);
|
|
538
|
-
local baseName = ident.value;
|
|
539
|
-
|
|
540
|
-
local baseScope, baseId = scope:resolve(baseName);
|
|
541
|
-
|
|
542
|
-
local indices = {};
|
|
543
|
-
local passSelf = false;
|
|
544
|
-
while(consume(self, TokenKind.Symbol, ".")) do
|
|
545
|
-
table.insert(indices, expect(self, TokenKind.Ident).value);
|
|
546
|
-
end
|
|
547
|
-
|
|
548
|
-
if(consume(self, TokenKind.Symbol, ":")) then
|
|
549
|
-
table.insert(indices, expect(self, TokenKind.Ident).value);
|
|
550
|
-
passSelf = true;
|
|
551
|
-
end
|
|
552
|
-
|
|
553
|
-
return {
|
|
554
|
-
scope = baseScope,
|
|
555
|
-
id = baseId,
|
|
556
|
-
indices = indices,
|
|
557
|
-
passSelf = passSelf,
|
|
558
|
-
token = ident,
|
|
559
|
-
};
|
|
560
|
-
end
|
|
561
|
-
|
|
562
|
-
-- Expression
|
|
563
|
-
function Parser:expression(scope)
|
|
564
|
-
return self:expressionOr(scope);
|
|
565
|
-
end
|
|
566
|
-
|
|
567
|
-
function Parser:expressionOr(scope)
|
|
568
|
-
local lhs = self:expressionAnd(scope);
|
|
569
|
-
|
|
570
|
-
if(consume(self, TokenKind.Keyword, "or")) then
|
|
571
|
-
local rhs = self:expressionOr(scope);
|
|
572
|
-
return Ast.OrExpression(lhs, rhs, true);
|
|
573
|
-
end
|
|
574
|
-
|
|
575
|
-
return lhs;
|
|
576
|
-
end
|
|
577
|
-
|
|
578
|
-
function Parser:expressionAnd(scope)
|
|
579
|
-
local lhs = self:expressionComparision(scope);
|
|
580
|
-
|
|
581
|
-
if(consume(self, TokenKind.Keyword, "and")) then
|
|
582
|
-
local rhs = self:expressionAnd(scope);
|
|
583
|
-
return Ast.AndExpression(lhs, rhs, true);
|
|
584
|
-
end
|
|
585
|
-
|
|
586
|
-
return lhs;
|
|
587
|
-
end
|
|
588
|
-
|
|
589
|
-
function Parser:expressionComparision(scope)
|
|
590
|
-
local curr = self:expressionStrCat(scope);
|
|
591
|
-
repeat
|
|
592
|
-
local found = false;
|
|
593
|
-
if(consume(self, TokenKind.Symbol, "<")) then
|
|
594
|
-
local rhs = self:expressionStrCat(scope);
|
|
595
|
-
curr = Ast.LessThanExpression(curr, rhs, true);
|
|
596
|
-
found = true;
|
|
597
|
-
end
|
|
598
|
-
|
|
599
|
-
if(consume(self, TokenKind.Symbol, ">")) then
|
|
600
|
-
local rhs = self:expressionStrCat(scope);
|
|
601
|
-
curr = Ast.GreaterThanExpression(curr, rhs, true);
|
|
602
|
-
found = true;
|
|
603
|
-
end
|
|
604
|
-
|
|
605
|
-
if(consume(self, TokenKind.Symbol, "<=")) then
|
|
606
|
-
local rhs = self:expressionStrCat(scope);
|
|
607
|
-
curr = Ast.LessThanOrEqualsExpression(curr, rhs, true);
|
|
608
|
-
found = true;
|
|
609
|
-
end
|
|
610
|
-
|
|
611
|
-
if(consume(self, TokenKind.Symbol, ">=")) then
|
|
612
|
-
local rhs = self:expressionStrCat(scope);
|
|
613
|
-
curr = Ast.GreaterThanOrEqualsExpression(curr, rhs, true);
|
|
614
|
-
found = true;
|
|
615
|
-
end
|
|
616
|
-
|
|
617
|
-
if(consume(self, TokenKind.Symbol, "~=")) then
|
|
618
|
-
local rhs = self:expressionStrCat(scope);
|
|
619
|
-
curr = Ast.NotEqualsExpression(curr, rhs, true);
|
|
620
|
-
found = true;
|
|
621
|
-
end
|
|
622
|
-
|
|
623
|
-
if(consume(self, TokenKind.Symbol, "==")) then
|
|
624
|
-
local rhs = self:expressionStrCat(scope);
|
|
625
|
-
curr = Ast.EqualsExpression(curr, rhs, true);
|
|
626
|
-
found = true;
|
|
627
|
-
end
|
|
628
|
-
until not found;
|
|
629
|
-
|
|
630
|
-
return curr;
|
|
631
|
-
end
|
|
632
|
-
|
|
633
|
-
function Parser:expressionStrCat(scope)
|
|
634
|
-
local lhs = self:expressionAddSub(scope);
|
|
635
|
-
|
|
636
|
-
if(consume(self, TokenKind.Symbol, "..")) then
|
|
637
|
-
local rhs = self:expressionStrCat(scope);
|
|
638
|
-
return Ast.StrCatExpression(lhs, rhs, true);
|
|
639
|
-
end
|
|
640
|
-
|
|
641
|
-
return lhs;
|
|
642
|
-
end
|
|
643
|
-
|
|
644
|
-
function Parser:expressionAddSub(scope)
|
|
645
|
-
local curr = self:expressionMulDivMod(scope);
|
|
646
|
-
|
|
647
|
-
repeat
|
|
648
|
-
local found = false;
|
|
649
|
-
if(consume(self, TokenKind.Symbol, "+")) then
|
|
650
|
-
local rhs = self:expressionMulDivMod(scope);
|
|
651
|
-
curr = Ast.AddExpression(curr, rhs, true);
|
|
652
|
-
found = true;
|
|
653
|
-
end
|
|
654
|
-
|
|
655
|
-
if(consume(self, TokenKind.Symbol, "-")) then
|
|
656
|
-
local rhs = self:expressionMulDivMod(scope);
|
|
657
|
-
curr = Ast.SubExpression(curr, rhs, true);
|
|
658
|
-
found = true;
|
|
659
|
-
end
|
|
660
|
-
until not found;
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
return curr;
|
|
664
|
-
end
|
|
665
|
-
|
|
666
|
-
function Parser:expressionMulDivMod(scope)
|
|
667
|
-
local curr = self:expressionUnary(scope);
|
|
668
|
-
|
|
669
|
-
repeat
|
|
670
|
-
local found = false;
|
|
671
|
-
if(consume(self, TokenKind.Symbol, "*")) then
|
|
672
|
-
local rhs = self:expressionUnary(scope);
|
|
673
|
-
curr = Ast.MulExpression(curr, rhs, true);
|
|
674
|
-
found = true;
|
|
675
|
-
end
|
|
676
|
-
|
|
677
|
-
if(consume(self, TokenKind.Symbol, "/")) then
|
|
678
|
-
local rhs = self:expressionUnary(scope);
|
|
679
|
-
curr = Ast.DivExpression(curr, rhs, true);
|
|
680
|
-
found = true;
|
|
681
|
-
end
|
|
682
|
-
|
|
683
|
-
if(consume(self, TokenKind.Symbol, "%")) then
|
|
684
|
-
local rhs = self:expressionUnary(scope);
|
|
685
|
-
curr = Ast.ModExpression(curr, rhs, true);
|
|
686
|
-
found = true;
|
|
687
|
-
end
|
|
688
|
-
until not found;
|
|
689
|
-
|
|
690
|
-
return curr;
|
|
691
|
-
end
|
|
692
|
-
|
|
693
|
-
function Parser:expressionUnary(scope)
|
|
694
|
-
if(consume(self, TokenKind.Keyword, "not")) then
|
|
695
|
-
local rhs = self:expressionUnary(scope);
|
|
696
|
-
return Ast.NotExpression(rhs, true);
|
|
697
|
-
end
|
|
698
|
-
|
|
699
|
-
if(consume(self, TokenKind.Symbol, "#")) then
|
|
700
|
-
local rhs = self:expressionUnary(scope);
|
|
701
|
-
return Ast.LenExpression(rhs, true);
|
|
702
|
-
end
|
|
703
|
-
|
|
704
|
-
if(consume(self, TokenKind.Symbol, "-")) then
|
|
705
|
-
local rhs = self:expressionUnary(scope);
|
|
706
|
-
return Ast.NegateExpression(rhs, true);
|
|
707
|
-
end
|
|
708
|
-
|
|
709
|
-
return self:expressionPow(scope);
|
|
710
|
-
end
|
|
711
|
-
|
|
712
|
-
function Parser:expressionPow(scope)
|
|
713
|
-
local lhs = self:tableOrFunctionLiteral(scope);
|
|
714
|
-
|
|
715
|
-
if(consume(self, TokenKind.Symbol, "^")) then
|
|
716
|
-
local rhs = self:expressionPow(scope);
|
|
717
|
-
return Ast.PowExpression(lhs, rhs, true);
|
|
718
|
-
end
|
|
719
|
-
|
|
720
|
-
return lhs;
|
|
721
|
-
end
|
|
722
|
-
|
|
723
|
-
-- Table Literals and Function Literals cannot directly be called or indexed
|
|
724
|
-
function Parser:tableOrFunctionLiteral(scope)
|
|
725
|
-
|
|
726
|
-
if(is(self, TokenKind.Symbol, "{")) then
|
|
727
|
-
return self:tableConstructor(scope);
|
|
728
|
-
end
|
|
729
|
-
|
|
730
|
-
if(is(self, TokenKind.Keyword, "function")) then
|
|
731
|
-
return self:expressionFunctionLiteral(scope);
|
|
732
|
-
end
|
|
733
|
-
|
|
734
|
-
return self:expressionFunctionCall(scope);
|
|
735
|
-
end
|
|
736
|
-
|
|
737
|
-
function Parser:expressionFunctionLiteral(parentScope)
|
|
738
|
-
local scope = Scope:new(parentScope);
|
|
739
|
-
|
|
740
|
-
expect(self, TokenKind.Keyword, "function");
|
|
741
|
-
|
|
742
|
-
expect(self, TokenKind.Symbol, "(");
|
|
743
|
-
local args = self:functionArgList(scope);
|
|
744
|
-
expect(self, TokenKind.Symbol, ")");
|
|
745
|
-
|
|
746
|
-
local body = self:block(nil, false, scope);
|
|
747
|
-
expect(self, TokenKind.Keyword, "end");
|
|
748
|
-
|
|
749
|
-
return Ast.FunctionLiteralExpression(args, body);
|
|
750
|
-
end
|
|
751
|
-
|
|
752
|
-
function Parser:functionArgList(scope)
|
|
753
|
-
local args = {};
|
|
754
|
-
if(consume(self, TokenKind.Symbol, "...")) then
|
|
755
|
-
table.insert(args, Ast.VarargExpression());
|
|
756
|
-
return args;
|
|
757
|
-
end
|
|
758
|
-
|
|
759
|
-
if(is(self, TokenKind.Ident)) then
|
|
760
|
-
local ident = get(self);
|
|
761
|
-
local name = ident.value;
|
|
762
|
-
|
|
763
|
-
local id = scope:addVariable(name, ident);
|
|
764
|
-
table.insert(args, Ast.VariableExpression(scope, id));
|
|
765
|
-
|
|
766
|
-
while(consume(self, TokenKind.Symbol, ",")) do
|
|
767
|
-
if(consume(self, TokenKind.Symbol, "...")) then
|
|
768
|
-
table.insert(args, Ast.VarargExpression());
|
|
769
|
-
return args;
|
|
770
|
-
end
|
|
771
|
-
|
|
772
|
-
ident = get(self);
|
|
773
|
-
name = ident.value;
|
|
774
|
-
|
|
775
|
-
id = scope:addVariable(name, ident);
|
|
776
|
-
table.insert(args, Ast.VariableExpression(scope, id));
|
|
777
|
-
end
|
|
778
|
-
end
|
|
779
|
-
|
|
780
|
-
return args;
|
|
781
|
-
end
|
|
782
|
-
|
|
783
|
-
function Parser:expressionFunctionCall(scope, base)
|
|
784
|
-
base = base or self:expressionIndex(scope);
|
|
785
|
-
|
|
786
|
-
-- Normal Function Call
|
|
787
|
-
local args = {};
|
|
788
|
-
if(is(self, TokenKind.String)) then
|
|
789
|
-
args = {
|
|
790
|
-
Ast.StringExpression(get(self).value),
|
|
791
|
-
};
|
|
792
|
-
elseif(is(self, TokenKind.Symbol, "{")) then
|
|
793
|
-
args = {
|
|
794
|
-
self:tableConstructor(scope),
|
|
795
|
-
};
|
|
796
|
-
elseif(consume(self, TokenKind.Symbol, "(")) then
|
|
797
|
-
if(not is(self, TokenKind.Symbol, ")")) then
|
|
798
|
-
args = self:exprList(scope);
|
|
799
|
-
end
|
|
800
|
-
expect(self, TokenKind.Symbol, ")");
|
|
801
|
-
else
|
|
802
|
-
return base;
|
|
803
|
-
end
|
|
804
|
-
|
|
805
|
-
local node = Ast.FunctionCallExpression(base, args);
|
|
806
|
-
|
|
807
|
-
-- the result of a function call can be indexed
|
|
808
|
-
if(is(self, TokenKind.Symbol, ".") or is(self, TokenKind.Symbol, "[") or is(self, TokenKind.Symbol, ":")) then
|
|
809
|
-
return self:expressionIndex(scope, node);
|
|
810
|
-
end
|
|
811
|
-
|
|
812
|
-
-- The result of a function call can be a function that is again called
|
|
813
|
-
if(is(self, TokenKind.Symbol, "(") or is(self, TokenKind.Symbol, "{") or is(self, TokenKind.String)) then
|
|
814
|
-
return self:expressionFunctionCall(scope, node);
|
|
815
|
-
end
|
|
816
|
-
|
|
817
|
-
return node;
|
|
818
|
-
end
|
|
819
|
-
|
|
820
|
-
function Parser:expressionIndex(scope, base)
|
|
821
|
-
base = base or self:expressionLiteral(scope);
|
|
822
|
-
|
|
823
|
-
-- Parse Indexing Expressions
|
|
824
|
-
while(consume(self, TokenKind.Symbol, "[")) do
|
|
825
|
-
local expr = self:expression(scope);
|
|
826
|
-
expect(self, TokenKind.Symbol, "]");
|
|
827
|
-
base = Ast.IndexExpression(base, expr);
|
|
828
|
-
end
|
|
829
|
-
|
|
830
|
-
-- Parse Indexing Expressions
|
|
831
|
-
while consume(self, TokenKind.Symbol, ".") do
|
|
832
|
-
local ident = expect(self, TokenKind.Ident);
|
|
833
|
-
base = Ast.IndexExpression(base, Ast.StringExpression(ident.value));
|
|
834
|
-
|
|
835
|
-
while(consume(self, TokenKind.Symbol, "[")) do
|
|
836
|
-
local expr = self:expression(scope);
|
|
837
|
-
expect(self, TokenKind.Symbol, "]");
|
|
838
|
-
base = Ast.IndexExpression(base, expr);
|
|
839
|
-
end
|
|
840
|
-
end
|
|
841
|
-
|
|
842
|
-
-- Function Passing self
|
|
843
|
-
if(consume(self, TokenKind.Symbol, ":")) then
|
|
844
|
-
local passSelfFunctionName = expect(self, TokenKind.Ident).value;
|
|
845
|
-
local args = {};
|
|
846
|
-
if(is(self, TokenKind.String)) then
|
|
847
|
-
args = {
|
|
848
|
-
Ast.StringExpression(get(self).value),
|
|
849
|
-
};
|
|
850
|
-
elseif(is(self, TokenKind.Symbol, "{")) then
|
|
851
|
-
args = {
|
|
852
|
-
self:tableConstructor(scope),
|
|
853
|
-
};
|
|
854
|
-
else
|
|
855
|
-
expect(self, TokenKind.Symbol, "(");
|
|
856
|
-
if(not is(self, TokenKind.Symbol, ")")) then
|
|
857
|
-
args = self:exprList(scope);
|
|
858
|
-
end
|
|
859
|
-
expect(self, TokenKind.Symbol, ")");
|
|
860
|
-
end
|
|
861
|
-
|
|
862
|
-
local node = Ast.PassSelfFunctionCallExpression(base, passSelfFunctionName, args);
|
|
863
|
-
|
|
864
|
-
-- the result of a function call can be indexed
|
|
865
|
-
if(is(self, TokenKind.Symbol, ".") or is(self, TokenKind.Symbol, "[") or is(self, TokenKind.Symbol, ":")) then
|
|
866
|
-
return self:expressionIndex(scope, node);
|
|
867
|
-
end
|
|
868
|
-
|
|
869
|
-
-- The result of a function call can be a function that is again called
|
|
870
|
-
if(is(self, TokenKind.Symbol, "(") or is(self, TokenKind.Symbol, "{") or is(self, TokenKind.String)) then
|
|
871
|
-
return self:expressionFunctionCall(scope, node);
|
|
872
|
-
end
|
|
873
|
-
|
|
874
|
-
return node
|
|
875
|
-
end
|
|
876
|
-
|
|
877
|
-
-- The result of a function call can be a function that is again called
|
|
878
|
-
if(is(self, TokenKind.Symbol, "(") or is(self, TokenKind.Symbol, "{") or is(self, TokenKind.String)) then
|
|
879
|
-
return self:expressionFunctionCall(scope, base);
|
|
880
|
-
end
|
|
881
|
-
|
|
882
|
-
return base;
|
|
883
|
-
end
|
|
884
|
-
|
|
885
|
-
function Parser:expressionLiteral(scope)
|
|
886
|
-
-- () expression
|
|
887
|
-
if(consume(self, TokenKind.Symbol, "(")) then
|
|
888
|
-
local expr = self:expression(scope);
|
|
889
|
-
expect(self, TokenKind.Symbol, ")");
|
|
890
|
-
return expr;
|
|
891
|
-
end
|
|
892
|
-
|
|
893
|
-
-- String Literal
|
|
894
|
-
if(is(self, TokenKind.String)) then
|
|
895
|
-
return Ast.StringExpression(get(self).value);
|
|
896
|
-
end
|
|
897
|
-
|
|
898
|
-
-- Number Literal
|
|
899
|
-
if(is(self, TokenKind.Number)) then
|
|
900
|
-
return Ast.NumberExpression(get(self).value);
|
|
901
|
-
end
|
|
902
|
-
|
|
903
|
-
-- True Literal
|
|
904
|
-
if(consume(self, TokenKind.Keyword, "true")) then
|
|
905
|
-
return Ast.BooleanExpression(true);
|
|
906
|
-
end
|
|
907
|
-
|
|
908
|
-
-- False Literal
|
|
909
|
-
if(consume(self, TokenKind.Keyword, "false")) then
|
|
910
|
-
return Ast.BooleanExpression(false);
|
|
911
|
-
end
|
|
912
|
-
|
|
913
|
-
-- Nil Literal
|
|
914
|
-
if(consume(self, TokenKind.Keyword, "nil")) then
|
|
915
|
-
return Ast.NilExpression();
|
|
916
|
-
end
|
|
917
|
-
|
|
918
|
-
-- Vararg Literal
|
|
919
|
-
if(consume(self, TokenKind.Symbol, "...")) then
|
|
920
|
-
return Ast.VarargExpression();
|
|
921
|
-
end
|
|
922
|
-
|
|
923
|
-
-- Variable
|
|
924
|
-
if(is(self, TokenKind.Ident)) then
|
|
925
|
-
local ident = get(self);
|
|
926
|
-
local name = ident.value;
|
|
927
|
-
|
|
928
|
-
local scope, id = scope:resolve(name);
|
|
929
|
-
return Ast.VariableExpression(scope, id);
|
|
930
|
-
end
|
|
931
|
-
|
|
932
|
-
if(self.disableLog) then error() end
|
|
933
|
-
logger:error(generateError(self, "Unexpected Token \"" .. peek(self).source .. "\". Expected a Expression!"))
|
|
934
|
-
end
|
|
935
|
-
|
|
936
|
-
function Parser:tableConstructor(scope)
|
|
937
|
-
-- TODO: Parse Table Literals
|
|
938
|
-
local entries = {};
|
|
939
|
-
|
|
940
|
-
expect(self, TokenKind.Symbol, "{");
|
|
941
|
-
|
|
942
|
-
while (not consume(self, TokenKind.Symbol, "}")) do
|
|
943
|
-
if(consume(self, TokenKind.Symbol, "[")) then
|
|
944
|
-
local key = self:expression(scope);
|
|
945
|
-
expect(self, TokenKind.Symbol, "]");
|
|
946
|
-
expect(self, TokenKind.Symbol, "=");
|
|
947
|
-
local value = self:expression(scope);
|
|
948
|
-
table.insert(entries, Ast.KeyedTableEntry(key, value));
|
|
949
|
-
elseif(is(self, TokenKind.Ident, 0) and is(self, TokenKind.Symbol, "=", 1)) then
|
|
950
|
-
local key = Ast.StringExpression(get(self).value);
|
|
951
|
-
expect(self, TokenKind.Symbol, "=");
|
|
952
|
-
local value = self:expression(scope);
|
|
953
|
-
table.insert(entries, Ast.KeyedTableEntry(key, value));
|
|
954
|
-
else
|
|
955
|
-
local value = self:expression(scope);
|
|
956
|
-
table.insert(entries, Ast.TableEntry(value));
|
|
957
|
-
end
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
if (not consume(self, TokenKind.Symbol, ";") and not consume(self, TokenKind.Symbol, ",") and not is(self, TokenKind.Symbol, "}")) then
|
|
961
|
-
if self.disableLog then error() end
|
|
962
|
-
logger:error(generateError(self, "expected a \";\" or a \",\""));
|
|
963
|
-
end
|
|
964
|
-
end
|
|
965
|
-
|
|
966
|
-
return Ast.TableConstructorExpression(entries);
|
|
967
|
-
end
|
|
968
|
-
|
|
969
|
-
return Parser
|