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 {
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
16
src/obj.rs
16
src/obj.rs
@@ -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());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user