Skip to content

Commit 6dc38ab

Browse files
committed
if
1 parent ba8130d commit 6dc38ab

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ It features:
1010
- [ ] Closures with `lambda`.
1111
- [x] Global variables with `define`.
1212
- [x] Local variables with `let`.
13-
- [ ] Flow control with `if`.
13+
- [x] Flow control with `if`.
1414

1515
## Usage
1616

Diff for: src/glisp.gleam

+22-2
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ fn new_state() -> State {
135135
#("not", Procedure(not_builtin)),
136136
#("and", Procedure(and_builtin)),
137137
#("or", Procedure(or_builtin)),
138+
#("if", Procedure(if_builtin)),
138139
#("define", Procedure(define_builtin)),
139140
])
140141
let local_scope = map.new()
@@ -351,6 +352,16 @@ fn or_builtin(expressions: List(Expression), state: State) -> Evaluated {
351352
}
352353
}
353354

355+
fn if_builtin(expressions: List(Expression), state: State) -> Evaluated {
356+
try #(condition, then, else) = expect_3(expressions)
357+
try #(condition, state) = evaluate_expression(condition, state)
358+
try bool = expect_bool(condition)
359+
case bool {
360+
True -> evaluate_expression(then, state)
361+
False -> evaluate_expression(else, state)
362+
}
363+
}
364+
354365
fn type_error(expected: String, value: Expression) -> Result(anything, Error) {
355366
Error(TypeError(expected: expected, got: type_name(value), value: value))
356367
}
@@ -399,7 +410,16 @@ fn expect_2(
399410
) -> Result(#(Expression, Expression), Error) {
400411
case expressions {
401412
[x, y] -> Ok(#(x, y))
402-
_ -> arity_error(1, expressions)
413+
_ -> arity_error(2, expressions)
414+
}
415+
}
416+
417+
fn expect_3(
418+
expressions: List(Expression),
419+
) -> Result(#(Expression, Expression, Expression), Error) {
420+
case expressions {
421+
[x, y, z] -> Ok(#(x, y, z))
422+
_ -> arity_error(3, expressions)
403423
}
404424
}
405425

@@ -419,7 +439,7 @@ fn print(value: Expression) -> String {
419439
Bool(True) -> "true"
420440
Bool(False) -> "false"
421441
List(xs) -> "'(" <> string.join(list.map(xs, print), " ") <> ")"
422-
Procedure(_) -> "#procedure"
442+
Procedure(_) -> "#<procedure>"
423443
Atom(x) -> "'" <> x
424444
}
425445
}

Diff for: test/glisp_test.gleam

+15-4
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,20 @@ pub fn let_nested_test() {
181181
// Here x is defined in both lets. The inner one does not leak
182182
assert Ok("1") =
183183
glisp.eval(
184-
"
185-
(let ((x 1)
186-
(y (let ((x 2)) x)))
187-
x)",
184+
"(let ((x 1)
185+
(y (let ((x 2)) x)))
186+
x)",
188187
)
189188
}
189+
190+
pub fn procedure_printing_test() {
191+
assert Ok("#<procedure>") = glisp.eval("let")
192+
}
193+
194+
pub fn if_true_test() {
195+
assert Ok("2") = glisp.eval("(if (= 1 1) (+ 1 1) (+ 2 2))")
196+
}
197+
198+
pub fn if_false_test() {
199+
assert Ok("4") = glisp.eval("(if (= 1 2) (+ 1 1) (+ 2 2))")
200+
}

0 commit comments

Comments
 (0)