diff --git a/compiler/checker.ts b/compiler/checker.ts index 1da414f..5f7160b 100644 --- a/compiler/checker.ts +++ b/compiler/checker.ts @@ -152,10 +152,11 @@ export class Checker { ) { return; } - const { returnType } = stmt.kind.vtype!; + if (returnType.type === "error") return returnType; this.fnReturnStack.push(returnType); const body = this.checkExpr(stmt.kind.body); + if (body.type === "error") return body; this.fnReturnStack.pop(); if (!vtypesEqual(returnType, body)) { @@ -174,13 +175,17 @@ export class Checker { } const pos = stmt.pos; const value = this.checkExpr(stmt.kind.value); + if (value.type === "error") { + return stmt.kind.param.vtype = value; + } if (stmt.kind.param.etype) { - const paramVtype = this.checkEType(stmt.kind.param.etype); - if (!vtypesEqual(value, paramVtype)) { + const paramVType = this.checkEType(stmt.kind.param.etype); + if (paramVType.type === "error") return paramVType; + if (!vtypesEqual(value, paramVType)) { this.report( `incompatible value type` + `, got '${vtypeToString(value)}'` + - `, expected '${vtypeToString(paramVtype)}'`, + `, expected '${vtypeToString(paramVType)}'`, pos, ); return; @@ -289,6 +294,9 @@ export class Checker { case "error": throw new Error("error in AST"); case "ident": + if (this.reporter.errorOccured()) { + return { type: "error" }; + } throw new Error("ident expr in AST"); case "sym": return this.checkSymExpr(expr); @@ -581,6 +589,9 @@ export class Checker { if (a.type === "array" && b.type === "array") { return this.reduceToSignificant(a.inner, b.inner); } + if (a.type === "generic" && b.type === "generic") { + return { a, b }; + } throw new Error("idk what to do here"); } @@ -740,6 +751,7 @@ export class Checker { } const pos = expr.pos; const subject = this.checkExpr(expr.kind.subject); + if (subject.type === "error") return subject; for (const operation of simpleUnaryOperations) { if (operation.unaryType !== expr.kind.unaryType) { continue; diff --git a/compiler/compiler.ts b/compiler/compiler.ts index aafc601..94da50f 100644 --- a/compiler/compiler.ts +++ b/compiler/compiler.ts @@ -9,6 +9,8 @@ import { FnNamesMap, Lowerer } from "./lowerer.ts"; import { Parser } from "./parser.ts"; import { Resolver } from "./resolver.ts"; +import * as path from "jsr:@std/path"; + export type CompiledFile = { filepath: string; program: number[]; @@ -28,7 +30,16 @@ export class Compiler { public async compile(): Promise { const text = await Deno.readTextFile(this.startFilePath); - const lexer = new Lexer(text, this.reporter); + const stdlib = await Deno.readTextFile( + path.join( + path.dirname(path.fromFileUrl(Deno.mainModule)), + "../stdlib.slg", + ), + ); + + const totalText = text + stdlib; + + const lexer = new Lexer(totalText, this.reporter); const parser = new Parser(lexer, this.astCreator, this.reporter); const ast = parser.parse(); @@ -50,7 +61,7 @@ export class Compiler { const lowerer = new Lowerer(monoFns, callMap, lexer.currentPos()); const { program, fnNames } = lowerer.lower(); - lowerer.printProgram(); + //lowerer.printProgram(); return { program, fnNames }; } diff --git a/compiler/deno.lock b/compiler/deno.lock index 5431e35..9c112a1 100644 --- a/compiler/deno.lock +++ b/compiler/deno.lock @@ -1,8 +1,14 @@ { "version": "4", "specifiers": { + "jsr:@std/path@*": "1.0.8", "npm:@types/node@*": "22.5.4" }, + "jsr": { + "@std/path@1.0.8": { + "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" + } + }, "npm": { "@types/node@22.5.4": { "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", diff --git a/compiler/desugar/special_loop.ts b/compiler/desugar/special_loop.ts index 4323ed9..425e062 100644 --- a/compiler/desugar/special_loop.ts +++ b/compiler/desugar/special_loop.ts @@ -80,7 +80,7 @@ export class SpecialLoopDesugarer implements AstVisitor { type: "call", subject: Expr({ type: "ident", - ident: "int_array_length", + ident: "array_length", }), args: [ Expr({ diff --git a/compiler/info.ts b/compiler/info.ts index 55a3dad..f51f991 100644 --- a/compiler/info.ts +++ b/compiler/info.ts @@ -42,7 +42,7 @@ export function printStackTrace() { } } try { - throw new ReportNotAnError(); + //throw new ReportNotAnError(); } catch (error) { if (!(error instanceof ReportNotAnError)) { throw error; diff --git a/compiler/parser.ts b/compiler/parser.ts index 9eb594c..4e692cd 100644 --- a/compiler/parser.ts +++ b/compiler/parser.ts @@ -868,7 +868,6 @@ export class Parser { } private report(msg: string, pos = this.pos()) { - console.log(`Parser: ${msg} at ${pos.line}:${pos.col}`); this.reporter.reportError({ msg, pos, diff --git a/editors/vim/syntax/slige.vim b/editors/vim/syntax/slige.vim index a9f334f..c9d4df1 100644 --- a/editors/vim/syntax/slige.vim +++ b/editors/vim/syntax/slige.vim @@ -7,6 +7,7 @@ if exists("b:current_syntax") finish endif + syn keyword Keyword break return let fn loop if else struct import or and not while for in syn keyword Special null syn keyword Type int string bool @@ -50,7 +51,9 @@ syn region Comment start=+/\*+ end=+\*/+ contains=Todo syn match Identifier '[a-z_]\w*' syn match Type '[A-Z]\w*' -syn match Function '[a-zA-Z_]\w*\ze(' +syn match Function '[a-zA-Z_]\w*\ze\s\{-}(.\{-})' +syn match Function '[a-zA-Z_]\w*\ze\s\{-}::<.\{-}>' +syn match Function ' \zs[a-zA-Z_]\w*\ze\s\{-}<.\{-}>\s\{-}(.\{-})' syn region sligeBlock start="{" end="}" transparent fold diff --git a/examples/generic_array.slg b/examples/generic_array.slg index 82cf74e..d223118 100644 --- a/examples/generic_array.slg +++ b/examples/generic_array.slg @@ -1,9 +1,14 @@ // -fn array_new() -> [T] #[builtin(ArrayNew)] {} -fn array_push(array: [T], value: T) #[builtin(ArrayPush)] {} -fn array_length(array: [T]) -> int #[builtin(ArrayLength)] {} -fn array_at(array: [T], index: int) -> string #[builtin(ArrayAt)] {} +//fn print(msg: string) #[builtin(Print)] {} +//fn println(msg: string) { print(msg + "\n") } +// +//fn itos(number: int) -> string #[builtin(IntToString)] {} +// +//fn array_new() -> [T] #[builtin(ArrayNew)] {} +//fn array_push(array: [T], value: T) #[builtin(ArrayPush)] {} +//fn array_length(array: [T]) -> int #[builtin(ArrayLength)] {} +//fn array_at(array: [T], index: int) -> T #[builtin(ArrayAt)] {} fn main() { @@ -14,6 +19,14 @@ fn main() { let ints = array_new::(); array_push(ints, 1); array_push(ints, 2); + + for v in strings { + println(v) + } + + for v in ints { + println(itos(v)) + } } diff --git a/examples/special_loops.slg b/examples/special_loops.slg index ef95343..d5e01c9 100644 --- a/examples/special_loops.slg +++ b/examples/special_loops.slg @@ -1,56 +1,3 @@ - -fn string_push_char(str: string, value: int) -> string #[builtin(StringPushChar)] {} -fn string_char_at(str: string, index: int) -> int #[builtin(StringCharAt)] {} -fn string_length(str: string) -> int #[builtin(StringLength)] {} - -fn string_array_new() -> [string] #[builtin(ArrayNew)] {} -fn string_array_push(array: [string], value: string) #[builtin(ArrayPush)] {} -fn string_array_length(array: [string]) -> int #[builtin(ArrayLength)] {} -fn string_array_at(array: [string], index: int) -> string #[builtin(ArrayAt)] {} - -fn int_array_new() -> [int] #[builtin(ArrayNew)] {} -fn int_array_push(array: [int], value: int) #[builtin(ArrayPush)] {} -fn int_array_length(array: [int]) -> int #[builtin(ArrayLength)] {} -fn int_array_at(array: [int], index: int) -> int #[builtin(ArrayAt)] {} - -fn file_open(filename: string, mode: string) -> int #[builtin(FileOpen)] {} -fn file_close(file: int) #[builtin(FileClose)] {} -fn file_write_string(file: int, content: string) -> int #[builtin(FileWriteString)] {} -fn file_read_char(file: int) -> int #[builtin(FileReadChar)] {} -fn file_read_to_string(file: int) -> string #[builtin(FileReadToString)] {} -fn file_flush(file: int) #[builtin(FileFlush)] {} -fn file_eof(file: int) -> bool #[builtin(FileEof)] {} - -fn stdin() -> int { 0 } -fn stdout() -> int { 1 } -fn stderr() -> int { 2 } - -fn file_read_line(file: int) -> string { - let line = ""; - loop { - if file_eof(file) { - break; - } - let ch = file_read_char(file); - if ch == "\n"[0] { - break; - } - line = string_push_char(line, ch); - } - line -} - -fn print(msg: string) #[builtin(Print)] {} -fn println(msg: string) { print(msg + "\n") } - -fn input(prompt: string) -> string { - print("> "); - file_flush(stdout()); - file_read_line(stdin()) -} - -// - fn main() { let i = 0; while i < 3 { @@ -63,18 +10,34 @@ fn main() { for char in chars { println(string_push_char("", char)); } + + let values = array_new::(); + array_push(values, 10); + array_push(values, 20); + array_push(values, 30); + + let pairs = array_new::<[int]>(); + + for (let i = 0; i < array_length(values); i += 1) { + let pair = array_new::(); + array_push(pair, i); + array_push(pair, values[i]); + array_push(pairs, pair); + } + + for pair in pairs { + println("values[" + itos(pair[0]) + "] = " + itos(pair[1])); + } } fn string_to_array(value: string) -> [int] { - let result = int_array_new(); + let result = array_new::(); let length = string_length(value); for (let i = 0; i < length; i += 1) { - int_array_push(result, value[i]); + array_push(result, value[i]); } result } - - diff --git a/runtime/alloc.hpp b/runtime/alloc.hpp index b75f515..51fa1af 100644 --- a/runtime/alloc.hpp +++ b/runtime/alloc.hpp @@ -202,7 +202,7 @@ private: } } - size_t max_size = 4; + size_t max_size = 8; std::vector heap_1; std::vector heap_2; diff --git a/stdlib.slg b/stdlib.slg index 1dba465..3cfd038 100644 --- a/stdlib.slg +++ b/stdlib.slg @@ -1,4 +1,6 @@ +// stdlib.slg + fn exit(status_code: int) #[builtin(Exit)] {} fn print(msg: string) #[builtin(Print)] {} @@ -11,15 +13,10 @@ fn string_char_at(str: string, index: int) -> int #[builtin(StringCharAt)] {} fn string_length(str: string) -> int #[builtin(StringLength)] {} fn string_to_int(str: string) -> int #[builtin(StringToInt)] {} -fn string_array_new() -> [string] #[builtin(ArrayNew)] {} -fn string_array_push(array: [string], value: string) #[builtin(ArrayPush)] {} -fn string_array_length(array: [string]) -> int #[builtin(ArrayLength)] {} -fn string_array_at(array: [string], index: int) -> string #[builtin(ArrayAt)] {} - -fn int_array_new() -> [int] #[builtin(ArrayNew)] {} -fn int_array_push(array: [int], value: int) #[builtin(ArrayPush)] {} -fn int_array_length(array: [int]) -> int #[builtin(ArrayLength)] {} -fn int_array_at(array: [int], index: int) -> int #[builtin(ArrayAt)] {} +fn array_new() -> [T] #[builtin(ArrayNew)] {} +fn array_push(array: [T], value: T) #[builtin(ArrayPush)] {} +fn array_length(array: [T]) -> int #[builtin(ArrayLength)] {} +fn array_at(array: [T], index: int) -> T #[builtin(ArrayAt)] {} fn file_open(filename: string, mode: string) -> int #[builtin(FileOpen)] {} fn file_close(file: int) #[builtin(FileClose)] {} @@ -73,7 +70,7 @@ fn string_abs(number: int) -> int { } fn string_split(str: string, seperator: int) -> [string] { - let result: [string] = string_array_new(); + let result = array_new::(); let i = 0; let current_str = ""; @@ -83,14 +80,14 @@ fn string_split(str: string, seperator: int) -> [string] { } let char = str[i]; if char == seperator { - string_array_push(result, current_str); + array_push(result, current_str); current_str = ""; } else { current_str = string_push_char(current_str, char); } i = i + 1; } - string_array_push(result, current_str); + array_push(result, current_str); result } @@ -120,20 +117,20 @@ fn string_contains(str: string, ch: int) -> bool { false } -fn array_clone(array: [int]) -> [int] { - let len = int_array_length(array); - let result = int_array_new(); +fn array_clone(array: [T]) -> [T] { + let len = array_length(array); + let result = array_new::(); let i = 0; loop { if i >= len { break; } - int_array_push(result, array[i]); + array_push(result, array[i]); i = 1 + 1; } result } fn array_sort_mut(array: [int]) { - let len = int_array_length(array); + let len = array_length(array); for (let i = 0; i < len; i += 1) { for (let j = i + 1; j < len; j += 1) { if array[j] < array[i] {