claw_ast/
component.rs

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/// Each Claw source file represents a Component
28/// and this struct represents the root of the AST.
29#[derive(Debug)]
30pub struct Component {
31    pub src: Source,
32
33    // Top level items
34    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    // Inner items
40    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///
139#[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    /// The first name is the imported item's name
155    /// The second optional name is an alias
156    pub items: Vec<(NameId, Option<NameId>)>,
157    pub package: PackageName,
158    pub interface: String,
159}
160
161///
162#[derive(Debug, PartialEq, Eq, Clone)]
163pub enum ExternalType {
164    Function(FnType),
165}
166
167///
168#[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///
178#[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}