Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions geth-eventql/src/codegen.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::{
Expr, ExprVisitor, Literal, NodeAttributes, Operation, Query, QueryVisitor, Var, parser::Record,
};
use crate::{Expr, ExprVisitor, Literal, NodeAttributes, Operation, Query, QueryVisitor, Var};

pub enum Instr {
Push(Literal),
Expand Down Expand Up @@ -45,14 +43,8 @@ impl ExprVisitor for ExprCodegen<'_> {
self.inner.instrs.push(Instr::LoadVar(var.clone()));
}

fn enter_record_entry(&mut self, _attrs: &NodeAttributes, key: &str, _expr: &Expr) {
self.inner
.instrs
.push(Instr::Push(Literal::String(key.to_string())));
}

fn exit_record(&mut self, _attrs: &NodeAttributes, record: &Record) {
self.inner.instrs.push(Instr::Rec(record.fields.len()));
fn exit_record(&mut self, _attrs: &NodeAttributes, record: &[Expr]) {
self.inner.instrs.push(Instr::Rec(record.len()));
}

fn exit_array(&mut self, _attrs: &NodeAttributes, values: &[Expr]) {
Expand Down
4 changes: 2 additions & 2 deletions geth-eventql/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashMap, fmt::Display};
use crate::{
Expr, Literal, Operation, Pos, Query, Scopes, Var,
error::InferError,
parser::{ExprVisitorMut, NodeAttributes, QueryVisitorMut, Record},
parser::{ExprVisitorMut, NodeAttributes, QueryVisitorMut},
};

pub struct InferedQuery {
Expand Down Expand Up @@ -238,7 +238,7 @@ impl ExprVisitorMut for TypecheckExpr<'_> {
fn exit_record(
&mut self,
attrs: &mut NodeAttributes,
_record: &mut Record,
_record: &mut [Expr],
) -> crate::Result<()> {
if attrs.tpe != Type::Unspecified && attrs.tpe != Type::Record {
bail!(attrs.pos, InferError::TypeMismatch(attrs.tpe, Type::Record));
Expand Down
106 changes: 78 additions & 28 deletions geth-eventql/src/parser/ast.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::BTreeMap, fmt::Display, ptr::NonNull};
use std::{fmt::Display, ptr::NonNull};

use crate::{
Pos, Type,
Expand Down Expand Up @@ -313,9 +313,9 @@ impl Expr {
None
}

pub fn as_record(&self) -> Option<&Record> {
if let Value::Record(r) = &self.value {
return Some(r);
pub fn as_record(&self) -> Option<Rec<'_>> {
if let Value::Record(inner) = &self.value {
return Some(Rec { inner });
}

None
Expand Down Expand Up @@ -344,6 +344,18 @@ impl Expr {
visitor.on_var(&mut node.attrs, var)?;
}

Value::Field { label, value } => {
if item.visited {
visitor.exit_field(&mut node.attrs, label.as_mut_str(), value.as_mut())?;
continue;
}

item.visited = true;
visitor.enter_field(&mut node.attrs, label.as_mut_str(), value.as_mut())?;
stack.push(item);
stack.push(ItemMut::new(value.as_mut()));
}

Value::Record(record) => {
if item.visited {
visitor.exit_record(&mut node.attrs, record)?;
Expand All @@ -354,8 +366,7 @@ impl Expr {
visitor.enter_record(&mut node.attrs, record)?;
stack.push(item);

for (key, expr) in record.fields.iter_mut() {
visitor.enter_record_entry(&mut node.attrs, key, expr)?;
for expr in record.iter_mut().rev() {
stack.push(ItemMut::new(expr));
}
}
Expand Down Expand Up @@ -433,6 +444,18 @@ impl Expr {
visitor.on_var(&item.value.attrs, var);
}

Value::Field { label, value } => {
if item.visited {
visitor.exit_field(&item.value.attrs, label.as_str(), value);
continue;
}

item.visited = true;
visitor.enter_field(&item.value.attrs, label.as_str(), value);
stack.push(item);
stack.push(Item::new(value));
}

Value::Record(record) => {
if item.visited {
visitor.exit_record(&item.value.attrs, record);
Expand All @@ -441,11 +464,9 @@ impl Expr {

item.visited = true;
visitor.enter_record(&item.value.attrs, record);
let attrs = &item.value.attrs;
stack.push(item);

for (key, expr) in record.fields.iter() {
visitor.enter_record_entry(attrs, key, expr);
for expr in record.iter().rev() {
stack.push(Item::new(expr));
}
}
Expand Down Expand Up @@ -548,6 +569,24 @@ pub struct UnaryOp<'a> {
pub expr: &'a Expr,
}

pub struct Rec<'a> {
inner: &'a Vec<Expr>,
}

impl Rec<'_> {
pub fn get(&self, id: &str) -> Option<&Expr> {
for expr in self.inner.iter() {
if let Value::Field { label, value } = &expr.value
&& label == id
{
return Some(value);
}
}

None
}
}

pub struct ApplyFun<'a> {
pub name: &'a String,
pub params: &'a Vec<Expr>,
Expand All @@ -573,34 +612,35 @@ impl Display for Var {

pub enum Value {
Literal(Literal),

Var(Var),
Record(Record),

Field {
label: String,
value: Box<Expr>,
},

Record(Vec<Expr>),

Array(Vec<Expr>),

App {
fun: String,
params: Vec<Expr>,
},

Binary {
lhs: Box<Expr>,
op: Operation,
rhs: Box<Expr>,
},

Unary {
op: Operation,
expr: Box<Expr>,
},
}

pub struct Record {
pub fields: BTreeMap<String, Expr>,
}

impl Record {
pub fn get(&self, id: &str) -> Option<&Expr> {
self.fields.get(id)
}
}

pub struct Sort {
pub expr: Expr,
pub order: Order,
Expand Down Expand Up @@ -746,24 +786,33 @@ pub trait ExprVisitorMut {
fn enter_record(
&mut self,
attrs: &mut NodeAttributes,
record: &mut Record,
record: &mut [Expr],
) -> crate::Result<()> {
Ok(())
}

fn enter_record_entry(
fn enter_field(
&mut self,
attrs: &mut NodeAttributes,
key: &str,
expr: &mut Expr,
label: &mut str,
value: &mut Expr,
) -> crate::Result<()> {
Ok(())
}

fn exit_field(
&mut self,
attrs: &mut NodeAttributes,
label: &mut str,
value: &mut Expr,
) -> crate::Result<()> {
Ok(())
}

fn exit_record(
&mut self,
attrs: &mut NodeAttributes,
record: &mut Record,
record: &mut [Expr],
) -> crate::Result<()> {
Ok(())
}
Expand Down Expand Up @@ -872,9 +921,10 @@ pub trait QueryVisitor {
pub trait ExprVisitor {
fn on_literal(&mut self, attrs: &NodeAttributes, lit: &Literal) {}
fn on_var(&mut self, attrs: &NodeAttributes, var: &Var) {}
fn enter_record(&mut self, attrs: &NodeAttributes, record: &Record) {}
fn enter_record_entry(&mut self, attrs: &NodeAttributes, key: &str, expr: &Expr) {}
fn exit_record(&mut self, attrs: &NodeAttributes, record: &Record) {}
fn enter_record(&mut self, attrs: &NodeAttributes, record: &[Expr]) {}
fn enter_field(&mut self, attrs: &NodeAttributes, label: &str, value: &Expr) {}
fn exit_field(&mut self, attrs: &NodeAttributes, label: &str, value: &Expr) {}
fn exit_record(&mut self, attrs: &NodeAttributes, record: &[Expr]) {}
fn enter_array(&mut self, attrs: &NodeAttributes, values: &[Expr]) {}
fn exit_array(&mut self, attrs: &NodeAttributes, values: &[Expr]) {}
fn enter_app(&mut self, attrs: &NodeAttributes, name: &str, params: &[Expr]) {}
Expand Down
16 changes: 11 additions & 5 deletions geth-eventql/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::{
sym::{Keyword, Literal, Sym},
tokenizer::{Lexer, Pos},
};
use std::collections::BTreeMap;

mod ast;
mod state;
Expand Down Expand Up @@ -406,15 +405,22 @@ fn parse_expr_single(state: &mut ParserState<'_>) -> crate::Result<Expr> {
Sym::LBrace => {
state.skip_whitespace()?;

let mut fields = BTreeMap::new();
let mut fields = Vec::new();

while let Some(Sym::Id(id)) = state.look_ahead()? {
let id = id.clone();
let label = id.clone();
let label_pos = state.pos();
state.shift()?;
state.skip_whitespace()?;
state.expect(Sym::Colon)?;
state.skip_whitespace()?;
fields.insert(id, parse_expr_single(state)?);
fields.push(Expr {
attrs: NodeAttributes::new(label_pos),
value: Value::Field {
label,
value: Box::new(parse_expr_single(state)?),
},
});
state.skip_whitespace()?;

if let Some(Sym::Comma) = state.look_ahead()? {
Expand All @@ -430,7 +436,7 @@ fn parse_expr_single(state: &mut ParserState<'_>) -> crate::Result<Expr> {

Ok(Expr {
attrs: NodeAttributes::new(pos),
value: Value::Record(Record { fields }),
value: Value::Record(fields),
})
}

Expand Down
14 changes: 12 additions & 2 deletions geth-eventql/src/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{
use crate::{
Expr, Literal, Query, Value, Var,
error::RenameError,
parser::{ExprVisitorMut, NodeAttributes, QueryVisitorMut, Record, parse_subject},
parser::{ExprVisitorMut, NodeAttributes, QueryVisitorMut, parse_subject},
};

pub fn rename(query: &mut Query) -> crate::Result<Scopes> {
Expand Down Expand Up @@ -160,10 +160,20 @@ impl ExprVisitorMut for RenameExpr<'_> {
Ok(())
}

fn exit_field(
&mut self,
attrs: &mut NodeAttributes,
_label: &mut str,
value: &mut Expr,
) -> crate::Result<()> {
attrs.scope = value.attrs.scope;
Ok(())
}

fn exit_record(
&mut self,
attrs: &mut NodeAttributes,
_record: &mut Record,
_record: &mut [Expr],
) -> crate::Result<()> {
attrs.scope = self.inner.scope_id();

Expand Down
Loading