From 09acd5540540cf7b7480da8a291d3b0ccf7d26c3 Mon Sep 17 00:00:00 2001 From: sfja Date: Thu, 11 Sep 2025 23:12:36 +0200 Subject: [PATCH] compile file --- compile.phi | 40 ++++++++++++++++++++++++++-------------- phi.js | 7 ++++--- program.phi | 3 ++- runtime.js | 20 +++++++++++++++----- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/compile.phi b/compile.phi index 69755b5..894c555 100644 --- a/compile.phi +++ b/compile.phi @@ -31,9 +31,20 @@ ) (if (== ty "string") ( (let (_ _ value) expr) (call emit (call format "{ type: \"string\", value: \"%\" }" (call string_escape value))) - ) (if (== ty "ident") ( + ) (if (== ty "ident") (do (let (_ _ value) expr) + (if (== value "null") (do + (call emit "{ type: \"null\" }") + (return) + ) (if (== value "false") (do + (call emit "{ type: \"bool\", value: false }") + (return) + ) (if (== value "true") (do + (call emit "{ type: \"bool\", value: true }") + (return) + )))) + (let sym (call get_sym value)) (if (== sym null) (do (call panic "undefined symbol '%'" value) @@ -43,9 +54,7 @@ (if (== sym_ty "builtin") (do (let (_ id) sym) (if (== id "println") (do - (call emit (call format - "((...args) => (runtime.setLine(%), runtime.builtinPrintln(...args)))" - line)) + (call emit "((...args) => runtime.builtinPrintln(...args))") ) (do (call panic "unknown builtin '%'" id) )) @@ -83,22 +92,24 @@ (call define_sym name ("fn" name line)) (call emit (call format ") {\n" name)) + (call emit (call format "runtime.pushCall(\"%\");" name)) (call emit_expr body) (call emit "}") ) (if (== id "do") (do (call emit_exprs (call slice s 1)) ) (if (== id "return") (do (let (_ value) s) + (call emit "runtime.popCall();\n") (call emit "return ") (if (!= value null) (do (call emit_expr value) ) (do (call emit "null") )) - (call emit ";") ) (if (== id "call") (do (let (_ callee) s) (let args (call slice s 2)) + (call emit (call format "(runtime.setLine(%), " line)) (call emit_expr callee) (call emit "(") @@ -112,7 +123,7 @@ (call emit_expr arg) )) - (call emit ")") + (call emit "))") ) (do (call emit "{ type: \"list\", values: [") (let first true) @@ -444,16 +455,17 @@ (return elems) )) +(let silent true) -(let input_filename "program.phi") +(let (_ input_filename) (call get_args)) -(call println "reading file...") +(if (not silent) (call println "reading file...")) (let text (call read_text_file input_filename)) //(call println "=== text ===") //(call println text) -(call println "tokenizing...") +(if (not silent) (call println "tokenizing...")) (let tokens (call tokenize text)) //(call println "=== tokens ===") @@ -461,7 +473,7 @@ // (call println "%\t%\t%" line tok (if (!= value null) value "")) //)) -(call println "parsing...") +(if (not silent) (call println "parsing...")) (let parser (call Parser tokens)) (let (parse) parser) (let ast (call parse)) @@ -471,15 +483,15 @@ // (call print_expr expr 0) //)) -(call println "emitting...") +(if (not silent) (call println "emitting...")) (let emitter (call Emitter ast input_filename)) (let (emit) emitter) (let js_code (call emit)) -(call println "=== js ===") -(call println js_code) +//(call println "=== js ===") +//(call println js_code) -(call println "writing file...") +(if (not silent) (call println "writing file...")) (call write_text_file "out.js" js_code) diff --git a/phi.js b/phi.js index 9f446aa..6abd4ec 100644 --- a/phi.js +++ b/phi.js @@ -21,7 +21,7 @@ function main() { lastValue = result.value; } if (lastValue !== null) { - console.log(Runtime.valueToJs(lastValue)); + // console.log(Runtime.valueToJs(lastValue)); } } @@ -58,8 +58,8 @@ class Evaluator { } else if (expr.type === "ident") { const sym = this.findSym(expr.value); if (!sym) { - throw new Error( - `could not find symbol '${expr.value}' on line ${expr.line}`, + this.panic( + `undefined symbol '${expr.value}'`, ); } if (sym.type === "local") { @@ -431,6 +431,7 @@ class Evaluator { "string_to_int": (...args) => this.runtime.builtinStringToInt(...args), "char_code": (...args) => this.runtime.builtinCharCode(...args), "strings_join": (...args) => this.runtime.builtinStringsJoin(...args), + "get_args": (...args) => this.runtime.builtinGetArgs(...args), }; consts = { diff --git a/program.phi b/program.phi index 2f47e27..915cd11 100644 --- a/program.phi +++ b/program.phi @@ -1,6 +1,7 @@ (fn hello () (do (call println "hello world") (call println "hello world") + (return null) )) -(call hello) \ No newline at end of file +(call hello) diff --git a/runtime.js b/runtime.js index 99d1b1a..6f06a19 100644 --- a/runtime.js +++ b/runtime.js @@ -13,7 +13,7 @@ export class Runtime { this.currentLine = line; } - pushCall(name, line) { + pushCall(name, line = this.currentLine) { this.callStack.push({ name, line }); } @@ -32,13 +32,14 @@ export class Runtime { } printCallStack() { - const last = this.callStack[this.callStack.length - 1]; + const reversedStack = this.callStack.toReversed(); + const last = reversedStack[0]; console.error( ` \x1b[90mat \x1b[37m${last.name} \x1b[90m(${this.filename}:${this.currentLine})\x1b[0m`, ); - for (let i = this.callStack.length - 2; i >= 0; --i) { - const name = this.callStack[i].name; - const line = this.callStack[i + 1].line; + for (let i = 0; i < reversedStack.length - 1 && i < 20; ++i) { + const name = reversedStack[i + 1].name; + const line = reversedStack[i].line; console.error( ` \x1b[90mat \x1b[37m${name} \x1b[90m(${this.filename}:${line})\x1b[0m`, ); @@ -156,6 +157,15 @@ export class Runtime { }; } + builtinGetArgs() { + return { + type: "list", + values: process.argv + .slice(2) + .map((value) => ({ type: "string", value })), + }; + } + static valueToPrint(value) { if (value.type === "null") { return "null";