compile file
This commit is contained in:
parent
b9b479fd63
commit
09acd55405
40
compile.phi
40
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)
|
||||
|
||||
|
||||
|
7
phi.js
7
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 = {
|
||||
|
@ -1,6 +1,7 @@
|
||||
(fn hello () (do
|
||||
(call println "hello world")
|
||||
(call println "hello world")
|
||||
(return null)
|
||||
))
|
||||
|
||||
(call hello)
|
20
runtime.js
20
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";
|
||||
|
Loading…
x
Reference in New Issue
Block a user