chirrtl_parser/
ast.rs

1use std::fmt::{Display, Debug};
2use num_bigint::{BigInt, ParseBigIntError};
3use num_traits::{FromPrimitive, Num};
4use std::str::FromStr;
5
6#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7pub struct Int(BigInt);
8
9impl Int {
10    pub fn to_u32(&self) -> u32 {
11      let (_, digits_u32) = self.0.to_u32_digits();
12      assert!(digits_u32.len() <= 1,
13          "to_u32 should only be called on small bigints that can be represented by a u32 len {}",
14          digits_u32.len());
15      *digits_u32.get(0).unwrap_or(&0)
16    }
17
18    pub fn from_str_radix(num: &str, radix: u32) -> Result<Self, ParseBigIntError>  {
19        let bigint = BigInt::from_str_radix(num, radix)?;
20        Ok(Self {
21            0: bigint
22        })
23    }
24
25    pub fn from_str(num: &str) -> Result<Self, ParseBigIntError> {
26        let bigint = BigInt::from_str(num)?;
27        Ok(Self {
28            0: bigint
29        })
30    }
31}
32
33impl From<u32> for Int {
34    fn from(value: u32) -> Self {
35        Self {
36            0: BigInt::from_u32(value)
37                .expect(&format!("BigInt from_u32 {}", value))
38        }
39    }
40}
41
42impl Debug for Int {
43    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        write!(f, "0h{}", self.0.to_str_radix(16).to_uppercase())
45    }
46}
47
48impl Display for Int {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        write!(f, "{}", self.0.to_string())
51    }
52}
53
54#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
55pub struct Info(pub String);
56
57impl Display for Info {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        write!(f, "@[{}]", self.0)
60    }
61}
62
63#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
64pub struct Width(pub u32);
65
66impl Display for Width {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        write!(f, "{}", self.0)
69    }
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
73pub enum Identifier {
74    ID(Int),
75    Name(String),
76}
77
78impl Display for Identifier {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        match self {
81            Self::ID(x)   => write!(f, "{:?}", x),
82            Self::Name(x) => write!(f, "{}", x)
83        }
84    }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
88pub struct Float {
89    pub integer: u32,
90    pub decimal: u32,
91}
92
93impl Float {
94    pub fn new(integer: u32, decimal: u32) -> Self {
95        Self { integer, decimal }
96    }
97}
98
99impl Display for Float {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        write!(f, "{}.{}", self.integer, self.decimal)
102    }
103}
104
105#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
106pub enum Reference {
107    Ref(Identifier),
108    RefDot(Box<Reference>, Identifier),
109    RefIdxInt(Box<Reference>, Int),
110    RefIdxExpr(Box<Reference>, Box<Expr>)
111}
112
113impl Display for Reference {
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        match self {
116            Self::Ref(name)    => write!(f, "{}", name),
117            Self::RefDot(r, name) => write!(f, "{}.{}", r, name),
118            Self::RefIdxInt(r, int) => write!(f, "{}[{:?}]", r, int),
119            Self::RefIdxExpr(r, expr) => write!(f, "{}[{}]", r, expr),
120        }
121    }
122}
123
124impl Debug for Reference {
125    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126        write!(f, "{}", self)
127    }
128}
129
130impl Reference {
131    pub fn root(&self) -> Identifier {
132        match self {
133            Self::Ref(name) => name.clone(),
134            Self::RefDot(parent, _)     |
135            Self::RefIdxInt(parent, _)  |
136            Self::RefIdxExpr(parent, _) => {
137                parent.root()
138            }
139        }
140    }
141}
142
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
144pub enum PrimOp2Expr {
145    Add,
146    Sub,
147    Mul,
148    Div,
149    Rem,
150    Lt,
151    Leq,
152    Gt,
153    Geq,
154    Eq,
155    Neq,
156    Dshl,
157    Dshr,
158    And,
159    Or,
160    Xor,
161    Cat,
162}
163
164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
165pub enum PrimOp1Expr {
166    AsUInt,
167    AsSInt,
168    AsClock,
169    AsAsyncReset,
170    Cvt,
171    Neg,
172    Not,
173    Andr,
174    Orr,
175    Xorr,
176}
177
178
179#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
180pub enum PrimOp1Expr1Int {
181    Pad,
182    Shl,
183    Shr,
184    Head,
185    Tail,
186    BitSel,
187}
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
190pub enum PrimOp1Expr2Int {
191    BitSelRange,
192}
193
194impl From<String> for PrimOp2Expr {
195    fn from(value: String) -> Self {
196        match value.as_str() {
197            "add" => { Self::Add },
198            "sub" => { Self::Sub },
199            "mul" => { Self::Mul },
200            "div" => { Self::Div },
201            "rem" => { Self::Rem },
202            "lt"  => { Self::Lt },
203            "leq"  => { Self::Leq },
204            "gt"  => { Self::Gt },
205            "geq"  => { Self::Geq },
206            "eq"  => { Self::Eq },
207            "neq"  => { Self::Neq },
208            "dshl"  => { Self::Dshl },
209            "dshr"  => { Self::Dshr },
210            "and"  => { Self::And },
211            "or"  => { Self::Or },
212            "xor"  => { Self::Xor },
213            "cat"  => { Self::Cat },
214            _ => {
215                panic!("Unrecognized operator {}", value);
216            }
217        }
218    }
219}
220
221impl Display for PrimOp2Expr {
222    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223        let s = match self {
224            PrimOp2Expr::Add => "add",
225            PrimOp2Expr::Sub => "sub",
226            PrimOp2Expr::Mul => "mul",
227            PrimOp2Expr::Div => "div",
228            PrimOp2Expr::Rem => "rem",
229            PrimOp2Expr::Lt => "lt",
230            PrimOp2Expr::Leq => "leq",
231            PrimOp2Expr::Gt => "gt",
232            PrimOp2Expr::Geq => "geq",
233            PrimOp2Expr::Eq => "eq",
234            PrimOp2Expr::Neq => "neq",
235            PrimOp2Expr::Dshl => "dshl",
236            PrimOp2Expr::Dshr => "dshr",
237            PrimOp2Expr::And => "and",
238            PrimOp2Expr::Or => "or",
239            PrimOp2Expr::Xor => "xor",
240            PrimOp2Expr::Cat => "cat",
241        };
242        write!(f, "{s}")
243    }
244}
245
246impl From<String> for PrimOp1Expr {
247    fn from(value: String) -> Self {
248        match value.as_str() {
249            "asUInt"  => { Self::AsUInt },
250            "asSInt"  => { Self::AsSInt },
251            "asClock"  => { Self::AsClock },
252            "asAsyncReset"  => { Self::AsAsyncReset },
253            "cvt"  => { Self::Cvt },
254            "neg"  => { Self::Neg },
255            "not"  => { Self::Not },
256            "andr"  => { Self::Andr },
257            "orr"  => { Self::Orr },
258            "xorr"  => { Self::Xorr },
259            _ => {
260                panic!("Unrecognized operator {}", value);
261            }
262        }
263    }
264}
265
266impl std::fmt::Display for PrimOp1Expr {
267    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
268        let s = match self {
269            PrimOp1Expr::AsUInt => "asUInt",
270            PrimOp1Expr::AsSInt => "asSInt",
271            PrimOp1Expr::AsClock => "asClock",
272            PrimOp1Expr::AsAsyncReset => "asAsyncReset",
273            PrimOp1Expr::Cvt => "cvt",
274            PrimOp1Expr::Neg => "neg",
275            PrimOp1Expr::Not => "not",
276            PrimOp1Expr::Andr => "andr",
277            PrimOp1Expr::Orr => "orr",
278            PrimOp1Expr::Xorr => "xorr",
279        };
280        write!(f, "{s}")
281    }
282}
283
284impl From<String> for PrimOp1Expr1Int {
285    fn from(value: String) -> Self {
286        match value.as_str() {
287            "pad"  => { Self::Pad },
288            "shl"  => { Self::Shl },
289            "shr"  => { Self::Shr },
290            "head"  => { Self::Head },
291            "tail"  => { Self::Tail },
292            _ => { Self::BitSel }
293        }
294    }
295}
296
297
298impl std::fmt::Display for PrimOp1Expr1Int {
299    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
300        let s = match self {
301            PrimOp1Expr1Int::Pad => "pad",
302            PrimOp1Expr1Int::Shl => "shl",
303            PrimOp1Expr1Int::Shr => "shr",
304            PrimOp1Expr1Int::Head => "head",
305            PrimOp1Expr1Int::Tail => "tail",
306            PrimOp1Expr1Int::BitSel => panic!("Display called for bitsel"),
307        };
308        write!(f, "{s}")
309    }
310}
311
312impl From<String> for PrimOp1Expr2Int {
313    fn from(value: String) -> Self {
314        assert!(value.contains("bit"));
315        Self::BitSelRange
316    }
317}
318
319impl std::fmt::Display for PrimOp1Expr2Int {
320    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
321        let s = match self {
322            PrimOp1Expr2Int::BitSelRange => "bits",
323        };
324        write!(f, "{s}")
325    }
326}
327
328pub type Exprs = Vec<Box<Expr>>;
329
330fn fmt_exprs(exprs: &Exprs) -> String {
331    let mut ret = "".to_string();
332    let len = exprs.len();
333    for (id, e) in exprs.iter().enumerate() {
334        ret.push_str(&format!("{}", e));
335        if id != len - 1 {
336            ret.push_str(", ");
337        }
338    }
339    return ret;
340}
341
342#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
343pub enum Expr {
344    UIntNoInit(Width),
345    UIntInit(Width, Int),
346    SIntNoInit(Width),
347    SIntInit(Width, Int),
348    Reference(Reference),
349    Mux(Box<Expr>, Box<Expr>, Box<Expr>),
350    ValidIf(Box<Expr>, Box<Expr>),
351    PrimOp2Expr(PrimOp2Expr, Box<Expr>, Box<Expr>),
352    PrimOp1Expr(PrimOp1Expr, Box<Expr>),
353    PrimOp1Expr1Int(PrimOp1Expr1Int, Box<Expr>, Int),
354    PrimOp1Expr2Int(PrimOp1Expr2Int, Box<Expr>, Int, Int),
355}
356
357impl Expr {
358    pub fn parse_radixint(s: &str) -> Result<Int, String> {
359        if let Some(num) = s.strip_prefix("0b") {
360            Int::from_str_radix(num, 2).map_err(|e| e.to_string())
361        } else if let Some(num) = s.strip_prefix("0o") {
362            Int::from_str_radix(num, 8).map_err(|e| e.to_string())
363        } else if let Some(num) = s.strip_prefix("0d") {
364            Int::from_str_radix(num, 10).map_err(|e| e.to_string())
365        } else if let Some(num) = s.strip_prefix("0h") {
366            Int::from_str_radix(num, 16).map_err(|e| e.to_string())
367        } else {
368            Err(format!("Invalid number format: {}", s))
369        }
370    }
371}
372
373impl Display for Expr {
374    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
375        match self {
376            Expr::UIntNoInit(w) => write!(f, "UInt<{}>()", w),
377            Expr::UIntInit(w, init) => write!(f, "UInt<{}>({:?})", w, init),
378            Expr::SIntNoInit(w) => write!(f, "SInt<{}>()", w),
379            Expr::SIntInit(w, init) => write!(f, "SInt<{}>({:?})", w, init),
380            Expr::Reference(r) => write!(f, "{}", r),
381            Expr::Mux(cond, te, fe) => write!(f, "mux({}, {}, {})", cond, te, fe),
382            Expr::ValidIf(cond, te) => write!(f, "validif({}, {})", cond, te),
383            Expr::PrimOp2Expr(op, a, b) => write!(f, "{}({}, {})", op, a, b),
384            Expr::PrimOp1Expr(op, a) => write!(f, "{}({})", op, a),
385            Expr::PrimOp1Expr1Int(PrimOp1Expr1Int::BitSel, a, b) => write!(f, "{}({})", a, b),
386            Expr::PrimOp1Expr1Int(op, a, b) => write!(f, "{}({}, {})", op, a, b),
387            Expr::PrimOp1Expr2Int(op, a, b, c) => write!(f, "{}({}, {}, {})", op, a, b, c),
388        }
389    }
390}
391
392#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
393pub enum TypeGround {
394    Clock,
395    Reset,
396    AsyncReset,
397    UInt(Option<Width>),
398    SInt(Option<Width>),
399// ProbeType
400// AnalType,
401// FixedType
402}
403
404impl Display for TypeGround {
405    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
406        match self {
407            Self::Clock => { write!(f, "Clock") }
408            Self::Reset => { write!(f, "Reset") }
409            Self::AsyncReset => { write!(f, "AsyncReset") }
410            Self::UInt(w_opt) => {
411                if let Some(w) = w_opt {
412                    write!(f, "UInt<{}>", w)
413                } else {
414                    write!(f, "UInt")
415                }
416            }
417            Self::SInt(w_opt) => {
418                if let Some(w) = w_opt {
419                    write!(f, "SInt<{}>", w)
420                } else {
421                    write!(f, "SInt")
422                }
423            }
424        }
425    }
426}
427
428pub type Fields = Vec<Box<Field>>;
429
430#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
431pub enum Field {
432    Straight(Identifier, Box<Type>),
433    Flipped(Identifier, Box<Type>),
434}
435
436impl Display for Field {
437    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
438        match self {
439            Self::Straight(id, tpe) => {
440                write!(f, "{}: {}", id, tpe)
441            }
442            Self::Flipped(id, tpe) => {
443                write!(f, "flip {}: {}", id, tpe)
444            }
445        }
446    }
447}
448
449#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
450pub enum TypeAggregate {
451    Fields(Box<Fields>),
452    Array(Box<Type>, Int),
453}
454
455impl Display for TypeAggregate {
456    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
457        match self {
458            Self::Fields(fields) => {
459                write!(f, "{{ ")?;
460                for field in fields.iter() {
461                    write!(f, "{}, ", field)?;
462                }
463                write!(f, " }}")
464            }
465            Self::Array(tpe, idx) => {
466                write!(f, "{}[{:?}]", tpe, idx)
467            }
468        }
469    }
470}
471
472#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
473pub enum Type {
474    TypeGround(TypeGround),
475    ConstTypeGround(TypeGround),
476    TypeAggregate(Box<TypeAggregate>),
477    ConstTypeAggregate(Box<TypeAggregate>),
478}
479
480impl Display for Type {
481    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
482        match self {
483            Self::TypeGround(tg) => write!(f, "{}", tg),
484            Self::ConstTypeGround(tg) => write!(f, "{}", tg),
485            Self::TypeAggregate(ta) => write!(f, "{}", ta),
486            Self::ConstTypeAggregate(ta) => write!(f, "{}", ta),
487        }
488    }
489}
490
491#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
492pub enum ChirrtlMemoryReadUnderWrite {
493    #[default]
494    Undefined,
495    Old,
496    New
497}
498
499#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
500pub enum ChirrtlMemory {
501    SMem(Identifier, Type, Option<ChirrtlMemoryReadUnderWrite>, Info),
502    CMem(Identifier, Type, Info),
503}
504
505impl Display for ChirrtlMemory {
506    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
507        match self {
508            Self::SMem(name, tpe, ruw_opt, info) => {
509                if let Some(ruw) = ruw_opt {
510                    write!(f, "smem {} : {}, {:?} {}", name, tpe, ruw, info)
511                } else {
512                    write!(f, "smem {} : {} {}", name, tpe, info)
513                }
514            }
515            Self::CMem(name, tpe, info) => {
516                    write!(f, "cmem {} : {} {}", name, tpe, info)
517            }
518        }
519    }
520}
521
522#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
523pub enum ChirrtlMemoryPort {
524    Write(Identifier, Identifier, Expr, Reference, Info),
525    Read (Identifier, Identifier, Expr, Reference, Info),
526    Infer(Identifier, Identifier, Expr, Reference, Info),
527}
528
529impl Display for ChirrtlMemoryPort {
530    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
531        match self {
532            ChirrtlMemoryPort::Write(port_name, mem_name, addr, clk, info) => {
533                write!(f, "write mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
534            }
535            ChirrtlMemoryPort::Read(port_name, mem_name, addr, clk, info) => {
536                write!(f, "read mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
537            }
538            ChirrtlMemoryPort::Infer(port_name, mem_name, addr, clk, info) => {
539                write!(f, "infer mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
540            }
541        }
542    }
543}
544
545pub type Stmts = Vec<Box<Stmt>>;
546
547#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
548pub enum Stmt {
549    Skip(Info),
550    Wire(Identifier, Type, Info),
551    Reg(Identifier,  Type, Expr, Info),
552    RegReset(Identifier, Type, Expr, Expr, Expr, Info),
553    ChirrtlMemory(ChirrtlMemory),
554    ChirrtlMemoryPort(ChirrtlMemoryPort),
555    Inst(Identifier, Identifier, Info),
556    Node(Identifier, Expr, Info),
557    Connect(Expr, Expr, Info),
558    Invalidate(Expr, Info),
559    When(Expr, Info, Stmts, Option<Stmts>),
560    Printf(Expr, Expr, String, Option<Exprs>, Info),
561    Assert(Expr, Expr, Expr, String, Info),
562// Memory()
563// Stop(Expr, Expr, u64, Info),
564// Stop(Expr, Expr, u64, Info),
565// Define(Define, Reference, Probe, Info),
566// Define(Define, Reference, Expr, Probe, Info),
567// Attach(References)
568// Connect(Reference, Read, Expr, Info),
569// Reference <- ???
570}
571
572impl Stmt {
573    pub fn traverse(&self) {
574        match self {
575            Self::When(e, i, tstmts, fstmts_opt) => {
576                println!("When, {:?}, {:?}", e, i);
577                for tstmt in tstmts.iter() {
578                    println!("{:?}", tstmt);
579                }
580                match fstmts_opt {
581                    Some(fstmts) => {
582                        println!("ELSE");
583                        for fstmt in fstmts.iter() {
584                            println!("{:?}", fstmt);
585                        }
586                    }
587                    None => {
588                    }
589                }
590            }
591            _ => {
592                println!("{:?}", self);
593            }
594        }
595    }
596}
597
598impl Display for Stmt {
599    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
600        match self {
601            Stmt::Skip(info) => write!(f, "skip {}", info),
602            Stmt::Wire(name, tpe, info) => write!(f, "wire {} : {} {}", name, tpe, info),
603            Stmt::Reg(name, tpe, clk, info) => write!(f, "reg {} : {}, {} {}", name, tpe, clk, info),
604            Stmt::RegReset(name, tpe, clk, rst, init, info) => write!(f, "reg {} : {}, {}, {}, {} {}", name, tpe, clk, rst, init, info),
605            Stmt::ChirrtlMemory(cm) => write!(f, "{}", cm),
606            Stmt::ChirrtlMemoryPort(cmp) => write!(f, "{}", cmp),
607            Stmt::Inst(inst, module, info) => write!(f, "{} of {} {}", inst, module, info),
608            Stmt::Node(name, expr, info) => write!(f, "node {} = {} {}", name, expr, info),
609            Stmt::Connect(lhs, rhs, info) => write!(f, "connect {}, {} {}", lhs, rhs, info),
610            Stmt::Invalidate(reference, info) => write!(f, "invalidate {} {}", reference, info),
611            Stmt::Printf(clk, clk_val, msg, fields_opt, info) => {
612                if let Some(fields) = fields_opt {
613                    write!(f, "printf({}, {}, {}, {}) : {}", clk, clk_val, msg, fmt_exprs(fields), info)
614                } else {
615                    write!(f, "printf({}, {}, {}) : {}", clk, clk_val, msg, info)
616                }
617            }
618            Stmt::Assert(clk, cond, cond_val, msg, info) => {
619                write!(f, "assert({}, {}, {}, {}) : {}", clk, cond, cond_val, msg, info)
620            }
621            Stmt::When(cond, info, when_stmts, else_stmts_opt) => {
622                // NOTE: Cannot track indent inside the Display trait, so this will cause weirdly
623                // indented stuff
624                writeln!(f, "when {} : {}", cond, info)?;
625                for stmt in when_stmts.iter() {
626                    writeln!(f, "{}{}", " ".repeat(2), stmt)?;
627                }
628                if let Some(else_stmts) = else_stmts_opt {
629                    writeln!(f, "else :")?;
630                    for stmt in else_stmts.iter() {
631                        writeln!(f, "{}{}", " ".repeat(2), stmt)?;
632                    }
633                }
634                Ok(())
635            }
636        }
637    }
638}
639
640#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
641pub enum Port {
642    Input(Identifier, Type, Info),
643    Output(Identifier, Type, Info),
644}
645
646impl Display for Port {
647    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
648        match self {
649            Self::Input(id, tpe, info) => {
650                write!(f, "input {} : {} {}", id, tpe, info)
651            }
652            Self::Output(id, tpe, info) => {
653                write!(f, "output {} : {} {}", id, tpe, info)
654            }
655        }
656    }
657}
658
659pub type Ports = Vec<Box<Port>>;
660
661#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
662pub struct Module  {
663    pub name: Identifier,
664    pub ports: Ports,
665    pub stmts: Stmts,
666    pub info: Info,
667}
668
669impl Module {
670    pub fn new(name: Identifier, ports: Ports, stmts: Stmts, info: Info) -> Self {
671        Self { name, ports, stmts, info, }
672    }
673}
674
675#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
676pub struct DefName(Identifier);
677
678impl From<Identifier> for DefName {
679    fn from(value: Identifier) -> Self {
680        Self(value)
681    }
682}
683
684impl Display for DefName {
685    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
686        write!(f, "defname = {}", self.0)
687    }
688}
689
690pub type Parameters = Vec<Box<Parameter>>;
691
692#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
693pub enum Parameter {
694    IntParam(Identifier, Int),
695    FloatParam(Identifier, Float),
696    StringParam(Identifier, String),
697}
698
699impl Display for Parameter {
700    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
701        match self {
702            Self::IntParam(name, value) => write!(f, "parameter {} = {:?}", name, value),
703            Self::FloatParam(name, value) => write!(f, "parameter {} = {}", name, value),
704            Self::StringParam(name, value) => write!(f, "parameter {} = {}", name, value),
705        }
706    }
707}
708
709#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
710pub struct ExtModule {
711    pub name: Identifier,
712    pub ports: Ports,
713    pub defname: DefName,
714    pub params: Parameters,
715    pub info: Info,
716}
717
718impl ExtModule {
719    pub fn new(name: Identifier, ports: Ports, defname: DefName, params: Parameters, info: Info) -> Self {
720        Self { name, ports, defname, params, info }
721    }
722}
723
724#[allow(dead_code)]
725pub struct IntModule {
726    pub name: Identifier,
727    pub ports: Ports,
728    pub params: Parameters,
729    pub info: Info,
730}
731
732#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
733pub enum CircuitModule {
734    Module(Module),
735    ExtModule(ExtModule),
736// IntModule(IntModule),
737}
738
739pub type CircuitModules = Vec<Box<CircuitModule>>;
740
741#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
742pub struct Annotations(pub serde_json::Value);
743
744impl Annotations {
745    pub fn from_str(input: String) -> Self {
746        let input = "[".to_owned() + &input + "]";
747        Self { 0: serde_json::from_str(&input).unwrap() }
748    }
749}
750
751#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
752pub struct Version(pub u32, pub u32, pub u32);
753
754impl Display for Version {
755    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
756        write!(f, "Version {}.{}.{}", self.0, self.1, self.2)
757    }
758}
759
760#[derive(Debug, Clone, Eq, PartialEq, Hash)]
761pub struct Circuit {
762    pub version: Version,
763    pub name: Identifier,
764    pub annos: Annotations,
765    pub modules: CircuitModules,
766}
767
768impl Circuit {
769    pub fn new(version: Version, name: Identifier, annos: Annotations, modules: CircuitModules) -> Self {
770        Self { version, name, annos, modules }
771    }
772}