Add type check error; Add parameter syntax

This commit is contained in:
Jeff 2023-11-28 10:29:42 -05:00
parent 2bd4ccb40d
commit 43d46cb289
9 changed files with 6464 additions and 6584 deletions

View File

@ -1,4 +1,4 @@
all_cards = {
all_cards <map> = {
rooms = ['Library' 'Kitchen' 'Conservatory']
suspects = ['White' 'Green' 'Scarlett']
weapons = ['Rope' 'Lead_Pipe' 'Knife']

View File

@ -30,28 +30,36 @@ impl Type {
| (Type::Map, Type::Map)
| (Type::String, Type::String)
| (Type::Table, Type::Table) => Ok(()),
(Type::Boolean, _) => Err(Error::ExpectedBoolean {
(Type::Boolean, _) => Err(Error::TypeCheck {
expected: Type::Boolean,
actual: value.clone(),
}),
(Type::Float, _) => Err(Error::ExpectedFloat {
(Type::Float, _) => Err(Error::TypeCheck {
expected: Type::Float,
actual: value.clone(),
}),
(Type::Function, _) => Err(Error::ExpectedFunction {
(Type::Function, _) => Err(Error::TypeCheck {
expected: Type::Function,
actual: value.clone(),
}),
(Type::Integer, _) => Err(Error::ExpectedInteger {
(Type::Integer, _) => Err(Error::TypeCheck {
expected: Type::Integer,
actual: value.clone(),
}),
(Type::List, _) => Err(Error::ExpectedList {
(Type::List, _) => Err(Error::TypeCheck {
expected: Type::List,
actual: value.clone(),
}),
(Type::Map, _) => Err(Error::ExpectedMap {
(Type::Map, _) => Err(Error::TypeCheck {
expected: Type::Map,
actual: value.clone(),
}),
(Type::String, _) => Err(Error::ExpectedString {
(Type::String, _) => Err(Error::TypeCheck {
expected: Type::String,
actual: value.clone(),
}),
(Type::Table, _) => Err(Error::ExpectedTable {
(Type::Table, _) => Err(Error::TypeCheck {
expected: Type::Table,
actual: value.clone(),
}),
}
@ -76,7 +84,7 @@ impl AbstractTree for Type {
"table" => Type::Table,
_ => {
return Err(Error::UnexpectedSyntaxNode {
expected: "bool, fn, int, list, map, string or table",
expected: "any, bool, float, fn, int, list, map, str or table",
actual: node.kind(),
location: node.start_position(),
relevant_source: source[node.byte_range()].to_string(),

View File

@ -5,7 +5,7 @@
use tree_sitter::{Node, Point};
use crate::{value::Value, Identifier};
use crate::{value::Value, Identifier, Type};
use std::{fmt, io, num::ParseFloatError, string::FromUtf8Error, sync::PoisonError, time};
@ -20,6 +20,11 @@ pub enum Error {
relevant_source: String,
},
TypeCheck {
expected: Type,
actual: Value,
},
/// The 'assert' macro did not resolve successfully.
AssertEqualFailed {
expected: Value,
@ -351,6 +356,10 @@ impl fmt::Display for Error {
Syntax { source, location } => {
write!(f, "Syntax error at {location}, this is not valid: {source}")
}
TypeCheck { expected, actual } => write!(
f,
"Type check error. Expected a {expected} but got {actual}."
),
}
}
}

View File

@ -20,32 +20,41 @@ impl Function {
impl AbstractTree for Function {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
let mut parameters = Vec::new();
let mut previous_identifier = None;
Error::expect_syntax_node(source, "function", node)?;
for index in 1..node.child_count() - 2 {
let child_count = node.child_count();
let mut parameters = Vec::new();
for index in 1..child_count - 2 {
let parameter_node = {
let child = node.child(index).unwrap();
if child.kind() == "identifier" {
previous_identifier = Some(Identifier::from_syntax_node(source, child)?);
if child.is_named() {
child
} else {
continue;
}
};
if child.kind() == "type" {
let identifier = previous_identifier.take().unwrap();
let r#type = Type::from_syntax_node(source, child)?;
Error::expect_syntax_node(source, "parameter", parameter_node)?;
let identifier_node = parameter_node.child(0).unwrap();
let identifier = Identifier::from_syntax_node(source, identifier_node)?;
let type_node = parameter_node.child(1).unwrap();
let r#type = Type::from_syntax_node(source, type_node)?;
parameters.push((identifier, r#type))
}
}
let return_type_node = node.child_by_field_name("return_type");
let return_type = if let Some(child) = return_type_node {
Some(Type::from_syntax_node(source, child)?)
let return_type_node = node.child(child_count - 2).unwrap();
let return_type = if return_type_node.is_named() {
Some(Type::from_syntax_node(source, return_type_node)?)
} else {
None
};
let body_node = node.child_by_field_name("body").unwrap();
let body_node = node.child(child_count - 1).unwrap();
let body = Block::from_syntax_node(source, body_node)?;
Ok(Function {

View File

@ -76,10 +76,12 @@ Complex Function
(expression
(value
(function
(parameter
(identifier)
(type)
(type))
(parameter
(identifier)
(type)
(type))
(block
(statement
(expression

View File

@ -276,13 +276,13 @@ module.exports = grammar({
function: $ => seq(
'|',
field('parameters', repeat($._function_parameters)),
repeat($.parameter),
'|',
optional(field('return_type', $.type)),
field('body', $.block),
optional($.type),
$.block,
),
_function_parameters: $ => seq(
parameter: $ => seq(
$.identifier,
$.type,
optional(','),

View File

@ -1166,7 +1166,7 @@
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "_function_parameters"
"name": "parameter"
}
},
{
@ -1177,12 +1177,8 @@
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "return_type",
"content": {
"type": "SYMBOL",
"name": "type"
}
},
{
"type": "BLANK"
@ -1190,16 +1186,12 @@
]
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "block"
}
}
]
},
"_function_parameters": {
"parameter": {
"type": "SEQ",
"members": [
{

View File

@ -184,34 +184,17 @@
{
"type": "function",
"named": true,
"fields": {
"body": {
"multiple": false,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "block",
"named": true
}
]
},
"return_type": {
"multiple": false,
"required": false,
"types": [
{
"type": "type",
"named": true
}
]
}
},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "identifier",
"type": "parameter",
"named": true
},
{
@ -455,6 +438,25 @@
"named": true,
"fields": {}
},
{
"type": "parameter",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "identifier",
"named": true
},
{
"type": "type",
"named": true
}
]
}
},
{
"type": "return",
"named": true,

File diff suppressed because it is too large Load Diff