Add FunctionExpression to fix syntax bug

This commit is contained in:
Jeff 2023-12-29 18:59:15 -05:00
parent 4a8242621d
commit 17fa708739
15 changed files with 13727 additions and 13118 deletions

2
Cargo.lock generated
View File

@ -316,7 +316,7 @@ dependencies = [
[[package]] [[package]]
name = "dust-lang" name = "dust-lang"
version = "0.3.91" version = "0.3.92"
dependencies = [ dependencies = [
"ansi_term", "ansi_term",
"cc", "cc",

View File

@ -2,17 +2,18 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{ use crate::{
AbstractTree, Error, Expression, Map, Result, Type, Value, ValueNode, BUILT_IN_FUNCTIONS, AbstractTree, Error, Expression, FunctionExpression, Map, Result, Type, Value,
BUILT_IN_FUNCTIONS,
}; };
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct FunctionCall { pub struct FunctionCall {
function_expression: Expression, function_expression: FunctionExpression,
arguments: Vec<Expression>, arguments: Vec<Expression>,
} }
impl FunctionCall { impl FunctionCall {
pub fn new(function_expression: Expression, arguments: Vec<Expression>) -> Self { pub fn new(function_expression: FunctionExpression, arguments: Vec<Expression>) -> Self {
Self { Self {
function_expression, function_expression,
arguments, arguments,
@ -22,10 +23,11 @@ impl FunctionCall {
impl AbstractTree for FunctionCall { impl AbstractTree for FunctionCall {
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> { fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
debug_assert_eq!("function_call", node.kind()); Error::expect_syntax_node(source, "function_call", node)?;
let expression_node = node.child(1).unwrap(); let function_node = node.child(1).unwrap();
let function_expression = Expression::from_syntax_node(source, expression_node, context)?; let function_expression =
FunctionExpression::from_syntax_node(source, function_node, context)?;
let function_type = function_expression.expected_type(context)?; let function_type = function_expression.expected_type(context)?;
let mut minimum_parameter_count = 0; let mut minimum_parameter_count = 0;
@ -65,7 +67,7 @@ impl AbstractTree for FunctionCall {
{ {
if arguments.len() < minimum_parameter_count { if arguments.len() < minimum_parameter_count {
return Err(Error::ExpectedFunctionArgumentMinimum { return Err(Error::ExpectedFunctionArgumentMinimum {
source: source[expression_node.byte_range()].to_string(), source: source[function_node.byte_range()].to_string(),
minumum_expected: minimum_parameter_count, minumum_expected: minimum_parameter_count,
actual: arguments.len(), actual: arguments.len(),
}); });
@ -80,8 +82,7 @@ impl AbstractTree for FunctionCall {
fn run(&self, source: &str, context: &Map) -> Result<Value> { fn run(&self, source: &str, context: &Map) -> Result<Value> {
let value = match &self.function_expression { let value = match &self.function_expression {
Expression::Value(value_node) => value_node.run(source, context)?, FunctionExpression::Identifier(identifier) => {
Expression::Identifier(identifier) => {
let key = identifier.inner(); let key = identifier.inner();
for built_in_function in BUILT_IN_FUNCTIONS { for built_in_function in BUILT_IN_FUNCTIONS {
@ -108,11 +109,9 @@ impl AbstractTree for FunctionCall {
)); ));
} }
} }
Expression::Index(index) => index.run(source, context)?, FunctionExpression::FunctionCall(function_call) => {
Expression::Math(math) => math.run(source, context)?, function_call.run(source, context)?
Expression::Logic(logic) => logic.run(source, context)?, }
Expression::FunctionCall(function_call) => function_call.run(source, context)?,
Expression::Yield(r#yield) => r#yield.run(source, context)?,
}; };
let mut arguments = Vec::with_capacity(self.arguments.len()); let mut arguments = Vec::with_capacity(self.arguments.len());
@ -128,16 +127,7 @@ impl AbstractTree for FunctionCall {
fn expected_type(&self, context: &Map) -> Result<Type> { fn expected_type(&self, context: &Map) -> Result<Type> {
match &self.function_expression { match &self.function_expression {
Expression::Value(value_node) => { FunctionExpression::Identifier(identifier) => {
if let ValueNode::Function(function) = value_node {
let return_type = function.return_type()?.clone();
Ok(return_type)
} else {
value_node.expected_type(context)
}
}
Expression::Identifier(identifier) => {
for built_in_function in BUILT_IN_FUNCTIONS { for built_in_function in BUILT_IN_FUNCTIONS {
if identifier.inner() == built_in_function.name() { if identifier.inner() == built_in_function.name() {
if let Type::Function { if let Type::Function {
@ -162,11 +152,7 @@ impl AbstractTree for FunctionCall {
Ok(identifier_type) Ok(identifier_type)
} }
} }
Expression::Index(index) => index.expected_type(context), FunctionExpression::FunctionCall(function_call) => function_call.expected_type(context),
Expression::Math(math) => math.expected_type(context),
Expression::Logic(logic) => logic.expected_type(context),
Expression::FunctionCall(function_call) => function_call.expected_type(context),
Expression::Yield(r#yield) => r#yield.expected_type(context),
} }
} }
} }

View File

@ -0,0 +1,51 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Error, FunctionCall, Identifier, Map, Result, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub enum FunctionExpression {
Identifier(Identifier),
FunctionCall(Box<FunctionCall>),
}
impl AbstractTree for FunctionExpression {
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
Error::expect_syntax_node(source, "function_expression", node)?;
let child = node.child(0).unwrap();
let function_expression = match child.kind() {
"identifier" => FunctionExpression::Identifier(Identifier::from_syntax_node(
source, child, context,
)?),
"function_call" => FunctionExpression::FunctionCall(Box::new(
FunctionCall::from_syntax_node(source, child, context)?,
)),
_ => {
return Err(Error::UnexpectedSyntaxNode {
expected: "identifier or function call",
actual: child.kind(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
})
}
};
Ok(function_expression)
}
fn run(&self, source: &str, context: &Map) -> Result<Value> {
match self {
FunctionExpression::Identifier(identifier) => identifier.run(source, context),
FunctionExpression::FunctionCall(function_call) => function_call.run(source, context),
}
}
fn expected_type(&self, context: &Map) -> Result<Type> {
match self {
FunctionExpression::Identifier(identifier) => identifier.expected_type(context),
FunctionExpression::FunctionCall(function_call) => function_call.expected_type(context),
}
}
}

View File

@ -11,6 +11,7 @@ pub mod block;
pub mod expression; pub mod expression;
pub mod r#for; pub mod r#for;
pub mod function_call; pub mod function_call;
pub mod function_expression;
pub mod identifier; pub mod identifier;
pub mod if_else; pub mod if_else;
pub mod index; pub mod index;
@ -26,9 +27,10 @@ pub mod r#while;
pub mod r#yield; pub mod r#yield;
pub use { pub use {
assignment::*, block::*, expression::*, function_call::*, identifier::*, if_else::*, index::*, assignment::*, block::*, expression::*, function_call::*, function_expression::*,
index_assignment::IndexAssignment, logic::*, math::*, r#for::*, r#match::*, r#use::*, identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, logic::*, math::*,
r#while::*, r#yield::*, statement::*, type_definition::*, value_node::*, r#for::*, r#match::*, r#use::*, r#while::*, r#yield::*, statement::*, type_definition::*,
value_node::*,
}; };
use tree_sitter::Node; use tree_sitter::Node;

View File

@ -1,7 +1,10 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Expression, FunctionCall, Map, Result, Type, Value}; use crate::{
function_expression::FunctionExpression, AbstractTree, Expression, FunctionCall, Map, Result,
Type, Value,
};
/// Abstract representation of a yield expression. /// Abstract representation of a yield expression.
/// ///
@ -17,7 +20,8 @@ impl AbstractTree for Yield {
let input = Expression::from_syntax_node(source, input_node, context)?; let input = Expression::from_syntax_node(source, input_node, context)?;
let expression_node = node.child(3).unwrap(); let expression_node = node.child(3).unwrap();
let function_expression = Expression::from_syntax_node(source, expression_node, context)?; let function_expression =
FunctionExpression::from_syntax_node(source, expression_node, context)?;
let mut arguments = Vec::new(); let mut arguments = Vec::new();

View File

@ -12,7 +12,7 @@ async { (output 'Whaddup') }
(statement (statement
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier (identifier
(built_in_function))) (built_in_function)))
(expression (expression

View File

@ -28,7 +28,7 @@ for i in [1, 2, 3] {
(statement (statement
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier (identifier
(built_in_function))) (built_in_function)))
(expression (expression
@ -62,7 +62,7 @@ for list in list_of_lists {
(statement (statement
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier (identifier
(built_in_function))) (built_in_function)))
(expression (expression

View File

@ -68,7 +68,7 @@ Function Call
(statement (statement
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier)) (identifier))
(expression (expression
(value (value
@ -93,7 +93,7 @@ Complex Function Call
(statement (statement
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier)) (identifier))
(expression (expression
(value (value
@ -146,12 +146,12 @@ x = (fn cb <() -> bool>) <bool> {
(statement (statement
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier)))))))))))) (identifier))))))))))))
(statement (statement
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier)) (identifier))
(expression (expression
(value (value
@ -176,12 +176,12 @@ Nested Function Call
(statement (statement
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier (identifier
(built_in_function))) (built_in_function)))
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier (identifier
(built_in_function))) (built_in_function)))
(expression (expression

View File

@ -109,7 +109,7 @@ x:(y):0
(identifier)) (identifier))
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier)))))) (identifier))))))
(expression (expression
(value (value

View File

@ -18,7 +18,7 @@ while true {
(statement (statement
(expression (expression
(function_call (function_call
(expression (function_expression
(identifier (identifier
(built_in_function))) (built_in_function)))
(expression (expression

View File

@ -13,7 +13,7 @@ Simple Yield
(expression (expression
(value (value
(integer))) (integer)))
(expression (function_expression
(identifier (identifier
(built_in_function))))))) (built_in_function)))))))
@ -35,9 +35,9 @@ x -> (foo) -> (bar) -> (abc)
(yield (yield
(expression (expression
(identifier)) (identifier))
(expression (function_expression
(identifier)))) (identifier))))
(expression (function_expression
(identifier)))) (identifier))))
(expression (function_expression
(identifier)))))) (identifier))))))

