implement string escapes

This commit is contained in:
nora 2023-07-29 22:05:44 +02:00
parent 09ae6cbb56
commit 3270e6b501
4 changed files with 52 additions and 8 deletions

View file

@ -11,10 +11,8 @@ import { exec } from "child_process";
const input = `
function main() = (
print("uwu
");
print("owo
");
print("\\3AAA\\n");
print("meow\\n");
);
`;

View file

@ -134,6 +134,7 @@ export function tokenize(input: string): Token[] {
break;
}
case '"': {
const result = [];
while (true) {
const next = input[i + 1];
span.end++;
@ -141,11 +142,48 @@ export function tokenize(input: string): Token[] {
if (next === '"') {
break;
}
if (next === "\\") {
span.end++;
i++;
switch (input[i]) {
case "\\":
result.push("\\");
break;
case '"':
result.push('"');
break;
case "n":
result.push("\n");
break;
case "r":
result.push("\r");
break;
case "t":
result.push("\t");
break;
case "a":
result.push("\x07");
break;
case "3":
// device control 3 for callie's big project
result.push("\x13");
break;
default:
throw new CompilerError(
`invalid escape character: ${input[i]}`,
{ start: span.end - 1, end: span.end }
);
}
continue;
}
result.push(next);
if (next === undefined) {
throw new CompilerError(`Unterminated string literal`, span);
}
}
const value = input.slice(span.start + 1, span.end - 1);
const value = result.join("");
tokens.push({ kind: "lit_string", span, value });
break;
}

View file

@ -112,7 +112,9 @@ export function lower(ast: Ast): wasm.Module {
}
});
cx.reservedHeapMemoryStart = (mod.datas[0].init.length & ~0x8) + 0x8;
const HEAP_ALIGN = 0x08;
cx.reservedHeapMemoryStart =
(mod.datas[0].init.length + (HEAP_ALIGN - 1)) & ~(HEAP_ALIGN - 1);
addRt(cx, ast);

View file

@ -138,8 +138,14 @@ function printString(s: string, f: Formatter) {
function printBinaryString(buf: Uint8Array, f: Formatter) {
const parts: string[] = [];
for (let i = 0; i < buf.length; i++) {
const idx = buf[i];
parts.push(`\\${idx.toString(16).padStart(2, "0")}`);
const byte = buf[i];
const noEscape =
(byte > 0x30 && byte <= 0x5a) || (byte > 0x61 && byte <= 0x71);
if (noEscape) {
parts.push(`${String.fromCharCode(byte)}`);
} else {
parts.push(`\\${byte.toString(16).padStart(2, "0")}`);
}
}
f.word(`"${parts.join("")}"`);