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
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
+ }