Skip to content

Commit 11d3dd5

Browse files
committed
Not done with the new evaluator
1 parent c8d56ee commit 11d3dd5

File tree

13 files changed

+1240
-489
lines changed

13 files changed

+1240
-489
lines changed

Cargo.lock

Lines changed: 466 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ strum = "0.26.3"
1111
strum_macros = "0.26.4"
1212
mopa = "0.2.2"
1313
ahash = "0.8.11"
14+
rustpython-parser = "0.4.0"
1415

1516
[profile.release]
1617
lto = "fat"

src/builtins/functions/compare.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1+
use rustpython_parser::ast::located::CmpOp;
12
use crate::builtins::function_utils::call_function_1_arg_min;
23
use crate::builtins::structure::magic_methods::PyMagicMethod;
34
use crate::builtins::structure::pyobject::{FuncReturnType, PyObject};
4-
use crate::parser::Comparator;
55
use crate::pyarena::PyArena;
66

7-
pub fn compare_op(left: &PyObject, right: &PyObject, comp: &Comparator, arena: &mut PyArena) -> FuncReturnType {
7+
pub fn compare_op(left: &PyObject, right: &PyObject, comp: &CmpOp, arena: &mut PyArena) -> FuncReturnType {
88
match comp {
9-
Comparator::Equal => left_hand_compare_op(&PyMagicMethod::Eq, left, right, arena),
10-
Comparator::NotEqual => left_hand_compare_op(&PyMagicMethod::Ne, left, right, arena),
11-
Comparator::LessThan => left_hand_compare_op(&PyMagicMethod::Lt, left, right, arena),
12-
Comparator::LessThanOrEqual => left_hand_compare_op(&PyMagicMethod::Le, left, right, arena),
13-
Comparator::GreaterThan => left_hand_compare_op(&PyMagicMethod::Gt, left, right, arena),
14-
Comparator::GreaterThanOrEqual => left_hand_compare_op(&PyMagicMethod::Ge, left, right, arena),
9+
CmpOp::Eq => left_hand_compare_op(&PyMagicMethod::Eq, left, right, arena),
10+
CmpOp::NotEq => left_hand_compare_op(&PyMagicMethod::Ne, left, right, arena),
11+
CmpOp::Lt => left_hand_compare_op(&PyMagicMethod::Lt, left, right, arena),
12+
CmpOp::LtE => left_hand_compare_op(&PyMagicMethod::Le, left, right, arena),
13+
CmpOp::Gt => left_hand_compare_op(&PyMagicMethod::Gt, left, right, arena),
14+
CmpOp::GtE => left_hand_compare_op(&PyMagicMethod::Ge, left, right, arena),
1515

16-
Comparator::Is => Ok(is_compare(false, left, right, arena)),
17-
Comparator::IsNot => Ok(is_compare(true, left, right, arena)),
18-
Comparator::In => {todo!()}
19-
Comparator::NotIn => {todo!()}
16+
CmpOp::Is => Ok(is_compare(false, left, right, arena)),
17+
CmpOp::IsNot => Ok(is_compare(true, left, right, arena)),
18+
CmpOp::In => {todo!()}
19+
CmpOp::NotIn => {todo!()}
2020
}
2121
}
2222

src/builtins/functions/math_op.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub fn math_op(left: PyObject, right: PyObject, py_magic_method: PyMagicMethod,
2323
right_hand_math_op(left, right, py_magic_method, arena)
2424
}
2525

26-
fn right_hand_math_op(left: PyObject, right: PyObject, mut py_magic_method: PyMagicMethod, arena: &mut PyArena) -> FuncReturnType {
26+
pub(crate) fn right_hand_math_op(left: PyObject, right: PyObject, mut py_magic_method: PyMagicMethod, arena: &mut PyArena) -> FuncReturnType {
2727
py_magic_method.make_right_handed();
2828

2929
let right_math_func = right.get_magic_method(&py_magic_method, arena);

src/builtins/globals.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ impl Globals {
4747
}
4848
}
4949

50-
pub fn create_exposed_globals(&self) -> AHashMap<String, Cell<PyObject>> {
50+
pub fn create_exposed_globals(&self) -> AHashMap<String, PyObject> {
5151
vec![
52-
("object".to_string(), Cell::new(PyObject::new_internal_class(self.object_class.clone()))),
53-
("int".to_string(), Cell::new(PyObject::new_internal_class(self.int_class.clone()))),
54-
("bool".to_string(), Cell::new(PyObject::new_internal_class(self.bool_class.clone()))),
55-
("float".to_string(), Cell::new(PyObject::new_internal_class(self.float_class.clone()))),
56-
("range".to_string(), Cell::new(PyObject::new_internal_class(self.range_class.clone()))),
57-
("print".to_string(), Cell::new(PyObject::new_internal_func(self.print_func.clone()))),
52+
("object".to_string(), PyObject::new_internal_class(self.object_class.clone())),
53+
("int".to_string(), PyObject::new_internal_class(self.int_class.clone())),
54+
("bool".to_string(), PyObject::new_internal_class(self.bool_class.clone())),
55+
("float".to_string(), PyObject::new_internal_class(self.float_class.clone())),
56+
("range".to_string(), PyObject::new_internal_class(self.range_class.clone())),
57+
("print".to_string(), PyObject::new_internal_func(self.print_func.clone())),
5858
].into_iter().collect()
5959
}
6060

src/builtins/structure/pyobject.rs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
use std::cell::{Ref, RefCell, RefMut};
22
use std::fmt::Debug;
33
use std::rc::Rc;
4-
use crate::parser::CodeBlock;
4+
// use crate::parser::CodeBlock;
55
use crate::pyarena::PyArena;
66
use crate::builtins::structure::magic_methods::{PyMagicMethod};
77
use crate::builtins::structure::pyclass::PyClass;
88
use crate::builtins::structure::pyexception::PyException;
99
use crate::builtins::structure::pyinstance::PyInstance;
1010

11+
#[derive(Debug)]
12+
pub enum StatementOperation {
13+
Return(Option<PyObject>),
14+
Expression(PyObject),
15+
Pass,
16+
Continue,
17+
Break
18+
}
19+
1120
#[derive(Clone, Debug)]
1221
pub enum PyObject {
1322
Immutable(Rc<PyImmutableObject>), // TODO, consider using Cow's here
1423
Mutable(PyPointer<PyMutableObject>),
1524
Internal(PyInternalObject),
16-
IteratorFlag(PyIteratorFlag)
25+
// IteratorFlag(PyIteratorFlag)
1726
}
1827

1928
impl PyObject {
@@ -48,14 +57,14 @@ impl PyObject {
4857
}
4958

5059

51-
pub fn break_() -> Self { // TODO prob should be moved out of the pyobject class (currently in here for legacy reasons)
52-
PyObject::IteratorFlag(PyIteratorFlag::Break)
53-
}
54-
55-
pub fn continue_() -> Self { // TODO prob should be moved out of the pyobject class (currently in here for legacy reasons)
56-
PyObject::IteratorFlag(PyIteratorFlag::Continue)
57-
}
58-
60+
// pub fn break_() -> Self { // TODO prob should be moved out of the pyobject class (currently in here for legacy reasons)
61+
// PyObject::IteratorFlag(PyIteratorFlag::Break)
62+
// }
63+
//
64+
// pub fn continue_() -> Self { // TODO prob should be moved out of the pyobject class (currently in here for legacy reasons)
65+
// PyObject::IteratorFlag(PyIteratorFlag::Continue)
66+
// }
67+
//
5968
pub fn create_new_none() -> Self {
6069
PyObject::Immutable(Rc::new(PyImmutableObject::None))
6170
}
@@ -68,9 +77,9 @@ impl PyObject {
6877
Self::new_immutable(PyImmutableObject::Bool(value))
6978
}
7079

71-
pub fn stop_iteration() -> Self { // TODO prob should be moved out of the pyobject class (currently in here for legacy reasons)
72-
PyObject::IteratorFlag(PyIteratorFlag::StopIteration)
73-
}
80+
// pub fn stop_iteration() -> Self { // TODO prob should be moved out of the pyobject class (currently in here for legacy reasons)
81+
// PyObject::IteratorFlag(PyIteratorFlag::StopIteration)
82+
// }
7483

7584
pub fn expect_immutable(&self) -> &Rc<PyImmutableObject> {
7685
match self {
@@ -97,7 +106,7 @@ impl PyObject {
97106
match self {
98107
PyObject::Immutable(inner) => inner.get_magic_method(py_magic_method, arena),
99108
PyObject::Mutable(inner) => inner.borrow().get_magic_method(py_magic_method, arena),
100-
PyObject::IteratorFlag(_) => {panic!("IteratorFlag has no magic methods")}
109+
// PyObject::IteratorFlag(_) => {panic!("IteratorFlag has no magic methods")}
101110
PyObject::Internal(_) => {todo!()}
102111
}
103112
}
@@ -106,7 +115,7 @@ impl PyObject {
106115
match *self {
107116
PyObject::Immutable(ref inner) => inner.get_class(arena).clone(),
108117
PyObject::Mutable(ref inner) => inner.borrow().get_class().clone(),
109-
PyObject::IteratorFlag(_) => {panic!("IteratorFlag has no class")}
118+
// PyObject::IteratorFlag(_) => {panic!("IteratorFlag has no class")}
110119
PyObject::Internal(_) => {todo!()}
111120
}
112121
}
@@ -116,7 +125,7 @@ impl PyObject {
116125
PyObject::Immutable(immutable) => &*immutable.clone() as *const PyImmutableObject as usize,
117126
PyObject::Mutable(mutable) => &*mutable.clone().borrow() as *const PyMutableObject as usize,
118127
PyObject::Internal(internal) => internal.get_memory_location(),
119-
PyObject::IteratorFlag(flag) => flag as *const PyIteratorFlag as usize
128+
// PyObject::IteratorFlag(flag) => flag as *const PyIteratorFlag as usize
120129
}
121130
}
122131
}
@@ -189,25 +198,25 @@ impl PyInternalObject {
189198

190199
#[derive(Debug)]
191200
pub enum PyMutableObject {
192-
// Class(Rc<PyClass>),
201+
Class(Rc<PyClass>),
193202
Instance(PyInstance),
194-
Function(PyFunction),
203+
// Function(PyFunction),
195204
}
196205

197206
impl PyMutableObject {
198207
pub fn get_class(&self) -> &Rc<PyClass> {
199208
match self {
200209
PyMutableObject::Instance(py_instance) => py_instance.get_class(),
201-
// PyMutableObject::Class(py_class) => py_class,
202-
PyMutableObject::Function(_py_function) => todo!(),
210+
PyMutableObject::Class(py_class) => py_class,
211+
// PyMutableObject::Function(_py_function) => todo!(),
203212
}
204213
}
205214

206215
pub fn get_field(&self, name: &str, arena: &mut PyArena) -> FuncReturnType {
207216
match self {
208217
PyMutableObject::Instance(instance) => instance.get_field(name, arena),
209-
// PyMutableObject::Class(py_class) => todo!(),
210-
PyMutableObject::Function(_py_function) => todo!(),
218+
PyMutableObject::Class(py_class) => todo!(),
219+
// PyMutableObject::Function(_py_function) => todo!(),
211220
}
212221
}
213222

@@ -228,19 +237,19 @@ impl PyMutableObject {
228237

229238
pub fn get_magic_method(&self, py_magic_method: &PyMagicMethod, _arena: &mut PyArena) -> Option<PyObject> {
230239
match self {
231-
// PyMutableObject::Class(_) => {todo!()}
240+
PyMutableObject::Class(_) => {todo!()}
232241
PyMutableObject::Instance(instance) => { instance.get_class().search_for_magic_method(py_magic_method) }
233-
PyMutableObject::Function(_) => {todo!()}
242+
// PyMutableObject::Function(_) => {todo!()}
234243
}
235244
}
236245
}
237246

238-
#[derive(Debug)]
239-
pub struct PyFunction {
240-
name: String,
241-
args: Vec<String>,
242-
body: Vec<CodeBlock>,
243-
}
247+
// #[derive(Debug)]
248+
// pub struct PyFunction {
249+
// name: String,
250+
// args: Vec<String>,
251+
// body: Vec<CodeBlock>,
252+
// }
244253

245254
pub type FuncReturnType = Result<PyObject, PyException>;
246255
pub type EmptyFuncReturnType = Result<(), PyException>;

src/builtins/types/pybool.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub fn convert_pyobj_to_bool(pyobj: &PyObject, arena: &mut PyArena) -> Result<bo
5555
PyObject::Immutable(ref immutable) => convert_immutable_to_bool(immutable, arena),
5656
PyObject::Mutable(ref mutable) => convert_mutable_to_bool(pyobj, &mutable.borrow(), arena),
5757
PyObject::Internal(_) => {todo!()}
58-
PyObject::IteratorFlag(_) => {panic!()}
58+
// PyObject::IteratorFlag(_) => {panic!()}
5959
}
6060
}
6161

src/evaluator.rs

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,82 @@
1-
use std::cell::Ref;
21
use std::ops::Deref;
32
use std::rc::Rc;
3+
use rustpython_parser::ast::{Mod, ModModule, Stmt, StmtReturn};
44
use crate::builtins::function_utils::{call_function, eval_internal_func, eval_obj_init};
55
use crate::builtins::functions::compare::compare_op;
66
use crate::builtins::functions::math_op::math_op;
77
use crate::builtins::structure::magic_methods::PyMagicMethod;
88
use crate::builtins::structure::magic_methods::PyMagicMethod::{Add, Mul, Pow, Sub, TrueDiv};
99
use crate::builtins::structure::pyexception::PyException;
10-
use crate::builtins::structure::pyobject::{EmptyFuncReturnType, FuncReturnType, PyInternalObject, PyIteratorFlag, PyObject};
10+
use crate::builtins::structure::pyobject::{EmptyFuncReturnType, FuncReturnType, PyInternalObject, PyIteratorFlag, PyObject, StatementOperation};
1111
use crate::builtins::types::pybool::{convert_pyobj_to_bool};
1212
use crate::builtins::types::str::py_repr;
13-
use crate::parser::*;
13+
// use crate::parser::*;
1414
use crate::pyarena::PyArena;
1515

16-
pub fn evaluate(code: CodeBlock) {
17-
let mut arena = PyArena::new();
16+
pub fn evaluate_mod(code: Mod) {
17+
// let mut arena = PyArena::new();
18+
let result = match code {
19+
Mod::Module(module ) => {evaluate_module(module)},
20+
Mod::Interactive(_) => {todo!()}
21+
Mod::Expression(_) => {todo!()}
22+
Mod::FunctionType(_) => {todo!()}
23+
};
1824

19-
let code_result = eval_code_block(&code, &mut arena);
25+
// let code_result = eval_code_block(&code, &mut arena);
2026

21-
if let Err(err) = code_result {
22-
println!("{}", err);
27+
print!("Exit Value: {:?}", result);
28+
29+
// if let Err(err) = code_result {
30+
// println!("{}", err);
31+
// }
32+
}
33+
34+
fn evaluate_module(module: ModModule) -> Result<(PyArena, i32), PyException> {
35+
let mut arena = PyArena::new();
36+
37+
for statement in module.body {
38+
let statement_value = match statement {
39+
Stmt::Break(..) => {StatementOperation::Break}
40+
Stmt::Continue(..) => {StatementOperation::Continue}
41+
Stmt::Pass(..) => {StatementOperation::Pass}
42+
Stmt::Return(stmt_return) => {StatementOperation::Return(eval_return_stmt(stmt_return, &mut arena)?)}
43+
Stmt::Expr(_) => {}
44+
Stmt::While(_) => {}
45+
Stmt::If(_) => {}
46+
Stmt::For(_) => {}
47+
Stmt::Assign(_) => {}
48+
Stmt::FunctionDef(_) => {}
49+
// not implemented
50+
Stmt::AsyncFunctionDef(_) => {todo!()}
51+
Stmt::ClassDef(_) => {todo!()}
52+
Stmt::Delete(_) => {todo!()}
53+
Stmt::TypeAlias(_) => {todo!()}
54+
Stmt::AugAssign(_) => {todo!()}
55+
Stmt::AnnAssign(_) => {todo!()}
56+
Stmt::AsyncFor(_) => {todo!()}
57+
Stmt::With(_) => {todo!()}
58+
Stmt::AsyncWith(_) => {todo!()}
59+
Stmt::Match(_) => {todo!()}
60+
Stmt::Raise(_) => {todo!()}
61+
Stmt::Try(_) => {todo!()}
62+
Stmt::TryStar(_) => {todo!()}
63+
Stmt::Assert(_) => {todo!()}
64+
Stmt::Import(_) => {todo!()}
65+
Stmt::ImportFrom(_) => {todo!()}
66+
Stmt::Global(_) => {todo!()}
67+
Stmt::Nonlocal(_) => {todo!()}
68+
}
69+
}
70+
71+
(arena, 0)
72+
}
73+
74+
fn eval_return_stmt(stmt: StmtReturn, arena: &mut PyArena) -> Result<Option<PyObject>, PyException> {
75+
// for expr in stmt.
76+
if let Some(expr) = stmt.value {
77+
return eval_expr(*expr, arena);
2378
}
79+
Ok(None)
2480
}
2581

2682
fn eval_var<'a>(name: &str, arena: &'a PyArena) -> Result<&'a PyObject, PyException> {
@@ -167,7 +223,8 @@ fn eval_expr(expr: &Expr, arena: &mut PyArena) -> FuncReturnType {
167223

168224
fn eval_defn_var(variable: &Rc<Variable>, expr: &Expr, arena: &mut PyArena) -> EmptyFuncReturnType {
169225
let result = eval_expr(expr, arena)?;
170-
arena.get_current_frame_mut().set(variable, result);
226+
// arena.get_current_frame_mut().set(variable, result);
227+
arena.set(variable, result);
171228

172229
Ok(())
173230
}

src/main.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@
33
#![feature(hash_raw_entry)]
44
#![feature(get_mut_unchecked)]
55

6-
mod parser;
76
mod evaluator;
87
mod pyarena;
98
mod builtins;
10-
mod preprocessor;
9+
mod new_evaluator;
1110

1211
use std::env;
1312
use std::fs::File;
1413
use std::io::Read;
1514
use crate::evaluator::{evaluate};
16-
use crate::parser::{parse_code, remove_comments};
15+
use rustpython_parser::{lexer::{lex}, parse_tokens, Mode};
1716

1817
#[macro_use]
1918
extern crate mopa;
@@ -31,23 +30,29 @@ fn main() {
3130

3231
} else if args.len() > 2 {
3332
panic!("Expect 1 arg for the test file name, got: {}", args.len() - 1);
34-
} else {
35-
let filename = &args[1];
36-
let mut file = File::open("tests/".to_string() + filename).unwrap_or_else(|_| panic!("file not found: {}", filename));
37-
33+
}
34+
let filename = &args[1];
35+
let file_path = "tests/".to_string() + filename;
36+
let mut file = File::open(file_path.clone()).unwrap_or_else(|_| panic!("file not found: {}", filename));
37+
38+
{
3839
let _ = file.read_to_string(&mut contents);
3940
}
40-
let contents = remove_comments(&contents);
41-
let contents = contents.trim();
41+
// let contents = remove_comments(&contents);
42+
// let contents = contents.trim();
43+
44+
let tokens = lex(&contents, Mode::Module);
45+
let ast = parse_tokens(tokens, Mode::Module, &file_path);
4246

43-
let parse_tree = parse_code(contents);
44-
if let Ok(parse_tree) = parse_tree.0 {
47+
// let parse_tree = parse_code(contents);
48+
if let Ok(ast) = ast {
4549

46-
println!("{:?}", parse_tree);
50+
println!("{:?}", ast);
4751

48-
evaluate(parse_tree);
52+
evaluate(ast);
4953

50-
} else if let Err(parse_tree_err) = parse_tree.0 {
51-
println!("Char: \"{}\"({})\nError: {:?}", contents.chars().nth(parse_tree_err.location.offset).unwrap_or_default(), contents.bytes().nth(parse_tree_err.location.offset).unwrap_or_default(), parse_tree_err);
54+
} else if let Err(parse_error) = ast {
55+
// println!("Char: \"{}\"({})\nError: {:?}", contents.chars().nth(parse_tree_err.location.offset).unwrap_or_default(), contents.bytes().nth(parse_tree_err.location.offset).unwrap_or_default(), parse_tree_err);
56+
println!("{:?}", parse_error);
5257
}
5358
}

0 commit comments

Comments
 (0)