relisp 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +14 -0
- data/README +22 -22
- data/Rakefile +4 -3
- data/examples/elisp_master/elisp_master.el +70 -34
- data/examples/elisp_master/ruby_slave.rb +37 -0
- data/examples/elisp_master/ruby_slave2.rb +33 -0
- data/examples/ruby_master/basic.rb +20 -0
- data/examples/ruby_master/debugging.rb +32 -0
- data/examples/ruby_master/elisp_data_types.rb +26 -0
- data/examples/ruby_master/method_missing.rb +24 -0
- data/examples/ruby_master/recursive_calling.rb +11 -0
- data/lib/relisp/elisp_functions.rb +30 -13
- data/lib/relisp/slaves.rb +39 -35
- data/lib/relisp/type_conversion/editing_types.rb +677 -643
- data/lib/relisp/type_conversion/programming_types.rb +70 -117
- data/lib/relisp/type_conversion.rb +43 -2
- data/lib/relisp.rb +5 -2
- data/manual_test/tests.el +0 -2
- data/manual_test/tests.rb +0 -29
- data/src/relisp.el +223 -220
- data/test/test_editing_types.rb +4 -3
- data/test/test_elisp_functions.rb +0 -1
- data/test/test_programming_types.rb +5 -4
- data/test/test_slaves.rb +2 -1
- metadata +15 -10
- data/examples/elisp_master/ruby_slave +0 -26
- data/examples/ruby_master/ruby_master_example +0 -27
- data/setup.rb +0 -1598
data/lib/relisp/slaves.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (C) 2009
|
2
|
+
# Copyright (C) 2009, 2010 Don March
|
3
3
|
#
|
4
4
|
# This file is part of Relisp.
|
5
5
|
#
|
@@ -18,6 +18,7 @@
|
|
18
18
|
# <http://www.gnu.org/licenses/>.
|
19
19
|
#++
|
20
20
|
#
|
21
|
+
|
21
22
|
# TODO: maybe catch Errno::EPIPE to see if slave died
|
22
23
|
|
23
24
|
module Relisp
|
@@ -53,6 +54,7 @@ module Relisp
|
|
53
54
|
CONSTANTS << BEGIN_ANSWER_CODE = '___WHATIS___'
|
54
55
|
CONSTANTS << ANSWER_CODE = '___FORTYTWO___'
|
55
56
|
CONSTANTS << ERROR_CODE = '___NO_THATSNOTTRUE_THATSIMPOSSIBLE___'
|
57
|
+
CONSTANTS << BEGIN_SLAVE_CODE = '___LETSDOTHISLIKEBRUTUS___'
|
56
58
|
TRANSMISSION_CODES_REGEXP = Regexp.new(CONSTANTS.join('|'))
|
57
59
|
|
58
60
|
# Every time ruby asks elisp to evaluate an expression, the result
|
@@ -67,7 +69,7 @@ module Relisp
|
|
67
69
|
# elisp it is in a context where any new variables set will drop
|
68
70
|
# out of scope immediately. The @local_binding is a way of
|
69
71
|
# allowing these variables to persist through multiple calls.
|
70
|
-
@local_binding =
|
72
|
+
@local_binding = binding
|
71
73
|
@current_elisp_variable_num = '0'
|
72
74
|
@debug = nil
|
73
75
|
Relisp.default_slave = self
|
@@ -93,7 +95,7 @@ module Relisp
|
|
93
95
|
# Run _code_ in the elisp process.
|
94
96
|
#
|
95
97
|
def elisp_exec(code)
|
96
|
-
code = code.to_s # maybe code is
|
98
|
+
code = code.to_s # maybe code is nil or something
|
97
99
|
write_to_emacs code
|
98
100
|
write_to_emacs COMMAND_CODE
|
99
101
|
receive_answer
|
@@ -125,7 +127,6 @@ module Relisp
|
|
125
127
|
output = ''
|
126
128
|
elsif output_line.strip == COMMAND_CODE
|
127
129
|
eval output, @local_binding
|
128
|
-
# write_to_emacs ""
|
129
130
|
write_to_emacs ANSWER_CODE
|
130
131
|
output = ''
|
131
132
|
elsif output_line.strip == ERROR_CODE
|
@@ -141,32 +142,29 @@ module Relisp
|
|
141
142
|
end
|
142
143
|
|
143
144
|
# Pass an elisp evaluation result to the appropriate Relisp class
|
144
|
-
# for translation. The first line of
|
145
|
+
# for translation. The first line of _result_ is the
|
145
146
|
# 'type-of' the elisp object. The line(s) after that are the text
|
146
147
|
# version of the object. In case the string representation isn't
|
147
148
|
# enough information to translate the object, the result needs to
|
148
149
|
# be kept (in emacs) in the variable +PREVIOUS_ELISP_RESULT+.
|
149
150
|
#
|
150
|
-
def to_ruby(
|
151
|
+
def to_ruby(result)
|
151
152
|
|
152
|
-
# The
|
153
|
+
# The result might have junk at the beginning caused by
|
153
154
|
# whatever emacs sends to the echo area while evaluating ruby's
|
154
155
|
# instructions (it doesn't seem possible to get around this
|
155
156
|
# using with-output-to-string because the output from
|
156
157
|
# save-buffer and other functions is 'message'd). It is also
|
157
158
|
# not possible to just pull off the last two elements, because
|
158
159
|
# sometimes the string representation of the result has newlines
|
159
|
-
# in it (Buffer#to_s, for example).
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
result_string = result_string.split("\n")
|
165
|
-
start_index = result_string.index(BEGIN_ANSWER_CODE) + 1
|
166
|
-
result_string = result_string[start_index..(result_string.size-1)]
|
160
|
+
# in it (Buffer#to_s, for example).
|
161
|
+
|
162
|
+
result = result.split("\n")
|
163
|
+
start_index = result.index(BEGIN_ANSWER_CODE) + 1
|
164
|
+
result = result[start_index..(result.size-1)]
|
167
165
|
|
168
|
-
elisp_type =
|
169
|
-
object_string =
|
166
|
+
elisp_type = result.shift
|
167
|
+
object_string = result.join("\n")
|
170
168
|
|
171
169
|
object_info = {
|
172
170
|
:string => object_string,
|
@@ -177,10 +175,11 @@ module Relisp
|
|
177
175
|
# Just one more reason to love Ruby. Call the Relisp class
|
178
176
|
# formed by rubyizing the 'type-of' the result (i.e., hash-table
|
179
177
|
# becomes HashTable).
|
180
|
-
ruby_type = (
|
178
|
+
ruby_type = Relisp.const_get(elisp_type.split("-").map { |a| a.capitalize }.join)
|
181
179
|
unless ruby_type.kind_of? Class
|
182
180
|
raise "#{ruby_type} not implemented"
|
183
181
|
end
|
182
|
+
|
184
183
|
ruby_type.from_elisp(object_info)
|
185
184
|
end
|
186
185
|
|
@@ -189,8 +188,9 @@ module Relisp
|
|
189
188
|
def send_constants
|
190
189
|
CONSTANTS.each do |constant|
|
191
190
|
read_from_emacs
|
192
|
-
write_to_emacs constant
|
191
|
+
write_to_emacs constant.to_s + "\n"
|
193
192
|
end
|
193
|
+
read_from_emacs
|
194
194
|
end
|
195
195
|
|
196
196
|
public
|
@@ -214,7 +214,7 @@ module Relisp
|
|
214
214
|
# emacs.elisp_eval('(ruby-eval "number")') # => 5
|
215
215
|
#
|
216
216
|
def provide(symbol, binding)
|
217
|
-
|
217
|
+
instance_variable_set "@__#{symbol.to_s}__binding".to_sym, binding
|
218
218
|
|
219
219
|
instance_eval <<-endstr
|
220
220
|
def #{symbol.to_s}
|
@@ -230,12 +230,17 @@ module Relisp
|
|
230
230
|
#
|
231
231
|
class RubySlave < Slave
|
232
232
|
|
233
|
+
# Creates a new RubySlave and immediately starts it.
|
234
|
+
#
|
235
|
+
def self.start
|
236
|
+
self.new.start
|
237
|
+
end
|
238
|
+
|
233
239
|
# Can be provided with a block, in which case the block is run in
|
234
|
-
# the context of the slave
|
235
|
-
#
|
236
|
-
#
|
237
|
-
#
|
238
|
-
# elisp are evaluated.
|
240
|
+
# the context of the slave. This makes slave methods available to
|
241
|
+
# the block without specifying an explicit receiver, and variables
|
242
|
+
# and functions defined in the block are in scope when requests
|
243
|
+
# from elisp are later evaluated.
|
239
244
|
#
|
240
245
|
def initialize
|
241
246
|
super
|
@@ -243,17 +248,17 @@ module Relisp
|
|
243
248
|
|
244
249
|
if block_given?
|
245
250
|
yield self
|
246
|
-
start
|
251
|
+
# start
|
247
252
|
end
|
248
|
-
|
249
253
|
end
|
250
254
|
|
251
255
|
# Begin the main listening loop.
|
252
256
|
#
|
253
257
|
def start
|
258
|
+
write_to_emacs BEGIN_SLAVE_CODE
|
259
|
+
write_to_emacs ANSWER_CODE
|
260
|
+
|
254
261
|
begin
|
255
|
-
@local_binding = binding
|
256
|
-
|
257
262
|
loop do
|
258
263
|
code = ''
|
259
264
|
input = read_from_emacs
|
@@ -275,7 +280,7 @@ module Relisp
|
|
275
280
|
dag_yo.backtrace.each do |b|
|
276
281
|
msg << " " + b + "\n"
|
277
282
|
end
|
278
|
-
write_to_emacs
|
283
|
+
write_to_emacs msg.chomp
|
279
284
|
#write_to_emacs(dag_yo.message)
|
280
285
|
write_to_emacs ERROR_CODE
|
281
286
|
retry
|
@@ -288,7 +293,8 @@ module Relisp
|
|
288
293
|
# the ruby process.
|
289
294
|
#
|
290
295
|
def write_to_emacs(code)
|
291
|
-
puts code
|
296
|
+
# puts code
|
297
|
+
print code
|
292
298
|
end
|
293
299
|
|
294
300
|
# Messages appear on ruby's stdin after emacs sends them to ruby
|
@@ -298,7 +304,7 @@ module Relisp
|
|
298
304
|
gets
|
299
305
|
end
|
300
306
|
end
|
301
|
-
|
307
|
+
|
302
308
|
# Provides an interface to an instance of emacs started as an IO
|
303
309
|
# object. See Relisp::Slave.
|
304
310
|
#
|
@@ -313,11 +319,9 @@ module Relisp
|
|
313
319
|
#
|
314
320
|
def initialize(cli_options = "--no-site-file --no-init-file", load_files = [])
|
315
321
|
super()
|
316
|
-
# load relisp.elc if available
|
322
|
+
# leave off '.el' to load relisp.elc if available
|
317
323
|
elisp_path = File.expand_path(File.join(File.dirname(__FILE__), '../../src/relisp'))
|
318
324
|
|
319
|
-
@local_binding = binding
|
320
|
-
|
321
325
|
emacs_command = if RUBY_PLATFORM.downcase.include?('mswin')
|
322
326
|
"start emacs --batch "
|
323
327
|
else
|