[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
when 'r'
repeat_stmt
when 'f'
for_stmt
when 'b'
break_stmt
else
@ -223,6 +225,38 @@ class Compiler
emit_label(end_label)
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
match('b')
if @break_stack.empty?
@ -466,6 +500,10 @@ class Compiler
emit("idiv #{op}")
end
def x86_inc(op)
emit("inc #{op}")
end
def x86_push(reg)
emit("push #{reg}")
end

View file

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