1
0

Implement function declarations

This commit is contained in:
Jeff 2023-11-30 09:30:25 -05:00
parent 57b06df9c2
commit 0ee26dcf0d
18 changed files with 8782 additions and 12865 deletions

View File

@ -1,408 +0,0 @@
module.exports = grammar({
name: "dust",
word: $ => $.identifier,
extras: $ => [/\s/, $._comment],
rules: {
root: $ =>
prec(1, repeat1($.statement)),
_comment: $ => /[#][^#\n]*[#|\n]/,
block: $ =>
seq(
optional("async"),
"{",
repeat1($.statement),
"}",
),
statement: $ =>
prec.left(
seq(
choice(
$.assignment,
$.block,
$.expression,
$.for,
$.if_else,
$.index_assignment,
$.match,
$.return,
$.use,
$.while,
),
optional(";"),
),
),
expression: $ =>
prec.right(
choice(
$._expression_kind,
seq(
"(",
$._expression_kind,
")",
),
),
),
_expression_kind: $ =>
prec.right(
choice(
$.function_call,
$.identifier,
$.index,
$.logic,
$.math,
$.value,
$.yield,
),
),
_expression_list: $ =>
repeat1(
prec.right(
seq(
$.expression,
optional(","),
),
),
),
identifier: $ =>
/[_a-zA-Z]+[_a-zA-Z0-9]?/,
value: $ =>
choice(
$.integer,
$.float,
$.string,
$.boolean,
$.list,
$.function,
$.table,
$.map,
),
integer: $ =>
token(
prec.left(
seq(
optional("-"),
repeat1(
choice(
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"0",
),
),
),
),
),
float: $ =>
token(
prec.left(
seq(
optional("-"),
repeat1(
choice(
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"0",
),
),
".",
repeat1(
choice(
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"0",
),
),
),
),
),
string: $ =>
/("[^"]*?")|('[^']*?')|(`[^`]*?`)/,
boolean: $ =>
choice("true", "false"),
list: $ =>
seq(
"[",
repeat(
prec.left(
seq(
$.expression,
optional(","),
),
),
),
"]",
),
map: $ =>
seq(
"{",
repeat(
seq(
$.identifier,
"=",
$.statement,
optional(","),
),
),
"}",
),
index: $ =>
prec.left(
1,
seq(
$.expression,
":",
$.expression,
optional(
seq("..", $.expression),
),
),
),
math: $ =>
prec.left(
seq(
$.expression,
$.math_operator,
$.expression,
),
),
math_operator: $ =>
choice("+", "-", "*", "/", "%"),
logic: $ =>
prec.right(
seq(
$.expression,
$.logic_operator,
$.expression,
),
),
logic_operator: $ =>
choice(
"==",
"!=",
"&&",
"||",
">",
"<",
">=",
"<=",
),
assignment: $ =>
seq(
field(
"identifier",
$.identifier,
),
optional(
field(
"type",
$.type_definition,
),
),
field(
"assignment_operator",
$.assignment_operator,
),
field("statement", $.statement),
),
index_assignment: $ =>
seq(
$.index,
$.assignment_operator,
$.statement,
),
assignment_operator: $ =>
prec.right(
choice("=", "+=", "-="),
),
if_else: $ =>
prec.right(
seq(
$.if,
repeat($.else_if),
optional($.else),
),
),
if: $ =>
seq("if", $.expression, $.block),
else_if: $ =>
seq(
"else if",
$.expression,
$.block,
),
else: $ => seq("else", $.block),
match: $ =>
prec.right(
seq(
"match",
$.expression,
repeat1(
seq(
$.expression,
"=>",
$.block,
),
),
),
),
while: $ =>
seq(
"while",
$.expression,
$.block,
),
for: $ =>
seq(
choice("for", "async for"),
$.identifier,
"in",
$.expression,
$.block,
),
identifier_list: $ =>
prec.right(
choice(
seq(
"|",
repeat(
seq(
$.identifier,
optional(","),
),
),
"|",
),
),
),
table: $ =>
prec.right(
seq(
"table",
$.identifier_list,
$.expression,
),
),
return: $ =>
seq("return", $.expression),
use: $ => seq("use", $.string),
type_definition: $ =>
seq("<", $.type, ">"),
type: $ =>
prec.right(
choice(
"any",
"bool",
"float",
seq(
"fn",
repeat(
seq(
$.type,
optional(","),
),
),
optional(seq("->", $.type)),
),
"int",
seq("list", $.type),
"map",
"num",
"str",
),
),
function: $ =>
seq(
"|",
repeat(
seq(
$.identifier,
optional(","),
),
),
"|",
$.block,
),
function_call: $ =>
prec.right(
1,
seq(
"(",
$.expression,
optional($._expression_list),
")",
),
),
yield: $ =>
prec.left(
seq(
$.expression,
"->",
"(",
$.expression,
optional($._expression_list),
")",
),
),
},
});

View File

@ -1,9 +1,7 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{
AbstractTree, Error, Function, Identifier, Map, Result, Statement, Type, TypeDefinition, Value,
};
use crate::{AbstractTree, Error, Identifier, Map, Result, Statement, Type, TypeDefinition, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Assignment {
@ -24,23 +22,25 @@ impl AbstractTree for Assignment {
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
Error::expect_syntax_node(source, "assignment", node)?;
let identifier_node = node.child_by_field_name("identifier").unwrap();
let child_count = node.child_count();
let identifier_node = node.child(0).unwrap();
let identifier = Identifier::from_syntax_node(source, identifier_node, context)?;
let type_node = node.child_by_field_name("type");
let type_node = node.child(1);
let type_definition = if let Some(type_node) = type_node {
Some(TypeDefinition::from_syntax_node(
source, type_node, context,
)?)
if type_node.kind() == "type_defintion" {
Some(TypeDefinition::from_syntax_node(
source, type_node, context,
)?)
} else {
None
}
} else {
None
};
let operator_node = node
.child_by_field_name("assignment_operator")
.unwrap()
.child(0)
.unwrap();
let operator_node = node.child(child_count - 2).unwrap().child(0).unwrap();
let operator = match operator_node.kind() {
"=" => AssignmentOperator::Equal,
"+=" => AssignmentOperator::PlusEqual,
@ -55,7 +55,7 @@ impl AbstractTree for Assignment {
}
};
let statement_node = node.child_by_field_name("statement").unwrap();
let statement_node = node.child(child_count - 1).unwrap();
let statement = Statement::from_syntax_node(source, statement_node, context)?;
if let Some(type_definition) = &type_definition {
@ -145,22 +145,11 @@ impl AbstractTree for Assignment {
AssignmentOperator::Equal => value,
};
let new_value = if let Some(type_definition) = &self.type_definition {
if let Some(type_definition) = &self.type_definition {
let new_value_type = new_value.r#type(context)?;
type_definition.runtime_check(&new_value_type, context)?;
if let Value::Function(function) = new_value {
Value::Function(Function::new(
function.parameters().clone(),
function.body().clone(),
))
} else {
new_value
}
} else {
new_value
};
}
context.variables_mut()?.insert(key.clone(), new_value);

View File

@ -49,7 +49,7 @@ impl AbstractTree for Expression {
}
_ => {
return Err(Error::UnexpectedSyntaxNode {
expected: "value, identifier, index, math, logic, function_call or yield",
expected: "value_node, identifier, index, math, logic, function_call or yield",
actual: child.kind(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),

View File

@ -77,14 +77,14 @@ impl AbstractTree for FunctionCall {
let mut function_context = Map::clone_from(context)?;
let parameter_expression_pairs = function.parameters().iter().zip(self.arguments.iter());
for (identifier, expression) in parameter_expression_pairs {
for ((identifier, _type), expression) in parameter_expression_pairs {
let key = identifier.clone().take_inner();
let value = expression.run(source, context)?;
function_context.variables_mut()?.insert(key, value);
}
function.run(source, &mut function_context)
function.body().run(source, &mut function_context)
}
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> {

View File

@ -0,0 +1,111 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{
AbstractTree, Block, Error, Function, Identifier, Map, Result, Type, TypeDefinition, Value,
};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct FunctionDeclaration {
name: Identifier,
_type_definition: TypeDefinition,
function: Function,
}
impl AbstractTree for FunctionDeclaration {
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
Error::expect_syntax_node(source, "function_declaration", node)?;
let name_node = node.child(0).unwrap();
let name = Identifier::from_syntax_node(source, name_node, context)?;
let type_node = node.child(1).unwrap();
let type_definition = TypeDefinition::from_syntax_node(source, type_node, context)?;
let (parameter_types, return_type) = if let Type::Function {
parameter_types,
return_type,
} = type_definition.inner()
{
(parameter_types, return_type)
} else {
return Err(Error::TypeCheck {
expected: TypeDefinition::new(Type::Function {
parameter_types: Vec::with_capacity(0),
return_type: Box::new(Type::Empty),
}),
actual: type_definition,
location: type_node.start_position(),
source: source[type_node.byte_range()].to_string(),
});
};
let function = {
let function_node = node.child(2).unwrap();
Error::expect_syntax_node(source, "function", function_node)?;
let child_count = function_node.child_count();
let mut parameters = Vec::new();
for index in 1..child_count - 2 {
let child = function_node.child(index).unwrap();
let parameter_index = parameters.len();
let parameter_type = parameter_types.get(parameter_index).unwrap_or(&Type::Empty);
if child.is_named() {
let identifier = Identifier::from_syntax_node(source, child, context)?;
parameters.push((identifier, TypeDefinition::new(parameter_type.clone())));
}
}
let body_node = function_node.child(child_count - 1).unwrap();
let body = Block::from_syntax_node(source, body_node, context)?;
Function::new(
parameters,
body,
TypeDefinition::new(return_type.as_ref().clone()),
)
};
Ok(FunctionDeclaration {
name,
_type_definition: type_definition,
function,
})
}
fn run(&self, _source: &str, context: &Map) -> Result<Value> {
let key = self.name.inner();
context
.variables_mut()?
.insert(key.clone(), Value::Function(self.function.clone()));
Ok(Value::Empty)
}
fn expected_type(&self, _context: &Map) -> Result<TypeDefinition> {
Ok(TypeDefinition::new(Type::Empty))
}
}
#[cfg(test)]
mod tests {
use crate::{evaluate, Value};
#[test]
fn simple_function_declaration() {
let test = evaluate(
"
fn foo <fn int -> int> = |x| { x }
(foo 42)
",
)
.unwrap();
assert_eq!(Value::Integer(42), test);
}
}

View File

@ -89,22 +89,29 @@ mod tests {
use crate::evaluate;
#[test]
fn evaluate_list_index() {
fn list_index() {
let test = evaluate("x = [1 [2] 3] x:1:0").unwrap();
assert_eq!(Value::Integer(2), test);
}
#[test]
fn evaluate_map_index() {
fn map_index() {
let test = evaluate("x = {y = {z = 2}} x:y:z").unwrap();
assert_eq!(Value::Integer(2), test);
}
#[test]
fn evaluate_complex_index() {
let test = evaluate("x = [1 2 3]; y = || { 0 } x:((y))").unwrap();
fn complex_index() {
let test = evaluate(
"
x = [1 2 3]
y <fn -> int> || { 0 }
x:((y))
",
)
.unwrap();
assert_eq!(Value::Integer(1), test);
}

View File

@ -11,6 +11,7 @@ pub mod block;
pub mod expression;
pub mod r#for;
pub mod function_call;
pub mod function_declaration;
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_defintion::*, value_node::*,
assignment::*, block::*, expression::*, function_call::*, function_declaration::*,
identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, logic::*, math::*,
r#for::*, r#match::*, r#use::*, r#while::*, r#yield::*, statement::*, type_defintion::*,
value_node::*,
};
use tree_sitter::Node;

View File

@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{
AbstractTree, Assignment, Block, Error, Expression, For, IfElse, IndexAssignment, Map, Match,
Result, TypeDefinition, Use, Value, While,
AbstractTree, Assignment, Block, Error, Expression, For, FunctionDeclaration, IfElse,
IndexAssignment, Map, Match, Result, TypeDefinition, Use, Value, While,
};
/// Abstract representation of a statement.
@ -12,6 +12,7 @@ pub enum Statement {
Assignment(Box<Assignment>),
Return(Expression),
Expression(Expression),
FunctionDeclaration(FunctionDeclaration),
IfElse(Box<IfElse>),
Match(Match),
While(Box<While>),
@ -36,7 +37,10 @@ impl AbstractTree for Statement {
Ok(Statement::Return(Expression::from_syntax_node(source, expression_node, context)?))
},
"expression" => Ok(Self::Expression(Expression::from_syntax_node(
"expression" => Ok(Statement::Expression(Expression::from_syntax_node(
source, child, context
)?)),
"function_declaration" => Ok(Statement::FunctionDeclaration(FunctionDeclaration::from_syntax_node(
source, child, context
)?)),
"if_else" => Ok(Statement::IfElse(Box::new(IfElse::from_syntax_node(
@ -72,6 +76,9 @@ impl AbstractTree for Statement {
Statement::Assignment(assignment) => assignment.run(source, context),
Statement::Return(expression) => expression.run(source, context),
Statement::Expression(expression) => expression.run(source, context),
Statement::FunctionDeclaration(function_declaration) => {
function_declaration.run(source, context)
}
Statement::IfElse(if_else) => if_else.run(source, context),
Statement::Match(r#match) => r#match.run(source, context),
Statement::While(r#while) => r#while.run(source, context),
@ -87,6 +94,9 @@ impl AbstractTree for Statement {
Statement::Assignment(assignment) => assignment.expected_type(context),
Statement::Return(expression) => expression.expected_type(context),
Statement::Expression(expression) => expression.expected_type(context),
Statement::FunctionDeclaration(function_declaration) => {
function_declaration.expected_type(context)
}
Statement::IfElse(if_else) => if_else.expected_type(context),
Statement::Match(r#match) => r#match.expected_type(context),
Statement::While(r#while) => r#while.expected_type(context),

View File

@ -61,6 +61,34 @@ impl TypeDefinition {
self_defintion.runtime_check(other_definition, context)
}
(
Type::Function {
parameter_types: self_parameter_types,
return_type: self_return_type,
},
Type::Function {
parameter_types: other_parameter_types,
return_type: other_return_type,
},
) => {
let parameter_type_pairs = self_parameter_types
.iter()
.zip(other_parameter_types.iter());
for (self_parameter_type, other_parameter_type) in parameter_type_pairs {
TypeDefinition::new(self_parameter_type.clone()).runtime_check(
&TypeDefinition::new(other_parameter_type.clone()),
context,
)?;
}
TypeDefinition::new(self_return_type.as_ref().clone()).runtime_check(
&TypeDefinition::new(other_return_type.as_ref().clone()),
context,
)?;
Ok(())
}
_ => Err(Error::RuntimeTypeCheck {
expected: self.clone(),
actual: other.clone(),

View File

@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{
AbstractTree, Error, Expression, Function, Identifier, List, Map, Result, Statement, Table,
Type, TypeDefinition, Value,
AbstractTree, Error, Expression, Identifier, List, Map, Result, Statement, Table, Type,
TypeDefinition, Value,
};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
@ -21,12 +21,11 @@ pub enum ValueNode {
column_names: Vec<Identifier>,
rows: Box<Expression>,
},
Function(Function),
}
impl AbstractTree for ValueNode {
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
debug_assert_eq!("value", node.kind());
Error::expect_syntax_node(source, "value", node)?;
let child = node.child(0).unwrap();
let value_node = match child.kind() {
@ -101,11 +100,9 @@ impl AbstractTree for ValueNode {
ValueNode::Map(child_nodes)
}
"function" => ValueNode::Function(Function::from_syntax_node(source, child, context)?),
_ => {
return Err(Error::UnexpectedSyntaxNode {
expected:
"string, integer, float, boolean, list, table, map, function or empty",
expected: "string, integer, float, boolean, list, table, map, or empty",
actual: child.kind(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
@ -175,7 +172,6 @@ impl AbstractTree for ValueNode {
Value::Table(table)
}
ValueNode::Function(function) => Value::Function(function.clone()),
};
Ok(value)
@ -214,7 +210,6 @@ impl AbstractTree for ValueNode {
column_names: _,
rows: _,
} => TypeDefinition::new(Type::Table),
ValueNode::Function(function) => return function.expected_type(context),
};
Ok(type_definition)

View File

@ -150,34 +150,6 @@ mod tests {
assert_eq!(evaluate("{ x = 1, foo = 'bar' }"), Ok(Value::Map(map)));
}
#[test]
fn evaluate_table() {
let mut table = Table::new(vec!["messages".to_string(), "numbers".to_string()]);
table
.insert(vec![Value::String("hiya".to_string()), Value::Integer(42)])
.unwrap();
table
.insert(vec![Value::String("foo".to_string()), Value::Integer(57)])
.unwrap();
table
.insert(vec![Value::String("bar".to_string()), Value::Float(99.99)])
.unwrap();
assert_eq!(
evaluate(
"
table |messages numbers| [
['hiya', 42]
['foo', 57]
['bar', 99.99]
]
"
),
Ok(Value::Table(table))
);
}
#[test]
fn evaluate_if() {
assert_eq!(

View File

@ -1,58 +1,39 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Block, Error, Identifier, Map, Result, TypeDefinition, Value};
use crate::{Block, Identifier, TypeDefinition};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Function {
parameters: Vec<Identifier>,
parameters: Vec<(Identifier, TypeDefinition)>,
body: Block,
return_type: TypeDefinition,
}
impl Function {
pub fn new(parameters: Vec<Identifier>, body: Block) -> Self {
Self { parameters, body }
pub fn new(
parameters: Vec<(Identifier, TypeDefinition)>,
body: Block,
return_type: TypeDefinition,
) -> Self {
Self {
parameters,
body,
return_type,
}
}
pub fn parameters(&self) -> &Vec<Identifier> {
pub fn parameters(&self) -> &Vec<(Identifier, TypeDefinition)> {
&self.parameters
}
pub fn body(&self) -> &Block {
&self.body
}
}
impl AbstractTree for Function {
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
Error::expect_syntax_node(source, "function", node)?;
let child_count = node.child_count();
let mut parameters = Vec::new();
for index in 1..child_count - 2 {
let child = node.child(index).unwrap();
if child.is_named() {
let identifier = Identifier::from_syntax_node(source, child, context)?;
parameters.push(identifier);
}
}
let body_node = node.child(child_count - 1).unwrap();
let body = Block::from_syntax_node(source, body_node, context)?;
Ok(Function { parameters, body })
}
fn run(&self, source: &str, context: &Map) -> Result<Value> {
self.body.run(source, context)
}
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> {
Value::Function(self.clone()).r#type(context)
pub fn return_type(&self) -> &TypeDefinition {
&self.return_type
}
}

View File

@ -1,37 +0,0 @@
================================================================================
Simple Function Call
================================================================================
(output 'hi')
--------------------------------------------------------------------------------
(root
(statement
(expression
(function_call
(expression
(identifier))
(expression
(value
(string)))))))
================================================================================
Nested Function Call
================================================================================
(assert_equal (random_integer) 4)
--------------------------------------------------------------------------------
(root
(statement
(expression
(function_call
(expression
(identifier))
(expression
(identifier))
(expression
(value
(integer)))))))

View File

@ -2,48 +2,23 @@
Simple Function
================================================================================
|| { "Hiya" }
foo <fn -> str> || { "Hiya" }
--------------------------------------------------------------------------------
(root
(statement
(expression
(value
(function
(block
(statement
(expression
(value
(string))))))))))
================================================================================
Function Assignment
================================================================================
x <fn num -> str> = |number| { "Hiya" }
--------------------------------------------------------------------------------
(root
(statement
(assignment
(function_declaration
(identifier)
(type_definition
(type
(type)
(type)))
(assignment_operator)
(statement
(expression
(value
(function
(identifier)
(block
(statement
(expression
(value
(string))))))))))))
(function
(block
(statement
(expression
(value
(string)))))))))
================================================================================
Function Call
@ -67,7 +42,7 @@ Function Call
Complex Function
================================================================================
|message number| {
foobar <fn str num> |message number| {
(output message)
(output number)
}
@ -76,26 +51,30 @@ Complex Function
(root
(statement
(expression
(value
(function
(identifier)
(identifier)
(block
(statement
(expression
(function_call
(expression
(identifier))
(expression
(identifier)))))
(statement
(expression
(function_call
(expression
(identifier))
(expression
(identifier)))))))))))
(function_declaration
(identifier)
(type_definition
(type
(type)
(type)))
(function
(identifier)
(identifier)
(block
(statement
(expression
(function_call
(expression
(identifier))
(expression
(identifier)))))
(statement
(expression
(function_call
(expression
(identifier))
(expression
(identifier))))))))))
================================================================================
Complex Function Call

View File

@ -27,6 +27,7 @@ module.exports = grammar({
$.block,
$.expression,
$.for,
$.function_declaration,
$.if_else,
$.index_assignment,
$.match,
@ -83,8 +84,6 @@ module.exports = grammar({
$.string,
$.boolean,
$.list,
$.function,
$.table,
$.map,
),
@ -231,21 +230,10 @@ module.exports = grammar({
assignment: $ =>
seq(
field(
'identifier',
$.identifier,
),
optional(
field(
'type',
$.type_definition,
),
),
field(
'assignment_operator',
$.assignment_operator,
),
field('statement', $.statement),
$.identifier,
optional($.type_definition),
$.assignment_operator,
$.statement,
),
index_assignment: $ =>
@ -328,15 +316,6 @@ module.exports = grammar({
),
),
table: $ =>
prec.right(
seq(
'table',
$.identifier_list,
$.expression,
),
),
return: $ =>
seq('return', $.expression),
@ -350,6 +329,7 @@ module.exports = grammar({
choice(
'any',
'bool',
'float',
seq(
'fn',
repeat(
@ -368,6 +348,13 @@ module.exports = grammar({
),
),
function_declaration: $ =>
seq(
$.identifier,
$.type_definition,
$.function,
),
function: $ =>
seq(
'|',

View File

@ -74,6 +74,10 @@
"type": "SYMBOL",
"name": "for"
},
{
"type": "SYMBOL",
"name": "function_declaration"
},
{
"type": "SYMBOL",
"name": "if_else"
@ -237,14 +241,6 @@
"type": "SYMBOL",
"name": "list"
},
{
"type": "SYMBOL",
"name": "function"
},
{
"type": "SYMBOL",
"name": "table"
},
{
"type": "SYMBOL",
"name": "map"
@ -700,23 +696,15 @@
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "identifier",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "type",
"content": {
"type": "SYMBOL",
"name": "type_definition"
}
"type": "SYMBOL",
"name": "type_definition"
},
{
"type": "BLANK"
@ -724,20 +712,12 @@
]
},
{
"type": "FIELD",
"name": "assignment_operator",
"content": {
"type": "SYMBOL",
"name": "assignment_operator"
}
"type": "SYMBOL",
"name": "assignment_operator"
},
{
"type": "FIELD",
"name": "statement",
"content": {
"type": "SYMBOL",
"name": "statement"
}
"type": "SYMBOL",
"name": "statement"
}
]
},
@ -992,27 +972,6 @@
]
}
},
"table": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "table"
},
{
"type": "SYMBOL",
"name": "identifier_list"
},
{
"type": "SYMBOL",
"name": "expression"
}
]
}
},
"return": {
"type": "SEQ",
"members": [
@ -1070,6 +1029,10 @@
"type": "STRING",
"value": "bool"
},
{
"type": "STRING",
"value": "float"
},
{
"type": "SEQ",
"members": [
@ -1156,6 +1119,23 @@
]
}
},
"function_declaration": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "SYMBOL",
"name": "type_definition"
},
{
"type": "SYMBOL",
"name": "function"
}
]
},
"function": {
"type": "SEQ",
"members": [

View File

@ -2,47 +2,28 @@
{
"type": "assignment",
"named": true,
"fields": {
"assignment_operator": {
"multiple": false,
"required": true,
"types": [
{
"type": "assignment_operator",
"named": true
}
]
},
"identifier": {
"multiple": false,
"required": true,
"types": [
{
"type": "identifier",
"named": true
}
]
},
"statement": {
"multiple": false,
"required": true,
"types": [
{
"type": "statement",
"named": true
}
]
},
"type": {
"multiple": false,
"required": false,
"types": [
{
"type": "type_definition",
"named": true
}
]
}
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "assignment_operator",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "statement",
"named": true
},
{
"type": "type_definition",
"named": true
}
]
}
},
{
@ -201,16 +182,24 @@
}
},
{
"type": "identifier_list",
"type": "function_declaration",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"required": true,
"types": [
{
"type": "function",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "type_definition",
"named": true
}
]
}
@ -450,6 +439,10 @@
"type": "for",
"named": true
},
{
"type": "function_declaration",
"named": true
},
{
"type": "if_else",
"named": true
@ -477,25 +470,6 @@
]
}
},
{
"type": "table",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "identifier_list",
"named": true
}
]
}
},
{
"type": "type",
"named": true,
@ -557,10 +531,6 @@
"type": "float",
"named": true
},
{
"type": "function",
"named": true
},
{
"type": "integer",
"named": true
@ -576,10 +546,6 @@
{
"type": "string",
"named": true
},
{
"type": "table",
"named": true
}
]
}
@ -750,6 +716,10 @@
"type": "float",
"named": true
},
{
"type": "float",
"named": false
},
{
"type": "fn",
"named": false
@ -806,10 +776,6 @@
"type": "string",
"named": true
},
{
"type": "table",
"named": false
},
{
"type": "true",
"named": false

File diff suppressed because it is too large Load Diff