[NEW] simple VB style for loop, f x = 1 >> 5 s = s + x e

This commit is contained in:
sjs 2009-05-20 11:39:21 -07:00
parent 221efca282
commit dd6d342dd4
2 changed files with 49 additions and 6 deletions

View file

@ -144,6 +144,8 @@ class Compiler
until_stmt until_stmt
when 'r' when 'r'
repeat_stmt repeat_stmt
when 'f'
for_stmt
when 'b' when 'b'
break_stmt break_stmt
else else
@ -223,6 +225,38 @@ class Compiler
emit_label(end_label) emit_label(end_label)
end end
# s = 0
# f x = 1 >> 5
# s = s + x
# e
def for_stmt
match('f')
start_label = unique_label(:for)
end_label = unique_label(:endfor)
counter = "[#{get_name}]"
match('=')
expression # initial value
x86_sub(:eax, 1) # pre-decrement because of the
# following pre-increment
x86_mov(counter, :eax) # stash the counter in memory
match('>'); match('>')
expression # final value
skip_any_whitespace
x86_push(:eax) # stash final value on stack
final = '[esp]'
emit_label(start_label)
x86_mov(:ecx, counter) # get the counter
x86_add(:ecx, 1) # increment
x86_mov(counter, :ecx) # store the counter
x86_cmp(final, :ecx) # check if we're done
x86_jz(end_label) # if so jump to the end
block(end_label) # otherwise execute the block
match('e')
x86_jmp(start_label) # lather, rinse, repeat
emit_label(end_label)
x86_add(:esp, 4) # clean up the stack
end
def break_stmt def break_stmt
match('b') match('b')
if @break_stack.empty? if @break_stack.empty?
@ -466,6 +500,10 @@ class Compiler
emit("idiv #{op}") emit("idiv #{op}")
end end
def x86_inc(op)
emit("inc #{op}")
end
def x86_push(reg) def x86_push(reg)
emit("push #{reg}") emit("push #{reg}")
end end

View file

@ -4,11 +4,11 @@ somethinglong=65536
x=5*(3-5) x=5*(3-5)
c=a-1 c=a-1
d=-1 d=-1
f=x*2+2 g=x*2+2
g=f-27/9 h=g-27/9
h=g-8/2 j=h-8/2
j=h-4*(5+5+5) k=j-4*(5+5+5)
k=h+85 m=k+85
i 1 i 1
d=3 d=3
@ -39,10 +39,15 @@ u 1
e e
r r
cc = cc * 2 cc = c * 2
i 1 i 1
b b
e e
e e
s=0
f x = 1 >> 5
s = s + x
e
xitcode=a-a xitcode=a-a