bend/imp/
mod.rs

1pub mod gen_map_get;
2mod order_kwargs;
3pub mod parser;
4pub mod to_fun;
5
6use crate::fun::{Name, Num, Op, Source, Type};
7use interner::global::GlobalString;
8
9#[derive(Clone, Debug)]
10pub enum Expr {
11  // "*"
12  Era,
13  // [a-zA-Z_]+
14  Var { nam: Name },
15  // "$" [a-zA-Z_]+
16  Chn { nam: Name },
17  // [0-9_]+
18  Num { val: Num },
19  // {fun}({args},{kwargs},)
20  Call { fun: Box<Expr>, args: Vec<Expr>, kwargs: Vec<(Name, Expr)> },
21  // "lambda" {names}* ":" {bod}
22  Lam { names: Vec<(Name, bool)>, bod: Box<Expr> },
23  // {lhs} {op} {rhs}
24  Opr { op: Op, lhs: Box<Expr>, rhs: Box<Expr> },
25  // "\"" ... "\""
26  Str { val: GlobalString },
27  // "[" ... "]"
28  Lst { els: Vec<Expr> },
29  // "(" ... ")"
30  Tup { els: Vec<Expr> },
31  // "{" {els} "}"
32  Sup { els: Vec<Expr> },
33  // {name} "{" {kwargs} "}"
34  Ctr { name: Name, args: Vec<Expr>, kwargs: Vec<(Name, Expr)> },
35  // "[" {term} "for" {bind} "in" {iter} ("if" {cond})? "]"
36  LstMap { term: Box<Expr>, bind: Name, iter: Box<Expr>, cond: Option<Box<Expr>> },
37  // "{" {entries} "}"
38  Map { entries: Vec<(Expr, Expr)> },
39  // {map} "[" {key} "]"
40  MapGet { nam: Name, key: Box<Expr> },
41  // "![" {left} "," {right} "]"
42  TreeNode { left: Box<Expr>, right: Box<Expr> },
43  // "!" {val}
44  TreeLeaf { val: Box<Expr> },
45}
46
47#[derive(Clone, Debug)]
48pub struct MatchArm {
49  pub lft: Option<Name>,
50  pub rgt: Stmt,
51}
52
53#[derive(Clone, Debug, Default)]
54pub enum AssignPattern {
55  // "*"
56  #[default]
57  Eraser,
58  // [a-zA-Z_]+
59  Var(Name),
60  // "$" [a-zA-Z_]+
61  Chn(Name),
62  // "(" ... ")"
63  Tup(Vec<AssignPattern>),
64  // "{" ... "}"
65  Sup(Vec<AssignPattern>),
66  // {name} "[" {expr} "]"
67  MapSet(Name, Expr),
68}
69
70#[derive(Clone, Debug)]
71pub enum InPlaceOp {
72  Add,
73  Sub,
74  Mul,
75  Div,
76  And,
77  Or,
78  Xor,
79  Map,
80}
81
82#[derive(Clone, Debug, Default)]
83pub enum Stmt {
84  // {pat} = {val} ";"? {nxt}
85  Assign {
86    pat: AssignPattern,
87    val: Box<Expr>,
88    nxt: Option<Box<Stmt>>,
89  },
90  // {var} += {val} ";"? {nxt}
91  InPlace {
92    op: InPlaceOp,
93    pat: Box<AssignPattern>,
94    val: Box<Expr>,
95    nxt: Box<Stmt>,
96  },
97  // "if" {cond} ":"
98  //  {then}
99  // "else" ":"
100  //  {otherwise}
101  // {nxt}?
102  If {
103    cond: Box<Expr>,
104    then: Box<Stmt>,
105    otherwise: Box<Stmt>,
106    nxt: Option<Box<Stmt>>,
107  },
108  // "match" ({bind} "=")? {arg} ("with" (({bind}) | ({bind} "=" {arg}) ","?)*)? ":"
109  //   "case" {lft} ":"
110  //     {rgt}
111  //   ...
112  // <nxt>?
113  Match {
114    arg: Box<Expr>,
115    bnd: Option<Name>,
116    with_bnd: Vec<Option<Name>>,
117    with_arg: Vec<Expr>,
118    arms: Vec<MatchArm>,
119    nxt: Option<Box<Stmt>>,
120  },
121  // "switch" ({bind} "=")? {arg}("with" (({bind}) | ({bind} "=" {arg}) ","?)*)? ":"
122  //   "case" 0 ":"
123  //     {stmt}
124  //   ...
125  //   "case" _ ":"
126  //     {stmt}
127  // <nxt>?
128  Switch {
129    arg: Box<Expr>,
130    bnd: Option<Name>,
131    with_bnd: Vec<Option<Name>>,
132    with_arg: Vec<Expr>,
133    arms: Vec<Stmt>,
134    nxt: Option<Box<Stmt>>,
135  },
136  // "bend" ({bind} ("=" {init})? ","?)*
137  //   "when" {cond} ":"
138  //     {step}
139  //   "else" ":"
140  //     {base}
141  // {nxt}}?
142  Bend {
143    bnd: Vec<Option<Name>>,
144    arg: Vec<Expr>,
145    cond: Box<Expr>,
146    step: Box<Stmt>,
147    base: Box<Stmt>,
148    nxt: Option<Box<Stmt>>,
149  },
150  // "fold" ({bind} "=")? {arg} ("with" (({bind}) | ({bind} "=" {arg}) ","?)*)? ":"
151  //   case {lft} ":"
152  //     {rgt}
153  //   ...
154  // {nxt}?
155  Fold {
156    arg: Box<Expr>,
157    bnd: Option<Name>,
158    with_bnd: Vec<Option<Name>>,
159    with_arg: Vec<Expr>,
160    arms: Vec<MatchArm>,
161    nxt: Option<Box<Stmt>>,
162  },
163  // "with" {typ} ":"
164  //   "ask" {id} = {expr} ";"?
165  //   ...
166  // <nxt>?
167  With {
168    typ: Name,
169    bod: Box<Stmt>,
170    nxt: Option<Box<Stmt>>,
171  },
172  // {pat} <- {val} ";"? {nxt}
173  Ask {
174    pat: AssignPattern,
175    val: Box<Expr>,
176    nxt: Option<Box<Stmt>>,
177  },
178  // "return" {expr} ";"?
179  Return {
180    term: Box<Expr>,
181  },
182  // "open" {typ} ":" {var} ";"? {nxt}
183  Open {
184    typ: Name,
185    var: Name,
186    nxt: Box<Stmt>,
187  },
188  // "use" {name} "=" {expr} ";"? {nxt}
189  Use {
190    nam: Name,
191    val: Box<Expr>,
192    nxt: Box<Stmt>,
193  },
194  // {def} {nxt}
195  LocalDef {
196    def: Box<Definition>,
197    nxt: Box<Stmt>,
198  },
199  #[default]
200  Err,
201}
202
203// "def" {name} "(" {params} ")" ":" {body}
204#[derive(Clone, Debug)]
205pub struct Definition {
206  pub name: Name,
207  pub typ: Type,
208  pub check: bool,
209  pub args: Vec<Name>,
210  pub body: Stmt,
211  pub source: Source,
212}
213
214impl InPlaceOp {
215  pub fn to_lang_op(self) -> Op {
216    match self {
217      InPlaceOp::Add => Op::ADD,
218      InPlaceOp::Sub => Op::SUB,
219      InPlaceOp::Mul => Op::MUL,
220      InPlaceOp::Div => Op::DIV,
221      InPlaceOp::And => Op::AND,
222      InPlaceOp::Or => Op::OR,
223      InPlaceOp::Xor => Op::XOR,
224      InPlaceOp::Map => unreachable!(),
225    }
226  }
227}