Refactor to move assingment out of other binary operations
This commit is contained in:
parent
b1337900fb
commit
5757f52dbd
@ -34,6 +34,12 @@ impl<T: Display> Display for Node<T> {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
|
Assignment {
|
||||||
|
identifier: Node<Identifier>,
|
||||||
|
operator: Node<AssignmentOperator>,
|
||||||
|
value: Box<Node<Statement>>,
|
||||||
|
},
|
||||||
|
|
||||||
// A sequence of statements
|
// A sequence of statements
|
||||||
Block(Vec<Node<Statement>>),
|
Block(Vec<Node<Statement>>),
|
||||||
|
|
||||||
@ -99,7 +105,7 @@ pub enum Statement {
|
|||||||
|
|
||||||
// Value collection expressions
|
// Value collection expressions
|
||||||
List(Vec<Node<Statement>>),
|
List(Vec<Node<Statement>>),
|
||||||
Map(Vec<(Node<Statement>, Node<Statement>)>),
|
Map(Vec<(Node<Identifier>, Node<Statement>)>),
|
||||||
|
|
||||||
// Hard-coded value
|
// Hard-coded value
|
||||||
Constant(Value),
|
Constant(Value),
|
||||||
@ -112,6 +118,7 @@ pub enum Statement {
|
|||||||
impl Statement {
|
impl Statement {
|
||||||
pub fn expected_type(&self, context: &Context) -> Option<Type> {
|
pub fn expected_type(&self, context: &Context) -> Option<Type> {
|
||||||
match self {
|
match self {
|
||||||
|
Statement::Assignment { .. } => None,
|
||||||
Statement::Block(nodes) => nodes.last().unwrap().inner.expected_type(context),
|
Statement::Block(nodes) => nodes.last().unwrap().inner.expected_type(context),
|
||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left,
|
left,
|
||||||
@ -132,8 +139,6 @@ impl Statement {
|
|||||||
| BinaryOperator::And
|
| BinaryOperator::And
|
||||||
| BinaryOperator::Or => Some(Type::Boolean),
|
| BinaryOperator::Or => Some(Type::Boolean),
|
||||||
|
|
||||||
BinaryOperator::Assign | BinaryOperator::AddAssign => None,
|
|
||||||
|
|
||||||
BinaryOperator::FieldAccess => {
|
BinaryOperator::FieldAccess => {
|
||||||
let left_type = left.inner.expected_type(context)?;
|
let left_type = left.inner.expected_type(context)?;
|
||||||
|
|
||||||
@ -180,9 +185,7 @@ impl Statement {
|
|||||||
let mut types = BTreeMap::new();
|
let mut types = BTreeMap::new();
|
||||||
|
|
||||||
for (identifier, item) in nodes {
|
for (identifier, item) in nodes {
|
||||||
if let Statement::Identifier(identifier) = &identifier.inner {
|
types.insert(identifier.inner.clone(), item.inner.expected_type(context)?);
|
||||||
types.insert(identifier.clone(), item.inner.expected_type(context)?);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Type::Map(types))
|
Some(Type::Map(types))
|
||||||
@ -215,7 +218,7 @@ impl Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_properties_mut(&mut self) -> Option<&mut Vec<(Node<Statement>, Node<Statement>)>> {
|
pub fn map_properties_mut(&mut self) -> Option<&mut Vec<(Node<Identifier>, Node<Statement>)>> {
|
||||||
match self {
|
match self {
|
||||||
Statement::Map(properties) => Some(properties),
|
Statement::Map(properties) => Some(properties),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -226,6 +229,13 @@ impl Statement {
|
|||||||
impl Display for Statement {
|
impl Display for Statement {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
Statement::Assignment {
|
||||||
|
identifier,
|
||||||
|
operator,
|
||||||
|
value,
|
||||||
|
} => {
|
||||||
|
write!(f, "{identifier} {operator} {value}")
|
||||||
|
}
|
||||||
Statement::Block(statements) => {
|
Statement::Block(statements) => {
|
||||||
write!(f, "{{ ")?;
|
write!(f, "{{ ")?;
|
||||||
|
|
||||||
@ -248,8 +258,6 @@ impl Display for Statement {
|
|||||||
BinaryOperator::FieldAccess => return write!(f, "{left}.{right}"),
|
BinaryOperator::FieldAccess => return write!(f, "{left}.{right}"),
|
||||||
BinaryOperator::ListIndex => return write!(f, "{left}[{right}]"),
|
BinaryOperator::ListIndex => return write!(f, "{left}[{right}]"),
|
||||||
BinaryOperator::Add => "+",
|
BinaryOperator::Add => "+",
|
||||||
BinaryOperator::AddAssign => "+=",
|
|
||||||
BinaryOperator::Assign => "=",
|
|
||||||
BinaryOperator::Divide => "/",
|
BinaryOperator::Divide => "/",
|
||||||
BinaryOperator::Equal => "==",
|
BinaryOperator::Equal => "==",
|
||||||
BinaryOperator::Greater => ">",
|
BinaryOperator::Greater => ">",
|
||||||
@ -422,6 +430,25 @@ impl Display for Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
pub enum AssignmentOperator {
|
||||||
|
Assign,
|
||||||
|
AddAssign,
|
||||||
|
SubtractAssign,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for AssignmentOperator {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
let operator = match self {
|
||||||
|
AssignmentOperator::Assign => "=",
|
||||||
|
AssignmentOperator::AddAssign => "+=",
|
||||||
|
AssignmentOperator::SubtractAssign => "-=",
|
||||||
|
};
|
||||||
|
|
||||||
|
write!(f, "{operator}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum BinaryOperator {
|
pub enum BinaryOperator {
|
||||||
// Accessors
|
// Accessors
|
||||||
@ -445,10 +472,6 @@ pub enum BinaryOperator {
|
|||||||
// Logic
|
// Logic
|
||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
|
|
||||||
// Assignment
|
|
||||||
Assign,
|
|
||||||
AddAssign,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
@ -75,28 +75,29 @@ impl<'a> Analyzer<'a> {
|
|||||||
|
|
||||||
fn analyze_statement(&mut self, node: &Node<Statement>) -> Result<(), AnalyzerError> {
|
fn analyze_statement(&mut self, node: &Node<Statement>) -> Result<(), AnalyzerError> {
|
||||||
match &node.inner {
|
match &node.inner {
|
||||||
|
Statement::Assignment {
|
||||||
|
identifier, value, ..
|
||||||
|
} => {
|
||||||
|
self.analyze_statement(value)?;
|
||||||
|
|
||||||
|
let value_type = value.inner.expected_type(self.context);
|
||||||
|
|
||||||
|
if let Some(r#type) = value_type {
|
||||||
|
self.context
|
||||||
|
.set_type(identifier.inner.clone(), r#type, identifier.position);
|
||||||
|
} else {
|
||||||
|
return Err(AnalyzerError::ExpectedValue {
|
||||||
|
actual: value.as_ref().clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left,
|
left,
|
||||||
operator,
|
operator,
|
||||||
right,
|
right,
|
||||||
} => {
|
} => {
|
||||||
if let BinaryOperator::Assign | BinaryOperator::AddAssign = operator.inner {
|
|
||||||
self.analyze_statement(right)?;
|
|
||||||
|
|
||||||
if let Statement::Identifier(identifier) = &left.inner {
|
|
||||||
let right_type = right.inner.expected_type(self.context).ok_or(
|
|
||||||
AnalyzerError::ExpectedValue {
|
|
||||||
actual: right.as_ref().clone(),
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.context
|
|
||||||
.set_type(identifier.clone(), right_type, left.position);
|
|
||||||
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let BinaryOperator::FieldAccess = operator.inner {
|
if let BinaryOperator::FieldAccess = operator.inner {
|
||||||
self.analyze_statement(left)?;
|
self.analyze_statement(left)?;
|
||||||
|
|
||||||
@ -738,7 +739,7 @@ mod tests {
|
|||||||
identifier: Node::new(Statement::Identifier(Identifier::new("y")), (10, 11)),
|
identifier: Node::new(Statement::Identifier(Identifier::new("y")), (10, 11)),
|
||||||
statement: Node::new(
|
statement: Node::new(
|
||||||
Statement::Map(vec![(
|
Statement::Map(vec![(
|
||||||
Node::new(Statement::Identifier(Identifier::new("x")), (2, 3)),
|
Node::new(Identifier::new("x"), (2, 3)),
|
||||||
Node::new(Statement::Constant(Value::integer(1)), (6, 7))
|
Node::new(Statement::Constant(Value::integer(1)), (6, 7))
|
||||||
)]),
|
)]),
|
||||||
(0, 9)
|
(0, 9)
|
||||||
@ -760,7 +761,7 @@ mod tests {
|
|||||||
identifier: Node::new(Statement::Constant(Value::string("y")), (10, 13)),
|
identifier: Node::new(Statement::Constant(Value::string("y")), (10, 13)),
|
||||||
statement: Node::new(
|
statement: Node::new(
|
||||||
Statement::Map(vec![(
|
Statement::Map(vec![(
|
||||||
Node::new(Statement::Identifier(Identifier::new("x")), (2, 3)),
|
Node::new(Identifier::new("x"), (2, 3)),
|
||||||
Node::new(Statement::Constant(Value::integer(1)), (6, 7))
|
Node::new(Statement::Constant(Value::integer(1)), (6, 7))
|
||||||
)]),
|
)]),
|
||||||
(0, 9)
|
(0, 9)
|
||||||
|
@ -15,8 +15,8 @@ pub mod value;
|
|||||||
pub mod vm;
|
pub mod vm;
|
||||||
|
|
||||||
pub use abstract_tree::{
|
pub use abstract_tree::{
|
||||||
AbstractSyntaxTree, BinaryOperator, Node, Statement, StructDefinition, StructInstantiation,
|
AbstractSyntaxTree, AssignmentOperator, BinaryOperator, Node, Statement, StructDefinition,
|
||||||
UnaryOperator,
|
StructInstantiation, UnaryOperator,
|
||||||
};
|
};
|
||||||
pub use analyzer::{analyze, Analyzer, AnalyzerError};
|
pub use analyzer::{analyze, Analyzer, AnalyzerError};
|
||||||
pub use built_in_function::{BuiltInFunction, BuiltInFunctionError};
|
pub use built_in_function::{BuiltInFunction, BuiltInFunctionError};
|
||||||
|
@ -12,9 +12,9 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AbstractSyntaxTree, BinaryOperator, BuiltInFunction, DustError, Identifier, LexError, Lexer,
|
AbstractSyntaxTree, AssignmentOperator, BinaryOperator, BuiltInFunction, DustError, Identifier,
|
||||||
Node, Span, Statement, StructDefinition, Token, TokenKind, TokenOwned, Type, UnaryOperator,
|
LexError, Lexer, Node, Span, Statement, StructDefinition, Token, TokenKind, TokenOwned, Type,
|
||||||
Value,
|
UnaryOperator, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Parses the input into an abstract syntax tree.
|
/// Parses the input into an abstract syntax tree.
|
||||||
@ -22,7 +22,7 @@ use crate::{
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// # use dust_lang::*;
|
/// # use dust_lang::*;
|
||||||
/// let tree = parse("x = 42").unwrap();
|
/// let tree = parse("x + 42").unwrap();
|
||||||
///
|
///
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// tree,
|
/// tree,
|
||||||
@ -35,7 +35,7 @@ use crate::{
|
|||||||
/// (0, 1),
|
/// (0, 1),
|
||||||
/// )),
|
/// )),
|
||||||
/// operator: Node::new(
|
/// operator: Node::new(
|
||||||
/// BinaryOperator::Assign,
|
/// BinaryOperator::Add,
|
||||||
/// (2, 3)
|
/// (2, 3)
|
||||||
/// ),
|
/// ),
|
||||||
/// right: Box::new(Node::new(
|
/// right: Box::new(Node::new(
|
||||||
@ -93,28 +93,8 @@ pub fn parse(source: &str) -> Result<AbstractSyntaxTree, DustError> {
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// assert_eq!(
|
/// let tree = AbstractSyntaxTree { nodes };
|
||||||
/// nodes,
|
///
|
||||||
/// Into::<VecDeque<Node<Statement>>>::into([
|
|
||||||
/// Node::new(
|
|
||||||
/// Statement::BinaryOperation {
|
|
||||||
/// left: Box::new(Node::new(
|
|
||||||
/// Statement::Identifier(Identifier::new("x")),
|
|
||||||
/// (0, 1),
|
|
||||||
/// )),
|
|
||||||
/// operator: Node::new(
|
|
||||||
/// BinaryOperator::Assign,
|
|
||||||
/// (2, 3),
|
|
||||||
/// ),
|
|
||||||
/// right: Box::new(Node::new(
|
|
||||||
/// Statement::Constant(Value::integer(42)),
|
|
||||||
/// (4, 6),
|
|
||||||
/// )),
|
|
||||||
/// },
|
|
||||||
/// (0, 6),
|
|
||||||
/// )
|
|
||||||
/// ]),
|
|
||||||
/// );
|
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Parser<'src> {
|
pub struct Parser<'src> {
|
||||||
source: &'src str,
|
source: &'src str,
|
||||||
@ -382,14 +362,14 @@ impl<'src> Parser<'src> {
|
|||||||
// Determine whether the new statement is a block or a map
|
// Determine whether the new statement is a block or a map
|
||||||
//
|
//
|
||||||
// If the first node is an assignment, this might be a map
|
// If the first node is an assignment, this might be a map
|
||||||
let mut statement = if let Statement::BinaryOperation {
|
let mut statement = if let Statement::Assignment {
|
||||||
left,
|
identifier: left,
|
||||||
operator:
|
operator:
|
||||||
Node {
|
Node {
|
||||||
inner: BinaryOperator::Assign,
|
inner: AssignmentOperator::Assign,
|
||||||
..
|
position: operator_position,
|
||||||
},
|
},
|
||||||
right,
|
value: right,
|
||||||
} = first_node.inner
|
} = first_node.inner
|
||||||
{
|
{
|
||||||
// If the current token is a comma or closing brace
|
// If the current token is a comma or closing brace
|
||||||
@ -400,14 +380,14 @@ impl<'src> Parser<'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The new statement is a map
|
// The new statement is a map
|
||||||
Statement::Map(vec![(*left, *right)])
|
Statement::Map(vec![(left, *right)])
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, the new statement is a block
|
// Otherwise, the new statement is a block
|
||||||
Statement::Block(vec![Node::new(
|
Statement::Block(vec![Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left,
|
identifier: left,
|
||||||
operator: Node::new(BinaryOperator::Assign, (0, 0)),
|
operator: Node::new(AssignmentOperator::Assign, operator_position),
|
||||||
right,
|
value: right,
|
||||||
},
|
},
|
||||||
first_node.position,
|
first_node.position,
|
||||||
)])
|
)])
|
||||||
@ -437,18 +417,18 @@ impl<'src> Parser<'src> {
|
|||||||
// If the new statement is already a map
|
// If the new statement is already a map
|
||||||
if let Some(map_properties) = statement.map_properties_mut() {
|
if let Some(map_properties) = statement.map_properties_mut() {
|
||||||
// Expect the next node to be an assignment
|
// Expect the next node to be an assignment
|
||||||
if let Statement::BinaryOperation {
|
if let Statement::Assignment {
|
||||||
left,
|
identifier,
|
||||||
operator:
|
operator:
|
||||||
Node {
|
Node {
|
||||||
inner: BinaryOperator::Assign,
|
inner: AssignmentOperator::Assign,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
right,
|
value,
|
||||||
} = next_node.inner
|
} = next_node.inner
|
||||||
{
|
{
|
||||||
// Add the new property to the map
|
// Add the new property to the map
|
||||||
map_properties.push((*left, *right));
|
map_properties.push((identifier, *value));
|
||||||
|
|
||||||
// Allow commas after properties
|
// Allow commas after properties
|
||||||
if let Token::Comma = self.current.0 {
|
if let Token::Comma = self.current.0 {
|
||||||
@ -654,6 +634,39 @@ impl<'src> Parser<'src> {
|
|||||||
};
|
};
|
||||||
let left_start = left.position.0;
|
let left_start = left.position.0;
|
||||||
|
|
||||||
|
if let Token::Equal | Token::PlusEqual | Token::MinusEqual = &self.current.0 {
|
||||||
|
let operator_position = self.current.1;
|
||||||
|
let operator = match self.current.0 {
|
||||||
|
Token::Equal => AssignmentOperator::Assign,
|
||||||
|
Token::PlusEqual => AssignmentOperator::AddAssign,
|
||||||
|
Token::MinusEqual => AssignmentOperator::SubtractAssign,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.next_token()?;
|
||||||
|
|
||||||
|
let identifier = if let Statement::Identifier(identifier) = left.inner {
|
||||||
|
Node::new(identifier, left.position)
|
||||||
|
} else {
|
||||||
|
return Err(ParseError::ExpectedToken {
|
||||||
|
expected: TokenKind::Identifier,
|
||||||
|
actual: self.current.0.to_owned(),
|
||||||
|
position: self.current.1,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
let right = self.parse_statement(operator_precedence)?;
|
||||||
|
let right_end = right.position.1;
|
||||||
|
|
||||||
|
return Ok(Node::new(
|
||||||
|
Statement::Assignment {
|
||||||
|
identifier,
|
||||||
|
operator: Node::new(operator, operator_position),
|
||||||
|
value: Box::new(right),
|
||||||
|
},
|
||||||
|
(left_start, right_end),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if let Token::Dot = &self.current.0 {
|
if let Token::Dot = &self.current.0 {
|
||||||
let operator_position = self.current.1;
|
let operator_position = self.current.1;
|
||||||
|
|
||||||
@ -724,14 +737,12 @@ impl<'src> Parser<'src> {
|
|||||||
Token::DoubleAmpersand => Node::new(BinaryOperator::And, self.current.1),
|
Token::DoubleAmpersand => Node::new(BinaryOperator::And, self.current.1),
|
||||||
Token::DoubleEqual => Node::new(BinaryOperator::Equal, self.current.1),
|
Token::DoubleEqual => Node::new(BinaryOperator::Equal, self.current.1),
|
||||||
Token::DoublePipe => Node::new(BinaryOperator::Or, self.current.1),
|
Token::DoublePipe => Node::new(BinaryOperator::Or, self.current.1),
|
||||||
Token::Equal => Node::new(BinaryOperator::Assign, self.current.1),
|
|
||||||
Token::Greater => Node::new(BinaryOperator::Greater, self.current.1),
|
Token::Greater => Node::new(BinaryOperator::Greater, self.current.1),
|
||||||
Token::GreaterEqual => Node::new(BinaryOperator::GreaterOrEqual, self.current.1),
|
Token::GreaterEqual => Node::new(BinaryOperator::GreaterOrEqual, self.current.1),
|
||||||
Token::Less => Node::new(BinaryOperator::Less, self.current.1),
|
Token::Less => Node::new(BinaryOperator::Less, self.current.1),
|
||||||
Token::LessEqual => Node::new(BinaryOperator::LessOrEqual, self.current.1),
|
Token::LessEqual => Node::new(BinaryOperator::LessOrEqual, self.current.1),
|
||||||
Token::Minus => Node::new(BinaryOperator::Subtract, self.current.1),
|
Token::Minus => Node::new(BinaryOperator::Subtract, self.current.1),
|
||||||
Token::Plus => Node::new(BinaryOperator::Add, self.current.1),
|
Token::Plus => Node::new(BinaryOperator::Add, self.current.1),
|
||||||
Token::PlusEqual => Node::new(BinaryOperator::AddAssign, self.current.1),
|
|
||||||
Token::Star => Node::new(BinaryOperator::Multiply, self.current.1),
|
Token::Star => Node::new(BinaryOperator::Multiply, self.current.1),
|
||||||
Token::Slash => Node::new(BinaryOperator::Divide, self.current.1),
|
Token::Slash => Node::new(BinaryOperator::Divide, self.current.1),
|
||||||
Token::Percent => Node::new(BinaryOperator::Modulo, self.current.1),
|
Token::Percent => Node::new(BinaryOperator::Modulo, self.current.1),
|
||||||
@ -1168,16 +1179,10 @@ mod tests {
|
|||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left: Box::new(Node::new(
|
left: Box::new(Node::new(
|
||||||
Statement::Map(vec![(
|
Statement::Map(vec![(
|
||||||
Node::new(
|
Node::new(Identifier::new("x"), (2, 3)),
|
||||||
Statement::Identifier(Identifier::new("x")),
|
|
||||||
(2, 3)
|
|
||||||
),
|
|
||||||
Node::new(
|
Node::new(
|
||||||
Statement::Map(vec![(
|
Statement::Map(vec![(
|
||||||
Node::new(
|
Node::new(Identifier::new("y"), (8, 9)),
|
||||||
Statement::Identifier(Identifier::new("y")),
|
|
||||||
(8, 9)
|
|
||||||
),
|
|
||||||
Node::new(
|
Node::new(
|
||||||
Statement::Constant(Value::integer(42)),
|
Statement::Constant(Value::integer(42)),
|
||||||
(12, 14)
|
(12, 14)
|
||||||
@ -1231,13 +1236,10 @@ mod tests {
|
|||||||
nodes: [
|
nodes: [
|
||||||
Node::new(
|
Node::new(
|
||||||
Statement::Nil(Box::new(Node::new(
|
Statement::Nil(Box::new(Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left: Box::new(Node::new(
|
identifier: Node::new(Identifier::new("a"), (0, 1)),
|
||||||
Statement::Identifier(Identifier::new("a")),
|
operator: Node::new(AssignmentOperator::Assign, (2, 3)),
|
||||||
(0, 1)
|
value: Box::new(Node::new(
|
||||||
)),
|
|
||||||
operator: Node::new(BinaryOperator::Assign, (2, 3)),
|
|
||||||
right: Box::new(Node::new(
|
|
||||||
Statement::Constant(Value::integer(1)),
|
Statement::Constant(Value::integer(1)),
|
||||||
(4, 5)
|
(4, 5)
|
||||||
)),
|
)),
|
||||||
@ -1336,13 +1338,10 @@ mod tests {
|
|||||||
nodes: [
|
nodes: [
|
||||||
Node::new(
|
Node::new(
|
||||||
Statement::Nil(Box::new(Node::new(
|
Statement::Nil(Box::new(Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left: Box::new(Node::new(
|
identifier: Node::new(Identifier::new("a"), (0, 1)),
|
||||||
Statement::Identifier(Identifier::new("a")),
|
operator: Node::new(AssignmentOperator::Assign, (2, 3)),
|
||||||
(0, 1)
|
value: Box::new(Node::new(
|
||||||
)),
|
|
||||||
operator: Node::new(BinaryOperator::Assign, (2, 3)),
|
|
||||||
right: Box::new(Node::new(
|
|
||||||
Statement::Constant(Value::boolean(false)),
|
Statement::Constant(Value::boolean(false)),
|
||||||
(4, 9)
|
(4, 9)
|
||||||
)),
|
)),
|
||||||
@ -1486,13 +1485,10 @@ mod tests {
|
|||||||
parse_error: ParseError::ExpectedAssignment {
|
parse_error: ParseError::ExpectedAssignment {
|
||||||
actual: Node::new(
|
actual: Node::new(
|
||||||
Statement::Nil(Box::new(Node::new(
|
Statement::Nil(Box::new(Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left: Box::new(Node::new(
|
identifier: Node::new(Identifier::new("z"), (16, 17)),
|
||||||
Statement::Identifier(Identifier::new("z")),
|
operator: Node::new(AssignmentOperator::Assign, (18, 19)),
|
||||||
(16, 17)
|
value: Box::new(Node::new(
|
||||||
)),
|
|
||||||
operator: Node::new(BinaryOperator::Assign, (18, 19)),
|
|
||||||
right: Box::new(Node::new(
|
|
||||||
Statement::Constant(Value::integer(3)),
|
Statement::Constant(Value::integer(3)),
|
||||||
(20, 21)
|
(20, 21)
|
||||||
)),
|
)),
|
||||||
@ -1531,13 +1527,10 @@ mod tests {
|
|||||||
)),
|
)),
|
||||||
body: Box::new(Node::new(
|
body: Box::new(Node::new(
|
||||||
Statement::Block(vec![Node::new(
|
Statement::Block(vec![Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left: Box::new(Node::new(
|
identifier: Node::new(Identifier::new("x"), (15, 16)),
|
||||||
Statement::Identifier(Identifier::new("x")),
|
operator: Node::new(AssignmentOperator::AddAssign, (17, 19)),
|
||||||
(15, 16)
|
value: Box::new(Node::new(
|
||||||
)),
|
|
||||||
operator: Node::new(BinaryOperator::AddAssign, (17, 19)),
|
|
||||||
right: Box::new(Node::new(
|
|
||||||
Statement::Constant(Value::integer(1)),
|
Statement::Constant(Value::integer(1)),
|
||||||
(20, 21)
|
(20, 21)
|
||||||
)),
|
)),
|
||||||
@ -1562,13 +1555,10 @@ mod tests {
|
|||||||
parse(input),
|
parse(input),
|
||||||
Ok(AbstractSyntaxTree {
|
Ok(AbstractSyntaxTree {
|
||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left: Box::new(Node::new(
|
identifier: Node::new(Identifier::new("a"), (0, 1)),
|
||||||
Statement::Identifier(Identifier::new("a")),
|
operator: Node::new(AssignmentOperator::AddAssign, (2, 4)),
|
||||||
(0, 1)
|
value: Box::new(Node::new(Statement::Constant(Value::integer(1)), (5, 6))),
|
||||||
)),
|
|
||||||
operator: Node::new(BinaryOperator::AddAssign, (2, 4)),
|
|
||||||
right: Box::new(Node::new(Statement::Constant(Value::integer(1)), (5, 6))),
|
|
||||||
},
|
},
|
||||||
(0, 6)
|
(0, 6)
|
||||||
)]
|
)]
|
||||||
@ -1659,13 +1649,10 @@ mod tests {
|
|||||||
Statement::Block(vec![
|
Statement::Block(vec![
|
||||||
Node::new(
|
Node::new(
|
||||||
Statement::Nil(Box::new(Node::new(
|
Statement::Nil(Box::new(Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left: Box::new(Node::new(
|
identifier: Node::new(Identifier::new("foo"), (2, 5)),
|
||||||
Statement::Identifier(Identifier::new("foo")),
|
operator: Node::new(AssignmentOperator::Assign, (6, 7)),
|
||||||
(2, 5)
|
value: Box::new(Node::new(
|
||||||
)),
|
|
||||||
operator: Node::new(BinaryOperator::Assign, (6, 7)),
|
|
||||||
right: Box::new(Node::new(
|
|
||||||
Statement::Constant(Value::integer(42)),
|
Statement::Constant(Value::integer(42)),
|
||||||
(8, 10)
|
(8, 10)
|
||||||
)),
|
)),
|
||||||
@ -1676,13 +1663,10 @@ mod tests {
|
|||||||
),
|
),
|
||||||
Node::new(
|
Node::new(
|
||||||
Statement::Nil(Box::new(Node::new(
|
Statement::Nil(Box::new(Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left: Box::new(Node::new(
|
identifier: Node::new(Identifier::new("bar"), (12, 15)),
|
||||||
Statement::Identifier(Identifier::new("bar")),
|
operator: Node::new(AssignmentOperator::Assign, (16, 17)),
|
||||||
(12, 15)
|
value: Box::new(Node::new(
|
||||||
)),
|
|
||||||
operator: Node::new(BinaryOperator::Assign, (16, 17)),
|
|
||||||
right: Box::new(Node::new(
|
|
||||||
Statement::Constant(Value::integer(42)),
|
Statement::Constant(Value::integer(42)),
|
||||||
(18, 20)
|
(18, 20)
|
||||||
)),
|
)),
|
||||||
@ -1692,13 +1676,10 @@ mod tests {
|
|||||||
(12, 21)
|
(12, 21)
|
||||||
),
|
),
|
||||||
Node::new(
|
Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left: Box::new(Node::new(
|
identifier: Node::new(Identifier::new("baz"), (22, 25)),
|
||||||
Statement::Identifier(Identifier::new("baz")),
|
operator: Node::new(AssignmentOperator::Assign, (26, 27)),
|
||||||
(22, 25)
|
value: Box::new(Node::new(
|
||||||
)),
|
|
||||||
operator: Node::new(BinaryOperator::Assign, (26, 27)),
|
|
||||||
right: Box::new(Node::new(
|
|
||||||
Statement::Constant(Value::string("42")),
|
Statement::Constant(Value::string("42")),
|
||||||
(28, 32)
|
(28, 32)
|
||||||
)),
|
)),
|
||||||
@ -1735,15 +1716,15 @@ mod tests {
|
|||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::Map(vec![
|
Statement::Map(vec![
|
||||||
(
|
(
|
||||||
Node::new(Statement::Identifier(Identifier::new("foo")), (2, 5)),
|
Node::new(Identifier::new("foo"), (2, 5)),
|
||||||
Node::new(Statement::Constant(Value::integer(42)), (8, 10))
|
Node::new(Statement::Constant(Value::integer(42)), (8, 10))
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Node::new(Statement::Identifier(Identifier::new("bar")), (12, 15)),
|
Node::new(Identifier::new("bar"), (12, 15)),
|
||||||
Node::new(Statement::Constant(Value::integer(42)), (18, 20))
|
Node::new(Statement::Constant(Value::integer(42)), (18, 20))
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Node::new(Statement::Identifier(Identifier::new("baz")), (22, 25)),
|
Node::new(Identifier::new("baz"), (22, 25)),
|
||||||
Node::new(Statement::Constant(Value::string("42")), (28, 32))
|
Node::new(Statement::Constant(Value::string("42")), (28, 32))
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
@ -1764,11 +1745,11 @@ mod tests {
|
|||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::Map(vec![
|
Statement::Map(vec![
|
||||||
(
|
(
|
||||||
Node::new(Statement::Identifier(Identifier::new("x")), (2, 3)),
|
Node::new(Identifier::new("x"), (2, 3)),
|
||||||
Node::new(Statement::Constant(Value::integer(42)), (6, 8))
|
Node::new(Statement::Constant(Value::integer(42)), (6, 8))
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Node::new(Statement::Identifier(Identifier::new("y")), (10, 11)),
|
Node::new(Identifier::new("y"), (10, 11)),
|
||||||
Node::new(Statement::Constant(Value::string("foobar")), (14, 22))
|
Node::new(Statement::Constant(Value::string("foobar")), (14, 22))
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
@ -1788,7 +1769,7 @@ mod tests {
|
|||||||
Ok(AbstractSyntaxTree {
|
Ok(AbstractSyntaxTree {
|
||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::Map(vec![(
|
Statement::Map(vec![(
|
||||||
Node::new(Statement::Identifier(Identifier::new("x")), (2, 3)),
|
Node::new(Identifier::new("x"), (2, 3)),
|
||||||
Node::new(Statement::Constant(Value::integer(42)), (6, 8))
|
Node::new(Statement::Constant(Value::integer(42)), (6, 8))
|
||||||
)]),
|
)]),
|
||||||
(0, 10)
|
(0, 10)
|
||||||
@ -2271,13 +2252,10 @@ mod tests {
|
|||||||
parse(input),
|
parse(input),
|
||||||
Ok(AbstractSyntaxTree {
|
Ok(AbstractSyntaxTree {
|
||||||
nodes: [Node::new(
|
nodes: [Node::new(
|
||||||
Statement::BinaryOperation {
|
Statement::Assignment {
|
||||||
left: Box::new(Node::new(
|
identifier: Node::new(Identifier::new("a"), (0, 1)),
|
||||||
Statement::Identifier(Identifier::new("a")),
|
operator: Node::new(AssignmentOperator::Assign, (2, 3)),
|
||||||
(0, 1)
|
value: Box::new(Node::new(
|
||||||
)),
|
|
||||||
operator: Node::new(BinaryOperator::Assign, (2, 3)),
|
|
||||||
right: Box::new(Node::new(
|
|
||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left: Box::new(Node::new(
|
left: Box::new(Node::new(
|
||||||
Statement::Constant(Value::integer(1)),
|
Statement::Constant(Value::integer(1)),
|
||||||
|
@ -50,6 +50,7 @@ pub enum Token<'src> {
|
|||||||
Less,
|
Less,
|
||||||
LessEqual,
|
LessEqual,
|
||||||
Minus,
|
Minus,
|
||||||
|
MinusEqual,
|
||||||
Percent,
|
Percent,
|
||||||
Plus,
|
Plus,
|
||||||
PlusEqual,
|
PlusEqual,
|
||||||
@ -94,6 +95,7 @@ impl<'src> Token<'src> {
|
|||||||
Token::Less => TokenOwned::Less,
|
Token::Less => TokenOwned::Less,
|
||||||
Token::LessEqual => TokenOwned::LessOrEqual,
|
Token::LessEqual => TokenOwned::LessOrEqual,
|
||||||
Token::Minus => TokenOwned::Minus,
|
Token::Minus => TokenOwned::Minus,
|
||||||
|
Token::MinusEqual => TokenOwned::MinusEqual,
|
||||||
Token::Percent => TokenOwned::Percent,
|
Token::Percent => TokenOwned::Percent,
|
||||||
Token::Plus => TokenOwned::Plus,
|
Token::Plus => TokenOwned::Plus,
|
||||||
Token::PlusEqual => TokenOwned::PlusEqual,
|
Token::PlusEqual => TokenOwned::PlusEqual,
|
||||||
@ -147,6 +149,7 @@ impl<'src> Token<'src> {
|
|||||||
Token::Less => "<",
|
Token::Less => "<",
|
||||||
Token::LessEqual => "<=",
|
Token::LessEqual => "<=",
|
||||||
Token::Minus => "-",
|
Token::Minus => "-",
|
||||||
|
Token::MinusEqual => "-=",
|
||||||
Token::Percent => "%",
|
Token::Percent => "%",
|
||||||
Token::Plus => "+",
|
Token::Plus => "+",
|
||||||
Token::PlusEqual => "+=",
|
Token::PlusEqual => "+=",
|
||||||
@ -197,6 +200,7 @@ impl<'src> Token<'src> {
|
|||||||
Token::Less => TokenKind::Less,
|
Token::Less => TokenKind::Less,
|
||||||
Token::LessEqual => TokenKind::LessOrEqual,
|
Token::LessEqual => TokenKind::LessOrEqual,
|
||||||
Token::Minus => TokenKind::Minus,
|
Token::Minus => TokenKind::Minus,
|
||||||
|
Token::MinusEqual => TokenKind::MinusEqual,
|
||||||
Token::Percent => TokenKind::Percent,
|
Token::Percent => TokenKind::Percent,
|
||||||
Token::Plus => TokenKind::Plus,
|
Token::Plus => TokenKind::Plus,
|
||||||
Token::PlusEqual => TokenKind::PlusEqual,
|
Token::PlusEqual => TokenKind::PlusEqual,
|
||||||
@ -322,6 +326,7 @@ pub enum TokenOwned {
|
|||||||
Less,
|
Less,
|
||||||
LessOrEqual,
|
LessOrEqual,
|
||||||
Minus,
|
Minus,
|
||||||
|
MinusEqual,
|
||||||
Percent,
|
Percent,
|
||||||
Plus,
|
Plus,
|
||||||
PlusEqual,
|
PlusEqual,
|
||||||
@ -367,6 +372,7 @@ impl Display for TokenOwned {
|
|||||||
TokenOwned::Less => Token::Less.fmt(f),
|
TokenOwned::Less => Token::Less.fmt(f),
|
||||||
TokenOwned::LessOrEqual => Token::LessEqual.fmt(f),
|
TokenOwned::LessOrEqual => Token::LessEqual.fmt(f),
|
||||||
TokenOwned::Minus => Token::Minus.fmt(f),
|
TokenOwned::Minus => Token::Minus.fmt(f),
|
||||||
|
TokenOwned::MinusEqual => Token::MinusEqual.fmt(f),
|
||||||
TokenOwned::Percent => Token::Percent.fmt(f),
|
TokenOwned::Percent => Token::Percent.fmt(f),
|
||||||
TokenOwned::Plus => Token::Plus.fmt(f),
|
TokenOwned::Plus => Token::Plus.fmt(f),
|
||||||
TokenOwned::PlusEqual => Token::PlusEqual.fmt(f),
|
TokenOwned::PlusEqual => Token::PlusEqual.fmt(f),
|
||||||
@ -433,6 +439,7 @@ pub enum TokenKind {
|
|||||||
Less,
|
Less,
|
||||||
LessOrEqual,
|
LessOrEqual,
|
||||||
Minus,
|
Minus,
|
||||||
|
MinusEqual,
|
||||||
Percent,
|
Percent,
|
||||||
Plus,
|
Plus,
|
||||||
PlusEqual,
|
PlusEqual,
|
||||||
@ -478,6 +485,7 @@ impl Display for TokenKind {
|
|||||||
TokenKind::Less => Token::Less.fmt(f),
|
TokenKind::Less => Token::Less.fmt(f),
|
||||||
TokenKind::LessOrEqual => Token::LessEqual.fmt(f),
|
TokenKind::LessOrEqual => Token::LessEqual.fmt(f),
|
||||||
TokenKind::Minus => Token::Minus.fmt(f),
|
TokenKind::Minus => Token::Minus.fmt(f),
|
||||||
|
TokenKind::MinusEqual => Token::MinusEqual.fmt(f),
|
||||||
TokenKind::Percent => Token::Percent.fmt(f),
|
TokenKind::Percent => Token::Percent.fmt(f),
|
||||||
TokenKind::Plus => Token::Plus.fmt(f),
|
TokenKind::Plus => Token::Plus.fmt(f),
|
||||||
TokenKind::PlusEqual => Token::PlusEqual.fmt(f),
|
TokenKind::PlusEqual => Token::PlusEqual.fmt(f),
|
||||||
|
@ -10,9 +10,10 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
parse, value::ValueInner, AbstractSyntaxTree, Analyzer, BinaryOperator, BuiltInFunctionError,
|
parse, value::ValueInner, AbstractSyntaxTree, Analyzer, AssignmentOperator, BinaryOperator,
|
||||||
Context, DustError, Identifier, Node, ParseError, Span, Statement, Struct, StructDefinition,
|
BuiltInFunctionError, Context, DustError, Identifier, Node, ParseError, Span, Statement,
|
||||||
StructInstantiation, StructType, Type, UnaryOperator, Value, ValueError,
|
Struct, StructDefinition, StructInstantiation, StructType, Type, UnaryOperator, Value,
|
||||||
|
ValueError,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Run the source code and return the result.
|
/// Run the source code and return the result.
|
||||||
@ -96,6 +97,53 @@ impl Vm {
|
|||||||
|
|
||||||
fn run_statement(&self, node: Node<Statement>) -> Result<Option<Value>, VmError> {
|
fn run_statement(&self, node: Node<Statement>) -> Result<Option<Value>, VmError> {
|
||||||
match node.inner {
|
match node.inner {
|
||||||
|
Statement::Assignment {
|
||||||
|
identifier,
|
||||||
|
operator,
|
||||||
|
value,
|
||||||
|
} => match operator.inner {
|
||||||
|
AssignmentOperator::Assign => {
|
||||||
|
let position = value.position;
|
||||||
|
let value = if let Some(value) = self.run_statement(*value)? {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
return Err(VmError::ExpectedValue { position });
|
||||||
|
};
|
||||||
|
|
||||||
|
self.context.set_value(identifier.inner, value);
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
AssignmentOperator::AddAssign => {
|
||||||
|
let left_value = if let Some(value) = self.context.get_value(&identifier.inner)
|
||||||
|
{
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
return Err(VmError::UndefinedVariable { identifier });
|
||||||
|
};
|
||||||
|
let value_position = value.position;
|
||||||
|
let right_value = if let Some(value) = self.run_statement(*value)? {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
return Err(VmError::ExpectedValue {
|
||||||
|
position: value_position,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
let new_value = left_value.add(&right_value).map_err(|value_error| {
|
||||||
|
VmError::ValueError {
|
||||||
|
error: value_error,
|
||||||
|
position: (identifier.position.0, value_position.1),
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.context.set_value(identifier.inner, new_value);
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
AssignmentOperator::SubtractAssign => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
},
|
||||||
Statement::BinaryOperation {
|
Statement::BinaryOperation {
|
||||||
left,
|
left,
|
||||||
operator,
|
operator,
|
||||||
@ -103,64 +151,6 @@ impl Vm {
|
|||||||
} => {
|
} => {
|
||||||
let right_position = right.position;
|
let right_position = right.position;
|
||||||
|
|
||||||
if let BinaryOperator::Assign = operator.inner {
|
|
||||||
let identifier = if let Statement::Identifier(identifier) = left.inner {
|
|
||||||
identifier
|
|
||||||
} else {
|
|
||||||
return Err(VmError::ExpectedIdentifier {
|
|
||||||
position: left.position,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
let value = if let Some(value) = self.run_statement(*right)? {
|
|
||||||
value
|
|
||||||
} else {
|
|
||||||
return Err(VmError::ExpectedValue {
|
|
||||||
position: right_position,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
self.context.set_value(identifier, value);
|
|
||||||
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let BinaryOperator::AddAssign = operator.inner {
|
|
||||||
let (identifier, left_value) =
|
|
||||||
if let Statement::Identifier(identifier) = left.inner {
|
|
||||||
let value = self.context.get_value(&identifier).ok_or_else(|| {
|
|
||||||
VmError::UndefinedVariable {
|
|
||||||
identifier: Node::new(
|
|
||||||
Statement::Identifier(identifier.clone()),
|
|
||||||
left.position,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
(identifier, value)
|
|
||||||
} else {
|
|
||||||
return Err(VmError::ExpectedIdentifier {
|
|
||||||
position: left.position,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
let right_value = if let Some(value) = self.run_statement(*right)? {
|
|
||||||
value
|
|
||||||
} else {
|
|
||||||
return Err(VmError::ExpectedValue {
|
|
||||||
position: right_position,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
let new_value = left_value.add(&right_value).map_err(|value_error| {
|
|
||||||
VmError::ValueError {
|
|
||||||
error: value_error,
|
|
||||||
position: right_position,
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
self.context.set_value(identifier, new_value);
|
|
||||||
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let BinaryOperator::FieldAccess = operator.inner {
|
if let BinaryOperator::FieldAccess = operator.inner {
|
||||||
let left_span = left.position;
|
let left_span = left.position;
|
||||||
let left_value = if let Some(value) = self.run_statement(*left)? {
|
let left_value = if let Some(value) = self.run_statement(*left)? {
|
||||||
@ -416,7 +406,7 @@ impl Vm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Err(VmError::UndefinedVariable {
|
Err(VmError::UndefinedVariable {
|
||||||
identifier: Node::new(Statement::Identifier(identifier), node.position),
|
identifier: Node::new(identifier, node.position),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Statement::If { condition, body } => {
|
Statement::If { condition, body } => {
|
||||||
@ -586,13 +576,6 @@ impl Vm {
|
|||||||
let mut values = BTreeMap::new();
|
let mut values = BTreeMap::new();
|
||||||
|
|
||||||
for (identifier, value_node) in nodes {
|
for (identifier, value_node) in nodes {
|
||||||
let identifier = if let Statement::Identifier(identifier) = identifier.inner {
|
|
||||||
identifier
|
|
||||||
} else {
|
|
||||||
return Err(VmError::ExpectedIdentifier {
|
|
||||||
position: identifier.position,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
let position = value_node.position;
|
let position = value_node.position;
|
||||||
let value = if let Some(value) = self.run_statement(value_node)? {
|
let value = if let Some(value) = self.run_statement(value_node)? {
|
||||||
value
|
value
|
||||||
@ -600,7 +583,7 @@ impl Vm {
|
|||||||
return Err(VmError::ExpectedValue { position });
|
return Err(VmError::ExpectedValue { position });
|
||||||
};
|
};
|
||||||
|
|
||||||
values.insert(identifier, value);
|
values.insert(identifier.inner, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(Value::map(values)))
|
Ok(Some(Value::map(values)))
|
||||||
@ -754,7 +737,7 @@ pub enum VmError {
|
|||||||
position: Span,
|
position: Span,
|
||||||
},
|
},
|
||||||
UndefinedVariable {
|
UndefinedVariable {
|
||||||
identifier: Node<Statement>,
|
identifier: Node<Identifier>,
|
||||||
},
|
},
|
||||||
UndefinedProperty {
|
UndefinedProperty {
|
||||||
value: Value,
|
value: Value,
|
||||||
|
Loading…
Reference in New Issue
Block a user