1
0

Begin new type checking system

This commit is contained in:
Jeff 2023-11-21 13:42:47 -05:00
parent 60ba9853ed
commit 8db95b237c
11 changed files with 12388 additions and 11826 deletions

View File

@ -68,7 +68,7 @@ impl AbstractTree for FunctionCall {
let parameter_expression_pairs = parameters.iter().zip(arguments.iter()); let parameter_expression_pairs = parameters.iter().zip(arguments.iter());
let mut variables = function_context.variables_mut()?; let mut variables = function_context.variables_mut()?;
for (identifier, expression) in parameter_expression_pairs { for ((identifier, _type), expression) in parameter_expression_pairs {
let key = identifier.clone().take_inner(); let key = identifier.clone().take_inner();
let value = expression.run(source, context)?; let value = expression.run(source, context)?;

View File

@ -26,6 +26,7 @@ pub mod remove;
pub mod select; pub mod select;
pub mod statement; pub mod statement;
pub mod transform; pub mod transform;
pub mod r#type;
pub mod r#use; pub mod r#use;
pub mod value_node; pub mod value_node;
pub mod r#while; pub mod r#while;
@ -34,8 +35,8 @@ pub mod r#yield;
pub use { pub use {
assignment::*, block::*, built_in_function::*, expression::*, filter::*, find::*, assignment::*, block::*, built_in_function::*, expression::*, filter::*, find::*,
function_call::*, identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, function_call::*, identifier::*, if_else::*, index::*, index_assignment::IndexAssignment,
insert::*, logic::*, math::*, r#for::*, r#match::*, r#use::*, r#while::*, r#yield::*, insert::*, logic::*, math::*, r#for::*, r#match::*, r#type::*, r#use::*, r#while::*,
remove::*, select::*, statement::*, transform::*, value_node::*, r#yield::*, remove::*, select::*, statement::*, transform::*, value_node::*,
}; };
use tree_sitter::Node; use tree_sitter::Node;

56
src/abstract_tree/type.rs Normal file
View File

@ -0,0 +1,56 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Error, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub enum Type {
Boolean,
Float,
Function,
Integer,
List,
Map,
String,
Table,
}
impl AbstractTree for Type {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
Error::expect_syntax_node(source, "type", node)?;
let r#type = match &source[node.byte_range()] {
"bool" => Type::Boolean,
"float" => Type::Float,
"fn" => Type::Function,
"int" => Type::Integer,
"list" => Type::List,
"map" => Type::Map,
"string" => Type::String,
"table" => Type::Table,
_ => {
return Err(Error::UnexpectedSyntaxNode {
expected: "bool, fn, int, list, map, string or table",
actual: node.kind(),
location: node.start_position(),
relevant_source: source[node.byte_range()].to_string(),
})
}
};
Ok(r#type)
}
fn run(&self, _source: &str, _context: &mut Map) -> Result<Value> {
match self {
Type::Boolean => Ok(Value::String("bool".to_string())),
Type::Float => Ok(Value::String("float".to_string())),
Type::Function => Ok(Value::String("fn".to_string())),
Type::Integer => Ok(Value::String("int".to_string())),
Type::List => Ok(Value::String("list".to_string())),
Type::Map => Ok(Value::String("map".to_string())),
Type::String => Ok(Value::String("string".to_string())),
Type::Table => Ok(Value::String("table".to_string())),
}
}
}

View File

@ -5,7 +5,7 @@ use tree_sitter::Node;
use crate::{ use crate::{
AbstractTree, Block, Error, Expression, Function, Identifier, List, Map, Result, Statement, AbstractTree, Block, Error, Expression, Function, Identifier, List, Map, Result, Statement,
Table, Value, ValueType, Table, Type, Value, ValueType,
}; };
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
@ -91,26 +91,35 @@ impl AbstractTree for ValueNode {
ValueType::Map(child_nodes) ValueType::Map(child_nodes)
} }
"function" => { "function" => {
let parameters_node = child.child_by_field_name("parameters");
let parameters = if let Some(node) = parameters_node {
let mut parameter_list = Vec::new(); let mut parameter_list = Vec::new();
let mut index = 0;
for index in 0..node.child_count() { while index < node.child_count() {
let child_node = node.child(index).unwrap(); let current_node = node.child(index).unwrap();
let next_node = node.child(index + 1);
if child_node.is_named() { if current_node.kind() == "identifier" {
let parameter = Identifier::from_syntax_node(source, child_node)?; let parameter = Identifier::from_syntax_node(source, current_node)?;
parameter_list.push(parameter); if let Some(next_node) = next_node {
if next_node.kind() == "type_definition" {
let r#type = Type::from_syntax_node(source, next_node)?;
parameter_list.push((parameter, r#type));
}
} }
} }
Some(parameter_list) index += 2
} else { }
None
};
let body_node = child.child_by_field_name("body").unwrap(); let body_node = child.child_by_field_name("body").unwrap();
let body = Block::from_syntax_node(source, body_node)?; let body = Block::from_syntax_node(source, body_node)?;
let parameters = if parameter_list.is_empty() {
None
} else {
Some(parameter_list)
};
ValueType::Function(Function::new(parameters, body)) ValueType::Function(Function::new(parameters, body))
} }

View File

@ -2,23 +2,23 @@ use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{Block, Identifier}; use crate::{Block, Identifier, Type};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Function { pub struct Function {
parameters: Option<Vec<Identifier>>, parameters: Option<Vec<(Identifier, Type)>>,
body: Box<Block>, body: Box<Block>,
} }
impl Function { impl Function {
pub fn new(parameters: Option<Vec<Identifier>>, body: Block) -> Self { pub fn new(parameters: Option<Vec<(Identifier, Type)>>, body: Block) -> Self {
Function { Function {
parameters, parameters,
body: Box::new(body), body: Box::new(body),
} }
} }
pub fn identifiers(&self) -> &Option<Vec<Identifier>> { pub fn identifiers(&self) -> &Option<Vec<(Identifier, Type)>> {
&self.parameters &self.parameters
} }

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},
Function, List, Map, Table, ValueType, Function, List, Map, Table, Type, ValueType,
}; };
use serde::{ use serde::{
@ -44,6 +44,20 @@ pub enum Value {
} }
impl Value { impl Value {
pub fn r#type(&self) -> Type {
match self {
Value::List(_) => Type::List,
Value::Map(_) => Type::Map,
Value::Table(_) => Type::Table,
Value::Function(_) => Type::Function,
Value::String(_) => Type::String,
Value::Float(_) => Type::Float,
Value::Integer(_) => todo!(),
Value::Boolean(_) => todo!(),
Value::Empty => todo!(),
}
}
pub fn value_type(&self) -> ValueType { pub fn value_type(&self) -> ValueType {
ValueType::from(self) ValueType::from(self)
} }

View File

@ -62,7 +62,7 @@ Function Call
Complex Function Complex Function
================================================================================ ================================================================================
|message number| => { |message:str number:int| => {
(output message) (output message)
(output number) (output number)
} }
@ -74,9 +74,10 @@ Complex Function
(expression (expression
(value (value
(function (function
(identifier_list
(identifier) (identifier)
(identifier)) (type_definition)
(identifier)
(type_definition)
(block (block
(statement (statement
(expression (expression

View File

@ -39,16 +39,6 @@ module.exports = grammar({
optional(';'), optional(';'),
)), )),
return: $ => seq(
'return',
$.expression,
),
use: $ => seq(
'use',
$.string,
),
expression: $ => prec.right(choice( expression: $ => prec.right(choice(
$._expression_kind, $._expression_kind,
seq('(', $._expression_kind, ')'), seq('(', $._expression_kind, ')'),
@ -258,8 +248,37 @@ module.exports = grammar({
$.expression, $.expression,
)), )),
return: $ => seq(
'return',
$.expression,
),
use: $ => seq(
'use',
$.string,
),
type_definition: $ => choice(
'bool',
'fn',
'int',
'list',
'map',
'str',
'table',
),
function: $ => seq( function: $ => seq(
field('parameters', optional($.identifier_list)), optional(seq(
'|',
field('parameter', repeat(seq(
$.identifier,
':',
$.type_definition,
optional(',')
))),
'|',
)),
'=>', '=>',
field('body', $.block), field('body', $.block),
), ),

View File

@ -123,32 +123,6 @@
] ]
} }
}, },
"return": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "return"
},
{
"type": "SYMBOL",
"name": "expression"
}
]
},
"use": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "use"
},
{
"type": "SYMBOL",
"name": "string"
}
]
},
"expression": { "expression": {
"type": "PREC_RIGHT", "type": "PREC_RIGHT",
"value": 0, "value": 0,
@ -1073,24 +1047,124 @@
] ]
} }
}, },
"return": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "return"
},
{
"type": "SYMBOL",
"name": "expression"
}
]
},
"use": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "use"
},
{
"type": "SYMBOL",
"name": "string"
}
]
},
"type_definition": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "bool"
},
{
"type": "STRING",
"value": "fn"
},
{
"type": "STRING",
"value": "int"
},
{
"type": "STRING",
"value": "list"
},
{
"type": "STRING",
"value": "map"
},
{
"type": "STRING",
"value": "str"
},
{
"type": "STRING",
"value": "table"
}
]
},
"function": { "function": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "FIELD",
"name": "parameters",
"content": {
"type": "CHOICE", "type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "FIELD",
"name": "parameter",
"content": {
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "identifier_list" "name": "identifier"
},
{
"type": "STRING",
"value": ":"
},
{
"type": "SYMBOL",
"name": "type_definition"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
}, },
{ {
"type": "BLANK" "type": "BLANK"
} }
] ]
} }
]
}
}
},
{
"type": "STRING",
"value": "|"
}
]
},
{
"type": "BLANK"
}
]
}, },
{ {
"type": "STRING", "type": "STRING",

View File

@ -172,12 +172,24 @@
} }
] ]
}, },
"parameters": { "parameter": {
"multiple": false, "multiple": true,
"required": false, "required": false,
"types": [ "types": [
{ {
"type": "identifier_list", "type": ",",
"named": false
},
{
"type": ":",
"named": false
},
{
"type": "identifier",
"named": true
},
{
"type": "type_definition",
"named": true "named": true
} }
] ]
@ -549,6 +561,11 @@
] ]
} }
}, },
{
"type": "type_definition",
"named": true,
"fields": {}
},
{ {
"type": "use", "type": "use",
"named": true, "named": true,
@ -769,6 +786,10 @@
"type": "bash", "type": "bash",
"named": false "named": false
}, },
{
"type": "bool",
"named": false
},
{ {
"type": "columns", "type": "columns",
"named": false "named": false
@ -801,6 +822,10 @@
"type": "float", "type": "float",
"named": true "named": true
}, },
{
"type": "fn",
"named": false
},
{ {
"type": "for", "type": "for",
"named": false "named": false
@ -833,6 +858,10 @@
"type": "insert", "type": "insert",
"named": false "named": false
}, },
{
"type": "int",
"named": false
},
{ {
"type": "integer", "type": "integer",
"named": true "named": true
@ -845,6 +874,14 @@
"type": "length", "type": "length",
"named": false "named": false
}, },
{
"type": "list",
"named": false
},
{
"type": "map",
"named": false
},
{ {
"type": "match", "type": "match",
"named": false "named": false
@ -909,6 +946,10 @@
"type": "sh", "type": "sh",
"named": false "named": false
}, },
{
"type": "str",
"named": false
},
{ {
"type": "string", "type": "string",
"named": true "named": true

File diff suppressed because it is too large Load Diff