Begin reimplementing the VM
This commit is contained in:
parent
40b5d15b96
commit
b48b5d4369
@ -11,60 +11,52 @@ use super::{Node, Statement};
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum Expression {
|
pub enum Expression {
|
||||||
WithBlock(Node<Box<ExpressionWithBlock>>),
|
Block(Node<Box<Block>>),
|
||||||
WithoutBlock(Node<Box<ExpressionWithoutBlock>>),
|
Call(Node<Box<CallExpression>>),
|
||||||
|
FieldAccess(Node<Box<FieldAccess>>),
|
||||||
|
Grouped(Node<Box<Expression>>),
|
||||||
|
Identifier(Node<Identifier>),
|
||||||
|
If(Node<Box<If>>),
|
||||||
|
List(Node<Box<ListExpression>>),
|
||||||
|
ListIndex(Node<Box<ListIndex>>),
|
||||||
|
Literal(Node<Box<LiteralExpression>>),
|
||||||
|
Loop(Node<Box<Loop>>),
|
||||||
|
Operator(Node<Box<OperatorExpression>>),
|
||||||
|
Range(Node<Box<Range>>),
|
||||||
|
Struct(Node<Box<StructExpression>>),
|
||||||
|
TupleAccess(Node<Box<TupleAccess>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub fn operator(operator_expression: OperatorExpression, position: Span) -> Self {
|
pub fn operator(operator_expression: OperatorExpression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Operator(Node::new(Box::new(operator_expression), position))
|
||||||
Box::new(ExpressionWithoutBlock::Operator(operator_expression)),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn range(start: Expression, end: Expression, position: Span) -> Self {
|
pub fn range(start: Expression, end: Expression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Range(Node::new(Box::new(Range { start, end }), position))
|
||||||
Box::new(ExpressionWithoutBlock::Range(Range { start, end })),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call(invoker: Expression, arguments: Vec<Expression>, position: Span) -> Self {
|
pub fn call(invoker: Expression, arguments: Vec<Expression>, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Call(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::Call(CallExpression {
|
Box::new(CallExpression { invoker, arguments }),
|
||||||
invoker,
|
|
||||||
arguments,
|
|
||||||
})),
|
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn field_access(container: Expression, field: Node<Identifier>, position: Span) -> Self {
|
pub fn field_access(container: Expression, field: Node<Identifier>, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::FieldAccess(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::FieldAccess(FieldAccess {
|
Box::new(FieldAccess { container, field }),
|
||||||
container,
|
|
||||||
field,
|
|
||||||
})),
|
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tuple_access(tuple: Expression, index: Node<usize>, position: Span) -> Self {
|
pub fn tuple_access(tuple: Expression, index: Node<usize>, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::TupleAccess(Node::new(Box::new(TupleAccess { tuple, index }), position))
|
||||||
Box::new(ExpressionWithoutBlock::TupleAccess(TupleAccess {
|
|
||||||
tuple,
|
|
||||||
index,
|
|
||||||
})),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assignment(assignee: Expression, value: Expression, position: Span) -> Self {
|
pub fn assignment(assignee: Expression, value: Expression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Operator(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::Operator(
|
Box::new(OperatorExpression::Assignment { assignee, value }),
|
||||||
OperatorExpression::Assignment { assignee, value },
|
|
||||||
)),
|
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -75,14 +67,12 @@ impl Expression {
|
|||||||
right: Expression,
|
right: Expression,
|
||||||
position: Span,
|
position: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Operator(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::Operator(
|
Box::new(OperatorExpression::Comparison {
|
||||||
OperatorExpression::Comparison {
|
left,
|
||||||
left,
|
operator,
|
||||||
operator,
|
right,
|
||||||
right,
|
}),
|
||||||
},
|
|
||||||
)),
|
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -93,14 +83,12 @@ impl Expression {
|
|||||||
modifier: Expression,
|
modifier: Expression,
|
||||||
position: Span,
|
position: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Operator(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::Operator(
|
Box::new(OperatorExpression::CompoundAssignment {
|
||||||
OperatorExpression::CompoundAssignment {
|
assignee,
|
||||||
assignee,
|
operator,
|
||||||
operator,
|
modifier,
|
||||||
modifier,
|
}),
|
||||||
},
|
|
||||||
)),
|
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -111,30 +99,26 @@ impl Expression {
|
|||||||
right: Expression,
|
right: Expression,
|
||||||
position: Span,
|
position: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Operator(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::Operator(OperatorExpression::Math {
|
Box::new(OperatorExpression::Math {
|
||||||
left,
|
left,
|
||||||
operator,
|
operator,
|
||||||
right,
|
right,
|
||||||
})),
|
}),
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn negation(expression: Expression, position: Span) -> Self {
|
pub fn negation(expression: Expression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Operator(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::Operator(
|
Box::new(OperatorExpression::Negation(expression)),
|
||||||
OperatorExpression::Negation(expression),
|
|
||||||
)),
|
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn not(expression: Expression, position: Span) -> Self {
|
pub fn not(expression: Expression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Operator(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::Operator(OperatorExpression::Not(
|
Box::new(OperatorExpression::Not(expression)),
|
||||||
expression,
|
|
||||||
))),
|
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -145,37 +129,30 @@ impl Expression {
|
|||||||
right: Expression,
|
right: Expression,
|
||||||
position: Span,
|
position: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Operator(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::Operator(
|
Box::new(OperatorExpression::Logic {
|
||||||
OperatorExpression::Logic {
|
left,
|
||||||
left,
|
operator,
|
||||||
operator,
|
right,
|
||||||
right,
|
}),
|
||||||
},
|
|
||||||
)),
|
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error_propagation(expression: Expression, position: Span) -> Self {
|
pub fn error_propagation(expression: Expression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Operator(Node::new(
|
||||||
Box::new(ExpressionWithoutBlock::Operator(
|
Box::new(OperatorExpression::ErrorPropagation(expression)),
|
||||||
OperatorExpression::ErrorPropagation(expression),
|
|
||||||
)),
|
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infinite_loop(block: Node<Block>, position: Span) -> Self {
|
pub fn infinite_loop(block: Node<Block>, position: Span) -> Self {
|
||||||
Expression::WithBlock(Node::new(
|
Self::Loop(Node::new(Box::new(Loop::Infinite { block }), position))
|
||||||
Box::new(ExpressionWithBlock::Loop(Loop::Infinite { block })),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn while_loop(condition: Expression, block: Node<Block>, position: Span) -> Self {
|
pub fn while_loop(condition: Expression, block: Node<Block>, position: Span) -> Self {
|
||||||
Expression::WithBlock(Node::new(
|
Self::Loop(Node::new(
|
||||||
Box::new(ExpressionWithBlock::Loop(Loop::While { condition, block })),
|
Box::new(Loop::While { condition, block }),
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -186,82 +163,51 @@ impl Expression {
|
|||||||
block: Node<Block>,
|
block: Node<Block>,
|
||||||
position: Span,
|
position: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Expression::WithBlock(Node::new(
|
Self::Loop(Node::new(
|
||||||
Box::new(ExpressionWithBlock::Loop(Loop::For {
|
Box::new(Loop::For {
|
||||||
identifier,
|
identifier,
|
||||||
iterator,
|
iterator,
|
||||||
block,
|
block,
|
||||||
})),
|
}),
|
||||||
position,
|
position,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn block(block: Block, position: Span) -> Self {
|
pub fn block(block: Block, position: Span) -> Self {
|
||||||
Expression::WithBlock(Node::new(
|
Self::Block(Node::new(Box::new(block), position))
|
||||||
Box::new(ExpressionWithBlock::Block(block)),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grouped(expression: Expression, position: Span) -> Self {
|
pub fn grouped(expression: Expression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Grouped(Node::new(Box::new(expression), position))
|
||||||
Box::new(ExpressionWithoutBlock::Grouped(expression)),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn r#struct(struct_expression: StructExpression, position: Span) -> Self {
|
pub fn r#struct(struct_expression: StructExpression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Struct(Node::new(Box::new(struct_expression), position))
|
||||||
Box::new(ExpressionWithoutBlock::Struct(struct_expression)),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn identifier(identifier: Identifier, position: Span) -> Self {
|
pub fn identifier(identifier: Identifier, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Identifier(Node::new(identifier, position))
|
||||||
Box::new(ExpressionWithoutBlock::Identifier(identifier)),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list(list_expression: ListExpression, position: Span) -> Self {
|
pub fn list(list_expression: ListExpression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::List(Node::new(Box::new(list_expression), position))
|
||||||
Box::new(ExpressionWithoutBlock::List(list_expression)),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_index(list_index: ListIndex, position: Span) -> Self {
|
pub fn list_index(list_index: ListIndex, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::ListIndex(Node::new(Box::new(list_index), position))
|
||||||
Box::new(ExpressionWithoutBlock::ListIndex(list_index)),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn r#if(r#if: If, position: Span) -> Self {
|
pub fn r#if(r#if: If, position: Span) -> Self {
|
||||||
Expression::WithBlock(Node::new(Box::new(ExpressionWithBlock::If(r#if)), position))
|
Self::If(Node::new(Box::new(r#if), position))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn literal(literal: LiteralExpression, position: Span) -> Self {
|
pub fn literal(literal: LiteralExpression, position: Span) -> Self {
|
||||||
Expression::WithoutBlock(Node::new(
|
Self::Literal(Node::new(Box::new(literal), position))
|
||||||
Box::new(ExpressionWithoutBlock::Literal(literal)),
|
|
||||||
position,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_identifier(&self) -> Option<&Identifier> {
|
pub fn as_identifier(&self) -> Option<&Identifier> {
|
||||||
if let Expression::WithoutBlock(Node {
|
if let Expression::Identifier(identifier) = self {
|
||||||
inner: expression_without_block,
|
Some(&identifier.inner)
|
||||||
..
|
|
||||||
}) = self
|
|
||||||
{
|
|
||||||
if let ExpressionWithoutBlock::Identifier(identifier) =
|
|
||||||
expression_without_block.as_ref()
|
|
||||||
{
|
|
||||||
Some(identifier)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -269,8 +215,20 @@ impl Expression {
|
|||||||
|
|
||||||
pub fn position(&self) -> Span {
|
pub fn position(&self) -> Span {
|
||||||
match self {
|
match self {
|
||||||
Expression::WithBlock(expression_node) => expression_node.position,
|
Expression::Block(block) => block.position,
|
||||||
Expression::WithoutBlock(expression_node) => expression_node.position,
|
Expression::Call(call) => call.position,
|
||||||
|
Expression::FieldAccess(field_access) => field_access.position,
|
||||||
|
Expression::Grouped(grouped) => grouped.position,
|
||||||
|
Expression::Identifier(identifier) => identifier.position,
|
||||||
|
Expression::If(r#if) => r#if.position,
|
||||||
|
Expression::List(list) => list.position,
|
||||||
|
Expression::ListIndex(list_index) => list_index.position,
|
||||||
|
Expression::Literal(literal) => literal.position,
|
||||||
|
Expression::Loop(r#loop) => r#loop.position,
|
||||||
|
Expression::Operator(operator) => operator.position,
|
||||||
|
Expression::Range(range) => range.position,
|
||||||
|
Expression::Struct(r#struct) => r#struct.position,
|
||||||
|
Expression::TupleAccess(tuple_access) => tuple_access.position,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,58 +236,20 @@ impl Expression {
|
|||||||
impl Display for Expression {
|
impl Display for Expression {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Expression::WithBlock(expression) => write!(f, "{}", expression),
|
Expression::Block(block) => write!(f, "{}", block.inner),
|
||||||
Expression::WithoutBlock(expression) => write!(f, "{}", expression),
|
Expression::Call(call) => write!(f, "{}", call.inner),
|
||||||
}
|
Expression::FieldAccess(field_access) => write!(f, "{}", field_access.inner),
|
||||||
}
|
Expression::Grouped(grouped) => write!(f, "({})", grouped.inner),
|
||||||
}
|
Expression::Identifier(identifier) => write!(f, "{}", identifier.inner),
|
||||||
|
Expression::If(r#if) => write!(f, "{}", r#if.inner),
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
Expression::List(list) => write!(f, "{}", list.inner),
|
||||||
pub enum ExpressionWithBlock {
|
Expression::ListIndex(list_index) => write!(f, "{}", list_index.inner),
|
||||||
Block(Block),
|
Expression::Literal(literal) => write!(f, "{}", literal.inner),
|
||||||
Loop(Loop),
|
Expression::Loop(r#loop) => write!(f, "{}", r#loop.inner),
|
||||||
If(If),
|
Expression::Operator(operator) => write!(f, "{}", operator.inner),
|
||||||
}
|
Expression::Range(range) => write!(f, "{}", range),
|
||||||
|
Expression::Struct(r#struct) => write!(f, "{}", r#struct.inner),
|
||||||
impl Display for ExpressionWithBlock {
|
Expression::TupleAccess(tuple_access) => write!(f, "{}", tuple_access),
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
ExpressionWithBlock::Block(block) => write!(f, "{}", block),
|
|
||||||
ExpressionWithBlock::Loop(r#loop) => write!(f, "{}", r#loop),
|
|
||||||
ExpressionWithBlock::If(r#if) => write!(f, "{}", r#if),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
|
||||||
pub enum ExpressionWithoutBlock {
|
|
||||||
Call(CallExpression),
|
|
||||||
List(ListExpression),
|
|
||||||
Literal(LiteralExpression),
|
|
||||||
Identifier(Identifier),
|
|
||||||
Operator(OperatorExpression),
|
|
||||||
Struct(StructExpression),
|
|
||||||
Grouped(Expression),
|
|
||||||
FieldAccess(FieldAccess),
|
|
||||||
ListIndex(ListIndex),
|
|
||||||
Range(Range),
|
|
||||||
TupleAccess(TupleAccess),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for ExpressionWithoutBlock {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
ExpressionWithoutBlock::Call(call_expression) => write!(f, "{}", call_expression),
|
|
||||||
ExpressionWithoutBlock::List(list) => write!(f, "{}", list),
|
|
||||||
ExpressionWithoutBlock::Literal(literal) => write!(f, "{}", literal),
|
|
||||||
ExpressionWithoutBlock::Identifier(identifier) => write!(f, "{}", identifier),
|
|
||||||
ExpressionWithoutBlock::Operator(expression) => write!(f, "{}", expression),
|
|
||||||
ExpressionWithoutBlock::Struct(struct_expression) => write!(f, "{}", struct_expression),
|
|
||||||
ExpressionWithoutBlock::Grouped(expression) => write!(f, "({})", expression),
|
|
||||||
ExpressionWithoutBlock::FieldAccess(field_access) => write!(f, "{}", field_access),
|
|
||||||
ExpressionWithoutBlock::ListIndex(list_index) => write!(f, "{}", list_index),
|
|
||||||
ExpressionWithoutBlock::Range(range) => write!(f, "{}", range),
|
|
||||||
ExpressionWithoutBlock::TupleAccess(tuple_access) => write!(f, "{}", tuple_access),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use std::{
|
|||||||
error::Error,
|
error::Error,
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
ops::Range,
|
ops::Range,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock, RwLockWriteGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::{
|
use serde::{
|
||||||
@ -135,13 +135,6 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_property(&self, property: &Identifier) -> Option<Value> {
|
|
||||||
match self {
|
|
||||||
Value::Immutable(inner) => inner.get_property(property),
|
|
||||||
Value::Mutable(inner_locked) => inner_locked.read().unwrap().get_property(property),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_boolean(&self) -> Option<bool> {
|
pub fn as_boolean(&self) -> Option<bool> {
|
||||||
match self {
|
match self {
|
||||||
Value::Immutable(arc) => match arc.as_ref() {
|
Value::Immutable(arc) => match arc.as_ref() {
|
||||||
@ -211,16 +204,6 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_range(&self) -> Option<&Range<i64>> {
|
|
||||||
if let Value::Immutable(arc) = self {
|
|
||||||
if let ValueData::Range(range) = arc.as_ref() {
|
|
||||||
return Some(range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_string(&self) -> Option<&String> {
|
pub fn as_string(&self) -> Option<&String> {
|
||||||
if let Value::Immutable(arc) = self {
|
if let Value::Immutable(arc) = self {
|
||||||
if let ValueData::String(string) = arc.as_ref() {
|
if let ValueData::String(string) = arc.as_ref() {
|
||||||
@ -231,6 +214,46 @@ impl Value {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_struct(&self) -> Option<&Struct> {
|
||||||
|
if let Value::Immutable(arc) = self {
|
||||||
|
if let ValueData::Struct(r#struct) = arc.as_ref() {
|
||||||
|
return Some(r#struct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value_data_immutable(&self) -> Option<&ValueData> {
|
||||||
|
if let Value::Immutable(inner) = self {
|
||||||
|
Some(inner.as_ref())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value_data_mutable(&self) -> Option<RwLockWriteGuard<ValueData>> {
|
||||||
|
if let Value::Mutable(inner) = self {
|
||||||
|
Some(inner.write().unwrap())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_field(&self, field: &Identifier) -> Option<Value> {
|
||||||
|
return match self {
|
||||||
|
Value::Immutable(inner) => inner.get_field(field),
|
||||||
|
Value::Mutable(inner) => inner.read().unwrap().get_field(field),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_index(&self, index: usize) -> Option<Value> {
|
||||||
|
return match self {
|
||||||
|
Value::Immutable(inner) => inner.get_index(index),
|
||||||
|
Value::Mutable(inner) => inner.read().unwrap().get_index(index),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add(&self, other: &Value) -> Result<Value, ValueError> {
|
pub fn add(&self, other: &Value) -> Result<Value, ValueError> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Value::Immutable(left), Value::Immutable(right)) => {
|
(Value::Immutable(left), Value::Immutable(right)) => {
|
||||||
@ -998,19 +1021,44 @@ impl ValueData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_property(&self, property: &Identifier) -> Option<Value> {
|
fn get_field(&self, property: &Identifier) -> Option<Value> {
|
||||||
match self {
|
if let ValueData::Struct(Struct::Fields { fields, .. }) = self {
|
||||||
ValueData::List(list) => {
|
fields.iter().find_map(|(identifier, value)| {
|
||||||
if property.as_str() == "length" {
|
if identifier == property {
|
||||||
Some(Value::integer(list.len() as i64))
|
Some(value.clone())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
ValueData::Map(value_map) => value_map.get(property).cloned(),
|
} else {
|
||||||
_ => None,
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_index(&self, index: usize) -> Option<Value> {
|
||||||
|
if let ValueData::List(list) = self {
|
||||||
|
return list.get(index).cloned();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let ValueData::Range(range) = self {
|
||||||
|
if range.contains(&(index as i64)) {
|
||||||
|
return Some(Value::integer(index as i64));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let ValueData::String(string) = self {
|
||||||
|
return string
|
||||||
|
.chars()
|
||||||
|
.nth(index)
|
||||||
|
.map(|character| Value::string(character.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let ValueData::Struct(Struct::Tuple { fields, .. }) = self {
|
||||||
|
return fields.get(index).cloned();
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ValueData {
|
impl Display for ValueData {
|
||||||
@ -1407,7 +1455,7 @@ pub struct Function {
|
|||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
pub fn call(
|
pub fn call(
|
||||||
self,
|
&self,
|
||||||
_type_arguments: Option<Vec<Type>>,
|
_type_arguments: Option<Vec<Type>>,
|
||||||
value_arguments: Option<Vec<Value>>,
|
value_arguments: Option<Vec<Value>>,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
@ -1415,14 +1463,14 @@ impl Function {
|
|||||||
let new_context = Context::with_variables_from(context);
|
let new_context = Context::with_variables_from(context);
|
||||||
|
|
||||||
if let (Some(value_parameters), Some(value_arguments)) =
|
if let (Some(value_parameters), Some(value_arguments)) =
|
||||||
(self.value_parameters, value_arguments)
|
(&self.value_parameters, value_arguments)
|
||||||
{
|
{
|
||||||
for ((identifier, _), value) in value_parameters.into_iter().zip(value_arguments) {
|
for ((identifier, _), value) in value_parameters.into_iter().zip(value_arguments) {
|
||||||
new_context.set_value(identifier, value);
|
new_context.set_value(identifier.clone(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut vm = Vm::new(self.body, new_context);
|
let mut vm = Vm::new(self.body.clone(), new_context);
|
||||||
|
|
||||||
vm.run()
|
vm.run()
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,12 @@ use std::{
|
|||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
abstract_tree::{AbstractSyntaxTree, Node, Statement},
|
abstract_tree::{AbstractSyntaxTree, Block, CallExpression, FieldAccess, Node, Statement},
|
||||||
parse, Analyzer, BuiltInFunctionError, Context, DustError, Identifier, ParseError, Span,
|
parse, Analyzer, BuiltInFunctionError, Context, DustError, Expression, Identifier, ParseError,
|
||||||
Struct, StructType, Type, Value, ValueError,
|
Span, Struct, StructType, Type, Value, ValueError,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Run the source code and return the result.
|
/// Run the source code and return the result.
|
||||||
@ -101,8 +103,110 @@ impl Vm {
|
|||||||
Ok(previous_value)
|
Ok(previous_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_statement(&self, node: Statement) -> Result<Option<Value>, VmError> {
|
fn run_statement(&self, statement: Statement) -> Result<Option<Value>, VmError> {
|
||||||
todo!()
|
match statement {
|
||||||
|
Statement::Expression(expression) => self.run_expression(expression),
|
||||||
|
Statement::ExpressionNullified(expression) => {
|
||||||
|
self.run_expression(expression.inner)?;
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
Statement::Let(_) => todo!(),
|
||||||
|
Statement::StructDefinition(_) => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_expression(&self, expression: Expression) -> Result<Option<Value>, VmError> {
|
||||||
|
match expression {
|
||||||
|
Expression::Block(Node { inner, position }) => match *inner {
|
||||||
|
Block::Async(statements) => {
|
||||||
|
let error_option = statements
|
||||||
|
.into_par_iter()
|
||||||
|
.find_map_any(|statement| self.run_statement(statement).err());
|
||||||
|
|
||||||
|
if let Some(error) = error_option {
|
||||||
|
Err(error)
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Block::Sync(statements) => {
|
||||||
|
let mut previous_value = None;
|
||||||
|
|
||||||
|
for statement in statements {
|
||||||
|
let position = statement.position();
|
||||||
|
|
||||||
|
previous_value = self.run_statement(statement)?;
|
||||||
|
|
||||||
|
self.context.collect_garbage(position.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(previous_value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Expression::Call(Node { inner, .. }) => {
|
||||||
|
let CallExpression { invoker, arguments } = *inner;
|
||||||
|
|
||||||
|
let invoker_position = invoker.position();
|
||||||
|
let invoker_value = if let Some(value) = self.run_expression(invoker)? {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
return Err(VmError::ExpectedValue {
|
||||||
|
position: invoker_position,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let function = if let Some(function) = invoker_value.as_function() {
|
||||||
|
function
|
||||||
|
} else {
|
||||||
|
return Err(VmError::ExpectedFunction {
|
||||||
|
actual: invoker_value,
|
||||||
|
position: invoker_position,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut value_arguments = Vec::new();
|
||||||
|
|
||||||
|
for argument in arguments {
|
||||||
|
let position = argument.position();
|
||||||
|
|
||||||
|
if let Some(value) = self.run_expression(argument)? {
|
||||||
|
value_arguments.push(value);
|
||||||
|
} else {
|
||||||
|
return Err(VmError::ExpectedValue { position });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let context = Context::new();
|
||||||
|
|
||||||
|
function.call(None, Some(value_arguments), &context)
|
||||||
|
}
|
||||||
|
Expression::FieldAccess(Node { inner, .. }) => {
|
||||||
|
let FieldAccess { container, field } = *inner;
|
||||||
|
|
||||||
|
let container_position = container.position();
|
||||||
|
let container_value = if let Some(value) = self.run_expression(container)? {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
return Err(VmError::ExpectedValue {
|
||||||
|
position: container_position,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(container_value.get_field(&field.inner))
|
||||||
|
}
|
||||||
|
Expression::Grouped(_) => todo!(),
|
||||||
|
Expression::Identifier(_) => todo!(),
|
||||||
|
Expression::If(_) => todo!(),
|
||||||
|
Expression::List(_) => todo!(),
|
||||||
|
Expression::ListIndex(_) => todo!(),
|
||||||
|
Expression::Literal(_) => todo!(),
|
||||||
|
Expression::Loop(_) => todo!(),
|
||||||
|
Expression::Operator(_) => todo!(),
|
||||||
|
Expression::Range(_) => todo!(),
|
||||||
|
Expression::Struct(_) => todo!(),
|
||||||
|
Expression::TupleAccess(_) => todo!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user