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