Continue type check implementation

This commit is contained in:
Jeff 2023-11-29 20:59:58 -05:00
parent bc2615a1ed
commit 081d349783
29 changed files with 7453 additions and 7193 deletions

View File

@ -1,4 +1,4 @@
fib = |i <int>| <int> { fib <fn int -> int> = |i| {
if i <= 1 { if i <= 1 {
1 1
} else { } else {

8
scripts/build_debug.fish Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/fish
# Build the project in debug mode.
cd tree-sitter-dust/
tree-sitter generate --debug-build --no-bindings
cd ..
cargo build

8
scripts/build_release.fish Executable file
View File

@ -0,0 +1,8 @@
#!/bin/fish
# Build the project in debug mode.
cd tree-sitter-dust/
tree-sitter generate --no-bindings
cd ..
cargo build --release

View File

@ -1,12 +1,12 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Identifier, Map, Result, Statement, TypeDefinition, Value}; use crate::{AbstractTree, Error, Identifier, Map, Result, Statement, Type, TypeDefintion, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Assignment { pub struct Assignment {
identifier: Identifier, identifier: Identifier,
r#type: Option<TypeDefinition>, type_definition: Option<TypeDefintion>,
operator: AssignmentOperator, operator: AssignmentOperator,
statement: Statement, statement: Statement,
} }
@ -26,8 +26,8 @@ impl AbstractTree for Assignment {
let identifier = Identifier::from_syntax_node(source, identifier_node)?; let identifier = Identifier::from_syntax_node(source, identifier_node)?;
let type_node = node.child_by_field_name("type"); let type_node = node.child_by_field_name("type");
let r#type = if let Some(type_node) = type_node { let type_definition = if let Some(type_node) = type_node {
Some(TypeDefinition::from_syntax_node(source, type_node)?) Some(TypeDefintion::from_syntax_node(source, type_node)?)
} else { } else {
None None
}; };
@ -56,7 +56,7 @@ impl AbstractTree for Assignment {
Ok(Assignment { Ok(Assignment {
identifier, identifier,
r#type, type_definition,
operator, operator,
statement, statement,
}) })
@ -66,6 +66,10 @@ impl AbstractTree for Assignment {
let key = self.identifier.inner(); let key = self.identifier.inner();
let value = self.statement.run(source, context)?; let value = self.statement.run(source, context)?;
if let Some(type_definition) = &self.type_definition {
type_definition.check(&value, context)?;
}
let new_value = match self.operator { let new_value = match self.operator {
AssignmentOperator::PlusEqual => { AssignmentOperator::PlusEqual => {
if let Some(mut previous_value) = context.variables()?.get(key).cloned() { if let Some(mut previous_value) = context.variables()?.get(key).cloned() {
@ -91,7 +95,7 @@ impl AbstractTree for Assignment {
Ok(Value::Empty) Ok(Value::Empty)
} }
fn expected_type(&self, _context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, _context: &Map) -> Result<Type> {
Ok(TypeDefinition::Empty) Ok(Type::Empty)
} }
} }

View File

@ -4,7 +4,7 @@ use rayon::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Map, Result, Statement, TypeDefinition, Value}; use crate::{AbstractTree, Error, Map, Result, Statement, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Block { pub struct Block {
@ -82,7 +82,7 @@ impl AbstractTree for Block {
} }
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
self.statements.last().unwrap().expected_type(context) self.statements.last().unwrap().expected_type(context)
} }
} }

View File

@ -2,8 +2,7 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{ use crate::{
value_node::ValueNode, AbstractTree, Error, Identifier, Index, Map, Result, TypeDefinition, value_node::ValueNode, AbstractTree, Error, Identifier, Index, Map, Result, Type, Value, Yield,
Value, Yield,
}; };
use super::{function_call::FunctionCall, logic::Logic, math::Math}; use super::{function_call::FunctionCall, logic::Logic, math::Math};
@ -64,7 +63,7 @@ impl AbstractTree for Expression {
} }
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
match self { match self {
Expression::Value(value_node) => value_node.expected_type(context), Expression::Value(value_node) => value_node.expected_type(context),
Expression::Identifier(identifier) => identifier.expected_type(context), Expression::Identifier(identifier) => identifier.expected_type(context),

View File

@ -2,9 +2,7 @@ use rayon::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{ use crate::{AbstractTree, Block, Error, Expression, Identifier, Map, Result, Type, Value};
AbstractTree, Block, Error, Expression, Identifier, Map, Result, TypeDefinition, Value,
};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct For { pub struct For {
@ -79,7 +77,7 @@ impl AbstractTree for For {
Ok(Value::Empty) Ok(Value::Empty)
} }
fn expected_type(&self, _context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, _context: &Map) -> Result<Type> {
Ok(TypeDefinition::Empty) Ok(Type::Empty)
} }
} }

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Map, Result, TypeDefinition, Value, BUILT_IN_FUNCTIONS}; use crate::{AbstractTree, Error, Map, Result, Type, Value, BUILT_IN_FUNCTIONS};
use super::expression::Expression; use super::expression::Expression;
@ -87,7 +87,7 @@ impl AbstractTree for FunctionCall {
function.run(source, &mut function_context) function.run(source, &mut function_context)
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
self.function.expected_type(context) self.function.expected_type(context)
} }
} }

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Map, Result, TypeDefinition, Value}; use crate::{AbstractTree, Error, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Identifier(String); pub struct Identifier(String);
@ -37,11 +37,11 @@ impl AbstractTree for Identifier {
} }
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
if let Some(value) = context.variables()?.get(&self.0) { if let Some(value) = context.variables()?.get(&self.0) {
Ok(value.r#type(context)?) Ok(value.r#type(context)?)
} else { } else {
Ok(TypeDefinition::Empty) Ok(Type::Empty)
} }
} }
} }

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Block, Expression, Map, Result, TypeDefinition, Value}; use crate::{AbstractTree, Block, Expression, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct IfElse { pub struct IfElse {
@ -81,7 +81,7 @@ impl AbstractTree for IfElse {
} }
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
self.if_block.expected_type(context) self.if_block.expected_type(context)
} }
} }

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Expression, List, Map, Result, TypeDefinition, Value}; use crate::{AbstractTree, Error, Expression, List, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Index { pub struct Index {
@ -74,7 +74,7 @@ impl AbstractTree for Index {
} }
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
self.collection.expected_type(context) self.collection.expected_type(context)
} }
} }
@ -100,7 +100,7 @@ mod tests {
#[test] #[test]
fn evaluate_complex_index() { fn evaluate_complex_index() {
let test = evaluate("x = [1 2 3]; y = || <int> { 0 } x:((y))").unwrap(); let test = evaluate("x = [1 2 3]; y = || { 0 } x:((y))").unwrap();
assert_eq!(Value::Integer(1), test); assert_eq!(Value::Integer(1), test);
} }

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Index, Map, Result, Statement, TypeDefinition, Value}; use crate::{AbstractTree, Error, Index, Map, Result, Statement, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct IndexAssignment { pub struct IndexAssignment {
@ -91,7 +91,7 @@ impl AbstractTree for IndexAssignment {
Ok(Value::Empty) Ok(Value::Empty)
} }
fn expected_type(&self, _context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, _context: &Map) -> Result<Type> {
Ok(TypeDefinition::Empty) Ok(Type::Empty)
} }
} }

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Expression, Map, Result, TypeDefinition, Value}; use crate::{AbstractTree, Error, Expression, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Logic { pub struct Logic {
@ -74,8 +74,8 @@ impl AbstractTree for Logic {
Ok(Value::Boolean(result)) Ok(Value::Boolean(result))
} }
fn expected_type(&self, _context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, _context: &Map) -> Result<Type> {
Ok(TypeDefinition::Boolean) Ok(Type::Boolean)
} }
} }

