From ecb7b1d9d7673732ae22b18ae967774f9acbece0 Mon Sep 17 00:00:00 2001 From: Drew Youngwerth Date: Mon, 23 Sep 2024 22:46:24 -0700 Subject: [PATCH] It works! --- src/lib/host-runtime/bool-to-int.ts | 1 - src/lib/host-runtime/index.ts | 1 - src/lib/host-runtime/strings.ts | 77 ----------------------------- src/parser/reader-macros/string.ts | 20 ++------ src/run.ts | 39 ++++++--------- src/semantics/init-entities.ts | 23 +++++++++ std/string.voyd | 4 +- 7 files changed, 46 insertions(+), 119 deletions(-) delete mode 100644 src/lib/host-runtime/bool-to-int.ts delete mode 100644 src/lib/host-runtime/index.ts delete mode 100644 src/lib/host-runtime/strings.ts diff --git a/src/lib/host-runtime/bool-to-int.ts b/src/lib/host-runtime/bool-to-int.ts deleted file mode 100644 index e5dd067c..00000000 --- a/src/lib/host-runtime/bool-to-int.ts +++ /dev/null @@ -1 +0,0 @@ -export const boolToInt = (bool: boolean) => (bool ? 1 : 0); diff --git a/src/lib/host-runtime/index.ts b/src/lib/host-runtime/index.ts deleted file mode 100644 index e9a3ed18..00000000 --- a/src/lib/host-runtime/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./strings.js"; diff --git a/src/lib/host-runtime/strings.ts b/src/lib/host-runtime/strings.ts deleted file mode 100644 index a9ae8684..00000000 --- a/src/lib/host-runtime/strings.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { boolToInt } from "./bool-to-int.js"; - -export class StringsTable { - readonly rotateAfterIndex = 500000; - readonly strings = new Map(); - nextStringIndex = 0; - - private getNextIndex() { - const index = this.nextStringIndex; - - if (this.nextStringIndex >= this.rotateAfterIndex) { - this.nextStringIndex = 0; - return index; - } - - this.nextStringIndex += 1; - return index; - } - - allocString(): number { - const index = this.getNextIndex(); - this.strings.set(index, ""); - return index; - } - - deAllocString(index: number) { - this.strings.delete(index); - } - - strLength(index: number) { - return this.strings.get(index)?.length ?? -1; - } - - printStr(index: number) { - console.log(this.strings.get(index)); - } - - addCharCodeToString(code: number, index: number) { - const str = this.strings.get(index) ?? ""; - this.strings.set(index, str + String.fromCharCode(code)); - } - - getCharCodeFromString(charIndex: number, strIndex: number) { - return this.strings.get(strIndex)?.[charIndex] ?? -1; - } - - strEquals(aIndex: number, bIndex: number): number { - return boolToInt(this.strings.get(aIndex) === this.strings.get(bIndex)); - } - - strStartsWith(aIndex: number, bIndex: number): number { - return boolToInt( - !!this.strings.get(aIndex)?.startsWith(this.strings.get(bIndex) ?? "") // this could probably cause bugs FYI, consider returning false if either string doesn't exist - ); - } - - strEndsWith(aIndex: number, bIndex: number): number { - return boolToInt( - !!this.strings.get(aIndex)?.endsWith(this.strings.get(bIndex) ?? "") // this could probably cause bugs FYI, consider returning false if either string doesn't exist - ); - } - - strIncludes(aIndex: number, bIndex: number): number { - return boolToInt( - !!this.strings.get(aIndex)?.endsWith(this.strings.get(bIndex) ?? "") // this could probably cause bugs FYI, consider returning false if either string doesn't exist - ); - } - - /** Pass -1 for default flags (g) */ - strTest(strIndex: number, regexIndex: number, flagsIndex: number): number { - const str = this.strings.get(strIndex); - const regex = this.strings.get(regexIndex); - const flags = flagsIndex !== -1 ? this.strings.get(flagsIndex) : "g"; - if (str === undefined || regex === undefined) return 0; - return boolToInt(new RegExp(regex, flags).test(str)); - } -} diff --git a/src/parser/reader-macros/string.ts b/src/parser/reader-macros/string.ts index 56300c99..77e394f8 100644 --- a/src/parser/reader-macros/string.ts +++ b/src/parser/reader-macros/string.ts @@ -1,4 +1,4 @@ -import { Identifier, List } from "../../syntax-objects/index.js"; +import { Identifier, StringLiteral } from "../../syntax-objects/index.js"; import { ReaderMacro } from "./types.js"; export const stringMacro: ReaderMacro = { @@ -31,19 +31,9 @@ export const stringMacro: ReaderMacro = { }); } - return new List([ - "String", - [ - "object", - [ - ":", - "chars", - [ - "FixedArray", - ...token.value.split("").map((char) => char.charCodeAt(0)), - ], - ], - ], - ]); + return new StringLiteral({ + value: token.value, + location: token.location, + }); }, }; diff --git a/src/run.ts b/src/run.ts index 1657f1c8..64be6e58 100644 --- a/src/run.ts +++ b/src/run.ts @@ -1,35 +1,28 @@ import binaryen from "binaryen"; -import { StringsTable } from "./lib/host-runtime/strings.js"; export function run(mod: binaryen.Module) { const binary = mod.emitBinary(); const compiled = new WebAssembly.Module(binary); - const strings = new StringsTable(); const instance = new WebAssembly.Instance(compiled, { - strings: { - "alloc-string": () => strings.allocString(), - "de-alloc-string": (index: number) => strings.deAllocString(index), - "add-char-code-to-string": (code: number, index: number) => - strings.addCharCodeToString(code, index), - "str-len": (index: number) => strings.strLength(index), - "print-str": (index: number) => strings.printStr(index), - "get-char-code-from-string": (charIndex: number, strIndex: number) => - strings.getCharCodeFromString(charIndex, strIndex), - "str-equals": (aIndex: number, bIndex: number) => - strings.strEquals(aIndex, bIndex), - "str-starts-with": (aIndex: number, bIndex: number) => - strings.strStartsWith(aIndex, bIndex), - "str-ends-with": (aIndex: number, bIndex: number) => - strings.strEndsWith(aIndex, bIndex), - "str-includes": (aIndex: number, bIndex: number) => - strings.strIncludes(aIndex, bIndex), - "str-test": (strIndex: number, regexIndex: number, flagsIndex: number) => - strings.strTest(strIndex, regexIndex, flagsIndex), - }, utils: { log: (val: number) => console.log(val), }, }); - console.log((instance.exports as any).main()); + const fns = instance.exports as any; + const newStringReader = fns.new_string_reader; + const read_next_char = fns.read_next_char; + const result = fns.main(); + const reader = newStringReader(result); + + let str = ""; + while (true) { + const char = read_next_char(reader); + if (char < 0) { + break; + } + str += String.fromCharCode(char); + } + + console.log(str); } diff --git a/src/semantics/init-entities.ts b/src/semantics/init-entities.ts index fd79903a..f17ae5ff 100644 --- a/src/semantics/init-entities.ts +++ b/src/semantics/init-entities.ts @@ -15,6 +15,7 @@ import { nop, UnionType, IntersectionType, + Identifier, } from "../syntax-objects/index.js"; import { Match, MatchCase } from "../syntax-objects/match.js"; import { SemanticProcessor } from "./types.js"; @@ -24,6 +25,28 @@ export const initEntities: SemanticProcessor = (expr) => { return expr.applyMap(initEntities); } + if (expr.isStringLiteral()) { + return initEntities( + new List({ + ...expr.metadata, + value: [ + "String", + [ + "object", + [ + ":", + "chars", + [ + "FixedArray", + ...expr.value.split("").map((c) => c.charCodeAt(0)), + ], + ], + ], + ], + }) + ); + } + if (!expr.isList()) return expr; if (expr.calls("define_function")) { diff --git a/std/string.voyd b/std/string.voyd index 06729f8f..5e0be137 100644 --- a/std/string.voyd +++ b/std/string.voyd @@ -2,7 +2,7 @@ use std::macros::all use array::all use operators::all -obj String { +pub obj String { chars: FixedArray } @@ -26,7 +26,7 @@ impl String pub fn length(self) -> i32 self.chars.length() - pub fn concatenated(self, other: String) -> String + pub fn '+'(self, other: String) -> String let new_length = self.chars.length() + other.chars.length() let new_chars = new_fixed_array(new_length) new_chars.copy({