fancy 0.5.0 → 0.6.0

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 (111) hide show
  1. data/AUTHORS +2 -0
  2. data/README.md +6 -1
  3. data/bin/fancy +6 -0
  4. data/bin/ifancy +44 -3
  5. data/boot/fancy_ext/module.rb +4 -0
  6. data/boot/fancy_ext/object.rb +4 -0
  7. data/boot/rbx-compiler/compiler/ast/block.rb +29 -1
  8. data/boot/rbx-compiler/compiler/ast/identifier.rb +6 -0
  9. data/boot/rbx-compiler/compiler/ast/message_send.rb +1 -0
  10. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  11. data/boot/rbx-compiler/parser/lexer.lex +2 -0
  12. data/boot/rbx-compiler/parser/parser.rb +6 -0
  13. data/boot/rbx-compiler/parser/parser.y +14 -1
  14. data/doc/api/fancy.jsonp +1 -1
  15. data/doc/features.md +24 -0
  16. data/examples/99bottles.fy +5 -0
  17. data/examples/conditions_exceptions.fy +9 -0
  18. data/examples/conditions_parsing.fy +68 -0
  19. data/examples/greeter.fy +9 -0
  20. data/examples/html_generator.fy +59 -29
  21. data/examples/webserver/webserver.fy +8 -11
  22. data/lib/argv.fy +6 -0
  23. data/lib/array.fy +17 -35
  24. data/lib/block.fy +82 -1
  25. data/lib/boot.fy +4 -2
  26. data/lib/compiler.fy +2 -2
  27. data/lib/compiler/ast/block.fy +24 -20
  28. data/lib/compiler/ast/message_send.fy +11 -0
  29. data/lib/contracts.fy +60 -0
  30. data/lib/dynamic_slot_object.fy +61 -0
  31. data/lib/enumerable.fy +432 -394
  32. data/lib/enumerator.fy +152 -150
  33. data/lib/fdoc.fy +4 -17
  34. data/lib/fiber.fy +4 -10
  35. data/lib/file.fy +33 -25
  36. data/lib/future.fy +59 -5
  37. data/lib/hash.fy +54 -1
  38. data/lib/html.fy +107 -0
  39. data/lib/kvo.fy +173 -0
  40. data/lib/main.fy +6 -2
  41. data/lib/message_sink.fy +19 -0
  42. data/lib/number.fy +48 -0
  43. data/lib/object.fy +65 -13
  44. data/lib/package.fy +12 -2
  45. data/lib/package/dependency.fy +13 -0
  46. data/lib/package/dependency_installer.fy +27 -0
  47. data/lib/package/installer.fy +4 -10
  48. data/lib/package/uninstaller.fy +1 -3
  49. data/lib/parser/ext/lexer.lex +8 -3
  50. data/lib/parser/ext/parser.y +4 -1
  51. data/lib/parser/methods.fy +7 -3
  52. data/lib/range.fy +1 -1
  53. data/lib/rbx.fy +2 -1
  54. data/lib/rbx/array.fy +28 -12
  55. data/lib/rbx/bignum.fy +1 -1
  56. data/lib/rbx/block.fy +27 -0
  57. data/lib/rbx/console.fy +6 -6
  58. data/lib/rbx/date.fy +6 -1
  59. data/lib/rbx/documentation.fy +8 -3
  60. data/lib/rbx/exception.fy +5 -0
  61. data/lib/rbx/file.fy +40 -7
  62. data/lib/rbx/fixnum.fy +12 -1
  63. data/lib/rbx/method.fy +9 -2
  64. data/lib/rbx/module.fy +24 -0
  65. data/lib/rbx/regexp.fy +8 -0
  66. data/lib/rbx/string.fy +23 -7
  67. data/lib/rbx/tcp_server.fy +4 -2
  68. data/lib/rbx/tcp_socket.fy +14 -0
  69. data/lib/remote_object.fy +59 -0
  70. data/lib/set.fy +15 -4
  71. data/lib/string.fy +38 -5
  72. data/lib/stringio.fy +1 -0
  73. data/lib/symbol.fy +4 -0
  74. data/lib/system.fy +22 -0
  75. data/lib/thread_pool.fy +2 -2
  76. data/lib/tuple.fy +18 -1
  77. data/lib/vars.fy +17 -0
  78. data/lib/version.fy +1 -1
  79. data/ruby_lib/fancy +6 -0
  80. data/tests/array.fy +30 -0
  81. data/tests/block.fy +106 -0
  82. data/tests/class.fy +19 -0
  83. data/tests/enumerable.fy +1 -1
  84. data/tests/enumerator.fy +5 -5
  85. data/tests/file.fy +28 -0
  86. data/tests/fixnum.fy +0 -50
  87. data/tests/future.fy +9 -24
  88. data/tests/hash.fy +35 -0
  89. data/tests/html.fy +33 -0
  90. data/tests/kvo.fy +101 -0
  91. data/tests/number.fy +75 -0
  92. data/tests/object.fy +50 -3
  93. data/tests/string.fy +19 -10
  94. data/tests/symbol.fy +5 -0
  95. data/tests/tuple.fy +7 -0
  96. data/tools/fancy-mode.el +5 -1
  97. metadata +22 -21
  98. data/boot/compiler/parser/ext/fancy_parser.bundle +0 -0
  99. data/boot/rbx-compiler/parser/Makefile +0 -156
  100. data/boot/rbx-compiler/parser/lexer.c +0 -2310
  101. data/boot/rbx-compiler/parser/lexer.h +0 -315
  102. data/boot/rbx-compiler/parser/parser.c +0 -2946
  103. data/boot/rbx-compiler/parser/parser.h +0 -151
  104. data/lib/fiber_pool.fy +0 -78
  105. data/lib/method.fy +0 -6
  106. data/lib/parser/ext/Makefile +0 -156
  107. data/lib/parser/ext/fancy_parser.bundle +0 -0
  108. data/lib/parser/ext/lexer.c +0 -2392
  109. data/lib/parser/ext/lexer.h +0 -315
  110. data/lib/parser/ext/parser.c +0 -3251
  111. data/lib/parser/ext/parser.h +0 -161
