nandgame-compiler/checker.ts

90 lines
2.6 KiB
TypeScript
Raw Normal View History

2023-04-27 01:32:06 +01:00
import { CheckedExpr, CheckedType } from "./checked.ts";
import { ParsedExpr } from "./parsed.ts";
2023-04-27 13:48:08 +01:00
import { CompileError, Position } from "./token.ts";
2023-04-27 01:32:06 +01:00
export type SymbolValue = {
id: number;
subject: string;
valueType: CheckedType;
};
export class SymbolTable {
private idCounter = 0;
private symbols: { [key: string]: SymbolValue } = {};
public define(subject: string, valueType: CheckedType) {
if (subject in this.symbols) {
throw new Error("redefinition not implemented");
}
const id = this.idCounter;
this.idCounter++;
this.symbols[subject] = { id, subject, valueType };
}
}
export class Checker {
private symbolTable = new SymbolTable();
public errors: CompileError[] = [];
public check(statements: ParsedExpr[]): CheckedExpr[] {
return statements as CheckedExpr[];
}
private searchTopLevelStatements(statements: ParsedExpr[]) {
for (const statement of statements) {
switch (statement.exprType) {
case "fn":
this.searchTopLevelFn(statement);
break;
case "let":
break;
default:
this.errors.push({
pos: statement.pos,
message:
`statement '${statement.exprType}' not supported in top level`,
});
break;
}
}
}
private searchTopLevelFn(statement: ParsedExpr & { exprType: "fn" }) {
}
2023-04-27 13:48:08 +01:00
private checkExpr(expr: ParsedExpr): CheckedExpr {
switch (expr.exprType) {
case "error":
return this.errorExpr(expr.message, expr.pos);
case "unit":
return { pos: expr.pos, exprType: "unit" };
case "id":
throw new Error("not implemented");
case "int":
case "if":
case "block":
case "call":
case "index":
case "increment":
case "decrement":
case "unary":
case "binary":
case "assign":
default:
return this.errorExpr(
`expected expression, got '${expr.exprType}' statement`,
expr.pos,
);
}
}
private errorExpr(message: string, pos: Position): CheckedExpr {
this.errors.push({ message, pos });
return {
pos,
exprType: "error",
message,
};
}
}