mirror of
https://github.com/samsonjs/compiler.git
synced 2026-04-27 14:57:45 +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
72
compiler.rb
72
compiler.rb
|
|
@ -264,39 +264,63 @@ class Compiler
|
||||||
# boolean expressions #
|
# boolean expressions #
|
||||||
#######################
|
#######################
|
||||||
|
|
||||||
def op(name)
|
|
||||||
asm.push(EAX)
|
|
||||||
expected(name) unless match_word(name)
|
|
||||||
yield
|
|
||||||
asm.add(ESP, 4)
|
|
||||||
end
|
|
||||||
|
|
||||||
def boolean_expression
|
def boolean_expression
|
||||||
boolean_term
|
boolean_term
|
||||||
while @look == '|'
|
while @look == '|'
|
||||||
op '||' do
|
scan
|
||||||
boolean_term
|
expected('||') unless match_word('||')
|
||||||
# !!! this method has moved, IMPLEMENT THIS!
|
|
||||||
emit("<logical or>")
|
false_label = asm.mklabel(:false)
|
||||||
end
|
truthy_label = asm.mklabel(:truthy)
|
||||||
|
done_label = asm.mklabel(:done)
|
||||||
|
|
||||||
|
asm.cmp(EAX, FALSE)
|
||||||
|
asm.jne(truthy_label)
|
||||||
|
|
||||||
|
boolean_term
|
||||||
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
def boolean_term
|
def boolean_term
|
||||||
not_factor
|
not_factor
|
||||||
while @look == '&'
|
while @look == '&'
|
||||||
op '&&' do
|
scan
|
||||||
not_factor
|
expected('&&') unless match_word('&&')
|
||||||
# !!! this method has moved, IMPLEMENT THIS!
|
false_label = asm.mklabel(:false)
|
||||||
emit("<logical and>")
|
done_label = asm.mklabel(:done)
|
||||||
end
|
|
||||||
|
asm.cmp(EAX, FALSE)
|
||||||
|
asm.je(false_label)
|
||||||
|
|
||||||
|
not_factor
|
||||||
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
def boolean_factor
|
def boolean_factor
|
||||||
if boolean?(@look)
|
if boolean?(@look)
|
||||||
if get_boolean == 'true'
|
if get_boolean == 'true'
|
||||||
asm.mov(EAX, -1)
|
asm.mov(EAX, TRUE)
|
||||||
else
|
else
|
||||||
asm.xor(EAX, EAX)
|
asm.xor(EAX, EAX)
|
||||||
end
|
end
|
||||||
|
|
@ -321,9 +345,9 @@ class Compiler
|
||||||
# semantically equivalent to !!reg in C or Ruby.
|
# semantically equivalent to !!reg in C or Ruby.
|
||||||
def make_boolean(reg=EAX)
|
def make_boolean(reg=EAX)
|
||||||
end_label = asm.mklabel(:endmakebool)
|
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.jz(end_label)
|
||||||
asm.mov(reg, -1) # truthy, make it true
|
asm.mov(reg, TRUE) # truthy, make it true
|
||||||
asm.deflabel(end_label)
|
asm.deflabel(end_label)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -389,13 +413,13 @@ class Compiler
|
||||||
asm.cmp(a, b)
|
asm.cmp(a, b)
|
||||||
asm.jl(true_label)
|
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.not_(EAX) if invert # (or true if inverted)
|
||||||
asm.jmp(end_label)
|
asm.jmp(end_label)
|
||||||
|
|
||||||
asm.deflabel(true_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.not_(EAX) unless invert # (or false if inverted)
|
||||||
|
|
||||||
asm.deflabel(end_label)
|
asm.deflabel(end_label)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue