Add a couple of builtin functions, and the Vm::call() method

* Builtin functions print and println have been added
* If a global lookup fails, the VM will attempt to look up a builtin
* Vm::call(fun, args) allows interrupting the current execution state
  and starting a new function instead. It will return the value left on
  top of the stack.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-10-07 17:21:01 -07:00
parent 76d0e6723f
commit 16063d50f8
6 changed files with 81 additions and 5 deletions

47
src/obj/builtin.rs Normal file
View File

@@ -0,0 +1,47 @@
use crate::{obj::{prelude::*, reserved::*}, vm::signal::*};
use maplit::btreemap;
use once_cell::sync::Lazy;
use std::collections::BTreeMap;
pub static PRINTLN_BUILTIN_FUN: Lazy<NativeFunRef> = Lazy::new(|| NativeFun::new_obj(|_, vm, args| {
// TODO : use __get_attr__ when it gets added
let to_string = {
let obj_ref = &args[0];
read_obj!(let obj = obj_ref);
obj.get_attr(STR_MEMBER_NAME.sym)
.or_else(|| obj.get_attr(REPR_MEMBER_NAME.sym))
.expect("no __str__ or __repr__ member")
};
let return_value = vm.call(to_string, vec![]);
let str_ref: &StrRef = std::any::Any::downcast_ref(&return_value).expect("to_string to return str value");
{
read_obj!(let str_obj = str_ref);
println!("{}", str_obj.value());
}
Signal::Return
}));
pub static PRINT_BUILTIN_FUN: Lazy<NativeFunRef> = Lazy::new(|| NativeFun::new_obj(|_, vm, args| {
// TODO : use __get_attr__ when it gets added
let to_string = {
let obj_ref = &args[0];
read_obj!(let obj = obj_ref);
obj.get_attr(STR_MEMBER_NAME.sym)
.or_else(|| obj.get_attr(REPR_MEMBER_NAME.sym))
.expect("no __str__ or __repr__ member")
};
let return_value = vm.call(to_string, vec![]);
let str_ref: &StrRef = std::any::Any::downcast_ref(&return_value).expect("to_string to return str value");
{
read_obj!(let str_obj = str_ref);
print!("{}", str_obj.value());
}
Signal::Return
}));
pub static BUILTIN_OBJS: Lazy<BTreeMap<Sym, ObjRef>> = Lazy::new(|| btreemap! {
PRINTLN_BUILTIN_NAME.sym => PRINTLN_BUILTIN_FUN.clone() as _,
PRINT_BUILTIN_NAME.sym => PRINT_BUILTIN_FUN.clone() as _,
});