Compare commits
2 Commits
76a67c5117
...
06f3a9b746
Author | SHA1 | Date | |
---|---|---|---|
06f3a9b746 | |||
cda0203242 |
@ -5,45 +5,44 @@ use std::{
|
|||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{Identifier, ReservedIdentifier, Span, Type, Value};
|
use crate::{Identifier, ReservedIdentifier, Type, Value};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct AbstractSyntaxTree {
|
pub struct AbstractSyntaxTree<P> {
|
||||||
pub nodes: VecDeque<Node>,
|
pub nodes: VecDeque<Node<P>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct Node {
|
pub struct Node<P> {
|
||||||
pub statement: Statement,
|
pub statement: Statement<P>,
|
||||||
pub span: Span,
|
pub position: P,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl<P> Node<P> {
|
||||||
pub fn new(operation: Statement, span: Span) -> Self {
|
pub fn new(operation: Statement<P>, position: P) -> Self {
|
||||||
Self {
|
Self {
|
||||||
statement: operation,
|
statement: operation,
|
||||||
span,
|
position,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Node {
|
impl<P> Display for Node<P> {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.statement)
|
write!(f, "{}", self.statement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum Statement {
|
pub enum Statement<P> {
|
||||||
// Top-level statements
|
// Top-level statements
|
||||||
Assign(Box<Node>, Box<Node>),
|
Assign(Box<Node<P>>, Box<Node<P>>),
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
Add(Box<Node>, Box<Node>),
|
Add(Box<Node<P>>, Box<Node<P>>),
|
||||||
BuiltInValue(Box<Node>),
|
PropertyAccess(Box<Node<P>>, Box<Node<P>>),
|
||||||
PropertyAccess(Box<Node>, Box<Node>),
|
List(Vec<Node<P>>),
|
||||||
List(Vec<Node>),
|
Multiply(Box<Node<P>>, Box<Node<P>>),
|
||||||
Multiply(Box<Node>, Box<Node>),
|
|
||||||
|
|
||||||
// Hard-coded values
|
// Hard-coded values
|
||||||
Constant(Value),
|
Constant(Value),
|
||||||
@ -51,12 +50,11 @@ pub enum Statement {
|
|||||||
ReservedIdentifier(ReservedIdentifier),
|
ReservedIdentifier(ReservedIdentifier),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Statement {
|
impl<P> Statement<P> {
|
||||||
pub fn expected_type(&self, variables: &HashMap<Identifier, Value>) -> Option<Type> {
|
pub fn expected_type(&self, variables: &HashMap<Identifier, Value>) -> Option<Type> {
|
||||||
match self {
|
match self {
|
||||||
Statement::Add(left, _) => left.statement.expected_type(variables),
|
Statement::Add(left, _) => left.statement.expected_type(variables),
|
||||||
Statement::Assign(_, _) => None,
|
Statement::Assign(_, _) => None,
|
||||||
Statement::BuiltInValue(reserved) => reserved.statement.expected_type(variables),
|
|
||||||
Statement::Constant(value) => Some(value.r#type(variables)),
|
Statement::Constant(value) => Some(value.r#type(variables)),
|
||||||
Statement::Identifier(identifier) => variables
|
Statement::Identifier(identifier) => variables
|
||||||
.get(identifier)
|
.get(identifier)
|
||||||
@ -72,12 +70,11 @@ impl Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Statement {
|
impl<P> Display for Statement<P> {
|
||||||
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::Assign(left, right) => write!(f, "{left} = {right}"),
|
Statement::Assign(left, right) => write!(f, "{left} = {right}"),
|
||||||
Statement::Add(left, right) => write!(f, "{left} + {right}"),
|
Statement::Add(left, right) => write!(f, "{left} + {right}"),
|
||||||
Statement::BuiltInValue(reserved) => write!(f, "{reserved}"),
|
|
||||||
Statement::PropertyAccess(left, right) => write!(f, "{left}.{right}"),
|
Statement::PropertyAccess(left, right) => write!(f, "{left}.{right}"),
|
||||||
Statement::List(nodes) => {
|
Statement::List(nodes) => {
|
||||||
write!(f, "[")?;
|
write!(f, "[")?;
|
||||||
|
@ -22,10 +22,10 @@ use crate::{AbstractSyntaxTree, Identifier, Node, Statement, Type, Value};
|
|||||||
///
|
///
|
||||||
/// assert!(result.is_err());
|
/// assert!(result.is_err());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn analyze(
|
pub fn analyze<P: Clone>(
|
||||||
abstract_tree: &AbstractSyntaxTree,
|
abstract_tree: &AbstractSyntaxTree<P>,
|
||||||
variables: &HashMap<Identifier, Value>,
|
variables: &HashMap<Identifier, Value>,
|
||||||
) -> Result<(), AnalyzerError> {
|
) -> Result<(), AnalyzerError<P>> {
|
||||||
let analyzer = Analyzer::new(abstract_tree, variables);
|
let analyzer = Analyzer::new(abstract_tree, variables);
|
||||||
|
|
||||||
analyzer.analyze()
|
analyzer.analyze()
|
||||||
@ -44,14 +44,14 @@ pub fn analyze(
|
|||||||
/// let result = analyzer.analyze();
|
/// let result = analyzer.analyze();
|
||||||
///
|
///
|
||||||
/// assert!(result.is_err());
|
/// assert!(result.is_err());
|
||||||
pub struct Analyzer<'a> {
|
pub struct Analyzer<'a, P> {
|
||||||
abstract_tree: &'a AbstractSyntaxTree,
|
abstract_tree: &'a AbstractSyntaxTree<P>,
|
||||||
variables: &'a HashMap<Identifier, Value>,
|
variables: &'a HashMap<Identifier, Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Analyzer<'a> {
|
impl<'a, P: Clone> Analyzer<'a, P> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
abstract_tree: &'a AbstractSyntaxTree,
|
abstract_tree: &'a AbstractSyntaxTree<P>,
|
||||||
variables: &'a HashMap<Identifier, Value>,
|
variables: &'a HashMap<Identifier, Value>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -60,7 +60,7 @@ impl<'a> Analyzer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn analyze(&self) -> Result<(), AnalyzerError> {
|
pub fn analyze(&self) -> Result<(), AnalyzerError<P>> {
|
||||||
for node in &self.abstract_tree.nodes {
|
for node in &self.abstract_tree.nodes {
|
||||||
self.analyze_node(node)?;
|
self.analyze_node(node)?;
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ impl<'a> Analyzer<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn analyze_node(&self, node: &Node) -> Result<(), AnalyzerError> {
|
fn analyze_node(&self, node: &Node<P>) -> Result<(), AnalyzerError<P>> {
|
||||||
match &node.statement {
|
match &node.statement {
|
||||||
Statement::Add(left, right) => {
|
Statement::Add(left, right) => {
|
||||||
if let Some(Type::Integer) | Some(Type::Float) =
|
if let Some(Type::Integer) | Some(Type::Float) =
|
||||||
@ -103,9 +103,6 @@ impl<'a> Analyzer<'a> {
|
|||||||
|
|
||||||
self.analyze_node(right)?;
|
self.analyze_node(right)?;
|
||||||
}
|
}
|
||||||
Statement::BuiltInValue(node) => {
|
|
||||||
self.analyze_node(node)?;
|
|
||||||
}
|
|
||||||
Statement::Constant(_) => {}
|
Statement::Constant(_) => {}
|
||||||
Statement::Identifier(_) => {
|
Statement::Identifier(_) => {
|
||||||
return Err(AnalyzerError::UnexpectedIdentifier {
|
return Err(AnalyzerError::UnexpectedIdentifier {
|
||||||
@ -160,10 +157,10 @@ impl<'a> Analyzer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum AnalyzerError {
|
pub enum AnalyzerError<P> {
|
||||||
ExpectedIdentifier { actual: Node },
|
ExpectedIdentifier { actual: Node<P> },
|
||||||
ExpectedIntegerOrFloat { actual: Node },
|
ExpectedIntegerOrFloat { actual: Node<P> },
|
||||||
UnexpectedIdentifier { identifier: Node },
|
UnexpectedIdentifier { identifier: Node<P> },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -23,20 +23,20 @@ use crate::{AbstractSyntaxTree, LexError, Lexer, Node, Span, Statement, Token, V
|
|||||||
/// statement: Statement::Assign(
|
/// statement: Statement::Assign(
|
||||||
/// Box::new(Node {
|
/// Box::new(Node {
|
||||||
/// statement: Statement::Identifier("x".into()),
|
/// statement: Statement::Identifier("x".into()),
|
||||||
/// span: (0, 1),
|
/// position: (0, 1),
|
||||||
/// }),
|
/// }),
|
||||||
/// Box::new(Node {
|
/// Box::new(Node {
|
||||||
/// statement: Statement::Constant(Value::integer(42)),
|
/// statement: Statement::Constant(Value::integer(42)),
|
||||||
/// span: (4, 6),
|
/// position: (4, 6),
|
||||||
/// })
|
/// })
|
||||||
/// ),
|
/// ),
|
||||||
/// span: (0, 6),
|
/// position: (0, 6),
|
||||||
/// }
|
/// }
|
||||||
/// ].into(),
|
/// ].into(),
|
||||||
/// }),
|
/// }),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
pub fn parse(input: &str) -> Result<AbstractSyntaxTree, ParseError> {
|
pub fn parse(input: &str) -> Result<AbstractSyntaxTree<Span>, ParseError> {
|
||||||
let lexer = Lexer::new(input);
|
let lexer = Lexer::new(input);
|
||||||
let mut parser = Parser::new(lexer);
|
let mut parser = Parser::new(lexer);
|
||||||
let mut nodes = VecDeque::new();
|
let mut nodes = VecDeque::new();
|
||||||
@ -77,19 +77,19 @@ pub fn parse(input: &str) -> Result<AbstractSyntaxTree, ParseError> {
|
|||||||
///
|
///
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// nodes,
|
/// nodes,
|
||||||
/// Into::<VecDeque<Node>>::into([
|
/// Into::<VecDeque<Node<Span>>>::into([
|
||||||
/// Node {
|
/// Node {
|
||||||
/// statement: Statement::Assign(
|
/// statement: Statement::Assign(
|
||||||
/// Box::new(Node {
|
/// Box::new(Node {
|
||||||
/// statement: Statement::Identifier("x".into()),
|
/// statement: Statement::Identifier("x".into()),
|
||||||
/// span: (0, 1),
|
/// position: (0, 1),
|
||||||
/// }),
|
/// }),
|
||||||
/// Box::new(Node {
|
/// Box::new(Node {
|
||||||
/// statement: Statement::Constant(Value::integer(42)),
|
/// statement: Statement::Constant(Value::integer(42)),
|
||||||
/// span: (4, 6),
|
/// position: (4, 6),
|
||||||
/// })
|
/// })
|
||||||
/// ),
|
/// ),
|
||||||
/// span: (0, 6),
|
/// position: (0, 6),
|
||||||
/// }
|
/// }
|
||||||
/// ]),
|
/// ]),
|
||||||
/// );
|
/// );
|
||||||
@ -107,7 +107,7 @@ impl<'src> Parser<'src> {
|
|||||||
Parser { lexer, current }
|
Parser { lexer, current }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(&mut self) -> Result<Node, ParseError> {
|
pub fn parse(&mut self) -> Result<Node<Span>, ParseError> {
|
||||||
self.parse_node(0)
|
self.parse_node(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,9 +121,9 @@ impl<'src> Parser<'src> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_node(&mut self, precedence: u8) -> Result<Node, ParseError> {
|
fn parse_node(&mut self, precedence: u8) -> Result<Node<Span>, ParseError> {
|
||||||
let left_node = self.parse_primary()?;
|
let left_node = self.parse_primary()?;
|
||||||
let left_start = left_node.span.0;
|
let left_start = left_node.position.0;
|
||||||
|
|
||||||
if precedence < self.current_precedence() {
|
if precedence < self.current_precedence() {
|
||||||
match &self.current {
|
match &self.current {
|
||||||
@ -131,7 +131,7 @@ impl<'src> Parser<'src> {
|
|||||||
self.next_token()?;
|
self.next_token()?;
|
||||||
|
|
||||||
let right_node = self.parse_node(self.current_precedence())?;
|
let right_node = self.parse_node(self.current_precedence())?;
|
||||||
let right_end = right_node.span.1;
|
let right_end = right_node.position.1;
|
||||||
|
|
||||||
return Ok(Node::new(
|
return Ok(Node::new(
|
||||||
Statement::Add(Box::new(left_node), Box::new(right_node)),
|
Statement::Add(Box::new(left_node), Box::new(right_node)),
|
||||||
@ -142,7 +142,7 @@ impl<'src> Parser<'src> {
|
|||||||
self.next_token()?;
|
self.next_token()?;
|
||||||
|
|
||||||
let right_node = self.parse_node(self.current_precedence())?;
|
let right_node = self.parse_node(self.current_precedence())?;
|
||||||
let right_end = right_node.span.1;
|
let right_end = right_node.position.1;
|
||||||
|
|
||||||
return Ok(Node::new(
|
return Ok(Node::new(
|
||||||
Statement::Multiply(Box::new(left_node), Box::new(right_node)),
|
Statement::Multiply(Box::new(left_node), Box::new(right_node)),
|
||||||
@ -153,7 +153,7 @@ impl<'src> Parser<'src> {
|
|||||||
self.next_token()?;
|
self.next_token()?;
|
||||||
|
|
||||||
let right_node = self.parse_node(self.current_precedence())?;
|
let right_node = self.parse_node(self.current_precedence())?;
|
||||||
let right_end = right_node.span.1;
|
let right_end = right_node.position.1;
|
||||||
|
|
||||||
return Ok(Node::new(
|
return Ok(Node::new(
|
||||||
Statement::Assign(Box::new(left_node), Box::new(right_node)),
|
Statement::Assign(Box::new(left_node), Box::new(right_node)),
|
||||||
@ -164,7 +164,7 @@ impl<'src> Parser<'src> {
|
|||||||
self.next_token()?;
|
self.next_token()?;
|
||||||
|
|
||||||
let right_node = self.parse_node(self.current_precedence())?;
|
let right_node = self.parse_node(self.current_precedence())?;
|
||||||
let right_end = right_node.span.1;
|
let right_end = right_node.position.1;
|
||||||
|
|
||||||
return Ok(Node::new(
|
return Ok(Node::new(
|
||||||
Statement::PropertyAccess(Box::new(left_node), Box::new(right_node)),
|
Statement::PropertyAccess(Box::new(left_node), Box::new(right_node)),
|
||||||
@ -178,7 +178,7 @@ impl<'src> Parser<'src> {
|
|||||||
Ok(left_node)
|
Ok(left_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_primary(&mut self) -> Result<Node, ParseError> {
|
fn parse_primary(&mut self) -> Result<Node<Span>, ParseError> {
|
||||||
match self.current.clone() {
|
match self.current.clone() {
|
||||||
(Token::Boolean(boolean), span) => {
|
(Token::Boolean(boolean), span) => {
|
||||||
self.next_token()?;
|
self.next_token()?;
|
||||||
|
@ -539,7 +539,7 @@ pub struct Function {
|
|||||||
pub name: Identifier,
|
pub name: Identifier,
|
||||||
pub type_parameters: Option<Vec<Type>>,
|
pub type_parameters: Option<Vec<Type>>,
|
||||||
pub value_parameters: Option<Vec<(Identifier, Type)>>,
|
pub value_parameters: Option<Vec<(Identifier, Type)>>,
|
||||||
pub body: Vec<Statement>,
|
pub body: Vec<Statement<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
|
@ -8,7 +8,7 @@ use crate::{
|
|||||||
pub fn run(
|
pub fn run(
|
||||||
input: &str,
|
input: &str,
|
||||||
variables: &mut HashMap<Identifier, Value>,
|
variables: &mut HashMap<Identifier, Value>,
|
||||||
) -> Result<Option<Value>, VmError> {
|
) -> Result<Option<Value>, VmError<Span>> {
|
||||||
let abstract_syntax_tree = parse(input)?;
|
let abstract_syntax_tree = parse(input)?;
|
||||||
let analyzer = Analyzer::new(&abstract_syntax_tree, variables);
|
let analyzer = Analyzer::new(&abstract_syntax_tree, variables);
|
||||||
|
|
||||||
@ -19,19 +19,19 @@ pub fn run(
|
|||||||
vm.run(variables)
|
vm.run(variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Vm {
|
pub struct Vm<P> {
|
||||||
abstract_tree: AbstractSyntaxTree,
|
abstract_tree: AbstractSyntaxTree<P>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vm {
|
impl<P: Copy> Vm<P> {
|
||||||
pub fn new(abstract_tree: AbstractSyntaxTree) -> Self {
|
pub fn new(abstract_tree: AbstractSyntaxTree<P>) -> Self {
|
||||||
Self { abstract_tree }
|
Self { abstract_tree }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(
|
pub fn run(
|
||||||
&mut self,
|
&mut self,
|
||||||
variables: &mut HashMap<Identifier, Value>,
|
variables: &mut HashMap<Identifier, Value>,
|
||||||
) -> Result<Option<Value>, VmError> {
|
) -> Result<Option<Value>, VmError<P>> {
|
||||||
let mut previous_value = None;
|
let mut previous_value = None;
|
||||||
|
|
||||||
while let Some(node) = self.abstract_tree.nodes.pop_front() {
|
while let Some(node) = self.abstract_tree.nodes.pop_front() {
|
||||||
@ -43,16 +43,15 @@ impl Vm {
|
|||||||
|
|
||||||
fn run_node(
|
fn run_node(
|
||||||
&self,
|
&self,
|
||||||
node: Node,
|
node: Node<P>,
|
||||||
variables: &mut HashMap<Identifier, Value>,
|
variables: &mut HashMap<Identifier, Value>,
|
||||||
) -> Result<Option<Value>, VmError> {
|
) -> Result<Option<Value>, VmError<P>> {
|
||||||
match node.statement {
|
match node.statement {
|
||||||
Statement::BuiltInValue(node) => self.run_node(*node, variables),
|
|
||||||
Statement::Constant(value) => Ok(Some(value.clone())),
|
Statement::Constant(value) => Ok(Some(value.clone())),
|
||||||
Statement::Identifier(_) => Ok(None),
|
Statement::Identifier(_) => Ok(None),
|
||||||
Statement::ReservedIdentifier(_) => Ok(None),
|
Statement::ReservedIdentifier(_) => Ok(None),
|
||||||
Statement::Add(left, right) => {
|
Statement::Add(left, right) => {
|
||||||
let left_span = left.span;
|
let left_span = left.position;
|
||||||
let left = if let Some(value) = self.run_node(*left, variables)? {
|
let left = if let Some(value) = self.run_node(*left, variables)? {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
@ -60,7 +59,7 @@ impl Vm {
|
|||||||
position: left_span,
|
position: left_span,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let right_span = right.span;
|
let right_span = right.position;
|
||||||
let right = if let Some(value) = self.run_node(*right, variables)? {
|
let right = if let Some(value) = self.run_node(*right, variables)? {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
@ -77,10 +76,10 @@ impl Vm {
|
|||||||
identifier
|
identifier
|
||||||
} else {
|
} else {
|
||||||
return Err(VmError::ExpectedIdentifier {
|
return Err(VmError::ExpectedIdentifier {
|
||||||
position: left.span,
|
position: left.position,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let right_span = right.span;
|
let right_span = right.position;
|
||||||
let value = if let Some(value) = self.run_node(*right, variables)? {
|
let value = if let Some(value) = self.run_node(*right, variables)? {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
@ -97,20 +96,20 @@ impl Vm {
|
|||||||
let values = nodes
|
let values = nodes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|node| {
|
.map(|node| {
|
||||||
let span = node.span;
|
let span = node.position;
|
||||||
if let Some(value) = self.run_node(node, variables)? {
|
if let Some(value) = self.run_node(node, variables)? {
|
||||||
Ok(value)
|
Ok(value)
|
||||||
} else {
|
} else {
|
||||||
Err(VmError::ExpectedValue { position: span })
|
Err(VmError::ExpectedValue { position: span })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<Value>, VmError>>()?;
|
.collect::<Result<Vec<Value>, VmError<P>>>()?;
|
||||||
|
|
||||||
Ok(Some(Value::list(values)))
|
Ok(Some(Value::list(values)))
|
||||||
}
|
}
|
||||||
Statement::Multiply(_, _) => todo!(),
|
Statement::Multiply(_, _) => todo!(),
|
||||||
Statement::PropertyAccess(left, right) => {
|
Statement::PropertyAccess(left, right) => {
|
||||||
let left_span = left.span;
|
let left_span = left.position;
|
||||||
let left = if let Some(value) = self.run_node(*left, variables)? {
|
let left = if let Some(value) = self.run_node(*left, variables)? {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
@ -118,7 +117,7 @@ impl Vm {
|
|||||||
position: left_span,
|
position: left_span,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let right_span = right.span;
|
let right_span = right.position;
|
||||||
|
|
||||||
if let Statement::ReservedIdentifier(reserved) = &right.statement {
|
if let Statement::ReservedIdentifier(reserved) = &right.statement {
|
||||||
match reserved {
|
match reserved {
|
||||||
@ -170,33 +169,33 @@ impl Vm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum VmError {
|
pub enum VmError<P> {
|
||||||
AnaylyzerError(AnalyzerError),
|
AnaylyzerError(AnalyzerError<P>),
|
||||||
ParseError(ParseError),
|
ParseError(ParseError),
|
||||||
ValueError(ValueError),
|
ValueError(ValueError),
|
||||||
|
|
||||||
// Anaylsis Failures
|
// Anaylsis Failures
|
||||||
// These should be prevented by running the analyzer before the VM
|
// These should be prevented by running the analyzer before the VM
|
||||||
ExpectedIdentifier { position: Span },
|
ExpectedIdentifier { position: P },
|
||||||
ExpectedIdentifierOrInteger { position: Span },
|
ExpectedIdentifierOrInteger { position: P },
|
||||||
ExpectedInteger { position: Span },
|
ExpectedInteger { position: P },
|
||||||
ExpectedList { position: Span },
|
ExpectedList { position: P },
|
||||||
ExpectedValue { position: Span },
|
ExpectedValue { position: P },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AnalyzerError> for VmError {
|
impl<P> From<AnalyzerError<P>> for VmError<P> {
|
||||||
fn from(error: AnalyzerError) -> Self {
|
fn from(error: AnalyzerError<P>) -> Self {
|
||||||
Self::AnaylyzerError(error)
|
Self::AnaylyzerError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ParseError> for VmError {
|
impl<P> From<ParseError> for VmError<P> {
|
||||||
fn from(error: ParseError) -> Self {
|
fn from(error: ParseError) -> Self {
|
||||||
Self::ParseError(error)
|
Self::ParseError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ValueError> for VmError {
|
impl<P> From<ValueError> for VmError<P> {
|
||||||
fn from(error: ValueError) -> Self {
|
fn from(error: ValueError) -> Self {
|
||||||
Self::ValueError(error)
|
Self::ValueError(error)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user