rVM 0.0.5 → 0.0.6

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.
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