From 7aa6fa7d155ed0ea9d40812ea815a6103b790615 Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Tue, 19 Jan 2010 23:32:30 -0800 Subject: [PATCH] cleaning out the cruft --- cradle.rb | 119 ----------------------- interpreter.rb | 227 -------------------------------------------- template.darwin.asm | 11 --- template.linux.asm | 13 --- 4 files changed, 370 deletions(-) delete mode 100644 cradle.rb delete mode 100644 interpreter.rb delete mode 100644 template.darwin.asm delete mode 100644 template.linux.asm diff --git a/cradle.rb b/cradle.rb deleted file mode 100644 index 8c8dbb1..0000000 --- a/cradle.rb +++ /dev/null @@ -1,119 +0,0 @@ -# A compiler skeleton, or cradle, as described by Jack Crenshaw in his -# famous book "Let's Build a Compiler". At least in the beginning, -# this code will closely reflect the Pascal code written by Jack. -# Over time it may become more idiomatic, however this is an academic -# exercise. - -class ParseError < StandardError; end - -class Compiler - def initialize(input=STDIN) - @look = '' # next lookahead char - @input = input # stream to read from - - # seed the lexer - get_char - end - - # Read the next character from the input stream - def get_char - @look = @input.getc - @look = @look.chr if @look - end - - # Report error and halt - def abort(msg) - raise ParseError, msg - end - - # Report what was expected - def expected(what) - if eof? - raise ParseError, "Premature end of file, expected: #{what}." - else - raise ParseError, "Expected: #{what}, got: #{@look}." - end - end - - # Match a specific input character - def match(char) - if @look == char - get_char - else - expected("'#{char}'") - end - end - - # Recognize an alphabetical character - def is_alpha(char) - ('A'..'Z') === char.upcase - end - - # Recognize a decimal digit - def is_digit(char) - ('0'..'9') === char - end - - # Get an identifier - def get_name - expected('identifier') unless is_alpha(@look) - c = @look - get_char - return c - end - - # Get a number - def get_num - expected('integer') unless is_digit(@look) - c = @look - get_char - return c - end - - # Print a tab followed by a string and a newline - def emit(s) - puts "\t#{s}" - end - - # Parse and translate a single mathematical term. Result is in eax. - def term - emit("mov eax, #{get_num}") - end - - # Parse an addition operator and the 2nd term. The 1st term is - # expected in ebx, and is added to the 2nd term leaving the result - # in eax. - def add - match('+') - term # result in eax - emit("add eax, ebx") - end - - # Parse a subtraction operator and the 2nd term (b). The 1st term - # (a) is expected in ebx, and the b is subtracted from a - # leaving the result in eax. - def subtract - match('-') - term # result in eax (b) - emit("sub eax, ebx") # subtract a from b (this is backwards) - emit("neg eax") # fix things up. -(b-a) == a-b - end - - # Parse and translate a mathematical expression of terms. Result is - # in eax. - def expression - term # result is in eax - emit("mov ebx, eax") # move 1st term to ebx (expected by - # add & subtract) - case @look - when '+': add - when '-': subtract - else - expected('Addition or subtraction operator (+ or -)') - end - end - - def eof? - @input.eof? && @look.nil? - end -end diff --git a/interpreter.rb b/interpreter.rb deleted file mode 100644 index ecf5945..0000000 --- a/interpreter.rb +++ /dev/null @@ -1,227 +0,0 @@ -# An interpreter as described by Jack Crenshaw in his famous book -# "Let's Build a Compiler". At least in the beginning, this code will -# closely reflect the Pascal code written by Jack. Over time it may -# become more idiomatic, however this is an academic exercise. -# -# sjs -# may 2009 - -class ParseError < StandardError; end - -class Interpreter - def initialize(input=STDIN) - @look = '' # next lookahead char - @input = input # stream to read from - @vars = Hash.new(0) - - # seed the lexer - get_char - end - - def run - statement until eof? || @look == '.' - end - - # Read the next character from the input stream - def get_char - @look = if @input.eof? - nil - else - @input.readbyte.chr - end - end - - # Report error and halt - def abort(msg) - raise ParseError, msg - end - - # Report what was expected - def expected(what) - msg = if eof? - "Premature end of file, expected: #{what}." - else - "Expected: #{what}, got: #{@look}." - end - abort(msg) - end - - - # Define a variable. - def define(name, value=nil) - abort("already defined '#{name}'") if @vars.has_key?(name) - set(name, value) - end - - # Set the value of a variable. - def set(name, value) - @vars[name] = value - end - - # Retrieve the value of a variable. - def get(name) - abort("undefined variable '#{name}'") unless @vars.has_key?(name) - @vars[name] - end - - - # Recognize an alphabetical character. - def alpha?(char) - ('A'..'Z') === char.upcase - end - - # Recognize a decimal digit. - def digit?(char) - ('0'..'9') === char - end - - # Recognize an alphanumeric character. - def alnum?(char) - alpha?(char) || digit?(char) - end - - def whitespace?(char) - char == ' ' || char == '\t' - end - - - # Match a specific input character. - def match(char) - expected("'#{char}'") unless @look == char - get_char - skip_whitespace - end - - # Parse zero or more consecutive characters for which the test is - # true. - def many(test) - token = '' - while test.call(@look) - token << @look - get_char - end - skip_whitespace - token - end - - # Get an identifier. - def get_name - expected('identifier') unless alpha?(@look) - many(method(:alpha?)) - end - - # Get a number. - def get_num - expected('integer') unless digit?(@look) - many(method(:digit?)).to_i - end - - # Skip all leading whitespace. - def skip_whitespace - get_char while whitespace?(@look) - end - - - - # Parse and evaluate a factor. - def factor - if @look == '(' - match('(') - value = expression - match(')') - elsif alpha?(@look) - value = get(get_name) - else - value = get_num - end - value - end - - # Parse and evaluate a term. - def term - value = factor - while mulop? - case @look - when '*' - match('*') - value *= factor - when '/' - match('/') - value /= factor - end - end - value - end - - # Parse and evaluate a mathematical expression. - def expression - # Fake unary plus and minus by prepending a 0 to them. - value = if addop? then 0 else term end - while addop? - case @look - when '+' - match('+') - value += term - when '-' - match('-') - value -= term - end - end - value - end - - # Parse one or more newlines. - def newline - if @look == "\n" || @look == "\r" - get_char while @look == "\n" || @look == "\r" - else - expected('newline') - end - end - - # Parse and evaluate an assignment statement. - def assignment - name = get_name - match('=') - set(name, expression) - end - - # Parse and evaluate any kind of statement. - def statement - value = case @look - when '?': input - when '!': output - else - assignment - end - newline - value - end - - # Read and store a number from standard input. - def input - match('?') - set(get_name, gets.to_i) - end - - # Print a value to standard output. - def output - match('!') - puts(get(get_name)) - end - - -private - - def eof? - @input.eof? && @look.nil? - end - - def addop? - @look == '+' || @look == '-' - end - - def mulop? - @look == '*' || @look == '/' - end -end diff --git a/template.darwin.asm b/template.darwin.asm deleted file mode 100644 index 673f104..0000000 --- a/template.darwin.asm +++ /dev/null @@ -1,11 +0,0 @@ -BITS 32 -GLOBAL _main -SECTION .data -{data} -SECTION .bss -{bss} -SECTION .text -_main: -{code} - ;; The result in eax is the exit code, just return. - ret diff --git a/template.linux.asm b/template.linux.asm deleted file mode 100644 index 0c851d1..0000000 --- a/template.linux.asm +++ /dev/null @@ -1,13 +0,0 @@ -BITS 32 -GLOBAL _start -SECTION .data -{data} -SECTION .bss -{bss} -SECTION .text -_start: -{code} - ;; The result in eax is the exit code, move it to ebx. - mov ebx, eax - mov eax, 1 ; _exit syscall - int 0x80 ; call Linux