sfrp 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/.ctags +3 -0
  3. data/.editorconfig +9 -0
  4. data/.gitignore +14 -0
  5. data/.rubocop.yml +629 -0
  6. data/.travis.yml +12 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE +28 -0
  9. data/README.md +34 -0
  10. data/Rakefile +1 -0
  11. data/base-library/Base.sfrp +81 -0
  12. data/base-library/IO/AVR/ATMEGA8.c +9 -0
  13. data/base-library/IO/AVR/ATMEGA8.h +6 -0
  14. data/base-library/IO/AVR/ATMEGA8.sfrp +4 -0
  15. data/base-library/IO/STDIO.c +40 -0
  16. data/base-library/IO/STDIO.h +13 -0
  17. data/base-library/IO/STDIO.sfrp +10 -0
  18. data/bin/sfrp +7 -0
  19. data/lib/sfrp.rb +2 -0
  20. data/lib/sfrp/command.rb +73 -0
  21. data/lib/sfrp/compiler.rb +94 -0
  22. data/lib/sfrp/error.rb +4 -0
  23. data/lib/sfrp/file.rb +18 -0
  24. data/lib/sfrp/flat/dsl.rb +33 -0
  25. data/lib/sfrp/flat/elements.rb +90 -0
  26. data/lib/sfrp/flat/exception.rb +45 -0
  27. data/lib/sfrp/flat/expression.rb +125 -0
  28. data/lib/sfrp/flat/set.rb +61 -0
  29. data/lib/sfrp/input/exception.rb +16 -0
  30. data/lib/sfrp/input/parser.rb +417 -0
  31. data/lib/sfrp/input/set.rb +29 -0
  32. data/lib/sfrp/input/transformer.rb +219 -0
  33. data/lib/sfrp/low/dsl.rb +126 -0
  34. data/lib/sfrp/low/element.rb +126 -0
  35. data/lib/sfrp/low/set.rb +62 -0
  36. data/lib/sfrp/mono/dsl.rb +120 -0
  37. data/lib/sfrp/mono/environment.rb +26 -0
  38. data/lib/sfrp/mono/exception.rb +21 -0
  39. data/lib/sfrp/mono/expression.rb +124 -0
  40. data/lib/sfrp/mono/function.rb +86 -0
  41. data/lib/sfrp/mono/memory.rb +32 -0
  42. data/lib/sfrp/mono/node.rb +125 -0
  43. data/lib/sfrp/mono/pattern.rb +69 -0
  44. data/lib/sfrp/mono/set.rb +151 -0
  45. data/lib/sfrp/mono/type.rb +210 -0
  46. data/lib/sfrp/mono/vconst.rb +134 -0
  47. data/lib/sfrp/output/set.rb +33 -0
  48. data/lib/sfrp/poly/dsl.rb +171 -0
  49. data/lib/sfrp/poly/elements.rb +168 -0
  50. data/lib/sfrp/poly/exception.rb +42 -0
  51. data/lib/sfrp/poly/expression.rb +170 -0
  52. data/lib/sfrp/poly/monofier.rb +73 -0
  53. data/lib/sfrp/poly/set.rb +90 -0
  54. data/lib/sfrp/poly/typing.rb +197 -0
  55. data/lib/sfrp/raw/dsl.rb +41 -0
  56. data/lib/sfrp/raw/elements.rb +164 -0
  57. data/lib/sfrp/raw/exception.rb +40 -0
  58. data/lib/sfrp/raw/expression.rb +168 -0
  59. data/lib/sfrp/raw/namespace.rb +30 -0
  60. data/lib/sfrp/raw/set.rb +109 -0
  61. data/lib/sfrp/version.rb +3 -0
  62. data/sfrp.gemspec +40 -0
  63. data/spec/sfrp/Test.sfrp +4 -0
  64. data/spec/sfrp/compiler_spec.rb +17 -0
  65. data/spec/sfrp/flat/set_spec.rb +40 -0
  66. data/spec/sfrp/input/parse_test.sfrp +20 -0
  67. data/spec/sfrp/input/set_spec.rb +18 -0
  68. data/spec/sfrp/low/set_spec.rb +20 -0
  69. data/spec/sfrp/mono/expected.yml +295 -0
  70. data/spec/sfrp/mono/set_spec.rb +152 -0
  71. data/spec/sfrp/output/set_spec.rb +29 -0
  72. data/spec/sfrp/poly/set_spec.rb +290 -0
  73. data/spec/sfrp/raw/set_spec.rb +38 -0
  74. data/spec/spec_helper.rb +16 -0
  75. data/test/IntTest/Main.c +5 -0
  76. data/test/IntTest/Main.h +6 -0
  77. data/test/IntTest/Main.sfrp +10 -0
  78. data/test/IntTest/in.txt +3 -0
  79. data/test/IntTest/out.txt +4 -0
  80. data/test/MaybeTest/Main.sfrp +8 -0
  81. data/test/MaybeTest/SubDir/Lib.sfrp +9 -0
  82. data/test/MaybeTest/in.txt +6 -0
  83. data/test/MaybeTest/out.txt +6 -0
  84. data/test/Rakefile +15 -0
  85. metadata +290 -0
