implement import
This commit is contained in:
parent
67cd456762
commit
f8ac0f3b6c
163
compile.phi
163
compile.phi
@ -1,11 +1,12 @@
|
||||
|
||||
(fn Emitter (ast filename) (do
|
||||
(fn Emitter (ast initial_filename) (do
|
||||
(let output (list))
|
||||
(let filename initial_filename)
|
||||
|
||||
(let (enter_scope leave_scope define_sym get_sym print_syms) (Syms))
|
||||
(let syms (Syms))
|
||||
|
||||
(let (let_node_reg_count let_node_reg_increment) (Counter))
|
||||
(let (sym_id_count sym_id_increment) (Counter))
|
||||
(let (let_node_reg_count let_node_reg_increment) (Counter))
|
||||
|
||||
(let builtin_syms (list
|
||||
(list "format" "builtinFormat")
|
||||
@ -33,6 +34,7 @@
|
||||
(define_builtin ident builtin_id)
|
||||
))
|
||||
|
||||
(enter_scope)
|
||||
(discover_syms ast)
|
||||
(emit_exprs ast)
|
||||
(return (strings_join output))
|
||||
@ -96,11 +98,17 @@
|
||||
(emit (format "_%%" value sym_id))
|
||||
) (if (== sym_ty "param") (do
|
||||
(emit (format "_%%" value sym_id))
|
||||
) (if (== sym_ty "let") (do
|
||||
) (if (== sym_ty "let") (do
|
||||
(emit (format "_%%" value sym_id))
|
||||
) (if (== sym_ty "imported") (do
|
||||
// this might give problems in the future.
|
||||
// the solution is to feed the imported symbol
|
||||
// back into this code, so that stuff gets
|
||||
// handled appropriately.
|
||||
(emit (format "_%%" value sym_id))
|
||||
) (do
|
||||
(panic "not implemented '%'" sym_ty)
|
||||
)))))
|
||||
))))))
|
||||
) (do
|
||||
(panic "unknown expr type '%' on line %" ty line)
|
||||
)))))
|
||||
@ -115,7 +123,57 @@
|
||||
(if (!= id_ty "ident") (do
|
||||
(panic "illegal function on line %" line)
|
||||
))
|
||||
(if (== id "fn") (do
|
||||
(if (== id "import") (do
|
||||
(let outer_filename filename)
|
||||
(let (_ (_ _ inner_filename) (_ _ idents)) s)
|
||||
(= filename inner_filename)
|
||||
|
||||
(let text (read_text_file filename))
|
||||
(let tokens (tokenize text))
|
||||
(let parser (Parser tokens))
|
||||
(let (parse) parser)
|
||||
(let ast (parse))
|
||||
(let (_ generate_imported) (Emitter ast filename))
|
||||
|
||||
(emit (format "runtime.setFile(\"%\");\n" filename))
|
||||
|
||||
(let outer_syms syms)
|
||||
(= syms (Syms))
|
||||
(for (ident builtin_id) builtin_syms (do
|
||||
(define_builtin ident builtin_id)
|
||||
))
|
||||
|
||||
(enter_scope)
|
||||
(discover_syms ast)
|
||||
(emit_exprs ast)
|
||||
(let sym_map (get_current_map))
|
||||
|
||||
(= syms outer_syms)
|
||||
(= filename outer_filename)
|
||||
|
||||
(emit (format "runtime.setFile(\"%\");\n" outer_filename))
|
||||
|
||||
(for (_ _ ident) idents (do
|
||||
(let sym null)
|
||||
(for (sym_ident found_sym) sym_map (do
|
||||
(if (== sym_ident ident) (do
|
||||
(= sym found_sym)
|
||||
(break)
|
||||
))
|
||||
))
|
||||
(if (== sym null) (do
|
||||
(println "sym_map = %" sym_map)
|
||||
(panic "no symbol '%' from imported '%'" ident filename)
|
||||
))
|
||||
(let (_ sym_type) sym)
|
||||
(if (== sym_type "imported") (do
|
||||
(define_sym ident sym)
|
||||
) (do
|
||||
(let (sym_id) sym)
|
||||
(define_sym ident (list sym_id "imported" sym))
|
||||
))
|
||||
))
|
||||
) (if (== id "fn") (do
|
||||
(let (_ (_ _ ident) (_ _ params) body) s)
|
||||
|
||||
(let sym (get_sym ident))
|
||||
@ -138,7 +196,7 @@
|
||||
|
||||
|
||||
(emit ") {\n")
|
||||
(emit (format "runtime.pushCall(\"%\");\n" ident))
|
||||
(emit (format "runtime.pushCall(\"%\", \"%\");\n" ident filename))
|
||||
|
||||
(emit_expr body)
|
||||
(emit ";\nruntime.popCall();\nreturn { type: \"null\" };\n}")
|
||||
@ -210,7 +268,7 @@
|
||||
) (if (== id "call") (do
|
||||
(let (_ callee) s)
|
||||
(let args (slice s 2))
|
||||
(emit (format "(runtime.setLine(%), " line))
|
||||
(emit (format "(%, " (rt_info line)))
|
||||
(emit_expr callee)
|
||||
(emit "(")
|
||||
|
||||
@ -235,7 +293,7 @@
|
||||
(emit_assign_expr s line "-")
|
||||
) (if (== id "or") (do
|
||||
(let (_ left right) s)
|
||||
(emit (format "(runtime.setLine(%)" line))
|
||||
(emit (format "(%" (rt_info line) line))
|
||||
(emit ", { type: \"bool\", value: runtime.truthy(")
|
||||
(emit_expr left)
|
||||
(emit ") || runtime.truthy(")
|
||||
@ -243,7 +301,7 @@
|
||||
(emit ") })")
|
||||
) (if (== id "and") (do
|
||||
(let (_ left right) s)
|
||||
(emit (format "(runtime.setLine(%)" line))
|
||||
(emit (format "(%" (rt_info line) line))
|
||||
(emit ", { type: \"bool\", value: runtime.truthy(")
|
||||
(emit_expr left)
|
||||
(emit ") && runtime.truthy(")
|
||||
@ -273,7 +331,7 @@
|
||||
) (do
|
||||
(let (callee) s)
|
||||
(let args (slice s 1))
|
||||
(emit (format "(runtime.setLine(%), " line))
|
||||
(emit (format "(%, " (rt_info line) line))
|
||||
(emit_expr callee)
|
||||
(emit "(")
|
||||
|
||||
@ -288,7 +346,7 @@
|
||||
))
|
||||
|
||||
(emit "))")
|
||||
)))))))))))))))))))))))))
|
||||
))))))))))))))))))))))))))
|
||||
))
|
||||
|
||||
(fn emit_list_literal (s) (do
|
||||
@ -334,12 +392,16 @@
|
||||
))
|
||||
|
||||
(fn emit_binary_op (s id) (do
|
||||
(let (_ left right) s)
|
||||
(emit (format "runtime.%(" id))
|
||||
(let ((_ line _) left right) s)
|
||||
(emit (format "(%, runtime.%(" (rt_info line) id))
|
||||
(emit_expr left)
|
||||
(emit ", ")
|
||||
(emit_expr right)
|
||||
(emit ")")
|
||||
(emit "))")
|
||||
))
|
||||
|
||||
(fn rt_info (line) (do
|
||||
(return (format "runtime.info(\"%\", %)" filename line))
|
||||
))
|
||||
|
||||
(fn emit_assign_expr (s line id) (do
|
||||
@ -410,6 +472,32 @@
|
||||
(return sym_id)
|
||||
))
|
||||
|
||||
// indirection for syms
|
||||
(fn enter_scope () (do
|
||||
(let (enter_scope) syms)
|
||||
(enter_scope)
|
||||
))
|
||||
(fn leave_scope () (do
|
||||
(let (_ leave_scope) syms)
|
||||
(leave_scope)
|
||||
))
|
||||
(fn define_sym (ident sym) (do
|
||||
(let (_ _ define_sym) syms)
|
||||
(return (define_sym ident sym))
|
||||
))
|
||||
(fn get_sym (ident) (do
|
||||
(let (_ _ _ get_sym) syms)
|
||||
(return (get_sym ident))
|
||||
))
|
||||
(fn get_current_map () (do
|
||||
(let (_ _ _ _ get_current_map) syms)
|
||||
(return (get_current_map))
|
||||
))
|
||||
(fn print_syms () (do
|
||||
(let (_ _ _ _ _ print_syms) syms)
|
||||
(print_syms)
|
||||
))
|
||||
|
||||
(return (list generate))
|
||||
))
|
||||
|
||||
@ -439,7 +527,7 @@
|
||||
(= syms parent)
|
||||
))
|
||||
|
||||
(fn define (ident sym) (do
|
||||
(fn define_sym (ident sym) (do
|
||||
(let (_ map) syms)
|
||||
(let i 0)
|
||||
(loop (do
|
||||
@ -471,10 +559,15 @@
|
||||
(return null)
|
||||
))
|
||||
|
||||
(fn get (ident) (do
|
||||
(fn get_sym (ident) (do
|
||||
(return (find_sym syms ident))
|
||||
))
|
||||
|
||||
(fn get_current_map () (do
|
||||
(let (_ map) syms)
|
||||
(return map)
|
||||
))
|
||||
|
||||
(fn print_syms_node (syms depth) (do
|
||||
(let (parent map) syms)
|
||||
(for (ident sym) map (do
|
||||
@ -492,8 +585,9 @@
|
||||
(return (list
|
||||
enter_scope
|
||||
leave_scope
|
||||
define
|
||||
get
|
||||
define_sym
|
||||
get_sym
|
||||
get_current_map
|
||||
print_syms
|
||||
))
|
||||
))
|
||||
@ -750,42 +844,15 @@
|
||||
(return elems)
|
||||
))
|
||||
|
||||
(let silent false)
|
||||
|
||||
(let (input_filename output_filename) (get_args))
|
||||
|
||||
(if (not silent) (println "reading file '%'..." input_filename))
|
||||
(println "compiling '%'..." input_filename)
|
||||
(let text (read_text_file input_filename))
|
||||
|
||||
//(println "=== text ===")
|
||||
// (println text)
|
||||
//(println (len text))
|
||||
|
||||
(if (not silent) (println "tokenizing..."))
|
||||
(let tokens (tokenize text))
|
||||
|
||||
//(println "=== tokens ===")
|
||||
//(for elem tokens (do
|
||||
// (let (tok line value) elem)
|
||||
// (if (!= value null) (do
|
||||
// (println "%\t%\t%" line tok value)
|
||||
// ) (do
|
||||
// (println "%\t%" line tok)
|
||||
// ))
|
||||
//))
|
||||
//(println (len tokens))
|
||||
|
||||
(if (not silent) (println "parsing..."))
|
||||
(let parser (Parser tokens))
|
||||
(let (parse) parser)
|
||||
(let ast (parse))
|
||||
|
||||
// (println "=== ast ===")
|
||||
// (for expr ast (do
|
||||
// (print_expr expr 0)
|
||||
// ))
|
||||
|
||||
(if (not silent) (println "emitting..."))
|
||||
(let emitter (Emitter ast input_filename))
|
||||
(let (emit) emitter)
|
||||
(let js_code (emit))
|
||||
@ -793,8 +860,8 @@
|
||||
// (println "=== js ===")
|
||||
// (println js_code)
|
||||
|
||||
(if (not silent) (println "writing file '%'..." output_filename))
|
||||
(write_text_file output_filename js_code)
|
||||
(println "written '%'!" output_filename)
|
||||
|
||||
|
||||
|
||||
|
11
runtime.js
11
runtime.js
@ -16,7 +16,12 @@ export class Runtime {
|
||||
this.currentLine = line;
|
||||
}
|
||||
|
||||
pushCall(name, filename = this.filename, line = this.currentLine) {
|
||||
info(filename, line) {
|
||||
this.currentFilename = filename;
|
||||
this.currentLine = line;
|
||||
}
|
||||
|
||||
pushCall(name, filename, line = this.currentLine) {
|
||||
this.callStack.push({ name, filename, line });
|
||||
}
|
||||
|
||||
@ -41,8 +46,8 @@ export class Runtime {
|
||||
` \x1b[90mat \x1b[37m${last.name} \x1b[90m(${this.currentFilename}:${this.currentLine})\x1b[0m`,
|
||||
);
|
||||
for (let i = 0; i < reversedStack.length - 1 && i < 20; ++i) {
|
||||
const name = reversedStack[i + 1].name;
|
||||
const { filename, line } = reversedStack[i];
|
||||
const { name, filename } = reversedStack[i + 1];
|
||||
const { line } = reversedStack[i];
|
||||
console.error(
|
||||
` \x1b[90mat \x1b[37m${name} \x1b[90m(${filename}:${line})\x1b[0m`,
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user