diff --git a/Makefile b/Makefile index e97ce0e..8dbcf65 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ build: # ruby test.rb '5-5+3-2-1' - ruby test.rb '5*3-5*2+3-9/3-1*1-8/2' +# ruby test.rb '5*3-5*2+3-9/3-1*1-8/2' + ruby test.rb '5*(3-5)*2+2-9/3-8/2-4*(5+5+5)' nasm -f elf -g -o test.o test.asm ld -o test test.o # $? indicates success as per unix convention diff --git a/compiler.rb b/compiler.rb index 390f4c6..ac02b3f 100644 --- a/compiler.rb +++ b/compiler.rb @@ -80,13 +80,19 @@ class Compiler # Parse and translate a single factor. Result is in eax. def factor - emit("mov eax, #{get_num}") + if @look == '(' + match('(') + expression + match(')') + else + emit("mov eax, #{get_num}") + end end # Parse and translate a single term. Result is in eax. def term factor # Result in eax. - while ['*', '/'].include?(@look) + while mulop? # Stash the 1st factor on the stack. This is expected by # multiply & divide. Because they leave their results in eax # associativity works. Each interim result is pushed on the @@ -106,9 +112,15 @@ class Compiler # Parse and translate a mathematical expression of terms. Result is # in eax. def expression - term # Result is in eax. + if addop? + # Clear eax simulating a zero before unary plus and minus + # operations. + emit("xor eax, eax") + else + term # Result is in eax. + end - while ['+', '-'].include?(@look) + while addop? # Stash the 1st term on the stack. This is expected by add & # subtract. Because they leave their results in eax # associativity works. Each interim result is pushed on the @@ -163,4 +175,12 @@ class Compiler def eof? @input.eof? && @look.nil? end + + def addop? + @look == '+' || @look == '-' + end + + def mulop? + @look == '*' || @look == '/' + end end