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