Skip to content

Instantly share code, notes, and snippets.

@mdaisuke
Created February 17, 2013 00:45
Show Gist options
  • Save mdaisuke/4969470 to your computer and use it in GitHub Desktop.
Save mdaisuke/4969470 to your computer and use it in GitHub Desktop.
translate to ruby
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