aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-08-21 13:50:59 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commit8e425d8aee01ce49d263ce401b46b83ef1a246e8 (patch)
tree54649c182d826d816f8dae1b86bb1e1e65566645
parentmove struct ops into library (diff)
downloadalive-8e425d8aee01ce49d263ce401b46b83ef1a246e8.tar.gz
alive-8e425d8aee01ce49d263ce401b46b83ef1a246e8.zip
fix if, add when
-rw-r--r--alv/builtins.moon38
1 files changed, 35 insertions, 3 deletions
diff --git a/alv/builtins.moon b/alv/builtins.moon
index a0a319a..8a08705 100644
--- a/alv/builtins.moon
+++ b/alv/builtins.moon
@@ -239,7 +239,7 @@ function is invoked."
scope\set name, RTNode :result
super RTNode!
-do_expr = Constant.meta
+do_ = Constant.meta
meta:
name: 'do'
summary: "Evaluate multiple expressions in a new scope."
@@ -278,7 +278,7 @@ to `then-expr`, otherwise it is equivalent to `else-xpr` if given, or nil otherw
if not xif\is_const!
msg = "'if'-expression needs to be constant, did you mean 'switch'?"
error Error 'argument', msg
- xif = xif\result!\unwrap!
+ xif = xif.result\unwrap!
super if xif
xthen\eval scope
@@ -287,6 +287,37 @@ to `then-expr`, otherwise it is equivalent to `else-xpr` if given, or nil otherw
else
RTNode!
+when_ = Constant.meta
+ meta:
+ name: 'when'
+ summary: "Make an evaltime const choice with side effects"
+ examples: { '(when bool then-exprs…)' }
+ description: "
+`bool` has to be an evaltime constant. If it is truthy, this expression is equivalent
+to `(do then-exprs…)`, otherwise it results in nil."
+
+ value: class extends Builtin
+ eval: (scope, tail) =>
+ L\trace "evaling #{@}"
+ assert #tail >= 2, "'when' needs at least two parameters"
+
+ xif = L\push tail[1]\eval, scope
+ if not xif\is_const!
+ msg = "'when'-expression needs to be constant, did you mean 'switch'?"
+ error Error 'argument', msg
+ xif = xif.result\unwrap!
+
+ super if xif
+ scope = Scope scope
+ children = [expr\eval scope for expr in *tail[2,]]
+ result = if last = children[#children] then last.result
+ if result and result.metatype == '='
+ result = result.type\mk_sig result\unwrap!
+
+ RTNode :children, :result
+ else
+ RTNode!
+
switch_ = Constant.meta
meta:
name: 'switch'
@@ -596,8 +627,9 @@ Scope.from_table {
'export*': export_star
:fn, :defn
- 'do': do_expr
+ 'do': do_
'if': if_
+ 'when': when_
'switch': switch_
'=': to_const