1use std::collections::HashMap;
2
3use cranelift_entity::{entity_impl, PrimaryMap};
4
5use crate::{expressions::ExpressionData, PackageName, TypeDefId, TypeDefinition};
6use claw_common::Source;
7
8use super::{
9 expressions::ExpressionId,
10 statements::{Let, Statement, StatementId},
11 types::FnType,
12 NameId, Span, TypeId, ValType,
13};
14
15#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
16pub struct ImportId(u32);
17entity_impl!(ImportId, "import");
18
19#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
20pub struct GlobalId(u32);
21entity_impl!(GlobalId, "global");
22
23#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
24pub struct FunctionId(u32);
25entity_impl!(FunctionId, "func");
26
27#[derive(Debug)]
30pub struct Component {
31 pub src: Source,
32
33 pub imports: PrimaryMap<ImportId, Import>,
35 pub type_defs: PrimaryMap<TypeDefId, TypeDefinition>,
36 pub globals: PrimaryMap<GlobalId, Global>,
37 pub functions: PrimaryMap<FunctionId, Function>,
38
39 pub types: PrimaryMap<TypeId, ValType>,
41 pub type_spans: HashMap<TypeId, Span>,
42
43 pub statements: PrimaryMap<StatementId, Statement>,
44 pub statement_spans: HashMap<StatementId, Span>,
45
46 pub expression_data: ExpressionData,
47
48 pub names: PrimaryMap<NameId, String>,
49 pub name_spans: HashMap<NameId, Span>,
50}
51
52impl Component {
53 pub fn new(src: Source) -> Self {
54 Self {
55 src,
56 imports: Default::default(),
57 type_defs: Default::default(),
58 globals: Default::default(),
59 functions: Default::default(),
60 types: Default::default(),
61 type_spans: Default::default(),
62 statements: Default::default(),
63 statement_spans: Default::default(),
64 expression_data: Default::default(),
65 names: Default::default(),
66 name_spans: Default::default(),
67 }
68 }
69
70 pub fn new_name(&mut self, name: String, span: Span) -> NameId {
71 let id = self.names.push(name);
72 self.name_spans.insert(id, span);
73 id
74 }
75
76 pub fn get_name(&self, id: NameId) -> &str {
77 self.names.get(id).unwrap()
78 }
79
80 pub fn name_span(&self, id: NameId) -> Span {
81 *self.name_spans.get(&id).unwrap()
82 }
83
84 pub fn new_type(&mut self, valtype: ValType, span: Span) -> TypeId {
85 let id = self.types.push(valtype);
86 self.type_spans.insert(id, span);
87 id
88 }
89
90 pub fn get_type(&self, id: TypeId) -> &ValType {
91 self.types.get(id).unwrap()
92 }
93
94 pub fn type_span(&self, id: TypeId) -> Span {
95 *self.type_spans.get(&id).unwrap()
96 }
97
98 pub fn new_statement(&mut self, statement: Statement, span: Span) -> StatementId {
99 let id = self.statements.push(statement);
100 self.statement_spans.insert(id, span);
101 id
102 }
103
104 pub fn get_statement(&self, id: StatementId) -> &Statement {
105 self.statements.get(id).unwrap()
106 }
107
108 pub fn statement_span(&self, id: StatementId) -> Span {
109 *self.statement_spans.get(&id).unwrap()
110 }
111
112 pub fn alloc_let(
113 &mut self,
114 mutable: bool,
115 ident: NameId,
116 annotation: Option<TypeId>,
117 expression: ExpressionId,
118 span: Span,
119 ) -> StatementId {
120 let let_ = Let {
121 mutable,
122 ident,
123 annotation,
124 expression,
125 };
126 self.new_statement(Statement::Let(let_), span)
127 }
128
129 pub fn expr(&self) -> &ExpressionData {
130 &self.expression_data
131 }
132
133 pub fn expr_mut(&mut self) -> &mut ExpressionData {
134 &mut self.expression_data
135 }
136}
137
138#[derive(Debug, PartialEq, Eq, Clone)]
140pub enum Import {
141 Plain(PlainImport),
142 ImportFrom(ImportFrom),
143}
144
145#[derive(Debug, PartialEq, Eq, Clone)]
146pub struct PlainImport {
147 pub ident: NameId,
148 pub alias: Option<NameId>,
149 pub external_type: ExternalType,
150}
151
152#[derive(Debug, PartialEq, Eq, Clone)]
153pub struct ImportFrom {
154 pub items: Vec<(NameId, Option<NameId>)>,
157 pub package: PackageName,
158 pub interface: String,
159}
160
161#[derive(Debug, PartialEq, Eq, Clone)]
163pub enum ExternalType {
164 Function(FnType),
165}
166
167#[derive(Debug)]
169pub struct Function {
170 pub exported: bool,
171 pub ident: NameId,
172 pub params: Vec<(NameId, TypeId)>,
173 pub results: Option<TypeId>,
174 pub body: Vec<StatementId>,
175}
176
177#[derive(Debug, Clone)]
179pub struct Global {
180 pub exported: bool,
181 pub mutable: bool,
182 pub ident: NameId,
183 pub type_id: TypeId,
184 pub init_value: ExpressionId,
185}