shell: primitives 'and' and 'or'

This commit is contained in:
Kartik K. Agaram 2021-04-25 22:19:00 -07:00
parent bd9c1e6a79
commit 891083c44d
2 changed files with 87 additions and 11 deletions

View File

@ -12,16 +12,6 @@
(hline1 screen y 0 (width screen) color)))
(vline . (fn () (screen y color)
(vline1 screen y 0 (height screen) color)))
(andf . (fn () (a b)
(if a
(if b
1
())
())))
(orf . (fn () (a b)
(if a
a
b)))
(brline . (fn () (screen x0 y0 x1 y1 color)
((fn (dx dy sx sy)
((fn (err)
@ -32,7 +22,7 @@
(sgn (- x1 x0))
(sgn (- y1 y0)))))
(brline1 . (fn () (screen x y xmax ymax dx dy sx sy err color)
(while (orf (< x xmax) (< y ymax))
(while (or (< x xmax) (< y ymax))
(pixel screen x y color)
((fn (e2)
(if (>= e2 dy)

View File

@ -248,6 +248,92 @@ fn evaluate _in: (addr handle cell), out: (addr handle cell), env-h: (handle cel
trace-higher trace
return
}
$evaluate:and: {
var expr/esi: (addr cell) <- copy in-addr
# if its first elem is not "and", break
var first-ah/ecx: (addr handle cell) <- get in-addr, left
var rest-ah/edx: (addr handle cell) <- get in-addr, right
var first/eax: (addr cell) <- lookup *first-ah
var first-type/ecx: (addr int) <- get first, type
compare *first-type, 2/symbol
break-if-!=
var sym-data-ah/eax: (addr handle stream byte) <- get first, text-data
var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah
var and?/eax: boolean <- stream-data-equal? sym-data, "and"
compare and?, 0/false
break-if-=
#
trace-text trace, "eval", "and"
trace-text trace, "eval", "evaluating first arg"
var rest/eax: (addr cell) <- lookup *rest-ah
var first-arg-ah/ecx: (addr handle cell) <- get rest, left
debug-print "R2", 4/fg, 0/bg
increment call-number
evaluate first-arg-ah, out, env-h, globals, trace, screen-cell, keyboard-cell, call-number
debug-print "S2", 4/fg, 0/bg
# if first arg is nil, short-circuit
var out-ah/eax: (addr handle cell) <- copy out
var out-a/eax: (addr cell) <- lookup *out-ah
var nil?/eax: boolean <- nil? out-a
compare nil?, 0/false
{
break-if-=
return
}
var rest/eax: (addr cell) <- lookup *rest-ah
rest-ah <- get rest, right
rest <- lookup *rest-ah
var second-ah/eax: (addr handle cell) <- get rest, left
debug-print "T2", 4/fg, 0/bg
increment call-number
evaluate second-ah, out, env-h, globals, trace, screen-cell, keyboard-cell, call-number
debug-print "U2", 4/fg, 0/bg
trace-higher trace
return
}
$evaluate:or: {
var expr/esi: (addr cell) <- copy in-addr
# if its first elem is not "or", break
var first-ah/ecx: (addr handle cell) <- get in-addr, left
var rest-ah/edx: (addr handle cell) <- get in-addr, right
var first/eax: (addr cell) <- lookup *first-ah
var first-type/ecx: (addr int) <- get first, type
compare *first-type, 2/symbol
break-if-!=
var sym-data-ah/eax: (addr handle stream byte) <- get first, text-data
var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah
var or?/eax: boolean <- stream-data-equal? sym-data, "or"
compare or?, 0/false
break-if-=
#
trace-text trace, "eval", "or"
trace-text trace, "eval", "evaluating first arg"
var rest/eax: (addr cell) <- lookup *rest-ah
var first-arg-ah/ecx: (addr handle cell) <- get rest, left
debug-print "R2", 4/fg, 0/bg
increment call-number
evaluate first-arg-ah, out, env-h, globals, trace, screen-cell, keyboard-cell, call-number
debug-print "S2", 4/fg, 0/bg
# if first arg is not nil, short-circuit
var out-ah/eax: (addr handle cell) <- copy out
var out-a/eax: (addr cell) <- lookup *out-ah
var nil?/eax: boolean <- nil? out-a
compare nil?, 0/false
{
break-if-!=
return
}
var rest/eax: (addr cell) <- lookup *rest-ah
rest-ah <- get rest, right
rest <- lookup *rest-ah
var second-ah/eax: (addr handle cell) <- get rest, left
debug-print "T2", 4/fg, 0/bg
increment call-number
evaluate second-ah, out, env-h, globals, trace, screen-cell, keyboard-cell, call-number
debug-print "U2", 4/fg, 0/bg
trace-higher trace
return
}
$evaluate:if: {
# trees starting with "if" are conditionals
var expr/esi: (addr cell) <- copy in-addr