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 CHANGED
@@ -2,33 +2,92 @@ require 'rvm/interpreter'
2
2
  require 'rvm/classes'
3
3
  require 'rvm/functions'
4
4
  require 'rvm/languages'
5
- #This is the rVM Library
6
- module RVM
7
- class << self
8
- @@strict = false
9
-
10
- def strict
11
- @@strict
12
- end
13
-
14
- def compile language, code
15
- compiler_for(language).compile(code)
16
- end
5
+ require 'timeout'
17
6
 
18
- def compiler_for language
19
- if l = RVM::Languages[language]
20
- l
21
- else
22
- raise "RVM Error: Unknown Language #{language}"
7
+ # This is the rVM library. Including it loads the very basic functionalites rVM offers.
8
+ #
9
+ # It however does not yet load any functions or languages for security propose.
10
+ # This will have to be done by hand for the reason that it will force the user to concider
11
+ # which functions he wants to offer and which not.
12
+ #
13
+ # You may very well load your own functions and languages with rVM in the same way you can
14
+ # load shipped languages.
15
+ #
16
+ # It also contains some usefull functions that wil allow to make the usuage easyer.
17
+ module RVM
18
+
19
+ # This class is designed to allow execting code more safely
20
+ #
21
+ # It allows to limit executin in multiple ways to prevent all sorty of runaway code.
22
+ class Safety
23
+
24
+ attr_reader :timeout
25
+ def initialize
26
+ @timeout = nil
27
+ end
28
+
29
+ # Sets the timeout for the executin, in seconds (you may use 0.5 and such)
30
+ #
31
+ # The execution is aboarded and a exeption thrown if the
32
+ def timeout=t
33
+ raise ArgumentError, "The timeout must be a number!" if not t.is_a? Numeric
34
+ @timeout = t
35
+ end
36
+
37
+ # Executes the code with the former set security measures.
38
+ #
39
+ # Exceptions are thrown according to the problem
40
+ def execute code, env
41
+ res = nil
42
+ if @timeout
43
+ Timeout::timeout(@timeout) do
44
+ res = code.execute(env)
45
+ end
46
+ else
47
+ res = code.execute(env)
48
+ end
49
+ res
23
50
  end
24
51
  end
25
-
26
- def strict= v
27
- @@strict = v
28
- end
29
-
30
- def debug text
31
- puts text if $DEBUG
32
- end
52
+ class << self
53
+ @@strict = false
54
+
55
+ # This getter returns if rVM handles types strict.
56
+ #
57
+ # Calling a method with wrong types will raise a error if this is true.
58
+ # If false rVM will try to typecast accordingly.
59
+ def strict
60
+ @@strict
61
+ end
62
+
63
+ # Sets if variables are strictly typed or casted for function calls.
64
+ # This allows to make a language either more secure or more flexible.
65
+ def strict= v
66
+ @@strict = v
67
+ end
68
+
69
+ # Compils a code the given language.
70
+ # A new compiler is created for that and discarded afterwards.
71
+ #
72
+ # Using +compiler_for+ and calling compile for it yourself
73
+ # is more performant if you plan on doing thise more then once.
74
+ def compile language, code
75
+ compiler_for(language).compile(code)
76
+ end
77
+
78
+ # Creates you a compiler object for the given language.
79
+ # If no language is given a error is raised.
80
+ def compiler_for language
81
+ if (l = RVM::Languages[language])
82
+ l.new
83
+ else
84
+ raise "RVM Error: Unknown Language #{language}"
85
+ end
86
+ end
87
+
88
+ # A utility function to give debug output based on weather $DEBUG is set or not
89
+ def debug text
90
+ puts text if $DEBUG
91
+ end
33
92
  end
34
93
  end
@@ -18,7 +18,7 @@ module RVM
18
18
  # string = RVM::Classes[:string].new
19
19
  module Classes
20
20
 
21
- extend PluginHost
21
+ extend RVM::PluginHost
22
22
  default :string
23
23
  # The Parent for new classes, meant never to be used alone.
24
24
  # It takes care of registering the calss to the PluginHost,
