Skip to content

Commit 3a2e3d6

Browse files
committed
parser transitions
1 parent f0d0c24 commit 3a2e3d6

File tree

2 files changed

+94
-4
lines changed

2 files changed

+94
-4
lines changed

codegen/htq/src/error.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use htq::ast::Register;
44
use p4::{
55
ast::{
66
Call, Control, ControlParameter, DeclarationInfo, Expression, Lvalue,
7-
Type,
7+
Transition, Type,
88
},
99
lexer::Token,
1010
};
@@ -114,6 +114,9 @@ pub enum CodegenError {
114114

115115
#[error("action not found in control\naction:\n{0:#?}\ncontrol:\n{1:#?}")]
116116
ActionNotFound(Lvalue, Control),
117+
118+
#[error("transition must be in parser context\n{0:#?}")]
119+
TransitionOutsideParser(Transition),
117120
}
118121

119122
#[derive(Error, Debug)]

codegen/htq/src/statement.rs

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
85170
fn 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

Comments
 (0)