├── .gitignore ├── LICENSE.txt ├── README.md ├── bin └── castl.js ├── castl.js ├── code.js ├── doc ├── annotations.md └── try catch implementation.lua ├── lua ├── castl │ ├── constructor │ ├── core_objects.lua │ ├── eval.lua │ ├── global_functions.lua │ ├── internal.lua │ ├── jscompile │ │ ├── castl.lua │ │ ├── castl_jit.lua │ │ ├── esprima.lua │ │ └── esprima_jit.lua │ ├── json.lua │ ├── jssupport.lua │ ├── math.lua │ ├── modules │ │ ├── bit.lua │ │ ├── common.lua │ │ ├── dateparser.lua │ │ ├── dkjson.lua │ │ ├── error_helper.lua │ │ └── regexphelper.lua │ ├── nodejs.lua │ ├── others.lua │ ├── protos.lua │ ├── prototype │ │ ├── array.lua │ │ ├── boolean.lua │ │ ├── date.lua │ │ ├── error │ │ │ ├── call_site.lua │ │ │ ├── error.lua │ │ │ ├── eval_error.lua │ │ │ ├── range_error.lua │ │ │ ├── reference_error.lua │ │ │ ├── syntax_error.lua │ │ │ ├── type_error.lua │ │ │ └── uri_error.lua │ │ ├── function.lua │ │ ├── number.lua │ │ ├── object.lua │ │ ├── regexp.lua │ │ └── string.lua │ └── runtime.lua └── jscompile.lua ├── package.json ├── runTests.js └── test ├── .gitignore ├── add.js ├── arguments.js ├── arithmetic.js ├── array.js ├── array_prototype.js ├── array_prototype_inherited.js ├── assignment.js ├── bit_operations.js ├── boolean.js ├── comparison.js ├── date_prototype.js ├── delete.js ├── equality_if.js ├── error.js ├── eval.js ├── expression.js ├── for.js ├── for_in.js ├── function.js ├── function_constructor.js ├── function_declaration.js ├── function_prototype.js ├── getter_setter.js ├── getter_setter_inheritance.js ├── global_functions.js ├── if.js ├── in.js ├── issues └── issue_13.js ├── json.js ├── label.js ├── logical_expression.js ├── math.js ├── modulo.js ├── null.js ├── number.js ├── number_prototype.js ├── obj.js ├── object.js ├── object_prototype.js ├── objects_comparison.js ├── octane2 ├── box2d.js ├── crypto.js ├── deltablue.js ├── navier-stokes.js ├── raytrace.js └── richards.js ├── plus_minus_operator.js ├── regexp.js ├── regexp_prototype.js ├── sanitize_identifier.js ├── scope.js ├── scope2.js ├── sequence.js ├── string.js ├── string_object_prototype.js ├── string_prototype.js ├── string_regexp.js ├── string_replace_replacer_not_string.js ├── switch.js ├── this_arg_functions.js ├── todo ├── function_reference.js ├── getter_setter.js ├── impossible.js ├── json_tostring.js └── object_access.js ├── tonumber.js ├── tostring.js ├── try_catch.js ├── typeof.js ├── undefined.js ├── update_expression.js ├── uri.js ├── void.js └── with.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .buildpath 3 | .project 4 | generateLuaCastl.sh 5 | lua/script.lua 6 | -------------------------------------------------------------------------------- /code.js: -------------------------------------------------------------------------------- 1 | // This is an example to compile 2 | function renderCurve() { 3 | // @number 4 | for (var a = 1, b = 10; a * b; a++, b--) 5 | console.log(new Array(a * b).join('*')); 6 | } 7 | renderCurve(); 8 | -------------------------------------------------------------------------------- /doc/annotations.md: -------------------------------------------------------------------------------- 1 | CASTL Annotations 2 | ========== 3 | 4 | Annotations are specific comments you put in your code to provide CASTL compiler with meta information. 5 | 6 | # Goal 7 | The goal of annotations is to optimize the generated Lua code. The compiler leverage the meta information contained in annotations to write better code. 8 | 9 | # Use 10 | 11 | An annotation is a string beginning with a '@' placed in a (block or line) comment. 12 | ``` // @number``` or ``` /* @number */``` are valid annotations. **An annotation concerns only the line of code directly below**. 13 | 14 | Note that you'll need to explicitly run castl with ```--annotation``` option so that the compiler takes annotations into account. 15 | 16 | ## Available annotations 17 | 18 | For now only *type* annotations are available: 19 | 20 | * ```// @number``` 21 | * ```// @string``` 22 | * ```// @boolean``` 23 | 24 | If you specify a type annotation, the compiler will take it into account for the following elements (in the code line directly below the annotation): 25 | 26 | * variables. E.g. ```myVariable``` 27 | * member expression. E.g. ```myObject.member``` 28 | * call expression. E.g. ```f()``` or ```myObject.method()``` 29 | 30 | ## When to use it 31 | 32 | Type annotations are useful to optimize 4 things currently: 33 | 34 | * + operator 35 | * ++ and -- operators 36 | * Comparisons operators <, <=, >, >= 37 | * Tests (if, while, ternary condition...) 38 | 39 | In the general case CASTL compiles + operation as a call to ```_add``` function which can be heavy. In the same way the general comparison operators are compiled as calls to ```_lt```, ```_le```, ```_gt```, ```_ge``` functions. The call to these functions is useless if operands are both strings or both numbers for instance. That's where annotations come into play. 40 | 41 | ### + operator 42 | 43 | ```Javascript 44 | // @number 45 | a = a + b 46 | // @string 47 | a = a + b 48 | ``` 49 | will directly be compiled to 50 | ```Lua 51 | a = a + b 52 | a = a .. b 53 | -- instead of 54 | -- a = _add(a, b) 55 | -- a = _add(a, b) 56 | ``` 57 | 58 | ### ++ and -- operators 59 | ```Javascript 60 | // @number 61 | ++a 62 | // @number 63 | --a 64 | ``` 65 | will directly be compiled to 66 | ```Lua 67 | a = a + 1 68 | a = a -1 69 | -- instead of 70 | -- a = inc(a) 71 | -- a = dec(a) 72 | ``` 73 | 74 | ### Comparisons 75 | 76 | ```Javascript 77 | // @number 78 | a < b 79 | ``` 80 | will directly be compiled to 81 | ```Lua 82 | a < b 83 | -- instead of 84 | -- _lt(a, b) 85 | 86 | ``` 87 | 88 | 89 | ### Tests 90 | 91 | ```Javascript 92 | // @boolean 93 | if(o.isEnabled()){} 94 | ``` 95 | will directly be compiled to 96 | ```Lua 97 | if(o.isEnabled()) 98 | 99 | end 100 | -- instead of 101 | -- if(_bool(o.isEnabled())) 102 | -- end 103 | 104 | ``` 105 | 106 | # Tips and warnings 107 | 108 | ## Quick optimization: loops 109 | If you had to optimize only one thing it should be loops. The most common and easy pattern to optimize is numerical loop. 110 | A numerical loop typically looks like that: 111 | ```JavaScript 112 | for(i = 0 ; i. 14 | --]] 15 | 16 | -- [[ CASTL Array constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array 18 | 19 | local Array 20 | 21 | local arrayProto = require("castl.protos").arrayProto 22 | local coreObjects = require("castl.core_objects") 23 | 24 | local getmetatable, type = getmetatable, type 25 | local pack = table.pack or function(...) return {n = select('#',...),...} end 26 | 27 | _ENV = nil 28 | 29 | Array = function (this, ...) 30 | local args = pack(...) 31 | local newArray = {} 32 | 33 | if args.n == 1 and type(args[1]) == "number" then 34 | newArray.length = args[1] 35 | else 36 | newArray.length = args.n 37 | for i = 0, args.n do 38 | newArray[i] = args[i + 1] 39 | end 40 | end 41 | 42 | return coreObjects.array(newArray, newArray.length) 43 | end 44 | 45 | Array.length = 1 46 | 47 | Array.isArray = function (this, arr) 48 | return (getmetatable(arr) or {})._prototype == arrayProto 49 | end 50 | 51 | Array.prototype = arrayProto 52 | arrayProto.constructor = Array 53 | 54 | return Array 55 | -------------------------------------------------------------------------------- /lua/castl/constructor/boolean.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Boolean constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean 18 | 19 | 20 | local objectToString = require("castl.core_objects").objectToString 21 | local booleanProto = require("castl.protos").booleanProto 22 | local internal = require("castl.internal") 23 | 24 | local Boolean 25 | 26 | local setmetatable = setmetatable 27 | local null, get, put, withinNew, ToNumber = internal.null, internal.get, internal.put, internal.withinNew, internal.ToNumber 28 | 29 | _ENV = nil 30 | 31 | local booleanPrimitive = function(var) 32 | if var == 0 or var == "" or var == null or var ~= var then 33 | return false 34 | elseif var then 35 | return true 36 | else 37 | return false 38 | end 39 | end 40 | 41 | Boolean = function(this, arg) 42 | -- Boolean constructor not called within a new 43 | if not withinNew(this, booleanProto) then 44 | return booleanPrimitive(arg) 45 | end 46 | 47 | local o = {} 48 | 49 | setmetatable(o, { 50 | __index = function (self, key) 51 | return get(self, booleanProto, key) 52 | end, 53 | __newindex = put, 54 | __tostring = function(self) 55 | return objectToString(self) 56 | end, 57 | _primitive = booleanPrimitive(arg), 58 | __sub = function(a, b) 59 | return ToNumber(a) - ToNumber(b) 60 | end, 61 | __mul = function(a, b) 62 | return ToNumber(a) * ToNumber(b) 63 | end, 64 | __div = function(a, b) 65 | return ToNumber(a) / ToNumber(b) 66 | end, 67 | _prototype = booleanProto 68 | }) 69 | 70 | return o 71 | end 72 | 73 | Boolean.prototype = booleanProto 74 | booleanProto.constructor = Boolean 75 | 76 | return Boolean 77 | -------------------------------------------------------------------------------- /lua/castl/constructor/date.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Date constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean 18 | 19 | local Date 20 | 21 | local internal = require("castl.internal") 22 | local dateparser = require("castl.modules.dateparser") 23 | local dateProto = require("castl.protos").dateProto 24 | 25 | local luajit = jit ~= nil 26 | local date, time = os.date, os.time 27 | local pack = table.pack or function(...) return {n = select('#',...),...} end 28 | local type, setmetatable, require, tonumber = type, setmetatable, require, tonumber 29 | local get, put, withinNew, ToNumber = internal.get, internal.put, internal.withinNew, internal.ToNumber 30 | 31 | _ENV = nil 32 | 33 | Date = function(this, ...) 34 | -- Date constructor not called within a new 35 | if not withinNew(this, dateProto) then 36 | return date("%a %h %d %Y %H:%M:%S GMT%z (%Z)") 37 | end 38 | 39 | local args = pack(...) 40 | local timestamp = 0 41 | 42 | if args.n == 0 then 43 | timestamp = Date.now() 44 | elseif args.n == 1 then 45 | local arg = args[1] 46 | local targ = type(arg) 47 | if targ == "number" then 48 | timestamp = arg * 1000 49 | elseif targ == "string" then 50 | timestamp = Date.parse(arg) 51 | end 52 | else 53 | -- special behavior for year between 0 and 100 54 | if args[1] >= 0 and args[1] <100 then 55 | args[1] = 1900 + args[1] 56 | end 57 | -- more than 1 arguments 58 | -- year, month, day, hour, minute, second, millisecond 59 | timestamp = time{year=args[1], 60 | month=args[2] + 1, 61 | day=args[3] or 1, 62 | hour=args[4] or 0, 63 | min = args[5] or 0, 64 | sec = args[6] or 0} 65 | 66 | timestamp = timestamp * 1000 + (args[7] or 0) 67 | end 68 | 69 | local o = {} 70 | o._timestamp = timestamp 71 | 72 | setmetatable(o, { 73 | __index = function (self, key) 74 | return get(self, dateProto, key) 75 | end, 76 | __newindex = put, 77 | __tostring = dateProto.toString, 78 | __sub = function(a, b) 79 | return ToNumber(a) - ToNumber(b) 80 | end, 81 | __mul = function(a, b) 82 | return ToNumber(a) * ToNumber(b) 83 | end, 84 | __div = function(a, b) 85 | return ToNumber(a) / ToNumber(b) 86 | end, 87 | _prototype = dateProto 88 | }) 89 | 90 | return o 91 | end 92 | 93 | Date._timestamp = 0 94 | 95 | if luajit then 96 | local ffi = require("ffi") 97 | -- posix systems only 98 | ffi.cdef[[ 99 | typedef struct timeval { 100 | long tv_sec; 101 | long tv_usec; 102 | } timeval; 103 | int gettimeofday(struct timeval *restrict tp, void *restrict tzp); 104 | ]] 105 | 106 | local te = ffi.new("timeval[1]") 107 | 108 | Date.now = function(this) 109 | ffi.C.gettimeofday(te, nil); 110 | return tonumber(te[0].tv_sec * 1000 + te[0].tv_usec / 1000); 111 | end 112 | else 113 | Date.now = function(this) 114 | -- TODO: write a C function to get milliseconds 115 | return time() * 1000 116 | end 117 | end 118 | 119 | Date.parse = function(this, str) 120 | -- TODO: parse RFC2822 only for now 121 | return dateparser.parse(str, 'RFC2822') * 1000 122 | end 123 | 124 | Date.UTC = function(this, year, month, day, hrs, min, sec, ms) 125 | local timestamp = time{year=year, 126 | month = month + 1, 127 | day = day or 1, 128 | hour = hrs or 0, 129 | min = min or 0, 130 | sec = sec or 0} 131 | 132 | timestamp = (timestamp + dateProto.getTimezoneOffset()) * 1000 + (ms or 0) 133 | 134 | return timestamp 135 | end 136 | 137 | Date.length = 7 138 | 139 | Date.prototype = dateProto 140 | dateProto.constructor = Date 141 | 142 | return Date 143 | -------------------------------------------------------------------------------- /lua/castl/constructor/error/call_site.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL CallSite constructor submodule]] -- 17 | 18 | local CallSite 19 | 20 | local callSiteProto = require("castl.protos").callSiteProto 21 | 22 | _ENV = nil 23 | 24 | CallSite = function(this, receiver, fun, pos, strict_mode) 25 | this.receiver = receiver 26 | this.fun = fun 27 | this.pos = pos 28 | end 29 | 30 | CallSite.prototype = callSiteProto 31 | callSiteProto.constructor = CallSite 32 | 33 | return CallSite 34 | -------------------------------------------------------------------------------- /lua/castl/constructor/error/error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Error constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error 18 | 19 | local Error 20 | 21 | local errorProto = require("castl.protos").errorProto 22 | local CallSite = require("castl.constructor.error.call_site") 23 | local internal = require("castl.internal") 24 | local coreObjects = require("castl.core_objects") 25 | 26 | local new, array, instanceof = coreObjects.new, coreObjects.array, coreObjects.instanceof 27 | 28 | local setmetatable, getmetatable, rawget, rawset = setmetatable, getmetatable, rawget, rawset 29 | local get, put, ToNumber = internal.get, internal.put, internal.ToNumber 30 | local getinfo = debug.getinfo 31 | local ipairs, remove = ipairs, table.remove 32 | 33 | _ENV = nil 34 | 35 | Error = function(this, message) 36 | local o = {} 37 | o.message = message 38 | 39 | setmetatable(o, { 40 | __index = function (self, key) 41 | return get(self, errorProto, key) 42 | end, 43 | __newindex = put, 44 | __tostring = function(self) 45 | return self:toString() 46 | end, 47 | __sub = function(a, b) 48 | return ToNumber(a) - ToNumber(b) 49 | end, 50 | __mul = function(a, b) 51 | return ToNumber(a) * ToNumber(b) 52 | end, 53 | __div = function(a, b) 54 | return ToNumber(a) / ToNumber(b) 55 | end, 56 | _prototype = errorProto} 57 | ) 58 | 59 | Error:captureStackTrace(o, Error) 60 | 61 | return o 62 | end 63 | 64 | Error.captureStackTrace = function(this, error, constructorOpt) 65 | local frames = {} 66 | local frame_idx = 1 67 | 68 | local info_idx = constructorOpt ~= nil and 3 or 2 69 | while true do 70 | local frame 71 | 72 | if frame_idx <= Error.stackTraceLimit then 73 | frame = getinfo(info_idx) 74 | end 75 | if frame == nil then 76 | break 77 | end 78 | 79 | -- create a CallSite 80 | local cs = new(CallSite, nil, frame.fun, 0) 81 | getmetatable(cs).frame = frame 82 | frames[frame_idx] = cs 83 | frame_idx = frame_idx + 1 84 | info_idx = info_idx + 1 85 | end 86 | 87 | -- add marker 88 | getmetatable(error).__stack = true 89 | 90 | error._gstack = function(this) 91 | if Error.prepareStackTrace then 92 | -- shift to 0-based index 93 | local tmp = rawget(frames, 1) 94 | remove(frames, 1) 95 | rawset(frames, 0, tmp) 96 | return Error:prepareStackTrace(this, array(frames, frame_idx - 1)) 97 | end 98 | 99 | local s = instanceof(error, Error) and error:toString() or "Error" 100 | for _, frame in ipairs(frames) do 101 | s = s .. "\n at " .. frame:toString() 102 | end 103 | return s 104 | end 105 | end 106 | 107 | Error.stackTraceLimit = 10 108 | 109 | Error.prototype = errorProto 110 | errorProto.constructor = Error 111 | 112 | return Error 113 | -------------------------------------------------------------------------------- /lua/castl/constructor/error/eval_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL EvalError constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError 18 | 19 | local EvalError 20 | 21 | local Error = require("castl.constructor.error.error") 22 | local evalErrorProto = require("castl.protos").evalErrorProto 23 | local internal = require("castl.internal") 24 | 25 | local setmetatable = setmetatable 26 | local get, put, ToNumber = internal.get, internal.put, internal.ToNumber 27 | 28 | _ENV = nil 29 | 30 | EvalError = function(this, message) 31 | local o = {} 32 | o.message = message 33 | 34 | setmetatable(o, { 35 | __index = function (self, key) 36 | return get(self, evalErrorProto, key) 37 | end, 38 | __newindex = put, 39 | __tostring = function(self) 40 | return self:toString() 41 | end, 42 | __sub = function(a, b) 43 | return ToNumber(a) - ToNumber(b) 44 | end, 45 | __mul = function(a, b) 46 | return ToNumber(a) * ToNumber(b) 47 | end, 48 | __div = function(a, b) 49 | return ToNumber(a) / ToNumber(b) 50 | end, 51 | _prototype = evalErrorProto}) 52 | 53 | Error:captureStackTrace(o, EvalError) 54 | 55 | return o 56 | end 57 | 58 | EvalError.prototype = evalErrorProto 59 | evalErrorProto.constructor = EvalError 60 | 61 | return EvalError 62 | -------------------------------------------------------------------------------- /lua/castl/constructor/error/range_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL RangeError constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError 18 | 19 | local RangeError 20 | 21 | local Error = require("castl.constructor.error.error") 22 | local rangeErrorProto = require("castl.protos").rangeErrorProto 23 | local internal = require("castl.internal") 24 | 25 | local setmetatable = setmetatable 26 | local get, put, ToNumber = internal.get, internal.put, internal.ToNumber 27 | 28 | _ENV = nil 29 | 30 | RangeError = function(this, message) 31 | local o = {} 32 | o.message = message 33 | 34 | setmetatable(o, { 35 | __index = function (self, key) 36 | return get(self, rangeErrorProto, key) 37 | end, 38 | __newindex = put, 39 | __tostring = function(self) 40 | return self:toString() 41 | end, 42 | __sub = function(a, b) 43 | return ToNumber(a) - ToNumber(b) 44 | end, 45 | __mul = function(a, b) 46 | return ToNumber(a) * ToNumber(b) 47 | end, 48 | __div = function(a, b) 49 | return ToNumber(a) / ToNumber(b) 50 | end, 51 | _prototype = rangeErrorProto}) 52 | 53 | Error:captureStackTrace(o, RangeError) 54 | 55 | return o 56 | end 57 | 58 | RangeError.prototype = rangeErrorProto 59 | rangeErrorProto.constructor = RangeError 60 | 61 | return RangeError 62 | -------------------------------------------------------------------------------- /lua/castl/constructor/error/reference_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL ReferenceError constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError 18 | 19 | local ReferenceError 20 | 21 | local Error = require("castl.constructor.error.error") 22 | local referenceErrorProto = require("castl.protos").referenceErrorProto 23 | local internal = require("castl.internal") 24 | 25 | local setmetatable = setmetatable 26 | local get, put, ToNumber = internal.get, internal.put, internal.ToNumber 27 | 28 | _ENV = nil 29 | 30 | ReferenceError = function(this, message) 31 | local o = {} 32 | o.message = message 33 | 34 | setmetatable(o, { 35 | __index = function (self, key) 36 | return get(self, referenceErrorProto, key) 37 | end, 38 | __newindex = put, 39 | __tostring = function(self) 40 | return self:toString() 41 | end, 42 | __sub = function(a, b) 43 | return ToNumber(a) - ToNumber(b) 44 | end, 45 | __mul = function(a, b) 46 | return ToNumber(a) * ToNumber(b) 47 | end, 48 | __div = function(a, b) 49 | return ToNumber(a) / ToNumber(b) 50 | end, 51 | _prototype = referenceErrorProto}) 52 | 53 | Error:captureStackTrace(o, ReferenceError) 54 | 55 | return o 56 | end 57 | 58 | ReferenceError.prototype = referenceErrorProto 59 | referenceErrorProto.constructor = ReferenceError 60 | 61 | return ReferenceError 62 | -------------------------------------------------------------------------------- /lua/castl/constructor/error/syntax_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL SyntaxError constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError 18 | 19 | local SyntaxError 20 | 21 | local Error = require("castl.constructor.error.error") 22 | local syntaxErrorProto = require("castl.protos").syntaxErrorProto 23 | local internal = require("castl.internal") 24 | 25 | local setmetatable = setmetatable 26 | local get, put, ToNumber = internal.get, internal.put, internal.ToNumber 27 | 28 | _ENV = nil 29 | 30 | SyntaxError = function(this, message) 31 | local o = {} 32 | o.message = message 33 | 34 | setmetatable(o, { 35 | __index = function (self, key) 36 | return get(self, syntaxErrorProto, key) 37 | end, 38 | __newindex = put, 39 | __tostring = function(self) 40 | return self:toString() 41 | end, 42 | __sub = function(a, b) 43 | return ToNumber(a) - ToNumber(b) 44 | end, 45 | __mul = function(a, b) 46 | return ToNumber(a) * ToNumber(b) 47 | end, 48 | __div = function(a, b) 49 | return ToNumber(a) / ToNumber(b) 50 | end, 51 | _prototype = syntaxErrorProto}) 52 | 53 | Error:captureStackTrace(o, SyntaxError) 54 | 55 | return o 56 | end 57 | 58 | SyntaxError.prototype = syntaxErrorProto 59 | syntaxErrorProto.constructor = SyntaxError 60 | 61 | return SyntaxError 62 | -------------------------------------------------------------------------------- /lua/castl/constructor/error/type_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL TypeError constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError 18 | 19 | local TypeError 20 | 21 | local Error = require("castl.constructor.error.error") 22 | local typeErrorProto = require("castl.protos").typeErrorProto 23 | local internal = require("castl.internal") 24 | 25 | local setmetatable = setmetatable 26 | local get, put, ToNumber = internal.get, internal.put, internal.ToNumber 27 | 28 | _ENV = nil 29 | 30 | TypeError = function(this, message) 31 | local o = {} 32 | o.message = message 33 | 34 | setmetatable(o, { 35 | __index = function (self, key) 36 | return get(self, typeErrorProto, key) 37 | end, 38 | __newindex = put, 39 | __tostring = function(self) 40 | return self:toString() 41 | end, 42 | __sub = function(a, b) 43 | return ToNumber(a) - ToNumber(b) 44 | end, 45 | __mul = function(a, b) 46 | return ToNumber(a) * ToNumber(b) 47 | end, 48 | __div = function(a, b) 49 | return ToNumber(a) / ToNumber(b) 50 | end, 51 | _prototype = typeErrorProto}) 52 | 53 | Error:captureStackTrace(o, TypeError) 54 | 55 | return o 56 | end 57 | 58 | TypeError.prototype = typeErrorProto 59 | typeErrorProto.constructor = TypeError 60 | 61 | return TypeError 62 | -------------------------------------------------------------------------------- /lua/castl/constructor/error/uri_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL URIError constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError 18 | 19 | local URIError 20 | 21 | local Error = require("castl.constructor.error.error") 22 | local uriErrorProto = require("castl.protos").uriErrorProto 23 | local internal = require("castl.internal") 24 | 25 | local setmetatable = setmetatable 26 | local get, put, ToNumber = internal.get, internal.put, internal.ToNumber 27 | 28 | _ENV = nil 29 | 30 | URIError = function(this, message) 31 | local o = {} 32 | o.message = message 33 | 34 | setmetatable(o, { 35 | __index = function (self, key) 36 | return get(self, uriErrorProto, key) 37 | end, 38 | __newindex = put, 39 | __tostring = function(self) 40 | return self:toString() 41 | end, 42 | __sub = function(a, b) 43 | return ToNumber(a) - ToNumber(b) 44 | end, 45 | __mul = function(a, b) 46 | return ToNumber(a) * ToNumber(b) 47 | end, 48 | __div = function(a, b) 49 | return ToNumber(a) / ToNumber(b) 50 | end, 51 | _prototype = uriErrorProto}) 52 | 53 | Error:captureStackTrace(o, URIError) 54 | 55 | return o 56 | end 57 | 58 | URIError.prototype = uriErrorProto 59 | uriErrorProto.constructor = URIError 60 | 61 | return URIError 62 | -------------------------------------------------------------------------------- /lua/castl/constructor/function.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Function constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function 18 | 19 | local esprima, castl, runtime 20 | local luajit = jit ~= nil 21 | 22 | local errorHelper = require("castl.modules.error_helper") 23 | local throw = require("castl.jssupport").throw 24 | local functionProto = require("castl.protos").functionProto 25 | 26 | local Function 27 | 28 | local pack = table.pack or function(...) return {n = select('#',...),...} end 29 | local require, assert, load, tinsert, concat = require, assert, load, table.insert, table.concat 30 | 31 | _ENV = nil 32 | 33 | Function = function(this, ...) 34 | if ... then 35 | local args = pack(...) 36 | local body = args[args.n] 37 | 38 | if luajit then 39 | castl = castl or require("castl.jscompile.castl_jit") 40 | esprima = esprima or require("castl.jscompile.esprima_jit") 41 | else 42 | castl = castl or require("castl.jscompile.castl") 43 | esprima = esprima or require("castl.jscompile.esprima") 44 | end 45 | 46 | -- parse body of the function in error-tolerant mode 47 | local esprimaOptions = {tolerant = true} 48 | local ast = esprima:parse(body, esprimaOptions) 49 | 50 | -- get the params 51 | local params = {"local this"} 52 | for i = 1, args.n - 1 do 53 | tinsert(params, ",") 54 | tinsert(params, args[i]) 55 | end 56 | tinsert(params, " = ...;\n") 57 | 58 | -- compile the ast 59 | -- castl used in eval mode 60 | local castlOptions = {jit = luajit} 61 | local castlResult = castl:compileAST(ast, castlOptions) 62 | 63 | local compiledFunction 64 | if castlResult.success then 65 | local luaCode = concat(params) .. castlResult.compiled 66 | -- eval lua code 67 | runtime = runtime or require("castl.runtime") 68 | compiledFunction = assert(load(luaCode, nil, "t", runtime)) 69 | else 70 | throw(errorHelper.newEvalError("Function(): Failed to compile AST to Lua code")) 71 | end 72 | 73 | return compiledFunction 74 | end 75 | 76 | return function () end 77 | end 78 | 79 | Function.prototype = functionProto 80 | functionProto.constructor = Function 81 | 82 | return Function 83 | -------------------------------------------------------------------------------- /lua/castl/constructor/number.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Number constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number 18 | 19 | local Number 20 | 21 | local coreObjects = require("castl.core_objects") 22 | local internal = require("castl.internal") 23 | local numberProto = require("castl.protos").numberProto 24 | local jssupport = require("castl.jssupport") 25 | local globalFunctions = require("castl.global_functions") 26 | 27 | local huge = math.huge 28 | local type, setmetatable = type, setmetatable 29 | local get, put, withinNew, ToNumber = internal.get, internal.put, internal.withinNew, internal.ToNumber 30 | 31 | _ENV = nil 32 | 33 | Number = function(this, arg) 34 | arg = ToNumber(arg) 35 | -- Number constructor not called within a new 36 | if not withinNew(this, numberProto) then 37 | return arg 38 | end 39 | 40 | local o = {} 41 | 42 | setmetatable(o, { 43 | __index = function (self, key) 44 | return get(self, numberProto, key) 45 | end, 46 | __newindex = put, 47 | __tostring = function(self) 48 | return coreObjects.objectToString(self) 49 | end, 50 | _primitive = arg, 51 | __sub = function(a, b) 52 | return ToNumber(a) - ToNumber(b) 53 | end, 54 | __mul = function(a, b) 55 | return ToNumber(a) * ToNumber(b) 56 | end, 57 | __div = function(a, b) 58 | return ToNumber(a) / ToNumber(b) 59 | end, 60 | _prototype = numberProto 61 | }) 62 | 63 | return o 64 | end 65 | 66 | Number.isFinite = function(this, arg) 67 | if type(arg) == 'number' then 68 | return arg ~= huge and arg ~= -huge and not (arg ~= arg) 69 | end 70 | 71 | return false 72 | end 73 | 74 | Number.isNaN = function (this, arg) 75 | if type(arg) == 'number' then 76 | return (arg ~= arg) 77 | end 78 | 79 | return false 80 | end 81 | 82 | Number.parseInt = function (this, str, radix) 83 | return globalFunctions.parseInt(this, str, radix) 84 | end 85 | 86 | Number.parseFloat = function (this, str) 87 | return globalFunctions.parseFloat(this, str) 88 | end 89 | 90 | -- Static properties 91 | Number.NaN = 0/0 92 | Number.MAX_VALUE = 1.7976931348623157e+308 93 | Number.MIN_VALUE = 5e-324 94 | Number.NEGATIVE_INFINITY = -jssupport.Infinity 95 | Number.POSITIVE_INFINITY = jssupport.Infinity 96 | 97 | Number.prototype = numberProto 98 | numberProto.constructor = Number 99 | 100 | return Number 101 | -------------------------------------------------------------------------------- /lua/castl/constructor/regexp.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL RegExp constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp 18 | 19 | local RegExp 20 | 21 | local regexpProto = require("castl.protos").regexpProto 22 | local internal = require("castl.internal") 23 | local errorHelper = require("castl.modules.error_helper") 24 | local throw = require("castl.jssupport").throw 25 | 26 | local find = string.find 27 | local setmetatable, getmetatable = setmetatable, getmetatable 28 | local ToString, get, put, withinNew, ToNumber = internal.ToString, internal.get, internal.put, internal.withinNew, internal.ToNumber 29 | 30 | _ENV = nil 31 | 32 | RegExp = function(this, pattern, flags) 33 | local patternIsRegexp = (getmetatable(pattern) or {})._prototype == regexpProto 34 | 35 | if patternIsRegexp and flags ~= nil then 36 | throw(errorHelper.newTypeError("Cannot supply flags when constructing one RegExp from another")) 37 | end 38 | 39 | if not withinNew(this, regexpProto) and patternIsRegexp then 40 | return pattern 41 | end 42 | 43 | flags = flags or "" 44 | 45 | local o = {} 46 | 47 | if patternIsRegexp then 48 | o.source = ToString(pattern.source) 49 | o.global = pattern.global 50 | o.ignoreCase = pattern.ignoreCase 51 | o.multiline = pattern.multiline 52 | else 53 | o.source = ToString(pattern) 54 | o.global = find(flags, "g") and true 55 | o.ignoreCase = find(flags, "i") and true 56 | o.multiline = find(flags, "m") and true 57 | end 58 | 59 | setmetatable(o, { 60 | __index = function (self, key) 61 | return get(self, regexpProto, key) 62 | end, 63 | __newindex = put, 64 | __tostring = regexpProto.toString, 65 | __sub = function(a, b) 66 | return ToNumber(a) - ToNumber(b) 67 | end, 68 | __mul = function(a, b) 69 | return ToNumber(a) * ToNumber(b) 70 | end, 71 | __div = function(a, b) 72 | return ToNumber(a) / ToNumber(b) 73 | end, 74 | _prototype = regexpProto 75 | }) 76 | 77 | return o 78 | 79 | end 80 | 81 | RegExp.prototype = regexpProto 82 | regexpProto.constructor = RegExp 83 | 84 | return RegExp 85 | -------------------------------------------------------------------------------- /lua/castl/constructor/string.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL String constructor submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String 18 | 19 | local String 20 | 21 | local stringProto = require("castl.protos").stringProto 22 | local bit = require("castl.modules.bit") 23 | local coreObjects = require("castl.core_objects") 24 | local internal = require("castl.internal") 25 | 26 | local bor, band, arshift = bit.bor, bit.band, bit.arshift 27 | local pack = table.pack or function(...) return {n = select('#',...),...} end 28 | local unpack, tinsert, concat, stochar = table.unpack or unpack, table.insert, table.concat, string.char 29 | local setmetatable = setmetatable 30 | local ToString, withinNew, get, put, ToNumber, ToUint16 = internal.ToString, internal.withinNew, internal.get, internal.put, internal.ToNumber, internal.ToUint16 31 | 32 | _ENV = nil 33 | 34 | String = function(this, ...) 35 | local arg = pack(...).n > 0 and ToString(...) or ""; 36 | 37 | -- String constructor not called within a new 38 | if not withinNew(this, stringProto) then 39 | return arg 40 | end 41 | 42 | local o = {length = arg.length} 43 | 44 | for i = 0, arg.length - 1 do 45 | o[i] = arg[i] 46 | end 47 | 48 | setmetatable(o, { 49 | __index = function (self, key) 50 | return get(self, stringProto, key) 51 | end, 52 | __newindex = put, 53 | __tostring = function(self) 54 | return coreObjects.objectToString(self) 55 | end, 56 | _primitive = arg, 57 | __sub = function(a, b) 58 | return ToNumber(a) - ToNumber(b) 59 | end, 60 | __mul = function(a, b) 61 | return ToNumber(a) * ToNumber(b) 62 | end, 63 | __div = function(a, b) 64 | return ToNumber(a) / ToNumber(b) 65 | end, 66 | _prototype = stringProto 67 | }) 68 | 69 | return o 70 | end 71 | 72 | local toUTF8Array = function (charcode) 73 | local utf8 = {} 74 | 75 | if charcode < 128 then 76 | tinsert(utf8, charcode) 77 | elseif charcode < 2048 then 78 | tinsert(utf8, bor(192, arshift(charcode, 6))) 79 | tinsert(utf8, bor(128, band(charcode, 63))) 80 | elseif (charcode < 55296) or (charcode >= 57344) then 81 | tinsert(utf8, bor(224, arshift(charcode, 12))) 82 | tinsert(utf8, bor(128, band(arshift(charcode, 6), 63))) 83 | tinsert(utf8, bor(128, band(charcode, 63))) 84 | end 85 | 86 | return utf8 87 | end 88 | 89 | String.fromCharCode = function(this, ...) 90 | local args = pack(...) 91 | local str = {} 92 | for i = 1, args.n do 93 | local charCode = ToUint16(args[i]); 94 | local char = stochar(unpack(toUTF8Array(charCode))) 95 | 96 | tinsert(str, char) 97 | end 98 | 99 | return concat(str) 100 | end 101 | 102 | String.prototype = stringProto 103 | stringProto.constructor = String 104 | 105 | return String 106 | -------------------------------------------------------------------------------- /lua/castl/eval.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | local castl, esprima, runtime 17 | local luajit = jit ~= nil 18 | 19 | local eval = {} 20 | local errorHelper = require("castl.modules.error_helper") 21 | local throw = require("castl.jssupport").throw 22 | 23 | local debug, setmetatable, assert, load, require, type = debug, setmetatable, assert, load, require, type 24 | 25 | _ENV = nil 26 | 27 | -- http://stackoverflow.com/a/2835433/1120148 28 | local locals = function(level) 29 | local variables = {} 30 | local idx = 1 31 | while true do 32 | local ln, lv = debug.getlocal(level, idx) 33 | if ln ~= nil then 34 | if lv ~= nil then 35 | variables[ln] = lv 36 | else 37 | variables[ln] = 0 38 | end 39 | else 40 | break 41 | end 42 | idx = 1 + idx 43 | end 44 | return variables 45 | end 46 | 47 | local upvalues = function(level) 48 | local variables = {} 49 | local idx = 1 50 | local func = debug.getinfo(level, "f").func 51 | while true do 52 | local ln, lv = debug.getupvalue(func, idx) 53 | if ln ~= nil then 54 | if lv ~= nil then 55 | variables[ln] = lv 56 | else 57 | variables[ln] = 0 58 | end 59 | else 60 | break 61 | end 62 | idx = 1 + idx 63 | end 64 | return variables 65 | end 66 | 67 | local getEvalENV = function(locals, upvalues, globals) 68 | return setmetatable({},{ 69 | __index = function(self, key) 70 | if locals[key] ~= nil then 71 | return locals[key] 72 | elseif upvalues[key] ~= nil then 73 | return upvalues[key] 74 | else 75 | return globals[key] 76 | end 77 | end, 78 | __newindex = function(self, key, value) 79 | if locals[key] ~= nil then 80 | locals[key] = value 81 | elseif upvalues[key] ~= nil then 82 | upvalues[key] = value 83 | else 84 | globals[key] = value 85 | end 86 | end 87 | }) 88 | end 89 | 90 | local evalLuaString = function(str, _G) 91 | local level = 4 92 | 93 | -- collect locals and upvalues 94 | local _l = locals(level) 95 | local _u = upvalues(level) 96 | local _evalENV = getEvalENV(_l, _u, _G) 97 | 98 | -- eval lua code 99 | local evaluated = assert(load(str, nil, "t", _evalENV)) 100 | local last, beforeLast 101 | local catch = function() 102 | beforeLast = last 103 | local _, v = debug.getlocal(2, 1) 104 | last = v 105 | end 106 | 107 | -- catch the last return 108 | debug.sethook(catch, "r") 109 | evaluated() 110 | debug.sethook() 111 | 112 | -- set upvalues 113 | local _idx = 1 114 | local _func = debug.getinfo(level - 1, "f").func 115 | while true do 116 | local ln = debug.getupvalue(_func, _idx) 117 | if ln ~= nil then 118 | if ln ~= "(*temporary)" and _u[ln] ~= nil then 119 | debug.setupvalue(_func, _idx, _u[ln]) 120 | end 121 | 122 | else 123 | break 124 | end 125 | _idx = 1 + _idx 126 | end 127 | 128 | -- set locals 129 | _idx = 1 130 | while true do 131 | local ln = debug.getlocal(level - 1, _idx) 132 | if ln ~= nil then 133 | if ln ~= "(*temporary)" and _l[ln] ~= nil then 134 | debug.setlocal(level - 1, _idx, _l[ln]) 135 | end 136 | else 137 | break 138 | end 139 | _idx = 1 + _idx 140 | end 141 | 142 | return beforeLast 143 | end 144 | 145 | function eval.eval(this, str) 146 | if type(str) ~= "string" then 147 | return str 148 | end 149 | 150 | if luajit then 151 | castl = castl or require("castl.jscompile.castl_jit") 152 | esprima = esprima or require("castl.jscompile.esprima_jit") 153 | else 154 | castl = castl or require("castl.jscompile.castl") 155 | esprima = esprima or require("castl.jscompile.esprima") 156 | end 157 | 158 | -- parse and compile JS code 159 | local ast = esprima:parse(str) 160 | -- castl used in eval mode 161 | local castlOptions = {jit = luajit, evalMode = true} 162 | local castlResult = castl:compileAST(ast, castlOptions) 163 | local ret 164 | 165 | if castlResult.success then 166 | local luaCode = castlResult.compiled 167 | runtime = runtime or require("castl.runtime") 168 | ret = evalLuaString(luaCode, runtime) 169 | else 170 | throw(errorHelper.newEvalError("Eval(): Failed to compile AST to Lua code")) 171 | end 172 | 173 | return ret 174 | end 175 | 176 | return eval 177 | -------------------------------------------------------------------------------- /lua/castl/json.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL others submodule]] -- 17 | 18 | local coreObjects = require("castl.core_objects") 19 | local internal = require("castl.internal") 20 | local json = require("castl.modules.dkjson") 21 | local errorHelper = require("castl.modules.error_helper") 22 | local throw = require("castl.jssupport").throw 23 | 24 | local null, ToString = internal.null, internal.ToString 25 | 26 | local JSON = {} 27 | 28 | _ENV = nil 29 | 30 | JSON.parse = function(this, text) 31 | text = ToString(text) 32 | local obj, pos, err = json.decode(text, 1, null, coreObjects.objectMt, coreObjects.arrayMt) 33 | if err then 34 | throw(errorHelper.newSyntaxError(err)) 35 | end 36 | 37 | return obj 38 | end 39 | 40 | JSON.stringify = function(this, value) 41 | if value == nil then return nil end 42 | return json.encode(value) 43 | end 44 | 45 | return JSON 46 | -------------------------------------------------------------------------------- /lua/castl/math.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Math object submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs 18 | 19 | local Math = {} 20 | 21 | local internal = require("castl.internal") 22 | local coreObjects = require("castl.core_objects") 23 | 24 | local math, tonumber, time = math, tonumber, os.time 25 | local null = internal.null 26 | 27 | _ENV = nil 28 | 29 | -- init random 30 | math.randomseed(time()) 31 | 32 | -- constants 33 | Math.E = math.exp(1) 34 | Math.LN2 = math.log(2) 35 | Math.LN10 = math.log(10) 36 | Math.LOG2E = 1 / math.log(2) 37 | Math.LOG10E = 1 / math.log(10) 38 | Math.PI = math.pi 39 | Math.SQRT1_2 = 1 / math.sqrt(2) 40 | Math.SQRT2 = math.sqrt(2) 41 | 42 | -- functions 43 | 44 | local san = function(x) 45 | return ((x == null) and 0 or tonumber(x)) or 0/0 46 | end 47 | 48 | Math.abs = function(this, x) return math.abs(san(x)) end 49 | Math.acos = function(this,x) return math.acos(san(x)) end 50 | Math.asin = function(this,x) return math.asin(san(x)) end 51 | Math.atan = function(this,x) return math.atan(san(x)) end 52 | Math.atan2 = function(this,x,y) return math.atan2(san(x),san(y)) end 53 | Math.ceil = function(this,x) return math.ceil(san(x)) end 54 | Math.cos = function(this,x) return math.cos(san(x)) end 55 | Math.exp = function(this,x) return math.exp(san(x)) end 56 | Math.floor = function(this,x) return math.floor(san(x)) end 57 | Math.log = function(this,x) return math.log(san(x)) end 58 | Math.max = function(this,x,y) return math.max(san(x), san(y)) end 59 | Math.min = function(this,x,y) return math.min(san(x), san(y)) end 60 | Math.pow = function(this,x,y) return (san(x) ^ san(y)) end 61 | Math.random = function(this) return math.random() end 62 | Math.round = function(this, x) return math.floor(san(x) + 0.5) end 63 | Math.sin = function(this,x) return math.sin(san(x)) end 64 | Math.sqrt = function(this,x) return math.sqrt(san(x)) end 65 | Math.tan = function(this,x) return math.tan(san(x)) end 66 | 67 | return coreObjects.obj(Math) 68 | -------------------------------------------------------------------------------- /lua/castl/modules/bit.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | local luajit = jit ~= nil 17 | local band, bor, bnot, bxor, lshift, rshift 18 | 19 | -- if executed by LuaJIT use its bit library as base 20 | if luajit then 21 | band, bor, bnot, bxor, lshift, rshift = bit.band, bit.bor, bit.bnot, bit.bxor, bit.lshift, bit.rshift 22 | else 23 | -- else use bit32 lib of Lua 5.2 24 | band, bor, bnot, bxor, lshift, rshift = bit32.band, bit32.bor, bit32.bnot, bit32.bxor, bit32.lshift, bit32.rshift 25 | end 26 | 27 | local bit = {} 28 | 29 | local ToUint32 = require("castl.internal").ToUint32 30 | local ToInteger = require("castl.internal").ToInteger 31 | 32 | _ENV = nil 33 | 34 | bit.lshift = function(x, disp) 35 | x, disp = ToInteger(x), ToUint32(disp) 36 | local shiftCount = band(disp, 0x1F) 37 | local ret = lshift(x, shiftCount); 38 | 39 | -- Ones' complement 40 | if band(ret, 0x80000000) > 0 then 41 | ret = -(bnot(ret) + 1) 42 | end 43 | 44 | return ret 45 | end 46 | 47 | bit.rshift = function(x, disp) 48 | x, disp = ToInteger(x), ToUint32(disp) 49 | if luajit and disp == 0 then 50 | return x % 0x100000000 51 | end 52 | 53 | local shiftCount = band(disp, 0x1F) 54 | return rshift(x, shiftCount) 55 | end 56 | 57 | bit.arshift = function(x, disp) 58 | x, disp = ToInteger(x), ToUint32(disp) 59 | local shiftCount = band(disp, 0x1F) 60 | local ret = rshift(x, shiftCount) 61 | 62 | if x < 0 then 63 | for i = 31, 31 - shiftCount, -1 do 64 | -- set bit to 1 65 | ret = bor(ret, lshift(1,i)) 66 | end 67 | -- Ones' complement 68 | ret = -(bnot(ret) + 1) 69 | end 70 | 71 | return ret 72 | end 73 | 74 | bit.band = function(x, y) 75 | return band(ToInteger(x), ToInteger(y)) 76 | end 77 | 78 | bit.bor = function(x, y) 79 | return bor(ToInteger(x), ToInteger(y)) 80 | end 81 | 82 | bit.bxor = function(x, y) 83 | return bxor(ToInteger(x), ToInteger(y)) 84 | end 85 | 86 | bit.bnot = function(x) 87 | return bnot(ToInteger(x)) 88 | end 89 | 90 | return bit 91 | -------------------------------------------------------------------------------- /lua/castl/modules/common.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL useful shared code submodule]] -- 17 | -- No 'require' dependency 18 | 19 | local common = {} 20 | 21 | local pairs = pairs 22 | local gsub = string.gsub 23 | 24 | _ENV = nil 25 | 26 | local magicChars = { 27 | ["%"] = "%%%%" , 28 | ["("] = "%%(" , 29 | [")"] = "%%)" , 30 | ["."] = "%%." , 31 | ["+"] = "%%+" , 32 | ["-"] = "%%-" , 33 | ["*"] = "%%*" , 34 | ["?"] = "%%?" , 35 | ["["] = "%%[" , 36 | ["]"] = "%%]" , 37 | ["$"] = "%%$"} 38 | 39 | common.escapeMagicChars = function(str) 40 | for c,r in pairs(magicChars) do 41 | str = gsub(str, "%" .. c, r) 42 | end 43 | return str 44 | end 45 | 46 | return common 47 | -------------------------------------------------------------------------------- /lua/castl/modules/dateparser.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | local difftime, time, date = os.difftime, os.time, os.date 17 | local tinsert = table.insert 18 | local pcall, ipairs, tostring, tonumber, type, setmetatable = pcall, ipairs, tostring, tonumber, type, setmetatable 19 | local match = string.match 20 | 21 | local DateParser = {} 22 | 23 | _ENV = nil 24 | 25 | --we shall use the host OS's time conversion facilities. Dealing with all those leap seconds by hand can be such a bore. 26 | local unix_timestamp 27 | do 28 | local now = time() 29 | local local_UTC_offset_sec = difftime(time(date("!*t", now)), time(date("*t", now))) 30 | unix_timestamp = function(t, offset_sec) 31 | local success, improper_time = pcall(time, t) 32 | if not success or not improper_time then return nil, "invalid date. os.time says: " .. (improper_time or "nothing") end 33 | return improper_time - local_UTC_offset_sec - offset_sec 34 | end 35 | end 36 | 37 | local formats = {} -- format names 38 | local format_func = setmetatable({}, {__mode='v'}) --format functions 39 | 40 | ---register a date format parsing function 41 | local register_format = function(format_name, format_function) 42 | if type(format_name)~="string" or type(format_function)~='function' then return nil, "improper arguments, can't register format handler" end 43 | 44 | local found 45 | for i, f in ipairs(format_func) do --for ordering 46 | if f==format_function then 47 | found=true 48 | break 49 | end 50 | end 51 | if not found then 52 | tinsert(format_func, format_function) 53 | end 54 | formats[format_name] = format_function 55 | return true 56 | end 57 | 58 | ---try to parse date string 59 | --@param str date string 60 | --@param date_format optional date format name, if known 61 | --@return unix timestamp if str can be parsed; nil, error otherwise. 62 | DateParser.parse = function(str, date_format) 63 | local success, res 64 | if date_format then 65 | if not formats[date_format] then return 'unknown date format: ' .. tostring(date_format) end 66 | success, res = pcall(formats[date_format], str) 67 | else 68 | for i, func in ipairs(format_func) do 69 | success, res = pcall(func, str) 70 | if success and res then return res end 71 | end 72 | end 73 | 74 | return success and res 75 | end 76 | 77 | 78 | do 79 | local tz_table = { --taken from http://www.timeanddate.com/library/abbreviations/timezones/ 80 | A = 1, B = 2, C = 3, D = 4, E=5, F = 6, G = 7, H = 8, I = 9, 81 | K = 10, L = 11, M = 12, N = -1, O = -2, P = -3, Q = -4, R = -5, 82 | S = -6, T = -7, U = -8, V = -9, W = -10, X = -11, Y = -12, 83 | Z = 0, 84 | 85 | EST = -5, EDT = -4, CST = -6, CDT = -5, 86 | MST = -7, MDT = -6, PST = -8, PDT = -7, 87 | 88 | GMT = 0, UT = 0, UTC = 0 89 | } 90 | 91 | local month_val = {Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8, Sep=9, Oct=10, Nov=11, Dec=12} 92 | 93 | register_format('RFC2822', function(rest) 94 | local year, month, day, day_of_year, week_of_year, weekday 95 | local hour, minute, second, second_fraction, offset_hours 96 | 97 | local alt_rest 98 | 99 | weekday, alt_rest = match(rest, "^(%w%w%w),%s+(.*)$") 100 | if weekday then rest=alt_rest end 101 | day, rest=match(rest,"^(%d%d?)%s+(.*)$") 102 | month, rest=match(rest,"^(%w%w%w)%s+(.*)$") 103 | month = month_val[month] 104 | year, rest = match(rest,"^(%d%d%d?%d?)%s+(.*)$") 105 | hour, rest = match(rest,"^(%d%d?):(.*)$") 106 | minute, rest = match(rest,"^(%d%d?)(.*)$") 107 | second, alt_rest = match(rest,"^:(%d%d)(.*)$") 108 | if second then rest = alt_rest end 109 | local tz, offset_sign, offset_h, offset_m 110 | tz, alt_rest = match(rest,"^%s+(%u+)(.*)$") 111 | if tz then 112 | rest = alt_rest 113 | offset_hours = tz_table[tz] 114 | else 115 | offset_sign, offset_h, offset_m, rest = match(rest,"^%s+([+-])(%d%d)(%d%d)%s*(.*)$") 116 | offset_hours = tonumber(offset_sign .. offset_h) + (tonumber(offset_m) or 0)/60 117 | end 118 | 119 | if #rest>0 or not (year and day and month and hour and minute) then 120 | return nil 121 | end 122 | 123 | year = tonumber(year) 124 | local d = { 125 | year = year and ((year > 100) and year or (year < 50 and (year + 2000) or (year + 1900))), 126 | month = month, 127 | day = tonumber(day), 128 | 129 | hour= tonumber(hour) or 0, 130 | min = tonumber(minute) or 0, 131 | sec = tonumber(second) or 0, 132 | isdst = false 133 | } 134 | return unix_timestamp(d, offset_hours * 3600) 135 | end) 136 | end 137 | 138 | return DateParser 139 | -------------------------------------------------------------------------------- /lua/castl/modules/error_helper.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | local errorHelper = {} 17 | 18 | local new 19 | local Error, TypeError, SyntaxError, RangeError, ReferenceError, URIError, EvalError 20 | local require = require 21 | 22 | _ENV = nil 23 | 24 | local loadError = function() 25 | new = new or require("castl.core_objects").new 26 | Error = Error or require("castl.constructor.error.error") 27 | end 28 | local loadTypeError = function() 29 | new = new or require("castl.core_objects").new 30 | TypeError = TypeError or require("castl.constructor.error.type_error") 31 | end 32 | local loadSyntaxError = function() 33 | new = new or require("castl.core_objects").new 34 | SyntaxError = SyntaxError or require("castl.constructor.error.syntax_error") 35 | end 36 | local loadRangeError = function() 37 | new = new or require("castl.core_objects").new 38 | RangeError = RangeError or require("castl.constructor.error.range_error") 39 | end 40 | local loadReferenceError = function() 41 | new = new or require("castl.core_objects").new 42 | ReferenceError = ReferenceError or require("castl.constructor.error.reference_error") 43 | end 44 | local loadEvalError = function() 45 | new = new or require("castl.core_objects").new 46 | EvalError = EvalError or require("castl.constructor.error.eval_error") 47 | end 48 | local loadURIError = function() 49 | new = new or require("castl.core_objects").new 50 | URIError = URIError or require("castl.constructor.error.uri_error") 51 | end 52 | 53 | function errorHelper.newError(message) 54 | loadError() 55 | return new(Error, message) 56 | end 57 | function errorHelper.newTypeError(message) 58 | loadTypeError() 59 | return new(TypeError, message) 60 | end 61 | function errorHelper.newSyntaxError(message) 62 | loadSyntaxError() 63 | return new(SyntaxError, message) 64 | end 65 | function errorHelper.newRangeError(message) 66 | loadRangeError() 67 | return new(RangeError, message) 68 | end 69 | function errorHelper.newReferenceError(message) 70 | loadReferenceError() 71 | return new(ReferenceError, message) 72 | end 73 | function errorHelper.newURIError(message) 74 | loadURIError() 75 | return new(URIError, message) 76 | end 77 | function errorHelper.newEvalError(message) 78 | loadEvalError() 79 | return new(EvalError, message) 80 | end 81 | 82 | return errorHelper 83 | -------------------------------------------------------------------------------- /lua/castl/modules/regexphelper.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | local regexHelper = {} 17 | 18 | local rex 19 | local require, type = require, type 20 | local regexEngineName = "rex_pcre" 21 | 22 | _ENV = nil 23 | 24 | regexHelper.getRex = function() 25 | return rex or require(regexEngineName) 26 | end 27 | 28 | regexHelper.getPCRECompilationFlag = function(regexp) 29 | if regexp.ignoreCase and regexp.multiline then 30 | return "im" 31 | elseif regexp.ignoreCase then 32 | return "i" 33 | elseif regexp.multiline then 34 | return "m" 35 | end 36 | 37 | return nil 38 | end 39 | 40 | regexHelper.split = function(subject, regexp) 41 | rex = rex or require(regexEngineName) 42 | 43 | -- compilation flags 44 | local cf = regexHelper.getPCRECompilationFlag(regexp) 45 | 46 | return rex.split(subject, regexp.source, cf) 47 | end 48 | 49 | -- TODO: it's a hack. maybe I missed something but it's the only way 50 | -- I found to know if second returned argument of rex.split is a capture or only the separator pattern itself 51 | -- http://rrthomas.github.io/lrexlib/manual.html#split 52 | regexHelper.regExpHasCaptures = function(subject, regexp) 53 | rex = rex or require(regexEngineName) 54 | local _,_,capture = rex.find(subject, regexp.source) 55 | return capture 56 | end 57 | 58 | regexHelper.gsub = function(subject, regexp, replacer) 59 | rex = rex or require(regexEngineName) 60 | 61 | -- compilation flags 62 | local cf = regexHelper.getPCRECompilationFlag(regexp) 63 | local n = not regexp.global and 1 or nil 64 | 65 | local match = regexp.source 66 | 67 | -- add a global capture to get the entire match 68 | -- passed to the function 69 | if type(replacer) == "function" then 70 | match = "(" .. match .. ")" 71 | end 72 | 73 | return rex.gsub(subject, match, replacer, n, cf) 74 | end 75 | 76 | return regexHelper 77 | -------------------------------------------------------------------------------- /lua/castl/nodejs.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL NodeJS basic support submodule]] -- 17 | 18 | local nodejs = {} 19 | 20 | local coreObject = require("castl.core_objects") 21 | local require = require 22 | 23 | local package = package 24 | local find, sub, len = string.find, string.sub, string.len 25 | 26 | _ENV = nil 27 | 28 | nodejs.require = function(this, packagename) 29 | local index = find(packagename, "/[^/]*$") 30 | if index then 31 | local path = sub(packagename, 1, index) 32 | local file = sub(packagename, index + 1) 33 | if sub(file, -3) == ".js" then 34 | file = sub(file, 1, len(file) - 3) 35 | end 36 | package.path = package.path .. ";" .. path .. "?.lua" 37 | package.path = package.path .. ";" .. path .. "?.js.lua" 38 | return require(file) 39 | end 40 | 41 | return require(packagename) 42 | end 43 | 44 | return nodejs 45 | -------------------------------------------------------------------------------- /lua/castl/others.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL others submodule]] -- 17 | 18 | local coreObjects = require("castl.core_objects") 19 | 20 | local others = {} 21 | local gsub = string.gsub 22 | local print, type = print, type 23 | 24 | _ENV = nil 25 | 26 | others.console = coreObjects.obj({ 27 | log = function (self, ...) 28 | print(...) 29 | end, 30 | info = function (self, ...) 31 | print(...) 32 | end, 33 | warn = function (self, ...) 34 | print(...) 35 | end, 36 | error = function (self, ...) 37 | print(...) 38 | end, 39 | dir = function(self, o) 40 | if type(o) == "string" then 41 | o = gsub(o, "\\", "\\\\") 42 | o = gsub(o, "\n", "\\n") 43 | o = gsub(o, "\r", "\\r") 44 | o = gsub(o, "\t", "\\t") 45 | o = gsub(o, "\b", "\\b") 46 | o = gsub(o, "\f", "\\f") 47 | o = "'" .. o .. "'"; 48 | end 49 | print(o) 50 | end 51 | }) 52 | 53 | return others 54 | -------------------------------------------------------------------------------- /lua/castl/protos.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | local protos = {} 17 | 18 | -- forward declaration 19 | protos.arrayProto = {} 20 | protos.booleanProto = {} 21 | protos.dateProto = {} 22 | protos.functionProto = {} 23 | protos.numberProto = {} 24 | protos.objectProto = {} 25 | protos.regexpProto = {} 26 | protos.stringProto = {} 27 | 28 | protos.errorProto = {} 29 | protos.rangeErrorProto = {} 30 | protos.referenceErrorProto = {} 31 | protos.syntaxErrorProto = {} 32 | protos.typeErrorProto = {} 33 | protos.evalErrorProto = {} 34 | protos.uriErrorProto = {} 35 | protos.callSiteProto = {} 36 | 37 | -- load definition 38 | protos.loadPrototypesDefinition = function() 39 | require("castl.prototype.array")(protos.arrayProto) 40 | require("castl.prototype.boolean")(protos.booleanProto) 41 | require("castl.prototype.date")(protos.dateProto) 42 | require("castl.prototype.function")(protos.functionProto) 43 | require("castl.prototype.number")(protos.numberProto) 44 | require("castl.prototype.object")(protos.objectProto) 45 | require("castl.prototype.regexp")(protos.regexpProto) 46 | require("castl.prototype.string")(protos.stringProto) 47 | 48 | require("castl.prototype.error.error")(protos.errorProto) 49 | require("castl.prototype.error.range_error")(protos.rangeErrorProto) 50 | require("castl.prototype.error.reference_error")(protos.referenceErrorProto) 51 | require("castl.prototype.error.syntax_error")(protos.syntaxErrorProto) 52 | require("castl.prototype.error.type_error")(protos.typeErrorProto) 53 | require("castl.prototype.error.eval_error")(protos.evalErrorProto) 54 | require("castl.prototype.error.uri_error")(protos.uriErrorProto) 55 | require("castl.prototype.error.call_site")(protos.callSiteProto) 56 | end 57 | 58 | return protos 59 | -------------------------------------------------------------------------------- /lua/castl/prototype/boolean.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Boolean prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/prototype 18 | 19 | return function(booleanPrototype) 20 | local getmetatable, tostring, type = getmetatable, tostring, type 21 | 22 | _ENV = nil 23 | 24 | booleanPrototype.toString = function (this) 25 | return tostring(this:valueOf()) 26 | end 27 | 28 | booleanPrototype.valueOf = function (this) 29 | if type(this) == "boolean" then 30 | return this 31 | else 32 | return getmetatable(this)._primitive 33 | end 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /lua/castl/prototype/date.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Date prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/prototype 18 | 19 | return function(datePrototype) 20 | local date, time, difftime = os.date, os.time, os.difftime 21 | local format = string.format 22 | 23 | _ENV = nil 24 | 25 | datePrototype.toString = function (this) 26 | return date('%a %h %d %Y %H:%M:%S GMT%z (%Z)', this._timestamp / 1000) 27 | end 28 | 29 | datePrototype.getDate = function (this) return date('*t', this._timestamp / 1000).day end 30 | datePrototype.getDay = function (this) return date('*t', this._timestamp / 1000).wday - 1 end 31 | datePrototype.getFullYear = function (this) return date('*t', this._timestamp / 1000).year end 32 | datePrototype.getHours = function (this) return date('*t', this._timestamp / 1000).hour end 33 | datePrototype.getMilliseconds = function (this) return this._timestamp % 1000 end 34 | datePrototype.getMinutes = function (this) return date('*t', this._timestamp / 1000).min end 35 | datePrototype.getMonth = function (this) return date('*t', this._timestamp / 1000).month - 1 end 36 | datePrototype.getSeconds = function (this) return date('*t', this._timestamp / 1000).sec end 37 | 38 | datePrototype.getTime = function(this) 39 | return this._timestamp 40 | end 41 | 42 | datePrototype.getTimezoneOffset = function(this) 43 | local now = time() 44 | return difftime(now, time(date("!*t", now))) / 60 45 | end 46 | 47 | datePrototype.getUTCDate = function (this) return date('!*t', this._timestamp / 1000).day end 48 | datePrototype.getUTCDay = function (this) return date('!*t', this._timestamp / 1000).wday - 1 end 49 | datePrototype.getUTCFullYear = function (this) return date('!*t', this._timestamp / 1000).year end 50 | datePrototype.getUTCHours = function (this) return date('!*t', this._timestamp / 1000).hour end 51 | datePrototype.getUTCMilliseconds = datePrototype.getMilliseconds 52 | datePrototype.getUTCMinutes = function (this) return date('!*t', this._timestamp / 1000).min end 53 | datePrototype.getUTCMonth = function (this) return date('!*t', this._timestamp / 1000).month - 1 end 54 | datePrototype.getUTCSeconds = function (this) return date('!*t', this._timestamp / 1000).sec end 55 | 56 | local setDateTime = function(this, key, value) 57 | local millis = this._timestamp % 1000 58 | local d = date('*t', this._timestamp / 1000) 59 | d[key] = value 60 | this._timestamp = (time(d) * 1000) + millis 61 | end 62 | 63 | local setDateTimeUTC = function(this, key, value) 64 | local millis = this._timestamp % 1000 65 | local d = date('!*t', this._timestamp / 1000) 66 | d[key] = value 67 | this._timestamp = (time(d) * 1000) + millis 68 | end 69 | 70 | datePrototype.setDate = function (this, dayValue) setDateTime(this, "day", dayValue) end 71 | datePrototype.setFullYear = function (this, yearValue) setDateTime(this, "year", yearValue) end 72 | datePrototype.setHours = function (this, hoursValue) setDateTime(this, "hour", hoursValue) end 73 | datePrototype.setMinutes = function (this, minutesValue) setDateTime(this, "min", minutesValue) end 74 | datePrototype.setMonth = function (this, monthValue) setDateTime(this, "month", monthValue + 1) end 75 | datePrototype.setSeconds = function (this, secondsValue) setDateTime(this, "sec", secondsValue) end 76 | 77 | datePrototype.setMilliseconds = function (this, millisValue) 78 | local d = date('*t', this._timestamp / 1000) 79 | this._timestamp = (time(d) * 1000) + millisValue 80 | end 81 | 82 | datePrototype.setTime = function (this, timeValue) 83 | this._timestamp = timeValue 84 | end 85 | 86 | datePrototype.setUTCDate = function (this, dayValue) setDateTimeUTC(this, "day", dayValue) end 87 | datePrototype.setUTCFullYear = function (this, yearValue) setDateTimeUTC(this, "year", yearValue) end 88 | datePrototype.setUTCHours = function (this, hoursValue) setDateTimeUTC(this, "hour", hoursValue) end 89 | datePrototype.setUTCMinutes = function (this, minutesValue) setDateTimeUTC(this, "min", minutesValue) end 90 | datePrototype.setUTCMonth = function (this, monthValue) setDateTimeUTC(this, "month", monthValue + 1) end 91 | datePrototype.setUTCSeconds = function (this, secondsValue) setDateTimeUTC(this, "sec", secondsValue) end 92 | 93 | datePrototype.setUTCMilliseconds = function (this, millisValue) 94 | local d = date('!*t', this._timestamp / 1000) 95 | this._timestamp = (time(d) * 1000) + millisValue 96 | end 97 | 98 | datePrototype.toDateString = function(this) 99 | return date('%a %h %d %Y', this._timestamp / 1000) 100 | end 101 | 102 | datePrototype.toISOString = function(this) 103 | return date('!%Y-%m-%dT%H:%M:%S.', this._timestamp / 1000) .. format('%03dZ', this._timestamp % 1000) 104 | end 105 | 106 | datePrototype.toJSON = datePrototype.toISOString 107 | datePrototype.toLocaleDateString = datePrototype.toDateString 108 | datePrototype.toLocaleString = datePrototype.toString 109 | 110 | datePrototype.toTimeString = function(this) 111 | return date('%H:%M:%S GMT%z (%Z)', this._timestamp / 1000) 112 | end 113 | 114 | datePrototype.toLocaleTimeString = function(this) 115 | return date('%H:%M:%S', this._timestamp / 1000) 116 | end 117 | 118 | datePrototype.toUTCString = function(this) 119 | return date('!%a %h %d %Y %H:%M:%S GMT', this._timestamp / 1000) 120 | end 121 | 122 | datePrototype.valueOf = function(this) 123 | return this._timestamp 124 | end 125 | 126 | end 127 | -------------------------------------------------------------------------------- /lua/castl/prototype/error/call_site.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL CallSite prototype submodule]] -- 17 | 18 | return function(callSitePrototype) 19 | local getmetatable = getmetatable 20 | local gsub = string.gsub 21 | _ENV = nil 22 | 23 | callSitePrototype.getThis = function(this) 24 | return this.receiver 25 | end 26 | callSitePrototype.getTypeName = function(this) 27 | end 28 | callSitePrototype.getFunction = function(this) 29 | return this.fun 30 | end 31 | callSitePrototype.getFunctionName = function(this) 32 | end 33 | callSitePrototype.getMethodName = function(this) 34 | end 35 | callSitePrototype.getFileName = function(this) 36 | return getmetatable(this).frame.short_src 37 | end 38 | callSitePrototype.getLineNumber = function(this) 39 | return getmetatable(this).frame.currentline 40 | end 41 | callSitePrototype.getColumnNumber = function(this) 42 | end 43 | callSitePrototype.getEvalOrigin = function(this) 44 | end 45 | callSitePrototype.isToplevel = function(this) 46 | end 47 | callSitePrototype.isEval = function(this) 48 | end 49 | callSitePrototype.isNative = function(this) 50 | end 51 | callSitePrototype.isConstructor = function(this) 52 | end 53 | 54 | callSitePrototype.toString = function (this) 55 | local frame = getmetatable(this).frame 56 | local name = frame.name or "" 57 | local file = gsub(frame.short_src, "%[[TC]%]. ", '') 58 | return name .. " (" .. file .. ":" .. frame.currentline .. ")" 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lua/castl/prototype/error/error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Error prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/prototype 18 | 19 | return function(errorPrototype) 20 | _ENV = nil 21 | 22 | errorPrototype.name = "Error" 23 | errorPrototype.message = "" 24 | 25 | errorPrototype.toString = function (this) 26 | if this.message ~= "" then 27 | return this.name .. ": " .. this.message 28 | else 29 | return this.name 30 | end 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /lua/castl/prototype/error/eval_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL URIError prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError/prototype 18 | 19 | return function(evalErrorPrototype) 20 | _ENV = nil 21 | 22 | evalErrorPrototype.name = "EvalError" 23 | evalErrorPrototype.message = "" 24 | end 25 | -------------------------------------------------------------------------------- /lua/castl/prototype/error/range_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL RangeError prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError/prototype 18 | 19 | return function(rangeErrorPrototype) 20 | _ENV = nil 21 | 22 | rangeErrorPrototype.name = "RangeError" 23 | rangeErrorPrototype.message = "" 24 | end 25 | -------------------------------------------------------------------------------- /lua/castl/prototype/error/reference_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL ReferenceError prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype 18 | 19 | return function(referenceErrorPrototype) 20 | _ENV = nil 21 | 22 | referenceErrorPrototype.name = "ReferenceError" 23 | referenceErrorPrototype.message = "" 24 | end 25 | -------------------------------------------------------------------------------- /lua/castl/prototype/error/syntax_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL SyntaxError prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype 18 | 19 | return function(syntaxErrorPrototype) 20 | _ENV = nil 21 | 22 | syntaxErrorPrototype.name = "SyntaxError" 23 | syntaxErrorPrototype.message = "" 24 | end 25 | -------------------------------------------------------------------------------- /lua/castl/prototype/error/type_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL TypeError prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError/prototype 18 | 19 | return function(typeErrorPrototype) 20 | _ENV = nil 21 | 22 | typeErrorPrototype.name = "TypeError" 23 | typeErrorPrototype.message = "" 24 | end 25 | -------------------------------------------------------------------------------- /lua/castl/prototype/error/uri_error.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL URIError prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError/prototype 18 | 19 | return function(uriErrorPrototype) 20 | _ENV = nil 21 | 22 | uriErrorPrototype.name = "URIError" 23 | uriErrorPrototype.message = "" 24 | end 25 | -------------------------------------------------------------------------------- /lua/castl/prototype/function.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Function prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype 18 | 19 | return function(functionPrototype) 20 | local pack = table.pack or function(...) return {n = select('#',...),...} end 21 | local unpack = table.unpack or unpack 22 | 23 | _ENV = nil 24 | 25 | functionPrototype.call = function(this, thisArg, ...) 26 | return this(thisArg, ...) 27 | end 28 | 29 | functionPrototype.bind = function(this, thisArg, ...) 30 | local argsToPrepend = pack(...) 31 | 32 | return function(_, ...) 33 | local argset, j = {}, 1 34 | local argsToAppend = pack(...) 35 | 36 | for i = 1, argsToPrepend.n do 37 | argset[j] = argsToPrepend[i] 38 | j = j + 1 39 | end 40 | 41 | for i = 1, argsToAppend.n do 42 | argset[j] = argsToAppend[i] 43 | j = j + 1 44 | end 45 | 46 | return this(thisArg, unpack(argset, 1, argsToPrepend.n + argsToAppend.n)) 47 | end 48 | end 49 | 50 | functionPrototype.apply = function(this, thisArg, argsArray) 51 | local args, length = {}, 0 52 | 53 | if argsArray ~= nil then 54 | length = argsArray.length 55 | for i = 0, length - 1 do 56 | args[i+1] = argsArray[i] 57 | end 58 | end 59 | 60 | return this(thisArg, unpack(args, 1, length)) 61 | end 62 | 63 | functionPrototype.toString = function(this) 64 | return "function (){}" 65 | end 66 | 67 | end 68 | -------------------------------------------------------------------------------- /lua/castl/prototype/number.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Number prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/prototype 18 | 19 | return function(numberPrototype) 20 | local errorHelper = require("castl.modules.error_helper") 21 | local throw = require("castl.jssupport").throw 22 | 23 | local tonumber, tostring, floor, concat, insert = tonumber, tostring, math.floor, table.concat, table.insert 24 | local strsub, strlen, gsub, format, getmetatable, type = string.sub, string.len, string.gsub, string.format, getmetatable, type 25 | 26 | _ENV = nil 27 | 28 | numberPrototype.valueOf = function (this) 29 | if type(this) == "number" then 30 | return this 31 | else 32 | return getmetatable(this)._primitive 33 | end 34 | end 35 | 36 | local valueof = numberPrototype.valueOf 37 | 38 | numberPrototype.toString = function(this, radix) 39 | local value = valueof(this) 40 | 41 | if not radix or radix == 10 then 42 | return tostring(value) 43 | end 44 | 45 | -- TODO: do not handle floating point numbers 46 | -- http://stackoverflow.com/a/3554821 47 | local n = floor(value) 48 | local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 49 | local t = {} 50 | local sign = "" 51 | if n < 0 then 52 | sign = "-" 53 | n = -n 54 | end 55 | repeat 56 | local d = (n % radix) + 1 57 | n = floor(n / radix) 58 | insert(t, 1, strsub(digits, d, d)) 59 | until n == 0 60 | 61 | return sign .. concat(t, "") 62 | end 63 | 64 | numberPrototype.toLocaleString = numberPrototype.toString 65 | 66 | numberPrototype.toFixed = function(this, digits) 67 | local value = valueof(this) 68 | digits = digits or 0 69 | return format("%." .. tonumber(digits) .. "f", value) 70 | end 71 | 72 | numberPrototype.toExponential = function(this, fractionDigits) 73 | local value = valueof(this) 74 | if fractionDigits == nil then 75 | fractionDigits = strlen(tostring(value)) - 1 76 | if floor(value) ~= value then 77 | fractionDigits = fractionDigits - 1 78 | end 79 | end 80 | if fractionDigits < 0 or fractionDigits > 20 then 81 | throw(errorHelper.newRangeError("toExponential() argument must be between 0 and 20")) 82 | end 83 | local formatted = format("%." .. fractionDigits .. "e", value) 84 | return (gsub(formatted, "%+0", "+")) 85 | end 86 | 87 | numberPrototype.toPrecision = function(this, precision) 88 | local value = valueof(this) 89 | if precision == nil then return tostring(value) end 90 | if precision < 1 or precision > 21 then 91 | throw(errorHelper.newRangeError("toPrecision() argument must be between 1 and 21")) 92 | end 93 | local formatted = format("%." .. precision .. "g", value) 94 | return (gsub(formatted, "%+0", "+")) 95 | end 96 | 97 | end 98 | -------------------------------------------------------------------------------- /lua/castl/prototype/object.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL Object prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype 18 | 19 | return function(objectPrototype) 20 | local internal = require("castl.internal") 21 | local protos = require("castl.protos") 22 | local arrayProto = protos.arrayProto 23 | local regexpProto = protos.regexpProto 24 | local dateProto = protos.dateProto 25 | 26 | local type, rawget = type, rawget 27 | local getmetatable = getmetatable 28 | local null, getPrototype, getFunctionProxy = internal.null, internal.prototype, internal.getFunctionProxy 29 | 30 | _ENV = nil 31 | 32 | objectPrototype.toString = function (this) 33 | local mt = getmetatable(this) 34 | local tthis = type(this) 35 | if this == nil then 36 | return "[object Undefined]" 37 | elseif this == null then 38 | return "[object Null]" 39 | elseif tthis == "string" then 40 | return "[object String]" 41 | elseif tthis == "number" then 42 | return "[object Number]" 43 | elseif tthis == "boolean" then 44 | return "[object Boolean]" 45 | elseif mt and mt._prototype == arrayProto then 46 | return "[object Array]" 47 | elseif mt and mt._prototype == regexpProto then 48 | return "[object RegExp]" 49 | elseif mt and mt._prototype == dateProto then 50 | return "[object Date]" 51 | elseif mt and mt._arguments then 52 | return "[object Arguments]" 53 | elseif tthis == "function" then 54 | return "[object Function]" 55 | end 56 | 57 | return '[object Object]' 58 | end 59 | 60 | objectPrototype.toLocaleString = objectPrototype.toString 61 | 62 | objectPrototype.valueOf = function (this) 63 | return this 64 | end 65 | 66 | objectPrototype.hasOwnProperty = function (this, p) 67 | local tthis = type(this) 68 | if tthis == "string" then 69 | return p == "length" 70 | end 71 | if tthis == "number" then 72 | return false 73 | end 74 | if tthis == "boolean" then 75 | return false 76 | end 77 | if tthis == "function" then 78 | this = getFunctionProxy(this) 79 | end 80 | 81 | return rawget(this, p) ~= nil 82 | end 83 | 84 | objectPrototype.isPrototypeOf = function(this, object) 85 | if this ~= nil then 86 | local classPrototypeAttribute = this 87 | local objProto = getPrototype(object) 88 | 89 | while objProto do 90 | if objProto == classPrototypeAttribute then 91 | return true 92 | end 93 | objProto = getPrototype(objProto) 94 | end 95 | end 96 | return false 97 | end 98 | 99 | -- TODO: enumerability 100 | objectPrototype.propertyIsEnumerable = function(this, prop) 101 | return this[prop] ~= nil 102 | end 103 | 104 | end 105 | -------------------------------------------------------------------------------- /lua/castl/prototype/regexp.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | -- [[ CASTL RegExp prototype submodule]] -- 17 | -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/prototype 18 | 19 | return function(regexpPrototype) 20 | local array = require("castl.core_objects").array 21 | local internal = require("castl.internal") 22 | local regexpHelper = require("castl.modules.regexphelper") 23 | 24 | local rawget, rawset = rawget, rawset 25 | local pack = table.pack or function(...) return {n = select('#',...),...} end 26 | local tinsert, tremove = table.insert, table.remove 27 | local null, ToString = internal.null, internal.ToString 28 | 29 | _ENV = nil 30 | 31 | regexpPrototype.global = false 32 | regexpPrototype.ignoreCase = false 33 | regexpPrototype.multiline = false 34 | regexpPrototype.source = "" 35 | regexpPrototype.lastIndex = 0 36 | 37 | regexpPrototype.exec = function(this, str) 38 | str = ToString(str) 39 | -- add a global capture to get the entire match 40 | -- (find don't return the entire match, only the captures) 41 | local source = "(" .. this.source .. ")" 42 | 43 | local cf = regexpHelper.getPCRECompilationFlag(this) 44 | local ret = {} 45 | 46 | local rex = regexpHelper.getRex() 47 | if this.global then 48 | local found = pack(rex.find(str, source, this.lastIndex + 1, cf)) 49 | if found[1] then 50 | this.lastIndex = found[2] 51 | ret.index = found[1] - 1 52 | ret.input = str 53 | for i = 3, found.n do 54 | tinsert(ret, found[i]) 55 | end 56 | else 57 | this.lastIndex = 0 58 | end 59 | else 60 | local found = pack(rex.find(str, source, 1, cf)) 61 | if found[1] then 62 | ret.index = found[1] - 1 63 | ret.input = str 64 | for i = 3, found.n do 65 | tinsert(ret, found[i]) 66 | end 67 | end 68 | end 69 | 70 | local length = #ret 71 | 72 | if length == 0 then 73 | return null 74 | end 75 | 76 | -- shift to 0-based index 77 | local tmp = rawget(ret, 1) 78 | tremove(ret, 1) 79 | rawset(ret, 0, tmp) 80 | 81 | return array(ret, length) 82 | end 83 | 84 | regexpPrototype.toString = function(this) 85 | local flags = "" 86 | if rawget(this, "global") then flags = flags .. 'g' end 87 | if rawget(this, "ignoreCase") then flags = flags .. 'i' end 88 | if rawget(this, "multiline") then flags = flags .. 'm' end 89 | 90 | return '/' .. this.source .. '/' .. flags 91 | end 92 | 93 | regexpPrototype.test = function(this, str) 94 | str = ToString(str) 95 | local cf = regexpHelper.getPCRECompilationFlag(this) 96 | 97 | local ret = false 98 | local rex = regexpHelper.getRex() 99 | if this.global then 100 | local _, endFound = rex.find(str, this.source, this.lastIndex + 1, cf) 101 | if endFound then 102 | this.lastIndex = endFound 103 | ret = true 104 | else 105 | this.lastIndex = 0 106 | ret = false 107 | end 108 | else 109 | local found = rex.find(str, this.source, 1, cf) 110 | ret = found and true or false 111 | end 112 | 113 | return ret 114 | end 115 | end 116 | -------------------------------------------------------------------------------- /lua/castl/runtime.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright (c) 2014, Paul Bernier 3 | 4 | CASTL is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | CASTL is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU Lesser General Public License for more details. 12 | You should have received a copy of the GNU Lesser General Public License 13 | along with CASTL. If not, see . 14 | --]] 15 | 16 | local internal = require("castl.internal") 17 | local protos = require("castl.protos") 18 | local jssupport = require("castl.jssupport") 19 | local coreObjects = require("castl.core_objects") 20 | local globalFunctions = require("castl.global_functions") 21 | local bit = require("castl.modules.bit") 22 | local others = require("castl.others") 23 | local json = require("castl.json") 24 | local Object = require("castl.constructor.object") 25 | local Function = require("castl.constructor.function") 26 | local Array = require("castl.constructor.array") 27 | local Boolean = require("castl.constructor.boolean") 28 | local Number = require("castl.constructor.number") 29 | local String = require("castl.constructor.string") 30 | local Date = require("castl.constructor.date") 31 | local Error = require("castl.constructor.error.error") 32 | local SyntaxError = require("castl.constructor.error.syntax_error") 33 | local TypeError = require("castl.constructor.error.type_error") 34 | local ReferenceError = require("castl.constructor.error.reference_error") 35 | local RangeError = require("castl.constructor.error.range_error") 36 | local URIError = require("castl.constructor.error.uri_error") 37 | local EvalError = require("castl.constructor.error.eval_error") 38 | local RegExp = require("castl.constructor.regexp") 39 | local Math = require("castl.math") 40 | local eval = require("castl.eval") 41 | 42 | -- load prototypes definitions 43 | protos.loadPrototypesDefinition() 44 | 45 | -- Exported environment 46 | local export = { 47 | -- jssupport 48 | _throw = jssupport.throw, 49 | _eq = jssupport.equal, 50 | _add = jssupport.add, 51 | _addStr1 = jssupport.addString1, 52 | _addStr2 = jssupport.addString2, 53 | _addNum1 = jssupport.addNumber1, 54 | _addNum2 = jssupport.addNumber2, 55 | _bool = jssupport.boolean, 56 | _type = jssupport.typeof, 57 | _break = jssupport._break, 58 | _continue = jssupport._continue, 59 | _in = jssupport.inOp, 60 | _with = jssupport.with, 61 | _void = jssupport.void, 62 | _e = jssupport.e, 63 | _inc = jssupport.inc, 64 | _dec = jssupport.dec, 65 | _mod = jssupport.modulo, 66 | _lt = jssupport.lt, 67 | _le = jssupport.le, 68 | _gt = jssupport.gt, 69 | _ge = jssupport.ge, 70 | NaN = 0/0, 71 | Infinity = jssupport.Infinity, 72 | 73 | -- global functions 74 | isNaN = globalFunctions.isNaN, 75 | isFinite = globalFunctions.isFinite, 76 | parseFloat = globalFunctions.parseFloat, 77 | parseInt = globalFunctions.parseInt, 78 | encodeURI = globalFunctions.encodeURI, 79 | encodeURIComponent = globalFunctions.encodeURIComponent, 80 | decodeURI = globalFunctions.decodeURI, 81 | decodeURIComponent = globalFunctions.decodeURIComponent, 82 | eval = eval.eval, 83 | 84 | -- internal 85 | _tonum = internal.ToNumber, 86 | null = internal.null, 87 | 88 | -- core object 89 | _obj = coreObjects.obj, 90 | _arr = coreObjects.array, 91 | _regexp = coreObjects.regexp, 92 | _args = coreObjects.arguments, 93 | _new = coreObjects.new, 94 | _instanceof = coreObjects.instanceof, 95 | _props = coreObjects.props, 96 | this = coreObjects.this, 97 | 98 | -- constructors 99 | Object = Object, 100 | Function = Function, 101 | Array = Array, 102 | Boolean = Boolean, 103 | Number = Number, 104 | String = String, 105 | Date = Date, 106 | RegExp = RegExp, 107 | Error = Error, 108 | TypeError = TypeError, 109 | SyntaxError = SyntaxError, 110 | ReferenceError = ReferenceError, 111 | RangeError = RangeError, 112 | URIError = URIError, 113 | EvalError = EvalError, 114 | 115 | -- others 116 | console = others.console, 117 | JSON = json, 118 | Math = Math, 119 | _lshift = bit.lshift, 120 | _rshift = bit.rshift, 121 | _arshift = bit.arshift, 122 | _bor = bit.bor, 123 | _bxor = bit.bxor, 124 | _band = bit.band, 125 | _bnot = bit.bnot, 126 | 127 | -- standard library export 128 | _tostr = tostring, 129 | _pcall = pcall, 130 | _ipairs = ipairs, 131 | _seq = table.remove 132 | } 133 | 134 | if jit ~= nil then 135 | export._wenv = setfenv 136 | end 137 | 138 | if _nodejs ~= nil then 139 | local nodejs = require("castl.nodejs") 140 | export.require = nodejs.require 141 | end 142 | 143 | return export 144 | -------------------------------------------------------------------------------- /lua/jscompile.lua: -------------------------------------------------------------------------------- 1 | local esprima = require("castl.jscompile.esprima") 2 | local castl = require("castl.jscompile.castl") 3 | 4 | local file = io.open("../code.js", "r") 5 | local str = file:read("*all") 6 | file:close() 7 | 8 | local ast = esprima:parse(str) 9 | local compiled = castl:compileAST(ast).compiled 10 | 11 | file = io.open("compiled.lua", "w") 12 | file:write(compiled) 13 | file:close() 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "castl", 3 | "version": "1.2.4", 4 | "description": "JavaScript to Lua compiler with runtime library", 5 | "keywords": [ 6 | "castl", 7 | "castlua", 8 | "lua", 9 | "compiler", 10 | "ast", 11 | "transpiler" 12 | ], 13 | "license": "LGPL-3.0", 14 | "author": "Paul Bernier", 15 | "repository": { 16 | "type": "git", 17 | "url": "http://github.com/PaulBernier/castl.git" 18 | }, 19 | "main": "castl.js", 20 | "scripts": { 21 | "test": "node runTests.js" 22 | }, 23 | "bin": { 24 | "castl": "./bin/castl.js" 25 | }, 26 | "dependencies": { 27 | "acorn": "3.0.2", 28 | "babel-core": "6.23.1", 29 | "babel-preset-es2015": "6.22.0", 30 | "babel-preset-es2016": "6.22.0", 31 | "babel-preset-es2017": "6.22.0", 32 | "commander": "2.9.0", 33 | "esmangle": "1.0.1", 34 | "esprima": "2.7.2" 35 | }, 36 | "engines": { 37 | "node": ">=0.12.0" 38 | }, 39 | "bugs": { 40 | "url": "http://github.com/PaulBernier/castl/issues" 41 | }, 42 | "readmeFilename": "README.md" 43 | } 44 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | *.lua 2 | -------------------------------------------------------------------------------- /test/add.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var c = "Hello"; 4 | c += (1 < 2) ? "s" : "o"; 5 | assert(c === "Hellos"); 6 | 7 | assert(8 + 9 === 17); 8 | assert("8" + "3" === "83"); 9 | assert(8 + "3" === "83"); 10 | assert("3" + 8 === "38"); 11 | assert(null + 8 === 8); 12 | assert(null + "8" === "null8"); 13 | assert(8 + null === 8); 14 | assert("8" + null === "8null"); 15 | -------------------------------------------------------------------------------- /test/arguments.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | (function () { 4 | var z = arguments; 5 | assert(!(z instanceof Array)); 6 | assert(z instanceof Object); 7 | assert(typeof (z) === "object"); 8 | assert(z.toString() === "[object Arguments]"); 9 | })(); 10 | 11 | (function (arguments) { 12 | assert(arguments === 4); 13 | })(4); 14 | 15 | (function () { 16 | assert(arguments[0] === 7); 17 | var arguments = 11; 18 | assert(arguments === 11); 19 | })(7); 20 | 21 | (function () { 22 | assert(arguments[0] === 99); 23 | var arguments = function () { 24 | assert(77) 25 | }; 26 | arguments(); 27 | })(99); 28 | 29 | (function () { 30 | arguments = 3; 31 | assert(arguments === 3); 32 | })(); 33 | 34 | (function () { 35 | arguments.z = 3; 36 | assert(arguments.z === 3); 37 | })(); 38 | -------------------------------------------------------------------------------- /test/array.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = new Array(21); 4 | var b = new Array(21, "pp", "test"); 5 | var c = Array(21); 6 | var d = Array(21, "foo", "bar"); 7 | var e = []; 8 | var f = [8, 12, "abs"]; 9 | 10 | assert(a.length === 21); 11 | assert(typeof a[0] === "undefined"); 12 | 13 | assert(b.length === 3); 14 | assert(b[0] === 21); 15 | assert(b[2] === "test"); 16 | assert(typeof b[3] === "undefined"); 17 | 18 | assert(c.length === 21); 19 | assert(typeof c[0] === "undefined"); 20 | 21 | assert(d.length === 3); 22 | assert(d[0] === 21); 23 | assert(d[2] === "bar"); 24 | assert(typeof d[3] === "undefined"); 25 | 26 | assert(e.length === 0); 27 | assert(typeof e[0] === "undefined"); 28 | 29 | assert(f.length === 3); 30 | assert(f[0] === 8); 31 | 32 | a[11] = "doctor"; 33 | assert(a[11] === "doctor"); 34 | 35 | // Instance of 36 | assert(Array instanceof Object); 37 | assert(a instanceof Array); 38 | assert(b instanceof Array); 39 | assert(c instanceof Array); 40 | assert(d instanceof Array); 41 | assert(e instanceof Array); 42 | assert(f instanceof Array); 43 | 44 | e[1336] = "foo"; 45 | assert(e.length === 1337); 46 | 47 | var g = [2, 3, , 5]; 48 | assert(typeof g[2] === "undefined"); 49 | 50 | assert(Array.isArray(a)); 51 | assert(Array.isArray(c)); 52 | assert(Array.isArray(e)); 53 | 54 | var dumbObject = {}; 55 | assert(!Array.isArray(dumbObject)); 56 | -------------------------------------------------------------------------------- /test/assignment.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var x = [1,5,11]; 4 | var j = 0, z; 5 | 6 | for (i = 0 ;i<2 ; ++i) { 7 | z = x[j] = x[j] + x[++j] 8 | } 9 | assert(z === 16); 10 | assert(j === 2); 11 | assert(x[0] === 6); 12 | assert(x[1] === 16); 13 | assert(x[2] === 11); 14 | 15 | var position = 1; 16 | var z = [7, 88, 12]; 17 | z[++position] -= 23; 18 | assert(position === 2); 19 | assert(z[0] === 7); 20 | assert(z[1] === 88); 21 | assert(z[2] === -11); 22 | 23 | position = 1; 24 | z = [7, 88, 12]; 25 | z[position++] -= 23; 26 | assert(position === 2); 27 | assert(z[0] === 7); 28 | assert(z[1] === 65); 29 | assert(z[2] === 12); 30 | 31 | position = 0; 32 | z = [7, 65, 12]; 33 | g = z[++position] -= z[++position] * 2; 34 | assert(position === 2); 35 | assert(g === 41); 36 | 37 | position = 1; 38 | z = [7, 88, 12]; 39 | z[++position] -= ++position; 40 | assert(position === 3); 41 | assert(z[0] === 7); 42 | assert(z[1] === 88); 43 | assert(z[2] === 9); 44 | 45 | position = 1; 46 | z = [7, 88, 12]; 47 | z[++position] -= position++; 48 | assert(position === 3); 49 | assert(z[0] === 7); 50 | assert(z[1] === 88); 51 | assert(z[2] === 10); 52 | assert(position === 3); 53 | 54 | // 8 types of assignment 55 | // a = 2; 56 | // a += 2; 57 | // a[index] = 2; 58 | // a[index] += 2; 59 | 60 | // z = (a = 2); 61 | // z = (a[index] = 2); 62 | // z = (a -= 2); 63 | // z = (a[index] -= 2); 64 | -------------------------------------------------------------------------------- /test/boolean.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = Boolean(true); 4 | assert(a); 5 | 6 | var b = new Boolean(true); 7 | assert(b); 8 | assert(b.toString() === "true"); 9 | 10 | var c = Boolean(false); 11 | assert(!c); 12 | 13 | var d = new Boolean(false); 14 | assert(d); 15 | assert(d.toString() === "false"); 16 | 17 | var e = new Boolean(c); 18 | assert(e); 19 | assert(e.toString() === "false"); 20 | 21 | var f = Boolean(c); 22 | assert(!f); 23 | 24 | var g = Boolean({}); 25 | assert(g); 26 | 27 | var h = Boolean(); 28 | assert(!h); 29 | 30 | var i = new Boolean(); 31 | assert(i); 32 | assert(i.toString() === "false"); 33 | 34 | ////// 35 | var n = Boolean(7) 36 | var m = new Boolean(77) 37 | var o = true 38 | 39 | assert(n == true); 40 | assert(m == true); 41 | assert(o == true); 42 | assert(n === true); 43 | assert(!(m === true)); 44 | assert(o === true); 45 | assert(typeof(n) === "boolean"); 46 | assert(typeof(m) === "object"); 47 | assert(typeof(o) === "boolean"); 48 | assert(!(n instanceof Boolean)); 49 | assert(m instanceof Boolean); 50 | assert(!(o instanceof Boolean)); 51 | assert(n.toString() === "true"); 52 | assert(m.toString() === "true"); 53 | assert(o.toString() === "true"); 54 | assert(-n === -1); 55 | assert(-m === -1); 56 | assert(-o === -1); 57 | -------------------------------------------------------------------------------- /test/comparison.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var result = [[false,true,false,true,true,true,true,false,false,false,false,true,false,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,true,false,true,true,false,false,false,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,false],[false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,false,true,true,false,true,false,true,true],[false,true,false,true,true,true,true,false,false,false,false,true,false,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,true,false,true,true,false,false,false,false,true,false,true,true,true,true,false,false,false,true,true,false,false,false,true,true,false,false,false,true,true,false,false,false],[false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,true,true,false,false,false,true,true,false,false,false,false,true,false,true,true,false,true,false,true,true],[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false],[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false],[false,true,false,true,false,true,true,false,false,false,false,true,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,false,true,false,true,true,true,true,false,false,false,false,true,false,true,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,false],[false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,false,true,true,false,true,false,true,true],[false,true,false,true,true,true,true,false,false,false,false,true,false,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,true,false,true,true,false,false,false,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,false],[false,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,true,true,false,false,true,true,false,false,false,false,false,false,false,false,true,true,false],[false,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,false,false,true,false,true,true,false,false,false,false,false,false,false,true,true,false],[false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,false,true,true,false,true,false,true,false],[false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,false,true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false,true,true,false,false,true,false,true,true,false,false,true,true,false,true,true,false,false,false,true,true,false,false,false,false,true,false,true,false,false,true,false,true,true]]; 4 | 5 | var array = [0,1, "0", "1", NaN, undefined,null,true, false, "str", function(){}, {valueOf: function(){return 1}}, {toString: function(){return "1"}}]; 6 | 7 | for(var i = 0 ; i array[j]) === result[i][j * 5 + 2]); 12 | assert((array[i] >= array[j]) === result[i][j * 5 + 3]); 13 | assert((array[i] == array[j]) === result[i][j * 5 + 4]); 14 | } 15 | } 16 | 17 | // Generator 18 | // 19 | //~ var array = [0,1, "0", "1", NaN, undefined,null,true, false, "str", function(){}, {valueOf: function(){return 1}}, {toString: function(){return "1"}}] 20 | //~ 21 | //~ var res = []; 22 | //~ for(var i = 0 ; i array[j]); 28 | //~ res[i].push(array[i] >= array[j]); 29 | //~ res[i].push(array[i] == array[j]); 30 | //~ } 31 | //~ } 32 | //~ 33 | //~ console.log(res); 34 | -------------------------------------------------------------------------------- /test/date_prototype.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var date = new Date(1989, 2, 15, 22, 15, 1, 233); 4 | 5 | assert(date.getDate() === 15); 6 | assert(date.getDay() === 3); 7 | assert(date.getFullYear() === 1989); 8 | assert(date.getHours() === 22); 9 | assert(date.getMilliseconds() === 233); 10 | assert(date.getMinutes() === 15); 11 | assert(date.getMonth() === 2); 12 | 13 | var theBigDay = new Date(1980, 6, 7); 14 | theBigDay.setUTCDate(24); 15 | assert(theBigDay.getUTCDate() === 24); 16 | assert(theBigDay.getUTCMonth() === 6); 17 | theBigDay.setUTCDate(36); 18 | assert(theBigDay.getUTCDate() === 5); 19 | assert(theBigDay.getUTCMonth() === 7); 20 | 21 | theBigDay = new Date(1980, 6, 7); 22 | theBigDay.setFullYear(2001); 23 | assert(theBigDay.getFullYear() === 2001); 24 | 25 | theBigDay = new Date(1980, 6, 7); 26 | theBigDay.setHours(5); 27 | assert(theBigDay.getHours() === 5); 28 | theBigDay.setHours(44); 29 | assert(theBigDay.getDate() === 8); 30 | assert(theBigDay.getHours() === 20); 31 | 32 | theBigDay = new Date(1980, 6, 7); 33 | theBigDay.setMinutes(5); 34 | assert(theBigDay.getMinutes() === 5); 35 | assert(theBigDay.getHours() === 0); 36 | theBigDay.setMinutes(88); 37 | assert(theBigDay.getDate() === 7); 38 | assert(theBigDay.getHours() === 1); 39 | assert(theBigDay.getMinutes() === 28); 40 | 41 | theBigDay = new Date(1980, 6, 7); 42 | theBigDay.setMonth(11); 43 | assert(theBigDay.getMonth() === 11); 44 | assert(theBigDay.getFullYear() === 1980); 45 | theBigDay.setMonth(20); 46 | assert(theBigDay.getMonth() === 8); 47 | assert(theBigDay.getFullYear() === 1981); 48 | 49 | theBigDay = new Date(1980, 6, 7); 50 | theBigDay.setSeconds(11); 51 | assert(theBigDay.getSeconds() === 11); 52 | assert(theBigDay.getMinutes() === 0); 53 | theBigDay.setSeconds(200); 54 | assert(theBigDay.getSeconds() === 20); 55 | assert(theBigDay.getMinutes() === 3); 56 | 57 | theBigDay = new Date(1980, 6, 7, 3, 15, 55, 123); 58 | theBigDay.setMilliseconds(11); 59 | assert(theBigDay.getDate() === 7); 60 | assert(theBigDay.getFullYear() === 1980); 61 | assert(theBigDay.getHours() === 3); 62 | assert(theBigDay.getMilliseconds() === 11); 63 | assert(theBigDay.getMinutes() === 15); 64 | assert(theBigDay.getMonth() === 6); 65 | assert(theBigDay.getSeconds() === 55); 66 | 67 | theBigDay.setMilliseconds(2100); 68 | assert(theBigDay.getDate() === 7); 69 | assert(theBigDay.getFullYear() === 1980); 70 | assert(theBigDay.getHours() === 3); 71 | assert(theBigDay.getMilliseconds() === 100); 72 | assert(theBigDay.getMinutes() === 15); 73 | assert(theBigDay.getMonth() === 6); 74 | assert(theBigDay.getSeconds() === 57); 75 | 76 | theBigDay = new Date(1980, 6, 7); 77 | var sameAsBigDay = new Date(); 78 | sameAsBigDay.setTime(theBigDay.getTime()); 79 | assert(theBigDay.getTime() === sameAsBigDay.getTime()); 80 | 81 | // Year between 0 and 100 82 | date = new Date(55, 2, 15); 83 | assert(date.getFullYear() === 1955); 84 | date = new Date(0, 2, 15); 85 | assert(date.getFullYear() === 1900); 86 | date = new Date(99, 2, 15); 87 | assert(date.getFullYear() === 1999); 88 | date = new Date(100, 2, 15); 89 | assert(date.getFullYear() === 100) 90 | -------------------------------------------------------------------------------- /test/delete.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | x = 42; 4 | var y = 43; 5 | myobj = { 6 | h: 4, 7 | k: 5 8 | }; 9 | 10 | var myobj2 = { 11 | h: 4, 12 | k: 5 13 | }; 14 | 15 | assert(delete x); 16 | assert(typeof x === "undefined"); 17 | assert(!(delete y)); 18 | assert(y === 43); 19 | assert(delete myobj.h); 20 | assert(typeof myobj.h === "undefined"); 21 | assert(delete myobj); 22 | assert(typeof myobj === "undefined"); 23 | 24 | assert(delete myobj2.h); 25 | assert(typeof myobj2.h === "undefined"); 26 | assert(!(delete myobj2)); 27 | assert(typeof myobj2 === "object"); 28 | 29 | function Foo() {} 30 | Foo.prototype.bar = 42; 31 | var foo = new Foo(); 32 | 33 | assert(delete foo.bar); 34 | assert(typeof foo.bar !== "undefined"); 35 | assert(delete Foo.prototype.bar); 36 | assert(typeof foo.bar === "undefined"); 37 | 38 | // Delete getter/setter 39 | 40 | var o = {get p () {return 12}, set s (v) {}} 41 | 42 | assert(o.p === 12); 43 | assert(delete o.p); 44 | assert(delete o.s); 45 | assert(typeof(o.p) === "undefined"); 46 | assert(typeof(o.s) === "undefined"); 47 | 48 | 49 | var o = {a: { get b () {return 7}}}; 50 | assert(o["a"].b === 7); 51 | assert(delete o["a"].b); 52 | assert(o["a"].b === undefined); 53 | 54 | o = {f: {get g () {return 7}}}; 55 | assert(o.f.g === 7); 56 | assert(delete o.f.g); 57 | assert(o.f.g === undefined); 58 | 59 | o = {b: {get c () {return 7}}}; 60 | assert(o.b["c"] === 7); 61 | assert(delete o.b["c"]); 62 | assert(o.b["c"] === undefined); 63 | 64 | k = {l: "u"} 65 | o = {get u () {return 7}}; 66 | assert(o[k["l"]] === 7); 67 | assert(delete o[k["l"]]); 68 | assert(o[k["l"]] === undefined); 69 | 70 | var kk = "t"; 71 | var ll = "yo"; 72 | o = {t: {t: { get yo (){return 7}}}} 73 | assert(o[kk].t[ll] === 7); 74 | assert(delete o[kk].t[ll]); 75 | assert(o[kk].t[ll] === undefined); 76 | 77 | -------------------------------------------------------------------------------- /test/equality_if.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | 3 | // Basic test 4 | var a = true; 5 | var nota = false; 6 | if (!a) 7 | assert(false); 8 | 9 | if (b) 10 | assert(false); 11 | 12 | var b = "test"; 13 | 14 | if (!(b === "test")) 15 | assert(false); 16 | 17 | if (b !== "test") 18 | assert(false); 19 | 20 | // Equality and strict equality 21 | var c = 21; 22 | 23 | if (c == "21") 24 | assert(true); 25 | else 26 | assert(false); 27 | 28 | if (c === "21") 29 | assert(false); 30 | else 31 | assert(true); 32 | 33 | // UpdateExpression in if 34 | var i = -1; 35 | var j = -1; 36 | 37 | if (j++) 38 | assert(true); 39 | else 40 | assert(false); 41 | 42 | if (j++) 43 | assert(false); 44 | else 45 | assert(true); 46 | 47 | if (++i) 48 | assert(false); 49 | else 50 | assert(true); 51 | 52 | if (++i) 53 | assert(true); 54 | else 55 | assert(false); 56 | 57 | // 0 and "" are false in lua 58 | if (0) 59 | assert(false); 60 | else 61 | assert(true); 62 | 63 | if ("") 64 | assert(false); 65 | else 66 | assert(true); 67 | 68 | // negation 69 | 70 | var zero = !!0 71 | if (zero) 72 | assert(false); 73 | else 74 | assert(true); 75 | 76 | zero = !0 77 | if (zero) 78 | assert(true); 79 | else 80 | assert(false); 81 | 82 | assert(!0); 83 | assert(!""); 84 | assert(!!0 === false); 85 | assert(!!"" === false); 86 | -------------------------------------------------------------------------------- /test/error.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = new Error("Whoops!"); 4 | 5 | assert(a.name === "Error"); 6 | assert(a.message === "Whoops!"); 7 | assert(a.toString() === "Error: Whoops!"); 8 | assert(a instanceof Error); 9 | 10 | try { 11 | throw a; 12 | } catch (e) { 13 | assert(e.name === "Error"); 14 | assert(e.message === "Whoops!"); 15 | assert(e.toString() === "Error: Whoops!"); 16 | assert(e instanceof Error); 17 | } 18 | 19 | // SyntaxError 20 | try{ 21 | throw SyntaxError("syntax"); 22 | }catch(e) { 23 | assert(e.message === "syntax"); 24 | assert(e.name === "SyntaxError"); 25 | } 26 | 27 | // TypeError 28 | try{ 29 | throw TypeError("type"); 30 | }catch(e) { 31 | assert(e.message === "type"); 32 | assert(e.name === "TypeError"); 33 | } 34 | 35 | // SyntaxError 36 | try{ 37 | throw RangeError("range"); 38 | }catch(e) { 39 | assert(e.message === "range"); 40 | assert(e.name === "RangeError"); 41 | } 42 | 43 | // SyntaxError 44 | try{ 45 | throw ReferenceError("reference"); 46 | }catch(e) { 47 | assert(e.message === "reference"); 48 | assert(e.name === "ReferenceError"); 49 | } 50 | 51 | // URIError 52 | try{ 53 | throw URIError("reference"); 54 | }catch(e) { 55 | assert(e.message === "reference"); 56 | assert(e.name === "URIError"); 57 | } 58 | 59 | // EvalError 60 | try{ 61 | throw EvalError("reference"); 62 | }catch(e) { 63 | assert(e.message === "reference"); 64 | assert(e.name === "EvalError"); 65 | } 66 | 67 | // 68 | var a = new RangeError("yolo"); 69 | assert(a instanceof Error); 70 | assert(a.toString === RangeError.prototype.toString); 71 | assert(a.toString === Error.prototype.toString); 72 | assert(!(RangeError.prototype === Error.prototype)); 73 | -------------------------------------------------------------------------------- /test/eval.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // global 4 | i = 12; 5 | samename = 90; 6 | samename2 = 111; 7 | 8 | // upvalue 9 | var j = 1337; 10 | var samename = 990; 11 | var samename2 = 1111; 12 | 13 | (function () { 14 | // local 15 | var k = 21 16 | var samename = 9900; 17 | // global 18 | l = 77; 19 | 20 | assert(eval("i = i + 2; j = j + 2; k = k + 2; l = l + 2; samename = samename + 2; samename2 = samename2 + 2") === 1113); 21 | 22 | assert(i === 14); 23 | assert(j === 1339); 24 | assert(k === 23); 25 | assert(l === 79); 26 | assert(samename === 9902); 27 | assert(samename2 === 1113); 28 | })() 29 | 30 | assert(i === 14); 31 | assert(j === 1339); 32 | assert(l === 79); 33 | assert(samename === 990); 34 | assert(samename2 === 1113); 35 | 36 | var call = eval('"abcde".replace("a", "Z");'); 37 | assert(call === "Zbcde"); 38 | 39 | var pi = eval("with(Math){PI.toFixed(7)}"); 40 | assert(pi === "3.1415927"); 41 | 42 | var a; 43 | b = eval("a = 5"); 44 | assert(a === 5); 45 | assert(b === 5); 46 | -------------------------------------------------------------------------------- /test/expression.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // This is an example to compile 4 | 5 | var b = "azerty"; 6 | var c = { 7 | j: "piou" 8 | }; 9 | var d = 20; 10 | var f = function () { 11 | return "RTT" 12 | }; 13 | 14 | // case "AssignmentExpression": 15 | assert((a = "abcd").replace("b", "Y") === "aYcd"); 16 | // case "Identifier": 17 | assert((b).replace("z", "B") === "aBerty"); 18 | // case "Literal": 19 | assert(("luap").replace("l", "L") === "Luap"); 20 | // case "UnaryExpression": 21 | assert((typeof "rr").replace("string", "hack") === "hack"); 22 | // case "BinaryExpression": 23 | assert(("a" + "b").replace("a", "Z") === "Zb"); 24 | // case "LogicalExpression": 25 | assert(("aaaah" || "ohhhh").replace("a", "Z") === "Zaaah"); 26 | // case "MemberExpression": 27 | assert((c.j).replace("u", "uuuuuuuuuu") === "piouuuuuuuuuu"); 28 | // case "CallExpression": 29 | assert((f()).replace("RTT", "work") === "work"); 30 | // case "NewExpression": 31 | assert((new Boolean()).toString() === "false"); 32 | // case "ThisExpression": 33 | assert((this).toString() === "[object Object]"); 34 | // case "ObjectExpression": 35 | assert(({ 36 | att: 21 37 | }).hasOwnProperty("att")); 38 | // case "UpdateExpression": 39 | assert((d++).toString() === "20"); 40 | assert((++d).toString() === "22"); 41 | // case "ArrayExpression": 42 | assert(([4, 7]).toString() === "4,7"); 43 | // case "ConditionalExpression": 44 | assert((true ? "hehe" : "hoho").replace("e", "a") === "hahe"); 45 | // case "SequenceExpression": 46 | assert(("joe", "henry", "dad").replace("d", "D") === "Dad"); 47 | -------------------------------------------------------------------------------- /test/for.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | for (var i = 0; i < 5; i++) { 4 | 5 | } 6 | 7 | for (var i = 0;;) { 8 | break; 9 | } 10 | 11 | for (; false;) { 12 | 13 | } 14 | 15 | for (;; i = 3) { 16 | break; 17 | } 18 | 19 | for (;;) { 20 | break; 21 | } 22 | 23 | for ((function () { 24 | return "t" 25 | })();;) { 26 | break; 27 | } 28 | 29 | for (var j = 0; j < 2; 30 | (function () { 31 | return "t" 32 | })()) { 33 | j++; 34 | } 35 | -------------------------------------------------------------------------------- /test/for_in.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // Object 4 | var obj = { 5 | a: 1, 6 | b: 2, 7 | c: 3, 8 | 21: 33 9 | }; 10 | 11 | var arr = []; 12 | for (var prop in obj) { 13 | arr.push(prop); 14 | } 15 | 16 | assert(arr.indexOf("a") > -1); 17 | assert(arr.indexOf("b") > -1); 18 | assert(arr.indexOf("c") > -1); 19 | assert(arr.indexOf("21") > -1); 20 | 21 | // Test break 22 | arr = []; 23 | for (var prop in obj) { 24 | break; 25 | arr.push(prop); 26 | } 27 | assert(arr.length === 0); 28 | 29 | // Test continue 30 | arr = []; 31 | for (var prop in obj) { 32 | continue; 33 | arr.push(prop); 34 | } 35 | assert(arr.length === 0); 36 | 37 | arr = []; 38 | for (var prop = 21 in obj) { 39 | arr.push(prop); 40 | } 41 | 42 | assert(arr.indexOf("a") > -1); 43 | assert(arr.indexOf("b") > -1); 44 | assert(arr.indexOf("c") > -1); 45 | assert(arr.indexOf("21") > -1); 46 | 47 | arr = []; 48 | for (prop2 in obj) { 49 | arr.push(prop2); 50 | } 51 | 52 | assert(arr.indexOf("a") > -1); 53 | assert(arr.indexOf("b") > -1); 54 | assert(arr.indexOf("c") > -1); 55 | assert(arr.indexOf("21") > -1); 56 | 57 | // array 58 | var array = ["a", "b", "c"]; 59 | array.prop = "prop"; 60 | arr = []; 61 | for (prop in array) { 62 | arr.push(prop); 63 | } 64 | 65 | assert(arr.indexOf("0") > -1); 66 | assert(arr.indexOf("1") > -1); 67 | assert(arr.indexOf("2") > -1); 68 | assert(arr.indexOf("prop") > -1); 69 | assert(arr.indexOf("length") === -1); 70 | 71 | // String 72 | var str = "abcedf"; 73 | arr = []; 74 | for (prop in str) { 75 | arr.push(prop); 76 | } 77 | assert(arr.indexOf("0") > -1); 78 | assert(arr.indexOf("1") > -1); 79 | assert(arr.indexOf("5") > -1); 80 | assert(arr.indexOf("6") === -1); 81 | assert(arr.indexOf("length") === -1); 82 | 83 | var str = new String("abcedf"); 84 | arr = []; 85 | for (prop in str) { 86 | arr.push(prop); 87 | } 88 | assert(arr.indexOf("0") > -1); 89 | assert(arr.indexOf("1") > -1); 90 | assert(arr.indexOf("5") > -1); 91 | assert(arr.indexOf("6") === -1); 92 | assert(arr.indexOf("length") === -1); 93 | 94 | // Inherited 95 | var triangle = { 96 | a: 1, 97 | b: 2, 98 | c: 3 99 | }; 100 | 101 | function ColoredTriangle() { 102 | this.color = "red"; 103 | } 104 | 105 | ColoredTriangle.prototype = triangle; 106 | 107 | var obj = new ColoredTriangle(); 108 | 109 | arr = [] 110 | for (var prop in obj) { 111 | if (obj.hasOwnProperty(prop)) { 112 | arr.push(prop); 113 | } 114 | } 115 | 116 | assert(arr.indexOf("color") > -1); 117 | assert(arr.indexOf("a") === -1); 118 | assert(arr.indexOf("b") === -1); 119 | assert(arr.indexOf("c") === -1); 120 | 121 | arr = [] 122 | for (var prop in obj) { 123 | arr.push(prop); 124 | } 125 | 126 | assert(arr.indexOf("color") > -1); 127 | assert(arr.indexOf("a") > -1); 128 | assert(arr.indexOf("b") > -1); 129 | assert(arr.indexOf("c") > -1); 130 | -------------------------------------------------------------------------------- /test/function.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // FunctionExpression 4 | var f = function () { 5 | return true; 6 | } 7 | 8 | assert(f()); 9 | 10 | // FunctionDeclaration 11 | function f2() { 12 | return true; 13 | } 14 | 15 | assert(f2()); 16 | 17 | // Anonymous function call 18 | (function () { 19 | assert(true); 20 | })(); 21 | 22 | if (!(function () { 23 | return true; 24 | })()) { 25 | assert(false); 26 | } 27 | 28 | // Params 29 | function f3(a, b) { 30 | assert(a === 1); 31 | assert(b === 2); 32 | } 33 | 34 | f3(1, 2); 35 | 36 | // Arguments 37 | 38 | function f4(a) { 39 | return arguments.length; 40 | } 41 | 42 | assert(f4(1, 2, 3, 4) === 4); 43 | 44 | function f5() { 45 | return arguments[4]; 46 | } 47 | 48 | assert(f5(1, 2, 3, 4, 21) === 21); 49 | 50 | // Variables with same identifier as one of arguments 51 | 52 | (function(a){ 53 | assert(a === 3); 54 | var a = 44; 55 | assert(a === 44); 56 | })(3); 57 | 58 | (function(b){ 59 | assert(b === 32); 60 | b = 11; 61 | assert(b === 11); 62 | })(32); 63 | 64 | var d = 12; 65 | function f(){ 66 | assert(typeof(d) === "undefined"); 67 | var d = 13; 68 | assert(d === 13); 69 | }; 70 | 71 | f(); 72 | -------------------------------------------------------------------------------- /test/function_constructor.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | i = 12; 4 | 5 | var f = new Function("i++"); 6 | f(); 7 | f(); 8 | assert(i === 14); 9 | 10 | var f2 = new Function("return 9"); 11 | assert(f2() === 9); 12 | 13 | var f3 = new Function("return arguments[0] * 2"); 14 | assert(f3(8,9,10) === 16); 15 | 16 | var f4 = new Function("a", "b", "return a * b"); 17 | assert(f4(8,9,10) === 72); 18 | -------------------------------------------------------------------------------- /test/function_declaration.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | assert(fun2() === 44); 4 | 5 | function fun() { 6 | return 44; 7 | } 8 | 9 | function fun2() { 10 | return fun(); 11 | } 12 | 13 | var f3, f6; 14 | 15 | assert(f() === 7); 16 | 17 | function f() { 18 | return 7; 19 | } 20 | 21 | f2 = function () { 22 | return 9; 23 | } 24 | 25 | f3 = function () { 26 | return 11; 27 | } 28 | 29 | f4 = function f5() { 30 | return 13; 31 | } 32 | 33 | f6 = function f7() { 34 | return 15; 35 | } 36 | 37 | assert(f4() === 13); 38 | assert(f6() === 15); 39 | 40 | ((function () { 41 | 42 | var f9; 43 | 44 | assert(f10() === 17); 45 | 46 | function f10() { 47 | return 17; 48 | } 49 | 50 | f8 = function () { 51 | return 19; 52 | } 53 | 54 | f9 = function () { 55 | return 111; 56 | } 57 | 58 | assert(f10() === 17); 59 | assert(f8() === 19); 60 | assert(f9() === 111); 61 | 62 | })()) 63 | 64 | assert(f8() === 19); 65 | -------------------------------------------------------------------------------- /test/function_prototype.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // Call 4 | 5 | var myFun = function (a, b, c) { 6 | return a + b + c; 7 | } 8 | 9 | assert(myFun.call(undefined, 1, 1, 1) === 3); 10 | 11 | var myFun2 = function () { 12 | return 21; 13 | } 14 | 15 | assert(myFun2.call(undefined) === 21) 16 | 17 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call 18 | // Test 1 19 | function Product(name, price) { 20 | this.name = name; 21 | this.price = price; 22 | 23 | if (price < 0) 24 | throw ('Cannot create product ' + name + ' with a negative price'); 25 | return this; 26 | } 27 | 28 | function Food(name, price) { 29 | Product.call(this, name, price); 30 | this.category = 'food'; 31 | } 32 | 33 | Food.prototype = Object.create(Product.prototype); 34 | 35 | function Toy(name, price) { 36 | Product.call(this, name, price); 37 | this.category = 'toy'; 38 | } 39 | 40 | Toy.prototype = Object.create(Product.prototype); 41 | 42 | var cheese = new Food('feta', 5); 43 | var fun = new Toy('robot', 40); 44 | 45 | assert(cheese.name === "feta"); 46 | assert(cheese.price === 5); 47 | assert(fun.name === "robot"); 48 | assert(fun.price === 40); 49 | 50 | var animals = [{ 51 | species: 'Lion', 52 | name: 'King' 53 | }, { 54 | species: 'Whale', 55 | name: 'Fail' 56 | }]; 57 | 58 | // Test 2 59 | var lines = [] 60 | for (var i = 0; i < animals.length; i++) { 61 | (function (i) { 62 | this.print = function () { 63 | lines.push('#' + i + ' ' + this.species + ': ' + this.name); 64 | } 65 | this.print(); 66 | }).call(animals[i], i); 67 | } 68 | 69 | assert(lines[0] === "#0 Lion: King"); 70 | assert(lines[1] === "#1 Whale: Fail"); 71 | 72 | // Bind 73 | 74 | var f = function (a, b, c) { 75 | return a * b * c; 76 | } 77 | 78 | var f2 = f.bind(undefined, 21) 79 | assert(f2(6, 7, 8) === 882) 80 | 81 | this.x = 9; 82 | var module = { 83 | x: 81, 84 | getX: function () { 85 | return this.x; 86 | } 87 | }; 88 | 89 | module.getX(); // 81 90 | 91 | var getX = module.getX; 92 | getX(); 93 | 94 | var boundGetX = getX.bind(module); 95 | assert(boundGetX() === 81); 96 | 97 | // 98 | function list() { 99 | return Array.prototype.slice.call(arguments); 100 | } 101 | 102 | var list1 = list(1, 2, 3); 103 | 104 | var leadingThirtysevenList = list.bind(undefined, 37); 105 | 106 | var list2 = leadingThirtysevenList(); // [37] 107 | var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3] 108 | assert(list2.length === 1); 109 | assert(list2[0] === 37); 110 | assert(list3.length === 4); 111 | assert(list3[0] === 37); 112 | assert(list3[1] === 1); 113 | assert(list3[2] === 2); 114 | assert(list3[3] === 3); 115 | 116 | // Apply 117 | 118 | assert(myFun.apply(undefined, [1, 2, 3]) === 6); 119 | assert(myFun2.apply(undefined) === 21); 120 | 121 | // 122 | Function.prototype.construct = function (aArgs) { 123 | var fConstructor = this, 124 | fNewConstr = function () { 125 | fConstructor.apply(this, aArgs); 126 | }; 127 | fNewConstr.prototype = fConstructor.prototype; 128 | return new fNewConstr(); 129 | }; 130 | 131 | function MyConstructor() { 132 | for (var nProp = 0; nProp < arguments.length; nProp++) { 133 | this["property" + nProp] = arguments[nProp]; 134 | } 135 | } 136 | 137 | var myArray = [4, "Hello world!", false]; 138 | var myInstance = MyConstructor.construct(myArray); 139 | 140 | assert(myInstance.property1 === "Hello world!"); 141 | assert(myInstance instanceof MyConstructor); 142 | -------------------------------------------------------------------------------- /test/getter_setter.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var o = {v: 11, get getV () {return this.v}}; 4 | assert(o.getV === 11); 5 | 6 | var o2 = {v: 12, set setV (r) {return this.v = r}}; 7 | o2.setV = 42; 8 | assert(o2.v === 42); 9 | 10 | var o3 = {v: 11, get 1 () {return this.v}}; 11 | assert(o3["1"] === 11); 12 | 13 | var o4 = {v: 12, set 1 (r) {return this.v = r}}; 14 | o4["1"] = 42; 15 | assert(o4.v === 42); 16 | 17 | var o5 = {v: 21}; 18 | Object.defineProperty(o5, "test", {get: function() {return this.v}}); 19 | assert(o5.test === 21); 20 | Object.defineProperty(o5, "test2", {set: function(r) {this.v = r}}); 21 | o5.test2 = 33; 22 | assert(o5.test === 33); 23 | Object.defineProperty(o5, "test3", {get: function() {return this.v}, set: function(r){ this.v = r}}); 24 | assert(o5.test3 === 33); 25 | o5.test3 = 14 26 | assert(o5.test3 === 14); 27 | 28 | // 29 | var obj = { 30 | get latest () { 31 | if (this.log.length == 0) return undefined; 32 | return this.log[this.log.length - 1] 33 | }, 34 | set current (str) { 35 | return this.log[this.log.length - 1] = str; 36 | }, 37 | log: [] 38 | } 39 | 40 | obj.log.push("pp") 41 | assert(obj.latest === "pp"); 42 | obj.current = 7; 43 | assert(obj.latest === 7); 44 | 45 | // Mozilla example 46 | 47 | function Archiver() { 48 | var temperature = null; 49 | var archive = []; 50 | 51 | Object.defineProperty(this, "temperature",{ 52 | get: function() { 53 | return temperature; 54 | }, 55 | set: function(value) { 56 | temperature = value; 57 | archive.push({val: temperature}); 58 | } 59 | }); 60 | 61 | this.getArchive = function() {return archive;}; 62 | } 63 | 64 | var arc = new Archiver(); 65 | arc.temperature; 66 | arc.temperature = 11; 67 | arc.temperature = 13; 68 | var result = arc.getArchive(); // [{val: 11}, {val: 13}] 69 | 70 | assert(result[0].val === 11); 71 | assert(result[1].val === 13); 72 | -------------------------------------------------------------------------------- /test/getter_setter_inheritance.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var Base = function(){}; 4 | Base.prototype = {get g () {return this.att}, set s (v) {this.z = v}}; 5 | 6 | var instance = new Base(); 7 | 8 | assert(instance.g === undefined); 9 | instance.att = 21; 10 | assert(instance.g === 21); 11 | 12 | instance.s = 44; 13 | assert(Base.prototype.z === undefined); 14 | assert(instance.z === 44); 15 | assert(Base.prototype.s === undefined); 16 | assert(instance.s=== undefined ); 17 | -------------------------------------------------------------------------------- /test/global_functions.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // isFinite 4 | assert(!isFinite(Infinity)); 5 | assert(!isFinite(NaN)); 6 | assert(!isFinite(-Infinity)); 7 | assert(isFinite(0)); 8 | assert(isFinite(2e64)); 9 | assert(isFinite("0")); 10 | 11 | // IsNan 12 | assert(isNaN(NaN)); 13 | assert(isNaN(undefined)); 14 | assert(isNaN({})); 15 | assert(isNaN({ 16 | a: 11 17 | })); 18 | assert(isNaN(isNaN)); 19 | 20 | assert(!isNaN(true)); 21 | assert(!isNaN(null)); 22 | assert(!isNaN(37)); 23 | assert(!isNaN({valueOf: function(){return 3}})); 24 | assert(isNaN({})); 25 | 26 | // strings 27 | assert(isNaN("NaN")); 28 | assert(!isNaN("37")); 29 | assert(!isNaN("37.37")); 30 | assert(!isNaN("")); 31 | assert(!isNaN(" ")); 32 | assert(isNaN("blabla")); 33 | 34 | //assert(isNaN(new Date()); // false 35 | //assert(isNaN(new Date().toString()); // true 36 | 37 | // parseFloat 38 | 39 | assert(parseFloat("3.14") === 3.14); 40 | assert(parseFloat("314e-2") === 3.14); 41 | assert(parseFloat("0.0314E+2") === 3.14); 42 | assert(isNaN(parseFloat("FF2"))); 43 | 44 | // parseInt 45 | 46 | assert(parseInt(" 0xF", 16) === 15); 47 | assert(parseInt(" F", 16) === 15); 48 | assert(parseInt("17", 8) === 15); 49 | assert(parseInt(021, 8) === 15); 50 | assert(parseInt("015", 10) === 15); 51 | assert(parseInt(15.99, 10) === 15); 52 | assert(parseInt("FXX123", 16) === 15); 53 | assert(parseInt("1111", 2) === 15); 54 | assert(parseInt("15*3", 10) === 15); 55 | assert(parseInt("15e2", 10) === 15); 56 | assert(parseInt("15px", 10) === 15); 57 | assert(parseInt("12", 13) === 15); 58 | 59 | assert(isNaN(parseInt("Hello", 8))); 60 | assert(isNaN(parseInt("546", 2))); 61 | 62 | assert(parseInt("-F", 16) === -15); 63 | assert(parseInt("-0F", 16) === -15); 64 | assert(parseInt("-0XF", 16) === -15); 65 | assert(parseInt(-15.1, 10) === -15); 66 | assert(parseInt(" -17", 8) === -15); 67 | assert(parseInt(" -15", 10) === -15); 68 | assert(parseInt("-1111", 2) === -15); 69 | assert(parseInt("-15e1", 10) === -15); 70 | assert(parseInt("-12", 13) === -15); 71 | 72 | assert(parseInt("0e0", 16) === 224); 73 | -------------------------------------------------------------------------------- /test/if.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | 3 | var a = 0; 4 | 5 | if (true) { 6 | a = 1; 7 | } 8 | assert(a === 1); 9 | 10 | if (false) { 11 | a = 2; 12 | } else { 13 | a = 3; 14 | } 15 | 16 | assert(a === 3); 17 | 18 | if (false) { 19 | a = 4; 20 | } else if (false) { 21 | a = 5; 22 | } else if (true) { 23 | a = 6; 24 | } 25 | 26 | assert(a === 6); 27 | 28 | if (false) { 29 | a = 7; 30 | } else if (false) { 31 | a = 8; 32 | } else if (false) { 33 | a = 9; 34 | } else { 35 | a = 10; 36 | } 37 | 38 | assert(a === 10); 39 | -------------------------------------------------------------------------------- /test/in.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); 4 | assert(0 in trees) 5 | assert(3 in trees) 6 | assert(!(6 in trees)) 7 | assert(!("bay" in trees)) 8 | assert("length" in trees) 9 | 10 | var mycar = { 11 | make: "Honda", 12 | model: "Accord", 13 | year: 1998 14 | }; 15 | assert("make" in mycar) 16 | assert("model" in mycar) 17 | 18 | var mycar = { 19 | make: "Honda", 20 | model: "Accord", 21 | year: 1998 22 | }; 23 | delete mycar.make; 24 | assert(!("make" in mycar)); 25 | 26 | var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); 27 | delete trees[3]; 28 | assert(!(3 in trees)); 29 | 30 | assert("toString" in {}); 31 | -------------------------------------------------------------------------------- /test/issues/issue_13.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | // https://github.com/PaulBernier/castl/issues/13 3 | var i = 0; 4 | var a = ++i && true; 5 | assert(i === 1); 6 | assert(a === true); 7 | 8 | i = -1; 9 | a = ++i && true; 10 | assert(i === 0); 11 | assert(a === 0); 12 | 13 | i = 0; 14 | a = i++ && true; 15 | assert(i === 1); 16 | assert(a === 0); 17 | 18 | i = -1; 19 | a = i++ && true; 20 | assert(i === 0); 21 | assert(a === true); 22 | 23 | ///////// OR 24 | 25 | var j = 1; 26 | var b = j++ || true; 27 | assert(j === 2); 28 | assert(b === 1); 29 | 30 | j = 1; 31 | b = ++j || true; 32 | assert(j === 2); 33 | assert(b === 2); 34 | 35 | j = -1; 36 | b = j++ || true; 37 | assert(j === 0); 38 | assert(b === -1); 39 | 40 | j = -1; 41 | b = ++j || true; 42 | assert(j === 0); 43 | assert(b === true); 44 | -------------------------------------------------------------------------------- /test/json.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // stringify 4 | assert(JSON.stringify(undefined) === undefined); 5 | assert(JSON.stringify(null) === "null"); 6 | assert(JSON.stringify({}) === "{}"); 7 | assert(JSON.stringify(0) === "0"); 8 | assert(JSON.stringify(21) === "21"); 9 | assert(JSON.stringify(true) === "true"); 10 | assert(JSON.stringify(false) === "false"); 11 | assert(JSON.stringify("foo") === '"foo"'); 12 | assert(JSON.stringify([1, "false", false]) === '[1,"false",false]'); 13 | assert(JSON.stringify({ 14 | x: 5 15 | }) === '{"x":5}'); 16 | assert(JSON.stringify(null) === 'null'); 17 | assert(JSON.stringify(undefined) === undefined); 18 | 19 | // ordering of keys pb 20 | // var test = {x: 3, t: ["op", true, "true", null, {k: 8}], j: true, uu: {arg: "yol"}} 21 | // console.log(JSON.stringify(test)); 22 | // assert(JSON.stringify(test) === '{"x":3,"t":["op",true,"true",null,{"k":8}],"j":true,"uu":{"arg":"yol"}}') 23 | 24 | // parse 25 | var ret = JSON.parse('{"a": [11, "z"]}'); 26 | assert(ret.a[0] === 11); 27 | assert(ret.a[1] === "z"); 28 | assert(ret.a.length === 2); 29 | assert(ret instanceof Object); 30 | assert(ret.a.push("t")); 31 | 32 | ret = JSON.parse('true'); 33 | assert(ret); 34 | assert(typeof (ret) === "boolean"); 35 | 36 | ret = JSON.parse('"foo"'); 37 | assert(ret === "foo") 38 | 39 | ret = JSON.parse('[1, 5, "false"]'); 40 | assert(ret instanceof Array); 41 | assert(ret[0] === 1); 42 | assert(ret[1] === 5); 43 | assert(ret[2] === "false"); 44 | 45 | ret = JSON.parse('null'); 46 | assert(ret === null); 47 | 48 | test = '{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}}'; 49 | 50 | ret = JSON.parse(test); 51 | assert(ret.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso[0] === "GML"); 52 | 53 | // reversibility 54 | // works but order of keys doesn't match 55 | //assert(JSON.stringify(JSON.parse(test)) === test); 56 | -------------------------------------------------------------------------------- /test/label.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var ret = []; 4 | var i, j 5 | 6 | // break loop1 7 | loop1: 8 | for (i = 0; i < 3; i++) { //The first for statement is labeled "loop1" 9 | loop2: for (j = 0; j < 3; j++) { //The second for statement is labeled "loop2" 10 | if (i == 1 && j == 1) { 11 | break loop1; 12 | } 13 | ret.push(i, j); 14 | } 15 | } 16 | 17 | assert(ret.length === 8); 18 | assert(ret[0] === 0); 19 | assert(ret[1] === 0); 20 | assert(ret[2] === 0); 21 | assert(ret[3] === 1); 22 | assert(ret[4] === 0); 23 | assert(ret[5] === 2); 24 | assert(ret[6] === 1); 25 | assert(ret[7] === 0); 26 | assert(i === 1); 27 | assert(j === 1); 28 | 29 | // break loop2 30 | ret = [] 31 | loop1: 32 | for (i = 0; i < 3; i++) { //The first for statement is labeled "loop1" 33 | loop2: for (j = 0; j < 3; j++) { //The second for statement is labeled "loop2" 34 | if (i == 1 && j == 1) { 35 | break loop2; 36 | } 37 | ret.push(i, j); 38 | } 39 | } 40 | 41 | assert(ret.length === 14); 42 | assert(ret[0] === 0); 43 | assert(ret[1] === 0); 44 | assert(ret[2] === 0); 45 | assert(ret[3] === 1); 46 | assert(ret[4] === 0); 47 | assert(ret[5] === 2); 48 | assert(ret[6] === 1); 49 | assert(ret[7] === 0); 50 | assert(ret[8] === 2); 51 | assert(ret[9] === 0); 52 | assert(ret[10] === 2); 53 | assert(ret[11] === 1); 54 | assert(ret[12] === 2); 55 | assert(ret[13] === 2); 56 | assert(i === 3); 57 | assert(j === 3); 58 | 59 | // Continue loop1 60 | ret = [] 61 | loop1: 62 | for (i = 0; i < 3; i++) { //The first for statement is labeled "loop1" 63 | loop2: for (j = 0; j < 3; j++) { //The second for statement is labeled "loop2" 64 | if (i == 1 && j == 1) { 65 | continue loop1; 66 | } 67 | ret.push(i, j); 68 | } 69 | } 70 | 71 | assert(ret.length === 14); 72 | assert(ret[0] === 0); 73 | assert(ret[1] === 0); 74 | assert(ret[2] === 0); 75 | assert(ret[3] === 1); 76 | assert(ret[4] === 0); 77 | assert(ret[5] === 2); 78 | assert(ret[6] === 1); 79 | assert(ret[7] === 0); 80 | assert(ret[8] === 2); 81 | assert(ret[9] === 0); 82 | assert(ret[10] === 2); 83 | assert(ret[11] === 1); 84 | assert(ret[12] === 2); 85 | assert(ret[13] === 2); 86 | assert(i === 3); 87 | assert(j === 3); 88 | 89 | // Continue loop2 90 | ret = [] 91 | loop1: 92 | for (i = 0; i < 3; i++) { //The first for statement is labeled "loop1" 93 | loop2: for (j = 0; j < 3; j++) { //The second for statement is labeled "loop2" 94 | if (i == 1 && j == 1) { 95 | continue loop2; 96 | } 97 | ret.push(i, j); 98 | } 99 | } 100 | 101 | assert(ret.length === 16); 102 | assert(ret[0] === 0); 103 | assert(ret[1] === 0); 104 | assert(ret[2] === 0); 105 | assert(ret[3] === 1); 106 | assert(ret[4] === 0); 107 | assert(ret[5] === 2); 108 | assert(ret[6] === 1); 109 | assert(ret[7] === 0); 110 | assert(ret[8] === 1); 111 | assert(ret[9] === 2); 112 | assert(ret[10] === 2); 113 | assert(ret[11] === 0); 114 | assert(ret[12] === 2); 115 | assert(ret[13] === 1); 116 | assert(ret[14] === 2); 117 | assert(ret[15] === 2); 118 | assert(i === 3); 119 | assert(j === 3); 120 | 121 | // Not iteration statement 122 | i, j = 0, j; 123 | label1:{ 124 | i = 54; 125 | break label1; 126 | j = 21; 127 | } 128 | 129 | assert(i === 54); 130 | assert(j === 0); 131 | -------------------------------------------------------------------------------- /test/logical_expression.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = false || "ok"; 4 | assert(a === "ok"); 5 | var b = "ok" || false; 6 | assert(b === "ok"); 7 | var c = "ok" || "ok2"; 8 | assert(c === "ok"); 9 | var d = false || null; 10 | assert(d === null); 11 | 12 | 13 | var a = null && "ok"; 14 | assert(a === null); 15 | var b = "ok" && null; 16 | assert(b === null); 17 | var c = "ok" && "ok2"; 18 | assert(c === "ok2"); 19 | var d = null && false ; 20 | assert(d === null); 21 | -------------------------------------------------------------------------------- /test/math.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // abs 4 | assert(Math.abs(-6) === 6); 5 | assert(Math.abs(7) === 7); 6 | assert(Math.abs(null) === 0); 7 | assert(Math.abs("-5") === 5); 8 | assert(Number.isNaN(Math.abs("str"))); 9 | assert(Number.isNaN(Math.abs())); 10 | -------------------------------------------------------------------------------- /test/modulo.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = [0, 1, -1, 2, -2, 1000, 100000, -21, 21, 1.234, 5.789, -3.2678, -7.896]; 4 | 5 | var result = [[NaN,0,0,0,0,0,0,0,0,0,0,0,0],[NaN,0,0,1,1,1,1,1,1,1,1,1,1],[NaN,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],[NaN,0,0,0,0,2,2,2,2,0.766,2,2,2],[NaN,0,0,0,0,-2,-2,-2,-2,-0.766,-2,-2,-2],[NaN,0,0,0,0,0,1000,13,13,0.4600000000000115,4.292000000000051,0.05320000000005631,5.104000000000012],[NaN,0,0,0,0,0,0,19,19,0.3420000000011516,0.814000000005155,2.0522000000056315,5.05600000000117],[NaN,0,0,-1,-1,-21,-21,0,0,-0.02200000000000024,-3.633000000000001,-1.393200000000001,-5.208],[NaN,0,0,1,1,21,21,0,0,0.02200000000000024,3.633000000000001,1.393200000000001,5.208],[NaN,0.23399999999999999,0.23399999999999999,1.234,1.234,1.234,1.234,1.234,1.234,0,1.234,1.234,1.234],[NaN,0.7889999999999997,0.7889999999999997,1.7889999999999997,1.7889999999999997,5.789,5.789,5.789,5.789,0.8529999999999998,0,2.5212,5.789],[NaN,-0.2677999999999998,-0.2677999999999998,-1.2677999999999998,-1.2677999999999998,-3.2678,-3.2678,-3.2678,-3.2678,-0.7997999999999998,-3.2678,0,-3.2678],[NaN,-0.8959999999999999,-0.8959999999999999,-1.896,-1.896,-7.896,-7.896,-7.896,-7.896,-0.492,-2.107,-1.3604000000000003,0]] 6 | 7 | var tmp; 8 | for(i = 0 ; i -1); 89 | assert(keys.indexOf("1") > -1); 90 | assert(keys.indexOf("2") > -1); 91 | 92 | var obj = { 93 | 0: "a", 94 | 1: "b", 95 | 2: "c" 96 | }; 97 | keys = Object.keys(obj); 98 | assert(keys.indexOf("0") > -1); 99 | assert(keys.indexOf("1") > -1); 100 | assert(keys.indexOf("2") > -1); 101 | 102 | obj = { 103 | 100: "a", 104 | 2: "b", 105 | 7: "c" 106 | }; 107 | keys = Object.keys(obj); 108 | assert(keys.indexOf("100") > -1); 109 | assert(keys.indexOf("7") > -1); 110 | assert(keys.indexOf("2") > -1); 111 | 112 | obj = { 113 | "lol": "a", 114 | 2: "b", 115 | 7: "c" 116 | }; 117 | keys = Object.keys(obj); 118 | assert(keys.indexOf("lol") > -1); 119 | assert(keys.indexOf("7") > -1); 120 | assert(keys.indexOf("2") > -1); 121 | 122 | // getPrototypeOf 123 | obj = {}; 124 | assert(Object.getPrototypeOf(obj) === Object.prototype); 125 | arr = []; 126 | assert(Object.getPrototypeOf(arr) === Array.prototype); 127 | var num = new Number(6); 128 | assert(Object.getPrototypeOf(num) === Number.prototype); 129 | var str = new String("6"); 130 | assert(Object.getPrototypeOf(str) === String.prototype); 131 | var bool = new Boolean(true); 132 | assert(Object.getPrototypeOf(bool) === Boolean.prototype); 133 | var fun = function () {}; 134 | assert(Object.getPrototypeOf(fun) === Function.prototype); 135 | 136 | var MyClass = function () {}; 137 | var instance = new MyClass(); 138 | assert(Object.getPrototypeOf(instance) === MyClass.prototype); 139 | 140 | // function as argument of Object.methods 141 | var f = function(){}; 142 | f.a = 21; 143 | var z = Object.create(f); 144 | assert(typeof(z) === "object"); 145 | assert(z.a == 21); 146 | Object.keys(f); 147 | z = Object.getOwnPropertyDescriptor(f, "a"); 148 | assert(z.value === 21); 149 | z = Object.getOwnPropertyDescriptor(f, "e"); 150 | assert(z === undefined); 151 | Object.defineProperty(f, "b", {value: 99, writable: true, enumerable: true}); 152 | assert(f.b === 99); 153 | Object.getOwnPropertyNames(f); 154 | assert(Object.getPrototypeOf(f) === Function.prototype); 155 | 156 | -------------------------------------------------------------------------------- /test/object_prototype.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // hasOwnProperty 4 | var o = new Object(); 5 | o.prop = 'exists'; 6 | 7 | function changeO() { 8 | o.newprop = o.prop; 9 | delete o.prop; 10 | } 11 | 12 | assert(o.hasOwnProperty('prop')); 13 | changeO(); 14 | assert(!o.hasOwnProperty('prop')); 15 | 16 | o = new Object(); 17 | o.prop = 'exists'; 18 | assert(o.hasOwnProperty('prop')); 19 | assert(!o.hasOwnProperty('toString')); 20 | assert(!o.hasOwnProperty('hasOwnProperty')); 21 | 22 | var foo = { 23 | hasOwnProperty: function () { 24 | return false; 25 | }, 26 | bar: 'Here be dragons' 27 | }; 28 | 29 | assert(!foo.hasOwnProperty('bar')); 30 | assert(({}).hasOwnProperty.call(foo, 'bar')); 31 | assert(Object.prototype.hasOwnProperty.call(foo, 'bar')); 32 | 33 | function f(){}; 34 | f.a = 21; 35 | assert(f.hasOwnProperty("a")); 36 | 37 | // toString 38 | 39 | var toString = Object.prototype.toString; 40 | 41 | var obj = {}; 42 | var str = ""; 43 | var num = 12; 44 | var bool = true; 45 | var array = [1, 2, 3]; 46 | var fun = function () {} 47 | 48 | assert(toString.call(undefined) === "[object Undefined]"); 49 | assert(toString.call(null) === "[object Null]"); 50 | assert(toString.call(array) === "[object Array]"); 51 | assert(toString.call(bool) === "[object Boolean]"); 52 | assert(toString.call(num) === "[object Number]"); 53 | assert(toString.call(str) === "[object String]"); 54 | assert(toString.call(obj) === "[object Object]"); 55 | 56 | // IsPrototypeOf 57 | var o = new Object() 58 | assert(Object.prototype.isPrototypeOf(o)) 59 | assert(!Object.isPrototypeOf(o)) 60 | 61 | function Fee() { 62 | } 63 | 64 | function Fi() { 65 | } 66 | Fi.prototype = new Fee(); 67 | 68 | function Fo() { 69 | } 70 | Fo.prototype = new Fi(); 71 | 72 | function Fum() { 73 | } 74 | Fum.prototype = new Fo(); 75 | 76 | var fum = new Fum(); 77 | 78 | 79 | assert(Fee.prototype.isPrototypeOf(fum)) 80 | assert(Fi.prototype.isPrototypeOf(fum)) 81 | assert(Fo.prototype.isPrototypeOf(fum)) 82 | assert(Fum.prototype.isPrototypeOf(fum)) 83 | 84 | -------------------------------------------------------------------------------- /test/objects_comparison.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | assert(0 < new Boolean(true)); 4 | assert(!(0 < new Boolean(false))); 5 | assert(!(new Boolean(true) < 1)); 6 | assert(new Boolean(false) < 1); 7 | assert("0" < new Boolean(true)); 8 | assert(!("0" < new Boolean(false))); 9 | assert(!(new Boolean(true) < "1")); 10 | assert(new Boolean(false) < "1"); 11 | assert(false < new Boolean(true)); 12 | assert(!(false < new Boolean(false))); 13 | assert(!(new Boolean(true) < true)); 14 | assert(new Boolean(false) < true); 15 | 16 | assert(0 < new Number(1)); 17 | assert(!(0 < new Number(0))); 18 | assert(!(new Number(1) < 1)); 19 | assert(new Number(0) < 1); 20 | assert("0" < new Number(1)); 21 | assert(!("0" < new Number(0))); 22 | assert(!(new Number(1) < "1")); 23 | assert(new Number(0) < "1"); 24 | assert(0 < new Number(1)); 25 | assert(!(0 < new Number(0))); 26 | assert(!(new Number(1) < 1)); 27 | assert(new Number(0) < 1); 28 | 29 | assert(0 < new String("1")); 30 | assert(!(0 < new String("0"))); 31 | assert(!(new String("1") < 1)); 32 | assert(new String("0") < 1); 33 | assert("0" < new String("1")); 34 | assert(!("0" < new String("0"))); 35 | assert(!(new String("1") < "1")); 36 | assert(new String("0") < "1"); 37 | assert(0 < new String("1")); 38 | assert(!(0 < new String("0"))); 39 | assert(!(new String("1") < 1)); 40 | assert(new String("0") < 1); 41 | 42 | var d1 = new Date(1989, 3, 15); 43 | var d2 = new Date(1989, 3, 16); 44 | assert(d1 < d2); 45 | 46 | var o1 = {valueOf: function(){return "a"}}; 47 | var o2 = {valueOf: function(){return "b"}}; 48 | 49 | assert(o1 < o2); 50 | 51 | var o3 = {toString: function(){return "a"}}; 52 | var o4 = {toString: function(){return "b"}}; 53 | 54 | assert(o3 < o4); 55 | 56 | var o5 = {valueOf: function(){return "b"}, toString: function(){return "a";}}; 57 | var o6 = {valueOf: function(){return "a"}, toString: function(){return "b";}}; 58 | 59 | assert(o5 > o6); 60 | 61 | 62 | -------------------------------------------------------------------------------- /test/plus_minus_operator.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | 3 | assert(("1" + 1) === "11"); 4 | assert((1 + 1) === 2); 5 | 6 | var a = "21"; 7 | 8 | assert((-a + 1) === -20); 9 | -------------------------------------------------------------------------------- /test/regexp.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = new RegExp("rr", "gim"); 4 | var b = new RegExp(a); 5 | var c = RegExp(a); 6 | 7 | assert(a.source === "rr"); 8 | assert(a.global === true); 9 | assert(a.ignoreCase === true); 10 | assert(a.multiline === true); 11 | 12 | assert(b.source === "rr"); 13 | assert(b.global === true); 14 | assert(b.ignoreCase === true); 15 | assert(b.multiline === true); 16 | 17 | assert(c.source === "rr"); 18 | assert(c.global === true); 19 | assert(c.ignoreCase === true); 20 | assert(c.multiline === true); 21 | 22 | assert(!(a === b)); 23 | assert(a === c); 24 | 25 | var d = new RegExp({toString: function(){return "test"}}); 26 | assert(d.source === "test"); 27 | -------------------------------------------------------------------------------- /test/regexp_prototype.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // tonumber 4 | assert(Number.isNaN(-(/g/))); 5 | 6 | // instanceof 7 | var re = /\d/g; 8 | assert(re instanceof RegExp); 9 | re = new RegExp("\\d", "gi"); 10 | assert(re instanceof RegExp); 11 | 12 | // test 13 | var str = "abcd32fzei8fzeji9"; 14 | 15 | re = /\d/g; 16 | 17 | assert(re.test(str)); 18 | assert(re.lastIndex === 5); 19 | assert(re.test(str)); 20 | assert(re.lastIndex === 6); 21 | assert(re.test(str)); 22 | assert(re.lastIndex === 11); 23 | 24 | var str2 = "3"; 25 | 26 | assert(!re.test(str2)); 27 | assert(re.lastIndex === 0); 28 | 29 | re = /\d/; 30 | assert(re.test(str2)); 31 | assert(re.lastIndex === 0); 32 | 33 | assert(re.test(str)); 34 | assert(re.lastIndex === 0); 35 | assert(re.test(str)); 36 | assert(re.lastIndex === 0); 37 | 38 | assert(!re.test("abdef")); 39 | assert(re.lastIndex === 0); 40 | 41 | re = /(\d)+/g; 42 | assert(re.test("abcd47fd")); 43 | assert(re.lastIndex === 6); 44 | 45 | // exec 46 | 47 | re = /d(b+)(d)/ig; 48 | var result = re.exec("cdbBdbsbz"); 49 | assert(result.length === 3); 50 | assert(result[0] === "dbBd"); 51 | assert(result[1] === "bB"); 52 | assert(result[2] === "d"); 53 | assert(re.lastIndex === 5); 54 | assert(result.index === 1); 55 | assert(result.input === "cdbBdbsbz"); 56 | 57 | re = /d(b+)(d)/i; 58 | result = re.exec("cdbBdbsbz"); 59 | assert(result.length === 3); 60 | assert(result[0] === "dbBd"); 61 | assert(result[1] === "bB"); 62 | assert(result[2] === "d"); 63 | assert(re.lastIndex === 0); 64 | assert(result.index === 1); 65 | assert(result.input === "cdbBdbsbz"); 66 | 67 | re = /d(b+)(d)/; 68 | result = re.exec("cdbBdbsbz"); 69 | assert(result === null); 70 | 71 | var myRe = /ab*/g; 72 | var str = "abbcdefabh"; 73 | var myArray; 74 | var ret = []; 75 | while ((myArray = myRe.exec(str)) !== null) { 76 | var msg = "Found " + myArray[0] + ". "; 77 | msg += "Next match starts at " + myRe.lastIndex; 78 | ret.push(msg); 79 | } 80 | 81 | assert(ret.length === 2); 82 | assert(ret[0] === "Found abb. Next match starts at 3"); 83 | assert(ret[1] === "Found ab. Next match starts at 9"); 84 | 85 | var matches = /(hello \S+)/.exec('This is a hello world!'); 86 | assert(matches[0] === "hello world!"); 87 | 88 | // difference of behavior between string.match and regexp.exec 89 | var re_once = /([a-z])([A-Z])/; 90 | var re_glob = /([a-z])([A-Z])/g; 91 | 92 | str = "aAbBcC"; 93 | 94 | ret = str.match(re_once); 95 | assert(ret.length === 3); 96 | assert(ret[0] === "aA"); 97 | assert(ret[1] === "a"); 98 | assert(ret[2] === "A"); 99 | assert(ret.index === 0); 100 | assert(ret.input === str); 101 | 102 | ret = str.match(re_glob); 103 | assert(ret.length === 3); 104 | assert(ret[0] === "aA"); 105 | assert(ret[1] === "bB"); 106 | assert(ret[2] === "cC"); 107 | assert(typeof (ret.index) === "undefined"); 108 | assert(typeof (ret.input) === "undefined"); 109 | 110 | ret = re_once.exec(str); 111 | assert(ret.length === 3); 112 | assert(ret[0] === "aA"); 113 | assert(ret[1] === "a"); 114 | assert(ret[2] === "A"); 115 | assert(ret.index === 0); 116 | assert(ret.input === str); 117 | assert(re_once.lastIndex === 0); 118 | 119 | ret = re_once.exec(str); 120 | assert(ret.length === 3); 121 | assert(ret[0] === "aA"); 122 | assert(ret[1] === "a"); 123 | assert(ret[2] === "A"); 124 | assert(ret.index === 0); 125 | assert(ret.input === str); 126 | assert(re_once.lastIndex === 0); 127 | 128 | ret = re_glob.exec(str); 129 | assert(ret.length === 3); 130 | assert(ret[0] === "aA"); 131 | assert(ret[1] === "a"); 132 | assert(ret[2] === "A"); 133 | assert(ret.index === 0); 134 | assert(ret.input === str); 135 | assert(re_glob.lastIndex === 2); 136 | 137 | ret = re_glob.exec(str); 138 | assert(ret.length === 3); 139 | assert(ret[0] === "bB"); 140 | assert(ret[1] === "b"); 141 | assert(ret[2] === "B"); 142 | assert(ret.index === 2); 143 | assert(ret.input === str); 144 | assert(re_glob.lastIndex === 4); 145 | 146 | ret = re_glob.exec(str); 147 | assert(ret.length === 3); 148 | assert(ret[0] === "cC"); 149 | assert(ret[1] === "c"); 150 | assert(ret[2] === "C"); 151 | assert(ret.index === 4); 152 | assert(ret.input === str); 153 | assert(re_glob.lastIndex === 6); 154 | -------------------------------------------------------------------------------- /test/sanitize_identifier.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | 3 | // Latin-1 Supplement 4 | var fÿz = 21; 5 | assert(fÿz === 21); 6 | 7 | // Conflict with jssupport lib 8 | var jssupport = 21; 9 | assert(("1" + 1) === "11"); // Will use jssupport.add 10 | 11 | // Conflict with Lua keywords 12 | var and = 21; 13 | assert(and === 21); 14 | var elseif = 21; 15 | assert(elseif === 21); 16 | var end = 21; 17 | assert(end === 21); 18 | var goto = 21; 19 | assert(goto === 21); 20 | var local = 21; 21 | assert(local === 21); 22 | var nil = 21; 23 | assert(nil === 21); 24 | var not = 21; 25 | assert(not === 21); 26 | var or = 21; 27 | assert(or === 21); 28 | var repeat = 21; 29 | assert(repeat === 21); 30 | var then = 21; 31 | assert(then === 21); 32 | var until = 21; 33 | assert(until === 21); 34 | 35 | // $ in variable names 36 | $_POST = "php is a good old language"; 37 | assert($_POST === "php is a good old language"); 38 | 39 | // sanitizing a member expression 40 | var test = {}; 41 | test.end = {}; 42 | test.end.end = 2; 43 | test.f = {}; 44 | test.f.end = function () { 45 | return "ok" 46 | }; 47 | test.f.end("hum"); 48 | test.f["end"]("hum"); 49 | 50 | assert(test.end.end === 2); 51 | assert(test.f.end("hum") === "ok"); 52 | assert(test.f["end"]("hum") === "ok"); 53 | 54 | test._toto = 6; 55 | assert(test._toto === 6); 56 | test._toto = function () { 57 | return "ok" 58 | }; 59 | assert(test._toto() === "ok"); 60 | assert(test["_toto"]() === "ok"); 61 | 62 | test["or"] = 11; 63 | assert(test.or === 11); 64 | -------------------------------------------------------------------------------- /test/scope.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // No block scope in Lua 4 | function f() { 5 | if (true) { 6 | var a = 12; 7 | assert(a === 12); 8 | } 9 | assert(a === 12); 10 | } 11 | f(); 12 | 13 | // Use of variable before declaration 14 | function oh() { 15 | 16 | var t = function () { 17 | assert(a === 1); 18 | } 19 | 20 | var a = 1; 21 | 22 | t(); 23 | } 24 | oh(); 25 | 26 | function one() { 27 | assert(b === 1) 28 | assert(typeof a === "undefined") 29 | } 30 | 31 | var b = 1; 32 | one(); 33 | var a = 21; 34 | -------------------------------------------------------------------------------- /test/scope2.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var m = 12; 4 | n = 3; 5 | 6 | var toBeMasked1 = "visible"; 7 | var toBeMasked2 = "visible"; 8 | 9 | function playFun() { 10 | assert(m === 11); 11 | assert(n === 3); 12 | assert(typeof j === "undefined"); 13 | 14 | assert(typeof tt === "undefined"); 15 | assert(toBeMasked1 === "visible"); 16 | assert(typeof toBeMasked2 === "undefined"); 17 | 18 | var tt = 777; 19 | tt = 456; 20 | 21 | // Mask 22 | toBeMasked1 = "masked"; 23 | var toBeMasked2 = "masked"; 24 | } 25 | 26 | m = 11; 27 | playFun(); 28 | freeVar = 8; 29 | var j = "defined"; 30 | -------------------------------------------------------------------------------- /test/sequence.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = (7, 5); 4 | assert(a === 5); 5 | 6 | var b = 12; 7 | var c = (b = 3, 4); 8 | assert(b === 3); 9 | assert(c === 4); 10 | 11 | // Multiple coma 12 | var d = (1, 2, 3, 4); 13 | assert(d === 4); 14 | 15 | // Examples from: http://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/ 16 | 17 | ////////////// 18 | // Example 1 19 | ////////////// 20 | 21 | var r = [], 22 | n = 0, 23 | a = 0, 24 | b = 1, 25 | next; 26 | 27 | function nextFibonacci() { 28 | next = a + b; 29 | return b = (a = b, next); 30 | } 31 | 32 | while (n++ < 10) { 33 | r.push(nextFibonacci()); 34 | } 35 | 36 | // r = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] 37 | assert(r[0] === 1); 38 | assert(r[6] === 21); 39 | assert(r[9] === 89); 40 | 41 | ////////////// 42 | // Example 2 43 | ////////////// 44 | 45 | for ( 46 | var i = 2, r = [0, 1]; i < 15; r.push(r[i - 1] + r[i - 2]), i++ 47 | ); 48 | 49 | // r = [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377] 50 | assert(r[0] === 0); 51 | assert(r[9] === 34); 52 | assert(r[14] === 377); 53 | assert(typeof r[15] === "undefined"); 54 | 55 | ////////////// 56 | // For fun 57 | ////////////// 58 | 59 | //~ function renderCurve() { 60 | //~ for(var a = 1, b = 10; a*b; a++, b--) 61 | //~ console.log(new Array(a*b).join('*')); 62 | //~ } 63 | //~ 64 | //~ renderCurve(); 65 | -------------------------------------------------------------------------------- /test/string.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // NB: type string and object String are mixed up in CAST 4 | // commented lines are a result of this 5 | 6 | var str = "abcdef"; 7 | assert(typeof str === "string"); 8 | assert(str.length === 6); 9 | assert(str[0] === "a"); 10 | assert(str[5] === "f"); 11 | assert(typeof str[21] === "undefined"); 12 | assert(!(str instanceof String)); 13 | 14 | var str2 = String(72); 15 | assert(typeof str2 === "string"); 16 | assert(str2 === "72"); 17 | assert(str2[0] === "7"); 18 | assert(!(str2 instanceof String)); 19 | 20 | var str3 = String("hum"); 21 | assert(typeof str3 === "string"); 22 | assert(str3 === "hum"); 23 | assert(str3[1] === "u"); 24 | assert(!(str3 instanceof String)); 25 | assert(!(str3 instanceof Object)); 26 | 27 | var str4 = new String(72); 28 | assert(typeof str4 === "object"); 29 | assert(str4.toString() === "72"); 30 | assert(str4[1] === "2"); 31 | assert(str4 instanceof String); 32 | assert(str4 instanceof Object); 33 | 34 | var str5 = new String("hum"); 35 | assert(typeof str5 === "object"); 36 | assert(str5.toString() === "hum"); 37 | assert(str5[1] === "u"); 38 | assert(str5 instanceof String); 39 | assert(str5 instanceof Object); 40 | 41 | var MyClass = function () {}; 42 | MyClass.prototype.toString = function () { 43 | return "custom toString" 44 | }; 45 | var instance = new MyClass(); 46 | var str6 = String(instance); 47 | assert(str6 === "custom toString"); 48 | 49 | var str7 = new String(instance); 50 | assert(str7.toString() === "custom toString"); 51 | 52 | // strings are immutable 53 | var str8 = "blabla"; 54 | str8.ptdr = 12; 55 | assert(str8.ptdr === undefined); 56 | str8[0] = 'v'; 57 | assert(str8[0] === "b"); 58 | 59 | // fromCharCode 60 | assert(String.fromCharCode(65, 66, 67) === "ABC"); 61 | assert(String.fromCharCode(65, "66", 67) === "ABC"); 62 | 63 | 64 | /////// 65 | var n = String("foo"); 66 | var m = new String("bar"); 67 | var o = "abwabwa"; 68 | 69 | assert(n == "foo"); 70 | assert(m == "bar"); 71 | assert(o == "abwabwa"); 72 | assert(n === "foo"); 73 | assert(!(m === "bar")); 74 | assert(o === "abwabwa"); 75 | assert(typeof(n) === "string"); 76 | assert(typeof(m) === "object"); 77 | assert(typeof(o) === "string"); 78 | assert(!(n instanceof String)); 79 | assert(m instanceof String); 80 | assert(!(o instanceof String)); 81 | assert(n.toString() === "foo"); 82 | assert(m.toString() === "bar"); 83 | assert(o.toString() === "abwabwa"); 84 | assert(Number.isNaN(-n)); 85 | assert(Number.isNaN(-m)); 86 | assert(Number.isNaN(-o)); 87 | -------------------------------------------------------------------------------- /test/string_replace_replacer_not_string.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var o = { 4 | toString: function () { 5 | return "foo" 6 | } 7 | } 8 | 9 | // Replace by undefined 10 | var str = "xx".replace("x"); 11 | assert(str === "undefinedx"); 12 | var str = "xx".replace(/x/g); 13 | assert(str === "undefinedundefined"); 14 | 15 | // Replace by number 16 | var str = "xx".replace("x", 7); 17 | assert(str === "7x"); 18 | var str = "xx".replace(/x/g, 7); 19 | assert(str === "77"); 20 | 21 | // Replace by boolean 22 | var str = "xx".replace("x", true); 23 | assert(str === "truex"); 24 | var str = "xx".replace(/x/g, true); 25 | assert(str === "truetrue"); 26 | 27 | // Replace by object 28 | var str = "xx".replace("x", o); 29 | assert(str === "foox"); 30 | var str = "xx".replace(/x/g, o); 31 | assert(str === "foofoo"); 32 | var str = "xx".replace("x", {}); 33 | assert(str === "[object Object]x"); 34 | var str = "xx".replace(/x/g, {}); 35 | assert(str === "[object Object][object Object]"); 36 | 37 | // Replace by regexp 38 | var str = "xx".replace("x", /abcdef/g); 39 | assert(str === "/abcdef/gx"); 40 | var str = "xx".replace(/x/g, /abcdef/g); 41 | assert(str === "/abcdef/g/abcdef/g"); 42 | 43 | // Function which doesn't return a string 44 | 45 | var str = "x".replace(/x/, function () { 46 | return {}; 47 | }); 48 | assert(str === "[object Object]"); 49 | 50 | var str = "x".replace(/x/, function () { 51 | return /abcdef/g; 52 | }); 53 | assert(str === "/abcdef/g"); 54 | 55 | var str = "x".replace("x", function () { 56 | return {}; 57 | }); 58 | assert(str === "[object Object]"); 59 | 60 | var str = "x".replace("x", function () { 61 | return /abcdef/g; 62 | }); 63 | assert(str === "/abcdef/g"); 64 | 65 | // This context of replacer functin 66 | function f() { 67 | this.z = 13; 68 | } 69 | 70 | f(); 71 | 72 | var str = "x".replace(/x/, function () { 73 | return this.z; 74 | }); 75 | assert(str === "13"); 76 | -------------------------------------------------------------------------------- /test/switch.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | 3 | var path = false; 4 | var path2 = false; 5 | 6 | // Normal switch 7 | var test = "B"; 8 | switch (test) { 9 | case "A": 10 | assert(false); 11 | break; 12 | case "B": 13 | path = true; 14 | break; 15 | default: 16 | assert(false); 17 | } 18 | assert(path) 19 | 20 | // Strict equality in switch test 21 | path = false; 22 | var test2 = 0; 23 | switch (test2) { 24 | case "0": 25 | assert(false); 26 | break; 27 | default: 28 | path = true; 29 | } 30 | assert(path); 31 | 32 | // Empty switch 33 | switch (test) {} 34 | 35 | // Switch without default 36 | var test3 = "A" 37 | path = false; 38 | switch (test3) { 39 | case "A": 40 | path = true; 41 | break; 42 | case "B": 43 | assert(false); 44 | break; 45 | } 46 | assert(path); 47 | 48 | // value not handled 49 | var test4 = "Z"; 50 | switch (test4) { 51 | case "A": 52 | assert(false); 53 | break; 54 | } 55 | 56 | // Switch with default only 57 | path = false; 58 | switch (test) { 59 | default: path = true; 60 | } 61 | assert(path) 62 | 63 | // Break in default 64 | path = false; 65 | switch (test) { 66 | default: path = true; 67 | break; 68 | } 69 | assert(path) 70 | 71 | // Case whihout break; 72 | var test5 = "A"; 73 | path = false; 74 | switch (test5) { 75 | case "A": 76 | case "B": 77 | path = true; 78 | break; 79 | } 80 | assert(path) 81 | 82 | // Default placed first 83 | var test6 = "B"; 84 | path = false; 85 | switch (test6) { 86 | default: assert(false); 87 | case "A": 88 | assert(false); 89 | break; 90 | case "B": 91 | path = true; 92 | break; 93 | } 94 | assert(path); 95 | 96 | // More complex expression as test 97 | 98 | var test7 = 21 99 | path = false; 100 | switch (test7) { 101 | case (function () { 102 | return 42; 103 | })(): 104 | assert(false); 105 | break; 106 | case (function () { 107 | return 21; 108 | })(): 109 | path = true; 110 | break 111 | default: 112 | assert(false); 113 | } 114 | assert(path); 115 | 116 | // Bonus 117 | 118 | var test8 = "C" 119 | path = false; 120 | path2 = false; 121 | 122 | switch (test8) { 123 | case "A": 124 | assert(false); 125 | default: 126 | path = true; 127 | case "B": 128 | path2 = true; 129 | } 130 | assert(path && path2); 131 | 132 | var test9 = "B"; 133 | path = false; 134 | path2 = false; 135 | switch (test9) { 136 | case "A": 137 | assert(false); 138 | case "B": 139 | path = true; 140 | default: 141 | path2 = true; 142 | } 143 | assert(path && path2); 144 | 145 | var test10 = "B"; 146 | path = false; 147 | switch (test10) { 148 | default: assert(false); 149 | case "A": 150 | assert(false); 151 | case "B": 152 | path = true; 153 | } 154 | 155 | assert(path); 156 | 157 | var test11 = "B"; 158 | path = false; 159 | switch (test11) { 160 | default: assert(false); 161 | case "A": 162 | assert(false); 163 | case "B": 164 | path = true; 165 | break; 166 | } 167 | assert(path); 168 | 169 | var i = 3; 170 | var a = []; 171 | while(i){ 172 | switch(i--){ 173 | case 3: 174 | a.push(3); 175 | break; 176 | case 2: 177 | a.push(2); 178 | break; 179 | case 1: 180 | a.push(1); 181 | break; 182 | } 183 | } 184 | assert(a.length === 3); 185 | assert(a[0] === 3); 186 | assert(a[1] === 2); 187 | assert(a[2] === 1); 188 | -------------------------------------------------------------------------------- /test/this_arg_functions.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | function B() {} 4 | 5 | B.prototype.foo = function(callback) { 6 | callback(); 7 | } 8 | 9 | B.prototype.bar = function() {} 10 | 11 | var b = new B(); 12 | 13 | b.foo(function() { 14 | // `this` should not equal `b` 15 | assert(typeof(this.bar) === "undefined"); 16 | }) 17 | 18 | // Access environment via this inside a function 19 | function f() { 20 | return this.parseInt("44") 21 | } 22 | 23 | assert(f() === 44); 24 | 25 | function f2() { 26 | this.z = 12; 27 | } 28 | 29 | f2() 30 | 31 | function f3() { 32 | return this.z 33 | } 34 | 35 | assert(f3() === 12); 36 | 37 | // This when function is a member expression 38 | var o = { 39 | parseInt: function() { 40 | return 77 41 | } 42 | } 43 | o.f = function() { 44 | return this.parseInt("44"); 45 | } 46 | 47 | assert(o.f() === 77); 48 | -------------------------------------------------------------------------------- /test/todo/function_reference.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var Class = { 4 | create: function () { 5 | return function () {} 6 | } 7 | }; 8 | var o = Class.create(); 9 | var o2 = Class.create(); 10 | assert(!(o === o2)); 11 | 12 | var arr = []; 13 | for(var i = 0 ;i<2 ; ++i) { 14 | arr[i] = function(){}; 15 | } 16 | assert(!(arr[0] === arr[1])); 17 | -------------------------------------------------------------------------------- /test/todo/getter_setter.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var f = {get test () {return 12}}; 4 | 5 | assert(f.test === 12); 6 | f.test = 33; 7 | assert(f.test === 12); 8 | -------------------------------------------------------------------------------- /test/todo/impossible.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var i, finallyCount = 0; 4 | for (i = 0; i < 3; ++i) { 5 | try { 6 | 7 | try { 8 | break; 9 | assert(false); 10 | } catch (e) { 11 | assert(false); 12 | } finally { 13 | finallyCount++; 14 | } 15 | 16 | } catch (e) { 17 | assert(false); 18 | } finally { 19 | finallyCount++; 20 | } 21 | } 22 | 23 | assert(finallyCount === 2); 24 | -------------------------------------------------------------------------------- /test/todo/json_tostring.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = JSON.stringify({ 4 | toJSON: function () { return "foo"; } 5 | }) 6 | 7 | assert(a === '"foo"'); 8 | 9 | var b = JSON.stringify({z: 10 | {toJSON: function () { return 21; }} 11 | }) 12 | 13 | assert(b === '{"z":21}'); 14 | 15 | var c = JSON.stringify({ 16 | w: function(){ return "66"}, 17 | q: "tt" 18 | }) 19 | 20 | assert(c === '{"q":"tt"}') 21 | -------------------------------------------------------------------------------- /test/todo/object_access.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // Weak typing 4 | var o = { 5 | 0: 0, 6 | "0": "zero", 7 | 1: 1, 8 | "1": "one", 9 | 2: 2, 10 | "3": "three", 11 | true: "VRAI", 12 | false: "FAUX" 13 | }; 14 | 15 | assert(o[true] === "VRAI"); 16 | assert(o[false] === "FAUX"); 17 | assert(o[0] === "zero"); 18 | assert(o["0"] === "zero"); 19 | assert(o[1] === "one"); 20 | assert(o["1"] === "one"); 21 | assert(o[2] === 2); 22 | assert(o["2"] === 2); 23 | assert(o[3] === "three"); 24 | assert(o["3"] === "three"); 25 | 26 | function f1() { 27 | return 0 28 | } 29 | 30 | function f2() { 31 | return "0" 32 | } 33 | 34 | function f3() { 35 | return 1 36 | } 37 | 38 | function f4() { 39 | return "1" 40 | } 41 | 42 | function f5() { 43 | return 2 44 | } 45 | 46 | function f6() { 47 | return "2" 48 | } 49 | 50 | function f7() { 51 | return 3 52 | } 53 | 54 | function f8() { 55 | return "3" 56 | } 57 | 58 | assert(o[f1()] === "zero"); 59 | assert(o[f2()] === "zero"); 60 | assert(o[f3()] === "one"); 61 | assert(o[f4()] === "one"); 62 | assert(o[f5()] === 2); 63 | assert(o[f6()] === 2); 64 | assert(o[f7()] === "three"); 65 | assert(o[f8()] === "three"); 66 | -------------------------------------------------------------------------------- /test/tonumber.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var o = {}; 4 | var f = function(){return 3}; 5 | var arr = [2,3]; 6 | var b = true; 7 | var n = 7; 8 | var s1 = "ji"; 9 | var s2 = "99"; 10 | var u = undefined; 11 | 12 | assert(Number.isNaN(-o)); 13 | assert(Number.isNaN(-f)); 14 | assert(Number.isNaN(-arr)); 15 | assert(-b === -1); 16 | assert(-n === -7); 17 | assert(Number.isNaN(-s1)); 18 | assert(-s2 === -99); 19 | assert(Number.isNaN(-u)); 20 | 21 | var arr2 = new Array(23, 11); 22 | var b2 = new Boolean(true); 23 | var date = new Date(89, 3, 15); 24 | var err = new Error("Message"); 25 | var f2 = new Function("return 9"); 26 | var n2 = new Number(333); 27 | var o2 = new Object({}); 28 | var regexp = new RegExp("8","g"); 29 | var s3 = new String("hihi"); 30 | 31 | assert(Number.isNaN(-arr2)); 32 | assert(-b2 === -1); 33 | // depends on timezone 34 | // assert(-date === -608594400000); 35 | assert(Number.isNaN(-err)); 36 | assert(Number.isNaN(-f2)); 37 | assert(-n2 === -333); 38 | assert(Number.isNaN(-o2)); 39 | assert(Number.isNaN(-regexp)); 40 | assert(Number.isNaN(-s3)); 41 | -------------------------------------------------------------------------------- /test/tostring.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = "sup"; 4 | var b = 12; 5 | var c = true; 6 | var d = [2, 3, 4, 5]; 7 | var e = { 8 | r: 1, 9 | 3: "hum" 10 | }; 11 | var f = /\d/gi; 12 | var g = new Date(1989, 3, 13); 13 | 14 | function h(a, b) { 15 | var foo = 12; 16 | return foo 17 | }; 18 | var i = arguments; 19 | 20 | // impossible to easily test __tostring metamethod 21 | //console.log(a); 22 | assert(a.toString() === "sup"); 23 | //console.log(b); 24 | assert(b.toString() === "12"); 25 | assert(b.toString(2) === "1100"); 26 | //console.log(c); 27 | assert(c.toString() === "true"); 28 | //console.log(d); 29 | assert(d.toString() === "2,3,4,5"); 30 | //console.log(e); 31 | assert(e.toString() === "[object Object]"); 32 | //console.log(f); 33 | assert(f.toString() === "/\\d/gi"); 34 | //console.log(g); 35 | // depends on Locale 36 | //assert(g.toString() === "Thu Apr 13 1989 00:00:00 GMT+0200 (CEST)"); 37 | //console.log(h); 38 | // not really supported by runtime 39 | //assert(h.toString()); 40 | //console.log(i); 41 | assert(i.toString() === "[object Arguments]"); 42 | 43 | var tostr = Object.prototype.toString; 44 | assert(tostr.call(a) === "[object String]"); 45 | assert(tostr.call(b) === "[object Number]"); 46 | assert(tostr.call(c) === "[object Boolean]"); 47 | assert(tostr.call(d) === "[object Array]"); 48 | assert(tostr.call(e) === "[object Object]"); 49 | assert(tostr.call(f) === "[object RegExp]"); 50 | assert(tostr.call(g) === "[object Date]"); 51 | assert(tostr.call(h) === "[object Function]"); 52 | assert(tostr.call(i) === "[object Arguments]"); 53 | -------------------------------------------------------------------------------- /test/try_catch.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var err, path = false, 4 | path2 = false, 5 | path3 = false; 6 | try { 7 | throw "Error" 8 | } catch (e) { 9 | err = e; 10 | } 11 | assert(err === "Error"); 12 | 13 | try { 14 | path = true; 15 | } catch (e) { 16 | assert(false); 17 | } 18 | assert(path); 19 | 20 | path = false; 21 | try { 22 | var uselesss = 21; 23 | } finally { 24 | path = true; 25 | } 26 | assert(path); 27 | 28 | // Return statement in catch 29 | function f() { 30 | try { 31 | throw "An error"; 32 | } catch (e) { 33 | return false; 34 | } finally { 35 | return true; 36 | } 37 | } 38 | 39 | assert(f()); 40 | 41 | // Return statement in try 42 | function f2() { 43 | try { 44 | return false 45 | } catch (e) {} finally { 46 | return true; 47 | } 48 | } 49 | 50 | assert(f2()); 51 | 52 | // Catch clause rethrow exception (or throw a new one) 53 | path = false; 54 | 55 | function f3() { 56 | try { 57 | throw "An error"; 58 | } catch (e) { 59 | // Rethrow 60 | throw e; 61 | } finally { 62 | path = true; 63 | } 64 | } 65 | 66 | try { 67 | f3(); 68 | } catch (e) {} 69 | 70 | assert(path); 71 | 72 | // No catch clause for the thrown exception 73 | path = false; 74 | 75 | function f4() { 76 | try { 77 | throw "An error"; 78 | } finally { 79 | path = true; 80 | } 81 | } 82 | 83 | try { 84 | f4(); 85 | } catch (e) {} 86 | 87 | assert(path); 88 | 89 | // Try catch inside a loop with break/continue 90 | 91 | var i, finallyCount = 0; 92 | for (i = 0; i < 3; ++i) { 93 | try { 94 | break; 95 | assert(false); 96 | } catch (e) { 97 | assert(false); 98 | } finally { 99 | finallyCount++; 100 | } 101 | } 102 | 103 | assert(finallyCount === 1); 104 | 105 | finallyCount = 0; 106 | for (i = 0; i < 3; ++i) { 107 | try { 108 | continue; 109 | assert(false); 110 | } catch (e) { 111 | assert(false); 112 | } finally { 113 | finallyCount++; 114 | } 115 | } 116 | assert(finallyCount === 3); 117 | 118 | // Try in a try 119 | 120 | path = false; 121 | path2 = false; 122 | try { 123 | try { 124 | throw "An error"; 125 | } catch (e) { 126 | // Rethrow 127 | throw e; 128 | } finally { 129 | path = true; 130 | } 131 | } catch (e) { 132 | path2 = true; 133 | } 134 | assert(path && path2); 135 | 136 | // Try in try in try 137 | path = false; 138 | path2 = false; 139 | path3 = false; 140 | 141 | try { 142 | try { 143 | try { 144 | throw "An error"; 145 | } catch (e) { 146 | // Rethrow 147 | throw e; 148 | } finally { 149 | path = true; 150 | } 151 | } catch (e) { 152 | throw e; 153 | path2 = true; 154 | } 155 | } catch (e) { 156 | path3 = true; 157 | } 158 | assert(path && path3); 159 | assert(!path2); 160 | 161 | // 162 | 163 | path = false 164 | try { 165 | var o = 3 166 | switch (o) { 167 | case 1: 168 | break; 169 | case 3: 170 | path = true; 171 | break; 172 | } 173 | 174 | } catch (e) {} 175 | 176 | assert(path); 177 | 178 | var i = 0 179 | try { 180 | for (i = 0; i < 23; ++i) { 181 | if (i == 7) 182 | break; 183 | } 184 | } catch (e) {} 185 | 186 | assert(i === 7); 187 | 188 | path = false 189 | for (i = 0; i < 5; ++i) { 190 | try { 191 | switch (i) { 192 | case 2: 193 | break; 194 | } 195 | 196 | } catch (e) { 197 | 198 | } 199 | if (i === 2) { 200 | path = true; 201 | } 202 | } 203 | 204 | assert(i === 5); 205 | assert(path); 206 | 207 | path = false 208 | for (i = 0; i < 5; ++i) { 209 | try { 210 | switch (i) { 211 | case 2: 212 | continue; 213 | } 214 | 215 | } catch (e) { 216 | 217 | } 218 | if (i === 2) { 219 | path = true; 220 | } 221 | } 222 | 223 | assert(i === 5); 224 | assert(!path); 225 | 226 | var i = 0 227 | try { 228 | 229 | while (i < 3) { 230 | try { 231 | throw "x" 232 | } catch (lexError) { 233 | if (true) { 234 | break; 235 | } else { 236 | throw lexError; 237 | } 238 | } 239 | i++ 240 | } 241 | 242 | } catch (e) { 243 | throw e; 244 | } 245 | 246 | assert(i === 0); 247 | 248 | -------------------------------------------------------------------------------- /test/typeof.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = 1; 4 | var b = "test"; 5 | var c = true; 6 | 7 | assert(typeof a === "number"); 8 | assert(typeof b === "string"); 9 | assert(typeof c === "boolean"); 10 | assert(typeof null === "object"); 11 | 12 | function f() {}; 13 | assert(typeof f === "function"); 14 | 15 | var o = {}; 16 | assert(typeof o === "object"); 17 | var o2 = new Object(); 18 | assert(typeof o2 === "object"); 19 | var o3 = Object.create(Object.prototype); 20 | assert(typeof o3 === "object"); 21 | -------------------------------------------------------------------------------- /test/undefined.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = undefined; 4 | 5 | assert(a === undefined); 6 | assert(typeof(a) === "undefined"); 7 | 8 | assert(Number.isNaN(a + 2)); 9 | assert(Number.isNaN(2 + a)); 10 | assert(Number.isNaN(a - 2)); 11 | assert(Number.isNaN(2 - a)); 12 | assert(Number.isNaN(a / 2)); 13 | assert(Number.isNaN(2 / a)); 14 | assert(Number.isNaN(a * 2)); 15 | assert(Number.isNaN(2 * a)); 16 | assert(Number.isNaN(a % 2)); 17 | assert(Number.isNaN(2 % a)); 18 | 19 | assert(Number.isNaN(a + true)); 20 | assert(Number.isNaN(true + a)); 21 | assert(Number.isNaN(a - true)); 22 | assert(Number.isNaN(true - a)); 23 | assert(Number.isNaN(a / true)); 24 | assert(Number.isNaN(true / a)); 25 | assert(Number.isNaN(a * true)); 26 | assert(Number.isNaN(true * a)); 27 | assert(Number.isNaN(a % true)); 28 | assert(Number.isNaN(true % a)); 29 | 30 | assert(!(a < 4)); 31 | assert(!(a > 4)); 32 | assert(!(a <= 4)); 33 | assert(!(a >= 4)); 34 | assert(!(a < -4)); 35 | assert(!(a > -4)); 36 | assert(!(a <= -4)); 37 | assert(!(a >= -4)); 38 | assert(!(4 < a)); 39 | assert(!(4 > a)); 40 | assert(!(4 <= a)); 41 | assert(!(4 >= a)); 42 | assert(!(-4 < a)); 43 | assert(!(-4 > a)); 44 | assert(!(-4 <= a)); 45 | assert(!(-4 >= a)); 46 | 47 | assert(!(a < "str")); 48 | assert(!(a > "str")); 49 | assert(!(a <= "str")); 50 | assert(!(a >= "str")); 51 | assert(!("str" < a)); 52 | assert(!("str" > a)); 53 | assert(!("str" <= a)); 54 | assert(!("str" >= a)); 55 | 56 | assert(("str" + a) === "strundefined"); 57 | assert((a + "str") === "undefinedstr"); 58 | assert(("2" + a) === "2undefined"); 59 | assert(Number.isNaN("str" - a)); 60 | assert(Number.isNaN(a - "str")); 61 | -------------------------------------------------------------------------------- /test/update_expression.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a = [1,2,3,4]; 4 | current = 0; 5 | ++(a[++current]); 6 | 7 | assert(current === 1); 8 | assert(a[0] === 1); 9 | assert(a[1] === 3); 10 | assert(a[2] === 3); 11 | assert(a[3] === 4); 12 | 13 | a = [1,2,3,4]; 14 | current = 0; 15 | z = ++(a[++current]); 16 | assert(current === 1); 17 | assert(z === 3); 18 | assert(a[0] === 1); 19 | assert(a[1] === 3); 20 | assert(a[2] === 3); 21 | assert(a[3] === 4); 22 | 23 | a = [1,2,3,4]; 24 | current = 0; 25 | z = (a[current++])++; 26 | 27 | assert(current === 1); 28 | assert(z === 1); 29 | assert(a[0] === 2); 30 | assert(a[1] === 2); 31 | assert(a[2] === 3); 32 | assert(a[3] === 4); 33 | -------------------------------------------------------------------------------- /test/uri.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // Encode 4 | assert(encodeURI("http://www.google.com/a file with spaces.html") === "http://www.google.com/a%20file%20with%20spaces.html"); 5 | assert(encodeURIComponent("http://www.google.com/a file with spaces.html") === "http%3A%2F%2Fwww.google.com%2Fa%20file%20with%20spaces.html"); 6 | 7 | var param1 = encodeURIComponent("http://xyz.com/?a=12&b=55"); 8 | var url = "http://www.domain.com/?param1=" + param1 + "¶m2=99"; 9 | assert(url === "http://www.domain.com/?param1=http%3A%2F%2Fxyz.com%2F%3Fa%3D12%26b%3D55¶m2=99"); 10 | 11 | // Decode 12 | assert(decodeURI("http://www.google.com/a%20file%20with%20spaces.html") === "http://www.google.com/a file with spaces.html"); 13 | assert(decodeURIComponent("http%3A%2F%2Fwww.google.com%2Fa%20file%20with%20spaces.html") === "http://www.google.com/a file with spaces.html"); 14 | assert(decodeURIComponent(param1) === "http://xyz.com/?a=12&b=55"); 15 | 16 | // Special chars 17 | assert(encodeURI("+") === "+"); 18 | assert(encodeURIComponent("+") === "%2B"); 19 | assert(decodeURI("%2B") === "%2B"); 20 | assert(decodeURIComponent("%2B") === "+"); 21 | assert(decodeURI("+") === "+"); 22 | assert(decodeURIComponent("+") === "+"); 23 | 24 | assert(encodeURI("#") === "#"); 25 | assert(encodeURIComponent("#") === "%23"); 26 | assert(decodeURI("%23") === "%23"); 27 | assert(decodeURIComponent("%23") === "#"); 28 | assert(decodeURI("#") === "#"); 29 | assert(decodeURIComponent("#") === "#"); 30 | 31 | assert(encodeURI("!") === "!"); 32 | assert(encodeURIComponent("!") === "!"); 33 | assert(decodeURI("!") === "!"); 34 | assert(decodeURIComponent("!") === "!"); 35 | assert(decodeURI("%21") === "!"); 36 | assert(decodeURIComponent("%21") === "!"); 37 | 38 | assert(encodeURI("$") === "$"); 39 | assert(encodeURIComponent("$") === "%24"); 40 | assert(decodeURI("$") === "$"); 41 | assert(decodeURI("%24") === "%24"); 42 | assert(decodeURIComponent("$") === "$"); 43 | assert(decodeURIComponent("%24") === "$"); 44 | 45 | assert(encodeURI(".") === "."); 46 | assert(encodeURIComponent(".") === "."); 47 | assert(decodeURI(".") === "."); 48 | assert(decodeURIComponent(".") === "."); 49 | assert(decodeURI("%2E") === "."); 50 | assert(decodeURIComponent("%2E") === "."); 51 | 52 | assert(encodeURI("%") === "%25"); 53 | assert(encodeURIComponent("%") === "%25"); 54 | assert(decodeURI("%25") === "%"); 55 | assert(decodeURIComponent("%25") === "%"); 56 | -------------------------------------------------------------------------------- /test/void.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | // ExpressionStatements 4 | this; 5 | [1,2,3]; 6 | {1,2,3}; 7 | (2,3,4); 8 | !true; 9 | 1 < 2; 10 | a = 6; 11 | a++ 12 | true && true 13 | a ? a : a 14 | new Object 15 | parseInt("0") 16 | a.b 17 | 18 | void 0 19 | -------------------------------------------------------------------------------- /test/with.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | var a, x, y; 4 | var r = 10; 5 | 6 | with(Math) { 7 | var p = PI; 8 | a = PI * r * r; 9 | x = r * cos(PI); 10 | y = r * sin(PI / 2); 11 | assert(Math instanceof Object); 12 | } 13 | 14 | assert(a > 314.1 && a < 314.2); 15 | assert(x == -10); 16 | assert(y == 10); 17 | assert(p < 3.15 && p > 3.14); 18 | assert(Math instanceof Object); 19 | 20 | var thisGlobal, thisWith 21 | var f = function () { 22 | thisGlobal = this; 23 | } 24 | f(); 25 | 26 | with(3.1267) { 27 | assert(toPrecision(2) === "3.1"); 28 | var f2 = function () { 29 | assert(toPrecision(2) === "3.1"); 30 | thisWith = this; 31 | }; 32 | f2(); 33 | } 34 | 35 | assert(thisGlobal === thisWith); 36 | 37 | var obj = { 38 | mark: 33 39 | } 40 | obj.lulz = function () { 41 | return this; 42 | } 43 | 44 | with(obj) { 45 | assert(lulz().mark === 33); 46 | } 47 | 48 | try { 49 | with(undefined) {} 50 | } catch (e) { 51 | assert(e instanceof TypeError); 52 | } 53 | 54 | try { 55 | with(null) {} 56 | } catch (e) { 57 | assert(e instanceof TypeError); 58 | } 59 | 60 | // new index 61 | var o = {p1: 3} 62 | 63 | with(o){ 64 | k = 11;// new global variable 65 | p1 = 12; // p1 property of o 66 | assert(p1 === 12); 67 | } 68 | 69 | assert(k === 11); 70 | assert(o.p1 === 12); 71 | --------------------------------------------------------------------------------