Val = Struct.new(:type, :value)
Apply = Struct.new(:type, :func, :args)
Return = Struct.new(:type, :val)
+ Var = Struct.new(:name, :type, :value)
+ IfStmt = Struct.new(:cond, :br1, :br2)
end
BuiltinSyms = {
:kind => :type,
:type => Type::Nil.new(0),
},
-# "nil" => {
-# :kind => :const,
-# :type => "Nil",
-# :value => Ast::Val.new("Nil", 0)
-# },
"Bool" => {
kind: :type,
type: Type::Int.new(0, 1)
},
-# "true" => {
-# kind: :const,
-# type: "Bool",
-# value: Ast::Val.new("Bool", 1)
-# },
-# "false" => {
-# kind: :const,
-# type: "Bool",
-# value: Ast::Val.new("Bool", 0)
-# },
"Char" => {
kind: :type,
type: Type::Int.new(0, 0x10FFFF)
"true" => :bool,
"false" => :bool,
"return" => :return,
+ "if" => :if,
+ "else" => :else,
}
def initialize(path)
@lex = Lexer.new(path)
@prev = nil
@next = nil
+ @name = nil
+ @imports = []
+ @symbols = {}
end
#######################################
#######################################
def module()
expect(:module)
- expect(:ident).text
+ @name = expect(:ident).text
+ @name
end
def imports()
expect(:imports)
expect("(")
- reqs = []
while (!matches(")"))
- reqs << expect(:ident).text
+ @imports << expect(:ident).text
expect(",") if !matches(")")
end
expect(")")
- reqs
+ @imports
end
def definitions()
- defs = {}
while !matches(:eof)
sym = {
export: accept("$"),
name: expect(:ident).text
}
- error("#{sym[:name]} multiply defined in module") if defs[sym[:name]]
+ error("#{sym[:name]} multiply defined in module") if @symbols[sym[:name]]
if matches(:is)
typedef(sym)
elsif matches(":")
else
error("invalid symbol definition")
end
- defs[sym[:name]] = sym
+ @symbols[sym[:name]] = sym
end
- defs
+ @symbols
end
#######################################
sym[:type] = Type::Func.new([], nil)
func_args(sym)
sym[:type].return = type_specifier() if accept(":")
- block(sym)
+ sym[:value] = block()
end
def func_args(sym)
expect(")")
end
- def block(sym)
- sym[:value] = []
+ def block()
+ block = []
expect("{")
while !matches("}")
- sym[:value] << statement()
+ block << statement()
end
expect("}")
+ block
end
#######################################
# Statement Parsing
#######################################
def statement()
- puts "statement"
if matches(:return)
- expect(:return)
- expr = expression()
- Ast::Return.new(expr[:type], expr)
+ return_statement()
elsif matches(:if)
- elseif matches(:ident)
- name = expect(:ident)
+ if_statement()
+ elsif matches(:ident)
+ ident = expect(:ident)
if matches(":")
-# declaration(name)
- elsif matches("=")
-# assignment
+ declaration(ident)
else
-# binary_expr(name) # procedure call / expression
+ binary(ident)
end
else
- error("invalid statment")
+ expression()
end
end
+ def return_statement()
+ expect(:return)
+ expr = expression()
+ Ast::Return.new(expr[:type], expr)
+ end
+
+ def if_statement()
+ stmt = Ast::IfStmt.new(nil, nil, nil)
+ expect(:if)
+ stmt.cond = expression()
+ stmt.br1 = block()
+ if accept(:else)
+ if matches(:if)
+ stmt.br2 = if_statement()
+ else
+ stmt.br2 = block()
+ end
+ end
+ stmt
+ end
+
+ def declaration(name)
+ var = Ast::Var.new(name.text, nil, nil)
+ expect(":")
+ var.type = type_specifier()
+ expect("=")
+ var.value = expression()
+ var
+ end
+
#######################################
# Expression Parsing
#######################################