Add index expressions to fix parsing bug
This commit is contained in:
parent
346ff1c0da
commit
2f0ec91c08
@ -30,10 +30,6 @@ impl AbstractTree for Identifier {
|
|||||||
|
|
||||||
let text = &source[node.byte_range()];
|
let text = &source[node.byte_range()];
|
||||||
|
|
||||||
if text.is_empty() {
|
|
||||||
println!("{node:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_assert!(!text.is_empty());
|
debug_assert!(!text.is_empty());
|
||||||
|
|
||||||
Ok(Identifier(text.to_string()))
|
Ok(Identifier(text.to_string()))
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{AbstractTree, Error, Expression, List, Map, Result, Type, Value};
|
use crate::{AbstractTree, Error, IndexExpression, List, Map, Result, Type, Value};
|
||||||
|
|
||||||
/// Abstract representation of an index expression.
|
/// Abstract representation of an index expression.
|
||||||
///
|
///
|
||||||
/// An index is a means of accessing values stored in list, maps and strings.
|
/// An index is a means of accessing values stored in list, maps and strings.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Index {
|
pub struct Index {
|
||||||
pub collection: Expression,
|
pub collection: IndexExpression,
|
||||||
pub index: Expression,
|
pub index: IndexExpression,
|
||||||
pub index_end: Option<Expression>,
|
pub index_end: Option<IndexExpression>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Index {
|
impl AbstractTree for Index {
|
||||||
@ -18,14 +18,14 @@ impl AbstractTree for Index {
|
|||||||
Error::expect_syntax_node(source, "index", node)?;
|
Error::expect_syntax_node(source, "index", node)?;
|
||||||
|
|
||||||
let collection_node = node.child(0).unwrap();
|
let collection_node = node.child(0).unwrap();
|
||||||
let collection = Expression::from_syntax_node(source, collection_node, context)?;
|
let collection = IndexExpression::from_syntax_node(source, collection_node, context)?;
|
||||||
|
|
||||||
let index_node = node.child(2).unwrap();
|
let index_node = node.child(2).unwrap();
|
||||||
let index = Expression::from_syntax_node(source, index_node, context)?;
|
let index = IndexExpression::from_syntax_node(source, index_node, context)?;
|
||||||
|
|
||||||
let index_end_node = node.child(4);
|
let index_end_node = node.child(4);
|
||||||
let index_end = if let Some(index_end_node) = index_end_node {
|
let index_end = if let Some(index_end_node) = index_end_node {
|
||||||
Some(Expression::from_syntax_node(
|
Some(IndexExpression::from_syntax_node(
|
||||||
source,
|
source,
|
||||||
index_end_node,
|
index_end_node,
|
||||||
context,
|
context,
|
||||||
@ -60,7 +60,7 @@ impl AbstractTree for Index {
|
|||||||
Ok(item)
|
Ok(item)
|
||||||
}
|
}
|
||||||
Value::Map(map) => {
|
Value::Map(map) => {
|
||||||
let value = if let Expression::Identifier(identifier) = &self.index {
|
let value = if let IndexExpression::Identifier(identifier) = &self.index {
|
||||||
let key = identifier.inner();
|
let key = identifier.inner();
|
||||||
|
|
||||||
map.variables()?
|
map.variables()?
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{AbstractTree, Error, Index, Map, Result, Statement, Type, Value};
|
use crate::{AbstractTree, Error, Index, IndexExpression, Map, Result, Statement, Type, Value};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct IndexAssignment {
|
pub struct IndexAssignment {
|
||||||
@ -52,7 +52,7 @@ impl AbstractTree for IndexAssignment {
|
|||||||
fn run(&self, source: &str, context: &Map) -> Result<Value> {
|
fn run(&self, source: &str, context: &Map) -> Result<Value> {
|
||||||
let index_collection = self.index.collection.run(source, context)?;
|
let index_collection = self.index.collection.run(source, context)?;
|
||||||
let index_context = index_collection.as_map().unwrap_or(context);
|
let index_context = index_collection.as_map().unwrap_or(context);
|
||||||
let index_key = if let crate::Expression::Identifier(identifier) = &self.index.index {
|
let index_key = if let IndexExpression::Identifier(identifier) = &self.index.index {
|
||||||
identifier.inner()
|
identifier.inner()
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::VariableIdentifierNotFound(
|
return Err(Error::VariableIdentifierNotFound(
|
||||||
|
68
src/abstract_tree/index_expression.rs
Normal file
68
src/abstract_tree/index_expression.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
value_node::ValueNode, AbstractTree, Error, FunctionCall, Identifier, Index, Map, Result, Type,
|
||||||
|
Value,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
|
pub enum IndexExpression {
|
||||||
|
Value(ValueNode),
|
||||||
|
Identifier(Identifier),
|
||||||
|
Index(Box<Index>),
|
||||||
|
FunctionCall(Box<FunctionCall>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbstractTree for IndexExpression {
|
||||||
|
fn from_syntax_node(source: &str, node: tree_sitter::Node, context: &Map) -> Result<Self> {
|
||||||
|
Error::expect_syntax_node(source, "index_expression", node)?;
|
||||||
|
|
||||||
|
let first_child = node.child(0).unwrap();
|
||||||
|
let child = if first_child.is_named() {
|
||||||
|
first_child
|
||||||
|
} else {
|
||||||
|
node.child(1).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let abstract_node = match child.kind() {
|
||||||
|
"value" => IndexExpression::Value(ValueNode::from_syntax_node(source, child, context)?),
|
||||||
|
"identifier" => {
|
||||||
|
IndexExpression::Identifier(Identifier::from_syntax_node(source, child, context)?)
|
||||||
|
}
|
||||||
|
"index" => {
|
||||||
|
IndexExpression::Index(Box::new(Index::from_syntax_node(source, child, context)?))
|
||||||
|
}
|
||||||
|
"function_call" => IndexExpression::FunctionCall(Box::new(
|
||||||
|
FunctionCall::from_syntax_node(source, child, context)?,
|
||||||
|
)),
|
||||||
|
_ => {
|
||||||
|
return Err(Error::UnexpectedSyntaxNode {
|
||||||
|
expected: "value, identifier, index or function call".to_string(),
|
||||||
|
actual: child.kind().to_string(),
|
||||||
|
location: child.start_position(),
|
||||||
|
relevant_source: source[child.byte_range()].to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(abstract_node)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, source: &str, context: &Map) -> Result<Value> {
|
||||||
|
match self {
|
||||||
|
IndexExpression::Value(value_node) => value_node.run(source, context),
|
||||||
|
IndexExpression::Identifier(identifier) => identifier.run(source, context),
|
||||||
|
IndexExpression::Index(index) => index.run(source, context),
|
||||||
|
IndexExpression::FunctionCall(function_call) => function_call.run(source, context),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expected_type(&self, context: &Map) -> Result<Type> {
|
||||||
|
match self {
|
||||||
|
IndexExpression::Value(value_node) => value_node.expected_type(context),
|
||||||
|
IndexExpression::Identifier(identifier) => identifier.expected_type(context),
|
||||||
|
IndexExpression::Index(index) => index.expected_type(context),
|
||||||
|
IndexExpression::FunctionCall(function_call) => function_call.expected_type(context),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ pub mod identifier;
|
|||||||
pub mod if_else;
|
pub mod if_else;
|
||||||
pub mod index;
|
pub mod index;
|
||||||
pub mod index_assignment;
|
pub mod index_assignment;
|
||||||
|
pub mod index_expression;
|
||||||
pub mod logic;
|
pub mod logic;
|
||||||
pub mod r#match;
|
pub mod r#match;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
@ -27,8 +28,9 @@ pub mod r#yield;
|
|||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
assignment::*, block::*, expression::*, function_call::*, function_expression::*,
|
assignment::*, block::*, expression::*, function_call::*, function_expression::*,
|
||||||
identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, logic::*, math::*,
|
identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, index_expression::*,
|
||||||
r#for::*, r#match::*, r#while::*, r#yield::*, statement::*, type_definition::*, value_node::*,
|
logic::*, math::*, r#for::*, r#match::*, r#while::*, r#yield::*, statement::*,
|
||||||
|
type_definition::*, value_node::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AbstractTree, Block, Error, Expression, Function, Identifier, List, Map, Result, Statement,
|
value::BuiltInValue, AbstractTree, Block, Error, Expression, Function, Identifier, List, Map,
|
||||||
Type, TypeDefinition, Value,
|
Result, Statement, Type, TypeDefinition, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -18,6 +18,7 @@ pub enum ValueNode {
|
|||||||
List(Vec<Expression>),
|
List(Vec<Expression>),
|
||||||
Option(Option<Box<Expression>>),
|
Option(Option<Box<Expression>>),
|
||||||
Map(BTreeMap<String, (Statement, Option<Type>)>),
|
Map(BTreeMap<String, (Statement, Option<Type>)>),
|
||||||
|
BuiltInValue(BuiltInValue),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for ValueNode {
|
impl AbstractTree for ValueNode {
|
||||||
@ -150,6 +151,15 @@ impl AbstractTree for ValueNode {
|
|||||||
ValueNode::Option(Some(Box::new(expression)))
|
ValueNode::Option(Some(Box::new(expression)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"built_in_value" => {
|
||||||
|
let built_in_value_node = child.child(0).unwrap();
|
||||||
|
|
||||||
|
ValueNode::BuiltInValue(BuiltInValue::from_syntax_node(
|
||||||
|
source,
|
||||||
|
built_in_value_node,
|
||||||
|
context,
|
||||||
|
)?)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::UnexpectedSyntaxNode {
|
return Err(Error::UnexpectedSyntaxNode {
|
||||||
expected: "string, integer, float, boolean, list, map, or option".to_string(),
|
expected: "string, integer, float, boolean, list, map, or option".to_string(),
|
||||||
@ -203,6 +213,7 @@ impl AbstractTree for ValueNode {
|
|||||||
|
|
||||||
Value::Map(map)
|
Value::Map(map)
|
||||||
}
|
}
|
||||||
|
ValueNode::BuiltInValue(built_in_value) => built_in_value.run(source, context)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
@ -244,6 +255,7 @@ impl AbstractTree for ValueNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ValueNode::Map(_) => Type::Map,
|
ValueNode::Map(_) => Type::Map,
|
||||||
|
ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(r#type)
|
Ok(r#type)
|
||||||
|
@ -223,5 +223,6 @@ fn display_value(value: &Value, ui: &mut egui::Ui) {
|
|||||||
ui.label("none");
|
ui.label("none");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Value::BuiltIn(_) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,13 @@ mod option;
|
|||||||
mod output;
|
mod output;
|
||||||
mod packages;
|
mod packages;
|
||||||
mod random;
|
mod random;
|
||||||
mod std;
|
|
||||||
mod r#type;
|
mod r#type;
|
||||||
|
|
||||||
/// All built-in functions recognized by the interpreter.
|
/// All built-in functions recognized by the interpreter.
|
||||||
///
|
///
|
||||||
/// This is the public interface to access built-in functions by iterating over
|
/// This is the public interface to access built-in functions by iterating over
|
||||||
/// the references it holds.
|
/// the references it holds.
|
||||||
pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 22] = [
|
pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 21] = [
|
||||||
&assert::Assert,
|
&assert::Assert,
|
||||||
&assert::AssertEqual,
|
&assert::AssertEqual,
|
||||||
&collections::Length,
|
&collections::Length,
|
||||||
@ -39,7 +38,6 @@ pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 22] = [
|
|||||||
&random::RandomBoolean,
|
&random::RandomBoolean,
|
||||||
&random::RandomFloat,
|
&random::RandomFloat,
|
||||||
&random::RandomInteger,
|
&random::RandomInteger,
|
||||||
&std::Std,
|
|
||||||
&r#type::TypeFunction,
|
&r#type::TypeFunction,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
use std::sync::OnceLock;
|
|
||||||
|
|
||||||
use crate::{interpret_with_context, BuiltInFunction, Error, Map, Result, Type, Value};
|
|
||||||
|
|
||||||
static STD: OnceLock<Map> = OnceLock::new();
|
|
||||||
|
|
||||||
pub struct Std;
|
|
||||||
|
|
||||||
impl BuiltInFunction for Std {
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
"std"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run(&self, arguments: &[Value], _context: &Map) -> Result<Value> {
|
|
||||||
Error::expect_argument_amount(self, 0, arguments.len())?;
|
|
||||||
|
|
||||||
let std_context = STD.get_or_init(|| {
|
|
||||||
let std_source = "say_hi = () <none> { output('hi') }";
|
|
||||||
let std_context = Map::new();
|
|
||||||
|
|
||||||
interpret_with_context(std_source, std_context.clone()).unwrap();
|
|
||||||
|
|
||||||
std_context
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(Value::Map(std_context.clone()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn r#type(&self) -> Type {
|
|
||||||
Type::Function {
|
|
||||||
parameter_types: vec![],
|
|
||||||
return_type: Box::new(Type::Map),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
//! Types that represent runtime values.
|
//! Types that represent runtime values.
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
Function, List, Map, Type,
|
interpret_with_context, AbstractTree, Function, List, Map, Type,
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::{
|
use serde::{
|
||||||
@ -9,6 +9,7 @@ use serde::{
|
|||||||
ser::SerializeTuple,
|
ser::SerializeTuple,
|
||||||
Deserialize, Serialize, Serializer,
|
Deserialize, Serialize, Serializer,
|
||||||
};
|
};
|
||||||
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
@ -16,12 +17,60 @@ use std::{
|
|||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ops::{Add, AddAssign, Div, Mul, Rem, Sub, SubAssign},
|
ops::{Add, AddAssign, Div, Mul, Rem, Sub, SubAssign},
|
||||||
|
sync::OnceLock,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod function;
|
pub mod function;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
|
|
||||||
|
static STD: OnceLock<Value> = OnceLock::new();
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
pub enum BuiltInValue {
|
||||||
|
Std,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuiltInValue {
|
||||||
|
fn r#type(&self) -> Type {
|
||||||
|
match self {
|
||||||
|
BuiltInValue::Std => Type::Map,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self) -> &Value {
|
||||||
|
STD.get_or_init(|| {
|
||||||
|
let std_source = "foobar = () <str> { 'foobar' }";
|
||||||
|
let std_context = Map::new();
|
||||||
|
|
||||||
|
interpret_with_context(std_source, std_context.clone()).unwrap();
|
||||||
|
|
||||||
|
Value::Map(std_context)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbstractTree for BuiltInValue {
|
||||||
|
fn from_syntax_node(_source: &str, node: Node, _context: &Map) -> Result<Self> {
|
||||||
|
let built_in_value = match node.kind() {
|
||||||
|
"std" => BuiltInValue::Std,
|
||||||
|
_ => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(built_in_value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, _source: &str, _context: &Map) -> Result<Value> {
|
||||||
|
Ok(self.get().clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expected_type(&self, _context: &Map) -> Result<Type> {
|
||||||
|
match self {
|
||||||
|
BuiltInValue::Std => Ok(Type::Map),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Dust value representation.
|
/// Dust value representation.
|
||||||
///
|
///
|
||||||
/// Every dust variable has a key and a Value. Variables are represented by
|
/// Every dust variable has a key and a Value. Variables are represented by
|
||||||
@ -37,6 +86,7 @@ pub enum Value {
|
|||||||
Integer(i64),
|
Integer(i64),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Option(Option<Box<Value>>),
|
Option(Option<Box<Value>>),
|
||||||
|
BuiltIn(BuiltInValue),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Value {
|
impl Default for Value {
|
||||||
@ -82,6 +132,7 @@ impl Value {
|
|||||||
Type::None
|
Type::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Value::BuiltIn(built_in_value) => built_in_value.r#type(),
|
||||||
};
|
};
|
||||||
|
|
||||||
r#type
|
r#type
|
||||||
@ -420,6 +471,8 @@ impl PartialOrd for Value {
|
|||||||
impl Ord for Value {
|
impl Ord for Value {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
|
(Value::BuiltIn(left), Value::BuiltIn(right)) => left.cmp(right),
|
||||||
|
(Value::BuiltIn(_), _) => Ordering::Greater,
|
||||||
(Value::String(left), Value::String(right)) => left.cmp(right),
|
(Value::String(left), Value::String(right)) => left.cmp(right),
|
||||||
(Value::String(_), _) => Ordering::Greater,
|
(Value::String(_), _) => Ordering::Greater,
|
||||||
(Value::Float(left), Value::Float(right)) => left.total_cmp(right),
|
(Value::Float(left), Value::Float(right)) => left.total_cmp(right),
|
||||||
@ -471,6 +524,7 @@ impl Serialize for Value {
|
|||||||
Value::Option(inner) => inner.serialize(serializer),
|
Value::Option(inner) => inner.serialize(serializer),
|
||||||
Value::Map(inner) => inner.serialize(serializer),
|
Value::Map(inner) => inner.serialize(serializer),
|
||||||
Value::Function(inner) => inner.serialize(serializer),
|
Value::Function(inner) => inner.serialize(serializer),
|
||||||
|
Value::BuiltIn(inner) => inner.serialize(serializer),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -498,6 +552,7 @@ impl Display for Value {
|
|||||||
}
|
}
|
||||||
Value::Map(map) => write!(f, "{map}"),
|
Value::Map(map) => write!(f, "{map}"),
|
||||||
Value::Function(function) => write!(f, "{function}"),
|
Value::Function(function) => write!(f, "{function}"),
|
||||||
|
Value::BuiltIn(_) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ mod index {
|
|||||||
"
|
"
|
||||||
x = [1 2 3]
|
x = [1 2 3]
|
||||||
y = () <int> { 2 }
|
y = () <int> { 2 }
|
||||||
x:y()
|
x:(y())
|
||||||
",
|
",
|
||||||
),
|
),
|
||||||
Ok(Value::Integer(3))
|
Ok(Value::Integer(3))
|
||||||
@ -356,7 +356,7 @@ mod index {
|
|||||||
x = {
|
x = {
|
||||||
y = () <int> { 2 }
|
y = () <int> { 2 }
|
||||||
}
|
}
|
||||||
(x:y)()
|
x:y()
|
||||||
",
|
",
|
||||||
),
|
),
|
||||||
Ok(Value::Integer(2))
|
Ok(Value::Integer(2))
|
||||||
|
@ -46,9 +46,9 @@ x:y = 1
|
|||||||
(statement
|
(statement
|
||||||
(index_assignment
|
(index_assignment
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(identifier))
|
(identifier))
|
||||||
(expression
|
(index_expression
|
||||||
(identifier)))
|
(identifier)))
|
||||||
(assignment_operator)
|
(assignment_operator)
|
||||||
(statement
|
(statement
|
||||||
@ -68,9 +68,9 @@ x:9 = 'foobar'
|
|||||||
(statement
|
(statement
|
||||||
(index_assignment
|
(index_assignment
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(identifier))
|
(identifier))
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(value
|
||||||
(integer))))
|
(integer))))
|
||||||
(assignment_operator)
|
(assignment_operator)
|
||||||
|
@ -85,16 +85,16 @@ foo:bar("Hiya")
|
|||||||
(root
|
(root
|
||||||
(statement
|
(statement
|
||||||
(expression
|
(expression
|
||||||
(index
|
(function_call
|
||||||
(expression
|
(function_expression
|
||||||
(identifier))
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(function_call
|
|
||||||
(function_expression
|
|
||||||
(identifier))
|
(identifier))
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(identifier))))
|
||||||
(string)))))))))
|
(expression
|
||||||
|
(value
|
||||||
|
(string)))))))
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
Double Function Call
|
Double Function Call
|
||||||
|
@ -14,33 +14,33 @@ foobar:1:42
|
|||||||
(statement
|
(statement
|
||||||
(expression
|
(expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(identifier))
|
(identifier))
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(value
|
||||||
(integer)))))
|
(integer)))))
|
||||||
(expression
|
(index_expression
|
||||||
(identifier)))))
|
(identifier)))))
|
||||||
(statement
|
(statement
|
||||||
(expression
|
(expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(identifier))
|
(identifier))
|
||||||
(expression
|
(index_expression
|
||||||
(identifier)))))
|
(identifier)))))
|
||||||
(statement
|
(statement
|
||||||
(expression
|
(expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(identifier))
|
(identifier))
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(value
|
||||||
(integer)))))
|
(integer)))))
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(value
|
||||||
(integer)))))))
|
(integer)))))))
|
||||||
|
|
||||||
@ -56,11 +56,11 @@ Nested Indexes
|
|||||||
(statement
|
(statement
|
||||||
(expression
|
(expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(value
|
||||||
(list
|
(list
|
||||||
(expression
|
(expression
|
||||||
@ -78,13 +78,13 @@ Nested Indexes
|
|||||||
(expression
|
(expression
|
||||||
(value
|
(value
|
||||||
(integer))))))
|
(integer))))))
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(value
|
||||||
(integer)))))
|
(integer)))))
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(value
|
||||||
(integer)))))
|
(integer)))))
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(value
|
||||||
(integer)))
|
(integer)))
|
||||||
(expression
|
(expression
|
||||||
@ -95,7 +95,7 @@ Nested Indexes
|
|||||||
Function Call Index
|
Function Call Index
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
x:y():0
|
x:(y()):0
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -103,14 +103,14 @@ x:y():0
|
|||||||
(statement
|
(statement
|
||||||
(expression
|
(expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(index
|
(index
|
||||||
(expression
|
(index_expression
|
||||||
(identifier))
|
(identifier))
|
||||||
(expression
|
(index_expression
|
||||||
(function_call
|
(function_call
|
||||||
(function_expression
|
(function_expression
|
||||||
(identifier))))))
|
(identifier))))))
|
||||||
(expression
|
(index_expression
|
||||||
(value
|
(value
|
||||||
(integer)))))))
|
(integer)))))))
|
||||||
|
@ -89,6 +89,7 @@ module.exports = grammar({
|
|||||||
$.list,
|
$.list,
|
||||||
$.map,
|
$.map,
|
||||||
$.option,
|
$.option,
|
||||||
|
$.built_in_value,
|
||||||
),
|
),
|
||||||
|
|
||||||
integer: $ =>
|
integer: $ =>
|
||||||
@ -202,15 +203,30 @@ module.exports = grammar({
|
|||||||
prec.left(
|
prec.left(
|
||||||
1,
|
1,
|
||||||
seq(
|
seq(
|
||||||
$.expression,
|
$.index_expression,
|
||||||
':',
|
':',
|
||||||
$.expression,
|
$.index_expression,
|
||||||
optional(
|
optional(
|
||||||
seq('..', $.expression),
|
seq('..', $.expression),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
index_expression: $ =>
|
||||||
|
prec(
|
||||||
|
1,
|
||||||
|
choice(
|
||||||
|
seq(
|
||||||
|
'(',
|
||||||
|
$.function_call,
|
||||||
|
')',
|
||||||
|
),
|
||||||
|
$.identifier,
|
||||||
|
$.index,
|
||||||
|
$.value,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
math: $ =>
|
math: $ =>
|
||||||
prec.left(
|
prec.left(
|
||||||
seq(
|
seq(
|
||||||
@ -388,8 +404,9 @@ module.exports = grammar({
|
|||||||
|
|
||||||
_function_expression_kind: $ =>
|
_function_expression_kind: $ =>
|
||||||
prec(
|
prec(
|
||||||
1,
|
2,
|
||||||
choice(
|
choice(
|
||||||
|
$.built_in_value,
|
||||||
$.function,
|
$.function,
|
||||||
$.function_call,
|
$.function_call,
|
||||||
$.identifier,
|
$.identifier,
|
||||||
@ -397,6 +414,7 @@ module.exports = grammar({
|
|||||||
$.yield,
|
$.yield,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
function_call: $ =>
|
function_call: $ =>
|
||||||
prec.right(
|
prec.right(
|
||||||
seq(
|
seq(
|
||||||
@ -447,5 +465,7 @@ module.exports = grammar({
|
|||||||
'to_json',
|
'to_json',
|
||||||
'write',
|
'write',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
built_in_value: $ => choice('std'),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -253,6 +253,10 @@
|
|||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "option"
|
"name": "option"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "built_in_value"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -605,7 +609,7 @@
|
|||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "expression"
|
"name": "index_expression"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
@ -613,7 +617,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "expression"
|
"name": "index_expression"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "CHOICE",
|
"type": "CHOICE",
|
||||||
@ -639,6 +643,44 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"index_expression": {
|
||||||
|
"type": "PREC",
|
||||||
|
"value": 1,
|
||||||
|
"content": {
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "("
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "function_call"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": ")"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "identifier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "index"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"math": {
|
"math": {
|
||||||
"type": "PREC_LEFT",
|
"type": "PREC_LEFT",
|
||||||
"value": 0,
|
"value": 0,
|
||||||
@ -1258,10 +1300,14 @@
|
|||||||
},
|
},
|
||||||
"_function_expression_kind": {
|
"_function_expression_kind": {
|
||||||
"type": "PREC",
|
"type": "PREC",
|
||||||
"value": 1,
|
"value": 2,
|
||||||
"content": {
|
"content": {
|
||||||
"type": "CHOICE",
|
"type": "CHOICE",
|
||||||
"members": [
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "built_in_value"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "function"
|
"name": "function"
|
||||||
@ -1448,6 +1494,15 @@
|
|||||||
"value": "write"
|
"value": "write"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"built_in_value": {
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "std"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"extras": [
|
"extras": [
|
||||||
|
@ -56,6 +56,11 @@
|
|||||||
"named": true,
|
"named": true,
|
||||||
"fields": {}
|
"fields": {}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "built_in_value",
|
||||||
|
"named": true,
|
||||||
|
"fields": {}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "else",
|
"type": "else",
|
||||||
"named": true,
|
"named": true,
|
||||||
@ -202,6 +207,10 @@
|
|||||||
"multiple": false,
|
"multiple": false,
|
||||||
"required": true,
|
"required": true,
|
||||||
"types": [
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "built_in_value",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "function",
|
"type": "function",
|
||||||
"named": true
|
"named": true
|
||||||
@ -293,6 +302,10 @@
|
|||||||
{
|
{
|
||||||
"type": "expression",
|
"type": "expression",
|
||||||
"named": true
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "index_expression",
|
||||||
|
"named": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -320,6 +333,33 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "index_expression",
|
||||||
|
"named": true,
|
||||||
|
"fields": {},
|
||||||
|
"children": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "function_call",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "identifier",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "index",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "value",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "list",
|
"type": "list",
|
||||||
"named": true,
|
"named": true,
|
||||||
@ -559,6 +599,10 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "built_in_value",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"named": true
|
"named": true
|
||||||
@ -884,6 +928,10 @@
|
|||||||
"type": "some",
|
"type": "some",
|
||||||
"named": false
|
"named": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "std",
|
||||||
|
"named": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"named": false
|
"named": false
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user