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 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 value = expression.run(source, context)?;

View File

@ -26,6 +26,7 @@ pub mod remove;
pub mod select;
pub mod statement;
pub mod transform;
pub mod r#type;
pub mod r#use;
pub mod value_node;
pub mod r#while;
@ -34,8 +35,8 @@ pub mod r#yield;
pub use {
assignment::*, block::*, built_in_function::*, expression::*, filter::*, find::*,
function_call::*, identifier::*, if_else::*, index::*, index_assignment::IndexAssignment,
insert::*, logic::*, math::*, r#for::*, r#match::*, r#use::*, r#while::*, r#yield::*,
remove::*, select::*, statement::*, transform::*, value_node::*,
insert::*, logic::*, math::*, r#for::*, r#match::*, r#type::*, r#use::*, r#while::*,
r#yield::*, remove::*, select::*, statement::*, transform::*, value_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::{
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)]
@ -91,26 +91,35 @@ impl AbstractTree for ValueNode {
ValueType::Map(child_nodes)
}
"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() {
let child_node = node.child(index).unwrap();
while index < node.child_count() {
let current_node = node.child(index).unwrap();
let next_node = node.child(index + 1);
if child_node.is_named() {
let parameter = Identifier::from_syntax_node(source, child_node)?;
if current_node.kind() == "identifier" {
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)
} else {
None
};
index += 2
}
let body_node = child.child_by_field_name("body").unwrap();
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))
}

View File

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

View File

@ -1,7 +1,7 @@
//! Types that represent runtime values.
use crate::{
error::{Error, Result},
Function, List, Map, Table, ValueType,
Function, List, Map, Table, Type, ValueType,
};
use serde::{
@ -44,6 +44,20 @@ pub enum 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 {
ValueType::from(self)
}

View File

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

View File

@ -39,16 +39,6 @@ module.exports = grammar({
optional(';'),
)),
return: $ => seq(
'return',
$.expression,
),
use: $ => seq(
'use',
$.string,
),
expression: $ => prec.right(choice(
$._expression_kind,
seq('(', $._expression_kind, ')'),
@ -258,8 +248,37 @@ module.exports = grammar({
$.expression,
)),
return: $ => seq(
'return',
$.expression,
),
use: $ => seq(
'use',
$.string,
),
type_definition: $ => choice(
'bool',
'fn',
'int',
'list',
'map',
'str',
'table',
),
function: $ => seq(
field('parameters', optional($.identifier_list)),
optional(seq(
'|',
field('parameter', repeat(seq(
$.identifier,
':',
$.type_definition,
optional(',')
))),
'|',
)),
'=>',
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": {
"type": "PREC_RIGHT",
"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": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "parameters",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier_list"
},
{
"type": "BLANK"
}
]
}
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "FIELD",
"name": "parameter",
"content": {
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "STRING",
"value": ":"
},
{
"type": "SYMBOL",
"name": "type_definition"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
}
},
{
"type": "STRING",
"value": "|"
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",

View File

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

File diff suppressed because it is too large Load Diff