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]]
name = "dust-lang"
version = "0.3.91"
version = "0.3.92"
dependencies = [
"ansi_term",
"cc",

View File

@ -2,17 +2,18 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node;
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)]
pub struct FunctionCall {
function_expression: Expression,
function_expression: FunctionExpression,
arguments: Vec<Expression>,
}
impl FunctionCall {
pub fn new(function_expression: Expression, arguments: Vec<Expression>) -> Self {
pub fn new(function_expression: FunctionExpression, arguments: Vec<Expression>) -> Self {
Self {
function_expression,
arguments,
@ -22,10 +23,11 @@ impl FunctionCall {
impl AbstractTree for FunctionCall {
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_expression = Expression::from_syntax_node(source, expression_node, context)?;
let function_node = node.child(1).unwrap();
let function_expression =
FunctionExpression::from_syntax_node(source, function_node, context)?;
let function_type = function_expression.expected_type(context)?;
let mut minimum_parameter_count = 0;
@ -65,7 +67,7 @@ impl AbstractTree for FunctionCall {
{
if arguments.len() < minimum_parameter_count {
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,
actual: arguments.len(),
});
@ -80,8 +82,7 @@ impl AbstractTree for FunctionCall {
fn run(&self, source: &str, context: &Map) -> Result<Value> {
let value = match &self.function_expression {
Expression::Value(value_node) => value_node.run(source, context)?,
Expression::Identifier(identifier) => {
FunctionExpression::Identifier(identifier) => {
let key = identifier.inner();
for built_in_function in BUILT_IN_FUNCTIONS {
@ -108,11 +109,9 @@ impl AbstractTree for FunctionCall {
));
}
}
Expression::Index(index) => index.run(source, context)?,
Expression::Math(math) => math.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)?,
FunctionExpression::FunctionCall(function_call) => {
function_call.run(source, context)?
}
};
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> {
match &self.function_expression {
Expression::Value(value_node) => {
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) => {
FunctionExpression::Identifier(identifier) => {
for built_in_function in BUILT_IN_FUNCTIONS {
if identifier.inner() == built_in_function.name() {
if let Type::Function {
@ -162,11 +152,7 @@ impl AbstractTree for FunctionCall {
Ok(identifier_type)
}
}
Expression::Index(index) => index.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),
FunctionExpression::FunctionCall(function_call) => function_call.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 r#for;
pub mod function_call;
pub mod function_expression;
pub mod identifier;
pub mod if_else;
pub mod index;
@ -26,9 +27,10 @@ pub mod r#while;
pub mod r#yield;
pub use {
assignment::*, block::*, expression::*, function_call::*, identifier::*, if_else::*, index::*,
index_assignment::IndexAssignment, logic::*, math::*, r#for::*, r#match::*, r#use::*,
r#while::*, r#yield::*, statement::*, type_definition::*, value_node::*,
assignment::*, block::*, expression::*, function_call::*, function_expression::*,
identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, logic::*, math::*,
r#for::*, r#match::*, r#use::*, r#while::*, r#yield::*, statement::*, type_definition::*,
value_node::*,
};
use tree_sitter::Node;

View File

@ -1,7 +1,10 @@
use serde::{Deserialize, Serialize};
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.
///
@ -17,7 +20,8 @@ impl AbstractTree for Yield {
let input = Expression::from_syntax_node(source, input_node, context)?;
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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -385,12 +385,18 @@ module.exports = grammar({
$.type_definition,
$.block,
),
function_expression: $ =>
choice(
$.identifier,
$.function_call,
),
function_call: $ =>
prec.right(
seq(
'(',
$.expression,
$.function_expression,
optional($._expression_list),
')',
),
@ -402,7 +408,7 @@ module.exports = grammar({
$.expression,
'->',
'(',
$.expression,
$.function_expression,
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": {
"type": "PREC_RIGHT",
"value": 0,
@ -1280,7 +1293,7 @@
},
{
"type": "SYMBOL",
"name": "expression"
"name": "function_expression"
},
{
"type": "CHOICE",
@ -1321,7 +1334,7 @@
},
{
"type": "SYMBOL",
"name": "expression"
"name": "function_expression"
},
{
"type": "CHOICE",

View File

@ -186,6 +186,29 @@
{
"type": "expression",
"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",
"named": true
},
{
"type": "function_expression",
"named": true
}
]
}
@ -743,11 +770,11 @@
},
{
"type": "float",
"named": false
"named": true
},
{
"type": "float",
"named": true
"named": false
},
{
"type": "fn",

File diff suppressed because it is too large Load Diff