fix færdighedsproblem

This commit is contained in:
SimonFJ20 2024-12-13 09:55:09 +01:00
parent 18eddd82a4
commit 8c172ccbe4
9 changed files with 61 additions and 40 deletions

View File

@ -49,9 +49,16 @@ export class Assembler {
const locs: { [key: string]: number } = {}; const locs: { [key: string]: number } = {};
const refs: { [key: number]: string } = {}; const refs: { [key: number]: string } = {};
let selectedLabel = "";
for (const line of this.lines) { for (const line of this.lines) {
for (const label of line.labels ?? []) { for (const label of line.labels ?? []) {
locs[label] = ip; const isAbsLabel = !label.startsWith(".");
if (isAbsLabel) {
selectedLabel = label;
locs[label] = ip;
} else {
locs[`${selectedLabel}${label}`] = ip;
}
} }
for (const lit of line.ins as Lit[]) { for (const lit of line.ins as Lit[]) {
if (typeof lit === "number") { if (typeof lit === "number") {
@ -69,7 +76,9 @@ export class Assembler {
} }
} else { } else {
output.push(0); output.push(0);
refs[ip] = lit.label; refs[ip] = lit.label.startsWith(".")
? `${selectedLabel}${lit.label}`
: refs[ip] = lit.label;
ip += 1; ip += 1;
} }
} }

View File

@ -4,6 +4,7 @@ import { LocalLeaf, Locals, LocalsFnRoot } from "./lowerer_locals.ts";
import { Ops } from "./mod.ts"; import { Ops } from "./mod.ts";
import { Assembler, Label } from "./assembler.ts"; import { Assembler, Label } from "./assembler.ts";
import { vtypeToString } from "./vtype.ts"; import { vtypeToString } from "./vtype.ts";
import { Pos } from "./token.ts";
export class Lowerer { export class Lowerer {
private program = new Assembler(); private program = new Assembler();
@ -11,7 +12,10 @@ export class Lowerer {
private fnStmtIdLabelMap: { [key: number]: string } = {}; private fnStmtIdLabelMap: { [key: number]: string } = {};
private breakStack: Label[] = []; private breakStack: Label[] = [];
public constructor(private lastPos: Pos) {}
public lower(stmts: Stmt[]) { public lower(stmts: Stmt[]) {
this.addSourceMap({ index: 0, line: 1, col: 1 });
this.program.add(Ops.PushPtr, { label: "_start" }); this.program.add(Ops.PushPtr, { label: "_start" });
this.program.add(Ops.Jump); this.program.add(Ops.Jump);
this.scoutFnHeaders(stmts); this.scoutFnHeaders(stmts);
@ -19,6 +23,7 @@ export class Lowerer {
this.lowerStaticStmt(stmt); this.lowerStaticStmt(stmt);
} }
this.program.setLabel({ label: "_start" }); this.program.setLabel({ label: "_start" });
this.addSourceMap(this.lastPos);
this.program.add(Ops.PushPtr, { label: "main" }); this.program.add(Ops.PushPtr, { label: "main" });
this.program.add(Ops.Call, 0); this.program.add(Ops.Call, 0);
this.program.add(Ops.Pop); this.program.add(Ops.Pop);
@ -28,6 +33,10 @@ export class Lowerer {
return this.program.assemble(); return this.program.assemble();
} }
private addSourceMap({ index, line, col }: Pos) {
this.program.add(Ops.SourceMap, index, line, col);
}
private scoutFnHeaders(stmts: Stmt[]) { private scoutFnHeaders(stmts: Stmt[]) {
for (const stmt of stmts) { for (const stmt of stmts) {
if (stmt.kind.type !== "fn") { if (stmt.kind.type !== "fn") {
@ -41,6 +50,7 @@ export class Lowerer {
} }
private lowerStaticStmt(stmt: Stmt) { private lowerStaticStmt(stmt: Stmt) {
this.addSourceMap(stmt.pos);
switch (stmt.kind.type) { switch (stmt.kind.type) {
case "fn": case "fn":
return this.lowerFnStmt(stmt); return this.lowerFnStmt(stmt);
@ -55,6 +65,7 @@ export class Lowerer {
} }
private lowerStmt(stmt: Stmt) { private lowerStmt(stmt: Stmt) {
this.addSourceMap(stmt.pos);
switch (stmt.kind.type) { switch (stmt.kind.type) {
case "error": case "error":
break; break;
@ -117,28 +128,6 @@ export class Lowerer {
this.program.add(Ops.Jump); this.program.add(Ops.Jump);
} }
private lowerBuiltinAnno(annoArgs: Expr[]) {
if (annoArgs.length !== 1) {
throw new Error("invalid # of arguments to builtin annotation");
}
const anno = annoArgs[0];
if (anno.kind.type !== "ident") {
throw new Error(
`unexpected argument type '${anno.kind.type}' expected 'ident'`,
);
}
const value = anno.kind.value;
const builtin = Object.entries(Builtins).find((entry) =>
entry[0] === value
)?.[1];
if (builtin === undefined) {
throw new Error(
`unrecognized builtin '${value}'`,
);
}
this.program.add(Ops.Builtin, builtin);
}
private lowerFnStmt(stmt: Stmt) { private lowerFnStmt(stmt: Stmt) {
if (stmt.kind.type !== "fn") { if (stmt.kind.type !== "fn") {
throw new Error(); throw new Error();
@ -158,7 +147,7 @@ export class Lowerer {
this.locals.allocSym(ident); this.locals.allocSym(ident);
} }
if (stmt.kind.anno?.ident === "builtin") { if (stmt.kind.anno?.ident === "builtin") {
this.lowerBuiltinAnno(stmt.kind.anno.values); this.lowerFnBuiltinBody(stmt.kind.anno.values);
} else { } else {
this.lowerExpr(stmt.kind.body); this.lowerExpr(stmt.kind.body);
} }
@ -176,6 +165,28 @@ export class Lowerer {
this.program = outerProgram; this.program = outerProgram;
} }
private lowerFnBuiltinBody(annoArgs: Expr[]) {
if (annoArgs.length !== 1) {
throw new Error("invalid # of arguments to builtin annotation");
}
const anno = annoArgs[0];
if (anno.kind.type !== "ident") {
throw new Error(
`unexpected argument type '${anno.kind.type}' expected 'ident'`,
);
}
const value = anno.kind.value;
const builtin = Object.entries(Builtins).find((entry) =>
entry[0] === value
)?.[1];
if (builtin === undefined) {
throw new Error(
`unrecognized builtin '${value}'`,
);
}
this.program.add(Ops.Builtin, builtin);
}
private lowerLetStmt(stmt: Stmt) { private lowerLetStmt(stmt: Stmt) {
if (stmt.kind.type !== "let") { if (stmt.kind.type !== "let") {
throw new Error(); throw new Error();
@ -231,10 +242,8 @@ export class Lowerer {
throw new Error(); throw new Error();
} }
if (expr.kind.sym.type === "let") { if (expr.kind.sym.type === "let") {
this.program.add( const symId = this.locals.symId(expr.kind.ident);
Ops.LoadLocal, this.program.add(Ops.LoadLocal, symId);
this.locals.symId(expr.kind.ident),
);
return; return;
} }
if (expr.kind.sym.type === "fn_param") { if (expr.kind.sym.type === "fn_param") {

View File

@ -36,7 +36,7 @@ if (reporter.errorOccured()) {
Deno.exit(1); Deno.exit(1);
} }
const lowerer = new Lowerer(); const lowerer = new Lowerer(lexer.currentPos());
lowerer.lower(ast); lowerer.lower(ast);
lowerer.printProgram(); lowerer.printProgram();
const program = lowerer.finish(); const program = lowerer.finish();

View File

@ -14,7 +14,7 @@ export async function compileWithDebug(path: string): Promise<number[]> {
const lexer = new Lexer(text, reporter); const lexer = new Lexer(text, reporter);
const parser = new Parser(lexer, reporter); const parser = new Parser(lexer, reporter);
const ast = parser.parseStmts(); const ast = parser.parse();
new Resolver(reporter).resolve(ast); new Resolver(reporter).resolve(ast);
new Checker(reporter).check(ast); new Checker(reporter).check(ast);
@ -23,7 +23,7 @@ export async function compileWithDebug(path: string): Promise<number[]> {
console.error("Errors occurred, stopping compilation."); console.error("Errors occurred, stopping compilation.");
} }
const lowerer = new Lowerer(); const lowerer = new Lowerer(lexer.currentPos());
lowerer.lower(ast); lowerer.lower(ast);
lowerer.printProgram(); lowerer.printProgram();
const program = lowerer.finish(); const program = lowerer.finish();

View File

@ -40,6 +40,9 @@ syn match Comment "//.*$" contains=Todo
syn region Comment start=+/\*+ end=+\*/+ contains=Todo 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('
syn region sligeBlock start="{" end="}" transparent fold syn region sligeBlock start="{" end="}" transparent fold

View File

@ -21,8 +21,9 @@ fn split(str: string, seperator: int) -> [string] {
let i = 0; let i = 0;
let current_str = ""; let current_str = "";
let str_length = string_length(str);
loop { loop {
if i >= string_length(str) { if i >= str_length {
break; break;
} }
let char = string_char_at(str, i); let char = string_char_at(str, i);
@ -30,7 +31,7 @@ fn split(str: string, seperator: int) -> [string] {
array_push_string(result, current_str); array_push_string(result, current_str);
current_str = ""; current_str = "";
} else { } else {
string_push_char(current_str, char); current_str = string_push_char(current_str, char);
} }
i = i + 1; i = i + 1;
} }
@ -38,15 +39,14 @@ fn split(str: string, seperator: int) -> [string] {
} }
fn main() { fn main() {
let array = split("aoisfjasoifjsaiofjsa", char("a")); let array = split("yaoisfjasoifjsaiofjsa", char("a"));
let i = 0; let i = 0;
let array_length = array_length_string(array); let array_length = array_length_string(array);
loop { loop {
if i >= array_length { if i >= array_length {
break; break;
} }
let v = array_at_string(array, 0); println(array_at_string(array, i));
println(v);
i = i + 1; i = i + 1;
} }
} }

View File

@ -9,7 +9,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
bool print_stack_debug = true; bool print_stack_debug = false;
int execute_file_and_exit(std::string filename) int execute_file_and_exit(std::string filename)
{ {

View File

@ -171,7 +171,7 @@ public:
inline auto to_repr_string() const -> std::string inline auto to_repr_string() const -> std::string
{ {
return std::format( return std::format(
"{}({})", value_type_to_string(this->m_type), to_string()); "{}({:.4s})", value_type_to_string(this->m_type), to_string());
} }
private: private:

View File

@ -1,6 +1,6 @@
{ {
"tasks": { "tasks": {
"bundle": "deno run -A bundle.ts" "bundle": "deno run --allow-read --allow-write --allow-env --allow-run bundle.ts"
}, },
"compilerOptions": { "compilerOptions": {
"checkJs": false, "checkJs": false,