emfrp 0.1.2 → 0.1.3

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +45 -12
  3. data/bin/emfrp +4 -1
  4. data/examples/LCDClock/LCDClock.mfrp +93 -93
  5. data/examples/LCDClock/LCDClock_LPC1768.bin +0 -0
  6. data/examples/LCDClock/README.md +24 -24
  7. data/examples/LCDPositioner/LCDPositioner.mfrp +30 -30
  8. data/examples/LCDPositioner/LCDPositionerMain.c +15 -15
  9. data/examples/MostDistantPoint/MostDistantPoint.mfrp +25 -25
  10. data/examples/MostDistantPoint/MostDistantPointMain.c +14 -14
  11. data/lib/emfrp/compile/c/alloc.rb +200 -200
  12. data/lib/emfrp/compile/c/codegen.rb +18 -18
  13. data/lib/emfrp/compile/c/codegen_context.rb +218 -218
  14. data/lib/emfrp/compile/c/monofy.rb +185 -185
  15. data/lib/emfrp/compile/c/syntax_codegen.rb +364 -364
  16. data/lib/emfrp/compile/c/syntax_exp_codegen.rb +119 -119
  17. data/lib/emfrp/compile/graphviz/graphviz.rb +53 -53
  18. data/lib/emfrp/compile_error.rb +95 -95
  19. data/lib/emfrp/interpreter/command_manager.rb +367 -367
  20. data/lib/emfrp/interpreter/evaluater.rb +146 -146
  21. data/lib/emfrp/interpreter/file_loader.rb +52 -52
  22. data/lib/emfrp/interpreter/interpreter.rb +200 -195
  23. data/lib/emfrp/parser/expression.rb +386 -386
  24. data/lib/emfrp/parser/misc.rb +184 -184
  25. data/lib/emfrp/parser/newnode_convert.rb +72 -72
  26. data/lib/emfrp/parser/operator.rb +25 -25
  27. data/lib/emfrp/parser/parser.rb +150 -150
  28. data/lib/emfrp/parser/parsing_error.rb +49 -49
  29. data/lib/emfrp/parser/toplevel.rb +555 -555
  30. data/lib/emfrp/pre_convert/pre_convert.rb +32 -32
  31. data/lib/emfrp/syntax.rb +171 -171
  32. data/lib/emfrp/typing/typing_error.rb +47 -47
  33. data/lib/emfrp/typing/union_type.rb +197 -197
  34. data/lib/emfrp/version.rb +1 -1
  35. data/mfrp_include/Std.mfrp +122 -122
  36. data/tests/Rakefile +8 -8
  37. data/tests/Rakefile.common +27 -27
  38. data/tests/command/Rakefile +2 -2
  39. data/tests/command/ReplaceNode.mfrp +39 -39
  40. data/tests/compiler/ComplexDataType/ComplexDataType.mfrp +14 -14
  41. data/tests/compiler/ComplexDataType/ComplexDataTypeMain.c +15 -15
  42. data/tests/compiler/ComplexDataType/Rakefile +2 -2
  43. data/tests/compiler/ComplexDataType/expected_out.txt +0 -0
  44. data/tests/compiler/ComplexDataType/in.txt +5 -5
  45. data/tests/compiler/LCDClock/LCDClock.mfrp +90 -90
  46. data/tests/compiler/LCDClock/LCDClockMain.c +0 -0
  47. data/tests/compiler/LCDClock/Rakefile +2 -2
  48. data/tests/compiler/LCDClock/expected_out.txt +0 -0
  49. data/tests/compiler/LCDClock/in.txt +0 -0
  50. data/tests/compiler/LCDPositioner/LCDPositioner.mfrp +30 -30
  51. data/tests/compiler/LCDPositioner/LCDPositionerMain.c +15 -15
  52. data/tests/compiler/LCDPositioner/Rakefile +2 -2
  53. data/tests/compiler/LCDPositioner/graph.dot +0 -0
  54. data/tests/compiler/LCDPositioner/graph.png +0 -0
  55. data/tests/compiler/Rakefile +8 -8
  56. data/tests/compiler/Rakefile.common +23 -23
  57. data/tests/compiler/UseData/Rakefile +2 -2
  58. data/tests/compiler/UseData/UseData.mfrp +8 -8
  59. data/tests/compiler/UseSubModule/Rakefile +2 -2
  60. data/tests/compiler/UseSubModule/SubModule.mfrp +8 -8
  61. data/tests/compiler/UseSubModule/SubModule2.mfrp +5 -5
  62. data/tests/compiler/UseSubModule/UseSubModule.mfrp +11 -11
  63. data/tests/core/FromAnnotation.mfrp +18 -18
  64. data/tests/core/Last.mfrp +10 -10
  65. data/tests/core/Rakefile +2 -2
  66. data/tests/core/TypingTest.mfrp +11 -11
  67. data/tests/core/WithoutInputs.mfrp +19 -19
  68. data/tests/load_time_error/Rakefile +32 -32
  69. data/tests/load_time_error/TypeMismatch.mfrp +4 -4
  70. metadata +3 -3
