mirror of
https://github.com/luau-lang/luau.git
synced 2025-04-03 02:10:53 +01:00
388 lines
14 KiB
C++
388 lines
14 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
#include "Luau/BuiltinDefinitions.h"
|
|
|
|
namespace Luau
|
|
{
|
|
|
|
static const std::string kBuiltinDefinitionBaseSrc = R"BUILTIN_SRC(
|
|
|
|
@checked declare function require(target: any): any
|
|
|
|
@checked declare function getfenv(target: any): { [string]: any }
|
|
|
|
declare _G: any
|
|
declare _VERSION: string
|
|
|
|
declare function gcinfo(): number
|
|
|
|
declare function print<T...>(...: T...)
|
|
|
|
declare function type<T>(value: T): string
|
|
declare function typeof<T>(value: T): string
|
|
|
|
-- `assert` has a magic function attached that will give more detailed type information
|
|
declare function assert<T>(value: T, errorMessage: string?): T
|
|
declare function error<T>(message: T, level: number?): never
|
|
|
|
declare function tostring<T>(value: T): string
|
|
declare function tonumber<T>(value: T, radix: number?): number?
|
|
|
|
declare function rawequal<T1, T2>(a: T1, b: T2): boolean
|
|
declare function rawget<K, V>(tab: {[K]: V}, k: K): V
|
|
declare function rawset<K, V>(tab: {[K]: V}, k: K, v: V): {[K]: V}
|
|
declare function rawlen<K, V>(obj: {[K]: V} | string): number
|
|
|
|
declare function setfenv<T..., R...>(target: number | (T...) -> R..., env: {[string]: any}): ((T...) -> R...)?
|
|
|
|
declare function ipairs<V>(tab: {V}): (({V}, number) -> (number?, V), {V}, number)
|
|
|
|
declare function pcall<A..., R...>(f: (A...) -> R..., ...: A...): (boolean, R...)
|
|
|
|
-- FIXME: The actual type of `xpcall` is:
|
|
-- <E, A..., R1..., R2...>(f: (A...) -> R1..., err: (E) -> R2..., A...) -> (true, R1...) | (false, R2...)
|
|
-- Since we can't represent the return value, we use (boolean, R1...).
|
|
declare function xpcall<E, A..., R1..., R2...>(f: (A...) -> R1..., err: (E) -> R2..., ...: A...): (boolean, R1...)
|
|
|
|
-- `select` has a magic function attached to provide more detailed type information
|
|
declare function select<A...>(i: string | number, ...: A...): ...any
|
|
|
|
-- FIXME: This type is not entirely correct - `loadstring` returns a function or
|
|
-- (nil, string).
|
|
declare function loadstring<A...>(src: string, chunkname: string?): (((A...) -> any)?, string?)
|
|
|
|
@checked declare function newproxy(mt: boolean?): any
|
|
|
|
-- Cannot use `typeof` here because it will produce a polytype when we expect a monotype.
|
|
declare function unpack<V>(tab: {V}, i: number?, j: number?): ...V
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
static const std::string kBuiltinDefinitionBit32Src = R"BUILTIN_SRC(
|
|
|
|
declare bit32: {
|
|
band: @checked (...number) -> number,
|
|
bor: @checked (...number) -> number,
|
|
bxor: @checked (...number) -> number,
|
|
btest: @checked (number, ...number) -> boolean,
|
|
rrotate: @checked (x: number, disp: number) -> number,
|
|
lrotate: @checked (x: number, disp: number) -> number,
|
|
lshift: @checked (x: number, disp: number) -> number,
|
|
arshift: @checked (x: number, disp: number) -> number,
|
|
rshift: @checked (x: number, disp: number) -> number,
|
|
bnot: @checked (x: number) -> number,
|
|
extract: @checked (n: number, field: number, width: number?) -> number,
|
|
replace: @checked (n: number, v: number, field: number, width: number?) -> number,
|
|
countlz: @checked (n: number) -> number,
|
|
countrz: @checked (n: number) -> number,
|
|
byteswap: @checked (n: number) -> number,
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
static const std::string kBuiltinDefinitionMathSrc = R"BUILTIN_SRC(
|
|
|
|
declare math: {
|
|
frexp: @checked (n: number) -> (number, number),
|
|
ldexp: @checked (s: number, e: number) -> number,
|
|
fmod: @checked (x: number, y: number) -> number,
|
|
modf: @checked (n: number) -> (number, number),
|
|
pow: @checked (x: number, y: number) -> number,
|
|
exp: @checked (n: number) -> number,
|
|
|
|
ceil: @checked (n: number) -> number,
|
|
floor: @checked (n: number) -> number,
|
|
abs: @checked (n: number) -> number,
|
|
sqrt: @checked (n: number) -> number,
|
|
|
|
log: @checked (n: number, base: number?) -> number,
|
|
log10: @checked (n: number) -> number,
|
|
|
|
rad: @checked (n: number) -> number,
|
|
deg: @checked (n: number) -> number,
|
|
|
|
sin: @checked (n: number) -> number,
|
|
cos: @checked (n: number) -> number,
|
|
tan: @checked (n: number) -> number,
|
|
sinh: @checked (n: number) -> number,
|
|
cosh: @checked (n: number) -> number,
|
|
tanh: @checked (n: number) -> number,
|
|
atan: @checked (n: number) -> number,
|
|
acos: @checked (n: number) -> number,
|
|
asin: @checked (n: number) -> number,
|
|
atan2: @checked (y: number, x: number) -> number,
|
|
|
|
min: @checked (number, ...number) -> number,
|
|
max: @checked (number, ...number) -> number,
|
|
|
|
pi: number,
|
|
huge: number,
|
|
|
|
randomseed: @checked (seed: number) -> (),
|
|
random: @checked (number?, number?) -> number,
|
|
|
|
sign: @checked (n: number) -> number,
|
|
clamp: @checked (n: number, min: number, max: number) -> number,
|
|
noise: @checked (x: number, y: number?, z: number?) -> number,
|
|
round: @checked (n: number) -> number,
|
|
map: @checked (x: number, inmin: number, inmax: number, outmin: number, outmax: number) -> number,
|
|
lerp: @checked (a: number, b: number, t: number) -> number,
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
static const std::string kBuiltinDefinitionOsSrc = R"BUILTIN_SRC(
|
|
|
|
type DateTypeArg = {
|
|
year: number,
|
|
month: number,
|
|
day: number,
|
|
hour: number?,
|
|
min: number?,
|
|
sec: number?,
|
|
isdst: boolean?,
|
|
}
|
|
|
|
type DateTypeResult = {
|
|
year: number,
|
|
month: number,
|
|
wday: number,
|
|
yday: number,
|
|
day: number,
|
|
hour: number,
|
|
min: number,
|
|
sec: number,
|
|
isdst: boolean,
|
|
}
|
|
|
|
declare os: {
|
|
time: (time: DateTypeArg?) -> number,
|
|
date: ((formatString: "*t" | "!*t", time: number?) -> DateTypeResult) & ((formatString: string?, time: number?) -> string),
|
|
difftime: (t2: DateTypeResult | number, t1: DateTypeResult | number) -> number,
|
|
clock: () -> number,
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
static const std::string kBuiltinDefinitionCoroutineSrc = R"BUILTIN_SRC(
|
|
|
|
declare coroutine: {
|
|
create: <A..., R...>(f: (A...) -> R...) -> thread,
|
|
resume: <A..., R...>(co: thread, A...) -> (boolean, R...),
|
|
running: () -> thread,
|
|
status: @checked (co: thread) -> "dead" | "running" | "normal" | "suspended",
|
|
wrap: <A..., R...>(f: (A...) -> R...) -> ((A...) -> R...),
|
|
yield: <A..., R...>(A...) -> R...,
|
|
isyieldable: () -> boolean,
|
|
close: @checked (co: thread) -> (boolean, any)
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
static const std::string kBuiltinDefinitionTableSrc = R"BUILTIN_SRC(
|
|
|
|
declare table: {
|
|
concat: <V>(t: {V}, sep: string?, i: number?, j: number?) -> string,
|
|
insert: (<V>(t: {V}, value: V) -> ()) & (<V>(t: {V}, pos: number, value: V) -> ()),
|
|
maxn: <V>(t: {V}) -> number,
|
|
remove: <V>(t: {V}, number?) -> V?,
|
|
sort: <V>(t: {V}, comp: ((V, V) -> boolean)?) -> (),
|
|
create: <V>(count: number, value: V?) -> {V},
|
|
find: <V>(haystack: {V}, needle: V, init: number?) -> number?,
|
|
|
|
unpack: <V>(list: {V}, i: number?, j: number?) -> ...V,
|
|
pack: <V>(...V) -> { n: number, [number]: V },
|
|
|
|
getn: <V>(t: {V}) -> number,
|
|
foreach: <K, V>(t: {[K]: V}, f: (K, V) -> ()) -> (),
|
|
foreachi: <V>({V}, (number, V) -> ()) -> (),
|
|
|
|
move: <V>(src: {V}, a: number, b: number, t: number, dst: {V}?) -> {V},
|
|
clear: <K, V>(table: {[K]: V}) -> (),
|
|
|
|
isfrozen: <K, V>(t: {[K]: V}) -> boolean,
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
static const std::string kBuiltinDefinitionDebugSrc = R"BUILTIN_SRC(
|
|
|
|
declare debug: {
|
|
info: ((thread: thread, level: number, options: string) -> ...any) & ((level: number, options: string) -> ...any) & (<A..., R1...>(func: (A...) -> R1..., options: string) -> ...any),
|
|
traceback: ((message: string?, level: number?) -> string) & ((thread: thread, message: string?, level: number?) -> string),
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
static const std::string kBuiltinDefinitionUtf8Src = R"BUILTIN_SRC(
|
|
|
|
declare utf8: {
|
|
char: @checked (...number) -> string,
|
|
charpattern: string,
|
|
codes: @checked (str: string) -> ((string, number) -> (number, number), string, number),
|
|
codepoint: @checked (str: string, i: number?, j: number?) -> ...number,
|
|
len: @checked (s: string, i: number?, j: number?) -> (number?, number?),
|
|
offset: @checked (s: string, n: number?, i: number?) -> number,
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
static const std::string kBuiltinDefinitionBufferSrc = R"BUILTIN_SRC(
|
|
--- Buffer API
|
|
declare buffer: {
|
|
create: @checked (size: number) -> buffer,
|
|
fromstring: @checked (str: string) -> buffer,
|
|
tostring: @checked (b: buffer) -> string,
|
|
len: @checked (b: buffer) -> number,
|
|
copy: @checked (target: buffer, targetOffset: number, source: buffer, sourceOffset: number?, count: number?) -> (),
|
|
fill: @checked (b: buffer, offset: number, value: number, count: number?) -> (),
|
|
readi8: @checked (b: buffer, offset: number) -> number,
|
|
readu8: @checked (b: buffer, offset: number) -> number,
|
|
readi16: @checked (b: buffer, offset: number) -> number,
|
|
readu16: @checked (b: buffer, offset: number) -> number,
|
|
readi32: @checked (b: buffer, offset: number) -> number,
|
|
readu32: @checked (b: buffer, offset: number) -> number,
|
|
readf32: @checked (b: buffer, offset: number) -> number,
|
|
readf64: @checked (b: buffer, offset: number) -> number,
|
|
writei8: @checked (b: buffer, offset: number, value: number) -> (),
|
|
writeu8: @checked (b: buffer, offset: number, value: number) -> (),
|
|
writei16: @checked (b: buffer, offset: number, value: number) -> (),
|
|
writeu16: @checked (b: buffer, offset: number, value: number) -> (),
|
|
writei32: @checked (b: buffer, offset: number, value: number) -> (),
|
|
writeu32: @checked (b: buffer, offset: number, value: number) -> (),
|
|
writef32: @checked (b: buffer, offset: number, value: number) -> (),
|
|
writef64: @checked (b: buffer, offset: number, value: number) -> (),
|
|
readstring: @checked (b: buffer, offset: number, count: number) -> string,
|
|
writestring: @checked (b: buffer, offset: number, value: string, count: number?) -> (),
|
|
readbits: @checked (b: buffer, bitOffset: number, bitCount: number) -> number,
|
|
writebits: @checked (b: buffer, bitOffset: number, bitCount: number, value: number) -> (),
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
static const std::string kBuiltinDefinitionVectorSrc = R"BUILTIN_SRC(
|
|
|
|
-- While vector would have been better represented as a built-in primitive type, type solver class handling covers most of the properties
|
|
declare class vector
|
|
x: number
|
|
y: number
|
|
z: number
|
|
end
|
|
|
|
declare vector: {
|
|
create: @checked (x: number, y: number, z: number?) -> vector,
|
|
magnitude: @checked (vec: vector) -> number,
|
|
normalize: @checked (vec: vector) -> vector,
|
|
cross: @checked (vec1: vector, vec2: vector) -> vector,
|
|
dot: @checked (vec1: vector, vec2: vector) -> number,
|
|
angle: @checked (vec1: vector, vec2: vector, axis: vector?) -> number,
|
|
floor: @checked (vec: vector) -> vector,
|
|
ceil: @checked (vec: vector) -> vector,
|
|
abs: @checked (vec: vector) -> vector,
|
|
sign: @checked (vec: vector) -> vector,
|
|
clamp: @checked (vec: vector, min: vector, max: vector) -> vector,
|
|
max: @checked (vector, ...vector) -> vector,
|
|
min: @checked (vector, ...vector) -> vector,
|
|
|
|
zero: vector,
|
|
one: vector,
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
std::string getBuiltinDefinitionSource()
|
|
{
|
|
std::string result = kBuiltinDefinitionBaseSrc;
|
|
|
|
result += kBuiltinDefinitionBit32Src;
|
|
result += kBuiltinDefinitionMathSrc;
|
|
result += kBuiltinDefinitionOsSrc;
|
|
result += kBuiltinDefinitionCoroutineSrc;
|
|
result += kBuiltinDefinitionTableSrc;
|
|
result += kBuiltinDefinitionDebugSrc;
|
|
result += kBuiltinDefinitionUtf8Src;
|
|
result += kBuiltinDefinitionBufferSrc;
|
|
result += kBuiltinDefinitionVectorSrc;
|
|
|
|
return result;
|
|
}
|
|
|
|
// TODO: split into separate tagged unions when the new solver can appropriately handle that.
|
|
static const std::string kBuiltinDefinitionTypesSrc = R"BUILTIN_SRC(
|
|
|
|
export type type = {
|
|
tag: "nil" | "unknown" | "never" | "any" | "boolean" | "number" | "string" | "buffer" | "thread" |
|
|
"singleton" | "negation" | "union" | "intesection" | "table" | "function" | "class" | "generic",
|
|
|
|
is: (self: type, arg: string) -> boolean,
|
|
|
|
-- for singleton type
|
|
value: (self: type) -> (string | boolean | nil),
|
|
|
|
-- for negation type
|
|
inner: (self: type) -> type,
|
|
|
|
-- for union and intersection types
|
|
components: (self: type) -> {type},
|
|
|
|
-- for table type
|
|
setproperty: (self: type, key: type, value: type?) -> (),
|
|
setreadproperty: (self: type, key: type, value: type?) -> (),
|
|
setwriteproperty: (self: type, key: type, value: type?) -> (),
|
|
readproperty: (self: type, key: type) -> type?,
|
|
writeproperty: (self: type, key: type) -> type?,
|
|
properties: (self: type) -> { [type]: { read: type?, write: type? } },
|
|
setindexer: (self: type, index: type, result: type) -> (),
|
|
setreadindexer: (self: type, index: type, result: type) -> (),
|
|
setwriteindexer: (self: type, index: type, result: type) -> (),
|
|
indexer: (self: type) -> { index: type, readresult: type, writeresult: type }?,
|
|
readindexer: (self: type) -> { index: type, result: type }?,
|
|
writeindexer: (self: type) -> { index: type, result: type }?,
|
|
setmetatable: (self: type, arg: type) -> (),
|
|
metatable: (self: type) -> type?,
|
|
|
|
-- for function type
|
|
setparameters: (self: type, head: {type}?, tail: type?) -> (),
|
|
parameters: (self: type) -> { head: {type}?, tail: type? },
|
|
setreturns: (self: type, head: {type}?, tail: type? ) -> (),
|
|
returns: (self: type) -> { head: {type}?, tail: type? },
|
|
setgenerics: (self: type, {type}?) -> (),
|
|
generics: (self: type) -> {type},
|
|
|
|
-- for class type
|
|
-- 'properties', 'metatable', 'indexer', 'readindexer' and 'writeindexer' are shared with table type
|
|
readparent: (self: type) -> type?,
|
|
writeparent: (self: type) -> type?,
|
|
|
|
-- for generic type
|
|
name: (self: type) -> string?,
|
|
ispack: (self: type) -> boolean,
|
|
}
|
|
|
|
declare types: {
|
|
unknown: type,
|
|
never: type,
|
|
any: type,
|
|
boolean: type,
|
|
number: type,
|
|
string: type,
|
|
thread: type,
|
|
buffer: type,
|
|
|
|
singleton: @checked (arg: string | boolean | nil) -> type,
|
|
generic: @checked (name: string, ispack: boolean?) -> type,
|
|
negationof: @checked (arg: type) -> type,
|
|
unionof: @checked (...type) -> type,
|
|
intersectionof: @checked (...type) -> type,
|
|
newtable: @checked (props: {[type]: type} | {[type]: { read: type, write: type } } | nil, indexer: { index: type, readresult: type, writeresult: type }?, metatable: type?) -> type,
|
|
newfunction: @checked (parameters: { head: {type}?, tail: type? }?, returns: { head: {type}?, tail: type? }?, generics: {type}?) -> type,
|
|
copy: @checked (arg: type) -> type,
|
|
}
|
|
|
|
)BUILTIN_SRC";
|
|
|
|
std::string getTypeFunctionDefinitionSource()
|
|
{
|
|
return kBuiltinDefinitionTypesSrc;
|
|
}
|
|
|
|
} // namespace Luau
|