mirror of
https://github.com/samsonjs/compiler.git
synced 2026-03-25 08:45:52 +00:00
implement lazy boolean OR and AND operators, || and && respectively
This commit is contained in:
parent
f7e44b7472
commit
9b5c3b795e
1 changed files with 48 additions and 24 deletions
64
compiler.rb
64
compiler.rb
|
|
@ -264,39 +264,63 @@ class Compiler
|
|||
# boolean expressions #
|
||||
#######################
|
||||
|
||||
def op(name)
|
||||
asm.push(EAX)
|
||||
expected(name) unless match_word(name)
|
||||
yield
|
||||
asm.add(ESP, 4)
|
||||
end
|
||||
|
||||
def boolean_expression
|
||||
boolean_term
|
||||
while @look == '|'
|
||||
op '||' do
|
||||
scan
|
||||
expected('||') unless match_word('||')
|
||||
|
||||
false_label = asm.mklabel(:false)
|
||||
truthy_label = asm.mklabel(:truthy)
|
||||
done_label = asm.mklabel(:done)
|
||||
|
||||
asm.cmp(EAX, FALSE)
|
||||
asm.jne(truthy_label)
|
||||
|
||||
boolean_term
|
||||
# !!! this method has moved, IMPLEMENT THIS!
|
||||
emit("<logical or>")
|
||||
end
|
||||
asm.cmp(EAX, FALSE)
|
||||
asm.je(false_label)
|
||||
|
||||
asm.deflabel(truthy_label)
|
||||
asm.mov(EAX, TRUE)
|
||||
asm.jmp(done_label)
|
||||
|
||||
asm.deflabel(false_label)
|
||||
asm.mov(EAX, FALSE)
|
||||
|
||||
asm.deflabel(done_label)
|
||||
end
|
||||
end
|
||||
|
||||
def boolean_term
|
||||
not_factor
|
||||
while @look == '&'
|
||||
op '&&' do
|
||||
scan
|
||||
expected('&&') unless match_word('&&')
|
||||
false_label = asm.mklabel(:false)
|
||||
done_label = asm.mklabel(:done)
|
||||
|
||||
asm.cmp(EAX, FALSE)
|
||||
asm.je(false_label)
|
||||
|
||||
not_factor
|
||||
# !!! this method has moved, IMPLEMENT THIS!
|
||||
emit("<logical and>")
|
||||
end
|
||||
asm.cmp(EAX, FALSE)
|
||||
asm.je(false_label)
|
||||
|
||||
asm.mov(EAX, TRUE)
|
||||
asm.jmp(done_label)
|
||||
|
||||
asm.deflabel(false_label)
|
||||
asm.mov(EAX, TRUE)
|
||||
|
||||
asm.deflabel(done_label)
|
||||
end
|
||||
end
|
||||
|
||||
def boolean_factor
|
||||
if boolean?(@look)
|
||||
if get_boolean == 'true'
|
||||
asm.mov(EAX, -1)
|
||||
asm.mov(EAX, TRUE)
|
||||
else
|
||||
asm.xor(EAX, EAX)
|
||||
end
|
||||
|
|
@ -321,9 +345,9 @@ class Compiler
|
|||
# semantically equivalent to !!reg in C or Ruby.
|
||||
def make_boolean(reg=EAX)
|
||||
end_label = asm.mklabel(:endmakebool)
|
||||
asm.cmp(reg, 0) # if false do nothing
|
||||
asm.cmp(reg, FALSE) # if false do nothing
|
||||
asm.jz(end_label)
|
||||
asm.mov(reg, -1) # truthy, make it true
|
||||
asm.mov(reg, TRUE) # truthy, make it true
|
||||
asm.deflabel(end_label)
|
||||
end
|
||||
|
||||
|
|
@ -389,12 +413,12 @@ class Compiler
|
|||
asm.cmp(a, b)
|
||||
asm.jl(true_label)
|
||||
|
||||
asm.xor(EAX, EAX) # return false
|
||||
asm.mov(EAX, FALSE) # return false
|
||||
asm.not_(EAX) if invert # (or true if inverted)
|
||||
asm.jmp(end_label)
|
||||
|
||||
asm.deflabel(true_label)
|
||||
asm.xor(EAX, EAX) # return true
|
||||
asm.mov(EAX, FALSE) # return true
|
||||
asm.not_(EAX) unless invert # (or false if inverted)
|
||||
|
||||
asm.deflabel(end_label)
|
||||
|
|
|
|||
Loading…
Reference in a new issue