lua-obfuscator 1.0.0

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.
Files changed (144) hide show
  1. package/dist/index.d.ts +14 -0
  2. package/dist/index.js +58 -0
  3. package/dist/prometheus/LICENSE +661 -0
  4. package/dist/prometheus/benchmark.lua +34 -0
  5. package/dist/prometheus/build.bat +10 -0
  6. package/dist/prometheus/cli.lua +12 -0
  7. package/dist/prometheus/doc/README.md +11 -0
  8. package/dist/prometheus/doc/SUMMARY.md +27 -0
  9. package/dist/prometheus/doc/advanced/using-prometheus-in-your-lua-application.md +31 -0
  10. package/dist/prometheus/doc/getting-started/command-line-options.md +13 -0
  11. package/dist/prometheus/doc/getting-started/installation.md +11 -0
  12. package/dist/prometheus/doc/getting-started/obfuscating-your-first-script.md +50 -0
  13. package/dist/prometheus/doc/getting-started/presets.md +10 -0
  14. package/dist/prometheus/doc/getting-started/the-config-object.md +58 -0
  15. package/dist/prometheus/doc/getting-started/writing-a-custom-config-file.md +56 -0
  16. package/dist/prometheus/doc/steps/anti-tamper.md +11 -0
  17. package/dist/prometheus/doc/steps/constantarray.md +71 -0
  18. package/dist/prometheus/doc/steps/encryptstrings.md +86 -0
  19. package/dist/prometheus/doc/steps/proxifylocals.md +47 -0
  20. package/dist/prometheus/doc/steps/splitstrings.md +40 -0
  21. package/dist/prometheus/doc/steps/vmify.md +9 -0
  22. package/dist/prometheus/doc/steps/wrapinfunction.md +29 -0
  23. package/dist/prometheus/prometheus-main.lua +1 -0
  24. package/dist/prometheus/readme.md +57 -0
  25. package/dist/prometheus/readme.txt +5 -0
  26. package/dist/prometheus/src/cli.lua +154 -0
  27. package/dist/prometheus/src/colors.lua +61 -0
  28. package/dist/prometheus/src/config.lua +35 -0
  29. package/dist/prometheus/src/highlightlua.lua +61 -0
  30. package/dist/prometheus/src/logger.lua +62 -0
  31. package/dist/prometheus/src/presets.lua +174 -0
  32. package/dist/prometheus/src/prometheus/ast.lua +792 -0
  33. package/dist/prometheus/src/prometheus/bit.lua +521 -0
  34. package/dist/prometheus/src/prometheus/compiler/compiler.lua +2365 -0
  35. package/dist/prometheus/src/prometheus/enums.lua +106 -0
  36. package/dist/prometheus/src/prometheus/namegenerators/Il.lua +41 -0
  37. package/dist/prometheus/src/prometheus/namegenerators/confuse.lua +169 -0
  38. package/dist/prometheus/src/prometheus/namegenerators/mangled.lua +26 -0
  39. package/dist/prometheus/src/prometheus/namegenerators/mangled_shuffled.lua +35 -0
  40. package/dist/prometheus/src/prometheus/namegenerators/number.lua +11 -0
  41. package/dist/prometheus/src/prometheus/namegenerators.lua +7 -0
  42. package/dist/prometheus/src/prometheus/parser.lua +969 -0
  43. package/dist/prometheus/src/prometheus/pipeline.lua +250 -0
  44. package/dist/prometheus/src/prometheus/randomLiterals.lua +41 -0
  45. package/dist/prometheus/src/prometheus/randomStrings.lua +24 -0
  46. package/dist/prometheus/src/prometheus/scope.lua +332 -0
  47. package/dist/prometheus/src/prometheus/step.lua +79 -0
  48. package/dist/prometheus/src/prometheus/steps/AddVararg.lua +33 -0
  49. package/dist/prometheus/src/prometheus/steps/AntiTamper.lua +194 -0
  50. package/dist/prometheus/src/prometheus/steps/ConstantArray.lua +521 -0
  51. package/dist/prometheus/src/prometheus/steps/EncryptStrings.lua +239 -0
  52. package/dist/prometheus/src/prometheus/steps/NumbersToExpressions.lua +82 -0
  53. package/dist/prometheus/src/prometheus/steps/ProxifyLocals.lua +313 -0
  54. package/dist/prometheus/src/prometheus/steps/SplitStrings.lua +338 -0
  55. package/dist/prometheus/src/prometheus/steps/Vmify.lua +30 -0
  56. package/dist/prometheus/src/prometheus/steps/Watermark.lua +61 -0
  57. package/dist/prometheus/src/prometheus/steps/WatermarkCheck.lua +50 -0
  58. package/dist/prometheus/src/prometheus/steps/WrapInFunction.lua +45 -0
  59. package/dist/prometheus/src/prometheus/steps.lua +12 -0
  60. package/dist/prometheus/src/prometheus/tokenizer.lua +546 -0
  61. package/dist/prometheus/src/prometheus/unparser.lua +866 -0
  62. package/dist/prometheus/src/prometheus/util.lua +297 -0
  63. package/dist/prometheus/src/prometheus/visitast.lua +245 -0
  64. package/dist/prometheus/src/prometheus.lua +71 -0
  65. package/dist/prometheus/tests/closures.lua +12 -0
  66. package/dist/prometheus/tests/fibonacci.lua +10 -0
  67. package/dist/prometheus/tests/loops.lua +8 -0
  68. package/dist/prometheus/tests/primes.lua +18 -0
  69. package/dist/prometheus/tests.lua +149 -0
  70. package/package.json +25 -0
  71. package/src/index.ts +76 -0
  72. package/src/prometheus/.editorconfig +4 -0
  73. package/src/prometheus/.gitattributes +2 -0
  74. package/src/prometheus/.gitbook.yaml +1 -0
  75. package/src/prometheus/.github/ISSUE_TEMPLATE/bug_report.md +25 -0
  76. package/src/prometheus/.github/workflows/Build.yml +49 -0
  77. package/src/prometheus/.github/workflows/Test.yml +19 -0
  78. package/src/prometheus/LICENSE +661 -0
  79. package/src/prometheus/benchmark.lua +34 -0
  80. package/src/prometheus/build.bat +10 -0
  81. package/src/prometheus/cli.lua +12 -0
  82. package/src/prometheus/doc/README.md +11 -0
  83. package/src/prometheus/doc/SUMMARY.md +27 -0
  84. package/src/prometheus/doc/advanced/using-prometheus-in-your-lua-application.md +31 -0
  85. package/src/prometheus/doc/getting-started/command-line-options.md +13 -0
  86. package/src/prometheus/doc/getting-started/installation.md +11 -0
  87. package/src/prometheus/doc/getting-started/obfuscating-your-first-script.md +50 -0
  88. package/src/prometheus/doc/getting-started/presets.md +10 -0
  89. package/src/prometheus/doc/getting-started/the-config-object.md +58 -0
  90. package/src/prometheus/doc/getting-started/writing-a-custom-config-file.md +56 -0
  91. package/src/prometheus/doc/steps/anti-tamper.md +11 -0
  92. package/src/prometheus/doc/steps/constantarray.md +71 -0
  93. package/src/prometheus/doc/steps/encryptstrings.md +86 -0
  94. package/src/prometheus/doc/steps/proxifylocals.md +47 -0
  95. package/src/prometheus/doc/steps/splitstrings.md +40 -0
  96. package/src/prometheus/doc/steps/vmify.md +9 -0
  97. package/src/prometheus/doc/steps/wrapinfunction.md +29 -0
  98. package/src/prometheus/prometheus-main.lua +1 -0
  99. package/src/prometheus/readme.md +57 -0
  100. package/src/prometheus/readme.txt +5 -0
  101. package/src/prometheus/src/cli.lua +154 -0
  102. package/src/prometheus/src/colors.lua +61 -0
  103. package/src/prometheus/src/highlightlua.lua +61 -0
  104. package/src/prometheus/src/logger.lua +62 -0
  105. package/src/prometheus/src/presets.lua +174 -0
  106. package/src/prometheus/src/prometheus/ast.lua +792 -0
  107. package/src/prometheus/src/prometheus/bit.lua +521 -0
  108. package/src/prometheus/src/prometheus/compiler/compiler.lua +2365 -0
  109. package/src/prometheus/src/prometheus/enums.lua +106 -0
  110. package/src/prometheus/src/prometheus/namegenerators/Il.lua +41 -0
  111. package/src/prometheus/src/prometheus/namegenerators/confuse.lua +169 -0
  112. package/src/prometheus/src/prometheus/namegenerators/mangled.lua +26 -0
  113. package/src/prometheus/src/prometheus/namegenerators/mangled_shuffled.lua +35 -0
  114. package/src/prometheus/src/prometheus/namegenerators/number.lua +11 -0
  115. package/src/prometheus/src/prometheus/namegenerators.lua +7 -0
  116. package/src/prometheus/src/prometheus/parser.lua +969 -0
  117. package/src/prometheus/src/prometheus/pipeline.lua +250 -0
  118. package/src/prometheus/src/prometheus/randomLiterals.lua +41 -0
  119. package/src/prometheus/src/prometheus/randomStrings.lua +24 -0
  120. package/src/prometheus/src/prometheus/scope.lua +332 -0
  121. package/src/prometheus/src/prometheus/step.lua +79 -0
  122. package/src/prometheus/src/prometheus/steps/AddVararg.lua +33 -0
  123. package/src/prometheus/src/prometheus/steps/AntiTamper.lua +194 -0
  124. package/src/prometheus/src/prometheus/steps/ConstantArray.lua +521 -0
  125. package/src/prometheus/src/prometheus/steps/EncryptStrings.lua +239 -0
  126. package/src/prometheus/src/prometheus/steps/NumbersToExpressions.lua +82 -0
  127. package/src/prometheus/src/prometheus/steps/ProxifyLocals.lua +313 -0
  128. package/src/prometheus/src/prometheus/steps/SplitStrings.lua +338 -0
  129. package/src/prometheus/src/prometheus/steps/Vmify.lua +30 -0
  130. package/src/prometheus/src/prometheus/steps/Watermark.lua +61 -0
  131. package/src/prometheus/src/prometheus/steps/WatermarkCheck.lua +50 -0
  132. package/src/prometheus/src/prometheus/steps/WrapInFunction.lua +45 -0
  133. package/src/prometheus/src/prometheus/steps.lua +12 -0
  134. package/src/prometheus/src/prometheus/tokenizer.lua +546 -0
  135. package/src/prometheus/src/prometheus/unparser.lua +866 -0
  136. package/src/prometheus/src/prometheus/util.lua +297 -0
  137. package/src/prometheus/src/prometheus/visitast.lua +245 -0
  138. package/src/prometheus/src/prometheus.lua +71 -0
  139. package/src/prometheus/tests/closures.lua +12 -0
  140. package/src/prometheus/tests/fibonacci.lua +10 -0
  141. package/src/prometheus/tests/loops.lua +8 -0
  142. package/src/prometheus/tests/primes.lua +18 -0
  143. package/src/prometheus/tests.lua +149 -0
  144. package/tsconfig.json +13 -0
