@@ -7,7 +7,7 @@ use pest::Parser;
77use pest_derive:: Parser ;
88use pest:: pratt_parser:: PrattParser ;
99use pest:: iterators:: Pairs ;
10- use std:: fmt;
10+ use std:: { fmt, process :: id , vec } ;
1111use baa:: BitVecValue ;
1212
1313use crate :: { ir:: * } ;
@@ -29,41 +29,63 @@ lazy_static::lazy_static! {
2929 } ;
3030}
3131
32- // pub fn parse_expr(pairs: Pairs<Rule>) -> Expr {
33- // PRATT_PARSER
34- // .map_primary(|primary| match primary.as_rule() {
35- // Rule::integer => {
36- // let int_str = primary.as_str();
37- // let int_value = int_str.parse::<i32>().unwrap();
38- // // FIXME: Is this the correct way to convert?
39- // let bitvec = BitVecValue::from_u64(int_value as u64, 32);
40- // Expr::Const(bitvec)
41- // }
42- // // if primary is an expression (due to parens), recursively parse its inner constituents
43- // Rule::expr => parse_expr(primary.into_inner()),
44- // rule => unreachable!("Expr::parse expected atom, found {:?}", rule)
45- // })
46- // .map_infix(|lhs, op, rhs| {
47- // let op = match op.as_rule() {
48- // Rule::eq => BinOp::Equal,
49- // Rule::log_and => BinOp::And,
50- // rule => unreachable!("Expr::parse expected infix operation, found {:?}", rule),
51- // };
52- // Expr::Binary {
53- // op,
54- // lhs: lhs.
55- // rhs: Box::new(rhs),
56- // }
57- // })
58- // .map_prefix(|op, arg| {
59- // let op = match op.as_rule() {
60- // Rule::negate => UnaryOperator::Negate,
61- // rule => unreachable!("Expr::parse expected prefix operation, found {:?}", rule),
62- // };
63- // Expr::UnaryOp {arg: Box::new(arg) , op: op }
64- // })
65- // .parse(pairs)
66- // }
32+ pub fn parse_expr ( pairs : Pairs < Rule > , tr : & mut Transaction , st : & mut SymbolTable ) -> ExprId {
33+ PRATT_PARSER
34+ . map_primary ( |primary| match primary. as_rule ( ) {
35+
36+ // parse integer literals
37+ Rule :: integer => {
38+ let int_str = primary. as_str ( ) ;
39+ let int_value = int_str. parse :: < i32 > ( ) . unwrap ( ) ;
40+ // FIXME: Is this the correct way to convert?
41+ let bitvec = BitVecValue :: from_u64 ( int_value as u64 , 32 ) ;
42+ tr. e ( Expr :: Const ( bitvec) )
43+ }
44+
45+ // parse path identifiers
46+ Rule :: path_id => {
47+ let path_id = primary. as_str ( ) ;
48+ let symbol_id = SymbolTable :: symbol_id_from_name ( st, path_id) ;
49+ match symbol_id {
50+ Some ( id) => tr. e ( Expr :: Sym ( id) ) ,
51+ None => panic ! ( "Referencing undefined symbol: {}" , path_id) ,
52+ }
53+ }
54+
55+ // if primary is an expression (due to parens), recursively parse its inner constituents
56+ Rule :: expr => parse_expr ( primary. into_inner ( ) , tr, st) ,
57+ rule => unreachable ! ( "Expr::parse expected atom, found {:?}" , rule)
58+ } )
59+
60+ // FIXME: two closures require unique access to `*tr` at the same time
61+ // Parse binary expressions
62+ . map_infix ( |lhs, op, rhs| {
63+ let op = match op. as_rule ( ) {
64+ Rule :: eq => BinOp :: Equal ,
65+ Rule :: log_and => BinOp :: And ,
66+ rule => unreachable ! ( "Expr::parse expected infix operation, found {:?}" , rule) ,
67+ } ;
68+ let bin_expression = Expr :: Binary (
69+ op,
70+ lhs,
71+ rhs
72+ ) ;
73+ tr. e ( bin_expression)
74+ } )
75+
76+ // Parse unary expressions
77+ . map_prefix ( |op, arg| {
78+ let op = match op. as_rule ( ) {
79+ Rule :: not => UnaryOp :: Not ,
80+ rule => unreachable ! ( "Expr::parse expected prefix operation, found {:?}" , rule) ,
81+ } ;
82+ let unary_expression = Expr :: Unary ( op, arg) ;
83+ tr. e ( unary_expression)
84+ } )
85+ . parse ( pairs)
86+ }
87+
88+
6789// fn build_ir(pair: pest::iterators::Pair<Rule>) -> (Transaction, SymbolTable) {
6890// match pair.as_rule() {
6991// Rule::file => {
@@ -93,25 +115,138 @@ lazy_static::lazy_static! {
93115// }
94116// }
95117
96- fn build_transaction ( pair : pest:: iterators:: Pair < Rule > , sym : & mut SymbolTable ) -> Transaction {
118+ fn build_struct ( pair : pest:: iterators:: Pair < Rule > , st : & mut SymbolTable ) -> StructId {
119+ let mut inner_rules = pair. into_inner ( ) ;
120+ let struct_id = inner_rules. next ( ) . unwrap ( ) . as_str ( ) ;
121+
122+ let pins = build_fields ( inner_rules. next ( ) . unwrap ( ) , st) ;
123+
124+ st. add_struct ( struct_id. to_string ( ) , pins)
125+ }
126+
127+ fn build_transaction ( pair : pest:: iterators:: Pair < Rule > , st : & mut SymbolTable ) -> Transaction {
97128 match pair. as_rule ( ) {
98129 Rule :: fun => {
99130 let mut inner_rules = pair. into_inner ( ) ;
100131 let id_pair = inner_rules. next ( ) . unwrap ( ) ;
101132 let id = id_pair. as_str ( ) ;
102- let mut trans = Transaction :: new ( id. to_string ( ) ) ;
103- trans. args = build_arglist ( inner_rules. next ( ) . unwrap ( ) , sym) ;
104- // Process the rest of the inner rules if needed
105- for inner_pair in inner_rules {
106- // Handle other inner pairs
133+ let mut tr = Transaction :: new ( id. to_string ( ) ) ;
134+ tr. args = build_arglist ( inner_rules. next ( ) . unwrap ( ) , st) ;
135+
136+ // Process the body of statements, adding them to the block as we go
137+ while let Some ( inner_pair) = inner_rules. next ( ) {
138+ match inner_pair. as_rule ( ) {
139+ Rule :: assign => {
140+ let stmt = parse_assign ( inner_pair, tr, st) ;
141+ tr. s ( stmt) ;
142+ }
143+ Rule :: cmd => {
144+ let stmt = parse_cmd ( inner_pair, tr, st) ;
145+ tr. s ( stmt) ;
146+ }
147+ Rule :: while_loop => {
148+ let stmt = parse_while ( inner_pair, tr, st) ;
149+ tr. s ( stmt) ;
150+ }
151+ Rule :: cond => {
152+ let stmt = parse_cond ( inner_pair, tr, st) ;
153+ tr. s ( stmt) ;
154+ }
155+ _ => panic ! ( "Unexpected rule: {:?}" , inner_pair. as_rule( ) ) ,
156+ }
107157 }
108- trans
158+ println ! ( "Transaction: {:?}" , tr) ;
159+ tr
109160 }
110161 _ => panic ! ( "Unexpected rule: {:?}" , pair. as_rule( ) ) ,
111162 }
112163}
113164
114- fn build_arglist ( pair : pest:: iterators:: Pair < Rule > , sym : & mut SymbolTable ) -> Vec < Arg > {
165+ fn parse_assign ( pair : pest:: iterators:: Pair < Rule > , tr : & mut Transaction , st : & mut SymbolTable ) -> Stmt {
166+ let path_id_rule = pair. into_inner ( ) . next ( ) . unwrap ( ) ;
167+ let expr_rule = pair. into_inner ( ) . next ( ) . unwrap ( ) ;
168+
169+ let path_id = path_id_rule. as_str ( ) ;
170+ // TODO: Error handling
171+ let symbol_id = match st. symbol_id_from_name ( path_id) {
172+ Some ( id) => id,
173+ None => panic ! ( "Assigning to undeclared symbol: {}" , path_id) ,
174+ } ;
175+
176+ let expr_id = parse_expr ( expr_rule. into_inner ( ) , tr, st) ;
177+
178+ // Dummy implementation
179+ Stmt :: Assign ( symbol_id, expr_id)
180+ }
181+
182+ fn parse_cmd ( pair : pest:: iterators:: Pair < Rule > , st : & mut SymbolTable ) -> Stmt {
183+ let cmd= pair. as_str ( ) ;
184+ match cmd {
185+ "step" => Stmt :: Step ,
186+ "fork" => Stmt :: Fork ,
187+ _ => panic ! ( "Unexpected command: {:?}" , cmd) ,
188+ }
189+ }
190+
191+ fn parse_while ( pair : pest:: iterators:: Pair < Rule > , tr : & mut Transaction , st : & mut SymbolTable ) -> Stmt {
192+ // Parse Expression
193+ let mut inner_rules = pair. into_inner ( ) ;
194+ let expr_rule = inner_rules. next ( ) . unwrap ( ) ;
195+ let guard: ExprId = parse_expr ( expr_rule. into_inner ( ) , tr, st) ;
196+
197+ // Parse Statement Block
198+ let body = parse_stmt_block ( inner_rules, tr, st) ;
199+
200+ Stmt :: While ( guard, body)
201+ }
202+
203+ fn parse_stmt_block ( stmt_pairs : Pairs < Rule > , tr : & mut Transaction , st : & mut SymbolTable ) -> StmtId {
204+ // Parse Statement Block. FIXME: Duplicate code.
205+ // Process the body of statements, adding them to the block as we go
206+ let stmts = Vec :: new ( ) ;
207+ while let Some ( inner_pair) = stmt_pairs. next ( ) {
208+ match inner_pair. as_rule ( ) {
209+ Rule :: assign => {
210+ let stmt = parse_assign ( inner_pair, tr, st) ;
211+ stmts. push ( tr. s ( stmt) ) ;
212+ }
213+ Rule :: cmd => {
214+ let stmt = parse_cmd ( inner_pair, tr, st) ;
215+ stmts. push ( tr. s ( stmt) ) ;
216+ }
217+ Rule :: while_loop => {
218+ let stmt = parse_while ( inner_pair, tr, st) ;
219+ stmts. push ( tr. s ( stmt) ) ;
220+ }
221+ Rule :: cond => {
222+ let stmt = parse_cond ( inner_pair, tr, st) ;
223+ stmts. push ( tr. s ( stmt) ) ;
224+ }
225+ _ => panic ! ( "Unexpected rule: {:?}" , inner_pair. as_rule( ) ) ,
226+ }
227+ }
228+ tr. s ( Stmt :: Block ( stmts) )
229+ }
230+
231+ fn parse_cond ( pair : pest:: iterators:: Pair < Rule > , tr : & mut Transaction , st : & mut SymbolTable ) -> Stmt {
232+ // Dummy implementation
233+ let mut inner_rules = pair. into_inner ( ) ;
234+
235+ let if_rule = inner_rules. next ( ) . unwrap ( ) ;
236+ let inner_if = if_rule. into_inner ( ) ;
237+ let expr_rule = inner_if. next ( ) . unwrap ( ) ;
238+ let expr_id = parse_expr ( expr_rule. into_inner ( ) , tr, st) ;
239+ let if_block = parse_stmt_block ( inner_if, tr, st) ;
240+
241+ let else_rule = inner_rules. next ( ) . unwrap ( ) ;
242+ let inner_else = else_rule. into_inner ( ) ;
243+ let else_block = parse_stmt_block ( inner_else, tr, st) ;
244+
245+ Stmt :: IfElse ( expr_id, if_block, else_block)
246+
247+ }
248+
249+ fn build_arglist ( pair : pest:: iterators:: Pair < Rule > , st : & mut SymbolTable ) -> Vec < Arg > {
115250 let mut args = Vec :: new ( ) ;
116251 for inner_pair in pair. into_inner ( ) {
117252 match inner_pair. as_rule ( ) {
@@ -125,12 +260,12 @@ fn build_arglist(pair : pest::iterators::Pair<Rule>, sym : &mut SymbolTable) ->
125260 let id = id_pair. as_str ( ) ;
126261 let tpe = parse_type ( tpe_pair) ;
127262
128- let symbol_id = sym . add_without_parent ( id. to_string ( ) , tpe) ;
263+ let symbol_id = st . add_without_parent ( id. to_string ( ) , tpe) ;
129264 let arg = Arg :: new ( symbol_id, dir) ;
130265 args. push ( arg) ;
131266 }
132267 Rule :: arglist => {
133- let mut nested_args = build_arglist ( inner_pair, sym ) ;
268+ let mut nested_args = build_arglist ( inner_pair, st ) ;
134269 args. append ( & mut nested_args) ;
135270 }
136271 _ => panic ! ( "Unexpected rule: {:?}" , inner_pair. as_rule( ) ) ,
@@ -139,6 +274,33 @@ fn build_arglist(pair : pest::iterators::Pair<Rule>, sym : &mut SymbolTable) ->
139274 args
140275}
141276
277+ fn build_fields ( pair : pest:: iterators:: Pair < Rule > , st : & mut SymbolTable ) -> Vec < Field > {
278+ let mut fields = Vec :: new ( ) ;
279+ for inner_pair in pair. into_inner ( ) {
280+ match inner_pair. as_rule ( ) {
281+ Rule :: arg => {
282+ let mut arg_inner = inner_pair. into_inner ( ) ;
283+ let dir_pair = arg_inner. next ( ) . unwrap ( ) ;
284+ let id_pair = arg_inner. next ( ) . unwrap ( ) ;
285+ let tpe_pair = arg_inner. next ( ) . unwrap ( ) ;
286+
287+ let dir = parse_dir ( dir_pair) ;
288+ let id = id_pair. as_str ( ) ;
289+ let tpe = parse_type ( tpe_pair) ;
290+
291+ let field = Field :: new ( id. to_string ( ) , dir, tpe) ;
292+ fields. push ( field) ;
293+ }
294+ Rule :: arglist => {
295+ let mut nested_fields = build_fields ( inner_pair, st) ;
296+ fields. append ( & mut nested_fields) ;
297+ }
298+ _ => panic ! ( "Unexpected rule: {:?}" , inner_pair. as_rule( ) ) ,
299+ }
300+ }
301+ fields
302+ }
303+
142304fn parse_dir ( pair : pest:: iterators:: Pair < Rule > ) -> Dir {
143305 match pair. as_rule ( ) {
144306 Rule :: dir => {
@@ -223,11 +385,15 @@ mod tests {
223385 }
224386 // println!("Length of pairs: {}", pairs.clone().count());
225387 let inner = pairs. clone ( ) . next ( ) . unwrap ( ) . into_inner ( ) ;
388+ let mut st: & mut SymbolTable = & mut SymbolTable :: default ( ) ;
226389 for pair in inner {
227- if pair. as_rule ( ) == Rule :: fun {
228- let mut sym = & mut SymbolTable :: default ( ) ;
229- let mut transaction = build_transaction ( pair, sym) ;
230- println ! ( "Transaction: {:?}" , transaction. name) ;
390+ if pair. as_rule ( ) == Rule :: struct_def {
391+ let _parsed_struct = build_struct ( pair, st) ;
392+ // println!("Struct: {:?}", struct.name);
393+ }
394+ else if pair. as_rule ( ) == Rule :: fun {
395+ let _tr = build_transaction ( pair, st) ;
396+ // println!("Transaction: {:?}", transaction.name);
231397 }
232398 }
233399 // let pair = pairs.into_inner();
0 commit comments