end
def const_or_ident()
- tok = consume()
- if tok.type == :bool
- IR::Const.new(tok.pos, Value::Bool, tok.text == "true")
- elsif tok.type == :string
- IR::Const.new(tok.pos, Value::String, tok.text)
- elsif tok.type == :int
- IR::Const.new(tok.pos, Value::Int, tok.text.to_i)
- elsif tok.type == :float
- IR::Const.new(tok.pos, Value::Float, tok.text.to_f)
- elsif tok.type == :void
- IR::Const.new(tok.pos, Value::Void, :void)
- elsif tok.type == :ident
- IR::Var.new(tok.pos, nil, tok.text.to_sym)
+ if matches("[")
+ array_literal()
+ elsif matches("{")
+ hash_literal()
else
- error("invalid constant #{tok}")
+ tok = consume()
+ if tok.type == :bool
+ IR::Const.new(tok.pos, Value::Bool, tok.text == "true")
+ elsif tok.type == :string
+ IR::Const.new(tok.pos, Value::String, tok.text)
+ elsif tok.type == :int
+ IR::Const.new(tok.pos, Value::Int, tok.text.to_i)
+ elsif tok.type == :float
+ IR::Const.new(tok.pos, Value::Float, tok.text.to_f)
+ elsif tok.type == :void
+ IR::Const.new(tok.pos, Value::Void, :void)
+ elsif tok.type == :ident
+ IR::Var.new(tok.pos, nil, tok.text.to_sym)
+ else
+ error("invalid constant #{tok}")
+ end
+ end
+ end
+
+ def array_literal()
+ exprs = []
+ expect("[")
+ loc = location()
+ while !matches("]")
+ exprs << expression()
+ expect(",") if !matches("]")
end
+ expect("]")
+ exprs
+ IR::Const.new(loc, nil, exprs)
+ end
+
+ def hash_literal()
+ exprs = {}
+ expect("{")
+# while !matches("}")
+# exprs << expression()
+# expect(",") if !matches("}")
+# end
+ expect("}")
+ exprs
end
end
def self.emit_const(state, v)
var = mktemp(state)
if v.value.is_a? Integer
- putln state, "Value #{var} = MakeInt(#{v.value});"
+ putln state, "Value #{var} = MakeInt(#{v.value});"
elsif v.value.is_a? Float
- putln state, "Value #{var} = MakeReal(#{v.value});"
+ putln state, "Value #{var} = MakeReal(#{v.value});"
elsif v.value == true || v.value == false
- putln state, "Value #{var} = MakeBool(#{v.value});"
+ putln state, "Value #{var} = MakeBool(#{v.value});"
elsif v.value.is_a? String
- putln state, "Value #{var} = MakeString(#{v.value});"
+ putln state, "Value #{var} = MakeString(#{v.value});"
+ elsif v.value.is_a? Array
+ putln state, "Value #{var} = MakeArrayOfLength(#{v.value.length});"
+ v.value.each_with_index do |e, i|
+ val = emit(state, e)
+ putln state, "Array_SetIndex(#{var}, #{i}, #{val});"
+
+ end
+ elsif v.value.is_a? Hash
+ putln state, "Value #{var} = MakeHash(#{v.value});"
else
raise "code emitting constants of this type not implemented"
end
$parser = Parser.new("cerise-c.m")
$checker = TypeChecker.new($parser)
-state = Codegen.init($parser)
+$state = Codegen.init($parser)
puts "#include <runtime.h>\n\n"
args = val.value.args.map{|e| "Value #{e.name}" }.join(", ")
puts "Value #{name}(#{args}) {"
$parser.syms.open_scope
- state.locals = val.value.locals
+ $state.locals = val.value.locals
val.value.args.each_with_index do |name, idx|
$parser.syms.add_sym(
name.name, name.loc, :param, name.type, idx)
end
val.value.body.each do |stmnt|
- Codegen.emit(state, stmnt)
+ Codegen.emit($state, stmnt)
end
puts "}\n\n"
$parser.syms.close_scope