compile file

This commit is contained in:
sfja 2025-09-11 23:12:36 +02:00
parent b9b479fd63
commit 09acd55405
4 changed files with 47 additions and 23 deletions

View File

@ -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)

7
phi.js
View File

@ -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 = {

View File

@ -1,6 +1,7 @@
(fn hello () (do
(call println "hello world")
(call println "hello world")
(return null)
))
(call hello)

View File

@ -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";