Created
February 17, 2013 00:45
-
-
Save mdaisuke/4969470 to your computer and use it in GitHub Desktop.
translate to ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Translator | |
| # | |
| # for executable binary on Max OS | |
| def self.asmheader | |
| print "#assemble/link with 'gcc file.s -o file\n" | |
| print " .text\n" | |
| print ".globl _main\n" | |
| print "_main:\n" | |
| print " pushl %ebp\n" | |
| end | |
| def self.asmfooter | |
| print "# contents of %eax will be the exit code\n" | |
| print " movl %esp, %ebp\n" | |
| print " subl $8, %esp\n" | |
| print " leave\n" | |
| print " ret\n" | |
| print " .subsections_via_symbols\n" | |
| end | |
| # | |
| # cradle | |
| # | |
| def initialize | |
| @look = nil; | |
| end | |
| def run | |
| init | |
| self.class.asmheader | |
| expression | |
| self.class.asmfooter | |
| end | |
| def error err | |
| $stderr.puts err | |
| end | |
| def fail err | |
| error err | |
| abort | |
| end | |
| def getChar | |
| @look = $stdin.getc | |
| exit if @look.nil? | |
| end | |
| def expected s | |
| fail "#{s} Expected" | |
| end | |
| def match c | |
| if c == @look | |
| getChar | |
| else | |
| expected "'#{c}'" | |
| end | |
| end | |
| def isAlpha c | |
| ('A'..'Z').include? c.upcase | |
| end | |
| def isDigit c | |
| Integer(c) != nil rescue false | |
| end | |
| def isAddop c | |
| c == '+' || c == '-' | |
| end | |
| def getName | |
| retval = 0 | |
| if !isAlpha @look | |
| expected "Name" | |
| else | |
| retval = @look.upcase | |
| getChar | |
| end | |
| retval | |
| end | |
| def getNum | |
| retval = 0 | |
| if !isDigit @look | |
| expected "Integer" | |
| else | |
| retval = @look | |
| getChar | |
| end | |
| retval | |
| end | |
| def emit s | |
| print "\t#{s}" | |
| end | |
| def emitln s | |
| print "\t#{s}\n" | |
| end | |
| def init | |
| getChar | |
| end | |
| def factor | |
| if @look == '(' | |
| match('(') | |
| expression | |
| match(')') | |
| else | |
| emitln "movl\t$#{getNum},%eax" | |
| end | |
| end | |
| def multiply | |
| match '*' | |
| factor | |
| emitln "pop\t%ebx" | |
| emitln "mul\t%ebx" | |
| end | |
| def divide | |
| match '/' | |
| factor | |
| emitln "mov\t%eax,%ebx" | |
| emitln "pop\t%eax" | |
| emitln "xor\t%edx,%edx" | |
| emitln "div\t%ebx" | |
| end | |
| def term | |
| factor | |
| while @look == '*' || @look == '/' | |
| emitln "push\t%eax" | |
| case @look | |
| when '*' then multiply | |
| when '/' then devide | |
| else expected "Mulop" | |
| end | |
| end | |
| end | |
| def add | |
| match '+' | |
| term | |
| emitln "pop\t%ebx" | |
| emitln "add\t%ebx,%eax" | |
| end | |
| def subtract | |
| match '-' | |
| term | |
| emitln "pop\t%ebx" | |
| emitln "sub\t%ebx,%eax" | |
| emitln "neg\t%eax" | |
| end | |
| def expression | |
| if isAddop @look | |
| emitln "xor\t%eax,%eax" | |
| else | |
| term | |
| while isAddop @look | |
| emitln "push\t%eax" | |
| case @look | |
| when '+' then add | |
| when '-' then subtract | |
| else expected "Addop" | |
| end | |
| end | |
| end | |
| end | |
| end | |
| Translator.new.run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment