1
0

Refine type checking and function calling

This commit is contained in:
Jeff 2023-12-17 19:06:36 -05:00
parent 70f0c6b887
commit 3bfedec5d6
5 changed files with 75 additions and 21 deletions

View File

@ -11,8 +11,8 @@ is_ready_to_solve = (fn cards <map>) <bool> {
} }
take_turn = (fn cards <map>, opponent_card <str>, current_room <str>) <map> { take_turn = (fn cards <map>, opponent_card <str>, current_room <str>) <map> {
cards = (remove_card opponent_card cards) cards = (remove_card cards opponent_card)
cards = (make_guess current_room cards) cards = (make_guess cards current_room)
cards cards
} }
@ -23,7 +23,7 @@ remove_card = (fn cards <map>, opponent_card <str>) <map> {
cards cards
} }
make_guess = (fn cards <map> current_room <str>) <map> { make_guess = (fn cards <map>, current_room <str>) <map> {
if (is_ready_to_solve cards) { if (is_ready_to_solve cards) {
(output 'It was ' (output 'It was '
+ cards:suspects:0 + cards:suspects:0

View File

@ -102,7 +102,15 @@ impl AbstractTree for FunctionCall {
Expression::Yield(r#yield) => r#yield.run(source, context)?, Expression::Yield(r#yield) => r#yield.run(source, context)?,
}; };
value.as_function()?.call(&self.arguments, source, context) let mut arguments = Vec::with_capacity(self.arguments.len());
for expression in &self.arguments {
let value = expression.run(source, context)?;
arguments.push(value);
}
value.as_function()?.call(&arguments, source, context)
} }
fn expected_type(&self, context: &Map) -> Result<Type> { fn expected_type(&self, context: &Map) -> Result<Type> {

View File

@ -50,19 +50,36 @@ impl AbstractTree for ValueNode {
} }
} }
let function_context = Map::clone_from(context)?;
for (parameter_name, parameter_type) in
parameters.iter().zip(parameter_types.iter())
{
function_context.set(
parameter_name.inner().clone(),
Value::Empty,
Some(parameter_type.clone()),
)?;
}
let return_type_node = child.child(child_count - 2).unwrap(); let return_type_node = child.child(child_count - 2).unwrap();
let return_type = let return_type =
TypeDefinition::from_syntax_node(source, return_type_node, context)?; TypeDefinition::from_syntax_node(source, return_type_node, context)?;
let body_node = child.child(child_count - 1).unwrap(); let body_node = child.child(child_count - 1).unwrap();
let body = Block::from_syntax_node(source, body_node, context)?; let body = Block::from_syntax_node(source, body_node, &function_context)?;
let r#type = Type::Function { let r#type = Type::Function {
parameter_types, parameter_types,
return_type: Box::new(return_type.take_inner()), return_type: Box::new(return_type.take_inner()),
}; };
ValueNode::Function(Function::new(parameters, body, Some(r#type))) ValueNode::Function(Function::new(
parameters,
body,
Some(r#type),
function_context,
))
} }
"integer" => ValueNode::Integer(source[child.byte_range()].to_string()), "integer" => ValueNode::Integer(source[child.byte_range()].to_string()),
"string" => { "string" => {

View File

@ -2,17 +2,23 @@ use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{AbstractTree, Block, Error, Expression, Identifier, Map, Result, Type, Value}; use crate::{AbstractTree, Block, Error, Identifier, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialOrd, Ord)]
pub struct Function { pub struct Function {
parameters: Vec<Identifier>, parameters: Vec<Identifier>,
body: Block, body: Block,
r#type: Type, r#type: Type,
context: Map,
} }
impl Function { impl Function {
pub fn new(parameters: Vec<Identifier>, body: Block, r#type: Option<Type>) -> Self { pub fn new(
parameters: Vec<Identifier>,
body: Block,
r#type: Option<Type>,
context: Map,
) -> Self {
let r#type = r#type.unwrap_or(Type::Function { let r#type = r#type.unwrap_or(Type::Function {
parameter_types: vec![Type::Any; parameters.len()], parameter_types: vec![Type::Any; parameters.len()],
return_type: Box::new(Type::Any), return_type: Box::new(Type::Any),
@ -22,6 +28,7 @@ impl Function {
parameters, parameters,
body, body,
r#type, r#type,
context,
} }
} }
@ -47,9 +54,7 @@ impl Function {
} }
} }
pub fn call(&self, arguments: &[Expression], source: &str, context: &Map) -> Result<Value> { pub fn call(&self, arguments: &[Value], source: &str, context: &Map) -> Result<Value> {
let function_context = Map::clone_from(context)?;
if self.parameters.len() != arguments.len() { if self.parameters.len() != arguments.len() {
return Err(Error::ExpectedArgumentAmount { return Err(Error::ExpectedArgumentAmount {
function_name: "", function_name: "",
@ -58,22 +63,37 @@ impl Function {
}); });
} }
let parameter_argument_pairs = self.parameters.iter().zip(arguments.iter()); for (key, (value, r#type)) in context.variables()?.iter() {
if self.context.variables()?.contains_key(key) {
continue;
}
for (identifier, expression) in parameter_argument_pairs { self.context
let value = expression.run(source, context)?; .set(key.clone(), value.clone(), Some(r#type.clone()))?;
let key = identifier.inner().clone();
function_context.set(key, value, None)?;
} }
let return_value = self.body.run(source, &function_context)?; let parameter_argument_pairs = self.parameters.iter().zip(arguments.iter());
for (identifier, value) in parameter_argument_pairs {
let key = identifier.inner().clone();
self.context.set(key, value.clone(), None)?;
}
let return_value = self.body.run(source, &self.context)?;
Ok(return_value) Ok(return_value)
} }
} }
impl PartialEq for Function {
fn eq(&self, other: &Self) -> bool {
self.r#type.eq(&other.r#type)
&& self.parameters.eq(&other.parameters)
&& self.body.eq(&other.body)
}
}
impl Display for Function { impl Display for Function {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!( write!(

View File

@ -1,4 +1,4 @@
use serde::{ser::SerializeMap, Serialize}; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize};
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
collections::BTreeMap, collections::BTreeMap,
@ -120,3 +120,12 @@ impl Serialize for Map {
map.end() map.end()
} }
} }
impl<'de> Deserialize<'de> for Map {
fn deserialize<D>(_deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
todo!()
}
}