sfrp 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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