let as last expr in block now returns rhs; clean up some comment cruft

This commit is contained in:
Scott Richmond 2025-06-04 18:27:17 -04:00
parent 61b1b7bf90
commit 2ce2e2c2d3
3 changed files with 25 additions and 114 deletions

View File

@ -315,14 +315,10 @@ pub struct Compiler<'a> {
loop_info: Vec<LoopInfo>, loop_info: Vec<LoopInfo>,
} }
fn is_binding(expr: &Spanned<Ast>) -> bool { fn is_let(expr: &Spanned<Ast>) -> bool {
let (ast, _) = expr; let (ast, _) = expr;
use Ast::*; use Ast::*;
match ast { matches!(ast, Let(..))
Let(..) | LBox(..) => true,
// Fn(name, ..) => !name.is_empty(),
_ => false,
}
} }
impl<'a> Compiler<'a> { impl<'a> Compiler<'a> {
@ -358,14 +354,6 @@ impl<'a> Compiler<'a> {
} }
} }
// pub fn kw_from(&self, kw: &str) -> Option<Value> {
// self.kw_index_from(kw).map(Value::Keyword)
// }
// pub fn kw_index_from(&self, kw: &str) -> Option<usize> {
// self.chunk.keywords.iter().position(|s| *s == kw)
// }
pub fn visit(&mut self, node: &'static Spanned<Ast>) { pub fn visit(&mut self, node: &'static Spanned<Ast>) {
let root_node = self.ast; let root_node = self.ast;
let root_span = self.span; let root_span = self.span;
@ -377,18 +365,6 @@ impl<'a> Compiler<'a> {
self.span = root_span; self.span = root_span;
} }
// fn emit_keyword(&mut self, s: &'static str) {
// // let existing_kw = self.chunk.keywords.iter().position(|kw| *kw == s);
// // let kw_index = match existing_kw {
// // Some(index) => index,
// // None => self.chunk.keywords.len(),
// // };
// // if kw_index == self.chunk.keywords.len() {
// // self.chunk.keywords.push(s);
// // }
// self.emit_constant(Value::Keyword(s));
// }
fn emit_constant(&mut self, val: Value) { fn emit_constant(&mut self, val: Value) {
let const_idx = if let Some(idx) = self.chunk.constants.iter().position(|v| *v == val) { let const_idx = if let Some(idx) = self.chunk.constants.iter().position(|v| *v == val) {
idx idx
@ -404,11 +380,7 @@ impl<'a> Compiler<'a> {
) )
} }
self.emit_op(Op::Constant); self.emit_op(Op::Constant);
// self.chunk.bytecode.push(Op::Constant as u8);
// self.spans.push(self.span);
self.emit_byte(const_idx); self.emit_byte(const_idx);
// self.chunk.bytecode.push(constant_index as u8);
// self.spans.push(self.span);
self.stack_depth += 1; self.stack_depth += 1;
} }
@ -535,12 +507,6 @@ impl<'a> Compiler<'a> {
self.stack_depth += 1; self.stack_depth += 1;
} }
String(s) => { String(s) => {
// let existing_str = self.chunk.strings.iter().position(|e| e == s);
// let str_index = match existing_str {
// Some(idx) => idx,
// None => self.chunk.strings.len(),
// };
// self.chunk.strings.push(s);
self.emit_constant(Value::Interned(s)); self.emit_constant(Value::Interned(s));
} }
Keyword(s) => self.emit_constant(Value::Keyword(s)), Keyword(s) => self.emit_constant(Value::Keyword(s)),
@ -548,31 +514,37 @@ impl<'a> Compiler<'a> {
self.scope_depth += 1; self.scope_depth += 1;
let stack_depth = self.stack_depth; let stack_depth = self.stack_depth;
for expr in lines.iter().take(lines.len() - 1) { for expr in lines.iter().take(lines.len() - 1) {
if is_binding(expr) { if is_let(expr) {
self.visit(expr); self.visit(expr);
} else { } else {
self.visit(expr); self.visit(expr);
self.pop(); self.pop();
// self.emit_op(Op::Pop);
} }
} }
let last_expr = lines.last().unwrap(); let last_expr = lines.last().unwrap();
// TODO: make sure this actually returns the RHS of the expression match last_expr {
if is_binding(last_expr) { (Let(patt, expr), _) => {
self.visit(last_expr); self.match_depth = 0;
self.emit_op(Op::Duplicate); self.emit_op(Op::ResetMatch);
self.stack_depth += 1; self.visit(expr);
} else { let expr_pos = self.stack_depth - 1;
self.visit(last_expr); self.visit(patt);
self.stack_depth += 1; self.emit_op(Op::PanicIfNoMatch);
self.emit_op(Op::PushBinding);
self.emit_byte(expr_pos);
self.stack_depth += 1;
}
_ => {
self.visit(last_expr);
}
} }
self.stack_depth += 1;
self.emit_op(Op::Store); self.emit_op(Op::Store);
self.scope_depth -= 1; self.scope_depth -= 1;
// reset bindings
while let Some(binding) = self.bindings.last() { while let Some(binding) = self.bindings.last() {
if binding.depth > self.scope_depth { if binding.depth > self.scope_depth {
let binding = self.bindings.pop().unwrap(); self.bindings.pop();
println!("popping: {:?}", binding);
} else { } else {
break; break;
} }
@ -670,14 +642,6 @@ impl<'a> Compiler<'a> {
self.bind(word); self.bind(word);
} }
StringPattern(s) => { StringPattern(s) => {
// let existing_str = self.chunk.strings.iter().position(|e| e == s);
// let str_index = match existing_str {
// Some(idx) => idx,
// None => self.chunk.strings.len(),
// };
// if str_index == self.chunk.strings.len() {
// self.chunk.strings.push(s)
// }
self.match_constant(Value::Interned(s)); self.match_constant(Value::Interned(s));
} }
TuplePattern(members) => { TuplePattern(members) => {
@ -706,11 +670,6 @@ impl<'a> Compiler<'a> {
self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1; self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1;
} }
for _ in 0..members.len() { for _ in 0..members.len() {
// this only runs if there's no match
// so don't change the representation of the stack
// contingencies will be handled by the binding forms
// (i.e., `let` and `match`)
// thus: emit Op::Pop directly
self.emit_op(Op::Pop); self.emit_op(Op::Pop);
} }
self.chunk.bytecode[before_load_tup_idx] = self.chunk.bytecode[before_load_tup_idx] =
@ -743,11 +702,6 @@ impl<'a> Compiler<'a> {
self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1; self.chunk.bytecode[idx] = self.len() as u8 - idx as u8 - 1;
} }
for _ in 0..members.len() { for _ in 0..members.len() {
// this only runs if there's no match
// so don't change the representation of the stack
// contingencies will be handled by the binding forms
// (i.e., `let` and `match`)
// thus: emit Op::Pop directly
self.emit_op(Op::Pop); self.emit_op(Op::Pop);
} }
self.chunk.bytecode[before_load_list_idx] = self.chunk.bytecode[before_load_list_idx] =
@ -766,15 +720,10 @@ impl<'a> Compiler<'a> {
let (PairPattern(key, pattern), _) = pair else { let (PairPattern(key, pattern), _) = pair else {
unreachable!() unreachable!()
}; };
// algo:
// push the keyword onto the stack
self.emit_constant(Value::Keyword(key)); self.emit_constant(Value::Keyword(key));
// pull the value out of the dict
self.emit_op(Op::LoadDictValue); self.emit_op(Op::LoadDictValue);
self.emit_byte(dict_stack_pos); self.emit_byte(dict_stack_pos);
// visit the pattern
self.visit(pattern); self.visit(pattern);
// jump if no match
self.emit_op(Op::JumpIfNoMatch); self.emit_op(Op::JumpIfNoMatch);
jump_idxes.push(self.len()); jump_idxes.push(self.len());
self.emit_byte(0xff); self.emit_byte(0xff);
@ -815,30 +764,14 @@ impl<'a> Compiler<'a> {
self.bind(name); self.bind(name);
} }
Dict(pairs) => { Dict(pairs) => {
println!("Compiling dict of len {}", pairs.len());
println!("Stack len: {}", self.stack_depth);
for pair in pairs { for pair in pairs {
self.visit(pair); self.visit(pair);
println!("Visited pair {:?}", pair);
println!("Current stack len: {}", self.stack_depth);
} }
self.emit_op(Op::PushDict); self.emit_op(Op::PushDict);
self.emit_byte(pairs.len()); self.emit_byte(pairs.len());
self.stack_depth = self.stack_depth + 1 - (pairs.len() * 2); self.stack_depth = self.stack_depth + 1 - (pairs.len() * 2);
println!(
"Finished compiling dict, stack len now: {}",
self.stack_depth
);
} }
Pair(key, value) => { Pair(key, value) => {
// let existing_kw = self.chunk.keywords.iter().position(|kw| kw == key);
// let kw_index = match existing_kw {
// Some(index) => index,
// None => self.chunk.keywords.len(),
// };
// if kw_index == self.chunk.keywords.len() {
// self.chunk.keywords.push(key);
// }
self.emit_constant(Value::Keyword(key)); self.emit_constant(Value::Keyword(key));
self.visit(value); self.visit(value);
} }
@ -905,10 +838,6 @@ impl<'a> Compiler<'a> {
self.stack_depth -= args.len() - 1; self.stack_depth -= args.len() - 1;
} }
None => { None => {
//algo
// visit all the args
// then store them
// then call the function
let arity = args.len(); let arity = args.len();
for arg in args { for arg in args {
self.visit(arg); self.visit(arg);

View File

@ -76,12 +76,12 @@ pub fn run(src: &'static str) {
pub fn main() { pub fn main() {
env::set_var("RUST_BACKTRACE", "1"); env::set_var("RUST_BACKTRACE", "1");
let src = " let src = "
let bar = 42
let foo = { let foo = {
let bar = :bar let (1, 2, 3) = (1, 2, 3)
fn baz () -> bar
} }
foo () foo
"; ";
run(src); run(src);
} }

View File

@ -6,24 +6,6 @@ use imbl::{HashMap, Vector};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
// #[derive(Clone, Debug, PartialEq)]
// pub struct Defined {
// pub name: &'static str,
// pub doc: Option<&'static str>,
// // pub enclosing: Vec<(usize, Value)>,
// // pub has_run: bool,
// // pub input: &'static str,
// // pub src: &'static str,
// pub chunks: Vec<(u8, Chunk)>,
// pub closed: Vec<Value>,
// }
// impl Defined {
// pub fn close(&mut self, val: Value) {
// self.closed.push(val);
// }
// }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum LFn { pub enum LFn {
Declared { Declared {
@ -162,7 +144,7 @@ impl std::fmt::Display for Value {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", ")
), ),
Box(value) => write!(f, "box {}", value.as_ref().borrow()), Box(value) => write!(f, "box {{ {} }}", value.as_ref().borrow()),
Fn(lfn) => write!(f, "fn {}", lfn.name()), Fn(lfn) => write!(f, "fn {}", lfn.name()),
BaseFn(_) => write!(f, "base fn"), BaseFn(_) => write!(f, "base fn"),
} }