Skip to content

Commit e9e250b

Browse files
committed
finally got the right codegen for the stack interpreter
1 parent f17e0c3 commit e9e250b

2 files changed

Lines changed: 74 additions & 84 deletions

File tree

geth-eventql/src/codegen.rs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use crate::{
2-
Expr, ExprVisitor, Literal, NodeAttributes, Operation, Query, QueryVisitor, Subject, Var,
3-
};
1+
use crate::{Expr, ExprVisitor, Literal, NodeAttributes, Operation, Var, Where};
42

53
pub trait IntoLiteral {
64
fn into_literal(self) -> Literal;
@@ -42,13 +40,19 @@ impl IntoLiteral for usize {
4240
}
4341
}
4442

43+
impl IntoLiteral for Literal {
44+
fn into_literal(self) -> Literal {
45+
self
46+
}
47+
}
48+
4549
pub enum Instr {
4650
Push(Literal),
4751
LoadVar(Var),
4852
Operation(Operation),
4953
Array(usize),
5054
Rec(usize),
51-
Call(String, usize),
55+
Call(String),
5256
}
5357

5458
impl Instr {
@@ -62,7 +66,7 @@ pub fn codegen_where_clause(where_clause: &Where) -> Vec<Instr> {
6266

6367
where_clause.expr.dfs_post_order(&mut state);
6468

65-
state.emit
69+
state.emit.inner
6670
}
6771

6872
#[derive(Default)]
@@ -71,7 +75,10 @@ struct Emit {
7175
}
7276

7377
impl Emit {
74-
fn push(&mut self, lit: impl IntoLiteral) {
78+
fn push<L>(&mut self, lit: L)
79+
where
80+
L: IntoLiteral,
81+
{
7582
self.inner.push(Instr::lit(lit));
7683
}
7784

@@ -82,6 +89,18 @@ impl Emit {
8289
fn rec(&mut self, siz: usize) {
8390
self.inner.push(Instr::Rec(siz));
8491
}
92+
93+
fn array(&mut self, siz: usize) {
94+
self.inner.push(Instr::Array(siz));
95+
}
96+
97+
fn call(&mut self, name: &str) {
98+
self.inner.push(Instr::Call(name.to_string()));
99+
}
100+
101+
fn op(&mut self, op: Operation) {
102+
self.inner.push(Instr::Operation(op));
103+
}
85104
}
86105

87106
#[derive(Default)]
@@ -99,13 +118,19 @@ impl ExprVisitor for ExprCodegen {
99118
}
100119

101120
fn exit_array(&mut self, _attrs: &NodeAttributes, values: &[Expr]) {
102-
self.emit.push(Instr::lit(values.len()));
103-
self.emit.push(Instr::Array);
121+
self.emit.array(values.len());
122+
}
123+
124+
fn exit_field(&mut self, _attrs: &NodeAttributes, label: &str, _value: &Expr) {
125+
self.emit.push(label);
126+
}
127+
128+
fn exit_record(&mut self, _attrs: &NodeAttributes, record: &[Expr]) {
129+
self.emit.rec(record.len());
104130
}
105131

106132
fn exit_app(&mut self, _attrs: &NodeAttributes, name: &str, _params: &[Expr]) {
107-
self.emit.push(Instr::lit(name));
108-
self.emit.push(Instr::Call);
133+
self.emit.call(name);
109134
}
110135

111136
fn exit_binary_op(
@@ -115,10 +140,10 @@ impl ExprVisitor for ExprCodegen {
115140
_lhs: &Expr,
116141
_rhs: &Expr,
117142
) {
118-
self.emit.push(Instr::Operation(*op));
143+
self.emit.op(*op);
119144
}
120145

121146
fn exit_unary_op(&mut self, _attrs: &NodeAttributes, op: &Operation, _expr: &Expr) {
122-
self.emit.push(Instr::Operation(*op));
147+
self.emit.op(*op);
123148
}
124149
}

geth-eventql/src/eval.rs

Lines changed: 37 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,6 @@ impl Stack {
7474
}
7575
}
7676

77-
fn pop_as_integral_or_bail(&mut self) -> Result<i64> {
78-
if let Either::Left(int) = self.pop_as_number_or_bail()? {
79-
return Ok(int);
80-
}
81-
82-
Err(EvalError::UnexpectedRuntimeError)
83-
}
84-
8577
fn pop_as_bool_or_bail(&mut self) -> Result<bool> {
8678
match self.pop_as_literal_or_bail()? {
8779
Literal::Bool(b) => Ok(b),
@@ -97,22 +89,6 @@ impl Stack {
9789
Err(EvalError::UnexpectedRuntimeError)
9890
}
9991

100-
fn pop_as_array_of_strings_or_bail(&mut self) -> Result<Vec<String>> {
101-
let vec_of_items = self.pop_as_array_or_bail()?;
102-
let mut result = Vec::with_capacity(vec_of_items.len());
103-
104-
for item in vec_of_items {
105-
if let Item::Literal(Literal::String(s)) = item {
106-
result.push(s);
107-
continue;
108-
}
109-
110-
return Err(EvalError::UnexpectedRuntimeError);
111-
}
112-
113-
Ok(result)
114-
}
115-
11692
fn push_literal(&mut self, lit: Literal) {
11793
self.inner.push(Item::Literal(lit));
11894
}
@@ -133,11 +109,7 @@ pub fn eval_where_clause(dict: &Dictionary, instrs: Vec<Instr>) -> Result<bool>
133109
match instr {
134110
Instr::Push(lit) => stack.push_literal(lit),
135111

136-
Instr::LoadVar => {
137-
let name = stack.pop_as_string_or_bail()?;
138-
let path = stack.pop_as_array_of_strings_or_bail()?;
139-
let var = Var { name, path };
140-
112+
Instr::LoadVar(var) => {
141113
stack.push_literal(dict.lookup(&var)?);
142114
}
143115

@@ -469,8 +441,7 @@ pub fn eval_where_clause(dict: &Dictionary, instrs: Vec<Instr>) -> Result<bool>
469441
}
470442
},
471443

472-
Instr::Array => {
473-
let siz = stack.pop_as_integral_or_bail()? as usize;
444+
Instr::Array(siz) => {
474445
let mut array = Vec::with_capacity(siz);
475446

476447
for _ in 0..siz {
@@ -480,58 +451,52 @@ pub fn eval_where_clause(dict: &Dictionary, instrs: Vec<Instr>) -> Result<bool>
480451
stack.push_array(array);
481452
}
482453

483-
Instr::Rec => {
484-
let siz = stack.pop_as_integral_or_bail()? as usize;
454+
Instr::Rec(siz) => {
485455
let mut fields = HashMap::with_capacity(siz);
486456

487-
todo!("the keys come first now, then the values");
488457
for _ in 0..siz {
489-
let value = stack.pop_or_bail()?;
490458
let key = stack.pop_as_string_or_bail()?;
459+
let value = stack.pop_or_bail()?;
491460

492461
fields.insert(key, value);
493462
}
494463

495464
stack.push_record(Rec { fields });
496465
}
497466

498-
Instr::Call => {
499-
let fun_name = stack.pop_as_string_or_bail()?;
500-
501-
match fun_name.as_str() {
502-
"abs" => match stack.pop_as_number_or_bail()? {
503-
Either::Left(i) => stack.push_literal(Literal::Integral(i.abs())),
504-
Either::Right(f) => stack.push_literal(Literal::Float(f.abs())),
505-
},
506-
507-
"ceil" => match stack.pop_as_number_or_bail()? {
508-
Either::Left(i) => stack.push_literal(Literal::Integral(i)),
509-
Either::Right(f) => stack.push_literal(Literal::Float(f.ceil())),
510-
},
511-
512-
"floor" => match stack.pop_as_number_or_bail()? {
513-
Either::Left(i) => stack.push_literal(Literal::Integral(i)),
514-
Either::Right(f) => stack.push_literal(Literal::Float(f.floor())),
515-
},
516-
517-
"sin" => match stack.pop_as_number_or_bail()? {
518-
Either::Left(i) => stack.push_literal(Literal::Float((i as f64).sin())),
519-
Either::Right(f) => stack.push_literal(Literal::Float(f.sin())),
520-
},
521-
522-
"cos" => match stack.pop_as_number_or_bail()? {
523-
Either::Left(i) => stack.push_literal(Literal::Float((i as f64).cos())),
524-
Either::Right(f) => stack.push_literal(Literal::Float(f.cos())),
525-
},
526-
527-
"tan" => match stack.pop_as_number_or_bail()? {
528-
Either::Left(i) => stack.push_literal(Literal::Float((i as f64).tan())),
529-
Either::Right(f) => stack.push_literal(Literal::Float(f.tan())),
530-
},
531-
532-
_ => return Err(EvalError::UnexpectedRuntimeError),
533-
}
534-
}
467+
Instr::Call(fun_name) => match fun_name.as_str() {
468+
"abs" => match stack.pop_as_number_or_bail()? {
469+
Either::Left(i) => stack.push_literal(Literal::Integral(i.abs())),
470+
Either::Right(f) => stack.push_literal(Literal::Float(f.abs())),
471+
},
472+
473+
"ceil" => match stack.pop_as_number_or_bail()? {
474+
Either::Left(i) => stack.push_literal(Literal::Integral(i)),
475+
Either::Right(f) => stack.push_literal(Literal::Float(f.ceil())),
476+
},
477+
478+
"floor" => match stack.pop_as_number_or_bail()? {
479+
Either::Left(i) => stack.push_literal(Literal::Integral(i)),
480+
Either::Right(f) => stack.push_literal(Literal::Float(f.floor())),
481+
},
482+
483+
"sin" => match stack.pop_as_number_or_bail()? {
484+
Either::Left(i) => stack.push_literal(Literal::Float((i as f64).sin())),
485+
Either::Right(f) => stack.push_literal(Literal::Float(f.sin())),
486+
},
487+
488+
"cos" => match stack.pop_as_number_or_bail()? {
489+
Either::Left(i) => stack.push_literal(Literal::Float((i as f64).cos())),
490+
Either::Right(f) => stack.push_literal(Literal::Float(f.cos())),
491+
},
492+
493+
"tan" => match stack.pop_as_number_or_bail()? {
494+
Either::Left(i) => stack.push_literal(Literal::Float((i as f64).tan())),
495+
Either::Right(f) => stack.push_literal(Literal::Float(f.tan())),
496+
},
497+
498+
_ => return Err(EvalError::UnexpectedRuntimeError),
499+
},
535500
}
536501
}
537502

0 commit comments

Comments
 (0)