View File

@ -6,7 +6,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Map, Result, TypeDefinition, Value}; use crate::{AbstractTree, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Match {} pub struct Match {}
@ -20,7 +20,7 @@ impl AbstractTree for Match {
todo!() todo!()
} }
fn expected_type(&self, _context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, _context: &Map) -> Result<Type> {
todo!() todo!()
} }
} }

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Expression, Map, Result, TypeDefinition, Value}; use crate::{AbstractTree, Error, Expression, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Math { pub struct Math {
@ -56,8 +56,8 @@ impl AbstractTree for Math {
Ok(value) Ok(value)
} }
fn expected_type(&self, _context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, _context: &Map) -> Result<Type> {
Ok(TypeDefinition::Number) Ok(Type::Number)
} }
} }

View File

@ -66,7 +66,7 @@ impl AbstractTree for Root {
Ok(value) Ok(value)
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
self.statements.last().unwrap().expected_type(context) self.statements.last().unwrap().expected_type(context)
} }
} }
@ -88,5 +88,5 @@ pub trait AbstractTree: Sized {
/// Execute dust code by traversing the tree. /// Execute dust code by traversing the tree.
fn run(&self, source: &str, context: &Map) -> Result<Value>; fn run(&self, source: &str, context: &Map) -> Result<Value>;
fn expected_type(&self, context: &Map) -> Result<TypeDefinition>; fn expected_type(&self, context: &Map) -> Result<Type>;
} }

