1use std::collections::HashMap;
8
9use super::SyntaxError;
10use super::lex::{Tok, Token, lex};
11use crate::error::Error;
12use crate::expr::{Context, Expr};
13use crate::ops::{BinOp, CmpOpExt, UnOp};
14use crate::{BitVec, SymbolKey, Width};
15
16#[derive(Clone, Debug, Default)]
18#[non_exhaustive]
19pub struct ParseOptions {
20 pub default_width: Option<Width>,
23 pub existing_symbols_only: bool,
25}
26
27impl ParseOptions {
28 pub fn width(w: Width) -> Self {
30 ParseOptions {
31 default_width: Some(w),
32 existing_symbols_only: false,
33 }
34 }
35
36 pub fn with_existing_symbols_only(mut self, yes: bool) -> Self {
38 self.existing_symbols_only = yes;
39 self
40 }
41}
42
43const MAX_DEPTH: u32 = 128;
44
45#[derive(Clone, Copy, Debug, PartialEq, Eq)]
46pub(crate) enum Derived {
47 UMin,
48 UMax,
49 SMin,
50 SMax,
51 AndN,
52 OrN,
53 XNor,
54 Abs,
55 AddCarry,
56 SubBorrow,
57 SAddOverflow,
58 SSubOverflow,
59 AddSatU,
60 AddSatS,
61 SubSatU,
62 SubSatS,
63}
64
65#[derive(Clone, Debug)]
66enum Kind {
67 Lit(Vec<u64>),
68 NegLit(Vec<u64>),
70 Bool(bool),
71 Sym(SymbolKey),
72 Un(UnOp, usize),
73 Bin(BinOp, usize, usize),
74 Cmp(CmpOpExt, usize, usize),
75 Zext(usize),
76 Sext(usize),
77 Extract(u16, usize),
78 Concat(usize, usize),
79 Select(usize, usize, usize),
80 Derived(Derived, usize, usize),
81 Ext(crate::ext::ExtId, u8, Vec<usize>),
83}
84
85struct PNode {
86 kind: Kind,
87 var: usize,
88 span: (usize, usize),
89}
90
91struct Widths {
93 parent: Vec<usize>,
94 value: Vec<Option<u16>>,
95}
96
97impl Widths {
98 fn fresh(&mut self) -> usize {
99 self.parent.push(self.parent.len());
100 self.value.push(None);
101 self.parent.len() - 1
102 }
103
104 fn find(&mut self, mut x: usize) -> usize {
105 while self.parent[x] != x {
106 self.parent[x] = self.parent[self.parent[x]];
107 x = self.parent[x];
108 }
109 x
110 }
111
112 fn get(&mut self, x: usize) -> Option<u16> {
113 let r = self.find(x);
114 self.value[r]
115 }
116
117 fn unify(&mut self, a: usize, b: usize) -> bool {
119 let (ra, rb) = (self.find(a), self.find(b));
120 if ra == rb {
121 return true;
122 }
123 let v = match (self.value[ra], self.value[rb]) {
124 (Some(x), Some(y)) if x != y => return false,
125 (x, y) => x.or(y),
126 };
127 self.parent[rb] = ra;
128 self.value[ra] = v;
129 true
130 }
131
132 fn fix(&mut self, a: usize, w: u16) -> bool {
133 let r = self.find(a);
134 match self.value[r] {
135 Some(x) => x == w,
136 None => {
137 self.value[r] = Some(w);
138 true
139 }
140 }
141 }
142}
143
144struct Parser<'a> {
145 toks: Vec<Token>,
146 pos: usize,
147 nodes: Vec<PNode>,
148 widths: Widths,
149 lets: HashMap<LetKey, usize>,
150 sym_vars: HashMap<SymbolKey, usize>,
151 cx: &'a Context,
152 opts: &'a ParseOptions,
153 depth: u32,
154}
155
156#[derive(Clone, PartialEq, Eq, Hash)]
157enum LetKey {
158 Num(u32),
159 Name(String),
160}
161
162type PResult<T> = Result<T, SyntaxError>;
163
164impl<'a> Parser<'a> {
165 fn peek(&self) -> &Tok {
166 &self.toks[self.pos].tok
167 }
168
169 fn span(&self) -> (usize, usize) {
170 let t = &self.toks[self.pos];
171 (t.start, t.end)
172 }
173
174 fn bump(&mut self) -> Token {
175 let t = self.toks[self.pos].clone();
176 if self.pos + 1 < self.toks.len() {
177 self.pos += 1;
178 }
179 t
180 }
181
182 fn error<T>(&self, msg: &str) -> PResult<T> {
183 let (s, e) = self.span();
184 Err(SyntaxError::new(msg, s, e))
185 }
186
187 fn expect(&mut self, t: Tok, what: &str) -> PResult<Token> {
188 if *self.peek() == t {
189 Ok(self.bump())
190 } else {
191 self.error(&format!("expected {what}"))
192 }
193 }
194
195 fn node(&mut self, kind: Kind, span: (usize, usize)) -> usize {
196 let var = self.widths.fresh();
197 self.nodes.push(PNode { kind, var, span });
198 self.nodes.len() - 1
199 }
200
201 fn var(&self, n: usize) -> usize {
202 self.nodes[n].var
203 }
204
205 fn unify(&mut self, a: usize, b: usize, span: (usize, usize)) -> PResult<()> {
206 let (va, vb) = (self.var(a), self.var(b));
207 if self.widths.unify(va, vb) {
208 Ok(())
209 } else {
210 let (wa, wb) = (self.widths.get(va), self.widths.get(vb));
211 Err(SyntaxError::new(
212 &format!(
213 "operand widths differ ({} vs {}); insert an explicit zext/sext/trunc",
214 wa.unwrap_or(0),
215 wb.unwrap_or(0)
216 ),
217 span.0,
218 span.1,
219 ))
220 }
221 }
222
223 fn fix(&mut self, n: usize, w: u16, span: (usize, usize)) -> PResult<()> {
224 let v = self.var(n);
225 if self.widths.fix(v, w) {
226 Ok(())
227 } else {
228 let have = self.widths.get(v).unwrap_or(0);
229 Err(SyntaxError::new(
230 &format!("width {w} conflicts with inferred width {have}"),
231 span.0,
232 span.1,
233 ))
234 }
235 }
236
237 fn enter(&mut self) -> PResult<()> {
238 self.depth += 1;
239 if self.depth > MAX_DEPTH {
240 return self.error("expression nested too deeply; use `let` bindings");
241 }
242 Ok(())
243 }
244
245 fn top(&mut self) -> PResult<usize> {
248 while matches!(self.peek(), Tok::Ident(s) if s == "let") {
249 self.bump();
250 let key = match self.bump().tok {
251 Tok::LetName(k) => LetKey::Num(k),
252 Tok::Ident(s) if !super::is_reserved(&s) => LetKey::Name(s),
253 _ => return self.error("expected a name after `let`"),
254 };
255 self.expect(Tok::Assign, "`=`")?;
256 let e = self.expr()?;
257 self.expect(Tok::Semi, "`;`")?;
258 if self.lets.insert(key, e).is_some() {
259 return self.error("this name is already bound by an earlier `let`");
260 }
261 }
262 let e = self.expr()?;
263 if *self.peek() != Tok::Eof {
264 return self.error("unexpected input after expression");
265 }
266 Ok(e)
267 }
268
269 fn expr(&mut self) -> PResult<usize> {
270 self.enter()?;
271 let start = self.span().0;
272 let lhs = self.binary(0)?;
273 let op = match self.peek() {
274 Tok::Eq => CmpOpExt::Eq,
275 Tok::Ne => CmpOpExt::Ne,
276 Tok::Ult => CmpOpExt::Ult,
277 Tok::Ule => CmpOpExt::Ule,
278 Tok::Ugt => CmpOpExt::Ugt,
279 Tok::Uge => CmpOpExt::Uge,
280 Tok::Slt => CmpOpExt::Slt,
281 Tok::Sle => CmpOpExt::Sle,
282 Tok::Sgt => CmpOpExt::Sgt,
283 Tok::Sge => CmpOpExt::Sge,
284 _ => {
285 self.depth -= 1;
286 return Ok(lhs);
287 }
288 };
289 self.bump();
290 let rhs = self.binary(0)?;
291 let span = (start, self.toks[self.pos.saturating_sub(1)].end);
292 self.unify(lhs, rhs, span)?;
293 let n = self.node(Kind::Cmp(op, lhs, rhs), span);
294 self.fix(n, 1, span)?;
295 if matches!(
296 self.peek(),
297 Tok::Eq
298 | Tok::Ne
299 | Tok::Ult
300 | Tok::Ule
301 | Tok::Ugt
302 | Tok::Uge
303 | Tok::Slt
304 | Tok::Sle
305 | Tok::Sgt
306 | Tok::Sge
307 ) {
308 return self.error("comparisons do not chain; add parentheses");
309 }
310 self.depth -= 1;
311 Ok(n)
312 }
313
314 fn binary_op(&self) -> Option<(BinOp, u8)> {
316 Some(match self.peek() {
317 Tok::Pipe => (BinOp::Or, 2),
318 Tok::Caret => (BinOp::Xor, 3),
319 Tok::Amp => (BinOp::And, 4),
320 Tok::Shl => (BinOp::Shl, 5),
321 Tok::LShr => (BinOp::LShr, 5),
322 Tok::AShr => (BinOp::AShr, 5),
323 Tok::Plus => (BinOp::Add, 6),
324 Tok::Minus => (BinOp::Sub, 6),
325 Tok::Star => (BinOp::Mul, 7),
326 _ => return None,
327 })
328 }
329
330 fn binary(&mut self, min_prec: u8) -> PResult<usize> {
332 let start = self.span().0;
333 let mut lhs = self.unary()?;
334 while let Some((op, prec)) = self.binary_op() {
335 if prec < min_prec {
336 break;
337 }
338 self.bump();
339 let rhs = self.binary(prec + 1)?;
340 let span = (start, self.toks[self.pos.saturating_sub(1)].end);
341 self.unify(lhs, rhs, span)?;
342 let n = self.node(Kind::Bin(op, lhs, rhs), span);
343 self.unify(n, lhs, span)?;
344 lhs = n;
345 }
346 Ok(lhs)
347 }
348
349 fn unary(&mut self) -> PResult<usize> {
350 let op = match self.peek() {
351 Tok::Tilde => UnOp::Not,
352 Tok::Minus => UnOp::Neg,
353 _ => return self.postfix(),
354 };
355 self.enter()?;
356 let start = self.bump().start;
357 let a = self.unary()?;
358 let span = (start, self.toks[self.pos.saturating_sub(1)].end);
359 if op == UnOp::Neg
360 && a + 1 == self.nodes.len()
361 && let Kind::Lit(limbs) = &self.nodes[a].kind
362 {
363 self.nodes[a].kind = Kind::NegLit(limbs.clone());
364 self.nodes[a].span = span;
365 self.depth -= 1;
366 return Ok(a);
367 }
368 let n = self.node(Kind::Un(op, a), span);
369 self.unify(n, a, span)?;
370 self.depth -= 1;
371 Ok(n)
372 }
373
374 fn postfix(&mut self) -> PResult<usize> {
375 let e = self.primary()?;
376 if *self.peek() == Tok::Colon {
377 self.bump();
378 let span = self.span();
379 let w = self.width_literal()?;
380 self.fix(e, w, span)?;
381 }
382 Ok(e)
383 }
384
385 fn width_literal(&mut self) -> PResult<u16> {
386 let span = self.span();
387 match self.bump().tok {
388 Tok::Int(d, 10) => d
389 .parse::<u16>()
390 .ok()
391 .filter(|w| Width::new(*w).is_ok())
392 .ok_or_else(|| SyntaxError::new("width must be in 1..=512", span.0, span.1)),
393 _ => Err(SyntaxError::new("expected a decimal width", span.0, span.1)),
394 }
395 }
396
397 fn primary(&mut self) -> PResult<usize> {
398 let span = self.span();
399 let t = self.bump();
400 match t.tok {
401 Tok::Int(digits, radix) => {
402 let limbs = parse_limbs(&digits, radix)
403 .ok_or_else(|| SyntaxError::new("literal exceeds 512 bits", span.0, span.1))?;
404 Ok(self.node(Kind::Lit(limbs), span))
405 }
406 Tok::LParen => {
407 let e = self.expr()?;
408 self.expect(Tok::RParen, "`)`")?;
409 Ok(e)
410 }
411 Tok::LetName(k) => self
412 .lets
413 .get(&LetKey::Num(k))
414 .copied()
415 .ok_or_else(|| SyntaxError::new(&format!("unbound name %{k}"), span.0, span.1)),
416 Tok::HashKey(k) => self.symbol(SymbolKey::U64(k), span),
417 Tok::FreshKey(k) => self.symbol(SymbolKey::Fresh(k), span),
418 Tok::Str(s) => self.symbol(SymbolKey::from(s), span),
419 Tok::Ext(name, k) => {
420 let op = self
421 .cx
422 .registry()
423 .and_then(|r| r.id(&name))
424 .ok_or_else(|| {
425 SyntaxError::new(
426 &format!("no extension operation `{name}` in this context"),
427 span.0,
428 span.1,
429 )
430 })?;
431 self.enter()?;
432 self.expect(Tok::LParen, "`(`")?;
433 let mut args = vec![self.expr()?];
434 while *self.peek() == Tok::Comma {
435 self.bump();
436 args.push(self.expr()?);
437 }
438 self.expect(Tok::RParen, "`)`")?;
439 self.depth -= 1;
440 let end = self.toks[self.pos.saturating_sub(1)].end;
441 if args.len() > crate::ext::MAX_ARGS {
442 return Err(SyntaxError::new(
443 &format!("`{name}` takes at most {} arguments", crate::ext::MAX_ARGS),
444 span.0,
445 end,
446 ));
447 }
448 Ok(self.node(Kind::Ext(op, k, args), (span.0, end)))
449 }
450 Tok::Ident(name) => {
451 if name == "true" || name == "false" {
452 let n = self.node(Kind::Bool(name == "true"), span);
453 self.fix(n, 1, span)?;
454 return Ok(n);
455 }
456 if let Some(&e) = self.lets.get(&LetKey::Name(name.clone())) {
457 return Ok(e);
458 }
459 if super::FUNCTIONS.contains(&name.as_str()) {
460 return self.call(&name, span);
461 }
462 if super::is_reserved(&name) {
463 return Err(SyntaxError::new(
464 &format!("`{name}` is reserved"),
465 span.0,
466 span.1,
467 ));
468 }
469 self.symbol(SymbolKey::from(name), span)
470 }
471 _ => Err(SyntaxError::new("expected an expression", span.0, span.1)),
472 }
473 }
474
475 fn symbol(&mut self, key: SymbolKey, span: (usize, usize)) -> PResult<usize> {
476 let existing = self
477 .cx
478 .find_symbol(&key)
479 .and_then(|e| self.cx.width(e).ok());
480 if existing.is_none() && self.opts.existing_symbols_only {
481 return Err(SyntaxError::new(
482 &format!("unknown symbol {key}"),
483 span.0,
484 span.1,
485 ));
486 }
487 let n = self.node(Kind::Sym(key.clone()), span);
488 if let Some(&v) = self.sym_vars.get(&key) {
489 let nv = self.var(n);
490 if !self.widths.unify(nv, v) {
491 return Err(SyntaxError::new("symbol width conflict", span.0, span.1));
492 }
493 } else {
494 self.sym_vars.insert(key, self.var(n));
495 }
496 if let Some(w) = existing {
497 self.fix(n, w.bits(), span)?;
498 }
499 Ok(n)
500 }
501
502 fn generics(&mut self, count: usize) -> PResult<Vec<u16>> {
503 self.expect(Tok::LAngle, "`<`")?;
504 let mut out = Vec::new();
505 for k in 0..count {
506 if k > 0 {
507 self.expect(Tok::Comma, "`,`")?;
508 }
509 let span = self.span();
510 match self.bump().tok {
511 Tok::Int(d, 10) => out.push(
512 d.parse::<u16>()
513 .map_err(|_| SyntaxError::new("number too large", span.0, span.1))?,
514 ),
515 _ => return Err(SyntaxError::new("expected a number", span.0, span.1)),
516 }
517 }
518 self.expect(Tok::RAngle, "`>`")?;
519 Ok(out)
520 }
521
522 fn args(&mut self, count: usize) -> PResult<Vec<usize>> {
523 self.expect(Tok::LParen, "`(`")?;
524 let mut out = Vec::new();
525 for k in 0..count {
526 if k > 0 {
527 self.expect(Tok::Comma, "`,`")?;
528 }
529 out.push(self.expr()?);
530 }
531 self.expect(Tok::RParen, "`)`")?;
532 Ok(out)
533 }
534
535 fn call(&mut self, name: &str, start: (usize, usize)) -> PResult<usize> {
536 self.enter()?;
537 let un = |n: &str| {
538 Some(match n {
539 "popcnt" => UnOp::Popcnt,
540 "clz" => UnOp::Clz,
541 "ctz" => UnOp::Ctz,
542 "bswap" => UnOp::Bswap,
543 "bitrev" => UnOp::BitRev,
544 _ => return None,
545 })
546 };
547 let bin = |n: &str| {
548 Some(match n {
549 "udiv" => BinOp::UDiv,
550 "urem" => BinOp::URem,
551 "sdiv" => BinOp::SDiv,
552 "srem" => BinOp::SRem,
553 "rotl" => BinOp::RotL,
554 "rotr" => BinOp::RotR,
555 "umulhi" => BinOp::UMulHi,
556 "smulhi" => BinOp::SMulHi,
557 "pdep" => BinOp::Pdep,
558 "pext" => BinOp::Pext,
559 _ => return None,
560 })
561 };
562 let derived = |n: &str| {
563 Some(match n {
564 "umin" => Derived::UMin,
565 "umax" => Derived::UMax,
566 "smin" => Derived::SMin,
567 "smax" => Derived::SMax,
568 "andn" => Derived::AndN,
569 "orn" => Derived::OrN,
570 "xnor" => Derived::XNor,
571 "abs" => Derived::Abs,
572 "add_carry" => Derived::AddCarry,
573 "sub_borrow" => Derived::SubBorrow,
574 "sadd_overflow" => Derived::SAddOverflow,
575 "ssub_overflow" => Derived::SSubOverflow,
576 "add_sat_u" => Derived::AddSatU,
577 "add_sat_s" => Derived::AddSatS,
578 "sub_sat_u" => Derived::SubSatU,
579 "sub_sat_s" => Derived::SubSatS,
580 _ => return None,
581 })
582 };
583 let span = |p: &Self| (start.0, p.toks[p.pos.saturating_sub(1)].end);
584 let n = if let Some(op) = un(name) {
585 let a = self.args(1)?[0];
586 let sp = span(self);
587 let n = self.node(Kind::Un(op, a), sp);
588 self.unify(n, a, sp)?;
589 n
590 } else if let Some(op) = bin(name) {
591 let a = self.args(2)?;
592 let sp = span(self);
593 self.unify(a[0], a[1], sp)?;
594 let n = self.node(Kind::Bin(op, a[0], a[1]), sp);
595 self.unify(n, a[0], sp)?;
596 n
597 } else if let Some(d) = derived(name) {
598 let unary = d == Derived::Abs;
599 let a = self.args(if unary { 1 } else { 2 })?;
600 let (x, y) = (a[0], if unary { a[0] } else { a[1] });
601 let sp = span(self);
602 self.unify(x, y, sp)?;
603 let n = self.node(Kind::Derived(d, x, y), sp);
604 if matches!(
605 d,
606 Derived::AddCarry
607 | Derived::SubBorrow
608 | Derived::SAddOverflow
609 | Derived::SSubOverflow
610 ) {
611 self.fix(n, 1, sp)?;
612 } else {
613 self.unify(n, x, sp)?;
614 }
615 n
616 } else {
617 match name {
618 "zext" | "sext" | "trunc" => {
619 let g = self.generics(1)?;
620 let a = self.args(1)?[0];
621 let sp = span(self);
622 let to = g[0];
623 if Width::new(to).is_err() {
624 return Err(SyntaxError::new("width must be in 1..=512", sp.0, sp.1));
625 }
626 let kind = match name {
627 "zext" => Kind::Zext(a),
628 "sext" => Kind::Sext(a),
629 _ => Kind::Extract(0, a),
630 };
631 let n = self.node(kind, sp);
632 self.fix(n, to, sp)?;
633 n
634 }
635 "extract" => {
636 let g = self.generics(2)?;
637 let a = self.args(1)?[0];
638 let sp = span(self);
639 if Width::new(g[1]).is_err() {
640 return Err(SyntaxError::new("width must be in 1..=512", sp.0, sp.1));
641 }
642 let n = self.node(Kind::Extract(g[0], a), sp);
643 self.fix(n, g[1], sp)?;
644 n
645 }
646 "concat" => {
647 let a = self.args(2)?;
648 let sp = span(self);
649 self.node(Kind::Concat(a[0], a[1]), sp)
650 }
651 "select" => {
652 let a = self.args(3)?;
653 let sp = span(self);
654 self.fix(a[0], 1, sp)?;
655 self.unify(a[1], a[2], sp)?;
656 let n = self.node(Kind::Select(a[0], a[1], a[2]), sp);
657 self.unify(n, a[1], sp)?;
658 n
659 }
660 _ => return self.error("unknown function"),
661 }
662 };
663 self.depth -= 1;
664 Ok(n)
665 }
666}
667
668fn parse_limbs(digits: &str, radix: u32) -> Option<Vec<u64>> {
670 let mut acc = vec![0u64; 9];
671 for ch in digits.chars() {
672 let d = ch.to_digit(radix)?;
673 let mut carry = u128::from(d);
674 for x in acc.iter_mut() {
675 let t = u128::from(*x) * u128::from(radix) + carry;
676 *x = t as u64;
677 carry = t >> 64;
678 }
679 if carry != 0 || acc[8] != 0 {
680 return None;
681 }
682 }
683 acc.truncate(8);
684 Some(acc)
685}
686
687fn concat_pass(p: &mut Parser<'_>, order: &[usize]) -> PResult<bool> {
690 let mut changed = false;
691 for &i in order {
692 if matches!(p.nodes[i].kind, Kind::Ext(..)) {
693 changed |= ext_pass(p, i)?;
694 continue;
695 }
696 let Kind::Concat(h, l) = p.nodes[i].kind else {
697 continue;
698 };
699 let (vn, vh, vl) = (p.nodes[i].var, p.nodes[h].var, p.nodes[l].var);
700 let (wn, wh, wl) = (p.widths.get(vn), p.widths.get(vh), p.widths.get(vl));
701 let span = p.nodes[i].span;
702 let bad = || SyntaxError::new("concatenation widths do not fit", span.0, span.1);
703 match (wn, wh, wl) {
704 (None, Some(a), Some(b)) => {
705 let t = u32::from(a) + u32::from(b);
706 if t > u32::from(Width::MAX_BITS) {
707 return Err(bad());
708 }
709 p.widths.fix(vn, t as u16);
710 changed = true;
711 }
712 (Some(t), Some(a), None) => {
713 if t <= a {
714 return Err(bad());
715 }
716 p.widths.fix(vl, t - a);
717 changed = true;
718 }
719 (Some(t), None, Some(b)) => {
720 if t <= b {
721 return Err(bad());
722 }
723 p.widths.fix(vh, t - b);
724 changed = true;
725 }
726 (Some(t), Some(a), Some(b)) if u32::from(t) != u32::from(a) + u32::from(b) => {
727 return Err(bad());
728 }
729 _ => {}
730 }
731 }
732 Ok(changed)
733}
734
735fn concat_fixpoint(p: &mut Parser<'_>) -> PResult<()> {
737 let concats: Vec<usize> = (0..p.nodes.len())
738 .filter(|&i| matches!(p.nodes[i].kind, Kind::Concat(..) | Kind::Ext(..)))
739 .collect();
740 if concats.is_empty() {
741 return Ok(());
742 }
743 let rev: Vec<usize> = concats.iter().rev().copied().collect();
744 loop {
745 let up = concat_pass(p, &concats)?;
746 let down = concat_pass(p, &rev)?;
747 if !up && !down {
748 return Ok(());
749 }
750 }
751}
752
753fn operands(k: &Kind) -> Vec<usize> {
755 match k {
756 Kind::Lit(_) | Kind::NegLit(_) | Kind::Bool(_) | Kind::Sym(_) => Vec::new(),
757 Kind::Un(_, a) | Kind::Zext(a) | Kind::Sext(a) | Kind::Extract(_, a) => vec![*a],
758 Kind::Bin(_, a, b) | Kind::Cmp(_, a, b) | Kind::Concat(a, b) | Kind::Derived(_, a, b) => {
759 vec![*a, *b]
760 }
761 Kind::Select(a, b, c) => vec![*a, *b, *c],
762 Kind::Ext(_, _, args) => args.clone(),
763 }
764}
765
766fn ext_pass(p: &mut Parser<'_>, i: usize) -> PResult<bool> {
768 let Kind::Ext(op, k, args) = &p.nodes[i].kind else {
769 return Ok(false);
770 };
771 let span = p.nodes[i].span;
772 let err = |m: String| SyntaxError::new(&m, span.0, span.1);
773 let mut widths = Vec::with_capacity(args.len());
774 for &a in args {
775 match p.widths.get(p.nodes[a].var) {
776 Some(w) => widths.push(Width::new(w).map_err(|e| err(e.to_string()))?),
777 None => return Ok(false),
778 }
779 }
780 let o =
781 p.cx.registry()
782 .and_then(|r| r.op(*op))
783 .ok_or_else(|| err("no such extension operation".into()))?;
784 let sig = o
785 .signature(&widths)
786 .map_err(|why| err(format!("`{}`: {why}", o.name())))?;
787 if sig.is_empty() || sig.len() > crate::ext::MAX_OUTPUTS {
788 return Err(err(format!(
789 "`{}` declares {} outputs (1 to {})",
790 o.name(),
791 sig.len(),
792 crate::ext::MAX_OUTPUTS
793 )));
794 }
795 let w = sig
796 .width(usize::from(*k))
797 .ok_or_else(|| err(format!("`{}` has no output {k}", o.name())))?;
798 let v = p.nodes[i].var;
799 match p.widths.get(v) {
800 None => {
801 p.widths.fix(v, w.bits());
802 Ok(true)
803 }
804 Some(have) if have != w.bits() => Err(err(format!(
805 "`{}` output {k} has {} bits, not {have}",
806 o.name(),
807 w.bits()
808 ))),
809 Some(_) => Ok(false),
810 }
811}
812
813fn resolve(p: &mut Parser<'_>) -> PResult<Vec<u16>> {
817 concat_fixpoint(p)?;
818 let mut under_ext = vec![false; p.nodes.len()];
823 for i in (0..p.nodes.len()).rev() {
824 if let Kind::Ext(_, _, args) = &p.nodes[i].kind {
825 let mut stack = args.clone();
826 while let Some(j) = stack.pop() {
827 if under_ext[j] {
828 continue;
829 }
830 under_ext[j] = true;
831 stack.extend(operands(&p.nodes[j].kind));
832 }
833 }
834 }
835 for stage in 0..3 {
836 let mut defaulted = false;
837 for (i, &under) in under_ext.iter().enumerate() {
838 let is_leaf = matches!(
839 p.nodes[i].kind,
840 Kind::Sym(_) | Kind::Lit(_) | Kind::NegLit(_)
841 );
842 let leaf = is_leaf
843 && match stage {
844 0 => under,
845 1 => matches!(p.nodes[i].kind, Kind::Sym(_)),
846 _ => true,
847 };
848 let v = p.nodes[i].var;
849 if leaf && p.widths.get(v).is_none() {
850 match p.opts.default_width {
851 Some(w) => {
852 p.widths.fix(v, w.bits());
853 defaulted = true;
854 }
855 None => {
856 let span = p.nodes[i].span;
857 return Err(SyntaxError::new(
858 "cannot infer this width; write `:W` (for example `1:32`)",
859 span.0,
860 span.1,
861 ));
862 }
863 }
864 }
865 }
866 if defaulted {
867 concat_fixpoint(p)?;
868 }
869 }
870 let mut out = Vec::with_capacity(p.nodes.len());
871 for i in 0..p.nodes.len() {
872 let v = p.nodes[i].var;
873 match p.widths.get(v) {
874 Some(w) => out.push(w),
875 None => {
876 let span = p.nodes[i].span;
877 return Err(SyntaxError::new("cannot infer this width", span.0, span.1));
878 }
879 }
880 }
881 validate(&p.nodes, &out)?;
882 Ok(out)
883}
884
885fn validate(nodes: &[PNode], widths: &[u16]) -> PResult<()> {
888 for (i, n) in nodes.iter().enumerate() {
889 let w = widths[i];
890 let err = |m: &str| Err(SyntaxError::new(m, n.span.0, n.span.1));
891 match &n.kind {
892 Kind::Lit(limbs) => {
893 let width =
894 Width::new(w).map_err(|_| SyntaxError::new("bad width", n.span.0, n.span.1))?;
895 if BitVec::from_limbs(width, limbs).is_err() {
896 return err(&format!("literal does not fit in {w} bits"));
897 }
898 }
899 Kind::NegLit(limbs) => {
900 let width =
901 Width::new(w).map_err(|_| SyntaxError::new("bad width", n.span.0, n.span.1))?;
902 let fits = BitVec::from_limbs(width, limbs)
903 .is_ok_and(|m| m.is_zero() || m == BitVec::smin(width) || !m.msb());
904 if !fits {
905 return err(&format!(
906 "negative literal does not fit in {w} bits (signed)"
907 ));
908 }
909 }
910 Kind::Un(UnOp::Bswap, _) if !w.is_multiple_of(8) => {
911 return err("bswap needs a width that is a multiple of 8");
912 }
913 Kind::Zext(a) | Kind::Sext(a) if widths[*a] > w => {
914 return err(&format!("cannot extend {} bits to {w} bits", widths[*a]));
915 }
916 Kind::Extract(lo, a) if u32::from(*lo) + u32::from(w) > u32::from(widths[*a]) => {
917 return err(&format!(
918 "extract of bits [{lo}, {lo}+{w}) does not fit in {} bits",
919 widths[*a]
920 ));
921 }
922 _ => {}
923 }
924 }
925 Ok(())
926}
927
928impl Context {
929 pub fn parse(&mut self, src: &str, opts: &ParseOptions) -> Result<Expr, Error> {
941 let toks = lex(src).map_err(Error::Syntax)?;
942 let (nodes, widths, root) = {
943 let mut p = Parser {
944 toks,
945 pos: 0,
946 nodes: Vec::new(),
947 widths: Widths {
948 parent: Vec::new(),
949 value: Vec::new(),
950 },
951 lets: HashMap::new(),
952 sym_vars: HashMap::new(),
953 cx: self,
954 opts,
955 depth: 0,
956 };
957 let root = p.top().map_err(Error::Syntax)?;
958 let widths = resolve(&mut p).map_err(Error::Syntax)?;
959 (p.nodes, widths, root)
960 };
961 let mut built: Vec<Expr> = Vec::with_capacity(nodes.len());
962 for (i, n) in nodes.iter().enumerate() {
963 let w = Width::new(widths[i]).map_err(Error::Width)?;
964 let at = |j: usize| built[j];
965 let spanned = |e: Error| match e {
966 Error::Width(we) => {
967 Error::Syntax(SyntaxError::new(&we.to_string(), n.span.0, n.span.1))
968 }
969 Error::Value(_) => Error::Syntax(SyntaxError::new(
970 &format!("literal does not fit in {} bits", w.bits()),
971 n.span.0,
972 n.span.1,
973 )),
974 other => other,
975 };
976 let e = match &n.kind {
977 Kind::Lit(limbs) => BitVec::from_limbs(w, limbs)
978 .map_err(Error::Value)
979 .and_then(|v| self.constant(&v)),
980 Kind::NegLit(limbs) => BitVec::from_limbs(w, limbs)
981 .map_err(Error::Value)
982 .and_then(|v| self.constant(&BitVec::un_unchecked(UnOp::Neg, &v))),
983 Kind::Bool(b) => self.bool(*b),
984 Kind::Sym(key) => self.symbol(key.clone(), w),
985 Kind::Un(op, a) => self.un(*op, at(*a)),
986 Kind::Bin(op, a, b) => self.bin(*op, at(*a), at(*b)),
987 Kind::Cmp(op, a, b) => self.cmp(*op, at(*a), at(*b)),
988 Kind::Zext(a) => self.zext(at(*a), w),
989 Kind::Sext(a) => self.sext(at(*a), w),
990 Kind::Extract(lo, a) => self.extract(at(*a), *lo, w),
991 Kind::Concat(h, l) => self.concat(at(*h), at(*l)),
992 Kind::Select(c, t, f) => self.select(at(*c), at(*t), at(*f)),
993 Kind::Ext(op, k, args) => {
994 let args: Vec<Expr> = args.iter().map(|&a| at(a)).collect();
995 self.ext_output(*op, usize::from(*k), &args)
996 }
997 Kind::Derived(d, a, b) => {
998 let (a, b) = (at(*a), at(*b));
999 match d {
1000 Derived::UMin => self.umin(a, b),
1001 Derived::UMax => self.umax(a, b),
1002 Derived::SMin => self.smin(a, b),
1003 Derived::SMax => self.smax(a, b),
1004 Derived::AndN => self.andn(a, b),
1005 Derived::OrN => self.orn(a, b),
1006 Derived::XNor => self.xnor(a, b),
1007 Derived::Abs => self.abs(a),
1008 Derived::AddCarry => self.add_carry(a, b),
1009 Derived::SubBorrow => self.sub_borrow(a, b),
1010 Derived::SAddOverflow => self.sadd_overflow(a, b),
1011 Derived::SSubOverflow => self.ssub_overflow(a, b),
1012 Derived::AddSatU => self.add_sat_u(a, b),
1013 Derived::AddSatS => self.add_sat_s(a, b),
1014 Derived::SubSatU => self.sub_sat_u(a, b),
1015 Derived::SubSatS => self.sub_sat_s(a, b),
1016 }
1017 }
1018 }
1019 .map_err(spanned)?;
1020 built.push(e);
1021 }
1022 Ok(built[root])
1023 }
1024}