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