View File

@ -3,7 +3,7 @@ use tree_sitter::Node;
use crate::{ use crate::{
AbstractTree, Assignment, Block, Error, Expression, For, IfElse, IndexAssignment, Map, Match, AbstractTree, Assignment, Block, Error, Expression, For, IfElse, IndexAssignment, Map, Match,
Result, TypeDefinition, Use, Value, While, Result, Type, Use, Value, While,
}; };
/// Abstract representation of a statement. /// Abstract representation of a statement.
@ -82,7 +82,7 @@ impl AbstractTree for Statement {
} }
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
match self { match self {
Statement::Assignment(assignment) => assignment.expected_type(context), Statement::Assignment(assignment) => assignment.expected_type(context),
Statement::Return(expression) => expression.expected_type(context), Statement::Return(expression) => expression.expected_type(context),

View File

@ -6,129 +6,171 @@ use tree_sitter::Node;
use crate::{AbstractTree, Error, Map, Result, Value}; use crate::{AbstractTree, Error, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub enum TypeDefinition { pub struct TypeDefintion {
r#type: Type,
}
impl AbstractTree for TypeDefintion {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
Error::expect_syntax_node(source, "type_definition", node)?;
let type_node = node.child(1).unwrap();
let r#type = Type::from_syntax_node(source, type_node)?;
Ok(TypeDefintion { r#type })
}
fn run(&self, source: &str, context: &Map) -> Result<Value> {
self.r#type.run(source, context)
}
fn expected_type(&self, context: &Map) -> Result<Type> {
self.r#type.expected_type(context)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub enum Type {
Any, Any,
Boolean, Boolean,
Empty, Empty,
Float, Float,
Function { Function {
parameter_types: Vec<TypeDefinition>, parameter_types: Vec<Type>,
return_type: Box<TypeDefinition>, return_type: Box<Type>,
}, },
Integer, Integer,
List(Box<TypeDefinition>), List(Box<Type>),
Map, Map,
Number, Number,
String, String,
Table, Table,
} }
impl TypeDefinition { impl TypeDefintion {
// pub fn check(&self, value: &Value) -> Result<()> { pub fn check(&self, value: &Value, context: &Map) -> Result<()> {
// match (self, value.r#type()?) { match (&self.r#type, value) {
// (Type::Any, _) (Type::Any, _)
// | (Type::Boolean, Type::Boolean) | (Type::Boolean, Value::Boolean(_))
// | (Type::Empty, Type::Empty) | (Type::Empty, Value::Empty)
// | (Type::Float, Type::Float) | (Type::Float, Value::Float(_))
// | (Type::Integer, Type::Integer) | (Type::Integer, Value::Integer(_))
// | (Type::Map, Type::Map) | (Type::Map, Value::Map(_))
// | (Type::Number, Type::Number) | (Type::Number, Value::Integer(_))
// | (Type::Number, Type::Integer) | (Type::Number, Value::Float(_))
// | (Type::Number, Type::Float) | (Type::String, Value::String(_))
// | (Type::Integer, Type::Number) | (Type::Table, Value::Table(_)) => Ok(()),
// | (Type::Float, Type::Number) (Type::List(_), Value::List(list)) => {
// | (Type::String, Type::String) if let Some(first) = list.items().first() {
// | (Type::Table, Type::Table) => Ok(()), self.check(first, context)
// (Type::List(expected), Type::List(actual)) => { } else {
// if expected != &actual { Ok(())
// Err(Error::TypeCheck { }
// expected: Type::List(expected.clone()), }
// actual: value.clone(), (
// }) Type::Function {
// } else { parameter_types,
// Ok(()) return_type,
// } },
// } Value::Function(function),
// ( ) => {
// Type::Function { let parameter_type_count = parameter_types.len();
// parameter_types: left_parameters, let parameter_count = function.parameters().len();
// return_type: left_return,
// }, if parameter_type_count != parameter_count
// Type::Function { || return_type.as_ref() != &function.body().expected_type(context)?
// parameter_types: right_parameters, {
// return_type: right_return, return Err(Error::TypeCheck {
// }, expected: self.r#type.clone(),
// ) => { actual: value.clone(),
// if left_parameters != &right_parameters || left_return != &right_return { });
// Err(Error::TypeCheck { }
// expected: Type::Function {
// parameter_types: left_parameters.clone(), Ok(())
// return_type: left_return.clone(), }
// }, (Type::Boolean, _) => Err(Error::TypeCheck {
// actual: value.clone(), expected: Type::Boolean,
// }) actual: value.clone(),
// } else { }),
// Ok(()) (Type::Empty, _) => Err(Error::TypeCheck {
// } expected: Type::Empty,
// } actual: value.clone(),
// (Type::Boolean, _) => Err(Error::TypeCheck { }),
// expected: Type::Boolean, (Type::Float, _) => Err(Error::TypeCheck {
// actual: value.clone(), expected: Type::Float,
// }), actual: value.clone(),
// (Type::Empty, _) => Err(Error::TypeCheck { }),
// expected: Type::Empty, (Type::Function { .. }, _) => Err(Error::TypeCheck {
// actual: value.clone(), expected: self.r#type.clone(),
// }), actual: value.clone(),
// (Type::Float, _) => Err(Error::TypeCheck { }),
// expected: Type::Float, (Type::Integer, _) => Err(Error::TypeCheck {
// actual: value.clone(), expected: Type::Integer,
// }), actual: value.clone(),
// (expected, _) => Err(Error::TypeCheck { }),
// expected: expected.clone(), (Type::List(_), _) => Err(Error::TypeCheck {
// actual: value.clone(), expected: self.r#type.clone(),
// }), actual: value.clone(),
// (Type::Integer, _) => Err(Error::TypeCheck { }),
// expected: Type::Integer, (Type::Map, _) => Err(Error::TypeCheck {
// actual: value.clone(), expected: Type::Map,
// }), actual: value.clone(),
// (expected, _) => Err(Error::TypeCheck { }),
// expected: expected.clone(), (Type::Number, _) => Err(Error::TypeCheck {
// actual: value.clone(), expected: Type::Number,
// }), actual: value.clone(),
// (Type::Map, _) => Err(Error::TypeCheck { }),
// expected: Type::Map, (Type::String, _) => Err(Error::TypeCheck {
// actual: value.clone(), expected: Type::String,
// }), actual: value.clone(),
// (Type::String, _) => Err(Error::TypeCheck { }),
// expected: Type::String, (Type::Table, _) => Err(Error::TypeCheck {
// actual: value.clone(), expected: Type::Table,
// }), actual: value.clone(),
// (Type::Table, _) => Err(Error::TypeCheck { }),
// expected: Type::Table, }
// actual: value.clone(), }
// }),
// }
// }
} }
impl AbstractTree for TypeDefinition { impl AbstractTree for Type {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> { fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
Error::expect_syntax_node(source, "type_definition", node)?; Error::expect_syntax_node(source, "type", node)?;
let type_node = node.child(1).unwrap(); let type_node = node.child(0).unwrap();
let type_symbol = &source[type_node.byte_range()];
let r#type = match type_symbol { let r#type = match type_node.kind() {
"any" => TypeDefinition::Any, "any" => Type::Any,
"bool" => TypeDefinition::Boolean, "bool" => Type::Boolean,
"float" => TypeDefinition::Float, "float" => Type::Float,
"fn" => { "fn" => {
todo!() let child_count = node.child_count();
let mut parameter_types = Vec::new();
for index in 1..child_count - 2 {
let parameter_type_node = node.child(index).unwrap();
let parameter_type = Type::from_syntax_node(source, parameter_type_node)?;
parameter_types.push(parameter_type);
} }
"int" => TypeDefinition::Integer,
"map" => TypeDefinition::Map, let return_type_node = node.child(child_count - 1).unwrap();
"str" => TypeDefinition::String, let return_type = Type::from_syntax_node(source, return_type_node)?;
"table" => TypeDefinition::Table,
Type::Function {
parameter_types,
return_type: Box::new(return_type),
}
}
"int" => Type::Integer,
"list" => {
let item_type_node = node.child(1).unwrap();
let item_type = Type::from_syntax_node(source, item_type_node)?;
Type::List(Box::new(item_type))
}
"map" => Type::Map,
"str" => Type::String,
"table" => Type::Table,
_ => { _ => {
return Err(Error::UnexpectedSyntaxNode { return Err(Error::UnexpectedSyntaxNode {
expected: "any, bool, float, fn, int, list, map, str or table", expected: "any, bool, float, fn, int, list, map, str or table",
@ -146,25 +188,25 @@ impl AbstractTree for TypeDefinition {
Ok(Value::Empty) Ok(Value::Empty)
} }
fn expected_type(&self, _context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, _context: &Map) -> Result<Type> {
Ok(TypeDefinition::Empty) Ok(Type::Empty)
} }
} }
impl Display for TypeDefinition { impl Display for Type {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self { match self {
TypeDefinition::Any => write!(f, "any"), Type::Any => write!(f, "any"),
TypeDefinition::Boolean => write!(f, "bool"), Type::Boolean => write!(f, "bool"),
TypeDefinition::Empty => write!(f, "empty"), Type::Empty => write!(f, "empty"),
TypeDefinition::Float => write!(f, "float"), Type::Float => write!(f, "float"),
TypeDefinition::Function { .. } => write!(f, "function"), Type::Function { .. } => write!(f, "function"),
TypeDefinition::Integer => write!(f, "integer"), Type::Integer => write!(f, "integer"),
TypeDefinition::List(_) => write!(f, "list"), Type::List(_) => write!(f, "list"),
TypeDefinition::Map => write!(f, "map"), Type::Map => write!(f, "map"),
TypeDefinition::Number => write!(f, "number"), Type::Number => write!(f, "number"),
TypeDefinition::String => write!(f, "string"), Type::String => write!(f, "string"),
TypeDefinition::Table => write!(f, "table"), Type::Table => write!(f, "table"),
} }
} }
} }

View File

@ -2,7 +2,7 @@ use std::fs::read_to_string;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{evaluate_with_context, AbstractTree, Error, Map, Result, TypeDefinition, Value}; use crate::{evaluate_with_context, AbstractTree, Error, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Use { pub struct Use {
@ -30,7 +30,7 @@ impl AbstractTree for Use {
Ok(Value::Map(file_context)) Ok(Value::Map(file_context))
} }
fn expected_type(&self, _context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, _context: &Map) -> Result<Type> {
Ok(TypeDefinition::Map) Ok(Type::Map)
} }
} }

View File

@ -5,7 +5,7 @@ use tree_sitter::Node;
use crate::{ use crate::{
AbstractTree, Error, Expression, Function, Identifier, List, Map, Result, Statement, Table, AbstractTree, Error, Expression, Function, Identifier, List, Map, Result, Statement, Table,
TypeDefinition, Value, Type, Value,
}; };
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
@ -177,27 +177,27 @@ impl AbstractTree for ValueNode {
Ok(value) Ok(value)
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
let r#type = match self { let r#type = match self {
ValueNode::Boolean(_) => TypeDefinition::Boolean, ValueNode::Boolean(_) => Type::Boolean,
ValueNode::Float(_) => TypeDefinition::Float, ValueNode::Float(_) => Type::Float,
ValueNode::Integer(_) => TypeDefinition::Integer, ValueNode::Integer(_) => Type::Integer,
ValueNode::String(_) => TypeDefinition::String, ValueNode::String(_) => Type::String,
ValueNode::List(expressions) => { ValueNode::List(expressions) => {
let first_expression_type = if let Some(first) = expressions.first() { let first_expression_type = if let Some(first) = expressions.first() {
first.expected_type(context)? first.expected_type(context)?
} else { } else {
TypeDefinition::Empty Type::Empty
}; };
TypeDefinition::List(Box::new(first_expression_type)) Type::List(Box::new(first_expression_type))
} }
ValueNode::Empty => TypeDefinition::Any, ValueNode::Empty => Type::Any,
ValueNode::Map(_) => TypeDefinition::Map, ValueNode::Map(_) => Type::Map,
ValueNode::Table { ValueNode::Table {
column_names: _, column_names: _,
rows: _, rows: _,
} => TypeDefinition::Table, } => Type::Table,
ValueNode::Function(function) => function.expected_type(context)?, ValueNode::Function(function) => function.expected_type(context)?,
}; };

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Block, Expression, Map, Result, TypeDefinition, Value}; use crate::{AbstractTree, Block, Expression, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct While { pub struct While {
@ -30,7 +30,7 @@ impl AbstractTree for While {
Ok(Value::Empty) Ok(Value::Empty)
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
self.block.expected_type(context) self.block.expected_type(context)
} }
} }

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Expression, FunctionCall, Map, Result, TypeDefinition, Value}; use crate::{AbstractTree, Expression, FunctionCall, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Yield { pub struct Yield {
@ -39,7 +39,7 @@ impl AbstractTree for Yield {
self.call.run(source, context) self.call.run(source, context)
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
self.call.expected_type(context) self.call.expected_type(context)
} }
} }

View File

@ -5,7 +5,7 @@
use tree_sitter::{Node, Point}; use tree_sitter::{Node, Point};
use crate::{value::Value, Identifier, TypeDefinition}; use crate::{value::Value, Identifier, Type};
use std::{fmt, io, num::ParseFloatError, string::FromUtf8Error, sync::PoisonError, time}; use std::{fmt, io, num::ParseFloatError, string::FromUtf8Error, sync::PoisonError, time};
@ -21,7 +21,7 @@ pub enum Error {
}, },
TypeCheck { TypeCheck {
expected: TypeDefinition, expected: Type,
actual: Value, actual: Value,
}, },

View File

@ -35,7 +35,7 @@ struct Args {
show_syntax_tree: bool, show_syntax_tree: bool,
/// Launch in interactive mode. /// Launch in interactive mode.
#[arg(short, long)] #[arg(short = 'n', long)]
interactive: bool, interactive: bool,
/// Location of the file to run. /// Location of the file to run.

View File

@ -3,7 +3,7 @@ use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Block, Error, Identifier, Map, Result, TypeDefinition, 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, PartialEq, PartialOrd, Ord)]
pub struct Function { pub struct Function {
@ -28,7 +28,7 @@ impl AbstractTree for Function {
let child_count = node.child_count(); let child_count = node.child_count();
let mut parameters = Vec::new(); let mut parameters = Vec::new();
for index in 0..child_count { for index in 1..child_count - 2 {
let child = node.child(index).unwrap(); let child = node.child(index).unwrap();
if child.is_named() { if child.is_named() {
@ -49,7 +49,7 @@ impl AbstractTree for Function {
Ok(return_value) Ok(return_value)
} }
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> { fn expected_type(&self, context: &Map) -> Result<Type> {
self.body.expected_type(context) self.body.expected_type(context)
} }
} }

View File

@ -1,7 +1,7 @@
//! Types that represent runtime values. //! Types that represent runtime values.
use crate::{ use crate::{
error::{Error, Result}, error::{Error, Result},
AbstractTree, Function, List, Map, Table, TypeDefinition, AbstractTree, Function, List, Map, Table, Type,
}; };
use serde::{ use serde::{
@ -43,19 +43,19 @@ pub enum Value {
} }
impl Value { impl Value {
pub fn r#type(&self, context: &Map) -> Result<TypeDefinition> { pub fn r#type(&self, context: &Map) -> Result<Type> {
let r#type = match self { let r#type = match self {
Value::List(list) => { Value::List(list) => {
let first_item_type = if let Some(first) = list.items().first() { let first_item_type = if let Some(first) = list.items().first() {
first.r#type(context)? first.r#type(context)?
} else { } else {
TypeDefinition::Empty Type::Empty
}; };
TypeDefinition::List(Box::new(first_item_type)) Type::List(Box::new(first_item_type))
} }
Value::Map(_) => TypeDefinition::Map, Value::Map(_) => Type::Map,
Value::Table(_) => TypeDefinition::Table, Value::Table(_) => Type::Table,
Value::Function(function) => { Value::Function(function) => {
let parameter_types = Vec::new(); let parameter_types = Vec::new();
@ -65,16 +65,16 @@ impl Value {
let return_type = function.body().expected_type(context)?; let return_type = function.body().expected_type(context)?;
TypeDefinition::Function { Type::Function {
parameter_types, parameter_types,
return_type: Box::new(return_type), return_type: Box::new(return_type),
} }
} }
Value::String(_) => TypeDefinition::String, Value::String(_) => Type::String,
Value::Float(_) => TypeDefinition::Float, Value::Float(_) => Type::Float,
Value::Integer(_) => TypeDefinition::Integer, Value::Integer(_) => Type::Integer,
Value::Boolean(_) => TypeDefinition::Boolean, Value::Boolean(_) => Type::Boolean,
Value::Empty => TypeDefinition::Empty, Value::Empty => Type::Empty,
}; };
Ok(r#type) Ok(r#type)

View File

@ -1,20 +0,0 @@
find = |list function| => {
for i in list {
if (function i) {
return i
}
}
}
map = |list function| => {
new_list = []
for i in list {
new_list += (function i)
}
new_list
}
[0 1 2] -> (map |i| => { i - 1})
-> (find |i| => { i == 1 })

View File

@ -1080,8 +1080,25 @@
{ {
"type": "REPEAT", "type": "REPEAT",
"content": { "content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL", "type": "SYMBOL",
"name": "type" "name": "type"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
} }
}, },
{ {

File diff suppressed because it is too large Load Diff