@@ -1,184 +1,186 @@
1
- class FancyEnumerator {
2
- def initialize: @collection {
3
- """
4
- @collection Collection to iterate over.
5
-
6
- Initializes a new FancyEnumerator with a given @collection,
7
- using #each: for iteration.
8
- """
9
-
10
- @iterator = 'each:
11
- rewind
12
- }
13
-
14
- def initialize: @collection with: @iterator {
15
- """
16
- @collection Collection to iterate over.
17
- @iterator Selector to use to iterate over @collection.
18
-
19
- Initializes a new FancyEnumerator with a given @collection
20
- and @iterator selector to be used for iteration.
21
- """
22
-
23
- rewind
24
- }
1
+ class Fancy {
2
+ class Enumerator {
3
+ def initialize: @collection {
4
+ """
5
+ @collection Collection to iterate over.
6
+
7
+ Initializes a new Enumerator with a given @collection,
8
+ using #each: for iteration.
9
+ """
10
+
11
+ @iterator = 'each:
12
+ rewind
13
+ }
25
14
 
26
- def next {
27
- """
28
- @return Next element in the collection this enumerator is attached to.
15
+ def initialize: @collection with: @iterator {
16
+ """
17
+ @collection Collection to iterate over.
18
+ @iterator Selector to use to iterate over @collection.
29
19
 
30
- Returns the next element in the collection this enumerator is attached to.
31
- It will move the internal position forward (compared to e.g. #peek, which doesn't).
20
+ Initializes a new Enumerator with a given @collection
21
+ and @iterator selector to be used for iteration.
22
+ """
32
23
 
33
- Example:
34
- a = [1,2,3]
35
- e = a to_enum
36
- e next # => 1
37
- e next # => 2
38
- e next # => 3
39
- e next # => raises Fancy StopIteration
40
- """
24
+ rewind
25
+ }
41
26
 
42
- if: @peeked then: {
43
- @peeked = false
44
- @peek
45
- } else: {
46
- result = @fiber resume
47
- if: (@fiber alive?) then: {
48
- return result
27
+ def next {
28
+ """
29
+ @return Next element in the collection this enumerator is attached to.
30
+
31
+ Returns the next element in the collection this enumerator is attached to.
32
+ It will move the internal position forward (compared to e.g. #peek, which doesn't).
33
+
34
+ Example:
35
+ a = [1,2,3]
36
+ e = a to_enum
37
+ e next # => 1
38
+ e next # => 2
39
+ e next # => 3
40
+ e next # => raises Fancy StopIteration
41
+ """
42
+
43
+ if: @peeked then: {
44
+ @peeked = false
45
+ @peek
49
46
  } else: {
50
- (Fancy StopIteration new: result) raise!
47
+ result = @fiber resume
48
+ if: (@fiber alive?) then: {
49
+ return result
50
+ } else: {
51
+ (Fancy StopIteration new: result) raise!
52
+ }
51
53
  }
52
54
  }
53
- }
54
-
55
- def ended? {
56
- """
57
- @return @true if the enumerator has ended (no more values left), @false otherwise.
58
55
 
59
- Indicates if an enumerator has ended (no more values left).
60
- """
56
+ def ended? {
57
+ """
58
+ @return @true if the enumerator has ended (no more values left), @false otherwise.
61
59
 
62
- @fiber alive? not
63
- }
60
+ Indicates if an enumerator has ended (no more values left).
61
+ """
64
62
 
65
- def peek {
66
- """
67
- Returns the next object in the FancyEnumerator, but doesn't move the
68
- internal position forward.
69
- When the position reaches the end, a Fancy StopIteration exception is
70
- raised.
71
-
72
- Example:
73
- a = [1,2,3]
74
- e = a to_enum
75
- e next p #=> 1
76
- e peek p #=> 2
77
- e peek p #=> 2
78
- e peek p #=> 2
79
- e next p #=> 2
80
- e next p #=> 3
81
- e next p #=> raises Fancy StopIteration
82
- """
83
-
84
- unless: @peeked do: {
85
- @peeked = true
86
- @peek = @fiber resume
87
- if: (@fiber alive?) then: {
88
- return @peek
89
- } else: {
90
- (Fancy StopIteration new: result) raise!
91
- }
63
+ @fiber alive? not
92
64
  }
93
65
 
94
- return @peek
95
- }
96
-
97
- def rewind {
98
- """
99
- Resets the enumerator to start from the collection's beginning.
100
- """
101
-
102
- @peeked = false
103
- @peek = nil
66
+ def peek {
67
+ """
68
+ Returns the next object in the Enumerator, but doesn't move the
69
+ internal position forward.
70
+ When the position reaches the end, a Fancy StopIteration exception is
71
+ raised.
72
+
73
+ Example:
74
+ a = [1,2,3]
75
+ e = a to_enum
76
+ e next p #=> 1
77
+ e peek p #=> 2
78
+ e peek p #=> 2
79
+ e peek p #=> 2
80
+ e next p #=> 2
81
+ e next p #=> 3
82
+ e next p #=> raises Fancy StopIteration
83
+ """
84
+
85
+ unless: @peeked do: {
86
+ @peeked = true
87
+ @peek = @fiber resume
88
+ if: (@fiber alive?) then: {
89
+ return @peek
90
+ } else: {
91
+ (Fancy StopIteration new: result) raise!
92
+ }
93
+ }
104
94
 
105
- @fiber = Fiber new: {
106
- param = |element| { yield: element }
107
- @collection receive_message: @iterator with_params: [param]
95
+ return @peek
108
96
  }
109
- }
110
97
 
111
- def with: object each: block {
112
- """
113
- @object Object to pass along to @block with each element in the collection.
114
- @block A @Block@ to be called with each element in the collection and @object.
98
+ def rewind {
99
+ """
100
+ Resets the enumerator to start from the collection's beginning.
101
+ """
115
102
 
116
- Similar to #each: but also passing in a given @object to each invocation of @block.
117
- """
103
+ @peeked = false
104
+ @peek = nil
118
105
 
119
- each: |element| {
120
- block call: [element, object]
106
+ @fiber = Fiber new: {
107
+ param = |element| { yield: element }
108
+ @collection receive_message: @iterator with_params: [param]
109
+ }
121
110
  }
122
111
 
123
- return object
124
- }
125
-
126
- def each: block {
127
- """
128
- @block @Block@ to be called with each element in the collection (iteration).
112
+ def with: object each: block {
113
+ """
114
+ @object Object to pass along to @block with each element in the collection.
115
+ @block A @Block@ to be called with each element in the collection and @object.
129
116
 
130
- Calls a given @Block@ with each element in the collection this enumerator is attached to.
131
- Used for iterating over the collection using this enumerator.
132
- """
117
+ Similar to #each: but also passing in a given @object to each invocation of @block.
118
+ """
133
119
 
134
- loop: {
135
- try {
136
- block call: [next]
137
- } catch (Fancy StopIteration) => ex {
138
- return self
120
+ each: |element| {
121
+ block call: [element, object]
139
122
  }
123
+
124
+ return object
140
125
  }
141
- }
142
126
 
143
- def chunk: block {
144
- Generator new: |inner_block| {
145
- enums = []
146
- last = nil
147
- previous = nil
148
- stack = []
127
+ def each: block {
128
+ """
129
+ @block @Block@ to be called with each element in the collection (iteration).
130
+
131
+ Calls a given @Block@ with each element in the collection this enumerator is attached to.
132
+ Used for iterating over the collection using this enumerator.
133
+ """
134
+
135
+ loop: {
136
+ try {
137
+ block call: [next]
138
+ } catch (Fancy StopIteration) => ex {
139
+ return self
140
+ }
141
+ }
142
+ }
149
143
 
150
- each: |element| {
151
- result = (block call: [element]) not not
152
- if: (previous == result) then: {
153
- stack << element
154
- } else: {
155
- previous if_nil: {
156
- # wait one gap to call
144
+ def chunk: block {
145
+ Generator new: |inner_block| {
146
+ enums = []
147
+ last = nil
148
+ previous = nil
149
+ stack = []
150
+
151
+ each: |element| {
152
+ result = (block call: [element]) not not
153
+ if: (previous == result) then: {
154
+ stack << element
157
155
  } else: {
158
- inner_block call: [[previous, stack]]
156
+ previous if_nil: {
157
+ # wait one gap to call
158
+ } else: {
159
+ inner_block call: [[previous, stack]]
160
+ }
161
+ previous = result
162
+ stack = [element]
163
+ last = [result, stack]
164
+ enums << last
159
165
  }
160
- previous = result
161
- stack = [element]
162
- last = [result, stack]
163
- enums << last
164
166
  }
165
- }
166
167
 
167
- self
168
- } . to_enum
169
- }
168
+ self
169
+ } . to_enum
170
+ }
170
171
 
171
- class Generator {
172
- def initialize: @block {}
172
+ class Generator {
173
+ def initialize: @block {}
173
174
 
174
- def each: block {
175
- @block call: [block]
175
+ def each: block {
176
+ @block call: [block]
177
+ }
176
178
  }
177
- }
178
179
 
179
- def to_a {
180
- output = []
181
- each: |element| { output << element }
182
- output
180
+ def to_a {
181
+ output = []
182
+ each: |element| { output << element }
183
+ output
184
+ }
183
185
  }
184
- }
186
+ }
@@ -208,50 +208,37 @@ class Fancy FDoc {
208
208
  def self create_class_references: str {
209
209
  """
210
210
  Creates class references for Fancy class names.
211
-
212
211
  A docstring may contain class names sorounded by @
213
212
  without space between the @.
214
213
 
215
214
  Nested classes can be indicated by using :: like
216
-
217
- Foo::Bar
218
-
215
+ Foo::Bar
219
216
  This will create references for both, @Foo and @Bar
220
217
 
221
218
  Instance methods should be written:
222
-
223
- Foo::Bar#baz
219
+ Foo::Bar#baz
224
220
 
225
221
  Class methods should be written:
226
-
227
- Foo::Bar.baz
222
+ Foo::Bar.baz
228
223
 
229
224
  Some examples:
230
-
231
225
  A simple class reference:
232
-
233
226
  @Fancy@
234
227
 
235
228
  Nested class reference:
236
-
237
229
  @Fancy::FDoc@
238
230
 
239
231
  A fancy method without arguments:
240
-
241
232
  @Fancy::FDoc::JSON#:generate_map@
242
233
 
243
234
  A ruby method reference (will link to ruby docs if available)
244
-
245
235
  @String#split@
246
236
 
247
237
  A fancy method with many arguments:
248
-
249
238
  @Fancy::Package::Installer#initialize:version:install_path:@
250
239
 
251
240
  A singleton method:
252
-
253
241
  @Fancy::FDoc::Formatter~format:@
254
-
255
242
  """
256
243
  str gsub(/@[A-Z][^\r\n\s]+?@/) |cstr| {
257
244
  names = cstr slice(1, cstr size() - 2) split("::")
@@ -319,7 +306,7 @@ class Fancy FDoc {
319
306
  }
320
307
 
321
308
  def self create_code: str {
322
- str gsub(/@([^\s,\]\)\}\.]+)/,
309
+ str gsub(/@([^\s,\]\)\{\}\.]+)/,
323
310
  "<code data-lang=\"fancy\">\\1</code>")
324
311
  }
325
312
 
@@ -6,17 +6,11 @@ class Fiber {
6
6
  There is no preemptive scheduler.
7
7
  """
8
8
 
9
- def sleep: seconds {
10
- @sleep_end = Time now + seconds
11
- }
12
-
13
- def asleep? {
14
- if: @sleep_end then: {
15
- Time now < @sleep_end
16
- }
17
- }
18
-
19
9
  def Fiber name {
20
10
  "Fiber"
21
11
  }
12
+
13
+ def Fiber inspect {
14
+ name
15
+ }
22
16
  }
@@ -4,33 +4,29 @@ class File {
4
4
  system on which Fancy is running.
5
5
  """
6
6
 
7
- # def self exists?: filename {
8
- # "Indicates, if a File exists with a given filename."
9
- # try {
10
- # f = File open: filename modes: ['read]
11
- # f close
12
- # true
13
- # } catch IOError => e {
14
- # nil
15
- # }
16
- # }
17
-
18
- def self read: filename {
19
- """
20
- Reads all the contens (in ASCII mode) of a given file and returns
21
- them as an Array of lines being read.
22
- """
23
-
24
- lines = []
25
- File open: filename modes: ['read] with: |f| {
26
- { f eof? } while_false: {
27
- lines << (f readln)
28
- }
29
- }
30
- lines join
7
+ def File write: filename with: block {
8
+ """
9
+ @filename Filename of @File@ to write to.
10
+ @block @Block@ called with a @File@ object to write to.
11
+
12
+ Opens a @File@ for writing and calls @block with it.
13
+ """
14
+
15
+ File open: filename modes: ['write] with: block
31
16
  }
32
17
 
33
- def self touch: filename {
18
+ def File read: filename with: block {
19
+ """
20
+ @filename Filename of @File@ to read from.
21
+ @block @Block@ called with a @File@ object to read from.
22
+
23
+ Opens a @File@ for reading and calls @block with it.
24
+ """
25
+
26
+ File open: filename modes: ['read] with: block
27
+ }
28
+
29
+ def File touch: filename {
34
30
  """
35
31
  @filename Name of @File@ to be created, if not already existant.
36
32
 
@@ -55,4 +51,16 @@ class File {
55
51
 
56
52
  alias_method: 'print: for: 'write:
57
53
  alias_method: 'println: for: 'writeln:
54
+
55
+ def expanded_path {
56
+ """
57
+ @return Expanded (absolute) path of @self.
58
+
59
+ Example:
60
+ f = File open: \"README.txt\"
61
+ f expanded_path # => \"/path/to/README.txt\" (when run from /path/to/)
62
+ """
63
+
64
+ File expand_path: path
65
+ }
58
66
  }