Implement Str methods
* to_str * to_repr * to_bool * len * __add__ * __mul__ Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -79,10 +79,28 @@ pub(crate) fn print(vm: &mut Vm, state: FunctionState) -> FunctionResult {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Base function implementations
|
||||
// BaseObjInst implementations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl BaseObjInst {
|
||||
//
|
||||
// Common functions
|
||||
//
|
||||
|
||||
pub(crate) fn to_repr(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
let str_value = format!("{}", vm.frame_stack()[0].borrow());
|
||||
vm.create_str(str_value).into()
|
||||
}
|
||||
|
||||
pub(crate) fn to_bool(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
vm.create_bool(vm.frame_stack()[0].borrow().is_truthy())
|
||||
.into()
|
||||
}
|
||||
|
||||
//
|
||||
// Operators
|
||||
//
|
||||
|
||||
pub(crate) fn and(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
let lhs = vm.frame_stack()[0].borrow();
|
||||
let rhs = vm.frame_stack()[1].borrow();
|
||||
@@ -149,15 +167,9 @@ impl BaseObjInst {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_repr(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
let str_value = format!("{}", vm.frame_stack()[0].borrow());
|
||||
vm.create_str(str_value).into()
|
||||
}
|
||||
|
||||
pub(crate) fn to_bool(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
vm.create_bool(vm.frame_stack()[0].borrow().is_truthy())
|
||||
.into()
|
||||
}
|
||||
//
|
||||
// Not implemented
|
||||
//
|
||||
|
||||
pub(crate) fn not_implemented_un(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
let fname = &vm.frame().name;
|
||||
@@ -175,5 +187,60 @@ impl BaseObjInst {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// StringInst implementations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
impl StrInst {
|
||||
pub(crate) fn to_str(_vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
// top item of the stack should just be ourselves, so return immediately
|
||||
FunctionResult::Return
|
||||
}
|
||||
|
||||
pub(crate) fn to_repr(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
let escaped: String =
|
||||
with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &StrInst| {
|
||||
str_inst.str_value().as_str().escape_default().collect()
|
||||
});
|
||||
vm.create_str(escaped).into()
|
||||
}
|
||||
|
||||
pub(crate) fn len(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
let len = with_obj_downcast(vm.frame_stack()[0].clone(), |str_inst: &StrInst| {
|
||||
str_inst.str_value().len() as i64
|
||||
});
|
||||
vm.create_int(len).into()
|
||||
}
|
||||
|
||||
pub(crate) fn add(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
let lhs = vm.frame_stack()[0].clone();
|
||||
let rhs = vm.frame_stack()[1].clone();
|
||||
if !obj_is_inst::<StrInst>(&rhs) {
|
||||
// TODO StrInst::add - throw an exception when the RHS is not a string
|
||||
// BLOCKED-ON: exceptions
|
||||
todo!(
|
||||
"can only concatenate Str, got {} instead",
|
||||
rhs.borrow().type_name()
|
||||
)
|
||||
}
|
||||
|
||||
let new = format!("{}{}", lhs.borrow(), rhs.borrow());
|
||||
vm.create_str(new).into()
|
||||
}
|
||||
|
||||
pub(crate) fn mul(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
|
||||
let lhs = vm.frame_stack()[0].clone();
|
||||
let rhs = vm.frame_stack()[1].clone();
|
||||
let repeat_count = if let Some(int_inst) = rhs.borrow().as_any().downcast_ref::<IntInst>() {
|
||||
int_inst.int_value()
|
||||
} else {
|
||||
// TODO StrInst::mul - throw an exception when the RHS is not an int
|
||||
// BLOCKED-ON: exceptions
|
||||
todo!(
|
||||
"can only repeat Str with Int, got {} instead",
|
||||
rhs.borrow().type_name()
|
||||
)
|
||||
};
|
||||
let repeat_count = repeat_count.max(0) as usize;
|
||||
let new = format!("{}", lhs.borrow()).repeat(repeat_count);
|
||||
vm.create_str(new).into()
|
||||
}
|
||||
}
|
||||
|
||||
16
src/obj.rs
16
src/obj.rs
@@ -116,9 +116,10 @@ pub fn init_types(builtins: &mut HashMap<String, ObjP>) {
|
||||
// type definitions
|
||||
Type {
|
||||
// Method conversion
|
||||
to_string => builtins.create_builtin_function("to_string", BaseObjInst::to_repr, 1),
|
||||
to_str => builtins.create_builtin_function("to_str", BaseObjInst::to_repr, 1),
|
||||
to_repr => builtins.create_builtin_function("to_repr", BaseObjInst::to_repr, 1),
|
||||
to_bool => builtins.create_builtin_function("to_bool", BaseObjInst::to_bool, 1),
|
||||
len => builtins.create_builtin_function("len", BaseObjInst::not_implemented_un, 1),
|
||||
// Operators
|
||||
__add__ => builtins.create_builtin_function("__add__", BaseObjInst::not_implemented_bin, 2),
|
||||
__sub__ => builtins.create_builtin_function("__sub__", BaseObjInst::not_implemented_bin, 2),
|
||||
@@ -137,7 +138,14 @@ pub fn init_types(builtins: &mut HashMap<String, ObjP>) {
|
||||
__not__ => builtins.create_builtin_function("__not__", BaseObjInst::not, 1),
|
||||
},
|
||||
Obj { },
|
||||
Str { },
|
||||
Str {
|
||||
to_str => builtins.create_builtin_function("to_str", StrInst::to_str, 1),
|
||||
to_repr => builtins.create_builtin_function("to_repr", StrInst::to_repr, 1),
|
||||
len => builtins.create_builtin_function("len", StrInst::len, 1),
|
||||
// Operators
|
||||
__add__ => builtins.create_builtin_function("__add__", StrInst::add, 2),
|
||||
__mul__ => builtins.create_builtin_function("__mul__", StrInst::mul, 2),
|
||||
},
|
||||
Int { },
|
||||
Float { },
|
||||
Bool { },
|
||||
@@ -824,7 +832,7 @@ fn test_obj_vtable() {
|
||||
let to_string_ptr = str1.borrow_mut().get_attr_lazy(
|
||||
str1.clone(),
|
||||
builtins.get("Method").unwrap().clone(),
|
||||
"to_string",
|
||||
"to_str",
|
||||
);
|
||||
assert!(to_string_ptr.is_some());
|
||||
|
||||
@@ -838,7 +846,7 @@ fn test_obj_vtable() {
|
||||
let method_to_string_ptr = to_string_ptr.borrow_mut().get_attr_lazy(
|
||||
to_string_ptr.clone(),
|
||||
builtins.get("Method").unwrap().clone(),
|
||||
"to_string",
|
||||
"to_str",
|
||||
);
|
||||
assert!(method_to_string_ptr.is_some());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user