"else" => :else,
}
+ attr_accessor :file
+ attr_accessor :data
+
def initialize(path)
@file = path
- @data = StringScanner.new(File.read(path))
+ @text = File.read(path)
+ @data = StringScanner.new(@text)
end
def get_id_type(str)
Tok.new("EOF", @file, @data.pos, :eof)
end
end
+
+ def linenum(tok = nil)
+ @text[0..(tok.pos || @data.pos)].count("\n") + 1
+ end
end
class Parser
RULES = {
"." => { prefix: nil, infix: :access, level: :call },
+ "[" => { prefix: nil, infix: :subscript, level: :call },
"(" => { prefix: :grouping, infix: :func_call, level: :call },
"+" => { prefix: :unary, infix: :binary, level: :term },
"-" => { prefix: :unary, infix: :binary, level: :term },
return_statement()
elsif matches(:if)
if_statement()
-# elsif matches(:ident)
-# ident = expect(:ident)
-# if matches(":")
-# declaration(ident)
-# else
-# binary(ident)
-# end
+ elsif matches(:ident)
+ decl_or_expr()
else
expression()
end
var
end
+ def decl_or_expr()
+ ident = Ast::Ident.new(expect(:ident).text)
+ if matches(":")
+ declaration(@prev)
+ else
+ parseNextLevel(ident, :none)
+ end
+ end
+
#######################################
# Expression Parsing
#######################################
consume()
prefixRule = getRule(@prev)[:prefix]
error("error parsing expression") if not prefixRule
- ast = send(prefixRule)
+ parseNextLevel(send(prefixRule), level)
+ end
+
+ def parseNextLevel(left, level)
+ ast = left
while keepGoing(level)
consume()
infixRule = getRule(@prev)[:infix]
end
end
+ def subscript(left)
+ right = expression()
+# p right
+ ast = Ast::Apply.new(nil, "[", [left, right])
+# p ast
+ expect("]")
+ p peek()
+ ast = parseNextLevel(ast, :call)
+# p ast
+ ast
+ end
+
def variable()
Ast::Ident.new(@prev.text)
end
# Parsing Primitives
#######################################
def error(str)
- puts str
+ puts "#{@lex.file}:#{@lex.linenum(@next || @prev)}: #{str}"
exit 1
end
fetchsel(sel : String)
{
# foo : String = 123
-# 1 + 1
-# return 0
# if 1 { return 5 } else {}
# if 1 {} else if 1 {}
-# cmd[1] = sel;
- Posix.exec(cmd)
-}
-
-main(args : [String]) : Int
-{
-# x : X11.Config = 0
-# X11.init(x)
-# X11.mkwin(x, 1, 1, X11.PropertyChangeMask)
-# XSel.init(x)
-# X11.loop(x, nil)
+ cmd[1] = sel
+# 1 + 1
+# Posix.exec(cmd)
# return 0
}
+#main(args : [String]) : Int
+#{
+## x : X11.Config = 0
+## X11.init(x)
+## X11.mkwin(x, 1, 1, X11.PropertyChangeMask)
+## XSel.init(x)
+## X11.loop(x, nil)
+## return 0
+#}
+