fancy 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +14 -14
- data/Rakefile +16 -4
- data/bin/fancy +3 -0
- data/bin/fspec +20 -0
- data/bin/fyi +27 -11
- data/bin/ifancy +1 -1
- data/boot/fancy_ext.rb +1 -0
- data/boot/fancy_ext/block_env.rb +1 -9
- data/boot/fancy_ext/delegator.rb +64 -0
- data/boot/fancy_ext/object.rb +4 -0
- data/boot/fancy_ext/thread.rb +4 -0
- data/boot/load.rb +5 -1
- data/boot/rbx-compiler/compiler/ast.rb +0 -1
- data/boot/rbx-compiler/compiler/ast/class_def.rb +2 -0
- data/boot/rbx-compiler/compiler/ast/method_def.rb +2 -0
- data/boot/rbx-compiler/compiler/ast/node.rb +10 -0
- data/boot/rbx-compiler/compiler/ast/ruby_args.rb +12 -0
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +2 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/lexer.lex +5 -11
- data/boot/rbx-compiler/parser/parser.rb +16 -5
- data/boot/rbx-compiler/parser/parser.y +39 -24
- data/doc/api/fancy.css +1 -1
- data/doc/api/fancy.jsonp +1 -1
- data/doc/api/fdoc.js +22 -4
- data/doc/api/index.html +5 -6
- data/doc/api/jquery-ui.min.js +401 -0
- data/doc/api/jquery.tools.min.js +192 -0
- data/doc/api/themeswitchertool.js +250 -0
- data/doc/features.md +17 -0
- data/examples/actor_bunnies.fy +32 -0
- data/examples/actors.fy +26 -0
- data/examples/actors_primitive.fy +27 -0
- data/examples/actors_ring.fy +37 -0
- data/examples/armstrong_numbers.fy +1 -1
- data/examples/array.fy +7 -9
- data/examples/async_send.fy +1 -2
- data/examples/blocks.fy +4 -4
- data/examples/call_with_receiver.fy +1 -1
- data/examples/class.fy +1 -1
- data/examples/default_args.fy +4 -1
- data/examples/define_methods.fy +2 -2
- data/examples/echo.fy +1 -1
- data/examples/factorial.fy +1 -1
- data/examples/future_composition.fy +2 -2
- data/examples/futures.fy +0 -5
- data/examples/game_of_life.fy +1 -1
- data/examples/person.fy +1 -1
- data/lib/argv.fy +7 -2
- data/lib/array.fy +109 -42
- data/lib/block.fy +39 -14
- data/lib/boot.fy +2 -0
- data/lib/class.fy +2 -0
- data/lib/compiler/ast.fy +2 -1
- data/lib/compiler/ast/assign.fy +2 -3
- data/lib/compiler/ast/async_send.fy +1 -15
- data/lib/compiler/ast/class_def.fy +2 -1
- data/lib/compiler/ast/expression_list.fy +4 -5
- data/lib/compiler/ast/future_send.fy +1 -10
- data/lib/compiler/ast/goto.fy +46 -0
- data/lib/compiler/ast/identifier.fy +9 -7
- data/lib/compiler/ast/literals.fy +8 -1
- data/lib/compiler/ast/match.fy +14 -4
- data/lib/compiler/ast/message_send.fy +34 -6
- data/lib/compiler/ast/method_def.fy +6 -6
- data/lib/compiler/ast/node.fy +3 -3
- data/lib/compiler/ast/range.fy +1 -0
- data/lib/compiler/ast/script.fy +0 -2
- data/lib/compiler/ast/singleton_method_def.fy +2 -4
- data/lib/compiler/ast/string_interpolation.fy +17 -0
- data/lib/compiler/ast/super.fy +5 -4
- data/lib/compiler/ast/try_catch.fy +8 -6
- data/lib/compiler/ast/tuple_literal.fy +3 -2
- data/lib/compiler/command.fy +0 -1
- data/lib/compiler/compiler.fy +1 -5
- data/lib/compiler/stages.fy +6 -14
- data/lib/documentation.fy +57 -46
- data/lib/enumerable.fy +257 -23
- data/lib/enumerator.fy +122 -15
- data/lib/false_class.fy +10 -1
- data/lib/fancy_spec.fy +263 -61
- data/lib/fdoc.fy +11 -25
- data/lib/fiber.fy +11 -0
- data/lib/file.fy +8 -11
- data/lib/future.fy +84 -5
- data/lib/hash.fy +65 -14
- data/lib/integer.fy +35 -0
- data/lib/iteration.fy +54 -29
- data/lib/message.fy +6 -0
- data/lib/method.fy +0 -16
- data/lib/nil_class.fy +58 -8
- data/lib/number.fy +49 -22
- data/lib/object.fy +371 -65
- data/lib/package.fy +24 -1
- data/lib/package/installer.fy +5 -9
- data/lib/package/specification.fy +2 -2
- data/lib/parser/ext/lexer.lex +15 -11
- data/lib/parser/ext/parser.y +70 -23
- data/lib/parser/methods.fy +33 -14
- data/lib/proxy.fy +33 -3
- data/lib/range.fy +28 -0
- data/lib/rbx.fy +3 -1
- data/lib/rbx/actor.fy +53 -0
- data/lib/rbx/alpha.fy +31 -0
- data/lib/rbx/array.fy +21 -12
- data/lib/rbx/bignum.fy +6 -2
- data/lib/rbx/block.fy +23 -26
- data/lib/rbx/class.fy +54 -2
- data/lib/rbx/code_loader.fy +8 -4
- data/lib/rbx/date.fy +9 -0
- data/lib/rbx/directory.fy +18 -0
- data/lib/rbx/environment_variables.fy +1 -0
- data/lib/rbx/exception.fy +9 -2
- data/lib/rbx/fiber.fy +22 -4
- data/lib/rbx/file.fy +5 -5
- data/lib/rbx/fixnum.fy +5 -0
- data/lib/rbx/float.fy +11 -3
- data/lib/rbx/hash.fy +31 -16
- data/lib/rbx/integer.fy +1 -0
- data/lib/rbx/io.fy +17 -7
- data/lib/rbx/match_data.fy +15 -4
- data/lib/rbx/method.fy +40 -7
- data/lib/rbx/name_error.fy +4 -0
- data/lib/rbx/object.fy +92 -24
- data/lib/rbx/range.fy +20 -6
- data/lib/rbx/regexp.fy +11 -3
- data/lib/rbx/string.fy +51 -1
- data/lib/rbx/stringio.fy +17 -0
- data/lib/rbx/symbol.fy +15 -1
- data/lib/rbx/system.fy +20 -2
- data/lib/rbx/tcp_server.fy +4 -1
- data/lib/rbx/tcp_socket.fy +11 -0
- data/lib/rbx/time.fy +6 -0
- data/lib/rbx/tuple.fy +14 -5
- data/lib/set.fy +144 -29
- data/lib/stack.fy +42 -11
- data/lib/string.fy +118 -8
- data/lib/struct.fy +13 -3
- data/lib/symbol.fy +21 -2
- data/lib/thread_pool.fy +2 -1
- data/lib/true_class.fy +45 -7
- data/lib/tuple.fy +27 -9
- data/lib/version.fy +2 -2
- data/ruby_lib/fancy +43 -0
- data/ruby_lib/fdoc +23 -0
- data/ruby_lib/fspec +3 -0
- data/ruby_lib/fyi +3 -0
- data/ruby_lib/ifancy +3 -0
- data/tests/argv.fy +5 -9
- data/tests/array.fy +323 -196
- data/tests/assignment.fy +29 -29
- data/tests/block.fy +72 -59
- data/tests/class.fy +227 -138
- data/tests/control_flow.fy +83 -51
- data/tests/documentation.fy +8 -8
- data/tests/enumerable.fy +8 -0
- data/tests/enumerator.fy +47 -29
- data/tests/exception.fy +49 -32
- data/tests/file.fy +28 -28
- data/tests/fixnum.fy +170 -0
- data/tests/future.fy +24 -7
- data/tests/hash.fy +55 -38
- data/tests/method.fy +50 -43
- data/tests/nil_class.fy +37 -37
- data/tests/object.fy +152 -70
- data/tests/pattern_matching.fy +67 -31
- data/tests/range.fy +6 -6
- data/tests/set.fy +101 -4
- data/tests/stack.fy +14 -5
- data/tests/string.fy +115 -61
- data/tests/stringio.fy +18 -0
- data/tests/struct.fy +27 -0
- data/tests/symbol.fy +19 -6
- data/tests/true_class.fy +34 -34
- data/tests/tuple.fy +30 -12
- metadata +103 -81
- data/boot/rbx-compiler/compiler/ast/require.rb +0 -20
- data/examples/actor.fy +0 -37
- data/examples/curl_async.fy +0 -37
- data/lib/compiler/ast/require.fy +0 -15
- data/tests/number.fy +0 -135
- data/tests/parsing/sexp.fy +0 -50
data/lib/fdoc.fy
CHANGED
@@ -109,10 +109,11 @@ class Fancy FDoc {
|
|
109
109
|
exec = cls send(type, n) executable()
|
110
110
|
methods delete(exec)
|
111
111
|
mdoc = Fancy Documentation for: exec
|
112
|
+
{ next } unless: mdoc # skip methods with no documentation
|
112
113
|
if: mdoc then: {
|
113
|
-
mattr
|
114
|
+
mattr['doc]: $ mdoc format: 'fdoc
|
114
115
|
if: (mdoc meta) then: {
|
115
|
-
mattr
|
116
|
+
mattr['arg]: $ mdoc meta at: 'argnames
|
116
117
|
}
|
117
118
|
}
|
118
119
|
if: (exec class() == Rubinius CompiledMethod) then: {
|
@@ -121,12 +122,12 @@ class Fancy FDoc {
|
|
121
122
|
# TODO: Fix, either use a -r (root) option or use __FILE__
|
122
123
|
relative_file = relative_file to_s gsub(/.*lib/, "lib")
|
123
124
|
lines = exec lines() to_a()
|
124
|
-
mattr
|
125
|
+
mattr['file]: $ relative_file
|
125
126
|
# TODO calculate line numbers from compiled method
|
126
127
|
# right now we only use the first line of code in the body.
|
127
|
-
mattr
|
128
|
+
mattr['lines]: $ [lines[3], lines[3]]
|
128
129
|
}
|
129
|
-
attr[(type ++ "s") intern()]
|
130
|
+
attr[(type ++ "s") intern()] [n]: mattr
|
130
131
|
}
|
131
132
|
}
|
132
133
|
|
@@ -137,7 +138,7 @@ class Fancy FDoc {
|
|
137
138
|
methods = @methods dup()
|
138
139
|
|
139
140
|
@classes each: |cls| {
|
140
|
-
name = cls name
|
141
|
+
name = cls name gsub("::", " ")
|
141
142
|
doc = Fancy Documentation for: cls
|
142
143
|
attr = <[
|
143
144
|
'doc => doc format: 'fdoc,
|
@@ -147,7 +148,7 @@ class Fancy FDoc {
|
|
147
148
|
]>
|
148
149
|
popuplate_methods: cls on: attr type: 'instance_method known: methods
|
149
150
|
popuplate_methods: cls on: attr type: 'method known: methods
|
150
|
-
map['classes]
|
151
|
+
map['classes][name]: attr
|
151
152
|
}
|
152
153
|
|
153
154
|
methods each: |cm| {
|
@@ -163,7 +164,7 @@ class Fancy FDoc {
|
|
163
164
|
'doc => doc format: 'fdoc
|
164
165
|
]>
|
165
166
|
|
166
|
-
map['methods]
|
167
|
+
map['methods][full_name]: attr
|
167
168
|
}
|
168
169
|
|
169
170
|
map
|
@@ -194,7 +195,7 @@ class Fancy FDoc {
|
|
194
195
|
def self format: doc {
|
195
196
|
str = doc to_s
|
196
197
|
tags = <[ ]>
|
197
|
-
str =
|
198
|
+
str = str skip_leading_indentation
|
198
199
|
str = remove_tags: str into: tags
|
199
200
|
str = create_tags: str with: tags
|
200
201
|
str = create_class_references: str
|
@@ -204,21 +205,6 @@ class Fancy FDoc {
|
|
204
205
|
str
|
205
206
|
}
|
206
207
|
|
207
|
-
def self remove_indentation: str {
|
208
|
-
"""
|
209
|
-
Remove leading white space for multi-line strings.
|
210
|
-
This method expects the first character to be an line return.
|
211
|
-
"""
|
212
|
-
m = /^(\r?\n)*(\s+)/ match(str)
|
213
|
-
str = str strip()
|
214
|
-
if: m then: {
|
215
|
-
pattern = "^ {" ++ (m[2] size()) ++ "}"
|
216
|
-
rex = Regexp.new(pattern)
|
217
|
-
str = str gsub(rex, "");
|
218
|
-
}
|
219
|
-
str
|
220
|
-
}
|
221
|
-
|
222
208
|
def self create_class_references: str {
|
223
209
|
"""
|
224
210
|
Creates class references for Fancy class names.
|
@@ -313,7 +299,7 @@ class Fancy FDoc {
|
|
313
299
|
ary = str split(/\r?\n/) map: |line| {
|
314
300
|
m = /^@([a-z@]\S+?)\s+(.*)/ match(line)
|
315
301
|
if: m then: {
|
316
|
-
map
|
302
|
+
map[m[1]]: (m[2])
|
317
303
|
nil
|
318
304
|
} else: {
|
319
305
|
line
|
data/lib/fiber.fy
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
class Fiber {
|
2
|
+
"""
|
3
|
+
Fiber class. Fibers are cooperatively scheduled coroutines supported
|
4
|
+
by the Rubinius VM.
|
5
|
+
Control flow between multiple Fibers is always explicitly handled.
|
6
|
+
There is no preemptive scheduler.
|
7
|
+
"""
|
8
|
+
|
2
9
|
def sleep: seconds {
|
3
10
|
@sleep_end = Time now + seconds
|
4
11
|
}
|
@@ -8,4 +15,8 @@ class Fiber {
|
|
8
15
|
Time now < @sleep_end
|
9
16
|
}
|
10
17
|
}
|
18
|
+
|
19
|
+
def Fiber name {
|
20
|
+
"Fiber"
|
21
|
+
}
|
11
22
|
}
|
data/lib/file.fy
CHANGED
@@ -31,6 +31,12 @@ class File {
|
|
31
31
|
}
|
32
32
|
|
33
33
|
def self touch: filename {
|
34
|
+
"""
|
35
|
+
@filename Name of @File@ to be created, if not already existant.
|
36
|
+
|
37
|
+
Creates a new empty file with the given @filename, if it doesn't already exist.
|
38
|
+
"""
|
39
|
+
|
34
40
|
file = File expand_path(filename)
|
35
41
|
File open: file modes: ['write] with: |f| {
|
36
42
|
f write: ""
|
@@ -47,15 +53,6 @@ class File {
|
|
47
53
|
newline
|
48
54
|
}
|
49
55
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
write: x
|
54
|
-
}
|
55
|
-
|
56
|
-
def println: x {
|
57
|
-
"Same as File#writeln:."
|
58
|
-
|
59
|
-
writeln: x
|
60
|
-
}
|
56
|
+
alias_method: 'print: for: 'write:
|
57
|
+
alias_method: 'println: for: 'writeln:
|
61
58
|
}
|
data/lib/future.fy
CHANGED
@@ -1,16 +1,91 @@
|
|
1
|
-
class
|
1
|
+
class FutureSend {
|
2
|
+
read_slots: [ 'fail_reason, 'receiver, 'message, 'params ]
|
3
|
+
def initialize: @actor receiver: @receiver message: @message with_params: @params ([]) {
|
4
|
+
@waiting_threads = []
|
5
|
+
@actor ! ('future, (@message, @params), self)
|
6
|
+
}
|
7
|
+
|
8
|
+
def failed: @fail_reason {
|
9
|
+
synchronized: {
|
10
|
+
@completed = true
|
11
|
+
@failed = true
|
12
|
+
completed!
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
def completed: @value {
|
17
|
+
synchronized: {
|
18
|
+
@completed = true
|
19
|
+
completed!
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
def completed! {
|
24
|
+
@waiting_threads each: 'run
|
25
|
+
@waiting_threads = []
|
26
|
+
}
|
27
|
+
|
28
|
+
private: 'completed!
|
29
|
+
|
30
|
+
def completed? {
|
31
|
+
synchronized: {
|
32
|
+
return @completed
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
def failed? {
|
37
|
+
synchronized: {
|
38
|
+
return @failed
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
def value {
|
43
|
+
if: completed? then: {
|
44
|
+
return @value
|
45
|
+
} else: {
|
46
|
+
synchronized: {
|
47
|
+
@waiting_threads << (Thread current)
|
48
|
+
}
|
49
|
+
Thread stop
|
50
|
+
return @value
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
def send_future: message with_params: params {
|
55
|
+
value send_future: message with_params: params
|
56
|
+
}
|
57
|
+
|
58
|
+
def when_done: block {
|
59
|
+
block send_future: 'call: with_params: [value]
|
60
|
+
}
|
61
|
+
|
62
|
+
def && block {
|
63
|
+
when_done: block
|
64
|
+
}
|
65
|
+
|
66
|
+
def inspect {
|
67
|
+
str = "#<FutureSend:0x" ++ (object_id to_s: 16) ++ " @receiver=" ++ @receiver
|
68
|
+
str << " @message="
|
69
|
+
str << (@message inspect)
|
70
|
+
str << " @params="
|
71
|
+
str << (@params inspect)
|
72
|
+
str + ">"
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
class PooledFuture {
|
2
77
|
@@thread_pool = nil
|
3
78
|
@@pool_size = 10
|
4
79
|
WaitInterval = 0.1
|
5
80
|
|
6
|
-
def
|
81
|
+
def PooledFuture pool: n {
|
7
82
|
@@pool_size = match n {
|
8
83
|
case 0 -> 10
|
9
84
|
case _ -> n
|
10
85
|
}
|
11
86
|
}
|
12
87
|
|
13
|
-
def
|
88
|
+
def PooledFuture join! {
|
14
89
|
@@thread_pool join
|
15
90
|
}
|
16
91
|
|
@@ -20,7 +95,7 @@ class Future {
|
|
20
95
|
}
|
21
96
|
|
22
97
|
def when_done: block {
|
23
|
-
|
98
|
+
PooledFuture new: {
|
24
99
|
block call: [value]
|
25
100
|
}
|
26
101
|
}
|
@@ -29,8 +104,12 @@ class Future {
|
|
29
104
|
when_done: block
|
30
105
|
}
|
31
106
|
|
107
|
+
def completed? {
|
108
|
+
@block complete?
|
109
|
+
}
|
110
|
+
|
32
111
|
def value {
|
33
|
-
{ Thread sleep: WaitInterval } until: {
|
112
|
+
{ Thread sleep: WaitInterval } until: { completed? }
|
34
113
|
@block completed_value
|
35
114
|
}
|
36
115
|
}
|
data/lib/hash.fy
CHANGED
@@ -6,16 +6,25 @@ class Hash {
|
|
6
6
|
|
7
7
|
include: FancyEnumerable
|
8
8
|
|
9
|
-
def []
|
10
|
-
"
|
9
|
+
def [key] {
|
10
|
+
"""
|
11
|
+
@key Key for value to get.
|
12
|
+
@return Value for given @key or @nil, if @key not set.
|
13
|
+
|
14
|
+
Returns the value for a given key.
|
15
|
+
"""
|
11
16
|
|
12
17
|
at: key
|
13
18
|
}
|
14
19
|
|
15
20
|
def each: block {
|
16
|
-
"
|
21
|
+
"""
|
22
|
+
@block @Block@ to be called with each key and value in @self.
|
23
|
+
@return @self
|
24
|
+
Calls a given @Block@ with each key and value.
|
25
|
+
"""
|
17
26
|
|
18
|
-
if: (block
|
27
|
+
if: (block arity == 1) then: {
|
19
28
|
keys each: |key| {
|
20
29
|
block call: [[key, at: key]]
|
21
30
|
}
|
@@ -24,33 +33,75 @@ class Hash {
|
|
24
33
|
block call: [key, at: key]
|
25
34
|
}
|
26
35
|
}
|
36
|
+
self
|
27
37
|
}
|
28
38
|
|
29
39
|
def each_key: block {
|
30
|
-
"
|
40
|
+
"""
|
41
|
+
@block @Block@ to be called with each key in @self.
|
42
|
+
@return @self
|
31
43
|
|
32
|
-
|
33
|
-
|
34
|
-
|
44
|
+
Calls a given @Block@ with each key.
|
45
|
+
"""
|
46
|
+
|
47
|
+
keys each: block
|
48
|
+
self
|
35
49
|
}
|
36
50
|
|
37
51
|
def each_value: block {
|
38
|
-
"
|
52
|
+
"""
|
53
|
+
@block @Block@ to be called with each value in @self.
|
54
|
+
@return @self
|
39
55
|
|
40
|
-
|
41
|
-
|
42
|
-
|
56
|
+
Calls a given @Block@ with each value.
|
57
|
+
"""
|
58
|
+
|
59
|
+
values each: block
|
60
|
+
self
|
43
61
|
}
|
44
62
|
|
45
63
|
def to_a {
|
46
|
-
"
|
64
|
+
"""
|
65
|
+
@return @Array@ of all key-value pairs in @self.
|
66
|
+
|
67
|
+
Returns an @Array@ of the key-value pairs in a @Hash@.
|
68
|
+
"""
|
47
69
|
|
48
70
|
map: |pair| { pair }
|
49
71
|
}
|
50
72
|
|
51
73
|
def to_s {
|
52
|
-
"
|
74
|
+
"""
|
75
|
+
@return @String@ representation of @self.
|
76
|
+
|
77
|
+
Returns a @String@ representation of a @Hash@.
|
78
|
+
"""
|
53
79
|
|
54
80
|
to_a to_s
|
55
81
|
}
|
82
|
+
|
83
|
+
def inspect {
|
84
|
+
str = "<["
|
85
|
+
each: |key val| {
|
86
|
+
str << (key inspect)
|
87
|
+
str << " => "
|
88
|
+
str << (val inspect)
|
89
|
+
} in_between: {
|
90
|
+
str << ", "
|
91
|
+
}
|
92
|
+
str << "]>"
|
93
|
+
str
|
94
|
+
}
|
95
|
+
|
96
|
+
def values_at: keys {
|
97
|
+
"""
|
98
|
+
@keys Collection of keys to get the values for.
|
99
|
+
@return @Array@ of all values for the given keys.
|
100
|
+
|
101
|
+
Example usage:
|
102
|
+
<['foo => 1, 'bar => 2, 'baz => 42]> values_at: ('foo, 'baz) # => [1, 42]
|
103
|
+
"""
|
104
|
+
|
105
|
+
keys map: |k| { at: k }
|
106
|
+
}
|
56
107
|
}
|
data/lib/integer.fy
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
class Integer {
|
2
|
+
"""
|
3
|
+
Base class for integer values in Fancy.
|
4
|
+
"""
|
5
|
+
|
6
|
+
def times: block {
|
7
|
+
"""
|
8
|
+
@block @Block@ to be called with each number between 0 and @self.
|
9
|
+
@return @self
|
10
|
+
|
11
|
+
Calls a given @Block@ with each number between 0 and @self.
|
12
|
+
"""
|
13
|
+
|
14
|
+
tmp = 0
|
15
|
+
while: { tmp < self } do: {
|
16
|
+
block call: [tmp]
|
17
|
+
tmp = tmp + 1
|
18
|
+
}
|
19
|
+
self
|
20
|
+
}
|
21
|
+
|
22
|
+
def times: block offset: offset {
|
23
|
+
"""
|
24
|
+
@block @Block@ to be called with each number between @offset and @self.
|
25
|
+
@offset Offset to be used as starting point of iteration.
|
26
|
+
@return @self.
|
27
|
+
|
28
|
+
Similar to #times: but starts at a given offset.
|
29
|
+
"""
|
30
|
+
|
31
|
+
self times: |i| {
|
32
|
+
block call: [i + offset]
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
data/lib/iteration.fy
CHANGED
@@ -1,12 +1,38 @@
|
|
1
1
|
class Fancy {
|
2
2
|
class BreakIteration : StdError {
|
3
|
-
|
4
|
-
|
3
|
+
"""
|
4
|
+
Raised to break the current iteration.
|
5
|
+
It is rescued by Block#loop.
|
6
|
+
|
7
|
+
Example:
|
8
|
+
10 times: |i| {
|
9
|
+
i println
|
10
|
+
if: (i == 3) then: {
|
11
|
+
Fancy BreakIteration new raise!
|
12
|
+
}
|
13
|
+
}
|
14
|
+
\"Done!\" println
|
15
|
+
|
16
|
+
Produces:
|
17
|
+
0
|
18
|
+
1
|
19
|
+
2
|
20
|
+
3
|
21
|
+
Done!
|
22
|
+
"""
|
23
|
+
|
24
|
+
read_slots: ['result]
|
25
|
+
def initialize: @result {}
|
5
26
|
}
|
6
27
|
|
7
28
|
class NextIteration : StdError {
|
8
|
-
|
9
|
-
|
29
|
+
"""
|
30
|
+
Raised to continue with next iteration (and stopping the current one).
|
31
|
+
It is rescued by Block#loop.
|
32
|
+
"""
|
33
|
+
|
34
|
+
read_slots: ['result]
|
35
|
+
def initialize: @result {}
|
10
36
|
}
|
11
37
|
|
12
38
|
class StopIteration : StdError {
|
@@ -15,17 +41,16 @@ class Fancy {
|
|
15
41
|
It is rescued by Block#loop.
|
16
42
|
|
17
43
|
Example:
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
44
|
+
{
|
45
|
+
'Hello println
|
46
|
+
Fancy StopIteration new raise!
|
47
|
+
'World println
|
48
|
+
} loop
|
49
|
+
'Done! println
|
24
50
|
|
25
51
|
Produces:
|
26
|
-
|
27
|
-
|
28
|
-
Done!
|
52
|
+
Hello
|
53
|
+
Done!
|
29
54
|
"""
|
30
55
|
|
31
56
|
def initialize { @result = nil }
|
@@ -35,23 +60,23 @@ class Fancy {
|
|
35
60
|
"""
|
36
61
|
Returns the return value of the iterator.
|
37
62
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
63
|
+
o = Object new
|
64
|
+
def o each: block {
|
65
|
+
block call: [1]
|
66
|
+
block call: [2]
|
67
|
+
block call: [3]
|
68
|
+
100
|
69
|
+
}
|
45
70
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
71
|
+
e = o to_enum
|
72
|
+
e next p #=> 1
|
73
|
+
e next p #=> 2
|
74
|
+
e next p #=> 3
|
75
|
+
try {
|
76
|
+
e next
|
77
|
+
} catch Fancy StopIteration => ex {
|
78
|
+
ex result p #=> 100
|
79
|
+
}
|
55
80
|
"""
|
56
81
|
|
57
82
|
@result
|