Implement function calls
This commit is contained in:
parent
eba12b13a3
commit
e272d99bae
@ -22,14 +22,34 @@ impl FunctionCall {
|
|||||||
|
|
||||||
impl AbstractTree for FunctionCall {
|
impl AbstractTree for FunctionCall {
|
||||||
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
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> {
|
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> {
|
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 {
|
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> {
|
pub fn as_return_value(self) -> Result<Value, ValidationError> {
|
||||||
if let Action::Return(value) = self {
|
if let Action::Return(value) = self {
|
||||||
Ok(value)
|
Ok(value)
|
||||||
|
@ -88,6 +88,8 @@ impl Error {
|
|||||||
ValidationError::CannotIndex(_) => todo!(),
|
ValidationError::CannotIndex(_) => todo!(),
|
||||||
ValidationError::CannotIndexWith(_, _) => todo!(),
|
ValidationError::CannotIndexWith(_, _) => todo!(),
|
||||||
ValidationError::InterpreterExpectedReturn => todo!(),
|
ValidationError::InterpreterExpectedReturn => todo!(),
|
||||||
|
ValidationError::ExpectedFunction => todo!(),
|
||||||
|
ValidationError::ExpectedValue => todo!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
report.finish()
|
report.finish()
|
||||||
@ -143,7 +145,9 @@ pub enum ValidationError {
|
|||||||
CannotIndex(Type),
|
CannotIndex(Type),
|
||||||
CannotIndexWith(Type, Type),
|
CannotIndexWith(Type, Type),
|
||||||
ExpectedBoolean,
|
ExpectedBoolean,
|
||||||
|
ExpectedFunction,
|
||||||
ExpectedIntegerOrFloat,
|
ExpectedIntegerOrFloat,
|
||||||
|
ExpectedValue,
|
||||||
InterpreterExpectedReturn,
|
InterpreterExpectedReturn,
|
||||||
RwLockPoison(RwLockPoisonError),
|
RwLockPoison(RwLockPoisonError),
|
||||||
TypeCheck(TypeCheckError),
|
TypeCheck(TypeCheckError),
|
||||||
|
33
src/value.rs
33
src/value.rs
@ -13,7 +13,7 @@ use stanza::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
abstract_tree::{Action, Identifier, Statement, Type},
|
abstract_tree::{AbstractTree, Action, Identifier, Statement, Type},
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
};
|
};
|
||||||
@ -129,6 +129,14 @@ impl Value {
|
|||||||
Err(ValidationError::ExpectedBoolean)
|
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>> {
|
pub fn as_list(&self) -> Option<&Vec<Value>> {
|
||||||
if let ValueInner::List(list) = self.inner().as_ref() {
|
if let ValueInner::List(list) = self.inner().as_ref() {
|
||||||
Some(list)
|
Some(list)
|
||||||
@ -338,6 +346,25 @@ pub enum Function {
|
|||||||
BuiltIn(BuiltInFunction),
|
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)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct ParsedFunction {
|
pub struct ParsedFunction {
|
||||||
parameters: Vec<(Identifier, Type)>,
|
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 {
|
match self {
|
||||||
BuiltInFunction::Output => {
|
BuiltInFunction::Output => {
|
||||||
println!("{value}");
|
println!("{}", arguments[0]);
|
||||||
|
|
||||||
Ok(Action::None)
|
Ok(Action::None)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user