Use pass-by-reference for variables, pass-by-value for expressions

This commit is contained in:
Alex Bethel 2021-06-14 16:19:56 -05:00
parent 5ac9117651
commit 0e6bf2b27e
3 changed files with 17 additions and 18 deletions

View file

@ -70,11 +70,7 @@ pub enum StmtKind {
}, },
Call { Call {
iden: Iden, iden: Iden,
args: Vec<Expr>,
// 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<Iden>,
}, },
Print(Expr), Print(Expr),
Melo(Iden), Melo(Iden),

View file

@ -20,7 +20,7 @@ use std::{
use rand::random; use rand::random;
use crate::{ use crate::{
ast::{Expr, Iden, Stmt, StmtKind}, ast::{Expr, ExprKind, Iden, Stmt, StmtKind},
base_55, base_55,
error::{Error, ErrorKind}, error::{Error, ErrorKind},
variables::{Functio, Value, Variable}, variables::{Functio, Value, Variable},
@ -286,16 +286,22 @@ impl ExecEnv {
/// Call a function with the given arguments (i.e., actual /// Call a function with the given arguments (i.e., actual
/// parameters). If the function invocation fails for some reason, /// parameters). If the function invocation fails for some reason,
/// report the error at `span`. /// report the error at `span`.
fn fn_call( fn fn_call(&mut self, func: Functio, args: &[Expr], span: &Range<usize>) -> Result<(), Error> {
&mut self, // Arguments that are ExprKind::Variable are pass by
func: Functio, // reference; all other expressions are pass by value.
args: &[Iden],
span: &Range<usize>,
) -> Result<(), Error> {
let args = args let args = args
.iter() .iter()
.map(|arg| self.get_var_rc(arg)) .map(|arg| {
.collect::<Result<Vec<Rc<RefCell<Value>>>, Error>>()?; 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::<Result<Vec<_>, Error>>()?;
match func { match func {
Functio::BfFunctio { Functio::BfFunctio {

View file

@ -469,10 +469,7 @@ impl<'source> Parser<'source> {
} }
self.require(Token::Semicolon)?; self.require(Token::Semicolon)?;
// Ok(StmtKind::Call { iden, args }) Ok(StmtKind::Call { iden, args })
// `args` needs to be a vector of Idens now. ~~Alex
todo!()
} }
/// Parse variable declaration /// Parse variable declaration