fancy 0.7.0 → 0.8.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.
- data/README.md +38 -86
- data/bin/fdoc +2 -22
- data/bin/fspec +8 -3
- data/bin/ifancy +1 -1
- data/boot/fancy_ext.rb +1 -0
- data/boot/fancy_ext/array.rb +19 -0
- data/boot/fancy_ext/class.rb +2 -4
- data/boot/fancy_ext/module.rb +2 -0
- data/boot/fancy_ext/object.rb +0 -17
- data/boot/rbx-compiler/compiler/ast/method_def.rb +0 -4
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +0 -7
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/fancy_parser.c +1 -0
- data/doc/api/fancy.css +10 -1
- data/doc/api/fancy.jsonp +1 -1
- data/doc/api/fdoc.js +22 -9
- data/doc/api/octocat.png +0 -0
- data/doc/features.md +1 -2
- data/examples/actors.fy +1 -2
- data/examples/armstrong_numbers.fy +7 -3
- data/examples/blocks.fy +3 -3
- data/examples/distributing_proxy.fy +31 -0
- data/examples/future_sends.fy +15 -0
- data/examples/person.fy +1 -2
- data/lib/argv.fy +1 -7
- data/lib/array.fy +7 -11
- data/lib/block.fy +15 -0
- data/lib/boot.fy +4 -3
- data/lib/class.fy +354 -10
- data/lib/compiler.fy +1 -1
- data/lib/compiler/ast/assign.fy +4 -8
- data/lib/compiler/ast/async_send.fy +1 -2
- data/lib/compiler/ast/block.fy +5 -0
- data/lib/compiler/ast/class_def.fy +2 -1
- data/lib/compiler/ast/expression_list.fy +1 -2
- data/lib/compiler/ast/future_send.fy +1 -2
- data/lib/compiler/ast/identifier.fy +34 -17
- data/lib/compiler/ast/literals.fy +31 -19
- data/lib/compiler/ast/match.fy +5 -4
- data/lib/compiler/ast/message_send.fy +3 -5
- data/lib/compiler/ast/method_def.fy +0 -3
- data/lib/compiler/ast/range.fy +2 -4
- data/lib/compiler/ast/return.fy +2 -4
- data/lib/compiler/ast/script.fy +2 -4
- data/lib/compiler/ast/singleton_method_def.fy +0 -3
- data/lib/compiler/ast/string_interpolation.fy +2 -2
- data/lib/compiler/ast/super.fy +2 -4
- data/lib/compiler/ast/try_catch.fy +13 -9
- data/lib/compiler/ast/tuple_literal.fy +1 -2
- data/lib/compiler/compiler.fy +2 -2
- data/lib/compiler/stages.fy +3 -6
- data/lib/contracts.fy +89 -57
- data/lib/dynamic_slot_object.fy +21 -3
- data/lib/enumerable.fy +140 -4
- data/lib/enumerator.fy +1 -1
- data/lib/eval.fy +23 -9
- data/lib/exception.fy +16 -0
- data/lib/false_class.fy +36 -5
- data/lib/fancy_spec.fy +64 -34
- data/lib/fdoc.fy +85 -24
- data/lib/file.fy +19 -0
- data/lib/future.fy +4 -46
- data/lib/hash.fy +113 -0
- data/lib/integer.fy +25 -6
- data/lib/iteration.fy +3 -3
- data/lib/main.fy +5 -0
- data/lib/matchers.fy +79 -0
- data/lib/nil_class.fy +8 -0
- data/lib/object.fy +109 -18
- data/lib/option_parser.fy +118 -0
- data/lib/package/dependency.fy +4 -8
- data/lib/package/dependency_installer.fy +1 -1
- data/lib/package/handler.fy +6 -0
- data/lib/package/installer.fy +43 -16
- data/lib/package/list.fy +1 -2
- data/lib/package/specification.fy +5 -5
- data/lib/package/uninstaller.fy +9 -2
- data/lib/parser.fy +1 -3
- data/lib/parser/ext/ext.c +1 -0
- data/lib/parser/ext/lexer.lex +5 -0
- data/lib/parser/methods.fy +48 -46
- data/lib/proxies.fy +151 -0
- data/lib/rbx.fy +1 -0
- data/lib/rbx/actor.fy +16 -18
- data/lib/rbx/array.fy +18 -3
- data/lib/rbx/block.fy +1 -7
- data/lib/rbx/class.fy +54 -9
- data/lib/rbx/code_loader.fy +2 -5
- data/lib/rbx/compiled_method.fy +31 -0
- data/lib/rbx/debugger.fy +66 -0
- data/lib/rbx/directory.fy +8 -3
- data/lib/rbx/documentation.fy +1 -1
- data/lib/rbx/file.fy +22 -0
- data/lib/rbx/integer.fy +1 -1
- data/lib/rbx/match_data.fy +2 -1
- data/lib/rbx/method.fy +26 -0
- data/lib/rbx/object.fy +8 -3
- data/lib/rbx/regexp.fy +6 -3
- data/lib/rbx/string.fy +9 -1
- data/lib/rbx/stringio.fy +12 -0
- data/lib/rbx/symbol.fy +4 -0
- data/lib/stack.fy +1 -1
- data/lib/string.fy +34 -0
- data/lib/stringio.fy +1 -1
- data/lib/symbol.fy +6 -2
- data/lib/system.fy +15 -1
- data/lib/tuple.fy +5 -2
- data/lib/version.fy +1 -1
- data/ruby_lib/fdoc +2 -22
- data/tests/array.fy +3 -17
- data/tests/class.fy +312 -10
- data/tests/contracts.fy +51 -0
- data/tests/distributing_proxy.fy +28 -0
- data/tests/enumerable.fy +104 -1
- data/tests/exception.fy +35 -0
- data/tests/fixnum.fy +1 -1
- data/tests/hash.fy +81 -1
- data/tests/integer.fy +9 -0
- data/tests/matchers.fy +18 -0
- data/tests/method.fy +8 -14
- data/tests/object.fy +76 -2
- data/tests/option_parser.fy +80 -0
- data/tests/string.fy +21 -0
- data/tests/stringio.fy +1 -1
- data/tests/tuple.fy +1 -1
- metadata +21 -44
- data/examples/arithmetic.fy +0 -7
- data/examples/array.fy +0 -50
- data/examples/boolean.fy +0 -24
- data/examples/class.fy +0 -68
- data/examples/constant_access.fy +0 -15
- data/examples/default_args.fy +0 -20
- data/examples/define_methods.fy +0 -15
- data/examples/dynamic_output.fy +0 -15
- data/examples/empty_catch.fy +0 -4
- data/examples/exception.fy +0 -9
- data/examples/files.fy +0 -23
- data/examples/finally.fy +0 -5
- data/examples/future.fy +0 -30
- data/examples/future_composition.fy +0 -20
- data/examples/futures.fy +0 -9
- data/examples/game_of_life.fy +0 -148
- data/examples/html_generator.fy +0 -84
- data/examples/implicit_return.fy +0 -3
- data/examples/matchers.fy +0 -6
- data/examples/nested_try.fy +0 -9
- data/examples/numbers.fy +0 -12
- data/examples/rbx/and_or.fy +0 -7
- data/examples/rbx/blocks.fy +0 -22
- data/examples/rbx/classes.fy +0 -32
- data/examples/rbx/hello.fy +0 -8
- data/examples/rbx/include.fy +0 -12
- data/examples/rbx/inherit.fy +0 -11
- data/examples/rbx/methods.fy +0 -15
- data/examples/rbx/nested_classes.fy +0 -9
- data/examples/rbx/require.fy +0 -3
- data/examples/rbx/strings.fy +0 -5
- data/examples/require.fy +0 -7
- data/examples/return.fy +0 -13
- data/examples/singleton_methods.fy +0 -21
- data/examples/threads.fy +0 -18
- data/examples/tuple.fy +0 -8
- data/examples/webserver/webserver.fy +0 -15
- data/lib/proxy.fy +0 -86
- data/lib/thread_pool.fy +0 -102
data/lib/proxies.fy
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
class Proxies {
|
|
2
|
+
class ProxyReceiver : Fancy BasicObject {
|
|
3
|
+
"""
|
|
4
|
+
A ProxyReceiver is an object which proxies all message sends to it to 2 other objects.
|
|
5
|
+
It will send each message first to its @proxy instance variable and then to the @obj instance variable.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
def initialize: @proxy for: @obj {
|
|
9
|
+
"""
|
|
10
|
+
@proxy Proxy receiver for @obj.
|
|
11
|
+
@obj Original receiver object.
|
|
12
|
+
|
|
13
|
+
Initializes a new ProxyReceiver with @proxy for @obj.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
self
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def unknown_message: msg with_params: params {
|
|
20
|
+
"""
|
|
21
|
+
@msg Incoming message name.
|
|
22
|
+
@params Paremeters of incoming message send.
|
|
23
|
+
|
|
24
|
+
Forwards all incoming messages to @self to @@proxy and then @@obj.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
@proxy receive_message: msg with_params: params
|
|
28
|
+
@obj receive_message: msg with_params: params
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Proxy = ProxyReceiver
|
|
33
|
+
|
|
34
|
+
class RespondsToProxy : Fancy BasicObject {
|
|
35
|
+
"""
|
|
36
|
+
A RespondsToProxy is a Proxy that forwards any message sent to it to it's @target instance variable
|
|
37
|
+
only if it responds to that message. Any messages that @target doesn't respond to simply won't be sent
|
|
38
|
+
and @nil will be returned.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def initialize: @target {
|
|
42
|
+
"""
|
|
43
|
+
@target Target receiver object.
|
|
44
|
+
|
|
45
|
+
Initializes a new RespondsToProxy for @target.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
self
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
def unknown_message: msg with_params: params {
|
|
52
|
+
"""
|
|
53
|
+
@msg Incoming message name.
|
|
54
|
+
@params Paremeters of incoming message send.
|
|
55
|
+
|
|
56
|
+
Forwards all incoming message to @self to @@target
|
|
57
|
+
only if @@target responds to them.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
if: (@target responds_to?: msg) then: {
|
|
61
|
+
@target receive_message: msg with_params: params
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
class ActorProxy : Fancy BasicObject {
|
|
67
|
+
"""
|
|
68
|
+
An ActorProxy is a Proxy that forwards any message sent to it to
|
|
69
|
+
it's @target object as a future send by default. If explicitly sent
|
|
70
|
+
an async message, it will forward the async send to @target,
|
|
71
|
+
returning @nil instead of a @FutureSend@, as expected.
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
ap = ActorProxy new: target_actor
|
|
75
|
+
|
|
76
|
+
# this:
|
|
77
|
+
f = ap some_future_send: an_arg
|
|
78
|
+
# is the same as:
|
|
79
|
+
f = target_actor @ some_future_send: an_arg
|
|
80
|
+
|
|
81
|
+
# and this:
|
|
82
|
+
ap @@ some_async_send: another_arg
|
|
83
|
+
# is the same as:
|
|
84
|
+
target_actor @@ some_async_send: another_arg
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
def initialize: @target
|
|
88
|
+
|
|
89
|
+
def send_future: m with_params: p {
|
|
90
|
+
@target send_future: m with_params: p
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
def send_async: m with_params: p {
|
|
94
|
+
@target send_async: m with_params: p
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
def unknown_message: m with_params: p {
|
|
98
|
+
@target send_future: m with_params: p
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
class DistributingProxy : Fancy BasicObject {
|
|
103
|
+
"""
|
|
104
|
+
DistributingProxy is a Proxy that round-robin distributes messages to objects
|
|
105
|
+
in a @Fancy::Enumerable@ specified upon creation.
|
|
106
|
+
|
|
107
|
+
Example:
|
|
108
|
+
p = DistributingProxy new: [worker1, worker2, worker3, worker4]
|
|
109
|
+
loop: {
|
|
110
|
+
req = @input receive_request
|
|
111
|
+
p handle_request: req # will be forwarded to worker1-4
|
|
112
|
+
}
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
def initialize {
|
|
116
|
+
ArgumentError raise: "Missing list of proxy targets"
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
def initialize: @targets {
|
|
120
|
+
@free = @targets to_a dup
|
|
121
|
+
@mutex = Mutex new
|
|
122
|
+
@waiting = ConditionVariable new
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
def __with_target__: block {
|
|
126
|
+
t = @mutex synchronize: {
|
|
127
|
+
{ @waiting wait: @mutex } until: { @free empty? not }
|
|
128
|
+
@free shift
|
|
129
|
+
}
|
|
130
|
+
val = block call: [t]
|
|
131
|
+
@mutex synchronize: { @free << t; @waiting broadcast }
|
|
132
|
+
val
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
instance_methods reject: /^(:initialize|initialize:|__with_target__:|unknown_message:with_params:|send_async:with_params:|send_future:with_params:|__send__)$/ . each: |m| {
|
|
136
|
+
undef_method(m)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
def unknown_message: m with_params: p {
|
|
140
|
+
__with_target__: @{ receive_message: m with_params: p }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
def send_async: m with_params: p {
|
|
144
|
+
__with_target__: @{ send_async: m with_params: p }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
def send_future: m with_params: p {
|
|
148
|
+
__with_target__: @{ send_future: m with_params: p }
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
data/lib/rbx.fy
CHANGED
data/lib/rbx/actor.fy
CHANGED
|
@@ -8,25 +8,24 @@ class Actor {
|
|
|
8
8
|
first-come, first-serve manner.
|
|
9
9
|
|
|
10
10
|
Actors are used to implement asynchronous and future message sends in Fancy
|
|
11
|
-
using the
|
|
12
|
-
|
|
13
|
-
Example
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
using the @ and @@ syntax.
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
a = Actor spawn: {
|
|
15
|
+
loop: {
|
|
16
|
+
match Actor receive {
|
|
17
|
+
case 'hello -> \"Hello World\" println
|
|
18
|
+
case 'quit ->
|
|
19
|
+
\"OK, done!\" println
|
|
20
|
+
break # Quit loop and let actor die
|
|
21
|
+
}
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
}
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
10 times: {
|
|
26
|
+
a ! 'hello # send 'hello to actor asynchronously
|
|
27
|
+
}
|
|
28
|
+
a ! 'quit
|
|
30
29
|
"""
|
|
31
30
|
|
|
32
31
|
alias_method(':!, '<<)
|
|
@@ -39,8 +38,7 @@ class Actor {
|
|
|
39
38
|
@block @Block@ that represents the @Actor@'s code body to be executed in a new @Thread@.
|
|
40
39
|
@return A new @Actor@ running @block in a seperate @Thread@.
|
|
41
40
|
|
|
42
|
-
Example
|
|
43
|
-
|
|
41
|
+
Example:
|
|
44
42
|
Actor spawn: {
|
|
45
43
|
loop: {
|
|
46
44
|
Actor receive println # print all incoming messages
|
data/lib/rbx/array.fy
CHANGED
|
@@ -5,8 +5,18 @@ class Array {
|
|
|
5
5
|
|
|
6
6
|
def Array new: size with: default {
|
|
7
7
|
"""
|
|
8
|
+
@size Initial size of @Array@.
|
|
9
|
+
@default Default value of new @Array@. Inserted @size times.
|
|
10
|
+
@return New @Array@ with @size values of @default in it.
|
|
11
|
+
|
|
8
12
|
Creates a new Array with a given size and default-value.
|
|
9
|
-
If @default is a @Block@, call
|
|
13
|
+
If @default is a @Block@, call it with each index instead and
|
|
14
|
+
store the return value.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
Array new: 3 with: 'hello # => ['hello, 'hello, 'hello]
|
|
18
|
+
# default can also be a block, taking the current index.
|
|
19
|
+
Array new: 3 with: @{ * 2 } # => [0, 2, 4]
|
|
10
20
|
"""
|
|
11
21
|
|
|
12
22
|
match default {
|
|
@@ -67,7 +77,7 @@ class Array {
|
|
|
67
77
|
"""
|
|
68
78
|
@idx Index to set a value for.
|
|
69
79
|
@obj Value (object) to be set at the given index.
|
|
70
|
-
@return @obj
|
|
80
|
+
@return @obj.
|
|
71
81
|
|
|
72
82
|
Inserts a given object at a given index (position) in the Array.
|
|
73
83
|
"""
|
|
@@ -83,8 +93,13 @@ class Array {
|
|
|
83
93
|
@return Index of the value passed in within the @Array@, or @nil, if value not present.
|
|
84
94
|
|
|
85
95
|
Returns the index of an item (or nil, if it isn't in the @Array@).
|
|
96
|
+
If @item is a @Block@, it will return the index of an element for which it yields @true.
|
|
86
97
|
"""
|
|
87
|
-
|
|
98
|
+
|
|
99
|
+
match item {
|
|
100
|
+
case Block -> index(&item)
|
|
101
|
+
case _ -> index(item)
|
|
102
|
+
}
|
|
88
103
|
}
|
|
89
104
|
|
|
90
105
|
def last: count {
|
data/lib/rbx/block.fy
CHANGED
|
@@ -47,8 +47,6 @@ class Block {
|
|
|
47
47
|
@top_scope receiver: recv
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
# Ugh. HACK.
|
|
51
|
-
# Use try/catch to deal with older and latest version of rbx (method got changed)
|
|
52
50
|
def call_with_receiver: receiver {
|
|
53
51
|
"""
|
|
54
52
|
@receiver Receiver (value of @self) when calling the @Block@.
|
|
@@ -63,11 +61,7 @@ class Block {
|
|
|
63
61
|
b call_with_receiver: r2 # => String
|
|
64
62
|
"""
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
return call_under(receiver, method() scope())
|
|
68
|
-
} catch {
|
|
69
|
-
return call_on_instance(receiver)
|
|
70
|
-
}
|
|
64
|
+
call_on_instance(receiver)
|
|
71
65
|
}
|
|
72
66
|
|
|
73
67
|
def call: args with_receiver: receiver {
|
data/lib/rbx/class.fy
CHANGED
|
@@ -3,9 +3,9 @@ class Class {
|
|
|
3
3
|
|
|
4
4
|
def new {
|
|
5
5
|
"""
|
|
6
|
-
@return A new @Class@
|
|
6
|
+
@return A new instance of @Class@ @self.
|
|
7
7
|
|
|
8
|
-
Creates a new
|
|
8
|
+
Creates a new instance of @self calling @initialize.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
obj = allocate()
|
|
@@ -14,16 +14,16 @@ class Class {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
# calls initialize:, if defined
|
|
17
|
-
def new:
|
|
17
|
+
def new: arg {
|
|
18
18
|
"""
|
|
19
|
-
@
|
|
20
|
-
@return A new @Class@
|
|
19
|
+
@arg Argument to @initialize:.
|
|
20
|
+
@return A new instance of @Class@ @self.
|
|
21
21
|
|
|
22
|
-
Creates a new
|
|
22
|
+
Creates a new instance of @self calling @initialize:.
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
25
|
obj = allocate()
|
|
26
|
-
obj initialize:
|
|
26
|
+
obj initialize: arg
|
|
27
27
|
obj
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -63,7 +63,10 @@ class Class {
|
|
|
63
63
|
body.
|
|
64
64
|
"""
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
match block {
|
|
67
|
+
case Block -> define_method(name message_name, &block)
|
|
68
|
+
case _ -> define_method(name message_name, block)
|
|
69
|
+
}
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
def undefine_method: name {
|
|
@@ -130,6 +133,10 @@ class Class {
|
|
|
130
133
|
instance_method(name message_name)
|
|
131
134
|
}
|
|
132
135
|
|
|
136
|
+
def has_method?: method_name {
|
|
137
|
+
lookup_method(method_name message_name) nil? not
|
|
138
|
+
}
|
|
139
|
+
|
|
133
140
|
def alias_method_rbx: new_method_name for: old_method_name {
|
|
134
141
|
"""
|
|
135
142
|
Rbx specific version of alias_method:for: due to bootstrap order
|
|
@@ -215,9 +222,47 @@ class Class {
|
|
|
215
222
|
}
|
|
216
223
|
|
|
217
224
|
def class_eval: str_or_block {
|
|
225
|
+
"""
|
|
226
|
+
@str_or_block @String@ or @Block@ to be evaluated in the context of this @Class@.
|
|
227
|
+
|
|
228
|
+
Evaluates a given @String@ of Fancy code or a @Block@ in the class context of @self.
|
|
229
|
+
Useful for dynamically defining methods on a class etc.
|
|
230
|
+
|
|
231
|
+
Example:
|
|
232
|
+
Array class_eval: \"def foo { 'foo println }\"
|
|
233
|
+
[1,2,3] foo # => prints 'foo
|
|
234
|
+
"""
|
|
235
|
+
|
|
218
236
|
match str_or_block {
|
|
219
237
|
case Block -> class_eval(&str_or_block)
|
|
220
|
-
case _ -> class_eval
|
|
238
|
+
case _ -> class_eval: { str_or_block to_s eval }
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
def expose_to_ruby: method_name as: ruby_method_name (nil) {
|
|
243
|
+
"""
|
|
244
|
+
@method_name Fancy method name to be exposed.
|
|
245
|
+
@ruby_method_name Name of method exposed to Ruby (optional).
|
|
246
|
+
|
|
247
|
+
Explicitly exposes a Fancy method to Ruby. If @ruby_method_name is
|
|
248
|
+
passed, use that name explicitly, otherwise uses @method_name.
|
|
249
|
+
|
|
250
|
+
Example:
|
|
251
|
+
class Foo {
|
|
252
|
+
def === other {
|
|
253
|
+
# ...
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
expose_to_ruby: '===
|
|
257
|
+
|
|
258
|
+
# if you don't want to expose it as :=== in Ruby:
|
|
259
|
+
expose_to_ruby: '=== as: 'some_other_name_for_ruby
|
|
260
|
+
}
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
match ruby_method_name {
|
|
264
|
+
case nil -> alias_method(method_name, method_name message_name)
|
|
265
|
+
case _ -> alias_method(ruby_method_name, method_name message_name)
|
|
221
266
|
}
|
|
222
267
|
}
|
|
223
268
|
}
|
data/lib/rbx/code_loader.fy
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class Rubinius CompiledMethod {
|
|
2
|
+
forwards_unary_ruby_methods
|
|
3
|
+
|
|
4
|
+
def selectors_with_args {
|
|
5
|
+
local_names = local_names to_a
|
|
6
|
+
if: (required_args > 0) then: {
|
|
7
|
+
name to_s split: ":" . map_with_index: |sel i| {
|
|
8
|
+
"#{sel}: #{local_names[i]}"
|
|
9
|
+
} . join: " "
|
|
10
|
+
} else: {
|
|
11
|
+
name to_s rest
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
def definition_line {
|
|
16
|
+
# don't use documentation#to_s since we need original docstring as written in source file to calculate the correct lines#
|
|
17
|
+
docstring = ""
|
|
18
|
+
if: documentation then: {
|
|
19
|
+
docstring = documentation docs join: "\n"
|
|
20
|
+
}
|
|
21
|
+
if: (lines size > 3) then: {
|
|
22
|
+
lines[3] - (docstring lines size)
|
|
23
|
+
} else: {
|
|
24
|
+
0 # UNKNOWN?
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
def last_line {
|
|
29
|
+
defined_line
|
|
30
|
+
}
|
|
31
|
+
}
|
data/lib/rbx/debugger.fy
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require("rubinius/debugger")
|
|
2
|
+
|
|
3
|
+
class Rubinius Debugger {
|
|
4
|
+
forwards_unary_ruby_methods
|
|
5
|
+
metaclass forwards_unary_ruby_methods
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
class Rubinius Debugger Command SetBreakPoint {
|
|
9
|
+
def match_method: method_identifier {
|
|
10
|
+
match method_identifier {
|
|
11
|
+
case /##/ ->
|
|
12
|
+
class_name, method_name = method_identifier split: "##"
|
|
13
|
+
method_identifier = "#{class_name}::#{method_name message_name}"
|
|
14
|
+
case /#/ ->
|
|
15
|
+
class_name, method_name = method_identifier split: "#"
|
|
16
|
+
method_identifier = "#{class_name}##{method_name message_name}"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/([A-Z]\w*(?:::[A-Z]\w*)*)([.#]|::)([a-zA-Z0-9_\[\]:]+[!?=]?)(?:[:](\d+))?/ match: method_identifier
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
alias_method('match_method, 'match_method:)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class Rubinius Location {
|
|
26
|
+
forwards_unary_ruby_methods
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class Rubinius Debugger Frame {
|
|
30
|
+
forwards_unary_ruby_methods
|
|
31
|
+
|
|
32
|
+
def describe {
|
|
33
|
+
arg_str = ""
|
|
34
|
+
recv = nil
|
|
35
|
+
loc = @location
|
|
36
|
+
|
|
37
|
+
if: (loc is_block) then: {
|
|
38
|
+
if: (method required_args == 0) then: {
|
|
39
|
+
recv = "{ } in #{loc describe_receiver}#{loc name}"
|
|
40
|
+
} else: {
|
|
41
|
+
block_args = method local_names join: ", "
|
|
42
|
+
recv = "|#{block_args}| { } in #{loc describe_receiver}#{loc name}"
|
|
43
|
+
}
|
|
44
|
+
} else: {
|
|
45
|
+
recv = loc describe
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
recv = recv replace: "#:" with: "#"
|
|
49
|
+
recv = recv replace: ".:" with: "##"
|
|
50
|
+
recv = recv replace: "." with: "##"
|
|
51
|
+
|
|
52
|
+
str = "#{recv} at #{loc method active_path}:#{loc line} (#{loc ip})"
|
|
53
|
+
{ str << " (+#{loc ip})" } if: $ @debugger variables['show_ip]
|
|
54
|
+
str
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
alias_method('describe, ':describe)
|
|
58
|
+
|
|
59
|
+
def run: code {
|
|
60
|
+
Fancy eval: (code to_s) binding: binding
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
alias_method('run, 'run:)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Rubinius Debugger start
|