@output = $stdout
end
+ def type_to_s(type)
+ if type.is_a? Symbol
+ type
+ elsif type.form == :array
+ "Value"
+ elsif type.form == :hash
+ "Value"
+ else
+ raise "unconvertable type: #{type}"
+ end
+ end
+
def output(outpath)
@output = File.open(outpath, "wb")
puts "#include <runtime.h>\n\n"
(@parser.imported_modules || {}).values.each do |mod|
@syms[mod[:name]].type.exports.each do |name, val|
- args = val.type[0..-2].map{|e| "Value" }.join(", ")
- puts "Value #{symname(val)}(#{args});"
+ args = val.type[0..-2].map{|e| type_to_s(e) }.join(", ")
+ puts "#{type_to_s(val.type.last)} #{symname(val)}(#{args});"
end
puts ""
end
@syms.each do |name, val|
- args = val.value.args.map{|e| "Value #{e.name}" }.join(", ")
- puts "Value #{symname(val)}(#{args});"
+ args = val.value.args.map{|e| "#{type_to_s(e.type)} #{e.name}" }.join(", ")
+ puts "#{type_to_s(val.type.last)} #{symname(val)}(#{args});"
end
puts ""
@syms.each do |name, val|
- args = val.value.args.map{|e| "Value #{e.name}" }.join(", ")
- puts "Value #{symname(val)}(#{args}) {"
+ args = val.value.args.map{|e| "#{type_to_s(e.type)} #{e.name}" }.join(", ")
+ puts "#{type_to_s(val.type.last)} #{symname(val)}(#{args}) {"
@syms.open_scope
@locals = val.value.locals
val.value.args.each_with_index do |name, idx|
def emit_const(v)
var = mktemp()
+ type = type_to_s(v.type)
if v.value.is_a? Integer
- putln "Value #{var} = MakeInt(#{v.value});"
+ putln "#{type} #{var} = (#{v.value});"
elsif v.value.is_a? Float
- putln "Value #{var} = MakeReal(#{v.value});"
+ putln "#{type} #{var} = (#{v.value});"
elsif v.value == true || v.value == false
- putln "Value #{var} = MakeBool(#{v.value});"
+ putln "#{type} #{var} = (#{v.value});"
elsif v.value.is_a? String
- putln "Value #{var} = MakeString(#{v.value});"
+ putln "#{type} #{var} = MakeString(#{v.value});"
elsif v.value.is_a? Array
- putln "Value #{var} = MakeArray(#{v.value.length});"
+ putln "#{type} #{var} = MakeArray(#{v.value.length});"
v.value.each_with_index do |e, i|
val = emit(e)
putln "Array_Set(#{var}, #{i}, #{val});"
if v.value
temp = emit(v.value)
putln "return #{temp};"
- else
- putln "return MakeNil();"
end
end
def emit_binop(v)
+ type = type_to_s(v.type)
if v.op == "&&"
lvar = emit(v.left)
result = mktemp();
- putln "Value #{result} = #{lvar};"
- putln "if (IsTrue(#{result})) {"
+ putln "#{type} #{result} = #{lvar};"
+ putln "if (#{result}) {"
@indent += 1
rvar = emit(v.right)
putln "#{result} = #{rvar};"
@indent -= 1
putln "} else {"
- putln " #{result} = MakeBool(false);"
+ putln " #{result} = (false);"
putln "}"
elsif v.op == "||"
lvar = emit(v.left)
result = mktemp();
- putln "Value #{result} = #{lvar};"
- putln "if (IsFalse(#{result})) {"
+ putln "#{type} #{result} = #{lvar};"
+ putln "if (!(#{result})) {"
@indent += 1
rvar = emit(v.right)
putln "#{result} = #{rvar};"
lvar = emit(v.left)
rvar = emit(v.right)
result = mktemp();
- putln "Value #{result} = Object_Get(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = Object_Get(#{lvar}, #{rvar});"
else
lvar = emit(v.left)
rvar = emit(v.right)
result = mktemp();
case v.op
when "+"
- putln "Value #{result} = OpAdd(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} + #{rvar});"
when "-"
- putln "Value #{result} = OpSub(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} - #{rvar});"
when "*"
- putln "Value #{result} = OpMul(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} * #{rvar});"
when "/"
- putln "Value #{result} = OpDiv(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} / #{rvar});"
when "%"
- putln "Value #{result} = OpMod(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} % #{rvar});"
when "<"
- putln "Value #{result} = OpLt(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} < #{rvar});"
when "<="
- putln "Value #{result} = OpLtEq(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} <= #{rvar});"
when ">"
- putln "Value #{result} = OpGt(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} > #{rvar});"
when ">="
- putln "Value #{result} = OpGtEq(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} >= #{rvar});"
when "=="
- putln "Value #{result} = OpEq(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} == #{rvar});"
when "!="
- putln "Value #{result} = OpNeq(#{lvar}, #{rvar});"
+ putln "#{type} #{result} = (#{lvar} != #{rvar});"
else
raise "not implemented"
end
func = lookup_func(v.func)
if (func.is_a? SymTable::Symbol) then
error v, "symbol '#{func.name}' is not a function" if (func.kind != :func)
- putln "Value #{result} = #{symname(func)}(#{vars});"
+ if v.type == :void
+ putln "#{symname(func)}(#{vars});"
+ else
+ type = type_to_s(func.type.last)
+ putln "#{type} #{result} = #{symname(func)}(#{vars});"
+ end
else
error v, "expression result is not a function"
end
def emit_if(v)
cond = emit(v.cond)
- putln "if (ValueAsBool(#{cond})) {"
+ putln "if (#{cond}) {"
emit_block(v.then)
putln "} else {"
emit_block(v.else)