View File

@ -386,11 +386,17 @@ module.exports = grammar({
$.block, $.block,
), ),
function_expression: $ =>
choice(
$.identifier,
$.function_call,
),
function_call: $ => function_call: $ =>
prec.right( prec.right(
seq( seq(
'(', '(',
$.expression, $.function_expression,
optional($._expression_list), optional($._expression_list),
')', ')',
), ),
@ -402,7 +408,7 @@ module.exports = grammar({
$.expression, $.expression,
'->', '->',
'(', '(',
$.expression, $.function_expression,
optional($._expression_list), optional($._expression_list),
')', ')',
), ),

View File

@ -1268,6 +1268,19 @@
} }
] ]
}, },
"function_expression": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "SYMBOL",
"name": "function_call"
}
]
},
"function_call": { "function_call": {
"type": "PREC_RIGHT", "type": "PREC_RIGHT",
"value": 0, "value": 0,
@ -1280,7 +1293,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expression" "name": "function_expression"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@ -1321,7 +1334,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expression" "name": "function_expression"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",

View File

@ -186,6 +186,29 @@
{ {
"type": "expression", "type": "expression",
"named": true "named": true
},
{
"type": "function_expression",
"named": true
}
]
}
},
{
"type": "function_expression",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "function_call",
"named": true
},
{
"type": "identifier",
"named": true
} }
] ]
} }
@ -585,6 +608,10 @@
{ {
"type": "expression", "type": "expression",
"named": true "named": true
},
{
"type": "function_expression",
"named": true
} }
] ]
} }
@ -743,11 +770,11 @@
}, },
{ {
"type": "float", "type": "float",
"named": false "named": true
}, },
{ {
"type": "float", "type": "float",
"named": true "named": false
}, },
{ {
"type": "fn", "type": "fn",

File diff suppressed because it is too large Load Diff