diff --git a/tl.lua b/tl.lua index 7c32483d3..8bfde5daf 100644 --- a/tl.lua +++ b/tl.lua @@ -57,8 +57,8 @@ do global record coroutine type Function = function(any...): any... - create: function(Function): thread close: function(thread): boolean, string + create: function(Function): thread isyieldable: function(): boolean resume: function(thread, any...): boolean, any... running: function(): thread, boolean @@ -164,9 +164,9 @@ do end global record math - abs: function(integer): integer - abs: function(number): number + type Numeric = number | integer + abs: function(N): N acos: function(number): number asin: function(number): number atan: function(number, ? number): number @@ -345,6 +345,8 @@ do insert: function({A}, integer, A) insert: function({A}, A) + move: function({A}, integer, integer, integer, ? {A}): {A} + pack: function(T...): PackTable pack: function(any...): {any:any} @@ -397,18 +399,35 @@ do collectgarbage: function(CollectGarbageIsRunning): boolean collectgarbage: function(string, ? number): (boolean | number) + dofile: function(? string): any... + error: function(? any, ? integer) + getmetatable: function(T): metatable ipairs: function({A}): (function():(integer, A)) load: function((string | LoadFunction), ? string, ? LoadMode, ? table): (function, string) load: function((string | LoadFunction), ? string, ? string, ? table): (function, string) + loadfile: function(? string, ? string, ? {any:any}): (function, string) + next: function({K:V}, ? K): (K, V) next: function({A}, ? integer): (integer, A) pairs: function({K:V}): (function():(K, V)) pcall: function(function(any...):(any...), any...): boolean, any... print: function(any...) + rawequal: function(any, any): boolean + + rawget: function({K:V}, K): V + rawget: function({any:any}, any): any + rawget: function(any, any): any + + rawlen: function({A}): integer + + rawset: function({K:V}, K, V): {K:V} + rawset: function({any:any}, any, any): {any:any} + rawset: function(any, any, any): any + require: function(string): any select: function(integer, T...): T... @@ -422,6 +441,7 @@ do tostring: function(any): string type: function(any): string + warn: function(string, string...) xpcall: function(function(any...):(any...), XpcallMsghFunction, any...): boolean, any... _VERSION: string end @@ -429,12 +449,19 @@ do global arg = StandardLibrary.arg global assert = StandardLibrary.assert global collectgarbage = StandardLibrary.collectgarbage + global dofile = StandardLibrary.dofile global error = StandardLibrary.error + global getmetatable = StandardLibrary.getmetatable global load = StandardLibrary.load + global loadfile = StandardLibrary.loadfile global next = StandardLibrary.next global pairs = StandardLibrary.pairs global pcall = StandardLibrary.pcall global print = StandardLibrary.print + global rawequal = StandardLibrary.rawequal + global rawget = StandardLibrary.rawget + global rawlen = StandardLibrary.rawlen + global rawset = StandardLibrary.rawset global require = StandardLibrary.require global select = StandardLibrary.select global setmetatable = StandardLibrary.setmetatable @@ -6264,6 +6291,16 @@ tl.new_env = function(opts) return env end +local function assert_no_stdlib_errors(errors, name) + if #errors ~= 0 then + local out = {} + for _, err in ipairs(errors) do + table.insert(out, err.y .. ":" .. err.x .. " " .. err.msg .. "\n") + end + error("Internal Compiler Error: standard library contains " .. name .. ":\n" .. table.concat(out), 2) + end +end + tl.init_env = function(lax, gen_compat, gen_target, predefined) if gen_compat == true or gen_compat == nil then gen_compat = "optional" @@ -6295,12 +6332,14 @@ tl.init_env = function(lax, gen_compat, gen_target, predefined) if not stdlib_globals then local program, syntax_errors = tl.parse(stdlib, "stdlib.d.tl") - assert(#syntax_errors == 0) + assert_no_stdlib_errors(syntax_errors, "syntax errors") + local result = tl.type_check(program, { filename = "@stdlib", env = env, }) - assert(#result.type_errors == 0) + assert_no_stdlib_errors(result.type_errors, "type errors") + stdlib_globals = env.globals; diff --git a/tl.tl b/tl.tl index 01fc7b771..370b21742 100644 --- a/tl.tl +++ b/tl.tl @@ -57,8 +57,8 @@ do global record coroutine type Function = function(any...): any... - create: function(Function): thread close: function(thread): boolean, string + create: function(Function): thread isyieldable: function(): boolean resume: function(thread, any...): boolean, any... running: function(): thread, boolean @@ -164,9 +164,9 @@ do end global record math - abs: function(integer): integer - abs: function(number): number + type Numeric = number | integer + abs: function(N): N acos: function(number): number asin: function(number): number atan: function(number, ? number): number @@ -345,6 +345,8 @@ do insert: function({A}, integer, A) insert: function({A}, A) + move: function({A}, integer, integer, integer, ? {A}): {A} + pack: function(T...): PackTable pack: function(any...): {any:any} @@ -397,18 +399,35 @@ do collectgarbage: function(CollectGarbageIsRunning): boolean collectgarbage: function(string, ? number): (boolean | number) - error: function(? any, ? number) + dofile: function(? string): any... + + error: function(? any, ? integer) + getmetatable: function(T): metatable ipairs: function({A}): (function():(integer, A)) load: function((string | LoadFunction), ? string, ? LoadMode, ? table): (function, string) load: function((string | LoadFunction), ? string, ? string, ? table): (function, string) + loadfile: function(? string, ? string, ? {any:any}): (function, string) + next: function({K:V}, ? K): (K, V) next: function({A}, ? integer): (integer, A) pairs: function({K:V}): (function():(K, V)) pcall: function(function(any...):(any...), any...): boolean, any... print: function(any...) + rawequal: function(any, any): boolean + + rawget: function({K:V}, K): V + rawget: function({any:any}, any): any + rawget: function(any, any): any + + rawlen: function({A}): integer + + rawset: function({K:V}, K, V): {K:V} + rawset: function({any:any}, any, any): {any:any} + rawset: function(any, any, any): any + require: function(string): any select: function(integer, T...): T... @@ -422,6 +441,7 @@ do tostring: function(any): string type: function(any): string + warn: function(string, string...) xpcall: function(function(any...):(any...), XpcallMsghFunction, any...): boolean, any... _VERSION: string end @@ -429,12 +449,19 @@ do global arg = StandardLibrary.arg global assert = StandardLibrary.assert global collectgarbage = StandardLibrary.collectgarbage + global dofile = StandardLibrary.dofile global error = StandardLibrary.error + global getmetatable = StandardLibrary.getmetatable global load = StandardLibrary.load + global loadfile = StandardLibrary.loadfile global next = StandardLibrary.next global pairs = StandardLibrary.pairs global pcall = StandardLibrary.pcall global print = StandardLibrary.print + global rawequal = StandardLibrary.rawequal + global rawget = StandardLibrary.rawget + global rawlen = StandardLibrary.rawlen + global rawset = StandardLibrary.rawset global require = StandardLibrary.require global select = StandardLibrary.select global setmetatable = StandardLibrary.setmetatable @@ -6264,6 +6291,16 @@ tl.new_env = function(opts: tl.EnvOptions): Env, string return env end +local function assert_no_stdlib_errors(errors: {Error}, name: string) + if #errors ~= 0 then + local out = {} + for _, err in ipairs(errors) do + table.insert(out, err.y .. ":" .. err.x .. " " .. err.msg .. "\n") + end + error("Internal Compiler Error: standard library contains " .. name .. ":\n" .. table.concat(out), 2) + end +end + tl.init_env = function(lax?: boolean, gen_compat?: boolean | CompatMode, gen_target?: TargetMode, predefined?: {string}): Env, string if gen_compat == true or gen_compat == nil then gen_compat = "optional" @@ -6295,12 +6332,14 @@ tl.init_env = function(lax?: boolean, gen_compat?: boolean | CompatMode, gen_tar if not stdlib_globals then local program, syntax_errors = tl.parse(stdlib, "stdlib.d.tl") - assert(#syntax_errors == 0) + assert_no_stdlib_errors(syntax_errors, "syntax errors") + local result = tl.type_check(program, { filename = "@stdlib", env = env }) - assert(#result.type_errors == 0) + assert_no_stdlib_errors(result.type_errors, "type errors") + stdlib_globals = env.globals; -- special cases for compatibility