Objs replace Values
* Obj is now a trait instead of a struct * Value enum is gone, replaced with individual structs that implement Obj * All instances where a Value was used, a Gc<(dyn Obj + 'static)> takes its place. ObjPtr is shorthand for this. * A __str__ method for objects is implemented for a couple builtin types as a proof-of-concept * println and print builtin functions are implemented using this interface There's still a lot to do, mostly with interned values. For example, whenever a new string object is created, a new __str__ function object is created each time, rather than reusing the first one that was created. Stuff like that. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::object::{BuiltinExit, Int, Value};
|
||||
use crate::object::{BuiltinExit, Obj, StrObj};
|
||||
use crate::vm::{error::RuntimeError, machine::MachineBuilder};
|
||||
|
||||
impl MachineBuilder {
|
||||
@@ -19,6 +19,7 @@ impl MachineBuilder {
|
||||
panic!();
|
||||
});
|
||||
|
||||
/*
|
||||
//
|
||||
// if
|
||||
//
|
||||
@@ -26,6 +27,7 @@ impl MachineBuilder {
|
||||
let if_false = machine.stack_pop()?;
|
||||
let if_true = machine.stack_pop()?;
|
||||
let condition = machine.stack_pop()?;
|
||||
|
||||
let value = if condition.is_truthy() {
|
||||
if_true
|
||||
} else {
|
||||
@@ -41,25 +43,75 @@ impl MachineBuilder {
|
||||
.into());
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
//
|
||||
// print
|
||||
//
|
||||
self.register_builtin_fun("print", |machine, _| {
|
||||
let value = machine.stack_pop()?;
|
||||
print!("{}", value);
|
||||
Ok(BuiltinExit::Return)
|
||||
self.register_builtin_fun("print", |machine, reentry| {
|
||||
const CALL_STR: usize = 1;
|
||||
if reentry == 0 {
|
||||
let obj = machine
|
||||
.stack_peek()
|
||||
.ok_or_else(|| RuntimeError::StackUnderflow)?;
|
||||
// Push the value's __str__ value, call it, and then print it.
|
||||
let str_fun = obj
|
||||
.get("__str__")
|
||||
.ok_or_else(|| RuntimeError::UnsetWord("__str__".to_string()))?;
|
||||
let call_site = machine.call_stack().last().unwrap().call_site().cloned();
|
||||
str_fun.call(call_site, machine)?;
|
||||
Ok(BuiltinExit::Resume(CALL_STR))
|
||||
} else if reentry == CALL_STR {
|
||||
let obj_ptr = machine.stack_pop()?;
|
||||
let str_obj: &(dyn Obj + 'static) = &*obj_ptr;
|
||||
if let Some(string) = str_obj.as_any().downcast_ref::<StrObj>() {
|
||||
print!("{}", string.value());
|
||||
Ok(BuiltinExit::Return)
|
||||
} else {
|
||||
panic!(
|
||||
"expected StrObj from __str__ function but got {:?} instead",
|
||||
str_obj
|
||||
);
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// println
|
||||
//
|
||||
self.register_builtin_fun("println", |machine, _| {
|
||||
let value = machine.stack_pop()?;
|
||||
println!("{}", value);
|
||||
Ok(BuiltinExit::Return)
|
||||
self.register_builtin_fun("println", |machine, reentry| {
|
||||
const CALL_STR: usize = 1;
|
||||
if reentry == 0 {
|
||||
let obj = machine
|
||||
.stack_peek()
|
||||
.ok_or_else(|| RuntimeError::StackUnderflow)?;
|
||||
// Push the value's __str__ value, call it, and then print it.
|
||||
let str_fun = obj
|
||||
.get("__str__")
|
||||
.ok_or_else(|| RuntimeError::UnsetWord("__str__".to_string()))?;
|
||||
let call_site = machine.call_stack().last().unwrap().call_site().cloned();
|
||||
str_fun.call(call_site, machine)?;
|
||||
Ok(BuiltinExit::Resume(CALL_STR))
|
||||
} else if reentry == CALL_STR {
|
||||
let obj_ptr = machine.stack_pop()?;
|
||||
let str_obj: &(dyn Obj + 'static) = &*obj_ptr;
|
||||
if let Some(string) = str_obj.as_any().downcast_ref::<StrObj>() {
|
||||
println!("{}", string.value());
|
||||
Ok(BuiltinExit::Return)
|
||||
} else {
|
||||
panic!(
|
||||
"expected StrObj from __str__ function but got {:?} instead",
|
||||
str_obj
|
||||
);
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
//
|
||||
// ==
|
||||
//
|
||||
@@ -79,5 +131,6 @@ impl MachineBuilder {
|
||||
machine.stack_push(Value::Int((lhs != rhs) as Int))?;
|
||||
Ok(BuiltinExit::Return)
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user