1
0

Compare commits

..

No commits in common. "d1b116cc35a02f83e4db6e56ba7a6987ea9d1425" and "df7cd0e9721e56787be9c00d6a7c0650a2064169" have entirely different histories.

14 changed files with 54765 additions and 82451 deletions

View File

@ -3,20 +3,28 @@ suspects = ['White' 'Green']
weapons = ['Rope' 'Lead_Pipe']
cards = [rooms suspects weapons]
take_turn = function current_room opponent_card
remove_card opponent_card
make_guess current_room
take_turn = function <current_room opponent_card> {
(remove_card opponent_card)
(make_guess current_room)
}
remove_card = function opponent_card
for card_list in cards
removed = remove card from card_list
remove_card = function <opponent_card> {
for card_list in cards {
# removed = remove card from card_list {
card == opponent_card
}
}
if type removed == 'empty'
output 'Card not found.'
if (type removed) == 'empty' {
(output 'Card not found.')
}
}
make_guess = function current_room
if length suspects == 1 && length rooms == 1 && length weapons == 1
make_guess = function <current_room> {
if (length suspects) == 1
&& (length rooms) == 1
&& (length weapons) == 1
{
(output 'It was '
+ suspects:0
+ ' in the '
@ -24,7 +32,7 @@ make_guess = function current_room
+ ' with the '
+ weapons:0
+ '!')
else
} else {
(output 'I accuse '
+ (random suspects)
+ ' in the '
@ -32,5 +40,7 @@ make_guess = function current_room
+ ' with the '
+ (random weapons)
+ '!')
}
}
(make_guess 'Library')

View File

