Merge pull request #144 from rmliddle/added_builtins

Added builtins
This commit is contained in:
Daniel Watkins
2018-09-12 22:01:37 -04:00
committed by GitHub
6 changed files with 126 additions and 4 deletions

View File

@@ -0,0 +1,5 @@
assert abs(-3) == 3
assert abs(7) == 7
assert abs(-3.21) == 3.21
assert abs(6.25) == 6.25

View File

@@ -0,0 +1,3 @@
assert divmod(11, 3) == (3, 2)
assert divmod(8,11) == (0, 8)
assert divmod(0.873, 0.252) == (3.0, 0.11699999999999999)

View File

@@ -45,7 +45,13 @@ fn dir_object(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyObjectRef {
vm.ctx.new_list(members_pystr)
}
// builtin_abs
fn builtin_abs(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(x, None)]);
match vm.get_attribute(x.clone(), &"__abs__") {
Ok(attrib) => vm.invoke(attrib, PyFuncArgs::new(vec![], vec![])),
Err(..) => Err(vm.new_type_error("bad operand for abs".to_string())),
}
}
fn builtin_all(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
for item in args.args {
@@ -122,7 +128,14 @@ fn builtin_dir(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
// builtin_divmod
fn builtin_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(x, None), (y, None)]);
match vm.get_attribute(x.clone(), &"__divmod__") {
Ok(attrib) => vm.invoke(attrib, PyFuncArgs::new(vec![y.clone()], vec![])),
Err(..) => Err(vm.new_type_error("unsupported operand type(s) for divmod".to_string())),
}
}
// builtin_enumerate
fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -373,7 +386,6 @@ fn builtin_setattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
// builtin_slice
// builtin_sorted
// builtin_staticmethod
// builtin_sum
// builtin_super
// builtin_vars
@@ -383,6 +395,7 @@ fn builtin_setattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
// scope[String::from("print")] = print;
let mut dict = HashMap::new();
dict.insert(String::from("abs"), ctx.new_rustfunc(builtin_abs));
dict.insert(String::from("all"), ctx.new_rustfunc(builtin_all));
dict.insert(String::from("any"), ctx.new_rustfunc(builtin_any));
dict.insert(String::from("bool"), ctx.bool_type());
@@ -390,6 +403,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
dict.insert(String::from("chr"), ctx.new_rustfunc(builtin_chr));
dict.insert(String::from("compile"), ctx.new_rustfunc(builtin_compile));
dict.insert(String::from("dict"), ctx.dict_type());
dict.insert(String::from("divmod"), ctx.new_rustfunc(builtin_divmod));
dict.insert(String::from("dir"), ctx.new_rustfunc(builtin_dir));
dict.insert(String::from("eval"), ctx.new_rustfunc(builtin_eval));
dict.insert(String::from("float"), ctx.float_type());

View File

