From ae0955209cb288a5b99be78f6c36c6404b995655 Mon Sep 17 00:00:00 2001 From: Alex Bethel Date: Mon, 14 Jun 2021 16:19:56 -0500 Subject: [PATCH] Use pass-by-reference for variables, pass-by-value for expressions --- src/ast.rs | 6 +----- src/interpret.rs | 24 +++++++++++++++--------- src/parser.rs | 5 +---- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index dcc1d2f..835e679 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -70,11 +70,7 @@ pub enum StmtKind { }, Call { iden: Iden, - - // NOTE(Alex): Function arguments are Iden's, not Expr's, - // because they're passed by reference rather than by value - // and therefore need to be assignable. - args: Vec, + args: Vec, }, Print(Expr), Melo(Iden), diff --git a/src/interpret.rs b/src/interpret.rs index b81ac7c..bb4aa85 100644 --- a/src/interpret.rs +++ b/src/interpret.rs @@ -20,7 +20,7 @@ use std::{ use rand::random; use crate::{ - ast::{Expr, Iden, Stmt, StmtKind}, + ast::{Expr, ExprKind, Iden, Stmt, StmtKind}, base_55, error::{Error, ErrorKind}, variables::{Functio, Value, Variable}, @@ -286,16 +286,22 @@ impl ExecEnv { /// Call a function with the given arguments (i.e., actual /// parameters). If the function invocation fails for some reason, /// report the error at `span`. - fn fn_call( - &mut self, - func: Functio, - args: &[Iden], - span: &Range, - ) -> Result<(), Error> { + fn fn_call(&mut self, func: Functio, args: &[Expr], span: &Range) -> Result<(), Error> { + // Arguments that are ExprKind::Variable are pass by + // reference; all other expressions are pass by value. let args = args .iter() - .map(|arg| self.get_var_rc(arg)) - .collect::>>, Error>>()?; + .map(|arg| { + if let ExprKind::Variable(name) = &arg.kind { + self.get_var_rc(&Iden { + iden: name.to_owned(), + span: arg.span.clone(), + }) + } else { + self.eval_expr(arg).map(|v| Rc::new(RefCell::new(v))) + } + }) + .collect::, Error>>()?; match func { Functio::BfFunctio { diff --git a/src/parser.rs b/src/parser.rs index 3d8797a..53b4cee 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -469,10 +469,7 @@ impl<'source> Parser<'source> { } self.require(Token::Semicolon)?; - // Ok(StmtKind::Call { iden, args }) - - // `args` needs to be a vector of Idens now. ~~Alex - todo!() + Ok(StmtKind::Call { iden, args }) } /// Parse variable declaration