import files once

This commit is contained in:
sfja 2025-09-23 23:54:07 +02:00
parent 3560718575
commit b286f9dca0
5 changed files with 1541 additions and 1937 deletions

View File

@ -1,6 +1,6 @@
(import "stdlib.phi" (slice contains indent)) (import "stdlib.phi" (slice contains indent))
(import "compiler/parse.phi" (Parser tokenize)) (import "compiler/parse.phi" (Parser tokenize))
(import "compiler/emit_js.phi" (Emitter)) (import "compiler/emit_js.phi" (JsEmitter))
(fn print_expr (expr depth) (do (fn print_expr (expr depth) (do
(let (ty line value) expr) (let (ty line value) expr)
@ -24,7 +24,7 @@
(let parser (Parser tokens)) (let parser (Parser tokens))
(let (parse) parser) (let (parse) parser)
(let ast (parse)) (let ast (parse))
(let emitter (Emitter ast input_filename)) (let emitter (JsEmitter ast input_filename))
(let (emit) emitter) (let (emit) emitter)
(let js_code (emit)) (let js_code (emit))
@ -32,7 +32,7 @@
// (println js_code) // (println js_code)
(write_text_file output_filename js_code) (write_text_file output_filename js_code)
(println "written '%'!" output_filename) (println "writing '%'" output_filename)

View File

@ -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/parse.phi" (Parser tokenize))
(import "compiler/syms.phi" (Syms)) (import "compiler/syms.phi" (Syms))
(fn Emitter (ast initial_filename) (do (fn JsEmitter (ast initial_filename) (do
(let output (list)) (let output (list))
(let filename initial_filename) (let filename initial_filename)
@ -11,6 +15,9 @@
(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 (let_node_reg_count let_node_reg_increment) (Counter))
(let import_stack (list filename))
(let imported_files (map))
(let builtin_syms (list (let builtin_syms (list
(list "format" "builtinFormat") (list "format" "builtinFormat")
(list "print" "builtinPrint") (list "print" "builtinPrint")
@ -127,34 +134,48 @@
(panic "illegal function on line %" line) (panic "illegal function on line %" line)
)) ))
(if (== id "import") (do (if (== id "import") (do
(let outer_filename filename)
(let (_ (_ _ inner_filename) (_ _ idents)) s) (let (_ (_ _ inner_filename) (_ _ idents)) s)
(= filename inner_filename)
(let text (read_text_file filename)) (if (list_contains import_stack inner_filename) (do
(let tokens (tokenize text)) (panic "circular dependendy: '%' imports '%'" filename inner_filename)
(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)
)) ))
(list_push import_stack inner_filename)
(enter_scope) (let sym_map null)
(discover_syms ast)
(emit_exprs ast)
(let sym_map (get_current_map))
(= syms outer_syms) (if (map_has imported_files inner_filename) (do
(= filename outer_filename) (= 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 (for (_ _ ident) idents (do
(let sym null) (let sym null)
@ -165,7 +186,7 @@
)) ))
)) ))
(if (== sym null) (do (if (== sym null) (do
(panic "no symbol '%' from imported '%'" ident filename) (panic "no symbol '%' from imported '%'" ident inner_filename)
)) ))
(let (_ sym_type) sym) (let (_ sym_type) sym)
(if (== sym_type "imported") (do (if (== sym_type "imported") (do

View File

@ -1,10 +1,10 @@
(import "stdlib.phi" (indent)) (import "stdlib.phi" (indent map map_has map_get map_set))
(fn Syms () (do (fn Syms () (do
(let syms (list null (list))) (let syms (list null (map)))
(fn enter_scope () (do (fn enter_scope () (do
(= syms (list syms (list))) (= syms (list syms (map)))
)) ))
(fn leave_scope () (do (fn leave_scope () (do
@ -14,29 +14,13 @@
(fn define_sym (ident sym) (do (fn define_sym (ident sym) (do
(let (_ map) syms) (let (_ map) syms)
(let i 0) (map_set map ident sym)
(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))
)) ))
(fn find_sym (syms ident) (do (fn find_sym (syms ident) (do
(let (parent map) syms) (let (parent map) syms)
(let i 0) (if (map_has map ident) (do
(loop (do (return (map_get map ident))
(if (>= i (len map)) (break))
(let (s_ident s_sym) (at map i))
(if (== ident s_ident) (do
(return s_sym)
))
(+= i 1)
)) ))
(if (!= parent null) (do (if (!= parent null) (do
(return (find_sym parent ident)) (return (find_sym parent ident))

3301
stage2.js

File diff suppressed because it is too large Load Diff

View File

@ -52,3 +52,75 @@
(return space) (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))
))