more compiler stuff

This commit is contained in:
Simon From Jakobsen 2025-09-22 16:22:03 +02:00
parent bdb3117e07
commit 4289d04ec3
4 changed files with 738 additions and 342 deletions

View File

@ -2,7 +2,9 @@
(fn Emitter (ast filename) (do
(let output ())
(let (enter_scope leave_scope define_sym get_sym) (call Syms))
(let (enter_scope leave_scope define_sym get_sym print_syms) (call Syms))
(let (let_node_reg_count let_node_reg_increment) (call Counter))
(fn generate () (do
(call emit "#!/usr/bin/env node\n")
@ -62,6 +64,7 @@
(let sym (call get_sym value))
(if (== sym null) (do
(call print_syms)
(call panic "undefined symbol '%' on line %" value line)
))
@ -122,11 +125,11 @@
(call leave_scope)
) (if (== id "let") (do
(let (_ pat expr) s)
(call emit "let ")
(call emit_pat pat)
(call emit " = runtime.assignValue(")
(let reg (call let_node_reg_count))
(call let_node_reg_increment)
(call emit (call format "let r_% = " reg))
(call emit_expr expr)
(call emit ")")
(call emit_let_node pat reg)
) (if (== id "do") (do
(call enter_scope)
(call discover_syms (call slice s 1))
@ -139,7 +142,7 @@
(call emit_pat pat)
(call emit " of ")
(call emit_expr expr)
(call emit ") {\n")
(call emit ".values) {\n")
(call emit_expr body)
(call emit "}")
(call leave_scope)
@ -251,6 +254,31 @@
))))))))))))))))))))))))
))
(fn emit_let_node (pat base_reg) (do
(let (pat_ty line) pat)
(if (== pat_ty "ident") (do
(let (_ _ ident) pat)
(if (== ident "_") (return))
(call emit (call format ";\nlet _% = r_%" ident base_reg))
(call define_sym ident ("let" line))
) (if (== pat_ty "list") (do
(let (_ _ pats) pat)
(let i 0)
(for pat pats (do
(let reg (call let_node_reg_count))
(call let_node_reg_increment)
(call emit (call format ";\nlet r_% = r_%.values[%]" reg base_reg i))
(call emit_let_node pat reg)
(+= i 1)
))
) (do
(call panic "malformed pattern on line %" line)
)))
))
(fn emit_binary_op (s id) (do
(let (_ left right) s)
(call emit (call format "runtime.%(" id))
@ -263,7 +291,6 @@
(fn emit_assign_expr (s line id) (do
(let (_ (target_type) expr) s)
(if (!= target_type "ident") (do
) (do
(call panic "cannot assign to expression on line %" line)
))
(let (_ (_ _ ident)) s)
@ -327,6 +354,20 @@
(return (generate))
))
(fn Counter () (do
(let counter 0)
(fn count () (do
(return counter)
))
(fn increment () (do
(+= counter 1)
))
(return (count increment))
))
(fn Syms () (do
(let syms (null (
("format" ("builtin" "builtinFormat"))
@ -389,12 +430,27 @@
(fn get (ident) (do
(return (call find_sym syms ident))
))
(fn print_syms_node (syms depth) (do
(let (parent map) syms)
(for (ident sym) map (do
(call println "%- %: %" (call indent depth) ident sym)
))
(if (!= parent null) (do
(call print_syms_node parent (+ depth 1))
))
))
(fn print_syms () (do
(call print_syms_node syms 0)
))
(return (
enter_scope
leave_scope
define
get
print_syms
))
))
@ -581,7 +637,6 @@
(call println "illegal char '%'" ch)
(+= i 1)
)))))))
))
(return tokens)
))
@ -658,16 +713,18 @@
(if (not silent) (call println "reading file..."))
(let text (call read_text_file input_filename))
//(call println "=== text ===")
//(call println text)
(call println "=== text ===")
// (call println text)
(call println (call len text))
(if (not silent) (call println "tokenizing..."))
(let tokens (call tokenize text))
// (call println "=== tokens ===")
(call println "=== tokens ===")
// (for (tok line value) tokens (do
// (call println "%\t%\t%" line tok (if (!= value null) value ""))
// ))
(call println (call len tokens))
(if (not silent) (call println "parsing..."))
(let parser (call Parser tokens))

View File

@ -2,8 +2,7 @@ import fs from "node:fs";
import process from "node:process";
export class Runtime {
constructor({ filename, args }) {
this.syms = { parent: undefined, map: new Map(this.builtins) };
constructor({ filename, args } = {}) {
this.callStack = [{ name: "<entry>", line: 0 }];
this.filename = filename;
this.args = args ?? process.argv.slice(2);

995
stage1.js

File diff suppressed because it is too large Load Diff

3
stage2.js Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env node
import { Runtime } from "./runtime.js"
const runtime = new Runtime("compile.phi")