Add FunctionExpression to fix syntax bug
This commit is contained in:
parent
4a8242621d
commit
17fa708739
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -316,7 +316,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dust-lang"
|
||||
version = "0.3.91"
|
||||
version = "0.3.92"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"cc",
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
51
src/abstract_tree/function_expression.rs
Normal file
51
src/abstract_tree/function_expression.rs
Normal 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),
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -12,7 +12,7 @@ async { (output 'Whaddup') }
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(expression
|
||||
(function_expression
|
||||
(identifier
|
||||
(built_in_function)))
|
||||
(expression
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -109,7 +109,7 @@ x:(y):0
|
||||
(identifier))
|
||||
(expression
|
||||
(function_call
|
||||
(expression
|
||||
(function_expression
|
||||
(identifier))))))
|
||||
(expression
|
||||
(value
|
||||
|
@ -18,7 +18,7 @@ while true {
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(expression
|
||||
(function_expression
|
||||
(identifier
|
||||
(built_in_function)))
|
||||
(expression
|
||||
|
@ -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))))))
|
||||
|
@ -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),
|
||||
')',
|
||||
),
|
||||
|
@ -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",
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user