#!/usr/bin/env ruby
require 'strscan'
+require 'pp'
module Type
Void = "void"
unary: 8,
call: 9,
primary: 10,
+ eof: 11
}
- RULES = {}
+ RULES = {
+ "(" => { prefix: :grouping, infix: :func_call, level: :call },
+ :int => { prefix: :constant, infix: nil, level: :none },
+ }
def initialize(path)
@lex = Lexer.new(path)
expect("=")
value = expression()
end
- pp value
+ p "value", value
end
def declaration(syms)
RULES[tok.type]
end
+ def keepGoing(level)
+ rule = getRule(peek())
+ (LEVELS[level] <= LEVELS[rule[:level]]) if rule
+ end
+
def parseLevel(level)
-# advance()
-# prefixRule = getRule(@prev)[:prefix]
-# if not prefixRule then
-# error("expected an expression")
-# end
-# send(prefixRule)
-# while (level <= LEVELS[getRule(@curr)[:level]])
-# advance()
-# infixRule = getRule(@prev)[:infix]
-# send(infixRule)
-# end
+ consume()
+ prefixRule = getRule(@prev)[:prefix]
+ if not prefixRule then
+ error("expected an expression")
+ end
+ ast = send(prefixRule)
+ while keepGoing(level)
+ consume()
+ infixRule = getRule(@prev)[:infix]
+ ast = send(infixRule, ast)
+ end
+ ast
end
def constant()
- if (peek().type == :int)
- AST::Value.new(Type::Int, consume().text.to_i)
+ if (@prev.type == :int)
+ AST::Value.new(Type::Int, @prev.text.to_i)
else
error("not a valid constant")
end
end
+ def grouping()
+ ast = expression()
+ expect(")")
+ ast
+ end
+
+ def func_call(ast)
+ expect(")")
+ ast
+ end
+
def error(str)
raise str
end