fancy 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +2 -0
- data/README.md +6 -1
- data/bin/fancy +6 -0
- data/bin/ifancy +44 -3
- data/boot/fancy_ext/module.rb +4 -0
- data/boot/fancy_ext/object.rb +4 -0
- data/boot/rbx-compiler/compiler/ast/block.rb +29 -1
- data/boot/rbx-compiler/compiler/ast/identifier.rb +6 -0
- data/boot/rbx-compiler/compiler/ast/message_send.rb +1 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/lexer.lex +2 -0
- data/boot/rbx-compiler/parser/parser.rb +6 -0
- data/boot/rbx-compiler/parser/parser.y +14 -1
- data/doc/api/fancy.jsonp +1 -1
- data/doc/features.md +24 -0
- data/examples/99bottles.fy +5 -0
- data/examples/conditions_exceptions.fy +9 -0
- data/examples/conditions_parsing.fy +68 -0
- data/examples/greeter.fy +9 -0
- data/examples/html_generator.fy +59 -29
- data/examples/webserver/webserver.fy +8 -11
- data/lib/argv.fy +6 -0
- data/lib/array.fy +17 -35
- data/lib/block.fy +82 -1
- data/lib/boot.fy +4 -2
- data/lib/compiler.fy +2 -2
- data/lib/compiler/ast/block.fy +24 -20
- data/lib/compiler/ast/message_send.fy +11 -0
- data/lib/contracts.fy +60 -0
- data/lib/dynamic_slot_object.fy +61 -0
- data/lib/enumerable.fy +432 -394
- data/lib/enumerator.fy +152 -150
- data/lib/fdoc.fy +4 -17
- data/lib/fiber.fy +4 -10
- data/lib/file.fy +33 -25
- data/lib/future.fy +59 -5
- data/lib/hash.fy +54 -1
- data/lib/html.fy +107 -0
- data/lib/kvo.fy +173 -0
- data/lib/main.fy +6 -2
- data/lib/message_sink.fy +19 -0
- data/lib/number.fy +48 -0
- data/lib/object.fy +65 -13
- data/lib/package.fy +12 -2
- data/lib/package/dependency.fy +13 -0
- data/lib/package/dependency_installer.fy +27 -0
- data/lib/package/installer.fy +4 -10
- data/lib/package/uninstaller.fy +1 -3
- data/lib/parser/ext/lexer.lex +8 -3
- data/lib/parser/ext/parser.y +4 -1
- data/lib/parser/methods.fy +7 -3
- data/lib/range.fy +1 -1
- data/lib/rbx.fy +2 -1
- data/lib/rbx/array.fy +28 -12
- data/lib/rbx/bignum.fy +1 -1
- data/lib/rbx/block.fy +27 -0
- data/lib/rbx/console.fy +6 -6
- data/lib/rbx/date.fy +6 -1
- data/lib/rbx/documentation.fy +8 -3
- data/lib/rbx/exception.fy +5 -0
- data/lib/rbx/file.fy +40 -7
- data/lib/rbx/fixnum.fy +12 -1
- data/lib/rbx/method.fy +9 -2
- data/lib/rbx/module.fy +24 -0
- data/lib/rbx/regexp.fy +8 -0
- data/lib/rbx/string.fy +23 -7
- data/lib/rbx/tcp_server.fy +4 -2
- data/lib/rbx/tcp_socket.fy +14 -0
- data/lib/remote_object.fy +59 -0
- data/lib/set.fy +15 -4
- data/lib/string.fy +38 -5
- data/lib/stringio.fy +1 -0
- data/lib/symbol.fy +4 -0
- data/lib/system.fy +22 -0
- data/lib/thread_pool.fy +2 -2
- data/lib/tuple.fy +18 -1
- data/lib/vars.fy +17 -0
- data/lib/version.fy +1 -1
- data/ruby_lib/fancy +6 -0
- data/tests/array.fy +30 -0
- data/tests/block.fy +106 -0
- data/tests/class.fy +19 -0
- data/tests/enumerable.fy +1 -1
- data/tests/enumerator.fy +5 -5
- data/tests/file.fy +28 -0
- data/tests/fixnum.fy +0 -50
- data/tests/future.fy +9 -24
- data/tests/hash.fy +35 -0
- data/tests/html.fy +33 -0
- data/tests/kvo.fy +101 -0
- data/tests/number.fy +75 -0
- data/tests/object.fy +50 -3
- data/tests/string.fy +19 -10
- data/tests/symbol.fy +5 -0
- data/tests/tuple.fy +7 -0
- data/tools/fancy-mode.el +5 -1
- metadata +22 -21
- data/boot/compiler/parser/ext/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/Makefile +0 -156
- data/boot/rbx-compiler/parser/lexer.c +0 -2310
- data/boot/rbx-compiler/parser/lexer.h +0 -315
- data/boot/rbx-compiler/parser/parser.c +0 -2946
- data/boot/rbx-compiler/parser/parser.h +0 -151
- data/lib/fiber_pool.fy +0 -78
- data/lib/method.fy +0 -6
- data/lib/parser/ext/Makefile +0 -156
- data/lib/parser/ext/fancy_parser.bundle +0 -0
- data/lib/parser/ext/lexer.c +0 -2392
- data/lib/parser/ext/lexer.h +0 -315
- data/lib/parser/ext/parser.c +0 -3251
- data/lib/parser/ext/parser.h +0 -161
data/lib/range.fy
CHANGED
data/lib/rbx.fy
CHANGED
@@ -25,8 +25,8 @@ require: "rbx/system"
|
|
25
25
|
require: "rbx/exception"
|
26
26
|
require: "rbx/io"
|
27
27
|
require: "rbx/file"
|
28
|
-
require: "rbx/tcp_server"
|
29
28
|
require: "rbx/tcp_socket"
|
29
|
+
require: "rbx/tcp_server"
|
30
30
|
require: "rbx/match_data"
|
31
31
|
require: "rbx/regexp"
|
32
32
|
require: "rbx/directory"
|
@@ -40,3 +40,4 @@ require: "rbx/date"
|
|
40
40
|
require: "rbx/time"
|
41
41
|
require: "rbx/actor"
|
42
42
|
require: "rbx/mutex"
|
43
|
+
require: "rbx/module"
|
data/lib/rbx/array.fy
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
class Array {
|
2
|
-
ruby_aliases: [ '==, '<<, 'pop, 'last, 'shift ]
|
2
|
+
ruby_aliases: [ '==, '<<, 'pop, 'last, 'shift, 'flatten ]
|
3
3
|
|
4
4
|
forwards_unary_ruby_methods
|
5
5
|
|
6
6
|
def Array new: size with: default {
|
7
|
-
"
|
7
|
+
"""
|
8
|
+
Creates a new Array with a given size and default-value.
|
9
|
+
If @default is a @Block@, call that block for each element instead.
|
10
|
+
"""
|
8
11
|
|
9
|
-
|
12
|
+
match default {
|
13
|
+
case Block -> Array new(size, &default)
|
14
|
+
case _ -> Array new(size, default)
|
15
|
+
}
|
10
16
|
}
|
11
17
|
|
12
18
|
def includes?: obj {
|
@@ -32,16 +38,14 @@ class Array {
|
|
32
38
|
delete_at(index)
|
33
39
|
return deleted
|
34
40
|
} else: {
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
count = count + 1
|
42
|
-
}
|
43
|
-
return deleted_values
|
41
|
+
count = 0
|
42
|
+
deleted_values = []
|
43
|
+
index each: |idx| {
|
44
|
+
deleted_values << (at: (idx - count))
|
45
|
+
delete_at(idx - count)
|
46
|
+
count = count + 1
|
44
47
|
}
|
48
|
+
return deleted_values
|
45
49
|
}
|
46
50
|
nil
|
47
51
|
}
|
@@ -106,6 +110,18 @@ class Array {
|
|
106
110
|
}
|
107
111
|
|
108
112
|
def unshift: value {
|
113
|
+
"""
|
114
|
+
@value Value to be added at the front of @self.
|
115
|
+
@return @self.
|
116
|
+
|
117
|
+
Inserts a value at the front of @self.
|
118
|
+
|
119
|
+
Example:
|
120
|
+
a = [1,2,3]
|
121
|
+
a unshift: 10
|
122
|
+
a # => [10,1,2,3]
|
123
|
+
"""
|
124
|
+
|
109
125
|
unshift(value)
|
110
126
|
}
|
111
127
|
}
|
data/lib/rbx/bignum.fy
CHANGED
data/lib/rbx/block.fy
CHANGED
@@ -50,6 +50,19 @@ class Block {
|
|
50
50
|
# Ugh. HACK.
|
51
51
|
# Use try/catch to deal with older and latest version of rbx (method got changed)
|
52
52
|
def call_with_receiver: receiver {
|
53
|
+
"""
|
54
|
+
@receiver Receiver (value of @self) when calling the @Block@.
|
55
|
+
|
56
|
+
Calls a @Block@ with @receiver as the receiver (referenced by @self within the Block).
|
57
|
+
|
58
|
+
Example:
|
59
|
+
r1 = [1,2,3]
|
60
|
+
r2 = \"hello world\"
|
61
|
+
b = { self class }
|
62
|
+
b call_with_receiver: r1 # => Array
|
63
|
+
b call_with_receiver: r2 # => String
|
64
|
+
"""
|
65
|
+
|
53
66
|
try {
|
54
67
|
return call_under(receiver, method() scope())
|
55
68
|
} catch {
|
@@ -58,6 +71,20 @@ class Block {
|
|
58
71
|
}
|
59
72
|
|
60
73
|
def call: args with_receiver: receiver {
|
74
|
+
"""
|
75
|
+
@args @Array@ of arguments passed to @self for invocation.
|
76
|
+
@receiver Receiver (value of @self) when calling the @Block@.
|
77
|
+
|
78
|
+
Same as @call_with_receiver: but passing along arguments to the @Block@.
|
79
|
+
|
80
|
+
Example:
|
81
|
+
r1 = [1,2,3]
|
82
|
+
r2 = \"hello world\"
|
83
|
+
b = |arg| { self to_s + arg }
|
84
|
+
b call: [\"foo\"] with_receiver: r1 # => \"123foo\"
|
85
|
+
b call: [\"foo\"] with_receiver: r2 # => \"hello worldfoo\"
|
86
|
+
"""
|
87
|
+
|
61
88
|
try {
|
62
89
|
return call_under(receiver, method() scope(), *args)
|
63
90
|
} catch {
|
data/lib/rbx/console.fy
CHANGED
@@ -38,11 +38,7 @@ class Console {
|
|
38
38
|
"""
|
39
39
|
|
40
40
|
Console print: message
|
41
|
-
|
42
|
-
nil
|
43
|
-
} else: {
|
44
|
-
STDIN gets() chomp
|
45
|
-
}
|
41
|
+
Console readln
|
46
42
|
}
|
47
43
|
|
48
44
|
def Console readln {
|
@@ -52,7 +48,11 @@ class Console {
|
|
52
48
|
Reads a line from @STDIN and returns it as a @String@.
|
53
49
|
"""
|
54
50
|
|
55
|
-
STDIN
|
51
|
+
if: (STDIN eof?) then: {
|
52
|
+
nil
|
53
|
+
} else: {
|
54
|
+
STDIN gets() chomp
|
55
|
+
}
|
56
56
|
}
|
57
57
|
|
58
58
|
def Console clear {
|
data/lib/rbx/date.fy
CHANGED
@@ -9,9 +9,14 @@ class Date {
|
|
9
9
|
metaclass forwards_unary_ruby_methods
|
10
10
|
|
11
11
|
metaclass ruby_alias: 'today
|
12
|
-
ruby_aliases: [ '==, '-, '+, '<, '
|
12
|
+
ruby_aliases: [ '==, '-, '+, '<, '>, 'cwday, 'wday ]
|
13
13
|
|
14
14
|
def != other {
|
15
|
+
"""
|
16
|
+
@other Other @Date@ to compare to.
|
17
|
+
@return @true if equal, @false otherwhise.
|
18
|
+
"""
|
19
|
+
|
15
20
|
self == other not
|
16
21
|
}
|
17
22
|
}
|
data/lib/rbx/documentation.fy
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
class Fancy {}
|
3
3
|
|
4
4
|
class Fancy Documentation {
|
5
|
-
|
6
5
|
def initialize: docstring {
|
7
6
|
@docs = [docstring]
|
8
7
|
}
|
@@ -42,6 +41,14 @@ class Fancy Documentation {
|
|
42
41
|
doc
|
43
42
|
}
|
44
43
|
|
44
|
+
def self for_method: method_name on_class: class is: docstring {
|
45
|
+
"""
|
46
|
+
Similar to @Fancy::Documentation##for:is:@ but taking the method name and the @Class@ for which @Method@ to define the docstring.
|
47
|
+
"""
|
48
|
+
|
49
|
+
class instance_method: method_name . documentation: docstring
|
50
|
+
}
|
51
|
+
|
45
52
|
for: (instance_method('initialize:)) is: "Create a new documentation object."
|
46
53
|
for: (method('for:is:)) is: "Sets the documentation for obj."
|
47
54
|
|
@@ -59,6 +66,4 @@ class Fancy Documentation {
|
|
59
66
|
"Append docstring to docs."
|
60
67
|
for: obj is: docstring
|
61
68
|
}
|
62
|
-
|
63
69
|
}
|
64
|
-
|
data/lib/rbx/exception.fy
CHANGED
data/lib/rbx/file.fy
CHANGED
@@ -8,6 +8,9 @@ class File {
|
|
8
8
|
'truncate => "w+"]>
|
9
9
|
|
10
10
|
ruby_aliases: [ 'eof?, 'closed?, 'flush ]
|
11
|
+
metaclass alias_method: 'expand_path: for_ruby: 'expand_path
|
12
|
+
|
13
|
+
forwards_unary_ruby_methods
|
11
14
|
|
12
15
|
def File open: filename modes: modes_arr with: block {
|
13
16
|
"""
|
@@ -46,16 +49,30 @@ class File {
|
|
46
49
|
File exists?(filename)
|
47
50
|
}
|
48
51
|
|
49
|
-
def
|
52
|
+
def File read: filename {
|
50
53
|
"""
|
51
|
-
|
54
|
+
@filename @String@ containing the path of the File to be read.
|
55
|
+
@return Contents of the File as a @String@.
|
56
|
+
|
57
|
+
Reads all the contens (in ASCII mode) of a given file and returns
|
58
|
+
them as an Array of lines being read.
|
52
59
|
"""
|
53
60
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
61
|
+
File read(filename)
|
62
|
+
}
|
63
|
+
|
64
|
+
def File read: filename length: length offset: offset (0) {
|
65
|
+
"""
|
66
|
+
@filename @String@ containing the path of the File to be read.
|
67
|
+
@length @Fixnum@ being the maximum length to read from the File.
|
68
|
+
@offset @Fixnum@ being the offset in bytes to start reading from the File.
|
69
|
+
@return Contents of the File as a @String@.
|
70
|
+
|
71
|
+
Reads all the contens (in ASCII mode) of a given file, length and offset
|
72
|
+
and returns them as an Array of lines being read.
|
73
|
+
"""
|
74
|
+
|
75
|
+
File read(filename, length, offset)
|
59
76
|
}
|
60
77
|
|
61
78
|
def File open: filename modes: modes_arr {
|
@@ -131,6 +148,22 @@ class File {
|
|
131
148
|
File rename(old_name, new_name)
|
132
149
|
}
|
133
150
|
|
151
|
+
def initialize: path {
|
152
|
+
initialize(path)
|
153
|
+
}
|
154
|
+
|
155
|
+
def close {
|
156
|
+
"""
|
157
|
+
Closes an opened @File@.
|
158
|
+
"""
|
159
|
+
|
160
|
+
try {
|
161
|
+
close()
|
162
|
+
} catch Errno::ENOENT => e {
|
163
|
+
IOError new: (e message) . raise!
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
134
167
|
def modes {
|
135
168
|
"""
|
136
169
|
@return @File@ access modes @Array@.
|
data/lib/rbx/fixnum.fy
CHANGED
@@ -9,11 +9,22 @@ class Fixnum {
|
|
9
9
|
|
10
10
|
ruby_aliases: [
|
11
11
|
'==, '-, '+, '*, '/, '<, '>, '<=, '>=,
|
12
|
-
'===, 'chr, 'to_i, 'to_f, '**, '&, '
|
12
|
+
'===, 'chr, 'to_i, 'to_f, '**, '&, '|,
|
13
|
+
'<<, '>>
|
13
14
|
]
|
14
15
|
|
15
16
|
alias_method: 'to_s: for: 'to_s
|
16
17
|
alias_method: 'modulo: for: 'modulo
|
17
18
|
alias_method: ":%" for: "modulo:" # use a : so we dont overwrite ruby's % operator
|
18
19
|
alias_method: 'div: for: 'div
|
20
|
+
|
21
|
+
def random {
|
22
|
+
"""
|
23
|
+
@return Random number between 0 and @self.
|
24
|
+
|
25
|
+
Returns a random number between 0 and @self.
|
26
|
+
"""
|
27
|
+
|
28
|
+
rand(self)
|
29
|
+
}
|
19
30
|
}
|
data/lib/rbx/method.fy
CHANGED
@@ -8,7 +8,7 @@ class MethodMixin {
|
|
8
8
|
@return Docstring for @self.
|
9
9
|
"""
|
10
10
|
|
11
|
-
Fancy Documentation for:
|
11
|
+
Fancy Documentation for: executable
|
12
12
|
}
|
13
13
|
|
14
14
|
def documentation: docstring {
|
@@ -16,7 +16,7 @@ class MethodMixin {
|
|
16
16
|
@docstring New docstring for @self.
|
17
17
|
"""
|
18
18
|
|
19
|
-
Fancy Documentation for:
|
19
|
+
Fancy Documentation for: executable is: docstring
|
20
20
|
}
|
21
21
|
|
22
22
|
def visibility {
|
@@ -66,7 +66,13 @@ class MethodMixin {
|
|
66
66
|
}
|
67
67
|
|
68
68
|
class Method {
|
69
|
+
"""
|
70
|
+
An instance of Method represents a method on a Class.
|
71
|
+
Every method in Fancy is an instance of the Method class.
|
72
|
+
"""
|
73
|
+
|
69
74
|
ruby_alias: 'arity
|
75
|
+
ruby_alias: 'executable
|
70
76
|
include: MethodMixin
|
71
77
|
forwards_unary_ruby_methods
|
72
78
|
}
|
@@ -77,6 +83,7 @@ class UnboundMethod {
|
|
77
83
|
"""
|
78
84
|
|
79
85
|
ruby_alias: 'arity
|
86
|
+
ruby_alias: 'executable
|
80
87
|
include: MethodMixin
|
81
88
|
forwards_unary_ruby_methods
|
82
89
|
}
|
data/lib/rbx/module.fy
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class Module {
|
2
|
+
forwards_unary_ruby_methods
|
3
|
+
|
4
|
+
def [constant_name] {
|
5
|
+
"""
|
6
|
+
@constant_name Name (@String@) of constant's name.
|
7
|
+
@return @constant_name's value.
|
8
|
+
|
9
|
+
Returns the value of the constant with the given name in @self.
|
10
|
+
"""
|
11
|
+
|
12
|
+
const_get(constant_name)
|
13
|
+
}
|
14
|
+
|
15
|
+
def included: module {
|
16
|
+
"""
|
17
|
+
@module @Module@ or @Class@ that has been included into @self.
|
18
|
+
Gets called when a @Class@ or @Module@ is included into another @Class@.
|
19
|
+
"""
|
20
|
+
|
21
|
+
# do nothing by default
|
22
|
+
nil
|
23
|
+
}
|
24
|
+
}
|
data/lib/rbx/regexp.fy
CHANGED
data/lib/rbx/string.fy
CHANGED
@@ -6,20 +6,25 @@ class String {
|
|
6
6
|
'chomp, 'inspect, 'to_sym, '<, '>
|
7
7
|
]
|
8
8
|
|
9
|
+
alias_method: 'ruby_idx: for_ruby: '[]
|
9
10
|
alias_method: '[]: for_ruby: '[]=
|
10
11
|
alias_method: 'scan: for_ruby: 'scan
|
12
|
+
alias_method: 'uppercase for: 'upcase
|
13
|
+
alias_method: 'lowercase for: 'downcase
|
11
14
|
|
12
15
|
forwards_unary_ruby_methods
|
13
16
|
|
14
17
|
def [index] {
|
15
|
-
"""
|
16
|
-
|
18
|
+
"""
|
19
|
+
Given an Array of 2 Numbers, it returns the substring between the given indices.
|
20
|
+
If given a Number, returns the character at that index.
|
21
|
+
"""
|
17
22
|
|
18
23
|
# if given an Array, interpret it as a from:to: range substring
|
19
|
-
|
20
|
-
from: (index[0]) to: (index[1])
|
21
|
-
|
22
|
-
|
24
|
+
match index {
|
25
|
+
case Array -> from: (index[0]) to: (index[1])
|
26
|
+
case Tuple -> ruby_idx: index
|
27
|
+
case _ -> ruby_idx: index . chr()
|
23
28
|
}
|
24
29
|
}
|
25
30
|
|
@@ -31,7 +36,8 @@ class String {
|
|
31
36
|
|
32
37
|
Returns a Substring from @from to @to.
|
33
38
|
"""
|
34
|
-
|
39
|
+
|
40
|
+
ruby_idx: (from .. to)
|
35
41
|
}
|
36
42
|
|
37
43
|
def each: block {
|
@@ -146,4 +152,14 @@ class String {
|
|
146
152
|
|
147
153
|
include?(substring)
|
148
154
|
}
|
155
|
+
|
156
|
+
def substitute: substring with: substitution {
|
157
|
+
"""
|
158
|
+
@substring @String@ or @Regexp@ to be substituted.
|
159
|
+
@substitution @String@ to replace @substring with.
|
160
|
+
@return A new @String@ where @substring is substituted by @substitution.
|
161
|
+
"""
|
162
|
+
|
163
|
+
gsub(substring, substitution)
|
164
|
+
}
|
149
165
|
}
|