mimium_lang/
ast.rs

1pub mod builder;
2pub mod operators;
3pub mod program;
4mod resolve_include;
5pub mod statement;
6use crate::ast::operators::Op;
7use crate::interner::{ExprNodeId, Symbol, TypeNodeId, with_session_globals};
8use crate::pattern::{TypedId, TypedPattern};
9use crate::utils::metadata::{Location, Span};
10use crate::utils::miniprint::MiniPrint;
11use std::fmt::{self};
12pub type Time = i64;
13
14#[derive(Clone, Debug, PartialEq)]
15pub enum StageKind {
16    Persistent = -1,
17    Macro = 0,
18    Main,
19}
20impl std::fmt::Display for StageKind {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        match self {
23            StageKind::Persistent => write!(f, "persistent"),
24            StageKind::Macro => write!(f, "macro"),
25            StageKind::Main => write!(f, "main"),
26        }
27    }
28}
29#[derive(Clone, Debug, PartialEq, Hash)]
30pub enum Literal {
31    String(Symbol),
32    Int(i64),
33    Float(Symbol),
34    SelfLit,
35    Now,
36    SampleRate,
37    PlaceHolder,
38}
39
40impl Expr {
41    fn into_id_inner(self, loc: Option<Location>) -> ExprNodeId {
42        let loc = loc.unwrap_or_default();
43        with_session_globals(|session_globals| session_globals.store_expr_with_location(self, loc))
44    }
45
46    pub fn into_id(self, loc: Location) -> ExprNodeId {
47        self.into_id_inner(Some(loc))
48    }
49
50    // For testing purposes
51    pub fn into_id_without_span(self) -> ExprNodeId {
52        self.into_id_inner(None)
53    }
54}
55
56#[derive(Clone, Debug, PartialEq)]
57pub struct RecordField {
58    pub name: Symbol,
59    pub expr: ExprNodeId,
60}
61
62#[derive(Clone, Debug, PartialEq)]
63pub enum Expr {
64    Literal(Literal), // literal, or special symbols (self, now, _)
65    Var(Symbol),
66    Block(Option<ExprNodeId>),
67    Tuple(Vec<ExprNodeId>),
68    Proj(ExprNodeId, i64),
69    ArrayAccess(ExprNodeId, ExprNodeId),
70    ArrayLiteral(Vec<ExprNodeId>),   // Array literal [e1, e2, ..., en]
71    RecordLiteral(Vec<RecordField>), // Complete record literal {field1 = expr1, field2 = expr2, ...}
72    ImcompleteRecord(Vec<RecordField>), // Incomplete record literal with default values {field1 = expr1, ..}
73    RecordUpdate(ExprNodeId, Vec<RecordField>), // Record update syntax: { record <- field1 = expr1, field2 = expr2, ... }
74    FieldAccess(ExprNodeId, Symbol),            // Record field access: record.field
75    Apply(ExprNodeId, Vec<ExprNodeId>),
76
77    MacroExpand(ExprNodeId, Vec<ExprNodeId>), // syntax sugar: hoge!(a,b) => ${hoge(a,b)}
78    BinOp(ExprNodeId, (Op, Span), ExprNodeId), // syntax sugar: LHS op RHS =>  OP(LHS, RHS) except for pipe operator : RHS(LHS)
79    UniOp((Op, Span), ExprNodeId), // syntax sugar: LHS op RHS =>  OP(LHS, RHS) except for pipe operator : RHS(LHS)
80    Paren(ExprNodeId),             // syntax sugar to preserve context for pretty printing
81
82    Lambda(Vec<TypedId>, Option<TypeNodeId>, ExprNodeId), //lambda, maybe information for internal state is needed
83    Assign(ExprNodeId, ExprNodeId),
84    Then(ExprNodeId, Option<ExprNodeId>),
85    Feed(Symbol, ExprNodeId), //feedback connection primitive operation. This will be shown only after self-removal stage
86    Let(TypedPattern, ExprNodeId, Option<ExprNodeId>),
87    LetRec(TypedId, ExprNodeId, Option<ExprNodeId>),
88    If(ExprNodeId, ExprNodeId, Option<ExprNodeId>),
89    //exprimental macro system using multi-stage computation
90    Bracket(ExprNodeId),
91    Escape(ExprNodeId),
92
93    Error,
94}
95
96impl ExprNodeId {
97    pub fn wrap_to_staged_expr(self) -> Self {
98        // TODO: what if more escape is used than minimum level??
99
100        // let min_level = self.get_min_stage_rec(0);
101        // let res = if min_level < 0 {
102        //     std::iter::repeat_n((), -min_level as usize).fold(self, |wrapped, _level| {
103        //         Expr::Bracket(wrapped).into_id_without_span()
104        //     })
105        // } else {
106        //     self
107        // };
108        //we have to wrap one more time because if there are no macro-related expression, that means stage-1(runtime) code.
109        Expr::Bracket(self).into_id_without_span()
110    }
111    fn get_min_stage_rec(self, current_level: i32) -> i32 {
112        let conv = move |e: &Self| e.get_min_stage_rec(current_level);
113        let conv2 = move |e1: &Self, e2: &Self| {
114            e1.get_min_stage_rec(current_level)
115                .min(e2.get_min_stage_rec(current_level))
116        };
117        let conv_opt = move |e: &Option<Self>| {
118            e.as_ref()
119                .map_or(current_level, |e| e.get_min_stage_rec(current_level))
120        };
121        let convvec = move |es: &[Self]| es.iter().map(conv).min().unwrap_or(current_level);
122        let convfields = move |fs: &[RecordField]| {
123            fs.iter()
124                .map(|f| f.expr.get_min_stage_rec(current_level))
125                .min()
126                .unwrap_or(current_level)
127        };
128        match self.to_expr() {
129            Expr::Bracket(e) => e.get_min_stage_rec(current_level + 1),
130            Expr::Escape(e) => e.get_min_stage_rec(current_level - 1),
131            Expr::MacroExpand(e, args) => conv(&e).min(convvec(&args)) - 1,
132            Expr::Proj(e, _)
133            | Expr::FieldAccess(e, _)
134            | Expr::UniOp(_, e)
135            | Expr::Paren(e)
136            | Expr::Lambda(_, _, e)
137            | Expr::Feed(_, e) => conv(&e),
138            Expr::ArrayAccess(e1, e2) | Expr::BinOp(e1, _, e2) | Expr::Assign(e1, e2) => {
139                conv2(&e1, &e2)
140            }
141            Expr::Block(e) => conv_opt(&e),
142            Expr::Tuple(es) | Expr::ArrayLiteral(es) => convvec(&es),
143
144            Expr::RecordLiteral(fields) | Expr::ImcompleteRecord(fields) => convfields(&fields),
145            Expr::RecordUpdate(e1, fields) => conv(&e1).min(convfields(&fields)),
146            Expr::Apply(e, args) => conv(&e).min(convvec(&args)),
147            Expr::Then(e1, e2) | Expr::Let(_, e1, e2) | Expr::LetRec(_, e1, e2) => {
148                conv(&e1).min(conv_opt(&e2))
149            }
150            Expr::If(cond, then, orelse) => conv(&cond).min(conv(&then)).min(conv_opt(&orelse)),
151
152            _ => current_level,
153        }
154    }
155}
156
157impl fmt::Display for Literal {
158    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159        match self {
160            Literal::Float(n) => write!(f, "(float {})", n),
161            Literal::Int(n) => write!(f, "(int {})", n),
162            Literal::String(s) => write!(f, "\"{}\"", s),
163            Literal::Now => write!(f, "now"),
164            Literal::SampleRate => write!(f, "samplerate"),
165            Literal::SelfLit => write!(f, "self"),
166            Literal::PlaceHolder => write!(f, "_"),
167        }
168    }
169}
170
171impl MiniPrint for Literal {
172    fn simple_print(&self) -> String {
173        self.to_string()
174    }
175}
176
177fn concat_vec<T: MiniPrint>(vec: &[T]) -> String {
178    vec.iter()
179        .map(|t| t.simple_print())
180        .collect::<Vec<_>>()
181        .join(" ")
182}
183
184impl MiniPrint for ExprNodeId {
185    fn simple_print(&self) -> String {
186        let span = self.to_span();
187        format!(
188            "{}:{}..{}",
189            self.to_expr().simple_print(),
190            span.start,
191            span.end
192        )
193    }
194}
195
196impl MiniPrint for Option<ExprNodeId> {
197    fn simple_print(&self) -> String {
198        match self {
199            Some(e) => e.simple_print(),
200            None => "()".to_string(),
201        }
202    }
203}
204
205impl MiniPrint for RecordField {
206    fn simple_print(&self) -> String {
207        format!("{}: {}", self.name, self.expr.simple_print())
208    }
209}
210
211impl MiniPrint for Expr {
212    fn simple_print(&self) -> String {
213        match self {
214            Expr::Literal(l) => l.simple_print(),
215            Expr::Var(v) => format!("{v}"),
216            Expr::Block(e) => e.map_or("".to_string(), |eid| {
217                format!("(block {})", eid.simple_print())
218            }),
219            Expr::Tuple(e) => {
220                let e1 = e.iter().map(|e| e.to_expr().clone()).collect::<Vec<Expr>>();
221                format!("(tuple ({}))", concat_vec(&e1))
222            }
223            Expr::Proj(e, idx) => format!("(proj {} {})", e.simple_print(), idx),
224            Expr::Apply(e1, e2) => {
225                format!("(app {} ({}))", e1.simple_print(), concat_vec(e2))
226            }
227            Expr::MacroExpand(e1, e2s) => {
228                format!("(macro {} ({}))", e1.simple_print(), concat_vec(e2s))
229            }
230            Expr::ArrayAccess(e, i) => {
231                format!("(arrayaccess {} ({}))", e.simple_print(), i.simple_print())
232            }
233            Expr::ArrayLiteral(items) => {
234                let items_str = items
235                    .iter()
236                    .map(|e| e.simple_print())
237                    .collect::<Vec<String>>()
238                    .join(", ");
239                format!("(array [{}])", items_str)
240            }
241            Expr::RecordLiteral(fields) => {
242                let fields_str = fields
243                    .iter()
244                    .map(|f| f.simple_print())
245                    .collect::<Vec<String>>()
246                    .join(", ");
247                format!("(record {{{}}})", fields_str)
248            }
249            Expr::ImcompleteRecord(fields) => {
250                let fields_str = fields
251                    .iter()
252                    .map(|f| f.simple_print())
253                    .collect::<Vec<String>>()
254                    .join(", ");
255                format!("(incomplete-record {{{}, ..}})", fields_str)
256            }
257            Expr::RecordUpdate(record, fields) => {
258                let fields_str = fields
259                    .iter()
260                    .map(|f| f.simple_print())
261                    .collect::<Vec<String>>()
262                    .join(", ");
263                format!(
264                    "(record-update {} {{{}}})",
265                    record.simple_print(),
266                    fields_str
267                )
268            }
269            Expr::FieldAccess(record, field) => {
270                format!("(field-access {} {})", record.simple_print(), field)
271            }
272            Expr::UniOp(op, expr) => {
273                format!("(unary {} {})", op.0, expr.simple_print())
274            }
275            Expr::BinOp(lhs, op, rhs) => {
276                format!(
277                    "(binop {} {} {})",
278                    op.0,
279                    lhs.simple_print(),
280                    rhs.simple_print()
281                )
282            }
283            Expr::Lambda(params, _, body) => {
284                format!("(lambda ({}) {})", concat_vec(params), body.simple_print())
285            }
286            Expr::Feed(id, body) => format!("(feed {} {})", id, body.simple_print()),
287            Expr::Let(id, body, then) => format!(
288                "(let {} {} {})",
289                id.simple_print(),
290                body.simple_print(),
291                then.simple_print()
292            ),
293            Expr::LetRec(id, body, then) => format!(
294                "(letrec {} {} {})",
295                &id.simple_print(),
296                body.simple_print(),
297                then.simple_print()
298            ),
299            Expr::Assign(lid, rhs) => {
300                format!("(assign {} {})", lid.simple_print(), rhs.simple_print())
301            }
302            Expr::Then(first, second) => {
303                format!("(then {} {})", first.simple_print(), second.simple_print())
304            }
305            Expr::If(cond, then, optelse) => format!(
306                "(if {} {} {})",
307                cond.simple_print(),
308                then.simple_print(),
309                optelse.simple_print()
310            ),
311            Expr::Bracket(e) => format!("(bracket {})", e.simple_print()),
312            Expr::Escape(e) => format!("(escape {})", e.simple_print()),
313            Expr::Error => "(error)".to_string(),
314            Expr::Paren(expr_node_id) => format!("(paren {})", expr_node_id.simple_print()),
315        }
316    }
317}