small improvements

This commit is contained in:
nora 2023-07-29 22:12:05 +02:00
parent 3270e6b501
commit f0227af982
4 changed files with 36 additions and 32 deletions

View file

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

View file

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

View file

@ -18,6 +18,7 @@ import {
TypeDef, TypeDef,
UNARY_KINDS, UNARY_KINDS,
UnaryKind, UnaryKind,
binaryExprPrecedenceClass,
foldAst, foldAst,
superFoldExpr, superFoldExpr,
} from "./ast"; } from "./ast";
@ -507,23 +508,42 @@ function unexpectedToken(token: Token): never {
function validateAst(ast: Ast) { function validateAst(ast: Ast) {
const validator: Folder = { const validator: Folder = {
...DEFAULT_FOLDER, ...DEFAULT_FOLDER,
expr(value: Expr): Expr { expr(expr: Expr): Expr {
if (value.kind === "block") { if (expr.kind === "block") {
value.exprs.forEach((expr) => { expr.exprs.forEach((inner) => {
if (expr.kind === "let") { if (inner.kind === "let") {
this.expr(expr.rhs); this.expr(inner.rhs);
if (expr.type) { if (inner.type) {
this.type(expr.type); this.type(inner.type);
} }
} else { } else {
this.expr(expr); this.expr(inner);
} }
}); });
return value; return expr;
} else if (value.kind === "let") { } else if (expr.kind === "let") {
throw new CompilerError("let is only allowed in blocks", value.span); throw new CompilerError("let is only allowed in blocks", expr.span);
} else if (expr.kind === "binary") {
const checkPrecedence = (inner: Expr, side: string) => {
if (inner.kind === "binary") {
const ourClass = binaryExprPrecedenceClass(expr.binaryKind);
const innerClass = binaryExprPrecedenceClass(inner.binaryKind);
if (ourClass !== innerClass) {
throw new CompilerError(
`mixing operators without parentheses is not allowed. ${side} is ${inner.binaryKind}, which is different from ${expr.binaryKind}`,
expr.span
);
}
}
};
checkPrecedence(expr.lhs, "left");
checkPrecedence(expr.rhs, "right");
return superFoldExpr(expr, this);
} else { } else {
return superFoldExpr(value, this); return superFoldExpr(expr, this);
} }
}, },
}; };

View file

@ -641,23 +641,6 @@ export function checkBody(
} }
function checkBinary(expr: Expr & ExprBinary): Expr { function checkBinary(expr: Expr & ExprBinary): Expr {
const checkPrecedence = (inner: Expr, side: string) => {
if (inner.kind === "binary") {
const ourClass = binaryExprPrecedenceClass(expr.binaryKind);
const innerClass = binaryExprPrecedenceClass(inner.binaryKind);
if (ourClass !== innerClass) {
throw new CompilerError(
`mixing operators without parentheses is not allowed. ${side} is ${inner.binaryKind}, which is different from ${expr.binaryKind}`,
expr.span
);
}
}
};
checkPrecedence(expr.lhs, "left");
checkPrecedence(expr.rhs, "right");
let lhsTy = expr.lhs.ty!; let lhsTy = expr.lhs.ty!;
let rhsTy = expr.rhs.ty!; let rhsTy = expr.rhs.ty!;