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]]
|
[[package]]
|
||||||
name = "dust-lang"
|
name = "dust-lang"
|
||||||
version = "0.3.91"
|
version = "0.3.92"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"cc",
|
"cc",
|
||||||
|
@ -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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 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;
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -109,7 +109,7 @@ x:(y):0
|
|||||||
(identifier))
|
(identifier))
|
||||||
(expression
|
(expression
|
||||||
(function_call
|
(function_call
|
||||||
(expression
|
(function_expression
|
||||||
(identifier))))))
|
(identifier))))))
|
||||||
(expression
|
(expression
|
||||||
(value
|
(value
|
||||||
|
@ -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
|
||||||
|
@ -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))))))
|
||||||
|
@ -385,12 +385,18 @@ module.exports = grammar({
|
|||||||
$.type_definition,
|
$.type_definition,
|
||||||
$.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),
|
||||||
')',
|
')',
|
||||||
),
|
),
|
||||||
|
@ -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",
|
||||||
|
@ -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
Loading…
Reference in New Issue
Block a user