rVM 0.0.1

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.
@@ -0,0 +1,332 @@
1
+ # = PluginHost
2
+ #
3
+ # $Id: plugin.rb 69 2006-07-11 06:00:20Z murphy $
4
+ #
5
+ # A simple subclass plugin system.
6
+ #
7
+ # Example:
8
+ # class Generators < PluginHost
9
+ # plugin_path 'app/generators'
10
+ # end
11
+ #
12
+ # class Generator
13
+ # extend Plugin
14
+ # PLUGIN_HOST = Generators
15
+ # end
16
+ #
17
+ # class FancyGenerator < Generator
18
+ # register_for :fancy
19
+ # end
20
+ #
21
+ # Generators[:fancy] #-> FancyGenerator
22
+ # # or
23
+ # require_plugin 'Generators/fancy'
24
+ #
25
+ # Thanks a lot to Murphy, this code is borrowed from coderay.
26
+ #
27
+ module PluginHost
28
+
29
+ # Raised if Encoders::[] fails because:
30
+ # * a file could not be found
31
+ # * the requested Encoder is not registered
32
+ PluginNotFound = Class.new Exception
33
+ HostNotFound = Class.new Exception
34
+
35
+ PLUGIN_HOSTS = []
36
+ PLUGIN_HOSTS_BY_ID = {} # dummy hash
37
+
38
+ # Loads all plugins using all_plugin_names and load.
39
+ def load_all
40
+ for plugin in all_plugin_names
41
+ load plugin
42
+ end
43
+ end
44
+
45
+ # Returns the Plugin for +id+.
46
+ #
47
+ # Example:
48
+ # yaml_plugin = MyPluginHost[:yaml]
49
+ def [] id, *args, &blk
50
+ plugin = validate_id(id)
51
+ begin
52
+ plugin = plugin_hash.[] plugin, *args, &blk
53
+ end while plugin.is_a? Symbol
54
+ plugin
55
+ end
56
+
57
+ # Alias for +[]+.
58
+ alias load []
59
+
60
+ def require_helper plugin_id, helper_name
61
+ path = path_to File.join(plugin_id, helper_name)
62
+ require path
63
+ end
64
+
65
+ class << self
66
+
67
+ # Adds the module/class to the PLUGIN_HOSTS list.
68
+ def extended mod
69
+ PLUGIN_HOSTS << mod
70
+ end
71
+
72
+ # Warns you that you should not #include this module.
73
+ def included mod
74
+ warn "#{name} should not be included. Use extend."
75
+ end
76
+
77
+ # Find the PluginHost for host_id.
78
+ def host_by_id host_id
79
+ unless PLUGIN_HOSTS_BY_ID.default_proc
80
+ ph = Hash.new do |h, a_host_id|
81
+ for host in PLUGIN_HOSTS
82
+ h[host.host_id] = host
83
+ end
84
+ h.fetch a_host_id, nil
85
+ end
86
+ PLUGIN_HOSTS_BY_ID.replace ph
87
+ end
88
+ PLUGIN_HOSTS_BY_ID[host_id]
89
+ end
90
+
91
+ end
92
+
93
+ # The path where the plugins can be found.
94
+ def plugin_path *args
95
+ unless args.empty?
96
+ @plugin_path = File.expand_path File.join(*args)
97
+ load_map
98
+ end
99
+ @plugin_path
100
+ end
101
+
102
+ # The host's ID.
103
+ #
104
+ # If PLUGIN_HOST_ID is not set, it is simply the class name.
105
+ def host_id
106
+ if self.const_defined? :PLUGIN_HOST_ID
107
+ self::PLUGIN_HOST_ID
108
+ else
109
+ name
110
+ end
111
+ end
112
+
113
+ # Map a plugin_id to another.
114
+ #
115
+ # Usage: Put this in a file plugin_path/_map.rb.
116
+ #
117
+ # class MyColorHost < PluginHost
118
+ # map :navy => :dark_blue,
119
+ # :maroon => :brown,
120
+ # :luna => :moon
121
+ # end
122
+ def map hash
123
+ for from, to in hash
124
+ from = validate_id from
125
+ to = validate_id to
126
+ plugin_hash[from] = to unless plugin_hash.has_key? from
127
+ end
128
+ end
129
+
130
+ # Define the default plugin to use when no plugin is found
131
+ # for a given id.
132
+ #
133
+ # See also map.
134
+ #
135
+ # class MyColorHost < PluginHost
136
+ # map :navy => :dark_blue
137
+ # default :gray
138
+ # end
139
+ def default id
140
+ id = validate_id id
141
+ plugin_hash[nil] = id
142
+ end
143
+
144
+ # Every plugin must register itself for one or more
145
+ # +ids+ by calling register_for, which calls this method.
146
+ #
147
+ # See Plugin#register_for.
148
+ def register plugin, *ids
149
+ for id in ids
150
+ unless id.is_a? Symbol
151
+ raise ArgumentError,
152
+ "id must be a Symbol, but it was a #{id.class}"
153
+ end
154
+ plugin_hash[validate_id(id)] = plugin
155
+ end
156
+ end
157
+
158
+ # A Hash of plugion_id => Plugin pairs.
159
+ def plugin_hash
160
+ @plugin_hash ||= create_plugin_hash
161
+ end
162
+
163
+ def has? id
164
+ plugin_hash.include? id
165
+ end
166
+ # Returns an array of all .rb files in the plugin path.
167
+ #
168
+ # The extension .rb is not included.
169
+ def all_plugin_names
170
+ Dir[path_to('*')].select do |file|
171
+ File.basename(file)[/^(?!_)\w+\.rb$/]
172
+ end.map do |file|
173
+ File.basename file, '.rb'
174
+ end
175
+ end
176
+
177
+ # Makes a map of all loaded plugins.
178
+ def inspect
179
+ map = plugin_hash.dup
180
+ map.each do |id, plugin|
181
+ map[id] = plugin.to_s[/(?>[\w_]+)$/]
182
+ end
183
+ "#{name}[#{host_id}]#{map.inspect}"
184
+ end
185
+
186
+ protected
187
+ # Created a new plugin list and stores it to @plugin_hash.
188
+ def create_plugin_hash
189
+ @plugin_hash =
190
+ Hash.new do |h, plugin_id|
191
+ id = validate_id(plugin_id)
192
+ path = Dir[File.join(plugin_path, "#{plugin_id}.rb")].first || path_to(id)
193
+ begin
194
+ require path
195
+ rescue LoadError => boom
196
+ if h.has_key? nil # default plugin
197
+ h[id] = h[nil]
198
+ else
199
+ raise PluginNotFound, 'Could not load plugin %p: %s' % [id, boom]
200
+ end
201
+ else
202
+ # Plugin should have registered by now
203
+ unless h.has_key? id
204
+ raise PluginNotFound,
205
+ "No #{self.name} plugin for #{id.inspect} found in #{path}."
206
+ end
207
+ end
208
+ h[id]
209
+ end
210
+ end
211
+
212
+ # Loads the map file (see map).
213
+ #
214
+ # This is done automatically when plugin_path is called.
215
+ def load_map
216
+ mapfile = path_to '_map'
217
+ if File.exist? mapfile
218
+ require mapfile
219
+ elsif $DEBUG
220
+ warn 'no _map.rb found for %s' % name
221
+ end
222
+ end
223
+
224
+ # Returns the Plugin for +id+.
225
+ # Use it like Hash#fetch.
226
+ #
227
+ # Example:
228
+ # yaml_plugin = MyPluginHost[:yaml, :default]
229
+ def fetch id, *args, &blk
230
+ plugin_hash.fetch validate_id(id), *args, &blk
231
+ end
232
+
233
+ # Returns the expected path to the plugin file for the given id.
234
+ def path_to plugin_id
235
+ File.join(plugin_path, "#{plugin_id}.rb")
236
+ end
237
+
238
+ # Converts +id+ to a Symbol if it is a String,
239
+ # or returns +id+ if it already is a Symbol.
240
+ #
241
+ # Raises +ArgumentError+ for all other objects, or if the
242
+ # given String includes non-alphanumeric characters (\W).
243
+ def validate_id id
244
+ if id.is_a? Symbol or id.nil?
245
+ id
246
+ elsif id.is_a? String
247
+ if id[/\w+/] == id
248
+ id.to_sym
249
+ else
250
+ raise ArgumentError, "Invalid id: '#{id}' given."
251
+ end
252
+ else
253
+ raise ArgumentError,
254
+ "String or Symbol expected, but #{id.class} given."
255
+ end
256
+ end
257
+
258
+ end
259
+
260
+
261
+ # = Plugin
262
+ #
263
+ # Plugins have to include this module.
264
+ #
265
+ # IMPORTANT: use extend for this module.
266
+ #
267
+ # Example: see PluginHost.
268
+ module Plugin
269
+
270
+ def included mod
271
+ warn "#{name} should not be included. Use extend."
272
+ end
273
+
274
+ # Register this class for the given langs.
275
+ # Example:
276
+ # class MyPlugin < PluginHost::BaseClass
277
+ # register_for :my_id
278
+ # ...
279
+ # end
280
+ #
281
+ # See PluginHost.register.
282
+ def register_for *ids
283
+ plugin_host.register self, *ids
284
+ end
285
+
286
+ # The host for this Plugin class.
287
+ def plugin_host host = nil
288
+ if host and not host.is_a? PluginHost
289
+ raise ArgumentError,
290
+ "PluginHost expected, but #{host.class} given."
291
+ end
292
+ self.const_set :PLUGIN_HOST, host if host
293
+ self::PLUGIN_HOST
294
+ end
295
+
296
+ # Require some helper files.
297
+ #
298
+ # Example:
299
+ #
300
+ # class MyPlugin < PluginHost::BaseClass
301
+ # register_for :my_id
302
+ # helper :my_helper
303
+ #
304
+ # The above example loads the file myplugin/my_helper.rb relative to the
305
+ # file in which MyPlugin was defined.
306
+ def helper *helpers
307
+ for helper in helpers
308
+ self::PLUGIN_HOST.require_helper plugin_id, helper.to_s
309
+ end
310
+ end
311
+
312
+ # Returns the pulgin id used by the engine.
313
+ def plugin_id
314
+ name[/[\w_]+$/].downcase
315
+ end
316
+
317
+ end
318
+
319
+
320
+ # Convenience method for plugin loading.
321
+ # The syntax used is:
322
+ #
323
+ # require_plugin '<Host ID>/<Plugin ID>'
324
+ #
325
+ # Returns the loaded plugin.
326
+ def require_plugin path
327
+ host_id, plugin_id = path.split '/', 2
328
+ host = PluginHost.host_by_id(host_id)
329
+ raise PluginHost::HostNotFound,
330
+ "No host for #{host_id.inspect} found." unless host
331
+ host.load plugin_id
332
+ end
@@ -0,0 +1,26 @@
1
+ module RVM
2
+ module Classes
3
+ class Block < RVM::Classes::Class
4
+ attr_accessor :code
5
+ register_for :block
6
+ def initialize code
7
+ super()
8
+ @type = :any
9
+ @code = code
10
+ end
11
+
12
+ def execute env
13
+ end
14
+
15
+ def execargs
16
+ true
17
+ end
18
+
19
+ def call params, env
20
+ #Logger.debug "Calling Block...(#{env},#{params})" if $DEBUG
21
+ env = RVM::Interpreter::Enviroment.new({:params => params||[]}, env)
22
+ @code.execute env
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ module RVM
2
+ module Classes
3
+ class Boolean < RVM::Classes::Class
4
+ register_for :boolean
5
+ def data_type
6
+ :boolean
7
+ end
8
+
9
+ def initialize value
10
+ super()
11
+ if value
12
+ if value.respond_to? :is_true?
13
+ @value = value.is_true?
14
+ else
15
+ @value = true
16
+ end
17
+ else
18
+ @value = false
19
+ end
20
+ end
21
+
22
+ def is_true?
23
+ @value
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module RVM
2
+ module Classes
3
+ class Error < RVM::Classes::Class
4
+ register_for :error
5
+ attr_accessor :value
6
+ @@type = :error
7
+ def initialize value, text = "This is an error!"
8
+ super()
9
+ @value = value.to_i
10
+ @text = text
11
+ end
12
+
13
+ def is_true?
14
+ false
15
+ end
16
+
17
+ def to_s
18
+ "##{@value.abs * -1} #{@text}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ require 'lib/base/classes'
2
+ module RVM
3
+ module Classes
4
+ class List < Array
5
+ extend Plugin
6
+ plugin_host Classes
7
+ register_for :list
8
+ @@type = :list
9
+ attr_reader :sepperator
10
+
11
+ def data_type
12
+ :list
13
+ end
14
+
15
+ def initialize source= [], sepperator = ' '
16
+ super()
17
+ if source.is_a?(::String) # Okay we've to hack here to get sure we get the /real/ String
18
+ source = source.split sepperator
19
+ elsif !source.is_a?(Array)
20
+ source = [source]
21
+ end
22
+ self.concat source
23
+ @sepperator = sepperator.to_s
24
+ end
25
+
26
+ def resplit(sep)
27
+ sep = sep.to_s
28
+ if sep != @sepperator
29
+ t = self.join(@sepperator)
30
+ @sepperator = sep
31
+ self.clear
32
+ self.concat(t.split(sep))
33
+ end
34
+ end
35
+
36
+ def sepperator= sep
37
+ @sepperator = sep.to_s
38
+ end
39
+
40
+ def to_s
41
+ if @sepperator
42
+ map{|i| i.to_s}.join(@sepperator)
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,70 @@
1
+ module RVM
2
+ module Classes
3
+ class Number < Class
4
+ register_for :number
5
+ @@type = :number
6
+
7
+ def initialize value
8
+ super()
9
+ if value.is_a? Numeric
10
+ @value = value
11
+ elsif value.respond_to?(:to_f) and ((v = value.to_f) != value.to_i)
12
+ @value = v
13
+ elsif value.respond_to?(:to_i)
14
+ @value = value.to_i
15
+ else
16
+ @value = "#{value}".to_f
17
+ end
18
+ if @value.to_f == @value.to_i
19
+ @value = @value.to_i
20
+ end
21
+ end
22
+
23
+ def == v
24
+ @value == v
25
+ end
26
+
27
+ def to_s
28
+ @value.to_s
29
+ end
30
+
31
+ def to_i
32
+ @value.to_i
33
+ end
34
+
35
+ def to_f
36
+ @value.to_f
37
+ end
38
+
39
+ def is_true?
40
+ @value != 0
41
+ end
42
+
43
+ def value
44
+ @value
45
+ end
46
+
47
+ def respond_to?(symbol,include_private = false)
48
+ super(symbol,include_private)
49
+ end
50
+
51
+ alias method_missing_old_number method_missing
52
+ def method_missing m, *args
53
+ if @value.respond_to? m
54
+ args.map! do |a|
55
+ if a.is_a? Number
56
+ a.value
57
+ else
58
+ Number.new(a).value
59
+ end
60
+ end
61
+ r = @value.send(m,*args)
62
+ r = Number.new(r) if r.is_a? Numeric
63
+ r
64
+ else
65
+ method_missing_old_number m, *args
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,73 @@
1
+ module RVM
2
+ module Classes
3
+ class String <String
4
+ extend Plugin
5
+ plugin_host Classes
6
+ register_for :string
7
+ @@type = :string
8
+ ANSI_MAP = {
9
+ 'h' => 1, 'H' => 22,
10
+ 'u' => 4, 'U' => 24,
11
+ 'f' => 5, 'f' => 25,
12
+ 'i' => 7, 'I' => 27,
13
+ 'n' => 0,
14
+ 'x' => 30, 'X' => 40,
15
+ 'r' => 31, 'R' => 41,
16
+ 'g' => 32, 'G' => 42,
17
+ 'y' => 33, 'Y' => 42,
18
+ 'b' => 34, 'B' => 44,
19
+ 'm' => 35, 'M' => 45,
20
+ 'c' => 36, 'C' => 45,
21
+ 'w' => 37, 'W' => 47,
22
+ }
23
+ def initialize val = ""
24
+ super val.to_s
25
+ end
26
+
27
+ def is_true?
28
+ not empty?
29
+ end
30
+
31
+ def data_type
32
+ :string
33
+ end
34
+
35
+ def center width, char = " "
36
+ c = char[0..0]
37
+ c = ' ' if c.empty?
38
+ width = width.to_i - self.length
39
+ width = 0 if width < 0
40
+ l = width / 2
41
+ r = width - l
42
+ self.class.new((c*l) + self + (c*r))
43
+ end
44
+
45
+ def ljust width, char = " "
46
+ c = char[0..0]
47
+ c = ' ' if c.empty?
48
+ width = width.to_i - self.length
49
+ width = 0 if width < 0
50
+ self.class.new(self + (c*width))
51
+ end
52
+
53
+ def rjust width, char = " "
54
+ c = char[0..0]
55
+ c = ' ' if c.empty?
56
+ width = width.to_i - self.length
57
+ width = 0 if width < 0
58
+ self.class.new((c*width) + self)
59
+ end
60
+
61
+ def + v
62
+ self.class.new(super(v))
63
+ end
64
+
65
+ def ansi colorset
66
+ colorset.gsub!(/[^#{ANSI_MAP.keys.join('')}]/,'')
67
+ colorcode = colorset.split('').map { |c| ANSI_MAP[c].to_s}.join(';')
68
+ c = "\e[#{colorcode}m"
69
+ self.class.new("#{c}#{self.gsub("\e[0m",c)}\e[0m")
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,49 @@
1
+ module RVM
2
+ module Functions
3
+ class Align < Function
4
+ #TODO: Fix this
5
+ def Align.execute params, env
6
+ if params.length >=2
7
+ alignments = params.shift
8
+ alignments.map! { |i| i.to_i }
9
+ data = []
10
+ alignments.size.times do
11
+ data << params.shift || []
12
+ end
13
+
14
+ filler = params.shift || " "
15
+ filler = filler.to_s
16
+ colsep = params.shift || " "
17
+ colsep = colsep.to_s
18
+ rowsep = params.shift || "\n"
19
+ rowsep = rowsep.to_s
20
+ running = true
21
+ str = ""
22
+ while running
23
+ i = 0;
24
+ running = false
25
+ alignments.each do |arg|
26
+ running = (item = data[i].shift) || running
27
+ if arg > 0
28
+ str << ljust(item || "",arg,filler)
29
+ else
30
+ str << rjust(item || "",arg*-1,filler)
31
+ end
32
+ str << colsep
33
+ i =+ 1
34
+ end
35
+ str << rowsep
36
+ end
37
+ RVM::Classes[:string].new(str.gsub(/[\n\s]+$/,''))
38
+ else
39
+ RVM::Classes[:error].new(1,"#-1 FUNCTION (#{self.class.to_s}) EXPECTS 2 OR MORE ARGUMENTS BUT GOT #{params.length}")
40
+ end
41
+ end
42
+
43
+ def Align.signature
44
+ [:list]
45
+ end
46
+ register_for :align
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ module RVM
2
+ module Functions
3
+ class Join < Function
4
+ def Join.execute params, env
5
+ if params.length == 2
6
+ RVM::Classes[:string].new(params[0].join(params[1]))
7
+ else
8
+ RVM::Classes[:error].new(1,"#-1 FUNCTION (#{self.class.to_s}) EXPECTS 2 OR 3 ARGUMENTS BUT GOT #{params.length}")
9
+ end
10
+ end
11
+
12
+ def Join.signature
13
+ [:list, :string]
14
+ end
15
+ register_for :join
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ module RVM
2
+ module Functions
3
+ class Map < Function
4
+ def Map.execute params, env
5
+ if params.length == 2
6
+ block = params[1]
7
+ i = 0
8
+ RVM::Classes[:list].new(params[0].map do |e|
9
+ e = block.call([e, RVM::Classes[:number].new(i)], env)
10
+ i += 1
11
+ e # needed to assure that the right value is returned
12
+ end,params[0].sepperator)
13
+ else
14
+ RVM::Classes[:error].new(1,"FUNCTION (#{self.class.to_s}) EXPECTS 2 ARGUMENTS BUT GOT #{params.length}")
15
+ end
16
+ end
17
+
18
+ def Map.signature
19
+ [:list, :block]
20
+ end
21
+ register_for :map
22
+ end
23
+ end
24
+ end