rVM 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rvm.rb +84 -25
- data/lib/rvm/classes.rb +11 -2
- data/lib/rvm/classes/block.rb +7 -1
- data/lib/rvm/classes/class.rb +48 -0
- data/lib/rvm/classes/number.rb +1 -0
- data/lib/rvm/classes/object.rb +33 -0
- data/lib/rvm/functions.rb +2 -2
- data/lib/rvm/functions/array.rb +3 -0
- data/lib/rvm/functions/array/append.rb +20 -0
- data/lib/rvm/functions/array/set_at.rb +25 -0
- data/lib/rvm/functions/general/eq.rb +19 -0
- data/lib/rvm/functions/general/gt.rb +19 -0
- data/lib/rvm/functions/general/gte.rb +19 -0
- data/lib/rvm/functions/general/lt.rb +19 -0
- data/lib/rvm/functions/general/lte.rb +19 -0
- data/lib/rvm/functions/general/neq.rb +19 -0
- data/lib/rvm/functions/logic.rb +3 -0
- data/lib/rvm/functions/logic/not.rb +17 -0
- data/lib/rvm/functions/logic/or.rb +24 -0
- data/lib/rvm/functions/math/add.rb +3 -3
- data/lib/rvm/functions/math/div.rb +4 -6
- data/lib/rvm/functions/math/mul.rb +1 -1
- data/lib/rvm/functions/math/sub.rb +1 -1
- data/lib/rvm/functions/objects/send.rb +22 -0
- data/lib/rvm/interpreter.rb +167 -41
- data/lib/rvm/languages.rb +4 -3
- data/lib/rvm/languages/brainfuck.rb +13 -4
- data/lib/rvm/languages/ecma.rb +997 -0
- data/lib/rvm/languages/math.rb +19 -1
- data/lib/rvm/library.rb +71 -0
- data/lib/rvm/plugin.rb +221 -219
- metadata +22 -8
- data/lib/rvm/languages/simple.rb +0 -15
- data/lib/rvm/languages/simple/compiler.rb +0 -73
- data/lib/rvm/languages/simple/tokenizer.rb +0 -75
- data/lib/rvm/languages/simple/tree.rb +0 -144
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.6
|
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-07-06 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -26,15 +26,27 @@ files:
|
|
26
26
|
- lib/rvm/classes
|
27
27
|
- lib/rvm/classes/block.rb
|
28
28
|
- lib/rvm/classes/boolean.rb
|
29
|
+
- lib/rvm/classes/class.rb
|
29
30
|
- lib/rvm/classes/error.rb
|
30
31
|
- lib/rvm/classes/list.rb
|
31
32
|
- lib/rvm/classes/number.rb
|
33
|
+
- lib/rvm/classes/object.rb
|
32
34
|
- lib/rvm/classes/string.rb
|
33
35
|
- lib/rvm/classes.rb
|
34
36
|
- lib/rvm/functions
|
35
37
|
- lib/rvm/functions/all.rb
|
38
|
+
- lib/rvm/functions/array
|
39
|
+
- lib/rvm/functions/array/append.rb
|
40
|
+
- lib/rvm/functions/array/set_at.rb
|
41
|
+
- lib/rvm/functions/array.rb
|
36
42
|
- lib/rvm/functions/general
|
37
43
|
- lib/rvm/functions/general/cmp.rb
|
44
|
+
- lib/rvm/functions/general/eq.rb
|
45
|
+
- lib/rvm/functions/general/gt.rb
|
46
|
+
- lib/rvm/functions/general/gte.rb
|
47
|
+
- lib/rvm/functions/general/lt.rb
|
48
|
+
- lib/rvm/functions/general/lte.rb
|
49
|
+
- lib/rvm/functions/general/neq.rb
|
38
50
|
- lib/rvm/functions/general.rb
|
39
51
|
- lib/rvm/functions/io
|
40
52
|
- lib/rvm/functions/io/print.rb
|
@@ -47,6 +59,9 @@ files:
|
|
47
59
|
- lib/rvm/functions/list.rb
|
48
60
|
- lib/rvm/functions/logic
|
49
61
|
- lib/rvm/functions/logic/and.rb
|
62
|
+
- lib/rvm/functions/logic/not.rb
|
63
|
+
- lib/rvm/functions/logic/or.rb
|
64
|
+
- lib/rvm/functions/logic.rb
|
50
65
|
- lib/rvm/functions/math
|
51
66
|
- lib/rvm/functions/math/add.rb
|
52
67
|
- lib/rvm/functions/math/div.rb
|
@@ -55,6 +70,8 @@ files:
|
|
55
70
|
- lib/rvm/functions/math/power.rb
|
56
71
|
- lib/rvm/functions/math/sub.rb
|
57
72
|
- lib/rvm/functions/math.rb
|
73
|
+
- lib/rvm/functions/objects
|
74
|
+
- lib/rvm/functions/objects/send.rb
|
58
75
|
- lib/rvm/functions/string
|
59
76
|
- lib/rvm/functions/string/ansi.rb
|
60
77
|
- lib/rvm/functions/string/capstr.rb
|
@@ -68,17 +85,14 @@ files:
|
|
68
85
|
- lib/rvm/interpreter.rb
|
69
86
|
- lib/rvm/languages
|
70
87
|
- lib/rvm/languages/brainfuck.rb
|
88
|
+
- lib/rvm/languages/ecma.rb
|
71
89
|
- lib/rvm/languages/math
|
72
90
|
- lib/rvm/languages/math/compiler.rb
|
73
91
|
- lib/rvm/languages/math/tokenizer.rb
|
74
92
|
- lib/rvm/languages/math/tree.rb
|
75
93
|
- lib/rvm/languages/math.rb
|
76
|
-
- lib/rvm/languages/simple
|
77
|
-
- lib/rvm/languages/simple/compiler.rb
|
78
|
-
- lib/rvm/languages/simple/tokenizer.rb
|
79
|
-
- lib/rvm/languages/simple/tree.rb
|
80
|
-
- lib/rvm/languages/simple.rb
|
81
94
|
- lib/rvm/languages.rb
|
95
|
+
- lib/rvm/library.rb
|
82
96
|
- lib/rvm/plugin.rb
|
83
97
|
- lib/rvm.rb
|
84
98
|
- README
|
@@ -104,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
118
|
requirements: []
|
105
119
|
|
106
120
|
rubyforge_project: rmush
|
107
|
-
rubygems_version: 1.
|
121
|
+
rubygems_version: 1.1.1
|
108
122
|
signing_key:
|
109
123
|
specification_version: 2
|
110
124
|
summary: A ruby based VM that lets one add secure scripting to ruby applications.
|
data/lib/rvm/languages/simple.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/simple/tokenizer'
|
2
|
-
require File.dirname(__FILE__) + '/simple/tree'
|
3
|
-
require File.dirname(__FILE__) + '/simple/compiler'
|
4
|
-
require 'rvm/functions/math'
|
5
|
-
module RVM
|
6
|
-
module Languages
|
7
|
-
class SimpleLanguage < Language
|
8
|
-
include Simple
|
9
|
-
def compile text
|
10
|
-
Compiler.compile(Tree.generate(Tokenizer.tokenize(text)))
|
11
|
-
end
|
12
|
-
register_for :simple
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
module RVM
|
2
|
-
module Languages
|
3
|
-
module Simple
|
4
|
-
class Compiler
|
5
|
-
include RVM::Interpreter
|
6
|
-
FUNCTION_MAP = {
|
7
|
-
'+' => :add,
|
8
|
-
'-' => :sub,
|
9
|
-
'/' => :div,
|
10
|
-
'*' => :mul,
|
11
|
-
'^' => :power
|
12
|
-
}
|
13
|
-
def Compiler.compile tree
|
14
|
-
if tree.is_a? Array
|
15
|
-
compile(tree.first)
|
16
|
-
elsif tree.is_a? Hash
|
17
|
-
case tree[:type]
|
18
|
-
when :paren
|
19
|
-
compile tree[:content]
|
20
|
-
when :number
|
21
|
-
Interpreter.const(:number, tree[:number])
|
22
|
-
when :function
|
23
|
-
params = tree[:params].map {|p| compile(p)}
|
24
|
-
case tree[:op]
|
25
|
-
when '-'
|
26
|
-
FunctionCall.new :neg, params
|
27
|
-
else
|
28
|
-
FunctionCall.new tree[:op], params
|
29
|
-
end
|
30
|
-
when :ident
|
31
|
-
Interpreter::Variable.new(Interpreter.const(:string, tree[:ident]))
|
32
|
-
when :op
|
33
|
-
case tree[:op]
|
34
|
-
when ';'
|
35
|
-
s = Interpreter::Sequence.new()
|
36
|
-
if (tree[:left][:type] == :op) and (tree[:left][:op] == ';')
|
37
|
-
s += compile(tree[:left])
|
38
|
-
else
|
39
|
-
s << compile(tree[:left])
|
40
|
-
end
|
41
|
-
if (tree[:right][:type] == :op) and (tree[:right][:op] == ';')
|
42
|
-
s += compile(tree[:right])
|
43
|
-
else
|
44
|
-
s << compile(tree[:right])
|
45
|
-
end
|
46
|
-
when '='
|
47
|
-
case tree[:left][:type]
|
48
|
-
when :ident
|
49
|
-
Interpreter::Assignment.new(Interpreter.const(:string, tree[:left][:ident]),compile(tree[:right]))
|
50
|
-
when :function
|
51
|
-
body = Interpreter::Sequence.new()
|
52
|
-
i = 0
|
53
|
-
tree[:left][:params].each do |p|
|
54
|
-
raise ArgumentError, "Bad ype for a function parameter: #{p[:type]} " if p[:type] != :ident
|
55
|
-
body << Interpreter::Assignment.new(Interpreter.const(:string, p[:ident]), Interpreter::Parameter.new(Interpreter.const(:number, i)))
|
56
|
-
i += 1
|
57
|
-
end
|
58
|
-
body << compile(tree[:right])
|
59
|
-
Interpreter::FunctionDefinition.new(Interpreter.const(:string, tree[:left][:op]), Interpreter.const(:block,body))
|
60
|
-
|
61
|
-
else
|
62
|
-
raise ArgumentError, "Bad name for a variable!"
|
63
|
-
end
|
64
|
-
else
|
65
|
-
FunctionCall.new(FUNCTION_MAP[tree[:op]], [compile(tree[:left]),compile(tree[:right])])
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'strscan'
|
2
|
-
module RVM
|
3
|
-
module Languages
|
4
|
-
module Simple
|
5
|
-
class Tokenizer
|
6
|
-
|
7
|
-
def Tokenizer.tokenize str
|
8
|
-
s = StringScanner.new str
|
9
|
-
tokens = []
|
10
|
-
state = :number
|
11
|
-
paren_deepth = 0
|
12
|
-
block_deepth = 0
|
13
|
-
while not s.eos?
|
14
|
-
s.skip(/\s*/)
|
15
|
-
if state == :number
|
16
|
-
if s.scan(/[+-]+/)
|
17
|
-
t = s.matched.gsub('+','').gsub('--','')
|
18
|
-
if t == '-'
|
19
|
-
tokens << [t, :function]
|
20
|
-
end
|
21
|
-
elsif s.scan(/[a-z][a-z0-9]*/i)
|
22
|
-
r = s.matched
|
23
|
-
if s.scan(/[(]/)
|
24
|
-
tokens << [r, :function]
|
25
|
-
paren_deepth += 1
|
26
|
-
else
|
27
|
-
tokens << [r, :ident]
|
28
|
-
state = :opperator
|
29
|
-
end
|
30
|
-
elsif s.scan(/[\d]+(\.\d+)?/i)
|
31
|
-
tokens << [s.matched, :number]
|
32
|
-
state = :opperator
|
33
|
-
elsif s.scan(/[(]/)
|
34
|
-
paren_deepth += 1
|
35
|
-
tokens << [s.matched, :paren_open]
|
36
|
-
elsif s.scan(/[{]/)
|
37
|
-
block_deepth += 1
|
38
|
-
tokens << [s.matched, :block_close]
|
39
|
-
else
|
40
|
-
raise "Unknown literal in term at positin #{s.pos}."
|
41
|
-
end
|
42
|
-
else
|
43
|
-
if s.scan(/[)]/)
|
44
|
-
paren_deepth -= 1
|
45
|
-
raise "Unmatched ')' parenthes at #{s.pos}" if paren_deepth < 0
|
46
|
-
tokens << [s.matched, :paren_close]
|
47
|
-
elsif s.scan(/[}]/)
|
48
|
-
block_deepth -= 1
|
49
|
-
raise "Unmatched '}' parenthes at #{s.pos}" if paren_deepth < 0
|
50
|
-
tokens << [s.matched, :block_close]
|
51
|
-
elsif s.scan(/,/)
|
52
|
-
tokens << [s.matched, :function_sep]
|
53
|
-
state = :number
|
54
|
-
elsif s.scan(/[*+\/^=-]/)
|
55
|
-
tokens << [s.matched, :opperator]
|
56
|
-
state = :number
|
57
|
-
elsif s.scan(/;/)
|
58
|
-
if paren_deepth == 0
|
59
|
-
tokens << [s.matched, :opperator]
|
60
|
-
state = :number
|
61
|
-
else
|
62
|
-
raise "Expression sepperator enclosed in parenthes at #{s.pos}"
|
63
|
-
end
|
64
|
-
else
|
65
|
-
raise "Unknown literal in term at positin #{s.pos}."
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
tokens
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
@@ -1,144 +0,0 @@
|
|
1
|
-
module RVM
|
2
|
-
module Languages
|
3
|
-
module Simple
|
4
|
-
class Tree
|
5
|
-
PRIORITIES = {
|
6
|
-
|
7
|
-
';' => -100,
|
8
|
-
'{' => -50,
|
9
|
-
'=' => -50,
|
10
|
-
'(' => 0,
|
11
|
-
'+' => 10,
|
12
|
-
'-' => 10,
|
13
|
-
'*' => 20,
|
14
|
-
'/' => 20,
|
15
|
-
'^' => 30,
|
16
|
-
}
|
17
|
-
ASSOSICATIONS = {
|
18
|
-
'{' => :left,
|
19
|
-
'+' => :left,
|
20
|
-
'-' => :left,
|
21
|
-
'*' => :left,
|
22
|
-
'/' => :left,
|
23
|
-
';' => :right,
|
24
|
-
'^' => :right,
|
25
|
-
'=' => :right
|
26
|
-
}
|
27
|
-
PARENS = {
|
28
|
-
'(' => ')',
|
29
|
-
'{' => '}'
|
30
|
-
}
|
31
|
-
def Tree.generate tokens
|
32
|
-
output = []
|
33
|
-
dbgoutput = []
|
34
|
-
pstack = []
|
35
|
-
stack = []
|
36
|
-
dbgstack = []
|
37
|
-
|
38
|
-
while not tokens.empty?
|
39
|
-
token = tokens.shift
|
40
|
-
case token[1]
|
41
|
-
when :function
|
42
|
-
fun = token[0]
|
43
|
-
stack << {:type => :function, :op => fun}
|
44
|
-
output << {:type => :function_end}
|
45
|
-
dbgoutput << ')'
|
46
|
-
dbgstack << fun
|
47
|
-
when :function_sep
|
48
|
-
while stack.last && (stack.last[:type] != :function)
|
49
|
-
output << stack.pop
|
50
|
-
dbgoutput << dbgstack.pop
|
51
|
-
end
|
52
|
-
#Parenthetes
|
53
|
-
when :paren_open
|
54
|
-
op = token[0]
|
55
|
-
pstack << op
|
56
|
-
stack << {:type => :paren, :op => op}
|
57
|
-
dbgstack << op
|
58
|
-
when :paren_close
|
59
|
-
while stack.last && (stack.last[:op] != ')')
|
60
|
-
output << stack.pop
|
61
|
-
dbgoutput << dbgstack.pop
|
62
|
-
end
|
63
|
-
stack.pop
|
64
|
-
dbgstack.pop
|
65
|
-
if stack.last && (stack.last[:type] == :function)
|
66
|
-
output << stack.pop
|
67
|
-
dbgoutput << dbgstack.pop
|
68
|
-
end
|
69
|
-
#Blocks
|
70
|
-
when :block_open
|
71
|
-
op = token[0]
|
72
|
-
pstack << op
|
73
|
-
stack << {:type => :block, :op => op}
|
74
|
-
dbgstack << op
|
75
|
-
when :block_close
|
76
|
-
while stack.last && (stack.last[:op] != '}')
|
77
|
-
output << stack.pop
|
78
|
-
dbgoutput << dbgstack.pop
|
79
|
-
end
|
80
|
-
stack.pop
|
81
|
-
dbgstack.pop
|
82
|
-
#numbers
|
83
|
-
when :number
|
84
|
-
output << {:type => :number, :number => token[0]}
|
85
|
-
dbgoutput << token[0]
|
86
|
-
#idents
|
87
|
-
when :ident
|
88
|
-
output << {:type => :ident, :ident => token[0]}
|
89
|
-
dbgoutput << token[0]
|
90
|
-
# opperators
|
91
|
-
when :opperator
|
92
|
-
op = token[0]
|
93
|
-
ass = ASSOSICATIONS[op]
|
94
|
-
o1p = PRIORITIES[op]
|
95
|
-
while stack.last &&
|
96
|
-
(((ass == :left) && (o1p <= PRIORITIES[stack.last[:op]])) ||
|
97
|
-
((ass == :right) && (o1p < PRIORITIES[stack.last[:op]])))
|
98
|
-
output << stack.pop
|
99
|
-
dbgoutput << dbgstack.pop
|
100
|
-
end
|
101
|
-
stack << {:type => :op, :op => op}
|
102
|
-
dbgstack << op
|
103
|
-
else
|
104
|
-
end
|
105
|
-
if $DEBUG
|
106
|
-
p dbgstack
|
107
|
-
p dbgoutput
|
108
|
-
end
|
109
|
-
end
|
110
|
-
while not stack.empty?
|
111
|
-
output << stack.pop
|
112
|
-
end
|
113
|
-
p output if $DEBUG
|
114
|
-
gen_tree output
|
115
|
-
end
|
116
|
-
|
117
|
-
private
|
118
|
-
def Tree.gen_tree data
|
119
|
-
p data if $DEBUG
|
120
|
-
item = data.pop
|
121
|
-
p item
|
122
|
-
case item[:type]
|
123
|
-
when :number, :ident
|
124
|
-
item
|
125
|
-
when :op
|
126
|
-
item[:right] = gen_tree(data)
|
127
|
-
item[:left] = gen_tree(data)
|
128
|
-
item
|
129
|
-
when :paren, :block
|
130
|
-
item[:content] = gen_tree(data)
|
131
|
-
item
|
132
|
-
when :function
|
133
|
-
item[:params] = []
|
134
|
-
while data.last && data.last[:type] != :function_end
|
135
|
-
item[:params] << gen_tree(data)
|
136
|
-
end
|
137
|
-
data.pop
|
138
|
-
item
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|