@ -286,7 +286,6 @@ impl AbstractTree for BuiltInFunction {
}
BuiltInFunction::AssertEqual(expressions) => {
let mut prev_value = None;
for expression in expressions {
let value = expression.run(source, context)?;

View File

@ -24,7 +24,7 @@ impl AbstractTree for FunctionCall {
for index in 1..node.child_count() {
let child = node.child(index).unwrap();
if child.is_named() {
if child.kind() == "expression" {
let expression = Expression::from_syntax_node(source, child)?;
arguments.push(expression);
@ -59,16 +59,13 @@ impl AbstractTree for FunctionCall {
return Err(Error::FunctionIdentifierNotFound(name.clone()));
};
let mut function_context = Map::clone_from(context);
let identifier_expression_pairs = definition.identifiers().iter().zip(arguments.iter());
if let Some(parameters) = definition.identifiers() {
let parameter_expression_pairs = parameters.iter().zip(arguments.iter());
for (identifier, expression) in identifier_expression_pairs {
let key = identifier.inner().clone();
let value = expression.run(source, context)?;
for (identifier, 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_context.variables_mut().insert(key, value);
}
definition.body().run(source, &mut function_context)

View File

@ -55,23 +55,22 @@ impl AbstractTree for ValueNode {
ValueType::List(expressions)
}
"table" => {
let identifier_list_node = child.child(1).unwrap();
let identifier_count = identifier_list_node.child_count();
let mut column_names = Vec::with_capacity(identifier_count);
let child_count = child.child_count();
let mut column_names = Vec::new();
for index in 0..identifier_count {
let identifier_node = identifier_list_node.child(index).unwrap();
let expression_node = child.child(child_count - 1).unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
if identifier_node.is_named() {
let identifier = Identifier::from_syntax_node(source, identifier_node)?;
for index in 2..child.child_count() - 2 {
let node = child.child(index).unwrap();
if node.is_named() {
let identifier = Identifier::from_syntax_node(source, node)?;
column_names.push(identifier)
}
}
let expression_node = child.child(2).unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
ValueType::Table {
column_names,
rows: Box::new(expression),
@ -100,28 +99,24 @@ impl AbstractTree for ValueNode {
ValueType::Map(child_nodes)
}
"function" => {
let parameters_node = child.child_by_field_name("parameters");
let parameters = if let Some(node) = parameters_node {
let mut parameter_list = Vec::new();
let mut identifiers = Vec::new();
for index in 0..node.child_count() {
let child_node = node.child(index).unwrap();
let block_node = child.child(child.child_count() - 1).unwrap();
let block = Block::from_syntax_node(source, block_node)?;
if child_node.is_named() {
let parameter = Identifier::from_syntax_node(source, child_node)?;
for index in 1..child.child_count() - 1 {
let child_node = child.child(index).unwrap();
parameter_list.push(parameter);
}
if child_node.kind() == "identifier" {
let identifier = Identifier::from_syntax_node(source, child_node)?;
identifiers.push(identifier);
}
}
Some(parameter_list)
} else {
None
};
let body_node = child.child_by_field_name("body").unwrap();
let body = Block::from_syntax_node(source, body_node)?;
let function = Function::new(identifiers, block);
ValueType::Function(Function::new(parameters, body))
ValueType::Function(function)
}
_ => {
return Err(Error::UnexpectedSyntaxNode {

View File

@ -174,7 +174,7 @@ mod tests {
assert_eq!(
evaluate(
"
table |messages numbers| [
table <messages, numbers> [
['hiya', 42]
['foo', 57]
['bar', 99.99]
@ -247,7 +247,7 @@ mod tests {
assert_eq!(
evaluate(
"
foobar = |message| => message
foobar = function <message> { message }
(foobar 'Hiya')
",
),

View File

@ -6,19 +6,19 @@ use crate::{Block, Identifier};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Function {
parameters: Option<Vec<Identifier>>,
parameters: Vec<Identifier>,
body: Box<Block>,
}
impl Function {
pub fn new(parameters: Option<Vec<Identifier>>, body: Block) -> Self {
pub fn new(parameters: Vec<Identifier>, body: Block) -> Self {
Function {
parameters,
body: Box::new(body),
}
}
pub fn identifiers(&self) -> &Option<Vec<Identifier>> {
pub fn identifiers(&self) -> &Vec<Identifier> {
&self.parameters
}

View File

@ -2,7 +2,7 @@
Simple Function
================================================================================
=> "Hiya"
function { "Hiya" }
--------------------------------------------------------------------------------
@ -18,30 +18,6 @@ Simple Function
(value
(string)))))))))))
================================================================================
Function Assignment
================================================================================
x = => "Hiya"
--------------------------------------------------------------------------------
(root
(block
(statement
(assignment
(identifier)
(assignment_operator)
(statement
(expression
(value
(function
(block
(statement
(expression
(value
(string)))))))))))))
================================================================================
Function Call
================================================================================
@ -64,7 +40,7 @@ Function Call
Complex Function
================================================================================
|message number| => {
function <message number> {
(output message)
(output number)
}
@ -77,9 +53,8 @@ Complex Function
(expression
(value
(function
(identifier_list
(identifier)
(identifier))
(identifier)
(identifier)
(block
(statement
(expression

View File

@ -24,7 +24,7 @@ if true { "True" }
Complex If
==================
if 1 == 1 && 2 == 2 && 3 == 3 "True"
if 1 == 1 && 2 == 2 && 3 == 3 { "True" }
---
@ -76,11 +76,13 @@ if 1 == 1 && 2 == 2 && 3 == 3 "True"
Nested If
==================
if true
if 42 == 12
if true {
if 42 == 12 {
'hiya'
else
} else {
'bye'
}
}
---

View File

@ -3,7 +3,7 @@ Simple Statements
==================
1
"one";
"one"
x
---
@ -26,7 +26,7 @@ x
Simple Assignment
==================
x = 1;
x = 1
y = "one"
---

View File

@ -2,23 +2,22 @@
Table Declaration
==================
table |messages numbers| [
['hiya' 42]
['foo' 57]
['bar' 99.99]
table <messages, numbers> [
['hiya', 42]
['foo', 57]
['bar', 99.99]
]
---
(root
(block
(statement
(statement
(expression
(value
(table
(identifier_list
(identifier)
(identifier))
(identifier)
(identifier)
(expression
(value
(list
@ -54,7 +53,7 @@ table |messages numbers| [
Table Access
==================
select |number| from foobar {
select <number> from foobar {
text == 'answer'
}
@ -64,8 +63,7 @@ select |number| from foobar {
(block
(statement
(select
(identifier_list
(identifier))
(identifier)
(expression
(identifier))
(block

View File

@ -6,7 +6,6 @@ module.exports = grammar({
extras: $ => [ /\s/, $.comment ],
conflicts: $ => [
[$.block],
[$.map, $.assignment_operator],
],
@ -15,32 +14,29 @@ module.exports = grammar({
comment: $ => /[#][^#\n]*[#|\n]/,
block: $ => choice(
block: $ => prec.right(choice(
repeat1($.statement),
seq('{', repeat1($.statement), '}'),
),
)),
statement: $ => prec.right(seq(
choice(
$.assignment,
$.async,
$.expression,
$.filter,
$.find,
$.for,
$.if_else,
$.insert,
$.match,
$.reduce,
$.remove,
$.select,
$.transform,
$.while,
),
optional(';'),
statement: $ => prec.right(choice(
$.assignment,
$.async,
$.expression,
$.filter,
$.find,
$.for,
$.if_else,
$.insert,
$.match,
$.reduce,
$.remove,
$.select,
$.transform,
$.while,
)),
expression: $ => prec.right(choice(
expression: $ => prec.left(choice(
$._expression_kind,
seq('(', $._expression_kind, ')'),
)),
@ -54,8 +50,6 @@ module.exports = grammar({
$.value,
)),
_expression_list: $ => repeat1(prec.right(seq($.expression, optional(',')))),
identifier: $ => /[_a-zA-Z]+[_a-zA-Z0-9]?/,
value: $ => choice(
@ -117,6 +111,12 @@ module.exports = grammar({
)),
)),
table: $ => prec.left(seq(
'table',
seq('<', repeat1(seq($.identifier, optional(','))), '>'),
$.expression,
)),
math: $ => prec.left(seq(
$.expression,
$.math_operator,
@ -160,28 +160,28 @@ module.exports = grammar({
"-=",
),
if_else: $ => prec.right(seq(
if_else: $ => prec.left(seq(
$.if,
repeat($.else_if),
optional($.else),
)),
if: $ => seq(
if: $ => prec.left(seq(
'if',
$.expression,
$.block,
),
)),
else_if: $ => seq(
else_if: $ => prec.left(seq(
'else if',
$.expression,
$.block,
),
)),
else: $ => seq(
else: $ => prec.left(seq(
'else',
$.block,
),
)),
match: $ => prec.right(seq(
'match',
@ -252,7 +252,9 @@ module.exports = grammar({
select: $ => prec.right(seq(
'select',
$.identifier_list,
'<',
repeat(seq($.identifier, optional(','))),
'>',
'from',
$.expression,
optional($.block),
@ -270,24 +272,10 @@ module.exports = grammar({
$.block,
),
identifier_list: $ => prec.right(choice(
seq(
'|',
repeat(seq($.identifier, optional(','))),
'|',
),
)),
table: $ => prec.right(seq(
'table',
$.identifier_list,
$.expression,
)),
function: $ => seq(
field('parameters', optional($.identifier_list)),
'=>',
field('body', $.block),
'function',
optional(seq('<', repeat(seq($.identifier, optional(','))), '>')),
$.block,
),
function_call: $ => choice(
@ -297,12 +285,12 @@ module.exports = grammar({
_context_defined_function: $ => prec.right(seq(
$.identifier,
optional($._expression_list),
repeat(prec.right(seq($.expression, optional(',')))),
)),
built_in_function: $ => prec.right(seq(
$._built_in_function_name,
optional($._expression_list),
repeat(prec.right(seq($.expression, optional(',')))),
)),
_built_in_function_name: $ => choice(

View File

@ -14,122 +14,109 @@
"value": "[#][^#\\n]*[#|\\n]"
},
"block": {
"type": "CHOICE",
"members": [
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "statement"
}
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "{"
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "statement"
}
},
{
"type": "STRING",
"value": "}"
}
]
}
]
},
"statement": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "assignment"
},
{
"type": "SYMBOL",
"name": "async"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "filter"
},
{
"type": "SYMBOL",
"name": "find"
},
{
"type": "SYMBOL",
"name": "for"
},
{
"type": "SYMBOL",
"name": "if_else"
},
{
"type": "SYMBOL",
"name": "insert"
},
{
"type": "SYMBOL",
"name": "match"
},
{
"type": "SYMBOL",
"name": "reduce"
},
{
"type": "SYMBOL",
"name": "remove"
},
{
"type": "SYMBOL",
"name": "select"
},
{
"type": "SYMBOL",
"name": "transform"
},
{
"type": "SYMBOL",
"name": "while"
}
]
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "statement"
}
},
{
"type": "CHOICE",
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ";"
"value": "{"
},
{
"type": "BLANK"
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "statement"
}
},
{
"type": "STRING",
"value": "}"
}
]
}
]
}
},
"expression": {
"statement": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "assignment"
},
{
"type": "SYMBOL",
"name": "async"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "filter"
},
{
"type": "SYMBOL",
"name": "find"
},
{
"type": "SYMBOL",
"name": "for"
},
{
"type": "SYMBOL",
"name": "if_else"
},
{
"type": "SYMBOL",
"name": "insert"
},
{
"type": "SYMBOL",
"name": "match"
},
{
"type": "SYMBOL",
"name": "reduce"
},
{
"type": "SYMBOL",
"name": "remove"
},
{
"type": "SYMBOL",
"name": "select"
},
{
"type": "SYMBOL",
"name": "transform"
},
{
"type": "SYMBOL",
"name": "while"
}
]
}
},
"expression": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "CHOICE",
"members": [
@ -190,34 +177,6 @@
]
}
},
"_expression_list": {
"type": "REPEAT1",
"content": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
}
},
"identifier": {
"type": "PATTERN",
"value": "[_a-zA-Z]+[_a-zA-Z0-9]?"
@ -600,6 +559,60 @@
]
}
},
"table": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "table"
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "<"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
},
{
"type": "STRING",
"value": ">"
}
]
},
{
"type": "SYMBOL",
"name": "expression"
}
]
}
},
"math": {
"type": "PREC_LEFT",
"value": 0,
@ -739,7 +752,7 @@
]
},
"if_else": {
"type": "PREC_RIGHT",
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
@ -771,51 +784,63 @@
}
},
"if": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "if"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "block"
}
]
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "if"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "block"
}
]
}
},
"else_if": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else if"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "block"
}
]
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else if"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "block"
}
]
}
},
"else": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else"
},
{
"type": "SYMBOL",
"name": "block"
}
]
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else"
},
{
"type": "SYMBOL",
"name": "block"
}
]
}
},
"match": {
"type": "PREC_RIGHT",
@ -1068,8 +1093,36 @@
"value": "select"
},
{
"type": "SYMBOL",
"name": "identifier_list"
"type": "STRING",
"value": "<"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
},
{
"type": "STRING",
"value": ">"
},
{
"type": "STRING",
@ -1132,103 +1185,61 @@
}
]
},
"identifier_list": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
},
{
"type": "STRING",
"value": "|"
}
]
}
]
}
},
"table": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "table"
},
{
"type": "SYMBOL",
"name": "identifier_list"
},
{
"type": "SYMBOL",
"name": "expression"
}
]
}
},
"function": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "parameters",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "identifier_list"
},
{
"type": "BLANK"
}
]
}
},
{
"type": "STRING",
"value": "=>"
"value": "function"
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "block"
}
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "<"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
},
{
"type": "STRING",
"value": ">"
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "block"
}
]
},
@ -1256,16 +1267,32 @@
"name": "identifier"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_expression_list"
},
{
"type": "BLANK"
"type": "REPEAT",
"content": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
]
}
}
]
}
@ -1281,16 +1308,32 @@
"name": "_built_in_function_name"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_expression_list"
},
{
"type": "BLANK"
"type": "REPEAT",
"content": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
]
}
}
]
}
@ -1432,9 +1475,6 @@
}
],
"conflicts": [
[
"block"
],
[
"map",
"assignment_operator"

View File

@ -241,27 +241,20 @@
{
"type": "function",
"named": true,
"fields": {
"body": {
"multiple": false,
"required": true,
"types": [
{
"type": "block",
"named": true
}
]
},
"parameters": {
"multiple": false,
"required": false,
"types": [
{
"type": "identifier_list",
"named": true
}
]
}
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "block",
"named": true
},
{
"type": "identifier",
"named": true
}
]
}
},
{
@ -287,21 +280,6 @@
]
}
},
{
"type": "identifier_list",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "identifier",
"named": true
}
]
}
},
{
"type": "if",
"named": true,
@ -557,7 +535,7 @@
"named": true
},
{
"type": "identifier_list",
"type": "identifier",
"named": true
}
]
@ -643,7 +621,7 @@
"named": true
},
{
"type": "identifier_list",
"type": "identifier",
"named": true
}
]
@ -790,10 +768,6 @@
"type": ":",
"named": false
},
{
"type": ";",
"named": false
},
{
"type": "<",
"named": false
@ -902,6 +876,10 @@
"type": "from_json",
"named": false
},
{
"type": "function",
"named": false
},
{
"type": "help",
"named": false
@ -1058,10 +1036,6 @@
"type": "{",
"named": false
},
{
"type": "|",
"named": false
},
{
"type": "||",
"named": false

File diff suppressed because it is too large Load Diff