Add type check error; Add parameter syntax
This commit is contained in:
parent
2bd4ccb40d
commit
43d46cb289
@ -1,4 +1,4 @@
|
||||
all_cards = {
|
||||
all_cards <map> = {
|
||||
rooms = ['Library' 'Kitchen' 'Conservatory']
|
||||
suspects = ['White' 'Green' 'Scarlett']
|
||||
weapons = ['Rope' 'Lead_Pipe' 'Knife']
|
||||
|
@ -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(),
|
||||
|
11
src/error.rs
11
src/error.rs
@ -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}."
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -76,10 +76,12 @@ Complex Function
|
||||
(expression
|
||||
(value
|
||||
(function
|
||||
(parameter
|
||||
(identifier)
|
||||
(type)
|
||||
(type))
|
||||
(parameter
|
||||
(identifier)
|
||||
(type)
|
||||
(type))
|
||||
(block
|
||||
(statement
|
||||
(expression
|
||||
|
@ -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(','),
|
||||
|
@ -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": [
|
||||
{
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user