Add Str.__repr__, Str.__str__, Str.__int__, Int.__repr__, and Int.__int__ builtins
Builtin functions for builtin types. This allows the "hello world" program to actually work how it's supposed to. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use crate::{obj::{prelude::*, reserved::*}, vm::error::*};
|
use crate::{obj::{prelude::*, reserved::*}, vm::error::*};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use shredder::Scan;
|
use shredder::Scan;
|
||||||
use std::{any::Any, fmt::{Debug, Formatter, self}};
|
use std::fmt::{Debug, Formatter, self};
|
||||||
|
|
||||||
pub type IntRef = ObjRef<Int>;
|
pub type IntRef = ObjRef<Int>;
|
||||||
|
|
||||||
@@ -22,8 +22,9 @@ impl Int {
|
|||||||
attrs: Default::default(),
|
attrs: Default::default(),
|
||||||
},
|
},
|
||||||
vtable: |obj_ref: ObjRef| vtable! {
|
vtable: |obj_ref: ObjRef| vtable! {
|
||||||
// TODO needs Method type so this function is given an argument when called
|
REPR_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), INT_STR_FUN.clone()),
|
||||||
STR_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), INT_STR_FUN.clone()),
|
STR_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), INT_STR_FUN.clone()),
|
||||||
|
INT_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), INT_INT_FUN.clone()),
|
||||||
PLUS_OP_NAME.sym => Method::new_obj(obj_ref.clone(), INT_ADD_FUN.clone()),
|
PLUS_OP_NAME.sym => Method::new_obj(obj_ref.clone(), INT_ADD_FUN.clone()),
|
||||||
MINUS_OP_NAME.sym => Method::new_obj(obj_ref.clone(), INT_SUB_FUN.clone()),
|
MINUS_OP_NAME.sym => Method::new_obj(obj_ref.clone(), INT_SUB_FUN.clone()),
|
||||||
TIMES_OP_NAME.sym => Method::new_obj(obj_ref.clone(), INT_MUL_FUN.clone()),
|
TIMES_OP_NAME.sym => Method::new_obj(obj_ref.clone(), INT_MUL_FUN.clone()),
|
||||||
@@ -54,12 +55,26 @@ impl Debug for Int {
|
|||||||
/// Int.__str__(self) impl
|
/// Int.__str__(self) impl
|
||||||
static INT_STR_FUN: Lazy<NativeFunRef> = Lazy::new(|| {
|
static INT_STR_FUN: Lazy<NativeFunRef> = Lazy::new(|| {
|
||||||
NativeFun::new_obj(1, |_callee, vm, args| {
|
NativeFun::new_obj(1, |_callee, vm, args| {
|
||||||
read_obj!(let int_obj = &args[0]);
|
read_obj_downcast!(let int_obj: Option<&Int> = &args[0]);
|
||||||
if let Some(int_obj) = Any::downcast_ref::<Int>(int_obj.as_any()) {
|
let int_obj = int_obj.ok_or_else(|| Error::ValueError {
|
||||||
vm.push(Str::new_obj(int_obj.value.to_string()));
|
error: "expected Int value".to_string(),
|
||||||
} else {
|
})?;
|
||||||
panic!("{:?} is not an int", int_obj)
|
vm.push(Str::new_obj(int_obj.value.to_string()));
|
||||||
|
Ok(crate::vm::signal::Signal::Return)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Int.__int__(self) impl
|
||||||
|
static INT_INT_FUN: Lazy<NativeFunRef> = Lazy::new(|| {
|
||||||
|
NativeFun::new_obj(1, |_callee, vm, args| {
|
||||||
|
{
|
||||||
|
read_obj_downcast!(let int_obj: Option<&Int> = &args[0]);
|
||||||
|
int_obj.ok_or_else(|| Error::ValueError {
|
||||||
|
error: "expected Int value".to_string(),
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
|
// just push a copy of the "self" object
|
||||||
|
vm.push(args[0].clone());
|
||||||
|
|
||||||
Ok(crate::vm::signal::Signal::Return)
|
Ok(crate::vm::signal::Signal::Return)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ name!(SELF_MEMBER_NAME, "__self__");
|
|||||||
name!(FUNC_MEMBER_NAME, "__func__");
|
name!(FUNC_MEMBER_NAME, "__func__");
|
||||||
name!(REPR_MEMBER_NAME, "__repr__");
|
name!(REPR_MEMBER_NAME, "__repr__");
|
||||||
name!(STR_MEMBER_NAME, "__str__");
|
name!(STR_MEMBER_NAME, "__str__");
|
||||||
|
name!(INT_MEMBER_NAME, "__int__");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Predefined VM-aware symbols
|
// Predefined VM-aware symbols
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
use crate::obj::prelude::*;
|
use crate::{obj::{prelude::*, reserved::*}, vm::error::*};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use shredder::Scan;
|
use shredder::Scan;
|
||||||
|
use std::fmt::{Debug, Formatter, self};
|
||||||
|
|
||||||
pub type StrRef = ObjRef<Str>;
|
pub type StrRef = ObjRef<Str>;
|
||||||
|
|
||||||
#[derive(Debug, Scan)]
|
#[derive(Scan)]
|
||||||
pub struct Str {
|
pub struct Str {
|
||||||
vtable: Vtable,
|
vtable: Vtable,
|
||||||
attrs: Attrs,
|
attrs: Attrs,
|
||||||
@@ -12,11 +14,18 @@ pub struct Str {
|
|||||||
|
|
||||||
impl Str {
|
impl Str {
|
||||||
pub fn new_obj(value: String) -> StrRef {
|
pub fn new_obj(value: String) -> StrRef {
|
||||||
StrRef::new(Str {
|
self_referring_obj! {
|
||||||
vtable: Default::default(),
|
Self {
|
||||||
attrs: Default::default(),
|
value,
|
||||||
value,
|
vtable: Default::default(),
|
||||||
})
|
attrs: Default::default(),
|
||||||
|
},
|
||||||
|
vtable: |obj_ref: ObjRef| vtable! {
|
||||||
|
STR_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), STR_STR_FUN.clone()),
|
||||||
|
REPR_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), STR_REPR_FUN.clone()),
|
||||||
|
INT_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), STR_INT_FUN.clone()),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn value(&self) -> &String {
|
pub fn value(&self) -> &String {
|
||||||
@@ -25,3 +34,62 @@ impl Str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl_obj_readonly!(Str);
|
impl_obj_readonly!(Str);
|
||||||
|
|
||||||
|
impl Debug for Str {
|
||||||
|
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||||
|
fmt.debug_struct("Str")
|
||||||
|
.field("value", &self.value)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Builtin Str functions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/// Str.__str__(self) impl
|
||||||
|
static STR_STR_FUN: Lazy<NativeFunRef> = Lazy::new(|| {
|
||||||
|
NativeFun::new_obj(1, |_callee, vm, args| {
|
||||||
|
{
|
||||||
|
read_obj_downcast!(let str_obj: Option<&Str> = &args[0]);
|
||||||
|
str_obj.ok_or_else(|| Error::ValueError {
|
||||||
|
error: "expected Str value".to_string(),
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
// just push a copy of the "self" object
|
||||||
|
vm.push(args[0].clone());
|
||||||
|
|
||||||
|
Ok(crate::vm::signal::Signal::Return)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Str.__repr__(self) impl
|
||||||
|
static STR_REPR_FUN: Lazy<NativeFunRef> = Lazy::new(|| {
|
||||||
|
NativeFun::new_obj(1, |_callee, vm, args| {
|
||||||
|
read_obj_downcast!(let str_obj: Option<&Str> = &args[0]);
|
||||||
|
let str_obj = str_obj.ok_or_else(|| Error::ValueError {
|
||||||
|
error: "expected Str value".to_string(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let repr = format!("\"{}\"", str_obj.value.escape_debug());
|
||||||
|
vm.push(Str::new_obj(repr));
|
||||||
|
|
||||||
|
Ok(crate::vm::signal::Signal::Return)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Str.__int__(self) impl
|
||||||
|
static STR_INT_FUN: Lazy<NativeFunRef> = Lazy::new(|| {
|
||||||
|
NativeFun::new_obj(1, |_callee, vm, args| {
|
||||||
|
read_obj_downcast!(let str_obj: Option<&Str> = &args[0]);
|
||||||
|
let str_obj = str_obj.ok_or_else(|| Error::ValueError {
|
||||||
|
error: "expected Str value".to_string(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let int: i64 = str_obj.value.parse()
|
||||||
|
.map_err(|_| Error::ValueError { error: "invalid Int value".to_string(), })?;
|
||||||
|
vm.push(Int::new_obj(int));
|
||||||
|
|
||||||
|
Ok(crate::vm::signal::Signal::Return)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user