Extract ast::Call

This commit is contained in:
numzero 2025-04-19 12:34:38 +03:00
parent eb51dd2702
commit 38659d86aa
3 changed files with 24 additions and 23 deletions

View File

@ -6,10 +6,7 @@ pub enum Statement {
target: Location,
source: Box<Expression>,
},
Call {
callee: Ident,
args: Vec<Expression>,
},
Call(Call),
Local {
name: Ident,
init: Option<Box<Expression>>,
@ -31,13 +28,16 @@ pub enum Location {
pub enum Expression {
Constant(Constant),
Variable(Location),
Call {
callee: Ident,
args: Vec<Expression>,
},
Call(Call),
Function(Function),
}
#[derive(Debug, Clone)]
pub struct Call {
pub callee: Ident,
pub args: Vec<Expression>,
}
#[derive(Debug, Clone, Default)]
pub struct Function {
pub name: Option<Ident>,

View File

@ -1,7 +1,7 @@
use std::{collections::HashMap, fmt::Debug, rc::Rc};
use crate::{
ast::{Constant, Expression, Location, Statement},
ast::{Call, Constant, Expression, Location, Statement},
types::{Value, ValueInner},
};
@ -91,18 +91,23 @@ impl Eval for Location {
}
}
impl Eval for Call {
fn eval(&self, scope: &mut Scope) -> Value {
let Self { callee, args } = self;
let Some(function) = scope.functions.get(callee.as_str()).cloned() else {
panic!("attempt to call non-existent function {callee}")
};
let args = args.iter().map(|arg| arg.eval(scope)).collect();
(function.inner)(scope, args)
}
}
impl Eval for Expression {
fn eval(&self, scope: &mut Scope) -> Value {
match self {
Expression::Constant(inner) => inner.eval(scope),
Expression::Variable(inner) => inner.eval(scope),
Expression::Call { callee, args } => {
let Some(function) = scope.functions.get(callee.as_str()).cloned() else {
panic!("attempt to call non-existent function {callee}")
};
let args = args.iter().map(|arg| arg.eval(scope)).collect();
(function.inner)(scope, args)
}
Expression::Call(inner) => inner.eval(scope),
Expression::Function { .. } => todo!(),
}
}
@ -134,12 +139,8 @@ impl Exec for Statement {
}
};
}
Statement::Call { callee, args } => {
Expression::Call {
callee: callee.clone(),
args: args.clone(),
}
.eval(scope);
Statement::Call(call) => {
call.eval(scope);
}
Statement::Local { .. } => todo!(),
}

View File

@ -149,7 +149,7 @@ fn build_in_scope(parent: &BuildContext<'_>, code: &ast::Function) -> Function {
source: Box::new(build_expression(&scope, source)),
});
}
ast::Statement::Call { callee, args } => {
ast::Statement::Call(ast::Call { callee, args }) => {
body.push(Statement::Call(Call {
callee: Box::new(build_expression(
&scope,