@@ -46,9 +46,18 @@ module RVM
46
46
  # end
47
47
  class Class
48
48
 
49
- extend Plugin
49
+ extend RVM::Plugin
50
50
  plugin_host Classes
51
51
 
52
+
53
+ def functions
54
+ @functions ||= {}
55
+ end
56
+
57
+ def variables
58
+ @variables ||= {:self => self, }
59
+ end
60
+
52
61
  # This defines the type of the class, it defaults to :any
53
62
  # it is important for tying and type conversion, as long as it
54
63
  # behaves like a string, it can look like a sting ;)
@@ -19,7 +19,13 @@ module RVM
19
19
  def call params, env
20
20
  #Logger.debug "Calling Block...(#{env},#{params})" if $DEBUG
21
21
  env = RVM::Interpreter::Enviroment.new({:params => params||[]}, env)
22
- @code.execute env
22
+ begin
23
+ @code.execute(env)
24
+ rescue RVM::Interpreter::ReturnException => e
25
+ RVM::debug "yuck, cought a result!" if $DEBUG
26
+ pp e if $DEBUG
27
+ return e.val
28
+ end
23
29
  end
24
30
  end
25
31
  end
@@ -0,0 +1,48 @@
1
+ module RVM
2
+ module Classes
3
+ class VMClass < RVM::Classes::Class
4
+ register_for :class
5
+
6
+ attr_reader :object_functions
7
+ attr_reader :functions
8
+
9
+ attr_reader :variables
10
+ attr_accessor :initializer
11
+ attr_accessor :parent
12
+
13
+ def data_type
14
+ :class
15
+ end
16
+
17
+ def initialize(parent = nil, initialize_name = "create");
18
+ super()
19
+ @initializer = initialize_name
20
+ @functions = {}
21
+ @variables = {}
22
+ @object_functions = {}
23
+ @parent = nil
24
+ end
25
+
26
+ def obj_send(method, params, env)
27
+ if method == @initializer
28
+ instance params, env
29
+ else
30
+ m = @functions[method] ||
31
+ m = @parent.functions(method) if not m and @parent
32
+ raise "Unknown method #{method} for object #{self}" if not m
33
+ params.unshift self
34
+ env = RVM::Interpreter::Enviroment.new({:params => params||[], :locals => @variables, :functions => @functions}, env)
35
+ m.call(params, env)
36
+ end
37
+ end
38
+
39
+ def instance params, env
40
+ o = RVM::Classes::Object.new self
41
+ env = RVM::Interpreter::Enviroment.new({:params => params||[], :locals => @variables, :functions => @functions}, env)
42
+ o.obj_send(@initializer, [], env) if @object_functions[@initializer]
43
+ o
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -48,6 +48,7 @@ module RVM
48
48
  super(symbol,include_private)
49
49
  end
50
50
 
51
+
51
52
  alias method_missing_old_number method_missing
52
53
  def method_missing m, *args
53
54
  if @value.respond_to? m
@@ -0,0 +1,33 @@
1
+ #TODO: 4
2
+ module RVM
3
+ module Classes
4
+ class Object < RVM::Classes::Class
5
+ register_for :object
6
+ attr_reader :functions
7
+ attr_reader :variables
8
+ attr_reader :object_class
9
+
10
+ def initialize objectClass
11
+ super()
12
+ @object_class = objectClass
13
+ @functions = {}
14
+ @variables = {}
15
+
16
+ end
17
+
18
+ def obj_send(method, params, env)
19
+ m = @functions[method] || @object_class.object_functions(method)
20
+ raise "Unknown method #{method} for object #{self}" if not m
21
+ params.unshift self
22
+ env = RVM::Interpreter::Enviroment.new({:params => params||[], :locals => @variables}, env)
23
+ m.call(params, env)
24
+ end
25
+
26
+
27
+ def data_type
28
+ :object
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -2,9 +2,9 @@ require File.dirname(__FILE__) + '/plugin'
2
2
  require File.dirname(__FILE__) + '/interpreter'
3
3
  module RVM
4
4
  module Functions
5
- extend PluginHost
5
+ extend RVM::PluginHost
6
6
  class Function
