mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Change rt to vm and change args into an object holding both args and kwargs
This commit is contained in:
@@ -4,15 +4,15 @@ use std::io::{self, Write};
|
||||
|
||||
use super::compile;
|
||||
use super::pyobject::DictProtocol;
|
||||
use super::pyobject::{PyContext, PyObject, PyObjectKind, PyObjectRef, PyResult, Scope, IdProtocol};
|
||||
use super::pyobject::{PyContext, PyObject, PyObjectKind, PyObjectRef, PyResult, Scope, IdProtocol, PyFuncArgs};
|
||||
use super::vm::VirtualMachine;
|
||||
use super::objbool;
|
||||
|
||||
|
||||
fn get_locals(rt: &mut VirtualMachine) -> PyObjectRef {
|
||||
let mut d = rt.new_dict();
|
||||
fn get_locals(vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
let mut d = vm.new_dict();
|
||||
// TODO: implement dict_iter_items?
|
||||
let locals = rt.get_locals();
|
||||
let locals = vm.get_locals();
|
||||
match locals.borrow().kind {
|
||||
PyObjectKind::Dict { ref elements } => {
|
||||
for l in elements {
|
||||
@@ -24,63 +24,64 @@ fn get_locals(rt: &mut VirtualMachine) -> PyObjectRef {
|
||||
d
|
||||
}
|
||||
|
||||
fn dir_locals(rt: &mut VirtualMachine) -> PyObjectRef {
|
||||
get_locals(rt)
|
||||
fn dir_locals(vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
get_locals(vm)
|
||||
}
|
||||
|
||||
fn dir_object(rt: &mut VirtualMachine, obj: PyObjectRef) -> PyObjectRef {
|
||||
let d = rt.new_dict();
|
||||
fn dir_object(vm: &mut VirtualMachine, obj: PyObjectRef) -> PyObjectRef {
|
||||
let d = vm.new_dict();
|
||||
d
|
||||
}
|
||||
|
||||
pub fn builtin_dir(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
if args.is_empty() {
|
||||
Ok(dir_locals(rt))
|
||||
pub fn builtin_dir(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
if args.args.is_empty() {
|
||||
Ok(dir_locals(vm))
|
||||
} else {
|
||||
let obj = args.into_iter().next().unwrap();
|
||||
Ok(dir_object(rt, obj))
|
||||
let obj = args.args.into_iter().next().unwrap();
|
||||
Ok(dir_object(vm, obj))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn builtin_id(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
if args.len() != 1 {
|
||||
return Err(rt.new_exception("Expected only one argument".to_string()))
|
||||
pub fn builtin_id(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
if args.args.len() != 1 {
|
||||
return Err(vm.new_exception("Expected only one argument".to_string()))
|
||||
}
|
||||
|
||||
Ok(rt.context().new_int(args[0].get_id() as i32))
|
||||
Ok(vm.context().new_int(args.args[0].get_id() as i32))
|
||||
}
|
||||
|
||||
pub fn builtin_print(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
pub fn builtin_print(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
trace!("print called with {:?}", args);
|
||||
for a in args {
|
||||
for a in args.args {
|
||||
print!("{} ", a.borrow().str());
|
||||
}
|
||||
println!();
|
||||
io::stdout().flush().unwrap();
|
||||
Ok(rt.get_none())
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
pub fn builtin_compile(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
if args.len() < 1 {
|
||||
return Err(rt.new_exception("Expected more arguments".to_string()))
|
||||
pub fn builtin_compile(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
if args.args.len() < 1 {
|
||||
return Err(vm.new_exception("Expected more arguments".to_string()))
|
||||
}
|
||||
// TODO:
|
||||
let mode = compile::Mode::Eval;
|
||||
let source = args[0].borrow().str();
|
||||
let source = args.args[0].borrow().str();
|
||||
|
||||
match compile::compile(rt, &source, mode) {
|
||||
match compile::compile(vm, &source, mode) {
|
||||
Ok(value) => Ok(value),
|
||||
Err(msg) => Err(rt.new_exception(msg)),
|
||||
Err(msg) => Err(vm.new_exception(msg)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn builtin_eval(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
pub fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let args = args.args;
|
||||
if args.len() > 3 {
|
||||
return Err(rt.new_exception("Expected at maximum of 3 arguments".to_string()))
|
||||
return Err(vm.new_exception("Expected at maximum of 3 arguments".to_string()))
|
||||
} else if args.len() > 2 {
|
||||
// TODO: handle optional global and locals
|
||||
} else {
|
||||
return Err(rt.new_exception("Expected at least one argument".to_string()))
|
||||
return Err(vm.new_exception("Expected at least one argument".to_string()))
|
||||
}
|
||||
let source = args[0].clone();
|
||||
let _globals = args[1].clone();
|
||||
@@ -96,27 +97,27 @@ pub fn builtin_eval(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult
|
||||
let scope = PyObject { kind: PyObjectKind::Scope { scope: scope_inner }, typ: None }.into_ref();
|
||||
|
||||
// Run the source:
|
||||
rt.run_code_obj(code_obj, scope)
|
||||
vm.run_code_obj(code_obj, scope)
|
||||
}
|
||||
|
||||
pub fn locals(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
Ok(rt.get_locals())
|
||||
pub fn builtin_locals(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.get_locals())
|
||||
}
|
||||
|
||||
pub fn len(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
if args.len() != 1 {
|
||||
pub fn builtin_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
if args.args.len() != 1 {
|
||||
panic!("len(s) expects exactly one parameter");
|
||||
}
|
||||
let len = match args[0].borrow().kind {
|
||||
let len = match args.args[0].borrow().kind {
|
||||
PyObjectKind::List { ref elements } => elements.len(),
|
||||
PyObjectKind::Tuple { ref elements } => elements.len(),
|
||||
PyObjectKind::String { ref value } => value.len(),
|
||||
_ => {
|
||||
return Err(rt.context()
|
||||
return Err(vm.context()
|
||||
.new_str("TypeError: object of this type has no len()".to_string()))
|
||||
}
|
||||
};
|
||||
Ok(rt.context().new_int(len as i32))
|
||||
Ok(vm.context().new_int(len as i32))
|
||||
}
|
||||
|
||||
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
@@ -129,10 +130,10 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
dict.insert(String::from("all"), ctx.new_rustfunc(builtin_all));
|
||||
dict.insert(String::from("any"), ctx.new_rustfunc(builtin_any));
|
||||
dict.insert(String::from("dir"), ctx.new_rustfunc(builtin_dir));
|
||||
dict.insert(String::from("locals"), ctx.new_rustfunc(locals));
|
||||
dict.insert(String::from("locals"), ctx.new_rustfunc(builtin_locals));
|
||||
dict.insert(String::from("compile"), ctx.new_rustfunc(builtin_compile));
|
||||
dict.insert(String::from("eval"), ctx.new_rustfunc(builtin_eval));
|
||||
dict.insert("len".to_string(), ctx.new_rustfunc(len));
|
||||
dict.insert("len".to_string(), ctx.new_rustfunc(builtin_len));
|
||||
let d2 = PyObject::new(PyObjectKind::Dict { elements: dict }, ctx.type_type.clone());
|
||||
let scope = PyObject::new(PyObjectKind::Scope { scope: Scope { locals: d2, parent: None} }, ctx.type_type.clone());
|
||||
let obj = PyObject::new(
|
||||
@@ -145,10 +146,10 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
obj
|
||||
}
|
||||
|
||||
fn builtin_any(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
Ok(rt.new_bool(args.into_iter().any(|e| objbool::boolval(e))))
|
||||
fn builtin_any(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.new_bool(args.args.into_iter().any(|e| objbool::boolval(e))))
|
||||
}
|
||||
|
||||
fn builtin_all(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
Ok(rt.new_bool(args.into_iter().all(|e| objbool::boolval(e))))
|
||||
fn builtin_all(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.new_bool(args.args.into_iter().all(|e| objbool::boolval(e))))
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ struct Compiler {
|
||||
nxt_label: usize,
|
||||
}
|
||||
|
||||
pub fn compile(rt: &mut VirtualMachine, source: &String, mode: Mode) -> Result<PyObjectRef, String> {
|
||||
pub fn compile(vm: &mut VirtualMachine, source: &String, mode: Mode) -> Result<PyObjectRef, String> {
|
||||
let mut compiler = Compiler::new();
|
||||
compiler.push_code_object(CodeObject::new(Vec::new()));
|
||||
match mode {
|
||||
@@ -43,7 +43,7 @@ pub fn compile(rt: &mut VirtualMachine, source: &String, mode: Mode) -> Result<P
|
||||
let code = compiler.pop_code_object();
|
||||
Ok(PyObject::new(
|
||||
PyObjectKind::Code { code: code },
|
||||
rt.get_type(),
|
||||
vm.get_type(),
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::pyobject::{PyObjectRef, PyResult};
|
||||
use super::vm::VirtualMachine;
|
||||
|
||||
pub fn set_item(rt: &mut VirtualMachine, d: PyObjectRef, idx: PyObjectRef, obj: PyObjectRef) -> PyResult {
|
||||
Ok(rt.get_none())
|
||||
pub fn set_item(vm: &mut VirtualMachine, d: PyObjectRef, idx: PyObjectRef, obj: PyObjectRef) -> PyResult {
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use super::pyobject::{PyObject, PyObjectKind, PyObjectRef};
|
||||
use super::pyobject::{PyObject, PyObjectKind, PyObjectRef, PyFuncArgs};
|
||||
use super::vm::VirtualMachine;
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn str(rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> Result<PyObjectRef, PyObjectRef> {
|
||||
Ok(rt.new_str("todo".to_string()))
|
||||
fn str(vm: &mut VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjectRef> {
|
||||
Ok(vm.new_str("todo".to_string()))
|
||||
}
|
||||
|
||||
fn add() {}
|
||||
|
||||
@@ -9,7 +9,7 @@ fn get_pos(l: &Vec<PyObjectRef>, p: i32) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_item(rt: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -> PyResult {
|
||||
pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -> PyResult {
|
||||
match &(b.borrow()).kind {
|
||||
PyObjectKind::Integer { value } => {
|
||||
let pos_index = get_pos(l, *value);
|
||||
@@ -17,7 +17,7 @@ pub fn get_item(rt: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -
|
||||
let obj = l[pos_index].clone();
|
||||
Ok(obj)
|
||||
} else {
|
||||
Err(rt.new_exception("Index out of bounds!".to_string()))
|
||||
Err(vm.new_exception("Index out of bounds!".to_string()))
|
||||
}
|
||||
}
|
||||
PyObjectKind::Slice { start, stop, step } => {
|
||||
@@ -39,11 +39,11 @@ pub fn get_item(rt: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -
|
||||
PyObjectKind::List {
|
||||
elements: l[start..stop].to_vec(),
|
||||
},
|
||||
rt.get_type(),
|
||||
vm.get_type(),
|
||||
);
|
||||
Ok(obj)
|
||||
}
|
||||
_ => Err(rt.new_exception(format!(
|
||||
_ => Err(vm.new_exception(format!(
|
||||
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
|
||||
l, b
|
||||
))),
|
||||
@@ -52,7 +52,7 @@ pub fn get_item(rt: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -
|
||||
|
||||
// set_item:
|
||||
pub fn set_item(
|
||||
rt: &mut VirtualMachine,
|
||||
vm: &mut VirtualMachine,
|
||||
l: &mut Vec<PyObjectRef>,
|
||||
idx: PyObjectRef,
|
||||
obj: PyObjectRef,
|
||||
@@ -61,7 +61,7 @@ pub fn set_item(
|
||||
PyObjectKind::Integer { value } => {
|
||||
let pos_index = get_pos(l, *value);
|
||||
l[pos_index] = obj;
|
||||
Ok(rt.get_none())
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
_ => panic!(
|
||||
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
|
||||
@@ -70,8 +70,8 @@ pub fn set_item(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn append(rt: &mut VirtualMachine, l: PyObjectRef, other: PyObjectRef) -> PyResult {
|
||||
Ok(rt.get_none())
|
||||
pub fn append(vm: &mut VirtualMachine, l: PyObjectRef, other: PyObjectRef) -> PyResult {
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
|
||||
@@ -11,12 +11,12 @@ fn str_pos(s: &String, p: i32) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subscript(rt: &mut VirtualMachine, value: &String, b: PyObjectRef) -> PyResult {
|
||||
pub fn subscript(vm: &mut VirtualMachine, value: &String, b: PyObjectRef) -> PyResult {
|
||||
// let value = a
|
||||
match &(*b.borrow()).kind {
|
||||
&PyObjectKind::Integer { value: ref pos } => {
|
||||
let idx = str_pos(value, *pos);
|
||||
Ok(rt.new_str(value[idx..idx + 1].to_string()))
|
||||
Ok(vm.new_str(value[idx..idx + 1].to_string()))
|
||||
}
|
||||
&PyObjectKind::Slice {
|
||||
ref start,
|
||||
@@ -38,7 +38,7 @@ pub fn subscript(rt: &mut VirtualMachine, value: &String, b: PyObjectRef) -> PyR
|
||||
&None => 1 as usize,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
Ok(rt.new_str(value[start2..stop2].to_string()))
|
||||
Ok(vm.new_str(value[start2..stop2].to_string()))
|
||||
}
|
||||
_ => panic!(
|
||||
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
|
||||
|
||||
@@ -9,7 +9,7 @@ fn get_pos(l: &Vec<PyObjectRef>, p: i32) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_item(rt: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -> PyResult {
|
||||
pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -> PyResult {
|
||||
match &(b.borrow()).kind {
|
||||
PyObjectKind::Integer { value } => {
|
||||
let pos_index = get_pos(l, *value);
|
||||
@@ -17,7 +17,7 @@ pub fn get_item(rt: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -
|
||||
let obj = l[pos_index].clone();
|
||||
Ok(obj)
|
||||
} else {
|
||||
Err(rt.new_exception("Index out of bounds!".to_string()))
|
||||
Err(vm.new_exception("Index out of bounds!".to_string()))
|
||||
}
|
||||
}
|
||||
PyObjectKind::Slice { start, stop, step } => {
|
||||
@@ -39,11 +39,11 @@ pub fn get_item(rt: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -
|
||||
PyObjectKind::Tuple {
|
||||
elements: l[start..stop].to_vec(),
|
||||
},
|
||||
rt.get_type(),
|
||||
vm.get_type(),
|
||||
);
|
||||
Ok(obj)
|
||||
}
|
||||
_ => Err(rt.new_exception(format!(
|
||||
_ => Err(vm.new_exception(format!(
|
||||
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
|
||||
l, b
|
||||
))),
|
||||
|
||||
@@ -222,7 +222,13 @@ impl fmt::Debug for PyObject {
|
||||
}
|
||||
}
|
||||
|
||||
type RustPyFunc = fn(rt: &mut VirtualMachine, Vec<PyObjectRef>) -> PyResult;
|
||||
#[derive(Debug)]
|
||||
pub struct PyFuncArgs {
|
||||
pub args: Vec<PyObjectRef>,
|
||||
// TODO: add kwargs here
|
||||
}
|
||||
|
||||
type RustPyFunc = fn(vm: &mut VirtualMachine, PyFuncArgs) -> PyResult;
|
||||
|
||||
pub enum PyObjectKind {
|
||||
String {
|
||||
@@ -316,9 +322,9 @@ impl PyObject {
|
||||
}.into_ref()
|
||||
}
|
||||
|
||||
pub fn call(&self, rt: &mut VirtualMachine, args: Vec<PyObjectRef>) -> PyResult {
|
||||
pub fn call(&self, vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
match self.kind {
|
||||
PyObjectKind::RustFunction { ref function } => function(rt, args),
|
||||
PyObjectKind::RustFunction { ref function } => function(vm, args),
|
||||
_ => {
|
||||
println!("Not impl {:?}", self);
|
||||
panic!("Not impl");
|
||||
|
||||
17
vm/src/vm.rs
17
vm/src/vm.rs
@@ -16,7 +16,7 @@ use super::objlist;
|
||||
use super::objstr;
|
||||
use super::objtuple;
|
||||
use super::pyobject::{DictProtocol, PyContext, PyObject, PyObjectKind, PyObjectRef,
|
||||
PyResult, ParentProtocol, Scope, IdProtocol};
|
||||
PyResult, ParentProtocol, Scope, IdProtocol, PyFuncArgs};
|
||||
|
||||
// use objects::objects;
|
||||
|
||||
@@ -30,7 +30,10 @@ pub struct VirtualMachine {
|
||||
|
||||
impl VirtualMachine {
|
||||
fn call(&mut self, f: PyObjectRef) -> PyResult {
|
||||
self.invoke(f, Vec::new())
|
||||
let args = PyFuncArgs {
|
||||
args: Vec::new(),
|
||||
};
|
||||
self.invoke(f, args)
|
||||
}
|
||||
|
||||
pub fn run_code_obj(&mut self, code: PyObjectRef, scope: PyObjectRef) -> PyResult {
|
||||
@@ -452,13 +455,13 @@ impl VirtualMachine {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_instance(&mut self, type_ref: PyObjectRef, args: Vec<PyObjectRef>) -> PyResult {
|
||||
fn new_instance(&mut self, type_ref: PyObjectRef, args: PyFuncArgs) -> PyResult {
|
||||
// more or less __new__ operator
|
||||
let obj = PyObject::new(PyObjectKind::None, type_ref.clone());
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
fn invoke(&mut self, func_ref: PyObjectRef, args: Vec<PyObjectRef>) -> PyResult {
|
||||
fn invoke(&mut self, func_ref: PyObjectRef, args: PyFuncArgs) -> PyResult {
|
||||
let f = func_ref.borrow();
|
||||
|
||||
match f.kind {
|
||||
@@ -466,7 +469,7 @@ impl VirtualMachine {
|
||||
PyObjectKind::Function { ref code, ref scope } => {
|
||||
let mut scope = self.new_scope(Some(scope.clone()));
|
||||
let code_object = copy_code(code.clone());
|
||||
for (name, value) in code_object.arg_names.iter().zip(args) {
|
||||
for (name, value) in code_object.arg_names.iter().zip(args.args) {
|
||||
scope.set_item(name, value);
|
||||
}
|
||||
let frame = Frame::new(code.clone(), scope);
|
||||
@@ -665,6 +668,10 @@ impl VirtualMachine {
|
||||
}
|
||||
bytecode::Instruction::CallFunction { count } => {
|
||||
let args: Vec<PyObjectRef> = self.pop_multiple(*count);
|
||||
// TODO: kwargs
|
||||
let args = PyFuncArgs {
|
||||
args: args
|
||||
};
|
||||
let func_ref = self.pop_value();
|
||||
|
||||
// Call function:
|
||||
|
||||
Reference in New Issue
Block a user