Tracing options, while loop

This commit is contained in:
2026-05-08 17:16:32 +03:00
parent 55e38af0ed
commit aa0026fa45
15 changed files with 253 additions and 59 deletions
+17 -15
View File
@@ -7,18 +7,20 @@
) )
) )
(print 1 "\t" (factorial 1)) (defun loop-factorial (x)
(print 2 "\t" (factorial 2)) (let (i 0 acc 1)
(print 3 "\t" (factorial 3)) (while (< i x)
(print 4 "\t" (factorial 4)) (setq i (+ i 1))
(print 5 "\t" (factorial 5)) (setq acc (* acc i))
(print 6 "\t" (factorial 6)) )
(print 7 "\t" (factorial 7)) acc
(print 8 "\t" (factorial 8)) )
(print 9 "\t" (factorial 9)) )
(print 10 "\t" (factorial 10))
(print 11 "\t" (factorial 11)) ;; TODO for loops?
(print 12 "\t" (factorial 12)) (let (i 0)
(print 13 "\t" (factorial 13)) (while (<= i 15)
(print 14 "\t" (factorial 14)) (print i "\t" (factorial i) "\t" (loop-factorial i))
(print 15 "\t" (factorial 15)) (setq i (+ i 1))
)
)
+25
View File
@@ -0,0 +1,25 @@
;; vi:ft=lisp:sw=2:ts=2
(defun replace-argument (x) (let (x 1) x))
(defun replace-let ()
(let (x 1)
(setq x 2) ;; mutate local x
x
)
)
(defun reassignment-in-a-loop (iterations)
(let (x 0 y 1)
(while (< x iterations)
(setq y (* y 2))
(setq x (+ x 1))
)
y
)
)
(assert (= (replace-argument 2) 1))
(assert (= (replace-argument 3) 1))
(assert (= (replace-let) 2))
(assert (= (reassignment-in-a-loop 4) 16))
+63 -15
View File
@@ -9,6 +9,7 @@ use crate::{
syntax::{ syntax::{
CallExpression, CondExpression, DefmacroExpression, DefunExpression, Expression, CallExpression, CondExpression, DefmacroExpression, DefunExpression, Expression,
FunctionBody, IfExpression, LambdaExpression, LetExpression, SetqExpression, FunctionBody, IfExpression, LambdaExpression, LetExpression, SetqExpression,
WhileExpression,
}, },
value::{BuiltinFunction, CompileConstant, CompileValue}, value::{BuiltinFunction, CompileConstant, CompileValue},
}, },
@@ -136,13 +137,19 @@ impl FunctionBlock {
self.labels.insert(label, self.instructions.len()); self.labels.insert(label, self.instructions.len());
} }
pub fn resolve_labels(self) -> CompiledFunction { pub fn resolve_labels(self, trace: bool) -> CompiledFunction {
let mut instructions = vec![]; let mut instructions = vec![];
// eprintln!("RESOLVE LABELS");
if trace {
eprintln!("Instruction resolution:");
}
for (function_offset, emitted) in self.instructions.into_iter().enumerate() { for (function_offset, emitted) in self.instructions.into_iter().enumerate() {
match emitted { match emitted {
Emitted::Instruction(instruction) => { Emitted::Instruction(instruction) => {
// eprintln!("{function_offset}: {instruction:?}"); if trace {
eprintln!("{function_offset}: {instruction:?}");
}
instructions.push(instruction); instructions.push(instruction);
} }
Emitted::Branch(label) => { Emitted::Branch(label) => {
@@ -151,9 +158,11 @@ impl FunctionBlock {
todo!() todo!()
} }
let diff = address.checked_signed_diff(function_offset).expect("TODO"); let diff = address.checked_signed_diff(function_offset).expect("TODO");
// eprintln!( if trace {
// "{function_offset}: branch to label {label} (@ {address}) -> {diff:+}" eprintln!(
// ); "{function_offset}: Branch: label {label} (@ {address}) -> {diff:+}"
);
}
let offset = U::from_signed(diff as i64).expect("TODO"); let offset = U::from_signed(diff as i64).expect("TODO");
instructions.push(Instruction::Branch(offset)); instructions.push(Instruction::Branch(offset));
} }
@@ -163,7 +172,11 @@ impl FunctionBlock {
todo!() todo!()
} }
let diff = address.checked_signed_diff(function_offset).expect("TODO"); let diff = address.checked_signed_diff(function_offset).expect("TODO");
// eprintln!("{function_offset}: jump to label {label} (@ {address}) -> {diff:+}"); if trace {
eprintln!(
"{function_offset}: jump to label {label} (@ {address}) -> {diff:+}"
);
}
let offset = U::from_signed(diff as i64).expect("TODO"); let offset = U::from_signed(diff as i64).expect("TODO");
instructions.push(Instruction::Jump(offset)); instructions.push(Instruction::Jump(offset));
} }
@@ -464,6 +477,30 @@ impl<'a> LocalBlock<'a> {
Ok(CompileValue::Stack) Ok(CompileValue::Stack)
} }
fn compile_while(&mut self, cloop: &WhileExpression) -> Result<CompileValue, CompileError> {
let label_start = self.function.new_label();
let label_end = self.function.new_label();
self.function.adjust_label(label_start);
// Condition
let condition_value = self.compile_expression(&cloop.condition)?;
self.compile_push(condition_value)?;
self.function.emit(Emitted::Branch(label_end));
// Body
for expression in &cloop.body.head {
self.compile_statement(expression)?;
}
self.compile_statement(&cloop.body.tail)?;
// Jump back
self.function.emit(Emitted::Jump(label_start));
self.function.adjust_label(label_end);
Ok(CompileValue::Nil)
}
fn compile_let(&mut self, binding: &LetExpression) -> Result<CompileValue, CompileError> { fn compile_let(&mut self, binding: &LetExpression) -> Result<CompileValue, CompileError> {
self.function.push_local_scope(); self.function.push_local_scope();
let mut indices = vec![]; let mut indices = vec![];
@@ -496,7 +533,16 @@ impl<'a> LocalBlock<'a> {
fn compile_setq(&mut self, setq: &SetqExpression) -> Result<CompileValue, CompileError> { fn compile_setq(&mut self, setq: &SetqExpression) -> Result<CompileValue, CompileError> {
for pair in setq.pairs.iter() { for pair in setq.pairs.iter() {
let value = self.compile_expression(&pair.value)?; let value = self.compile_expression(&pair.value)?;
self.compile_set_global(&pair.identifier, value)?; if let Some(index) = self
.function
.local_scope_ref()
.and_then(|scope| scope.get(&pair.identifier))
{
self.compile_push(value)?;
self.function.emit(Instruction::SetLocal(index));
} else {
self.compile_set_global(&pair.identifier, value)?;
}
} }
Ok(CompileValue::Nil) Ok(CompileValue::Nil)
} }
@@ -524,6 +570,7 @@ impl<'a> LocalBlock<'a> {
Expression::Setq(setq) => self.compile_setq(setq), Expression::Setq(setq) => self.compile_setq(setq),
Expression::Defmacro(defmacro) => self.compile_defmacro(defmacro), Expression::Defmacro(defmacro) => self.compile_defmacro(defmacro),
Expression::Quote(quote) => self.compile_quote(quote), Expression::Quote(quote) => self.compile_quote(quote),
Expression::While(cloop) => self.compile_while(cloop),
Expression::SyntaxError(_) => unreachable!(), Expression::SyntaxError(_) => unreachable!(),
} }
@@ -600,7 +647,8 @@ mod tests {
}; };
let mut local = LocalBlock::root(&mut function, &mut module); let mut local = LocalBlock::root(&mut function, &mut module);
let value = local.compile_expression(&Rc::new(expression)).unwrap(); let value = local.compile_expression(&Rc::new(expression)).unwrap();
(module, function.resolve_labels(), value) let trace = module.options.trace_compile;
(module, function.resolve_labels(trace), value)
} }
#[test] #[test]
@@ -647,9 +695,9 @@ mod tests {
&f.instructions, &f.instructions,
&[ &[
Instruction::PushBool(false), // 0 Instruction::PushBool(false), // 0
Instruction::Branch(U::truncate(4)), // 1 Instruction::Branch(U::truncate(3)), // 1
Instruction::PushInteger(U::truncate(1)), // 2 Instruction::PushInteger(U::truncate(1)), // 2
Instruction::Jump(U::truncate(5)), // 3 Instruction::Jump(U::truncate(2)), // 3
Instruction::PushInteger(U::truncate(2)) // 4 Instruction::PushInteger(U::truncate(2)) // 4
// 5 // 5
] ]
@@ -676,13 +724,13 @@ mod tests {
&f.instructions, &f.instructions,
&[ &[
Instruction::PushBool(false), // 0 Instruction::PushBool(false), // 0
Instruction::Branch(U::truncate(4)), // 1 Instruction::Branch(U::truncate(3)), // 1
Instruction::PushInteger(U::truncate(1)), // 2 Instruction::PushInteger(U::truncate(1)), // 2
Instruction::Jump(U::truncate(9)), // 3 Instruction::Jump(U::truncate(6)), // 3
Instruction::PushBool(true), // 4 Instruction::PushBool(true), // 4
Instruction::Branch(U::truncate(8)), // 5 Instruction::Branch(U::truncate(3)), // 5
Instruction::PushInteger(U::truncate(2)), // 6 Instruction::PushInteger(U::truncate(2)), // 6
Instruction::Jump(U::truncate(9)), // 7 Instruction::Jump(U::truncate(2)), // 7
Instruction::PushInteger(U::truncate(3)), // 8 Instruction::PushInteger(U::truncate(3)), // 8
// 9 // 9
] ]
+5
View File
@@ -13,3 +13,8 @@ pub use syntax::{
CallExpression, ExpectedWhat, ExpectedWhere, Expression, FunctionBody, LambdaExpression, CallExpression, ExpectedWhat, ExpectedWhere, Expression, FunctionBody, LambdaExpression,
ParseError, ParseErrorKind, ParseError, ParseErrorKind,
}; };
#[derive(Default, Clone)]
pub struct CompileOptions {
pub trace_compile: bool,
}
+10 -1
View File
@@ -2,6 +2,7 @@ use std::{collections::HashMap, rc::Rc};
use crate::{ use crate::{
compile::{ compile::{
CompileOptions,
block::{CompiledFunction, FunctionBlock}, block::{CompiledFunction, FunctionBlock},
error::CompileError, error::CompileError,
function::FunctionSignature, function::FunctionSignature,
@@ -19,12 +20,20 @@ use crate::{
pub struct CompilationModule { pub struct CompilationModule {
pub(crate) constant_pool: Pool<CompileConstant, { ConstantId::BITS }>, pub(crate) constant_pool: Pool<CompileConstant, { ConstantId::BITS }>,
pub(crate) local_functions: HashMap<u32, CompiledFunction>, pub(crate) local_functions: HashMap<u32, CompiledFunction>,
pub(crate) options: CompileOptions,
macros: HashMap<Rc<str>, DefmacroExpression>, macros: HashMap<Rc<str>, DefmacroExpression>,
local_function_index: u32, local_function_index: u32,
root: Option<u32>, root: Option<u32>,
} }
impl CompilationModule { impl CompilationModule {
pub fn new(options: CompileOptions) -> Self {
Self {
options,
..Default::default()
}
}
pub fn define_macro(&mut self, defmacro: DefmacroExpression) { pub fn define_macro(&mut self, defmacro: DefmacroExpression) {
self.macros.insert(defmacro.name.clone(), defmacro); self.macros.insert(defmacro.name.clone(), defmacro);
} }
@@ -49,7 +58,7 @@ impl CompilationModule {
self.local_function_index += 1; self.local_function_index += 1;
let mut function = FunctionBlock::new(signature); let mut function = FunctionBlock::new(signature);
function.compile_body(self, body)?; function.compile_body(self, body)?;
let function = function.resolve_labels(); let function = function.resolve_labels(self.options.trace_compile);
self.local_functions.insert(index, function); self.local_functions.insert(index, function);
if root { if root {
self.root = Some(index); self.root = Some(index);
+3 -3
View File
@@ -64,9 +64,9 @@ impl IfExpression {
Some(Expression::parse_inner(if_false)) Some(Expression::parse_inner(if_false))
}; };
Ok(Self { Ok(Self {
condition: condition.into(), condition,
if_true: if_true.into(), if_true,
if_false: if_false.map(Into::into), if_false,
}) })
} }
} }
+41
View File
@@ -0,0 +1,41 @@
use std::rc::Rc;
use crate::{
compile::{
ExpectedWhat, ExpectedWhere, Expression, FunctionBody, ParseError, ParseErrorKind,
syntax::CollectErrors,
},
vm::value::{ConsCell, Keyword, Value},
};
#[derive(Debug, PartialEq)]
pub struct WhileExpression {
pub condition: Rc<Expression>,
pub body: FunctionBody,
}
impl WhileExpression {
pub(super) fn parse(value: &Value, input: &Value) -> Result<Self, ParseError> {
let Value::Cons(cons) = value else {
return Err(ParseError {
input: input.clone(),
error: ParseErrorKind::Expected(
ExpectedWhat::ProperList,
ExpectedWhere::AfterKeyword(Keyword::While),
),
});
};
let ConsCell(car, cdr) = cons.as_ref();
let condition = Expression::parse_inner(car);
let body = FunctionBody::parse(cdr, input, Keyword::While)?;
Ok(Self { condition, body })
}
}
impl CollectErrors<ParseError> for WhileExpression {
fn collect_errors(&self, errors: &mut Vec<ParseError>) -> bool {
let a = self.condition.collect_errors(errors);
let b = self.body.collect_errors(errors);
a | b
}
}
+7
View File
@@ -8,6 +8,7 @@ mod condition;
mod error; mod error;
mod function; mod function;
mod lambda; mod lambda;
mod loops;
mod macros; mod macros;
pub use binding::*; pub use binding::*;
@@ -16,6 +17,7 @@ pub use condition::*;
pub use error::*; pub use error::*;
pub use function::*; pub use function::*;
pub use lambda::*; pub use lambda::*;
pub use loops::*;
pub use macros::*; pub use macros::*;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@@ -35,6 +37,7 @@ pub enum Expression {
Defmacro(DefmacroExpression), Defmacro(DefmacroExpression),
SyntaxError(ParseError), SyntaxError(ParseError),
Quote(Rc<Value>), Quote(Rc<Value>),
While(WhileExpression),
} }
impl Expression { impl Expression {
@@ -97,6 +100,9 @@ impl Expression {
}; };
Rc::new(Self::Quote(value.into())) Rc::new(Self::Quote(value.into()))
} }
Value::Keyword(Keyword::While) => {
Self::map_or(WhileExpression::parse(cdr, value), Expression::While)
}
_ => Self::map_or(CallExpression::parse(cons, value), Expression::Call), _ => Self::map_or(CallExpression::parse(cons, value), Expression::Call),
} }
} }
@@ -123,6 +129,7 @@ impl CollectErrors<ParseError> for Expression {
Self::Let(let_) => let_.collect_errors(errors), Self::Let(let_) => let_.collect_errors(errors),
Self::Setq(setq) => setq.collect_errors(errors), Self::Setq(setq) => setq.collect_errors(errors),
Self::Defmacro(defmacro) => defmacro.collect_errors(errors), Self::Defmacro(defmacro) => defmacro.collect_errors(errors),
Self::While(cloop) => cloop.collect_errors(errors),
Self::Nil Self::Nil
| Self::IntegerLiteral(_) | Self::IntegerLiteral(_)
| Self::Identifier(_) | Self::Identifier(_)
+47 -8
View File
@@ -3,11 +3,12 @@ use std::{
io::{self, BufReader}, io::{self, BufReader},
path::{Path, PathBuf}, path::{Path, PathBuf},
process::ExitCode, process::ExitCode,
str::FromStr,
}; };
use clap::Parser; use clap::Parser;
use lysp::{ use lysp::{
compile::{CompileError, ParseError}, compile::{CompileError, CompileOptions, ParseError},
error::{EvalError, MachineErrorKind}, error::{EvalError, MachineErrorKind},
read::{InteractiveReader, ModuleReader, read}, read::{InteractiveReader, ModuleReader, read},
util::Either, util::Either,
@@ -25,8 +26,32 @@ enum Error {
Printed, Printed,
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Trace {
Compile,
Execute,
}
impl FromStr for Trace {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"compile" => Ok(Self::Compile),
"execute" => Ok(Self::Execute),
_ => Err(format!("Unknown trace flag: {s:?}")),
}
}
}
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
struct Args { struct Args {
#[clap(
short = 'T',
long = "trace",
help = "Enable tracing of execution/compilation steps"
)]
trace: Vec<Trace>,
module: Option<PathBuf>, module: Option<PathBuf>,
} }
@@ -88,8 +113,13 @@ fn handle_module_error(input: Either<EvalError, Vec<ParseError>>) -> Error {
} }
} }
fn eval(vm: &mut Machine, env: &mut Environment, value: Value) -> Option<Value> { fn eval(
let result = vm.eval_value(env, value.clone()); options: &CompileOptions,
vm: &mut Machine,
env: &mut Environment,
value: Value,
) -> Option<Value> {
let result = vm.eval_value(options.clone(), env, value.clone());
match result { match result {
Ok(r) => Some(r), Ok(r) => Some(r),
Err(error) => { Err(error) => {
@@ -99,7 +129,11 @@ fn eval(vm: &mut Machine, env: &mut Environment, value: Value) -> Option<Value>
} }
} }
fn run_interactive(vm: &mut Machine, env: &mut Environment) -> Result<(), Error> { fn run_interactive(
compile_options: &CompileOptions,
vm: &mut Machine,
env: &mut Environment,
) -> Result<(), Error> {
let mut reader = InteractiveReader::new("> ", ">> "); let mut reader = InteractiveReader::new("> ", ">> ");
loop { loop {
@@ -111,7 +145,7 @@ fn run_interactive(vm: &mut Machine, env: &mut Environment) -> Result<(), Error>
continue; continue;
} }
}; };
if let Some(value) = eval(vm, env, value) { if let Some(value) = eval(compile_options, vm, env, value) {
println!("== {value}"); println!("== {value}");
} else { } else {
reader.reset(); reader.reset();
@@ -122,6 +156,7 @@ fn run_interactive(vm: &mut Machine, env: &mut Environment) -> Result<(), Error>
} }
fn run_module<P: AsRef<Path>>( fn run_module<P: AsRef<Path>>(
compile_options: &CompileOptions,
vm: &mut Machine, vm: &mut Machine,
env: &mut Environment, env: &mut Environment,
path: P, path: P,
@@ -129,7 +164,7 @@ fn run_module<P: AsRef<Path>>(
let path = path.as_ref(); let path = path.as_ref();
let reader = BufReader::new(File::open(path)?); let reader = BufReader::new(File::open(path)?);
let module_reader = ModuleReader::new(reader); let module_reader = ModuleReader::new(reader);
let module = match module_reader.compile(env) { let module = match module_reader.compile(compile_options, env) {
Ok(module) => module, Ok(module) => module,
Err(error) => return Err(handle_module_error(error)), Err(error) => return Err(handle_module_error(error)),
}; };
@@ -143,11 +178,15 @@ fn run_module<P: AsRef<Path>>(
fn main() -> ExitCode { fn main() -> ExitCode {
let args = Args::parse(); let args = Args::parse();
let mut vm = Machine::default(); let mut vm = Machine::default();
let compile_options = CompileOptions {
trace_compile: args.trace.contains(&Trace::Compile),
};
vm.trace_instructions = args.trace.contains(&Trace::Execute);
let mut env = Environment::default(); let mut env = Environment::default();
prelude::load(&mut env); prelude::load(&mut env);
let result = match args.module.as_ref() { let result = match args.module.as_ref() {
Some(module) => run_module(&mut vm, &mut env, module), Some(module) => run_module(&compile_options, &mut vm, &mut env, module),
None => run_interactive(&mut vm, &mut env), None => run_interactive(&compile_options, &mut vm, &mut env),
}; };
match result { match result {
Ok(()) => ExitCode::SUCCESS, Ok(()) => ExitCode::SUCCESS,
+8 -4
View File
@@ -5,7 +5,9 @@ use std::{
}; };
use crate::{ use crate::{
compile::{CompilationModule, Expression, FunctionBody, FunctionSignature, ParseError}, compile::{
CompilationModule, CompileOptions, Expression, FunctionBody, FunctionSignature, ParseError,
},
error::EvalError, error::EvalError,
parse::{self, parse_value}, parse::{self, parse_value},
util::Either, util::Either,
@@ -106,6 +108,7 @@ impl<R: BufRead> ModuleReader<R> {
pub fn read_expression( pub fn read_expression(
&mut self, &mut self,
options: &CompileOptions,
env: &mut Environment, env: &mut Environment,
) -> Result<Option<Rc<Expression>>, Either<EvalError, Vec<ParseError>>> { ) -> Result<Option<Rc<Expression>>, Either<EvalError, Vec<ParseError>>> {
loop { loop {
@@ -117,7 +120,7 @@ impl<R: BufRead> ModuleReader<R> {
let expression = Expression::parse(&value).map_err(Either::Right)?; let expression = Expression::parse(&value).map_err(Either::Right)?;
if let Expression::Defmacro(_) = expression.as_ref() { if let Expression::Defmacro(_) = expression.as_ref() {
self.macro_machine self.macro_machine
.eval_value(env, value) .eval_value(options.clone(), env, value)
.map_err(Either::Left)?; .map_err(Either::Left)?;
continue; continue;
} }
@@ -127,9 +130,10 @@ impl<R: BufRead> ModuleReader<R> {
pub fn compile( pub fn compile(
mut self, mut self,
options: &CompileOptions,
env: &mut Environment, env: &mut Environment,
) -> Result<ModuleRef, Either<EvalError, Vec<ParseError>>> { ) -> Result<ModuleRef, Either<EvalError, Vec<ParseError>>> {
let mut module = CompilationModule::default(); let mut module = CompilationModule::new(options.clone());
let mut body = FunctionBody { let mut body = FunctionBody {
head: vec![], head: vec![],
tail: Rc::new(Expression::Nil), tail: Rc::new(Expression::Nil),
@@ -138,7 +142,7 @@ impl<R: BufRead> ModuleReader<R> {
let mut syntax_errors = vec![]; let mut syntax_errors = vec![];
loop { loop {
let expression = match self.read_expression(env) { let expression = match self.read_expression(options, env) {
Ok(Some(expression)) => expression, Ok(Some(expression)) => expression,
Ok(None) => break, Ok(None) => break,
Err(Either::Left(error)) => return Err(Either::Left(error)), Err(Either::Left(error)) => return Err(Either::Left(error)),
+8 -2
View File
@@ -91,7 +91,7 @@ pub enum Instruction {
} }
pub type ConstantId = U<12>; pub type ConstantId = U<12>;
pub type FunctionOffset = U<12>; pub type FunctionOffset = U<10>;
pub type LocalId = U<8>; pub type LocalId = U<8>;
pub type ArgumentId = U<6>; pub type ArgumentId = U<6>;
pub type ArgumentCount = U<6>; pub type ArgumentCount = U<6>;
@@ -222,7 +222,7 @@ impl TryFrom<u32> for Instruction {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::vm::instruction::U; use crate::vm::instruction::{FunctionOffset, U};
#[test] #[test]
fn test_u_convert() { fn test_u_convert() {
@@ -238,4 +238,10 @@ mod tests {
let t = T::from_signed(-0x1000001); let t = T::from_signed(-0x1000001);
assert!(t.is_none()); assert!(t.is_none());
} }
#[test]
fn test_branch_target_extend() {
let target = FunctionOffset::truncate(1022);
assert_eq!(target.sign_extend_i64(), -2);
}
} }
+3 -1
View File
@@ -1,6 +1,7 @@
use std::{collections::HashMap, fmt}; use std::{collections::HashMap, fmt};
use crate::{ use crate::{
compile::CompileOptions,
error::{EvalError, MachineError, MachineErrorKind}, error::{EvalError, MachineError, MachineErrorKind},
vm::{ vm::{
env::Environment, env::Environment,
@@ -516,11 +517,12 @@ impl Machine {
pub fn eval_value( pub fn eval_value(
&mut self, &mut self,
compile_options: CompileOptions,
environment: &mut Environment, environment: &mut Environment,
value: Value, value: Value,
) -> Result<Value, EvalError> { ) -> Result<Value, EvalError> {
let value = value.macro_expand(self, environment, false)?; let value = value.macro_expand(self, environment, false)?;
let module = Module::compile_value(&value)?; let module = Module::compile_value(compile_options, &value)?;
let module = ModuleRef::from(module); let module = ModuleRef::from(module);
self.eval_module(environment, module) self.eval_module(environment, module)
} }
+14 -8
View File
@@ -7,7 +7,10 @@ use std::{
}; };
use crate::{ use crate::{
compile::{CompilationModule, CompileError, Expression, FunctionBody, FunctionSignature}, compile::{
CompilationModule, CompileError, CompileOptions, Expression, FunctionBody,
FunctionSignature,
},
vm::{ vm::{
instruction::{ConstantId, Instruction}, instruction::{ConstantId, Instruction},
pool::Pool, pool::Pool,
@@ -122,9 +125,9 @@ impl Module {
self.entry self.entry
} }
pub fn compile_value(value: &Value) -> Result<Self, CompileError> { pub fn compile_value(options: CompileOptions, value: &Value) -> Result<Self, CompileError> {
let expression = Expression::parse(value).map_err(CompileError::Parse)?; let expression = Expression::parse(value).map_err(CompileError::Parse)?;
let mut module = CompilationModule::default(); let mut module = CompilationModule::new(options);
module.compile_function( module.compile_function(
FunctionSignature::EMPTY, FunctionSignature::EMPTY,
&FunctionBody { &FunctionBody {
@@ -215,10 +218,13 @@ impl fmt::Display for ModuleConstant {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::vm::{ use crate::{
instruction::{Instruction, MathInstruction, U}, compile::CompileOptions,
module::Module, vm::{
value::Value, instruction::{Instruction, MathInstruction, U},
module::Module,
value::Value,
},
}; };
#[test] #[test]
@@ -228,7 +234,7 @@ mod tests {
Value::Integer(1), Value::Integer(1),
Value::Integer(2), Value::Integer(2),
]); ]);
let m = Module::compile_value(&v).unwrap(); let m = Module::compile_value(CompileOptions::default(), &v).unwrap();
assert!(m.constants.is_empty()); assert!(m.constants.is_empty());
let is = [ let is = [
Instruction::PushInteger(U::truncate(2)), Instruction::PushInteger(U::truncate(2)),
+1 -1
View File
@@ -102,7 +102,7 @@ pub fn load(env: &mut Environment) {
[_, _] => todo!(), [_, _] => todo!(),
_ => todo!(), _ => todo!(),
}; };
let value = match vm.eval_value(env, value.clone()) { let value = match vm.eval_value(Default::default(), env, value.clone()) {
Ok(result) => result, Ok(result) => result,
_ => todo!(), _ => todo!(),
}; };
+1 -1
View File
@@ -30,7 +30,7 @@ fn eval_str_in(code: &str, env: &mut Environment) -> Result<Value, EvalError> {
Err(error) => panic!("{error}"), Err(error) => panic!("{error}"),
}; };
last_value = Some(machine.eval_value(env, value)); last_value = Some(machine.eval_value(Default::default(), env, value));
} }
last_value.expect("no expressions evaluated") last_value.expect("no expressions evaluated")