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                write!(f, "{{ ")?;
457                for field in fields.iter() {
458                    write!(f, "{}, ", field)?;
459                }
460                write!(f, " }}")
461            }
462            Self::Array(tpe, idx) => {
463                write!(f, "{}[{:?}]", tpe, idx)
464            }
465        }
466    }
467}
468
469#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
470pub enum Type {
471    TypeGround(TypeGround),
472    ConstTypeGround(TypeGround),
473    TypeAggregate(Box<TypeAggregate>),
474    ConstTypeAggregate(Box<TypeAggregate>),
475}
476
477impl Display for Type {
478    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
479        match self {
480            Self::TypeGround(tg) => write!(f, "{}", tg),
481            Self::ConstTypeGround(tg) => write!(f, "{}", tg),
482            Self::TypeAggregate(ta) => write!(f, "{}", ta),
483            Self::ConstTypeAggregate(ta) => write!(f, "{}", ta),
484        }
485    }
486}
487
488#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
489pub enum ChirrtlMemoryReadUnderWrite {
490    #[default]
491    Undefined,
492    Old,
493    New
494}
495
496#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
497pub enum ChirrtlMemory {
498    SMem(Identifier, Type, Option<ChirrtlMemoryReadUnderWrite>, Info),
499    CMem(Identifier, Type, Info),
500}
501
502impl Display for ChirrtlMemory {
503    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
504        match self {
505            Self::SMem(name, tpe, ruw_opt, info) => {
506                if let Some(ruw) = ruw_opt {
507                    write!(f, "smem {} : {}, {:?} {}", name, tpe, ruw, info)
508                } else {
509                    write!(f, "smem {} : {} {}", name, tpe, info)
510                }
511            }
512            Self::CMem(name, tpe, info) => {
513                    write!(f, "cmem {} : {} {}", name, tpe, info)
514            }
515        }
516    }
517}
518
519#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
520pub enum ChirrtlMemoryPort {
521    Write(Identifier, Identifier, Expr, Reference, Info),
522    Read (Identifier, Identifier, Expr, Reference, Info),
523    Infer(Identifier, Identifier, Expr, Reference, Info),
524}
525
526impl Display for ChirrtlMemoryPort {
527    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
528        match self {
529            ChirrtlMemoryPort::Write(port_name, mem_name, addr, clk, info) => {
530                write!(f, "write mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
531            }
532            ChirrtlMemoryPort::Read(port_name, mem_name, addr, clk, info) => {
533                write!(f, "read mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
534            }
535            ChirrtlMemoryPort::Infer(port_name, mem_name, addr, clk, info) => {
536                write!(f, "infer mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
537            }
538        }
539    }
540}
541
542pub type Stmts = Vec<Box<Stmt>>;
543
544#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
545pub enum Stmt {
546    Skip(Info),
547    Wire(Identifier, Type, Info),
548    Reg(Identifier,  Type, Expr, Info),
549    RegReset(Identifier, Type, Expr, Expr, Expr, Info),
550    ChirrtlMemory(ChirrtlMemory),
551    ChirrtlMemoryPort(ChirrtlMemoryPort),
552    Inst(Identifier, Identifier, Info),
553    Node(Identifier, Expr, Info),
554    Connect(Expr, Expr, Info),
555    Invalidate(Expr, Info),
556    When(Expr, Info, Stmts, Option<Stmts>),
557    Printf(Expr, Expr, String, Option<Exprs>, Info),
558    Assert(Expr, Expr, Expr, String, Info),
559// Memory()
560// Stop(Expr, Expr, u64, Info),
561// Stop(Expr, Expr, u64, Info),
562// Define(Define, Reference, Probe, Info),
563// Define(Define, Reference, Expr, Probe, Info),
564// Attach(References)
565// Connect(Reference, Read, Expr, Info),
566// Reference <- ???
567}
568
569impl Stmt {
570    pub fn traverse(&self) {
571        match self {
572            Self::When(e, i, tstmts, fstmts_opt) => {
573                println!("When, {:?}, {:?}", e, i);
574                for tstmt in tstmts.iter() {
575                    println!("{:?}", tstmt);
576                }
577                match fstmts_opt {
578                    Some(fstmts) => {
579                        println!("ELSE");
580                        for fstmt in fstmts.iter() {
581                            println!("{:?}", fstmt);
582                        }
583                    }
584                    None => {
585                    }
586                }
587            }
588            _ => {
589                println!("{:?}", self);
590            }
591        }
592    }
593}
594
595impl Display for Stmt {
596    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
597        match self {
598            Stmt::Skip(info) => write!(f, "skip {}", info),
599            Stmt::Wire(name, tpe, info) => write!(f, "wire {} : {} {}", name, tpe, info),
600            Stmt::Reg(name, tpe, clk, info) => write!(f, "reg {} : {}, {} {}", name, tpe, clk, info),
601            Stmt::RegReset(name, tpe, clk, rst, init, info) => write!(f, "reg {} : {}, {}, {}, {} {}", name, tpe, clk, rst, init, info),
602            Stmt::ChirrtlMemory(cm) => write!(f, "{}", cm),
603            Stmt::ChirrtlMemoryPort(cmp) => write!(f, "{}", cmp),
604            Stmt::Inst(inst, module, info) => write!(f, "{} of {} {}", inst, module, info),
605            Stmt::Node(name, expr, info) => write!(f, "node {} = {} {}", name, expr, info),
606            Stmt::Connect(lhs, rhs, info) => write!(f, "connect {}, {} {}", lhs, rhs, info),
607            Stmt::Invalidate(reference, info) => write!(f, "invalidate {} {}", reference, info),
608            Stmt::Printf(clk, clk_val, msg, fields_opt, info) => {
609                if let Some(fields) = fields_opt {
610                    write!(f, "printf({}, {}, {}, {}) : {}", clk, clk_val, msg, fmt_exprs(fields), info)
611                } else {
612                    write!(f, "printf({}, {}, {}) : {}", clk, clk_val, msg, info)
613                }
614            }
615            Stmt::Assert(clk, cond, cond_val, msg, info) => {
616                write!(f, "assert({}, {}, {}, {}) : {}", clk, cond, cond_val, msg, info)
617            }
618            Stmt::When(cond, info, when_stmts, else_stmts_opt) => {
619                // NOTE: Cannot track indent inside the Display trait, so this will cause weirdly
620                // indented stuff
621                writeln!(f, "when {} : {}", cond, info)?;
622                for stmt in when_stmts.iter() {
623                    writeln!(f, "{}{}", " ".repeat(2), stmt)?;
624                }
625                if let Some(else_stmts) = else_stmts_opt {
626                    writeln!(f, "else :")?;
627                    for stmt in else_stmts.iter() {
628                        writeln!(f, "{}{}", " ".repeat(2), stmt)?;
629                    }
630                }
631                Ok(())
632            }
633        }
634    }
635}
636
637#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
638pub enum Port {
639    Input(Identifier, Type, Info),
640    Output(Identifier, Type, Info),
641}
642
643impl Display for Port {
644    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
645        match self {
646            Self::Input(id, tpe, info) => {
647                write!(f, "input {} : {} {}", id, tpe, info)
648            }
649            Self::Output(id, tpe, info) => {
650                write!(f, "output {} : {} {}", id, tpe, info)
651            }
652        }
653    }
654}
655
656pub type Ports = Vec<Box<Port>>;
657
658#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
659pub struct Module  {
660    pub name: Identifier,
661    pub ports: Ports,
662    pub stmts: Stmts,
663    pub info: Info,
664}
665
666impl Module {
667    pub fn new(name: Identifier, ports: Ports, stmts: Stmts, info: Info) -> Self {
668        Self { name, ports, stmts, info, }
669    }
670}
671
672#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
673pub struct DefName(Identifier);
674
675impl From<Identifier> for DefName {
676    fn from(value: Identifier) -> Self {
677        Self(value)
678    }
679}
680
681impl Display for DefName {
682    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
683        write!(f, "defname = {}", self.0)
684    }
685}
686
687pub type Parameters = Vec<Box<Parameter>>;
688
689#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
690pub enum Parameter {
691    IntParam(Identifier, Int),
692    FloatParam(Identifier, Float),
693    StringParam(Identifier, String),
694}
695
696impl Display for Parameter {
697    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
698        match self {
699            Self::IntParam(name, value) => write!(f, "parameter {} = {:?}", name, value),
700            Self::FloatParam(name, value) => write!(f, "parameter {} = {}", name, value),
701            Self::StringParam(name, value) => write!(f, "parameter {} = {}", name, value),
702        }
703    }
704}
705
706#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
707pub struct ExtModule {
708    pub name: Identifier,
709    pub ports: Ports,
710    pub defname: DefName,
711    pub params: Parameters,
712    pub info: Info,
713}
714
715impl ExtModule {
716    pub fn new(name: Identifier, ports: Ports, defname: DefName, params: Parameters, info: Info) -> Self {
717        Self { name, ports, defname, params, info }
718    }
719}
720
721#[allow(dead_code)]
722pub struct IntModule {
723    pub name: Identifier,
724    pub ports: Ports,
725    pub params: Parameters,
726    pub info: Info,
727}
728
729#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
730pub enum CircuitModule {
731    Module(Module),
732    ExtModule(ExtModule),
733// IntModule(IntModule),
734}
735
736pub type CircuitModules = Vec<Box<CircuitModule>>;
737
738#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
739pub struct Annotations(pub serde_json::Value);
740
741impl Annotations {
742    pub fn from_str(input: String) -> Self {
743        let input = "[".to_owned() + &input + "]";
744        Self { 0: serde_json::from_str(&input).unwrap() }
745    }
746}
747
748#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
749pub struct Version(pub u32, pub u32, pub u32);
750
751impl Display for Version {
752    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
753        write!(f, "Version {}.{}.{}", self.0, self.1, self.2)
754    }
755}
756
757#[derive(Debug, Clone, Eq, PartialEq, Hash)]
758pub struct Circuit {
759    pub version: Version,
760    pub name: Identifier,
761    pub annos: Annotations,
762    pub modules: CircuitModules,
763}
764
765impl Circuit {
766    pub fn new(version: Version, name: Identifier, annos: Annotations, modules: CircuitModules) -> Self {
767        Self { version, name, annos, modules }
768    }
769}