@@ -77,11 +77,96 @@ pub(crate) fn emit_statement(
77
77
Ok ( ( stmts, Vec :: default ( ) ) )
78
78
}
79
79
S :: Constant ( _c) => Ok ( ( Vec :: default ( ) , Vec :: default ( ) ) ) , //TODO
80
- S :: Transition ( _t) => Ok ( ( Vec :: default ( ) , Vec :: default ( ) ) ) , //TODO
81
- S :: Return ( _r) => Ok ( ( Vec :: default ( ) , Vec :: default ( ) ) ) , //TODO
80
+ S :: Transition ( t) => emit_transition (
81
+ hlir,
82
+ ast,
83
+ context,
84
+ names,
85
+ t,
86
+ ra,
87
+ afa,
88
+ psub,
89
+ table_context,
90
+ ) ,
91
+ S :: Return ( _r) => Ok ( ( Vec :: default ( ) , Vec :: default ( ) ) ) , //TODO
82
92
}
83
93
}
84
94
95
+ fn emit_transition (
96
+ _hlir : & Hlir ,
97
+ _ast : & p4:: ast:: AST ,
98
+ context : & P4Context < ' _ > ,
99
+ _names : & mut HashMap < String , NameInfo > ,
100
+ transition : & p4:: ast:: Transition ,
101
+ ra : & mut RegisterAllocator ,
102
+ _afa : & mut AsyncFlagAllocator ,
103
+ _psub : & mut HashMap < ControlParameter , Vec < Register > > ,
104
+ _table_context : & mut TableContext ,
105
+ ) -> Result <
106
+ ( Vec < htq:: ast:: Statement > , Vec < htq:: ast:: StatementBlock > ) ,
107
+ CodegenError ,
108
+ > {
109
+ let parser = match & context {
110
+ P4Context :: Parser ( p) => * p,
111
+ P4Context :: Control ( _) => {
112
+ return Err ( CodegenError :: TransitionOutsideParser (
113
+ transition. clone ( ) ,
114
+ ) )
115
+ }
116
+ } ;
117
+
118
+ let transition_to = match & transition {
119
+ p4:: ast:: Transition :: Reference ( lval) => lval,
120
+ p4:: ast:: Transition :: Select ( _) => todo ! ( "transition select" ) ,
121
+ } ;
122
+
123
+ let mut args = Vec :: default ( ) ;
124
+ let mut targets = Vec :: default ( ) ;
125
+ for x in & parser. parameters {
126
+ if x. direction . is_out ( ) {
127
+ targets. push ( ra. alloc ( & x. name ) ) ;
128
+ }
129
+ args. push ( Value :: reg ( ra. get ( & x. name ) . ok_or (
130
+ CodegenError :: NoRegisterForParameter ( x. name . clone ( ) , ra. clone ( ) ) ,
131
+ ) ?) ) ;
132
+ }
133
+
134
+ let hdr = targets[ 0 ] . clone ( ) ;
135
+
136
+ let mut stmts = Vec :: default ( ) ;
137
+ match transition_to. name . as_str ( ) {
138
+ "accept" => {
139
+ stmts. push ( htq:: ast:: Statement :: SetValid ( htq:: ast:: SetValid {
140
+ output : ra. alloc ( & hdr. 0 ) ,
141
+ target : hdr. clone ( ) ,
142
+ offsets : Vec :: default ( ) ,
143
+ source : htq:: ast:: Value :: bool ( true ) ,
144
+ } ) ) ;
145
+ }
146
+ "reject" => {
147
+ stmts. push ( htq:: ast:: Statement :: SetValid ( htq:: ast:: SetValid {
148
+ output : ra. alloc ( & hdr. 0 ) ,
149
+ target : hdr. clone ( ) ,
150
+ offsets : Vec :: default ( ) ,
151
+ source : htq:: ast:: Value :: bool ( false ) ,
152
+ } ) ) ;
153
+ }
154
+ _ => {
155
+ stmts. push ( htq:: ast:: Statement :: Call ( htq:: ast:: Call {
156
+ fname : format ! ( "{}_{}" , parser. name, transition_to. name) ,
157
+ args,
158
+ targets : targets. clone ( ) ,
159
+ } ) ) ;
160
+ }
161
+ }
162
+
163
+ stmts. push ( htq:: ast:: Statement :: Return ( htq:: ast:: Return {
164
+ registers : targets,
165
+ } ) ) ;
166
+
167
+ Ok ( ( stmts, Vec :: default ( ) ) )
168
+ }
169
+
85
170
fn emit_if_block (
86
171
hlir : & Hlir ,
87
172
ast : & p4:: ast:: AST ,
@@ -430,7 +515,9 @@ fn emit_assignment(
430
515
// TODO store instr
431
516
}
432
517
DeclarationInfo :: StructMember | DeclarationInfo :: HeaderMember => {
433
- let treg = ra. alloc ( target. root ( ) ) ;
518
+ let treg = ra. get ( target. root ( ) ) . ok_or (
519
+ CodegenError :: RegisterDoesNotExistForLval ( target. clone ( ) ) ,
520
+ ) ?;
434
521
let output = ra. alloc ( target. root ( ) ) ;
435
522
let offsets = member_offsets ( ast, names, target) ?;
436
523
let instr = Fset {
0 commit comments