compile file
This commit is contained in:
parent
b9b479fd63
commit
09acd55405
40
compile.phi
40
compile.phi
@ -31,9 +31,20 @@
|
|||||||
) (if (== ty "string") (
|
) (if (== ty "string") (
|
||||||
(let (_ _ value) expr)
|
(let (_ _ value) expr)
|
||||||
(call emit (call format "{ type: \"string\", value: \"%\" }" (call string_escape value)))
|
(call emit (call format "{ type: \"string\", value: \"%\" }" (call string_escape value)))
|
||||||
) (if (== ty "ident") (
|
) (if (== ty "ident") (do
|
||||||
(let (_ _ value) expr)
|
(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))
|
(let sym (call get_sym value))
|
||||||
(if (== sym null) (do
|
(if (== sym null) (do
|
||||||
(call panic "undefined symbol '%'" value)
|
(call panic "undefined symbol '%'" value)
|
||||||
@ -43,9 +54,7 @@
|
|||||||
(if (== sym_ty "builtin") (do
|
(if (== sym_ty "builtin") (do
|
||||||
(let (_ id) sym)
|
(let (_ id) sym)
|
||||||
(if (== id "println") (do
|
(if (== id "println") (do
|
||||||
(call emit (call format
|
(call emit "((...args) => runtime.builtinPrintln(...args))")
|
||||||
"((...args) => (runtime.setLine(%), runtime.builtinPrintln(...args)))"
|
|
||||||
line))
|
|
||||||
) (do
|
) (do
|
||||||
(call panic "unknown builtin '%'" id)
|
(call panic "unknown builtin '%'" id)
|
||||||
))
|
))
|
||||||
@ -83,22 +92,24 @@
|
|||||||
(call define_sym name ("fn" name line))
|
(call define_sym name ("fn" name line))
|
||||||
|
|
||||||
(call emit (call format ") {\n" name))
|
(call emit (call format ") {\n" name))
|
||||||
|
(call emit (call format "runtime.pushCall(\"%\");" name))
|
||||||
(call emit_expr body)
|
(call emit_expr body)
|
||||||
(call emit "}")
|
(call emit "}")
|
||||||
) (if (== id "do") (do
|
) (if (== id "do") (do
|
||||||
(call emit_exprs (call slice s 1))
|
(call emit_exprs (call slice s 1))
|
||||||
) (if (== id "return") (do
|
) (if (== id "return") (do
|
||||||
(let (_ value) s)
|
(let (_ value) s)
|
||||||
|
(call emit "runtime.popCall();\n")
|
||||||
(call emit "return ")
|
(call emit "return ")
|
||||||
(if (!= value null) (do
|
(if (!= value null) (do
|
||||||
(call emit_expr value)
|
(call emit_expr value)
|
||||||
) (do
|
) (do
|
||||||
(call emit "null")
|
(call emit "null")
|
||||||
))
|
))
|
||||||
(call emit ";")
|
|
||||||
) (if (== id "call") (do
|
) (if (== id "call") (do
|
||||||
(let (_ callee) s)
|
(let (_ callee) s)
|
||||||
(let args (call slice s 2))
|
(let args (call slice s 2))
|
||||||
|
(call emit (call format "(runtime.setLine(%), " line))
|
||||||
(call emit_expr callee)
|
(call emit_expr callee)
|
||||||
(call emit "(")
|
(call emit "(")
|
||||||
|
|
||||||
@ -112,7 +123,7 @@
|
|||||||
(call emit_expr arg)
|
(call emit_expr arg)
|
||||||
))
|
))
|
||||||
|
|
||||||
(call emit ")")
|
(call emit "))")
|
||||||
) (do
|
) (do
|
||||||
(call emit "{ type: \"list\", values: [")
|
(call emit "{ type: \"list\", values: [")
|
||||||
(let first true)
|
(let first true)
|
||||||
@ -444,16 +455,17 @@
|
|||||||
(return elems)
|
(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))
|
(let text (call read_text_file input_filename))
|
||||||
|
|
||||||
//(call println "=== text ===")
|
//(call println "=== text ===")
|
||||||
//(call println text)
|
//(call println text)
|
||||||
|
|
||||||
(call println "tokenizing...")
|
(if (not silent) (call println "tokenizing..."))
|
||||||
(let tokens (call tokenize text))
|
(let tokens (call tokenize text))
|
||||||
|
|
||||||
//(call println "=== tokens ===")
|
//(call println "=== tokens ===")
|
||||||
@ -461,7 +473,7 @@
|
|||||||
// (call println "%\t%\t%" line tok (if (!= value null) value ""))
|
// (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 parser (call Parser tokens))
|
||||||
(let (parse) parser)
|
(let (parse) parser)
|
||||||
(let ast (call parse))
|
(let ast (call parse))
|
||||||
@ -471,15 +483,15 @@
|
|||||||
// (call print_expr expr 0)
|
// (call print_expr expr 0)
|
||||||
//))
|
//))
|
||||||
|
|
||||||
(call println "emitting...")
|
(if (not silent) (call println "emitting..."))
|
||||||
(let emitter (call Emitter ast input_filename))
|
(let emitter (call Emitter ast input_filename))
|
||||||
(let (emit) emitter)
|
(let (emit) emitter)
|
||||||
(let js_code (call emit))
|
(let js_code (call emit))
|
||||||
|
|
||||||
(call println "=== js ===")
|
//(call println "=== js ===")
|
||||||
(call println js_code)
|
//(call println js_code)
|
||||||
|
|
||||||
(call println "writing file...")
|
(if (not silent) (call println "writing file..."))
|
||||||
(call write_text_file "out.js" js_code)
|
(call write_text_file "out.js" js_code)
|
||||||
|
|
||||||
|
|
||||||
|
7
phi.js
7
phi.js
@ -21,7 +21,7 @@ function main() {
|
|||||||
lastValue = result.value;
|
lastValue = result.value;
|
||||||
}
|
}
|
||||||
if (lastValue !== null) {
|
if (lastValue !== null) {
|
||||||
console.log(Runtime.valueToJs(lastValue));
|
// console.log(Runtime.valueToJs(lastValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,8 +58,8 @@ class Evaluator {
|
|||||||
} else if (expr.type === "ident") {
|
} else if (expr.type === "ident") {
|
||||||
const sym = this.findSym(expr.value);
|
const sym = this.findSym(expr.value);
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
throw new Error(
|
this.panic(
|
||||||
`could not find symbol '${expr.value}' on line ${expr.line}`,
|
`undefined symbol '${expr.value}'`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (sym.type === "local") {
|
if (sym.type === "local") {
|
||||||
@ -431,6 +431,7 @@ class Evaluator {
|
|||||||
"string_to_int": (...args) => this.runtime.builtinStringToInt(...args),
|
"string_to_int": (...args) => this.runtime.builtinStringToInt(...args),
|
||||||
"char_code": (...args) => this.runtime.builtinCharCode(...args),
|
"char_code": (...args) => this.runtime.builtinCharCode(...args),
|
||||||
"strings_join": (...args) => this.runtime.builtinStringsJoin(...args),
|
"strings_join": (...args) => this.runtime.builtinStringsJoin(...args),
|
||||||
|
"get_args": (...args) => this.runtime.builtinGetArgs(...args),
|
||||||
};
|
};
|
||||||
|
|
||||||
consts = {
|
consts = {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
(fn hello () (do
|
(fn hello () (do
|
||||||
(call println "hello world")
|
(call println "hello world")
|
||||||
(call println "hello world")
|
(call println "hello world")
|
||||||
|
(return null)
|
||||||
))
|
))
|
||||||
|
|
||||||
(call hello)
|
(call hello)
|
20
runtime.js
20
runtime.js
@ -13,7 +13,7 @@ export class Runtime {
|
|||||||
this.currentLine = line;
|
this.currentLine = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
pushCall(name, line) {
|
pushCall(name, line = this.currentLine) {
|
||||||
this.callStack.push({ name, line });
|
this.callStack.push({ name, line });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,13 +32,14 @@ export class Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printCallStack() {
|
printCallStack() {
|
||||||
const last = this.callStack[this.callStack.length - 1];
|
const reversedStack = this.callStack.toReversed();
|
||||||
|
const last = reversedStack[0];
|
||||||
console.error(
|
console.error(
|
||||||
` \x1b[90mat \x1b[37m${last.name} \x1b[90m(${this.filename}:${this.currentLine})\x1b[0m`,
|
` \x1b[90mat \x1b[37m${last.name} \x1b[90m(${this.filename}:${this.currentLine})\x1b[0m`,
|
||||||
);
|
);
|
||||||
for (let i = this.callStack.length - 2; i >= 0; --i) {
|
for (let i = 0; i < reversedStack.length - 1 && i < 20; ++i) {
|
||||||
const name = this.callStack[i].name;
|
const name = reversedStack[i + 1].name;
|
||||||
const line = this.callStack[i + 1].line;
|
const line = reversedStack[i].line;
|
||||||
console.error(
|
console.error(
|
||||||
` \x1b[90mat \x1b[37m${name} \x1b[90m(${this.filename}:${line})\x1b[0m`,
|
` \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) {
|
static valueToPrint(value) {
|
||||||
if (value.type === "null") {
|
if (value.type === "null") {
|
||||||
return "null";
|
return "null";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user