@@ -61,6 +61,11 @@ fn float_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(vm.ctx.new_bool(result))
}
fn float_abs(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(i, Some(vm.ctx.float_type()))]);
Ok(vm.ctx.new_float(get_value(i).abs()))
}
fn float_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
@@ -78,13 +83,45 @@ fn float_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
fn float_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
);
let args = PyFuncArgs::new(vec![i.clone(), i2.clone()], vec![]);
if objtype::isinstance(i2, vm.ctx.float_type()) || objtype::isinstance(i2, vm.ctx.int_type()) {
let r1 = float_floordiv(vm, args.clone());
let r2 = float_mod(vm, args.clone());
Ok(vm.ctx.new_tuple(vec![r1.unwrap(), r2.unwrap()]))
} else {
Err(vm.new_type_error(format!("Cannot divmod power {:?} and {:?}", i, i2)))
}
}
fn float_floordiv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
);
if objtype::isinstance(i2, vm.ctx.float_type()) {
Ok(vm.ctx.new_float((get_value(i) / get_value(i2)).floor()))
} else if objtype::isinstance(i2, vm.ctx.int_type()) {
Ok(vm
.ctx
.new_float((get_value(i) / objint::get_value(i2) as f64).floor()))
} else {
Err(vm.new_type_error(format!("Cannot floordiv {:?} and {:?}", i, i2)))
}
}
fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
);
let v1 = get_value(i);
if objtype::isinstance(i2, vm.ctx.float_type()) {
Ok(vm.ctx.new_float(v1 - get_value(i2)))
@@ -95,6 +132,23 @@ fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
fn float_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
);
if objtype::isinstance(i2, vm.ctx.float_type()) {
Ok(vm.ctx.new_float(get_value(i) % get_value(i2)))
} else if objtype::isinstance(i2, vm.ctx.int_type()) {
Ok(vm
.ctx
.new_float(get_value(i) % objint::get_value(i2) as f64))
} else {
Err(vm.new_type_error(format!("Cannot mod {:?} and {:?}", i, i2)))
}
}
fn float_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
@@ -117,8 +171,12 @@ fn float_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
pub fn init(context: &PyContext) {
let ref float_type = context.float_type;
float_type.set_attr("__eq__", context.new_rustfunc(float_eq));
float_type.set_attr("__abs__", context.new_rustfunc(float_abs));
float_type.set_attr("__add__", context.new_rustfunc(float_add));
float_type.set_attr("__divmod__", context.new_rustfunc(float_divmod));
float_type.set_attr("__floordiv__", context.new_rustfunc(float_floordiv));
float_type.set_attr("__init__", context.new_rustfunc(float_init));
float_type.set_attr("__mod__", context.new_rustfunc(float_mod));
float_type.set_attr("__pow__", context.new_rustfunc(float_pow));
float_type.set_attr("__sub__", context.new_rustfunc(float_sub));
float_type.set_attr("__repr__", context.new_rustfunc(float_repr));

View File

@@ -99,6 +99,11 @@ fn int_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(vm.ctx.new_bool(result))
}
fn int_abs(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(i, Some(vm.ctx.int_type()))]);
Ok(vm.ctx.new_int(get_value(i).abs()))
}
fn int_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
@@ -115,6 +120,19 @@ fn int_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
fn int_floordiv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
);
if objtype::isinstance(i2, vm.ctx.int_type()) {
Ok(vm.ctx.new_int(get_value(i) / get_value(i2)))
} else {
Err(vm.new_type_error(format!("Cannot floordiv {:?} and {:?}", i, i2)))
}
}
fn int_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
@@ -139,6 +157,10 @@ fn int_mul(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
);
if objtype::isinstance(i2, vm.ctx.int_type()) {
Ok(vm.ctx.new_int(get_value(i) * get_value(i2)))
} else if objtype::isinstance(i2, vm.ctx.float_type()) {
Ok(vm
.ctx
.new_float(get_value(i) as f64 * objfloat::get_value(i2)))
} else {
Err(vm.new_type_error(format!("Cannot multiply {:?} and {:?}", i, i2)))
}
@@ -192,6 +214,22 @@ fn int_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
fn int_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
);
let args = PyFuncArgs::new(vec![i.clone(), i2.clone()], vec![]);
if objtype::isinstance(i2, vm.ctx.int_type()) {
let r1 = int_floordiv(vm, args.clone());
let r2 = int_mod(vm, args.clone());
Ok(vm.ctx.new_tuple(vec![r1.unwrap(), r2.unwrap()]))
} else {
Err(vm.new_type_error(format!("Cannot divmod power {:?} and {:?}", i, i2)))
}
}
fn int_xor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
@@ -240,8 +278,11 @@ fn int_and(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
pub fn init(context: &PyContext) {
let ref int_type = context.int_type;
int_type.set_attr("__eq__", context.new_rustfunc(int_eq));
int_type.set_attr("__abs__", context.new_rustfunc(int_abs));
int_type.set_attr("__add__", context.new_rustfunc(int_add));
int_type.set_attr("__and__", context.new_rustfunc(int_and));
int_type.set_attr("__divmod__", context.new_rustfunc(int_divmod));
int_type.set_attr("__floordiv__", context.new_rustfunc(int_floordiv));
int_type.set_attr("__new__", context.new_rustfunc(int_new));
int_type.set_attr("__mod__", context.new_rustfunc(int_mod));
int_type.set_attr("__mul__", context.new_rustfunc(int_mul));

View File

@@ -443,6 +443,7 @@ impl VirtualMachine {
// self.invoke('__neg__'
match a.borrow().kind {
PyObjectKind::Integer { value: ref value1 } => Ok(self.ctx.new_int(-*value1)),
PyObjectKind::Float { value: ref value1 } => Ok(self.ctx.new_float(-*value1)),
_ => panic!("Not impl {:?}", a),
}
}