fancy 0.5.0 → 0.6.0

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