Add complex basic type

This commit is contained in:
Windel Bouwman committed 2018-10-29 21:55:58 +01:00
1 parent 5053d6d167
commit 1e3b45ee0d
16 files changed
+149 -10

No files matched your search

Generated
+16
View File
@@ -409,6 +409,19 @@ name = "nodrop"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-complex"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ordermap"
version = "0.3.5"
@@ -595,6 +608,7 @@ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustpython_parser 0.0.1",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -916,6 +930,8 @@ dependencies = [
"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "107b9be86cd2481930688277b675b0114578227f034674726605b8a482d8baf8"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
"checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998"
+1
View File
@@ -300,4 +300,5 @@ pub enum Comparison {
pub enum Number {
Integer { value: i32 },
Float { value: f64 },
Complex { real: f64, imag: f64 },
}
+1
View File
@@ -3,6 +3,7 @@
pub enum Tok {
Name { name: String },
Number { value: String },
Complex { real: f64, imag: f64 },
String { value: String },
Bytes { value: Vec<u8> },
Newline,
+4
View File
@@ -37,3 +37,7 @@ except TypeError:
pass
assert int() == 0
a = complex(2, 4)
assert type(a) is complex
assert type(a + a) is complex
+1
View File
@@ -5,6 +5,7 @@ authors = ["Shing Lyu <shing.lyu@gmail.com>"]
[dependencies]
bitflags = "1.0.4"
num-complex = "0.2"
log = "0.3"
rustpython_parser = {path = "../parser"}
serde = "1.0.66"
+1 -1
View File
@@ -126,7 +126,6 @@ fn builtin_compile(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
compile::compile(vm, &source, mode, None)
}
// builtin_complex
// builtin_delattr
fn builtin_dir(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -543,6 +542,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
dict.insert(String::from("bytes"), ctx.bytes_type());
dict.insert(String::from("chr"), ctx.new_rustfunc(builtin_chr));
dict.insert(String::from("compile"), ctx.new_rustfunc(builtin_compile));
dict.insert(String::from("complex"), ctx.complex_type());
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));
+3 -2
View File
@@ -10,9 +10,9 @@ let call_function = 0x64;
/*
* Primitive instruction type, which can be encoded and decoded.
*/
extern crate rustpython_parser;
use self::rustpython_parser::ast;
use num_complex::Complex64;
use rustpython_parser::ast;
use std::collections::HashMap;
use std::fmt;
@@ -197,6 +197,7 @@ pub enum CallType {
pub enum Constant {
Integer { value: i32 }, // TODO: replace by arbitrary big int math.
Float { value: f64 },
Complex { value: Complex64 },
Boolean { value: bool },
String { value: String },
Bytes { value: Vec<u8> },
+6 -4
View File
@@ -6,12 +6,11 @@
* https://github.com/micropython/micropython/blob/master/py/compile.c
*/
extern crate rustpython_parser;
use self::rustpython_parser::{ast, parser};
use super::bytecode::{self, CallType, CodeObject, Instruction};
use super::pyobject::{PyObject, PyObjectKind, PyResult};
use super::vm::VirtualMachine;
use num_complex::Complex64;
use rustpython_parser::{ast, parser};
struct Compiler {
code_object_stack: Vec<CodeObject>,
@@ -846,6 +845,9 @@ impl Compiler {
let const_value = match value {
ast::Number::Integer { value } => bytecode::Constant::Integer { value: *value },
ast::Number::Float { value } => bytecode::Constant::Float { value: *value },
ast::Number::Complex { real, imag } => bytecode::Constant::Complex {
value: Complex64::new(*real, *imag),
},
};
self.emit(Instruction::LoadConst { value: const_value });
}
@@ -1301,8 +1303,8 @@ mod tests {
use super::bytecode::CodeObject;
use super::bytecode::Constant::*;
use super::bytecode::Instruction::*;
use super::rustpython_parser::parser;
use super::Compiler;
use rustpython_parser::parser;
fn compile_exec(source: &str) -> CodeObject {
let mut compiler = Compiler::new();
compiler.push_new_code_object(Option::None, "<module>".to_string());
+1
View File
@@ -1074,6 +1074,7 @@ impl Frame {
match *value {
bytecode::Constant::Integer { ref value } => vm.ctx.new_int(*value),
bytecode::Constant::Float { ref value } => vm.ctx.new_float(*value),
bytecode::Constant::Complex { ref value } => vm.ctx.new_complex(*value),
bytecode::Constant::String { ref value } => vm.new_str(value.clone()),
bytecode::Constant::Bytes { ref value } => vm.ctx.new_bytes(value.clone()),
bytecode::Constant::Boolean { ref value } => vm.new_bool(value.clone()),
+3
View File
@@ -3,9 +3,12 @@ extern crate bitflags;
#[macro_use]
extern crate log;
// extern crate env_logger;
extern crate num_complex;
extern crate serde;
extern crate serde_json;
extern crate rustpython_parser;
//extern crate eval; use eval::eval::*;
// use py_code_object::{Function, NativeType, PyCodeObject};
+1
View File
@@ -1,5 +1,6 @@
pub mod objbool;
pub mod objbytes;
pub mod objcomplex;
pub mod objdict;
pub mod objfloat;
pub mod objfunction;
+71
View File
@@ -0,0 +1,71 @@
use super::super::pyobject::{
AttributeProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult,
TypeProtocol,
};
use super::super::vm::VirtualMachine;
use super::objfloat;
use super::objtype;
use num_complex::Complex64;
pub fn init(context: &PyContext) {
let ref complex_type = context.complex_type;
complex_type.set_attr("__add__", context.new_rustfunc(complex_add));
complex_type.set_attr("__new__", context.new_rustfunc(complex_new));
complex_type.set_attr("__repr__", context.new_rustfunc(complex_repr));
}
pub fn get_value(obj: &PyObjectRef) -> Complex64 {
if let PyObjectKind::Complex { value } = &obj.borrow().kind {
*value
} else {
panic!("Inner error getting complex");
}
}
fn complex_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(cls, None)],
optional = [(real, None), (imag, None)]
);
if !objtype::issubclass(cls, &vm.ctx.complex_type()) {
return Err(vm.new_type_error(format!("{:?} is not a subtype of complex", cls)));
}
let real = match real {
None => 0.0,
Some(value) => objfloat::make_float(vm, value)?,
};
let imag = match imag {
None => 0.0,
Some(value) => objfloat::make_float(vm, value)?,
};
let value = Complex64::new(real, imag);
Ok(PyObject::new(PyObjectKind::Complex { value }, cls.clone()))
}
fn complex_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(i, Some(vm.ctx.complex_type())), (i2, None)]
);
let v1 = get_value(i);
if objtype::isinstance(i2, &vm.ctx.complex_type()) {
Ok(vm.ctx.new_complex(v1 + get_value(i2)))
} else {
Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2)))
}
}
fn complex_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, Some(vm.ctx.complex_type()))]);
let v = get_value(obj);
Ok(vm.new_str(v.to_string()))
}
+11 -1
View File
@@ -5,7 +5,7 @@ use super::super::vm::VirtualMachine;
use super::objint;
use super::objtype;
fn float_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjectRef> {
fn float_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(float, Some(vm.ctx.float_type()))]);
let v = get_value(float);
Ok(vm.new_str(v.to_string()))
@@ -38,6 +38,16 @@ pub fn get_value(obj: &PyObjectRef) -> f64 {
}
}
pub fn make_float(vm: &mut VirtualMachine, obj: &PyObjectRef) -> Result<f64, PyObjectRef> {
if objtype::isinstance(obj, &vm.ctx.float_type()) {
Ok(get_value(obj))
} else if objtype::isinstance(obj, &vm.ctx.int_type()) {
Ok(objint::get_value(obj) as f64)
} else {
Err(vm.new_type_error(format!("Cannot cast {:?} to float", obj)))
}
}
fn set_value(obj: &PyObjectRef, value: f64) {
obj.borrow_mut().kind = PyObjectKind::Float { value };
}
+6 -2
View File
@@ -1,5 +1,6 @@
use super::super::pyobject::{
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
AttributeProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult,
TypeProtocol,
};
use super::super::vm::VirtualMachine;
use super::objbool;
@@ -56,7 +57,10 @@ fn list_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
};
Ok(vm.ctx.new_list(elements))
Ok(PyObject::new(
PyObjectKind::List { elements: elements },
cls.clone(),
))
}
fn list_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
+19
View File
@@ -3,6 +3,7 @@ use super::exceptions;
use super::frame::Frame;
use super::obj::objbool;
use super::obj::objbytes;
use super::obj::objcomplex;
use super::obj::objdict;
use super::obj::objfloat;
use super::obj::objfunction;
@@ -16,6 +17,7 @@ use super::obj::objstr;
use super::obj::objtuple;
use super::obj::objtype;
use super::vm::VirtualMachine;
use num_complex::Complex64;
use std::cell::RefCell;
use std::collections::HashMap;
use std::fmt;
@@ -57,6 +59,7 @@ pub struct PyContext {
pub dict_type: PyObjectRef,
pub int_type: PyObjectRef,
pub float_type: PyObjectRef,
pub complex_type: PyObjectRef,
pub bytes_type: PyObjectRef,
pub bool_type: PyObjectRef,
pub true_value: PyObjectRef,
@@ -130,6 +133,7 @@ impl PyContext {
let set_type = create_type("set", &type_type, &object_type, &dict_type);
let int_type = create_type("int", &type_type, &object_type, &dict_type);
let float_type = create_type("float", &type_type, &object_type, &dict_type);
let complex_type = create_type("complex", &type_type, &object_type, &dict_type);
let bytes_type = create_type("bytes", &type_type, &object_type, &dict_type);
let tuple_type = create_type("tuple", &type_type, &object_type, &dict_type);
let iter_type = create_type("iter", &type_type, &object_type, &dict_type);
@@ -146,6 +150,7 @@ impl PyContext {
let context = PyContext {
int_type: int_type,
float_type: float_type,
complex_type: complex_type,
bytes_type: bytes_type,
list_type: list_type,
set_type: set_type,
@@ -176,6 +181,7 @@ impl PyContext {
objgenerator::init(&context);
objint::init(&context);
objfloat::init(&context);
objcomplex::init(&context);
objbytes::init(&context);
objstr::init(&context);
objtuple::init(&context);
@@ -193,6 +199,10 @@ impl PyContext {
self.float_type.clone()
}
pub fn complex_type(&self) -> PyObjectRef {
self.complex_type.clone()
}
pub fn bytes_type(&self) -> PyObjectRef {
self.bytes_type.clone()
}
@@ -262,6 +272,10 @@ impl PyContext {
PyObject::new(PyObjectKind::Float { value: i }, self.float_type())
}
pub fn new_complex(&self, i: Complex64) -> PyObjectRef {
PyObject::new(PyObjectKind::Complex { value: i }, self.complex_type())
}
pub fn new_str(&self, s: String) -> PyObjectRef {
PyObject::new(PyObjectKind::String { value: s }, self.str_type())
}
@@ -624,6 +638,9 @@ pub enum PyObjectKind {
Float {
value: f64,
},
Complex {
value: Complex64,
},
Bytes {
value: Vec<u8>,
},
@@ -690,6 +707,7 @@ impl fmt::Debug for PyObjectKind {
&PyObjectKind::String { ref value } => write!(f, "str \"{}\"", value),
&PyObjectKind::Integer { ref value } => write!(f, "int {}", value),
&PyObjectKind::Float { ref value } => write!(f, "float {}", value),
&PyObjectKind::Complex { ref value } => write!(f, "complex {}", value),
&PyObjectKind::Bytes { ref value } => write!(f, "bytes {:?}", value),
&PyObjectKind::List { elements: _ } => write!(f, "list"),
&PyObjectKind::Tuple { elements: _ } => write!(f, "tuple"),
@@ -740,6 +758,7 @@ impl PyObject {
PyObjectKind::String { ref value } => value.clone(),
PyObjectKind::Integer { ref value } => format!("{:?}", value),
PyObjectKind::Float { ref value } => format!("{:?}", value),
PyObjectKind::Complex { ref value } => format!("{:?}", value),
PyObjectKind::Bytes { ref value } => format!("b'{:?}'", value),
PyObjectKind::List { ref elements } => format!(
"[{}]",
+4
View File
@@ -13,6 +13,7 @@ use super::super::pyobject::{
AttributeProtocol, DictProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol,
};
use super::super::VirtualMachine;
use num_complex::Complex64;
use std::ops::Deref;
/*
@@ -391,6 +392,9 @@ fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectR
let py_n = match value {
ast::Number::Integer { value } => ctx.new_int(*value),
ast::Number::Float { value } => ctx.new_float(*value),
ast::Number::Complex { real, imag } => {
ctx.new_complex(Complex64::new(*real, *imag))
}
};
node.set_attr("n", py_n);