class SFRP::Mono::Type
Attributes
str[R]
Public Class Methods
new(str, vconst_strs = nil, static = false, native_str = nil)
click to toggle source
# File lib/sfrp/mono/type.rb, line 6 def initialize(str, vconst_strs = nil, static = false, native_str = nil) @str = str @vconst_strs = vconst_strs @static = static @native_str = native_str end
Public Instance Methods
==(other)
click to toggle source
# File lib/sfrp/mono/type.rb, line 17 def ==(other) comp == other.comp end
all_pattern_examples(set)
click to toggle source
# File lib/sfrp/mono/type.rb, line 59 def all_pattern_examples(set) return [Pattern::PatternExample.new(nil, [])] if infinite? @vconst_strs.flat_map do |vc_str| set.vconst(vc_str).all_pattern_examples(set) end end
comp()
click to toggle source
# File lib/sfrp/mono/type.rb, line 13 def comp [@str, @vconst_strs, @static, @native_str] end
gen(src_set, dest_set)
click to toggle source
Generate C's elements for this type.
# File lib/sfrp/mono/type.rb, line 113 def gen(src_set, dest_set) gen_struct(src_set, dest_set) gen_typedef(src_set, dest_set) gen_constructor(src_set, dest_set) gen_allocator(src_set, dest_set) gen_mark_function(src_set, dest_set) end
gen_mark_cleanup_stmt(src_set, stmts)
click to toggle source
Generate statement to clean up objects of this types.
# File lib/sfrp/mono/type.rb, line 122 def gen_mark_cleanup_stmt(src_set, stmts) return unless need_mark?(src_set) return if src_set.memory(@str) == 0 stmts << L.stmt("#{low_allocator_str}(1)") end
has_meta_in_struct?()
click to toggle source
# File lib/sfrp/mono/type.rb, line 55 def has_meta_in_struct? !(static? && single_vconst?) end
infinite?()
click to toggle source
Does this type has infinite amount of vconsts?
# File lib/sfrp/mono/type.rb, line 28 def infinite? @vconst_strs.nil? end
linear?(set)
click to toggle source
Does this type has single vconst of native type parameters e.g. Tuple3(Int, Int, Int)
# File lib/sfrp/mono/type.rb, line 39 def linear?(set) single_vconst? && set.vconst(@vconst_strs[0]).native_args?(set) end
low_allocator_str()
click to toggle source
# File lib/sfrp/mono/type.rb, line 83 def low_allocator_str "alloc_#{@str}" end
low_mark_func_str()
click to toggle source
# File lib/sfrp/mono/type.rb, line 87 def low_mark_func_str "mark_#{@str}" end
low_member_pointers_for_single_vconst(set, receiver_str)
click to toggle source
# File lib/sfrp/mono/type.rb, line 107 def low_member_pointers_for_single_vconst(set, receiver_str) raise unless single_vconst? set.vconst(@vconst_strs[0]).low_member_pointers(self, receiver_str) end
low_type_str()
click to toggle source
# File lib/sfrp/mono/type.rb, line 79 def low_type_str @native_str ? @native_str : @str end
low_typedef_for_alias(alias_str)
click to toggle source
# File lib/sfrp/mono/type.rb, line 75 def low_typedef_for_alias(alias_str) L.typedef("#{low_type_str} #{alias_str}") end
memory(set)
click to toggle source
Return max memory size to hold an instance of this type.
# File lib/sfrp/mono/type.rb, line 67 def memory(set) return Memory.one(@str) if infinite? x = @vconst_strs.reduce(Memory.empty) do |m, v_str| m.or(set.vconst(v_str).memory(set)) end Memory.one(@str).and(x) end
meta_access_str(receiver_str)
click to toggle source
# File lib/sfrp/mono/type.rb, line 91 def meta_access_str(receiver_str) "#{receiver_str}#{static? ? '.' : '->'}meta" end
native?()
click to toggle source
Is this type native type?
# File lib/sfrp/mono/type.rb, line 33 def native? @native_str end
need_mark?(set)
click to toggle source
Do objects of this type need to be passed to mark-function?
# File lib/sfrp/mono/type.rb, line 49 def need_mark?(set) return true unless static? return false if infinite? @vconst_strs.any? { |v_str| set.vconst(v_str).param_needing_mark?(set) } end
single_vconst?()
click to toggle source
Does this type has only one vconst?
# File lib/sfrp/mono/type.rb, line 44 def single_vconst? !infinite? && @vconst_strs.size == 1 end
static?()
click to toggle source
Are objects of this type passed through value? Defalut is passing through referrence.
# File lib/sfrp/mono/type.rb, line 23 def static? @static end
term_id(vconst_str)
click to toggle source
Return term-id of given vconst of this type.
# File lib/sfrp/mono/type.rb, line 100 def term_id(vconst_str) raise "#{@str} is infinite" if infinite? res = @vconst_strs.index(vconst_str) raise "#{vconst_str} is not a vconst of #{@str}" unless res res end
terms_access_str(receiver_str)
click to toggle source
# File lib/sfrp/mono/type.rb, line 95 def terms_access_str(receiver_str) "#{receiver_str}#{static? ? '.' : '->'}terms" end
Private Instance Methods
gen_allocator(src_set, dest_set)
click to toggle source
Generate allocator-function for type.
# File lib/sfrp/mono/type.rb, line 165 def gen_allocator(src_set, dest_set) return if static? count = src_set.memory(@str) memory_var = "memory_#{low_type_str}" dest_set << L.function(low_allocator_str, low_type_str) do |f| f.append_param('int', 'clean_up') f << L.stmt('static int i = 0') f << L.stmt("static struct #{low_type_str} #{memory_var}[#{count}]") f << L.if_stmt('clean_up') do |if_stmts| e = "#{memory_var}[i].meta.mark = 0" if_stmts << L.stmt("for (i = 0; i < #{count}; i++) #{e}") if_stmts << L.stmt('i = 0') if_stmts << L.stmt('return 0') end f << L.stmt("while (#{memory_var}[i++].meta.mark)") f << L.stmt("return #{memory_var} + (i - 1)") end end
gen_constructor(src_set, dest_set)
click to toggle source
Generate constructor-functions for vconsts.
# File lib/sfrp/mono/type.rb, line 157 def gen_constructor(src_set, dest_set) return if infinite? @vconst_strs.each_with_index do |v_str, term_id| src_set.vconst(v_str).gen_constructor(src_set, term_id, dest_set) end end
gen_mark_function(src_set, dest_set)
click to toggle source
Generate mark function for this type.
# File lib/sfrp/mono/type.rb, line 185 def gen_mark_function(src_set, dest_set) return unless need_mark?(src_set) dest_set << L.function(low_mark_func_str, 'int') do |f| f.append_param(low_type_str, 'target') f << L.stmt("#{meta_access_str('target')}.mark = 1") unless static? @vconst_strs.each_with_index do |v_str, term_id| vconst = src_set.vconst(v_str) cond_exps = vconst.low_compare_exps(src_set, 'target') mark_exps = vconst.low_mark_element_exps(src_set, term_id, 'target') next if mark_exps.empty? mark_stmt = L.stmt(mark_exps.join(', ')) if cond_exps.empty? f << mark_stmt else cond_exp = cond_exps.reduce { |a, e| "#{a} && #{e}" } f << L.if_stmt(cond_exp) do |i| i << mark_stmt end end end f << L.stmt('return 0') end end
gen_struct(src_set, dest_set)
click to toggle source
Generate struct for this type.
# File lib/sfrp/mono/type.rb, line 131 def gen_struct(src_set, dest_set) return if native? || infinite? dest_set << L.struct(@str) do |top| if has_meta_in_struct? top << L.member_structure('struct', 'meta') do |meta| meta << L.member('unsigned char term_id : 7') meta << L.member('unsigned char mark : 1') end end top << L.member_structure('union', 'terms') do |terms| @vconst_strs.each_with_index do |v_str, term_id| vconst = src_set.vconst(v_str) vconst.gen_term_definition(src_set, term_id, terms) end end end end
gen_typedef(_src_set, dest_set)
click to toggle source
Generate typedef for this type.
# File lib/sfrp/mono/type.rb, line 150 def gen_typedef(_src_set, dest_set) return if native? asta = static? ? '' : '*' dest_set << L.typedef("struct #{@str}#{asta} #{@str}") end