Skip to content
Permalink
Browse files

Support print statements

  • Loading branch information
mattgreen committed Jun 3, 2014
0 parents commit 57db4000f7581ad8aba1d243a0869dfecea55571
Showing with 80 additions and 0 deletions.
  1. +74 −0 alpha/alpha.rb
  2. +6 −0 alpha/input.txt
@@ -0,0 +1,74 @@
# Dirt-simple lexer that parses statements of the form:
# print "<str>"
class Lexer
def lex(code)
tokens = []

i = 0
line = 1

while i < code.length
chunk = code[i..code.length]

if print_statement = chunk[/\Aprint \"(.*)\"/]
tokens << [:PRINT, $1]
i += print_statement.length

elsif chunk[0] == "\n"
line += 1
i += 1

else
raise "Unexpected input on line #{line}: \"#{chunk[0..chunk.index("\n")-1]}\""

end
end

tokens
end
end

# An AST with only one node :)
class PrintNode < Struct.new(:str)
end

# Converts token stream produced by lexer into AST nodes
class Parser
def initialize
@nodes = []
end

def parse(tokens)
nodes = []

tokens.each do |token|
if token[0] == :PRINT
nodes << PrintNode.new(token[1])
else
raise "Unexpected token: #{token}"
end
end

nodes
end
end

# Walks the specified AST, executing it
class Interpreter
def evaluate(nodes)
nodes.each do |node|
method = "evaluate" + node.class.name.gsub(/([A-Z])/) { "_#{$1.downcase}" }

__send__(method, node)
end
end

def evaluate_print_node(node)
print node.str + "\n"
end
end

tokens = Lexer.new.lex(File.read(ARGV[0]))
nodes = Parser.new.parse(tokens)
Interpreter.new.evaluate(nodes)

@@ -0,0 +1,6 @@
print "Hello"

print "Several words"
print "Last line"
print ""
print "I am Matt"

0 comments on commit 57db400

Please sign in to comment.
You can’t perform that action at this time.