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,41 @@
1
+ module SFRP
2
+ module Raw
3
+ extend SFRP::R = self
4
+
5
+ def r(rname, qualifier = nil)
6
+ Ref.new(rname, qualifier)
7
+ end
8
+
9
+ def t(tconst_ref, args, sp = nil)
10
+ TypeAnnotationType.new(tconst_ref, args, sp)
11
+ end
12
+
13
+ def tv(var_str, sp = nil)
14
+ TypeAnnotationVar.new(var_str, sp)
15
+ end
16
+
17
+ def ft(ret_t, arg_ts)
18
+ FuncTypeAnnotation.new(ret_t, arg_ts)
19
+ end
20
+
21
+ def v_e(var_str, sp = nil)
22
+ VarRefExp.new(var_str, sp)
23
+ end
24
+
25
+ def nr_e(node_ref, last, sp = nil)
26
+ NodeRefExp.new(node_ref, last, sp)
27
+ end
28
+
29
+ def call_e(func_ref, args, sp = nil)
30
+ FuncCallExp.new(func_ref, args, sp)
31
+ end
32
+
33
+ def vc_call_e(vconst_ref, args, sp = nil)
34
+ VConstCallExp.new(vconst_ref, args, sp)
35
+ end
36
+
37
+ def seq_e(exps, func_refs, sp = nil)
38
+ SequenceExp.new(exps, func_refs, sp)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,164 @@
1
+ module SFRP
2
+ module Raw
3
+ class Function < Struct.new(:rname, :ns, :ret_ta, :pstrs, :ptas, :exp, :ffi_str, :effect, :sp)
4
+ def absolute_name
5
+ ns.absolute_name(rname)
6
+ end
7
+
8
+ def vconst_refs
9
+ exp ? exp.vconst_refs : []
10
+ end
11
+
12
+ def gen_flat(src_set, dest_set)
13
+ exp.blame_side_effect if exp && !effect
14
+ flat_exp = exp && exp.to_flat(src_set, ns)
15
+ flat_ret_ta = ret_ta && ret_ta.to_flat(src_set, ns)
16
+ flat_ptas = ptas.map { |ta| ta && ta.to_flat(src_set, ns) }
17
+ dest_set << Flat::Function.new(
18
+ absolute_name, flat_ret_ta, pstrs, flat_ptas, flat_exp, ffi_str, sp
19
+ )
20
+ end
21
+ end
22
+
23
+ class TConst < Struct.new(:rname, :ns, :pstrs, :vconsts, :native_str, :static, :sp)
24
+ def absolute_name
25
+ ns.absolute_name(rname)
26
+ end
27
+
28
+ def gen_flat(_src_set, dest_set)
29
+ vconst_strs = vconsts.map(&:absolute_name)
30
+ dest_set << Flat::TConst.new(absolute_name, pstrs, vconst_strs, native_str, static, sp)
31
+ end
32
+ end
33
+
34
+ class VConst < Struct.new(:rname, :tconst_rname, :ns, :native_str, :param_tas, :sp)
35
+ def absolute_name
36
+ ns.absolute_name(rname)
37
+ end
38
+
39
+ def gen_flat(src_set, dest_set)
40
+ tconst_str = src_set.tconst(ns, Ref.new(tconst_rname), sp).absolute_name
41
+ flat_param_tas = param_tas.map { |ta| ta.to_flat(src_set, ns) }
42
+ dest_set << Flat::VConst.new(absolute_name, tconst_str, native_str, flat_param_tas, sp)
43
+ end
44
+ end
45
+
46
+ class PrimTConst < Struct.new(:rname, :ns, :native_str, :pat, :rep, :sp)
47
+ def absolute_name
48
+ ns.absolute_name(rname)
49
+ end
50
+
51
+ def vconst_match?(vconst_str)
52
+ pat.match(vconst_str)
53
+ end
54
+
55
+ def make_vconst(vconst_str)
56
+ raise vconst_str unless vconst_match?(vconst_str)
57
+ VConst.new(vconst_str, rname, ns, vconst_str.gsub(pat, rep), [], sp)
58
+ end
59
+
60
+ def gen_flat(_src_set, dest_set)
61
+ dest_set << Flat::TConst.new(absolute_name, [], nil, native_str, true, sp)
62
+ end
63
+ end
64
+
65
+ class Init < Struct.new(:ns, :func_ref, :arg_exps, :line_number)
66
+ def func_rname
67
+ "%init#{line_number}"
68
+ end
69
+
70
+ def function
71
+ exp = FuncCallExp.new(func_ref, arg_exps, true)
72
+ Function.new(func_rname, ns, nil, [], [], exp, nil, true)
73
+ end
74
+
75
+ def gen_flat(src_set, dest_set)
76
+ function.gen_flat(src_set, dest_set)
77
+ dest_set.append_init_func_str(function.absolute_name)
78
+ end
79
+ end
80
+
81
+ class Node < Struct.new(:rname, :ns, :ta, :exp, :init_exp, :sp)
82
+ def absolute_name
83
+ ns.absolute_name(rname)
84
+ end
85
+
86
+ def vconst_refs
87
+ [exp, init_exp].reject(&:nil?).flat_map(&:vconst_refs)
88
+ end
89
+
90
+ def gen_flat(src_set, dest_set)
91
+ exp.blame_side_effect
92
+ flat_ta = ta && ta.to_flat(src_set, ns)
93
+ flat_init_exp = init_exp && init_exp.to_flat(src_set, ns)
94
+ flat_exp = exp && exp.to_flat(src_set, ns)
95
+ dest_set << Flat::Node.new(absolute_name, flat_ta, flat_exp, flat_init_exp, sp)
96
+ end
97
+ end
98
+
99
+ class Output < Struct.new(:ns, :exps, :func_ref, :line_number, :sp)
100
+ def rname
101
+ "%output_line#{line_number}"
102
+ end
103
+
104
+ def absolute_name
105
+ ns.absolute_name(rname)
106
+ end
107
+
108
+ def convert
109
+ exp = FuncCallExp.new(func_ref, exps, false, sp)
110
+ ta = TypeAnnotationType.new(Ref.new('Unit'), [])
111
+ Node.new(rname, ns, ta, exp, nil, sp)
112
+ end
113
+ end
114
+
115
+ class Input < Struct.new(:rname, :ns, :ta, :arg_exps, :init_exp, :func_ref, :sp)
116
+ def convert
117
+ exp = FuncCallExp.new(func_ref, arg_exps, false, sp)
118
+ Node.new(rname, ns, ta, exp, init_exp, sp)
119
+ end
120
+ end
121
+
122
+ class Infix < Struct.new(:ns, :func_ref, :priority, :direction, :sp)
123
+ LEFT, RIGHT, NONE = :left, :right, :none
124
+
125
+ def absolute_func_name(set)
126
+ func_name = set.func(ns, func_ref, sp).absolute_name
127
+ raise NameError.new(func_ref.to_s, sp) unless func_name
128
+ func_name
129
+ end
130
+
131
+ def absolute_priority(position)
132
+ case direction
133
+ when LEFT
134
+ [priority, 1000 - position]
135
+ when RIGHT
136
+ [priority, position]
137
+ when NONE
138
+ [priority, 0]
139
+ end
140
+ end
141
+ end
142
+
143
+ class FuncTypeAnnotation < Struct.new(:ret_ta, :arg_tas, :sp)
144
+ def to_flat(set, ns)
145
+ flat_arg_tas = arg_tas.map { |ta| ta.to_flat(set, ns) }
146
+ Flat::FuncTypeAnnotation.new(ret_ta.to_flat(set, ns), flat_arg_tas, sp)
147
+ end
148
+ end
149
+
150
+ class TypeAnnotationType < Struct.new(:tconst_ref, :arg_tas, :sp)
151
+ def to_flat(set, ns)
152
+ ab_tc_name = set.tconst(ns, tconst_ref, sp).absolute_name
153
+ flat_arg_tas = arg_tas.map { |ta| ta.to_flat(set, ns) }
154
+ Flat::TypeAnnotationType.new(ab_tc_name, flat_arg_tas, sp)
155
+ end
156
+ end
157
+
158
+ class TypeAnnotationVar < Struct.new(:var_str, :sp)
159
+ def to_flat(_set, _ns)
160
+ Flat::TypeAnnotationVar.new(var_str, sp)
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,40 @@
1
+ require 'sfrp/error'
2
+
3
+ module SFRP
4
+ module Raw
5
+ class NameError < CompileError
6
+ def initialize(target_str, source_position)
7
+ @target_str = target_str
8
+ @source_position = source_position
9
+ end
10
+
11
+ def message
12
+ "Cannot resolve '#{@target_str}'"
13
+ end
14
+ end
15
+
16
+ class AmbiguousNameError < CompileError
17
+ def initialize(target_str, selection_strs, source_position)
18
+ @target_str = target_str
19
+ @selection_strs = selection_strs
20
+ @source_position = source_position
21
+ end
22
+
23
+ def message
24
+ "Ambiguous name '#{@target_str}':\n" +
25
+ @selection_strs.map { |s| ' ' + s }.join("\n")
26
+ end
27
+ end
28
+
29
+ class IllegalSideEffectError < CompileError
30
+ def initialize(target_str, source_position)
31
+ @target_str = target_str
32
+ @source_position = source_position
33
+ end
34
+
35
+ def message
36
+ "Don't call side-effect function '#{@target_str}'"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,168 @@
1
+ module SFRP
2
+ module Raw
3
+ class FuncCallExp < Struct.new(:func_ref, :arg_exps, :effect, :sp)
4
+ def vconst_refs
5
+ arg_exps.flat_map(&:vconst_refs)
6
+ end
7
+
8
+ def blame_side_effect
9
+ raise IllegalSideEffectError.new(func_ref.to_s, sp) if effect
10
+ arg_exps.each(&:blame_side_effect)
11
+ end
12
+
13
+ def to_flat(set, ns)
14
+ ab_func_name = set.func(ns, func_ref, sp).absolute_name
15
+ args = arg_exps.map { |e| e.to_flat(set, ns) }
16
+ Flat::FuncCallExp.new(ab_func_name, args, sp)
17
+ end
18
+ end
19
+
20
+ class VConstCallExp < Struct.new(:vconst_ref, :arg_exps, :sp)
21
+ def vconst_refs
22
+ [vconst_ref, *arg_exps.flat_map(&:vconst_refs)]
23
+ end
24
+
25
+ def blame_side_effect
26
+ arg_exps.each(&:blame_side_effect)
27
+ end
28
+
29
+ def to_flat(set, ns)
30
+ ab_vc_name = set.vconst(ns, vconst_ref, sp).absolute_name
31
+ args = arg_exps.map { |e| e.to_flat(set, ns) }
32
+ Flat::VConstCallExp.new(ab_vc_name, args, sp)
33
+ end
34
+ end
35
+
36
+ class NodeRefExp < Struct.new(:node_ref, :last, :sp)
37
+ def vconst_refs
38
+ []
39
+ end
40
+
41
+ def blame_side_effect
42
+ nil
43
+ end
44
+
45
+ def to_flat(set, ns)
46
+ ab_node_name = set.node(ns, node_ref, sp).absolute_name
47
+ Flat::NodeRefExp.new(ab_node_name, last)
48
+ end
49
+ end
50
+
51
+ class MatchExp < Struct.new(:left_exp, :cases, :sp)
52
+ Case = Struct.new(:pattern, :exp)
53
+
54
+ class Pattern < Struct.new(:vconst_ref, :ref_var_str, :args, :sp)
55
+ def vconst_refs
56
+ (vconst_ref ? [vconst_ref] : []) + args.flat_map(&:vconst_refs)
57
+ end
58
+
59
+ def to_flat(set, ns)
60
+ flat_args = args.map { |a| a.to_flat(set, ns) }
61
+ if vconst_ref
62
+ ab_vc_name = set.vconst(ns, vconst_ref, sp).absolute_name
63
+ Flat::MatchExp::Pattern.new(ab_vc_name, ref_var_str, flat_args, sp)
64
+ else
65
+ Flat::MatchExp::Pattern.new(nil, ref_var_str, flat_args, sp)
66
+ end
67
+ end
68
+ end
69
+
70
+ def vconst_refs
71
+ [left_exp, *cases.map(&:pattern), *cases.map(&:exp)].flat_map(&:vconst_refs)
72
+ end
73
+
74
+ def blame_side_effect
75
+ left_exp.blame_side_effect
76
+ cases.map(&:exp).each(&:blame_side_effect)
77
+ end
78
+
79
+ def to_flat(set, ns)
80
+ flat_cases = cases.map do |c|
81
+ flat_pattern = c.pattern.to_flat(set, ns)
82
+ Flat::MatchExp::Case.new(flat_pattern, c.exp.to_flat(set, ns))
83
+ end
84
+ Flat::MatchExp.new(left_exp.to_flat(set, ns), flat_cases, sp)
85
+ end
86
+ end
87
+
88
+ class VarRefExp < Struct.new(:var_str, :sp)
89
+ def vconst_refs
90
+ []
91
+ end
92
+
93
+ def blame_side_effect
94
+ nil
95
+ end
96
+
97
+ def to_flat(_set, _ns)
98
+ Flat::VarRefExp.new(var_str, sp)
99
+ end
100
+ end
101
+
102
+ class SequenceExp < Struct.new(:exps, :func_refs, :sp)
103
+ def vconst_refs
104
+ exps.flat_map(&:vconst_refs)
105
+ end
106
+
107
+ def blame_side_effect
108
+ exps.each { |e| e.blame_side_effect }
109
+ end
110
+
111
+ def convert(set, ns)
112
+ return exps[0] if exps.size == 1
113
+ pos = set.weakest_op_position(ns, func_refs, sp)
114
+ lseq = SequenceExp.new(exps.take(pos + 1), func_refs.take(pos), sp)
115
+ rseq = SequenceExp.new(exps.drop(pos + 1), func_refs.drop(pos + 1), sp)
116
+ args = [lseq.convert(set, ns), rseq.convert(set, ns)]
117
+ FuncCallExp.new(func_refs[pos], args, false, sp)
118
+ end
119
+
120
+ def to_flat(set, ns)
121
+ convert(set, ns).to_flat(set, ns)
122
+ end
123
+ end
124
+
125
+ module SugarExp
126
+ def vconst_refs
127
+ convert.vconst_refs
128
+ end
129
+
130
+ def blame_side_effect
131
+ convert.blame_side_effect
132
+ end
133
+
134
+ def to_flat(set, ns)
135
+ convert.to_flat(set, ns)
136
+ end
137
+ end
138
+
139
+ class IfExp < Struct.new(:cond_exp, :then_exp, :else_exp, :sp)
140
+ include SugarExp
141
+
142
+ def convert
143
+ cases = [
144
+ MatchExp::Case.new(
145
+ MatchExp::Pattern.new(Ref.new('True'), nil, [], sp), then_exp
146
+ ),
147
+ MatchExp::Case.new(
148
+ MatchExp::Pattern.new(Ref.new('False'), nil, [], sp), else_exp
149
+ )
150
+ ]
151
+ MatchExp.new(cond_exp, cases, sp)
152
+ end
153
+ end
154
+
155
+ class LetExp < Struct.new(:exp, :assignments, :sp)
156
+ include SugarExp
157
+
158
+ Assignment = Struct.new(:pattern, :exp)
159
+
160
+ def convert
161
+ raise if assignments.empty?
162
+ assignments.reverse.reduce(exp) do |e, ass|
163
+ MatchExp.new(ass.exp, [MatchExp::Case.new(ass.pattern, e)], sp)
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,30 @@
1
+ module SFRP
2
+ module Raw
3
+ class Ref < Struct.new(:relative_name, :qualifier_name, :sp)
4
+ def to_s
5
+ return relative_name if qualifier_name.nil?
6
+ qualifier_name + '.' + relative_name
7
+ end
8
+ end
9
+
10
+ class Import < Struct.new(:absolute_namespace_name, :qualifier_name)
11
+
12
+ end
13
+
14
+ class Namespace
15
+ def initialize(absolute_namespace_name, imports)
16
+ @absolute_namespace_name = absolute_namespace_name
17
+ @imports = [Import.new(absolute_namespace_name, nil), *imports]
18
+ end
19
+
20
+ def absolute_name(relative_name)
21
+ @absolute_namespace_name + '.' + relative_name
22
+ end
23
+
24
+ def search_for_absolute_names(ref)
25
+ @imports.select { |i| i.qualifier_name == ref.qualifier_name }
26
+ .map { |i| i.absolute_namespace_name + '.' + ref.relative_name }
27
+ end
28
+ end
29
+ end
30
+ end