diff --git a/.vscode/settings.json b/.vscode/settings.json index a01cb98..f029406 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,13 +2,12 @@ "files.associations": {}, "editor.insertSpaces": false, "files.eol": "\n", + "editor.rulers": [ 80, 120 ], "cSpell.words": [ "bitcode", "codegen", - "Fuwawa", "impls", - "iovs", - "Yeet" + "iovs" ], "deno.enable": true } \ No newline at end of file diff --git a/source/bnf/syntax.bnf b/source/bnf/syntax.bnf index b53a0d1..c7ab220 100644 --- a/source/bnf/syntax.bnf +++ b/source/bnf/syntax.bnf @@ -1,5 +1,5 @@ program ::= %w* ( stmt_top %w* )* ; - stmt_top ::= function | structure ; + stmt_top ::= function | structure | external ; #============================= @@ -32,8 +32,10 @@ constant ::= boolean | string | float | integer ; -string ::= string_text ; - string_text ::= %"\'" ( ( "\\" !"" ) | !( "\'" ) )* %"\'" ; +string ::= string_ascii | string_utf8 ; + string_ascii ::= %"\'" ( str_escape | !( "\'" ) )* %"\'" ; + string_utf8 ::= %"\"" ( str_escape | !( "\"" ) )* %"\"" ; + str_escape ::= %"\\" !"" ; boolean ::= "true" | "false" ; @@ -80,7 +82,7 @@ container ::= %(w* "[" w*) ( container_item ( %(w* "," w*) container_item )* %w* #============================= # Function #============================= -function ::= func_head %w* ( block | ";" ) ; +function ::= func_head %w* ( block | ";" ) %w* ; func_head ::= %("fn" w+) ...name %( w* "(" w* ) func_args %(w* ")" w*) %(":" w*) access ; func_args ::= ( func_arg %w* ( %( "," w* ) func_arg )* )? ; func_arg ::= ...name %( w* ":" w* ) access ; @@ -91,10 +93,11 @@ block ::= %( "{" w* ) block_stmt* %( w* "}" w* ) ; func_call ::= access func_call_body; func_call_body ::= %( w* "(" w* ) ( expr %w* ( %( "," w* ) expr %w* )* )? %( ")" w* ) ; -return ::= %"return" "_call"? %w+ expr? %( ";" w* ); +return ::= %"return" "_tail"? ( %w+ expr)? %( w* ";" w* ); raise ::= %"raise" %w+ expr %( ";" w* ); # TODO rename to lift # drop ::= %"drop" %w+ expr %( ";" w* ); + #============================= # Expression #============================= @@ -105,16 +108,26 @@ expr ::= expr_arg %w* ( ...expr_infix %w* expr_arg %w* )* ; | "as" | "instanceof" | "." | "->" ; expr_postfix ::= expr_call | expr_get | expr_param | expr_loan ; - expr_param ::= %"#[" %w* arg_list %w* %"]" ; - expr_call ::= %"(" %w* arg_list %w* %")" ; - expr_get ::= %"[" %w* arg_list %w* %"]" ; + expr_param ::= %"#[" %w* arg_list? %w* %"]" ; + expr_call ::= %"(" %w* arg_list? %w* %")" ; + expr_get ::= %"[" %w* arg_list? %w* %"]" ; expr_loan ::= "@" | "$" ; expr_arg ::= expr_prefix? %w* expr_val %w* expr_postfix* ; expr_val ::= constant | expr_brackets | block | container | if | name ; expr_brackets ::= %( "(" w* ) expr %( w* ")" ) ; -arg_list ::= ( expr %w* ","? %w* )* ; +arg_list ::= expr ( %(w* "," w*) expr )* ; if ::= %("if" w*) expr %w* expr %w* ( %"else" %w* expr )? ; -statement ::= expr %terminate ; \ No newline at end of file +statement ::= expr %terminate ; + + +#============================= +# External +#============================= +external ::= %( "external" w+ ) ( ext_import | ext_export ) ; + ext_import ::= %( "import" w* "{" w* ) ext_imports* %( w* "}" w* "from" w*) string %(w* ";" w*) ; + ext_imports ::= function | ext_import_var ; + ext_import_var ::= %( "let" w* ) name %( w* ":" w* ) access %(w* ";" w*); + ext_export ::= "export" ; \ No newline at end of file diff --git a/source/bnf/syntax.d.ts b/source/bnf/syntax.d.ts index f94c7c3..ffdc097 100644 --- a/source/bnf/syntax.d.ts +++ b/source/bnf/syntax.d.ts @@ -33,7 +33,7 @@ export type Term_Stmt_top = { count: number, ref: _Shared.ReferenceRange, value: [ - (Term_Function | Term_Structure) + (Term_Function | Term_Structure | Term_External) ] } export declare function Parse_Stmt_top (i: string, refMapping?: boolean): _Shared.ParseError | { @@ -235,7 +235,7 @@ export type Term_String = { count: number, ref: _Shared.ReferenceRange, value: [ - Term_String_text + (Term_String_ascii | Term_String_utf8) ] } export declare function Parse_String (i: string, refMapping?: boolean): _Shared.ParseError | { @@ -245,28 +245,52 @@ export declare function Parse_String (i: string, refMapping?: boolean): _Shared. isPartial: boolean } -export type Term_String_text = { - type: 'string_text', +export type Term_String_ascii = { + type: 'string_ascii', start: number, end: number, count: number, ref: _Shared.ReferenceRange, value: [ - { type: '(...)*', value: Array<({ - type: '(...)', + { type: '(...)*', value: Array<(Term_Str_escape | _Literal)>, start: number, end: number, count: number, ref: _Shared.ReferenceRange } + ] +} +export declare function Parse_String_ascii (i: string, refMapping?: boolean): _Shared.ParseError | { + root: _Shared.SyntaxNode & Term_String_ascii, + reachBytes: number, + reach: null | _Shared.Reference, + isPartial: boolean +} + +export type Term_String_utf8 = { + type: 'string_utf8', start: number, end: number, count: number, ref: _Shared.ReferenceRange, value: [ - _Literal & {value: "\x5c"}, - _Literal + { type: '(...)*', value: Array<(Term_Str_escape | _Literal)>, start: number, end: number, count: number, ref: _Shared.ReferenceRange } ] -} | _Literal)>, start: number, end: number, count: number, ref: _Shared.ReferenceRange } +} +export declare function Parse_String_utf8 (i: string, refMapping?: boolean): _Shared.ParseError | { + root: _Shared.SyntaxNode & Term_String_utf8, + reachBytes: number, + reach: null | _Shared.Reference, + isPartial: boolean +} + +export type Term_Str_escape = { + type: 'str_escape', + start: number, + end: number, + count: number, + ref: _Shared.ReferenceRange, + value: [ + _Literal ] } -export declare function Parse_String_text (i: string, refMapping?: boolean): _Shared.ParseError | { - root: _Shared.SyntaxNode & Term_String_text, +export declare function Parse_Str_escape (i: string, refMapping?: boolean): _Shared.ParseError | { + root: _Shared.SyntaxNode & Term_Str_escape, reachBytes: number, reach: null | _Shared.Reference, isPartial: boolean @@ -913,8 +937,17 @@ export type Term_Return = { count: number, ref: _Shared.ReferenceRange, value: [ - { type: '(...)?', value: [] | [_Literal & {value: "\x5fcall"}], start: number, end: number, count: number, ref: _Shared.ReferenceRange }, - { type: '(...)?', value: [] | [Term_Expr], start: number, end: number, count: number, ref: _Shared.ReferenceRange } + { type: '(...)?', value: [] | [_Literal & {value: "\x5ftail"}], start: number, end: number, count: number, ref: _Shared.ReferenceRange }, + { type: '(...)?', value: [] | [{ + type: '(...)', + start: number, + end: number, + count: number, + ref: _Shared.ReferenceRange, + value: [ + Term_Expr + ] +}], start: number, end: number, count: number, ref: _Shared.ReferenceRange } ] } export declare function Parse_Return (i: string, refMapping?: boolean): _Shared.ParseError | { @@ -1027,7 +1060,7 @@ export type Term_Expr_param = { count: number, ref: _Shared.ReferenceRange, value: [ - Term_Arg_list + { type: '(...)?', value: [] | [Term_Arg_list], start: number, end: number, count: number, ref: _Shared.ReferenceRange } ] } export declare function Parse_Expr_param (i: string, refMapping?: boolean): _Shared.ParseError | { @@ -1044,7 +1077,7 @@ export type Term_Expr_call = { count: number, ref: _Shared.ReferenceRange, value: [ - Term_Arg_list + { type: '(...)?', value: [] | [Term_Arg_list], start: number, end: number, count: number, ref: _Shared.ReferenceRange } ] } export declare function Parse_Expr_call (i: string, refMapping?: boolean): _Shared.ParseError | { @@ -1061,7 +1094,7 @@ export type Term_Expr_get = { count: number, ref: _Shared.ReferenceRange, value: [ - Term_Arg_list + { type: '(...)?', value: [] | [Term_Arg_list], start: number, end: number, count: number, ref: _Shared.ReferenceRange } ] } export declare function Parse_Expr_get (i: string, refMapping?: boolean): _Shared.ParseError | { @@ -1148,6 +1181,7 @@ export type Term_Arg_list = { count: number, ref: _Shared.ReferenceRange, value: [ + Term_Expr, { type: '(...)*', value: Array<{ type: '(...)', start: number, @@ -1155,8 +1189,7 @@ export type Term_Arg_list = { count: number, ref: _Shared.ReferenceRange, value: [ - Term_Expr, - { type: '(...)?', value: [] | [_Literal & {value: "\x2c"}], start: number, end: number, count: number, ref: _Shared.ReferenceRange } + Term_Expr ] }>, start: number, end: number, count: number, ref: _Shared.ReferenceRange } ] @@ -1212,3 +1245,90 @@ export declare function Parse_Statement (i: string, refMapping?: boolean): _Shar reach: null | _Shared.Reference, isPartial: boolean } + +export type Term_External = { + type: 'external', + start: number, + end: number, + count: number, + ref: _Shared.ReferenceRange, + value: [ + (Term_Ext_import | Term_Ext_export) + ] +} +export declare function Parse_External (i: string, refMapping?: boolean): _Shared.ParseError | { + root: _Shared.SyntaxNode & Term_External, + reachBytes: number, + reach: null | _Shared.Reference, + isPartial: boolean +} + +export type Term_Ext_import = { + type: 'ext_import', + start: number, + end: number, + count: number, + ref: _Shared.ReferenceRange, + value: [ + { type: '(...)*', value: Array, start: number, end: number, count: number, ref: _Shared.ReferenceRange }, + Term_String + ] +} +export declare function Parse_Ext_import (i: string, refMapping?: boolean): _Shared.ParseError | { + root: _Shared.SyntaxNode & Term_Ext_import, + reachBytes: number, + reach: null | _Shared.Reference, + isPartial: boolean +} + +export type Term_Ext_imports = { + type: 'ext_imports', + start: number, + end: number, + count: number, + ref: _Shared.ReferenceRange, + value: [ + (Term_Function | Term_Ext_import_var) + ] +} +export declare function Parse_Ext_imports (i: string, refMapping?: boolean): _Shared.ParseError | { + root: _Shared.SyntaxNode & Term_Ext_imports, + reachBytes: number, + reach: null | _Shared.Reference, + isPartial: boolean +} + +export type Term_Ext_import_var = { + type: 'ext_import_var', + start: number, + end: number, + count: number, + ref: _Shared.ReferenceRange, + value: [ + Term_Name, + Term_Access + ] +} +export declare function Parse_Ext_import_var (i: string, refMapping?: boolean): _Shared.ParseError | { + root: _Shared.SyntaxNode & Term_Ext_import_var, + reachBytes: number, + reach: null | _Shared.Reference, + isPartial: boolean +} + +export type Term_Ext_export = { + type: 'ext_export', + start: number, + end: number, + count: number, + ref: _Shared.ReferenceRange, + value: [ + _Literal & {value: "export"} + ] +} +export declare function Parse_Ext_export (i: string, refMapping?: boolean): _Shared.ParseError | { + root: _Shared.SyntaxNode & Term_Ext_export, + reachBytes: number, + reach: null | _Shared.Reference, + isPartial: boolean +} diff --git a/source/bnf/syntax.js b/source/bnf/syntax.js index 847bd51..18be400 100644 --- a/source/bnf/syntax.js +++ b/source/bnf/syntax.js @@ -1,5 +1,5 @@ import * as _Shared from "./shared.js"; -let _rawWasm = _Shared.DecodeBase64("AGFzbQEAAAABIQZgAAF/YAF/AGABfwF/YAN/f38AYAN/f38Bf2ACf38BfwIQAQJqcwlwcmludF9pMzIAAQNEQwACAwQBBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBAEBAQoGIAZ/AEGSBQt/AUEAC38BQQALfwFBAAt/AUEAC38BQQALB+8FQgZtZW1vcnkCAAVpbnB1dAMABXJlYWNoAwULaW5wdXRMZW5ndGgDAgVfaW5pdAABB3Byb2dyYW0ABwhzdG10X3RvcAAIAXcACQJubAAKBWRpZ2l0AAsIZGlnaXRfbnoADAZsZXR0ZXIADQl0ZXJtaW5hdGUADgdjb21tZW50AA8OY29tbWVudF9zaW5nbGUAEA1jb21tZW50X211bHRpABEIY29uc3RhbnQAEgZzdHJpbmcAEwtzdHJpbmdfdGV4dAAUB2Jvb2xlYW4AFQR2b2lkABYHaW50ZWdlcgAXCWludGVnZXJfdQAYBHplcm8AGQVmbG9hdAAaBG5hbWUAGwZhY2Nlc3MAHAhhY2Nlc3NvcgAdDWFjY2Vzc19zdGF0aWMAHg5hY2Nlc3NfZHluYW1pYwAfC2FjY2Vzc19jb21wACAHZGVjbGFyZQAhBmFzc2lnbgAiCXN0cnVjdHVyZQAjC3N0cnVjdF90eXBlACQLc3RydWN0X3N0bXQAJQtzdHJ1Y3RfYXR0cgAmDXN0cnVjdF9zcHJlYWQAJwljb250YWluZXIAKA5jb250YWluZXJfaXRlbQApDWNvbnRhaW5lcl9tYXAAKg9jb250YWluZXJfdmFsdWUAKwhmdW5jdGlvbgAsCWZ1bmNfaGVhZAAtCWZ1bmNfYXJncwAuCGZ1bmNfYXJnAC8FYmxvY2sAMApibG9ja19zdG10ADEJZnVuY19jYWxsADIOZnVuY19jYWxsX2JvZHkAMwZyZXR1cm4ANAVyYWlzZQA1BGV4cHIANgtleHByX3ByZWZpeAA3CmV4cHJfaW5maXgAOAxleHByX3Bvc3RmaXgAOQpleHByX3BhcmFtADoJZXhwcl9jYWxsADsIZXhwcl9nZXQAPAlleHByX2xvYW4APQhleHByX2FyZwA+CGV4cHJfdmFsAD8NZXhwcl9icmFja2V0cwBACGFy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AyQDDAELIwNBADYCACMDQQc2AgQjAyMENgIMIwNBATYCECADQRRqQYsCQQEQAyADQRVqEAIkAwskAwJAIABBAUYNACMDQQAhAyMDIgAjBDYCCCAAQRRqJAMDQBAJQQFGRQRAIANBAWohAwwBCwsgAEESNgIAIABBBjYCBCAAIwQ2AgwgACADNgIQJANBACEAQQANABAcIgBBAUYNACMDQQAhAyMDIgAjBDYCCCAAQRRqJAMDQBAJQQFGRQRAIANBAWohAwwBCwsgAEESNgIAIABBBjYCBCAAIwQ2AgwgACADNgIQJANBACEAQQANAAsgAEEBRgRAQQEhACACKAIIJAQgAiQDBSACQQc2AgAgAkEFNgIEIAIjBDYCDCACQQE2AhALIABBAUYNACAEQQFqIgRBAUcNAQsLIAFBDDYCACABQQY2AgQgASMENgIMIAEgBDYCEEEAIQBBAA0AQQAhBSMDIgMjBDYCCCADQRRqJAMDQAJAIwMiAiMENgIIIAJBFGokAyMDIwMiASMENgIIIAFBFGokAyMDIgQjBDYCCCMEQYwCQQEQBCEHIAcjBGokBCMEEAUCQCAHQQFHBEBBASEAIAQoAggkBCAEJAMMAQsjA0EANgIAIwNBBzYCBCMDIwQ2AgwjA0EBNgIQIARBFGpBjAJBARADIARBFWoQAiQDCwJAIABBAUYNAEEAIQQjAyIAIwQ2AgggAEEUaiQDA0AQCUEBRkUEQCAEQQFqIQQMAQsLIABBEjYCACAAQQY2AgQgACMENgIMIAAgBDYCEEEAIQBBAA0ACyAAQQFGBEBBASEAIAEoAggkBCABJAMFIAFBBzYCACABQQU2AgQgASMENgIMIAFBAjYCEAskAwJAIABBAUYNABA2IgBBAUYNAAsgAEEBRgRAQQEhACACKAIIJAQgAiQDBSACQQc2AgAgAkEFNgIEIAIjBDYCDCACQQE2AhALIABBAUYNACAFQQFqIgVBAUcNAQsLIANBDDYCACADQQY2AgQgAyMENgIMIAMgBTYCEEEAIQBBAA0AIwMjAyICIwQ2AgggAkEUaiQDQQAhASMDIgAjBDYCCCAAQRRqJAMDQBAJQQFGRQRAIAFBAWohAQwBCwsgAEESNgIAIABBBjYCBCAAIwQ2AgwgACABNgIQAkBBACEAQQANACMDIgEjBDYCCCMEQcwAQQEQBCED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ASMDIgAjBDYCCCMEQYQEQQIQBCECIAIjBGokBCMEEAUCQCACQQJHBEBBASEBIAAoAggkBCAAJAMMAQsjA0EANgIAIwNBBzYCBCMDIwQ2AgwjA0ECNgIQIABBFGpBhARBAhADIABBFmoQAiQDCyABRQ0AQQAhASMDIgAjBDYCCCMEQYYEQQIQBCECIAIjBGokBCMEEAUCQCACQQJHBEBBASEBIAAoAggkBCAAJAMMAQsjA0EANgIAIwNBBzYCBCMDIwQ2AgwjA0ECNgIQIABBFGpBhgRBAhADIABBFmoQAiQDCyABRQ0AQQAhASMDIgAjBDYCCCMEQYgEQQIQBCECIAIjBGokBCMEEAUCQCACQQJHBEBBASEBIAAoAggkBCAAJAMMAQsjA0EANgIAIwNBBzYCBCMDIwQ2AgwjA0ECNgIQIABBFGpBiARBAhADIABBFmoQAiQDCyABRQ0AQQAhASMDIgAjBDYCCCMEQYoEQQIQBCECIAIjBGokBCMEEAUCQCACQQJHBEBBASEBIAAoAggkBCAAJAMMAQsjA0EANgIAIwNBBzYCBCMDIwQ2AgwjA0ECNgIQIABBFGpBigRBAhADIABBFmoQAiQDCyABRQ0AQQAhASMDIgAjBDYCCCMEQYwEQQEQBCECIAIjBGokBCMEEAUCQCACQQFHBEBBASEBIAAoAggkBCAAJAMMAQsjA0EANgIAIwNBBzYCBCMDIwQ2AgwjA0EBNgIQIABBFGpBjARBARADIABBFWoQAiQDCyABRQ0AQQAhASMDIgAjBDYCCCMEQY0EQQEQBCECIAIjBGokBCMEEAUCQCACQQFHBEBBASEBIAAoAggkBCAAJAMMAQsjA0EANgIAIwNBBzYCBCMDIwQ2AgwjA0EBNgIQIABBFGpBjQRBARADIABBFWoQAiQDCyABRQ0AQQAhASMDIgAjBDYCCCMEQY4EQQEQBCECIAIjBGokBCMEEAUCQCACQQFHBEBBASEBIAAoAggkBCAAJAMMAQsjA0EANgIAIwNBBzYCBCMDIwQ2AgwjA0EBNgIQIABBFGpBjgRBARADIABBFWoQAiQDCyABRQ0AQQAhASMDIgAjBDYCCCMEQY8EQQEQBCECIAIjBGokBCMEEAUCQCACQQFHBEBBASEBIAAoAggkBCAAJAMMAQsjA0EANgIAIwNBBzYCBCMDIwQ2Agwj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"); +let _rawWasm = _Shared.DecodeBase64("AGFzbQEAAAABIQZgAAF/YAF/AGABfwF/YAN/f38AYAN/f38Bf2ACf38BfwIQAQJqcwlwcmludF9pMzIAAQNLSgACAwQBBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQQBAQEKBiAGfwBB7gULfwFBAAt/AUEAC38BQQALfwFBAAt/AUEACwfPBkkGbWVtb3J5AgAFaW5wdXQDAAVyZWFjaAMFC2lucHV0TGVuZ3RoAwIFX2luaXQAAQdwcm9ncmFtAAcIc3RtdF90b3AACAF3AAkCbmwACgVkaWdpdAALCGRpZ2l0X256AAwGbGV0dGVyAA0JdGVybWluYXRlAA4HY29tbWVudAAPDmNvbW1lbnRfc2luZ2xlABANY29tbWVudF9tdWx0aQARCGNvbnN0YW50ABIGc3RyaW5nABMMc3RyaW5nX2FzY2lpABQLc3RyaW5nX3V0ZjgAFQpzdHJfZXNjYXBlABYHYm9vbGVhbgAXBHZvaWQAGAdpbnRlZ2VyABkJaW50ZWdlcl91ABoEemVybwAbBWZsb2F0ABwEbmFtZQAdBmFjY2VzcwAeCGFjY2Vzc29yAB8NYWNjZXNzX3N0YXRpYwAgDmFjY2Vzc19keW5hbWljACELYWNjZXNzX2NvbXAAIgdkZWNsYXJlACMGYXNzaWduACQJc3RydWN0dXJlACULc3RydWN0X3R5cGUAJgtzdHJ1Y3Rfc3RtdAAnC3N0cnVjdF9hdHRyACgNc3RydWN0X3NwcmVhZAApCWNvbnRhaW5lcgAqDmNvbnRhaW5lcl9pdGVtACsNY29udGFpbmVyX21hcAAsD2NvbnRhaW5lcl92YWx1ZQAtCGZ1bmN0aW9uAC4JZnVuY19oZWFkAC8JZnVuY19hcmdzADAIZnVuY19hcmcAMQVibG9jawAyCmJsb2NrX3N0bXQAMwlmdW5jX2NhbGwANA5mdW5jX2NhbGxfYm9keQA1BnJldHVybgA2BXJhaXNlADcEZXhwcgA4C2V4cHJfcHJlZml4ADkKZXhwcl9pbmZpeAA6DGV4cHJfcG9zdGZpeAA7CmV4cHJfcGFyYW0APAlleHByX2NhbGwAPQhleHByX2dldAA+CWV4cHJfbG9hbgA/CGV4cHJf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AwsgAUUNAEEAIQEjAyIAIwQ2AggjBEGkBEEBEAQhAiACIwRqJAQjBBAFAkAgAkEBRwRAQQEhASAAKAIIJAQgACQDDAELIwNBADYCACMDQQc2AgQjAyMENgIMIwNBATYCECAAQRRqQaQEQQEQAyAAQRVqEAIkAwsgAUUNAEEAIQEjAyIAIwQ2AggjBEGlBEEBEAQhAiACIwRqJAQjBBAFAkAgAkEBRwRAQQEhASAAKAIIJAQgACQDDAELIwNBADYCACMDQQc2AgQjAyMENgIMIwNBATYCECAAQRRqQaUEQQEQAyAAQRVqEAIkAwsgAUUNAEEAIQEjAyIAIwQ2AggjBEGmBEEBEAQhAiACIwRqJAQjBBAFAkAgAkEBRwRAQQEhASAAKAIIJAQgACQDDAELIwNBADYCACMDQQc2AgQjAyMENgIMIwNBATYCECAAQRRqQaYEQQEQAyAAQRVqEAIkAwsgAUUNAEEAIQEjAyIAIwQ2AggjBEGnBEEBEAQhAiACIwRqJAQjBBAFAkAgAkEBRwRAQQEhASAAKAIIJAQgACQDDAELIwNBADYCACMDQQc2AgQjAyMENgIMIwNBATYCECAAQRRqQacEQQEQAyAAQRVqEAIkAwsgAUUNAEEAIQEjAyIAIwQ2AggjBEGoBEEBEAQhAiACIwRqJAQjBBAFAkAgAkEBRwRAQQEhASAAKAIIJAQgACQDDAELIwNBADYCACMDQQc2AgQjAyMENgIMIwNBATYCECAAQRRqQagEQQEQAyAAQRVqEAIkAwsgAUUNAEEAIQEjAyIAIwQ2AggjBEGKBEEBEAQhAiACIwRqJAQjBBAFAkAgAkEBRwRAQQEhASAAKAIIJAQgACQDDAELIwNBADYCACMDQQc2AgQjAyMENgIMIwNBATYCECAAQRRqQYoEQQEQAyAAQRVqEAIkAwsgAUUNAEEAIQEjAyIAIwQ2AggjBEGpBEECEAQhAiACIwRqJAQjBBAFAkAgAkECRwRAQQEhASAAKAIIJAQgACQDDAELIwNBADYCACMDQQc2AgQjAyMENgIMIwNBAjYCECAAQRRqQakEQQIQAyAAQRZqEAIkAwsgAUUNAEEAIQEjAyIAIwQ2AggjBEGrBEEKEAQhAiACIwRqJAQjBBAFAkAgAkEKRwRAQQEhASAAKAIIJAQgACQDDAELIwNBADYCACMDQQc2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"); let _ctx = null; if (typeof window === 'undefined') { _ctx = new WebAssembly.Instance( @@ -60,8 +60,14 @@ export function Parse_Constant (data, refMapping = true) { export function Parse_String (data, refMapping = true) { return _Shared.Parse(_ctx, data, refMapping, "string"); } -export function Parse_String_text (data, refMapping = true) { - return _Shared.Parse(_ctx, data, refMapping, "string_text"); +export function Parse_String_ascii (data, refMapping = true) { + return _Shared.Parse(_ctx, data, refMapping, "string_ascii"); +} +export function Parse_String_utf8 (data, refMapping = true) { + return _Shared.Parse(_ctx, data, refMapping, "string_utf8"); +} +export function Parse_Str_escape (data, refMapping = true) { + return _Shared.Parse(_ctx, data, refMapping, "str_escape"); } export function Parse_Boolean (data, refMapping = true) { return _Shared.Parse(_ctx, data, refMapping, "boolean"); @@ -204,3 +210,18 @@ export function Parse_If (data, refMapping = true) { export function Parse_Statement (data, refMapping = true) { return _Shared.Parse(_ctx, data, refMapping, "statement"); } +export function Parse_External (data, refMapping = true) { + return _Shared.Parse(_ctx, data, refMapping, "external"); +} +export function Parse_Ext_import (data, refMapping = true) { + return _Shared.Parse(_ctx, data, refMapping, "ext_import"); +} +export function Parse_Ext_imports (data, refMapping = true) { + return _Shared.Parse(_ctx, data, refMapping, "ext_imports"); +} +export function Parse_Ext_import_var (data, refMapping = true) { + return _Shared.Parse(_ctx, data, refMapping, "ext_import_var"); +} +export function Parse_Ext_export (data, refMapping = true) { + return _Shared.Parse(_ctx, data, refMapping, "ext_export"); +} diff --git a/source/cli.ts b/source/cli.ts index 14fd007..dc11f03 100644 --- a/source/cli.ts +++ b/source/cli.ts @@ -8,7 +8,7 @@ import Function from "~/compiler/function.ts"; import Package from "~/compiler/package.ts"; import Project from "~/compiler/project.ts"; import { DisplayTimers, TimerStart, TimerEnd } from "~/helper.ts"; -import { Panic } from "~/helper.ts"; +import { Panic } from "~/compiler/helper.ts"; if (Deno.args.includes("--version")) { console.log("version: 0.0.0"); @@ -54,7 +54,7 @@ TimerEnd("serialize"); TimerStart("wasm2wat"); const command = new Deno.Command( "wasm2wat", - { args: ["-v", "out.wasm", "-o", "out.wat"] } + { args: ["-v", "out.wasm", "-o", "out.wat", "--enable-all"] } ); const { code, stdout, stderr } = await command.output(); if (code !== 0) { diff --git a/source/compiler/codegen/allocation/stack.ts b/source/compiler/codegen/allocation/stack.ts index 41a9ec7..0ecc4c8 100644 --- a/source/compiler/codegen/allocation/stack.ts +++ b/source/compiler/codegen/allocation/stack.ts @@ -1,4 +1,5 @@ -import { AssertUnreachable, AlignUpInteger, AlignDownInteger, LatentValue } from "~/helper.ts"; +import { AlignUpInteger, AlignDownInteger } from "~/compiler/helper.ts"; +import { AssertUnreachable, LatentValue } from "~/helper.ts"; /** * Used for calculating the relative stack location of variables within a function stack @@ -171,7 +172,7 @@ export class StackAllocator { } resolve() { - if (this.checkpointRef.hasAllocations()) throw new Error( + if (this.checkpointRef.hasAllocations()) console.warn( `Stack leak: ${this.checkpointRef.getAllocationCount()} stack values are still allocated after stack frame end ` + this.checkpointRef.getAllocations() ); diff --git a/source/compiler/codegen/context.ts b/source/compiler/codegen/context.ts index 87ebe6d..745e009 100644 --- a/source/compiler/codegen/context.ts +++ b/source/compiler/codegen/context.ts @@ -10,12 +10,14 @@ import Function from "~/compiler/function.ts"; import { BasePointerType, LinearType, OperandType, SolidType, IsRuntimeType, IsSolidType } from "~/compiler/codegen/expression/type.ts"; import { IntrinsicType, IntrinsicValue, none, never } from "~/compiler/intrinsic.ts"; import { Instruction, AnyInstruction } from "~/wasm/index.ts"; +import { ReferenceRange, SourceView } from "~/parser.ts"; import { ResolveLinearType, Store } from "~/compiler/codegen/expression/helper.ts" -import { AssertUnreachable, Panic } from "~/helper.ts"; -import { ReferenceRange } from "~/parser.ts"; +import { AssertUnreachable } from "~/helper.ts"; import { CompileExpr } from "~/compiler/codegen/expression/index.ts"; +import { VirtualType } from "~/compiler/intrinsic.ts"; import { Variable } from "~/compiler/codegen/variable.ts"; import { Block } from "~/wasm/instruction/control-flow.ts"; +import { Panic } from "~/compiler/helper.ts"; export class Context { file: File; @@ -57,6 +59,11 @@ export class Context { } } + markFailure(reason: string, ref: ReferenceRange) { + console.error(reason + SourceView(this.file.path, this.file.name, ref)); + this.file.markFailure(); + } + mergeBlock() { if (this.block.length !== 1) return; if (!(this.block[0] instanceof Block)) return; @@ -81,10 +88,10 @@ function CompileDeclare(ctx: Context, syntax: Syntax.Term_Declare) { const expr = syntax.value[2].value[0]; - - if (banned.namespaces.includes(name)) Panic( + // Worth continuing compilation, to test the validity of the invalid variable name's use + if (banned.namespaces.includes(name)) ctx.markFailure( `${colors.red("Error")}: You're not allowed to call a variable ${name}\n`, - { path: ctx.file.path, name: ctx.file.name, ref: syntax.value[0].value[0].ref } + syntax.value[0].value[0].ref ) if (ctx.scope.hasVariable(name)) Panic( @@ -150,16 +157,18 @@ function CompileDeclare(ctx: Context, syntax: Syntax.Term_Declare) { if (resolveType instanceof IntrinsicValue) { const alloc = ctx.scope.stack.allocate(resolveType.type.size, resolveType.type.align); linear = LinearType.make(resolveType.type.value, alloc, ctx.file.owner.project.stackBase); + + variable = ctx.scope.registerVariable(name, linear, syntax.ref); + linear.markConsumed(syntax.ref); // uninited + linear.pin(); } else if (resolveType instanceof LinearType) { - linear = resolveType; + // Just claim ownership of the container created in the expr + variable = ctx.scope.registerVariable(name, resolveType, syntax.ref); + variable.type.pin(); + return; } else AssertUnreachable(resolveType); - - variable = ctx.scope.registerVariable(name, linear, syntax.ref); - linear.markConsumed(syntax.ref); // uninited - linear.pin(); } - Assign(ctx, variable.type, resolveType, syntax.ref); } @@ -216,9 +225,9 @@ export function Assign(ctx: Context, target: LinearType, expr: OperandType, ref: { path: ctx.file.path, name: ctx.file.name, ref: ref } ) - const error = () => Panic( + const error = () => ctx.markFailure( `${colors.red("Error")}: ${target.type.getTypeName()} != ${expr.getTypeName()}\n`, - { path: ctx.file.path, name: ctx.file.name, ref: ref } + ref ); if (expr instanceof IntrinsicValue) { @@ -239,7 +248,7 @@ export function Assign(ctx: Context, target: LinearType, expr: OperandType, ref: ctx.block.push(Instruction.local.get(reg.ref)); reg.free(); - Store(ctx, expr.type, target.offset); + Store(ctx, expr.type, target.offset, ref); target.markDefined(); return; } @@ -273,6 +282,10 @@ export function Assign(ctx: Context, target: LinearType, expr: OperandType, ref: function CompileStatement(ctx: Context, syntax: Syntax.Term_Statement) { const res = CompileExpr(ctx, syntax.value[0]); + if (res instanceof LinearType) res.dispose(); + + // TOOD: drop structs properly + if (res !== none && res !== never) { ctx.block.push(Instruction.drop()); } @@ -281,17 +294,30 @@ function CompileStatement(ctx: Context, syntax: Syntax.Term_Statement) { function CompileReturn(ctx: Context, syntax: Syntax.Term_Return): typeof never { - const maybe_expr = syntax.value[1].value[0]; + const maybe_expr = syntax.value[1].value[0]?.value[0]; const isTail = syntax.value[0].value.length > 0; const ref = syntax.ref; - if (isTail) Panic( - `${colors.red("Error")}: Unimplemented tail call return\n`, - { path: ctx.file.path, name: ctx.file.name, ref } - ); + // Guard: tail call + if (isTail) { + if (!maybe_expr) Panic( + `${colors.red("Error")}: Missing return_call expression\n`, + { path: ctx.file.path, name: ctx.file.name, ref } + ); + + if (maybe_expr.value[0].value[0].value.length != 0) Panic( + `${colors.red("Error")}: Missing return_call expression\n`, + { path: ctx.file.path, name: ctx.file.name, ref } + ); + + const expr = CompileExpr(ctx, maybe_expr, undefined, true); + if (expr !== never) throw new Error("Expected a never returning expression"); + + return never; + } // Guard: return none - if (ctx.function.returns.length === 0) { + if (ctx.function.returns instanceof VirtualType) { if (maybe_expr) Panic( `${colors.red("Error")}: This function should have no return value\n`, { path: ctx.file.path, name: ctx.file.name, ref } @@ -300,7 +326,7 @@ function CompileReturn(ctx: Context, syntax: Syntax.Term_Return): typeof never { ctx.scope.cleanup(true); ctx.block.push(Instruction.return()); ctx.done = true; - return never; + return ctx.function.returns; } if (!maybe_expr) Panic( @@ -322,10 +348,7 @@ function CompileReturn(ctx: Context, syntax: Syntax.Term_Return): typeof never { // Guard: simple intrinsic return if (goal.type instanceof IntrinsicType) { - if (!goal.type.like(expr)) Panic( - `${colors.red("Error")}: Return type miss-match, expected ${colors.cyan(goal.type.getTypeName())} got ${colors.cyan(expr.getTypeName())}\n`, - { path: ctx.file.path, name: ctx.file.name, ref } - ); + if (!goal.type.like(expr)) ctx.markFailure(`${colors.red("Error")}: Return type miss-match, expected ${colors.cyan(goal.type.getTypeName())} got ${colors.cyan(expr.getTypeName())}\n`, ref); if (expr instanceof LinearType) { ResolveLinearType(ctx, expr, ref, true); diff --git a/source/compiler/codegen/expression/constant.ts b/source/compiler/codegen/expression/constant.ts index bcf3afb..2b96446 100644 --- a/source/compiler/codegen/expression/constant.ts +++ b/source/compiler/codegen/expression/constant.ts @@ -2,7 +2,7 @@ import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; import type * as Syntax from "~/bnf/syntax.d.ts"; import { IntrinsicType, bool, u8, i8, u16, i16, u32, i32, u64, i64, f32, f64 } from "~/compiler/intrinsic.ts"; -import { AssertUnreachable, Panic } from "~/helper.ts"; +import { AssertUnreachable } from "~/helper.ts"; import { IntrinsicValue } from "~/compiler/intrinsic.ts"; import { Instruction } from "~/wasm/index.ts"; import { SolidType } from "~/compiler/codegen/expression/type.ts"; @@ -33,17 +33,17 @@ export function CompileBool(ctx: Context, syntax: Syntax.Term_Boolean) { } function CompileInt(ctx: Context, syntax: Syntax.Term_Integer, expect?: IntrinsicType) { - const num = Number(syntax.value[0].value); + let num = Number(syntax.value[0].value); - if (isNaN(num)) - Panic(`${colors.red("Error")}: Invalid number ${syntax.value[0].value}\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (isNaN(num)) { + ctx.markFailure(`${colors.red("Error")}: Invalid number ${syntax.value[0].value}\n`, syntax.ref); + num = 0; + } - if (!Number.isInteger(num)) - Panic(`${colors.red("Error")}: Invalid integer ${syntax.value[0].value}\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (!Number.isInteger(num)) { + ctx.markFailure(`${colors.red("Error")}: Invalid integer ${syntax.value[0].value}\n`, syntax.ref) + num = 0; + }; const unsigned = expect === u8 || expect === u16 || expect === u32 || expect === u64; const size = expect?.size || 4; @@ -51,20 +51,13 @@ function CompileInt(ctx: Context, syntax: Syntax.Term_Integer, expect?: Intrinsi if (size === 8) { ctx.block.push(Instruction.const.i64(num)); if (unsigned) { - if (num > 2**64) Panic(`${colors.red("Error")}: Value too big for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (num > 2**64) ctx.markFailure(`${colors.red("Error")}: Value too big for size\n`, syntax.ref); return u64.value; } - if (num > 2**63) Panic(`${colors.red("Error")}: Value too big for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); - - if (num < -(2**63)) Panic(`${colors.red("Error")}: Value too small for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (num < -(2**63)) ctx.markFailure(`${colors.red("Error")}: Value too small for size\n`, syntax.ref); + if (num > 2**63) ctx.markFailure(`${colors.red("Error")}: Value too big for size\n`, syntax.ref); return i64.value; } @@ -72,20 +65,13 @@ function CompileInt(ctx: Context, syntax: Syntax.Term_Integer, expect?: Intrinsi if (size === 2) { ctx.block.push(Instruction.const.i32(num)); if (unsigned) { - if (num > 2**16) Panic(`${colors.red("Error")}: Value too big for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (num > 2**16) ctx.markFailure(`${colors.red("Error")}: Value too big for size\n`, syntax.ref); return u16.value; } - if (num > 2**15) Panic(`${colors.red("Error")}: Value too big for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); - - if (num < -(2**15)) Panic(`${colors.red("Error")}: Value too small for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (num < -(2**15)) ctx.markFailure(`${colors.red("Error")}: Value too small for size\n`, syntax.ref); + if (num > 2**15) ctx.markFailure(`${colors.red("Error")}: Value too big for size\n`, syntax.ref); return i16.value; } @@ -93,40 +79,26 @@ function CompileInt(ctx: Context, syntax: Syntax.Term_Integer, expect?: Intrinsi if (size === 1) { ctx.block.push(Instruction.const.i32(num)); if (unsigned) { - if (num > 2**8) Panic(`${colors.red("Error")}: Value too big for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (num > 2**8) ctx.markFailure(`${colors.red("Error")}: Value too big for size\n`, syntax.ref); return u8.value; } - if (num > 2**7) Panic(`${colors.red("Error")}: Value too big for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); - - if (num < -(2**7)) Panic(`${colors.red("Error")}: Value too small for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (num < -(2**7)) ctx.markFailure(`${colors.red("Error")}: Value too small for size\n`, syntax.ref); + if (num > 2**7) ctx.markFailure(`${colors.red("Error")}: Value too big for size\n`, syntax.ref); return i8.value; } ctx.block.push(Instruction.const.i32(num)); if (unsigned) { - if (num > 2**32) Panic(`${colors.red("Error")}: Value too big for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (num > 2**32) ctx.markFailure(`${colors.red("Error")}: Value too big for size\n`, syntax.ref); return u32.value; } - if (num > 2**31) Panic(`${colors.red("Error")}: Value too big for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); - - if (num < -(2**31)) Panic(`${colors.red("Error")}: Value too small for size\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (num < -(2**31)) ctx.markFailure(`${colors.red("Error")}: Value too small for size\n`, syntax.ref); + if (num > 2**31) ctx.markFailure(`${colors.red("Error")}: Value too big for size\n`, syntax.ref); return i32.value; } @@ -134,9 +106,7 @@ function CompileInt(ctx: Context, syntax: Syntax.Term_Integer, expect?: Intrinsi function CompileFloat(ctx: Context, syntax: Syntax.Term_Float, expect?: IntrinsicType) { const num = Number(syntax.value[0].value); - if (isNaN(num)) Panic(`${colors.red("Error")}: Invalid number ${syntax.value[0].value}\n`, { - path: ctx.file.path, name: ctx.file.name, ref: syntax.ref - }); + if (isNaN(num)) ctx.markFailure(`${colors.red("Error")}: Invalid number ${syntax.value[0].value}\n`, syntax.ref); if (expect === f64) { ctx.block.push(Instruction.const.f64(num)); @@ -146,4 +116,29 @@ function CompileFloat(ctx: Context, syntax: Syntax.Term_Float, expect?: Intrinsi ctx.block.push(Instruction.const.f32(num)); return f32.value; +} + +export function SimplifyString(syntax: Syntax.Term_String) { + const inner = syntax.value[0]; + const type = inner.type === "string_ascii" ? "ascii" : "utf8"; + let str = ""; + + for (const chunk of inner.value[0].value) { + if (chunk.type == "literal") { + str += chunk.value; + continue; + } + + const esc = chunk.value[0].value; + switch (esc) { + case "0": str += "\0"; break; + case "f": str += "\f"; break; + case "n": str += "\n"; break; + case "r": str += "\r"; break; + case "v": str += "\v"; break; + default: str += esc; + } + } + + return { type, str } } \ No newline at end of file diff --git a/source/compiler/codegen/expression/container.ts b/source/compiler/codegen/expression/container.ts index af2f2d0..fcc282b 100644 --- a/source/compiler/codegen/expression/container.ts +++ b/source/compiler/codegen/expression/container.ts @@ -10,7 +10,7 @@ import { Instruction } from "~/wasm/index.ts"; import { SourceView } from "~/parser.ts"; import { Context } from "~/compiler/codegen/context.ts"; import { Assign } from "~/compiler/codegen/context.ts"; -import { Panic } from "~/helper.ts"; +import { Panic } from "~/compiler/helper.ts"; export function StructBuilder(ctx: Context, syntax: Syntax.Term_Container, expect?: SolidType): OperandType { if (!(expect instanceof Structure)) Panic( @@ -58,11 +58,10 @@ function NestedStructBuilder(ctx: Context, linear: LinearType, syntax: Syntax.Te for (const item of iterator(zeroed)) { const elm = item.value[0]; if (elm.type === "container_value") { - console.error( - `${colors.red("Error")}: Unexpected array value as struct member\n` - + SourceView(ctx.file.path, ctx.file.name, elm.ref) + ctx.markFailure( + `${colors.red("Error")}: Unexpected array value as struct member\n`, + elm.ref ); - ctx.file.markFailure(); continue; } diff --git a/source/compiler/codegen/expression/helper.ts b/source/compiler/codegen/expression/helper.ts index 8378e06..912cb18 100644 --- a/source/compiler/codegen/expression/helper.ts +++ b/source/compiler/codegen/expression/helper.ts @@ -1,6 +1,6 @@ import type * as Syntax from "~/bnf/syntax.d.ts"; -import { AssertUnreachable, LatentOffset, Panic } from "~/helper.ts"; +import { AssertUnreachable, LatentOffset } from "~/helper.ts"; import { BasePointerType, LinearType } from "~/compiler/codegen/expression/type.ts"; import { ReferenceRange } from "~/bnf/shared.js"; import { IntrinsicType } from "~/compiler/intrinsic.ts"; @@ -26,7 +26,7 @@ export function MaybeSingularExprArg(syntax: Syntax.Term_Expr) { } -export function Store(ctx: Context, type: IntrinsicType, offset: number | LatentOffset) { +export function Store(ctx: Context, type: IntrinsicType, offset: number | LatentOffset, ref: ReferenceRange) { switch (type.name) { case "u32": case "i32": ctx.block.push(Instruction.i32.store(offset, 0)); break; case "u64": case "i64": ctx.block.push(Instruction.i64.store(offset, 0)); break; @@ -35,12 +35,12 @@ export function Store(ctx: Context, type: IntrinsicType, offset: number | Latent case "f32": ctx.block.push(Instruction.f32.store(offset, 1)); break; case "f64": ctx.block.push(Instruction.f64.store(offset, 1)); break; - default: Panic(`Unhandled store type ${type.name}`); + default: ctx.markFailure(`Unhandled store type ${type.name}`, ref); } } -export function Load(ctx: Context, type: IntrinsicType, offset: number | LatentOffset) { +export function Load(ctx: Context, type: IntrinsicType, offset: number | LatentOffset, ref: ReferenceRange) { switch (type.name) { case "u32": case "i32": ctx.block.push(Instruction.i32.load(offset, 0)); break; case "u64": case "i64": ctx.block.push(Instruction.i64.load(offset, 0)); break; @@ -51,7 +51,7 @@ export function Load(ctx: Context, type: IntrinsicType, offset: number | LatentO case "f32": ctx.block.push(Instruction.f32.load(offset, 0)); break; case "f64": ctx.block.push(Instruction.f64.load(offset, 0)); break; - default: Panic(`Unhandled store type ${type.name}`); + default: ctx.markFailure(`Unhandled store type ${type.name}`, ref); } } @@ -78,7 +78,7 @@ export function ResolveLinearType(ctx: Context, type: LinearType, ref: Reference // Auto load intrinsic value from a linear type if (baseType instanceof IntrinsicType) { - Load(ctx, baseType, type.offset); + Load(ctx, baseType, type.offset, ref); return baseType.value; } diff --git a/source/compiler/codegen/expression/index.ts b/source/compiler/codegen/expression/index.ts index 00a02fe..3b8b34b 100644 --- a/source/compiler/codegen/expression/index.ts +++ b/source/compiler/codegen/expression/index.ts @@ -5,9 +5,9 @@ import { CompileInfix } from "~/compiler/codegen/expression/infix.ts"; import { CompileArg } from "~/compiler/codegen/expression/operand.ts"; import { Context } from "~/compiler/codegen/context.ts"; -export function CompileExpr(ctx: Context, syntax: Syntax.Term_Expr, expect?: SolidType): OperandType { +export function CompileExpr(ctx: Context, syntax: Syntax.Term_Expr, expect?: SolidType, tailCall: boolean = false): OperandType { const elm = ApplyPrecedence(syntax); - if (elm.type === "expr_arg") return CompileArg(ctx, elm, expect); + if (elm.type === "expr_arg") return CompileArg(ctx, elm, expect, tailCall); - return CompileInfix(ctx, elm.lhs, elm.op, elm.rhs, elm.ref, expect); + return CompileInfix(ctx, elm.lhs, elm.op, elm.rhs, elm.ref, expect, tailCall); } \ No newline at end of file diff --git a/source/compiler/codegen/expression/infix.ts b/source/compiler/codegen/expression/infix.ts index edd31ff..e9b2c89 100644 --- a/source/compiler/codegen/expression/infix.ts +++ b/source/compiler/codegen/expression/infix.ts @@ -9,10 +9,10 @@ import { ReferenceRange } from "~/parser.ts"; import { Instruction } from "~/wasm/index.ts"; import { CompileArg } from "~/compiler/codegen/expression/operand.ts"; import { Context } from "~/compiler/codegen/context.ts"; -import { Panic } from "~/helper.ts"; +import { Panic } from "~/compiler/helper.ts"; -export function CompileInfix(ctx: Context, lhs: PrecedenceTree, op: string, rhs: PrecedenceTree, ref: ReferenceRange, expect?: SolidType): OperandType { +export function CompileInfix(ctx: Context, lhs: PrecedenceTree, op: string, rhs: PrecedenceTree, ref: ReferenceRange, expect?: SolidType, tailCall = false): OperandType { if (op === "as") return CompileAs(ctx, lhs, rhs); if (op === ".") return CompileStaticAccess(ctx, lhs, rhs, expect); @@ -24,7 +24,7 @@ export function CompileInfix(ctx: Context, lhs: PrecedenceTree, op: string, rhs: path: ctx.file.path, name: ctx.file.name, ref: lhs.ref }); - let b = CompilePrecedence(ctx, rhs, a.type); + let b = CompilePrecedence(ctx, rhs, a.type, tailCall); if (b instanceof LinearType && b.type instanceof IntrinsicValue) b = ResolveLinearType(ctx, b, rhs.ref); if (!(b instanceof IntrinsicValue)) Panic( `${colors.red("Error")}: Cannot apply arithmetic infix operation to non-intrinsics ${colors.cyan(b.getTypeName())}\n`, { @@ -56,8 +56,8 @@ export function CompileInfix(ctx: Context, lhs: PrecedenceTree, op: string, rhs: } } -function CompilePrecedence(ctx: Context, elm: PrecedenceTree, expect?: SolidType): OperandType { - if (elm.type === "expr_arg") return CompileArg(ctx, elm, expect); +function CompilePrecedence(ctx: Context, elm: PrecedenceTree, expect?: SolidType, tailCall = false): OperandType { + if (elm.type === "expr_arg") return CompileArg(ctx, elm, expect, tailCall); return CompileInfix(ctx, elm.lhs, elm.op, elm.rhs, elm.ref, expect); } @@ -127,9 +127,10 @@ function CompileStaticAccess(ctx: Context, lhs: PrecedenceTree, rhs: PrecedenceT function CompileAdd(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot add unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot add unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value || lhs === u8.value || lhs === u16.value || lhs === u32.value) { ctx.block.push(Instruction.i32.add()); @@ -157,9 +158,10 @@ function CompileAdd(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileSub(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot subtract unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot subtract unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value || lhs === u8.value || lhs === u16.value || lhs === u32.value) { ctx.block.push(Instruction.i32.sub()); @@ -190,9 +192,10 @@ function CompileSub(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: function CompileMul(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot multiply unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot multiply unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value || lhs === u8.value || lhs === u16.value || lhs === u32.value) { ctx.block.push(Instruction.i32.mul()); @@ -220,9 +223,10 @@ function CompileMul(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileDiv(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot divide unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot divide unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.div_s()); @@ -258,9 +262,10 @@ function CompileDiv(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileRem(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot remainder unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot remainder unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.rem_s()); @@ -281,52 +286,128 @@ function CompileRem(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: return lhs; } - if (lhs === f32.value) { - const regA = ctx.scope.register.allocate(f32.bitcode, false); - const regB = ctx.scope.register.allocate(f32.bitcode, false); - ctx.block.push(Instruction.local.set(regB.ref)); - ctx.block.push(Instruction.local.set(regA.ref)); - - ctx.block.push(Instruction.local.get(regA.ref)); // a - - - ctx.block.push(Instruction.local.get(regA.ref)); // floor(a/b) - ctx.block.push(Instruction.local.get(regB.ref)); - ctx.block.push(Instruction.f32.div()); - ctx.block.push(Instruction.f32.trunc()); + if (lhs === f32.value || lhs === f64.value) return CompileFloatRemainder(ctx, lhs, ref); - ctx.block.push(Instruction.local.get(regB.ref)); // * b - ctx.block.push(Instruction.f32.mul()); + Panic(`${colors.red("Error")}: Unhandled type ${lhs.type.name}\n`, { + path: ctx.file.path, name: ctx.file.name, ref + }); +} - ctx.block.push(Instruction.f32.sub()); +function CompileFloatRemainder(ctx: Context, type: IntrinsicValue, ref: ReferenceRange) { + /** + * float fmod(float x, float y) { + if (y == 0.0) return NaN; - regA.free(); - regB.free(); - return lhs; - } + float quotient = x / y; + float remainder = x - trunc(quotient) * y; - if (lhs === f64.value) { - const regA = ctx.scope.register.allocate(f64.bitcode, false); - const regB = ctx.scope.register.allocate(f64.bitcode, false); - ctx.block.push(Instruction.local.set(regA.ref)); - ctx.block.push(Instruction.local.set(regB.ref)); + if (remainder == 0.0 && quotient < 0.0) return -0.0; + else return remainder; + }*/ - ctx.block.push(Instruction.local.get(regA.ref)); - ctx.block.push(Instruction.local.get(regB.ref)); - ctx.block.push(Instruction.f64.div()); - ctx.block.push(Instruction.f64.trunc()); + if (type === f32.value) { + const x = ctx.scope.register.allocate(f32.bitcode); + const y = ctx.scope.register.allocate(f32.bitcode); + ctx.block.push(Instruction.local.set(y.ref)); + ctx.block.push(Instruction.local.set(x.ref)); - ctx.block.push(Instruction.local.get(regB.ref)); - ctx.block.push(Instruction.f64.mul()); + const q = ctx.scope.register.allocate(f32.bitcode); + const r = ctx.scope.register.allocate(f32.bitcode); - ctx.block.push(Instruction.local.get(regA.ref)); - ctx.block.push(Instruction.f64.sub()); - - regA.free(); - regB.free(); - return lhs; - } - - Panic(`${colors.red("Error")}: Unhandled type ${lhs.type.name}\n`, { + // if (y == 0) return NaN; + ctx.block.push(Instruction.local.get(y.ref)); + ctx.block.push(Instruction.const.f32(0.0)); + ctx.block.push(Instruction.f32.eq()); + ctx.block.push(Instruction.if(type.type.bitcode, [ + Instruction.const.f32(NaN) + ], [ + Instruction.local.get(x.ref), // q = x / y + Instruction.local.get(y.ref), + Instruction.f32.div(), + Instruction.local.set(q.ref), + + Instruction.local.get(x.ref), // x - trunc(q)*y + Instruction.local.get(q.ref), + Instruction.f32.trunc(), + Instruction.local.get(y.ref), + Instruction.f32.mul(), + Instruction.f32.sub(), + Instruction.local.set(r.ref), + + Instruction.local.get(r.ref), // remainder == 0.0 + Instruction.const.f32(0.0), + Instruction.f32.eq(), + + Instruction.local.get(q.ref), // quotient < 0.0 + Instruction.const.f32(0.0), + Instruction.f32.lt(), + + Instruction.i32.and(), // && + Instruction.if(f32.bitcode, [ + Instruction.const.f32(-0.0) + ], [ + Instruction.local.get(r.ref) + ]) + ])); + + x.free(); y.free(); + q.free(); r.free(); + + return type; + } + + if (type === f64.value) { + const x = ctx.scope.register.allocate(f64.bitcode); + const y = ctx.scope.register.allocate(f64.bitcode); + ctx.block.push(Instruction.local.set(y.ref)); + ctx.block.push(Instruction.local.set(x.ref)); + + const q = ctx.scope.register.allocate(f64.bitcode); + const r = ctx.scope.register.allocate(f64.bitcode); + + // if (y == 0) return NaN; + ctx.block.push(Instruction.local.get(y.ref)); + ctx.block.push(Instruction.const.f64(0.0)); + ctx.block.push(Instruction.f64.eq()); + ctx.block.push(Instruction.if(type.type.bitcode, [ + Instruction.const.f64(NaN) + ], [ + Instruction.local.get(x.ref), // q = x / y + Instruction.local.get(y.ref), + Instruction.f64.div(), + Instruction.local.set(q.ref), + + Instruction.local.get(x.ref), // x - trunc(q)*y + Instruction.local.get(q.ref), + Instruction.f64.trunc(), + Instruction.local.get(y.ref), + Instruction.f64.mul(), + Instruction.f64.sub(), + Instruction.local.set(r.ref), + + Instruction.local.get(r.ref), // remainder == 0.0 + Instruction.const.f64(0.0), + Instruction.f64.eq(), + + Instruction.local.get(q.ref), // quotient < 0.0 + Instruction.const.f64(0.0), + Instruction.f64.lt(), + + Instruction.i32.and(), // && + Instruction.if(f64.bitcode, [ + Instruction.const.f64(-0.0) + ], [ + Instruction.local.get(r.ref) + ]) + ])); + + x.free(); y.free(); + q.free(); r.free(); + + return type; + } + + Panic(`${colors.red("Error")}: Unhandled type ${type.type.name}\n`, { path: ctx.file.path, name: ctx.file.name, ref }); } @@ -336,9 +417,10 @@ function CompileRem(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: function CompileAnd(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot && unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot && unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.and()); @@ -364,9 +446,10 @@ function CompileAnd(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileOr(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot || unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot || unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.or()); @@ -393,9 +476,10 @@ function CompileOr(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileXor(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot ^ unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot ^ unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.xor()); @@ -426,9 +510,10 @@ function CompileXor(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: function CompileEq(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot == unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot == unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.eq()); @@ -464,9 +549,10 @@ function CompileEq(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileNeq(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot != unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot != unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.ne()); @@ -502,9 +588,10 @@ function CompileNeq(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileLt(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot < unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot < unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.lt_s()); @@ -540,9 +627,10 @@ function CompileLt(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileLe(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot <= unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot <= unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.le_s()); @@ -578,9 +666,10 @@ function CompileLe(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileGt(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot > unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot > unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.gt_s()); @@ -616,9 +705,10 @@ function CompileGt(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: } function CompileGe(ctx: Context, lhs: IntrinsicValue, rhs: IntrinsicValue, ref: ReferenceRange) { - if (lhs !== rhs) Panic(`${colors.red("Error")}: Cannot >= unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, { - path: ctx.file.path, name: ctx.file.name, ref - }); + if (lhs !== rhs) ctx.markFailure( + `${colors.red("Error")}: Cannot >= unmatched types ${lhs.type.name} != ${rhs.type.name}\n`, + ref + ); if (lhs === i8.value || lhs === i16.value || lhs === i32.value) { ctx.block.push(Instruction.i32.ge_s()); diff --git a/source/compiler/codegen/expression/operand.ts b/source/compiler/codegen/expression/operand.ts index 15473e6..2c00296 100644 --- a/source/compiler/codegen/expression/operand.ts +++ b/source/compiler/codegen/expression/operand.ts @@ -1,22 +1,22 @@ import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; import type * as Syntax from "~/bnf/syntax.d.ts"; +import Structure from "~/compiler/structure.ts"; import { LinearType, SolidType, OperandType } from "~/compiler/codegen/expression/type.ts"; -import { IntrinsicValue, VirtualType, bool } from "~/compiler/intrinsic.ts"; +import { IntrinsicValue, VirtualType, bool, never } from "~/compiler/intrinsic.ts"; import { ArrayBuilder, StructBuilder } from "~/compiler/codegen/expression/container.ts"; -import { AssertUnreachable, Panic } from "~/helper.ts"; -import { CompilePostfixes } from "~/compiler/codegen/expression/postfix.ts"; +import { AssertUnreachable } from "~/helper.ts"; +import { CompilePostfixes } from "~/compiler/codegen/expression/postfix/index.ts"; import { CompileConstant } from "~/compiler/codegen/expression/constant.ts"; import { CompilePrefix } from "~/compiler/codegen/expression/prefix.ts"; import { CompileExpr } from "~/compiler/codegen/expression/index.ts"; import { IsNamespace } from "~/compiler/file.ts"; import { Instruction } from "~/wasm/index.ts"; import { Context } from "~/compiler/codegen/context.ts"; -import Structure from "~/compiler/structure.ts"; -import { ResolveLinearType } from "~/compiler/codegen/expression/helper.ts"; +import { Panic } from "~/compiler/helper.ts"; -export function CompileArg(ctx: Context, syntax: Syntax.Term_Expr_arg, expect?: SolidType): OperandType { +export function CompileArg(ctx: Context, syntax: Syntax.Term_Expr_arg, expect?: SolidType, tailCall = false): OperandType { const val = syntax.value[1].value[0]; let res: OperandType; switch (val.type) { @@ -30,7 +30,16 @@ export function CompileArg(ctx: Context, syntax: Syntax.Term_Expr_arg, expect?: } const postfix = syntax.value[2].value; - if (postfix.length > 0) res = CompilePostfixes(ctx, postfix, res, expect); + if (postfix.length > 0) res = CompilePostfixes(ctx, postfix, res, tailCall); + + if (tailCall) { + if (res != never) ctx.markFailure( + `${colors.red("Error")}: No actual tail call present where required\n`, + syntax.ref + ); + + return never; + } const prefix = syntax.value[0].value[0]; if (prefix) res = CompilePrefix(ctx, prefix, res, expect); @@ -52,16 +61,16 @@ function CompileContainer(ctx: Context, syntax: Syntax.Term_Container, expect?: }) } -function CompileBrackets(ctx: Context, syntax: Syntax.Term_Expr_brackets, expect?: SolidType) { +function CompileBrackets(ctx: Context, syntax: Syntax.Term_Expr_brackets, expect?: SolidType): OperandType { return CompileExpr(ctx, syntax.value[0], expect); } -function CompileName(ctx: Context, syntax: Syntax.Term_Name) { +function CompileName(ctx: Context, syntax: Syntax.Term_Name): OperandType { const name = syntax.value[0].value; const variable = ctx.scope.getVariable(name, true); if (!variable) { const found = ctx.file.access(name); - if (found === null) Panic(`${colors.red("Error")}: Undeclared term ${name}\n`, { + if (found === null) Panic(`${colors.red("Error")}: Undeclared term ${colors.cyan(name)}\n`, { path: ctx.file.path, name: ctx.file.name, ref: syntax.ref }); @@ -71,7 +80,7 @@ function CompileName(ctx: Context, syntax: Syntax.Term_Name) { return variable.type; } -function CompileIf(ctx: Context, syntax: Syntax.Term_If, expect?: SolidType) { +function CompileIf(ctx: Context, syntax: Syntax.Term_If, expect?: SolidType): OperandType { const cond = CompileExpr(ctx, syntax.value[0]); if (cond instanceof LinearType && cond.type !== bool.value) Panic( `${colors.red("Error")}: Invalid comparison type ${cond.type.getTypeName()}\n`, diff --git a/source/compiler/codegen/expression/postfix.ts b/source/compiler/codegen/expression/postfix.ts deleted file mode 100644 index baff977..0000000 --- a/source/compiler/codegen/expression/postfix.ts +++ /dev/null @@ -1,120 +0,0 @@ -import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; - -import type * as Syntax from "~/bnf/syntax.d.ts"; -import Function from "~/compiler/function.ts"; -import { AssertUnreachable, Panic } from "~/helper.ts"; -import { IntrinsicType, i32 } from "~/compiler/intrinsic.ts"; -import { ResolveLinearType } from "~/compiler/codegen/expression/helper.ts"; -import { IntrinsicValue } from "~/compiler/intrinsic.ts"; -import { OperandType } from "~/compiler/codegen/expression/type.ts"; -import { CompileExpr } from "~/compiler/codegen/expression/index.ts"; -import { IsNamespace } from "~/compiler/file.ts"; -import { Instruction } from "~/wasm/index.ts"; -import { VirtualType } from "~/compiler/intrinsic.ts"; -import { LinearType } from "~/compiler/codegen/expression/type.ts"; -import { Context } from "~/compiler/codegen/context.ts"; -import { none } from "~/compiler/intrinsic.ts"; - - - -export function CompilePostfixes(ctx: Context, syntax: Syntax.Term_Expr_postfix[], type: OperandType, expect?: OperandType): OperandType { - let res = type; - for (const postfix of syntax) { - const act = postfix.value[0]; - - switch (act.type) { - case "expr_call": res = CompileCall(ctx, act, res); break; - - case "expr_get": case "expr_loan": case "expr_param": - Panic( - `${colors.red("Error")}: Unimplemented postfix operation ${act.type}\n`, - { path: ctx.file.path, name: ctx.file.name, ref: act.ref } - ); break; - default: AssertUnreachable(act); - } - } - - return res; -} - - -function CompileCall(ctx: Context, syntax: Syntax.Term_Expr_call, operand: OperandType, expect?: OperandType) { - if (!(operand instanceof Function)) Panic( - `${colors.red("Error")}: Cannot call on a non function value\n`, - { path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } - ); - - operand.compile(); // check the function is compiled - - if (!operand.ref) throw new Error("A function somehow compiled with no reference generated"); - - const stackReg = ctx.file.owner.project.stackReg.ref; - let returnType: VirtualType | IntrinsicValue | LinearType = none; - - if (operand.returns.length == 1) { - const primary = operand.returns[0]; - if (primary.type instanceof IntrinsicType) { - returnType = primary.type.value; - } else { - const alloc = ctx.scope.stack.allocate(primary.type.size, primary.type.align); - const forward = primary.type instanceof IntrinsicType - ? primary.type.value - : primary.type; - returnType = LinearType.make(forward, alloc, ctx.file.owner.project.stackBase); - - ctx.block.push(Instruction.global.get(stackReg)); - ctx.block.push(Instruction.const.i32(alloc.getOffset())); - } - } else Panic( - `${colors.red("Error")}: Multi-return is currently unsupported\n`, - { path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } - ); - - const args = LineariseArgList(syntax.value[0]); - if (args.length != operand.arguments.length) Panic( - `${colors.red("Error")}: Miss matched argument count\n`, - { path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } - ); - - for (let i=0; i x.value[0]); -} \ No newline at end of file diff --git a/source/compiler/codegen/expression/postfix/call.ts b/source/compiler/codegen/expression/postfix/call.ts new file mode 100644 index 0000000..1d5ba8e --- /dev/null +++ b/source/compiler/codegen/expression/postfix/call.ts @@ -0,0 +1,179 @@ +import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; + +import type * as Syntax from "~/bnf/syntax.d.ts"; +import Function from "~/compiler/function.ts"; +import { IntrinsicType, IntrinsicValue, VirtualType, i32, never } from "~/compiler/intrinsic.ts"; +import { OperandType, LinearType } from "~/compiler/codegen/expression/type.ts"; +import { ResolveLinearType } from "~/compiler/codegen/expression/helper.ts"; +import { LineariseArgList } from "~/compiler/codegen/expression/postfix/index.ts"; +import { ReferenceRange } from "~/parser.ts"; +import { CompileExpr } from "~/compiler/codegen/expression/index.ts"; +import { IsNamespace } from "~/compiler/file.ts"; +import { Instruction } from "~/wasm/index.ts"; +import { Context } from "~/compiler/codegen/context.ts"; +import { Panic } from "~/compiler/helper.ts"; + + +export function CompileCall(ctx: Context, syntax: Syntax.Term_Expr_call, operand: OperandType, tailCall: boolean = false) { + if (tailCall) return CompileTailCall(ctx, syntax, operand); + + if (!(operand instanceof Function)) Panic( + `${colors.red("Error")}: Cannot call on a non function value\n`, + { path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } + ); + + operand.compile(); // check the function is compiled + + if (!operand.ref) throw new Error("A function somehow compiled with no reference generated"); + + const returnType = PrepareReturn(ctx, operand, syntax.ref); + PrepareArguments(ctx, operand, syntax.value[0].value[0], false, syntax.ref); + + const stackReg = ctx.file.owner.project.stackReg.ref; + + // Shift the stack pointer forward + const stackBk = ctx.scope.register.allocate(i32.bitcode); + ctx.block.push(Instruction.global.get(stackReg)); + ctx.block.push(Instruction.local.tee(stackBk.ref)); + ctx.block.push(Instruction.const.i32(ctx.scope.stack.getLatentSize())); + ctx.block.push(Instruction.i32.add()); + ctx.block.push(Instruction.global.set(stackReg)); + + ctx.block.push(Instruction.call(operand.ref)); + + // Restore stack pointer + ctx.block.push(Instruction.local.get(stackBk.ref)); + ctx.block.push(Instruction.global.set(stackReg)); + stackBk.free(); + + return returnType; +} + +function PrepareReturn(ctx: Context, target: Function, ref: ReferenceRange): VirtualType | IntrinsicValue | LinearType { + const stackReg = ctx.file.owner.project.stackReg.ref; + + if (target.returns instanceof VirtualType) { + return target.returns; + } + + if (target.returns.length != 1) Panic( + `${colors.red("Error")}: Multi-return is currently unsupported\n`, + { path: ctx.file.path, name: ctx.file.name, ref } + ); + + const primary = target.returns[0]; + if (primary.type instanceof IntrinsicType) { + return primary.type.value; + } else { + const alloc = ctx.scope.stack.allocate(primary.type.size, primary.type.align); + const forward = primary.type instanceof IntrinsicType + ? primary.type.value + : primary.type; + const returnType = LinearType.make(forward, alloc, ctx.file.owner.project.stackBase); + returnType.markDefined(); + + ctx.block.push(Instruction.global.get(stackReg)); + ctx.block.push(Instruction.const.i32(alloc.getOffset())); + + return returnType; + } +} + +function PrepareArguments(ctx: Context, target: Function, args: Syntax.Term_Arg_list | undefined, tailCall: boolean, ref: ReferenceRange) { + + let i = 0; + for (const arg of LineariseArgList(args)) { + if (target.arguments.length <= i) Panic( + `${colors.red("Error")}: Too many arguments supplied\n`, + { path: ctx.file.path, name: ctx.file.name, ref } + ); + + const signature = target.arguments[i]; + i++; + + const res = CompileExpr(ctx, arg, signature.type); + if (IsNamespace(res)) { + ctx.markFailure(`${colors.red("Error")}: Cannot use a namespace as an argument\n`, arg.ref); + continue; + } + + if (!res.like(signature.type)) ctx.markFailure( + `${colors.red("Error")}: Call argument type miss-match, expected ${colors.cyan(signature.type.name)} got ${colors.cyan(res.getTypeName())}\n`, + arg.ref + ); + + // Special post-processing for linear types + if (!(res instanceof LinearType)) continue; + + const final = ResolveLinearType(ctx, res, arg.ref, true); + if (tailCall && !(final instanceof IntrinsicValue) && res.alloc !== null) ctx.markFailure( + `${colors.red("Error")}: Cannot use a locally created value as a tail call argument\n`, + arg.ref + ); + } + + if (i != target.arguments.length) ctx.markFailure( + `${colors.red("Error")}: Miss matched argument count\n`, + ref + ); +} + + + + + +export function CompileTailCall(ctx: Context, syntax: Syntax.Term_Expr_call, operand: OperandType) { + if (!(operand instanceof Function)) Panic( + `${colors.red("Error")}: Cannot call on a non function value\n`, + { path: ctx.file.path, name: ctx.file.name, ref: syntax.ref } + ); + + operand.compile(); // check the function is compiled + + if (!operand.ref) throw new Error("A function somehow compiled with no reference generated"); + + const expect = Array.isArray(ctx.function.returns) ? ctx.function.returns[0].type : ctx.function.returns; + const returnType = PrepareReturnTail(ctx, operand, syntax.ref); + if (returnType != expect) ctx.markFailure( + `${colors.red("Error")}: Return type miss-match, expected ${colors.cyan(expect.getTypeName())} got ${colors.cyan(returnType.getTypeName())}\n`, + syntax.ref + ); + + PrepareArguments(ctx, operand, syntax.value[0].value[0], true, syntax.ref); + + ctx.scope.cleanup(true); + + if (ctx.function.owner.owner.project.flags.tailCall) { + ctx.block.push(Instruction.return_call(operand.ref)); + } else { + ctx.block.push(Instruction.call(operand.ref)); + ctx.block.push(Instruction.return()); + } + + if (returnType instanceof LinearType) returnType.dispose(); + ctx.done = true; + return never; +} + +function PrepareReturnTail(ctx: Context, target: Function, ref: ReferenceRange) { + if (target.returns instanceof VirtualType) { + return target.returns; + } + + if (target.returns.length != 1) Panic( + `${colors.red("Error")}: Multi-return is currently unsupported\n`, + { path: ctx.file.path, name: ctx.file.name, ref } + ); + + const primary = target.returns[0]; + if (primary.type instanceof IntrinsicType) { + return primary.type; + } else { + const out = ctx.scope.getVariable("return", false); + if (!out) throw new Error("Return variable somehow wasn't declared"); + + ResolveLinearType(ctx, out.type, ref); + } + + return primary.type; +} \ No newline at end of file diff --git a/source/compiler/codegen/expression/postfix/index.ts b/source/compiler/codegen/expression/postfix/index.ts new file mode 100644 index 0000000..6e24d85 --- /dev/null +++ b/source/compiler/codegen/expression/postfix/index.ts @@ -0,0 +1,47 @@ +import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; + +import type * as Syntax from "~/bnf/syntax.d.ts"; +import { AssertUnreachable } from "~/helper.ts"; +import { CompileCall } from "~/compiler/codegen/expression/postfix/call.ts"; +import { OperandType } from "~/compiler/codegen/expression/type.ts"; +import { Context } from "~/compiler/codegen/context.ts"; +import { Panic } from "~/compiler/helper.ts"; + + + +export function CompilePostfixes(ctx: Context, syntax: Syntax.Term_Expr_postfix[], type: OperandType, tailCall = false): OperandType { + let res = type; + + for (let i=0; i { + if (args === undefined) return; + + yield args.value[0]; + + for (const child of args.value[1].value) { + yield child.value[0]; + } + + return; +} \ No newline at end of file diff --git a/source/compiler/codegen/expression/precedence.ts b/source/compiler/codegen/expression/precedence.ts index 43f36f7..bb1fbc0 100644 --- a/source/compiler/codegen/expression/precedence.ts +++ b/source/compiler/codegen/expression/precedence.ts @@ -1,29 +1,32 @@ import type { Term_Expr, Term_Expr_arg, _Literal } from "~/bnf/syntax.d.ts"; import { ReferenceRange } from "~/parser.ts"; -import { Panic } from "~/helper.ts"; +import { Panic } from "~/compiler/helper.ts"; +import { assert } from "https://deno.land/std@0.201.0/assert/assert.ts"; const precedence = { ".": 1, "->": 1, - "*" : 3, "/" : 3, "%" : 3, - "+" : 4, "-" : 4, - "<<": 5, ">>": 5, - "<" : 6, ">" : 6, "<=": 6, ">=": 6, - "instanceof": 6.5, - "==": 7, "!=": 7, - "as": 7.5, - "&": 8, - "^": 9, - "|": 10, - "&&": 11, - "||": 12, + "**": 2, + "%": 3, + "*" : 4, "/" : 4, + "+" : 5, "-" : 5, + "<<": 6, ">>": 6, + "<" : 7, ">" : 7, "<=": 7, ">=": 7, + "instanceof": 8, + "==": 9, "!=": 9, + "&": 10, + "^": 11, + "|": 12, + "as": 13, + "&&": 14, + "||": 15, } as { [key: string]: number }; export function GetPrecedence (a: string, b: string) { const A = precedence[a]; const B = precedence[b]; - if (!A) Panic(`Unknown infix operation ${a}`); - if (!B) Panic(`Unknown infix operation ${a}`); + if (A === undefined) Panic(`Unknown infix operation ${a} 0x${a.charCodeAt(0).toString(16)}`); + if (B === undefined) Panic(`Unknown infix operation ${b} 0x${b.charCodeAt(0).toString(16)}`); return A !== B ? Math.min(1, Math.max(-1, A-B)) @@ -39,51 +42,69 @@ export type PrecedenceTree = Term_Expr_arg | { }; export function ApplyPrecedence(syntax: Term_Expr) { - let root: PrecedenceTree = syntax.value[0] as PrecedenceTree; + const rpn = new Array(); + const op_stack = new Array(); + rpn.push(syntax.value[0]); for (const action of syntax.value[1].value) { - const op = action.value[0].value; - const arg = action.value[1] - - // First action - if (root.type !== "infix") { - root = { - type: "infix", - lhs: root, - op, - rhs: arg, - ref: ReferenceRange.union(root.ref, arg.ref) - }; - continue; + const op = action.value[0].value; + while (op_stack.length > 0) { + const prev = op_stack[op_stack.length - 1]!; // peak + if (GetPrecedence(prev, op) <= 0) { + rpn.push(op_stack.pop()!); + } else break; } + op_stack.push(op); + rpn.push(action.value[1]); + } + + // Drain remaining operators + while (op_stack.length > 0) { + rpn.push(op_stack.pop()!); + } - const p = GetPrecedence(root.op, op); - if (p > 0) { - // Transform stealing previous operand - // (1 + 2) * 3 -> (2 * 3) + 1 - root = { - type: "infix", - lhs: { - type: "infix", - lhs: root.rhs, - op, - rhs: arg, - ref: ReferenceRange.union(root.ref, arg.ref) - }, - op: root.op, - rhs: root.lhs, - ref: ReferenceRange.union(arg.ref, arg.ref) - } - } else { - root = { - type: "infix", - lhs: root, - op: op, - rhs: arg, - ref: ReferenceRange.union(root.ref, arg.ref) - } + // This could probably be optimised in the future to not use a stack, and just manipulate a raw root node + const stack = new Array(); + while (rpn.length > 0) { + const token = rpn.shift()!; + + if (typeof token != "string") { + stack.push(token); + continue; } + + const rhs = stack.pop()!; + const lhs = stack.pop()!; + + stack.push({ + type: "infix", + lhs: lhs, + op: token, + rhs: rhs, + ref: ReferenceRange.union(lhs.ref, rhs.ref) + }) } + const root = stack.pop()!; + assert(typeof root !== "string", "Expression somehow has no arguments during precedence calculation"); + assert(stack.length == 0, "Expression somehow has only operators during precedence calculation"); + return root; +} + + +// For debugging assistance when hell breaks loose +function StringifyPrecedence(tree: PrecedenceTree | string): string { + if (typeof tree === "string") return tree; + + if (tree.type === "infix") return `(${StringifyPrecedence(tree.lhs)} ${tree.op} ${StringifyPrecedence(tree.rhs)})`; + + const arg = tree.value[1].value[0]; + if (arg.type == "expr_brackets") return `(...)`; + if (arg.type != "constant") return `type[${arg.type}]`; + + if (arg.value[0].type == "boolean") return arg.value[0].value[0].value; + if (arg.value[0].type == "integer") return arg.value[0].value[0].value; + if (arg.value[0].type == "float") return arg.value[0].value[0].value; + return "str"; } \ No newline at end of file diff --git a/source/compiler/codegen/expression/prefix.ts b/source/compiler/codegen/expression/prefix.ts index fc6ea53..9bc544f 100644 --- a/source/compiler/codegen/expression/prefix.ts +++ b/source/compiler/codegen/expression/prefix.ts @@ -2,13 +2,14 @@ import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; import type * as Syntax from "~/bnf/syntax.d.ts"; import { IntrinsicValue, f32, f64, i16, i32, i64, i8, u16, u32, u64, u8 } from "~/compiler/intrinsic.ts"; -import { AssertUnreachable, Panic } from "~/helper.ts"; import { OperandType, SolidType } from "~/compiler/codegen/expression/type.ts"; +import { AssertUnreachable } from "~/helper.ts"; import { Instruction } from "~/wasm/index.ts"; import { Context } from "~/compiler/codegen/context.ts"; +import { Panic } from "~/compiler/helper.ts"; -export function CompilePrefix(ctx: Context, prefix: Syntax.Term_Expr_prefix, type: OperandType, expect?: SolidType) { +export function CompilePrefix(ctx: Context, prefix: Syntax.Term_Expr_prefix, type: OperandType, expect?: SolidType): OperandType { const op = prefix.value[0].value; switch (op) { case "!": @@ -21,16 +22,16 @@ export function CompilePrefix(ctx: Context, prefix: Syntax.Term_Expr_prefix, typ } } -function CompileInverse(ctx: Context, type: OperandType, prefix: Syntax.Term_Expr_prefix) { +function CompileInverse(ctx: Context, type: OperandType, prefix: Syntax.Term_Expr_prefix): OperandType { if (!(type instanceof IntrinsicValue)) Panic( `${colors.red("Error")}: Cannot apply prefix operation to non-variable\n`, { path: ctx.file.path, name: ctx.file.name, ref: prefix.ref }); - if (type === u8.value || type === u16.value || type === u32.value || type === u64.value) Panic( - `${colors.red("Error")}: Cannot invert an unsigned integer\n`, - { path: ctx.file.path, name: ctx.file.name, ref: prefix.ref } - ); + if (type === u8.value || type === u16.value || type === u32.value || type === u64.value) { + ctx.markFailure(`${colors.red("Error")}: Cannot invert an unsigned integer\n`, prefix.ref); + return type; + }; if (type === i8.value || type === i16.value || type === i32.value) { ctx.block.push(Instruction.const.i32(-1)); diff --git a/source/compiler/codegen/scope.ts b/source/compiler/codegen/scope.ts index 05041c2..9c99c50 100644 --- a/source/compiler/codegen/scope.ts +++ b/source/compiler/codegen/scope.ts @@ -48,7 +48,7 @@ export class Scope { ctx.block.push(Instruction.global.get(ctx.file.owner.project.stackReg.ref)); // value ctx.block.push(Instruction.local.get(reg.ref)); - Store(ctx, type, linear.offset); + Store(ctx, type, linear.offset, ref); this.vars[name] = new Variable(name, linear); reg.free(); diff --git a/source/compiler/file.ts b/source/compiler/file.ts index df36873..72fbc83 100644 --- a/source/compiler/file.ts +++ b/source/compiler/file.ts @@ -1,17 +1,20 @@ /// import type Package from "./package.ts"; -import type { Term_Access, Term_Function, Term_Program, Term_Structure } from "~/bnf/syntax.d.ts"; +import type { Term_Access, Term_External, Term_Function, Term_Program, Term_Structure } from "~/bnf/syntax.d.ts"; -import { IntrinsicType, bool, u8, i8, u16, i16, i32, i64, u32, u64, f32, f64 } from "~/compiler/intrinsic.ts"; -import { AssertUnreachable, FlatAccess, FlattenAccess } from "~/helper.ts"; -import { Parse } from "~/parser.ts"; import Structure from "~/compiler/structure.ts"; import Function from "~/compiler/function.ts"; import Global from "~/compiler/global.ts"; import Import from "~/compiler/import.ts"; +import { IntrinsicType, bool, u8, i8, u16, i16, i32, i64, u32, u64, f32, f64, none, never } from "~/compiler/intrinsic.ts"; +import { FlatAccess, FlattenAccess } from "~/compiler/helper.ts"; +import { AssertUnreachable } from "~/helper.ts"; +import { SimplifyString } from "~/compiler/codegen/expression/constant.ts"; +import { VirtualType } from "~/compiler/intrinsic.ts"; +import { Parse } from "~/parser.ts"; -export type Namespace = Function | Import | Global | Structure | IntrinsicType ; +export type Namespace = Function | Import | Global | Structure | IntrinsicType | VirtualType ; // deno-lint-ignore no-explicit-any export function IsNamespace(val: any): val is Namespace { @@ -37,6 +40,7 @@ export class File { this.path = path; this.namespace = { + none, never, bool, // virtual native types u8, i8, u16, i16, // virtual native types i32, i64, u32, u64, // native int types @@ -83,15 +87,16 @@ function Ingest(file: File, syntax: Term_Program) { const inner = stmt_top.value[0]; switch (inner.type) { - case "function": IngestFunction(file, inner); break; + case "function": IngestFunction(file, inner); break; case "structure": IngestStructure(file, inner); break; + case "external": IngestExternal(file, inner); break; default: AssertUnreachable(inner); } } } -function IngestFunction(file: File, syntax: Term_Function) { - const func = new Function(file, syntax); +function IngestFunction(file: File, syntax: Term_Function, external?: string) { + const func = new Function(file, syntax, external); const existing = file.namespace[func.name]; if (!existing) { @@ -99,11 +104,6 @@ function IngestFunction(file: File, syntax: Term_Function) { return; } - if (existing instanceof Function) { - existing.merge(func); - return; - } - throw new Error(`Cannot merge a function with a non-function ${func.name}`); } @@ -117,4 +117,38 @@ function IngestStructure(file: File, syntax: Term_Structure) { } throw new Error(`Structures cannot share a namespace`); +} + + + +function IngestExternal(file: File, syntax: Term_External) { + if (syntax.value[0].type !== "ext_import") throw new Error(`Unsupported external export`); + + const name = SimplifyString(syntax.value[0].value[1]); + for (const inner of syntax.value[0].value[0].value) { + const line = inner.value[0]; + const type = line.type; + switch (type) { + case "function": { + IngestFunction(file, line, name.str); + } break; + case "ext_import_var": throw new Error(`Import global unimplemented`); + default: AssertUnreachable(type); + } + } + + // const func = new Function(file, syntax); + + // const existing = file.namespace[func.name]; + // if (!existing) { + // file.namespace[func.name] = func; + // return; + // } + + // if (existing instanceof Function) { + // existing.merge(func); + // return; + // } + + // throw new Error(`Cannot merge a function with a non-function ${func.name}`); } \ No newline at end of file diff --git a/source/compiler/function.ts b/source/compiler/function.ts index 17ef469..f04f00b 100644 --- a/source/compiler/function.ts +++ b/source/compiler/function.ts @@ -3,13 +3,13 @@ import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; import type { Term_Access, Term_Function } from "~/bnf/syntax.d.ts"; import type { File, Namespace } from "./file.ts"; +import Structure from "~/compiler/structure.ts"; +import { IntrinsicType, VirtualType, never } from "~/compiler/intrinsic.ts"; import { ReferenceRange, SourceView } from "~/parser.ts"; import { IsSolidType, SolidType } from "~/compiler/codegen/expression/type.ts"; -import { IntrinsicType } from "~/compiler/intrinsic.ts"; import { Context } from "~/compiler/codegen/context.ts"; import { FuncRef } from "~/wasm/funcRef.ts"; import { Scope } from "~/compiler/codegen/scope.ts"; -import { Panic } from "~/helper.ts"; class Argument { @@ -31,20 +31,23 @@ export default class Function { name: string; ref: FuncRef | null; + external?: string; + isCompiled: boolean; isLinking: boolean; isLinked: boolean; arguments: Argument[]; - returns: Argument[]; + returns: Argument[] | VirtualType; - constructor(owner: File, ast: Term_Function) { + constructor(owner: File, ast: Term_Function, external?: string) { + this.external = external; this.owner = owner; this.name = ast.value[0].value[0].value; this.ast = ast; this.ref = null; - this.returns = []; + this.returns = never; this.arguments = []; this.isLinking = false; @@ -91,9 +94,20 @@ export default class Function { if (types === null) return; for (let i=0; i !(x.type instanceof IntrinsicType)) - .map(x => x.type.getBitcode()), - ...this.arguments - .map(x => x.type.getBitcode()) - ], - this.returns - .filter(x => x.type instanceof IntrinsicType) - .map(x => x.type.getBitcode()), - ); + + const body = this.ast.value[1]; + if (this.external) { + const file = this.getFile(); + if (body.type !== "literal") { + console.error(`${colors.red("Error")}: External imports must have no body\n`+ + SourceView(file.path, file.name, body.ref) + ); + file.markFailure(); + return; + } + + const mod = file.owner.project.module; + const typeIdx = mod.makeType(args, rets); + const ref = mod.importFunction(this.external, this.name, typeIdx); + if (ref === null) { + console.error(`${colors.red("Error")}: Import name conflict\n`+ + SourceView(file.path, file.name, this.ast.ref) + ); + file.markFailure(); + return; + } + + this.ref = ref; + + return; + } + + + const func = project.module.makeFunction( args, rets ); this.ref = func.ref; const scope = new Scope(func); const ctx = new Context(this.getFile(), this, scope, func.code); - for (const ret of this.returns) { - if (ret.type instanceof IntrinsicType) continue; - scope.registerArgument(ctx, ret.name, ret.type, ret.ref); + if (Array.isArray(this.returns)) for (const ret of this.returns) { + if (ret.type instanceof Structure) scope.registerArgument(ctx, ret.name, ret.type, ret.ref); } for (const arg of this.arguments) { scope.registerArgument(ctx, arg.name, arg.type, arg.ref) } - const body = this.ast.value[1]; - if (body.type === "literal") throw new Error("Missing function body"); + if (body.type === "literal") { + console.error(`${colors.red("Error")}: Missing function body\n`+ + SourceView(ctx.file.path, ctx.file.name, body.ref) + ); + ctx.file.markFailure(); + return; + } ctx.compile(body.value[0].value); scope.stack.resolve(); - if (!ctx.done) Panic(`${colors.red("Error")}: Function ${colors.brightBlue(this.name)} does not return\n`, { - path: ctx.file.path, name: ctx.file.name, ref: body.ref - }) + if (!ctx.done) { + console.error(`${colors.red("Error")}: Function ${colors.brightBlue(this.name)} does not return\n`+ + SourceView(ctx.file.path, ctx.file.name, body.ref) + ); + ctx.file.markFailure(); + } } } @@ -162,7 +220,7 @@ export default class Function { function LinkTypes(scope: File, syntax: Term_Access[]) { - const out: SolidType[] = []; + const out: Array = []; let failed = false; for (const arg of syntax) { @@ -177,7 +235,7 @@ function LinkTypes(scope: File, syntax: Term_Access[]) { ) failed = true; continue; - } else if (!IsSolidType(res)) { + } else if (!IsSolidType(res) && !(res instanceof VirtualType)) { console.error( `${colors.red("Error")}: Function parameters must be a solid type\n` + SourceView(scope.path, scope.name, arg.ref) diff --git a/source/compiler/helper.ts b/source/compiler/helper.ts new file mode 100644 index 0000000..dc0f282 --- /dev/null +++ b/source/compiler/helper.ts @@ -0,0 +1,52 @@ +import { assert } from "https://deno.land/std@0.201.0/assert/mod.ts"; + +import type { Term_Access, Term_Access_comp, Term_Access_dynamic, Term_Access_static, Term_Name } from "~/bnf/syntax.d.ts"; +import type { ReferenceRange } from "~/bnf/shared.d.ts"; +import { SourceView } from "~/parser.ts"; + +export type FlatAccess = (Term_Name | Term_Access_static | Term_Access_dynamic | Term_Access_comp)[]; + +export function FlattenAccess(syntax: Term_Access): FlatAccess { + return [ + syntax.value[0], + ...syntax.value[1].value.map(x => x.value[0].value[0]) + ].reverse(); +} + + + + + +export type SourceMap = { + path: string, + name: string, + ref: ReferenceRange +} + +export function Panic(x: string, source?: SourceMap): never { + if (source) console.error(x + SourceView(source.path, source.name, source.ref)); + else console.error(x); + Deno.exit(1); +} + + + + + +export function AlignUpInteger(x: number, multiple: number) { + assert(multiple !== 0, "Cannot align by zero"); + + const remainder = x % multiple; + return remainder !== 0 + ? x + (multiple - remainder) + : x; +} + +export function AlignDownInteger(x: number, multiple: number) { + assert(multiple !== 0, "Cannot align by zero"); + + const remainder = x % multiple; + return remainder !== 0 + ? x - remainder + : x; +} \ No newline at end of file diff --git a/source/compiler/project.ts b/source/compiler/project.ts index eda86f3..69ef7db 100644 --- a/source/compiler/project.ts +++ b/source/compiler/project.ts @@ -5,6 +5,10 @@ import { GlobalRegister } from "~/wasm/section/global.ts"; import { Instruction } from "~/wasm/index.ts"; import { Intrinsic } from "~/wasm/type.ts"; +type ProjectFlags = { + tailCall: boolean; +} + export default class Project { module: Module; packages: Package[]; @@ -12,6 +16,8 @@ export default class Project { stackReg: GlobalRegister; stackBase: BasePointer; + flags: ProjectFlags; + failed: boolean; constructor() { @@ -27,6 +33,10 @@ export default class Project { this.stackBase = new BasePointer(BasePointerType.global, this.stackReg.ref); this.module.addMemory(1, 1); + + this.flags = { + tailCall: true + }; } markFailure() { diff --git a/source/compiler/structure.ts b/source/compiler/structure.ts index a7d972e..66e2619 100644 --- a/source/compiler/structure.ts +++ b/source/compiler/structure.ts @@ -2,10 +2,11 @@ import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; import type { Term_Structure } from "~/bnf/syntax.d.ts"; import type { File, Namespace } from "~/compiler/file.ts"; -import { AssertUnreachable, Panic } from "~/helper.ts"; import { IsSolidType, SolidType } from "~/compiler/codegen/expression/type.ts"; +import { AssertUnreachable } from "~/helper.ts"; import { ReferenceRange } from "~/bnf/shared.d.ts"; import { SourceView } from "~/parser.ts"; +import { Panic } from "~/compiler/helper.ts"; import { i32 } from "~/compiler/intrinsic.ts"; export default class Structure { diff --git a/source/helper.ts b/source/helper.ts index 8a3447e..8b7dbeb 100644 --- a/source/helper.ts +++ b/source/helper.ts @@ -1,32 +1,4 @@ -import { assert } from "https://deno.land/std@0.201.0/assert/mod.ts"; - -import type { Term_Access, Term_Access_comp, Term_Access_dynamic, Term_Access_static, Term_Name } from "~/bnf/syntax.d.ts"; -import type { ReferenceRange } from "~/bnf/shared.d.ts"; -import { SourceView } from "~/parser.ts"; - -export type FlatAccess = (Term_Name | Term_Access_static | Term_Access_dynamic | Term_Access_comp)[]; - -export function FlattenAccess(syntax: Term_Access): FlatAccess { - return [ - syntax.value[0], - ...syntax.value[1].value.map(x => x.value[0].value[0]) - ].reverse(); -} - - -export function FlatAccessToStr(access: FlatAccess): string { - return access.map(x => - x.type === "access_static" ? `.${x.value}` - : x.type === "name" ? `.${x.value}` - : x.type === "access_dynamic" ? "[]" - : x.type === "access_comp" ? "#[]" - : "UNK" - ).join("") -} - - export type Byte = number; - export function isByte(value: number): value is Byte { return Number.isInteger(value) && value >= 0 && value <= 255; } @@ -37,18 +9,14 @@ export function AssertUnreachable(x: never): never { } -export type SourceMap = { - path: string, - name: string, - ref: ReferenceRange -} -export function Panic(x: string, source?: SourceMap): never { - if (source) console.error(x + SourceView(source.path, source.name, source.ref)); - else console.error(x); - Deno.exit(1); -} +export class Box { + value: T; + constructor(val: T) { + this.value = val; + } +} export class LatentValue { private value: T | null; @@ -75,65 +43,35 @@ export class LatentValue { } } -export type LatentLike = LatentValue | T; - - -export function ReadLatentLike(v: LatentLike) { - if (v instanceof LatentValue) return v.get(); - return v; -} - export class LatentOffset { private base: LatentValue; private offset: number; - private value: number | null; + private cache: number | null; constructor(base: LatentValue | LatentOffset, offset: number) { if (base instanceof LatentOffset) { this.offset = base.offset + offset; this.base = base.base; - this.value = null; + this.cache = null; } else { this.offset = offset; this.base = base; - this.value = null; + this.cache = null; } } get (): number { - if (this.value === null) { - this.value = this.base.get() + this.offset; + if (this.cache === null) { + this.cache = this.base.get() + this.offset; } - return this.value; + return this.cache; } } - -export function AlignUpInteger(x: number, multiple: number) { - assert(multiple !== 0, "Cannot align by zero"); - - const remainder = x % multiple; - return remainder !== 0 - ? x + (multiple - remainder) - : x; -} - -export function AlignDownInteger(x: number, multiple: number) { - assert(multiple !== 0, "Cannot align by zero"); - - const remainder = x % multiple; - return remainder !== 0 - ? x - remainder - : x; -} - - - - const _timer: { [key: string]: { start: number, end: number } } = {}; export function TimerStart(key: string) { const now = Date.now(); diff --git a/source/parser.ts b/source/parser.ts index 4a30c52..34b6b9f 100644 --- a/source/parser.ts +++ b/source/parser.ts @@ -3,7 +3,7 @@ import * as colors from "https://deno.land/std@0.201.0/fmt/colors.ts"; import * as Instance from "~/bnf/syntax.js"; import * as Syntax from "~/bnf/syntax.d.ts"; import { ParseError, ReferenceRange, Reference, SyntaxNode } from "~/bnf/shared.js"; -import { Panic } from "~/helper.ts"; +import { Panic } from "~/compiler/helper.ts"; await Instance.ready; diff --git a/source/wasm/instruction/index.ts b/source/wasm/instruction/index.ts index d43bc60..479600c 100644 --- a/source/wasm/instruction/index.ts +++ b/source/wasm/instruction/index.ts @@ -1,4 +1,4 @@ -import { Unreachable, IfBlock, Block, Loop, NoOp, Br, Br_If, Return } from "./control-flow.ts"; +import { Unreachable, IfBlock, Block, Loop, NoOp, Br, Br_If, Return } from "~/wasm/instruction/control-flow.ts"; import { EncodeU32 } from "~/wasm/type.ts"; import { FuncRef } from "~/wasm/funcRef.ts"; @@ -24,6 +24,21 @@ export class Call { } } +export class ReturnCall { + x: FuncRef | number; + + constructor(funcRef: FuncRef | number) { + this.x = funcRef; + } + + toBinary(): Byte[] { + return [ + 0x12, + ...EncodeU32(this.x instanceof FuncRef ? this.x.get() : this.x) + ]; + } +} + export class Drop { constructor() {} @@ -78,6 +93,7 @@ const wrapper = { block: (typeIdx: number, n?: Any[]) => new Block(typeIdx, n), if : (typeIdx: number, t?: Any[], f?: Any[]) => new IfBlock(typeIdx, t, f), loop : (typeIdx: number, n?: Any[]) => new Loop(typeIdx, n), + return_call : (funcRef: FuncRef | number) => new ReturnCall(funcRef), call : (funcRef: FuncRef | number) => new Call(funcRef), br_if: (i: number) => new Br_If(i), br : (i: number) => new Br(i), diff --git a/source/wasm/module.ts b/source/wasm/module.ts index a921c4f..b0f12bf 100644 --- a/source/wasm/module.ts +++ b/source/wasm/module.ts @@ -1,12 +1,11 @@ // https://webassembly.github.io/spec/core/binary/modules.html - import * as Section from "~/wasm/section/index.ts"; import { MemoryRef } from "~/wasm/memoryRef.ts"; import { Intrinsic } from "~/wasm/type.ts"; +import { Box, Byte } from "~/helper.ts"; import { Constant } from "~/wasm/instruction/constant.ts"; import { Function } from "~/wasm/function.ts"; import { FuncRef } from "~/wasm/funcRef.ts"; -import { Byte } from "~/helper.ts"; @@ -14,6 +13,7 @@ import { Byte } from "~/helper.ts"; export default class Module { typeSect : Section.Type; importSect : Section.Import; + funcSect : Section.Function; memorySect : Section.Memory; globalSect : Section.Global; exportSect : Section.Export; @@ -22,39 +22,16 @@ export default class Module { entryFunc : null | FuncRef; - funcs: Function[]; - constructor() { this.typeSect = new Section.Type(); this.importSect = new Section.Import(); + this.funcSect = new Section.Function(); this.memorySect = new Section.Memory(); this.globalSect = new Section.Global(); this.exportSect = new Section.Export(); this.startSect = new Section.Start(); this.dataSect = new Section.Data(); - this.entryFunc = null; - this.funcs = []; - } - - importFunction(mod: string, name: string, typeIdx: number) { - const idx = this.importSect.registerFunction(mod, name, typeIdx); - - const ref = new FuncRef(true); - ref.resolve(idx); - - return ref; - } - - exportFunction(name: string, func: FuncRef) { - return this.exportSect.bind(name, func); - } - - startFunction(func: FuncRef) { - return this.startSect.ref = func; - } - - exportMemory(name: string, mem: MemoryRef) { - return this.exportSect.bind(name, mem); + this.entryFunc = null; } addMemory(minPages: number, maxPages?: number): MemoryRef { @@ -68,10 +45,14 @@ export default class Module { return this.dataSect.setData(offset, data); } + makeType(input: Intrinsic[], output: Intrinsic[]): number { + return this.typeSect.makeType(input, output); + } + makeFunction(input: Intrinsic[], output: Intrinsic[]): Function { const type = this.makeType(input, output); const func = new Function(type, input.length, output.length); - this.bindFunction(func); + this.funcSect.push(func); return func; } @@ -80,58 +61,51 @@ export default class Module { return this.globalSect.bind(type, mut, expr); } - bindFunction(func: Function) { - if (this.funcs.includes(func)) - return; - - this.funcs.push(func); + importFunction(mod: string, name: string, typeIdx: number) { + return this.importSect.registerFunction(mod, name, typeIdx); } - setEntry(ref: FuncRef) { - this.entryFunc = ref; + + exportFunction(name: string, func: FuncRef) { + return this.exportSect.bind(name, func); } - unbindFunction(func: Function) { - const index = this.funcs.indexOf(func); - if (index == -1) return; + exportMemory(name: string, mem: MemoryRef) { + return this.exportSect.bind(name, mem); + } - this.funcs.splice(index, 1); + setEntry(ref: FuncRef) { + this.entryFunc = ref; } - makeType(input: Intrinsic[], output: Intrinsic[]): number { - return this.typeSect.makeType(input, output); + startFunction(func: FuncRef) { + return this.startSect.ref = func; } toBinary() { const buffer: Byte[] = []; - buffer.push(...[0x00, 0x61, 0x73, 0x6d]); // PREAMBLE - buffer.push(...[0x01, 0x00, 0x00, 0x00]); // WASM_BINARY_VERSION - buffer.push(...this.typeSect.toBinary()); // functype* : typesec - buffer.push(...this.importSect.toBinary()); // imports* : importsec - buffer.push( // typeidx^n : funcsec - ...Section.Function.toBinary( - this.importSect.getFuncs(), - this.funcs - ) - ); + const funcID = new Box(0); + + buffer.push(...[0x00, 0x61, 0x73, 0x6d]); // PREAMBLE + buffer.push(...[0x01, 0x00, 0x00, 0x00]); // WASM_BINARY_VERSION + + buffer.push(...this.typeSect.toBinary()); // functype* : typesec + buffer.push(...this.importSect.toBinary(funcID)); // imports* : importsec + buffer.push(...this.funcSect.headerToBinary(funcID)); // typeidx^n : funcsec // table* : tablesec - buffer.push(...this.memorySect.toBinary(0)) // mem* : memsec - buffer.push(...this.globalSect.toBinary()) // global* : globalsec - buffer.push(...this.exportSect.toBinary()) // export* : exportsec - - if (this.entryFunc) { - buffer.push( // start? : startsec - ...Section.Start.toBinary(this.entryFunc) - ) - } + buffer.push(...this.memorySect.toBinary(0)) // mem* : memsec + buffer.push(...this.globalSect.toBinary()) // global* : globalsec + buffer.push(...this.exportSect.toBinary()) // export* : exportsec + + // start? : startsec + if (this.entryFunc) buffer.push(...Section.Start.toBinary(this.entryFunc)) + // elm* : elmsec // buffer.push( // m? : datacountsec // ...Section.DataCount.toBinary(this.dataSect) // ) - buffer.push( // code^n : codesec - ...Section.Code.toBinary(this.funcs) - ); + buffer.push(...this.funcSect.bodyToBinary()); // code^n : codesec buffer.push(...this.dataSect.toBinary()) // data^m : datasec diff --git a/source/wasm/section/code.ts b/source/wasm/section/code.ts deleted file mode 100644 index ee12e0c..0000000 --- a/source/wasm/section/code.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { EncodeU32 } from "~/wasm/type.ts"; -import { Function } from "~/wasm/function.ts"; -import { Byte } from "~/helper.ts"; - - -export default class CodeSection { - - constructor() {} - - static toBinary (funcs: Function[]): Byte[] { - const buf = EncodeU32(funcs.length); - for (const func of funcs) { - buf.push(...func.toBinary()) - } - - return [CodeSection.typeID, ...EncodeU32(buf.length), ...buf]; - } - - static typeID = 10; -} \ No newline at end of file diff --git a/source/wasm/section/export.ts b/source/wasm/section/export.ts index dd2d60c..3722c19 100644 --- a/source/wasm/section/export.ts +++ b/source/wasm/section/export.ts @@ -1,3 +1,4 @@ +// https://webassembly.github.io/spec/core/binary/modules.html#export-section import { EncodeName, EncodeU32 } from "~/wasm/type.ts"; import { MemoryRef } from "~/wasm/memoryRef.ts"; import { FuncRef } from "~/wasm/funcRef.ts"; diff --git a/source/wasm/section/function.ts b/source/wasm/section/function.ts index fbf6eea..ef630ab 100644 --- a/source/wasm/section/function.ts +++ b/source/wasm/section/function.ts @@ -1,23 +1,49 @@ import { EncodeU32 } from "~/wasm/type.ts"; +import { Box, Byte } from "~/helper.ts"; import { Function } from "~/wasm/function.ts"; -import { Byte } from "~/helper.ts"; export default class FunctionSection { - static typeID = 3; + static headerTypeID = 3; // typeidx^n : funcsec + static bodyTypeID = 10; // code^n : codesec - static toBinary(idxOffset: number, funcs: Function[]) { - let buf: Byte[] = EncodeU32(funcs.length); + private funcs: Function[]; - for (const func of funcs) { - func.resolve(idxOffset++, true); + constructor() { + this.funcs = []; + } + + push(func: Function) { + if (this.funcs.includes(func)) return; + + this.funcs.push(func); + } + + headerToBinary(funcID: Box) { + const buf: Byte[] = EncodeU32(this.funcs.length); + + for (const func of this.funcs) { + func.resolve(funcID.value++, true); buf.push(...EncodeU32(func.type)); } return [ - FunctionSection.typeID, + FunctionSection.headerTypeID, ...EncodeU32(buf.length), ...buf ]; } + + bodyToBinary (): Byte[] { + const buf = EncodeU32(this.funcs.length); + for (const func of this.funcs) { + buf.push(...func.toBinary()) + } + + return [ + FunctionSection.bodyTypeID, + ...EncodeU32(buf.length), + ...buf + ]; + } } \ No newline at end of file diff --git a/source/wasm/section/import.ts b/source/wasm/section/import.ts index 8f0b121..8ba0e1e 100644 --- a/source/wasm/section/import.ts +++ b/source/wasm/section/import.ts @@ -1,17 +1,19 @@ import type { Byte } from "~/helper.ts"; import { EncodeName, EncodeU32 } from "~/wasm/type.ts"; +import { FuncRef } from "~/wasm/funcRef.ts"; +import { Box } from "~/helper.ts"; class Register { mod: string; name: string; type: number; - idx: number; + ref: FuncRef; - constructor (mod: string, name: string, typeIdx: number, idx: number) { + constructor (mod: string, name: string, typeIdx: number) { this.mod = mod; this.name = name; this.type = typeIdx; - this.idx = idx; + this.ref = new FuncRef(false); } toBinary(): Byte[] { @@ -24,17 +26,17 @@ class Register { } } -interface InnerObject { +interface ModuleMap { [key: string]: Register; } -interface OuterObject { - [key: string]: InnerObject; +interface NamespaceMap { + [key: string]: ModuleMap; } export default class ImportSection { - _entries: OuterObject; + _entries: NamespaceMap; _funcs: number; constructor() { @@ -49,19 +51,17 @@ export default class ImportSection { const mod = this._entries[module]; if (!mod[name]) { - mod[name] = new Register(module, name, typeIdx, this._funcs++); - } else if (mod[name].type !== typeIdx) { - throw new Error(`Attempting to register import "${module}" "${name}" with new type`); - } + mod[name] = new Register(module, name, typeIdx); + } else if (mod[name].type !== typeIdx) return null; - return mod[name].idx; + return mod[name].ref; } getFuncs(): number { return this._funcs; } - toBinary (): Byte[] { + toBinary (funcID: Box): Byte[] { let length = 0; const buffer = []; @@ -69,6 +69,7 @@ export default class ImportSection { const mod = this._entries[module]; for (const name in mod) { + mod[name].ref.resolve(funcID.value++, true); buffer.push(...mod[name].toBinary()); length++; } diff --git a/source/wasm/section/index.ts b/source/wasm/section/index.ts index 864df07..42be845 100644 --- a/source/wasm/section/index.ts +++ b/source/wasm/section/index.ts @@ -8,11 +8,10 @@ import Global from "~/wasm/section/global.ts"; import Export from "~/wasm/section/export.ts"; import Start from "~/wasm/section/start.ts"; import Element from "~/wasm/section/element.ts"; -import Code from "~/wasm/section/code.ts"; import Data from "~/wasm/section/data.ts"; import DataCount from "~/wasm/section/data-count.ts"; -export type Section = Custom | Type | Import | Function | Table | Memory | Global | Export | Start | Element | Code | Data | DataCount ; +export type Section = Custom | Type | Import | Function | Table | Memory | Global | Export | Start | Element | Data | DataCount ; export { Custom, @@ -25,7 +24,6 @@ export { Export, Start, Element, - Code, Data, DataCount } \ No newline at end of file diff --git a/tests/e2e/compiler/fibonacci.test.ts b/tests/e2e/compiler/fibonacci.test.ts index 3e4ada9..e8b0296 100644 --- a/tests/e2e/compiler/fibonacci.test.ts +++ b/tests/e2e/compiler/fibonacci.test.ts @@ -19,7 +19,7 @@ Deno.test(`Signed integer Fibonacci test`, async () => { if n <= 0 { return a; } else { - return fib_tail(n - 1, b, a + b); + return_tail fib_tail(n - 1, b, a + b); }; }` ); diff --git a/tests/e2e/compiler/import.test.ts b/tests/e2e/compiler/import.test.ts new file mode 100644 index 0000000..0c38fd6 --- /dev/null +++ b/tests/e2e/compiler/import.test.ts @@ -0,0 +1,50 @@ +/// +import { fail, assertEquals, assertNotEquals, assert } from "https://deno.land/std@0.201.0/assert/mod.ts"; + +import * as CompilerFunc from "~/compiler/function.ts"; +import Package from "~/compiler/package.ts"; +import Project from "~/compiler/project.ts"; +import { FuncRef } from "~/wasm/funcRef.ts"; + +const source = ` +external import { + fn randInt(): i32; +} from "node"; + +fn main(): i32 { + return randInt() + 2; +}`; + +Deno.test(`Import test`, async () => { + const project = new Project(); + const mainPck = new Package(project, "./"); + const mainFile = mainPck.importRaw(source); + + const mainFunc = mainFile.namespace["main"]; + assert(mainFunc instanceof CompilerFunc.default, "Missing main function"); + mainFunc.compile(); + assertNotEquals(mainFunc.ref, null, "Main function hasn't compiled"); + project.module.exportFunction("_start", mainFunc.ref as FuncRef); + + let next = 0; + function randInt() { + next = Math.floor(Math.random()*65536); + return next; + } + + const wasmModule = new WebAssembly.Module(project.module.toBinary()); + const instance = await WebAssembly.instantiate(wasmModule, { + node: { randInt } + }); + const exports = instance.exports; + + // Call the _start function + let main: () => number = typeof exports._start === "function" + ? exports._start as any + : fail(`Expected _start to be a function`); + + for (let i=0; i<10; i++) { + const res = main(); + assertEquals(res, next + 2) + } +}); \ No newline at end of file diff --git a/tests/e2e/compiler/numeric.test.ts b/tests/e2e/compiler/numeric.test.ts index 9311509..a0234d3 100644 --- a/tests/e2e/compiler/numeric.test.ts +++ b/tests/e2e/compiler/numeric.test.ts @@ -1,18 +1,55 @@ /// -import { fail, assertEquals, assertNotEquals, assert } from "https://deno.land/std@0.201.0/assert/mod.ts"; +import { fail, assertNotEquals, assert } from "https://deno.land/std@0.201.0/assert/mod.ts"; import * as CompilerFunc from "~/compiler/function.ts"; import Package from "~/compiler/package.ts"; import Project from "~/compiler/project.ts"; import { FuncRef } from "~/wasm/funcRef.ts"; -const decoder = new TextDecoder(); +const source = ` +fn left(): f32 { + // (-2.5 % 2.0) * -3.0; + return -2.5 % 2.0 * -3.0; +} + +fn right(): i32 { + // 10.0 - 0.5 - 8.0 + // return 10.0 - 1.0 / 2.0 % 10.0 - 8.0; + return 10 - 0 - 8; +} + +fn main(): i32 { + + // if ( 10.0 - ( 3.0 / 2.0 ) - 8.0 != 10.0 - 3.0 / 2.0 - 8.0 ) { + // return 20; + // }; + + // (-2.5 % 2.0) * -3.0 == 10.0 - ((1.0 / 2.0) % 10.0) - 8.0; + // 1.5 == 1.5 + // true == 1 + + // doing this in a single expression to also ensure == is applied correctly + if ( (-2.5 % 2.0) * -3.0 ) != ( 10.0 - ( (1.0 / 2.0) % 10.0 ) - 8.0 ) { + return 29; + }; -const goalStdout = ""; + if ( (-2.5 % 2.0) * -3.0 != 10.0 - ( (1.0 / 2.0) % 10.0 ) - 8.0 ) { + return 33; + }; -const source = ` -fn main(): f32 { - return -3.5 % 2.0; + if ( (-2.5 % 2.0) * -3.0 != 10.0 - ( 1.0 / 2.0 % 10.0 ) - 8.0 ) { + return 37; + }; + + if ( -2.5 % 2.0 * -3.0 != 10.0 - ( 1.0 / 2.0 % 10.0 ) - 8.0 ) { + return 41; + }; + + if ( -2.5 % 2.0 * -3.0 != 10.0 - 1.0 / 2.0 % 10.0 - 8.0 ) { + return 45; + }; + + return 0; }`; Deno.test(`Numeric logic test`, async () => { @@ -27,48 +64,36 @@ Deno.test(`Numeric logic test`, async () => { assertNotEquals(mainFunc.ref, null, "Main function hasn't compiled"); project.module.exportFunction("_start", mainFunc.ref as FuncRef); - let stdout = ""; - let memory: WebAssembly.Memory; - - const imports = { - wasi_snapshot_preview1: { - fd_write: (fd: number, iovs: number, iovs_len: number, n_written: number) => { - const memoryArray = new Int32Array(memory.buffer); - const byteArray = new Uint8Array(memory.buffer); - for (let iovIdx = 0; iovIdx < iovs_len; iovIdx++) { - const bufPtr = memoryArray.at(iovs/4 + iovIdx*2) || 0; - const bufLen = memoryArray.at(iovs/4 + iovIdx*2 + 1) || 0; - const data = decoder.decode(byteArray.slice(bufPtr, bufPtr + bufLen)); - stdout += data; - } - return 0; // Return 0 to indicate success - } - } - }; + const left = mainFile.namespace["left"]; + assert(left instanceof CompilerFunc.default, "Missing left function"); + left.compile(); + assertNotEquals(left.ref, null, "Left function hasn't compiled"); + project.module.exportFunction("left", left.ref as FuncRef); - // Load the wasm module - const wasmModule = new WebAssembly.Module(project.module.toBinary()); + const right = mainFile.namespace["right"]; + assert(right instanceof CompilerFunc.default, "Missing right function"); + right.compile(); + assertNotEquals(right.ref, null, "Right function hasn't compiled"); + project.module.exportFunction("right", right.ref as FuncRef); - try { - // Instantiate the wasm module - const instance = await WebAssembly.instantiate(wasmModule, imports); + const wasmModule = new WebAssembly.Module(project.module.toBinary()); + const instance = await WebAssembly.instantiate(wasmModule, {}); - const exports = instance.exports; - memory = exports.memory as WebAssembly.Memory; + const exports = instance.exports; - // Call the _start function - if (typeof exports._start === "function") { - (exports._start as Function)() as any; - } else { - fail(`Expected _start to be a function`); - } + // Call the _start function + let main: () => number = typeof exports._start === "function" + ? exports._start as any + : fail(`Expected _start to be a function`); - // Check stdout - assertEquals(stdout, goalStdout); + const code = main() as number; + if (code !== 0) { + const leftFn: () => number = exports.left as any; + assert(leftFn instanceof Function, "Missing left function"); - } catch (err) { - // If there's an error, the test will fail - fail(`Failed to run wasm module: ${err}`); - } + const rightFn: () => number = exports.right as any; + assert(rightFn instanceof Function, "Missing right function"); + fail(`equivalence checks failed ${leftFn()} != ${rightFn()} at line ${code}`); + }; }); \ No newline at end of file diff --git a/tests/e2e/wasm/hello-world.test.ts b/tests/e2e/wasm/hello-world.test.ts index c15e448..8c5438b 100644 --- a/tests/e2e/wasm/hello-world.test.ts +++ b/tests/e2e/wasm/hello-world.test.ts @@ -12,10 +12,10 @@ Deno.test(`Wasm module test: should print "${goalText}"`, async () => { const mem = mod.addMemory(1); mod.exportMemory("memory", mem); - const type0 = mod.makeType([Type.Intrinsic.i32], [Type.Intrinsic.i32]); const type1 = mod.makeType([Type.Intrinsic.i32, Type.Intrinsic.i32, Type.Intrinsic.i32, Type.Intrinsic.i32], [Type.Intrinsic.i32]); const fd_write = mod.importFunction("wasi_snapshot_preview1", "fd_write", type1); + if (fd_write === null) fail(`Unable to import fd_write`); mod.setData(0, goalText); // The WASI iovec struct, which consists of a pointer to