Begin completing syntax revision
This commit is contained in:
parent
ea4ffb492c
commit
d1b116cc35
@ -3,28 +3,20 @@ 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 '
|
||||
@ -32,7 +24,7 @@ make_guess = function <current_room> {
|
||||
+ ' with the '
|
||||
+ weapons:0
|
||||
+ '!')
|
||||
} else {
|
||||
else
|
||||
(output 'I accuse '
|
||||
+ (random suspects)
|
||||
+ ' in the '
|
||||
@ -40,7 +32,5 @@ make_guess = function <current_room> {
|
||||
+ ' with the '
|
||||
+ (random weapons)
|
||||
+ '!')
|
||||
}
|
||||
}
|
||||
|
||||
(make_guess 'Library')
|
||||
|
@ -286,6 +286,7 @@ impl AbstractTree for BuiltInFunction {
|
||||
}
|
||||
BuiltInFunction::AssertEqual(expressions) => {
|
||||
let mut prev_value = None;
|
||||
|
||||
for expression in expressions {
|
||||
let value = expression.run(source, context)?;
|
||||
|
||||
|
@ -24,7 +24,7 @@ impl AbstractTree for FunctionCall {
|
||||
for index in 1..node.child_count() {
|
||||
let child = node.child(index).unwrap();
|
||||
|
||||
if child.kind() == "expression" {
|
||||
if child.is_named() {
|
||||
let expression = Expression::from_syntax_node(source, child)?;
|
||||
|
||||
arguments.push(expression);
|
||||
@ -59,13 +59,16 @@ 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());
|
||||
|
||||
for (identifier, expression) in identifier_expression_pairs {
|
||||
let key = identifier.inner().clone();
|
||||
let value = expression.run(source, context)?;
|
||||
if let Some(parameters) = definition.identifiers() {
|
||||
let parameter_expression_pairs = parameters.iter().zip(arguments.iter());
|
||||
|
||||
function_context.variables_mut().insert(key, value);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
definition.body().run(source, &mut function_context)
|
||||
|
@ -55,22 +55,23 @@ impl AbstractTree for ValueNode {
|
||||
ValueType::List(expressions)
|
||||
}
|
||||
"table" => {
|
||||
let child_count = child.child_count();
|
||||
let mut column_names = Vec::new();
|
||||
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 expression_node = child.child(child_count - 1).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
for index in 0..identifier_count {
|
||||
let identifier_node = identifier_list_node.child(index).unwrap();
|
||||
|
||||
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)?;
|
||||
if identifier_node.is_named() {
|
||||
let identifier = Identifier::from_syntax_node(source, identifier_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),
|
||||
@ -99,24 +100,28 @@ impl AbstractTree for ValueNode {
|
||||
ValueType::Map(child_nodes)
|
||||
}
|
||||
"function" => {
|
||||
let mut identifiers = Vec::new();
|
||||
let parameters_node = child.child_by_field_name("parameters");
|
||||
let parameters = if let Some(node) = parameters_node {
|
||||
let mut parameter_list = Vec::new();
|
||||
|
||||
let block_node = child.child(child.child_count() - 1).unwrap();
|
||||
let block = Block::from_syntax_node(source, block_node)?;
|
||||
for index in 0..node.child_count() {
|
||||
let child_node = node.child(index).unwrap();
|
||||
|
||||
for index in 1..child.child_count() - 1 {
|
||||
let child_node = child.child(index).unwrap();
|
||||
if child_node.is_named() {
|
||||
let parameter = Identifier::from_syntax_node(source, child_node)?;
|
||||
|
||||
if child_node.kind() == "identifier" {
|
||||
let identifier = Identifier::from_syntax_node(source, child_node)?;
|
||||
|
||||
identifiers.push(identifier);
|
||||
parameter_list.push(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let function = Function::new(identifiers, block);
|
||||
Some(parameter_list)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let body_node = child.child_by_field_name("body").unwrap();
|
||||
let body = Block::from_syntax_node(source, body_node)?;
|
||||
|
||||
ValueType::Function(function)
|
||||
ValueType::Function(Function::new(parameters, body))
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::UnexpectedSyntaxNode {
|
||||
|
@ -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 = function <message> { message }
|
||||
foobar = |message| => message
|
||||
(foobar 'Hiya')
|
||||
",
|
||||
),
|
||||
|
@ -6,19 +6,19 @@ use crate::{Block, Identifier};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub struct Function {
|
||||
parameters: Vec<Identifier>,
|
||||
parameters: Option<Vec<Identifier>>,
|
||||
body: Box<Block>,
|
||||
}
|
||||
|
||||
impl Function {
|
||||
pub fn new(parameters: Vec<Identifier>, body: Block) -> Self {
|
||||
pub fn new(parameters: Option<Vec<Identifier>>, body: Block) -> Self {
|
||||
Function {
|
||||
parameters,
|
||||
body: Box::new(body),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identifiers(&self) -> &Vec<Identifier> {
|
||||
pub fn identifiers(&self) -> &Option<Vec<Identifier>> {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
Simple Function
|
||||
================================================================================
|
||||
|
||||
function { "Hiya" }
|
||||
=> "Hiya"
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -18,6 +18,30 @@ function { "Hiya" }
|
||||
(value
|
||||
(string)))))))))))
|
||||
|
||||
================================================================================
|
||||
Function Assignment
|
||||
================================================================================
|
||||
|
||||
x = => "Hiya"
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
(statement
|
||||
(assignment
|
||||
(identifier)
|
||||
(assignment_operator)
|
||||
(statement
|
||||
(expression
|
||||
(value
|
||||
(function
|
||||
(block
|
||||
(statement
|
||||
(expression
|
||||
(value
|
||||
(string)))))))))))))
|
||||
|
||||
================================================================================
|
||||
Function Call
|
||||
================================================================================
|
||||
@ -40,7 +64,7 @@ Function Call
|
||||
Complex Function
|
||||
================================================================================
|
||||
|
||||
function <message number> {
|
||||
|message number| => {
|
||||
(output message)
|
||||
(output number)
|
||||
}
|
||||
@ -53,7 +77,7 @@ function <message number> {
|
||||
(expression
|
||||
(value
|
||||
(function
|
||||
(parameter_list
|
||||
(identifier_list
|
||||
(identifier)
|
||||
(identifier))
|
||||
(block
|
||||
|
@ -2,7 +2,7 @@
|
||||
Table Declaration
|
||||
==================
|
||||
|
||||
table messages numbers [
|
||||
table |messages numbers| [
|
||||
['hiya' 42]
|
||||
['foo' 57]
|
||||
['bar' 99.99]
|
||||
@ -16,7 +16,7 @@ table messages numbers [
|
||||
(expression
|
||||
(value
|
||||
(table
|
||||
(parameter_list
|
||||
(identifier_list
|
||||
(identifier)
|
||||
(identifier))
|
||||
(expression
|
||||
@ -54,7 +54,7 @@ table messages numbers [
|
||||
Table Access
|
||||
==================
|
||||
|
||||
select <number> from foobar {
|
||||
select |number| from foobar {
|
||||
text == 'answer'
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ select <number> from foobar {
|
||||
(block
|
||||
(statement
|
||||
(select
|
||||
(parameter_list
|
||||
(identifier_list
|
||||
(identifier))
|
||||
(expression
|
||||
(identifier))
|
||||
|
@ -6,6 +6,7 @@ module.exports = grammar({
|
||||
extras: $ => [ /\s/, $.comment ],
|
||||
|
||||
conflicts: $ => [
|
||||
[$.block],
|
||||
[$.map, $.assignment_operator],
|
||||
],
|
||||
|
||||
@ -14,10 +15,10 @@ module.exports = grammar({
|
||||
|
||||
comment: $ => /[#][^#\n]*[#|\n]/,
|
||||
|
||||
block: $ => prec.right(choice(
|
||||
block: $ => choice(
|
||||
repeat1($.statement),
|
||||
seq('{', repeat1($.statement), '}'),
|
||||
)),
|
||||
),
|
||||
|
||||
statement: $ => prec.right(seq(
|
||||
choice(
|
||||
@ -116,19 +117,6 @@ module.exports = grammar({
|
||||
)),
|
||||
)),
|
||||
|
||||
_identifier_list: $ => repeat1(seq($.identifier, optional(','))),
|
||||
|
||||
parameter_list: $ => prec.right(choice(
|
||||
$._identifier_list,
|
||||
seq('<', $._identifier_list, '>'),
|
||||
)),
|
||||
|
||||
table: $ => prec.right(seq(
|
||||
'table',
|
||||
$.parameter_list,
|
||||
$.expression,
|
||||
)),
|
||||
|
||||
math: $ => prec.left(seq(
|
||||
$.expression,
|
||||
$.math_operator,
|
||||
@ -264,7 +252,7 @@ module.exports = grammar({
|
||||
|
||||
select: $ => prec.right(seq(
|
||||
'select',
|
||||
$.parameter_list,
|
||||
$.identifier_list,
|
||||
'from',
|
||||
$.expression,
|
||||
optional($.block),
|
||||
@ -282,10 +270,24 @@ module.exports = grammar({
|
||||
$.block,
|
||||
),
|
||||
|
||||
identifier_list: $ => prec.right(choice(
|
||||
seq(
|
||||
'|',
|
||||
repeat(seq($.identifier, optional(','))),
|
||||
'|',
|
||||
),
|
||||
)),
|
||||
|
||||
table: $ => prec.right(seq(
|
||||
'table',
|
||||
$.identifier_list,
|
||||
$.expression,
|
||||
)),
|
||||
|
||||
function: $ => seq(
|
||||
'function',
|
||||
optional($.parameter_list),
|
||||
$.block,
|
||||
field('parameters', optional($.identifier_list)),
|
||||
'=>',
|
||||
field('body', $.block),
|
||||
),
|
||||
|
||||
function_call: $ => choice(
|
||||
|
@ -14,40 +14,36 @@
|
||||
"value": "[#][^#\\n]*[#|\\n]"
|
||||
},
|
||||
"block": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"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": "}"
|
||||
}
|
||||
]
|
||||
"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",
|
||||
@ -604,81 +600,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"_identifier_list": {
|
||||
"type": "REPEAT1",
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "identifier"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ","
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"parameter_list": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_identifier_list"
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "<"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_identifier_list"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ">"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "table"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "parameter_list"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "expression"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"math": {
|
||||
"type": "PREC_LEFT",
|
||||
"value": 0,
|
||||
@ -1148,7 +1069,7 @@
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "parameter_list"
|
||||
"name": "identifier_list"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
@ -1211,28 +1132,103 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"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": "function"
|
||||
"value": "=>"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "parameter_list"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "block"
|
||||
"type": "FIELD",
|
||||
"name": "body",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "block"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -1436,6 +1432,9 @@
|
||||
}
|
||||
],
|
||||
"conflicts": [
|
||||
[
|
||||
"block"
|
||||
],
|
||||
[
|
||||
"map",
|
||||
"assignment_operator"
|
||||
|
@ -241,20 +241,27 @@
|
||||
{
|
||||
"type": "function",
|
||||
"named": true,
|
||||
"fields": {},
|
||||
"children": {
|
||||
"multiple": true,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "block",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "parameter_list",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
"fields": {
|
||||
"body": {
|
||||
"multiple": false,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "block",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"parameters": {
|
||||
"multiple": false,
|
||||
"required": false,
|
||||
"types": [
|
||||
{
|
||||
"type": "identifier_list",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -280,6 +287,21 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "identifier_list",
|
||||
"named": true,
|
||||
"fields": {},
|
||||
"children": {
|
||||
"multiple": true,
|
||||
"required": false,
|
||||
"types": [
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "if",
|
||||
"named": true,
|
||||
@ -457,21 +479,6 @@
|
||||
"named": true,
|
||||
"fields": {}
|
||||
},
|
||||
{
|
||||
"type": "parameter_list",
|
||||
"named": true,
|
||||
"fields": {},
|
||||
"children": {
|
||||
"multiple": true,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "reduce",
|
||||
"named": true,
|
||||
@ -550,7 +557,7 @@
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "parameter_list",
|
||||
"type": "identifier_list",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
@ -636,7 +643,7 @@
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "parameter_list",
|
||||
"type": "identifier_list",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
@ -895,10 +902,6 @@
|
||||
"type": "from_json",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
"named": false
|
||||
@ -1055,6 +1058,10 @@
|
||||
"type": "{",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "|",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "||",
|
||||
"named": false
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user