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,152 @@
1
+ require 'spec_helper'
2
+ require 'sfrp/mono/set'
3
+ require 'sfrp/low/set'
4
+
5
+ module SFRP
6
+ describe 'Compiled Low-Set from Mono-Set' do
7
+ let(:lset) do
8
+ set = Mono::Set.new
9
+
10
+ # type MaybeInt = JustInt(TInt) | NothingInt
11
+ set << M.type('MaybeInt', ['JustInt', 'NothingInt'])
12
+ set << M.vconst('MaybeInt', 'JustInt', ['Int'])
13
+ set << M.vconst('MaybeInt', 'NothingInt', [])
14
+
15
+ # type Pair = Pair(Int, Int)
16
+ set << M.type('Pair', ['Pair'])
17
+ set << M.vconst('Pair', 'Pair', ['Int', 'Int'])
18
+
19
+ # type Int{int}
20
+ set << M.type('Int', nil, true, 'int')
21
+ set << M.vconst('Int', '0', [], '0')
22
+ set << M.vconst('Int', '1', [], '1')
23
+
24
+ # type X = X1(MabybeInt) | X2(MaybeInt, MaybeInt)
25
+ set << M.type('X', ['X1', 'X2'])
26
+ set << M.vconst('X', 'X1', ['MaybeInt'])
27
+ set << M.vconst('X', 'X2', ['MaybeInt', 'MaybeInt'])
28
+
29
+ # type XX = XX(MaybeInt)
30
+ set << M.type('XX', ['XX'])
31
+ set << M.vconst('XX', 'XX', ['MaybeInt'])
32
+
33
+ # type STupleIntInt = STupleIntInt(Int, Int)
34
+ set << M.type('STupleIntInt', ['STupleIntInt'], true)
35
+ set << M.vconst('STupleIntInt', 'STupleIntInt', ['Int', 'Int'])
36
+
37
+ # func getMaybeInt(){get_maybe_int}
38
+ set << M.func('MaybeInt', 'getMaybeInt') do |f|
39
+ f.ffi_str('get_maybe_int')
40
+ end
41
+
42
+ set << M.func('Int', 'id') do |f|
43
+ f.param('Int', 'x')
44
+ f.exp { M.v_e('Int', 'x') }
45
+ end
46
+
47
+ set << M.func('Int', 'initialize') do |f|
48
+ f.ffi_str('init_system')
49
+ end
50
+
51
+ set << M.func('MaybeInt', 'initialMaybeInt') do |f|
52
+ f.exp { M.vc_call_e('MaybeInt', 'JustInt', M.vc_call_e('Int', '1')) }
53
+ end
54
+
55
+ set << M.func('Pair', 'ffiPair') do |f|
56
+ f.ffi_str('ffi_pair')
57
+ end
58
+
59
+ # func (arg) = arg of MaybeInt(x) -> Pair(x, x), NothingInt -> (0, 0)
60
+ set << M.func('Pair', 'toPair') do |f|
61
+ f.param('MaybeInt', 'arg')
62
+ f.exp do
63
+ M.match_e('Pair', M.v_e('MaybeInt', 'arg')) do |m|
64
+ m.case(M.pat('MaybeInt', 'JustInt', M.pany('Int', 'x'))) do
65
+ M.vc_call_e('Pair', 'Pair', M.v_e('Int', 'x'), M.v_e('Int', 'x'))
66
+ end
67
+ m.case(M.pref('MaybeInt', 'NothingInt', 'hoge')) do
68
+ zero = M.call_e('Int', 'id', M.vc_call_e('Int', '0'))
69
+ M.vc_call_e('Pair', 'Pair', zero, zero)
70
+ end
71
+ m.case(M.pany('MaybeInt')) do
72
+ M.call_e('Pair', 'ffiPair')
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ # func (arg) = arg of VX(x, y) -> VX(y, x)
79
+ set << M.func('X', 'swap') do |f|
80
+ f.param('X', 'arg')
81
+ f.exp do
82
+ M.match_e('X', M.v_e('X', 'arg'))do |m|
83
+ mint = 'MaybeInt'
84
+ m.case(M.pat('X', 'X1', M.pany(mint, 'x'))) do
85
+ M.vc_call_e('X', 'X1', M.v_e(mint, 'x'))
86
+ end
87
+ m.case(M.pat('X', 'X2', M.pany(mint, 'x'), M.pany(mint, 'y'))) do
88
+ M.vc_call_e('X', 'X2', M.v_e(mint, 'y'), M.v_e(mint, 'x'))
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ # node bufNode[1] = getMaybeInt()
95
+ set << M.node('MaybeInt', 'bufNode', 'getMaybeInt', 'initialMaybeInt')
96
+
97
+ # node node1 = toPair(bufNode, @bufNode)
98
+ set << M.node('Pair', 'node1', 'toPair', nil) do |n|
99
+ n.c('bufNode')
100
+ n.l('bufNode')
101
+ end
102
+
103
+ set.append_output_node_str('node1')
104
+ set.append_init_func_str('initialize')
105
+
106
+ set.to_low
107
+ end
108
+
109
+ let(:expected) do
110
+ require 'yaml'
111
+ YAML.load_file(File.expand_path('../expected.yml', __FILE__))
112
+ end
113
+
114
+ it 'has includes' do
115
+ expect(lset.includes.map(&:to_s)).to contain_exactly(
116
+ *expected['includes']
117
+ )
118
+ end
119
+
120
+ it 'has macros' do
121
+ expect(lset.macros.map(&:to_s)).to contain_exactly(
122
+ *expected['macros']
123
+ )
124
+ end
125
+
126
+ it 'has typedefs' do
127
+ expect(lset.typedefs.map(&:to_s)).to contain_exactly(
128
+ *expected['typedefs']
129
+ )
130
+ end
131
+
132
+ it 'has structs' do
133
+ expect(lset.structs.map(&:to_s)).to contain_exactly(
134
+ *expected['structs'].map(&:chomp)
135
+ )
136
+ end
137
+
138
+ it 'has prototypes of the function' do
139
+ expect(lset.functions.map(&:pretty_code_prototype)).to contain_exactly(
140
+ *expected['proto_functions']
141
+ )
142
+ end
143
+
144
+ it 'has functions' do
145
+ expected_functions = expected['functions'].map(&:chomp).sort
146
+ actual_functions = lset.functions.map(&:to_s).sort
147
+ actual_functions.zip(expected_functions) do |a, e|
148
+ expect(a).to eql e
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'sfrp/output/set'
3
+
4
+ module SFRP
5
+ describe 'Output-Set' do
6
+ let(:oset) do
7
+ Output::Set.new do |s|
8
+ s.create_file('Hoge.Fuga.Piyo', 'txt', 'I am piyo.')
9
+ s.create_file('Hoge.Fuga.Hina', 'txt', 'I am hina.')
10
+ end
11
+ end
12
+
13
+ let(:sample_vf) do
14
+ VirtualFile.new('Hoge', 'txt', 'I am hoge.')
15
+ end
16
+
17
+ it 'generates files' do
18
+ Dir.mktmpdir do |dirpath|
19
+ oset.generate!(dirpath, [sample_vf])
20
+ expect(File.open(dirpath + '/Hoge.txt', 'r', &:read))
21
+ .to eql 'I am hoge.'
22
+ expect(File.open(dirpath + '/Hoge/Fuga/Piyo.txt', 'r', &:read))
23
+ .to eql 'I am piyo.'
24
+ expect(File.open(dirpath + '/Hoge/Fuga/Hina.txt', 'r', &:read))
25
+ .to eql 'I am hina.'
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,290 @@
1
+ require 'spec_helper'
2
+ require 'sfrp/poly/set'
3
+ require 'sfrp/mono/set'
4
+
5
+ module SFRP
6
+ describe do
7
+ def define_maybe(set)
8
+ # type Maybe[a] = Just(a) | Nothing
9
+ set << P.tconst('Maybe', ['a'], false, nil, false) do |t|
10
+ set << t.vconst('Just', [P.tv('a')])
11
+ set << t.vconst('Nothing', [])
12
+ end
13
+ end
14
+
15
+ def define_prims(set)
16
+ # type Int{int}
17
+ set << P.tconst('Int', [], true, 'int', true) do |t|
18
+ set << t.vconst('1', [], '1')
19
+ end
20
+
21
+ # type Float{float}
22
+ set << P.tconst('Float', [], true, 'float', true) do |t|
23
+ set << t.vconst('1.0', [], '1.0f')
24
+ end
25
+ end
26
+
27
+ def define_id(set)
28
+ # fun id(x) = x
29
+ set << P.func('id') do |f|
30
+ f.param('x')
31
+ f.exp { P.v_e('x') }
32
+ end
33
+ end
34
+
35
+ describe 'Compiled Mono-Set from Poly-Set' do
36
+ let(:mset) do
37
+ set = Poly::Set.new
38
+
39
+ define_maybe(set)
40
+ define_prims(set)
41
+ define_id(set)
42
+
43
+ # fun getOrElse(m : Maybe[a], x : a) : a =
44
+ # m of Just(y) -> y, Nothing -> x
45
+ set << P.func('getOrElse', P.tv('a')) do |f|
46
+ f.param('m', P.t('Maybe', P.tv('a')))
47
+ f.param('x', P.tv('a'))
48
+ f.exp do
49
+ P.match_e P.v_e('m') do |m|
50
+ m.case P.pat('Just', P.pany('y')) do
51
+ P.v_e('y')
52
+ end
53
+ m.case P.pref('Nothing', 'z') do
54
+ P.v_e('x')
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ # @const1 = 1
61
+ set << P.node('const1') do |n|
62
+ set << n.eval_func('const1') do |f|
63
+ f.exp { P.call_e('id', P.vc_call_e('1')) }
64
+ end
65
+ end
66
+
67
+ # @const1f = 1.0
68
+ set << P.node('const1f') do |n|
69
+ set << n.eval_func('const1f') do |f|
70
+ f.exp { P.vc_call_e('1.0') }
71
+ end
72
+ n.init_func_str('const1f')
73
+ end
74
+
75
+ # in @intEventInput{int_input}
76
+ set << P.node('intEventInput') do |n|
77
+ set << n.eval_func('intEventInput', P.t('Maybe', P.t('Int'))) do |f|
78
+ f.ffi_str('int_input')
79
+ end
80
+ end
81
+
82
+ # in @floatEventInput{float_input}
83
+ set << P.node('floatEventInput') do |n|
84
+ type_annot = P.t('Maybe', P.t('Float'))
85
+ set << n.eval_func('floatEventInput', type_annot) do |f|
86
+ f.ffi_str('float_input')
87
+ end
88
+ end
89
+
90
+ # @nodeA = getOrElse(@intEventInput, @const1)
91
+ set << P.node('nodeA') do |n|
92
+ n.c('intEventInput')
93
+ n.c('const1')
94
+ n.eval_func_str('getOrElse')
95
+ set << n.init_func('const1p') do |f|
96
+ f.exp { P.vc_call_e('1') }
97
+ end
98
+ end
99
+
100
+ # @nodeB = getOrElse(@floatEventInput, @const1f)
101
+ set << P.node('nodeB') do |n|
102
+ n.c('floatEventInput')
103
+ n.l('const1f')
104
+ n.eval_func_str('getOrElse')
105
+ end
106
+
107
+ set.append_init_func_str('const1')
108
+ set.append_output_node_str('nodeA')
109
+ set.append_output_node_str('nodeB')
110
+
111
+ set.to_mono
112
+ end
113
+
114
+ let(:tn) do
115
+ {
116
+ 'Int' => 'Tdbac6zj10nxdw8xn2685',
117
+ '1' => 'Vak3k1f5x3ru64v23ddxo',
118
+ 'Float' => 'Tdol7n8wg95lij6rzba37',
119
+ '1.0' => 'Vgd6wjf0djtw07gffly24',
120
+ 'Maybe[Int]' => 'T1vln6in9rw26e0oi25tr',
121
+ 'Just[Int]' => 'V267hxr1z5484l2obo663',
122
+ 'Nothing[Int]' => 'V3xq78u7xhmdqdujsb6jg',
123
+ 'Maybe[Float]' => 'T42ehv13rimthj4vjuw82',
124
+ 'Just[Float]' => 'Vrop52fzho740v9tsltiw',
125
+ 'Nothing[Float]' => 'V25o2b9281sk5e1a01hwk'
126
+ }
127
+ end
128
+
129
+ let(:nn) do
130
+ {
131
+ 'const1' => 'Napz6tziasvc3wsva7uov',
132
+ 'const1f' => 'Nay5c9siqvwjrt17nbhi7',
133
+ 'intEventInput' => 'N75e1fe4ly80ewfy5he9o',
134
+ 'floatEventInput' => 'N4hir3j06phk4qgum8mzq',
135
+ 'nodeA' => 'N41pxec9xx86xsu72arao',
136
+ 'nodeB' => 'N7z0xlt28om41dd3woeo2',
137
+ }
138
+ end
139
+
140
+ let(:fn) do
141
+ {
142
+ 'const1' => 'F7op98r2iqkw8315rmrqy',
143
+ 'const1p' => 'Fbklzqgjeljjjfzp2dz1p',
144
+ 'const1f' => 'Fas5dh5k278eyt0v8zxta',
145
+ 'intEventInput' => 'Fcdjtu42izdz9j034zrq5',
146
+ 'floatEventInput' => 'Fb5zku91p46q56qxlthw8',
147
+ 'getOrElse[Int]' => 'F5tfjznkktzudbvf3y27c',
148
+ 'getOrElse[Float]' => 'F3syi296xo0a73js0soxt',
149
+ 'id[Int]' => 'Fe3mll7ofsdrbjhj24qsy',
150
+ }
151
+ end
152
+
153
+ it 'has types' do
154
+ expect(mset.types).to contain_exactly(
155
+ M.type(tn['Int'], nil, true, 'int'),
156
+ M.type(tn['Float'], nil, true, 'float'),
157
+ M.type(tn['Maybe[Int]'], [tn['Just[Int]'], tn['Nothing[Int]']]),
158
+ M.type(tn['Maybe[Float]'], [tn['Just[Float]'], tn['Nothing[Float]']])
159
+ )
160
+ end
161
+
162
+ it 'has vconsts' do
163
+ expect(mset.vconsts).to contain_exactly(
164
+ M.vconst(tn['Maybe[Int]'], tn['Just[Int]'], [tn['Int']]),
165
+ M.vconst(tn['Maybe[Int]'], tn['Nothing[Int]'], []),
166
+ M.vconst(tn['Maybe[Float]'], tn['Just[Float]'], [tn['Float']]),
167
+ M.vconst(tn['Maybe[Float]'], tn['Nothing[Float]'], []),
168
+ M.vconst(tn['Int'], tn['1'], [], '1'),
169
+ M.vconst(tn['Float'], tn['1.0'], [], '1.0f'),
170
+ )
171
+ end
172
+
173
+ it 'has nodes' do
174
+ expect(mset.nodes).to contain_exactly(
175
+ M.node(tn['Int'], nn['const1'], fn['const1']),
176
+ M.node(tn['Float'], nn['const1f'], fn['const1f'], fn['const1f']),
177
+ M.node(tn['Maybe[Int]'], nn['intEventInput'], fn['intEventInput']),
178
+ M.node(tn['Maybe[Float]'], nn['floatEventInput'], fn['floatEventInput']),
179
+ M.node(tn['Int'], nn['nodeA'], fn['getOrElse[Int]'], fn['const1p']) do |n|
180
+ n.c nn['intEventInput']
181
+ n.c nn['const1']
182
+ end,
183
+ M.node(tn['Float'], nn['nodeB'], fn['getOrElse[Float]']) do |n|
184
+ n.c nn['floatEventInput']
185
+ n.l nn['const1f']
186
+ end,
187
+ )
188
+ end
189
+
190
+ it 'has funcs' do
191
+ funcs = [
192
+ M.func(tn['Int'], fn['const1']) do |f|
193
+ f.exp do
194
+ M.call_e(tn['Int'], fn['id[Int]'], M.vc_call_e(tn['Int'], tn['1']))
195
+ end
196
+ end,
197
+ M.func(tn['Int'], fn['const1p']) do |f|
198
+ f.exp { M.vc_call_e(tn['Int'], tn['1']) }
199
+ end,
200
+ M.func(tn['Float'], fn['const1f']) do |f|
201
+ f.exp { M.vc_call_e(tn['Float'], tn['1.0']) }
202
+ end,
203
+ M.func(tn['Maybe[Int]'], fn['intEventInput']) do |f|
204
+ f.ffi_str('int_input')
205
+ end,
206
+ M.func(tn['Maybe[Float]'], fn['floatEventInput']) do |f|
207
+ f.ffi_str('float_input')
208
+ end,
209
+ M.func(tn['Int'], fn['getOrElse[Int]']) do |f|
210
+ f.param(tn['Maybe[Int]'], 'm')
211
+ f.param(tn['Int'], 'x')
212
+ f.exp do
213
+ M.match_e(tn['Int'], M.v_e(tn['Maybe[Int]'], 'm')) do |m|
214
+ m.case M.pat(tn['Maybe[Int]'], tn['Just[Int]'], M.pany(tn['Int'], 'y')) do
215
+ M.v_e(tn['Int'], 'y')
216
+ end
217
+ m.case M.pref(tn['Maybe[Int]'], tn['Nothing[Int]'], 'z') do
218
+ M.v_e(tn['Int'], 'x')
219
+ end
220
+ end
221
+ end
222
+ end,
223
+ M.func(tn['Float'], fn['getOrElse[Float]']) do |f|
224
+ f.param(tn['Maybe[Float]'], 'm')
225
+ f.param(tn['Float'], 'x')
226
+ f.exp do
227
+ M.match_e(tn['Float'], M.v_e(tn['Maybe[Float]'], 'm')) do |m|
228
+ m.case M.pat(tn['Maybe[Float]'], tn['Just[Float]'], M.pany(tn['Float'], 'y')) do
229
+ M.v_e(tn['Float'], 'y')
230
+ end
231
+ m.case M.pref(tn['Maybe[Float]'], tn['Nothing[Float]'], 'z') do
232
+ M.v_e(tn['Float'], 'x')
233
+ end
234
+ end
235
+ end
236
+ end,
237
+ M.func(tn['Int'], fn['id[Int]']) do |f|
238
+ f.param(tn['Int'], 'x')
239
+ f.exp { M.v_e(tn['Int'], 'x') }
240
+ end,
241
+ ]
242
+ expect(mset.funcs).to contain_exactly(*funcs)
243
+ end
244
+ end
245
+
246
+ describe 'Poly-Set including undeterminable type var' do
247
+ let(:pset) do
248
+ set = Poly::Set.new
249
+
250
+ define_maybe(set)
251
+
252
+ set << P.node('node') do |n|
253
+ set << n.eval_func('nothing') do |f|
254
+ f.exp { P.vc_call_e('Nothing') }
255
+ end
256
+ end
257
+
258
+ set
259
+ end
260
+
261
+ it 'raises UndeterminableTypeError' do
262
+ err_msg = 'undeterminable type Maybe[a0]'
263
+ expect { pset.to_mono }.to raise_error(
264
+ Poly::UndeterminableTypeError, err_msg
265
+ )
266
+ end
267
+ end
268
+
269
+ describe 'Poly-Set including ununifyable type var' do
270
+ let(:pset) do
271
+ set = Poly::Set.new
272
+
273
+ define_prims(set)
274
+
275
+ set << P.node('node', P.t('Float')) do |n|
276
+ set << n.eval_func('one') do |f|
277
+ f.exp { P.vc_call_e('1') }
278
+ end
279
+ end
280
+
281
+ set
282
+ end
283
+
284
+ it 'raises UnifyError' do
285
+ err_msg = 'cannot unify Int and Float'
286
+ expect { pset.to_mono }.to raise_error(Poly::UnifyError, err_msg)
287
+ end
288
+ end
289
+ end
290
+ end