@@ -0,0 +1,125 @@
1
+ module SFRP
2
+ module Mono
3
+ class Node
4
+ NodeRef = Struct.new(:node_str, :last)
5
+
6
+ attr_reader :str
7
+
8
+ def initialize(
9
+ str, type_str, node_refs, eval_func_str, init_func_str = nil
10
+ )
11
+ @str = str
12
+ @type_str = type_str
13
+ @node_refs = node_refs
14
+ @eval_func_str = eval_func_str
15
+ @init_func_str = init_func_str
16
+ end
17
+
18
+ def comp
19
+ [@str, @type_str, @node_refs, @eval_func_str, @init_func_str]
20
+ end
21
+
22
+ def ==(other)
23
+ comp == other.comp
24
+ end
25
+
26
+ # Is this node initialized?
27
+ def initialized?
28
+ @init_func_str
29
+ end
30
+
31
+ # Name of variable to hold current and last evaluated value of this node.
32
+ def low_node_str
33
+ @str
34
+ end
35
+
36
+ def memory_used_to_eval_node(set)
37
+ set.func(@eval_func_str).memory(set)
38
+ end
39
+
40
+ def memory_used_to_init_node(set)
41
+ return Memory.empty unless initialized?
42
+ set.func(@init_func_str).memory(set)
43
+ end
44
+
45
+ def memory_used_to_hold_node(set)
46
+ set.type(@type_str).memory(set)
47
+ end
48
+
49
+ # Return referrence name of current evaluated value of this node.
50
+ def low_node_ref_current_str
51
+ index = (initialized? ? 'c' : '0')
52
+ "#{low_node_str}[#{index}]"
53
+ end
54
+
55
+ # Return referrence name of last evaluated value of this node.
56
+ def low_node_ref_last_str
57
+ "#{low_node_str}[l]"
58
+ end
59
+
60
+ # Return a list of nodes sorted by evaluation-order including this node.
61
+ # The list includes only nodes (recursively) depended by this node.
62
+ # So if you want to get a list including all nodes, you must call this
63
+ # method for an output node.
64
+ def sorted_node_strs(set)
65
+ cur = current_referred_node_strs(set)
66
+ last = last_referred_node_strs(set)
67
+ cur + (last - cur)
68
+ end
69
+
70
+ # Generate a statement of initialization if needed.
71
+ def gen_initialize_stmt(set, stmts)
72
+ return unless initialized?
73
+ call_exp = set.func(@init_func_str).low_call_exp([])
74
+ stmts << L.stmt("#{low_node_str}[l] = #{call_exp}")
75
+ end
76
+
77
+ # Generate declaration for variable to hold value of node.
78
+ def gen_node_var_declaration(set, stmts)
79
+ type = set.type(@type_str)
80
+ size = (initialized? ? '2' : '1')
81
+ stmts << L.stmt("#{type.low_type_str} #{low_node_str}[#{size}]")
82
+ end
83
+
84
+ # Generate ststement to evaluate this node.
85
+ def gen_evaluate_stmt(set, stmts)
86
+ arg_exps = @node_refs.map do |node_ref|
87
+ n = set.node(node_ref.node_str)
88
+ node_ref.last ? n.low_node_ref_last_str : n.low_node_ref_current_str
89
+ end
90
+ call_exp = set.func(@eval_func_str).low_call_exp(arg_exps)
91
+ stmts << L.stmt("#{low_node_ref_current_str} = #{call_exp}")
92
+ end
93
+
94
+ # Generate statement to mark node[l].
95
+ def gen_node_var_mark_stmt(set, stmts)
96
+ return unless initialized?
97
+ return unless set.type(@type_str).need_mark?(set)
98
+ mark_func_str = set.type(@type_str).low_mark_func_str
99
+ stmts << L.stmt("#{mark_func_str}(#{low_node_str}[l])")
100
+ end
101
+
102
+ protected
103
+
104
+ # Return a list of (recursively) current-referred nodes including myself.
105
+ def current_referred_node_strs(set, visited = {})
106
+ return [] if visited.key?(@str)
107
+ visited[@str] = true
108
+ prereq_node_strs = @node_refs.reject(&:last).flat_map do |r|
109
+ set.node(r.node_str).current_referred_node_strs(set, visited)
110
+ end
111
+ prereq_node_strs + [@str]
112
+ end
113
+
114
+ # Return a list of (recursively) last-referred nodes.
115
+ def last_referred_node_strs(set, visited = {})
116
+ return [] if visited.key?(@str)
117
+ visited[@str] = true
118
+ rec = @node_refs.reject(&:last).flat_map do |r|
119
+ set.node(r.node_str).last_referred_node_strs(set, visited)
120
+ end
121
+ (@node_refs.select(&:last).map(&:node_str) + rec).uniq
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,69 @@
1
+ module SFRP
2
+ module Mono
3
+ class Pattern
4
+ PatternExample = Struct.new(:vconst_str, :args)
5
+
6
+ def initialize(type_str, vconst_str, ref_var_str, arg_patterns)
7
+ @type_str = type_str
8
+ @vconst_str = vconst_str
9
+ @ref_var_str = ref_var_str
10
+ @arg_patterns = arg_patterns
11
+ end
12
+
13
+ def comp
14
+ [@type_str, @vconst_str, @ref_var_str, @arg_patterns]
15
+ end
16
+
17
+ def ==(other)
18
+ comp == other.comp
19
+ end
20
+
21
+ def any?
22
+ @vconst_str.nil?
23
+ end
24
+
25
+ def named?
26
+ @ref_var_str
27
+ end
28
+
29
+ def accept?(pattern_example)
30
+ return true if any?
31
+ return false unless pattern_example.vconst_str == @vconst_str
32
+ @arg_patterns.zip(pattern_example.args).all? do |pat, pat_exam|
33
+ pat.accept?(pat_exam)
34
+ end
35
+ end
36
+
37
+ # Return whole conditional-low-exps for the pattern-matching.
38
+ def low_cond_exps(set, receiver_exp)
39
+ return [] if any?
40
+ vconst = set.vconst(@vconst_str)
41
+ children = @arg_patterns.each_with_index.flat_map do |pat, mem_id|
42
+ new_receiver = child_receiver_exp(set, receiver_exp, mem_id)
43
+ pat.low_cond_exps(set, new_receiver)
44
+ end
45
+ vconst.low_compare_exps(set, receiver_exp) + children
46
+ end
47
+
48
+ # Return whole let-low-exps for the pattern-matching.
49
+ def low_let_exps(set, receiver_exp, env)
50
+ env.add_var(@ref_var_str, @type_str) if named?
51
+ lets = (named? ? ["#{@ref_var_str} = (#{receiver_exp})"] : [])
52
+ return lets if any?
53
+ children = @arg_patterns.each_with_index.flat_map do |pat, mem_id|
54
+ new_receiver = child_receiver_exp(set, receiver_exp, mem_id)
55
+ pat.low_let_exps(set, new_receiver, env)
56
+ end
57
+ lets + children
58
+ end
59
+
60
+ private
61
+
62
+ def child_receiver_exp(set, parent_receiver_exp, member_id)
63
+ type = set.type(@type_str)
64
+ terms_str = type.terms_access_str(parent_receiver_exp)
65
+ "#{terms_str}.term#{type.term_id(@vconst_str)}.member#{member_id}"
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,151 @@
1
+ require 'sfrp/mono/environment'
2
+ require 'sfrp/mono/expression'
3
+ require 'sfrp/mono/function'
4
+ require 'sfrp/mono/memory'
5
+ require 'sfrp/mono/node'
6
+ require 'sfrp/mono/pattern'
7
+ require 'sfrp/mono/type'
8
+ require 'sfrp/mono/vconst'
9
+ require 'sfrp/mono/dsl'
10
+
11
+ module SFRP
12
+ module Mono
13
+ class Set
14
+ def initialize(&block)
15
+ @func_h = {}
16
+ @node_h = {}
17
+ @type_h = {}
18
+ @vconst_h = {}
19
+ @output_node_strs = []
20
+ @init_func_strs = []
21
+ @type_alias_h = {}
22
+ @constructor_alias_h = {}
23
+ block.call(self) if block
24
+ end
25
+
26
+ def to_low(include_file_strs = [])
27
+ Low::Set.new do |low_set|
28
+ include_file_strs.each { |s| low_set << L.include_dq(s) }
29
+ @type_alias_h.each do |alias_str, original_str|
30
+ low_set << type(original_str).low_typedef_for_alias(alias_str)
31
+ end
32
+ @constructor_alias_h.each do |alias_str, original_str|
33
+ low_set << vconst(original_str).low_macro_for_alias(alias_str)
34
+ end
35
+ @func_h.values.each { |func| func.gen(self, low_set) }
36
+ @type_h.values.each { |type| type.gen(self, low_set) }
37
+ gen_main_func(low_set)
38
+ end
39
+ end
40
+
41
+ def check
42
+ # TODO: Check that all init_func does not waste any memory.
43
+ # TODO: Check completeness of pattern matchings.
44
+ end
45
+
46
+ def memory(type_str)
47
+ @memory ||= begin
48
+ to_init_nodes = nodes.reduce(Memory.empty) do |m, node|
49
+ m.and(node.memory_used_to_init_node(self))
50
+ end
51
+ to_hold_memoized_nodes = nodes.reduce(Memory.empty) do |m, node|
52
+ node.initialized? ? m.and(node.memory_used_to_hold_node(self)) : m
53
+ end
54
+ to_eval_nodes = nodes.reduce(Memory.empty) do |m, node|
55
+ m.and(node.memory_used_to_eval_node(self))
56
+ end
57
+ to_hold_memoized_nodes.and(to_eval_nodes).or(to_init_nodes)
58
+ end
59
+ @memory.count(type_str)
60
+ end
61
+
62
+ def <<(element)
63
+ case element
64
+ when Function
65
+ @func_h[element.str] = element
66
+ when Node
67
+ @node_h[element.str] = element
68
+ when Type
69
+ @type_h[element.str] = element
70
+ when VConst
71
+ @vconst_h[element.str] = element
72
+ else
73
+ raise
74
+ end
75
+ end
76
+
77
+ def append_output_node_str(output_node_str)
78
+ @output_node_strs << output_node_str
79
+ end
80
+
81
+ def append_init_func_str(init_func_str)
82
+ @init_func_strs << init_func_str
83
+ end
84
+
85
+ def func(func_str)
86
+ raise func_str unless @func_h.key?(func_str)
87
+ @func_h[func_str]
88
+ end
89
+
90
+ def node(node_str)
91
+ raise node_str unless @node_h.key?(node_str)
92
+ @node_h[node_str]
93
+ end
94
+
95
+ def type(type_str)
96
+ raise type_str unless @type_h.key?(type_str)
97
+ @type_h[type_str]
98
+ end
99
+
100
+ def vconst(vconst_str)
101
+ raise vconst_str unless @vconst_h.key?(vconst_str)
102
+ @vconst_h[vconst_str]
103
+ end
104
+
105
+ def funcs
106
+ @func_h.values
107
+ end
108
+
109
+ def nodes
110
+ @node_h.values
111
+ end
112
+
113
+ def types
114
+ @type_h.values
115
+ end
116
+
117
+ def vconsts
118
+ @vconst_h.values
119
+ end
120
+
121
+ private
122
+
123
+ # All used nodes.
124
+ def used_nodes
125
+ node_strs = @output_node_strs.flat_map do |node_str|
126
+ node(node_str).sorted_node_strs(self)
127
+ end
128
+ node_strs.uniq.map { |node_str| node(node_str) }
129
+ end
130
+
131
+ # Generate the main-function.
132
+ def gen_main_func(dest_set)
133
+ dest_set << L.function('main', 'int') do |f|
134
+ f << L.stmt('int c = 0, l = 1')
135
+ used_nodes.each { |node| node.gen_node_var_declaration(self, f) }
136
+ @init_func_strs.each do |func_str|
137
+ f << L.stmt(func(func_str).low_call_exp([]))
138
+ end
139
+ used_nodes.each { |node| node.gen_initialize_stmt(self, f) }
140
+ f << L.while('1') do |wh|
141
+ @type_h.values.each { |type| type.gen_mark_cleanup_stmt(self, wh) }
142
+ used_nodes.each { |node| node.gen_node_var_mark_stmt(self, wh) }
143
+ used_nodes.each { |node| node.gen_evaluate_stmt(self, wh) }
144
+ wh << L.stmt('c ^= 1, l ^= 1')
145
+ end
146
+ f << L.stmt('return 0')
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,210 @@
1
+ module SFRP
2
+ module Mono
3
+ class Type
4
+ attr_reader :str
5
+
6
+ def initialize(str, vconst_strs = nil, static = false, native_str = nil)
7
+ @str = str
8
+ @vconst_strs = vconst_strs
9
+ @static = static
10
+ @native_str = native_str
11
+ end
12
+
13
+ def comp
14
+ [@str, @vconst_strs, @static, @native_str]
15
+ end
16
+
17
+ def ==(other)
18
+ comp == other.comp
19
+ end
20
+
21
+ # Are objects of this type passed through value?
22
+ # Defalut is passing through referrence.
23
+ def static?
24
+ @static
25
+ end
26
+
27
+ # Does this type has infinite amount of vconsts?
28
+ def infinite?
29
+ @vconst_strs.nil?
30
+ end
31
+
32
+ # Is this type native type?
33
+ def native?
34
+ @native_str
35
+ end
36
+
37
+ # Does this type has single vconst of native type parameters
38
+ # e.g. Tuple3(Int, Int, Int)
39
+ def linear?(set)
40
+ single_vconst? && set.vconst(@vconst_strs[0]).native_args?(set)
41
+ end
42
+
43
+ # Does this type has only one vconst?
44
+ def single_vconst?
45
+ !infinite? && @vconst_strs.size == 1
46
+ end
47
+
48
+ # Do objects of this type need to be passed to mark-function?
49
+ def need_mark?(set)
50
+ return true unless static?
51
+ return false if infinite?
52
+ @vconst_strs.any? { |v_str| set.vconst(v_str).param_needing_mark?(set) }
53
+ end
54
+
55
+ def has_meta_in_struct?
56
+ !(static? && single_vconst?)
57
+ end
58
+
59
+ def all_pattern_examples(set)
60
+ return [Pattern::PatternExample.new(nil, [])] if infinite?
61
+ @vconst_strs.flat_map do |vc_str|
62
+ set.vconst(vc_str).all_pattern_examples(set)
63
+ end
64
+ end
65
+
66
+ # Return max memory size to hold an instance of this type.
67
+ def memory(set)
68
+ return Memory.one(@str) if infinite?
69
+ x = @vconst_strs.reduce(Memory.empty) do |m, v_str|
70
+ m.or(set.vconst(v_str).memory(set))
71
+ end
72
+ Memory.one(@str).and(x)
73
+ end
74
+
75
+ def low_typedef_for_alias(alias_str)
76
+ L.typedef("#{low_type_str} #{alias_str}")
77
+ end
78
+
79
+ def low_type_str
80
+ @native_str ? @native_str : @str
81
+ end
82
+
83
+ def low_allocator_str
84
+ "alloc_#{@str}"
85
+ end
86
+
87
+ def low_mark_func_str
88
+ "mark_#{@str}"
89
+ end
90
+
91
+ def meta_access_str(receiver_str)
92
+ "#{receiver_str}#{static? ? '.' : '->'}meta"
93
+ end
94
+
95
+ def terms_access_str(receiver_str)
96
+ "#{receiver_str}#{static? ? '.' : '->'}terms"
97
+ end
98
+
99
+ # Return term-id of given vconst of this type.
100
+ def term_id(vconst_str)
101
+ raise "#{@str} is infinite" if infinite?
102
+ res = @vconst_strs.index(vconst_str)
103
+ raise "#{vconst_str} is not a vconst of #{@str}" unless res
104
+ res
105
+ end
106
+
107
+ def low_member_pointers_for_single_vconst(set, receiver_str)
108
+ raise unless single_vconst?
109
+ set.vconst(@vconst_strs[0]).low_member_pointers(self, receiver_str)
110
+ end
111
+
112
+ # Generate C's elements for this type.
113
+ def gen(src_set, dest_set)
114
+ gen_struct(src_set, dest_set)
115
+ gen_typedef(src_set, dest_set)
116
+ gen_constructor(src_set, dest_set)
117
+ gen_allocator(src_set, dest_set)
118
+ gen_mark_function(src_set, dest_set)
119
+ end
120
+
121
+ # Generate statement to clean up objects of this types.
122
+ def gen_mark_cleanup_stmt(src_set, stmts)
123
+ return unless need_mark?(src_set)
124
+ return if src_set.memory(@str) == 0
125
+ stmts << L.stmt("#{low_allocator_str}(1)")
126
+ end
127
+
128
+ private
129
+
130
+ # Generate struct for this type.
131
+ def gen_struct(src_set, dest_set)
132
+ return if native? || infinite?
133
+ dest_set << L.struct(@str) do |top|
134
+ if has_meta_in_struct?
135
+ top << L.member_structure('struct', 'meta') do |meta|
136
+ meta << L.member('unsigned char term_id : 7')
137
+ meta << L.member('unsigned char mark : 1')
138
+ end
139
+ end
140
+ top << L.member_structure('union', 'terms') do |terms|
141
+ @vconst_strs.each_with_index do |v_str, term_id|
142
+ vconst = src_set.vconst(v_str)
143
+ vconst.gen_term_definition(src_set, term_id, terms)
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ # Generate typedef for this type.
150
+ def gen_typedef(_src_set, dest_set)
151
+ return if native?
152
+ asta = static? ? '' : '*'
153
+ dest_set << L.typedef("struct #{@str}#{asta} #{@str}")
154
+ end
155
+
156
+ # Generate constructor-functions for vconsts.
157
+ def gen_constructor(src_set, dest_set)
158
+ return if infinite?
159
+ @vconst_strs.each_with_index do |v_str, term_id|
160
+ src_set.vconst(v_str).gen_constructor(src_set, term_id, dest_set)
161
+ end
162
+ end
163
+
164
+ # Generate allocator-function for type.
165
+ def gen_allocator(src_set, dest_set)
166
+ return if static?
167
+ count = src_set.memory(@str)
168
+ memory_var = "memory_#{low_type_str}"
169
+ dest_set << L.function(low_allocator_str, low_type_str) do |f|
170
+ f.append_param('int', 'clean_up')
171
+ f << L.stmt('static int i = 0')
172
+ f << L.stmt("static struct #{low_type_str} #{memory_var}[#{count}]")
173
+ f << L.if_stmt('clean_up') do |if_stmts|
174
+ e = "#{memory_var}[i].meta.mark = 0"
175
+ if_stmts << L.stmt("for (i = 0; i < #{count}; i++) #{e}")
176
+ if_stmts << L.stmt('i = 0')
177
+ if_stmts << L.stmt('return 0')
178
+ end
179
+ f << L.stmt("while (#{memory_var}[i++].meta.mark)")
180
+ f << L.stmt("return #{memory_var} + (i - 1)")
181
+ end
182
+ end
183
+
184
+ # Generate mark function for this type.
185
+ def gen_mark_function(src_set, dest_set)
186
+ return unless need_mark?(src_set)
187
+ dest_set << L.function(low_mark_func_str, 'int') do |f|
188
+ f.append_param(low_type_str, 'target')
189
+ f << L.stmt("#{meta_access_str('target')}.mark = 1") unless static?
190
+ @vconst_strs.each_with_index do |v_str, term_id|
191
+ vconst = src_set.vconst(v_str)
192
+ cond_exps = vconst.low_compare_exps(src_set, 'target')
193
+ mark_exps = vconst.low_mark_element_exps(src_set, term_id, 'target')
194
+ next if mark_exps.empty?
195
+ mark_stmt = L.stmt(mark_exps.join(', '))
196
+ if cond_exps.empty?
197
+ f << mark_stmt
198
+ else
199
+ cond_exp = cond_exps.reduce { |a, e| "#{a} && #{e}" }
200
+ f << L.if_stmt(cond_exp) do |i|
201
+ i << mark_stmt
202
+ end
203
+ end
204
+ end
205
+ f << L.stmt('return 0')
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end