Skip to content

Commit 62cb3e2

Browse files
committed
Add slice object
1 parent b4e9064 commit 62cb3e2

File tree

8 files changed

+206
-95
lines changed

8 files changed

+206
-95
lines changed

parser/src/ast.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ pub enum Expression {
8181
op: Operator,
8282
b: Box<Expression>,
8383
},
84+
Compare {
85+
a: Box<Expression>,
86+
op: Comparison,
87+
b: Box<Expression>,
88+
},
8489
Call {
8590
function: Box<Expression>,
8691
args: Vec<Expression>,
@@ -120,4 +125,15 @@ pub enum Operator {
120125
BitXor,
121126
BitAnd,
122127
FloorDiv,
128+
129+
}
130+
131+
#[derive(Debug, PartialEq)]
132+
pub enum Comparison {
133+
Equal,
134+
NotEqual,
135+
Less,
136+
LessOrEqual,
137+
Greater,
138+
GreaterOrEqual,
123139
}

parser/src/python.lalrpop

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,19 @@ AndTest: ast::Expression = {
118118
};
119119

120120
NotTest: ast::Expression = {
121+
<e:Comparison> => e,
122+
};
123+
124+
Comparison: ast::Expression = {
125+
<e1:Comparison> <op:CompOp> <e2:Expression> => ast::Expression::Compare { a: Box::new(e1), op: op, b: Box::new(e2) },
121126
<e:Expression> => e,
122127
};
123128

129+
CompOp: ast::Comparison = {
130+
"==" => ast::Comparison::Equal,
131+
"!=" => ast::Comparison::NotEqual,
132+
};
133+
124134
Expression: ast::Expression = {
125135
<e1:Expression> "|" <e2:XorExpression> => ast::Expression::Binop { a: Box::new(e1), op: ast::Operator::BitOr, b: Box::new(e2) },
126136
<e:XorExpression> => e,
@@ -236,6 +246,8 @@ extern {
236246
"=" => lexer::Tok::Equal,
237247
"+=" => lexer::Tok::PlusEqual,
238248
"-=" => lexer::Tok::MinusEqual,
249+
"==" => lexer::Tok::EqEqual,
250+
"!=" => lexer::Tok::NotEqual,
239251
"assert" => lexer::Tok::Assert,
240252
"import" => lexer::Tok::Import,
241253
"break" => lexer::Tok::Break,

py_code_object/src/convert.rs

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,24 @@ impl Converter {
2828
}
2929

3030
pub fn convert(&mut self, code: PyCodeObject) {
31-
self.code = Some(code);
32-
for op_code in self.code.unwrap().co_code {
33-
self.dispatch(op_code);
31+
// self.code = Some(code);
32+
for op_code in &code.co_code {
33+
self.dispatch(&code, op_code);
3434
}
3535
}
3636

37-
fn dispatch(&mut self, op_code: (usize, String, Option<usize>)) {
37+
fn dispatch(&mut self, code: &PyCodeObject, op_code: &(usize, String, Option<usize>)) {
3838
debug!("Converting op code: {:?}", op_code);
3939
match (op_code.1.as_ref(), op_code.2) {
4040
("LOAD_CONST", Some(consti)) => {
4141
// println!("Loading const at index: {}", consti);
42-
let value = match self.code.unwrap().co_consts[consti] {
42+
let cons = &code.co_consts[consti];
43+
let value = match cons {
4344
// NativeType::Boolean { value } => { bytecode::Constant::Boolean { true } },
44-
// NativeType::Int { value } => { bytecode::Constant::Integer { value: value } },
45-
_ => { panic!("Not impl "); }
45+
NativeType::Int { 0: value } => { bytecode::Constant::Integer { value: *value } },
46+
NativeType::Str { 0: ref value } => { bytecode::Constant::String { value: value.clone() } }
47+
NativeType::NoneType => { bytecode::Constant::None }
48+
_ => { panic!("Not impl {:?}", cons); }
4649
};
4750
self.emit(bytecode::Instruction::LoadConst { value: value });
4851
},
@@ -56,12 +59,12 @@ impl Converter {
5659
},
5760
("STORE_NAME", Some(namei)) => {
5861
// println!("Loading const at index: {}", consti);
59-
let name = self.code.unwrap().co_names[namei].clone();
62+
let name = code.co_names[namei].clone();
6063
self.emit(bytecode::Instruction::StoreName { name });
6164
},
6265
("LOAD_NAME", Some(namei)) => {
6366
// println!("Loading const at index: {}", consti);
64-
let name = self.code.unwrap().co_names[namei].clone();
67+
let name = code.co_names[namei].clone();
6568
self.emit(bytecode::Instruction::LoadName { name });
6669
},
6770
("LOAD_GLOBAL", Some(namei)) => {
@@ -76,12 +79,10 @@ impl Converter {
7679
self.emit(bytecode::Instruction::BuildList { size: count });
7780
},
7881

79-
/*
8082
("BUILD_SLICE", Some(count)) => {
81-
let curr_frame = self.curr_frame();
8283
assert!(count == 2 || count == 3);
84+
self.emit(bytecode::Instruction::BuildSlice { size: count });
8385
},
84-
*/
8586

8687
("GET_ITER", None) => {
8788
self.emit(bytecode::Instruction::GetIter);
@@ -91,28 +92,28 @@ impl Converter {
9192
self.emit(bytecode::Instruction::ForIter);
9293
},
9394

94-
/*
9595
("COMPARE_OP", Some(cmp_op_i)) => {
96-
let curr_frame = self.curr_frame();
96+
let op = match cmp_op_i {
97+
0 => bytecode::ComparisonOperator::Less,
98+
1 => bytecode::ComparisonOperator::LessOrEqual,
99+
2 => bytecode::ComparisonOperator::Equal,
100+
3 => bytecode::ComparisonOperator::NotEqual,
101+
4 => bytecode::ComparisonOperator::Greater,
102+
5 => bytecode::ComparisonOperator::GreaterOrEqual,
103+
_ => { panic!("Not impl {:?}", cmp_op_i); }
104+
};
105+
self.emit(bytecode::Instruction::CompareOperation { op: op} );
97106
},
98107
("POP_JUMP_IF_TRUE", Some(ref target)) => {
99-
let curr_frame = self.curr_frame();
100-
let v = curr_frame.stack.pop().unwrap();
101-
if *v == NativeType::Boolean(true) {
102-
curr_frame.lasti = curr_frame.labels.get(target).unwrap().clone();
103-
}
104-
None
105-
108+
self.emit(bytecode::Instruction::JumpIf { target: *target} );
106109
}
110+
/*
107111
("POP_JUMP_IF_FALSE", Some(ref target)) => {
108-
let curr_frame = self.curr_frame();
109-
let v = curr_frame.stack.pop().unwrap();
110-
if *v == NativeType::Boolean(false) {
111-
curr_frame.lasti = curr_frame.labels.get(target).unwrap().clone();
112-
}
113-
None
114-
115-
}
112+
// Convert into two internal bytecodes:
113+
self.emit(bytecode::Instruction::UnaryOperation { op: bytecode::UnaryOperation::Not } );
114+
self.emit(bytecode::Instruction::JumpIf { target: target} );
115+
}*/
116+
/*
116117
("JUMP_FORWARD", Some(ref delta)) => {
117118
let curr_frame = self.curr_frame();
118119
let last_offset = curr_frame.get_bytecode_offset().unwrap();
@@ -129,16 +130,11 @@ impl Converter {
129130
self.unwind("break".to_string());
130131
None //?
131132
},
133+
*/
132134
("RAISE_VARARGS", Some(argc)) => {
133-
let curr_frame = self.curr_frame();
134-
// let (exception, params, traceback) = match argc {
135-
let exception = match argc {
136-
1 => curr_frame.stack.pop().unwrap(),
137-
0 | 2 | 3 => panic!("Not implemented!"),
138-
_ => panic!("Invalid paramter for RAISE_VARARGS, must be between 0 to 3")
139-
};
140-
panic!("{:?}", exception);
135+
self.emit(bytecode::Instruction::Raise { argc: argc });
141136
}
137+
/*
142138
("INPLACE_ADD", None) => {
143139
self.emit(bytecode::Instruction::BinaryOperation { op: BinaryOperator::Add });
144140
},
@@ -179,12 +175,12 @@ impl Converter {
179175
("BINARY_SUBTRACT", None) => {
180176
self.emit(bytecode::Instruction::BinaryOperation { op: bytecode::BinaryOperator::Subtract });
181177
},
182-
183-
/*
178+
("BINARY_SUBSCR", None) => {
179+
self.emit(bytecode::Instruction::BinaryOperation { op: bytecode::BinaryOperator::Subscript });
180+
},
184181
("ROT_TWO", None) => {
185-
// TODO: self.emit(Instruction::BinaryOperation { op: bytecode::BinaryOperator::RotTwo });
182+
self.emit(bytecode::Instruction::Rotate { amount: 2 });
186183
}
187-
*/
188184
("UNARY_NEGATIVE", None) => {
189185
self.emit(bytecode::Instruction::UnaryOperation { op: bytecode::UnaryOperator::Minus });
190186
},
@@ -210,14 +206,10 @@ impl Converter {
210206
let pos_count = (argc & 0xFF) as usize;
211207
self.emit(bytecode::Instruction::CallFunction { count: pos_count });
212208
},
213-
/*
214209
("RETURN_VALUE", None) => {
215-
// Hmmm... what is this used?
216-
// I believe we need to push this to the next frame
217-
self.curr_frame().return_value = (*self.curr_frame().stack.pop().unwrap()).clone();
218-
Some("return".to_string())
219-
self.emit(bytecode::Instruction::CallFunction { });
210+
self.emit(bytecode::Instruction::ReturnValue);
220211
},
212+
/*
221213
("SETUP_LOOP", Some(delta)) => {
222214
let curr_frame = self.curr_frame();
223215
let curr_offset = curr_frame.get_bytecode_offset().unwrap();

py_code_object/test_snippets.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414

1515

1616
logger = logging.getLogger('tests')
17-
TEST_DIR = os.path.abspath(os.path.join('..', 'tests'))
18-
CPYTHON_RUNNER_DIR = os.path.abspath(os.path.join('..', 'vm', 'RustPython'))
17+
THIS_DIR = '.'
18+
TEST_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', 'tests'))
19+
CPYTHON_RUNNER_DIR = os.path.abspath(os.path.join(THIS_DIR))
1920

2021

2122
@contextlib.contextmanager
@@ -34,8 +35,11 @@ def perform_test(filename):
3435
compile_code.compile_to_bytecode(filename, out_file=f)
3536

3637
# Step2: run cpython bytecode:
38+
env = os.environ.copy()
39+
env['RUST_LOG'] = 'debug'
40+
env['RUST_BACKTRACE'] = '1'
3741
with pushd(CPYTHON_RUNNER_DIR):
38-
subprocess.check_call(['cargo', 'run', bytecode_filename])
42+
subprocess.check_call(['cargo', 'run', bytecode_filename], env=env)
3943

4044

4145
def create_test_function(cls, filename):

src/compile.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,21 @@ impl Compiler {
235235
let i = Instruction::BinaryOperation { op: i };
236236
self.emit(i);
237237
}
238+
ast::Expression::Compare { a, op, b } => {
239+
self.compile_expression(*a);
240+
self.compile_expression(*b);
241+
242+
let i = match op {
243+
ast::Comparison::Equal => bytecode::ComparisonOperator::Equal,
244+
ast::Comparison::NotEqual => bytecode::ComparisonOperator::NotEqual,
245+
ast::Comparison::Less => bytecode::ComparisonOperator::Less,
246+
ast::Comparison::LessOrEqual => bytecode::ComparisonOperator::LessOrEqual,
247+
ast::Comparison::Greater => bytecode::ComparisonOperator::Greater,
248+
ast::Comparison::GreaterOrEqual => bytecode::ComparisonOperator::GreaterOrEqual,
249+
};
250+
let i = Instruction::CompareOperation { op: i };
251+
self.emit(i);
252+
}
238253
ast::Expression::Number { value } => {
239254
self.emit(Instruction::LoadConst { value: bytecode::Constant::Integer { value: value } });
240255
}

vm/src/bytecode.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ pub enum Instruction {
3636
LoadConst { value: Constant },
3737
UnaryOperation { op: UnaryOperator },
3838
BinaryOperation { op: BinaryOperator },
39+
CompareOperation { op: ComparisonOperator },
3940
Pop,
41+
Rotate { amount: usize },
42+
Duplicate,
4043
GetIter,
4144
Pass,
4245
Continue,
@@ -49,9 +52,11 @@ pub enum Instruction {
4952
ReturnValue,
5053
PushBlock { start: Label, end: Label },
5154
PopBlock,
55+
Raise { argc: usize },
5256
BuildTuple { size: usize },
5357
BuildList { size: usize },
5458
BuildMap { size: usize },
59+
BuildSlice { size: usize },
5560
}
5661

5762
#[derive(Debug, Clone)]
@@ -62,6 +67,20 @@ pub enum Constant {
6267
None,
6368
}
6469

70+
#[derive(Debug, Clone)]
71+
pub enum ComparisonOperator {
72+
Greater,
73+
GreaterOrEqual,
74+
Less,
75+
LessOrEqual,
76+
Equal,
77+
NotEqual,
78+
In,
79+
NotIn,
80+
Is,
81+
NotIs,
82+
}
83+
6584
#[derive(Debug, Clone)]
6685
pub enum BinaryOperator {
6786
Power,
@@ -72,6 +91,7 @@ pub enum BinaryOperator {
7291
Modulo,
7392
Add,
7493
Subtract,
94+
Subscript,
7595
Lshift,
7696
Rshift,
7797
And,
@@ -82,6 +102,7 @@ pub enum BinaryOperator {
82102
#[derive(Debug, Clone)]
83103
pub enum UnaryOperator {
84104
Not,
105+
Invert,
85106
Minus,
86107
Plus,
87108
}

vm/src/pyobject.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ pub enum PyObject {
3939
position: usize,
4040
iterated_obj: PyObjectRef,
4141
},
42+
Slice {
43+
elements: Vec<PyObjectRef>,
44+
},
4245
Code {
4346
code: bytecode::CodeObject,
4447
},

0 commit comments

Comments
 (0)