@@ -0,0 +1,546 @@
1
+ -- This Script is Part of the Prometheus Obfuscator by Levno_710
2
+ --
3
+ -- tokenizer.lua
4
+ -- Overview:
5
+ -- This Script provides a class for lexical Analysis of lua code.
6
+ -- This Tokenizer is Capable of tokenizing LuaU and Lua5.1
7
+ local Enums = require("prometheus.enums");
8
+ local util = require("prometheus.util");
9
+ local logger = require("logger");
10
+ local config = require("config");
11
+
12
+ local LuaVersion = Enums.LuaVersion;
13
+ local lookupify = util.lookupify;
14
+ local unlookupify = util.unlookupify;
15
+ local escape = util.escape;
16
+ local chararray = util.chararray;
17
+ local keys = util.keys;
18
+ local Tokenizer = {};
19
+
20
+ Tokenizer.EOF_CHAR = "<EOF>";
21
+ Tokenizer.WHITESPACE_CHARS = lookupify{
22
+ " ", "\t", "\n", "\r",
23
+ }
24
+
25
+ Tokenizer.ANNOTATION_CHARS = lookupify(chararray("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"))
26
+ Tokenizer.ANNOTATION_START_CHARS = lookupify(chararray("!@"))
27
+
28
+ Tokenizer.Conventions = Enums.Conventions;
29
+
30
+ Tokenizer.TokenKind = {
31
+ Eof = "Eof",
32
+ Keyword = "Keyword",
33
+ Symbol = "Symbol",
34
+ Ident = "Identifier",
35
+ Number = "Number",
36
+ String = "String",
37
+ }
38
+
39
+ Tokenizer.EOF_TOKEN = {
40
+ kind = Tokenizer.TokenKind.Eof,
41
+ value = "<EOF>",
42
+ startPos = -1,
43
+ endPos = -1,
44
+ source = "<EOF>",
45
+ }
46
+
47
+ local function token(self, startPos, kind, value)
48
+ local line, linePos = self:getPosition(self.index);
49
+ local annotations = self.annotations
50
+ self.annotations = {};
51
+ return {
52
+ kind = kind,
53
+ value = value,
54
+ startPos = startPos,
55
+ endPos = self.index,
56
+ source = self.source:sub(startPos + 1, self.index),
57
+ line = line,
58
+ linePos = linePos,
59
+ annotations = annotations,
60
+ }
61
+ end
62
+
63
+ local function generateError(self, message)
64
+ local line, linePos = self:getPosition(self.index);
65
+ return "Lexing Error at Position " .. tostring(line) .. ":" .. tostring(linePos) .. ", " .. message;
66
+ end
67
+
68
+ local function generateWarning(token, message)
69
+ return "Warning at Position " .. tostring(token.line) .. ":" .. tostring(token.linePos) .. ", " .. message;
70
+ end
71
+
72
+ function Tokenizer:getPosition(i)
73
+ local column = self.columnMap[i]
74
+
75
+ if not column then --// `i` is bigger than self.length, this shouldnt happen, but it did. (Theres probably some error in the tokenizer, cant find it.)
76
+ column = self.columnMap[#self.columnMap]
77
+ end
78
+
79
+ return column.id, column.charMap[i]
80
+ end
81
+
82
+ --// Prepare columnMap for getPosition
83
+ function Tokenizer:prepareGetPosition()
84
+ local columnMap, column = {}, { charMap = {}, id = 1, length = 0 }
85
+
86
+ for index = 1, self.length do
87
+ local character = string.sub(self.source, index, index) -- NOTE_1: this could use table.clone to reduce amount of NEWTABLE (if that causes any performance issues)
88
+
89
+ local columnLength = column.length + 1
90
+ column.length = columnLength
91
+ column.charMap[index] = columnLength
92
+
93
+ if character == "\n" then
94
+ column = { charMap = {}, id = column.id + 1, length = 0 } -- NOTE_1
95
+ end
96
+
97
+ columnMap[index] = column
98
+ end
99
+
100
+ self.columnMap = columnMap
101
+ end
102
+
103
+ -- Constructor for Tokenizer
104
+ function Tokenizer:new(settings)
105
+ local luaVersion = (settings and (settings.luaVersion or settings.LuaVersion)) or LuaVersion.LuaU;
106
+ local conventions = Tokenizer.Conventions[luaVersion];
107
+
108
+ if(conventions == nil) then
109
+ logger:error("The Lua Version \"" .. luaVersion .. "\" is not recognised by the Tokenizer! Please use one of the following: \"" .. table.concat(keys(Tokenizer.Conventions), "\",\"") .. "\"");
110
+ end
111
+
112
+ local tokenizer = {
113
+ index = 0, -- Index where the current char is read
114
+ length = 0,
115
+ source = "", -- Source to Tokenize
116
+ luaVersion = luaVersion, -- LuaVersion to be used while Tokenizing
117
+ conventions = conventions;
118
+
119
+ NumberChars = conventions.NumberChars,
120
+ NumberCharsLookup = lookupify(conventions.NumberChars),
121
+ Keywords = conventions.Keywords,
122
+ KeywordsLookup = lookupify(conventions.Keywords),
123
+ BinaryNumberChars = conventions.BinaryNumberChars,
124
+ BinaryNumberCharsLookup = lookupify(conventions.BinaryNumberChars);
125
+ BinaryNums = conventions.BinaryNums,
126
+ HexadecimalNums = conventions.HexadecimalNums,
127
+ HexNumberChars = conventions.HexNumberChars,
128
+ HexNumberCharsLookup = lookupify(conventions.HexNumberChars),
129
+ DecimalExponent = conventions.DecimalExponent,
130
+ DecimalSeperators = conventions.DecimalSeperators,
131
+ IdentChars = conventions.IdentChars,
132
+ IdentCharsLookup = lookupify(conventions.IdentChars),
133
+
134
+ EscapeSequences = conventions.EscapeSequences,
135
+ NumericalEscapes = conventions.NumericalEscapes,
136
+ EscapeZIgnoreNextWhitespace = conventions.EscapeZIgnoreNextWhitespace,
137
+ HexEscapes = conventions.HexEscapes,
138
+ UnicodeEscapes = conventions.UnicodeEscapes,
139
+
140
+ SymbolChars = conventions.SymbolChars,
141
+ SymbolCharsLookup = lookupify(conventions.SymbolChars),
142
+ MaxSymbolLength = conventions.MaxSymbolLength,
143
+ Symbols = conventions.Symbols,
144
+ SymbolsLookup = lookupify(conventions.Symbols),
145
+
146
+ StringStartLookup = lookupify({"\"", "\'"}),
147
+ annotations = {},
148
+ };
149
+
150
+ setmetatable(tokenizer, self);
151
+ self.__index = self;
152
+
153
+ return tokenizer;
154
+ end
155
+
156
+ -- Reset State of Tokenizer to Tokenize another File
157
+ function Tokenizer:reset()
158
+ self.index = 0;
159
+ self.length = 0;
160
+ self.source = "";
161
+ self.annotations = {};
162
+ self.columnMap = {};
163
+ end
164
+
165
+ -- Append String to this Tokenizer
166
+ function Tokenizer:append(code)
167
+ self.source = self.source .. code
168
+ self.length = self.length + code:len();
169
+ self:prepareGetPosition();
170
+ end
171
+
172
+ -- Function to peek the n'th char in the source of the tokenizer
173
+ local function peek(self, n)
174
+ n = n or 0;
175
+ local i = self.index + n + 1;
176
+ if i > self.length then
177
+ return Tokenizer.EOF_CHAR
178
+ end
179
+ return self.source:sub(i, i);
180
+ end
181
+
182
+ -- Function to get the next char in the source
183
+ local function get(self)
184
+ local i = self.index + 1;
185
+ if i > self.length then
186
+ logger:error(generateError(self, "Unexpected end of Input"));
187
+ end
188
+ self.index = self.index + 1;
189
+ return self.source:sub(i, i);
190
+ end
191
+
192
+ -- The same as get except it throws an Error if the char is not contained in charOrLookup
193
+ local function expect(self, charOrLookup)
194
+ if(type(charOrLookup) == "string") then
195
+ charOrLookup = {[charOrLookup] = true};
196
+ end
197
+
198
+ local char = peek(self);
199
+ if charOrLookup[char] ~= true then
200
+ local etb = unlookupify(charOrLookup);
201
+ for i, v in ipairs(etb) do
202
+ etb[i] = escape(v);
203
+ end
204
+ local errorMessage = "Unexpected char \"" .. escape(char) .. "\"! Expected one of \"" .. table.concat(etb, "\",\"") .. "\"";
205
+ logger:error(generateError(self, errorMessage));
206
+ end
207
+
208
+ self.index = self.index + 1;
209
+ return char;
210
+ end
211
+
212
+ -- Returns wether the n'th char is in the lookup
213
+ local function is(self, charOrLookup, n)
214
+ local char = peek(self, n);
215
+ if(type(charOrLookup) == "string") then
216
+ return char == charOrLookup;
217
+ end
218
+ return charOrLookup[char];
219
+ end
220
+
221
+ function Tokenizer:parseAnnotation()
222
+ if is(self, Tokenizer.ANNOTATION_START_CHARS) then
223
+ self.index = self.index + 1;
224
+ local source, length = {}, 0;
225
+ while(is(self, Tokenizer.ANNOTATION_CHARS)) do
226
+ source[length + 1] = get(self)
227
+ length = #source
228
+ end
229
+ if length > 0 then
230
+ self.annotations[string.lower(table.concat(source))] = true;
231
+ end
232
+ return nil;
233
+ end
234
+ return get(self);
235
+ end
236
+
237
+ -- skip one or 0 Comments and return wether one was found
238
+ function Tokenizer:skipComment()
239
+ if(is(self, "-", 0) and is(self, "-", 1)) then
240
+ self.index = self.index + 2;
241
+ if(is(self, "[")) then
242
+ self.index = self.index + 1;
243
+ local eqCount = 0;
244
+ while(is(self, "=")) do
245
+ self.index = self.index + 1;
246
+ eqCount = eqCount + 1;
247
+ end
248
+ if(is(self, "[")) then
249
+ -- Multiline Comment
250
+ -- Get all Chars to Closing bracket but also consider that the count of equal signs must be the same
251
+ while true do
252
+ if(self:parseAnnotation() == ']') then
253
+ local eqCount2 = 0;
254
+ while(is(self, "=")) do
255
+ self.index = self.index + 1;
256
+ eqCount2 = eqCount2 + 1;
257
+ end
258
+ if(is(self, "]")) then
259
+ if(eqCount2 == eqCount) then
260
+ self.index = self.index + 1;
261
+ return true
262
+ end
263
+ end
264
+ end
265
+ end
266
+ end
267
+ end
268
+ -- Single Line Comment
269
+ -- Get all Chars to next Newline
270
+ while(self.index < self.length and self:parseAnnotation() ~= "\n") do end
271
+ return true;
272
+ end
273
+ return false;
274
+ end
275
+
276
+ -- skip All Whitespace and Comments to next Token
277
+ function Tokenizer:skipWhitespaceAndComments()
278
+ while self:skipComment() do end
279
+ while is(self, Tokenizer.WHITESPACE_CHARS) do
280
+ self.index = self.index + 1;
281
+ while self:skipComment() do end
282
+ end
283
+ end
284
+
285
+ local function int(self, chars, seperators)
286
+ local buffer = {};
287
+ while true do
288
+ if (is(self, chars)) then
289
+ buffer[#buffer + 1] = get(self)
290
+ elseif (is(self, seperators)) then
291
+ self.index = self.index + 1;
292
+ else
293
+ break
294
+ end
295
+ end
296
+ return table.concat(buffer);
297
+ end
298
+
299
+ -- Lex the next token as a Number
300
+ function Tokenizer:number()
301
+ local startPos = self.index;
302
+ local source = expect(self, setmetatable({["."] = true}, {__index = self.NumberCharsLookup}));
303
+
304
+ if source == "0" then
305
+ if self.BinaryNums and is(self, lookupify(self.BinaryNums)) then
306
+ self.index = self.index + 1;
307
+ source = int(self, self.BinaryNumberCharsLookup, lookupify(self.DecimalSeperators or {}));
308
+ local value = tonumber(source, 2);
309
+ return token(self, startPos, Tokenizer.TokenKind.Number, value);
310
+ end
311
+
312
+ if self.HexadecimalNums and is(self, lookupify(self.HexadecimalNums)) then
313
+ self.index = self.index + 1;
314
+ source = int(self, self.HexNumberCharsLookup, lookupify(self.DecimalSeperators or {}));
315
+ local value = tonumber(source, 16);
316
+ return token(self, startPos, Tokenizer.TokenKind.Number, value);
317
+ end
318
+ end
319
+
320
+ if source == "." then
321
+ source = source .. int(self, self.NumberCharsLookup, lookupify(self.DecimalSeperators or {}));
322
+ else
323
+ source = source .. int(self, self.NumberCharsLookup, lookupify(self.DecimalSeperators or {}));
324
+ if(is(self, ".")) then
325
+ source = source .. get(self) .. int(self, self.NumberCharsLookup, lookupify(self.DecimalSeperators or {}));
326
+ end
327
+ end
328
+
329
+ if(self.DecimalExponent and is(self, lookupify(self.DecimalExponent))) then
330
+ source = source .. get(self);
331
+ if(is(self, lookupify({"+","-"}))) then
332
+ source = source .. get(self);
333
+ end
334
+ local v = int(self, self.NumberCharsLookup, lookupify(self.DecimalSeperators or {}));
335
+ if(v:len() < 1) then
336
+ logger:error(generateError(self, "Expected a Valid Exponent!"));
337
+ end
338
+ source = source .. v;
339
+ end
340
+
341
+ local value = tonumber(source);
342
+ return token(self, startPos, Tokenizer.TokenKind.Number, value);
343
+ end
344
+
345
+ -- Lex the Next Token as Identifier or Keyword
346
+ function Tokenizer:ident()
347
+ local startPos = self.index;
348
+ local source = expect(self, self.IdentCharsLookup)
349
+ local sourceAddContent = {source}
350
+ while(is(self, self.IdentCharsLookup)) do
351
+ -- source = source .. get(self);
352
+ table.insert(sourceAddContent, get(self))
353
+ end
354
+ source = table.concat(sourceAddContent)
355
+ if(self.KeywordsLookup[source]) then
356
+ return token(self, startPos, Tokenizer.TokenKind.Keyword, source);
357
+ end
358
+
359
+ local tk = token(self, startPos, Tokenizer.TokenKind.Ident, source);
360
+
361
+ if(string.sub(source, 1, string.len(config.IdentPrefix)) == config.IdentPrefix) then
362
+ logger:warn(generateWarning(tk, string.format("identifiers should not start with \"%s\" as this may break the program", config.IdentPrefix)));
363
+ end
364
+
365
+ return tk;
366
+ end
367
+
368
+ function Tokenizer:singleLineString()
369
+ local startPos = self.index;
370
+ local startChar = expect(self, self.StringStartLookup);
371
+ local buffer = {};
372
+
373
+ while (not is(self, startChar)) do
374
+ local char = get(self);
375
+
376
+ -- Single Line String may not contain Linebreaks except when they are escaped by \
377
+ if(char == '\n') then
378
+ self.index = self.index - 1;
379
+ logger:error(generateError(self, "Unterminated String"));
380
+ end
381
+
382
+
383
+ if(char == "\\") then
384
+ char = get(self);
385
+
386
+ local escape = self.EscapeSequences[char];
387
+ if(type(escape) == "string") then
388
+ char = escape;
389
+
390
+ elseif(self.NumericalEscapes and self.NumberCharsLookup[char]) then
391
+ local numstr = char;
392
+
393
+ if(is(self, self.NumberCharsLookup)) then
394
+ char = get(self);
395
+ numstr = numstr .. char;
396
+ end
397
+
398
+ if(is(self, self.NumberCharsLookup)) then
399
+ char = get(self);
400
+ numstr = numstr .. char;
401
+ end
402
+
403
+ char = string.char(tonumber(numstr));
404
+
405
+ elseif(self.UnicodeEscapes and char == "u") then
406
+ expect(self, "{");
407
+ local num = "";
408
+ while (is(self, self.HexNumberCharsLookup)) do
409
+ num = num .. get(self);
410
+ end
411
+ expect(self, "}");
412
+ char = util.utf8char(tonumber(num, 16));
413
+ elseif(self.HexEscapes and char == "x") then
414
+ local hex = expect(self, self.HexNumberCharsLookup) .. expect(self, self.HexNumberCharsLookup);
415
+ char = string.char(tonumber(hex, 16));
416
+ elseif(self.EscapeZIgnoreNextWhitespace and char == "z") then
417
+ char = "";
418
+ while(is(self, Tokenizer.WHITESPACE_CHARS)) do
419
+ self.index = self.index + 1;
420
+ end
421
+ end
422
+ end
423
+
424
+ --// since table.insert is slower in lua51
425
+ buffer[#buffer + 1] = char
426
+ end
427
+
428
+ expect(self, startChar);
429
+
430
+ return token(self, startPos, Tokenizer.TokenKind.String, table.concat(buffer))
431
+ end
432
+
433
+ function Tokenizer:multiLineString()
434
+ local startPos = self.index;
435
+ if(is(self, "[")) then
436
+ self.index = self.index + 1;
437
+ local eqCount = 0;
438
+ while(is(self, "=")) do
439
+ self.index = self.index + 1;
440
+ eqCount = eqCount + 1;
441
+ end
442
+ if(is(self, "[")) then
443
+ -- Multiline String
444
+ -- Parse String to Closing bracket but also consider that the count of equal signs must be the same
445
+
446
+ -- Skip Leading newline if existing
447
+ self.index = self.index + 1;
448
+ if(is(self, "\n")) then
449
+ self.index = self.index + 1;
450
+ end
451
+
452
+ local value = "";
453
+ while true do
454
+ local char = get(self);
455
+ if(char == ']') then
456
+ local eqCount2 = 0;
457
+ while(is(self, "=")) do
458
+ char = char .. get(self);
459
+ eqCount2 = eqCount2 + 1;
460
+ end
461
+ if(is(self, "]")) then
462
+ if(eqCount2 == eqCount) then
463
+ self.index = self.index + 1;
464
+ return token(self, startPos, Tokenizer.TokenKind.String, value), true
465
+ end
466
+ end
467
+ end
468
+ value = value .. char;
469
+ end
470
+ end
471
+ end
472
+ self.index = startPos;
473
+ return nil, false -- There was not an actual multiline string at the given Position
474
+ end
475
+
476
+ function Tokenizer:symbol()
477
+ local startPos = self.index;
478
+ for len = self.MaxSymbolLength, 1, -1 do
479
+ local str = self.source:sub(self.index + 1, self.index + len);
480
+ if self.SymbolsLookup[str] then
481
+ self.index = self.index + len;
482
+ return token(self, startPos, Tokenizer.TokenKind.Symbol, str);
483
+ end
484
+ end
485
+ logger:error(generateError(self, "Unknown Symbol"));
486
+ end
487
+
488
+
489
+ -- get the Next token
490
+ function Tokenizer:next()
491
+ -- Skip All Whitespace before the token
492
+ self:skipWhitespaceAndComments();
493
+
494
+ local startPos = self.index;
495
+ if startPos >= self.length then
496
+ return token(self, startPos, Tokenizer.TokenKind.Eof);
497
+ end
498
+
499
+ -- Numbers
500
+ if(is(self, self.NumberCharsLookup)) then
501
+ return self:number();
502
+ end
503
+
504
+ -- Identifiers and Keywords
505
+ if(is(self, self.IdentCharsLookup)) then
506
+ return self:ident();
507
+ end
508
+
509
+ -- Singleline String Literals
510
+ if(is(self, self.StringStartLookup)) then
511
+ return self:singleLineString();
512
+ end
513
+
514
+ -- Multiline String Literals
515
+ if(is(self, "[", 0)) then
516
+ -- The isString variable is due to the fact that "[" could also be a symbol for indexing
517
+ local value, isString = self:multiLineString();
518
+ if isString then
519
+ return value;
520
+ end
521
+ end
522
+
523
+ -- Number starting with dot
524
+ if(is(self, ".") and is(self, self.NumberCharsLookup, 1)) then
525
+ return self:number();
526
+ end
527
+
528
+ -- Symbols
529
+ if(is(self, self.SymbolCharsLookup)) then
530
+ return self:symbol();
531
+ end
532
+
533
+
534
+ logger:error(generateError(self, "Unexpected char \"" .. escape(peek(self)) .. "\"!"));
535
+ end
536
+
537
+ function Tokenizer:scanAll()
538
+ local tb = {};
539
+ repeat
540
+ local token = self:next();
541
+ table.insert(tb, token);
542
+ until token.kind == Tokenizer.TokenKind.Eof
543
+ return tb
544
+ end
545
+
546
+ return Tokenizer