borx 0.0.1.alpha2 → 0.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,19 @@
1
1
  module Borx
2
2
 
3
+ def self.Binding(binding = nil)
4
+ if binding.kind_of? ::Binding
5
+ return Binding::Adapter.new(binding)
6
+ elsif binding.kind_of? Binding
7
+ return binding
8
+ elsif binding.nil?
9
+ return Binding::Terminal.new
10
+ else
11
+ raise ArgumentError, "Expected a Binding, got #{binding.inspect}"
12
+ end
13
+ end
14
+
3
15
  end
4
16
 
5
17
  require 'borx/environment'
6
18
  require 'borx/rewriter'
19
+ require 'borx/binding'
@@ -31,6 +31,20 @@ class Borx::Binding
31
31
  @variables[name] = value
32
32
  end
33
33
 
34
+ alias actual_binding binding
35
+
36
+ def cached_actual_binding
37
+ @actual_binding ||= actual_binding
38
+ end
39
+
40
+ def binding
41
+ return self
42
+ end
43
+
44
+ def eval(code, *args)
45
+ Kernel::eval(code, cached_actual_binding, *args)
46
+ end
47
+
34
48
  def block(*args, &block)
35
49
  Block.new(self, args, block)
36
50
  end
@@ -54,6 +68,28 @@ class Borx::Binding
54
68
 
55
69
  end
56
70
 
71
+ class Terminal < self
72
+
73
+ def initialize
74
+ @variables = {}
75
+ end
76
+
77
+ def get_variable(name)
78
+ return @variables[name]
79
+ end
80
+
81
+ def set_variable(name, value)
82
+ return @variables[name] = value
83
+ end
84
+
85
+ def variable?(name)
86
+ return @variables.key?(name)
87
+ end
88
+
89
+ alias set_variable! set_variable
90
+
91
+ end
92
+
57
93
  class Adapter < self
58
94
 
59
95
  def initialize(real_binding)
@@ -73,6 +109,10 @@ class Borx::Binding
73
109
  return @binding.eval("local_variables.any?{|v| v.to_s == #{name.inspect}}")
74
110
  end
75
111
 
112
+ def eval(*args)
113
+ @binding.eval(*args)
114
+ end
115
+
76
116
  end
77
117
 
78
118
  end
@@ -22,6 +22,58 @@ base = Class.new do
22
22
  raise Borx::Environment::NotImplemented::SetVariable
23
23
  end
24
24
 
25
+ def get_magic(binding, name, actual)
26
+ raise Borx::Environment::NotImplemented::GetMagic
27
+ end
28
+
29
+ # @!method eval(code, binding = nil, file = 'borx', line = 0)
30
+ # @param [String, Borx::Code] code
31
+ # @param [Binding, Borx::Binding, nil] binding
32
+ # @param [String] file
33
+ # @param [Numeric] line
34
+ #
35
+ # @!method eval(code, options = {})
36
+ # @param [String, Borx::Code] code
37
+ # @param [Hash] options
38
+ # @option options [Binding, Borx::Binding] :binding
39
+ # @option options [Object] :self main object, only used when no binding is given
40
+ # @option options [String] :file
41
+ # @option options [Numeric] :line
42
+ #
43
+ def eval(code, opts_or_binding = nil, file = 'borx', line = 0)
44
+ bindink = opts_or_binding
45
+ case(opts_or_binding)
46
+ when nil then
47
+ bindink = proc{}.binding
48
+ when Hash then
49
+ opts = opts_or_binding
50
+ if opts[:binding]
51
+ bindink = opts[:binding]
52
+ elsif opts[:self]
53
+ bindink = opts[:self].instance_eval{ binding }
54
+ else
55
+ bindink = proc{}.binding
56
+ end
57
+ file = opts[:file] || 'borx'
58
+ line = opts[:line] || 0
59
+ when Borx::Binding, ::Binding then
60
+ bindink = opts_or_binding
61
+ else
62
+ raise ArgumentException, "Expected a Hash or a Binding, got #{opts_or_binding.inspect}"
63
+ end
64
+ eval_code( Borx::Rewriter.rewrite(code), bindink, file, line)
65
+ end
66
+
67
+ private
68
+
69
+ def eval_code(code, binding, file, line)
70
+ old_borx, setter = binding.eval('__borx__ ||= nil ; __borx_binding__ = Borx::Binding(binding) ; [__borx__, lambda{|v| __borx__ = v}]')
71
+ setter.call(self)
72
+ binding.eval(code.code, file, line)
73
+ ensure
74
+ setter.call(old_borx) if setter
75
+ end
76
+
25
77
  end
26
78
 
27
79
  class Borx::Environment < base
@@ -76,9 +128,16 @@ class Borx::Environment < base
76
128
  include GetConstant
77
129
  end
78
130
 
131
+ module GetMagic
132
+ def get_magic(_binding, _name, actual)
133
+ return actual
134
+ end
135
+ end
136
+
79
137
  include GetSetVariable
80
138
  include GetSetConstant
81
139
  include CallMethod
140
+ include GetMagic
82
141
 
83
142
  class NotImplemented < StandardError
84
143
  class GetConstant < self
@@ -91,20 +150,8 @@ class Borx::Environment < base
91
150
  end
92
151
  class SetVariable < self
93
152
  end
94
- end
95
-
96
- def eval(code, bin_ding = nil)
97
- bin_ding ||= proc{}.binding
98
- eval_code( Borx::Rewriter.rewrite(code), bin_ding)
99
- end
100
-
101
- private
102
- def eval_code(code, binding, file = '(eval)', line = 0)
103
- old_borx, setter = binding.eval('__borx__ ||= nil ; __borx_binding__ = Borx::Binding::Adapter.new(binding) ; [__borx__, lambda{|v| __borx__ = v}]')
104
- setter.call(self)
105
- binding.eval(code.code, file, line)
106
- ensure
107
- setter.call(old_borx) if setter
153
+ class GetMagic < self
154
+ end
108
155
  end
109
156
 
110
157
  end
@@ -1,10 +1,4 @@
1
- begin
2
- require 'ripper'
3
- rescue NotFound
4
- # :nocov:
5
- raise NotFound, "Ripper extension not found. Please add it to your bundle."
6
- # :nocov:
7
- end
1
+ require 'ripper'
8
2
  require 'sorcerer'
9
3
  require 'borx/code'
10
4
  class Borx::Rewriter < Ripper::SexpBuilder
@@ -69,13 +63,18 @@ private
69
63
 
70
64
  def on_var_ref(x)
71
65
  var = super
66
+ if var[1][0] == :@kw
67
+ return call_borx('get_magic', [:args_add,
68
+ [:args_add, [:args_new], ident_to_string(var[1])],
69
+ var
70
+ ])
71
+ end
72
72
  fun = case(var[1][0])
73
73
  when :@const then 'get_constant'
74
74
  when :@gvar then 'get_global_variable'
75
75
  when :@cvar then 'get_class_variable'
76
76
  when :@ivar then 'get_instance_variable'
77
77
  when :@ident then 'get_variable'
78
- when :@kw then 'get_magic'
79
78
  # :nocov:
80
79
  else
81
80
  raise "Unknown var_ref type in #{var[1]}, this is a bug, please report it"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: borx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.alpha2
4
+ version: 0.0.1.beta1
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors: