Implement function calls
This commit is contained in:
parent
eba12b13a3
commit
e272d99bae
@ -22,14 +22,34 @@ impl FunctionCall {
|
||||
|
||||
impl AbstractTree for FunctionCall {
|
||||
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||
todo!()
|
||||
if let Type::Function { return_type, .. } = self.function.expected_type(_context)? {
|
||||
Ok(*return_type)
|
||||
} else {
|
||||
Err(ValidationError::ExpectedFunction)
|
||||
}
|
||||
}
|
||||
|
||||
fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
|
||||
todo!()
|
||||
if let Type::Function { .. } = self.function.expected_type(_context)? {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ValidationError::ExpectedFunction)
|
||||
}
|
||||
}
|
||||
|
||||
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
|
||||
todo!()
|
||||
let value = self.function.run(_context)?.as_value()?;
|
||||
let function = value.as_function()?;
|
||||
let mut arguments = Vec::with_capacity(self.arguments.len());
|
||||
|
||||
for expression in self.arguments {
|
||||
let value = expression.run(_context)?.as_value()?;
|
||||
|
||||
arguments.push(value);
|
||||
}
|
||||
|
||||
let function_context = Context::new();
|
||||
|
||||
function.call(arguments, function_context)
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,14 @@ pub enum Action {
|
||||
}
|
||||
|
||||
impl Action {
|
||||
pub fn as_value(self) -> Result<Value, ValidationError> {
|
||||
match self {
|
||||
Action::Break(value) => Ok(value),
|
||||
Action::Return(value) => Ok(value),
|
||||
Action::None => Err(ValidationError::ExpectedValue),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_return_value(self) -> Result<Value, ValidationError> {
|
||||
if let Action::Return(value) = self {
|
||||
Ok(value)
|
||||
|
@ -88,6 +88,8 @@ impl Error {
|
||||
ValidationError::CannotIndex(_) => todo!(),
|
||||
ValidationError::CannotIndexWith(_, _) => todo!(),
|
||||
ValidationError::InterpreterExpectedReturn => todo!(),
|
||||
ValidationError::ExpectedFunction => todo!(),
|
||||
ValidationError::ExpectedValue => todo!(),
|
||||
}
|
||||
|
||||
report.finish()
|
||||
@ -143,7 +145,9 @@ pub enum ValidationError {
|
||||
CannotIndex(Type),
|
||||
CannotIndexWith(Type, Type),
|
||||
ExpectedBoolean,
|
||||
ExpectedFunction,
|
||||
ExpectedIntegerOrFloat,
|
||||
ExpectedValue,
|
||||
InterpreterExpectedReturn,
|
||||
RwLockPoison(RwLockPoisonError),
|
||||
TypeCheck(TypeCheckError),
|
||||
|
33
src/value.rs
33
src/value.rs
@ -13,7 +13,7 @@ use stanza::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
abstract_tree::{Action, Identifier, Statement, Type},
|
||||
abstract_tree::{AbstractTree, Action, Identifier, Statement, Type},
|
||||
context::Context,
|
||||
error::{RuntimeError, ValidationError},
|
||||
};
|
||||
@ -129,6 +129,14 @@ impl Value {
|
||||
Err(ValidationError::ExpectedBoolean)
|
||||
}
|
||||
|
||||
pub fn as_function(&self) -> Result<&Function, ValidationError> {
|
||||
if let ValueInner::Function(function) = self.0.as_ref() {
|
||||
return Ok(function);
|
||||
}
|
||||
|
||||
Err(ValidationError::ExpectedFunction)
|
||||
}
|
||||
|
||||
pub fn as_list(&self) -> Option<&Vec<Value>> {
|
||||
if let ValueInner::List(list) = self.inner().as_ref() {
|
||||
Some(list)
|
||||
@ -338,6 +346,25 @@ pub enum Function {
|
||||
BuiltIn(BuiltInFunction),
|
||||
}
|
||||
|
||||
impl Function {
|
||||
pub fn call(&self, arguments: Vec<Value>, context: Context) -> Result<Action, RuntimeError> {
|
||||
let action = match self {
|
||||
Function::Parsed(ParsedFunction {
|
||||
parameters, body, ..
|
||||
}) => {
|
||||
for ((identifier, _), value) in parameters.into_iter().zip(arguments.into_iter()) {
|
||||
context.set_value(identifier.clone(), value)?;
|
||||
}
|
||||
|
||||
body.clone().run(&context)?
|
||||
}
|
||||
Function::BuiltIn(built_in_function) => built_in_function.call(arguments, &context)?,
|
||||
};
|
||||
|
||||
Ok(action)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub struct ParsedFunction {
|
||||
parameters: Vec<(Identifier, Type)>,
|
||||
@ -368,10 +395,10 @@ impl BuiltInFunction {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call(self, value: Value, _context: &Context) -> Result<Action, RuntimeError> {
|
||||
pub fn call(&self, arguments: Vec<Value>, _context: &Context) -> Result<Action, RuntimeError> {
|
||||
match self {
|
||||
BuiltInFunction::Output => {
|
||||
println!("{value}");
|
||||
println!("{}", arguments[0]);
|
||||
|
||||
Ok(Action::None)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user