Add hash builtin function.

This commit is contained in:
Windel Bouwman
2018-10-21 23:33:06 +02:00
parent 525807c319
commit 104bc56bc1
4 changed files with 43 additions and 1 deletions

View File

@@ -237,7 +237,12 @@ fn builtin_hasattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}
// builtin_hash
fn builtin_hash(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, None)]);
vm.call_method(obj, "__hash__", vec![])
}
// builtin_help
// builtin_hex
@@ -522,6 +527,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
dict.insert(String::from("float"), ctx.float_type());
dict.insert(String::from("getattr"), ctx.new_rustfunc(builtin_getattr));
dict.insert(String::from("hasattr"), ctx.new_rustfunc(builtin_hasattr));
dict.insert(String::from("hash"), ctx.new_rustfunc(builtin_hash));
dict.insert(String::from("id"), ctx.new_rustfunc(builtin_id));
dict.insert(String::from("int"), ctx.int_type());
dict.insert(

View File

@@ -99,6 +99,13 @@ fn int_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(vm.ctx.new_bool(result))
}
fn int_hash(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.int_type()))]);
// TODO: how to hash int?
Ok(zelf.clone())
}
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()))
@@ -283,6 +290,7 @@ pub fn init(context: &PyContext) {
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("__hash__", context.new_rustfunc(int_hash));
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

@@ -49,6 +49,13 @@ fn object_ne(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
objbool::not(vm, &eq)
}
fn object_hash(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(_zelf, Some(vm.ctx.object()))]);
// For now default to non hashable
Err(vm.new_type_error("unhashable type".to_string()))
}
// TODO: is object the right place for delattr?
fn object_delattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
@@ -91,6 +98,7 @@ pub fn init(context: &PyContext) {
object.set_attr("__ne__", context.new_rustfunc(object_ne));
object.set_attr("__delattr__", context.new_rustfunc(object_delattr));
object.set_attr("__dict__", context.new_member_descriptor(object_dict));
object.set_attr("__hash__", context.new_rustfunc(object_hash));
object.set_attr("__str__", context.new_rustfunc(object_str));
object.set_attr("__repr__", context.new_rustfunc(object_repr));
}

View File

@@ -3,6 +3,7 @@ use super::super::pyobject::{
};
use super::super::vm::VirtualMachine;
use super::objbool;
use super::objint;
use super::objsequence::{get_item, seq_equal};
use super::objstr;
use super::objtype;
@@ -24,6 +25,24 @@ fn tuple_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(vm.ctx.new_bool(result))
}
fn tuple_hash(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.tuple_type()))]);
let mut x: usize = 0x345678;
let elements = get_elements(zelf);
let len: usize = elements.len();
let mut mult = 0xf4243;
for elem in &elements {
let y: usize = objint::get_value(&vm.call_method(elem, "__hash__", vec![])?) as usize;
x = (x ^ y) * mult;
mult = mult + 82520 + len * 2;
}
x += 97531;
Ok(vm.ctx.new_int(x as i32))
}
fn tuple_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.tuple_type()))]);
let elements = get_elements(zelf);
@@ -93,6 +112,7 @@ pub fn init(context: &PyContext) {
tuple_type.set_attr("__eq__", context.new_rustfunc(tuple_eq));
tuple_type.set_attr("__contains__", context.new_rustfunc(tuple_contains));
tuple_type.set_attr("__getitem__", context.new_rustfunc(tuple_getitem));
tuple_type.set_attr("__hash__", context.new_rustfunc(tuple_hash));
tuple_type.set_attr("__len__", context.new_rustfunc(tuple_len));
tuple_type.set_attr("__repr__", context.new_rustfunc(tuple_repr));
}