rVM 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rvm.rb +1 -0
- data/lib/rvm/classes.rb +4 -1
- data/lib/rvm/functions.rb +0 -5
- data/lib/rvm/functions/all.rb +3 -0
- data/lib/rvm/functions/general.rb +3 -0
- data/lib/rvm/functions/general/cmp.rb +19 -0
- data/lib/rvm/functions/io.rb +3 -0
- data/lib/rvm/functions/io/print.rb +18 -0
- data/lib/rvm/functions/list.rb +3 -0
- data/lib/rvm/functions/math.rb +3 -0
- data/lib/rvm/functions/string.rb +3 -0
- data/lib/rvm/functions/string/chr.rb +16 -0
- data/lib/rvm/interpreter.rb +17 -2
- data/lib/rvm/languages.rb +0 -1
- data/lib/rvm/languages/brainfuck.rb +145 -0
- data/lib/rvm/languages/math.rb +1 -0
- data/lib/rvm/plugin.rb +4 -65
- metadata +14 -2
data/lib/rvm.rb
CHANGED
data/lib/rvm/classes.rb
CHANGED
@@ -19,7 +19,6 @@ module RVM
|
|
19
19
|
module Classes
|
20
20
|
|
21
21
|
extend PluginHost
|
22
|
-
plugin_path File.dirname(__FILE__), '/classes/'
|
23
22
|
default :string
|
24
23
|
# The Parent for new classes, meant never to be used alone.
|
25
24
|
# It takes care of registering the calss to the PluginHost,
|
@@ -77,3 +76,7 @@ module RVM
|
|
77
76
|
end
|
78
77
|
end
|
79
78
|
end
|
79
|
+
|
80
|
+
Dir[File.dirname(__FILE__) + '/classes/*.rb'].each do |c|
|
81
|
+
require c
|
82
|
+
end
|
data/lib/rvm/functions.rb
CHANGED
@@ -3,7 +3,6 @@ require File.dirname(__FILE__) + '/interpreter'
|
|
3
3
|
module RVM
|
4
4
|
module Functions
|
5
5
|
extend PluginHost
|
6
|
-
plugin_path File.dirname(__FILE__), '/functions/*/'
|
7
6
|
class Function
|
8
7
|
extend Plugin
|
9
8
|
plugin_host Functions
|
@@ -14,10 +13,6 @@ module RVM
|
|
14
13
|
end
|
15
14
|
|
16
15
|
alias method_missing_old method_missing
|
17
|
-
alias respond_to_old respond_to?
|
18
|
-
def respond_to?(symbol,include_private = false)
|
19
|
-
respond_to_old(symbol,include_private)
|
20
|
-
end
|
21
16
|
|
22
17
|
def method_missing(m, *args)
|
23
18
|
if (RVM::Functions.has? m)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RVM
|
2
|
+
module Functions
|
3
|
+
class Cmp < RVM::Functions::Function
|
4
|
+
class << self
|
5
|
+
def execute params, env
|
6
|
+
if params.length == 2
|
7
|
+
return RVM::Classes[:number].new(params[0] <=> params[1])
|
8
|
+
else
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def signature
|
13
|
+
[:any]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
register_for :cmp
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/rvm/interpreter.rb
CHANGED
@@ -99,6 +99,20 @@ module RVM
|
|
99
99
|
|
100
100
|
end
|
101
101
|
|
102
|
+
class Loop
|
103
|
+
def initialize(condition, body)
|
104
|
+
@condition = condition
|
105
|
+
@body = body
|
106
|
+
end
|
107
|
+
|
108
|
+
def execute env
|
109
|
+
while @condition.execute(env).is_true?
|
110
|
+
@body.execute(env)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
102
116
|
# A constant, it evaluates to thevalue given and end the evaluation.
|
103
117
|
# Meaning that no further execution is done in this tree branch, so the
|
104
118
|
# value isn't evaluated.
|
@@ -169,7 +183,8 @@ module RVM
|
|
169
183
|
end
|
170
184
|
|
171
185
|
def execute env
|
172
|
-
|
186
|
+
v = @value.execute(env)
|
187
|
+
if v and v.is_true?
|
173
188
|
RVM::debug "Executing Condition... (true)"
|
174
189
|
@true_case.execute env
|
175
190
|
elsif @false_case
|
@@ -218,7 +233,7 @@ module RVM
|
|
218
233
|
def execute env
|
219
234
|
RVM::debug "Executing Variable..."
|
220
235
|
r = env[@name.execute(env).to_s]
|
221
|
-
@type = r.data_type
|
236
|
+
@type = r.data_type if r
|
222
237
|
r
|
223
238
|
end
|
224
239
|
end
|
data/lib/rvm/languages.rb
CHANGED
@@ -22,7 +22,6 @@ module RVM
|
|
22
22
|
# code = RVM::Classes[:math].compile '(1 + 1) * 3^2'
|
23
23
|
module Languages
|
24
24
|
extend PluginHost
|
25
|
-
plugin_path File.dirname(__FILE__), '/languages'
|
26
25
|
|
27
26
|
# The Compiler class, it holds the compiler. As those grow big I suggest
|
28
27
|
# to split the actuall code into multiple fils. Have a look at the MUSHCode
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
require 'rvm/functions/math/add'
|
3
|
+
require 'rvm/functions/math/sub'
|
4
|
+
require 'rvm/functions/io/print'
|
5
|
+
module RVM
|
6
|
+
module Languages
|
7
|
+
class Brainfuck < RVM::Languages::Language
|
8
|
+
def make_tree str
|
9
|
+
str.gsub!(/\/\/.*?\n/,'') #delete comments
|
10
|
+
str.gsub!(/[^<>+\[\].,\d-]/,'')
|
11
|
+
s = StringScanner.new(str)
|
12
|
+
tree = []
|
13
|
+
cur = tree
|
14
|
+
stack = []
|
15
|
+
while (!s.eos?)
|
16
|
+
c = s.scan(/./)
|
17
|
+
case (c)
|
18
|
+
when '+'
|
19
|
+
if cur.last and cur.last[0] == :inc
|
20
|
+
cur.last[1] += 1
|
21
|
+
else
|
22
|
+
cur << [:inc, 1]
|
23
|
+
end
|
24
|
+
when '-'
|
25
|
+
if cur.last and cur.last[0] == :dec
|
26
|
+
cur.last[1] += 1
|
27
|
+
else
|
28
|
+
cur << [:dec, 1]
|
29
|
+
end
|
30
|
+
when '<'
|
31
|
+
if cur.last and cur.last[0] == :left
|
32
|
+
cur.last[1] += 1
|
33
|
+
else
|
34
|
+
cur << [:left, 1]
|
35
|
+
end
|
36
|
+
when '>'
|
37
|
+
if cur.last and cur.last[0] == :right
|
38
|
+
cur.last[1] += 1
|
39
|
+
else
|
40
|
+
cur << [:right, 1]
|
41
|
+
end
|
42
|
+
when '['
|
43
|
+
tmp = []
|
44
|
+
cur << [:loop, tmp]
|
45
|
+
stack << cur
|
46
|
+
cur = tmp
|
47
|
+
when '.'
|
48
|
+
cur << [:print]
|
49
|
+
when ','
|
50
|
+
cur << [:read]
|
51
|
+
when ']'
|
52
|
+
cur = stack.pop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
tree
|
56
|
+
end
|
57
|
+
|
58
|
+
def compile code
|
59
|
+
make_vmcode(make_tree(code))
|
60
|
+
end
|
61
|
+
|
62
|
+
def make_vmcode tree
|
63
|
+
root = RVM::Interpreter::Sequence.new();
|
64
|
+
ptr = Interpreter::Variable.new(Interpreter.const(:string,'ptr'))
|
65
|
+
val = Interpreter::Variable.new(ptr)
|
66
|
+
tree.each do |item|
|
67
|
+
case item[0]
|
68
|
+
when :inc
|
69
|
+
root << Interpreter::Assignment.new(
|
70
|
+
ptr,
|
71
|
+
Interpreter::FunctionCall.new(
|
72
|
+
:add,
|
73
|
+
[
|
74
|
+
Interpreter::Condition.new(
|
75
|
+
val,
|
76
|
+
val,
|
77
|
+
Interpreter.const(:number,0)
|
78
|
+
),
|
79
|
+
Interpreter.const(:number,item[1])
|
80
|
+
]
|
81
|
+
)
|
82
|
+
)
|
83
|
+
when :dec
|
84
|
+
root << Interpreter::Assignment.new(
|
85
|
+
ptr,
|
86
|
+
Interpreter::FunctionCall.new(
|
87
|
+
:sub,
|
88
|
+
[
|
89
|
+
Interpreter::Condition.new(
|
90
|
+
val,
|
91
|
+
val,
|
92
|
+
Interpreter.const(:number,0)
|
93
|
+
),
|
94
|
+
Interpreter.const(:number,item[1])
|
95
|
+
]
|
96
|
+
)
|
97
|
+
)
|
98
|
+
when :left
|
99
|
+
root << Interpreter::Assignment.new(
|
100
|
+
Interpreter.const(:string,'ptr'),
|
101
|
+
Interpreter::FunctionCall.new(
|
102
|
+
:sub,
|
103
|
+
[
|
104
|
+
ptr,
|
105
|
+
Interpreter.const(:number,item[1])
|
106
|
+
]
|
107
|
+
)
|
108
|
+
)
|
109
|
+
when :right
|
110
|
+
root << Interpreter::Assignment.new(
|
111
|
+
Interpreter.const(:string,'ptr'),
|
112
|
+
Interpreter::FunctionCall.new(
|
113
|
+
:add,
|
114
|
+
[
|
115
|
+
ptr,
|
116
|
+
Interpreter.const(:number,item[1])
|
117
|
+
]
|
118
|
+
)
|
119
|
+
)
|
120
|
+
when :print
|
121
|
+
root << Interpreter::FunctionCall.new(:print, [Interpreter::FunctionCall.new(:chr,[val])])
|
122
|
+
when :read
|
123
|
+
when :loop
|
124
|
+
body = make_vmcode(item[1])
|
125
|
+
root << Interpreter::Loop.new(val, body)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
root
|
129
|
+
end
|
130
|
+
|
131
|
+
register_for :brainfuck
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def bfpp str
|
137
|
+
str.gsub!(/\/\/.*?\n/,'')
|
138
|
+
|
139
|
+
str.gsub!(/[^<>+\[\].,\dv-]/,'')
|
140
|
+
str.gsub!('v','[-]')
|
141
|
+
str.gsub!(/(.)(\d+)/) do |s|
|
142
|
+
s[0].chr * s.gsub(/^./,'').to_i
|
143
|
+
end
|
144
|
+
str
|
145
|
+
end
|
data/lib/rvm/languages/math.rb
CHANGED
data/lib/rvm/plugin.rb
CHANGED
@@ -36,11 +36,7 @@ module PluginHost
|
|
36
36
|
PLUGIN_HOSTS_BY_ID = {} # dummy hash
|
37
37
|
|
38
38
|
# Loads all plugins using all_plugin_names and load.
|
39
|
-
|
40
|
-
for plugin in all_plugin_names
|
41
|
-
load plugin
|
42
|
-
end
|
43
|
-
end
|
39
|
+
|
44
40
|
|
45
41
|
# Returns the Plugin for +id+.
|
46
42
|
#
|
@@ -57,11 +53,6 @@ module PluginHost
|
|
57
53
|
# Alias for +[]+.
|
58
54
|
alias load []
|
59
55
|
|
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
56
|
class << self
|
66
57
|
|
67
58
|
# Adds the module/class to the PLUGIN_HOSTS list.
|
@@ -90,15 +81,6 @@ module PluginHost
|
|
90
81
|
|
91
82
|
end
|
92
83
|
|
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
84
|
# The host's ID.
|
103
85
|
#
|
104
86
|
# If PLUGIN_HOST_ID is not set, it is simply the class name.
|
@@ -161,17 +143,7 @@ module PluginHost
|
|
161
143
|
end
|
162
144
|
|
163
145
|
def has? id
|
164
|
-
plugin_hash.
|
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
|
146
|
+
plugin_hash.has_key? id
|
175
147
|
end
|
176
148
|
|
177
149
|
# Makes a map of all loaded plugins.
|
@@ -188,39 +160,10 @@ protected
|
|
188
160
|
def create_plugin_hash
|
189
161
|
@plugin_hash =
|
190
162
|
Hash.new do |h, plugin_id|
|
191
|
-
|
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]
|
163
|
+
raise "Plugin #{plugin_id} not loaded."
|
209
164
|
end
|
210
165
|
end
|
211
166
|
|
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
167
|
# Returns the Plugin for +id+.
|
225
168
|
# Use it like Hash#fetch.
|
226
169
|
#
|
@@ -230,10 +173,6 @@ protected
|
|
230
173
|
plugin_hash.fetch validate_id(id), *args, &blk
|
231
174
|
end
|
232
175
|
|
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
176
|
|
238
177
|
# Converts +id+ to a Symbol if it is a String,
|
239
178
|
# or returns +id+ if it already is a Symbol.
|
@@ -289,7 +228,7 @@ module Plugin
|
|
289
228
|
raise ArgumentError,
|
290
229
|
"PluginHost expected, but #{host.class} given."
|
291
230
|
end
|
292
|
-
self.const_set :PLUGIN_HOST, host if host
|
231
|
+
self.const_set :PLUGIN_HOST, host if host and not self.const_defined?(:PLUGIN_HOST)
|
293
232
|
self::PLUGIN_HOST
|
294
233
|
end
|
295
234
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rVM
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Heinz N. Gies
|
@@ -9,7 +9,7 @@ autorequire: ""
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-03-04 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -32,11 +32,19 @@ files:
|
|
32
32
|
- lib/rvm/classes/string.rb
|
33
33
|
- lib/rvm/classes.rb
|
34
34
|
- lib/rvm/functions
|
35
|
+
- lib/rvm/functions/all.rb
|
36
|
+
- lib/rvm/functions/general
|
37
|
+
- lib/rvm/functions/general/cmp.rb
|
38
|
+
- lib/rvm/functions/general.rb
|
39
|
+
- lib/rvm/functions/io
|
40
|
+
- lib/rvm/functions/io/print.rb
|
41
|
+
- lib/rvm/functions/io.rb
|
35
42
|
- lib/rvm/functions/list
|
36
43
|
- lib/rvm/functions/list/align.rb
|
37
44
|
- lib/rvm/functions/list/join.rb
|
38
45
|
- lib/rvm/functions/list/map.rb
|
39
46
|
- lib/rvm/functions/list/split.rb
|
47
|
+
- lib/rvm/functions/list.rb
|
40
48
|
- lib/rvm/functions/logic
|
41
49
|
- lib/rvm/functions/logic/and.rb
|
42
50
|
- lib/rvm/functions/math
|
@@ -46,16 +54,20 @@ files:
|
|
46
54
|
- lib/rvm/functions/math/neg.rb
|
47
55
|
- lib/rvm/functions/math/power.rb
|
48
56
|
- lib/rvm/functions/math/sub.rb
|
57
|
+
- lib/rvm/functions/math.rb
|
49
58
|
- lib/rvm/functions/string
|
50
59
|
- lib/rvm/functions/string/ansi.rb
|
51
60
|
- lib/rvm/functions/string/capstr.rb
|
52
61
|
- lib/rvm/functions/string/center.rb
|
62
|
+
- lib/rvm/functions/string/chr.rb
|
53
63
|
- lib/rvm/functions/string/ljust.rb
|
54
64
|
- lib/rvm/functions/string/regmatch.rb
|
55
65
|
- lib/rvm/functions/string/rjust.rb
|
66
|
+
- lib/rvm/functions/string.rb
|
56
67
|
- lib/rvm/functions.rb
|
57
68
|
- lib/rvm/interpreter.rb
|
58
69
|
- lib/rvm/languages
|
70
|
+
- lib/rvm/languages/brainfuck.rb
|
59
71
|
- lib/rvm/languages/math
|
60
72
|
- lib/rvm/languages/math/compiler.rb
|
61
73
|
- lib/rvm/languages/math/tokenizer.rb
|