@output = $stdout
end
+ def type_lookup(type)
+ if type.is_a? IR::Var
+ if type.module.nil?
+ type = @syms[type.name].value || @syms[type.name].type
+ else
+ if type.module == @parser.module
+ type = @syms[type.name].type || @syms[type.name].value
+ else
+ type = @syms[type.module].type.exports[type.name]
+ type = type.type || type.value
+ end
+ end
+ end
+ type
+ end
+
def type_to_s(type)
+ result = ""
if type == :string
- "_string"
+ result = "_string"
elsif type.is_a? Symbol
- type
- elsif type.is_a? IR::Var and type.module
- "#{type.module || @parser.module}_#{type.name}"
- elsif type.is_a? IR::Var and not type.module
- "#{type.name}"
+ result = type
+ elsif type.is_a? IR::Var
+ if type.module.nil?
+ sym = @syms[type.name].value || @syms[type.name].type
+ result = "#{type.name}"
+ else
+ if type.module == @parser.module
+ sym = @syms[type.name].type || @syms[type.name].value
+ else
+ sym = @syms[type.module].type.exports[type.name]
+ sym = sym.type || sym.value
+ end
+ result = "#{type.module || @parser.module}_#{type.name}"
+ end
+ result += "*" if sym.is_a?(Value::Type) and sym.form == :record
elsif type.form == :array
- "_array"
+ result = "_array"
elsif type.form == :hash
- "_dict"
+ result = "_dict"
else
raise "unconvertable type: #{type}"
end
+ result
end
def declare_sym(sym)
type = sym.value
if type.form == :record
puts "struct #{symname(sym)} {"
- if (type.base)
- puts " #{type_to_s(type.base)} _base;"
- end
type.fields.each do |k,v|
- is_ref = reference_type?(v)
- puts " #{type_to_s(v)}#{is_ref ? "*" : ""} #{k};"
+ puts " #{type_to_s(v)} #{k};"
end
puts "};"
end
@syms.add_sym(v.name.name, v.loc, :local, v.type, v.value)
temp = emit(v.value)
error v, "invalid local definition: #{v.name.name}" if not @locals.index(v.name.name)
+
+# if v.type.module.nil?
+# sym = @syms[v.type.name].value || @syms[v.type.name].type
+# else
+# if type.module == @parser.module
+# sym = @syms[v.type.name].type || @syms[v.type.name].value
+# else
+# sym = @syms[v.type.module].type.exports[v.type.name]
+# sym = sym.type || sym.value
+# end
+# end
+# is_record = sym.is_a?(Value::Type) and sym.form == :record
+
putln "#{type_to_s(v.value.type)} #{v.name.name} = #{temp};"
end
def type_definition(name)
if accept(:record)
- base_type = nil
- if accept("(")
- base_type = qualified_identifier()
- expect(")")
- end
- type = Value::Type.new(:record, {}, base_type, 0)
- expect("{")
- while not matches("}")
- name = expect(:ident).text.to_sym
- if type.fields[name]
- error("field #{name} already defined in record")
- end
- expect("=")
- type.fields[name] = type_specifier()
- end
- # parse fields here
- expect("}")
+ type = record_definition(name)
else
type = type_specifier()
type = Value::Type.new(:alias, nil, type, 0)
type
end
+ def record_definition(name)
+ base_type = nil
+ base_fields = {}
+ if accept("(")
+ base_type = qualified_identifier()
+ base_fields = type_lookup(base_type).fields.clone
+ expect(")")
+ end
+ type = Value::Type.new(:record, base_fields, base_type, 0)
+ expect("{")
+ while not matches("}")
+ name = expect(:ident).text.to_sym
+ if type.fields[name]
+ error("field #{name} already defined in record")
+ end
+ expect("=")
+ type.fields[name] = type_specifier()
+ end
+ # parse fields here
+ expect("}")
+ type
+ end
+
def constant_definition(name)
error("constant definitions not yet supported")
end
+ def type_lookup(type)
+ if type.module.nil?
+ type = @syms[type.name].value || @syms[type.name].type
+ else
+ if type.module == @parser.module
+ type = @syms[type.name].type || @syms[type.name].value
+ else
+ type = @syms[type.module].type.exports[type.name]
+ type = type.type || type.value
+ end
+ end
+ type
+ end
+
def function_arglist()
args = []
expect("(")