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 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 (sym_id_count sym_id_increment) (Counter))
|
||||||
|
(let (let_node_reg_count let_node_reg_increment) (Counter))
|
||||||
|
|
||||||
(let builtin_syms (list
|
(let builtin_syms (list
|
||||||
(list "format" "builtinFormat")
|
(list "format" "builtinFormat")
|
||||||
@ -33,6 +34,7 @@
|
|||||||
(define_builtin ident builtin_id)
|
(define_builtin ident builtin_id)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
(enter_scope)
|
||||||
(discover_syms ast)
|
(discover_syms ast)
|
||||||
(emit_exprs ast)
|
(emit_exprs ast)
|
||||||
(return (strings_join output))
|
(return (strings_join output))
|
||||||
@ -96,11 +98,17 @@
|
|||||||
(emit (format "_%%" value sym_id))
|
(emit (format "_%%" value sym_id))
|
||||||
) (if (== sym_ty "param") (do
|
) (if (== sym_ty "param") (do
|
||||||
(emit (format "_%%" value sym_id))
|
(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))
|
(emit (format "_%%" value sym_id))
|
||||||
) (do
|
) (do
|
||||||
(panic "not implemented '%'" sym_ty)
|
(panic "not implemented '%'" sym_ty)
|
||||||
)))))
|
))))))
|
||||||
) (do
|
) (do
|
||||||
(panic "unknown expr type '%' on line %" ty line)
|
(panic "unknown expr type '%' on line %" ty line)
|
||||||
)))))
|
)))))
|
||||||
@ -115,7 +123,57 @@
|
|||||||
(if (!= id_ty "ident") (do
|
(if (!= id_ty "ident") (do
|
||||||
(panic "illegal function on line %" line)
|
(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 (_ (_ _ ident) (_ _ params) body) s)
|
||||||
|
|
||||||
(let sym (get_sym ident))
|
(let sym (get_sym ident))
|
||||||
@ -138,7 +196,7 @@
|
|||||||
|
|
||||||
|
|
||||||
(emit ") {\n")
|
(emit ") {\n")
|
||||||
(emit (format "runtime.pushCall(\"%\");\n" ident))
|
(emit (format "runtime.pushCall(\"%\", \"%\");\n" ident filename))
|
||||||
|
|
||||||
(emit_expr body)
|
(emit_expr body)
|
||||||
(emit ";\nruntime.popCall();\nreturn { type: \"null\" };\n}")
|
(emit ";\nruntime.popCall();\nreturn { type: \"null\" };\n}")
|
||||||
@ -210,7 +268,7 @@
|
|||||||
) (if (== id "call") (do
|
) (if (== id "call") (do
|
||||||
(let (_ callee) s)
|
(let (_ callee) s)
|
||||||
(let args (slice s 2))
|
(let args (slice s 2))
|
||||||
(emit (format "(runtime.setLine(%), " line))
|
(emit (format "(%, " (rt_info line)))
|
||||||
(emit_expr callee)
|
(emit_expr callee)
|
||||||
(emit "(")
|
(emit "(")
|
||||||
|
|
||||||
@ -235,7 +293,7 @@
|
|||||||
(emit_assign_expr s line "-")
|
(emit_assign_expr s line "-")
|
||||||
) (if (== id "or") (do
|
) (if (== id "or") (do
|
||||||
(let (_ left right) s)
|
(let (_ left right) s)
|
||||||
(emit (format "(runtime.setLine(%)" line))
|
(emit (format "(%" (rt_info line) line))
|
||||||
(emit ", { type: \"bool\", value: runtime.truthy(")
|
(emit ", { type: \"bool\", value: runtime.truthy(")
|
||||||
(emit_expr left)
|
(emit_expr left)
|
||||||
(emit ") || runtime.truthy(")
|
(emit ") || runtime.truthy(")
|
||||||
@ -243,7 +301,7 @@
|
|||||||
(emit ") })")
|
(emit ") })")
|
||||||
) (if (== id "and") (do
|
) (if (== id "and") (do
|
||||||
(let (_ left right) s)
|
(let (_ left right) s)
|
||||||
(emit (format "(runtime.setLine(%)" line))
|
(emit (format "(%" (rt_info line) line))
|
||||||
(emit ", { type: \"bool\", value: runtime.truthy(")
|
(emit ", { type: \"bool\", value: runtime.truthy(")
|
||||||
(emit_expr left)
|
(emit_expr left)
|
||||||
(emit ") && runtime.truthy(")
|
(emit ") && runtime.truthy(")
|
||||||
@ -273,7 +331,7 @@
|
|||||||
) (do
|
) (do
|
||||||
(let (callee) s)
|
(let (callee) s)
|
||||||
(let args (slice s 1))
|
(let args (slice s 1))
|
||||||
(emit (format "(runtime.setLine(%), " line))
|
(emit (format "(%, " (rt_info line) line))
|
||||||
(emit_expr callee)
|
(emit_expr callee)
|
||||||
(emit "(")
|
(emit "(")
|
||||||
|
|
||||||
@ -288,7 +346,7 @@
|
|||||||
))
|
))
|
||||||
|
|
||||||
(emit "))")
|
(emit "))")
|
||||||
)))))))))))))))))))))))))
|
))))))))))))))))))))))))))
|
||||||
))
|
))
|
||||||
|
|
||||||
(fn emit_list_literal (s) (do
|
(fn emit_list_literal (s) (do
|
||||||
@ -334,12 +392,16 @@
|
|||||||
))
|
))
|
||||||
|
|
||||||
(fn emit_binary_op (s id) (do
|
(fn emit_binary_op (s id) (do
|
||||||
(let (_ left right) s)
|
(let ((_ line _) left right) s)
|
||||||
(emit (format "runtime.%(" id))
|
(emit (format "(%, runtime.%(" (rt_info line) id))
|
||||||
(emit_expr left)
|
(emit_expr left)
|
||||||
(emit ", ")
|
(emit ", ")
|
||||||
(emit_expr right)
|
(emit_expr right)
|
||||||
(emit ")")
|
(emit "))")
|
||||||
|
))
|
||||||
|
|
||||||
|
(fn rt_info (line) (do
|
||||||
|
(return (format "runtime.info(\"%\", %)" filename line))
|
||||||
))
|
))
|
||||||
|
|
||||||
(fn emit_assign_expr (s line id) (do
|
(fn emit_assign_expr (s line id) (do
|
||||||
@ -410,6 +472,32 @@
|
|||||||
(return sym_id)
|
(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))
|
(return (list generate))
|
||||||
))
|
))
|
||||||
|
|
||||||
@ -439,7 +527,7 @@
|
|||||||
(= syms parent)
|
(= syms parent)
|
||||||
))
|
))
|
||||||
|
|
||||||
(fn define (ident sym) (do
|
(fn define_sym (ident sym) (do
|
||||||
(let (_ map) syms)
|
(let (_ map) syms)
|
||||||
(let i 0)
|
(let i 0)
|
||||||
(loop (do
|
(loop (do
|
||||||
@ -471,10 +559,15 @@
|
|||||||
(return null)
|
(return null)
|
||||||
))
|
))
|
||||||
|
|
||||||
(fn get (ident) (do
|
(fn get_sym (ident) (do
|
||||||
(return (find_sym syms ident))
|
(return (find_sym syms ident))
|
||||||
))
|
))
|
||||||
|
|
||||||
|
(fn get_current_map () (do
|
||||||
|
(let (_ map) syms)
|
||||||
|
(return map)
|
||||||
|
))
|
||||||
|
|
||||||
(fn print_syms_node (syms depth) (do
|
(fn print_syms_node (syms depth) (do
|
||||||
(let (parent map) syms)
|
(let (parent map) syms)
|
||||||
(for (ident sym) map (do
|
(for (ident sym) map (do
|
||||||
@ -492,8 +585,9 @@
|
|||||||
(return (list
|
(return (list
|
||||||
enter_scope
|
enter_scope
|
||||||
leave_scope
|
leave_scope
|
||||||
define
|
define_sym
|
||||||
get
|
get_sym
|
||||||
|
get_current_map
|
||||||
print_syms
|
print_syms
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
@ -750,42 +844,15 @@
|
|||||||
(return elems)
|
(return elems)
|
||||||
))
|
))
|
||||||
|
|
||||||
(let silent false)
|
|
||||||
|
|
||||||
(let (input_filename output_filename) (get_args))
|
(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))
|
(let text (read_text_file input_filename))
|
||||||
|
|
||||||
//(println "=== text ===")
|
|
||||||
// (println text)
|
|
||||||
//(println (len text))
|
|
||||||
|
|
||||||
(if (not silent) (println "tokenizing..."))
|
|
||||||
(let tokens (tokenize text))
|
(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 parser (Parser tokens))
|
||||||
(let (parse) parser)
|
(let (parse) parser)
|
||||||
(let ast (parse))
|
(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 emitter (Emitter ast input_filename))
|
||||||
(let (emit) emitter)
|
(let (emit) emitter)
|
||||||
(let js_code (emit))
|
(let js_code (emit))
|
||||||
@ -793,8 +860,8 @@
|
|||||||
// (println "=== js ===")
|
// (println "=== js ===")
|
||||||
// (println js_code)
|
// (println js_code)
|
||||||
|
|
||||||
(if (not silent) (println "writing file '%'..." output_filename))
|
|
||||||
(write_text_file output_filename js_code)
|
(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;
|
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 });
|
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`,
|
` \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) {
|
for (let i = 0; i < reversedStack.length - 1 && i < 20; ++i) {
|
||||||
const name = reversedStack[i + 1].name;
|
const { name, filename } = reversedStack[i + 1];
|
||||||
const { filename, line } = reversedStack[i];
|
const { line } = reversedStack[i];
|
||||||
console.error(
|
console.error(
|
||||||
` \x1b[90mat \x1b[37m${name} \x1b[90m(${filename}:${line})\x1b[0m`,
|
` \x1b[90mat \x1b[37m${name} \x1b[90m(${filename}:${line})\x1b[0m`,
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user