remove explicit call syntax

This commit is contained in:
sfja 2025-09-23 17:05:23 +02:00
parent a9d744d278
commit 20cbcf7963
2 changed files with 261 additions and 261 deletions

View File

@ -2,10 +2,10 @@
(fn Emitter (ast filename) (do (fn Emitter (ast filename) (do
(let output (list)) (let output (list))
(let (enter_scope leave_scope define_sym get_sym print_syms) (call Syms)) (let (enter_scope leave_scope define_sym get_sym print_syms) (Syms))
(let (let_node_reg_count let_node_reg_increment) (call Counter)) (let (let_node_reg_count let_node_reg_increment) (Counter))
(let (sym_id_count sym_id_increment) (call Counter)) (let (sym_id_count sym_id_increment) (Counter))
(let builtin_syms (list (let builtin_syms (list
(list "format" "builtinFormat") (list "format" "builtinFormat")
@ -25,25 +25,25 @@
)) ))
(fn generate () (do (fn generate () (do
(call emit "#!/usr/bin/env node\n") (emit "#!/usr/bin/env node\n")
(call emit "import { Runtime } from \"./runtime.js\";\n") (emit "import { Runtime } from \"./runtime.js\";\n")
(call emit "const runtime = new Runtime({ filename: \"") (emit "const runtime = new Runtime({ filename: \"")
(call emit filename) (emit filename)
(call emit "\" });\n") (emit "\" });\n")
(for (ident builtin_id) builtin_syms (do (for (ident builtin_id) builtin_syms (do
(call define_builtin ident builtin_id) (define_builtin ident builtin_id)
)) ))
(call discover_syms ast) (discover_syms ast)
(call emit_exprs ast) (emit_exprs ast)
(return (call strings_join output)) (return (strings_join output))
)) ))
(fn emit_exprs (exprs) (do (fn emit_exprs (exprs) (do
(for expr exprs (do (for expr exprs (do
(call emit_expr expr) (emit_expr expr)
(call emit ";\n") (emit ";\n")
)) ))
)) ))
@ -52,11 +52,11 @@
(let (ty line) expr) (let (ty line) expr)
(if (!= ty "list") (return)) (if (!= ty "list") (return))
(let (_ _ s) expr) (let (_ _ s) expr)
(if (== (call len s) 0) (return)) (if (== (len s) 0) (return))
(let ((_ _ id)) s) (let ((_ _ id)) s)
(if (== id "fn") (do (if (== id "fn") (do
(let (_ (_ _ ident) (_ _ params) body) s) (let (_ (_ _ ident) (_ _ params) body) s)
(call define_fn ident line) (define_fn ident line)
)) ))
)) ))
)) ))
@ -64,247 +64,247 @@
(fn emit_expr (expr) (do (fn emit_expr (expr) (do
(let (ty line) expr) (let (ty line) expr)
(if (== ty "list") (do (if (== ty "list") (do
(call emit_list expr) (emit_list expr)
) (if (== ty "int") (do ) (if (== ty "int") (do
(let (_ _ value) expr) (let (_ _ value) expr)
(call emit (call format "({ type: \"int\", value: % })" value)) (emit (format "({ type: \"int\", value: % })" value))
) (if (== ty "string") (do ) (if (== ty "string") (do
(let (_ _ value) expr) (let (_ _ value) expr)
(call emit (call format "({ type: \"string\", value: \"%\" })" (call string_escape value))) (emit (format "({ type: \"string\", value: \"%\" })" (string_escape value)))
) (if (== ty "ident") (do ) (if (== ty "ident") (do
(let (_ _ value) expr) (let (_ _ value) expr)
(if (== value "null") (do (if (== value "null") (do
(call emit "({ type: \"null\" })") (emit "({ type: \"null\" })")
(return) (return)
) (if (== value "false") (do ) (if (== value "false") (do
(call emit "({ type: \"bool\", value: false })") (emit "({ type: \"bool\", value: false })")
(return) (return)
) (if (== value "true") (do ) (if (== value "true") (do
(call emit "({ type: \"bool\", value: true })") (emit "({ type: \"bool\", value: true })")
(return) (return)
)))) ))))
(let sym (call get_sym value)) (let sym (get_sym value))
(if (== sym null) (do (if (== sym null) (do
(call panic "undefined symbol '%' on line %" value line) (panic "undefined symbol '%' on line %" value line)
)) ))
(let (sym_id sym_ty) sym) (let (sym_id sym_ty) sym)
(if (== sym_ty "builtin") (do (if (== sym_ty "builtin") (do
(let (_ _ id) sym) (let (_ _ id) sym)
(call emit (call format "((...args) => runtime.%(...args))" id)) (emit (format "((...args) => runtime.%(...args))" id))
) (if (== sym_ty "fn") (do ) (if (== sym_ty "fn") (do
(call emit (call format "_%%" value sym_id)) (emit (format "_%%" value sym_id))
) (if (== sym_ty "param") (do ) (if (== sym_ty "param") (do
(call emit (call format "_%%" value sym_id)) (emit (format "_%%" value sym_id))
) (if (== sym_ty "let") (do ) (if (== sym_ty "let") (do
(call emit (call format "_%%" value sym_id)) (emit (format "_%%" value sym_id))
) (do ) (do
(call panic "not implemented '%'" sym_ty) (panic "not implemented '%'" sym_ty)
))))) )))))
) (do ) (do
(call panic "unknown expr type '%' on line %" ty line) (panic "unknown expr type '%' on line %" ty line)
))))) )))))
)) ))
(fn emit_list (expr) (do (fn emit_list (expr) (do
(let (ty line s) expr) (let (ty line s) expr)
(if (== (call len s) 0) (do (if (== (len s) 0) (do
(call panic "illegal function call on line %" line) (panic "illegal function on line %" line)
)) ))
(let ((id_ty _ id)) s) (let ((id_ty _ id)) s)
(if (!= id_ty "ident") (do (if (!= id_ty "ident") (do
(call panic "illegal function call on line %" line) (panic "illegal function on line %" line)
)) ))
(if (== id "fn") (do (if (== id "fn") (do
(let (_ (_ _ ident) (_ _ params) body) s) (let (_ (_ _ ident) (_ _ params) body) s)
(let sym (call get_sym ident)) (let sym (get_sym ident))
(let (sym_id) sym) (let (sym_id) sym)
(call emit (call format "function _%%(" ident sym_id)) (emit (format "function _%%(" ident sym_id))
(call enter_scope) (enter_scope)
(let first true) (let first true)
(for (_ _ ident) params (do (for (_ _ ident) params (do
(if (not first) (do (if (not first) (do
(call emit ", ") (emit ", ")
)) ))
(= first false) (= first false)
(let sym_id (call define_param ident line)) (let sym_id (define_param ident line))
(call emit (call format "_%%" ident sym_id)) (emit (format "_%%" ident sym_id))
)) ))
(call emit ") {\n") (emit ") {\n")
(call emit (call format "runtime.pushCall(\"%\");\n" ident)) (emit (format "runtime.pushCall(\"%\");\n" ident))
(call emit_expr body) (emit_expr body)
(call emit ";\nruntime.popCall();\nreturn { type: \"null\" };\n}") (emit ";\nruntime.popCall();\nreturn { type: \"null\" };\n}")
(call leave_scope) (leave_scope)
) (if (== id "let") (do ) (if (== id "let") (do
(let (_ pat expr) s) (let (_ pat expr) s)
(let reg (call let_node_reg_count)) (let reg (let_node_reg_count))
(call let_node_reg_increment) (let_node_reg_increment)
(call emit (call format "const r_% = " reg)) (emit (format "const r_% = " reg))
(call emit_expr expr) (emit_expr expr)
(call emit_let_node pat reg) (emit_let_node pat reg)
) (if (== id "do") (do ) (if (== id "do") (do
(call enter_scope) (enter_scope)
(call discover_syms (call slice s 1)) (discover_syms (slice s 1))
(call emit_exprs (call slice s 1)) (emit_exprs (slice s 1))
(call leave_scope) (leave_scope)
) (if (== id "for") (do ) (if (== id "for") (do
(let (_ pat expr body) s) (let (_ pat expr body) s)
(let reg (call let_node_reg_count)) (let reg (let_node_reg_count))
(call let_node_reg_increment) (let_node_reg_increment)
(call emit (call format "for (const r_% of " reg)) (emit (format "for (const r_% of " reg))
(call emit_expr expr) (emit_expr expr)
(call emit ".values) {") (emit ".values) {")
(call enter_scope) (enter_scope)
(call emit_let_node pat reg) (emit_let_node pat reg)
(call enter_scope) (enter_scope)
(call emit ";\n") (emit ";\n")
(call emit_expr body) (emit_expr body)
(call emit "}") (emit "}")
(call leave_scope) (leave_scope)
(call leave_scope) (leave_scope)
) (if (== id "loop") (do ) (if (== id "loop") (do
(let (_ body) s) (let (_ body) s)
(call emit "while (true) {\n") (emit "while (true) {\n")
(call emit_expr body) (emit_expr body)
(call emit "}") (emit "}")
) (if (== id "if") (do ) (if (== id "if") (do
(let (_ cond truthy falsy) s) (let (_ cond truthy falsy) s)
(call emit "if (runtime.truthy(") (emit "if (runtime.truthy(")
(call emit_expr cond) (emit_expr cond)
(call emit ")) {\n") (emit ")) {\n")
(call emit_expr truthy) (emit_expr truthy)
(call emit "}") (emit "}")
(if (!= falsy null) (do (if (!= falsy null) (do
(call emit " else {\n") (emit " else {\n")
(call emit_expr falsy) (emit_expr falsy)
(call emit "}") (emit "}")
)) ))
) (if (== id "return") (do ) (if (== id "return") (do
(let (_ value) s) (let (_ value) s)
(call emit "runtime.popCall();\n") (emit "runtime.popCall();\n")
(call emit "return ") (emit "return ")
(if (!= value null) (do (if (!= value null) (do
(call emit_expr value) (emit_expr value)
) (do ) (do
(call emit "{ type: \"null\" }") (emit "{ type: \"null\" }")
)) ))
) (if (== id "break") (do ) (if (== id "break") (do
(let (_ value) s) (let (_ value) s)
(call emit "break") (emit "break")
(if (!= value null) (do (if (!= value null) (do
(call panic "not implemented") (panic "not implemented")
)) ))
) (if (== id "call") (do ) (if (== id "call") (do
(let (_ callee) s) (let (_ callee) s)
(let args (call slice s 2)) (let args (slice s 2))
(call emit (call format "(runtime.setLine(%), " line)) (emit (format "(runtime.setLine(%), " line))
(call emit_expr callee) (emit_expr callee)
(call emit "(") (emit "(")
(let first true) (let first true)
(for arg args (do (for arg args (do
(if (not first) (do (if (not first) (do
(call emit ", ") (emit ", ")
)) ))
(= first false) (= first false)
(call emit_expr arg) (emit_expr arg)
)) ))
(call emit "))") (emit "))")
) (if (== id "list") (do ) (if (== id "list") (do
(call emit_list_literal (call slice s 1)) (emit_list_literal (slice s 1))
) (if (== id "=") (do ) (if (== id "=") (do
(call emit_assign_expr s line "=") (emit_assign_expr s line "=")
) (if (== id "+=") (do ) (if (== id "+=") (do
(call emit_assign_expr s line "+") (emit_assign_expr s line "+")
) (if (== id "-=") (do ) (if (== id "-=") (do
(call 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)
(call emit (call format "(runtime.setLine(%)" line)) (emit (format "(runtime.setLine(%)" line))
(call emit ", { type: \"bool\", value: runtime.truthy(") (emit ", { type: \"bool\", value: runtime.truthy(")
(call emit_expr left) (emit_expr left)
(call emit ") || runtime.truthy(") (emit ") || runtime.truthy(")
(call emit_expr right) (emit_expr right)
(call emit ") })") (emit ") })")
) (if (== id "and") (do ) (if (== id "and") (do
(let (_ left right) s) (let (_ left right) s)
(call emit (call format "(runtime.setLine(%)" line)) (emit (format "(runtime.setLine(%)" line))
(call emit ", { type: \"bool\", value: runtime.truthy(") (emit ", { type: \"bool\", value: runtime.truthy(")
(call emit_expr left) (emit_expr left)
(call emit ") && runtime.truthy(") (emit ") && runtime.truthy(")
(call emit_expr right) (emit_expr right)
(call emit ") })") (emit ") })")
) (if (== id "==") (do ) (if (== id "==") (do
(call emit_binary_op s "opEq") (emit_binary_op s "opEq")
) (if (== id "!=") (do ) (if (== id "!=") (do
(call emit_binary_op s "opNe") (emit_binary_op s "opNe")
) (if (== id "<") (do ) (if (== id "<") (do
(call emit_binary_op s "opLt") (emit_binary_op s "opLt")
) (if (== id ">") (do ) (if (== id ">") (do
(call emit_binary_op s "opGt") (emit_binary_op s "opGt")
) (if (== id "<=") (do ) (if (== id "<=") (do
(call emit_binary_op s "opLte") (emit_binary_op s "opLte")
) (if (== id ">=") (do ) (if (== id ">=") (do
(call emit_binary_op s "opGte") (emit_binary_op s "opGte")
) (if (== id "+") (do ) (if (== id "+") (do
(call emit_binary_op s "opAdd") (emit_binary_op s "opAdd")
) (if (== id "-") (do ) (if (== id "-") (do
(call emit_binary_op s "opSub") (emit_binary_op s "opSub")
) (if (== id "not") (do ) (if (== id "not") (do
(let (_ expr) s) (let (_ expr) s)
(call emit "runtime.opNot(") (emit "runtime.opNot(")
(call emit_expr expr) (emit_expr expr)
(call emit ")") (emit ")")
) (do ) (do
(let (callee) s) (let (callee) s)
(let args (call slice s 1)) (let args (slice s 1))
(call emit (call format "(runtime.setLine(%), " line)) (emit (format "(runtime.setLine(%), " line))
(call emit_expr callee) (emit_expr callee)
(call emit "(") (emit "(")
(let first true) (let first true)
(for arg args (do (for arg args (do
(if (not first) (do (if (not first) (do
(call emit ", ") (emit ", ")
)) ))
(= first false) (= first false)
(call emit_expr arg) (emit_expr arg)
)) ))
(call emit "))") (emit "))")
))))))))))))))))))))))))) )))))))))))))))))))))))))
)) ))
(fn emit_list_literal (s) (do (fn emit_list_literal (s) (do
(call emit "({ type: \"list\", values: [") (emit "({ type: \"list\", values: [")
(let first true) (let first true)
(for e s (do (for e s (do
(if (not first) (do (if (not first) (do
(call emit ", ") (emit ", ")
)) ))
(= first false) (= first false)
(call emit_expr e) (emit_expr e)
)) ))
(call emit "] })") (emit "] })")
)) ))
(fn emit_let_node (pat base_reg) (do (fn emit_let_node (pat base_reg) (do
@ -314,117 +314,117 @@
(if (== ident "_") (return)) (if (== ident "_") (return))
(let sym_id (call define_let ident line)) (let sym_id (define_let ident line))
(call emit (call format ";\nlet _%% = r_%" ident sym_id base_reg)) (emit (format ";\nlet _%% = r_%" ident sym_id base_reg))
) (if (== pat_ty "list") (do ) (if (== pat_ty "list") (do
(let (_ _ pats) pat) (let (_ _ pats) pat)
//(call emit (call format //(emit (format
// (+ ";\nif (r_%.type !== \"list\") {\nruntime.setLine(%);" // (+ ";\nif (r_%.type !== \"list\") {\nruntime.setLine(%);"
// "\nruntime.panic(\"expected list\");\n}\n") // "\nruntime.panic(\"expected list\");\n}\n")
// base_reg // base_reg
// line // line
//)) //))
//(call emit (call format //(emit (format
// (+ ";\nif (% > r_%.values.length) {\nruntime.setLine(%);\nruntime.panic" // (+ ";\nif (% > r_%.values.length) {\nruntime.setLine(%);\nruntime.panic"
// "(`expected % elements, got ${r_%.values.length}`);\n}\n") // "(`expected % elements, got ${r_%.values.length}`);\n}\n")
// (call len pats) // (len pats)
// base_reg // base_reg
// line // line
// (call len pats) // (len pats)
// base_reg // base_reg
//)) //))
(let i 0) (let i 0)
(for pat pats (do (for pat pats (do
(let reg (call let_node_reg_count)) (let reg (let_node_reg_count))
(call let_node_reg_increment) (let_node_reg_increment)
(call emit (call format (emit (format
";\nconst r_% = r_%.values[%] ?? { type: \"null\"}" ";\nconst r_% = r_%.values[%] ?? { type: \"null\"}"
reg base_reg i reg base_reg i
)) ))
(call emit_let_node pat reg) (emit_let_node pat reg)
(+= i 1) (+= i 1)
)) ))
) (do ) (do
(call panic "malformed pattern on line %" line) (panic "malformed pattern on line %" line)
))) )))
)) ))
(fn emit_binary_op (s id) (do (fn emit_binary_op (s id) (do
(let (_ left right) s) (let (_ left right) s)
(call emit (call format "runtime.%(" id)) (emit (format "runtime.%(" id))
(call emit_expr left) (emit_expr left)
(call emit ", ") (emit ", ")
(call emit_expr right) (emit_expr right)
(call emit ")") (emit ")")
)) ))
(fn emit_assign_expr (s line id) (do (fn emit_assign_expr (s line id) (do
(let (_ (target_type) expr) s) (let (_ (target_type) expr) s)
(if (!= target_type "ident") (do (if (!= target_type "ident") (do
(call panic "cannot assign to expression on line %" line) (panic "cannot assign to expression on line %" line)
)) ))
(let (_ (_ _ ident)) s) (let (_ (_ _ ident)) s)
(let sym (call get_sym ident)) (let sym (get_sym ident))
(if (== sym null) (do (if (== sym null) (do
(call panic "could not find symbol '%' on line %" ident line) (panic "could not find symbol '%' on line %" ident line)
)) ))
(let (sym_id sym_type sym_ident _) sym) (let (sym_id sym_type sym_ident _) sym)
(if (== sym_type "let") (do (if (== sym_type "let") (do
(call emit (call format "(_%% = " sym_ident sym_id)) (emit (format "(_%% = " sym_ident sym_id))
(if (== id "=") (do (if (== id "=") (do
(call emit_expr expr) (emit_expr expr)
) (if (== id "+") (do ) (if (== id "+") (do
(call emit (call format "runtime.opAdd(_%%, " sym_ident sym_id)) (emit (format "runtime.opAdd(_%%, " sym_ident sym_id))
(call emit_expr expr) (emit_expr expr)
(call emit ")") (emit ")")
) (if (== id "-") (do ) (if (== id "-") (do
(call emit (call format "runtime.opSub(_%%, " sym_ident sym_id)) (emit (format "runtime.opSub(_%%, " sym_ident sym_id))
(call emit_expr expr) (emit_expr expr)
(call emit ")") (emit ")")
) (do ) (do
(call panic "not implemented") (panic "not implemented")
)))) ))))
(call emit ")") (emit ")")
) (do ) (do
(call panic "cannot assign to symbol '%' on line %" sym_ident line) (panic "cannot assign to symbol '%' on line %" sym_ident line)
)) ))
)) ))
(fn emit (str) (do (fn emit (str) (do
(call push output str) (push output str)
)) ))
(fn define_builtin (ident builtin_id) (do (fn define_builtin (ident builtin_id) (do
(let sym_id (call sym_id_count)) (let sym_id (sym_id_count))
(call sym_id_increment) (sym_id_increment)
(call define_sym ident (list sym_id "builtin" builtin_id)) (define_sym ident (list sym_id "builtin" builtin_id))
(return sym_id) (return sym_id)
)) ))
(fn define_fn (ident line) (do (fn define_fn (ident line) (do
(let sym_id (call sym_id_count)) (let sym_id (sym_id_count))
(call sym_id_increment) (sym_id_increment)
(call define_sym ident (list sym_id "fn" ident line)) (define_sym ident (list sym_id "fn" ident line))
(return sym_id) (return sym_id)
)) ))
(fn define_param (ident line) (do (fn define_param (ident line) (do
(let sym_id (call sym_id_count)) (let sym_id (sym_id_count))
(call sym_id_increment) (sym_id_increment)
(call define_sym ident (list sym_id "param" ident line)) (define_sym ident (list sym_id "param" ident line))
(return sym_id) (return sym_id)
)) ))
(fn define_let (ident line) (do (fn define_let (ident line) (do
(let sym_id (call sym_id_count)) (let sym_id (sym_id_count))
(call sym_id_increment) (sym_id_increment)
(call define_sym ident (list sym_id "let" ident line)) (define_sym ident (list sym_id "let" ident line))
(return sym_id) (return sym_id)
)) ))
@ -461,50 +461,50 @@
(let (_ map) syms) (let (_ map) syms)
(let i 0) (let i 0)
(loop (do (loop (do
(if (>= i (call len map)) (break)) (if (>= i (len map)) (break))
(let (s_ident _) (call at map i)) (let (s_ident _) (at map i))
(if (== ident s_ident) (do (if (== ident s_ident) (do
(call set map i (list ident sym)) (set map i (list ident sym))
(return) (return)
)) ))
(+= i 1) (+= i 1)
)) ))
(call push map (list ident sym)) (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) (let i 0)
(loop (do (loop (do
(if (>= i (call len map)) (break)) (if (>= i (len map)) (break))
(let (s_ident s_sym) (call at map i)) (let (s_ident s_sym) (at map i))
(if (== ident s_ident) (do (if (== ident s_ident) (do
(return s_sym) (return s_sym)
)) ))
(+= i 1) (+= i 1)
)) ))
(if (!= parent null) (do (if (!= parent null) (do
(return (call find_sym parent ident)) (return (find_sym parent ident))
)) ))
(return null) (return null)
)) ))
(fn get (ident) (do (fn get (ident) (do
(return (call find_sym syms ident)) (return (find_sym syms ident))
)) ))
(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
(call println "%- %: %" (call indent depth) ident sym) (println "%- %: %" (indent depth) ident sym)
)) ))
(if (!= parent null) (do (if (!= parent null) (do
(call print_syms_node parent (+ depth 1)) (print_syms_node parent (+ depth 1))
)) ))
)) ))
(fn print_syms () (do (fn print_syms () (do
(call print_syms_node syms 0) (print_syms_node syms 0)
)) ))
(return (list (return (list
@ -518,12 +518,12 @@
(fn string_escape (str) (do (fn string_escape (str) (do
(let str_len (call len str)) (let str_len (len str))
(let i 0) (let i 0)
(let result "") (let result "")
(loop (do (loop (do
(if (>= i str_len) (break)) (if (>= i str_len) (break))
(let ch (call at str i)) (let ch (at str i))
(if (== ch "\\") (do (if (== ch "\\") (do
(+= result "\\\\") (+= result "\\\\")
) (if (== ch "\"") (do ) (if (== ch "\"") (do
@ -546,69 +546,69 @@
(fn Parser (tokens) (do (fn Parser (tokens) (do
(let i 0) (let i 0)
(let tok (call at tokens i)) (let tok (at tokens i))
(fn parse () (do (fn parse () (do
(let exprs (list)) (let exprs (list))
(loop (do (loop (do
(if (call done) (break)) (if (done) (break))
(call push exprs (call parse_expr)) (push exprs (parse_expr))
)) ))
(return exprs) (return exprs)
)) ))
(fn parse_expr () (do (fn parse_expr () (do
(let (ty line value) tok) (let (ty line value) tok)
(if (call eat "(") (do (if (eat "(") (do
(let values (list)) (let values (list))
(loop (do (loop (do
(if (call test ")") (break)) (if (test ")") (break))
(call push values (call parse_expr)) (push values (parse_expr))
)) ))
(if (not (call eat ")")) (do (if (not (eat ")")) (do
(call panic "expected ')' on line %" (call at tok 1)) (panic "expected ')' on line %" (at tok 1))
)) ))
(return (list "list" line values)) (return (list "list" line values))
) (if (call eat "string") (do ) (if (eat "string") (do
(return (list "string" line value)) (return (list "string" line value))
) (if (call eat "int") (do ) (if (eat "int") (do
(return (list "int" line (call string_to_int value))) (return (list "int" line (string_to_int value)))
) (if (call eat "ident") (do ) (if (eat "ident") (do
(return (list "ident" line value)) (return (list "ident" line value))
) (do ) (do
(call panic "expected expression, got '%' on line %" ty line) (panic "expected expression, got '%' on line %" ty line)
))))) )))))
)) ))
(fn eat (pat) (do (fn eat (pat) (do
(if (not (call test pat)) (return false)) (if (not (test pat)) (return false))
(call step) (step)
(return true) (return true)
)) ))
(fn step () (do (fn step () (do
(+= i 1) (+= i 1)
(if (not (call done)) (do (if (not (done)) (do
(let new_tok (call at tokens i)) (let new_tok (at tokens i))
(= tok new_tok) (= tok new_tok)
)) ))
)) ))
(fn test (pat) (do (fn test (pat) (do
(if (call done) (return false)) (if (done) (return false))
(let (ty) tok) (let (ty) tok)
(return (== pat ty)) (return (== pat ty))
)) ))
(fn done () (do (fn done () (do
(return (>= i (call len tokens))) (return (>= i (len tokens)))
)) ))
(return (list parse)) (return (list parse))
)) ))
(fn tokenize (text) (do (fn tokenize (text) (do
(let text_len (call len text)) (let text_len (len text))
(let tokens (list)) (let tokens (list))
(let i 0) (let i 0)
@ -620,27 +620,27 @@
(loop (do (loop (do
(if (>= i text_len) (break)) (if (>= i text_len) (break))
(let ch (call at text i)) (let ch (at text i))
(if (call contains " \t\r\n" ch) (do (if (contains " \t\r\n" ch) (do
(if (== ch "\n") (do (if (== ch "\n") (do
(+= line 1) (+= line 1)
)) ))
(+= i 1) (+= i 1)
) (if (call slice_eq text i "//") (do ) (if (slice_eq text i "//") (do
(loop (do (loop (do
(if (or (>= i text_len) (== (call at text i) "\n")) (do (if (or (>= i text_len) (== (at text i) "\n")) (do
(break) (break)
)) ))
(+= i 1) (+= i 1)
)) ))
) (if (call contains "()" ch) (do ) (if (contains "()" ch) (do
(call push tokens (list ch line)) (push tokens (list ch line))
(+= i 1) (+= i 1)
) (if (== ch "\"") (do ) (if (== ch "\"") (do
(let value "") (let value "")
(+= i 1) (+= i 1)
(= ch (call at text i)) (= ch (at text i))
(loop (do (loop (do
(if (or (>= i text_len) (== ch "\"")) (do (if (or (>= i text_len) (== ch "\"")) (do
(break) (break)
@ -650,7 +650,7 @@
(if (>= i text_len) (do (if (>= i text_len) (do
(break) (break)
)) ))
(= ch (call at text i)) (= ch (at text i))
(if (== ch "t") (do (if (== ch "t") (do
(+= value "\t") (+= value "\t")
) (if (== ch "r") (do ) (if (== ch "r") (do
@ -666,37 +666,37 @@
(+= value ch) (+= value ch)
)) ))
(+= i 1) (+= i 1)
(= ch (call at text i)) (= ch (at text i))
)) ))
(if (or (>= i text_len) (!= ch "\"")) (do (if (or (>= i text_len) (!= ch "\"")) (do
(call panic "expected '\"' on line %" line) (panic "expected '\"' on line %" line)
)) ))
(+= i 1) (+= i 1)
(call push tokens (list "string" line value)) (push tokens (list "string" line value))
) (if (call contains "0123456789" ch) (do ) (if (contains "0123456789" ch) (do
(let value "") (let value "")
(loop (do (loop (do
(= ch (call at text i)) (= ch (at text i))
(if (or (>= i text_len) (not (call contains "0123456789" ch))) (do (if (or (>= i text_len) (not (contains "0123456789" ch))) (do
(break) (break)
)) ))
(+= value ch) (+= value ch)
(+= i 1) (+= i 1)
)) ))
(call push tokens (list "int" line value)) (push tokens (list "int" line value))
) (if (call contains ident_chars ch) (do ) (if (contains ident_chars ch) (do
(let value "") (let value "")
(loop (do (loop (do
(= ch (call at text i)) (= ch (at text i))
(if (or (>= i text_len) (not (call contains ident_chars ch))) (do (if (or (>= i text_len) (not (contains ident_chars ch))) (do
(break) (break)
)) ))
(+= value ch) (+= value ch)
(+= i 1) (+= i 1)
)) ))
(call push tokens (list "ident" line value)) (push tokens (list "ident" line value))
) (do ) (do
(call println "illegal char '%'" ch) (println "illegal char '%'" ch)
(+= i 1) (+= i 1)
))))))) )))))))
)) ))
@ -704,11 +704,11 @@
)) ))
(fn contains (text ch) (do (fn contains (text ch) (do
(let text_len (call len text)) (let text_len (len text))
(let i 0) (let i 0)
(loop (do (loop (do
(if (>= i text_len) (break)) (if (>= i text_len) (break))
(if (== (call at text i) ch) (do (if (== (at text i) ch) (do
(return true) (return true)
)) ))
(+= i 1) (+= i 1)
@ -717,15 +717,15 @@
)) ))
(fn slice_eq (str slice_idx substr) (do (fn slice_eq (str slice_idx substr) (do
(let str_len (call len str)) (let str_len (len str))
(let substr_len (call len substr)) (let substr_len (len substr))
(let i 0) (let i 0)
(loop (do (loop (do
(if (>= i substr_len) (if (>= i substr_len)
(return true)) (return true))
(if (>= (+ slice_idx i) str_len) (if (>= (+ slice_idx i) str_len)
(return false)) (return false))
(if (!= (call at str (+ slice_idx i)) (call at substr i)) (if (!= (at str (+ slice_idx i)) (at substr i))
(return false)) (return false))
(+= i 1) (+= i 1)
)) ))
@ -735,13 +735,13 @@
(fn print_expr (expr depth) (do (fn print_expr (expr depth) (do
(let (ty line value) expr) (let (ty line value) expr)
(if (== ty "list") (do (if (== ty "list") (do
(call println "%(% %" (call indent depth) ty line) (println "%(% %" (indent depth) ty line)
(for e value (do (for e value (do
(call print_expr e (+ depth 1)) (print_expr e (+ depth 1))
)) ))
(call println "%)" (call indent depth)) (println "%)" (indent depth))
) (do ) (do
(call println "%%" (call indent depth) expr) (println "%%" (indent depth) expr)
)) ))
)) ))
@ -757,12 +757,12 @@
)) ))
(fn slice (list idx) (do (fn slice (list idx) (do
(let list_len (call len list)) (let list_len (len list))
(let elems (list)) (let elems (list))
(let i idx) (let i idx)
(loop (do (loop (do
(if (>= i list_len) (break)) (if (>= i list_len) (break))
(call push elems (call at list i)) (push elems (at list i))
(+= i 1) (+= i 1)
)) ))
(return elems) (return elems)
@ -770,49 +770,49 @@
(let silent false) (let silent false)
(let (input_filename output_filename) (call get_args)) (let (input_filename output_filename) (get_args))
(if (not silent) (call println "reading file '%'..." input_filename)) (if (not silent) (println "reading file '%'..." input_filename))
(let text (call read_text_file input_filename)) (let text (read_text_file input_filename))
//(call println "=== text ===") //(println "=== text ===")
// (call println text) // (println text)
//(call println (call len text)) //(println (len text))
(if (not silent) (call println "tokenizing...")) (if (not silent) (println "tokenizing..."))
(let tokens (call tokenize text)) (let tokens (tokenize text))
//(call println "=== tokens ===") //(println "=== tokens ===")
//(for elem tokens (do //(for elem tokens (do
// (let (tok line value) elem) // (let (tok line value) elem)
// (if (!= value null) (do // (if (!= value null) (do
// (call println "%\t%\t%" line tok value) // (println "%\t%\t%" line tok value)
// ) (do // ) (do
// (call println "%\t%" line tok) // (println "%\t%" line tok)
// )) // ))
//)) //))
//(call println (call len tokens)) //(println (len tokens))
(if (not silent) (call println "parsing...")) (if (not silent) (println "parsing..."))
(let parser (call Parser tokens)) (let parser (Parser tokens))
(let (parse) parser) (let (parse) parser)
(let ast (call parse)) (let ast (parse))
// (call println "=== ast ===") // (println "=== ast ===")
// (for expr ast (do // (for expr ast (do
// (call print_expr expr 0) // (print_expr expr 0)
// )) // ))
(if (not silent) (call println "emitting...")) (if (not silent) (println "emitting..."))
(let emitter (call Emitter ast input_filename)) (let emitter (Emitter ast input_filename))
(let (emit) emitter) (let (emit) emitter)
(let js_code (call emit)) (let js_code (emit))
// (call println "=== js ===") // (println "=== js ===")
// (call println js_code) // (println js_code)
(if (not silent) (call println "writing file '%'..." output_filename)) (if (not silent) (println "writing file '%'..." output_filename))
(call write_text_file output_filename js_code) (write_text_file output_filename js_code)

View File

@ -202,7 +202,7 @@ let _line77 = r_67;
const r_68 = r_65.values[2] ?? { type: "null"}; const r_68 = r_65.values[2] ?? { type: "null"};
let _s78 = r_68; let _s78 = r_68;
if (runtime.truthy(runtime.opEq((runtime.setLine(113), ((...args) => runtime.builtinLen(...args))(_s78)), ({ type: "int", value: 0 })))) { if (runtime.truthy(runtime.opEq((runtime.setLine(113), ((...args) => runtime.builtinLen(...args))(_s78)), ({ type: "int", value: 0 })))) {
(runtime.setLine(114), ((...args) => runtime.builtinPanic(...args))(({ type: "string", value: "illegal function call on line %" }), _line77)); (runtime.setLine(114), ((...args) => runtime.builtinPanic(...args))(({ type: "string", value: "illegal function on line %" }), _line77));
}; };
const r_69 = _s78; const r_69 = _s78;
const r_70 = r_69.values[0] ?? { type: "null"}; const r_70 = r_69.values[0] ?? { type: "null"};
@ -212,7 +212,7 @@ const r_72 = r_70.values[1] ?? { type: "null"};
const r_73 = r_70.values[2] ?? { type: "null"}; const r_73 = r_70.values[2] ?? { type: "null"};
let _id80 = r_73; let _id80 = r_73;
if (runtime.truthy(runtime.opNe(_id_ty79, ({ type: "string", value: "ident" })))) { if (runtime.truthy(runtime.opNe(_id_ty79, ({ type: "string", value: "ident" })))) {
(runtime.setLine(118), ((...args) => runtime.builtinPanic(...args))(({ type: "string", value: "illegal function call on line %" }), _line77)); (runtime.setLine(118), ((...args) => runtime.builtinPanic(...args))(({ type: "string", value: "illegal function on line %" }), _line77));
}; };
if (runtime.truthy(runtime.opEq(_id80, ({ type: "string", value: "fn" })))) { if (runtime.truthy(runtime.opEq(_id80, ({ type: "string", value: "fn" })))) {
const r_74 = _s78; const r_74 = _s78;