diff --git a/src/ast/nodes.rs b/src/ast/nodes.rs index 31fe040..b1ccd1f 100644 --- a/src/ast/nodes.rs +++ b/src/ast/nodes.rs @@ -115,15 +115,23 @@ pub enum UntypedKind { then_br: Box>, else_br: Option>>, }, - // CLOSURE SUPPORT + // DEFINITION (new) + Def { + name: Arc, + value: Box>, + }, Lambda { params: Vec>, - body: Arc>, // Arc for cheap cloning into closure + body: Arc>, }, Call { callee: Box>, args: Vec>, }, + // BLOCK (do ...) to evaluate multiple expressions + Block { + exprs: Vec>, + }, Extension(Box), } @@ -148,19 +156,32 @@ impl Node { } else { Ok(Value::Void) } - } - - // --- CLOSURE IMPLEMENTATION --- + }, + + // --- DEF (Assignment) --- + UntypedKind::Def { name, value } => { + let val = value.eval(ctx)?; + let mut scope = ctx.scope.lock().unwrap(); + scope.define(name, val.clone()); + Ok(val) // Return value of definition + }, + + // --- BLOCK (do) --- + UntypedKind::Block { exprs } => { + let mut last_val = Value::Void; + for expr in exprs { + last_val = expr.eval(ctx)?; + } + Ok(last_val) + }, + UntypedKind::Lambda { params, body } => { let captured_scope = ctx.scope.clone(); let params = params.clone(); let body = body.clone(); Ok(Value::Function(Arc::new(move |args| { - // 1. New Scope with captured parent let mut new_scope = Scope::new(Some(captured_scope.clone())); - - // 2. Bind Args for (i, param) in params.iter().enumerate() { if i < args.len() { new_scope.define(param, args[i].clone()); @@ -168,10 +189,6 @@ impl Node { new_scope.define(param, Value::Void); } } - - // 3. Eval Body - // Note: We swallow errors here because Value::Function signature is simple. - // In a full VM, we'd return Result. let mut sub_ctx = Context { scope: Arc::new(Mutex::new(new_scope)) }; body.eval(&mut sub_ctx).unwrap_or(Value::Void) }))) @@ -179,17 +196,15 @@ impl Node { UntypedKind::Call { callee, args } => { let func_val = callee.eval(ctx)?; - let mut eval_args = Vec::with_capacity(args.len()); for arg in args { eval_args.push(arg.eval(ctx)?); } - match func_val { Value::Function(f) => Ok(f(eval_args)), _ => Err(format!("Attempt to call a non-function value: {}", func_val)), } - } + }, UntypedKind::Extension(ext) => ext.eval(self, ctx), } diff --git a/src/ast/parser.rs b/src/ast/parser.rs index 44066e7..6d39127 100644 --- a/src/ast/parser.rs +++ b/src/ast/parser.rs @@ -75,15 +75,15 @@ impl<'a> Parser<'a> { return Err(format!("Empty list () is not a valid expression at {:?}", start_loc)); } - // Peek at head to check for special forms - // We parse the first expression to check if it's an identifier "if", "fn", etc. let head = self.parse_expression()?; let result = if let UntypedKind::Identifier(name) = &head.kind { match name.as_ref() { "if" => self.parse_if(identity), "fn" => self.parse_fn(identity), - _ => self.parse_call(head, identity), // Pass head + identity + "def" => self.parse_def(identity), + "do" => self.parse_do(identity), + _ => self.parse_call(head, identity), } } else { self.parse_call(head, identity) @@ -94,7 +94,6 @@ impl<'a> Parser<'a> { } fn parse_if(&mut self, identity: Identity) -> Result, String> { - // 'if' was already consumed as head let cond = Box::new(self.parse_expression()?); let then_br = Box::new(self.parse_expression()?); let mut else_br = None; @@ -109,8 +108,34 @@ impl<'a> Parser<'a> { }) } + fn parse_def(&mut self, identity: Identity) -> Result, String> { + // (def name value) + let name_node = self.parse_expression()?; + let name = match name_node.kind { + UntypedKind::Identifier(s) => s, + _ => return Err("Expected identifier for def name".to_string()), + }; + + let value = Box::new(self.parse_expression()?); + + Ok(Node { + identity, + kind: UntypedKind::Def { name, value }, + }) + } + + fn parse_do(&mut self, identity: Identity) -> Result, String> { + let mut exprs = Vec::new(); + while *self.peek() != TokenKind::RightParen && *self.peek() != TokenKind::EOF { + exprs.push(self.parse_expression()?); + } + Ok(Node { + identity, + kind: UntypedKind::Block { exprs }, + }) + } + fn parse_fn(&mut self, identity: Identity) -> Result, String> { - // 'fn' was consumed. Next must be [params] vector. let params = self.parse_param_vector()?; let body = self.parse_expression()?; @@ -157,14 +182,10 @@ impl<'a> Parser<'a> { fn parse_vector_literal(&mut self) -> Result, String> { let token = self.advance()?; // consume '[' let mut elements = Vec::new(); - - // Temporary evaluation context for literals let mut temp_ctx = Context::new(); while *self.peek() != TokenKind::RightBracket && *self.peek() != TokenKind::EOF { let expr = self.parse_expression()?; - // Simple direct eval for literals inside vectors (e.g. [1 2 3]) - // In a full compiler, we would return a VectorNode here instead of evaluating immediately. match expr.eval(&mut temp_ctx) { Ok(val) => elements.push(val), Err(e) => return Err(format!("Vector literal error: {}", e)),