11use crate :: {
2- Expr , ExprVisitor , Literal , NodeAttributes , Operation , Query , QueryVisitor , Var , parser:: Record ,
2+ Expr , ExprVisitor , Literal , NodeAttributes , Operation , Query , QueryVisitor , Subject , Var ,
3+ parser:: Record ,
34} ;
45
6+ trait IntoLiteral {
7+ fn into_literal ( self ) -> Literal ;
8+ }
9+
10+ impl IntoLiteral for String {
11+ fn into_literal ( self ) -> Literal {
12+ Literal :: String ( self )
13+ }
14+ }
15+
16+ impl IntoLiteral for & ' _ str {
17+ fn into_literal ( self ) -> Literal {
18+ Literal :: String ( self . to_string ( ) )
19+ }
20+ }
21+
22+ impl IntoLiteral for & ' _ String {
23+ fn into_literal ( self ) -> Literal {
24+ Literal :: String ( self . to_string ( ) )
25+ }
26+ }
27+
28+ impl IntoLiteral for u64 {
29+ fn into_literal ( self ) -> Literal {
30+ Literal :: Integral ( self as i64 )
31+ }
32+ }
33+
34+ impl IntoLiteral for i64 {
35+ fn into_literal ( self ) -> Literal {
36+ Literal :: Integral ( self )
37+ }
38+ }
39+
40+ impl IntoLiteral for usize {
41+ fn into_literal ( self ) -> Literal {
42+ Literal :: Integral ( self as i64 )
43+ }
44+ }
45+
546pub enum Instr {
47+ EnterScope ,
48+ ExitScope ,
649 Push ( Literal ) ,
7- LoadVar ( Var ) ,
50+ EnterSource ,
51+ ExitSource ,
52+ LoadVar ,
53+ LoadSource ,
854 Operation ( Operation ) ,
9- Array ( usize ) ,
55+ Array ,
1056 Rec ( usize ) ,
1157 Call ( String ) ,
1258}
1359
60+ impl Instr {
61+ pub fn push ( value : impl IntoLiteral ) -> Self {
62+ Instr :: Push ( value. into_literal ( ) )
63+ }
64+ }
65+
66+ pub enum SourceKind {
67+ Events ,
68+ Subject ,
69+ Subquery ,
70+ }
71+
72+ pub struct LoadSource {
73+ binding : String ,
74+ scope : u64 ,
75+ }
76+
1477pub fn codegen ( query : & Query ) -> Vec < Instr > {
1578 let mut state = Codegen :: default ( ) ;
1679
@@ -27,6 +90,54 @@ pub struct Codegen {
2790impl QueryVisitor for Codegen {
2891 type Inner < ' a > = ExprCodegen < ' a > ;
2992
93+ fn enter_query ( & mut self , attrs : & NodeAttributes ) {
94+ self . instrs . push ( Instr :: push ( attrs. scope ) ) ;
95+ self . instrs . push ( Instr :: EnterScope ) ;
96+ }
97+
98+ fn enter_from ( & mut self , attrs : & NodeAttributes , _ident : & str ) {
99+ self . instrs . push ( Instr :: push ( attrs. scope ) ) ;
100+ self . instrs . push ( Instr :: EnterSource ) ;
101+ }
102+
103+ fn on_source_events ( & mut self , attrs : & NodeAttributes , ident : & str ) {
104+ self . instrs . push ( Instr :: push ( attrs. scope ) ) ;
105+ self . instrs . push ( Instr :: push ( ident) ) ;
106+ self . instrs . push ( Instr :: push ( 0i64 ) ) ;
107+ self . instrs . push ( Instr :: LoadSource ) ;
108+ }
109+
110+ fn on_source_subject ( & mut self , attrs : & NodeAttributes , ident : & str , subject : & Subject ) {
111+ self . instrs . push ( Instr :: push ( attrs. scope ) ) ;
112+ self . instrs . push ( Instr :: push ( ident) ) ;
113+ for seg in subject. inner . iter ( ) {
114+ self . instrs . push ( Instr :: push ( seg) ) ;
115+ }
116+
117+ self . instrs . push ( Instr :: push ( subject. inner . len ( ) ) ) ;
118+ self . instrs . push ( Instr :: Array ) ;
119+ self . instrs . push ( Instr :: push ( 1i64 ) ) ;
120+ self . instrs . push ( Instr :: LoadSource ) ;
121+ }
122+
123+ fn on_source_subquery ( & mut self , attrs : & NodeAttributes , ident : & str ) -> bool {
124+ self . instrs . push ( Instr :: push ( attrs. scope ) ) ;
125+ self . instrs . push ( Instr :: push ( ident) ) ;
126+ self . instrs . push ( Instr :: push ( 2i64 ) ) ;
127+ self . instrs . push ( Instr :: LoadSource ) ;
128+
129+ true
130+ }
131+
132+ fn exit_from ( & mut self , attrs : & NodeAttributes , ident : & str ) {
133+ self . instrs . push ( Instr :: push ( attrs. scope ) ) ;
134+ self . instrs . push ( Instr :: ExitSource ) ;
135+ }
136+
137+ fn exit_query ( & mut self ) {
138+ self . instrs . push ( Instr :: ExitScope ) ;
139+ }
140+
30141 fn expr_visitor < ' a > ( & ' a mut self ) -> Self :: Inner < ' a > {
31142 ExprCodegen { inner : self }
32143 }
@@ -41,8 +152,17 @@ impl ExprVisitor for ExprCodegen<'_> {
41152 self . inner . instrs . push ( Instr :: Push ( lit. clone ( ) ) ) ;
42153 }
43154
44- fn on_var ( & mut self , _attrs : & NodeAttributes , var : & Var ) {
45- self . inner . instrs . push ( Instr :: LoadVar ( var. clone ( ) ) ) ;
155+ fn on_var ( & mut self , attrs : & NodeAttributes , var : & Var ) {
156+ self . inner . instrs . push ( Instr :: push ( attrs. scope ) ) ;
157+
158+ self . inner . instrs . push ( Instr :: push ( var. name . as_str ( ) ) ) ;
159+ for seg in & var. path {
160+ self . inner . instrs . push ( Instr :: push ( seg) ) ;
161+ }
162+
163+ self . inner . instrs . push ( Instr :: push ( var. path . len ( ) + 1 ) ) ;
164+ self . inner . instrs . push ( Instr :: Array ) ;
165+ self . inner . instrs . push ( Instr :: LoadVar ) ;
46166 }
47167
48168 fn enter_record_entry ( & mut self , _attrs : & NodeAttributes , key : & str , _expr : & Expr ) {
@@ -56,7 +176,8 @@ impl ExprVisitor for ExprCodegen<'_> {
56176 }
57177
58178 fn exit_array ( & mut self , _attrs : & NodeAttributes , values : & [ Expr ] ) {
59- self . inner . instrs . push ( Instr :: Array ( values. len ( ) ) ) ;
179+ self . inner . instrs . push ( Instr :: push ( values. len ( ) ) ) ;
180+ self . inner . instrs . push ( Instr :: Array ) ;
60181 }
61182
62183 fn exit_app ( & mut self , _attrs : & NodeAttributes , name : & str , _params : & [ Expr ] ) {
0 commit comments