├── LICENSE ├── README.md ├── equals.lua ├── errorgen.lua ├── parser-gen-tests.lua ├── parser-gen.lua ├── parsers ├── lua-5.3.4-tests │ ├── all.lua │ ├── api.lua │ ├── attrib.lua │ ├── big.lua │ ├── bitwise.lua │ ├── calls.lua │ ├── closure.lua │ ├── code.lua │ ├── constructs.lua │ ├── coroutine.lua │ ├── db.lua │ ├── errors.lua │ ├── events.lua │ ├── files.lua │ ├── gc.lua │ ├── goto.lua │ ├── literals.lua │ ├── locals.lua │ ├── main.lua │ ├── math.lua │ ├── nextvar.lua │ ├── pm.lua │ ├── sort.lua │ ├── strings.lua │ ├── tpack.lua │ ├── utf8.lua │ ├── vararg.lua │ └── verybig.lua ├── lua-parser-tests.lua ├── lua-parser.lua └── tiny-parser.lua ├── peg-parser-tests.lua ├── peg-parser.lua ├── rockspecs ├── parser-gen-1.0.rockspec ├── parser-gen-1.1.rockspec └── parser-gen-1.2.rockspec └── stack.lua /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Benas Vaitkevicius 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /equals.lua: -------------------------------------------------------------------------------- 1 | -- this function compares if two tables are equal 2 | local function equals(o1, o2, ignore_mt) 3 | if o1 == o2 then return true end 4 | local o1Type = type(o1) 5 | local o2Type = type(o2) 6 | if o1Type ~= o2Type then return false end 7 | if o1Type ~= 'table' then return false end 8 | 9 | if not ignore_mt then 10 | local mt1 = getmetatable(o1) 11 | if mt1 and mt1.__eq then 12 | --compare using built in method 13 | return o1 == o2 14 | end 15 | end 16 | 17 | local keySet = {} 18 | 19 | for key1, value1 in pairs(o1) do 20 | local value2 = o2[key1] 21 | if value2 == nil or equals(value1, value2, ignore_mt) == false then 22 | return false 23 | end 24 | keySet[key1] = true 25 | end 26 | 27 | for key2, _ in pairs(o2) do 28 | if not keySet[key2] then return false end 29 | end 30 | return true 31 | end 32 | return {equals=equals} -------------------------------------------------------------------------------- /errorgen.lua: -------------------------------------------------------------------------------- 1 | -- Error generation code for LL(1) grammars 2 | -- AST funcs: 3 | 4 | local function isfinal(t) 5 | return t["t"] or t["nt"] or t["func"] or t["s"] or t["num"] 6 | end 7 | 8 | local function isaction(t) 9 | return t["action"] 10 | end 11 | 12 | 13 | local function isrule(t) 14 | return t and t["rulename"] 15 | end 16 | 17 | local function isgrammar(t) 18 | if type(t) == "table" and not(t["action"]) then 19 | return isrule(t[1]) 20 | end 21 | return false 22 | end 23 | local function istoken (t) 24 | return t["token"] == "1" 25 | end 26 | 27 | local function finalNode (t) 28 | if t["t"] then 29 | return"t",t["t"] -- terminal 30 | elseif t["nt"] then 31 | return "nt", t["nt"], istoken(t) -- nonterminal 32 | elseif t["func"] then 33 | return "func", t["func"] -- function 34 | elseif t["s"] then 35 | return "s", t["s"] 36 | elseif t["num"] then 37 | return "num", t["num"] 38 | end 39 | return nil 40 | end 41 | 42 | --[[ 43 | 44 | function rightleaf: 45 | 46 | returns the right-most concatenation in the AST. 47 | used for followset keys 48 | 49 | input: ((A B) C) 50 | output: {"nt_C"} 51 | 52 | input: (A / B / C) (D / 'e') 53 | output: {"nt_D","t_e"} 54 | 55 | input: A* 56 | output: {'',"nt_A"} 57 | 58 | input: !A 59 | output: {"not_nt_A"} 60 | ]] 61 | local function addnot(t) 62 | local ret = {} 63 | for k,v in pairs(t) do 64 | ret[k] = "not_"..v 65 | end 66 | return ret 67 | end 68 | local function addepsilon(t) 69 | local ret = t 70 | table.insert(ret, '') 71 | return ret 72 | end 73 | local function mergetables(first,second) 74 | local ret = first 75 | for k,v in pairs(second) do 76 | table.insert(ret, v) 77 | end 78 | return ret 79 | end 80 | 81 | local function rightleaf(t) 82 | local action = t.action 83 | local op1 = t.op1 84 | local op2 = t.op2 85 | 86 | if isfinal(t) then 87 | 88 | -- todo: replace nt_A with FIRST(A) 89 | local typefn, fn, tok = finalNode(t) 90 | local ret = typefn .. "_" .. fn -- terminals: t_if, nonterminals: nt_if 91 | return {ret} 92 | 93 | end 94 | 95 | 96 | if action == "or" then 97 | 98 | return mergetables(rightleaf(op1), rightleaf(op2)) 99 | 100 | elseif action == "and" then -- consider only RHS 101 | 102 | return rightleaf(op2) 103 | 104 | elseif action == "&" then 105 | 106 | return rightleaf(op1) 107 | 108 | elseif action == "!" then 109 | 110 | return addnot(rightleaf(op1)) 111 | 112 | elseif action == "+" then 113 | 114 | return rightleaf(op1) 115 | 116 | elseif action == "*" or action == "?" then 117 | 118 | return addepsilon(rightleaf(op1)) 119 | 120 | elseif action == "^" then 121 | 122 | op2 = op2["num"] -- second operand is number 123 | if op2 >= 1 then 124 | return rightleaf(op1) 125 | else 126 | return addepsilon(rightleaf(op1)) 127 | end 128 | 129 | elseif action == "^LABEL" or action == "->" or action == "=>" or action == "tcap" or action == "gcap" or action == "subcap" or action == "scap" then 130 | 131 | return rightleaf(op1) 132 | 133 | elseif action == "bref" or action == "poscap" then 134 | 135 | return addepsilon({}) -- only empty string 136 | 137 | elseif action == "anychar" then 138 | 139 | return {"_anychar"} 140 | 141 | elseif action == "label" then 142 | 143 | return addepsilon({}) 144 | 145 | elseif action == "%" then 146 | 147 | return addepsilon({}) 148 | 149 | elseif action == "invert" then 150 | 151 | return addnot(rightleaf(op1)) 152 | 153 | elseif action == "range" then 154 | 155 | return {"_anychar"} 156 | 157 | else 158 | error("Unsupported action '"..action.."'") 159 | end 160 | 161 | end 162 | 163 | 164 | local FOLLOW = {} 165 | 166 | local function follow_aux(t, dontsplit) 167 | 168 | local action = t.action 169 | local op1 = t.op1 170 | local op2 = t.op2 171 | 172 | 173 | if isfinal(t) then 174 | 175 | return {t} 176 | 177 | end 178 | 179 | if action == "or" then 180 | 181 | if dontsplit then -- do not split "(B / C)" in "A (B / C)" 182 | return {t} 183 | else -- return both 184 | return mergetables(follow_aux(op1), follow_aux(op2)) 185 | end 186 | 187 | elseif action == "and" then -- magic happens here 188 | 189 | -- (A (B / D)) (!E C / D) 190 | 191 | -- 1) FOLLOW(B) = FOLLOW(D) = {(!E C / D)} 192 | local rightset = rightleaf(op1) 193 | local rhs = follow_aux(op2) 194 | for k,v in pairs(rightset) do 195 | if not FOLLOW[v] then 196 | FOLLOW[v] = {} 197 | end 198 | -- TODO: check if rhs already exists in FOLLOW(v) 199 | table.insert(FOLLOW[v],rhs) 200 | 201 | end 202 | 203 | -- 2) FOLLOW(A) = {(B / D)} 204 | 205 | return follow_aux(op1) 206 | 207 | 208 | elseif action == "&" then 209 | 210 | return follow_aux(op1) 211 | 212 | elseif action == "!" then 213 | 214 | return {action="!", op1=follow_aux(op1)} 215 | 216 | elseif action == "+" then 217 | 218 | return follow_aux(op1) 219 | 220 | elseif action == "*" then 221 | 222 | return addepsilon(follow_aux(op1)) 223 | 224 | elseif action == "?" then 225 | 226 | return addepsilon(follow_aux(op1)) 227 | 228 | elseif action == "^" then 229 | 230 | op2 = op2["num"] 231 | 232 | if op2 >= 1 then 233 | return follow_aux(op1) 234 | else 235 | return addepsilon(follow_aux(op1)) 236 | end 237 | 238 | elseif action == "^LABEL" or action == "->" or action == "=>" or action == "tcap" or action == "gcap" or action == "subcap" or action == "scap" then 239 | 240 | return follow_aux(op1) 241 | 242 | elseif action == "bref" or action == "poscap" then 243 | 244 | return addepsilon({}) -- only empty string 245 | 246 | elseif action == "anychar" then 247 | 248 | return {"_anychar"} 249 | 250 | elseif action == "label" then 251 | 252 | return addepsilon({}) 253 | 254 | elseif action == "%" then 255 | 256 | return addepsilon({}) 257 | 258 | elseif action == "invert" then 259 | 260 | return {t} -- whole table 261 | 262 | elseif action == "range" then 263 | 264 | return {"_anychar"} 265 | 266 | else 267 | error("Unsupported action '"..action.."'") 268 | end 269 | end 270 | 271 | -- function: follow 272 | -- finds follow set for the whole AST, with key (rule, term) 273 | local function follow (t) 274 | local followset = {} 275 | if isgrammar(t) then 276 | for pos,val in pairs(t) do 277 | local rule = val.rulename 278 | FOLLOW = {} -- reset for each rule 279 | follow_aux(val.rule) -- apply recursive function 280 | followset[rule] = FOLLOW 281 | end 282 | else 283 | FOLLOW = {} 284 | follow_aux(t) 285 | followset[''] = FOLLOW 286 | end 287 | return followset 288 | end 289 | 290 | -- functions to add errors 291 | -- find size of table 292 | local function getn (t) 293 | local size = 0 294 | for _, _ in pairs(t) do 295 | size = size+1 296 | end 297 | return size 298 | end 299 | -- generate error message by traversing table to the left 300 | local function printexpect(op) 301 | --peg.print_r(op) 302 | if isfinal(op) then 303 | if op["t"] then 304 | return "'"..op["t"].."'" 305 | end 306 | return op["nt"] or op["func"] or op["s"] or op["num"] 307 | else 308 | local test = op.op1 309 | if not test then 310 | return op.action 311 | else 312 | return printexpect(test) 313 | end 314 | end 315 | end 316 | local GENERATED_ERRORS = 0 317 | local TERRS = {} 318 | local function generateerror(op, after) 319 | 320 | local desc = "Expected "..printexpect(op) 321 | 322 | local err = GENERATED_ERRORS+1 323 | if err >= 255 then 324 | error("Error label limit reached(255)") 325 | end 326 | local name = "errorgen"..err 327 | TERRS[name] = desc 328 | GENERATED_ERRORS = GENERATED_ERRORS+1 329 | return name 330 | end 331 | 332 | 333 | local function tryadderror(op, after) 334 | 335 | if FOLLOW then 336 | 337 | local rhs = rightleaf(after) 338 | -- (A / B) C 339 | -- generate error iff #FOLLOW(A) OR #FOLLOW(B) = 1 340 | local generate = false 341 | for k,v in pairs(rhs) do 342 | if FOLLOW[v] then 343 | local n = getn(FOLLOW[v]) 344 | generate = generate or n==1 345 | end 346 | end 347 | if generate then 348 | local lab = generateerror(op, after) 349 | return {action="^LABEL",op1=op,op2={s=lab}} 350 | end 351 | end 352 | return op 353 | end 354 | 355 | 356 | -- function: adderrors 357 | -- traverses the AST and adds error labels where possible 358 | 359 | local function adderrors_aux(ast,tokenrule) 360 | 361 | if not ast then 362 | return nil 363 | end 364 | 365 | if isaction(ast) then 366 | 367 | local act, op1, op2 368 | act = ast["action"] 369 | op1 = ast["op1"] 370 | op2 = ast["op2"] 371 | 372 | if act == "and" and not tokenrule then 373 | 374 | op2 = tryadderror(op2, op1) 375 | 376 | end 377 | 378 | ast["op1"] = adderrors_aux(op1,tokenrule) 379 | ast["op2"] = adderrors_aux(op2,tokenrule) 380 | end 381 | return ast 382 | end 383 | local function adderrors(t, followset) 384 | GENERATED_ERRORS = 0 385 | TERRS = {} 386 | if isgrammar(t) then 387 | for pos,val in pairs(t) do 388 | local currentrule = val.rulename 389 | FOLLOW = followset[currentrule] 390 | local rule = val.rule 391 | local istokenrule = val.token == "1" 392 | adderrors_aux(rule,istokenrule) 393 | end 394 | else 395 | FOLLOW = followset[''] 396 | adderrors_aux(t,false) 397 | end 398 | return TERRS 399 | end 400 | 401 | return {follow=follow,adderrors=adderrors} 402 | -------------------------------------------------------------------------------- /parser-gen-tests.lua: -------------------------------------------------------------------------------- 1 | local pg = require "parser-gen" 2 | local peg = require "peg-parser" 3 | local re = require "relabel" 4 | 5 | local eq = require "equals" 6 | 7 | local equals = eq.equals 8 | 9 | 10 | local pr = peg.print_r 11 | 12 | 13 | -- terminals 14 | -- space allowed 15 | rule = pg.compile [[ 16 | rule <- 'a' 17 | ]] 18 | str = "a a aa " 19 | res = pg.parse(str,rule) 20 | assert(res) 21 | 22 | -- space not allowed 23 | rule = pg.compile [[ 24 | RULE <- 'a' 'b' 25 | ]] 26 | str = "a b" 27 | res = pg.parse(str,rule) 28 | assert(not res) 29 | 30 | -- space not allowed 2 31 | rule = pg.compile [[ 32 | rule <- 'a' 'b' 33 | SKIP <- '' 34 | SYNC <- '' 35 | ]] 36 | str = "a b" 37 | res = pg.parse(str,rule) 38 | assert(not res) 39 | 40 | -- custom space 41 | rule = pg.compile [[ 42 | rule <- 'a' 'b' 43 | SKIP <- DOT 44 | DOT <- '.' 45 | ]] 46 | str = "a...b" 47 | res = pg.parse(str,rule) 48 | assert(res) 49 | 50 | -- non terminals 51 | -- space allowed 52 | rule = pg.compile [[ 53 | rule <- A B 54 | A <- 'a' 55 | B <- 'b' 56 | ]] 57 | str = "a b" 58 | res, err = pg.parse(str,rule) 59 | assert(res) 60 | -- no spaces allowed 61 | rule = pg.compile [[ 62 | RULE <- A B 63 | A <- 'a' 64 | B <- 'b' 65 | ]] 66 | str = "a b" 67 | res = pg.parse(str,rule) 68 | assert(not res) 69 | 70 | -- space in the beginning and end of string 71 | rule = pg.compile [[ 72 | rule <- A B 73 | A <- 'a' 74 | B <- 'b' 75 | ]] 76 | str = " a b " 77 | res = pg.parse(str,rule) 78 | assert(res) 79 | 80 | 81 | 82 | -- TESTING CAPTURES 83 | 84 | r = pg.compile([[ rule <- {| {:'a' 'b':}* |} 85 | 86 | ]],_,_,true) 87 | res = pg.parse("ababab", r) 88 | 89 | assert(equals(res,{"ab","ab","ab"})) 90 | -- space in capture 91 | 92 | rule = pg.compile([[ rule <- {| {: 'a' :}* |} 93 | ]],_,_,true) 94 | str = " a a a " 95 | res = pg.parse(str,rule) 96 | 97 | assert(equals(res,{"a","a","a"})) -- fails 98 | 99 | -- TESTING ERROR LABELS 100 | local labs = {errName = "Error number 1",errName2 = "Error number 2"} 101 | pg.setlabels(labs) 102 | rule = pg.compile [[ rule <- 'a' / %{errName} 103 | SYNC <- '' 104 | ]] 105 | local errorcalled = false 106 | local function err(desc, line, col, sfail, recexp) 107 | errorcalled = true 108 | assert(desc == "Error number 1") 109 | end 110 | res = pg.parse("b",rule,err) 111 | assert(errorcalled) 112 | 113 | -- TESTING ERROR RECOVERY 114 | 115 | local labs = {errName = "Error number 1",errName2 = "Error number 2"} 116 | pg.setlabels(labs) 117 | 118 | rule = pg.compile [[ 119 | rule <- As //{errName,errName2} Bs 120 | As <- 'a'* / %{errName2} 121 | Bs <- 'b'* 122 | ]] 123 | res1 = pg.parse(" a a a",rule) 124 | res2 = pg.parse("b b b ",rule) 125 | assert(res1 and res2) 126 | 127 | -- TESTING ERROR GENERATION 128 | 129 | pg.setlabels({}) 130 | rule = pg.compile([[ 131 | rule <- A B C 132 | A <- 'a' 133 | B <- 'b' 134 | C <- 'c' 135 | 136 | ]],_,true) 137 | res1, errs = pg.parse("ab",rule) 138 | assert(errs[1]["msg"] == "Expected C") 139 | 140 | -- TESTING RECOVERY GENERATION 141 | 142 | 143 | -- SELF-DESCRIPTION 144 | pg.setlabels(peg.labels) 145 | gram = pg.compile(peg.gram, peg.defs,_,true) 146 | res1, errs = pg.parse(peg.gram,gram) 147 | assert(res1) -- parse succesful 148 | 149 | --[[ this test is invalid since tool added ^LABEL syntax 150 | r = re.compile(peg.gram,peg.defs) 151 | res2 = r:match(peg.gram) 152 | 153 | --peg.print_r(res2) 154 | 155 | assert(equals(res1, res2)) 156 | ]]-- 157 | 158 | 159 | 160 | print("all tests succesful") -------------------------------------------------------------------------------- /parser-gen.lua: -------------------------------------------------------------------------------- 1 | local m = require "lpeglabel" 2 | local peg = require "peg-parser" 3 | local eg = require "errorgen" 4 | local s = require "stack" 5 | 6 | -- create stack for tokens inside captures. nil - not inside capture, 0 - inside capture, 1 - token found inside capture 7 | local tokenstack = s.Stack:Create() 8 | 9 | 10 | 11 | local subject, errors, errorfunc 12 | 13 | -- Lua 5.1 compatibility: 14 | local unpack = unpack or table.unpack 15 | 16 | 17 | local Predef = { nl = m.P"\n", cr = m.P"\r", tab = m.P"\t" } 18 | 19 | 20 | local mem = {} -- for compiled grammars 21 | 22 | local function updatelocale() 23 | m.locale(Predef) 24 | local any = m.P(1) 25 | Predef.a = Predef.alpha 26 | Predef.c = Predef.cntrl 27 | Predef.d = Predef.digit 28 | Predef.g = Predef.graph 29 | Predef.l = Predef.lower 30 | Predef.p = Predef.punct 31 | Predef.s = Predef.space 32 | Predef.u = Predef.upper 33 | Predef.w = Predef.alnum 34 | Predef.x = Predef.xdigit 35 | Predef.A = any - Predef.a 36 | Predef.C = any - Predef.c 37 | Predef.D = any - Predef.d 38 | Predef.G = any - Predef.g 39 | Predef.L = any - Predef.l 40 | Predef.P = any - Predef.p 41 | Predef.S = any - Predef.s 42 | Predef.U = any - Predef.u 43 | Predef.W = any - Predef.w 44 | Predef.X = any - Predef.x 45 | mem = {} 46 | end 47 | 48 | updatelocale() 49 | 50 | local definitions = {} 51 | local tlabels = {} 52 | local totallabels = 0 53 | local tlabelnames = {} -- reverse table 54 | local tdescs = {} 55 | local trecs = {} -- recovery for each error 56 | 57 | 58 | local function defaultsync(patt) 59 | return (m.P(1)^-1) * (-patt * m.P(1))^0 60 | end 61 | 62 | -- TODO: store these variables for each grammar 63 | local SKIP = (Predef.space + Predef.nl) 64 | local SYNC = defaultsync(SKIP) 65 | 66 | 67 | local recovery = true 68 | local skipspaces = true 69 | local buildast = true 70 | 71 | local function sync (patt) 72 | return patt --(-patt * m.P(1))^0 * patt^0 -- skip until we find the pattern and consume it(if we do) 73 | end 74 | 75 | 76 | local function pattspaces (patt) 77 | if skipspaces then 78 | return patt * SKIP^0 79 | else 80 | return patt 81 | end 82 | end 83 | 84 | local function token (patt) 85 | local incapture = tokenstack:pop() -- returns nil if not in capture 86 | if not incapture then 87 | return pattspaces(patt) 88 | end 89 | tokenstack:push(1) 90 | return patt 91 | end 92 | 93 | 94 | 95 | 96 | -- functions used by the tool 97 | 98 | local function iscompiled (gr) 99 | return m.type(gr) == "pattern" 100 | end 101 | 102 | local function istoken (t) 103 | return t["token"] == "1" 104 | end 105 | 106 | local function isfinal(t) 107 | return t["t"] or t["nt"] or t["func"] or t["s"] or t["num"] 108 | end 109 | 110 | local function isaction(t) 111 | return t["action"] 112 | end 113 | 114 | 115 | local function isrule(t) 116 | return t and t["rulename"] 117 | end 118 | local function isgrammar(t) 119 | if type(t) == "table" and not(t["action"]) then 120 | return isrule(t[1]) 121 | end 122 | return false 123 | end 124 | 125 | local function iscapture (action) 126 | return action == "=>" or action == "gcap" or action == "scap" or action == "subcap" or action == "poscap" 127 | end 128 | 129 | local function finalNode (t) 130 | if t["t"] then 131 | return"t",t["t"] -- terminal 132 | elseif t["nt"] then 133 | return "nt", t["nt"], istoken(t) -- nonterminal 134 | elseif t["func"] then 135 | return "func", t["func"] -- function 136 | elseif t["s"] then 137 | return "s", t["s"] 138 | elseif t["num"] then 139 | return "num", t["num"] 140 | end 141 | return nil 142 | end 143 | local bg = {} -- local variable to keep global function buildgrammar 144 | 145 | 146 | local function addspaces (caps) 147 | local hastoken = tokenstack:pop() 148 | if hastoken == 1 then 149 | return pattspaces(caps) 150 | end 151 | return caps 152 | end 153 | 154 | local function applyaction(action, op1, op2, labels,tokenrule) 155 | if action == "or" then 156 | if labels then -- labels = {{s="errName"},{s="errName2"}} 157 | for i, v in ipairs(labels) do 158 | local labname = v["s"] 159 | local lab = tlabels[labname] 160 | if not lab then 161 | error("Label '"..labname.."' undefined") 162 | end 163 | labels[i] = lab 164 | end 165 | return m.Rec(op1,op2,unpack(labels)) 166 | end 167 | return op1 + op2 168 | elseif action == "and" then 169 | 170 | return op1 * op2 171 | elseif action == "&" then 172 | return #op1 173 | elseif action == "!" then 174 | return -op1 175 | elseif action == "+" then 176 | return op1^1 177 | elseif action == "*" then 178 | return op1^0 179 | elseif action == "?" then 180 | return op1^-1 181 | elseif action == "^" then 182 | return op1^op2 183 | elseif action == "^LABEL" then 184 | local lab = tlabels[op2] 185 | if not lab then 186 | error("Label '"..op2.."' unspecified using setlabels()") 187 | end 188 | return op1 + m.T(lab) 189 | elseif action == "->" then 190 | return op1 / op2 191 | -- in captures we add SPACES^0 192 | elseif action == "=>" then 193 | return addspaces(m.Cmt(op1,op2)) 194 | elseif action == "tcap" then 195 | return m.Ct(op1) -- nospaces 196 | elseif action == "gcap" then 197 | return addspaces(m.Cg(op1, op2)) 198 | elseif action == "bref" then 199 | return m.Cb(op1) --m.Cmt(m.Cb(op1), equalcap) -- do we need to add spaces to bcap? 200 | elseif action == "poscap" then 201 | return addspaces(m.Cp()) 202 | elseif action == "subcap" then 203 | return addspaces(m.Cs(op1)) 204 | elseif action == "scap" then 205 | return addspaces(m.C(op1)) 206 | elseif action == "anychar" then 207 | if buildast and not tokenrule then 208 | return m.C(m.P(1)) 209 | end 210 | return m.P(1) 211 | elseif action == "label" then 212 | local lab = tlabels[op1] 213 | if not lab then 214 | error("Label '"..op1.."' unspecified using setlabels()") 215 | end 216 | return m.T(lab) -- lpeglabel 217 | elseif action == "%" then 218 | if definitions[op1] then 219 | return definitions[op1] 220 | elseif Predef[op1] then 221 | return Predef[op1] 222 | else 223 | error("Definition for '%"..op1.."' unspecified(use second parameter of parser-gen.compile())") 224 | end 225 | elseif action == "invert" then 226 | return m.P(1) - op1 227 | elseif action == "range" then 228 | local res = m.R(op1) 229 | if not tokenrule then 230 | if buildast then 231 | res = m.C(res) 232 | end 233 | res = token(res) 234 | end 235 | return res 236 | else 237 | error("Unsupported action '"..action.."'") 238 | end 239 | end 240 | 241 | local function applyfinal(action, term, tokenterm, tokenrule) 242 | 243 | if action == "t" then 244 | local res = m.P(term) 245 | if not tokenrule then 246 | if buildast then 247 | res = m.C(res) 248 | end 249 | if skipspaces then 250 | res = token(res) 251 | end 252 | end 253 | return res 254 | elseif action == "nt" then 255 | if skipspaces and tokenterm and (not tokenrule) then 256 | return token(m.V(term)) 257 | else 258 | return m.V(term) 259 | end 260 | elseif action == "func" then 261 | if definitions[term] then 262 | return definitions[term] 263 | else 264 | error("Definition for function '"..term.."' unspecified (use second parameter of parser-gen.compile())") 265 | end 266 | elseif action == "s" then -- simple string 267 | return term 268 | elseif action == "num" then -- numbered string 269 | return tonumber(term) 270 | end 271 | end 272 | 273 | 274 | local function applygrammar(gram) 275 | return m.P(gram) 276 | end 277 | 278 | local function traverse (ast, tokenrule) 279 | if not ast then 280 | return nil 281 | end 282 | 283 | if isfinal(ast) then 284 | local typefn, fn, tok = finalNode(ast) 285 | return applyfinal(typefn, fn, tok, tokenrule) 286 | 287 | elseif isaction(ast) then 288 | 289 | local act, op1, op2, labs, ret1, ret2 290 | act = ast["action"] 291 | op1 = ast["op1"] 292 | op2 = ast["op2"] 293 | labs = ast["condition"] -- recovery operations 294 | 295 | -- post-order traversal 296 | if iscapture(act) then 297 | tokenstack:push(0) -- not found any tokens yet 298 | end 299 | 300 | ret1 = traverse(op1, tokenrule) 301 | ret2 = traverse(op2, tokenrule) 302 | 303 | 304 | return applyaction(act, ret1, ret2, labs, tokenrule) 305 | 306 | elseif isgrammar(ast) then 307 | -- 308 | local g = bg.buildgrammar (ast) 309 | return applygrammar (g) 310 | 311 | else 312 | peg.print_r(ast) 313 | error("Unsupported AST") 314 | end 315 | 316 | end 317 | 318 | local function specialrules(ast, builder) 319 | -- initialize values 320 | SKIP = (Predef.space + Predef.nl) 321 | skipspaces = true 322 | SYNC = nil 323 | recovery = true 324 | -- find SPACE and SYNC rules 325 | for i, v in ipairs(ast) do 326 | local name = v["rulename"] 327 | local rule 328 | if name == "SKIP" then 329 | rule = traverse(v["rule"], true) 330 | if v["rule"]["t"] == '' then 331 | skipspaces = false 332 | else 333 | skipspaces = true 334 | SKIP = rule 335 | end 336 | builder[name] = rule 337 | elseif name == "SYNC" then 338 | rule = traverse(v["rule"], true) 339 | if v["rule"]["t"] == '' then-- SYNC <- '' 340 | recovery=false 341 | else 342 | recovery= true 343 | SYNC = rule 344 | end 345 | builder[name] = rule 346 | end 347 | end 348 | if not SYNC and recovery then 349 | SYNC = defaultsync(SKIP) 350 | end 351 | end 352 | 353 | local function recorderror(position,label) 354 | -- call error function here 355 | local line, col = peg.calcline(subject, position) 356 | local desc 357 | if label == 0 then 358 | desc = "Syntax error" 359 | else 360 | desc = tdescs[label] 361 | end 362 | if errorfunc then 363 | local temp = string.sub(subject,position) 364 | local strend = string.find(temp, "\n") 365 | local sfail = string.sub(temp, 1, strend) 366 | errorfunc(desc,line,col,sfail,trecs[label]) 367 | end 368 | 369 | local err = { line = line, col = col, label=tlabelnames[label], msg = desc } 370 | table.insert(errors, err) 371 | 372 | end 373 | local function record(label) 374 | return (m.Cp() * m.Cc(label)) / recorderror 375 | end 376 | 377 | local function buildrecovery(grammar) 378 | 379 | local synctoken = pattspaces(sync(SYNC)) 380 | local grec = grammar 381 | 382 | for k,v in pairs(tlabels) do 383 | 384 | if trecs[v] then -- custom sync token 385 | grec = m.Rec(grec,record(v) * pattspaces(trecs[v]), v) 386 | else -- use global sync token 387 | grec = m.Rec(grec,record(v) * synctoken, v) 388 | end 389 | end 390 | return grec 391 | 392 | end 393 | local usenode = false 394 | 395 | local function usenodes(val) 396 | usenode = val 397 | end 398 | 399 | 400 | function bg.buildgrammar (ast) 401 | local builder = {} 402 | specialrules(ast, builder) 403 | local initialrule 404 | for i, v in ipairs(ast) do 405 | local istokenrule = v["token"] == "1" 406 | local isfragment = v["fragment"] == "1" 407 | local isnode = v["node"] == "1" 408 | 409 | if isnode and not usenodes then 410 | error("Node mode disabled - please use parser-gen.usenodes(true) before compiling the grammar") 411 | end 412 | 413 | local name = v["rulename"] 414 | local isspecial = name == "SKIP" or name == "SYNC" 415 | local rule = v["rule"] 416 | if i == 1 then 417 | initialrule = name 418 | table.insert(builder, name) -- lpeg syntax 419 | builder[name] = traverse(rule, istokenrule) 420 | else 421 | if not builder[name] then -- dont traverse rules for SKIP and SYNC twice 422 | builder[name] = traverse(rule, istokenrule) 423 | end 424 | end 425 | if buildast and not isfragment and not isspecial and ((not usenode) or (usenode and isnode)) then 426 | if istokenrule then 427 | builder[name] = m.C(builder[name]) 428 | end 429 | builder[name] = m.Ct(m.Cg(m.Cc(name),"rule") * m.Cg(m.Cp(),"pos") * builder[name]) 430 | end 431 | end 432 | 433 | if skipspaces then 434 | builder[initialrule] = SKIP^0 * builder[initialrule] -- skip spaces at the beginning of the input 435 | end 436 | if recovery then 437 | builder[initialrule] = buildrecovery(builder[initialrule]) -- build recovery on top of initial rule 438 | end 439 | return builder 440 | end 441 | 442 | 443 | 444 | 445 | local function build(ast, defs) 446 | if defs then 447 | definitions = defs 448 | end 449 | if isgrammar(ast) then 450 | return traverse(ast) 451 | else 452 | SKIP = (Predef.space + Predef.nl) 453 | skipspaces = true 454 | SYNC = nil 455 | recovery = true 456 | SYNC = defaultsync(SKIP) 457 | local res = SKIP ^0 * traverse(ast) 458 | if buildast then 459 | res = m.Ct(res) 460 | end 461 | return res -- input is not a grammar - skip spaces and sync by default 462 | end 463 | end 464 | 465 | 466 | 467 | -- recovery grammar 468 | 469 | 470 | 471 | 472 | -- end 473 | 474 | 475 | 476 | -- t = {errName="Error description",...} 477 | local function setlabels (t, errorgen) 478 | local index 479 | if errorgen then 480 | index = totallabels + 1 481 | else 482 | -- reset error tables 483 | index = 1 484 | tlabels = {} 485 | 486 | tdescs = {} 487 | trecs = {} 488 | end 489 | for key,value in pairs(t) do 490 | if index >= 255 then 491 | error("Error label limit reached(255)") 492 | end 493 | if type(value) == "table" then -- we have a recovery expression 494 | tdescs[index] = value[1] 495 | 496 | trecs[index] = traverse(peg.pegToAST(value[2]), true)-- PEG to LPEG 497 | else 498 | tdescs[index] = value 499 | end 500 | tlabels[key] = index 501 | tlabelnames[index] = key -- reverse table 502 | index = index + 1 503 | end 504 | totallabels = index-1 505 | end 506 | 507 | 508 | local function compile (input, defs, generrors, nocaptures) 509 | if iscompiled(input) then 510 | return input 511 | end 512 | if not mem[input] then 513 | buildast = true 514 | if nocaptures then 515 | buildast=false 516 | end 517 | --re.setlabels(tlabels) 518 | --re.compile(input,defs) 519 | -- build ast 520 | local ast = peg.pegToAST(input) 521 | if generrors then 522 | local follow = eg.follow(ast) 523 | local errors = eg.adderrors(ast, follow) 524 | setlabels (errors, true) -- add errors generated by errorgen 525 | end 526 | local gram = build(ast,defs) 527 | if not gram then 528 | -- find error using relabel module 529 | 530 | end 531 | mem[input] = gram-- store if the user forgets to compile it 532 | end 533 | return mem[input] 534 | end 535 | 536 | 537 | 538 | 539 | 540 | 541 | local function parse (input, grammar, errorfunction) 542 | if not iscompiled(grammar) then 543 | 544 | local cp = compile(grammar) 545 | grammar = cp 546 | end 547 | -- set up recovery table 548 | errorfunc = errorfunction 549 | subject = input 550 | errors = {} 551 | -- end 552 | local r, e, sfail = m.match(grammar,input) 553 | if not r then 554 | recorderror(#input - #sfail, e) 555 | end 556 | if #errors == 0 then errors=nil end 557 | return r, errors 558 | end 559 | 560 | 561 | 562 | 563 | 564 | 565 | local pg = {compile=compile, setlabels=setlabels, parse=parse,follow=follow, calcline = peg.calcline, usenodes = usenodes} 566 | 567 | return pg 568 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/all.lua: -------------------------------------------------------------------------------- 1 | #!../lua 2 | -- $Id: all.lua,v 1.95 2016/11/07 13:11:28 roberto Exp $ 3 | -- See Copyright Notice at the end of this file 4 | 5 | 6 | 7 | local version = "Lua 5.3" 8 | if _VERSION ~= version then 9 | io.stderr:write("\nThis test suite is for ", version, ", not for ", _VERSION, 10 | "\nExiting tests\n") 11 | return 12 | end 13 | 14 | 15 | _G._ARG = arg -- save arg for other tests 16 | 17 | 18 | -- next variables control the execution of some tests 19 | -- true means no test (so an undefined variable does not skip a test) 20 | -- defaults are for Linux; test everything. 21 | -- Make true to avoid long or memory consuming tests 22 | _soft = rawget(_G, "_soft") or false 23 | -- Make true to avoid non-portable tests 24 | _port = rawget(_G, "_port") or false 25 | -- Make true to avoid messages about tests not performed 26 | _nomsg = rawget(_G, "_nomsg") or false 27 | 28 | 29 | local usertests = rawget(_G, "_U") 30 | 31 | if usertests then 32 | -- tests for sissies ;) Avoid problems 33 | _soft = true 34 | _port = true 35 | _nomsg = true 36 | end 37 | 38 | -- tests should require debug when needed 39 | debug = nil 40 | 41 | if usertests then 42 | T = nil -- no "internal" tests for user tests 43 | else 44 | T = rawget(_G, "T") -- avoid problems with 'strict' module 45 | end 46 | 47 | math.randomseed(0) 48 | 49 | --[=[ 50 | example of a long [comment], 51 | [[spanning several [lines]]] 52 | 53 | ]=] 54 | 55 | print("current path:\n****" .. package.path .. "****\n") 56 | 57 | 58 | local initclock = os.clock() 59 | local lastclock = initclock 60 | local walltime = os.time() 61 | 62 | local collectgarbage = collectgarbage 63 | 64 | do -- ( 65 | 66 | -- track messages for tests not performed 67 | local msgs = {} 68 | function Message (m) 69 | if not _nomsg then 70 | print(m) 71 | msgs[#msgs+1] = string.sub(m, 3, -3) 72 | end 73 | end 74 | 75 | assert(os.setlocale"C") 76 | 77 | local T,print,format,write,assert,type,unpack,floor = 78 | T,print,string.format,io.write,assert,type,table.unpack,math.floor 79 | 80 | -- use K for 1000 and M for 1000000 (not 2^10 -- 2^20) 81 | local function F (m) 82 | local function round (m) 83 | m = m + 0.04999 84 | return format("%.1f", m) -- keep one decimal digit 85 | end 86 | if m < 1000 then return m 87 | else 88 | m = m / 1000 89 | if m < 1000 then return round(m).."K" 90 | else 91 | return round(m/1000).."M" 92 | end 93 | end 94 | end 95 | 96 | local showmem 97 | if not T then 98 | local max = 0 99 | showmem = function () 100 | local m = collectgarbage("count") * 1024 101 | max = (m > max) and m or max 102 | print(format(" ---- total memory: %s, max memory: %s ----\n", 103 | F(m), F(max))) 104 | end 105 | else 106 | showmem = function () 107 | T.checkmemory() 108 | local total, numblocks, maxmem = T.totalmem() 109 | local count = collectgarbage("count") 110 | print(format( 111 | "\n ---- total memory: %s (%.0fK), max use: %s, blocks: %d\n", 112 | F(total), count, F(maxmem), numblocks)) 113 | print(format("\t(strings: %d, tables: %d, functions: %d, ".. 114 | "\n\tudata: %d, threads: %d)", 115 | T.totalmem"string", T.totalmem"table", T.totalmem"function", 116 | T.totalmem"userdata", T.totalmem"thread")) 117 | end 118 | end 119 | 120 | 121 | -- 122 | -- redefine dofile to run files through dump/undump 123 | -- 124 | local function report (n) print("\n***** FILE '"..n.."'*****") end 125 | local olddofile = dofile 126 | local dofile = function (n, strip) 127 | showmem() 128 | local c = os.clock() 129 | print(string.format("time: %g (+%g)", c - initclock, c - lastclock)) 130 | lastclock = c 131 | report(n) 132 | local f = assert(loadfile(n)) 133 | local b = string.dump(f, strip) 134 | f = assert(load(b)) 135 | return f() 136 | end 137 | 138 | dofile('main.lua') 139 | 140 | do 141 | local next, setmetatable, stderr = next, setmetatable, io.stderr 142 | -- track collections 143 | local mt = {} 144 | -- each time a table is collected, remark it for finalization 145 | -- on next cycle 146 | mt.__gc = function (o) 147 | stderr:write'.' -- mark progress 148 | local n = setmetatable(o, mt) -- remark it 149 | end 150 | local n = setmetatable({}, mt) -- create object 151 | end 152 | 153 | report"gc.lua" 154 | local f = assert(loadfile('gc.lua')) 155 | f() 156 | 157 | dofile('db.lua') 158 | assert(dofile('calls.lua') == deep and deep) 159 | olddofile('strings.lua') 160 | olddofile('literals.lua') 161 | dofile('tpack.lua') 162 | assert(dofile('attrib.lua') == 27) 163 | 164 | assert(dofile('locals.lua') == 5) 165 | dofile('constructs.lua') 166 | dofile('code.lua', true) 167 | if not _G._soft then 168 | report('big.lua') 169 | local f = coroutine.wrap(assert(loadfile('big.lua'))) 170 | assert(f() == 'b') 171 | assert(f() == 'a') 172 | end 173 | dofile('nextvar.lua') 174 | dofile('pm.lua') 175 | dofile('utf8.lua') 176 | dofile('api.lua') 177 | assert(dofile('events.lua') == 12) 178 | dofile('vararg.lua') 179 | dofile('closure.lua') 180 | dofile('coroutine.lua') 181 | dofile('goto.lua', true) 182 | dofile('errors.lua') 183 | dofile('math.lua') 184 | dofile('sort.lua', true) 185 | dofile('bitwise.lua') 186 | assert(dofile('verybig.lua', true) == 10); collectgarbage() 187 | dofile('files.lua') 188 | 189 | if #msgs > 0 then 190 | print("\ntests not performed:") 191 | for i=1,#msgs do 192 | print(msgs[i]) 193 | end 194 | print() 195 | end 196 | 197 | -- no test module should define 'debug' 198 | assert(debug == nil) 199 | 200 | local debug = require "debug" 201 | 202 | print(string.format("%d-bit integers, %d-bit floats", 203 | string.packsize("j") * 8, string.packsize("n") * 8)) 204 | 205 | debug.sethook(function (a) assert(type(a) == 'string') end, "cr") 206 | 207 | -- to survive outside block 208 | _G.showmem = showmem 209 | 210 | end --) 211 | 212 | local _G, showmem, print, format, clock, time, difftime, assert, open = 213 | _G, showmem, print, string.format, os.clock, os.time, os.difftime, 214 | assert, io.open 215 | 216 | -- file with time of last performed test 217 | local fname = T and "time-debug.txt" or "time.txt" 218 | local lasttime 219 | 220 | if not usertests then 221 | -- open file with time of last performed test 222 | local f = io.open(fname) 223 | if f then 224 | lasttime = assert(tonumber(f:read'a')) 225 | f:close(); 226 | else -- no such file; assume it is recording time for first time 227 | lasttime = nil 228 | end 229 | end 230 | 231 | -- erase (almost) all globals 232 | print('cleaning all!!!!') 233 | for n in pairs(_G) do 234 | if not ({___Glob = 1, tostring = 1})[n] then 235 | _G[n] = nil 236 | end 237 | end 238 | 239 | 240 | collectgarbage() 241 | collectgarbage() 242 | collectgarbage() 243 | collectgarbage() 244 | collectgarbage() 245 | collectgarbage();showmem() 246 | 247 | local clocktime = clock() - initclock 248 | walltime = difftime(time(), walltime) 249 | 250 | print(format("\n\ntotal time: %.2fs (wall time: %gs)\n", clocktime, walltime)) 251 | 252 | if not usertests then 253 | lasttime = lasttime or clocktime -- if no last time, ignore difference 254 | -- check whether current test time differs more than 5% from last time 255 | local diff = (clocktime - lasttime) / lasttime 256 | local tolerance = 0.05 -- 5% 257 | if (diff >= tolerance or diff <= -tolerance) then 258 | print(format("WARNING: time difference from previous test: %+.1f%%", 259 | diff * 100)) 260 | end 261 | assert(open(fname, "w")):write(clocktime):close() 262 | end 263 | 264 | print("final OK !!!") 265 | 266 | 267 | 268 | --[[ 269 | ***************************************************************************** 270 | * Copyright (C) 1994-2016 Lua.org, PUC-Rio. 271 | * 272 | * Permission is hereby granted, free of charge, to any person obtaining 273 | * a copy of this software and associated documentation files (the 274 | * "Software"), to deal in the Software without restriction, including 275 | * without limitation the rights to use, copy, modify, merge, publish, 276 | * distribute, sublicense, and/or sell copies of the Software, and to 277 | * permit persons to whom the Software is furnished to do so, subject to 278 | * the following conditions: 279 | * 280 | * The above copyright notice and this permission notice shall be 281 | * included in all copies or substantial portions of the Software. 282 | * 283 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 284 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 285 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 286 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 287 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 288 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 289 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 290 | ***************************************************************************** 291 | ]] 292 | 293 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/attrib.lua: -------------------------------------------------------------------------------- 1 | -- $Id: attrib.lua,v 1.65 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print "testing require" 5 | 6 | assert(require"string" == string) 7 | assert(require"math" == math) 8 | assert(require"table" == table) 9 | assert(require"io" == io) 10 | assert(require"os" == os) 11 | assert(require"coroutine" == coroutine) 12 | 13 | assert(type(package.path) == "string") 14 | assert(type(package.cpath) == "string") 15 | assert(type(package.loaded) == "table") 16 | assert(type(package.preload) == "table") 17 | 18 | assert(type(package.config) == "string") 19 | print("package config: "..string.gsub(package.config, "\n", "|")) 20 | 21 | do 22 | -- create a path with 'max' templates, 23 | -- each with 1-10 repetitions of '?' 24 | local max = _soft and 100 or 2000 25 | local t = {} 26 | for i = 1,max do t[i] = string.rep("?", i%10 + 1) end 27 | t[#t + 1] = ";" -- empty template 28 | local path = table.concat(t, ";") 29 | -- use that path in a search 30 | local s, err = package.searchpath("xuxu", path) 31 | -- search fails; check that message has an occurence of 32 | -- '??????????' with ? replaced by xuxu and at least 'max' lines 33 | assert(not s and 34 | string.find(err, string.rep("xuxu", 10)) and 35 | #string.gsub(err, "[^\n]", "") >= max) 36 | -- path with one very long template 37 | local path = string.rep("?", max) 38 | local s, err = package.searchpath("xuxu", path) 39 | assert(not s and string.find(err, string.rep('xuxu', max))) 40 | end 41 | 42 | do 43 | local oldpath = package.path 44 | package.path = {} 45 | local s, err = pcall(require, "no-such-file") 46 | assert(not s and string.find(err, "package.path")) 47 | package.path = oldpath 48 | end 49 | 50 | print('+') 51 | 52 | 53 | -- The next tests for 'require' assume some specific directories and 54 | -- libraries. 55 | 56 | if not _port then --[ 57 | 58 | local dirsep = string.match(package.config, "^([^\n]+)\n") 59 | 60 | -- auxiliary directory with C modules and temporary files 61 | local DIR = "libs" .. dirsep 62 | 63 | -- prepend DIR to a name and correct directory separators 64 | local function D (x) 65 | x = string.gsub(x, "/", dirsep) 66 | return DIR .. x 67 | end 68 | 69 | -- prepend DIR and pospend proper C lib. extension to a name 70 | local function DC (x) 71 | local ext = (dirsep == '\\') and ".dll" or ".so" 72 | return D(x .. ext) 73 | end 74 | 75 | 76 | local function createfiles (files, preextras, posextras) 77 | for n,c in pairs(files) do 78 | io.output(D(n)) 79 | io.write(string.format(preextras, n)) 80 | io.write(c) 81 | io.write(string.format(posextras, n)) 82 | io.close(io.output()) 83 | end 84 | end 85 | 86 | function removefiles (files) 87 | for n in pairs(files) do 88 | os.remove(D(n)) 89 | end 90 | end 91 | 92 | local files = { 93 | ["names.lua"] = "do return {...} end\n", 94 | ["err.lua"] = "B = 15; a = a + 1;", 95 | ["synerr.lua"] = "B =", 96 | ["A.lua"] = "", 97 | ["B.lua"] = "assert(...=='B');require 'A'", 98 | ["A.lc"] = "", 99 | ["A"] = "", 100 | ["L"] = "", 101 | ["XXxX"] = "", 102 | ["C.lua"] = "package.loaded[...] = 25; require'C'", 103 | } 104 | 105 | AA = nil 106 | local extras = [[ 107 | NAME = '%s' 108 | REQUIRED = ... 109 | return AA]] 110 | 111 | createfiles(files, "", extras) 112 | 113 | -- testing explicit "dir" separator in 'searchpath' 114 | assert(package.searchpath("C.lua", D"?", "", "") == D"C.lua") 115 | assert(package.searchpath("C.lua", D"?", ".", ".") == D"C.lua") 116 | assert(package.searchpath("--x-", D"?", "-", "X") == D"XXxX") 117 | assert(package.searchpath("---xX", D"?", "---", "XX") == D"XXxX") 118 | assert(package.searchpath(D"C.lua", "?", dirsep) == D"C.lua") 119 | assert(package.searchpath(".\\C.lua", D"?", "\\") == D"./C.lua") 120 | 121 | local oldpath = package.path 122 | 123 | package.path = string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", DIR) 124 | 125 | local try = function (p, n, r) 126 | NAME = nil 127 | local rr = require(p) 128 | assert(NAME == n) 129 | assert(REQUIRED == p) 130 | assert(rr == r) 131 | end 132 | 133 | a = require"names" 134 | assert(a[1] == "names" and a[2] == D"names.lua") 135 | 136 | _G.a = nil 137 | local st, msg = pcall(require, "err") 138 | assert(not st and string.find(msg, "arithmetic") and B == 15) 139 | st, msg = pcall(require, "synerr") 140 | assert(not st and string.find(msg, "error loading module")) 141 | 142 | assert(package.searchpath("C", package.path) == D"C.lua") 143 | assert(require"C" == 25) 144 | assert(require"C" == 25) 145 | AA = nil 146 | try('B', 'B.lua', true) 147 | assert(package.loaded.B) 148 | assert(require"B" == true) 149 | assert(package.loaded.A) 150 | assert(require"C" == 25) 151 | package.loaded.A = nil 152 | try('B', nil, true) -- should not reload package 153 | try('A', 'A.lua', true) 154 | package.loaded.A = nil 155 | os.remove(D'A.lua') 156 | AA = {} 157 | try('A', 'A.lc', AA) -- now must find second option 158 | assert(package.searchpath("A", package.path) == D"A.lc") 159 | assert(require("A") == AA) 160 | AA = false 161 | try('K', 'L', false) -- default option 162 | try('K', 'L', false) -- default option (should reload it) 163 | assert(rawget(_G, "_REQUIREDNAME") == nil) 164 | 165 | AA = "x" 166 | try("X", "XXxX", AA) 167 | 168 | 169 | removefiles(files) 170 | 171 | 172 | -- testing require of sub-packages 173 | 174 | local _G = _G 175 | 176 | package.path = string.gsub("D/?.lua;D/?/init.lua", "D/", DIR) 177 | 178 | files = { 179 | ["P1/init.lua"] = "AA = 10", 180 | ["P1/xuxu.lua"] = "AA = 20", 181 | } 182 | 183 | createfiles(files, "_ENV = {}\n", "\nreturn _ENV\n") 184 | AA = 0 185 | 186 | local m = assert(require"P1") 187 | assert(AA == 0 and m.AA == 10) 188 | assert(require"P1" == m) 189 | assert(require"P1" == m) 190 | 191 | assert(package.searchpath("P1.xuxu", package.path) == D"P1/xuxu.lua") 192 | m.xuxu = assert(require"P1.xuxu") 193 | assert(AA == 0 and m.xuxu.AA == 20) 194 | assert(require"P1.xuxu" == m.xuxu) 195 | assert(require"P1.xuxu" == m.xuxu) 196 | assert(require"P1" == m and m.AA == 10) 197 | 198 | 199 | removefiles(files) 200 | 201 | 202 | package.path = "" 203 | assert(not pcall(require, "file_does_not_exist")) 204 | package.path = "??\0?" 205 | assert(not pcall(require, "file_does_not_exist1")) 206 | 207 | package.path = oldpath 208 | 209 | -- check 'require' error message 210 | local fname = "file_does_not_exist2" 211 | local m, err = pcall(require, fname) 212 | for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do 213 | t = string.gsub(t, "?", fname) 214 | assert(string.find(err, t, 1, true)) 215 | end 216 | 217 | do -- testing 'package.searchers' not being a table 218 | local searchers = package.searchers 219 | package.searchers = 3 220 | local st, msg = pcall(require, 'a') 221 | assert(not st and string.find(msg, "must be a table")) 222 | package.searchers = searchers 223 | end 224 | 225 | local function import(...) 226 | local f = {...} 227 | return function (m) 228 | for i=1, #f do m[f[i]] = _G[f[i]] end 229 | end 230 | end 231 | 232 | -- cannot change environment of a C function 233 | assert(not pcall(module, 'XUXU')) 234 | 235 | 236 | 237 | -- testing require of C libraries 238 | 239 | 240 | local p = "" -- On Mac OS X, redefine this to "_" 241 | 242 | -- check whether loadlib works in this system 243 | local st, err, when = package.loadlib(DC"lib1", "*") 244 | if not st then 245 | local f, err, when = package.loadlib("donotexist", p.."xuxu") 246 | assert(not f and type(err) == "string" and when == "absent") 247 | ;(Message or print)('\n >>> cannot load dynamic library <<<\n') 248 | print(err, when) 249 | else 250 | -- tests for loadlib 251 | local f = assert(package.loadlib(DC"lib1", p.."onefunction")) 252 | local a, b = f(15, 25) 253 | assert(a == 25 and b == 15) 254 | 255 | f = assert(package.loadlib(DC"lib1", p.."anotherfunc")) 256 | assert(f(10, 20) == "10%20\n") 257 | 258 | -- check error messages 259 | local f, err, when = package.loadlib(DC"lib1", p.."xuxu") 260 | assert(not f and type(err) == "string" and when == "init") 261 | f, err, when = package.loadlib("donotexist", p.."xuxu") 262 | assert(not f and type(err) == "string" and when == "open") 263 | 264 | -- symbols from 'lib1' must be visible to other libraries 265 | f = assert(package.loadlib(DC"lib11", p.."luaopen_lib11")) 266 | assert(f() == "exported") 267 | 268 | -- test C modules with prefixes in names 269 | package.cpath = DC"?" 270 | local lib2 = require"lib2-v2" 271 | -- check correct access to global environment and correct 272 | -- parameters 273 | assert(_ENV.x == "lib2-v2" and _ENV.y == DC"lib2-v2") 274 | assert(lib2.id("x") == "x") 275 | 276 | -- test C submodules 277 | local fs = require"lib1.sub" 278 | assert(_ENV.x == "lib1.sub" and _ENV.y == DC"lib1") 279 | assert(fs.id(45) == 45) 280 | end 281 | 282 | _ENV = _G 283 | 284 | 285 | -- testing preload 286 | 287 | do 288 | local p = package 289 | package = {} 290 | p.preload.pl = function (...) 291 | local _ENV = {...} 292 | function xuxu (x) return x+20 end 293 | return _ENV 294 | end 295 | 296 | local pl = require"pl" 297 | assert(require"pl" == pl) 298 | assert(pl.xuxu(10) == 30) 299 | assert(pl[1] == "pl" and pl[2] == nil) 300 | 301 | package = p 302 | assert(type(package.path) == "string") 303 | end 304 | 305 | print('+') 306 | 307 | end --] 308 | 309 | print("testing assignments, logical operators, and constructors") 310 | 311 | local res, res2 = 27 312 | 313 | a, b = 1, 2+3 314 | assert(a==1 and b==5) 315 | a={} 316 | function f() return 10, 11, 12 end 317 | a.x, b, a[1] = 1, 2, f() 318 | assert(a.x==1 and b==2 and a[1]==10) 319 | a[f()], b, a[f()+3] = f(), a, 'x' 320 | assert(a[10] == 10 and b == a and a[13] == 'x') 321 | 322 | do 323 | local f = function (n) local x = {}; for i=1,n do x[i]=i end; 324 | return table.unpack(x) end; 325 | local a,b,c 326 | a,b = 0, f(1) 327 | assert(a == 0 and b == 1) 328 | A,b = 0, f(1) 329 | assert(A == 0 and b == 1) 330 | a,b,c = 0,5,f(4) 331 | assert(a==0 and b==5 and c==1) 332 | a,b,c = 0,5,f(0) 333 | assert(a==0 and b==5 and c==nil) 334 | end 335 | 336 | a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6 337 | assert(not a and b and c and d==6) 338 | 339 | d = 20 340 | a, b, c, d = f() 341 | assert(a==10 and b==11 and c==12 and d==nil) 342 | a,b = f(), 1, 2, 3, f() 343 | assert(a==10 and b==1) 344 | 345 | assert(ab == true) 346 | assert((10 and 2) == 2) 347 | assert((10 or 2) == 10) 348 | assert((10 or assert(nil)) == 10) 349 | assert(not (nil and assert(nil))) 350 | assert((nil or "alo") == "alo") 351 | assert((nil and 10) == nil) 352 | assert((false and 10) == false) 353 | assert((true or 10) == true) 354 | assert((false or 10) == 10) 355 | assert(false ~= nil) 356 | assert(nil ~= false) 357 | assert(not nil == true) 358 | assert(not not nil == false) 359 | assert(not not 1 == true) 360 | assert(not not a == true) 361 | assert(not not (6 or nil) == true) 362 | assert(not not (nil and 56) == false) 363 | assert(not not (nil and true) == false) 364 | assert(not 10 == false) 365 | assert(not {} == false) 366 | assert(not 0.5 == false) 367 | assert(not "x" == false) 368 | 369 | assert({} ~= {}) 370 | print('+') 371 | 372 | a = {} 373 | a[true] = 20 374 | a[false] = 10 375 | assert(a[1<2] == 20 and a[1>2] == 10) 376 | 377 | function f(a) return a end 378 | 379 | local a = {} 380 | for i=3000,-3000,-1 do a[i + 0.0] = i; end 381 | a[10e30] = "alo"; a[true] = 10; a[false] = 20 382 | assert(a[10e30] == 'alo' and a[not 1] == 20 and a[10<20] == 10) 383 | for i=3000,-3000,-1 do assert(a[i] == i); end 384 | a[print] = assert 385 | a[f] = print 386 | a[a] = a 387 | assert(a[a][a][a][a][print] == assert) 388 | a[print](a[a[f]] == a[print]) 389 | assert(not pcall(function () local a = {}; a[nil] = 10 end)) 390 | assert(not pcall(function () local a = {[nil] = 10} end)) 391 | assert(a[nil] == nil) 392 | a = nil 393 | 394 | a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'} 395 | a, a.x, a.y = a, a[-3] 396 | assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y) 397 | a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2 398 | a[1].alo(a[2]==10 and b==10 and c==print) 399 | 400 | 401 | -- test of large float/integer indices 402 | 403 | -- compute maximum integer where all bits fit in a float 404 | local maxint = math.maxinteger 405 | 406 | while maxint - 1.0 == maxint - 0.0 do -- trim (if needed) to fit in a float 407 | maxint = maxint // 2 408 | end 409 | 410 | maxintF = maxint + 0.0 -- float version 411 | 412 | assert(math.type(maxintF) == "float" and maxintF >= 2.0^14) 413 | 414 | -- floats and integers must index the same places 415 | a[maxintF] = 10; a[maxintF - 1.0] = 11; 416 | a[-maxintF] = 12; a[-maxintF + 1.0] = 13; 417 | 418 | assert(a[maxint] == 10 and a[maxint - 1] == 11 and 419 | a[-maxint] == 12 and a[-maxint + 1] == 13) 420 | 421 | a[maxint] = 20 422 | a[-maxint] = 22 423 | 424 | assert(a[maxintF] == 20 and a[maxintF - 1.0] == 11 and 425 | a[-maxintF] == 22 and a[-maxintF + 1.0] == 13) 426 | 427 | a = nil 428 | 429 | 430 | -- test conflicts in multiple assignment 431 | do 432 | local a,i,j,b 433 | a = {'a', 'b'}; i=1; j=2; b=a 434 | i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i 435 | assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and 436 | b[3] == 1) 437 | end 438 | 439 | -- repeat test with upvalues 440 | do 441 | local a,i,j,b 442 | a = {'a', 'b'}; i=1; j=2; b=a 443 | local function foo () 444 | i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i 445 | end 446 | foo() 447 | assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and 448 | b[3] == 1) 449 | local t = {} 450 | (function (a) t[a], a = 10, 20 end)(1); 451 | assert(t[1] == 10) 452 | end 453 | 454 | -- bug in 5.2 beta 455 | local function foo () 456 | local a 457 | return function () 458 | local b 459 | a, b = 3, 14 -- local and upvalue have same index 460 | return a, b 461 | end 462 | end 463 | 464 | local a, b = foo()() 465 | assert(a == 3 and b == 14) 466 | 467 | print('OK') 468 | 469 | return res 470 | 471 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/big.lua: -------------------------------------------------------------------------------- 1 | -- $Id: big.lua,v 1.32 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | if _soft then 5 | return 'a' 6 | end 7 | 8 | print "testing large tables" 9 | 10 | local debug = require"debug" 11 | 12 | local lim = 2^18 + 1000 13 | local prog = { "local y = {0" } 14 | for i = 1, lim do prog[#prog + 1] = i end 15 | prog[#prog + 1] = "}\n" 16 | prog[#prog + 1] = "X = y\n" 17 | prog[#prog + 1] = ("assert(X[%d] == %d)"):format(lim - 1, lim - 2) 18 | prog[#prog + 1] = "return 0" 19 | prog = table.concat(prog, ";") 20 | 21 | local env = {string = string, assert = assert} 22 | local f = assert(load(prog, nil, nil, env)) 23 | 24 | f() 25 | assert(env.X[lim] == lim - 1 and env.X[lim + 1] == lim) 26 | for k in pairs(env) do env[k] = nil end 27 | 28 | -- yields during accesses larger than K (in RK) 29 | setmetatable(env, { 30 | __index = function (t, n) coroutine.yield('g'); return _G[n] end, 31 | __newindex = function (t, n, v) coroutine.yield('s'); _G[n] = v end, 32 | }) 33 | 34 | X = nil 35 | co = coroutine.wrap(f) 36 | assert(co() == 's') 37 | assert(co() == 'g') 38 | assert(co() == 'g') 39 | assert(co() == 0) 40 | 41 | assert(X[lim] == lim - 1 and X[lim + 1] == lim) 42 | 43 | -- errors in accesses larger than K (in RK) 44 | getmetatable(env).__index = function () end 45 | getmetatable(env).__newindex = function () end 46 | local e, m = pcall(f) 47 | assert(not e and m:find("global 'X'")) 48 | 49 | -- errors in metamethods 50 | getmetatable(env).__newindex = function () error("hi") end 51 | local e, m = xpcall(f, debug.traceback) 52 | assert(not e and m:find("'__newindex'")) 53 | 54 | f, X = nil 55 | 56 | coroutine.yield'b' 57 | 58 | if 2^32 == 0 then -- (small integers) { 59 | 60 | print "testing string length overflow" 61 | 62 | local repstrings = 192 -- number of strings to be concatenated 63 | local ssize = math.ceil(2.0^32 / repstrings) + 1 -- size of each string 64 | 65 | assert(repstrings * ssize > 2.0^32) -- it should be larger than maximum size 66 | 67 | local longs = string.rep("\0", ssize) -- create one long string 68 | 69 | -- create function to concatentate 'repstrings' copies of its argument 70 | local rep = assert(load( 71 | "local a = ...; return " .. string.rep("a", repstrings, ".."))) 72 | 73 | local a, b = pcall(rep, longs) -- call that function 74 | 75 | -- it should fail without creating string (result would be too large) 76 | assert(not a and string.find(b, "overflow")) 77 | 78 | end -- } 79 | 80 | print'OK' 81 | 82 | return 'a' 83 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/bitwise.lua: -------------------------------------------------------------------------------- 1 | -- $Id: bitwise.lua,v 1.26 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print("testing bitwise operations") 5 | 6 | local numbits = string.packsize('j') * 8 7 | 8 | assert(~0 == -1) 9 | 10 | assert((1 << (numbits - 1)) == math.mininteger) 11 | 12 | -- basic tests for bitwise operators; 13 | -- use variables to avoid constant folding 14 | local a, b, c, d 15 | a = 0xFFFFFFFFFFFFFFFF 16 | assert(a == -1 and a & -1 == a and a & 35 == 35) 17 | a = 0xF0F0F0F0F0F0F0F0 18 | assert(a | -1 == -1) 19 | assert(a ~ a == 0 and a ~ 0 == a and a ~ ~a == -1) 20 | assert(a >> 4 == ~a) 21 | a = 0xF0; b = 0xCC; c = 0xAA; d = 0xFD 22 | assert(a | b ~ c & d == 0xF4) 23 | 24 | a = 0xF0.0; b = 0xCC.0; c = "0xAA.0"; d = "0xFD.0" 25 | assert(a | b ~ c & d == 0xF4) 26 | 27 | a = 0xF0000000; b = 0xCC000000; 28 | c = 0xAA000000; d = 0xFD000000 29 | assert(a | b ~ c & d == 0xF4000000) 30 | assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1) 31 | 32 | a = a << 32 33 | b = b << 32 34 | c = c << 32 35 | d = d << 32 36 | assert(a | b ~ c & d == 0xF4000000 << 32) 37 | assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1) 38 | 39 | assert(-1 >> 1 == (1 << (numbits - 1)) - 1 and 1 << 31 == 0x80000000) 40 | assert(-1 >> (numbits - 1) == 1) 41 | assert(-1 >> numbits == 0 and 42 | -1 >> -numbits == 0 and 43 | -1 << numbits == 0 and 44 | -1 << -numbits == 0) 45 | 46 | assert((2^30 - 1) << 2^30 == 0) 47 | assert((2^30 - 1) >> 2^30 == 0) 48 | 49 | assert(1 >> -3 == 1 << 3 and 1000 >> 5 == 1000 << -5) 50 | 51 | 52 | -- coercion from strings to integers 53 | assert("0xffffffffffffffff" | 0 == -1) 54 | assert("0xfffffffffffffffe" & "-1" == -2) 55 | assert(" \t-0xfffffffffffffffe\n\t" & "-1" == 2) 56 | assert(" \n -45 \t " >> " -2 " == -45 * 4) 57 | 58 | -- out of range number 59 | assert(not pcall(function () return "0xffffffffffffffff.0" | 0 end)) 60 | 61 | -- embedded zeros 62 | assert(not pcall(function () return "0xffffffffffffffff\0" | 0 end)) 63 | 64 | print'+' 65 | 66 | 67 | package.preload.bit32 = function () --{ 68 | 69 | -- no built-in 'bit32' library: implement it using bitwise operators 70 | 71 | local bit = {} 72 | 73 | function bit.bnot (a) 74 | return ~a & 0xFFFFFFFF 75 | end 76 | 77 | 78 | -- 79 | -- in all vararg functions, avoid creating 'arg' table when there are 80 | -- only 2 (or less) parameters, as 2 parameters is the common case 81 | -- 82 | 83 | function bit.band (x, y, z, ...) 84 | if not z then 85 | 86 | else 87 | local arg = {...} 88 | local res = x & y & z 89 | for i = 1, #arg do res = res & arg[i] end 90 | return res & 0xFFFFFFFF 91 | end 92 | end 93 | 94 | function bit.bor (x, y, z, ...) 95 | if not z then 96 | return ((x or 0) | (y or 0)) & 0xFFFFFFFF 97 | else 98 | local arg = {...} 99 | local res = x | y | z 100 | for i = 1, #arg do res = res | arg[i] end 101 | return res & 0xFFFFFFFF 102 | end 103 | end 104 | 105 | function bit.bxor (x, y, z, ...) 106 | if not z then 107 | return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF 108 | else 109 | local arg = {...} 110 | local res = x ~ y ~ z 111 | for i = 1, #arg do res = res ~ arg[i] end 112 | return res & 0xFFFFFFFF 113 | end 114 | end 115 | 116 | function bit.btest (...) 117 | return bit.band(...) ~= 0 118 | end 119 | 120 | function bit.lshift (a, b) 121 | return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF 122 | end 123 | 124 | function bit.rshift (a, b) 125 | return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF 126 | end 127 | 128 | function bit.arshift (a, b) 129 | a = a & 0xFFFFFFFF 130 | if b <= 0 or (a & 0x80000000) == 0 then 131 | return (a >> b) & 0xFFFFFFFF 132 | else 133 | return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF 134 | end 135 | end 136 | 137 | function bit.lrotate (a ,b) 138 | b = b & 31 139 | a = a & 0xFFFFFFFF 140 | a = (a << b) | (a >> (32 - b)) 141 | return a & 0xFFFFFFFF 142 | end 143 | 144 | function bit.rrotate (a, b) 145 | return bit.lrotate(a, -b) 146 | end 147 | 148 | local function checkfield (f, w) 149 | w = w or 1 150 | assert(f >= 0, "field cannot be negative") 151 | assert(w > 0, "width must be positive") 152 | assert(f + w <= 32, "trying to access non-existent bits") 153 | return f, ~(-1 << w) 154 | end 155 | 156 | function bit.extract (a, f, w) 157 | local f, mask = checkfield(f, w) 158 | return (a >> f) & mask 159 | end 160 | 161 | function bit.replace (a, v, f, w) 162 | local f, mask = checkfield(f, w) 163 | v = v & mask 164 | a = (a & ~(mask << f)) | (v << f) 165 | return a & 0xFFFFFFFF 166 | end 167 | 168 | return bit 169 | 170 | end --} 171 | 172 | 173 | print("testing bitwise library") 174 | 175 | local bit32 = require'bit32' 176 | 177 | assert(bit32.band() == bit32.bnot(0)) 178 | assert(bit32.btest() == true) 179 | assert(bit32.bor() == 0) 180 | assert(bit32.bxor() == 0) 181 | 182 | assert(bit32.band() == bit32.band(0xffffffff)) 183 | assert(bit32.band(1,2) == 0) 184 | 185 | 186 | -- out-of-range numbers 187 | assert(bit32.band(-1) == 0xffffffff) 188 | assert(bit32.band((1 << 33) - 1) == 0xffffffff) 189 | assert(bit32.band(-(1 << 33) - 1) == 0xffffffff) 190 | assert(bit32.band((1 << 33) + 1) == 1) 191 | assert(bit32.band(-(1 << 33) + 1) == 1) 192 | assert(bit32.band(-(1 << 40)) == 0) 193 | assert(bit32.band(1 << 40) == 0) 194 | assert(bit32.band(-(1 << 40) - 2) == 0xfffffffe) 195 | assert(bit32.band((1 << 40) - 4) == 0xfffffffc) 196 | 197 | assert(bit32.lrotate(0, -1) == 0) 198 | assert(bit32.lrotate(0, 7) == 0) 199 | assert(bit32.lrotate(0x12345678, 0) == 0x12345678) 200 | assert(bit32.lrotate(0x12345678, 32) == 0x12345678) 201 | assert(bit32.lrotate(0x12345678, 4) == 0x23456781) 202 | assert(bit32.rrotate(0x12345678, -4) == 0x23456781) 203 | assert(bit32.lrotate(0x12345678, -8) == 0x78123456) 204 | assert(bit32.rrotate(0x12345678, 8) == 0x78123456) 205 | assert(bit32.lrotate(0xaaaaaaaa, 2) == 0xaaaaaaaa) 206 | assert(bit32.lrotate(0xaaaaaaaa, -2) == 0xaaaaaaaa) 207 | for i = -50, 50 do 208 | assert(bit32.lrotate(0x89abcdef, i) == bit32.lrotate(0x89abcdef, i%32)) 209 | end 210 | 211 | assert(bit32.lshift(0x12345678, 4) == 0x23456780) 212 | assert(bit32.lshift(0x12345678, 8) == 0x34567800) 213 | assert(bit32.lshift(0x12345678, -4) == 0x01234567) 214 | assert(bit32.lshift(0x12345678, -8) == 0x00123456) 215 | assert(bit32.lshift(0x12345678, 32) == 0) 216 | assert(bit32.lshift(0x12345678, -32) == 0) 217 | assert(bit32.rshift(0x12345678, 4) == 0x01234567) 218 | assert(bit32.rshift(0x12345678, 8) == 0x00123456) 219 | assert(bit32.rshift(0x12345678, 32) == 0) 220 | assert(bit32.rshift(0x12345678, -32) == 0) 221 | assert(bit32.arshift(0x12345678, 0) == 0x12345678) 222 | assert(bit32.arshift(0x12345678, 1) == 0x12345678 // 2) 223 | assert(bit32.arshift(0x12345678, -1) == 0x12345678 * 2) 224 | assert(bit32.arshift(-1, 1) == 0xffffffff) 225 | assert(bit32.arshift(-1, 24) == 0xffffffff) 226 | assert(bit32.arshift(-1, 32) == 0xffffffff) 227 | assert(bit32.arshift(-1, -1) == bit32.band(-1 * 2, 0xffffffff)) 228 | 229 | assert(0x12345678 << 4 == 0x123456780) 230 | assert(0x12345678 << 8 == 0x1234567800) 231 | assert(0x12345678 << -4 == 0x01234567) 232 | assert(0x12345678 << -8 == 0x00123456) 233 | assert(0x12345678 << 32 == 0x1234567800000000) 234 | assert(0x12345678 << -32 == 0) 235 | assert(0x12345678 >> 4 == 0x01234567) 236 | assert(0x12345678 >> 8 == 0x00123456) 237 | assert(0x12345678 >> 32 == 0) 238 | assert(0x12345678 >> -32 == 0x1234567800000000) 239 | 240 | print("+") 241 | -- some special cases 242 | local c = {0, 1, 2, 3, 10, 0x80000000, 0xaaaaaaaa, 0x55555555, 243 | 0xffffffff, 0x7fffffff} 244 | 245 | for _, b in pairs(c) do 246 | assert(bit32.band(b) == b) 247 | assert(bit32.band(b, b) == b) 248 | assert(bit32.band(b, b, b, b) == b) 249 | assert(bit32.btest(b, b) == (b ~= 0)) 250 | assert(bit32.band(b, b, b) == b) 251 | assert(bit32.band(b, b, b, ~b) == 0) 252 | assert(bit32.btest(b, b, b) == (b ~= 0)) 253 | assert(bit32.band(b, bit32.bnot(b)) == 0) 254 | assert(bit32.bor(b, bit32.bnot(b)) == bit32.bnot(0)) 255 | assert(bit32.bor(b) == b) 256 | assert(bit32.bor(b, b) == b) 257 | assert(bit32.bor(b, b, b) == b) 258 | assert(bit32.bor(b, b, 0, ~b) == 0xffffffff) 259 | assert(bit32.bxor(b) == b) 260 | assert(bit32.bxor(b, b) == 0) 261 | assert(bit32.bxor(b, b, b) == b) 262 | assert(bit32.bxor(b, b, b, b) == 0) 263 | assert(bit32.bxor(b, 0) == b) 264 | assert(bit32.bnot(b) ~= b) 265 | assert(bit32.bnot(bit32.bnot(b)) == b) 266 | assert(bit32.bnot(b) == (1 << 32) - 1 - b) 267 | assert(bit32.lrotate(b, 32) == b) 268 | assert(bit32.rrotate(b, 32) == b) 269 | assert(bit32.lshift(bit32.lshift(b, -4), 4) == bit32.band(b, bit32.bnot(0xf))) 270 | assert(bit32.rshift(bit32.rshift(b, 4), -4) == bit32.band(b, bit32.bnot(0xf))) 271 | end 272 | 273 | -- for this test, use at most 24 bits (mantissa of a single float) 274 | c = {0, 1, 2, 3, 10, 0x800000, 0xaaaaaa, 0x555555, 0xffffff, 0x7fffff} 275 | for _, b in pairs(c) do 276 | for i = -40, 40 do 277 | local x = bit32.lshift(b, i) 278 | local y = math.floor(math.fmod(b * 2.0^i, 2.0^32)) 279 | assert(math.fmod(x - y, 2.0^32) == 0) 280 | end 281 | end 282 | 283 | assert(not pcall(bit32.band, {})) 284 | assert(not pcall(bit32.bnot, "a")) 285 | assert(not pcall(bit32.lshift, 45)) 286 | assert(not pcall(bit32.lshift, 45, print)) 287 | assert(not pcall(bit32.rshift, 45, print)) 288 | 289 | print("+") 290 | 291 | 292 | -- testing extract/replace 293 | 294 | assert(bit32.extract(0x12345678, 0, 4) == 8) 295 | assert(bit32.extract(0x12345678, 4, 4) == 7) 296 | assert(bit32.extract(0xa0001111, 28, 4) == 0xa) 297 | assert(bit32.extract(0xa0001111, 31, 1) == 1) 298 | assert(bit32.extract(0x50000111, 31, 1) == 0) 299 | assert(bit32.extract(0xf2345679, 0, 32) == 0xf2345679) 300 | 301 | assert(not pcall(bit32.extract, 0, -1)) 302 | assert(not pcall(bit32.extract, 0, 32)) 303 | assert(not pcall(bit32.extract, 0, 0, 33)) 304 | assert(not pcall(bit32.extract, 0, 31, 2)) 305 | 306 | assert(bit32.replace(0x12345678, 5, 28, 4) == 0x52345678) 307 | assert(bit32.replace(0x12345678, 0x87654321, 0, 32) == 0x87654321) 308 | assert(bit32.replace(0, 1, 2) == 2^2) 309 | assert(bit32.replace(0, -1, 4) == 2^4) 310 | assert(bit32.replace(-1, 0, 31) == (1 << 31) - 1) 311 | assert(bit32.replace(-1, 0, 1, 2) == (1 << 32) - 7) 312 | 313 | 314 | -- testing conversion of floats 315 | 316 | assert(bit32.bor(3.0) == 3) 317 | assert(bit32.bor(-4.0) == 0xfffffffc) 318 | 319 | -- large floats and large-enough integers? 320 | if 2.0^50 < 2.0^50 + 1.0 and 2.0^50 < (-1 >> 1) then 321 | assert(bit32.bor(2.0^32 - 5.0) == 0xfffffffb) 322 | assert(bit32.bor(-2.0^32 - 6.0) == 0xfffffffa) 323 | assert(bit32.bor(2.0^48 - 5.0) == 0xfffffffb) 324 | assert(bit32.bor(-2.0^48 - 6.0) == 0xfffffffa) 325 | end 326 | 327 | print'OK' 328 | 329 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/calls.lua: -------------------------------------------------------------------------------- 1 | -- $Id: calls.lua,v 1.60 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print("testing functions and calls") 5 | 6 | local debug = require "debug" 7 | 8 | -- get the opportunity to test 'type' too ;) 9 | 10 | assert(type(1<2) == 'boolean') 11 | assert(type(true) == 'boolean' and type(false) == 'boolean') 12 | assert(type(nil) == 'nil' 13 | and type(-3) == 'number' 14 | and type'x' == 'string' 15 | and type{} == 'table' 16 | and type(type) == 'function') 17 | 18 | assert(type(assert) == type(print)) 19 | function f (x) return a:x (x) end 20 | assert(type(f) == 'function') 21 | assert(not pcall(type)) 22 | 23 | 24 | do -- test error in 'print' too... 25 | local tostring = _ENV.tostring 26 | 27 | _ENV.tostring = nil 28 | local st, msg = pcall(print, 1) 29 | assert(st == false and string.find(msg, "attempt to call a nil value")) 30 | 31 | _ENV.tostring = function () return {} end 32 | local st, msg = pcall(print, 1) 33 | assert(st == false and string.find(msg, "must return a string")) 34 | 35 | _ENV.tostring = tostring 36 | end 37 | 38 | 39 | -- testing local-function recursion 40 | fact = false 41 | do 42 | local res = 1 43 | local function fact (n) 44 | if n==0 then return res 45 | else return n*fact(n-1) 46 | end 47 | end 48 | assert(fact(5) == 120) 49 | end 50 | assert(fact == false) 51 | 52 | -- testing declarations 53 | a = {i = 10} 54 | self = 20 55 | function a:x (x) return x+self.i end 56 | function a.y (x) return x+self end 57 | 58 | assert(a:x(1)+10 == a.y(1)) 59 | 60 | a.t = {i=-100} 61 | a["t"].x = function (self, a,b) return self.i+a+b end 62 | 63 | assert(a.t:x(2,3) == -95) 64 | 65 | do 66 | local a = {x=0} 67 | function a:add (x) self.x, a.y = self.x+x, 20; return self end 68 | assert(a:add(10):add(20):add(30).x == 60 and a.y == 20) 69 | end 70 | 71 | local a = {b={c={}}} 72 | 73 | function a.b.c.f1 (x) return x+1 end 74 | function a.b.c:f2 (x,y) self[x] = y end 75 | assert(a.b.c.f1(4) == 5) 76 | a.b.c:f2('k', 12); assert(a.b.c.k == 12) 77 | 78 | print('+') 79 | 80 | t = nil -- 'declare' t 81 | function f(a,b,c) local d = 'a'; t={a,b,c,d} end 82 | 83 | f( -- this line change must be valid 84 | 1,2) 85 | assert(t[1] == 1 and t[2] == 2 and t[3] == nil and t[4] == 'a') 86 | f(1,2, -- this one too 87 | 3,4) 88 | assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a') 89 | 90 | function fat(x) 91 | if x <= 1 then return 1 92 | else return x*load("return fat(" .. x-1 .. ")", "")() 93 | end 94 | end 95 | 96 | assert(load "load 'assert(fat(6)==720)' () ")() 97 | a = load('return fat(5), 3') 98 | a,b = a() 99 | assert(a == 120 and b == 3) 100 | print('+') 101 | 102 | function err_on_n (n) 103 | if n==0 then error(); exit(1); 104 | else err_on_n (n-1); exit(1); 105 | end 106 | end 107 | 108 | do 109 | function dummy (n) 110 | if n > 0 then 111 | assert(not pcall(err_on_n, n)) 112 | dummy(n-1) 113 | end 114 | end 115 | end 116 | 117 | dummy(10) 118 | 119 | function deep (n) 120 | if n>0 then deep(n-1) end 121 | end 122 | deep(10) 123 | deep(200) 124 | 125 | -- testing tail call 126 | function deep (n) if n>0 then return deep(n-1) else return 101 end end 127 | assert(deep(30000) == 101) 128 | a = {} 129 | function a:deep (n) if n>0 then return self:deep(n-1) else return 101 end end 130 | assert(a:deep(30000) == 101) 131 | 132 | print('+') 133 | 134 | 135 | a = nil 136 | (function (x) a=x end)(23) 137 | assert(a == 23 and (function (x) return x*2 end)(20) == 40) 138 | 139 | 140 | -- testing closures 141 | 142 | -- fixed-point operator 143 | Z = function (le) 144 | local function a (f) 145 | return le(function (x) return f(f)(x) end) 146 | end 147 | return a(a) 148 | end 149 | 150 | 151 | -- non-recursive factorial 152 | 153 | F = function (f) 154 | return function (n) 155 | if n == 0 then return 1 156 | else return n*f(n-1) end 157 | end 158 | end 159 | 160 | fat = Z(F) 161 | 162 | assert(fat(0) == 1 and fat(4) == 24 and Z(F)(5)==5*Z(F)(4)) 163 | 164 | local function g (z) 165 | local function f (a,b,c,d) 166 | return function (x,y) return a+b+c+d+a+x+y+z end 167 | end 168 | return f(z,z+1,z+2,z+3) 169 | end 170 | 171 | f = g(10) 172 | assert(f(9, 16) == 10+11+12+13+10+9+16+10) 173 | 174 | Z, F, f = nil 175 | print('+') 176 | 177 | -- testing multiple returns 178 | 179 | function unlpack (t, i) 180 | i = i or 1 181 | if (i <= #t) then 182 | return t[i], unlpack(t, i+1) 183 | end 184 | end 185 | 186 | function equaltab (t1, t2) 187 | assert(#t1 == #t2) 188 | for i = 1, #t1 do 189 | assert(t1[i] == t2[i]) 190 | end 191 | end 192 | 193 | local pack = function (...) return (table.pack(...)) end 194 | 195 | function f() return 1,2,30,4 end 196 | function ret2 (a,b) return a,b end 197 | 198 | local a,b,c,d = unlpack{1,2,3} 199 | assert(a==1 and b==2 and c==3 and d==nil) 200 | a = {1,2,3,4,false,10,'alo',false,assert} 201 | equaltab(pack(unlpack(a)), a) 202 | equaltab(pack(unlpack(a), -1), {1,-1}) 203 | a,b,c,d = ret2(f()), ret2(f()) 204 | assert(a==1 and b==1 and c==2 and d==nil) 205 | a,b,c,d = unlpack(pack(ret2(f()), ret2(f()))) 206 | assert(a==1 and b==1 and c==2 and d==nil) 207 | a,b,c,d = unlpack(pack(ret2(f()), (ret2(f())))) 208 | assert(a==1 and b==1 and c==nil and d==nil) 209 | 210 | a = ret2{ unlpack{1,2,3}, unlpack{3,2,1}, unlpack{"a", "b"}} 211 | assert(a[1] == 1 and a[2] == 3 and a[3] == "a" and a[4] == "b") 212 | 213 | 214 | -- testing calls with 'incorrect' arguments 215 | rawget({}, "x", 1) 216 | rawset({}, "x", 1, 2) 217 | assert(math.sin(1,2) == math.sin(1)) 218 | table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a 10 or a[i]() ~= x 161 | assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4) 162 | 163 | 164 | -- testing closures created in 'then' and 'else' parts of 'if's 165 | a = {} 166 | for i = 1, 10 do 167 | if i % 3 == 0 then 168 | local y = 0 169 | a[i] = function (x) local t = y; y = x; return t end 170 | elseif i % 3 == 1 then 171 | goto L1 172 | error'not here' 173 | ::L1:: 174 | local y = 1 175 | a[i] = function (x) local t = y; y = x; return t end 176 | elseif i % 3 == 2 then 177 | local t 178 | goto l4 179 | ::l4a:: a[i] = t; goto l4b 180 | error("should never be here!") 181 | ::l4:: 182 | local y = 2 183 | t = function (x) local t = y; y = x; return t end 184 | goto l4a 185 | error("should never be here!") 186 | ::l4b:: 187 | end 188 | end 189 | 190 | for i = 1, 10 do 191 | assert(a[i](i * 10) == i % 3 and a[i]() == i * 10) 192 | end 193 | 194 | print'+' 195 | 196 | 197 | -- test for correctly closing upvalues in tail calls of vararg functions 198 | local function t () 199 | local function c(a,b) assert(a=="test" and b=="OK") end 200 | local function v(f, ...) c("test", f() ~= 1 and "FAILED" or "OK") end 201 | local x = 1 202 | return v(function() return x end) 203 | end 204 | t() 205 | 206 | 207 | -- test for debug manipulation of upvalues 208 | local debug = require'debug' 209 | 210 | do 211 | local a , b, c = 3, 5, 7 212 | foo1 = function () return a+b end; 213 | foo2 = function () return b+a end; 214 | do 215 | local a = 10 216 | foo3 = function () return a+b end; 217 | end 218 | end 219 | 220 | assert(debug.upvalueid(foo1, 1)) 221 | assert(debug.upvalueid(foo1, 2)) 222 | assert(not pcall(debug.upvalueid, foo1, 3)) 223 | assert(debug.upvalueid(foo1, 1) == debug.upvalueid(foo2, 2)) 224 | assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo2, 1)) 225 | assert(debug.upvalueid(foo3, 1)) 226 | assert(debug.upvalueid(foo1, 1) ~= debug.upvalueid(foo3, 1)) 227 | assert(debug.upvalueid(foo1, 2) == debug.upvalueid(foo3, 2)) 228 | 229 | assert(debug.upvalueid(string.gmatch("x", "x"), 1) ~= nil) 230 | 231 | assert(foo1() == 3 + 5 and foo2() == 5 + 3) 232 | debug.upvaluejoin(foo1, 2, foo2, 2) 233 | assert(foo1() == 3 + 3 and foo2() == 5 + 3) 234 | assert(foo3() == 10 + 5) 235 | debug.upvaluejoin(foo3, 2, foo2, 1) 236 | assert(foo3() == 10 + 5) 237 | debug.upvaluejoin(foo3, 2, foo2, 2) 238 | assert(foo3() == 10 + 3) 239 | 240 | assert(not pcall(debug.upvaluejoin, foo1, 3, foo2, 1)) 241 | assert(not pcall(debug.upvaluejoin, foo1, 1, foo2, 3)) 242 | assert(not pcall(debug.upvaluejoin, foo1, 0, foo2, 1)) 243 | assert(not pcall(debug.upvaluejoin, print, 1, foo2, 1)) 244 | assert(not pcall(debug.upvaluejoin, {}, 1, foo2, 1)) 245 | assert(not pcall(debug.upvaluejoin, foo1, 1, print, 1)) 246 | 247 | print'OK' 248 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/code.lua: -------------------------------------------------------------------------------- 1 | -- $Id: code.lua,v 1.42 2016/11/07 13:04:32 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | if T==nil then 5 | (Message or print)('\n >>> testC not active: skipping opcode tests <<<\n') 6 | return 7 | end 8 | print "testing code generation and optimizations" 9 | 10 | 11 | -- this code gave an error for the code checker 12 | do 13 | local function f (a) 14 | for k,v,w in a do end 15 | end 16 | end 17 | 18 | 19 | -- testing reuse in constant table 20 | local function checkKlist (func, list) 21 | local k = T.listk(func) 22 | assert(#k == #list) 23 | for i = 1, #k do 24 | assert(k[i] == list[i] and math.type(k[i]) == math.type(list[i])) 25 | end 26 | end 27 | 28 | local function foo () 29 | local a 30 | a = 3; 31 | a = 0; a = 0.0; a = -7 + 7 32 | a = 3.78/4; a = 3.78/4 33 | a = -3.78/4; a = 3.78/4; a = -3.78/4 34 | a = -3.79/4; a = 0.0; a = -0; 35 | a = 3; a = 3.0; a = 3; a = 3.0 36 | end 37 | 38 | checkKlist(foo, {3, 0, 0.0, 3.78/4, -3.78/4, -3.79/4, 3.0}) 39 | 40 | 41 | -- testing opcodes 42 | 43 | function check (f, ...) 44 | local arg = {...} 45 | local c = T.listcode(f) 46 | for i=1, #arg do 47 | -- print(arg[i], c[i]) 48 | assert(string.find(c[i], '- '..arg[i]..' *%d')) 49 | end 50 | assert(c[#arg+2] == nil) 51 | end 52 | 53 | 54 | function checkequal (a, b) 55 | a = T.listcode(a) 56 | b = T.listcode(b) 57 | for i = 1, #a do 58 | a[i] = string.gsub(a[i], '%b()', '') -- remove line number 59 | b[i] = string.gsub(b[i], '%b()', '') -- remove line number 60 | assert(a[i] == b[i]) 61 | end 62 | end 63 | 64 | 65 | -- some basic instructions 66 | check(function () 67 | (function () end){f()} 68 | end, 'CLOSURE', 'NEWTABLE', 'GETTABUP', 'CALL', 'SETLIST', 'CALL', 'RETURN') 69 | 70 | 71 | -- sequence of LOADNILs 72 | check(function () 73 | local a,b,c 74 | local d; local e; 75 | local f,g,h; 76 | d = nil; d=nil; b=nil; a=nil; c=nil; 77 | end, 'LOADNIL', 'RETURN') 78 | 79 | check(function () 80 | local a,b,c,d = 1,1,1,1 81 | d=nil;c=nil;b=nil;a=nil 82 | end, 'LOADK', 'LOADK', 'LOADK', 'LOADK', 'LOADNIL', 'RETURN') 83 | 84 | do 85 | local a,b,c,d = 1,1,1,1 86 | d=nil;c=nil;b=nil;a=nil 87 | assert(a == nil and b == nil and c == nil and d == nil) 88 | end 89 | 90 | 91 | -- single return 92 | check (function (a,b,c) return a end, 'RETURN') 93 | 94 | 95 | -- infinite loops 96 | check(function () while true do local a = -1 end end, 97 | 'LOADK', 'JMP', 'RETURN') 98 | 99 | check(function () while 1 do local a = -1 end end, 100 | 'LOADK', 'JMP', 'RETURN') 101 | 102 | check(function () repeat local x = 1 until true end, 103 | 'LOADK', 'RETURN') 104 | 105 | 106 | -- concat optimization 107 | check(function (a,b,c,d) return a..b..c..d end, 108 | 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN') 109 | 110 | -- not 111 | check(function () return not not nil end, 'LOADBOOL', 'RETURN') 112 | check(function () return not not false end, 'LOADBOOL', 'RETURN') 113 | check(function () return not not true end, 'LOADBOOL', 'RETURN') 114 | check(function () return not not 1 end, 'LOADBOOL', 'RETURN') 115 | 116 | -- direct access to locals 117 | check(function () 118 | local a,b,c,d 119 | a = b*2 120 | c[2], a[b] = -((a + d/2 - a[b]) ^ a.x), b 121 | end, 122 | 'LOADNIL', 123 | 'MUL', 124 | 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW', 125 | 'UNM', 'SETTABLE', 'SETTABLE', 'RETURN') 126 | 127 | 128 | -- direct access to constants 129 | check(function () 130 | local a,b 131 | a.x = 3.2 132 | a.x = b 133 | a[b] = 'x' 134 | end, 135 | 'LOADNIL', 'SETTABLE', 'SETTABLE', 'SETTABLE', 'RETURN') 136 | 137 | check(function () 138 | local a,b 139 | a = 1 - a 140 | b = 1/a 141 | b = 5-4 142 | end, 143 | 'LOADNIL', 'SUB', 'DIV', 'LOADK', 'RETURN') 144 | 145 | check(function () 146 | local a,b 147 | a[true] = false 148 | end, 149 | 'LOADNIL', 'SETTABLE', 'RETURN') 150 | 151 | 152 | -- constant folding 153 | local function checkK (func, val) 154 | check(func, 'LOADK', 'RETURN') 155 | local k = T.listk(func) 156 | assert(#k == 1 and k[1] == val and math.type(k[1]) == math.type(val)) 157 | assert(func() == val) 158 | end 159 | checkK(function () return 0.0 end, 0.0) 160 | checkK(function () return 0 end, 0) 161 | checkK(function () return -0//1 end, 0) 162 | checkK(function () return 3^-1 end, 1/3) 163 | checkK(function () return (1 + 1)^(50 + 50) end, 2^100) 164 | checkK(function () return (-2)^(31 - 2) end, -0x20000000 + 0.0) 165 | checkK(function () return (-3^0 + 5) // 3.0 end, 1.0) 166 | checkK(function () return -3 % 5 end, 2) 167 | checkK(function () return -((2.0^8 + -(-1)) % 8)/2 * 4 - 3 end, -5.0) 168 | checkK(function () return -((2^8 + -(-1)) % 8)//2 * 4 - 3 end, -7.0) 169 | checkK(function () return 0xF0.0 | 0xCC.0 ~ 0xAA & 0xFD end, 0xF4) 170 | checkK(function () return ~(~0xFF0 | 0xFF0) end, 0) 171 | checkK(function () return ~~-100024.0 end, -100024) 172 | checkK(function () return ((100 << 6) << -4) >> 2 end, 100) 173 | 174 | 175 | -- no foldings 176 | check(function () return -0.0 end, 'LOADK', 'UNM', 'RETURN') 177 | check(function () return 3/0 end, 'DIV', 'RETURN') 178 | check(function () return 0%0 end, 'MOD', 'RETURN') 179 | check(function () return -4//0 end, 'IDIV', 'RETURN') 180 | 181 | -- bug in constant folding for 5.1 182 | check(function () return -nil end, 'LOADNIL', 'UNM', 'RETURN') 183 | 184 | 185 | check(function () 186 | local a,b,c 187 | b[c], a = c, b 188 | b[a], a = c, b 189 | a, b = c, a 190 | a = a 191 | end, 192 | 'LOADNIL', 193 | 'MOVE', 'MOVE', 'SETTABLE', 194 | 'MOVE', 'MOVE', 'MOVE', 'SETTABLE', 195 | 'MOVE', 'MOVE', 'MOVE', 196 | -- no code for a = a 197 | 'RETURN') 198 | 199 | 200 | -- x == nil , x ~= nil 201 | checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end, 202 | function () if (a==9) then a=1 end; if a~=9 then a=1 end end) 203 | 204 | check(function () if a==nil then a='a' end end, 205 | 'GETTABUP', 'EQ', 'JMP', 'SETTABUP', 'RETURN') 206 | 207 | -- de morgan 208 | checkequal(function () local a; if not (a or b) then b=a end end, 209 | function () local a; if (not a and not b) then b=a end end) 210 | 211 | checkequal(function (l) local a; return 0 <= a and a <= l end, 212 | function (l) local a; return not (not(a >= 0) or not(a <= l)) end) 213 | 214 | 215 | -- if-goto optimizations 216 | check(function (a, b, c, d, e) 217 | if a == b then goto l1 218 | elseif a == c then goto l2 219 | elseif a == d then goto l2 220 | else if a == e then goto l3 221 | else goto l3 222 | end 223 | end 224 | ::l1:: ::l2:: ::l3:: ::l4:: 225 | end, 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'EQ', 'JMP', 'JMP', 'RETURN') 226 | 227 | checkequal( 228 | function (a) while a < 10 do a = a + 1 end end, 229 | function (a) ::L2:: if not(a < 10) then goto L1 end; a = a + 1; 230 | goto L2; ::L1:: end 231 | ) 232 | 233 | checkequal( 234 | function (a) while a < 10 do a = a + 1 end end, 235 | function (a) while true do if not(a < 10) then break end; a = a + 1; end end 236 | ) 237 | 238 | print 'OK' 239 | 240 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/constructs.lua: -------------------------------------------------------------------------------- 1 | -- $Id: constructs.lua,v 1.41 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | ;;print "testing syntax";; 5 | 6 | local debug = require "debug" 7 | 8 | 9 | local function checkload (s, msg) 10 | assert(string.find(select(2, load(s)), msg)) 11 | end 12 | 13 | -- testing semicollons 14 | do ;;; end 15 | ; do ; a = 3; assert(a == 3) end; 16 | ; 17 | 18 | 19 | -- invalid operations should not raise errors when not executed 20 | if false then a = 3 // 0; a = 0 % 0 end 21 | 22 | 23 | -- testing priorities 24 | 25 | assert(2^3^2 == 2^(3^2)); 26 | assert(2^3*4 == (2^3)*4); 27 | assert(2.0^-2 == 1/4 and -2^- -2 == - - -4); 28 | assert(not nil and 2 and not(2>3 or 3<2)); 29 | assert(-3-1-5 == 0+0-9); 30 | assert(-2^2 == -4 and (-2)^2 == 4 and 2*2-3-1 == 0); 31 | assert(-3%5 == 2 and -3+5 == 2) 32 | assert(2*1+3/3 == 3 and 1+2 .. 3*1 == "33"); 33 | assert(not(2+1 > 3*1) and "a".."b" > "a"); 34 | 35 | assert("7" .. 3 << 1 == 146) 36 | assert(10 >> 1 .. "9" == 0) 37 | assert(10 | 1 .. "9" == 27) 38 | 39 | assert(0xF0 | 0xCC ~ 0xAA & 0xFD == 0xF4) 40 | assert(0xFD & 0xAA ~ 0xCC | 0xF0 == 0xF4) 41 | assert(0xF0 & 0x0F + 1 == 0x10) 42 | 43 | assert(3^4//2^3//5 == 2) 44 | 45 | assert(-3+4*5//2^3^2//9+4%10/3 == (-3)+(((4*5)//(2^(3^2)))//9)+((4%10)/3)) 46 | 47 | assert(not ((true or false) and nil)) 48 | assert( true or false and nil) 49 | 50 | -- old bug 51 | assert((((1 or false) and true) or false) == true) 52 | assert((((nil and true) or false) and true) == false) 53 | 54 | local a,b = 1,nil; 55 | assert(-(1 or 2) == -1 and (1 and 2)+(-1.25 or -4) == 0.75); 56 | x = ((b or a)+1 == 2 and (10 or a)+1 == 11); assert(x); 57 | x = (((2<3) or 1) == true and (2<3 and 4) == 4); assert(x); 58 | 59 | x,y=1,2; 60 | assert((x>y) and x or y == 2); 61 | x,y=2,1; 62 | assert((x>y) and x or y == 2); 63 | 64 | assert(1234567890 == tonumber('1234567890') and 1234567890+1 == 1234567891) 65 | 66 | 67 | -- silly loops 68 | repeat until 1; repeat until true; 69 | while false do end; while nil do end; 70 | 71 | do -- test old bug (first name could not be an `upvalue') 72 | local a; function f(x) x={a=1}; x={x=1}; x={G=1} end 73 | end 74 | 75 | function f (i) 76 | if type(i) ~= 'number' then return i,'jojo'; end; 77 | if i > 0 then return i, f(i-1); end; 78 | end 79 | 80 | x = {f(3), f(5), f(10);}; 81 | assert(x[1] == 3 and x[2] == 5 and x[3] == 10 and x[4] == 9 and x[12] == 1); 82 | assert(x[nil] == nil) 83 | x = {f'alo', f'xixi', nil}; 84 | assert(x[1] == 'alo' and x[2] == 'xixi' and x[3] == nil); 85 | x = {f'alo'..'xixi'}; 86 | assert(x[1] == 'aloxixi') 87 | x = {f{}} 88 | assert(x[2] == 'jojo' and type(x[1]) == 'table') 89 | 90 | 91 | local f = function (i) 92 | if i < 10 then return 'a'; 93 | elseif i < 20 then return 'b'; 94 | elseif i < 30 then return 'c'; 95 | end; 96 | end 97 | 98 | assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == nil) 99 | 100 | for i=1,1000 do break; end; 101 | n=100; 102 | i=3; 103 | t = {}; 104 | a=nil 105 | while not a do 106 | a=0; for i=1,n do for i=i,1,-1 do a=a+1; t[i]=1; end; end; 107 | end 108 | assert(a == n*(n+1)/2 and i==3); 109 | assert(t[1] and t[n] and not t[0] and not t[n+1]) 110 | 111 | function f(b) 112 | local x = 1; 113 | repeat 114 | local a; 115 | if b==1 then local b=1; x=10; break 116 | elseif b==2 then x=20; break; 117 | elseif b==3 then x=30; 118 | else local a,b,c,d=math.sin(1); x=x+1; 119 | end 120 | until x>=12; 121 | return x; 122 | end; 123 | 124 | assert(f(1) == 10 and f(2) == 20 and f(3) == 30 and f(4)==12) 125 | 126 | 127 | local f = function (i) 128 | if i < 10 then return 'a' 129 | elseif i < 20 then return 'b' 130 | elseif i < 30 then return 'c' 131 | else return 8 132 | end 133 | end 134 | 135 | assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == 8) 136 | 137 | local a, b = nil, 23 138 | x = {f(100)*2+3 or a, a or b+2} 139 | assert(x[1] == 19 and x[2] == 25) 140 | x = {f=2+3 or a, a = b+2} 141 | assert(x.f == 5 and x.a == 25) 142 | 143 | a={y=1} 144 | x = {a.y} 145 | assert(x[1] == 1) 146 | 147 | function f(i) 148 | while 1 do 149 | if i>0 then i=i-1; 150 | else return; end; 151 | end; 152 | end; 153 | 154 | function g(i) 155 | while 1 do 156 | if i>0 then i=i-1 157 | else return end 158 | end 159 | end 160 | 161 | f(10); g(10); 162 | 163 | do 164 | function f () return 1,2,3; end 165 | local a, b, c = f(); 166 | assert(a==1 and b==2 and c==3) 167 | a, b, c = (f()); 168 | assert(a==1 and b==nil and c==nil) 169 | end 170 | 171 | local a,b = 3 and f(); 172 | assert(a==1 and b==nil) 173 | 174 | function g() f(); return; end; 175 | assert(g() == nil) 176 | function g() return nil or f() end 177 | a,b = g() 178 | assert(a==1 and b==nil) 179 | 180 | print'+'; 181 | 182 | 183 | f = [[ 184 | return function ( a , b , c , d , e ) 185 | local x = a >= b or c or ( d and e ) or nil 186 | return x 187 | end , { a = 1 , b = 2 >= 1 , } or { 1 }; 188 | ]] 189 | f = string.gsub(f, "%s+", "\n"); -- force a SETLINE between opcodes 190 | f,a = load(f)(); 191 | assert(a.a == 1 and a.b) 192 | 193 | function g (a,b,c,d,e) 194 | if not (a>=b or c or d and e or nil) then return 0; else return 1; end; 195 | end 196 | 197 | function h (a,b,c,d,e) 198 | while (a>=b or c or (d and e) or nil) do return 1; end; 199 | return 0; 200 | end; 201 | 202 | assert(f(2,1) == true and g(2,1) == 1 and h(2,1) == 1) 203 | assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) 204 | assert(f(1,2,'a') 205 | ~= -- force SETLINE before nil 206 | nil, "") 207 | assert(f(1,2,'a') == 'a' and g(1,2,'a') == 1 and h(1,2,'a') == 1) 208 | assert(f(1,2,nil,1,'x') == 'x' and g(1,2,nil,1,'x') == 1 and 209 | h(1,2,nil,1,'x') == 1) 210 | assert(f(1,2,nil,nil,'x') == nil and g(1,2,nil,nil,'x') == 0 and 211 | h(1,2,nil,nil,'x') == 0) 212 | assert(f(1,2,nil,1,nil) == nil and g(1,2,nil,1,nil) == 0 and 213 | h(1,2,nil,1,nil) == 0) 214 | 215 | assert(1 and 2<3 == true and 2<3 and 'a'<'b' == true) 216 | x = 2<3 and not 3; assert(x==false) 217 | x = 2<1 or (2>1 and 'a'); assert(x=='a') 218 | 219 | 220 | do 221 | local a; if nil then a=1; else a=2; end; -- this nil comes as PUSHNIL 2 222 | assert(a==2) 223 | end 224 | 225 | function F(a) 226 | assert(debug.getinfo(1, "n").name == 'F') 227 | return a,2,3 228 | end 229 | 230 | a,b = F(1)~=nil; assert(a == true and b == nil); 231 | a,b = F(nil)==nil; assert(a == true and b == nil) 232 | 233 | ---------------------------------------------------------------- 234 | ------------------------------------------------------------------ 235 | 236 | -- sometimes will be 0, sometimes will not... 237 | _ENV.GLOB1 = math.floor(os.time()) % 2 238 | 239 | -- basic expressions with their respective values 240 | local basiccases = { 241 | {"nil", nil}, 242 | {"false", false}, 243 | {"true", true}, 244 | {"10", 10}, 245 | {"(0==_ENV.GLOB1)", 0 == _ENV.GLOB1}, 246 | } 247 | 248 | print('testing short-circuit optimizations (' .. _ENV.GLOB1 .. ')') 249 | 250 | 251 | -- operators with their respective values 252 | local binops = { 253 | {" and ", function (a,b) if not a then return a else return b end end}, 254 | {" or ", function (a,b) if a then return a else return b end end}, 255 | } 256 | 257 | local cases = {} 258 | 259 | -- creates all combinations of '(cases[i] op cases[n-i])' plus 260 | -- 'not(cases[i] op cases[n-i])' (syntax + value) 261 | local function createcases (n) 262 | local res = {} 263 | for i = 1, n - 1 do 264 | for _, v1 in ipairs(cases[i]) do 265 | for _, v2 in ipairs(cases[n - i]) do 266 | for _, op in ipairs(binops) do 267 | local t = { 268 | "(" .. v1[1] .. op[1] .. v2[1] .. ")", 269 | op[2](v1[2], v2[2]) 270 | } 271 | res[#res + 1] = t 272 | res[#res + 1] = {"not" .. t[1], not t[2]} 273 | end 274 | end 275 | end 276 | end 277 | return res 278 | end 279 | 280 | -- do not do too many combinations for soft tests 281 | local level = _soft and 3 or 4 282 | 283 | cases[1] = basiccases 284 | for i = 2, level do cases[i] = createcases(i) end 285 | print("+") 286 | 287 | local prog = [[if %s then IX = true end; return %s]] 288 | 289 | local i = 0 290 | for n = 1, level do 291 | for _, v in pairs(cases[n]) do 292 | local s = v[1] 293 | local p = load(string.format(prog, s, s), "") 294 | IX = false 295 | assert(p() == v[2] and IX == not not v[2]) 296 | i = i + 1 297 | if i % 60000 == 0 then print('+') end 298 | end 299 | end 300 | ------------------------------------------------------------------ 301 | 302 | -- testing some syntax errors (chosen through 'gcov') 303 | checkload("for x do", "expected") 304 | checkload("x:call", "expected") 305 | 306 | if not _soft then 307 | -- control structure too long 308 | local s = string.rep("a = a + 1\n", 2^18) 309 | s = "while true do " .. s .. "end" 310 | checkload(s, "too long") 311 | end 312 | 313 | print'OK' 314 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/db.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsbenas/parser-gen/8d6311a439ae32f598eaa13880e54a5f0896e898/parsers/lua-5.3.4-tests/db.lua -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/events.lua: -------------------------------------------------------------------------------- 1 | -- $Id: events.lua,v 1.45 2016/12/21 19:23:02 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print('testing metatables') 5 | 6 | local debug = require'debug' 7 | 8 | X = 20; B = 30 9 | 10 | _ENV = setmetatable({}, {__index=_G}) 11 | 12 | collectgarbage() 13 | 14 | X = X+10 15 | assert(X == 30 and _G.X == 20) 16 | B = false 17 | assert(B == false) 18 | B = nil 19 | assert(B == 30) 20 | 21 | assert(getmetatable{} == nil) 22 | assert(getmetatable(4) == nil) 23 | assert(getmetatable(nil) == nil) 24 | a={name = "NAME"}; setmetatable(a, {__metatable = "xuxu", 25 | __tostring=function(x) return x.name end}) 26 | assert(getmetatable(a) == "xuxu") 27 | assert(tostring(a) == "NAME") 28 | -- cannot change a protected metatable 29 | assert(pcall(setmetatable, a, {}) == false) 30 | a.name = "gororoba" 31 | assert(tostring(a) == "gororoba") 32 | 33 | local a, t = {10,20,30; x="10", y="20"}, {} 34 | assert(setmetatable(a,t) == a) 35 | assert(getmetatable(a) == t) 36 | assert(setmetatable(a,nil) == a) 37 | assert(getmetatable(a) == nil) 38 | assert(setmetatable(a,t) == a) 39 | 40 | 41 | function f (t, i, e) 42 | assert(not e) 43 | local p = rawget(t, "parent") 44 | return (p and p[i]+3), "dummy return" 45 | end 46 | 47 | t.__index = f 48 | 49 | a.parent = {z=25, x=12, [4] = 24} 50 | assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10") 51 | 52 | collectgarbage() 53 | 54 | a = setmetatable({}, t) 55 | function f(t, i, v) rawset(t, i, v-3) end 56 | setmetatable(t, t) -- causes a bug in 5.1 ! 57 | t.__newindex = f 58 | a[1] = 30; a.x = "101"; a[5] = 200 59 | assert(a[1] == 27 and a.x == 98 and a[5] == 197) 60 | 61 | do -- bug in Lua 5.3.2 62 | local mt = {} 63 | mt.__newindex = mt 64 | local t = setmetatable({}, mt) 65 | t[1] = 10 -- will segfault on some machines 66 | assert(mt[1] == 10) 67 | end 68 | 69 | 70 | local c = {} 71 | a = setmetatable({}, t) 72 | t.__newindex = c 73 | a[1] = 10; a[2] = 20; a[3] = 90 74 | assert(c[1] == 10 and c[2] == 20 and c[3] == 90) 75 | 76 | 77 | do 78 | local a; 79 | a = setmetatable({}, {__index = setmetatable({}, 80 | {__index = setmetatable({}, 81 | {__index = function (_,n) return a[n-3]+4, "lixo" end})})}) 82 | a[0] = 20 83 | for i=0,10 do 84 | assert(a[i*3] == 20 + i*4) 85 | end 86 | end 87 | 88 | 89 | do -- newindex 90 | local foi 91 | local a = {} 92 | for i=1,10 do a[i] = 0; a['a'..i] = 0; end 93 | setmetatable(a, {__newindex = function (t,k,v) foi=true; rawset(t,k,v) end}) 94 | foi = false; a[1]=0; assert(not foi) 95 | foi = false; a['a1']=0; assert(not foi) 96 | foi = false; a['a11']=0; assert(foi) 97 | foi = false; a[11]=0; assert(foi) 98 | foi = false; a[1]=nil; assert(not foi) 99 | foi = false; a[1]=nil; assert(foi) 100 | end 101 | 102 | 103 | setmetatable(t, nil) 104 | function f (t, ...) return t, {...} end 105 | t.__call = f 106 | 107 | do 108 | local x,y = a(table.unpack{'a', 1}) 109 | assert(x==a and y[1]=='a' and y[2]==1 and y[3]==nil) 110 | x,y = a() 111 | assert(x==a and y[1]==nil) 112 | end 113 | 114 | 115 | local b = setmetatable({}, t) 116 | setmetatable(b,t) 117 | 118 | function f(op) 119 | return function (...) cap = {[0] = op, ...} ; return (...) end 120 | end 121 | t.__add = f("add") 122 | t.__sub = f("sub") 123 | t.__mul = f("mul") 124 | t.__div = f("div") 125 | t.__idiv = f("idiv") 126 | t.__mod = f("mod") 127 | t.__unm = f("unm") 128 | t.__pow = f("pow") 129 | t.__len = f("len") 130 | t.__band = f("band") 131 | t.__bor = f("bor") 132 | t.__bxor = f("bxor") 133 | t.__shl = f("shl") 134 | t.__shr = f("shr") 135 | t.__bnot = f("bnot") 136 | 137 | assert(b+5 == b) 138 | assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==nil) 139 | assert(b+'5' == b) 140 | assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==nil) 141 | assert(5+b == 5) 142 | assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==nil) 143 | assert('5'+b == '5') 144 | assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==nil) 145 | b=b-3; assert(getmetatable(b) == t) 146 | assert(5-a == 5) 147 | assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==nil) 148 | assert('5'-a == '5') 149 | assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==nil) 150 | assert(a*a == a) 151 | assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==nil) 152 | assert(a/0 == a) 153 | assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==nil) 154 | assert(a%2 == a) 155 | assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==nil) 156 | assert(a // (1/0) == a) 157 | assert(cap[0] == "idiv" and cap[1] == a and cap[2] == 1/0 and cap[3]==nil) 158 | assert(a & "hi" == a) 159 | assert(cap[0] == "band" and cap[1] == a and cap[2] == "hi" and cap[3]==nil) 160 | assert(a | "hi" == a) 161 | assert(cap[0] == "bor" and cap[1] == a and cap[2] == "hi" and cap[3]==nil) 162 | assert("hi" ~ a == "hi") 163 | assert(cap[0] == "bxor" and cap[1] == "hi" and cap[2] == a and cap[3]==nil) 164 | assert(-a == a) 165 | assert(cap[0] == "unm" and cap[1] == a) 166 | assert(a^4 == a) 167 | assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==nil) 168 | assert(a^'4' == a) 169 | assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==nil) 170 | assert(4^a == 4) 171 | assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==nil) 172 | assert('4'^a == '4') 173 | assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==nil) 174 | assert(#a == a) 175 | assert(cap[0] == "len" and cap[1] == a) 176 | assert(~a == a) 177 | assert(cap[0] == "bnot" and cap[1] == a) 178 | assert(a << 3 == a) 179 | assert(cap[0] == "shl" and cap[1] == a and cap[2] == 3) 180 | assert(1.5 >> a == 1.5) 181 | assert(cap[0] == "shr" and cap[1] == 1.5 and cap[2] == a) 182 | 183 | 184 | -- test for rawlen 185 | t = setmetatable({1,2,3}, {__len = function () return 10 end}) 186 | assert(#t == 10 and rawlen(t) == 3) 187 | assert(rawlen"abc" == 3) 188 | assert(not pcall(rawlen, io.stdin)) 189 | assert(not pcall(rawlen, 34)) 190 | assert(not pcall(rawlen)) 191 | 192 | -- rawlen for long strings 193 | assert(rawlen(string.rep('a', 1000)) == 1000) 194 | 195 | 196 | t = {} 197 | t.__lt = function (a,b,c) 198 | collectgarbage() 199 | assert(c == nil) 200 | if type(a) == 'table' then a = a.x end 201 | if type(b) == 'table' then b = b.x end 202 | return aOp(1)) and not(Op(1)>Op(2)) and (Op(2)>Op(1))) 215 | assert(not(Op('a')>Op('a')) and not(Op('a')>Op('b')) and (Op('b')>Op('a'))) 216 | assert((Op(1)>=Op(1)) and not(Op(1)>=Op(2)) and (Op(2)>=Op(1))) 217 | assert((1 >= Op(1)) and not(1 >= Op(2)) and (Op(2) >= 1)) 218 | assert((Op('a')>=Op('a')) and not(Op('a')>=Op('b')) and (Op('b')>=Op('a'))) 219 | assert(('a' >= Op('a')) and not(Op('a') >= 'b') and (Op('b') >= Op('a'))) 220 | end 221 | 222 | test() 223 | 224 | t.__le = function (a,b,c) 225 | assert(c == nil) 226 | if type(a) == 'table' then a = a.x end 227 | if type(b) == 'table' then b = b.x end 228 | return a<=b, "dummy" 229 | end 230 | 231 | test() -- retest comparisons, now using both `lt' and `le' 232 | 233 | 234 | -- test `partial order' 235 | 236 | local function rawSet(x) 237 | local y = {} 238 | for _,k in pairs(x) do y[k] = 1 end 239 | return y 240 | end 241 | 242 | local function Set(x) 243 | return setmetatable(rawSet(x), t) 244 | end 245 | 246 | t.__lt = function (a,b) 247 | for k in pairs(a) do 248 | if not b[k] then return false end 249 | b[k] = nil 250 | end 251 | return next(b) ~= nil 252 | end 253 | 254 | t.__le = nil 255 | 256 | assert(Set{1,2,3} < Set{1,2,3,4}) 257 | assert(not(Set{1,2,3,4} < Set{1,2,3,4})) 258 | assert((Set{1,2,3,4} <= Set{1,2,3,4})) 259 | assert((Set{1,2,3,4} >= Set{1,2,3,4})) 260 | assert((Set{1,3} <= Set{3,5})) -- wrong!! model needs a `le' method ;-) 261 | 262 | t.__le = function (a,b) 263 | for k in pairs(a) do 264 | if not b[k] then return false end 265 | end 266 | return true 267 | end 268 | 269 | assert(not (Set{1,3} <= Set{3,5})) -- now its OK! 270 | assert(not(Set{1,3} <= Set{3,5})) 271 | assert(not(Set{1,3} >= Set{3,5})) 272 | 273 | t.__eq = function (a,b) 274 | for k in pairs(a) do 275 | if not b[k] then return false end 276 | b[k] = nil 277 | end 278 | return next(b) == nil 279 | end 280 | 281 | local s = Set{1,3,5} 282 | assert(s == Set{3,5,1}) 283 | assert(not rawequal(s, Set{3,5,1})) 284 | assert(rawequal(s, s)) 285 | assert(Set{1,3,5,1} == rawSet{3,5,1}) 286 | assert(rawSet{1,3,5,1} == Set{3,5,1}) 287 | assert(Set{1,3,5} ~= Set{3,5,1,6}) 288 | 289 | -- '__eq' is not used for table accesses 290 | t[Set{1,3,5}] = 1 291 | assert(t[Set{1,3,5}] == nil) 292 | 293 | 294 | if not T then 295 | (Message or print)('\n >>> testC not active: skipping tests for \z 296 | userdata equality <<<\n') 297 | else 298 | local u1 = T.newuserdata(0) 299 | local u2 = T.newuserdata(0) 300 | local u3 = T.newuserdata(0) 301 | assert(u1 ~= u2 and u1 ~= u3) 302 | debug.setuservalue(u1, 1); 303 | debug.setuservalue(u2, 2); 304 | debug.setuservalue(u3, 1); 305 | debug.setmetatable(u1, {__eq = function (a, b) 306 | return debug.getuservalue(a) == debug.getuservalue(b) 307 | end}) 308 | debug.setmetatable(u2, {__eq = function (a, b) 309 | return true 310 | end}) 311 | assert(u1 == u3 and u3 == u1 and u1 ~= u2) 312 | assert(u2 == u1 and u2 == u3 and u3 == u2) 313 | assert(u2 ~= {}) -- different types cannot be equal 314 | end 315 | 316 | 317 | t.__concat = function (a,b,c) 318 | assert(c == nil) 319 | if type(a) == 'table' then a = a.val end 320 | if type(b) == 'table' then b = b.val end 321 | if A then return a..b 322 | else 323 | return setmetatable({val=a..b}, t) 324 | end 325 | end 326 | 327 | c = {val="c"}; setmetatable(c, t) 328 | d = {val="d"}; setmetatable(d, t) 329 | 330 | A = true 331 | assert(c..d == 'cd') 332 | assert(0 .."a".."b"..c..d.."e".."f"..(5+3).."g" == "0abcdef8g") 333 | 334 | A = false 335 | assert((c..d..c..d).val == 'cdcd') 336 | x = c..d 337 | assert(getmetatable(x) == t and x.val == 'cd') 338 | x = 0 .."a".."b"..c..d.."e".."f".."g" 339 | assert(x.val == "0abcdefg") 340 | 341 | 342 | -- concat metamethod x numbers (bug in 5.1.1) 343 | c = {} 344 | local x 345 | setmetatable(c, {__concat = function (a,b) 346 | assert(type(a) == "number" and b == c or type(b) == "number" and a == c) 347 | return c 348 | end}) 349 | assert(c..5 == c and 5 .. c == c) 350 | assert(4 .. c .. 5 == c and 4 .. 5 .. 6 .. 7 .. c == c) 351 | 352 | 353 | -- test comparison compatibilities 354 | local t1, t2, c, d 355 | t1 = {}; c = {}; setmetatable(c, t1) 356 | d = {} 357 | t1.__eq = function () return true end 358 | t1.__lt = function () return true end 359 | setmetatable(d, t1) 360 | assert(c == d and c < d and not(d <= c)) 361 | t2 = {} 362 | t2.__eq = t1.__eq 363 | t2.__lt = t1.__lt 364 | setmetatable(d, t2) 365 | assert(c == d and c < d and not(d <= c)) 366 | 367 | 368 | 369 | -- test for several levels of calls 370 | local i 371 | local tt = { 372 | __call = function (t, ...) 373 | i = i+1 374 | if t.f then return t.f(...) 375 | else return {...} 376 | end 377 | end 378 | } 379 | 380 | local a = setmetatable({}, tt) 381 | local b = setmetatable({f=a}, tt) 382 | local c = setmetatable({f=b}, tt) 383 | 384 | i = 0 385 | x = c(3,4,5) 386 | assert(i == 3 and x[1] == 3 and x[3] == 5) 387 | 388 | 389 | assert(_G.X == 20) 390 | 391 | print'+' 392 | 393 | local _g = _G 394 | _ENV = setmetatable({}, {__index=function (_,k) return _g[k] end}) 395 | 396 | 397 | a = {} 398 | rawset(a, "x", 1, 2, 3) 399 | assert(a.x == 1 and rawget(a, "x", 3) == 1) 400 | 401 | print '+' 402 | 403 | -- testing metatables for basic types 404 | mt = {__index = function (a,b) return a+b end, 405 | __len = function (x) return math.floor(x) end} 406 | debug.setmetatable(10, mt) 407 | assert(getmetatable(-2) == mt) 408 | assert((10)[3] == 13) 409 | assert((10)["3"] == 13) 410 | assert(#3.45 == 3) 411 | debug.setmetatable(23, nil) 412 | assert(getmetatable(-2) == nil) 413 | 414 | debug.setmetatable(true, mt) 415 | assert(getmetatable(false) == mt) 416 | mt.__index = function (a,b) return a or b end 417 | assert((true)[false] == true) 418 | assert((false)[false] == false) 419 | debug.setmetatable(false, nil) 420 | assert(getmetatable(true) == nil) 421 | 422 | debug.setmetatable(nil, mt) 423 | assert(getmetatable(nil) == mt) 424 | mt.__add = function (a,b) return (a or 0) + (b or 0) end 425 | assert(10 + nil == 10) 426 | assert(nil + 23 == 23) 427 | assert(nil + nil == 0) 428 | debug.setmetatable(nil, nil) 429 | assert(getmetatable(nil) == nil) 430 | 431 | debug.setmetatable(nil, {}) 432 | 433 | 434 | -- loops in delegation 435 | a = {}; setmetatable(a, a); a.__index = a; a.__newindex = a 436 | assert(not pcall(function (a,b) return a[b] end, a, 10)) 437 | assert(not pcall(function (a,b,c) a[b] = c end, a, 10, true)) 438 | 439 | -- bug in 5.1 440 | T, K, V = nil 441 | grandparent = {} 442 | grandparent.__newindex = function(t,k,v) T=t; K=k; V=v end 443 | 444 | parent = {} 445 | parent.__newindex = parent 446 | setmetatable(parent, grandparent) 447 | 448 | child = setmetatable({}, parent) 449 | child.foo = 10 --> CRASH (on some machines) 450 | assert(T == parent and K == "foo" and V == 10) 451 | 452 | print 'OK' 453 | 454 | return 12 455 | 456 | 457 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/files.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsbenas/parser-gen/8d6311a439ae32f598eaa13880e54a5f0896e898/parsers/lua-5.3.4-tests/files.lua -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/goto.lua: -------------------------------------------------------------------------------- 1 | -- $Id: goto.lua,v 1.13 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | collectgarbage() 5 | 6 | local function errmsg (code, m) 7 | local st, msg = load(code) 8 | assert(not st and string.find(msg, m)) 9 | end 10 | 11 | -- cannot see label inside block 12 | errmsg([[ goto l1; do ::l1:: end ]], "label 'l1'") 13 | errmsg([[ do ::l1:: end goto l1; ]], "label 'l1'") 14 | 15 | -- repeated label 16 | errmsg([[ ::l1:: ::l1:: ]], "label 'l1'") 17 | 18 | 19 | -- undefined label 20 | errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'") 21 | 22 | -- jumping over variable definition 23 | errmsg([[ 24 | do local bb, cc; goto l1; end 25 | local aa 26 | ::l1:: print(3) 27 | ]], "local 'aa'") 28 | 29 | -- jumping into a block 30 | errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'") 31 | errmsg([[ goto l1 do ::l1:: end ]], "label 'l1'") 32 | 33 | -- cannot continue a repeat-until with variables 34 | errmsg([[ 35 | repeat 36 | if x then goto cont end 37 | local xuxu = 10 38 | ::cont:: 39 | until xuxu < x 40 | ]], "local 'xuxu'") 41 | 42 | -- simple gotos 43 | local x 44 | do 45 | local y = 12 46 | goto l1 47 | ::l2:: x = x + 1; goto l3 48 | ::l1:: x = y; goto l2 49 | end 50 | ::l3:: ::l3_1:: assert(x == 13) 51 | 52 | 53 | -- long labels 54 | do 55 | local prog = [[ 56 | do 57 | local a = 1 58 | goto l%sa; a = a + 1 59 | ::l%sa:: a = a + 10 60 | goto l%sb; a = a + 2 61 | ::l%sb:: a = a + 20 62 | return a 63 | end 64 | ]] 65 | local label = string.rep("0123456789", 40) 66 | prog = string.format(prog, label, label, label, label) 67 | assert(assert(load(prog))() == 31) 68 | end 69 | 70 | -- goto to correct label when nested 71 | do goto l3; ::l3:: end -- does not loop jumping to previous label 'l3' 72 | 73 | -- ok to jump over local dec. to end of block 74 | do 75 | goto l1 76 | local a = 23 77 | x = a 78 | ::l1::; 79 | end 80 | 81 | while true do 82 | goto l4 83 | goto l1 -- ok to jump over local dec. to end of block 84 | goto l1 -- multiple uses of same label 85 | local x = 45 86 | ::l1:: ;;; 87 | end 88 | ::l4:: assert(x == 13) 89 | 90 | if print then 91 | goto l1 -- ok to jump over local dec. to end of block 92 | error("should not be here") 93 | goto l2 -- ok to jump over local dec. to end of block 94 | local x 95 | ::l1:: ; ::l2:: ;; 96 | else end 97 | 98 | -- to repeat a label in a different function is OK 99 | local function foo () 100 | local a = {} 101 | goto l3 102 | ::l1:: a[#a + 1] = 1; goto l2; 103 | ::l2:: a[#a + 1] = 2; goto l5; 104 | ::l3:: 105 | ::l3a:: a[#a + 1] = 3; goto l1; 106 | ::l4:: a[#a + 1] = 4; goto l6; 107 | ::l5:: a[#a + 1] = 5; goto l4; 108 | ::l6:: assert(a[1] == 3 and a[2] == 1 and a[3] == 2 and 109 | a[4] == 5 and a[5] == 4) 110 | if not a[6] then a[6] = true; goto l3a end -- do it twice 111 | end 112 | 113 | ::l6:: foo() 114 | 115 | 116 | do -- bug in 5.2 -> 5.3.2 117 | local x 118 | ::L1:: 119 | local y -- cannot join this SETNIL with previous one 120 | assert(y == nil) 121 | y = true 122 | if x == nil then 123 | x = 1 124 | goto L1 125 | else 126 | x = x + 1 127 | end 128 | assert(x == 2 and y == true) 129 | end 130 | 131 | -------------------------------------------------------------------------------- 132 | -- testing closing of upvalues 133 | 134 | local debug = require 'debug' 135 | 136 | local function foo () 137 | local t = {} 138 | do 139 | local i = 1 140 | local a, b, c, d 141 | t[1] = function () return a, b, c, d end 142 | ::l1:: 143 | local b 144 | do 145 | local c 146 | t[#t + 1] = function () return a, b, c, d end -- t[2], t[4], t[6] 147 | if i > 2 then goto l2 end 148 | do 149 | local d 150 | t[#t + 1] = function () return a, b, c, d end -- t[3], t[5] 151 | i = i + 1 152 | local a 153 | goto l1 154 | end 155 | end 156 | end 157 | ::l2:: return t 158 | end 159 | 160 | local a = foo() 161 | assert(#a == 6) 162 | 163 | -- all functions share same 'a' 164 | for i = 2, 6 do 165 | assert(debug.upvalueid(a[1], 1) == debug.upvalueid(a[i], 1)) 166 | end 167 | 168 | -- 'b' and 'c' are shared among some of them 169 | for i = 2, 6 do 170 | -- only a[1] uses external 'b'/'b' 171 | assert(debug.upvalueid(a[1], 2) ~= debug.upvalueid(a[i], 2)) 172 | assert(debug.upvalueid(a[1], 3) ~= debug.upvalueid(a[i], 3)) 173 | end 174 | 175 | for i = 3, 5, 2 do 176 | -- inner functions share 'b'/'c' with previous ones 177 | assert(debug.upvalueid(a[i], 2) == debug.upvalueid(a[i - 1], 2)) 178 | assert(debug.upvalueid(a[i], 3) == debug.upvalueid(a[i - 1], 3)) 179 | -- but not with next ones 180 | assert(debug.upvalueid(a[i], 2) ~= debug.upvalueid(a[i + 1], 2)) 181 | assert(debug.upvalueid(a[i], 3) ~= debug.upvalueid(a[i + 1], 3)) 182 | end 183 | 184 | -- only external 'd' is shared 185 | for i = 2, 6, 2 do 186 | assert(debug.upvalueid(a[1], 4) == debug.upvalueid(a[i], 4)) 187 | end 188 | 189 | -- internal 'd's are all different 190 | for i = 3, 5, 2 do 191 | for j = 1, 6 do 192 | assert((debug.upvalueid(a[i], 4) == debug.upvalueid(a[j], 4)) 193 | == (i == j)) 194 | end 195 | end 196 | 197 | -------------------------------------------------------------------------------- 198 | -- testing if x goto optimizations 199 | 200 | local function testG (a) 201 | if a == 1 then 202 | goto l1 203 | error("should never be here!") 204 | elseif a == 2 then goto l2 205 | elseif a == 3 then goto l3 206 | elseif a == 4 then 207 | goto l1 -- go to inside the block 208 | error("should never be here!") 209 | ::l1:: a = a + 1 -- must go to 'if' end 210 | else 211 | goto l4 212 | ::l4a:: a = a * 2; goto l4b 213 | error("should never be here!") 214 | ::l4:: goto l4a 215 | error("should never be here!") 216 | ::l4b:: 217 | end 218 | do return a end 219 | ::l2:: do return "2" end 220 | ::l3:: do return "3" end 221 | ::l1:: return "1" 222 | end 223 | 224 | assert(testG(1) == "1") 225 | assert(testG(2) == "2") 226 | assert(testG(3) == "3") 227 | assert(testG(4) == 5) 228 | assert(testG(5) == 10) 229 | -------------------------------------------------------------------------------- 230 | 231 | 232 | print'OK' 233 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/literals.lua: -------------------------------------------------------------------------------- 1 | -- $Id: literals.lua,v 1.36 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print('testing scanner') 5 | 6 | local debug = require "debug" 7 | 8 | 9 | local function dostring (x) return assert(load(x), "")() end 10 | 11 | dostring("x \v\f = \t\r 'a\0a' \v\f\f") 12 | assert(x == 'a\0a' and string.len(x) == 3) 13 | 14 | -- escape sequences 15 | assert('\n\"\'\\' == [[ 16 | 17 | "'\]]) 18 | 19 | assert(string.find("\a\b\f\n\r\t\v", "^%c%c%c%c%c%c%c$")) 20 | 21 | -- assume ASCII just for tests: 22 | assert("\09912" == 'c12') 23 | assert("\99ab" == 'cab') 24 | assert("\099" == '\99') 25 | assert("\099\n" == 'c\10') 26 | assert('\0\0\0alo' == '\0' .. '\0\0' .. 'alo') 27 | 28 | assert(010 .. 020 .. -030 == "1020-30") 29 | 30 | -- hexadecimal escapes 31 | assert("\x00\x05\x10\x1f\x3C\xfF\xe8" == "\0\5\16\31\60\255\232") 32 | 33 | local function lexstring (x, y, n) 34 | local f = assert(load('return ' .. x .. 35 | ', require"debug".getinfo(1).currentline', '')) 36 | local s, l = f() 37 | assert(s == y and l == n) 38 | end 39 | 40 | lexstring("'abc\\z \n efg'", "abcefg", 2) 41 | lexstring("'abc\\z \n\n\n'", "abc", 4) 42 | lexstring("'\\z \n\t\f\v\n'", "", 3) 43 | lexstring("[[\nalo\nalo\n\n]]", "alo\nalo\n\n", 5) 44 | lexstring("[[\nalo\ralo\n\n]]", "alo\nalo\n\n", 5) 45 | lexstring("[[\nalo\ralo\r\n]]", "alo\nalo\n", 4) 46 | lexstring("[[\ralo\n\ralo\r\n]]", "alo\nalo\n", 4) 47 | lexstring("[[alo]\n]alo]]", "alo]\n]alo", 2) 48 | 49 | assert("abc\z 50 | def\z 51 | ghi\z 52 | " == 'abcdefghi') 53 | 54 | 55 | -- UTF-8 sequences 56 | assert("\u{0}\u{00000000}\x00\0" == string.char(0, 0, 0, 0)) 57 | 58 | -- limits for 1-byte sequences 59 | assert("\u{0}\u{7F}" == "\x00\z\x7F") 60 | 61 | -- limits for 2-byte sequences 62 | assert("\u{80}\u{7FF}" == "\xC2\x80\z\xDF\xBF") 63 | 64 | -- limits for 3-byte sequences 65 | assert("\u{800}\u{FFFF}" == "\xE0\xA0\x80\z\xEF\xBF\xBF") 66 | 67 | -- limits for 4-byte sequences 68 | assert("\u{10000}\u{10FFFF}" == "\xF0\x90\x80\x80\z\xF4\x8F\xBF\xBF") 69 | 70 | 71 | -- Error in escape sequences 72 | local function lexerror (s, err) 73 | local st, msg = load('return ' .. s, '') 74 | if err ~= '' then err = err .. "'" end 75 | assert(not st and string.find(msg, "near .-" .. err)) 76 | end 77 | 78 | lexerror([["abc\x"]], [[\x"]]) 79 | lexerror([["abc\x]], [[\x]]) 80 | lexerror([["\x]], [[\x]]) 81 | lexerror([["\x5"]], [[\x5"]]) 82 | lexerror([["\x5]], [[\x5]]) 83 | lexerror([["\xr"]], [[\xr]]) 84 | lexerror([["\xr]], [[\xr]]) 85 | lexerror([["\x.]], [[\x.]]) 86 | lexerror([["\x8%"]], [[\x8%%]]) 87 | lexerror([["\xAG]], [[\xAG]]) 88 | lexerror([["\g"]], [[\g]]) 89 | lexerror([["\g]], [[\g]]) 90 | lexerror([["\."]], [[\%.]]) 91 | 92 | lexerror([["\999"]], [[\999"]]) 93 | lexerror([["xyz\300"]], [[\300"]]) 94 | lexerror([[" \256"]], [[\256"]]) 95 | 96 | -- errors in UTF-8 sequences 97 | lexerror([["abc\u{110000}"]], [[abc\u{110000]]) -- too large 98 | lexerror([["abc\u11r"]], [[abc\u1]]) -- missing '{' 99 | lexerror([["abc\u"]], [[abc\u"]]) -- missing '{' 100 | lexerror([["abc\u{11r"]], [[abc\u{11r]]) -- missing '}' 101 | lexerror([["abc\u{11"]], [[abc\u{11"]]) -- missing '}' 102 | lexerror([["abc\u{11]], [[abc\u{11]]) -- missing '}' 103 | lexerror([["abc\u{r"]], [[abc\u{r]]) -- no digits 104 | 105 | -- unfinished strings 106 | lexerror("[=[alo]]", "") 107 | lexerror("[=[alo]=", "") 108 | lexerror("[=[alo]", "") 109 | lexerror("'alo", "") 110 | lexerror("'alo \\z \n\n", "") 111 | lexerror("'alo \\z", "") 112 | lexerror([['alo \98]], "") 113 | 114 | -- valid characters in variable names 115 | for i = 0, 255 do 116 | local s = string.char(i) 117 | assert(not string.find(s, "[a-zA-Z_]") == not load(s .. "=1", "")) 118 | assert(not string.find(s, "[a-zA-Z_0-9]") == 119 | not load("a" .. s .. "1 = 1", "")) 120 | end 121 | 122 | 123 | -- long variable names 124 | 125 | var1 = string.rep('a', 15000) .. '1' 126 | var2 = string.rep('a', 15000) .. '2' 127 | prog = string.format([[ 128 | %s = 5 129 | %s = %s + 1 130 | return function () return %s - %s end 131 | ]], var1, var2, var1, var1, var2) 132 | local f = dostring(prog) 133 | assert(_G[var1] == 5 and _G[var2] == 6 and f() == -1) 134 | var1, var2, f = nil 135 | print('+') 136 | 137 | -- escapes -- 138 | assert("\n\t" == [[ 139 | 140 | ]]) 141 | assert([[ 142 | 143 | $debug]] == "\n $debug") 144 | assert([[ [ ]] ~= [[ ] ]]) 145 | -- long strings -- 146 | b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789" 147 | assert(string.len(b) == 960) 148 | prog = [=[ 149 | print('+') 150 | 151 | a1 = [["this is a 'string' with several 'quotes'"]] 152 | a2 = "'quotes'" 153 | 154 | assert(string.find(a1, a2) == 34) 155 | print('+') 156 | 157 | a1 = [==[temp = [[an arbitrary value]]; ]==] 158 | assert(load(a1))() 159 | assert(temp == 'an arbitrary value') 160 | -- long strings -- 161 | b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789" 162 | assert(string.len(b) == 960) 163 | print('+') 164 | 165 | a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789 166 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 167 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 168 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 169 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 170 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 171 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 172 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 173 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 174 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 175 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 176 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 177 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 178 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 179 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 180 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 181 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 182 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 183 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 184 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 185 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 186 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 187 | 00123456789012345678901234567890123456789123456789012345678901234567890123456789 188 | ]] 189 | assert(string.len(a) == 1863) 190 | assert(string.sub(a, 1, 40) == string.sub(b, 1, 40)) 191 | x = 1 192 | ]=] 193 | 194 | print('+') 195 | x = nil 196 | dostring(prog) 197 | assert(x) 198 | 199 | prog = nil 200 | a = nil 201 | b = nil 202 | 203 | 204 | -- testing line ends 205 | prog = [[ 206 | a = 1 -- a comment 207 | b = 2 208 | 209 | 210 | x = [=[ 211 | hi 212 | ]=] 213 | y = "\ 214 | hello\r\n\ 215 | " 216 | return require"debug".getinfo(1).currentline 217 | ]] 218 | 219 | for _, n in pairs{"\n", "\r", "\n\r", "\r\n"} do 220 | local prog, nn = string.gsub(prog, "\n", n) 221 | assert(dostring(prog) == nn) 222 | assert(_G.x == "hi\n" and _G.y == "\nhello\r\n\n") 223 | end 224 | 225 | 226 | -- testing comments and strings with long brackets 227 | a = [==[]=]==] 228 | assert(a == "]=") 229 | 230 | a = [==[[===[[=[]]=][====[]]===]===]==] 231 | assert(a == "[===[[=[]]=][====[]]===]===") 232 | 233 | a = [====[[===[[=[]]=][====[]]===]===]====] 234 | assert(a == "[===[[=[]]=][====[]]===]===") 235 | 236 | a = [=[]]]]]]]]]=] 237 | assert(a == "]]]]]]]]") 238 | 239 | 240 | --[===[ 241 | x y z [==[ blu foo 242 | ]== 243 | ] 244 | ]=]==] 245 | error error]=]===] 246 | 247 | -- generate all strings of four of these chars 248 | local x = {"=", "[", "]", "\n"} 249 | local len = 4 250 | local function gen (c, n) 251 | if n==0 then coroutine.yield(c) 252 | else 253 | for _, a in pairs(x) do 254 | gen(c..a, n-1) 255 | end 256 | end 257 | end 258 | 259 | for s in coroutine.wrap(function () gen("", len) end) do 260 | assert(s == load("return [====[\n"..s.."]====]", "")()) 261 | end 262 | 263 | 264 | -- testing decimal point locale 265 | if os.setlocale("pt_BR") or os.setlocale("ptb") then 266 | assert(tonumber("3,4") == 3.4 and tonumber"3.4" == 3.4) 267 | assert(tonumber(" -.4 ") == -0.4) 268 | assert(tonumber(" +0x.41 ") == 0X0.41) 269 | assert(not load("a = (3,4)")) 270 | assert(assert(load("return 3.4"))() == 3.4) 271 | assert(assert(load("return .4,3"))() == .4) 272 | assert(assert(load("return 4."))() == 4.) 273 | assert(assert(load("return 4.+.5"))() == 4.5) 274 | 275 | assert(" 0x.1 " + " 0x,1" + "-0X.1\t" == 0x0.1) 276 | 277 | assert(tonumber"inf" == nil and tonumber"NAN" == nil) 278 | 279 | assert(assert(load(string.format("return %q", 4.51)))() == 4.51) 280 | 281 | local a,b = load("return 4.5.") 282 | assert(string.find(b, "'4%.5%.'")) 283 | 284 | assert(os.setlocale("C")) 285 | else 286 | (Message or print)( 287 | '\n >>> pt_BR locale not available: skipping decimal point tests <<<\n') 288 | end 289 | 290 | 291 | -- testing %q x line ends 292 | local s = "a string with \r and \n and \r\n and \n\r" 293 | local c = string.format("return %q", s) 294 | assert(assert(load(c))() == s) 295 | 296 | -- testing errors 297 | assert(not load"a = 'non-ending string") 298 | assert(not load"a = 'non-ending string\n'") 299 | assert(not load"a = '\\345'") 300 | assert(not load"a = [=x]") 301 | 302 | print('OK') 303 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/locals.lua: -------------------------------------------------------------------------------- 1 | -- $Id: locals.lua,v 1.37 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print('testing local variables and environments') 5 | 6 | local debug = require"debug" 7 | 8 | 9 | -- bug in 5.1: 10 | 11 | local function f(x) x = nil; return x end 12 | assert(f(10) == nil) 13 | 14 | local function f() local x; return x end 15 | assert(f(10) == nil) 16 | 17 | local function f(x) x = nil; local y; return x, y end 18 | assert(f(10) == nil and select(2, f(20)) == nil) 19 | 20 | do 21 | local i = 10 22 | do local i = 100; assert(i==100) end 23 | do local i = 1000; assert(i==1000) end 24 | assert(i == 10) 25 | if i ~= 10 then 26 | local i = 20 27 | else 28 | local i = 30 29 | assert(i == 30) 30 | end 31 | end 32 | 33 | 34 | 35 | f = nil 36 | 37 | local f 38 | x = 1 39 | 40 | a = nil 41 | load('local a = {}')() 42 | assert(a == nil) 43 | 44 | function f (a) 45 | local _1, _2, _3, _4, _5 46 | local _6, _7, _8, _9, _10 47 | local x = 3 48 | local b = a 49 | local c,d = a,b 50 | if (d == b) then 51 | local x = 'q' 52 | x = b 53 | assert(x == 2) 54 | else 55 | assert(nil) 56 | end 57 | assert(x == 3) 58 | local f = 10 59 | end 60 | 61 | local b=10 62 | local a; repeat local b; a,b=1,2; assert(a+1==b); until a+b==3 63 | 64 | 65 | assert(x == 1) 66 | 67 | f(2) 68 | assert(type(f) == 'function') 69 | 70 | 71 | local function getenv (f) 72 | local a,b = debug.getupvalue(f, 1) 73 | assert(a == '_ENV') 74 | return b 75 | end 76 | 77 | -- test for global table of loaded chunks 78 | assert(getenv(load"a=3") == _G) 79 | local c = {}; local f = load("a = 3", nil, nil, c) 80 | assert(getenv(f) == c) 81 | assert(c.a == nil) 82 | f() 83 | assert(c.a == 3) 84 | 85 | -- old test for limits for special instructions (now just a generic test) 86 | do 87 | local i = 2 88 | local p = 4 -- p == 2^i 89 | repeat 90 | for j=-3,3 do 91 | assert(load(string.format([[local a=%s; 92 | a=a+%s; 93 | assert(a ==2^%s)]], j, p-j, i), '')) () 94 | assert(load(string.format([[local a=%s; 95 | a=a-%s; 96 | assert(a==-2^%s)]], -j, p-j, i), '')) () 97 | assert(load(string.format([[local a,b=0,%s; 98 | a=b-%s; 99 | assert(a==-2^%s)]], -j, p-j, i), '')) () 100 | end 101 | p = 2 * p; i = i + 1 102 | until p <= 0 103 | end 104 | 105 | print'+' 106 | 107 | 108 | if rawget(_G, "querytab") then 109 | -- testing clearing of dead elements from tables 110 | collectgarbage("stop") -- stop GC 111 | local a = {[{}] = 4, [3] = 0, alo = 1, 112 | a1234567890123456789012345678901234567890 = 10} 113 | 114 | local t = querytab(a) 115 | 116 | for k,_ in pairs(a) do a[k] = nil end 117 | collectgarbage() -- restore GC and collect dead fiels in `a' 118 | for i=0,t-1 do 119 | local k = querytab(a, i) 120 | assert(k == nil or type(k) == 'number' or k == 'alo') 121 | end 122 | end 123 | 124 | 125 | -- testing lexical environments 126 | 127 | assert(_ENV == _G) 128 | 129 | do 130 | local dummy 131 | local _ENV = (function (...) return ... end)(_G, dummy) -- { 132 | 133 | do local _ENV = {assert=assert}; assert(true) end 134 | mt = {_G = _G} 135 | local foo,x 136 | A = false -- "declare" A 137 | do local _ENV = mt 138 | function foo (x) 139 | A = x 140 | do local _ENV = _G; A = 1000 end 141 | return function (x) return A .. x end 142 | end 143 | end 144 | assert(getenv(foo) == mt) 145 | x = foo('hi'); assert(mt.A == 'hi' and A == 1000) 146 | assert(x('*') == mt.A .. '*') 147 | 148 | do local _ENV = {assert=assert, A=10}; 149 | do local _ENV = {assert=assert, A=20}; 150 | assert(A==20);x=A 151 | end 152 | assert(A==10 and x==20) 153 | end 154 | assert(x==20) 155 | 156 | 157 | print('OK') 158 | 159 | return 5,f 160 | 161 | end -- } 162 | 163 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/main.lua: -------------------------------------------------------------------------------- 1 | #! testing special comment on first line 2 | -- $Id: main.lua,v 1.65 2016/11/07 13:11:28 roberto Exp $ 3 | -- See Copyright Notice in file all.lua 4 | 5 | -- most (all?) tests here assume a reasonable "Unix-like" shell 6 | if _port then return end 7 | 8 | -- use only "double quotes" inside shell scripts (better change to 9 | -- run on Windows) 10 | 11 | 12 | print ("testing stand-alone interpreter") 13 | 14 | assert(os.execute()) -- machine has a system command 15 | 16 | local arg = arg or _ARG 17 | 18 | local prog = os.tmpname() 19 | local otherprog = os.tmpname() 20 | local out = os.tmpname() 21 | 22 | local progname 23 | do 24 | local i = 0 25 | while arg[i] do i=i-1 end 26 | progname = arg[i+1] 27 | end 28 | print("progname: "..progname) 29 | 30 | local prepfile = function (s, p) 31 | p = p or prog 32 | io.output(p) 33 | io.write(s) 34 | assert(io.close()) 35 | end 36 | 37 | local function getoutput () 38 | io.input(out) 39 | local t = io.read("a") 40 | io.input():close() 41 | assert(os.remove(out)) 42 | return t 43 | end 44 | 45 | local function checkprogout (s) 46 | local t = getoutput() 47 | for line in string.gmatch(s, ".-\n") do 48 | assert(string.find(t, line, 1, true)) 49 | end 50 | end 51 | 52 | local function checkout (s) 53 | local t = getoutput() 54 | if s ~= t then print(string.format("'%s' - '%s'\n", s, t)) end 55 | assert(s == t) 56 | return t 57 | end 58 | 59 | 60 | local function RUN (p, ...) 61 | p = string.gsub(p, "lua", '"'..progname..'"', 1) 62 | local s = string.format(p, ...) 63 | assert(os.execute(s)) 64 | end 65 | 66 | local function NoRun (msg, p, ...) 67 | p = string.gsub(p, "lua", '"'..progname..'"', 1) 68 | local s = string.format(p, ...) 69 | s = string.format("%s 2> %s", s, out) -- will send error to 'out' 70 | assert(not os.execute(s)) 71 | assert(string.find(getoutput(), msg, 1, true)) -- check error message 72 | end 73 | 74 | RUN('lua -v') 75 | 76 | print(string.format("(temporary program file used in these tests: %s)", prog)) 77 | 78 | -- running stdin as a file 79 | prepfile"" 80 | RUN('lua - < %s > %s', prog, out) 81 | checkout("") 82 | 83 | prepfile[[ 84 | print( 85 | 1, a 86 | ) 87 | ]] 88 | RUN('lua - < %s > %s', prog, out) 89 | checkout("1\tnil\n") 90 | 91 | RUN('echo "print(10)\nprint(2)\n" | lua > %s', out) 92 | checkout("10\n2\n") 93 | 94 | 95 | -- test option '-' 96 | RUN('echo "print(arg[1])" | lua - -h > %s', out) 97 | checkout("-h\n") 98 | 99 | -- test environment variables used by Lua 100 | 101 | prepfile("print(package.path)") 102 | 103 | -- test LUA_PATH 104 | RUN('env LUA_INIT= LUA_PATH=x lua %s > %s', prog, out) 105 | checkout("x\n") 106 | 107 | -- test LUA_PATH_version 108 | RUN('env LUA_INIT= LUA_PATH_5_3=y LUA_PATH=x lua %s > %s', prog, out) 109 | checkout("y\n") 110 | 111 | -- test LUA_CPATH 112 | prepfile("print(package.cpath)") 113 | RUN('env LUA_INIT= LUA_CPATH=xuxu lua %s > %s', prog, out) 114 | checkout("xuxu\n") 115 | 116 | -- test LUA_CPATH_version 117 | RUN('env LUA_INIT= LUA_CPATH_5_3=yacc LUA_CPATH=x lua %s > %s', prog, out) 118 | checkout("yacc\n") 119 | 120 | -- test LUA_INIT (and its access to 'arg' table) 121 | prepfile("print(X)") 122 | RUN('env LUA_INIT="X=tonumber(arg[1])" lua %s 3.2 > %s', prog, out) 123 | checkout("3.2\n") 124 | 125 | -- test LUA_INIT_version 126 | prepfile("print(X)") 127 | RUN('env LUA_INIT_5_3="X=10" LUA_INIT="X=3" lua %s > %s', prog, out) 128 | checkout("10\n") 129 | 130 | -- test LUA_INIT for files 131 | prepfile("x = x or 10; print(x); x = x + 1") 132 | RUN('env LUA_INIT="@%s" lua %s > %s', prog, prog, out) 133 | checkout("10\n11\n") 134 | 135 | -- test errors in LUA_INIT 136 | NoRun('LUA_INIT:1: msg', 'env LUA_INIT="error(\'msg\')" lua') 137 | 138 | -- test option '-E' 139 | local defaultpath, defaultCpath 140 | 141 | do 142 | prepfile("print(package.path, package.cpath)") 143 | RUN('env LUA_INIT="error(10)" LUA_PATH=xxx LUA_CPATH=xxx lua -E %s > %s', 144 | prog, out) 145 | local out = getoutput() 146 | defaultpath = string.match(out, "^(.-)\t") 147 | defaultCpath = string.match(out, "\t(.-)$") 148 | end 149 | 150 | -- paths did not changed 151 | assert(not string.find(defaultpath, "xxx") and 152 | string.find(defaultpath, "lua") and 153 | not string.find(defaultCpath, "xxx") and 154 | string.find(defaultCpath, "lua")) 155 | 156 | 157 | -- test replacement of ';;' to default path 158 | local function convert (p) 159 | prepfile("print(package.path)") 160 | RUN('env LUA_PATH="%s" lua %s > %s', p, prog, out) 161 | local expected = getoutput() 162 | expected = string.sub(expected, 1, -2) -- cut final end of line 163 | assert(string.gsub(p, ";;", ";"..defaultpath..";") == expected) 164 | end 165 | 166 | convert(";") 167 | convert(";;") 168 | convert(";;;") 169 | convert(";;;;") 170 | convert(";;;;;") 171 | convert(";;a;;;bc") 172 | 173 | 174 | -- test -l over multiple libraries 175 | prepfile("print(1); a=2; return {x=15}") 176 | prepfile(("print(a); print(_G['%s'].x)"):format(prog), otherprog) 177 | RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out) 178 | checkout("1\n2\n15\n2\n15\n") 179 | 180 | -- test 'arg' table 181 | local a = [[ 182 | assert(#arg == 3 and arg[1] == 'a' and 183 | arg[2] == 'b' and arg[3] == 'c') 184 | assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == '%s') 185 | assert(arg[4] == nil and arg[-4] == nil) 186 | local a, b, c = ... 187 | assert(... == 'a' and a == 'a' and b == 'b' and c == 'c') 188 | ]] 189 | a = string.format(a, progname) 190 | prepfile(a) 191 | RUN('lua "-e " -- %s a b c', prog) -- "-e " runs an empty command 192 | 193 | -- test 'arg' availability in libraries 194 | prepfile"assert(arg)" 195 | prepfile("assert(arg)", otherprog) 196 | RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) 197 | 198 | -- test messing up the 'arg' table 199 | RUN('echo "print(...)" | lua -e "arg[1] = 100" - > %s', out) 200 | checkout("100\n") 201 | NoRun("'arg' is not a table", 'echo "" | lua -e "arg = 1" -') 202 | 203 | -- test error in 'print' 204 | RUN('echo 10 | lua -e "print=nil" -i > /dev/null 2> %s', out) 205 | assert(string.find(getoutput(), "error calling 'print'")) 206 | 207 | -- test 'debug.debug' 208 | RUN('echo "io.stderr:write(1000)\ncont" | lua -e "require\'debug\'.debug()" 2> %s', out) 209 | checkout("lua_debug> 1000lua_debug> ") 210 | 211 | -- test many arguments 212 | prepfile[[print(({...})[30])]] 213 | RUN('lua %s %s > %s', prog, string.rep(" a", 30), out) 214 | checkout("a\n") 215 | 216 | RUN([[lua "-eprint(1)" -ea=3 -e "print(a)" > %s]], out) 217 | checkout("1\n3\n") 218 | 219 | -- test iteractive mode 220 | prepfile[[ 221 | (6*2-6) -- === 222 | a = 223 | 10 224 | print(a) 225 | a]] 226 | RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) 227 | checkprogout("6\n10\n10\n\n") 228 | 229 | prepfile("a = [[b\nc\nd\ne]]\n=a") 230 | RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) 231 | checkprogout("b\nc\nd\ne\n\n") 232 | 233 | prompt = "alo" 234 | prepfile[[ -- 235 | a = 2 236 | ]] 237 | RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) 238 | local t = getoutput() 239 | assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt)) 240 | 241 | -- test for error objects 242 | prepfile[[ 243 | debug = require "debug" 244 | m = {x=0} 245 | setmetatable(m, {__tostring = function(x) 246 | return tostring(debug.getinfo(4).currentline + x.x) 247 | end}) 248 | error(m) 249 | ]] 250 | NoRun(progname .. ": 6\n", [[lua %s]], prog) 251 | 252 | prepfile("error{}") 253 | NoRun("error object is a table value", [[lua %s]], prog) 254 | 255 | 256 | -- chunk broken in many lines 257 | s = [=[ -- 258 | function f ( x ) 259 | local a = [[ 260 | xuxu 261 | ]] 262 | local b = "\ 263 | xuxu\n" 264 | if x == 11 then return 1 + 12 , 2 + 20 end --[[ test multiple returns ]] 265 | return x + 1 266 | --\\ 267 | end 268 | return( f( 100 ) ) 269 | assert( a == b ) 270 | do return f( 11 ) end ]=] 271 | s = string.gsub(s, ' ', '\n\n') -- change all spaces for newlines 272 | prepfile(s) 273 | RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) 274 | checkprogout("101\n13\t22\n\n") 275 | 276 | prepfile[[#comment in 1st line without \n at the end]] 277 | RUN('lua %s', prog) 278 | 279 | prepfile[[#test line number when file starts with comment line 280 | debug = require"debug" 281 | print(debug.getinfo(1).currentline) 282 | ]] 283 | RUN('lua %s > %s', prog, out) 284 | checkprogout('3') 285 | 286 | -- close Lua with an open file 287 | prepfile(string.format([[io.output(%q); io.write('alo')]], out)) 288 | RUN('lua %s', prog) 289 | checkout('alo') 290 | 291 | -- bug in 5.2 beta (extra \0 after version line) 292 | RUN([[lua -v -e"print'hello'" > %s]], out) 293 | t = getoutput() 294 | assert(string.find(t, "PUC%-Rio\nhello")) 295 | 296 | 297 | -- testing os.exit 298 | prepfile("os.exit(nil, true)") 299 | RUN('lua %s', prog) 300 | prepfile("os.exit(0, true)") 301 | RUN('lua %s', prog) 302 | prepfile("os.exit(true, true)") 303 | RUN('lua %s', prog) 304 | prepfile("os.exit(1, true)") 305 | NoRun("", "lua %s", prog) -- no message 306 | prepfile("os.exit(false, true)") 307 | NoRun("", "lua %s", prog) -- no message 308 | 309 | -- remove temporary files 310 | assert(os.remove(prog)) 311 | assert(os.remove(otherprog)) 312 | assert(not os.remove(out)) 313 | 314 | -- invalid options 315 | NoRun("unrecognized option '-h'", "lua -h") 316 | NoRun("unrecognized option '---'", "lua ---") 317 | NoRun("unrecognized option '-Ex'", "lua -Ex") 318 | NoRun("unrecognized option '-vv'", "lua -vv") 319 | NoRun("unrecognized option '-iv'", "lua -iv") 320 | NoRun("'-e' needs argument", "lua -e") 321 | NoRun("syntax error", "lua -e a") 322 | NoRun("'-l' needs argument", "lua -l") 323 | 324 | 325 | if T then -- auxiliary library? 326 | print("testing 'not enough memory' to create a state") 327 | NoRun("not enough memory", "env MEMLIMIT=100 lua") 328 | end 329 | print('+') 330 | 331 | print('testing Ctrl C') 332 | do 333 | -- interrupt a script 334 | local function kill (pid) 335 | return os.execute(string.format('kill -INT %d 2> /dev/null', pid)) 336 | end 337 | 338 | -- function to run a script in background, returning its output file 339 | -- descriptor and its pid 340 | local function runback (luaprg) 341 | -- shell script to run 'luaprg' in background and echo its pid 342 | local shellprg = string.format('%s -e "%s" & echo $!', progname, luaprg) 343 | local f = io.popen(shellprg, "r") -- run shell script 344 | local pid = f:read() -- get pid for Lua script 345 | print("(if test fails now, it may leave a Lua script running in \z 346 | background, pid " .. pid .. ")") 347 | return f, pid 348 | end 349 | 350 | -- Lua script that runs protected infinite loop and then prints '42' 351 | local f, pid = runback[[ 352 | pcall(function () print(12); while true do end end); print(42)]] 353 | -- wait until script is inside 'pcall' 354 | assert(f:read() == "12") 355 | kill(pid) -- send INT signal to Lua script 356 | -- check that 'pcall' captured the exception and script continued running 357 | assert(f:read() == "42") -- expected output 358 | assert(f:close()) 359 | print("done") 360 | 361 | -- Lua script in a long unbreakable search 362 | local f, pid = runback[[ 363 | print(15); string.find(string.rep('a', 100000), '.*b')]] 364 | -- wait (so script can reach the loop) 365 | assert(f:read() == "15") 366 | assert(os.execute("sleep 1")) 367 | -- must send at least two INT signals to stop this Lua script 368 | local n = 100 369 | for i = 0, 100 do -- keep sending signals 370 | if not kill(pid) then -- until it fails 371 | n = i -- number of non-failed kills 372 | break 373 | end 374 | end 375 | assert(f:close()) 376 | assert(n >= 2) 377 | print(string.format("done (with %d kills)", n)) 378 | 379 | end 380 | 381 | print("OK") 382 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/nextvar.lua: -------------------------------------------------------------------------------- 1 | -- $Id: nextvar.lua,v 1.79 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print('testing tables, next, and for') 5 | 6 | local function checkerror (msg, f, ...) 7 | local s, err = pcall(f, ...) 8 | assert(not s and string.find(err, msg)) 9 | end 10 | 11 | 12 | local a = {} 13 | 14 | -- make sure table has lots of space in hash part 15 | for i=1,100 do a[i.."+"] = true end 16 | for i=1,100 do a[i.."+"] = nil end 17 | -- fill hash part with numeric indices testing size operator 18 | for i=1,100 do 19 | a[i] = true 20 | assert(#a == i) 21 | end 22 | 23 | -- testing ipairs 24 | local x = 0 25 | for k,v in ipairs{10,20,30;x=12} do 26 | x = x + 1 27 | assert(k == x and v == x * 10) 28 | end 29 | 30 | for _ in ipairs{x=12, y=24} do assert(nil) end 31 | 32 | -- test for 'false' x ipair 33 | x = false 34 | local i = 0 35 | for k,v in ipairs{true,false,true,false} do 36 | i = i + 1 37 | x = not x 38 | assert(x == v) 39 | end 40 | assert(i == 4) 41 | 42 | -- iterator function is always the same 43 | assert(type(ipairs{}) == 'function' and ipairs{} == ipairs{}) 44 | 45 | 46 | if not T then 47 | (Message or print) 48 | ('\n >>> testC not active: skipping tests for table sizes <<<\n') 49 | else --[ 50 | -- testing table sizes 51 | 52 | local function log2 (x) return math.log(x, 2) end 53 | 54 | local function mp2 (n) -- minimum power of 2 >= n 55 | local mp = 2^math.ceil(log2(n)) 56 | assert(n == 0 or (mp/2 < n and n <= mp)) 57 | return mp 58 | end 59 | 60 | local function fb (n) 61 | local r, nn = T.int2fb(n) 62 | assert(r < 256) 63 | return nn 64 | end 65 | 66 | -- test fb function 67 | for a = 1, 10000 do -- all numbers up to 10^4 68 | local n = fb(a) 69 | assert(a <= n and n <= a*1.125) 70 | end 71 | local a = 1024 -- plus a few up to 2 ^30 72 | local lim = 2^30 73 | while a < lim do 74 | local n = fb(a) 75 | assert(a <= n and n <= a*1.125) 76 | a = math.ceil(a*1.3) 77 | end 78 | 79 | 80 | local function check (t, na, nh) 81 | local a, h = T.querytab(t) 82 | if a ~= na or h ~= nh then 83 | print(na, nh, a, h) 84 | assert(nil) 85 | end 86 | end 87 | 88 | 89 | -- testing C library sizes 90 | do 91 | local s = 0 92 | for _ in pairs(math) do s = s + 1 end 93 | check(math, 0, mp2(s)) 94 | end 95 | 96 | 97 | -- testing constructor sizes 98 | local lim = 40 99 | local s = 'return {' 100 | for i=1,lim do 101 | s = s..i..',' 102 | local s = s 103 | for k=0,lim do 104 | local t = load(s..'}', '')() 105 | assert(#t == i) 106 | check(t, fb(i), mp2(k)) 107 | s = string.format('%sa%d=%d,', s, k, k) 108 | end 109 | end 110 | 111 | 112 | -- tests with unknown number of elements 113 | local a = {} 114 | for i=1,lim do a[i] = i end -- build auxiliary table 115 | for k=0,lim do 116 | local a = {table.unpack(a,1,k)} 117 | assert(#a == k) 118 | check(a, k, 0) 119 | a = {1,2,3,table.unpack(a,1,k)} 120 | check(a, k+3, 0) 121 | assert(#a == k + 3) 122 | end 123 | 124 | 125 | -- testing tables dynamically built 126 | local lim = 130 127 | local a = {}; a[2] = 1; check(a, 0, 1) 128 | a = {}; a[0] = 1; check(a, 0, 1); a[2] = 1; check(a, 0, 2) 129 | a = {}; a[0] = 1; a[1] = 1; check(a, 1, 1) 130 | a = {} 131 | for i = 1,lim do 132 | a[i] = 1 133 | assert(#a == i) 134 | check(a, mp2(i), 0) 135 | end 136 | 137 | a = {} 138 | for i = 1,lim do 139 | a['a'..i] = 1 140 | assert(#a == 0) 141 | check(a, 0, mp2(i)) 142 | end 143 | 144 | a = {} 145 | for i=1,16 do a[i] = i end 146 | check(a, 16, 0) 147 | do 148 | for i=1,11 do a[i] = nil end 149 | for i=30,50 do a[i] = nil end -- force a rehash (?) 150 | check(a, 0, 8) -- only 5 elements in the table 151 | a[10] = 1 152 | for i=30,50 do a[i] = nil end -- force a rehash (?) 153 | check(a, 0, 8) -- only 6 elements in the table 154 | for i=1,14 do a[i] = nil end 155 | for i=18,50 do a[i] = nil end -- force a rehash (?) 156 | check(a, 0, 4) -- only 2 elements ([15] and [16]) 157 | end 158 | 159 | -- reverse filling 160 | for i=1,lim do 161 | local a = {} 162 | for i=i,1,-1 do a[i] = i end -- fill in reverse 163 | check(a, mp2(i), 0) 164 | end 165 | 166 | -- size tests for vararg 167 | lim = 35 168 | function foo (n, ...) 169 | local arg = {...} 170 | check(arg, n, 0) 171 | assert(select('#', ...) == n) 172 | arg[n+1] = true 173 | check(arg, mp2(n+1), 0) 174 | arg.x = true 175 | check(arg, mp2(n+1), 1) 176 | end 177 | local a = {} 178 | for i=1,lim do a[i] = true; foo(i, table.unpack(a)) end 179 | 180 | end --] 181 | 182 | 183 | -- test size operation on empty tables 184 | assert(#{} == 0) 185 | assert(#{nil} == 0) 186 | assert(#{nil, nil} == 0) 187 | assert(#{nil, nil, nil} == 0) 188 | assert(#{nil, nil, nil, nil} == 0) 189 | print'+' 190 | 191 | 192 | local nofind = {} 193 | 194 | a,b,c = 1,2,3 195 | a,b,c = nil 196 | 197 | 198 | -- next uses always the same iteraction function 199 | assert(next{} == next{}) 200 | 201 | local function find (name) 202 | local n,v 203 | while 1 do 204 | n,v = next(_G, n) 205 | if not n then return nofind end 206 | assert(v ~= nil) 207 | if n == name then return v end 208 | end 209 | end 210 | 211 | local function find1 (name) 212 | for n,v in pairs(_G) do 213 | if n==name then return v end 214 | end 215 | return nil -- not found 216 | end 217 | 218 | 219 | assert(print==find("print") and print == find1("print")) 220 | assert(_G["print"]==find("print")) 221 | assert(assert==find1("assert")) 222 | assert(nofind==find("return")) 223 | assert(not find1("return")) 224 | _G["ret" .. "urn"] = nil 225 | assert(nofind==find("return")) 226 | _G["xxx"] = 1 227 | assert(xxx==find("xxx")) 228 | 229 | -- invalid key to 'next' 230 | checkerror("invalid key", next, {10,20}, 3) 231 | 232 | -- both 'pairs' and 'ipairs' need an argument 233 | checkerror("bad argument", pairs) 234 | checkerror("bad argument", ipairs) 235 | 236 | print('+') 237 | 238 | a = {} 239 | for i=0,10000 do 240 | if math.fmod(i,10) ~= 0 then 241 | a['x'..i] = i 242 | end 243 | end 244 | 245 | n = {n=0} 246 | for i,v in pairs(a) do 247 | n.n = n.n+1 248 | assert(i and v and a[i] == v) 249 | end 250 | assert(n.n == 9000) 251 | a = nil 252 | 253 | do -- clear global table 254 | local a = {} 255 | for n,v in pairs(_G) do a[n]=v end 256 | for n,v in pairs(a) do 257 | if not package.loaded[n] and type(v) ~= "function" and 258 | not string.find(n, "^[%u_]") then 259 | _G[n] = nil 260 | end 261 | collectgarbage() 262 | end 263 | end 264 | 265 | 266 | -- 267 | 268 | local function checknext (a) 269 | local b = {} 270 | do local k,v = next(a); while k do b[k] = v; k,v = next(a,k) end end 271 | for k,v in pairs(b) do assert(a[k] == v) end 272 | for k,v in pairs(a) do assert(b[k] == v) end 273 | end 274 | 275 | checknext{1,x=1,y=2,z=3} 276 | checknext{1,2,x=1,y=2,z=3} 277 | checknext{1,2,3,x=1,y=2,z=3} 278 | checknext{1,2,3,4,x=1,y=2,z=3} 279 | checknext{1,2,3,4,5,x=1,y=2,z=3} 280 | 281 | assert(#{} == 0) 282 | assert(#{[-1] = 2} == 0) 283 | assert(#{1,2,3,nil,nil} == 3) 284 | for i=0,40 do 285 | local a = {} 286 | for j=1,i do a[j]=j end 287 | assert(#a == i) 288 | end 289 | 290 | -- 'maxn' is now deprecated, but it is easily defined in Lua 291 | function table.maxn (t) 292 | local max = 0 293 | for k in pairs(t) do 294 | max = (type(k) == 'number') and math.max(max, k) or max 295 | end 296 | return max 297 | end 298 | 299 | assert(table.maxn{} == 0) 300 | assert(table.maxn{["1000"] = true} == 0) 301 | assert(table.maxn{["1000"] = true, [24.5] = 3} == 24.5) 302 | assert(table.maxn{[1000] = true} == 1000) 303 | assert(table.maxn{[10] = true, [100*math.pi] = print} == 100*math.pi) 304 | 305 | table.maxn = nil 306 | 307 | -- int overflow 308 | a = {} 309 | for i=0,50 do a[2^i] = true end 310 | assert(a[#a]) 311 | 312 | print('+') 313 | 314 | 315 | -- erasing values 316 | local t = {[{1}] = 1, [{2}] = 2, [string.rep("x ", 4)] = 3, 317 | [100.3] = 4, [4] = 5} 318 | 319 | local n = 0 320 | for k, v in pairs( t ) do 321 | n = n+1 322 | assert(t[k] == v) 323 | t[k] = nil 324 | collectgarbage() 325 | assert(t[k] == nil) 326 | end 327 | assert(n == 5) 328 | 329 | 330 | local function test (a) 331 | assert(not pcall(table.insert, a, 2, 20)); 332 | table.insert(a, 10); table.insert(a, 2, 20); 333 | table.insert(a, 1, -1); table.insert(a, 40); 334 | table.insert(a, #a+1, 50) 335 | table.insert(a, 2, -2) 336 | assert(not pcall(table.insert, a, 0, 20)); 337 | assert(not pcall(table.insert, a, #a + 2, 20)); 338 | assert(table.remove(a,1) == -1) 339 | assert(table.remove(a,1) == -2) 340 | assert(table.remove(a,1) == 10) 341 | assert(table.remove(a,1) == 20) 342 | assert(table.remove(a,1) == 40) 343 | assert(table.remove(a,1) == 50) 344 | assert(table.remove(a,1) == nil) 345 | assert(table.remove(a) == nil) 346 | assert(table.remove(a, #a) == nil) 347 | end 348 | 349 | a = {n=0, [-7] = "ban"} 350 | test(a) 351 | assert(a.n == 0 and a[-7] == "ban") 352 | 353 | a = {[-7] = "ban"}; 354 | test(a) 355 | assert(a.n == nil and #a == 0 and a[-7] == "ban") 356 | 357 | a = {[-1] = "ban"} 358 | test(a) 359 | assert(#a == 0 and table.remove(a) == nil and a[-1] == "ban") 360 | 361 | a = {[0] = "ban"} 362 | assert(#a == 0 and table.remove(a) == "ban" and a[0] == nil) 363 | 364 | table.insert(a, 1, 10); table.insert(a, 1, 20); table.insert(a, 1, -1) 365 | assert(table.remove(a) == 10) 366 | assert(table.remove(a) == 20) 367 | assert(table.remove(a) == -1) 368 | assert(table.remove(a) == nil) 369 | 370 | a = {'c', 'd'} 371 | table.insert(a, 3, 'a') 372 | table.insert(a, 'b') 373 | assert(table.remove(a, 1) == 'c') 374 | assert(table.remove(a, 1) == 'd') 375 | assert(table.remove(a, 1) == 'a') 376 | assert(table.remove(a, 1) == 'b') 377 | assert(table.remove(a, 1) == nil) 378 | assert(#a == 0 and a.n == nil) 379 | 380 | a = {10,20,30,40} 381 | assert(table.remove(a, #a + 1) == nil) 382 | assert(not pcall(table.remove, a, 0)) 383 | assert(a[#a] == 40) 384 | assert(table.remove(a, #a) == 40) 385 | assert(a[#a] == 30) 386 | assert(table.remove(a, 2) == 20) 387 | assert(a[#a] == 30 and #a == 2) 388 | 389 | do -- testing table library with metamethods 390 | local function test (proxy, t) 391 | for i = 1, 10 do 392 | table.insert(proxy, 1, i) 393 | end 394 | assert(#proxy == 10 and #t == 10) 395 | for i = 1, 10 do 396 | assert(t[i] == 11 - i) 397 | end 398 | table.sort(proxy) 399 | for i = 1, 10 do 400 | assert(t[i] == i and proxy[i] == i) 401 | end 402 | assert(table.concat(proxy, ",") == "1,2,3,4,5,6,7,8,9,10") 403 | for i = 1, 8 do 404 | assert(table.remove(proxy, 1) == i) 405 | end 406 | assert(#proxy == 2 and #t == 2) 407 | local a, b, c = table.unpack(proxy) 408 | assert(a == 9 and b == 10 and c == nil) 409 | end 410 | 411 | -- all virtual 412 | local t = {} 413 | local proxy = setmetatable({}, { 414 | __len = function () return #t end, 415 | __index = t, 416 | __newindex = t, 417 | }) 418 | test(proxy, t) 419 | 420 | -- only __newindex 421 | local count = 0 422 | t = setmetatable({}, { 423 | __newindex = function (t,k,v) count = count + 1; rawset(t,k,v) end}) 424 | test(t, t) 425 | assert(count == 10) -- after first 10, all other sets are not new 426 | 427 | -- no __newindex 428 | t = setmetatable({}, { 429 | __index = function (_,k) return k + 1 end, 430 | __len = function (_) return 5 end}) 431 | assert(table.concat(t, ";") == "2;3;4;5;6") 432 | 433 | end 434 | 435 | 436 | if not T then 437 | (Message or print) 438 | ('\n >>> testC not active: skipping tests for table library on non-tables <<<\n') 439 | else --[ 440 | local debug = require'debug' 441 | local tab = {10, 20, 30} 442 | local mt = {} 443 | local u = T.newuserdata(0) 444 | checkerror("table expected", table.insert, u, 40) 445 | checkerror("table expected", table.remove, u) 446 | debug.setmetatable(u, mt) 447 | checkerror("table expected", table.insert, u, 40) 448 | checkerror("table expected", table.remove, u) 449 | mt.__index = tab 450 | checkerror("table expected", table.insert, u, 40) 451 | checkerror("table expected", table.remove, u) 452 | mt.__newindex = tab 453 | checkerror("table expected", table.insert, u, 40) 454 | checkerror("table expected", table.remove, u) 455 | mt.__len = function () return #tab end 456 | table.insert(u, 40) 457 | assert(#u == 4 and #tab == 4 and u[4] == 40 and tab[4] == 40) 458 | assert(table.remove(u) == 40) 459 | table.insert(u, 1, 50) 460 | assert(#u == 4 and #tab == 4 and u[4] == 30 and tab[1] == 50) 461 | 462 | mt.__newindex = nil 463 | mt.__len = nil 464 | local tab2 = {} 465 | local u2 = T.newuserdata(0) 466 | debug.setmetatable(u2, {__newindex = function (_, k, v) tab2[k] = v end}) 467 | table.move(u, 1, 4, 1, u2) 468 | assert(#tab2 == 4 and tab2[1] == tab[1] and tab2[4] == tab[4]) 469 | 470 | end -- ] 471 | 472 | print('+') 473 | 474 | a = {} 475 | for i=1,1000 do 476 | a[i] = i; a[i-1] = nil 477 | end 478 | assert(next(a,nil) == 1000 and next(a,1000) == nil) 479 | 480 | assert(next({}) == nil) 481 | assert(next({}, nil) == nil) 482 | 483 | for a,b in pairs{} do error"not here" end 484 | for i=1,0 do error'not here' end 485 | for i=0,1,-1 do error'not here' end 486 | a = nil; for i=1,1 do assert(not a); a=1 end; assert(a) 487 | a = nil; for i=1,1,-1 do assert(not a); a=1 end; assert(a) 488 | 489 | do 490 | print("testing floats in numeric for") 491 | local a 492 | -- integer count 493 | a = 0; for i=1, 1, 1 do a=a+1 end; assert(a==1) 494 | a = 0; for i=10000, 1e4, -1 do a=a+1 end; assert(a==1) 495 | a = 0; for i=1, 0.99999, 1 do a=a+1 end; assert(a==0) 496 | a = 0; for i=9999, 1e4, -1 do a=a+1 end; assert(a==0) 497 | a = 0; for i=1, 0.99999, -1 do a=a+1 end; assert(a==1) 498 | 499 | -- float count 500 | a = 0; for i=0, 0.999999999, 0.1 do a=a+1 end; assert(a==10) 501 | a = 0; for i=1.0, 1, 1 do a=a+1 end; assert(a==1) 502 | a = 0; for i=-1.5, -1.5, 1 do a=a+1 end; assert(a==1) 503 | a = 0; for i=1e6, 1e6, -1 do a=a+1 end; assert(a==1) 504 | a = 0; for i=1.0, 0.99999, 1 do a=a+1 end; assert(a==0) 505 | a = 0; for i=99999, 1e5, -1.0 do a=a+1 end; assert(a==0) 506 | a = 0; for i=1.0, 0.99999, -1 do a=a+1 end; assert(a==1) 507 | end 508 | 509 | -- conversion 510 | a = 0; for i="10","1","-2" do a=a+1 end; assert(a==5) 511 | 512 | do -- checking types 513 | local c 514 | local function checkfloat (i) 515 | assert(math.type(i) == "float") 516 | c = c + 1 517 | end 518 | 519 | c = 0; for i = 1.0, 10 do checkfloat(i) end 520 | assert(c == 10) 521 | 522 | c = 0; for i = -1, -10, -1.0 do checkfloat(i) end 523 | assert(c == 10) 524 | 525 | local function checkint (i) 526 | assert(math.type(i) == "integer") 527 | c = c + 1 528 | end 529 | 530 | local m = math.maxinteger 531 | c = 0; for i = m, m - 10, -1 do checkint(i) end 532 | assert(c == 11) 533 | 534 | c = 0; for i = 1, 10.9 do checkint(i) end 535 | assert(c == 10) 536 | 537 | c = 0; for i = 10, 0.001, -1 do checkint(i) end 538 | assert(c == 10) 539 | 540 | c = 0; for i = 1, "10.8" do checkint(i) end 541 | assert(c == 10) 542 | 543 | c = 0; for i = 9, "3.4", -1 do checkint(i) end 544 | assert(c == 6) 545 | 546 | c = 0; for i = 0, " -3.4 ", -1 do checkint(i) end 547 | assert(c == 4) 548 | 549 | c = 0; for i = 100, "96.3", -2 do checkint(i) end 550 | assert(c == 2) 551 | 552 | c = 0; for i = 1, math.huge do if i > 10 then break end; checkint(i) end 553 | assert(c == 10) 554 | 555 | c = 0; for i = -1, -math.huge, -1 do 556 | if i < -10 then break end; checkint(i) 557 | end 558 | assert(c == 10) 559 | 560 | 561 | for i = math.mininteger, -10e100 do assert(false) end 562 | for i = math.maxinteger, 10e100, -1 do assert(false) end 563 | 564 | end 565 | 566 | collectgarbage() 567 | 568 | 569 | -- testing generic 'for' 570 | 571 | local function f (n, p) 572 | local t = {}; for i=1,p do t[i] = i*10 end 573 | return function (_,n) 574 | if n > 0 then 575 | n = n-1 576 | return n, table.unpack(t) 577 | end 578 | end, nil, n 579 | end 580 | 581 | local x = 0 582 | for n,a,b,c,d in f(5,3) do 583 | x = x+1 584 | assert(a == 10 and b == 20 and c == 30 and d == nil) 585 | end 586 | assert(x == 5) 587 | 588 | 589 | 590 | -- testing __pairs and __ipairs metamethod 591 | a = {} 592 | do 593 | local x,y,z = pairs(a) 594 | assert(type(x) == 'function' and y == a and z == nil) 595 | end 596 | 597 | local function foo (e,i) 598 | assert(e == a) 599 | if i <= 10 then return i+1, i+2 end 600 | end 601 | 602 | local function foo1 (e,i) 603 | i = i + 1 604 | assert(e == a) 605 | if i <= e.n then return i,a[i] end 606 | end 607 | 608 | setmetatable(a, {__pairs = function (x) return foo, x, 0 end}) 609 | 610 | local i = 0 611 | for k,v in pairs(a) do 612 | i = i + 1 613 | assert(k == i and v == k+1) 614 | end 615 | 616 | a.n = 5 617 | a[3] = 30 618 | 619 | -- testing ipairs with metamethods 620 | a = {n=10} 621 | setmetatable(a, { __index = function (t,k) 622 | if k <= t.n then return k * 10 end 623 | end}) 624 | i = 0 625 | for k,v in ipairs(a) do 626 | i = i + 1 627 | assert(k == i and v == i * 10) 628 | end 629 | assert(i == a.n) 630 | 631 | print"OK" 632 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/pm.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsbenas/parser-gen/8d6311a439ae32f598eaa13880e54a5f0896e898/parsers/lua-5.3.4-tests/pm.lua -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/sort.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsbenas/parser-gen/8d6311a439ae32f598eaa13880e54a5f0896e898/parsers/lua-5.3.4-tests/sort.lua -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/strings.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsbenas/parser-gen/8d6311a439ae32f598eaa13880e54a5f0896e898/parsers/lua-5.3.4-tests/strings.lua -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/tpack.lua: -------------------------------------------------------------------------------- 1 | -- $Id: tpack.lua,v 1.13 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | local pack = string.pack 5 | local packsize = string.packsize 6 | local unpack = string.unpack 7 | 8 | print "testing pack/unpack" 9 | 10 | -- maximum size for integers 11 | local NB = 16 12 | 13 | local sizeshort = packsize("h") 14 | local sizeint = packsize("i") 15 | local sizelong = packsize("l") 16 | local sizesize_t = packsize("T") 17 | local sizeLI = packsize("j") 18 | local sizefloat = packsize("f") 19 | local sizedouble = packsize("d") 20 | local sizenumber = packsize("n") 21 | local little = (pack("i2", 1) == "\1\0") 22 | local align = packsize("!xXi16") 23 | 24 | assert(1 <= sizeshort and sizeshort <= sizeint and sizeint <= sizelong and 25 | sizefloat <= sizedouble) 26 | 27 | print("platform:") 28 | print(string.format( 29 | "\tshort %d, int %d, long %d, size_t %d, float %d, double %d,\n\z 30 | \tlua Integer %d, lua Number %d", 31 | sizeshort, sizeint, sizelong, sizesize_t, sizefloat, sizedouble, 32 | sizeLI, sizenumber)) 33 | print("\t" .. (little and "little" or "big") .. " endian") 34 | print("\talignment: " .. align) 35 | 36 | 37 | -- check errors in arguments 38 | function checkerror (msg, f, ...) 39 | local status, err = pcall(f, ...) 40 | -- print(status, err, msg) 41 | assert(not status and string.find(err, msg)) 42 | end 43 | 44 | -- minimum behavior for integer formats 45 | assert(unpack("B", pack("B", 0xff)) == 0xff) 46 | assert(unpack("b", pack("b", 0x7f)) == 0x7f) 47 | assert(unpack("b", pack("b", -0x80)) == -0x80) 48 | 49 | assert(unpack("H", pack("H", 0xffff)) == 0xffff) 50 | assert(unpack("h", pack("h", 0x7fff)) == 0x7fff) 51 | assert(unpack("h", pack("h", -0x8000)) == -0x8000) 52 | 53 | assert(unpack("L", pack("L", 0xffffffff)) == 0xffffffff) 54 | assert(unpack("l", pack("l", 0x7fffffff)) == 0x7fffffff) 55 | assert(unpack("l", pack("l", -0x80000000)) == -0x80000000) 56 | 57 | 58 | for i = 1, NB do 59 | -- small numbers with signal extension ("\xFF...") 60 | local s = string.rep("\xff", i) 61 | assert(pack("i" .. i, -1) == s) 62 | assert(packsize("i" .. i) == #s) 63 | assert(unpack("i" .. i, s) == -1) 64 | 65 | -- small unsigned number ("\0...\xAA") 66 | s = "\xAA" .. string.rep("\0", i - 1) 67 | assert(pack("I" .. i, 0xAA) == s:reverse()) 70 | assert(unpack(">I" .. i, s:reverse()) == 0xAA) 71 | end 72 | 73 | do 74 | local lnum = 0x13121110090807060504030201 75 | local s = pack("i" .. i, ("\xFF"):rep(i - sizeLI) .. s:reverse()) == -lnum) 86 | assert(unpack("i" .. i, "\1" .. ("\x00"):rep(i - 1)) 91 | end 92 | end 93 | 94 | for i = 1, sizeLI do 95 | local lstr = "\1\2\3\4\5\6\7\8\9\10\11\12\13" 96 | local lnum = 0x13121110090807060504030201 97 | local n = lnum & (~(-1 << (i * 8))) 98 | local s = string.sub(lstr, 1, i) 99 | assert(pack("i" .. i, n) == s:reverse()) 101 | assert(unpack(">i" .. i, s:reverse()) == n) 102 | end 103 | 104 | -- sign extension 105 | do 106 | local u = 0xf0 107 | for i = 1, sizeLI - 1 do 108 | assert(unpack("I"..i, "\xf0"..("\xff"):rep(i - 1)) == u) 110 | u = u * 256 + 0xff 111 | end 112 | end 113 | 114 | -- mixed endianness 115 | do 116 | assert(pack(">i2 i2", "\10\0\0\20") 118 | assert(a == 10 and b == 20) 119 | assert(pack("=i4", 2001) == pack("i4", 2001)) 120 | end 121 | 122 | print("testing invalid formats") 123 | 124 | checkerror("out of limits", pack, "i0", 0) 125 | checkerror("out of limits", pack, "i" .. NB + 1, 0) 126 | checkerror("out of limits", pack, "!" .. NB + 1, 0) 127 | checkerror("%(17%) out of limits %[1,16%]", pack, "Xi" .. NB + 1) 128 | checkerror("invalid format option 'r'", pack, "i3r", 0) 129 | checkerror("16%-byte integer", unpack, "i16", string.rep('\3', 16)) 130 | checkerror("not power of 2", pack, "!4i3", 0); 131 | checkerror("missing size", pack, "c", "") 132 | checkerror("variable%-length format", packsize, "s") 133 | checkerror("variable%-length format", packsize, "z") 134 | 135 | -- overflow in option size (error will be in digit after limit) 136 | checkerror("invalid format", packsize, "c1" .. string.rep("0", 40)) 137 | 138 | if packsize("i") == 4 then 139 | -- result would be 2^31 (2^3 repetitions of 2^28 strings) 140 | local s = string.rep("c268435456", 2^3) 141 | checkerror("too large", packsize, s) 142 | -- one less is OK 143 | s = string.rep("c268435456", 2^3 - 1) .. "c268435455" 144 | assert(packsize(s) == 0x7fffffff) 145 | end 146 | 147 | -- overflow in packing 148 | for i = 1, sizeLI - 1 do 149 | local umax = (1 << (i * 8)) - 1 150 | local max = umax >> 1 151 | local min = ~max 152 | checkerror("overflow", pack, "I" .. i, umax + 1) 155 | 156 | checkerror("overflow", pack, ">i" .. i, umax) 157 | checkerror("overflow", pack, ">i" .. i, max + 1) 158 | checkerror("overflow", pack, "i" .. i, pack(">i" .. i, max)) == max) 161 | assert(unpack("I" .. i, pack(">I" .. i, umax)) == umax) 163 | end 164 | 165 | -- Lua integer size 166 | assert(unpack(">j", pack(">j", math.maxinteger)) == math.maxinteger) 167 | assert(unpack("f", 24)) 174 | end 175 | 176 | print "testing pack/unpack of floating-point numbers" 177 | 178 | for _, n in ipairs{0, -1.1, 1.9, 1/0, -1/0, 1e20, -1e20, 0.1, 2000.7} do 179 | assert(unpack("n", pack("n", n)) == n) 180 | assert(unpack("n", pack(">n", n)) == n) 182 | assert(pack("f", n):reverse()) 183 | assert(pack(">d", n) == pack("f", pack(">f", n)) == n) 190 | assert(unpack("d", pack(">d", n)) == n) 192 | end 193 | 194 | print "testing pack/unpack of strings" 195 | do 196 | local s = string.rep("abc", 1000) 197 | assert(pack("zB", s, 247) == s .. "\0\xF7") 198 | local s1, b = unpack("zB", s .. "\0\xF9") 199 | assert(b == 249 and s1 == s) 200 | s1 = pack("s", s) 201 | assert(unpack("s", s1) == s) 202 | 203 | checkerror("does not fit", pack, "s1", s) 204 | 205 | checkerror("contains zeros", pack, "z", "alo\0"); 206 | 207 | for i = 2, NB do 208 | local s1 = pack("s" .. i, s) 209 | assert(unpack("s" .. i, s1) == s and #s1 == #s + i) 210 | end 211 | end 212 | 213 | do 214 | local x = pack("s", "alo") 215 | checkerror("too short", unpack, "s", x:sub(1, -2)) 216 | checkerror("too short", unpack, "c5", "abcd") 217 | checkerror("out of limits", pack, "s100", "alo") 218 | end 219 | 220 | do 221 | assert(pack("c0", "") == "") 222 | assert(packsize("c0") == 0) 223 | assert(unpack("c0", "") == "") 224 | assert(pack("!4 c6", "abcdef") == "abcdef") 227 | assert(pack("c3", "123") == "123") 228 | assert(pack("c0", "") == "") 229 | assert(pack("c8", "123456") == "123456\0\0") 230 | assert(pack("c88", "") == string.rep("\0", 88)) 231 | assert(pack("c188", "ab") == "ab" .. string.rep("\0", 188 - 2)) 232 | local a, b, c = unpack("!4 z c3", "abcdefghi\0xyz") 233 | assert(a == "abcdefghi" and b == "xyz" and c == 14) 234 | checkerror("longer than", pack, "c3", "1234") 235 | end 236 | 237 | 238 | -- testing multiple types and sequence 239 | do 240 | local x = pack("!8 b Xh i4 i8 c1 Xi8", -12, 100, 200, "\xEC") 251 | assert(#x == packsize(">!8 b Xh i4 i8 c1 Xi8")) 252 | assert(x == "\xf4" .. "\0\0\0" .. 253 | "\0\0\0\100" .. 254 | "\0\0\0\0\0\0\0\xC8" .. 255 | "\xEC" .. "\0\0\0\0\0\0\0") 256 | local a, b, c, d, pos = unpack(">!8 c1 Xh i4 i8 b Xi8 XI XH", x) 257 | assert(a == "\xF4" and b == 100 and c == 200 and d == -20 and (pos - 1) == #x) 258 | 259 | x = pack(">!4 c3 c4 c2 z i4 c5 c2 Xi4", 260 | "abc", "abcd", "xz", "hello", 5, "world", "xy") 261 | assert(x == "abcabcdxzhello\0\0\0\0\0\5worldxy\0") 262 | local a, b, c, d, e, f, g, pos = unpack(">!4 c3 c4 c2 z i4 c5 c2 Xh Xi4", x) 263 | assert(a == "abc" and b == "abcd" and c == "xz" and d == "hello" and 264 | e == 5 and f == "world" and g == "xy" and (pos - 1) % 4 == 0) 265 | 266 | x = pack(" b b Xd b Xb x", 1, 2, 3) 267 | assert(packsize(" b b Xd b Xb x") == 4) 268 | assert(x == "\1\2\3\0") 269 | a, b, c, pos = unpack("bbXdb", x) 270 | assert(a == 1 and b == 2 and c == 3 and pos == #x) 271 | 272 | -- only alignment 273 | assert(packsize("!8 xXi8") == 8) 274 | local pos = unpack("!8 xXi8", "0123456701234567"); assert(pos == 9) 275 | assert(packsize("!8 xXi2") == 2) 276 | local pos = unpack("!8 xXi2", "0123456701234567"); assert(pos == 3) 277 | assert(packsize("!2 xXi2") == 2) 278 | local pos = unpack("!2 xXi2", "0123456701234567"); assert(pos == 3) 279 | assert(packsize("!2 xXi8") == 2) 280 | local pos = unpack("!2 xXi8", "0123456701234567"); assert(pos == 3) 281 | assert(packsize("!16 xXi16") == 16) 282 | local pos = unpack("!16 xXi16", "0123456701234567"); assert(pos == 17) 283 | 284 | checkerror("invalid next option", pack, "X") 285 | checkerror("invalid next option", unpack, "XXi", "") 286 | checkerror("invalid next option", unpack, "X i", "") 287 | checkerror("invalid next option", pack, "Xc1") 288 | end 289 | 290 | do -- testing initial position 291 | local x = pack("i4i4i4i4", 1, 2, 3, 4) 292 | for pos = 1, 16, 4 do 293 | local i, p = unpack("i4", x, pos) 294 | assert(i == pos//4 + 1 and p == pos + 4) 295 | end 296 | 297 | -- with alignment 298 | for pos = 0, 12 do -- will always round position to power of 2 299 | local i, p = unpack("!4 i4", x, pos + 1) 300 | assert(i == (pos + 3)//4 + 1 and p == i*4 + 1) 301 | end 302 | 303 | -- negative indices 304 | local i, p = unpack("!4 i4", x, -4) 305 | assert(i == 4 and p == 17) 306 | local i, p = unpack("!4 i4", x, -7) 307 | assert(i == 4 and p == 17) 308 | local i, p = unpack("!4 i4", x, -#x) 309 | assert(i == 1 and p == 5) 310 | 311 | -- limits 312 | for i = 1, #x + 1 do 313 | assert(unpack("c0", x, i) == "") 314 | end 315 | checkerror("out of string", unpack, "c0", x, 0) 316 | checkerror("out of string", unpack, "c0", x, #x + 2) 317 | checkerror("out of string", unpack, "c0", x, -(#x + 1)) 318 | 319 | end 320 | 321 | print "OK" 322 | 323 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/utf8.lua: -------------------------------------------------------------------------------- 1 | -- $Id: utf8.lua,v 1.12 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print "testing UTF-8 library" 5 | 6 | local utf8 = require'utf8' 7 | 8 | 9 | local function checkerror (msg, f, ...) 10 | local s, err = pcall(f, ...) 11 | assert(not s and string.find(err, msg)) 12 | end 13 | 14 | 15 | local function len (s) 16 | return #string.gsub(s, "[\x80-\xBF]", "") 17 | end 18 | 19 | 20 | local justone = "^" .. utf8.charpattern .. "$" 21 | 22 | -- 't' is the list of codepoints of 's' 23 | local function checksyntax (s, t) 24 | local ts = {"return '"} 25 | for i = 1, #t do ts[i + 1] = string.format("\\u{%x}", t[i]) end 26 | ts[#t + 2] = "'" 27 | ts = table.concat(ts) 28 | assert(assert(load(ts))() == s) 29 | end 30 | 31 | assert(utf8.offset("alo", 5) == nil) 32 | assert(utf8.offset("alo", -4) == nil) 33 | 34 | -- 't' is the list of codepoints of 's' 35 | local function check (s, t) 36 | local l = utf8.len(s) 37 | assert(#t == l and len(s) == l) 38 | assert(utf8.char(table.unpack(t)) == s) 39 | 40 | assert(utf8.offset(s, 0) == 1) 41 | 42 | checksyntax(s, t) 43 | 44 | local t1 = {utf8.codepoint(s, 1, -1)} 45 | assert(#t == #t1) 46 | for i = 1, #t do assert(t[i] == t1[i]) end 47 | 48 | for i = 1, l do 49 | local pi = utf8.offset(s, i) -- position of i-th char 50 | local pi1 = utf8.offset(s, 2, pi) -- position of next char 51 | assert(string.find(string.sub(s, pi, pi1 - 1), justone)) 52 | assert(utf8.offset(s, -1, pi1) == pi) 53 | assert(utf8.offset(s, i - l - 1) == pi) 54 | assert(pi1 - pi == #utf8.char(utf8.codepoint(s, pi))) 55 | for j = pi, pi1 - 1 do 56 | assert(utf8.offset(s, 0, j) == pi) 57 | end 58 | for j = pi + 1, pi1 - 1 do 59 | assert(not utf8.len(s, j)) 60 | end 61 | assert(utf8.len(s, pi, pi) == 1) 62 | assert(utf8.len(s, pi, pi1 - 1) == 1) 63 | assert(utf8.len(s, pi) == l - i + 1) 64 | assert(utf8.len(s, pi1) == l - i) 65 | assert(utf8.len(s, 1, pi) == i) 66 | end 67 | 68 | local i = 0 69 | for p, c in utf8.codes(s) do 70 | i = i + 1 71 | assert(c == t[i] and p == utf8.offset(s, i)) 72 | assert(utf8.codepoint(s, p) == c) 73 | end 74 | assert(i == #t) 75 | 76 | i = 0 77 | for p, c in utf8.codes(s) do 78 | i = i + 1 79 | assert(c == t[i] and p == utf8.offset(s, i)) 80 | end 81 | assert(i == #t) 82 | 83 | i = 0 84 | for c in string.gmatch(s, utf8.charpattern) do 85 | i = i + 1 86 | assert(c == utf8.char(t[i])) 87 | end 88 | assert(i == #t) 89 | 90 | for i = 1, l do 91 | assert(utf8.offset(s, i) == utf8.offset(s, i - l - 1, #s + 1)) 92 | end 93 | 94 | end 95 | 96 | 97 | do -- error indication in utf8.len 98 | local function check (s, p) 99 | local a, b = utf8.len(s) 100 | assert(not a and b == p) 101 | end 102 | check("abc\xE3def", 4) 103 | check("汉字\x80", #("汉字") + 1) 104 | check("\xF4\x9F\xBF", 1) 105 | check("\xF4\x9F\xBF\xBF", 1) 106 | end 107 | 108 | -- error in utf8.codes 109 | checkerror("invalid UTF%-8 code", 110 | function () 111 | local s = "ab\xff" 112 | for c in utf8.codes(s) do assert(c) end 113 | end) 114 | 115 | 116 | -- error in initial position for offset 117 | checkerror("position out of range", utf8.offset, "abc", 1, 5) 118 | checkerror("position out of range", utf8.offset, "abc", 1, -4) 119 | checkerror("position out of range", utf8.offset, "", 1, 2) 120 | checkerror("position out of range", utf8.offset, "", 1, -1) 121 | checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) 122 | checkerror("continuation byte", utf8.offset, "𦧺", 1, 2) 123 | checkerror("continuation byte", utf8.offset, "\x80", 1) 124 | 125 | 126 | 127 | local s = "hello World" 128 | local t = {string.byte(s, 1, -1)} 129 | for i = 1, utf8.len(s) do assert(t[i] == string.byte(s, i)) end 130 | check(s, t) 131 | 132 | check("汉字/漢字", {27721, 23383, 47, 28450, 23383,}) 133 | 134 | do 135 | local s = "áéí\128" 136 | local t = {utf8.codepoint(s,1,#s - 1)} 137 | assert(#t == 3 and t[1] == 225 and t[2] == 233 and t[3] == 237) 138 | checkerror("invalid UTF%-8 code", utf8.codepoint, s, 1, #s) 139 | checkerror("out of range", utf8.codepoint, s, #s + 1) 140 | t = {utf8.codepoint(s, 4, 3)} 141 | assert(#t == 0) 142 | checkerror("out of range", utf8.codepoint, s, -(#s + 1), 1) 143 | checkerror("out of range", utf8.codepoint, s, 1, #s + 1) 144 | end 145 | 146 | assert(utf8.char() == "") 147 | assert(utf8.char(97, 98, 99) == "abc") 148 | 149 | assert(utf8.codepoint(utf8.char(0x10FFFF)) == 0x10FFFF) 150 | 151 | checkerror("value out of range", utf8.char, 0x10FFFF + 1) 152 | 153 | local function invalid (s) 154 | checkerror("invalid UTF%-8 code", utf8.codepoint, s) 155 | assert(not utf8.len(s)) 156 | end 157 | 158 | -- UTF-8 representation for 0x11ffff (value out of valid range) 159 | invalid("\xF4\x9F\xBF\xBF") 160 | 161 | -- overlong sequences 162 | invalid("\xC0\x80") -- zero 163 | invalid("\xC1\xBF") -- 0x7F (should be coded in 1 byte) 164 | invalid("\xE0\x9F\xBF") -- 0x7FF (should be coded in 2 bytes) 165 | invalid("\xF0\x8F\xBF\xBF") -- 0xFFFF (should be coded in 3 bytes) 166 | 167 | 168 | -- invalid bytes 169 | invalid("\x80") -- continuation byte 170 | invalid("\xBF") -- continuation byte 171 | invalid("\xFE") -- invalid byte 172 | invalid("\xFF") -- invalid byte 173 | 174 | 175 | -- empty string 176 | check("", {}) 177 | 178 | -- minimum and maximum values for each sequence size 179 | s = "\0 \x7F\z 180 | \xC2\x80 \xDF\xBF\z 181 | \xE0\xA0\x80 \xEF\xBF\xBF\z 182 | \xF0\x90\x80\x80 \xF4\x8F\xBF\xBF" 183 | s = string.gsub(s, " ", "") 184 | check(s, {0,0x7F, 0x80,0x7FF, 0x800,0xFFFF, 0x10000,0x10FFFF}) 185 | 186 | x = "日本語a-4\0éó" 187 | check(x, {26085, 26412, 35486, 97, 45, 52, 0, 233, 243}) 188 | 189 | 190 | -- Supplementary Characters 191 | check("𣲷𠜎𠱓𡁻𠵼ab𠺢", 192 | {0x23CB7, 0x2070E, 0x20C53, 0x2107B, 0x20D7C, 0x61, 0x62, 0x20EA2,}) 193 | 194 | check("𨳊𩶘𦧺𨳒𥄫𤓓\xF4\x8F\xBF\xBF", 195 | {0x28CCA, 0x29D98, 0x269FA, 0x28CD2, 0x2512B, 0x244D3, 0x10ffff}) 196 | 197 | 198 | local i = 0 199 | for p, c in string.gmatch(x, "()(" .. utf8.charpattern .. ")") do 200 | i = i + 1 201 | assert(utf8.offset(x, i) == p) 202 | assert(utf8.len(x, p) == utf8.len(x) - i + 1) 203 | assert(utf8.len(c) == 1) 204 | for j = 1, #c - 1 do 205 | assert(utf8.offset(x, 0, p + j - 1) == p) 206 | end 207 | end 208 | 209 | print'ok' 210 | 211 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/vararg.lua: -------------------------------------------------------------------------------- 1 | -- $Id: vararg.lua,v 1.25 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print('testing vararg') 5 | 6 | function f(a, ...) 7 | local arg = {n = select('#', ...), ...} 8 | for i=1,arg.n do assert(a[i]==arg[i]) end 9 | return arg.n 10 | end 11 | 12 | function c12 (...) 13 | assert(arg == _G.arg) -- no local 'arg' 14 | local x = {...}; x.n = #x 15 | local res = (x.n==2 and x[1] == 1 and x[2] == 2) 16 | if res then res = 55 end 17 | return res, 2 18 | end 19 | 20 | function vararg (...) return {n = select('#', ...), ...} end 21 | 22 | local call = function (f, args) return f(table.unpack(args, 1, args.n)) end 23 | 24 | assert(f() == 0) 25 | assert(f({1,2,3}, 1, 2, 3) == 3) 26 | assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5) 27 | 28 | assert(c12(1,2)==55) 29 | a,b = assert(call(c12, {1,2})) 30 | assert(a == 55 and b == 2) 31 | a = call(c12, {1,2;n=2}) 32 | assert(a == 55 and b == 2) 33 | a = call(c12, {1,2;n=1}) 34 | assert(not a) 35 | assert(c12(1,2,3) == false) 36 | local a = vararg(call(next, {_G,nil;n=2})) 37 | local b,c = next(_G) 38 | assert(a[1] == b and a[2] == c and a.n == 2) 39 | a = vararg(call(call, {c12, {1,2}})) 40 | assert(a.n == 2 and a[1] == 55 and a[2] == 2) 41 | a = call(print, {'+'}) 42 | assert(a == nil) 43 | 44 | local t = {1, 10} 45 | function t:f (...) local arg = {...}; return self[...]+#arg end 46 | assert(t:f(1,4) == 3 and t:f(2) == 11) 47 | print('+') 48 | 49 | lim = 20 50 | local i, a = 1, {} 51 | while i <= lim do a[i] = i+0.3; i=i+1 end 52 | 53 | function f(a, b, c, d, ...) 54 | local more = {...} 55 | assert(a == 1.3 and more[1] == 5.3 and 56 | more[lim-4] == lim+0.3 and not more[lim-3]) 57 | end 58 | 59 | function g(a,b,c) 60 | assert(a == 1.3 and b == 2.3 and c == 3.3) 61 | end 62 | 63 | call(f, a) 64 | call(g, a) 65 | 66 | a = {} 67 | i = 1 68 | while i <= lim do a[i] = i; i=i+1 end 69 | assert(call(math.max, a) == lim) 70 | 71 | print("+") 72 | 73 | 74 | -- new-style varargs 75 | 76 | function oneless (a, ...) return ... end 77 | 78 | function f (n, a, ...) 79 | local b 80 | assert(arg == _G.arg) -- no local 'arg' 81 | if n == 0 then 82 | local b, c, d = ... 83 | return a, b, c, d, oneless(oneless(oneless(...))) 84 | else 85 | n, b, a = n-1, ..., a 86 | assert(b == ...) 87 | return f(n, a, ...) 88 | end 89 | end 90 | 91 | a,b,c,d,e = assert(f(10,5,4,3,2,1)) 92 | assert(a==5 and b==4 and c==3 and d==2 and e==1) 93 | 94 | a,b,c,d,e = f(4) 95 | assert(a==nil and b==nil and c==nil and d==nil and e==nil) 96 | 97 | 98 | -- varargs for main chunks 99 | f = load[[ return {...} ]] 100 | x = f(2,3) 101 | assert(x[1] == 2 and x[2] == 3 and x[3] == nil) 102 | 103 | 104 | f = load[[ 105 | local x = {...} 106 | for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end 107 | assert(x[select('#', ...)+1] == nil) 108 | return true 109 | ]] 110 | 111 | assert(f("a", "b", nil, {}, assert)) 112 | assert(f()) 113 | 114 | a = {select(3, table.unpack{10,20,30,40})} 115 | assert(#a == 2 and a[1] == 30 and a[2] == 40) 116 | a = {select(1)} 117 | assert(next(a) == nil) 118 | a = {select(-1, 3, 5, 7)} 119 | assert(a[1] == 7 and a[2] == nil) 120 | a = {select(-2, 3, 5, 7)} 121 | assert(a[1] == 5 and a[2] == 7 and a[3] == nil) 122 | pcall(select, 10000) 123 | pcall(select, -10000) 124 | 125 | 126 | -- bug in 5.2.2 127 | 128 | function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 129 | p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, 130 | p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, 131 | p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, 132 | p41, p42, p43, p44, p45, p46, p48, p49, p50, ...) 133 | local a1,a2,a3,a4,a5,a6,a7 134 | local a8,a9,a10,a11,a12,a13,a14 135 | end 136 | 137 | -- assertion fail here 138 | f() 139 | 140 | 141 | print('OK') 142 | 143 | -------------------------------------------------------------------------------- /parsers/lua-5.3.4-tests/verybig.lua: -------------------------------------------------------------------------------- 1 | -- $Id: verybig.lua,v 1.25 2016/11/07 13:11:28 roberto Exp $ 2 | -- See Copyright Notice in file all.lua 3 | 4 | print "testing RK" 5 | 6 | -- testing opcodes with RK arguments larger than K limit 7 | local function foo () 8 | local dummy = { 9 | -- fill first 256 entries in table of constants 10 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 11 | 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 12 | 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 13 | 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 14 | 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 15 | 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 16 | 97, 98, 99, 100, 101, 102, 103, 104, 17 | 105, 106, 107, 108, 109, 110, 111, 112, 18 | 113, 114, 115, 116, 117, 118, 119, 120, 19 | 121, 122, 123, 124, 125, 126, 127, 128, 20 | 129, 130, 131, 132, 133, 134, 135, 136, 21 | 137, 138, 139, 140, 141, 142, 143, 144, 22 | 145, 146, 147, 148, 149, 150, 151, 152, 23 | 153, 154, 155, 156, 157, 158, 159, 160, 24 | 161, 162, 163, 164, 165, 166, 167, 168, 25 | 169, 170, 171, 172, 173, 174, 175, 176, 26 | 177, 178, 179, 180, 181, 182, 183, 184, 27 | 185, 186, 187, 188, 189, 190, 191, 192, 28 | 193, 194, 195, 196, 197, 198, 199, 200, 29 | 201, 202, 203, 204, 205, 206, 207, 208, 30 | 209, 210, 211, 212, 213, 214, 215, 216, 31 | 217, 218, 219, 220, 221, 222, 223, 224, 32 | 225, 226, 227, 228, 229, 230, 231, 232, 33 | 233, 234, 235, 236, 237, 238, 239, 240, 34 | 241, 242, 243, 244, 245, 246, 247, 248, 35 | 249, 250, 251, 252, 253, 254, 255, 256, 36 | } 37 | assert(24.5 + 0.6 == 25.1) 38 | local t = {foo = function (self, x) return x + self.x end, x = 10} 39 | t.t = t 40 | assert(t:foo(1.5) == 11.5) 41 | assert(t.t:foo(0.5) == 10.5) -- bug in 5.2 alpha 42 | assert(24.3 == 24.3) 43 | assert((function () return t.x end)() == 10) 44 | end 45 | 46 | 47 | foo() 48 | foo = nil 49 | 50 | if _soft then return 10 end 51 | 52 | print "testing large programs (>64k)" 53 | 54 | -- template to create a very big test file 55 | prog = [[$ 56 | 57 | local a,b 58 | 59 | b = {$1$ 60 | b30009 = 65534, 61 | b30010 = 65535, 62 | b30011 = 65536, 63 | b30012 = 65537, 64 | b30013 = 16777214, 65 | b30014 = 16777215, 66 | b30015 = 16777216, 67 | b30016 = 16777217, 68 | b30017 = 0x7fffff, 69 | b30018 = -0x7fffff, 70 | b30019 = 0x1ffffff, 71 | b30020 = -0x1ffffd, 72 | b30021 = -65534, 73 | b30022 = -65535, 74 | b30023 = -65536, 75 | b30024 = -0xffffff, 76 | b30025 = 15012.5, 77 | $2$ 78 | }; 79 | 80 | assert(b.a50008 == 25004 and b["a11"] == -5.5) 81 | assert(b.a33007 == -16503.5 and b.a50009 == -25004.5) 82 | assert(b["b"..30024] == -0xffffff) 83 | 84 | function b:xxx (a,b) return a+b end 85 | assert(b:xxx(10, 12) == 22) -- pushself with non-constant index 86 | b.xxx = nil 87 | 88 | s = 0; n=0 89 | for a,b in pairs(b) do s=s+b; n=n+1 end 90 | -- with 32-bit floats, exact value of 's' depends on summation order 91 | assert(81800000.0 < s and s < 81860000 and n == 70001) 92 | 93 | a = nil; b = nil 94 | print'+' 95 | 96 | function f(x) b=x end 97 | 98 | a = f{$3$} or 10 99 | 100 | assert(a==10) 101 | assert(b[1] == "a10" and b[2] == 5 and b[#b-1] == "a50009") 102 | 103 | 104 | function xxxx (x) return b[x] end 105 | 106 | assert(xxxx(3) == "a11") 107 | 108 | a = nil; b=nil 109 | xxxx = nil 110 | 111 | return 10 112 | 113 | ]] 114 | 115 | -- functions to fill in the $n$ 116 | 117 | local function sig (x) 118 | return (x % 2 == 0) and '' or '-' 119 | end 120 | 121 | F = { 122 | function () -- $1$ 123 | for i=10,50009 do 124 | io.write('a', i, ' = ', sig(i), 5+((i-10)/2), ',\n') 125 | end 126 | end, 127 | 128 | function () -- $2$ 129 | for i=30026,50009 do 130 | io.write('b', i, ' = ', sig(i), 15013+((i-30026)/2), ',\n') 131 | end 132 | end, 133 | 134 | function () -- $3$ 135 | for i=10,50009 do 136 | io.write('"a', i, '", ', sig(i), 5+((i-10)/2), ',\n') 137 | end 138 | end, 139 | } 140 | 141 | file = os.tmpname() 142 | io.output(file) 143 | for s in string.gmatch(prog, "$([^$]+)") do 144 | local n = tonumber(s) 145 | if not n then io.write(s) else F[n]() end 146 | end 147 | io.close() 148 | result = dofile(file) 149 | assert(os.remove(file)) 150 | print'OK' 151 | return result 152 | 153 | -------------------------------------------------------------------------------- /parsers/lua-parser.lua: -------------------------------------------------------------------------------- 1 | --[==[ 2 | Parser for Lua 5.3 3 | Based on https://github.com/antlr/grammars-v4/blob/master/lua/Lua.g4 and https://github.com/andremm/lua-parser/blob/master/lua-parser/parser.lua 4 | ]==] 5 | package.path = package.path .. ";../?.lua" 6 | local pg = require "parser-gen" 7 | function equals(s,i,a,b) return #a == #b end 8 | function fixexp (...) 9 | local exp = {...} 10 | local len = #exp 11 | if len > 1 then 12 | exp.rule = "exp" 13 | exp[len].rule = "exp" 14 | return exp 15 | elseif exp[1] then 16 | if exp[1].rule == "expTokens" then 17 | return exp[1] 18 | else 19 | return exp[1][1] 20 | end 21 | end 22 | end 23 | function fold (...) 24 | local exp = {...} 25 | local len = #exp 26 | if len > 1 then 27 | local folded = { rule = "exp", fixexp(exp[1]) } 28 | for i = 2, len, 2 do 29 | folded = { rule = "exp", folded, exp[i], fixexp(exp[i+1]) } 30 | end 31 | return folded 32 | elseif exp[1] then 33 | return exp[1][1] 34 | end 35 | end 36 | -- from https://github.com/andremm/lua-parser/blob/master/lua-parser/parser.lua 37 | local labels = { 38 | ErrExtra="unexpected character(s), expected EOF", 39 | ErrInvalidStat={"unexpected token, invalid start of statement",[[ (!%nl .)* ]]}, 40 | 41 | ErrEndIf="expected 'end' to close the if statement", 42 | ErrExprIf="expected a condition after 'if'", 43 | ErrThenIf="expected 'then' after the condition", 44 | ErrExprEIf="expected a condition after 'elseif'", 45 | ErrThenEIf="expected 'then' after the condition", 46 | 47 | ErrEndDo="expected 'end' to close the do block", 48 | ErrExprWhile="expected a condition after 'while'", 49 | ErrDoWhile="expected 'do' after the condition", 50 | ErrEndWhile="expected 'end' to close the while loop", 51 | ErrUntilRep="expected 'until' at the end of the repeat loop", 52 | ErrExprRep="expected a conditions after 'until'", 53 | 54 | ErrForRange="expected a numeric or generic range after 'for'", 55 | ErrEndFor="expected 'end' to close the for loop", 56 | ErrExprFor1="expected a starting expression for the numeric range", 57 | ErrCommaFor="expected ',' to split the start and end of the range", 58 | ErrExprFor2="expected an ending expression for the numeric range", 59 | ErrExprFor3={"expected a step expression for the numeric range after ','",[[ (!'do' !%nl .)* ]]}, 60 | ErrInFor="expected '=' or 'in' after the variable(s)", 61 | ErrEListFor="expected one or more expressions after 'in'", 62 | ErrDoFor="expected 'do' after the range of the for loop", 63 | 64 | ErrDefLocal="expected a function definition or assignment after local", 65 | ErrNameLFunc="expected a function name after 'function'", 66 | ErrEListLAssign="expected one or more expressions after '='", 67 | ErrEListAssign="expected one or more expressions after '='", 68 | 69 | ErrFuncName="expected a function name after 'function'", 70 | ErrNameFunc1="expected a function name after '.'", 71 | ErrNameFunc2="expected a method name after ':'", 72 | ErrOParenPList="expected '(' for the parameter list", 73 | ErrCParenPList="expected ')' to close the parameter list", 74 | ErrEndFunc="expected 'end' to close the function body", 75 | ErrParList="expected a variable name or '...' after ','", 76 | 77 | ErrLabel="expected a label name after '::'", 78 | ErrCloseLabel="expected '::' after the label", 79 | ErrGoto="expected a label after 'goto'", 80 | 81 | ErrVarList={"expected a variable name after ','",[[ (!'=' !%nl .)* ]]}, 82 | ErrExprList="expected an expression after ','", 83 | 84 | ErrOrExpr="expected an expression after 'or'", 85 | ErrAndExpr="expected an expression after 'and'", 86 | ErrRelExpr="expected an expression after the relational operator", 87 | 88 | ErrBitwiseExpr="expected an expression after bitwise operator", 89 | 90 | ErrConcatExpr="expected an expression after '..'", 91 | ErrAddExpr="expected an expression after the additive operator", 92 | ErrMulExpr="expected an expression after the multiplicative operator", 93 | ErrUnaryExpr="expected an expression after the unary operator", 94 | ErrPowExpr="expected an expression after '^'", 95 | 96 | ErrExprParen="expected an expression after '('", 97 | ErrCParenExpr="expected ')' to close the expression", 98 | ErrNameIndex="expected a field name after '.'", 99 | ErrExprIndex="expected an expression after '['", 100 | ErrCBracketIndex="expected ']' to close the indexing expression", 101 | ErrNameMeth="expected a method name after ':'", 102 | ErrMethArgs="expected some arguments for the method call (or '()')", 103 | 104 | 105 | ErrCParenArgs="expected ')' to close the argument list", 106 | 107 | ErrCBraceTable="expected '}' to close the table constructor", 108 | ErrEqField="expected '=' after the table key", 109 | ErrExprField="expected an expression after '='", 110 | ErrExprFKey={"expected an expression after '[' for the table key",[[ (!']' !%nl .)* ]] }, 111 | ErrCBracketFKey={"expected ']' to close the table key",[[ (!'=' !%nl .)* ]]}, 112 | 113 | ErrDigitHex="expected one or more hexadecimal digits after '0x'", 114 | ErrDigitDeci="expected one or more digits after the decimal point", 115 | ErrDigitExpo="expected one or more digits for the exponent", 116 | 117 | ErrQuote="unclosed string", 118 | ErrHexEsc={"expected exactly two hexadecimal digits after '\\x'",[[ (!('"' / "'" / %nl) .)* ]]}, 119 | ErrOBraceUEsc="expected '{' after '\\u'", 120 | ErrDigitUEsc={"expected one or more hexadecimal digits for the UTF-8 code point",[[ (!'}' !%nl .)* ]]}, 121 | ErrCBraceUEsc={"expected '}' after the code point",[[ (!('"' / "'") .)* ]]}, 122 | ErrEscSeq={"invalid escape sequence",[[ (!('"' / "'" / %nl) .)* ]]}, 123 | ErrCloseLStr="unclosed long string", 124 | ErrEqAssign="expected '=' after variable list in assign statement" 125 | } 126 | pg.setlabels(labels) 127 | local grammar = pg.compile([==[ 128 | chunk <- block (!.)^ErrExtra 129 | block <- stat* retstat? 130 | stat <- ';' / 131 | functioncall / 132 | varlist '='^ErrEqAssign explist^ErrEListAssign / 133 | 'break' / 134 | 'goto' NAME^ErrGoto / 135 | 'do' block 'end'^ErrEndDo / 136 | 'while' exp^ErrExprWhile 'do'^ErrDoWhile block 'end'^ErrEndWhile / 137 | 'repeat' block 'until'^ErrUntilRep exp^ErrExprRep / 138 | 'if' exp^ErrExprIf 'then'^ErrThenIf block ('elseif' exp^ErrExprEIf 'then'^ErrThenEIf block)* ('else' block)? 'end'^ErrEndIf / 139 | 'for' (forNum / forIn)^ErrForRange 'do'^ErrDoFor block 'end'^ErrEndFor / 140 | 141 | 'function' funcname^ErrFuncName funcbody / 142 | 'local' (localAssign / localFunc)^ErrDefLocal / 143 | label / 144 | !blockEnd %{ErrInvalidStat} 145 | blockEnd <- 'return' / 'end' / 'elseif' / 'else' / 'until' / !. 146 | retstat <- 'return' explist? ';'? 147 | forNum <- NAME '=' exp^ErrExprFor1 ','^ErrCommaFor exp^ErrExprFor2 (',' exp^ErrExprFor3)? 148 | forIn <- namelist 'in'^ErrInFor explist^ErrEListFor 149 | localFunc <- 'function' NAME^ErrNameLFunc funcbody 150 | localAssign <- namelist ('=' explist^ErrEListLAssign)? 151 | label <- '::' NAME^ErrLabel '::'^ErrCloseLabel 152 | funcname <- NAME ('.' NAME^ErrNameFunc1)* (':' NAME^ErrNameFunc2)? 153 | varlist <- var (',' var^ErrVarList)* 154 | namelist <- NAME (',' NAME)* 155 | explist <- exp (',' exp^ErrExprList )* 156 | 157 | exp <- expOR -> fixexp 158 | expOR <- (expAND (operatorOr expAND^ErrOrExpr)*) -> fold 159 | expAND <- (expREL (operatorAnd expREL^ErrAndExpr)*) -> fold 160 | expREL <- (expBIT (operatorComparison expBIT^ErrRelExpr)*) -> fold 161 | expBIT <- (expCAT (operatorBitwise expCAT^ErrBitwiseExpr)*) -> fold 162 | expCAT <- (expADD (operatorStrcat expCAT^ErrConcatExpr)?) -> fixexp 163 | expADD <- (expMUL (operatorAddSub expMUL^ErrAddExpr)*) -> fold 164 | expMUL <- (expUNA (operatorMulDivMod expUNA^ErrMulExpr)*) -> fold 165 | expUNA <- ((operatorUnary expUNA^ErrUnaryExpr) / expPOW) -> fixexp 166 | expPOW <- (expTokens (operatorPower expUNA^ErrPowExpr)?) -> fixexp 167 | 168 | expTokens <- 'nil' / 'false' / 'true' / 169 | number / 170 | string / 171 | '...' / 172 | 'function' funcbody / 173 | tableconstructor / 174 | prefixexp 175 | 176 | prefixexp <- varOrExp nameAndArgs* 177 | functioncall <- varOrExp nameAndArgs+ 178 | varOrExp <- var / brackexp 179 | brackexp <- '(' exp^ErrExprParen ')'^ErrCParenExpr 180 | var <- (NAME / brackexp varSuffix) varSuffix* 181 | varSuffix <- nameAndArgs* ('[' exp^ErrExprIndex ']'^ErrCBracketIndex / '.' !'.' NAME^ErrNameIndex) 182 | nameAndArgs <- (':' !':' NAME^ErrNameMeth args^ErrMethArgs) / 183 | args 184 | args <- '(' explist? ')'^ErrCParenArgs / tableconstructor / string 185 | funcbody <- '('^ErrOParenPList parlist? ')'^ErrCParenPList block 'end'^ErrEndFunc 186 | parlist <- namelist (',' '...'^ErrParList)? / '...' 187 | tableconstructor<- '{' fieldlist? '}'^ErrCBraceTable 188 | fieldlist <- field (fieldsep field)* fieldsep? 189 | field <- !OPEN '[' exp^ErrExprFKey ']'^ErrCBracketFKey '='^ErrEqField exp^ErrExprField / 190 | NAME '=' exp / 191 | exp 192 | fieldsep <- ',' / ';' 193 | operatorOr <- 'or' 194 | operatorAnd <- 'and' 195 | operatorComparison<- '<=' / '>=' / '~=' / '==' / '<' !'<' / '>' !'>' 196 | operatorStrcat <- !'...' '..' 197 | operatorAddSub <- '+' / '-' 198 | operatorMulDivMod<- '*' / '%' / '//' / '/' 199 | operatorBitwise <- '&' / '|' / !'~=' '~' / '<<' / '>>' 200 | operatorUnary <- 'not' / '#' / '-' / !'~=' '~' 201 | operatorPower <- '^' 202 | number <- FLOAT / HEX_FLOAT / HEX / INT 203 | string <- NORMALSTRING / CHARSTRING / LONGSTRING 204 | -- lexer 205 | fragment 206 | RESERVED <- KEYWORDS !IDREST 207 | fragment 208 | IDREST <- [a-zA-Z_0-9] 209 | fragment 210 | KEYWORDS <- 'and' / 'break' / 'do' / 'elseif' / 'else' / 'end' / 211 | 'false' / 'for' / 'function' / 'goto' / 'if' / 'in' / 212 | 'local' / 'nil' / 'not' / 'or' / 'repeat' / 'return' / 213 | 'then' / 'true' / 'until' / 'while' 214 | NAME <- !RESERVED [a-zA-Z_] [a-zA-Z_0-9]* 215 | fragment 216 | NORMALSTRING <- '"' {( ESC / [^"\] )*} '"'^ErrQuote 217 | fragment 218 | CHARSTRING <- "'" {( ESC / [^\'] )*} "'"^ErrQuote 219 | fragment 220 | LONGSTRING <- (OPEN {(!CLOSEEQ .)*} CLOSE^ErrCloseLStr) -> 1 -- capture only the string 221 | 222 | fragment 223 | OPEN <- '[' {:openEq: EQUALS :} '[' %nl? 224 | fragment 225 | CLOSE <- ']' {EQUALS} ']' 226 | fragment 227 | EQUALS <- '='* 228 | fragment 229 | CLOSEEQ <- (CLOSE =openEq) => equals 230 | 231 | INT <- DIGIT+ 232 | HEX <- '0' [xX] HEXDIGIT+^ErrDigitHex 233 | FLOAT <- DIGIT+ '.' DIGIT* ExponentPart? / 234 | '.' !'.' DIGIT+^ErrDigitDeci ExponentPart? / 235 | DIGIT+ ExponentPart 236 | HEX_FLOAT <- '0' [xX] HEXDIGIT+ '.' HEXDIGIT* HexExponentPart? / 237 | '0' [xX] '.' HEXDIGIT+ HexExponentPart? / 238 | '0' [xX] HEXDIGIT+^ErrDigitHex HexExponentPart 239 | fragment 240 | ExponentPart <- [eE] [+-]? DIGIT+^ErrDigitExpo 241 | fragment 242 | HexExponentPart <- [pP] [+-]? DIGIT+^ErrDigitExpo 243 | fragment 244 | ESC <- '\' [abfnrtvz"'\] / 245 | '\' %nl / 246 | DECESC / 247 | HEXESC/ 248 | UTFESC/ 249 | '\' %{ErrEscSeq} 250 | fragment 251 | DECESC <- '\' ( DIGIT DIGIT? / [0-2] DIGIT DIGIT) 252 | fragment 253 | HEXESC <- '\' 'x' (HEXDIGIT HEXDIGIT)^ErrHexEsc 254 | fragment 255 | UTFESC <- '\' 'u' '{'^ErrOBraceUEsc HEXDIGIT+^ErrDigitUEsc '}'^ErrCBraceUEsc 256 | fragment 257 | DIGIT <- [0-9] 258 | fragment 259 | HEXDIGIT <- [0-9a-fA-F] 260 | 261 | 262 | fragment 263 | COMMENT <- '--' LONGSTRING -> 0 -- skip this 264 | fragment 265 | LINE_COMMENT <- '--' COM_TYPES ( %nl / !.) 266 | fragment 267 | COM_TYPES <- '[' '='* [^[=%nl] [^%nl]* / 268 | '[' '='* / 269 | [^[%nl] [^%nl]* / 270 | '' 271 | fragment 272 | SHEBANG <- '#' '!' [^%nl]* 273 | 274 | 275 | SKIP <- %nl / %s / COMMENT / LINE_COMMENT / SHEBANG 276 | fragment 277 | HELPER <- RESERVED / '(' / ')' -- for sync expression 278 | SYNC <- ((!HELPER !SKIP .)+ / .?) SKIP* -- either sync to reserved keyword or skip characters and consume them 279 | 280 | ]==],{ equals = equals, fixexp = fixexp, fold = fold }) 281 | local errnr = 1 282 | local function err (desc, line, col, sfail, recexp) 283 | print("Syntax error #"..errnr..": "..desc.." at line "..line.."(col "..col..")") 284 | errnr = errnr+1 285 | end 286 | local function parse (input) 287 | errnr = 1 288 | local ast, errs = pg.parse(input,grammar,err) 289 | return ast, errs 290 | end 291 | return {parse=parse} 292 | -------------------------------------------------------------------------------- /parsers/tiny-parser.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path .. ";../?.lua" 2 | local pg = require "parser-gen" 3 | local peg = require "peg-parser" 4 | local errs = {errMissingThen = "Missing Then"} 5 | pg.setlabels(errs) 6 | 7 | 8 | local grammar = pg.compile([[ 9 | 10 | program <- stmtsequence !. 11 | stmtsequence <- statement (';' statement)* 12 | statement <- ifstmt / repeatstmt / assignstmt / readstmt / writestmt 13 | ifstmt <- 'if' exp 'then'^errMissingThen stmtsequence elsestmt? 'end' 14 | elsestmt <- ('else' stmtsequence) 15 | repeatstmt <- 'repeat' stmtsequence 'until' exp 16 | assignstmt <- IDENTIFIER ':=' exp 17 | readstmt <- 'read' IDENTIFIER 18 | writestmt <- 'write' exp 19 | exp <- simpleexp (COMPARISONOP simpleexp)* 20 | COMPARISONOP <- '<' / '=' 21 | simpleexp <- term (ADDOP term)* 22 | ADDOP <- [+-] 23 | term <- factor (MULOP factor)* 24 | MULOP <- [*/] 25 | factor <- '(' exp ')' / NUMBER / IDENTIFIER 26 | 27 | NUMBER <- '-'? [0-9]+ 28 | KEYWORDS <- 'if' / 'repeat' / 'read' / 'write' / 'then' / 'else' / 'end' / 'until' 29 | RESERVED <- KEYWORDS ![a-zA-Z] 30 | IDENTIFIER <- !RESERVED [a-zA-Z]+ 31 | HELPER <- ';' / %nl / %s / KEYWORDS / !. 32 | SYNC <- (!HELPER .)* 33 | 34 | ]], _, true) 35 | local errors = 0 36 | local function printerror(desc,line,col,sfail,trec) 37 | errors = errors+1 38 | print("Error #"..errors..": "..desc.." on line "..line.."(col "..col..")") 39 | end 40 | 41 | 42 | local function parse(input) 43 | errors = 0 44 | result, errors = pg.parse(input,grammar,printerror) 45 | return result, errors 46 | end 47 | 48 | if arg[1] then 49 | -- argument must be in quotes if it contains spaces 50 | res, errs = parse(arg[1]) 51 | peg.print_t(res) 52 | peg.print_r(errs) 53 | end 54 | local ret = {parse=parse} 55 | return ret 56 | -------------------------------------------------------------------------------- /peg-parser-tests.lua: -------------------------------------------------------------------------------- 1 | local peg = require "peg-parser" 2 | local f = peg.pegToAST 3 | 4 | local eq = require "equals" 5 | local equals = eq.equals 6 | 7 | 8 | -- self-description of peg-parser: 9 | 10 | --assert(f(peg.gram)) 11 | 12 | -- ( p ) grouping 13 | e = f("('a')") 14 | res = {t="a"} 15 | 16 | assert(equals(e,res)) 17 | 18 | -- 'string' literal string 19 | 20 | e = f("'string'") 21 | res = {t="string"} 22 | assert(equals(e,res)) 23 | 24 | -- "string" literal string 25 | e = f('"string"') 26 | res = {t="string"} 27 | 28 | assert(equals(e,res)) 29 | --[class] character class 30 | e = f("[^a-zA-Z01]") 31 | res = { 32 | action = "invert", 33 | op1 = { 34 | action = "or", 35 | op1 = { 36 | action = "or", 37 | op1 = { 38 | action = "or", 39 | op1 = { 40 | action = "range", 41 | op1 = { 42 | s = "az" 43 | } 44 | }, 45 | op2 = { 46 | action = "range", 47 | op1 = { 48 | s = "AZ" 49 | } 50 | } 51 | }, 52 | op2 = { 53 | t = "0" 54 | } 55 | }, 56 | op2 = { 57 | t = "1" 58 | } 59 | } 60 | } 61 | 62 | 63 | assert(equals(e,res)) 64 | 65 | --. any character 66 | e = f(".") 67 | res = {action="anychar"} 68 | 69 | assert(equals(e,res)) 70 | --%name pattern defs[name] or a pre-defined pattern 71 | e = f("%name") 72 | res = {action="%", op1={s="name"}} 73 | 74 | assert(equals(e,res)) 75 | --name non terminal 76 | e = f("name") 77 | res = {nt="name"} 78 | 79 | assert(equals(e,res)) 80 | 81 | -- non terminal 82 | e = f("") 83 | res = {nt="name"} 84 | 85 | assert(equals(e,res)) 86 | 87 | --{} position capture 88 | e = f("{}") 89 | 90 | res = {action="poscap"} 91 | 92 | assert(equals(e,res)) 93 | 94 | --{ p } simple capture 95 | e = f("{name}") 96 | res = {action="scap", op1= {nt="name"}} 97 | 98 | assert(equals(e,res)) 99 | 100 | --{: p :} anonymous group capture 101 | e = f("{:name:}") 102 | res = {action="gcap", op1= {nt="name"}} 103 | 104 | assert(equals(e,res)) 105 | 106 | --{:name: p :} named group capture 107 | e = f("{:g: name:}") 108 | res = {action="gcap", op1= {nt="name"} , op2={s="g"}} 109 | 110 | assert(equals(e,res)) 111 | --{~ p ~} substitution capture 112 | e = f("{~ name ~}") 113 | 114 | res = {action="subcap", op1= {nt="name"}} 115 | 116 | assert(equals(e,res)) 117 | 118 | --{| p |} table capture 119 | e = f("{| name |}") 120 | res = {action="tcap", op1= {nt="name"}} 121 | assert(equals(e,res)) 122 | 123 | --=name back reference 124 | e = f("=name") 125 | res = {action="bref", op1= {s="name"}} 126 | assert(equals(e,res)) 127 | 128 | --p ? optional match 129 | e = f("name?") 130 | res = {action="?", op1= {nt="name"}} 131 | assert(equals(e,res)) 132 | 133 | --p * zero or more repetitions 134 | e = f("name*") 135 | res = {action="*", op1= {nt="name"}} 136 | assert(equals(e,res)) 137 | 138 | --p + one or more repetitions 139 | e = f("name+") 140 | res = {action="+", op1= {nt="name"}} 141 | assert(equals(e,res)) 142 | 143 | --p^num exactly n repetitions 144 | e = f("name^3") 145 | res = {action="^", op1= {nt="name"}, op2 = {num="3"}} 146 | assert(equals(e,res)) 147 | 148 | --p^+num at least n repetitions 149 | e = f("name^+3") 150 | res = {action="^", op1= {nt="name"}, op2 = {num="+3"}} 151 | assert(equals(e,res)) 152 | 153 | --p^-num at most n repetitions 154 | e = f("name^-3") 155 | res = {action="^", op1= {nt="name"}, op2 = {num="-3"}} 156 | assert(equals(e,res)) 157 | 158 | --p^LABEL error label 159 | e = f("name^err") 160 | res = {action = "^LABEL", op1= {nt="name"}, op2 = {s="err"}} 161 | assert(equals(e,res)) 162 | 163 | --p -> 'string' string capture 164 | e = f("name -> 'a'") 165 | res = {action="->", op1= {nt="name"}, op2 = {s="a"}} 166 | assert(equals(e,res)) 167 | 168 | --p -> "string" string capture 169 | e = f('name -> "a"') 170 | res = {action="->", op1= {nt="name"}, op2 = {s="a"}} 171 | assert(equals(e,res)) 172 | 173 | --p -> num numbered capture 174 | 175 | e = f('name -> 3') 176 | 177 | res = {action="->", op1= {nt="name"}, op2 = {num="3"}} 178 | 179 | assert(equals(e,res)) 180 | 181 | --p -> name function/query/string capture equivalent to p / defs[name] 182 | 183 | e = f('name -> func') 184 | res = {action="->", op1= {nt="name"}, op2 = {func="func"}} 185 | 186 | assert(equals(e,res)) 187 | 188 | 189 | 190 | --p => name match-time capture equivalent to lpeg.Cmt(p, defs[name]) 191 | 192 | e = f('name => func') 193 | res = {action="=>", op1= {nt="name"}, op2 = {func="func"}} 194 | 195 | assert(equals(e,res)) 196 | 197 | 198 | --& p and predicate 199 | 200 | e = f('&name') 201 | res = {action="&", op1= {nt="name"}} 202 | 203 | assert(equals(e,res)) 204 | 205 | 206 | --! p not predicate 207 | 208 | 209 | e = f('!name') 210 | res = {action="!", op1= {nt="name"}} 211 | 212 | assert(equals(e,res)) 213 | 214 | 215 | --p1 p2 p3 concatenation with left association 216 | 217 | e = f('name name2 name3') 218 | res = {action="and", op1= {action = "and", op1={nt="name"}, op2={nt="name2"}}, op2={nt="name3"}} 219 | 220 | assert(equals(e,res)) 221 | 222 | --p1 / p2 / p3 ordered choice with left association 223 | 224 | e = f('name / name2 / name3') 225 | res = {action="or", op1= {action = "or", op1={nt="name"}, op2={nt="name2"}}, op2={nt="name3"}} 226 | 227 | assert(equals(e,res)) 228 | 229 | 230 | --(name <- p)+ grammar 231 | 232 | e = f('a <- b b <- c') 233 | res = { 234 | {rulename = "a", rule = {nt="b"}}, 235 | {rulename = "b", rule = {nt="c"}} 236 | } 237 | 238 | assert(equals(e,res)) 239 | 240 | -- error labels 241 | -- %{errName} 242 | 243 | --peg.setlabels({errName=1}) 244 | e = f('%{errName}') 245 | 246 | res = {action="label", op1={s="errName"}} 247 | 248 | assert(equals(e,res)) 249 | 250 | -- a //{errName,errName2} b 251 | 252 | --peg.setlabels({errName=1, errName2=2}) 253 | e = f('a //{errName,errName2} b') 254 | 255 | res = {action="or", condition={{s="errName"},{s="errName2"}}, op1={nt="a"}, op2={nt="b"}} 256 | 257 | 258 | assert(equals(e,res)) 259 | 260 | print("all tests succesful") -------------------------------------------------------------------------------- /peg-parser.lua: -------------------------------------------------------------------------------- 1 | local re = require "relabel" 2 | 3 | local peg = {} 4 | 5 | -- from relabel.lua 6 | 7 | local errinfo = { 8 | {"NoPatt", "no pattern found"}, 9 | {"ExtraChars", "unexpected characters after the pattern"}, 10 | 11 | {"ExpPatt1", "expected a pattern after '/' or '//{...}'"}, 12 | 13 | {"ExpPatt2", "expected a pattern after '&'"}, 14 | {"ExpPatt3", "expected a pattern after '!'"}, 15 | 16 | {"ExpPatt4", "expected a pattern after '('"}, 17 | {"ExpPatt5", "expected a pattern after ':'"}, 18 | {"ExpPatt6", "expected a pattern after '{~'"}, 19 | {"ExpPatt7", "expected a pattern after '{|'"}, 20 | 21 | {"ExpPatt8", "expected a pattern after '<-'"}, 22 | 23 | {"ExpPattOrClose", "expected a pattern or closing '}' after '{'"}, 24 | 25 | {"ExpNum", "expected a number after '^', '+' or '-' (no space)"}, 26 | {"ExpNumOrLab", "expected a number or a label after ^"}, 27 | {"ExpCap", "expected a string, number, '{}' or name after '->'"}, 28 | 29 | {"ExpName1", "expected the name of a rule after '=>'"}, 30 | {"ExpName2", "expected the name of a rule after '=' (no space)"}, 31 | {"ExpName3", "expected the name of a rule after '<' (no space)"}, 32 | 33 | {"ExpLab1", "expected at least one label after '{'"}, 34 | {"ExpLab2", "expected a label after the comma"}, 35 | 36 | {"ExpNameOrLab", "expected a name or label after '%' (no space)"}, 37 | 38 | {"ExpItem", "expected at least one item after '[' or '^'"}, 39 | 40 | {"MisClose1", "missing closing ')'"}, 41 | {"MisClose2", "missing closing ':}'"}, 42 | {"MisClose3", "missing closing '~}'"}, 43 | {"MisClose4", "missing closing '|}'"}, 44 | {"MisClose5", "missing closing '}'"}, -- for the captures 45 | 46 | {"MisClose6", "missing closing '>'"}, 47 | {"MisClose7", "missing closing '}'"}, -- for the labels 48 | 49 | {"MisClose8", "missing closing ']'"}, 50 | 51 | {"MisTerm1", "missing terminating single quote"}, 52 | {"MisTerm2", "missing terminating double quote"}, 53 | } 54 | 55 | local errmsgs = {} 56 | local labels = {} 57 | 58 | for i, err in ipairs(errinfo) do 59 | errmsgs[i] = err[2] 60 | labels[err[1]] = i 61 | end 62 | 63 | re.setlabels(labels) 64 | 65 | local function concat(a,b) 66 | return a..b 67 | end 68 | local function foldtable(action,t) 69 | local re 70 | local first = true 71 | for key,value in pairs(t) do 72 | if first then 73 | re = value 74 | first = false 75 | else 76 | 77 | local temp = re 78 | if action == "suf" then -- suffix actions 79 | local act = value[1] 80 | if act == "*" or act == "?" or act == "+" then 81 | re = {action=act, op1=temp} 82 | else 83 | re = {action=act, op1=temp, op2=value[2]} 84 | end 85 | elseif action == "or" and #value == 2 then -- recovery expression 86 | local labels = value[1] 87 | local op2 = value[2] 88 | re = {action=action, op1=temp, op2=op2, condition=labels} 89 | else 90 | re = {action=action, op1=temp, op2=value} 91 | end 92 | end 93 | end 94 | return re 95 | end 96 | 97 | 98 | local gram = [=[ 99 | 100 | pattern <- (exp / %{NoPatt}) (!. / %{ExtraChars}) 101 | exp <- S (grammar / alternative) 102 | 103 | labels <- {| '{' {: (label / %{ExpLab1}) :} (',' {: (label / %{ExpLab2}) :})* ('}' / %{MisClose7}) |} 104 | 105 | 106 | alternative <- ( {:''->'or':} {| {: seq :} ('/' (('/' {| {: labels :} S {: (seq / %{ExpPatt1}) :} |}) / (S {: (seq / %{ExpPatt1}) :} ) ) )* |} ) -> foldtable 107 | 108 | 109 | seq <- ( {:''->'and':} {| {: prefix :}+ |} ) -> foldtable 110 | 111 | 112 | prefix <- {| {:action: '&' :} S {:op1: (prefix / %{ExpPatt2}) :} |} 113 | / {| {:action: '!' :} S {:op1: (prefix / %{ExpPatt3}) :} |} 114 | / suffix 115 | 116 | suffix <- ( {:''->'suf':} {| primary S {| suffixaction S |}* |} ) -> foldtable 117 | 118 | 119 | suffixaction <- {[+*?]} 120 | / {'^'} {| {:num: [+-]? NUM:} |} 121 | / '^'->'^LABEL' (label / %{ExpNumOrLab}) 122 | / {'->'} S ((string / {| {:action:'{}'->'poscap':} |} / funcname / {|{:num: NUM :} |}) / %{ExpCap}) 123 | / {'=>'} S (funcname / %{ExpName1}) 124 | 125 | 126 | 127 | 128 | primary <- '(' (exp / %{ExpPatt4}) (')' / %{MisClose1}) 129 | / term 130 | / class 131 | / defined 132 | / {| {:action: '%'->'label':} ('{' / %{ExpNameOrLab}) S ({:op1: label:} / %{ExpLab1}) S ('}' / %{MisClose7}) |} 133 | / {| {:action: '{:'->'gcap':} {:op2: defname:} ':' !'}' ({:op1:exp:} / %{ExpPatt5}) (':}' / %{MisClose2}) |} 134 | / {| {:action: '{:'->'gcap':} ({:op1:exp:} / %{ExpPatt5}) (':}' / %{MisClose2}) |} 135 | / {| {:action: '='->'bref':} ({:op1: defname:} / %{ExpName2}) |} 136 | / {| {:action: '{}'->'poscap':} |} 137 | / {| {:action: '{~'->'subcap':} ({:op1: exp:} / %{ExpPatt6}) ('~}' / %{MisClose3}) |} 138 | / {| {:action: '{|'->'tcap':} ({:op1: exp:} / %{ExpPatt7}) ('|}' / %{MisClose4}) |} 139 | / {| {:action: '{'->'scap':} ({:op1: exp:} / %{ExpPattOrClose}) ('}' / %{MisClose5}) |} 140 | / {| {:action: '.'->'anychar':} |} 141 | / !frag !nodee name S !ARROW 142 | / '<' (name / %{ExpName3}) ('>' / %{MisClose6}) -- old-style non terminals 143 | 144 | grammar <- {| definition+ |} 145 | definition <- {| (frag / nodee)? (token / nontoken) S ARROW ({:rule: exp :} / %{ExpPatt8}) |} 146 | 147 | label <- {| {:s: ERRORNAME :} |} 148 | 149 | frag <- {:fragment: 'fragment'->'1' :} ![0-9_a-z] S !ARROW 150 | nodee <- {:node: 'node'->'1' :} ![0-9_a-z] S !ARROW 151 | token <- {:rulename: TOKENNAME :} {:token:''->'1':} 152 | nontoken <- {:rulename: NAMESTRING :} 153 | 154 | class <- '[' ( ('^' {| {:action:''->'invert':} {:op1: classset :} |} ) / classset ) (']' / %{MisClose8}) 155 | classset <- ( {:''->'or':} {| {: (item / %{ExpItem}) :} (!']' {: (item / %{ExpItem}) :})* |} ) -> foldtable 156 | item <- defined / range / {| {:t: . :} |} 157 | range <- {| {:action:''->'range':} {:op1: {| {:s: ({: . :} ('-') {: [^]] :} ) -> concat :} |} :} |} 158 | 159 | S <- (%s / '--' [^%nl]*)* -- spaces and comments 160 | name <- {| {:nt: TOKENNAME :} {:token:''->'1':} / {:nt: NAMESTRING :} |} 161 | 162 | funcname <- {| {:func: NAMESTRING :} |} 163 | ERRORNAME <- NAMESTRING 164 | NAMESTRING <- [A-Za-z][A-Za-z0-9_]* 165 | TOKENNAME <- [A-Z_]+ ![0-9a-z] 166 | defname <- {| {:s: NAMESTRING :} |} 167 | ARROW <- '<-' 168 | NUM <- [0-9]+ 169 | term <- {| '"' {:t: [^"]* :} ('"' / %{MisTerm2}) / "'" {:t: [^']* :} ("'" / %{MisTerm1}) |} 170 | string <- {| '"' {:s: [^"]* :} ('"' / %{MisTerm2}) / "'" {:s: [^']* :} ("'" / %{MisTerm1}) |} 171 | defined <- {| {:action: '%':} {:op1: defname :} |} 172 | ]=] 173 | 174 | local defs = {foldtable=foldtable, concat=concat} 175 | peg.gram = gram 176 | peg.defs = defs 177 | peg.labels = labels 178 | local p = re.compile ( gram, defs) 179 | 180 | 181 | 182 | 183 | --[[ 184 | Function: pegToAST(input) 185 | 186 | Input: a grammar in PEG format, described in https://github.com/vsbenas/parser-gen 187 | 188 | Output: if parsing successful - a table of grammar rules, else - runtime error 189 | 190 | Example input: " 191 | 192 | Program <- stmt* / SPACE 193 | stmt <- ('a' / 'b')+ 194 | SPACE <- '' 195 | 196 | " 197 | 198 | Example output: { 199 | {rulename = "Program", rule = {action = "or", op1 = {action = "*", op1 = {nt = "stmt"}}, op2 = {nt = "SPACE", token="1"}}}, 200 | {rulename = "stmt", rule = {action = "+", op1 = {action="or", op1 = {t = "a"}, op2 = {t = "b"}}}}, 201 | {rulename = "SPACE", rule = {t=""}, token=1}, 202 | } 203 | 204 | The rules are further processed and turned into lpeg compatible format in parser-gen.lua 205 | 206 | Action names: 207 | or (has parameter condition for recovery expresions) 208 | and 209 | & 210 | ! 211 | + 212 | * 213 | ? 214 | ^num (num is a number with an optional plus or minus sign) 215 | ^label (label is an error label set with setlabels) 216 | -> 217 | => 218 | tcap 219 | gcap (op2= name, anonymous otherwise) 220 | bref 221 | poscap 222 | subcap 223 | scap 224 | anychar 225 | label 226 | % 227 | range 228 | 229 | Final token actions: 230 | t - terminal 231 | nt - non terminal 232 | func - function definition 233 | s - literal string 234 | num - literal number 235 | ]]-- 236 | local function splitlines(str) 237 | local t = {} 238 | local function helper(line) table.insert(t, line) return "" end 239 | helper((str:gsub("(.-)\r?\n", helper))) 240 | return t 241 | end 242 | function peg.pegToAST(input, defs) 243 | local r, e, sfail = p:match(input, defs) 244 | if not r then 245 | local lab 246 | if e == 0 then 247 | lab = "Syntax error" 248 | else 249 | lab = errmsgs[e] 250 | end 251 | local lines = splitlines(input) 252 | local line, col = re.calcline(input, #input - #sfail + 1) 253 | local err = {} 254 | table.insert(err, "L" .. line .. ":C" .. col .. ": " .. lab) 255 | table.insert(err, lines[line]) 256 | table.insert(err, string.rep(" ", col-1) .. "^") 257 | error("syntax error(s) in pattern\n" .. table.concat(err, "\n"), 3) 258 | end 259 | return r 260 | end 261 | 262 | 263 | function peg.print_r ( t ) -- for debugging 264 | local print_r_cache={} 265 | local function sub_print_r(t,indent) 266 | if (print_r_cache[tostring(t)]) then 267 | print(indent.."*"..tostring(t)) 268 | else 269 | print_r_cache[tostring(t)]=true 270 | if (type(t)=="table") then 271 | for pos,val in pairs(t) do 272 | if (type(val)=="table") then 273 | print(indent.."["..pos.."] => {") 274 | sub_print_r(val,indent..string.rep(" ",string.len(pos)+8)) 275 | print(indent..string.rep(" ",string.len(pos)+6).."}") 276 | else 277 | print(indent.."["..pos.."] => '"..tostring(val).."'") 278 | end 279 | end 280 | else 281 | print(indent..tostring(t)) 282 | end 283 | end 284 | end 285 | sub_print_r(t,"") 286 | end 287 | function peg.print_t ( t ) -- for debugging 288 | local print_r_cache={} 289 | local function sub_print_r (t,indent) 290 | if (print_r_cache[tostring(t)]) then 291 | print(indent.."*"..tostring(t)) 292 | else 293 | print_r_cache[tostring(t)]=true 294 | if (type(t)=="table") then 295 | local function subprint (pos,val,indent) 296 | if (type(val)=="table") then 297 | print(indent.."{") 298 | sub_print_r(val,indent..string.rep(" ",string.len(pos)+8)) 299 | print(indent..string.rep(" ",string.len(pos)-1).."},") 300 | else 301 | if type(val) ~= "number" then 302 | val = "'"..tostring(val).."'" 303 | end 304 | 305 | if tonumber(pos) then 306 | print(indent..val..",") 307 | else 308 | print(indent..pos.."="..val..",") 309 | end 310 | end 311 | end 312 | if t["rule"] then 313 | subprint("rule",t["rule"],indent) 314 | end 315 | if t["pos"] then 316 | subprint("pos",t["pos"],indent) 317 | end 318 | for pos,val in pairs(t) do 319 | if pos ~= "rule" and pos ~= "pos" then 320 | subprint(pos,val,indent) 321 | end 322 | end 323 | else 324 | print(indent..tostring(t)) 325 | end 326 | end 327 | end 328 | sub_print_r(t,"") 329 | end 330 | 331 | function peg.calcline(subject, pos) 332 | return re.calcline(subject,pos) 333 | end 334 | return peg -------------------------------------------------------------------------------- /rockspecs/parser-gen-1.0.rockspec: -------------------------------------------------------------------------------- 1 | package = "parser-gen" 2 | version = "1.0-7" 3 | source = { 4 | url = "git://github.com/vsbenas/parser-gen", 5 | tag = "v1.0" 6 | } 7 | description = { 8 | summary = "A PEG parser generator that handles space characters, generates ASTs and adds error labels automatically.", 9 | homepage = "https://github.com/vsbenas/parser-gen", 10 | license = "MIT/X11" 11 | } 12 | dependencies = { 13 | "lua >= 5.1, < 5.4", 14 | "lpeglabel >= 0.12.2" 15 | } 16 | build = { 17 | type = "builtin", 18 | modules = { 19 | ["parser-gen"] = "parser-gen.lua", 20 | ["peg-parser"] = "peg-parser.lua", 21 | ["stack"] = "stack.lua", 22 | ["equals"] = "equals.lua", 23 | ["errorgen"] = "errorgen.lua", 24 | 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /rockspecs/parser-gen-1.1.rockspec: -------------------------------------------------------------------------------- 1 | package = "parser-gen" 2 | version = "1.1-0" 3 | source = { 4 | url = "git://github.com/vsbenas/parser-gen", 5 | tag = "v1.1" 6 | } 7 | description = { 8 | summary = "A PEG parser generator that handles space characters, generates ASTs and adds error labels automatically.", 9 | homepage = "https://github.com/vsbenas/parser-gen", 10 | license = "MIT/X11" 11 | } 12 | dependencies = { 13 | "lua >= 5.1, < 5.4", 14 | "lpeglabel >= 0.12.2" 15 | } 16 | build = { 17 | type = "builtin", 18 | modules = { 19 | ["parser-gen"] = "parser-gen.lua", 20 | ["peg-parser"] = "peg-parser.lua", 21 | ["stack"] = "stack.lua", 22 | ["equals"] = "equals.lua", 23 | ["errorgen"] = "errorgen.lua", 24 | 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /rockspecs/parser-gen-1.2.rockspec: -------------------------------------------------------------------------------- 1 | package = "parser-gen" 2 | version = "1.2-0" 3 | source = { 4 | url = "git://github.com/vsbenas/parser-gen", 5 | tag = "v1.2" 6 | } 7 | description = { 8 | summary = "A PEG parser generator that handles space characters, generates ASTs and adds error labels automatically.", 9 | homepage = "https://github.com/vsbenas/parser-gen", 10 | license = "MIT/X11" 11 | } 12 | dependencies = { 13 | "lua >= 5.1, < 5.4", 14 | "lpeglabel >= 0.12.2" 15 | } 16 | build = { 17 | type = "builtin", 18 | modules = { 19 | ["parser-gen"] = "parser-gen.lua", 20 | ["peg-parser"] = "peg-parser.lua", 21 | ["stack"] = "stack.lua", 22 | ["equals"] = "equals.lua", 23 | ["errorgen"] = "errorgen.lua", 24 | 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /stack.lua: -------------------------------------------------------------------------------- 1 | -- Stack Table 2 | -- Uses a table as stack, use :push(value) and
:pop() 3 | -- Lua 5.1 compatible 4 | local unpack = unpack or table.unpack 5 | -- GLOBAL 6 | local Stack = {} 7 | 8 | -- Create a Table with stack functions 9 | function Stack:Create() 10 | 11 | -- stack table 12 | local t = {} 13 | -- entry table 14 | t._et = {} 15 | 16 | -- push a value on to the stack 17 | function t:push(...) 18 | if ... then 19 | local targs = {...} 20 | -- add values 21 | for _,v in ipairs(targs) do 22 | table.insert(self._et, v) 23 | end 24 | end 25 | end 26 | 27 | -- pop a value from the stack 28 | function t:pop(num) 29 | 30 | -- get num values from stack 31 | local num = num or 1 32 | 33 | -- return table 34 | local entries = {} 35 | 36 | -- get values into entries 37 | for i = 1, num do 38 | -- get last entry 39 | if #self._et ~= 0 then 40 | table.insert(entries, self._et[#self._et]) 41 | -- remove last value 42 | table.remove(self._et) 43 | else 44 | break 45 | end 46 | end 47 | -- return unpacked entries 48 | return unpack(entries) 49 | end 50 | 51 | -- get entries 52 | function t:getn() 53 | return #self._et 54 | end 55 | 56 | -- list values 57 | function t:list() 58 | for i,v in pairs(self._et) do 59 | print(i, v) 60 | end 61 | end 62 | return t 63 | end 64 | 65 | return {Stack=Stack} 66 | 67 | -- CHILLCODE™ --------------------------------------------------------------------------------