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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c76aeb70edc85f68ce0412805037f3edd13f585
4
- data.tar.gz: b2ea35157930fd7911dfaf3a5ece84ac0dfbe6ad
3
+ metadata.gz: 47841f28c3f4f205e6ffd86414321a77b8f94600
4
+ data.tar.gz: e6652a888ebe7432b7c4b8b95523cf7c6f350a29
5
5
  SHA512:
6
- metadata.gz: d43fd34857af5a6a55293fc5b1ccdb699fb468cf1d9b3cbc5b7b39dba9c51a7e077939536c60c621e82b10cff3404780892461cd2f6ed2a08de39b613c0db23f
7
- data.tar.gz: b1f3486218100ed207900d54c26797ed5d2c17dcadfdf0cc63b4405b65d46b01e3d0f4482bd42faa241e772fcfdabe790414dd068288d6ffb012d4ce88b8503f
6
+ metadata.gz: f49280862f5de248a70dcd7b7aaf7ad2912273ece39531961815b4e4e2ac928d63a47a3cd7cde8eac4ab4726a400bb54c1685bd6beb5e96c2f0a55cf5a2f0ed6
7
+ data.tar.gz: 12c38a3ab709acbdc13e544f716f2c598e2869f3871bfee00ac0d9b6abf854c89c948e67bf8ea69846e2ee33710815743d3315a7bb0185a811f67563211bd625
data/README.md CHANGED
@@ -1,28 +1,61 @@
1
1
  # Emfrp
2
2
 
3
- Pure Functional Programming with your microcomputer.
3
+ Pure Functional Reactive Programming Language for Small-Scale Embedded Systems
4
4
 
5
- # Requirement
5
+ ## Installation
6
6
 
