Newer
Older
use crate::format_forge_error;
use crate::parse::ast::{BinaryOp, Program, UnaryOp, ValueExpression, VoidExpression};
use crate::parser::ast::GroupedExpression;
use crate::parser::parse_program;
use crate::runtime::executor::Visitor;
use crate::runtime::value::ForgeValue;
use crate::runtime::vm::{Chunk, ChunkRef, OpCode, VmError};
pub struct ChunkBuilder {
current_chunk: Chunk,
}
impl ChunkBuilder {
pub fn new() -> Self {
Self {
current_chunk: Chunk::default(),
}
}
pub fn parse(code: &str) -> Result<Chunk, VmError> {
let mut builder = ChunkBuilder::new();
let program = parse_program(code)?; //.map_err(|fe| VmError::ast_parser(format_forge_error(code, &fe)))?;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
builder.evaluate_program(&program)?;
Ok(builder.take_chunk())
}
pub fn chunk_ref(&self) -> ChunkRef {
self.current_chunk.as_ref()
}
pub fn take_chunk(&mut self) -> Chunk {
std::mem::take(&mut self.current_chunk)
}
}
impl Visitor for ChunkBuilder {
type Output = ();
type Error = VmError;
fn evaluate_value_expression(
&mut self,
expression: &ValueExpression,
) -> Result<Self::Output, Self::Error> {
match expression {
ValueExpression::Unary { operator, operand } => {
self.evaluate_value_expression(operand.as_ref())?;
match operator {
UnaryOp::Not => Err(VmError::chunk_parser("Unsupported expression")),
UnaryOp::Negate => {
self.current_chunk.push_op(OpCode::Invert);
Ok(())
}
}
}
ValueExpression::Binary { lhs, rhs, operator } => {
self.evaluate_value_expression(lhs.as_ref())?;
self.evaluate_value_expression(rhs.as_ref())?;
match operator {
BinaryOp::Add => {
self.current_chunk.push_op(OpCode::Add);
Ok(())
}
BinaryOp::Subtract => {
self.current_chunk.push_op(OpCode::Subtract);
Ok(())
}
BinaryOp::Multiply => {
self.current_chunk.push_op(OpCode::Multiply);
Ok(())
}
BinaryOp::Divide => {
self.current_chunk.push_op(OpCode::Divide);
Ok(())
}
BinaryOp::Modulo => Err(VmError::chunk_parser("Unsupported expression")),
BinaryOp::Equals => Err(VmError::chunk_parser("Unsupported expression")),
BinaryOp::BoolAnd => Err(VmError::chunk_parser("Unsupported expression")),
BinaryOp::BoolOr => Err(VmError::chunk_parser("Unsupported expression")),
BinaryOp::NotEquals => Err(VmError::chunk_parser("Unsupported expression")),
BinaryOp::LessThan => Err(VmError::chunk_parser("Unsupported expression")),
BinaryOp::GreaterThan => Err(VmError::chunk_parser("Unsupported expression")),
BinaryOp::LessThanEqual => Err(VmError::chunk_parser("Unsupported expression")),
BinaryOp::GreaterThanEqual => {
Err(VmError::chunk_parser("Unsupported expression"))
}
}
}
ValueExpression::Grouped(GroupedExpression { inner }) => {
self.evaluate_value_expression(inner.as_ref())
}
ValueExpression::Block(_) => Err(VmError::chunk_parser("Unsupported expression")),
ValueExpression::Literal(val) => {
self.current_chunk
.op_constant(ForgeValue::from(val.clone()));
Ok(())
}
ValueExpression::DeclareIdentifier(_) => {
Err(VmError::chunk_parser("Unsupported expression"))
}
ValueExpression::Assignment(_) => Err(VmError::chunk_parser("Unsupported expression")),
ValueExpression::ConditionalBlock(_) => {
Err(VmError::chunk_parser("Unsupported expression"))
}
ValueExpression::Identifier(_) => Err(VmError::chunk_parser("Unsupported expression")),

Louis
committed
ValueExpression::Accessor(_) => Err(VmError::chunk_parser("Unsupported expression")),
ValueExpression::FunctionCall(_) => {
Err(VmError::chunk_parser("Unsupported expression"))
}
ValueExpression::DeclareFunction(_) => {
Err(VmError::chunk_parser("Unsupported expression"))
}
ValueExpression::Typeof(_) => Err(VmError::chunk_parser("Unsupported expression")),
}
}
fn evaluate_void_expression(
&mut self,
expression: &VoidExpression,
) -> Result<Self::Output, Self::Error> {
match expression {
VoidExpression::ConditionLoop(_) => {
Err(VmError::chunk_parser("Unsupported expression"))
}
VoidExpression::Import(_) => Err(VmError::chunk_parser("Unsupported expression")),
VoidExpression::Export(_) => Err(VmError::chunk_parser("Unsupported expression")),
VoidExpression::Print(_) => Err(VmError::chunk_parser("Unsupported expression")),

Louis
committed
VoidExpression::Return(_) => Err(VmError::chunk_parser("Unsupported expression")),
}
}
fn evaluate_program(&mut self, program: &Program) -> Result<Self::Output, Self::Error> {
for expr in program.0.iter() {
self.evaluate_expression(expr)?;
}
self.current_chunk.push_op(OpCode::Return);
Ok(())
}
}