mirror of
https://github.com/samsonjs/compiler.git
synced 2026-04-27 14:57:45 +00:00
[CHANGED] if statement supports else clause
This commit is contained in:
parent
f5678a312e
commit
0431cd60f3
2 changed files with 49 additions and 8 deletions
49
compiler.rb
49
compiler.rb
|
|
@ -24,7 +24,9 @@ class Compiler
|
||||||
@code = '' # code section
|
@code = '' # code section
|
||||||
@vars = {} # symbol table
|
@vars = {} # symbol table
|
||||||
@num_labels = 0 # used to generate unique labels
|
@num_labels = 0 # used to generate unique labels
|
||||||
@keywords = %w[i e] # reserved words (... constant?)
|
@num_labels_with_suffix = Hash.new(0)
|
||||||
|
@keywords = %w[i l e] # reserved words (... constant?)
|
||||||
|
@num_conditions = 0
|
||||||
|
|
||||||
# seed the lexer
|
# seed the lexer
|
||||||
get_char
|
get_char
|
||||||
|
|
@ -129,7 +131,7 @@ class Compiler
|
||||||
def statement
|
def statement
|
||||||
case @look
|
case @look
|
||||||
when 'i'
|
when 'i'
|
||||||
if_stmt
|
if_else_stmt
|
||||||
else
|
else
|
||||||
assignment
|
assignment
|
||||||
newline
|
newline
|
||||||
|
|
@ -138,7 +140,7 @@ class Compiler
|
||||||
|
|
||||||
# Parse a code block.
|
# Parse a code block.
|
||||||
def block
|
def block
|
||||||
until @look == 'e' || eof?
|
until @look == 'l' || @look == 'e' || eof?
|
||||||
statement
|
statement
|
||||||
skip_any_whitespace
|
skip_any_whitespace
|
||||||
end
|
end
|
||||||
|
|
@ -147,17 +149,38 @@ class Compiler
|
||||||
# Parse an if statement.
|
# Parse an if statement.
|
||||||
def if_stmt
|
def if_stmt
|
||||||
match('i')
|
match('i')
|
||||||
label = unique_label
|
|
||||||
condition
|
condition
|
||||||
|
label = unique_label(:end)
|
||||||
x86_jz(label)
|
x86_jz(label)
|
||||||
block
|
block
|
||||||
match('e')
|
match('e')
|
||||||
emit_label(label)
|
emit_label(label)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Parse an if-else statement.
|
||||||
|
def if_else_stmt
|
||||||
|
match('i')
|
||||||
|
condition
|
||||||
|
else_label = unique_label(:else)
|
||||||
|
end_label = unique_label(:end)
|
||||||
|
x86_jz(else_label)
|
||||||
|
block
|
||||||
|
if @look == 'l'
|
||||||
|
match('l')
|
||||||
|
x86_jmp(end_label)
|
||||||
|
emit_label(else_label)
|
||||||
|
block
|
||||||
|
else
|
||||||
|
emit_label(else_label) # we end up with an extra label, oh well
|
||||||
|
end
|
||||||
|
match('e')
|
||||||
|
emit_label(end_label)
|
||||||
|
end
|
||||||
|
|
||||||
# Dummy condition function. Will handle boolean expressions later.
|
# Dummy condition function. Will handle boolean expressions later.
|
||||||
def condition
|
def condition
|
||||||
emit('<condition>')
|
@num_conditions += 1
|
||||||
|
emit("<condition ##{@num_conditions}>")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Parse an addition operator and the 2nd term (b). The result is
|
# Parse an addition operator and the 2nd term (b). The result is
|
||||||
|
|
@ -352,9 +375,13 @@ class Compiler
|
||||||
end
|
end
|
||||||
|
|
||||||
# Generate a unique label.
|
# Generate a unique label.
|
||||||
def unique_label
|
def unique_label(suffix=nil)
|
||||||
@num_labels += 1
|
@num_labels += 1
|
||||||
"L#{sprintf "%06d", @num_labels}"
|
if suffix
|
||||||
|
@num_labels_with_suffix[suffix] += 1
|
||||||
|
suffix = "_#{suffix}_#{@num_labels_with_suffix[suffix]}"
|
||||||
|
end
|
||||||
|
"L#{sprintf "%06d", @num_labels}#{suffix}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -403,4 +430,12 @@ class Compiler
|
||||||
def x86_jz(label)
|
def x86_jz(label)
|
||||||
emit("jz #{label}")
|
emit("jz #{label}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def x86_jnz(label)
|
||||||
|
emit("jnz #{label}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def x86_jmp(label)
|
||||||
|
emit("jmp #{label}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -16,3 +16,9 @@ e
|
||||||
ib=3
|
ib=3
|
||||||
ic=4
|
ic=4
|
||||||
ee
|
ee
|
||||||
|
|
||||||
|
i b=3
|
||||||
|
i c=4
|
||||||
|
e
|
||||||
|
l b=2
|
||||||
|
e
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue