mimium_lang/ast/
statement.rs1use crate::{
2 ast::Expr,
3 interner::ExprNodeId,
4 pattern::{TypedId, TypedPattern},
5 utils::metadata::{Location, Span},
6};
7
8use super::StageKind;
9#[derive(Clone, Debug, PartialEq)]
13pub enum Statement {
14 Let(TypedPattern, ExprNodeId),
15 LetRec(TypedId, ExprNodeId),
16 Assign(ExprNodeId, ExprNodeId),
17 Single(ExprNodeId),
18 DeclareStage(StageKind),
19 Error,
20}
21
22pub fn stmt_from_expr_top(expr: ExprNodeId) -> Vec<Statement> {
23 let mut res = vec![];
24 stmt_from_expr(expr, &mut res);
25 res
26}
27fn stmt_from_expr(expr: ExprNodeId, target: &mut Vec<Statement>) {
28 match expr.to_expr() {
29 Expr::Let(pat, e, then_opt) => {
30 target.push(Statement::Let(pat, e));
31 if let Some(then) = then_opt {
32 stmt_from_expr(then, target);
33 }
34 }
35 Expr::LetRec(id, e, then_opt) => {
36 target.push(Statement::LetRec(id, e));
37 if let Some(then) = then_opt {
38 stmt_from_expr(then, target);
39 }
40 }
41 _ => target.push(Statement::Single(expr)),
42 }
43}
44
45pub(crate) fn into_then_expr(stmts: &[(Statement, Location)]) -> Option<ExprNodeId> {
47 type ClsType = Box<dyn FnOnce(Option<ExprNodeId>) -> Option<ExprNodeId>>;
51 let mut last_stage = StageKind::Main;
52 let mut closures = Vec::<ClsType>::new();
53 for (stmt, loc) in stmts.iter() {
54 let stmt = stmt.clone();
55 let loc = loc.clone();
56 let cls = match stmt {
57 Statement::Let(typed_pattern, expr_node_id) => Box::new(move |then| {
58 Some(Expr::Let(typed_pattern.clone(), expr_node_id, then).into_id(loc.clone()))
59 }) as ClsType,
60 Statement::LetRec(typed_id, expr_node_id) => Box::new(move |then| {
61 Some(Expr::LetRec(typed_id.clone(), expr_node_id, then).into_id(loc.clone()))
62 }) as ClsType,
63 Statement::Assign(expr_node_id, expr_node_id1) => Box::new(move |then| {
64 Some(
65 Expr::Then(
66 Expr::Assign(expr_node_id, expr_node_id1).into_id(loc.clone()),
67 then,
68 )
69 .into_id(loc.clone()),
70 )
71 }) as ClsType,
72 Statement::Single(expr_node_id) => {
73 Box::new(move |then: Option<ExprNodeId>| match then {
74 None => Some(expr_node_id),
75 Some(t) => Some(Expr::Then(expr_node_id, Some(t)).into_id(loc.clone())),
76 }) as ClsType
77 }
78 Statement::DeclareStage(stage_kind) => {
79 let res = match (&last_stage, stage_kind.clone()) {
80 (StageKind::Macro, StageKind::Main) => {
81 Box::new(|then: Option<_>| then.map(|e| Expr::Bracket(e).into_id(loc)))
82 as ClsType
83 }
84 (StageKind::Main, StageKind::Macro) => {
85 Box::new(|then: Option<_>| then.map(|e| Expr::Escape(e).into_id(loc)))
86 as ClsType
87 }
88 (StageKind::Persistent, _) => {
89 log::warn!("Persistent stage declaration is not supported yet,ignored");
90 Box::new(move |then: Option<ExprNodeId>| then) as ClsType
91 }
92 (_, _) => Box::new(move |then: Option<ExprNodeId>| then) as ClsType,
93 };
94 last_stage = stage_kind.clone();
95 res
96 }
97 Statement::Error => Box::new(move |then| {
98 Some(Expr::Then(Expr::Error.into_id(loc.clone()), then).into_id(loc.clone()))
99 }) as ClsType,
100 };
101 closures.push(cls);
102 }
103 let e_pre = closures
104 .into_iter()
105 .rev()
106 .fold(None, move |then, cls: ClsType| cls(then));
107 e_pre
109}