1#![allow(clippy::wildcard_imports)]
10use crate::ir::*;
11
12use core::fmt::Debug;
13use std::ops::Range;
14use crate::symbol::Ident;
15use crate::symbol_table::SymbolTable;
16use crate::Span;
17use index_vec::IndexVec;
18use crate::literals::StringLiteral;
19use crate::ir::ids::IdRange;
20
21pub struct Ast {
55 pub branches: IndexVec<BranchId, AttributeNode<BranchDeclaration>>,
57 pub nets: IndexVec<NetId, AttributeNode<Net>>,
58 pub ports: IndexVec<PortId, AttributeNode<Port>>,
59 pub variables: IndexVec<VariableId, AttributeNode<Variable>>,
60 pub parameters: IndexVec<ParameterId, AttributeNode<Parameter>>,
61 pub modules: IndexVec<ModuleId, AttributeNode<Module>>,
62 pub functions: IndexVec<FunctionId, AttributeNode<Function>>,
63 pub disciplines: IndexVec<DisciplineId, AttributeNode<Discipline>>,
64 pub natures: IndexVec<NatureId, AttributeNode<Nature>>,
65 pub expressions: IndexVec<ExpressionId, Node<Expression>>,
67 pub blocks: IndexVec<BlockId, AttributeNode<SeqBlock>>,
68 pub attributes: IndexVec<AttributeId, Attribute>,
69 pub statements: IndexVec<StatementId, Statement>,
70 pub top_symbols: SymbolTable,
71}
72
73impl Ast {
74 #[must_use]
75 pub fn new() -> Self {
76 Self {
79 branches: IndexVec::with_capacity(32),
80 nets: IndexVec::with_capacity(32),
81 ports: IndexVec::with_capacity(32),
82 variables: IndexVec::with_capacity(512),
83 parameters: IndexVec::with_capacity(512),
84 modules: IndexVec::with_capacity(1),
85 functions: IndexVec::with_capacity(16),
86 disciplines: IndexVec::with_capacity(8),
87 natures: IndexVec::with_capacity(8),
88 expressions: IndexVec::with_capacity(u16::MAX as usize),
89 blocks: IndexVec::with_capacity(32),
90 attributes: IndexVec::with_capacity(128),
91 statements: IndexVec::with_capacity(4096),
92 top_symbols: SymbolTable::with_capacity_and_hasher(32, Default::default()),
93 }
94 }
95}
96
97impl_id_type!(BranchId in Ast::branches -> AttributeNode<BranchDeclaration>);
98
99impl_id_type!(NetId in Ast::nets -> AttributeNode<Net>);
100
101impl_id_type!(PortId in Ast::ports -> AttributeNode<Port>);
102
103impl_id_type!(ParameterId in Ast::parameters -> AttributeNode<Parameter>);
104
105impl_id_type!(VariableId in Ast::variables -> AttributeNode<Variable>);
106
107impl_id_type!(ModuleId in Ast::modules -> AttributeNode<Module>);
108
109impl_id_type!(FunctionId in Ast::functions -> AttributeNode<Function>);
110
111impl_id_type!(DisciplineId in Ast::disciplines -> AttributeNode<Discipline>);
112
113impl_id_type!(ExpressionId in Ast::expressions -> Node<Expression>);
114
115impl_id_type!(AttributeId in Ast::attributes -> Attribute);
116
117impl_id_type!(StatementId in Ast::statements -> Statement);
118
119impl_id_type!(BlockId in Ast::blocks -> AttributeNode<SeqBlock>);
120
121impl_id_type!(NatureId in Ast::natures -> AttributeNode<Nature>);
122
123#[derive(Clone, Debug)]
124pub enum TopNode {
125 Module(ModuleId),
126 Nature(NatureId),
127 Discipline(DisciplineId),
128}
129
130#[derive(Copy, Clone)]
131pub struct Nature {
132 pub name: Ident,
133 pub abstol: ExpressionId,
134 pub units: ExpressionId,
135 pub access: Ident,
136 pub idt_nature: Option<Ident>,
137 pub ddt_nature: Option<Ident>,
138}
139
140pub enum NatureParentType {
141 Nature,
142 DisciplineFlow,
143 DisciplinePotential,
144}
145
146#[derive(Clone)]
147pub struct Module {
148 pub name: Ident,
149 pub port_list: IdRange<PortId>,
150 pub branch_list: IdRange<BranchId>,
151 pub symbol_table: SymbolTable,
152 pub children: Vec<ModuleItem>,
153}
154
155#[derive(Clone, Debug)]
156pub struct Parameter {
157 pub name: Ident,
158 pub parameter_type: ParameterType,
159 pub default_value: ExpressionId,
160}
161
162#[derive(Clone, Debug)]
163pub enum ParameterType {
164 Numerical {
165 parameter_type: VariableType,
166 from_ranges: Vec<Range<NumericalParameterRangeBound<ExpressionId>>>,
167 excluded: Vec<NumericalParameterRangeExclude<ExpressionId>>,
168 },
169 String(
170 ),
172}
173
174#[derive(Clone, Copy, Debug)]
175pub struct Port {
176 pub name: Ident,
177 pub input: bool,
178 pub output: bool,
179 pub discipline: Ident, pub signed: bool,
181 pub net_type: NetType,
182}
183
184impl Default for Port {
185 fn default() -> Self {
186 Self {
187 name: Ident::empty(),
188 input: false,
189 output: false,
190 discipline: Ident::empty(),
191 signed: false,
192 net_type: NetType::UNDECLARED,
193 }
194 }
195}
196
197#[derive(Clone, Debug)]
198pub struct BranchDeclaration {
199 pub name: Ident,
200 pub branch: Branch,
201}
202
203#[derive(Clone, Debug)]
204pub enum Branch {
205 Port(HierarchicalId),
206 NetToGround(HierarchicalId),
207 Nets(HierarchicalId, HierarchicalId),
208}
209
210#[derive(Clone, Copy, Debug)]
211pub enum ModuleItem {
212 AnalogStmt(StatementId),
213 GenerateStatement, }
215
216#[derive(Clone, Copy, Debug)]
217pub struct Discipline {
218 pub name: Ident,
219 pub flow_nature: Option<Ident>,
220 pub potential_nature: Option<Ident>,
221 pub continuous: Option<bool>,
222}
223
224#[derive(Clone, Debug)]
225pub struct Function {
226 pub name: Ident,
227 pub args: Vec<FunctionArg>,
228 pub declarations: SymbolTable,
229 pub return_variable: VariableId,
230 pub body: StatementId,
231}
232
233#[derive(Clone, Debug, PartialEq, Eq, Copy)]
234pub struct FunctionArg {
235 pub name: Ident,
236 pub input: bool,
237 pub output: bool,
238}
239
240#[derive(Debug, Clone, Copy)]
241pub struct Net {
242 pub name: Ident,
243 pub discipline: Ident,
244 pub signed: bool,
245 pub net_type: NetType,
246}
247
248#[derive(Clone, Copy, Debug)]
249pub struct Variable {
250 pub name: Ident,
251 pub variable_type: VariableType,
252 pub default_value: Option<ExpressionId>,
253}
254
255#[derive(Clone, Copy, Debug, PartialEq, Eq)]
256pub enum NetType {
257 UNDECLARED,
258 REG,
259 WREAL,
260 SUPPLY0,
261 SUPPLY1,
262 TRI,
263 TRIAND,
264 TRIOR,
265 TRI0,
266 TRI1,
267 WIRE,
268 UWIRE,
269 WAND,
270 WOR,
271 GROUND,
272}
273
274#[derive(Clone, Debug)]
275pub enum Statement {
276 Block(BlockId),
277 Condition(AttributeNode<Condition>),
278 Contribute(Attributes, Ident, Node<BranchAccess>, ExpressionId),
279 Assign(Attributes, HierarchicalId, ExpressionId),
281 FunctionCall(Attributes, HierarchicalId, Vec<ExpressionId>),
282 While(AttributeNode<WhileLoop>),
283 DisplayTask(DisplayTaskKind, Vec<ExpressionId>),
284}
285
286#[derive(Clone)]
287pub struct SeqBlock {
288 pub scope: Option<BlockScope>,
289 pub statements: Vec<StatementId>,
290}
291
292#[derive(Clone, Debug)]
293pub struct BlockScope {
294 pub name: Ident,
295 pub symbols: SymbolTable,
296}
297
298#[derive(Clone, Copy, Debug)]
299pub struct WhileLoop {
300 pub condition: ExpressionId,
301 pub body: StatementId,
302}
303
304#[derive(Clone, Debug)]
305pub struct Condition {
306 pub condition: ExpressionId,
307 pub if_statement: StatementId,
308 pub else_statement: Option<StatementId>,
309}
310
311#[derive(Clone, Debug)]
312pub enum Expression {
313 BinaryOperator(ExpressionId, Node<BinaryOperator>, ExpressionId),
314 UnaryOperator(Node<UnaryOperator>, ExpressionId),
315 Condtion(ExpressionId, Span, ExpressionId, Span, ExpressionId),
316 Primary(Primary),
317}
318
319#[derive(Clone, Debug)]
320pub enum BranchAccess {
321 BranchOrNodePotential(HierarchicalId),
322 Implicit(Branch),
323}
324
325#[derive(Clone, Debug)]
326pub enum Primary {
327 Integer(i64),
328 UnsignedInteger(u32),
329 Real(f64),
330 String(StringLiteral),
331 VariableOrNetReference(HierarchicalId),
332 FunctionCall(HierarchicalId, Vec<ExpressionId>),
333 SystemFunctionCall(
334 SystemFunctionCall<ExpressionId, ExpressionId, HierarchicalId, HierarchicalId>,
335 ),
336 BranchAccess(Ident, Node<BranchAccess>),
337 BuiltInFunctionCall1p(BuiltInFunctionCall1p, ExpressionId),
338 BuiltInFunctionCall2p(BuiltInFunctionCall2p, ExpressionId, ExpressionId),
339 Noise(NoiseSource<ExpressionId, ()>, Option<StringLiteral>),
340 DerivativeByBranch(ExpressionId, Ident, Node<BranchAccess>),
341 DerivativeByTime(ExpressionId),
342 DerivativeByTemperature(ExpressionId),
343}
344
345#[derive(Clone, Copy, Debug, PartialEq, Eq)]
346pub enum BinaryOperator {
347 Sum,
348 Subtract,
349 Multiply,
350 Divide,
351 Exponent,
352 Modulus,
353
354 ShiftLeft,
355 ShiftRight,
356
357 LessThen,
358 LessEqual,
359 GreaterThen,
360 GreaterEqual,
361 LogicEqual,
362 LogicalNotEqual,
363
364 LogicOr,
365 LogicAnd,
366
367 Xor,
368 NXor,
369 And,
370 Or,
371}
372
373#[derive(Clone, Copy, Debug, PartialEq, Eq)]
374pub enum UnaryOperator {
375 BitNegate,
376 LogicNegate,
377 ArithmeticNegate,
378 ExplicitPositive,
379}
380
381#[derive(Clone, Copy, Debug, PartialEq, Eq)]
382pub enum VariableType {
383 INTEGER,
384 REAL,
385}
386
387#[derive(Clone, Debug)]
388pub struct HierarchicalId {
389 pub names: Vec<Ident>,
390}
391
392impl HierarchicalId {
393 #[must_use]
394 pub fn span(&self) -> Span {
395 self.names[0]
396 .span
397 .extend(self.names[self.names.len() - 1].span)
398 }
399}
400impl From<Vec<Ident>> for HierarchicalId {
401 fn from(raw: Vec<Ident>) -> Self {
402 Self { names: raw }
403 }
404}