Class: Emfrp::TypeDef

Inherits:
Object
  • Object
show all
Defined in:
lib/emfrp/compile/c/syntax_codegen.rb

Instance Method Summary collapse

Instance Method Details

#constructor_gen(ct) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 135

def constructor_gen(ct)
  return if enum?(ct)
  self[:tvalues].each_with_index do |tvalue, i|
    params = tvalue[:params].each_with_index.map do |param, i|
      [ct.tref(param), "member#{i}"]
    end
    ct.define_func(ref_name(ct), tvalue.constructor_name(ct), params) do |s|
      while_stmts = []
      while_stmts << "#{memory_counter_name(ct)}++;"
      while_stmts << "#{memory_counter_name(ct)} %= #{memory_size_name(ct)};"
      mn = "#{memory_name(ct)}[#{memory_counter_name(ct)}].mark"
      while_stmts << "if (#{mn} < Counter) { x = #{memory_name(ct)} + #{memory_counter_name(ct)}; break; }"
      s << "#{ref_name(ct)} x;"
      s << ct.make_block("while (1) {", while_stmts, "}")
      s << "x->mark = 0;"
      s << "x->tvalue_id = #{i};" if self[:tvalues].length > 1
      tvalue[:params].each_with_index do |param, i|
        s << "x->value.#{tvalue.struct_name(ct)}.member#{i} = member#{i};"
      end
      s << "return x;"
    end
  end
end

#enum?(ct) ⇒ Boolean

Returns:

  • (Boolean)


183
184
185
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 183

def enum?(ct)
  self[:tvalues].all?{|x| x[:params].length == 0}
end

#marker_func_name(ct) ⇒ Object



195
196
197
198
199
200
201
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 195

def marker_func_name(ct)
  unless enum?(ct)
    "mark_#{struct_name(ct)}"
  else
    raise
  end
end

#marker_gen(ct) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 159

def marker_gen(ct)
  return if enum?(ct)
  params = [[ref_name(ct), "x"], ["int", "mark"]]
  ct.define_func("void", marker_func_name(ct), params) do |x|
    x << "if (mark > x->mark) { x->mark = mark; }" unless self[:static]
    accessor = self[:static] ? "." : "->"
    cases = []
    self[:tvalues].each_with_index do |tvalue, i|
      calls = []
      tvalue[:params].each_with_index do |param, i|
        if ct.tdef(param).is_a?(TypeDef) && !ct.tdef(param).enum?(ct)
          fn = ct.tdef(param).marker_func_name(ct)
          calls << "#{fn}(x#{accessor}value.#{tvalue.struct_name(ct)}.member#{i}, mark);"
        end
      end
      cases << "case #{i}: #{calls.join(" ")} break;" if calls.size > 0
    end
    if cases.size > 0
      switch_exp = self[:tvalues].size == 1 ? "0" : "x#{accessor}tvalue_id"
      x << ct.make_block("switch (#{switch_exp}) {", cases, "}")
    end
  end
end

#memory_counter_name(ct) ⇒ Object



219
220
221
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 219

def memory_counter_name(ct)
  "counter_#{struct_name(ct)}"
end

#memory_name(ct) ⇒ Object



211
212
213
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 211

def memory_name(ct)
  "memory_#{struct_name(ct)}"
end

#memory_size_name(ct) ⇒ Object



215
216
217
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 215

def memory_size_name(ct)
  "size_#{struct_name(ct)}"
end

#ref_name(ct) ⇒ Object



203
204
205
206
207
208
209
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 203

def ref_name(ct)
  if enum?(ct)
    "int"
  else
    "struct " + struct_name(ct) + (self[:static] ? "" : "*")
  end
end

#struct_gen(ct) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 117

def struct_gen(ct)
  return if enum?(ct)
  ct.define_struct("struct", struct_name(ct), nil) do |s1|
    s1 << "int tvalue_id;" if self[:tvalues].length > 1
    s1 << "int mark;" unless self[:static]
    s1 << ct.define_struct("union", nil, "value") do |s2|
      self[:tvalues].each_with_index do |tvalue, i|
        next if tvalue[:params].size == 0
        s2 << ct.define_struct("struct", nil, tvalue.struct_name(ct)) do |s3|
          tvalue[:params].each_with_index do |param, i|
            s3 << "#{ct.tref(param)} member#{i};"
          end
        end
      end
    end
  end
end

#struct_name(ct) ⇒ Object



187
188
189
190
191
192
193
# File 'lib/emfrp/compile/c/syntax_codegen.rb', line 187

def struct_name(ct)
  unless enum?(ct)
    self[:tvalues][0][:typing].to_flatten_uniq_str
  else
    raise
  end
end