emfrp 0.1.2 → 0.1.3

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