tangled
alpha
login
or
join now
oppi.li
/
tbsp
5
fork
atom
tree-based source processing language
5
fork
atom
overview
issues
pulls
pipelines
add list::push and list::pop
oppi.li
2 years ago
90473b06
7b5f9b93
+52
-4
2 changed files
expand all
collapse all
unified
split
src
builtins.rs
eval.rs
+44
src/builtins.rs
reviewed
···
39
39
// list
40
40
length,
41
41
member,
42
42
+
push,
43
43
+
pop,
42
44
}
43
45
44
46
fn print(ctx: &mut Context, args: &[ast::Expr]) -> Result {
···
150
152
.any(|item| item == &element)
151
153
.wrap(Value::Boolean)
152
154
.wrap(Ok)
155
155
+
}
156
156
+
157
157
+
fn push(ctx: &mut Context, args: &[ast::Expr]) -> Result {
158
158
+
let [lhs, rhs] = get_args::<2>(args)?;
159
159
+
let ast::Expr::Ident(ident) = lhs else {
160
160
+
return Err(Error::MalformedExpr(format!(
161
161
+
"malformed assigment, lhs: {:?}",
162
162
+
lhs
163
163
+
)));
164
164
+
};
165
165
+
let element = ctx.eval_expr(&rhs)?;
166
166
+
let variable = ctx.lookup_mut(ident)?;
167
167
+
variable.mutate(|v| match &mut v.value {
168
168
+
Value::List(l) => {
169
169
+
l.push(element);
170
170
+
Ok(Value::Unit)
171
171
+
}
172
172
+
_ => Err(Error::TypeMismatch {
173
173
+
expected: ast::Type::List,
174
174
+
got: v.ty().clone(),
175
175
+
}),
176
176
+
})
177
177
+
}
178
178
+
179
179
+
fn pop(ctx: &mut Context, args: &[ast::Expr]) -> Result {
180
180
+
let [lhs] = get_args::<1>(args)?;
181
181
+
let ast::Expr::Ident(ident) = lhs else {
182
182
+
return Err(Error::MalformedExpr(format!(
183
183
+
"malformed assigment, lhs: {:?}",
184
184
+
lhs
185
185
+
)));
186
186
+
};
187
187
+
let variable = ctx.lookup_mut(ident)?;
188
188
+
variable.mutate(|v| match &mut v.value {
189
189
+
Value::List(l) => l
190
190
+
.pop()
191
191
+
.ok_or_else(|| Error::ArrayOutOfBounds { idx: 0, len: 0 }),
192
192
+
_ => Err(Error::TypeMismatch {
193
193
+
expected: ast::Type::List,
194
194
+
got: v.ty().clone(),
195
195
+
}),
196
196
+
})
153
197
}
154
198
155
199
fn get_args<const N: usize>(args: &[ast::Expr]) -> std::result::Result<&[ast::Expr; N], Error> {
+8
-4
src/eval.rs
reviewed
···
15
15
&self.value
16
16
}
17
17
18
18
-
fn ty(&self) -> &ast::Type {
18
18
+
pub(crate) fn ty(&self) -> &ast::Type {
19
19
&self.ty
20
20
}
21
21
···
30
30
})
31
31
}
32
32
}
33
33
+
34
34
+
pub(crate) fn mutate(&mut self, f: impl FnOnce(&mut Self) -> Result) -> Result {
35
35
+
f(self)
36
36
+
}
33
37
}
34
38
35
39
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
···
45
49
type NodeId = usize;
46
50
47
51
impl Value {
48
48
-
fn ty(&self) -> ast::Type {
52
52
+
pub(crate) fn ty(&self) -> ast::Type {
49
53
match self {
50
54
Self::Unit => ast::Type::Unit,
51
55
Self::Integer(_) => ast::Type::Integer,
···
562
566
.wrap_ok()
563
567
}
564
568
565
565
-
fn lookup(&mut self, ident: &ast::Identifier) -> std::result::Result<&Variable, Error> {
569
569
+
pub(crate) fn lookup(&mut self, ident: &ast::Identifier) -> std::result::Result<&Variable, Error> {
566
570
self.variables
567
571
.get(ident)
568
572
.ok_or_else(|| Error::FailedLookup(ident.to_owned()))
569
573
}
570
574
571
571
-
fn lookup_mut(&mut self, ident: &ast::Identifier) -> std::result::Result<&mut Variable, Error> {
575
575
+
pub(crate) fn lookup_mut(&mut self, ident: &ast::Identifier) -> std::result::Result<&mut Variable, Error> {
572
576
self.variables
573
577
.get_mut(ident)
574
578
.ok_or_else(|| Error::FailedLookup(ident.to_owned()))