fix færdighedsproblem
This commit is contained in:
parent
18eddd82a4
commit
8c172ccbe4
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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") {
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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:
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user