7
- extend Plugin
7
+ extend RVM::Plugin
8
8
  plugin_host Functions
9
9
  class << self
10
10
 
@@ -0,0 +1,3 @@
1
+ Dir[File.dirname(__FILE__) + '/array/*.rb'].each do |c|
2
+ require c
3
+ end
@@ -0,0 +1,20 @@
1
+ module RVM
2
+ module Functions
3
+ class Append < Function
4
+ def Append.execute params, env
5
+ if params.length == 2
6
+ array = params.shift
7
+ value = params.shift
8
+ array << value
9
+ else
10
+ RVM::Classes[:error].new(1,"#-1 FUNCTION (#{self.class.to_s}) EXPECTS 2 OR MORE ARGUMENTS BUT GOT #{params.length}")
11
+ end
12
+ end
13
+
14
+ def Append.signature
15
+ [:list, :any]
16
+ end
17
+ register_for :append
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ module RVM
2
+ module Functions
3
+ class SetAt < Function
4
+ def SetAt.execute params, env
5
+ if params.length == 3
6
+ p params
7
+ array = params.shift
8
+ pos = params.shift
9
+ value = params.shift
10
+ p array
11
+ p pos
12
+ p value
13
+ array[pos.to_i] = value
14
+ else
15
+ RVM::Classes[:error].new(1,"FUNCTION (#{self.class}) EXPECTS 3 ARGUMENTS BUT GOT #{params.length}")
16
+ end
17
+ end
18
+
19
+ def SetAt.signature
20
+ [:list, :number, :any]
21
+ end
22
+ register_for :set_at
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ module RVM
2
+ module Functions
3
+ class Eq < RVM::Functions::Function
4
+ class << self
5
+ def execute params, env
6
+ if params.length == 2
7
+ return RVM::Classes[:boolean].new(params[0] == params[1])
8
+ else
9
+ end
10
+ end
11
+
12
+ def signature
13
+ [:any]
14
+ end
15
+ end
16
+ register_for :eq
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module RVM
2
+ module Functions
3
+ class Gt < RVM::Functions::Function
4
+ class << self
5
+ def execute params, env
6
+ if params.length == 2
7
+ return RVM::Classes[:boolean].new(params[0] > params[1])
8
+ else
9
+ end
10
+ end
11
+
12
+ def signature
13
+ [:any]
14
+ end
15
+ end
16
+ register_for :gt
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module RVM
2
+ module Functions
3
+ class Gte < RVM::Functions::Function
4
+ class << self
5
+ def execute params, env
6
+ if params.length == 2
7
+ return RVM::Classes[:boolean].new(params[0] >= params[1])
8
+ else
9
+ end
10
+ end
11
+
12
+ def signature
13
+ [:any]
14
+ end
15
+ end
16
+ register_for :gte
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module RVM
2
+ module Functions
3
+ class Lt < RVM::Functions::Function
4
+ class << self
5
+ def execute params, env
6
+ if params.length == 2
7
+ return RVM::Classes[:boolean].new(params[0] < params[1])
8
+ else
9
+ end
10
+ end
11
+
12
+ def signature
13
+ [:any]
14
+ end
15
+ end
16
+ register_for :lt
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module RVM
2
+ module Functions
3
+ class Lte < RVM::Functions::Function
4
+ class << self
5
+ def execute params, env
6
+ if params.length == 2
7
+ return RVM::Classes[:boolean].new(params[0] <= params[1])
8
+ else
9
+ end
10
+ end
11
+
12
+ def signature
13
+ [:any]
14
+ end
15
+ end
16
+ register_for :lte
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module RVM
2
+ module Functions
3
+ class Neq < RVM::Functions::Function
4
+ class << self
5
+ def execute params, env
6
+ if params.length == 2
7
+ return RVM::Classes[:boolean].new(params[0] != params[1])
8
+ else
9
+ end
10
+ end
11
+
12
+ def signature
13
+ [:any]
14
+ end
15
+ end
16
+ register_for :neq
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ Dir[File.dirname(__FILE__) + '/logic/*.rb'].each do |c|
2
+ require c
3
+ end