7
- * Ruby2.0 or later (and it's Gem client)
7
+ Requirement
8
+ * Ruby 2.0 or later (and it's Gem client)
9
+ * C (or C++) compiler for your favorite target platform
8
10
 
9
- ## Installation
10
- You can get executables via RubyGems.
11
- ```sh
11
+ ### via RubyGems
12
+
13
+ Just type the following command.
14
+ ```
12
15
  $ gem install emfrp
13
16
  ```
17
+ You are all set. Enjoy!
14
18
 
15
- # Command-line-interpreter (REPL)
19
+ ### from Source
20
+
21
+ Install `Bundler` if it is not installed.
16
22
  ```sh
17
- $ emfrpi
23
+ $ gem install bundler
18
24
  ```
19
25
 
20
- # Compiler
26
+ Clone this repository and install from the cloned source as follows.
21
27
  ```sh
22
- $ emfrp <src-file>
28
+ $ cd emfrp
29
+ $ rake install
23
30
  ```
24
31
 
32
+ ***NOTE***
33
+ Some environments require that you need to be an administrator to perform `gem install` or `rake install`.
34
+
25
35
  ## Usage
36
+ Command-line-interpreter (REPL)
37
+ ```sh
38
+ $ emfrpi
39
+ ```
40
+
41
+ Compiler
42
+ ```sh
43
+ $ emfrp [options] <src-file>
44
+ ```
45
+
46
+ Options
47
+ * `--nomain`
48
+ does not generate _main_ file
49
+ * `--cpp`
50
+ generates `.cpp` instead of `.c`
51
+
52
+ See the wiki of this repository for details.
53
+
54
+ ## Sample Code
55
+
56
+ * [emfrp_samples](https://github.com/psg-titech/emfrp_samples)
57
+
26
58
 
27
- See wiki:
28
- https://github.com/sawaken/emfrp/wiki
59
+ ## History
60
+ Originally developed by [Kensuke Sawada](https://github.com/sawaken)
61
+ * [Paper](http://www.psg.c.titech.ac.jp/posts/2016-03-15-CROW2016.html)
data/bin/emfrp CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
3
 
4
+ require 'optparse'
4
5
  require 'emfrp'
5
6
 
7
+ opts = ARGV.getopts("", "cpp", "nomain")
8
+
6
9
  unless ARGV[0]
7
10
  puts "usage: emfrp <emfrp-module-file-path>"
8
11
  exit(1)
@@ -10,7 +13,7 @@ end
10
13
 
11
14
  begin
12
15
  inter = Emfrp::Interpreter.new(Emfrp::IncludeDirs, STDOUT, ARGV[0])
13
- if inter.compile_default()
16
+ if inter.compile_default(opts["cpp"], !opts["nomain"])
14
17
  exit(1)
15
18
  end
16
19
  rescue Emfrp::Interpreter::InterpreterError
@@ -1,93 +1,93 @@
1
- module LCDClock
2
- in
3
- btnMode(False) : Bool, # Is mode-button pushed now?
4
- btnNext(False) : Bool, # Is next-button pushed now?
5
- btnRotate(False) : Bool, # Is rotate-button pushed now?
6
- pulse100ms : Bool # input to be True only once per 100ms
7
- out
8
- hour, min, sec, # current time to display
9
- maskHour, maskMin, maskSec # Is it now needed to display -- instead of two-digits?
10
- use
11
- Std
12
-
13
- # Functions
14
- # --------------------
15
-
16
- type Mode = Normal | Edit
17
- type EditPos = HourPos | MinPos | SecPos
18
- type Time = Time(Int, Int, Int)
19
-
20
- func nextMode(m) = m of Normal -> Edit, Edit -> Normal
21
-
22
- func editable(m) = m of Normal -> False, Edit -> True
23
-
24
- func nextPos(p) = p of:
25
- HourPos -> MinPos
26
- MinPos -> SecPos
27
- SecPos -> HourPos
28
-
29
- func positiveEdge(a, b) = !a && b
30
-
31
- # proceed Time by 1sec
32
- func proceedTime(t) = {
33
- Time(h, m, s) = t
34
- newS = s + 1
35
- newM = m + (newS / 60)
36
- newH = h + (newM / 60)
37
- Time(newH % 24, newM % 60, newS % 60)
38
- }
39
-
40
- func roundingTime(t, dh, dm, ds) = {
41
- Time(h, m, s) = t
42
- Time((h + dh) % 24, (m + dm) % 60, (s + ds) % 60)
43
- }
44
-
45
- # Nodes
46
- # --------------------
47
-
48
- # mod-10 counter incremented by every 100ms
49
- node init[0] counter : Int =
50
- (if pulse100ms then counter@last + 1 else counter@last) % 10
51
-
52
- # time-varying value to be True only once per 1sec
53
- node pulse1s : Bool =
54
- counter == 0 && counter@last != 0
55
-
56
- # time-varying value switching True/False by every 500ms
57
- node flash : Bool =
58
- counter < 5
59
-
60
- # time-varying value representing current time-set mode
61
- node init[Normal] curMode : Mode =
62
- if btnMode@last `positiveEdge` btnMode then curMode@last.nextMode else curMode@last
63
-
64
- # time-varying value representing current editing-cursor-position
65
- node init[HourPos] curPos : EditPos =
66
- if btnNext@last `positiveEdge` btnNext then curPos@last.nextPos else curPos@last
67
-
68
- # time-varying value representing diffs to add to current time.
69
- node (dh, dm, ds) : (Int, Int, Int) =
70
- if curMode.editable && (btnRotate@last `positiveEdge` btnRotate) then
71
- curPos of:
72
- HourPos -> (1, 0, 0)
73
- MinPos -> (0, 1, 0)
74
- SecPos -> (0, 0, 1)
75
- else
76
- (0, 0, 0)
77
-
78
- # time-varying value representing current time
79
- node init[Time(0, 0, 0)] Time(hour, min, sec) as curTime =
80
- if pulse1s then
81
- curTime@last.proceedTime.roundingTime(dh, dm, ds)
82
- else
83
- curTime@last.roundingTime(dh, dm, ds)
84
-
85
- # time-varying value representing need of masking
86
- node (maskHour, maskMin, maskSec) =
87
- if curMode.editable && flash then
88
- curPos of:
89
- HourPos -> (True, False, False)
90
- MinPos -> (False, True, False)
91
- SecPos -> (False, False, True)
92
- else
93
- (False, False, False)
1
+ module LCDClock
2
+ in
3
+ btnMode(False) : Bool, # Is mode-button pushed now?
4
+ btnNext(False) : Bool, # Is next-button pushed now?
5
+ btnRotate(False) : Bool, # Is rotate-button pushed now?
6
+ pulse100ms : Bool # input to be True only once per 100ms
7
+ out
8
+ hour, min, sec, # current time to display
9
+ maskHour, maskMin, maskSec # Is it now needed to display -- instead of two-digits?
10
+ use
11
+ Std
12
+
13
+ # Functions
14
+ # --------------------
15
+
16
+ type Mode = Normal | Edit
17
+ type EditPos = HourPos | MinPos | SecPos
18
+ type Time = Time(Int, Int, Int)
19
+
20
+ func nextMode(m) = m of Normal -> Edit, Edit -> Normal
21
+
22
+ func editable(m) = m of Normal -> False, Edit -> True
23
+
24
+ func nextPos(p) = p of:
25
+ HourPos -> MinPos
26
+ MinPos -> SecPos
27
+ SecPos -> HourPos
28
+
29
+ func positiveEdge(a, b) = !a && b
30
+
31
+ # proceed Time by 1sec
32
+ func proceedTime(t) = {
33
+ Time(h, m, s) = t
34
+ newS = s + 1
35
+ newM = m + (newS / 60)
36
+ newH = h + (newM / 60)
37
+ Time(newH % 24, newM % 60, newS % 60)
38
+ }
39
+
40
+ func roundingTime(t, dh, dm, ds) = {
41
+ Time(h, m, s) = t
42
+ Time((h + dh) % 24, (m + dm) % 60, (s + ds) % 60)
43
+ }
44
+
45
+ # Nodes
46
+ # --------------------
47
+
48
+ # mod-10 counter incremented by every 100ms
49
+ node init[0] counter : Int =
50
+ (if pulse100ms then counter@last + 1 else counter@last) % 10
51
+
52
+ # time-varying value to be True only once per 1sec
53
+ node pulse1s : Bool =
54
+ counter == 0 && counter@last != 0
55
+
56
+ # time-varying value switching True/False by every 500ms
57
+ node flash : Bool =
58
+ counter < 5
59
+
60
+ # time-varying value representing current time-set mode
61
+ node init[Normal] curMode : Mode =
62
+ if btnMode@last `positiveEdge` btnMode then curMode@last.nextMode else curMode@last
63
+
64
+ # time-varying value representing current editing-cursor-position
65
+ node init[HourPos] curPos : EditPos =
66
+ if btnNext@last `positiveEdge` btnNext then curPos@last.nextPos else curPos@last
67
+
68
+ # time-varying value representing diffs to add to current time.
69
+ node (dh, dm, ds) : (Int, Int, Int) =
70
+ if curMode.editable && (btnRotate@last `positiveEdge` btnRotate) then
71
+ curPos of:
72
+ HourPos -> (1, 0, 0)
73
+ MinPos -> (0, 1, 0)
74
+ SecPos -> (0, 0, 1)
75
+ else
76
+ (0, 0, 0)
77
+
78
+ # time-varying value representing current time
79
+ node init[Time(0, 0, 0)] Time(hour, min, sec) as curTime =
80
+ if pulse1s then
81
+ curTime@last.proceedTime.roundingTime(dh, dm, ds)
82
+ else
83
+ curTime@last.roundingTime(dh, dm, ds)
84
+
85
+ # time-varying value representing need of masking
86
+ node (maskHour, maskMin, maskSec) =
87
+ if curMode.editable && flash then
88
+ curPos of:
89
+ HourPos -> (True, False, False)
90
+ MinPos -> (False, True, False)
91
+ SecPos -> (False, False, True)
92
+ else
93
+ (False, False, False)
File without changes
@@ -1,24 +1,24 @@
1
- # LCD Clock
2
-
3
- This is a program of the digital clock.
4
-
5
- ## Functions
6
- * Center (push) button (of joystick) toggles on-off of time-set mode.
7
- * Right button moves cursor of time-set targets (hour, minute and second).
8
- * Up button raises time-set target's value (+1) if time-set mode is on.
9
-
10
- ## Target device
11
- mbed LPC1768 with application board
12
-
13
- ## IO library
14
- Following libraries are required.
15
- * Basic IO library `mbed` (official)
16
- * LCD's manipulation library `C12832_lcd` (third-party)
17
-
18
- Both they are available from official library repository of *mbed.org*.
19
-
20
- ## Sample
21
-
22
- ![Sample Image](https://raw.githubusercontent.com/wiki/sawaken/emfrp/images/LCDClock.jpg)
23
-
24
- * [Watch on YouTube](https://www.youtube.com/watch?v=Fah2iJAaouo)
1
+ # LCD Clock
2
+
3
+ This is a program of the digital clock.
4
+
5
+ ## Functions
6
+ * Center (push) button (of joystick) toggles on-off of time-set mode.
7
+ * Right button moves cursor of time-set targets (hour, minute and second).
8
+ * Up button raises time-set target's value (+1) if time-set mode is on.
9
+
10
+ ## Target device
11
+ mbed LPC1768 with application board
12
+
13
+ ## IO library
14
+ Following libraries are required.
15
+ * Basic IO library `mbed` (official)
16
+ * LCD's manipulation library `C12832_lcd` (third-party)
17
+
18
+ Both they are available from official library repository of *mbed.org*.
19
+
20
+ ## Sample
21
+
22
+ ![Sample Image](https://raw.githubusercontent.com/wiki/sawaken/emfrp/images/LCDClock.jpg)
23
+
24
+ * [Watch on YouTube](https://www.youtube.com/watch?v=Fah2iJAaouo)
@@ -1,30 +1,30 @@
1
- module LCDPositioner
2
- in
3
- up : Bool,
4
- down : Bool,
5
- left : Bool,
6
- right : Bool,
7
- pulse10ms : Bool
8
- out
9
- x, y
10
- use
11
- Std
12
-
13
- node dy = down.boolToInt - up.boolToInt
14
- node dx = right.boolToInt - left.boolToInt
15
-
16
- node init[(False, 0)] (pulse40ms, pulse40msCount) as pulse = {
17
- c = (pulse40msCount@last + pulse10ms.boolToInt) % 4
18
- (c == 0 && pulse10ms, c)
19
- }
20
-
21
- node init[(0,0)] (x, y) as pos =
22
- if pulse40ms then (x@last + dx, y@last + dy) else pos@last
23
-
24
-
25
- #@ :assert-module
26
- #- True, False, False, False, True => 0, 0
27
- #@ : True, False, False, False, True => 0, 0
28
- #@ : True, False, False, False, True => 0, 0
29
- #@ : True, False, False, False, True => 0, -1
30
- #@ : True, False, False, False, True => 0, -1
1
+ module LCDPositioner
2
+ in
3
+ up : Bool,
4
+ down : Bool,
5
+ left : Bool,
6
+ right : Bool,
7
+ pulse10ms : Bool
8
+ out
9
+ x, y
10
+ use
11
+ Std
12
+
13
+ node dy = down.boolToInt - up.boolToInt
14
+ node dx = right.boolToInt - left.boolToInt
15
+
16
+ node init[(False, 0)] (pulse40ms, pulse40msCount) as pulse = {
17
+ c = (pulse40msCount@last + pulse10ms.boolToInt) % 4
18
+ (c == 0 && pulse10ms, c)
19
+ }
20
+
21
+ node init[(0,0)] (x, y) as pos =
22
+ if pulse40ms then (x@last + dx, y@last + dy) else pos@last
23
+
24
+
25
+ #@ :assert-module
26
+ #- True, False, False, False, True => 0, 0
27
+ #@ : True, False, False, False, True => 0, 0
28
+ #@ : True, False, False, False, True => 0, 0
29
+ #@ : True, False, False, False, True => 0, -1
30
+ #@ : True, False, False, False, True => 0, -1
@@ -1,15 +1,15 @@
1
- #include "LCDPositioner.h"
2
- #include <stdio.h>
3
- #include <stdlib.h>
4
-
5
- void Input(int* up, int* down, int* left, int* right, int* pulse10ms) {
6
- if (scanf("%d %d %d %d %d", up, down, left, right, pulse10ms) == EOF) {
7
- exit(0);
8
- }
9
- }
10
- void Output(int* x, int* y) {
11
- printf("%d %d\n", *x, *y);
12
- }
13
- int main() {
14
- ActivateLCDPositioner();
15
- }
1
+ #include "LCDPositioner.h"
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+
5
+ void Input(int* up, int* down, int* left, int* right, int* pulse10ms) {
6
+ if (scanf("%d %d %d %d %d", up, down, left, right, pulse10ms) == EOF) {
7
+ exit(0);
8
+ }
9
+ }
10
+ void Output(int* x, int* y) {
11
+ printf("%d %d\n", *x, *y);
12
+ }
13
+ int main() {
14
+ ActivateLCDPositioner();
15
+ }
@@ -1,25 +1,25 @@
1
- module MostDistantPoint
2
- in
3
- inX : Int, inY : Int
4
- out
5
- outX, outY
6
- use
7
- Std
8
-
9
- #@ :assert-equals 2, distant2((1, 1), (2, 2))
10
- func distant2(pointA, pointB) = {
11
- dx = pointA.fst - pointB.fst
12
- dy = pointA.snd - pointB.snd
13
- dx * dx + dy * dy
14
- }
15
-
16
- node init[(0, 0)] (outX, outY) as point = {
17
- d1 = distant2((0, 0), point@last)
18
- d2 = distant2((0, 0), (inX, inY))
19
- if d1 < d2 then (inX, inY) else point@last
20
- }
21
-
22
- #@ :assert-module
23
- #- 0, 0 => 0, 0
24
- #@ : 1, 1 => 1, 1
25
- #@ : 0, 0 => 1, 1
1
+ module MostDistantPoint
2
+ in
3
+ inX : Int, inY : Int
4
+ out
5
+ outX, outY
6
+ use
7
+ Std
8
+
9
+ #@ :assert-equals 2, distant2((1, 1), (2, 2))
10
+ func distant2(pointA, pointB) = {
11
+ dx = pointA.fst - pointB.fst
12
+ dy = pointA.snd - pointB.snd
13
+ dx * dx + dy * dy
14
+ }
15
+
16
+ node init[(0, 0)] (outX, outY) as point = {
17
+ d1 = distant2((0, 0), point@last)
18
+ d2 = distant2((0, 0), (inX, inY))
19
+ if d1 < d2 then (inX, inY) else point@last
20
+ }
21
+
22
+ #@ :assert-module
23
+ #- 0, 0 => 0, 0
24
+ #@ : 1, 1 => 1, 1
25
+ #@ : 0, 0 => 1, 1
@@ -1,14 +1,14 @@
1
- #include "MostDistantPoint.h"
2
- #include <stdio.h>
3
-
4
- void Input(int* inX, int* inY) {
5
- scanf("%d %d", inX, inY);
6
- }
7
-
8
- void Output(int* outX, int* outY) {
9
- printf("%d %d\n", *outX, *outY);
10
- }
11
-
12
- int main() {
13
- ActivateMostDistantPoint();
14
- }
1
+ #include "MostDistantPoint.h"
2
+ #include <stdio.h>
3
+
4
+ void Input(int* inX, int* inY) {
5
+ scanf("%d %d", inX, inY);
6
+ }
7
+
8
+ void Output(int* outX, int* outY) {
9
+ printf("%d %d\n", *outX, *outY);
10
+ }
11
+
12
+ int main() {
13
+ ActivateMostDistantPoint();
14
+ }