import files once
This commit is contained in:
parent
3560718575
commit
b286f9dca0
@ -1,6 +1,6 @@
|
||||
(import "stdlib.phi" (slice contains indent))
|
||||
(import "compiler/parse.phi" (Parser tokenize))
|
||||
(import "compiler/emit_js.phi" (Emitter))
|
||||
(import "compiler/emit_js.phi" (JsEmitter))
|
||||
|
||||
(fn print_expr (expr depth) (do
|
||||
(let (ty line value) expr)
|
||||
@ -24,7 +24,7 @@
|
||||
(let parser (Parser tokens))
|
||||
(let (parse) parser)
|
||||
(let ast (parse))
|
||||
(let emitter (Emitter ast input_filename))
|
||||
(let emitter (JsEmitter ast input_filename))
|
||||
(let (emit) emitter)
|
||||
(let js_code (emit))
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
// (println js_code)
|
||||
|
||||
(write_text_file output_filename js_code)
|
||||
(println "written '%'!" output_filename)
|
||||
(println "writing '%'" output_filename)
|
||||
|
||||
|
||||
|
||||
|
@ -1,8 +1,12 @@
|
||||
(import "stdlib.phi" (slice contains))
|
||||
(import "stdlib.phi" (
|
||||
slice contains
|
||||
list_push list_pop list_contains
|
||||
map map_has map_get map_set
|
||||
))
|
||||
(import "compiler/parse.phi" (Parser tokenize))
|
||||
(import "compiler/syms.phi" (Syms))
|
||||
|
||||
(fn Emitter (ast initial_filename) (do
|
||||
(fn JsEmitter (ast initial_filename) (do
|
||||
(let output (list))
|
||||
(let filename initial_filename)
|
||||
|
||||
@ -11,6 +15,9 @@
|
||||
(let (sym_id_count sym_id_increment) (Counter))
|
||||
(let (let_node_reg_count let_node_reg_increment) (Counter))
|
||||
|
||||
(let import_stack (list filename))
|
||||
(let imported_files (map))
|
||||
|
||||
(let builtin_syms (list
|
||||
(list "format" "builtinFormat")
|
||||
(list "print" "builtinPrint")
|
||||
@ -127,34 +134,48 @@
|
||||
(panic "illegal function on line %" line)
|
||||
))
|
||||
(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)
|
||||
(if (list_contains import_stack inner_filename) (do
|
||||
(panic "circular dependendy: '%' imports '%'" filename inner_filename)
|
||||
))
|
||||
(list_push import_stack inner_filename)
|
||||
|
||||
(enter_scope)
|
||||
(discover_syms ast)
|
||||
(emit_exprs ast)
|
||||
(let sym_map (get_current_map))
|
||||
(let sym_map null)
|
||||
|
||||
(= syms outer_syms)
|
||||
(= filename outer_filename)
|
||||
(if (map_has imported_files inner_filename) (do
|
||||
(= sym_map (map_get imported_files inner_filename))
|
||||
) (do
|
||||
(println "compiling '%'" inner_filename)
|
||||
(let outer_filename filename)
|
||||
(= filename inner_filename)
|
||||
|
||||
(emit (format "runtime.setFile(\"%\");\n" outer_filename))
|
||||
(let text (read_text_file filename))
|
||||
(let tokens (tokenize text))
|
||||
(let parser (Parser tokens))
|
||||
(let (parse) parser)
|
||||
(let ast (parse))
|
||||
|
||||
(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)
|
||||
(= sym_map (get_current_map))
|
||||
(map_set imported_files filename sym_map)
|
||||
|
||||
(= syms outer_syms)
|
||||
(= filename outer_filename)
|
||||
|
||||
(emit (format "runtime.setFile(\"%\");\n" outer_filename))
|
||||
))
|
||||
(list_pop import_stack)
|
||||
|
||||
(for (_ _ ident) idents (do
|
||||
(let sym null)
|
||||
@ -165,7 +186,7 @@
|
||||
))
|
||||
))
|
||||
(if (== sym null) (do
|
||||
(panic "no symbol '%' from imported '%'" ident filename)
|
||||
(panic "no symbol '%' from imported '%'" ident inner_filename)
|
||||
))
|
||||
(let (_ sym_type) sym)
|
||||
(if (== sym_type "imported") (do
|
||||
|
@ -1,10 +1,10 @@
|
||||
(import "stdlib.phi" (indent))
|
||||
(import "stdlib.phi" (indent map map_has map_get map_set))
|
||||
|
||||
(fn Syms () (do
|
||||
(let syms (list null (list)))
|
||||
(let syms (list null (map)))
|
||||
|
||||
(fn enter_scope () (do
|
||||
(= syms (list syms (list)))
|
||||
(= syms (list syms (map)))
|
||||
))
|
||||
|
||||
(fn leave_scope () (do
|
||||
@ -14,29 +14,13 @@
|
||||
|
||||
(fn define_sym (ident sym) (do
|
||||
(let (_ map) syms)
|
||||
(let i 0)
|
||||
(loop (do
|
||||
(if (>= i (len map)) (break))
|
||||
(let (s_ident _) (at map i))
|
||||
(if (== ident s_ident) (do
|
||||
(set map i (list ident sym))
|
||||
(return)
|
||||
))
|
||||
(+= i 1)
|
||||
))
|
||||
(push map (list ident sym))
|
||||
(map_set map ident sym)
|
||||
))
|
||||
|
||||
(fn find_sym (syms ident) (do
|
||||
(let (parent map) syms)
|
||||
(let i 0)
|
||||
(loop (do
|
||||
(if (>= i (len map)) (break))
|
||||
(let (s_ident s_sym) (at map i))
|
||||
(if (== ident s_ident) (do
|
||||
(return s_sym)
|
||||
))
|
||||
(+= i 1)
|
||||
(if (map_has map ident) (do
|
||||
(return (map_get map ident))
|
||||
))
|
||||
(if (!= parent null) (do
|
||||
(return (find_sym parent ident))
|
||||
|
72
stdlib.phi
72
stdlib.phi
@ -52,3 +52,75 @@
|
||||
(return space)
|
||||
))
|
||||
|
||||
(fn list_push (list_ value) (do
|
||||
(let list_len (len list_))
|
||||
(let i 0)
|
||||
(loop (do
|
||||
(if (>= i list_len) (break))
|
||||
(if (== (at list_ i) null) (do
|
||||
(set list_ i value)
|
||||
(return)
|
||||
))
|
||||
(+= i 1)
|
||||
))
|
||||
(push list_ value)
|
||||
))
|
||||
|
||||
(fn list_pop (list_) (do
|
||||
(let i (- (len list_) 1))
|
||||
(loop (do
|
||||
(if (< i 0) (break))
|
||||
(let value (at list_ i))
|
||||
(if (!= value null) (do
|
||||
(set list_ i null)
|
||||
(return value)
|
||||
))
|
||||
(-= i 1)
|
||||
))
|
||||
(return null)
|
||||
))
|
||||
|
||||
(fn list_contains (list_ value) (do
|
||||
(for elem list_ (do
|
||||
(if (== elem value) (do
|
||||
(return true)
|
||||
))
|
||||
))
|
||||
(return false)
|
||||
))
|
||||
|
||||
(fn map () (do
|
||||
(return (list))
|
||||
))
|
||||
|
||||
(fn map_has (map key) (do
|
||||
(for (m_key _) map (do
|
||||
(if (== m_key key) (do
|
||||
(return true)
|
||||
))
|
||||
))
|
||||
(return false)
|
||||
))
|
||||
|
||||
(fn map_get (map key) (do
|
||||
(for (m_key value) map (do
|
||||
(if (== m_key key) (do
|
||||
(return value)
|
||||
))
|
||||
))
|
||||
(return null)
|
||||
))
|
||||
|
||||
(fn map_set (map key value) (do
|
||||
(for entry map (do
|
||||
(let (entry_key _) entry)
|
||||
(if (== entry_key key) (do
|
||||
(set entry 1 value)
|
||||
(return)
|
||||
))
|
||||
))
|
||||
(push map (list key value))
|
||||
))
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user