@@ -77,11 +77,96 @@ pub(crate) fn emit_statement(
7777 Ok ( ( stmts, Vec :: default ( ) ) )
7878 }
7979 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
8292 }
8393}
8494
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+
85170fn emit_if_block (
86171 hlir : & Hlir ,
87172 ast : & p4:: ast:: AST ,
@@ -430,7 +515,9 @@ fn emit_assignment(
430515 // TODO store instr
431516 }
432517 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+ ) ?;
434521 let output = ra. alloc ( target. root ( ) ) ;
435522 let offsets = member_offsets ( ast, names, target) ?;
436523 let instr = Fset {
0 commit comments