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.
- checksums.yaml +7 -0
- data/.ctags +3 -0
- data/.editorconfig +9 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +629 -0
- data/.travis.yml +12 -0
- data/Gemfile +2 -0
- data/LICENSE +28 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/base-library/Base.sfrp +81 -0
- data/base-library/IO/AVR/ATMEGA8.c +9 -0
- data/base-library/IO/AVR/ATMEGA8.h +6 -0
- data/base-library/IO/AVR/ATMEGA8.sfrp +4 -0
- data/base-library/IO/STDIO.c +40 -0
- data/base-library/IO/STDIO.h +13 -0
- data/base-library/IO/STDIO.sfrp +10 -0
- data/bin/sfrp +7 -0
- data/lib/sfrp.rb +2 -0
- data/lib/sfrp/command.rb +73 -0
- data/lib/sfrp/compiler.rb +94 -0
- data/lib/sfrp/error.rb +4 -0
- data/lib/sfrp/file.rb +18 -0
- data/lib/sfrp/flat/dsl.rb +33 -0
- data/lib/sfrp/flat/elements.rb +90 -0
- data/lib/sfrp/flat/exception.rb +45 -0
- data/lib/sfrp/flat/expression.rb +125 -0
- data/lib/sfrp/flat/set.rb +61 -0
- data/lib/sfrp/input/exception.rb +16 -0
- data/lib/sfrp/input/parser.rb +417 -0
- data/lib/sfrp/input/set.rb +29 -0
- data/lib/sfrp/input/transformer.rb +219 -0
- data/lib/sfrp/low/dsl.rb +126 -0
- data/lib/sfrp/low/element.rb +126 -0
- data/lib/sfrp/low/set.rb +62 -0
- data/lib/sfrp/mono/dsl.rb +120 -0
- data/lib/sfrp/mono/environment.rb +26 -0
- data/lib/sfrp/mono/exception.rb +21 -0
- data/lib/sfrp/mono/expression.rb +124 -0
- data/lib/sfrp/mono/function.rb +86 -0
- data/lib/sfrp/mono/memory.rb +32 -0
- data/lib/sfrp/mono/node.rb +125 -0
- data/lib/sfrp/mono/pattern.rb +69 -0
- data/lib/sfrp/mono/set.rb +151 -0
- data/lib/sfrp/mono/type.rb +210 -0
- data/lib/sfrp/mono/vconst.rb +134 -0
- data/lib/sfrp/output/set.rb +33 -0
- data/lib/sfrp/poly/dsl.rb +171 -0
- data/lib/sfrp/poly/elements.rb +168 -0
- data/lib/sfrp/poly/exception.rb +42 -0
- data/lib/sfrp/poly/expression.rb +170 -0
- data/lib/sfrp/poly/monofier.rb +73 -0
- data/lib/sfrp/poly/set.rb +90 -0
- data/lib/sfrp/poly/typing.rb +197 -0
- data/lib/sfrp/raw/dsl.rb +41 -0
- data/lib/sfrp/raw/elements.rb +164 -0
- data/lib/sfrp/raw/exception.rb +40 -0
- data/lib/sfrp/raw/expression.rb +168 -0
- data/lib/sfrp/raw/namespace.rb +30 -0
- data/lib/sfrp/raw/set.rb +109 -0
- data/lib/sfrp/version.rb +3 -0
- data/sfrp.gemspec +40 -0
- data/spec/sfrp/Test.sfrp +4 -0
- data/spec/sfrp/compiler_spec.rb +17 -0
- data/spec/sfrp/flat/set_spec.rb +40 -0
- data/spec/sfrp/input/parse_test.sfrp +20 -0
- data/spec/sfrp/input/set_spec.rb +18 -0
- data/spec/sfrp/low/set_spec.rb +20 -0
- data/spec/sfrp/mono/expected.yml +295 -0
- data/spec/sfrp/mono/set_spec.rb +152 -0
- data/spec/sfrp/output/set_spec.rb +29 -0
- data/spec/sfrp/poly/set_spec.rb +290 -0
- data/spec/sfrp/raw/set_spec.rb +38 -0
- data/spec/spec_helper.rb +16 -0
- data/test/IntTest/Main.c +5 -0
- data/test/IntTest/Main.h +6 -0
- data/test/IntTest/Main.sfrp +10 -0
- data/test/IntTest/in.txt +3 -0
- data/test/IntTest/out.txt +4 -0
- data/test/MaybeTest/Main.sfrp +8 -0
- data/test/MaybeTest/SubDir/Lib.sfrp +9 -0
- data/test/MaybeTest/in.txt +6 -0
- data/test/MaybeTest/out.txt +6 -0
- data/test/Rakefile +15 -0
- metadata +290 -0
@@ -0,0 +1,134 @@
|
|
1
|
+
module SFRP
|
2
|
+
module Mono
|
3
|
+
class VConst
|
4
|
+
attr_reader :str
|
5
|
+
|
6
|
+
def initialize(str, type_str, arg_type_strs, native_str = nil)
|
7
|
+
@str = str
|
8
|
+
@type_str = type_str
|
9
|
+
@arg_type_strs = arg_type_strs
|
10
|
+
@native_str = native_str
|
11
|
+
end
|
12
|
+
|
13
|
+
def comp
|
14
|
+
[@str, @type_str, @arg_type_strs, @native_str]
|
15
|
+
end
|
16
|
+
|
17
|
+
def ==(other)
|
18
|
+
comp == other.comp
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return max memory size to hold an instance of this vconst.
|
22
|
+
def memory(set)
|
23
|
+
@arg_type_strs.reduce(Memory.empty) do |m, t_str|
|
24
|
+
m.and(set.type(t_str).memory(set))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Is this vconst expressed in native C value?
|
29
|
+
def native?
|
30
|
+
@native_str
|
31
|
+
end
|
32
|
+
|
33
|
+
def native_args?(set)
|
34
|
+
@arg_type_strs.all? { |s| set.type(s).native? }
|
35
|
+
end
|
36
|
+
|
37
|
+
def all_pattern_examples(set)
|
38
|
+
return [Pattern::PatternExample.new(@str, [])] if @arg_type_strs.empty?
|
39
|
+
head, *tail = @arg_type_strs.map do |type_str|
|
40
|
+
set.type(type_str).all_pattern_examples(set)
|
41
|
+
end
|
42
|
+
head.product(*tail).map do |args|
|
43
|
+
Pattern::PatternExample.new(@str, args)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Generate a struct-element of term for this vconst.
|
48
|
+
def gen_term_definition(set, term_id, terms)
|
49
|
+
return if native?
|
50
|
+
terms << L.member_structure('struct', "term#{term_id}") do |term|
|
51
|
+
@arg_type_strs.each_with_index do |t_str, idx|
|
52
|
+
low_type_str = set.type(t_str).low_type_str
|
53
|
+
term << L.member("#{low_type_str} member#{idx}")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Do elements of this vconst need marking?
|
59
|
+
def param_needing_mark?(set)
|
60
|
+
@arg_type_strs.any? { |type_str| set.type(type_str).need_mark?(set) }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Generate constructor-function in C.
|
64
|
+
def gen_constructor(src_set, term_id, dest_set)
|
65
|
+
return if native?
|
66
|
+
type = src_set.type(@type_str)
|
67
|
+
dest_set << L.function(low_constructor_str, type.low_type_str) do |f|
|
68
|
+
@arg_type_strs.each_with_index.map do |t_str, mem_idx|
|
69
|
+
f.append_param(src_set.type(t_str).low_type_str, "member#{mem_idx}")
|
70
|
+
end
|
71
|
+
if type.static?
|
72
|
+
f << L.stmt("#{type.low_type_str} x")
|
73
|
+
else
|
74
|
+
f << L.stmt("#{type.low_type_str} x = #{type.low_allocator_str}(0)")
|
75
|
+
end
|
76
|
+
if type.has_meta_in_struct?
|
77
|
+
f << L.stmt("#{type.meta_access_str('x')}.term_id = #{term_id}")
|
78
|
+
end
|
79
|
+
@arg_type_strs.size.times do |mem_idx|
|
80
|
+
terms = type.terms_access_str('x')
|
81
|
+
m = "member#{mem_idx}"
|
82
|
+
f << L.stmt("#{terms}.term#{term_id}.#{m} = #{m}")
|
83
|
+
end
|
84
|
+
f << L.stmt('return x')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# return low-expression to make a new instance by this vconst
|
89
|
+
def low_constructor_call_exp(low_arg_exps)
|
90
|
+
return @native_str if native?
|
91
|
+
"#{low_constructor_str}(#{low_arg_exps.join(', ')})"
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return conditional-low-exps to match this vconst and receiver-exp.
|
95
|
+
def low_compare_exps(set, receiver_exp)
|
96
|
+
type = set.type(@type_str)
|
97
|
+
return [] if type.single_vconst?
|
98
|
+
return ["#{receiver_exp} == #{@native_str}"] if native?
|
99
|
+
meta = type.meta_access_str(receiver_exp)
|
100
|
+
term_id = type.term_id(@str)
|
101
|
+
["#{meta}.term_id == #{term_id}"]
|
102
|
+
end
|
103
|
+
|
104
|
+
# name of constructor-function in C for this vconst
|
105
|
+
def low_constructor_str
|
106
|
+
'VC_' + @str
|
107
|
+
end
|
108
|
+
|
109
|
+
# Return alias of the constructor of this vconst.
|
110
|
+
def low_macro_for_alias(alias_str)
|
111
|
+
arg = ('a'..'z').take(@arg_type_strs.size).join(', ')
|
112
|
+
L.macro("#{alias_str}(#{arg}) #{low_constructor_str}(#{arg})")
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return low-exp to mark elements of this vconst.
|
116
|
+
def low_mark_element_exps(set, term_id, receiver_str)
|
117
|
+
types = @arg_type_strs.map { |t_str| set.type(t_str) }
|
118
|
+
types_needing_mark = types.select { |t| t.need_mark?(set) }
|
119
|
+
types_needing_mark.each_with_index.map do |type, mem_idx|
|
120
|
+
term_access = "#{type.terms_access_str(receiver_str)}.term#{term_id}"
|
121
|
+
"#{type.low_mark_func_str}(#{term_access}.member#{mem_idx})"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def low_member_pointers(type, receiver_str)
|
126
|
+
term_id = type.term_id(@str)
|
127
|
+
terms_access = "#{type.terms_access_str(receiver_str)}.term#{term_id}"
|
128
|
+
@arg_type_strs.each_with_index.map do |_, mem_idx|
|
129
|
+
"&#{terms_access}.member#{mem_idx}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'sfrp/file'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module SFRP
|
5
|
+
module Output
|
6
|
+
class Set
|
7
|
+
attr_reader :virtual_files
|
8
|
+
|
9
|
+
def initialize(&block)
|
10
|
+
@virtual_files = []
|
11
|
+
block.call(self) if block
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate!(output_dir_path, other_virtual_files = [])
|
15
|
+
unless File.directory?(output_dir_path)
|
16
|
+
FileUtils.mkdir_p(output_dir_path)
|
17
|
+
end
|
18
|
+
FileUtils.cd(output_dir_path) do
|
19
|
+
(@virtual_files + other_virtual_files).each do |vf|
|
20
|
+
relative_path = vf.fmodule_uri.gsub('.', '/') + '.' + vf.file_ext
|
21
|
+
dirname = File.dirname(relative_path)
|
22
|
+
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
23
|
+
File.open(relative_path, 'w') { |f| f.write(vf.content) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_file(relative_position, file_ext, content)
|
29
|
+
@virtual_files << VirtualFile.new(relative_position, file_ext, content)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module SFRP
|
2
|
+
module Poly
|
3
|
+
module DSL
|
4
|
+
extend SFRP::P = self
|
5
|
+
|
6
|
+
def tconst(tconst_str, var_strs, static, native_str, infinite, &block)
|
7
|
+
tp = TConstProxy.new(tconst_str, var_strs, infinite)
|
8
|
+
block.call(tp) if block
|
9
|
+
argc = var_strs.size
|
10
|
+
TConst.new(tconst_str, argc, tp.vconst_strs, static, native_str)
|
11
|
+
end
|
12
|
+
|
13
|
+
def func(func_str, ret_type_annot = nil, &block)
|
14
|
+
fp = FuncProxy.new(func_str, ret_type_annot)
|
15
|
+
block.call(fp) if block
|
16
|
+
fp.to_func
|
17
|
+
end
|
18
|
+
|
19
|
+
def node(node_str, type_annot = nil, &block)
|
20
|
+
np = NodeProxy.new(node_str, type_annot)
|
21
|
+
block.call(np) if block
|
22
|
+
np.to_node
|
23
|
+
end
|
24
|
+
|
25
|
+
def t(tconst_str, *args)
|
26
|
+
TypeAnnotationType.new(tconst_str, args)
|
27
|
+
end
|
28
|
+
|
29
|
+
def tv(var_str)
|
30
|
+
TypeAnnotationVar.new(var_str)
|
31
|
+
end
|
32
|
+
|
33
|
+
def match_e(left_exp, &block)
|
34
|
+
cp = CaseProxy.new
|
35
|
+
block.call(cp) if block
|
36
|
+
MatchExp.new(left_exp, cp.to_a)
|
37
|
+
end
|
38
|
+
|
39
|
+
def call_e(func_str, *arg_exps)
|
40
|
+
FuncCallExp.new(func_str, arg_exps)
|
41
|
+
end
|
42
|
+
|
43
|
+
def vc_call_e(vconst_str, *arg_exps)
|
44
|
+
VConstCallExp.new(vconst_str, arg_exps)
|
45
|
+
end
|
46
|
+
|
47
|
+
def v_e(var_str)
|
48
|
+
VarRefExp.new(var_str)
|
49
|
+
end
|
50
|
+
|
51
|
+
def pat(vconst_str, *arg_patterns)
|
52
|
+
Pattern.new(vconst_str, nil, arg_patterns)
|
53
|
+
end
|
54
|
+
|
55
|
+
def pref(vconst_str, ref_var_str, *arg_patterns)
|
56
|
+
Pattern.new(vconst_str, ref_var_str, arg_patterns)
|
57
|
+
end
|
58
|
+
|
59
|
+
def pany(ref_var_str = nil)
|
60
|
+
Pattern.new(nil, ref_var_str, [])
|
61
|
+
end
|
62
|
+
|
63
|
+
class TConstProxy
|
64
|
+
def initialize(tconst_str, var_strs, infinite)
|
65
|
+
args = var_strs.map { |v| TypeAnnotationVar.new(v) }
|
66
|
+
@ret_type_annot = TypeAnnotationType.new(tconst_str, args)
|
67
|
+
@var_strs = var_strs
|
68
|
+
@infinite = infinite
|
69
|
+
@vconst_strs = []
|
70
|
+
end
|
71
|
+
|
72
|
+
def vconst(vconst_str, arg_type_annots, native_str = nil)
|
73
|
+
ftype_annot = FuncTypeAnnotation.new(@ret_type_annot, arg_type_annots)
|
74
|
+
@vconst_strs << vconst_str
|
75
|
+
VConst.new(vconst_str, @var_strs, ftype_annot, native_str)
|
76
|
+
end
|
77
|
+
|
78
|
+
def vconst_strs
|
79
|
+
@infinite ? nil : @vconst_strs
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class FuncProxy
|
84
|
+
def initialize(func_str, ret_type_annot = nil)
|
85
|
+
@func_str = func_str
|
86
|
+
@ret_type_annot = ret_type_annot || DSL.tv('%a0')
|
87
|
+
@param_strs = []
|
88
|
+
@type_annots = []
|
89
|
+
end
|
90
|
+
|
91
|
+
def param(param_str, type_annot = nil)
|
92
|
+
@param_strs << param_str
|
93
|
+
@type_annots << (type_annot || DSL.tv('%a' + @param_strs.size.to_s))
|
94
|
+
end
|
95
|
+
|
96
|
+
def ffi_str(str)
|
97
|
+
@ffi_str = str
|
98
|
+
end
|
99
|
+
|
100
|
+
def exp(&block)
|
101
|
+
@exp = block.call
|
102
|
+
end
|
103
|
+
|
104
|
+
def to_func
|
105
|
+
ftype_annot = FuncTypeAnnotation.new(@ret_type_annot, @type_annots)
|
106
|
+
Function.new(@func_str, @param_strs, ftype_annot, @exp, @ffi_str)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class NodeProxy
|
111
|
+
def initialize(node_str, type_annot)
|
112
|
+
@node_str = node_str
|
113
|
+
@type_annot = type_annot || TypeAnnotationVar.new('%a0')
|
114
|
+
@node_refs = []
|
115
|
+
@type_annots = []
|
116
|
+
end
|
117
|
+
|
118
|
+
def c(node_str)
|
119
|
+
dep(node_str, false)
|
120
|
+
end
|
121
|
+
|
122
|
+
def l(node_str)
|
123
|
+
dep(node_str, true)
|
124
|
+
end
|
125
|
+
|
126
|
+
def dep(node_str, last)
|
127
|
+
@node_refs << Node::NodeRef.new(node_str, last)
|
128
|
+
@type_annots << TypeAnnotationVar.new('%a' + @node_refs.size.to_s)
|
129
|
+
end
|
130
|
+
|
131
|
+
def eval_func(func_str, ret_type_annot = nil, &block)
|
132
|
+
@eval_func_str = func_str
|
133
|
+
DSL.func(func_str, ret_type_annot, &block)
|
134
|
+
end
|
135
|
+
|
136
|
+
def init_func(func_str, ret_type_annot = nil, &block)
|
137
|
+
@init_func_str = func_str
|
138
|
+
DSL.func(func_str, ret_type_annot, &block)
|
139
|
+
end
|
140
|
+
|
141
|
+
def eval_func_str(func_str)
|
142
|
+
@eval_func_str = func_str
|
143
|
+
end
|
144
|
+
|
145
|
+
def init_func_str(func_str)
|
146
|
+
@init_func_str = func_str
|
147
|
+
end
|
148
|
+
|
149
|
+
def to_node
|
150
|
+
a = @node_refs.size.times.map { |i| TypeAnnotationVar.new("a#{i}") }
|
151
|
+
annot = FuncTypeAnnotation.new(@type_annot, a)
|
152
|
+
Node.new(@node_str, @node_refs, annot, @eval_func_str, @init_func_str)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class CaseProxy
|
157
|
+
def initialize
|
158
|
+
@cases = []
|
159
|
+
end
|
160
|
+
|
161
|
+
def case(pattern, &exp_block)
|
162
|
+
@cases << MatchExp::Case.new(pattern, exp_block.call)
|
163
|
+
end
|
164
|
+
|
165
|
+
def to_a
|
166
|
+
@cases
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module SFRP
|
2
|
+
module Poly
|
3
|
+
class Function
|
4
|
+
attr_reader :str
|
5
|
+
|
6
|
+
def initialize(str, param_strs, ftype_annot, exp = nil, ffi_str = nil)
|
7
|
+
raise ArgumentError if exp.nil? && ffi_str.nil?
|
8
|
+
@str = str
|
9
|
+
@param_strs = param_strs
|
10
|
+
@ftype_annot = ftype_annot
|
11
|
+
@exp = exp
|
12
|
+
@ffi_str = ffi_str
|
13
|
+
end
|
14
|
+
|
15
|
+
def ftyping(set)
|
16
|
+
@ftyping ||= @ftype_annot.to_ftyping.instance do |ft|
|
17
|
+
var_env = {}
|
18
|
+
@param_strs.zip(ft.params) { |str, typing| var_env[str] = typing }
|
19
|
+
ft.body.unify(@exp.typing(set, var_env)) if @exp
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def clone
|
24
|
+
exp = (@exp ? @exp.clone : nil)
|
25
|
+
Function.new(@str, @param_strs, @ftype_annot, exp, @ffi_str)
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_recursion(set, path = [])
|
29
|
+
return if @exp == nil
|
30
|
+
if path.include?(@str)
|
31
|
+
raise RecursiveError.new(path.drop_while { |s| s != @str })
|
32
|
+
end
|
33
|
+
@exp.called_func_strs.each do |str|
|
34
|
+
set.func(str).check_recursion(set, path + [@str])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_mono(monofier, mono_func_str)
|
39
|
+
raise UndeterminableTypeError.new(@str, @ftyping) unless @ftyping.mono?
|
40
|
+
mono_type_str = monofier.use_type(@ftyping.body)
|
41
|
+
M.func(mono_type_str, mono_func_str) do |f|
|
42
|
+
@param_strs.zip(@ftyping.params) do |str, typing|
|
43
|
+
f.param(monofier.use_type(typing), str)
|
44
|
+
end
|
45
|
+
f.exp { @exp.to_mono(monofier) } if @exp
|
46
|
+
f.ffi_str(@ffi_str) if @ffi_str
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Node
|
52
|
+
attr_reader :str
|
53
|
+
|
54
|
+
NodeRef = Struct.new(:node_str, :last)
|
55
|
+
|
56
|
+
def initialize(
|
57
|
+
str, node_refs, ftype_annot, eval_func_str, init_func_str = nil
|
58
|
+
)
|
59
|
+
@str = str
|
60
|
+
@node_refs = node_refs
|
61
|
+
@ftype_annot = ftype_annot
|
62
|
+
@eval_func_str = eval_func_str
|
63
|
+
@init_func_str = init_func_str
|
64
|
+
end
|
65
|
+
|
66
|
+
def typing(set)
|
67
|
+
return @typing if @typing
|
68
|
+
@typing = Typing.new
|
69
|
+
@ftyping = set.func(@eval_func_str).ftyping(set).instance do |eval_ft|
|
70
|
+
@node_refs.zip(eval_ft.params) do |node_ref, typing|
|
71
|
+
set.node(node_ref.node_str).typing(set).unify(typing)
|
72
|
+
end
|
73
|
+
next unless @init_func_str
|
74
|
+
@init_ftyping = set.func(@init_func_str).ftyping(set).instance do |ft|
|
75
|
+
raise unless ft.params.empty?
|
76
|
+
ft.body.unify(eval_ft.body)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
@ftyping.unify(@ftype_annot.to_ftyping).body.unify(@typing)
|
80
|
+
end
|
81
|
+
|
82
|
+
def check_recursion(set, path = [])
|
83
|
+
if path.include?(@str)
|
84
|
+
raise RecursiveError.new(path.drop_while { |s| s != @str })
|
85
|
+
end
|
86
|
+
@node_refs.each do |nr|
|
87
|
+
next if nr.last
|
88
|
+
set.node(nr.node_str).check_recursion(set, path + [@str])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_mono(monofier)
|
93
|
+
raise UndeterminableTypeError.new(@str, @typing) unless @typing.mono?
|
94
|
+
type_str = monofier.use_type(@typing)
|
95
|
+
node_str = monofier.use_node(@str)
|
96
|
+
eval_func_str = monofier.use_func(@eval_func_str, @ftyping)
|
97
|
+
if @init_func_str
|
98
|
+
init_func_str = monofier.use_func(@init_func_str, @init_ftyping)
|
99
|
+
else
|
100
|
+
init_func_str = nil
|
101
|
+
end
|
102
|
+
M.node(type_str, node_str, eval_func_str, init_func_str) do |n|
|
103
|
+
@node_refs.each do |node_ref|
|
104
|
+
node_str = monofier.use_node(node_ref.node_str)
|
105
|
+
node_ref.last ? n.l(node_str) : n.c(node_str)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class TConst
|
112
|
+
attr_reader :str
|
113
|
+
|
114
|
+
def initialize(
|
115
|
+
str, paramc, vconst_strs = nil, static = false, native_str = nil
|
116
|
+
)
|
117
|
+
@str = str
|
118
|
+
@paramc = paramc
|
119
|
+
@vconst_strs = vconst_strs
|
120
|
+
@static = static
|
121
|
+
@native_str = native_str
|
122
|
+
end
|
123
|
+
|
124
|
+
def typing
|
125
|
+
@typing ||= Typing.new(@str, Array.new(@paramc) { Typing.new })
|
126
|
+
end
|
127
|
+
|
128
|
+
def clone
|
129
|
+
TConst.new(@str, @paramc, @vconst_strs, @static, @native_str)
|
130
|
+
end
|
131
|
+
|
132
|
+
def to_mono(monofier)
|
133
|
+
raise UndeterminableTypeError.new(@str, @typing) unless @typing.mono?
|
134
|
+
type_str = monofier.use_type(@typing)
|
135
|
+
return M.type(type_str, nil, @static, @native_str) unless @vconst_strs
|
136
|
+
vconst_strs = @vconst_strs.map { |s| monofier.use_vconst(s, @typing) }
|
137
|
+
M.type(type_str, vconst_strs, @static, @native_str)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class VConst
|
142
|
+
attr_reader :str
|
143
|
+
|
144
|
+
def initialize(str, annot_vars, ftype_annot, native_str = nil)
|
145
|
+
@str = str
|
146
|
+
@annot_vars = annot_vars
|
147
|
+
@ftype_annot = ftype_annot
|
148
|
+
@native_str = native_str
|
149
|
+
end
|
150
|
+
|
151
|
+
def ftyping
|
152
|
+
@ftyping ||= @ftype_annot.to_ftyping(@annot_vars)
|
153
|
+
end
|
154
|
+
|
155
|
+
def clone
|
156
|
+
VConst.new(@str, @annot_vars, @ftype_annot, @native_str)
|
157
|
+
end
|
158
|
+
|
159
|
+
def to_mono(monofier)
|
160
|
+
raise UndeterminableTypeError.new(@str, @ftyping) unless @ftyping.mono?
|
161
|
+
type_str = monofier.use_type(@ftyping.body)
|
162
|
+
vconst_str = monofier.use_vconst(@str, @ftyping.body)
|
163
|
+
arg_type_strs = @ftyping.params.map { |t| monofier.use_type(t) }
|
164
|
+
M.vconst(type_str, vconst_str, arg_type_strs, @native_str)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|