@@ -1,146 +1,146 @@
1
- module Emfrp
2
- class Interpreter
3
- module Evaluater
4
- extend self
5
-
6
- def eval_exp(top, exp, env={})
7
- case exp
8
- when FuncCall
9
- case f = top[:dict][:func_space][exp[:name][:desc]].get
10
- when PrimFuncDef
11
- if ruby_exp = f[:foreigns].find{|x| x[:language][:desc] == "ruby"}
12
- proc_str = "proc{|#{f[:params].map{|x| x[:name][:desc]}.join(",")}| #{ruby_exp[:desc]}}"
13
- return eval(proc_str).call(*exp[:args].map{|e| eval_exp(top, e, env)})
14
- else
15
- raise "Primitive Function `#{f[:name][:desc]}` is not defined for ruby"
16
- end
17
- when FuncDef
18
- f[:params].map{|param| [param[:name], Link.new(f)]}.zip(exp[:args]).each do |key, arg|
19
- env[key] = eval_exp(top, arg, env)
20
- end
21
- return eval_exp(top, f[:exp], env)
22
- end
23
- when ValueConst
24
- return [exp[:name][:desc].to_sym] + exp[:args].map{|e| eval_exp(top, e, env)}
25
- when LiteralIntegral
26
- return exp[:entity][:desc].to_i
27
- when LiteralChar
28
- return exp[:entity].ord
29
- when LiteralFloating
30
- return exp[:entity][:desc].to_f
31
- when VarRef
32
- key = [exp[:name], exp[:binder]]
33
- unless env[key]
34
- if exp[:binder].get.is_a?(DataDef)
35
- env[key] = eval_exp(top, exp[:binder].get[:exp], env)
36
- else
37
- raise "Assertion error: #{key} is unbound"
38
- end
39
- end
40
- return env[key]
41
- when ParenthExp
42
- return eval_exp(top, exp[:exp], env)
43
- when MatchExp
44
- left_val = eval_exp(top, exp[:exp], env)
45
- exp[:cases].each do |c|
46
- if match_result = pattern_match(c, left_val)
47
- return eval_exp(top, c[:exp], env.merge(match_result))
48
- end
49
- end
50
- raise "pattern match fail"
51
- when SkipExp
52
- throw :skip, :skip
53
- else
54
- raise "Unexpected expression type #{exp.class} (bug)"
55
- end
56
- end
57
-
58
- def eval_node_as_func(top, node_def, exps)
59
- env = {}
60
- if node_def[:params].size != exps.size
61
- raise "Assertion error: invalid length of args"
62
- end
63
- node_def[:params].map{|param| [param[:as], Link.new(node_def)]}.zip(exps).each do |key, arg|
64
- env[key] = eval_exp(top, arg, env)
65
- end
66
- return catch(:skip) do
67
- return eval_exp(top, node_def[:exp], env)
68
- end
69
- end
70
-
71
- def eval_module(top, input_exps, current_state, last_state, replacement)
72
- top[:inputs].zip(input_exps).each do |i, e|
73
- current_state[i] = eval_exp(top, e)
74
- end
75
- unless last_state
76
- last_state = {}
77
- (top[:inputs] + top[:nodes]).each do |d|
78
- last_state[d] = eval_exp(top, d[:init_exp]) if d[:init_exp]
79
- end
80
- end
81
- (top[:inputs] + top[:nodes]).each do |d|
82
- eval_node(top, d, current_state, last_state, replacement)
83
- end
84
- return top[:outputs].map do |x|
85
- eval_node(top, top[:dict][:node_space][x[:name][:desc]].get, current_state, last_state, replacement)
86
- end
87
- end
88
-
89
- def eval_node(top, node_def, current_state, last_state, replacement)
90
- if replacement[node_def[:name][:desc]]
91
- rep_node = replacement[node_def[:name][:desc]]
92
- return eval_node(top, rep_node, current_state, last_state, replacement)
93
- end
94
- return current_state[node_def] if current_state[node_def]
95
- env = {}
96
- node_def[:params].each do |param|
97
- key = [param[:as], Link.new(node_def)]
98
- pn = top[:dict][:node_space][param[:name][:desc]].get
99
- if param[:last]
100
- raise "Assertion error" unless last_state[pn]
101
- if rep_node = replacement[param[:name][:desc]]
102
- env[key] = last_state[rep_node]
103
- else
104
- env[key] = last_state[pn]
105
- end
106
- else
107
- env[key] = eval_node(top, pn, current_state, last_state, replacement)
108
- end
109
- end
110
- res = catch(:skip){ eval_exp(top, node_def[:exp], env) }
111
- return current_state[node_def] = res == :skip ? last_state[node_def] : res
112
- end
113
-
114
- def pattern_match(c, v, pattern=c[:pattern], vars={})
115
- if pattern[:ref]
116
- key = [pattern[:ref], Link.new(c)]
117
- vars[key] = v
118
- end
119
- case pattern
120
- when ValuePattern
121
- if v.is_a?(Array) && pattern[:name][:desc].to_sym == v[0]
122
- res = v.drop(1).zip(pattern[:args]).all? do |ch_v, ch_p|
123
- pattern_match(c, ch_v, ch_p, vars)
124
- end
125
- return vars if res
126
- end
127
- when IntegralPattern
128
- if v.is_a?(Integer) && pattern[:val][:entity][:desc].to_i == v
129
- return vars
130
- end
131
- when AnyPattern
132
- return vars
133
- end
134
- return nil
135
- end
136
-
137
- def value_to_s(val)
138
- if val.is_a?(Array) && val.first.is_a?(Symbol)
139
- "#{val.first}" + (val.size > 1 ? "(#{val.drop(1).map{|x| value_to_s(x)}.join(", ")})" : "")
140
- else
141
- val.to_s
142
- end
143
- end
144
- end
145
- end
146
- end
1
+ module Emfrp
2
+ class Interpreter
3
+ module Evaluater
4
+ extend self
5
+
6
+ def eval_exp(top, exp, env={})
7
+ case exp
8
+ when FuncCall
9
+ case f = top[:dict][:func_space][exp[:name][:desc]].get
10
+ when PrimFuncDef
11
+ if ruby_exp = f[:foreigns].find{|x| x[:language][:desc] == "ruby"}
12
+ proc_str = "proc{|#{f[:params].map{|x| x[:name][:desc]}.join(",")}| #{ruby_exp[:desc]}}"
13
+ return eval(proc_str).call(*exp[:args].map{|e| eval_exp(top, e, env)})
14
+ else
15
+ raise "Primitive Function `#{f[:name][:desc]}` is not defined for ruby"
16
+ end
17
+ when FuncDef
18
+ f[:params].map{|param| [param[:name], Link.new(f)]}.zip(exp[:args]).each do |key, arg|
19
+ env[key] = eval_exp(top, arg, env)
20
+ end
21
+ return eval_exp(top, f[:exp], env)
22
+ end
23
+ when ValueConst
24
+ return [exp[:name][:desc].to_sym] + exp[:args].map{|e| eval_exp(top, e, env)}
25
+ when LiteralIntegral
26
+ return exp[:entity][:desc].to_i
27
+ when LiteralChar
28
+ return exp[:entity].ord
29
+ when LiteralFloating
30
+ return exp[:entity][:desc].to_f
31
+ when VarRef
32
+ key = [exp[:name], exp[:binder]]
33
+ unless env[key]
34
+ if exp[:binder].get.is_a?(DataDef)
35
+ env[key] = eval_exp(top, exp[:binder].get[:exp], env)
36
+ else
37
+ raise "Assertion error: #{key} is unbound"
38
+ end
39
+ end
40
+ return env[key]
41
+ when ParenthExp
42
+ return eval_exp(top, exp[:exp], env)
43
+ when MatchExp
44
+ left_val = eval_exp(top, exp[:exp], env)
45
+ exp[:cases].each do |c|
46
+ if match_result = pattern_match(c, left_val)
47
+ return eval_exp(top, c[:exp], env.merge(match_result))
48
+ end
49
+ end
50
+ raise "pattern match fail"
51
+ when SkipExp
52
+ throw :skip, :skip
53
+ else
54
+ raise "Unexpected expression type #{exp.class} (bug)"
55
+ end
56
+ end
57
+
58
+ def eval_node_as_func(top, node_def, exps)
59
+ env = {}
60
+ if node_def[:params].size != exps.size
61
+ raise "Assertion error: invalid length of args"
62
+ end
63
+ node_def[:params].map{|param| [param[:as], Link.new(node_def)]}.zip(exps).each do |key, arg|
64
+ env[key] = eval_exp(top, arg, env)
65
+ end
66
+ return catch(:skip) do
67
+ return eval_exp(top, node_def[:exp], env)
68
+ end
69
+ end
70
+
71
+ def eval_module(top, input_exps, current_state, last_state, replacement)
72
+ top[:inputs].zip(input_exps).each do |i, e|
73
+ current_state[i] = eval_exp(top, e)
74
+ end
75
+ unless last_state
76
+ last_state = {}
77
+ (top[:inputs] + top[:nodes]).each do |d|
78
+ last_state[d] = eval_exp(top, d[:init_exp]) if d[:init_exp]
79
+ end
80
+ end
81
+ (top[:inputs] + top[:nodes]).each do |d|
82
+ eval_node(top, d, current_state, last_state, replacement)
83
+ end
84
+ return top[:outputs].map do |x|
85
+ eval_node(top, top[:dict][:node_space][x[:name][:desc]].get, current_state, last_state, replacement)
86
+ end
87
+ end
88
+
89
+ def eval_node(top, node_def, current_state, last_state, replacement)
90
+ if replacement[node_def[:name][:desc]]
91
+ rep_node = replacement[node_def[:name][:desc]]
92
+ return eval_node(top, rep_node, current_state, last_state, replacement)
93
+ end
94
+ return current_state[node_def] if current_state[node_def]
95
+ env = {}
96
+ node_def[:params].each do |param|
97
+ key = [param[:as], Link.new(node_def)]
98
+ pn = top[:dict][:node_space][param[:name][:desc]].get
99
+ if param[:last]
100
+ raise "Assertion error" unless last_state[pn]
101
+ if rep_node = replacement[param[:name][:desc]]
102
+ env[key] = last_state[rep_node]
103
+ else
104
+ env[key] = last_state[pn]
105
+ end
106
+ else
107
+ env[key] = eval_node(top, pn, current_state, last_state, replacement)
108
+ end
109
+ end
110
+ res = catch(:skip){ eval_exp(top, node_def[:exp], env) }
111
+ return current_state[node_def] = res == :skip ? last_state[node_def] : res
112
+ end
113
+
114
+ def pattern_match(c, v, pattern=c[:pattern], vars={})
115
+ if pattern[:ref]
116
+ key = [pattern[:ref], Link.new(c)]
117
+ vars[key] = v
118
+ end
119
+ case pattern
120
+ when ValuePattern
121
+ if v.is_a?(Array) && pattern[:name][:desc].to_sym == v[0]
122
+ res = v.drop(1).zip(pattern[:args]).all? do |ch_v, ch_p|
123
+ pattern_match(c, ch_v, ch_p, vars)
124
+ end
125
+ return vars if res
126
+ end
127
+ when IntegralPattern
128
+ if v.is_a?(Integer) && pattern[:val][:entity][:desc].to_i == v
129
+ return vars
130
+ end
131
+ when AnyPattern
132
+ return vars
133
+ end
134
+ return nil
135
+ end
136
+
137
+ def value_to_s(val)
138
+ if val.is_a?(Array) && val.first.is_a?(Symbol)
139
+ "#{val.first}" + (val.size > 1 ? "(#{val.drop(1).map{|x| value_to_s(x)}.join(", ")})" : "")
140
+ else
141
+ val.to_s
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -1,52 +1,52 @@
1
- module Emfrp
2
- class FileLoader
3
- FileLoadError = Class.new(StandardError)
4
-
5
- def initialize(include_dirs)
6
- @include_dirs = include_dirs
7
- @loaded_hash = {}
8
- end
9
-
10
- def loaded?(path)
11
- @loaded_hash.has_key?(path)
12
- end
13
-
14
- def loaded_full_path(path)
15
- raise "assertion error" unless loaded?(path)
16
- @loaded_hash[path][1]
17
- end
18
-
19
- def get_src_from_full_path(required_full_path)
20
- @loaded_hash.each do |path, x|
21
- src_str, full_path = *x
22
- if full_path == required_full_path
23
- return src_str
24
- end
25
- end
26
- raise "#{required_full_path} is not found"
27
- end
28
-
29
- def add_to_loaded(path, src)
30
- @loaded_hash[path] = [src, path]
31
- end
32
-
33
- def load(path)
34
- path_str = path.is_a?(Array) ? path.join("/") : path
35
- if path =~ /^\/.*?/ && File.exist?(path)
36
- src_str = File.open(path, 'r'){|f| f.read}
37
- return @loaded_hash[path] = [src_str, path]
38
- end
39
- @include_dirs.each do |d|
40
- full_path = File.expand_path(d + path_str)
41
- if File.exist?(full_path) && File.ftype(full_path) == "file"
42
- src_str = File.open(full_path, 'r'){|f| f.read}
43
- return @loaded_hash[path] = [src_str, full_path]
44
- elsif File.exist?(full_path + ".mfrp") && File.ftype(full_path + ".mfrp") == "file"
45
- src_str = File.open(full_path + ".mfrp", 'r'){|f| f.read}
46
- return @loaded_hash[path] = [src_str, full_path + ".mfrp"]
47
- end
48
- end
49
- raise FileLoadError.new("Cannot load #{path_str}")
50
- end
51
- end
52
- end
1
+ module Emfrp
2
+ class FileLoader
3
+ FileLoadError = Class.new(StandardError)
4
+
5
+ def initialize(include_dirs)
6
+ @include_dirs = include_dirs
7
+ @loaded_hash = {}
8
+ end
9
+
10
+ def loaded?(path)
11
+ @loaded_hash.has_key?(path)
12
+ end
13
+
14
+ def loaded_full_path(path)
15
+ raise "assertion error" unless loaded?(path)
16
+ @loaded_hash[path][1]
17
+ end
18
+
19
+ def get_src_from_full_path(required_full_path)
20
+ @loaded_hash.each do |path, x|
21
+ src_str, full_path = *x
22
+ if full_path == required_full_path
23
+ return src_str
24
+ end
25
+ end
26
+ raise "#{required_full_path} is not found"
27
+ end
28
+
29
+ def add_to_loaded(path, src)
30
+ @loaded_hash[path] = [src, path]
31
+ end
32
+
33
+ def load(path)
34
+ path_str = path.is_a?(Array) ? path.join("/") : path
35
+ if path =~ /^\/.*?/ && File.exist?(path)
36
+ src_str = File.open(path, 'r'){|f| f.read}
37
+ return @loaded_hash[path] = [src_str, path]
38
+ end
39
+ @include_dirs.each do |d|
40
+ full_path = File.expand_path(d + path_str)
41
+ if File.exist?(full_path) && File.ftype(full_path) == "file"
42
+ src_str = File.open(full_path, 'r'){|f| f.read}
43
+ return @loaded_hash[path] = [src_str, full_path]
44
+ elsif File.exist?(full_path + ".mfrp") && File.ftype(full_path + ".mfrp") == "file"
45
+ src_str = File.open(full_path + ".mfrp", 'r'){|f| f.read}
46
+ return @loaded_hash[path] = [src_str, full_path + ".mfrp"]
47
+ end
48
+ end
49
+ raise FileLoadError.new("Cannot load #{path_str}")
50
+ end
51
+ end
52
+ end