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:
2024-09-24 14:47:44 -07:00
parent a5d106bdfd
commit ebd5bf96c3
2 changed files with 90 additions and 15 deletions

View File

@@ -79,10 +79,28 @@ pub(crate) fn print(vm: &mut Vm, state: FunctionState) -> FunctionResult {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Base function implementations // BaseObjInst implementations
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
impl BaseObjInst { 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 { pub(crate) fn and(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
let lhs = vm.frame_stack()[0].borrow(); let lhs = vm.frame_stack()[0].borrow();
let rhs = vm.frame_stack()[1].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()); // Not implemented
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()
}
pub(crate) fn not_implemented_un(vm: &mut Vm, _state: FunctionState) -> FunctionResult { pub(crate) fn not_implemented_un(vm: &mut Vm, _state: FunctionState) -> FunctionResult {
let fname = &vm.frame().name; 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()
}
}

View File

@@ -116,9 +116,10 @@ pub fn init_types(builtins: &mut HashMap<String, ObjP>) {
// type definitions // type definitions
Type { Type {
// Method conversion // 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_repr => builtins.create_builtin_function("to_repr", BaseObjInst::to_repr, 1),
to_bool => builtins.create_builtin_function("to_bool", BaseObjInst::to_bool, 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 // Operators
__add__ => builtins.create_builtin_function("__add__", BaseObjInst::not_implemented_bin, 2), __add__ => builtins.create_builtin_function("__add__", BaseObjInst::not_implemented_bin, 2),
__sub__ => builtins.create_builtin_function("__sub__", 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), __not__ => builtins.create_builtin_function("__not__", BaseObjInst::not, 1),
}, },
Obj { }, 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 { }, Int { },
Float { }, Float { },
Bool { }, Bool { },
@@ -824,7 +832,7 @@ fn test_obj_vtable() {
let to_string_ptr = str1.borrow_mut().get_attr_lazy( let to_string_ptr = str1.borrow_mut().get_attr_lazy(
str1.clone(), str1.clone(),
builtins.get("Method").unwrap().clone(), builtins.get("Method").unwrap().clone(),
"to_string", "to_str",
); );
assert!(to_string_ptr.is_some()); 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( let method_to_string_ptr = to_string_ptr.borrow_mut().get_attr_lazy(
to_string_ptr.clone(), to_string_ptr.clone(),
builtins.get("Method").unwrap().clone(), builtins.get("Method").unwrap().clone(),
"to_string", "to_str",
); );
assert!(method_to_string_ptr.is_some()); assert!(method_to_string_ptr.is_some());