AmberVM 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/README +38 -0
  2. data/bin/ambervm +278 -0
  3. data/lib/amber/acts_as_rvm_type.rb +157 -0
  4. data/lib/amber/classes/association.rb +36 -0
  5. data/lib/amber/classes/block.rb +52 -0
  6. data/lib/amber/classes/boolean.rb +40 -0
  7. data/lib/amber/classes/class.rb +50 -0
  8. data/lib/amber/classes/error.rb +22 -0
  9. data/lib/amber/classes/list.rb +96 -0
  10. data/lib/amber/classes/null.rb +35 -0
  11. data/lib/amber/classes/number.rb +95 -0
  12. data/lib/amber/classes/object.rb +56 -0
  13. data/lib/amber/classes/string.rb +79 -0
  14. data/lib/amber/classes.rb +113 -0
  15. data/lib/amber/environment.rb +251 -0
  16. data/lib/amber/fukubukuro/ecma_core.rb +409 -0
  17. data/lib/amber/fukubukuro.rb +866 -0
  18. data/lib/amber/functions/all.rb +3 -0
  19. data/lib/amber/functions/array/append.rb +50 -0
  20. data/lib/amber/functions/array/at.rb +50 -0
  21. data/lib/amber/functions/array/set_at.rb +50 -0
  22. data/lib/amber/functions/array.rb +30 -0
  23. data/lib/amber/functions/association/assoc_get.rb +55 -0
  24. data/lib/amber/functions/association/assoc_set.rb +56 -0
  25. data/lib/amber/functions/bitwise/bitwise_and.rb +41 -0
  26. data/lib/amber/functions/bitwise/bitwise_not.rb +41 -0
  27. data/lib/amber/functions/bitwise/bitwise_or.rb +41 -0
  28. data/lib/amber/functions/bitwise/bitwise_xor.rb +41 -0
  29. data/lib/amber/functions/bitwise.rb +3 -0
  30. data/lib/amber/functions/collection/get.rb +66 -0
  31. data/lib/amber/functions/collection/set.rb +67 -0
  32. data/lib/amber/functions/collection/size.rb +54 -0
  33. data/lib/amber/functions/general/cmp.rb +43 -0
  34. data/lib/amber/functions/general/eq.rb +45 -0
  35. data/lib/amber/functions/general/gt.rb +45 -0
  36. data/lib/amber/functions/general/gte.rb +45 -0
  37. data/lib/amber/functions/general/lt.rb +45 -0
  38. data/lib/amber/functions/general/lte.rb +45 -0
  39. data/lib/amber/functions/general/neq.rb +45 -0
  40. data/lib/amber/functions/general/type.rb +43 -0
  41. data/lib/amber/functions/general.rb +3 -0
  42. data/lib/amber/functions/io/print.rb +45 -0
  43. data/lib/amber/functions/io.rb +3 -0
  44. data/lib/amber/functions/list/align.rb +73 -0
  45. data/lib/amber/functions/list/join.rb +45 -0
  46. data/lib/amber/functions/list/map.rb +58 -0
  47. data/lib/amber/functions/list/split.rb +55 -0
  48. data/lib/amber/functions/list.rb +3 -0
  49. data/lib/amber/functions/logic/and.rb +55 -0
  50. data/lib/amber/functions/logic/not.rb +40 -0
  51. data/lib/amber/functions/logic/or.rb +50 -0
  52. data/lib/amber/functions/logic.rb +3 -0
  53. data/lib/amber/functions/math/abs.rb +39 -0
  54. data/lib/amber/functions/math/acos.rb +39 -0
  55. data/lib/amber/functions/math/add.rb +40 -0
  56. data/lib/amber/functions/math/asin.rb +39 -0
  57. data/lib/amber/functions/math/atan.rb +39 -0
  58. data/lib/amber/functions/math/ceil.rb +39 -0
  59. data/lib/amber/functions/math/cos.rb +39 -0
  60. data/lib/amber/functions/math/dec.rb +39 -0
  61. data/lib/amber/functions/math/div.rb +44 -0
  62. data/lib/amber/functions/math/exp.rb +39 -0
  63. data/lib/amber/functions/math/floor.rb +39 -0
  64. data/lib/amber/functions/math/inc.rb +39 -0
  65. data/lib/amber/functions/math/log.rb +39 -0
  66. data/lib/amber/functions/math/mod.rb +41 -0
  67. data/lib/amber/functions/math/mul.rb +43 -0
  68. data/lib/amber/functions/math/neg.rb +43 -0
  69. data/lib/amber/functions/math/power.rb +43 -0
  70. data/lib/amber/functions/math/rand.rb +36 -0
  71. data/lib/amber/functions/math/round.rb +39 -0
  72. data/lib/amber/functions/math/shl.rb +41 -0
  73. data/lib/amber/functions/math/shr.rb +41 -0
  74. data/lib/amber/functions/math/sin.rb +39 -0
  75. data/lib/amber/functions/math/sub.rb +43 -0
  76. data/lib/amber/functions/math/tan.rb +39 -0
  77. data/lib/amber/functions/math.rb +3 -0
  78. data/lib/amber/functions/objects/send.rb +22 -0
  79. data/lib/amber/functions/rails/print.rb +44 -0
  80. data/lib/amber/functions/rails.rb +3 -0
  81. data/lib/amber/functions/string/ansi.rb +24 -0
  82. data/lib/amber/functions/string/capstr.rb +23 -0
  83. data/lib/amber/functions/string/center.rb +25 -0
  84. data/lib/amber/functions/string/chr.rb +16 -0
  85. data/lib/amber/functions/string/ljust.rb +26 -0
  86. data/lib/amber/functions/string/regmatch.rb +34 -0
  87. data/lib/amber/functions/string/rjust.rb +26 -0
  88. data/lib/amber/functions/string.rb +3 -0
  89. data/lib/amber/functions.rb +103 -0
  90. data/lib/amber/interpreter.rb +1380 -0
  91. data/lib/amber/languages/brainfuck.rb +153 -0
  92. data/lib/amber/languages/ecma/compiler.rb +1661 -0
  93. data/lib/amber/languages/ecma/core-math.js +67 -0
  94. data/lib/amber/languages/ecma/core-objects.js +57 -0
  95. data/lib/amber/languages/ecma.rb +9 -0
  96. data/lib/amber/languages/ecma_fuku/compiler.rb +1622 -0
  97. data/lib/amber/languages/ecma_fuku/core-math.js +67 -0
  98. data/lib/amber/languages/ecma_fuku/core-objects.js +56 -0
  99. data/lib/amber/languages/ecma_fuku.rb +13 -0
  100. data/lib/amber/languages/math/compiler.rb +70 -0
  101. data/lib/amber/languages/math/tokenizer.rb +69 -0
  102. data/lib/amber/languages/math/tree.rb +110 -0
  103. data/lib/amber/languages/math.rb +26 -0
  104. data/lib/amber/languages.rb +99 -0
  105. data/lib/amber/library.rb +79 -0
  106. data/lib/amber/optimisation.rb +299 -0
  107. data/lib/amber/plugin.rb +337 -0
  108. data/lib/amber/rails.rb +90 -0
  109. data/lib/amber.rb +106 -0
  110. data/spec/amber/class_spec.rb +27 -0
  111. data/spec/amber/enviroment_spec.rb +61 -0
  112. data/spec/amber/function_spec.rb +25 -0
  113. data/spec/amber/functions/association/assoc_get_spec.rb +41 -0
  114. data/spec/amber/functions/association/assoc_set_spec.rb +43 -0
  115. data/spec/amber/functions/collection/get_spec.rb +12 -0
  116. data/spec/amber/functions/collection/set_spec.rb +10 -0
  117. data/spec/amber/functions/collection/size_spec.rb +10 -0
  118. data/spec/amber/functions/list/split_spec.rb +47 -0
  119. data/spec/amber/functions/string/ansi_spec.rb +44 -0
  120. data/spec/amber/functions/string/capstr_spec.rb +42 -0
  121. data/spec/amber/functions/string/center_spec.rb +49 -0
  122. data/spec/amber/functions/string/ljust_spec.rb +49 -0
  123. data/spec/amber/functions/string/regmatch_spec.rb +52 -0
  124. data/spec/amber/functions/string/rjust_spec.rb +49 -0
  125. data/spec/amber/interpreter/assignment_spec.rb +22 -0
  126. data/spec/amber/interpreter/condition_spec.rb +103 -0
  127. data/spec/amber/interpreter/constant_spec.rb +31 -0
  128. data/spec/amber/interpreter/core_call_spec.rb +72 -0
  129. data/spec/amber/interpreter/interpreter_spec.rb +11 -0
  130. data/spec/amber/interpreter/parameter_spec.rb +24 -0
  131. data/spec/amber/interpreter/sequence_spec.rb +47 -0
  132. data/spec/amber/interpreter/variable_spec.rb +24 -0
  133. data/spec/amber/plugin_spec.rb +10 -0
  134. data/spec/classes/atom/association_spec.rb +39 -0
  135. data/spec/classes/atom/block_spec.rb +25 -0
  136. data/spec/classes/atom/boolean_spec.rb +67 -0
  137. data/spec/classes/atom/error_spec.rb +43 -0
  138. data/spec/classes/atom/list_spec.rb +68 -0
  139. data/spec/classes/atom/number_spec.rb +132 -0
  140. data/spec/classes/atom/string_spec.rb +175 -0
  141. data/spec/languages/ecma/ecma_array_spec.rb +79 -0
  142. data/spec/languages/ecma/ecma_closure_spec.rb +38 -0
  143. data/spec/languages/ecma/ecma_literals_spec.rb +71 -0
  144. data/spec/languages/ecma/ecma_objects_spec.rb +165 -0
  145. data/spec/languages/ecma/ecma_old_spec.rb +540 -0
  146. data/spec/languages/ecma/ecma_spec.rb +64 -0
  147. data/spec/languages/ecma_fuku/ecma_array_spec.rb +61 -0
  148. data/spec/languages/ecma_fuku/ecma_closure_spec.rb +33 -0
  149. data/spec/languages/ecma_fuku/ecma_function_spec.rb +84 -0
  150. data/spec/languages/ecma_fuku/ecma_literals_spec.rb +55 -0
  151. data/spec/languages/ecma_fuku/ecma_objects_spec.rb +133 -0
  152. data/spec/languages/ecma_fuku/ecma_old_spec.rb +415 -0
  153. data/spec/languages/ecma_fuku/ecma_operator_spec.rb +33 -0
  154. data/spec/languages/ecma_fuku/ecma_spec.rb +52 -0
  155. data/spec/languages/math/compiler_spec.rb +49 -0
  156. data/spec/languages/math/tokenizer_spec.rb +73 -0
  157. data/spec/languages/math/tree_spec.rb +153 -0
  158. metadata +225 -0
data/README ADDED
@@ -0,0 +1,38 @@
1
+ = rVM
2
+
3
+ rVM is the implementation of a VirtualMachine in pure Ruby. To clarify, no virtual machine as in VMWare that lets you virtualize a computer. But rather like ruby 1.9 or JRuby that both implement a virtual machine (written in C or Java) to execute Ruby code.
4
+ Just that rVM takes it the other way around, it is written in ruby and lets you execute code within ruby.
5
+
6
+ = So what is so cool about that?
7
+
8
+ For once, the challenge to pull this off ;P. Then it has on huge advantage. It makes it pretty easy to give ruby programs a interface for scripting.
9
+
10
+ Now you might think 'wow cool but I could just use ruby!' that is right, and wrong. Imagine just short code snippets to make a query, perhaps you want to implement a SQL based language to let a user query data in your program? Also consider you want your website to allow user side scripts. I would not want to have ruby code executed for random visitors. Then again I might be more tempted to let them execute code within a VM that has no access to anything outside it's VM neither variables nor hardware nor memory.
11
+
12
+ = Example
13
+
14
+
15
+ The following example implements a pretty easy calculator using the the math language shipped with rVM. Set variables and are not used outside one line
16
+
17
+ require 'rubygems'
18
+ require 'amber' # This loads the rVM gem
19
+ require 'amber/languages/math' #This loads the math plugin as well as the math function library
20
+ s =''
21
+ compiler = AmberVM::Languages[:math].new #Lets get us the compiler
22
+ while s!= 'QUIT'
23
+ s=gets.chomp
24
+ puts compiler.compile(s).execute(compiler.env) # We pass an fresh environment as we don't need an environment.
25
+ end
26
+
27
+ Here one example that keeps set variables due to using one environment for all the calls.
28
+
29
+ require 'rubygems'
30
+ require 'amber' # This loads the rVM gem
31
+ require 'amber/languages/math' #This loads the math plugin as well as the math function library
32
+ s =''
33
+ compiler = AmberVM::Languages[:math].new #Lets get us the compiler
34
+ env = compiler.env
35
+ while s!= 'QUIT'
36
+ s=gets.chomp
37
+ puts compiler.compile(s).execute(env) # We pass an fresh environment as we don't need an environment.
38
+ end
data/bin/ambervm ADDED
@@ -0,0 +1,278 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << "lib"
4
+ require 'optparse'
5
+ require 'ostruct'
6
+ require 'pp'
7
+ require 'amber'
8
+ require 'rubygems'
9
+
10
+
11
+ rcfile = File.expand_path('~/.amberrc')
12
+ if File.exist?(rcfile)
13
+ File.new(rcfile).each do |line|
14
+ line.chomp!
15
+ ARGV << line.gsub(/\s.*$/,'')
16
+ ARGV << line.gsub(/^.*?\s/,'')
17
+ end
18
+ end
19
+
20
+ def v text
21
+ puts text if @options.verbose
22
+ end
23
+
24
+ def load_compiler lang
25
+ begin
26
+ if require("amber/languages/#{lang}")
27
+ v "Loading Compiler: #{lang}" if @options
28
+ @compiler = AmberVM::Languages[lang].new
29
+ else
30
+ puts "ERROR: could not find compiler: #{lang}"
31
+ exit 2
32
+ end
33
+ rescue Exception => e
34
+ puts "ERROR: could not load compiler for: #{lang} #=> #{e}"
35
+ exit 3
36
+ end
37
+ @compiler
38
+ end
39
+
40
+ class AmberVMOptParser
41
+ #
42
+ # Return a structure describing the options.
43
+ #
44
+ LANGUAGES = %w[ecma ecma_fuku bf math]
45
+ LANGUAGES_ALIASES = { "js" => "ecma", "javascript" => "ecma" }
46
+ def self.parse(args)
47
+ # The options specified on the command line will be collected in *options*.
48
+ # We set default values here.
49
+ options = OpenStruct.new
50
+ options.library = []
51
+ options.amber_library = []
52
+ options.core_library = []
53
+ options.verbose = false
54
+ options.language = :ecma
55
+ options.code = nil
56
+ options.use_default_core_libs = true
57
+ options.run_as_core = false
58
+ options.only_compilation = false
59
+
60
+
61
+ o = OptionParser.new do |opts|
62
+ opts.banner = "Usage: amber [options]"
63
+
64
+ opts.separator ""
65
+ opts.separator "Specific options:"
66
+
67
+ # Mandatory argument.
68
+ opts.on("-r", "--require LIBRARY", "Require the LIBRARY before executing your script. This is for own libraries.") do |lib|
69
+ options.library << lib;
70
+ end
71
+
72
+ opts.on("-i", "--amber-require AmberVM_LIBRARY", "Require the AmberVM_LIBRARY before executing your script. This is for amber internal libraries.") do |lib|
73
+ options.amber_library << "amber/#{lib}"
74
+ end
75
+
76
+ opts.on("-b", "--no-corelibs", "Used to disable standard core libraries to be imported automatically") do |b|
77
+ options.use_default_core_libs = !b
78
+ end
79
+ opts.on("-c", "--core-require CORE_LIBRARY", "Require an additional CORE_LIBRARY before executing your script. This is for libraries that allow access to AmberVM library functions.") do |lib|
80
+ options.core_library << "#{lib}"
81
+ end
82
+
83
+ opts.on("-f", "--function NAMESPACE/FUNCTION", "Require the function before executing your script. This is for amber internal functions.") do |lib|
84
+ options.amber_library << "amber/functions/#{lib}"
85
+ end
86
+
87
+ language_list = (LANGUAGES_ALIASES.keys + LANGUAGES).join(',')
88
+ opts.on("-l", "--language LANGUAGE", LANGUAGES, LANGUAGES_ALIASES, "Select interpreter language", " (#{language_list})") do |language|
89
+ options.language = language
90
+ end
91
+
92
+ # Boolean switch.
93
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
94
+ options.verbose = v
95
+ end
96
+
97
+
98
+ opts.on("-d", "--[no-]debug", "Run in debug mode (attention spammy! Implies -v") do |d|
99
+ options.verbose = true if $DEBUG = options.debug = d
100
+ end
101
+
102
+ opts.on("-e", "--execute CODE", "Executes CODE directly.") do |code|
103
+ options.code = code
104
+ end
105
+
106
+ opts.on("-o", "--optimize", "Optimizes the code prior to execution") do |optimize|
107
+ options.optimize = optimize
108
+ end
109
+
110
+ opts.on_tail("-x", "--run-as-core", "Runs the code in core library mode (direct access to the rVM libraries)") do |c|
111
+ options.run_as_core = c
112
+ end
113
+
114
+ opts.separator ""
115
+ opts.separator "Common options:"
116
+
117
+ # No argument, shows at tail. This will print an options summary.
118
+ # Try it and see!
119
+ opts.on_tail("-h", "--help", "Show this message") do
120
+ puts opts
121
+ exit
122
+ end
123
+
124
+ opts.on("-s", "--source", "Shows the source before executing.") do
125
+ options.show_source = true
126
+ end
127
+
128
+ opts.on("-p", "--compilation", "Only show the result of the compiler without executing it.") do
129
+ options.compilation = true
130
+ end
131
+
132
+ opts.on("-n", "--dont-execute", "The code is only compiled but not executed.") do
133
+ options.dont_execute = true
134
+ end
135
+
136
+
137
+ # Another typical switch to print the version.
138
+ opts.on_tail("--version", "Show version") do
139
+ print "AmberVM version: #{AmberVM::VERSION}"
140
+ if options.language
141
+ puts ", #{options.language} compiler version: #{load_compiler(options.language).version}"
142
+ else
143
+ puts "."
144
+ end
145
+ exit
146
+ end
147
+ end
148
+ o.parse!(args)
149
+ options
150
+ end
151
+
152
+ end
153
+
154
+ @options = AmberVMOptParser.parse(ARGV)
155
+ @compiler = nil
156
+ @optvars = {}
157
+
158
+ v "Initializing environment."
159
+
160
+ @options.amber_library.each do |lib|
161
+ v "Loading AmberVM Library: #{lib}."
162
+ unless require(lib)
163
+ puts "ERROR: could not require internal library: #{lib}"
164
+ exit 1
165
+ end
166
+ end
167
+
168
+ load_compiler @options.language
169
+
170
+ if not @options.dont_execute
171
+
172
+ if @options.use_default_core_libs
173
+ if @options.optimize
174
+ @env = @compiler.optimized_env(@optvars)
175
+ else
176
+ @env = @compiler.env()
177
+ end
178
+ else
179
+ @env = AmberVM::Interpreter.env
180
+ end
181
+
182
+ @options.core_library.each do |lib|
183
+ v "Loading core library #{lib}."
184
+ if File.exist?(lib)
185
+
186
+ begin
187
+ v "Compiling core library #{lib}."
188
+ code = @compiler.compile(File.read(lib), true)
189
+ v "Optimizing library #{lib}" if @options.optimize
190
+ code = code.optimize(@optvars) if @options.optimize
191
+ begin
192
+ v "Executing library #{lib}."
193
+ code.execute(@env)
194
+ rescue Exception => e
195
+ puts "ERROR: could not execute core library: #{lib} #=> #{e}"
196
+ exit 4
197
+ end
198
+ rescue Exception => e
199
+ puts "ERROR: could not compile core library: #{lib} #=> #{e}"
200
+ exit 5
201
+ end
202
+ else
203
+ puts "ERROR: Could not load core library: #{lib}"
204
+ exit 6
205
+ end
206
+ end
207
+
208
+ @options.library.each do |lib|
209
+ v "Loading library #{lib}."
210
+ if File.exist?(lib)
211
+ begin
212
+ v "Compiling library #{lib}."
213
+ code = @compiler.compile(File.read(lib))
214
+ v "Optimizing library #{lib}" if @options.optimize
215
+ code = code.optimize(@optvars) if @options.optimize
216
+ begin
217
+ v "Executing library #{lib}."
218
+ code.execute(@env)
219
+ rescue Exception => e
220
+ puts "ERROR: could not execute library: #{lib} #=> #{e}"
221
+ exit 4
222
+ end
223
+ rescue Exception => e
224
+ puts "ERROR: could not compile library: #{lib} #=> #{e}"
225
+ exit 5
226
+ end
227
+ else
228
+ puts "ERROR: Could not load library: #{lib}"
229
+ exit 6
230
+ end
231
+ end
232
+ end
233
+
234
+ if @options.code
235
+ v "Executing: #{@options.code}."
236
+ @source = @options.code
237
+ else
238
+ if file = ARGV.first
239
+ if File.exist?(file)
240
+ @source = File.read(file)
241
+ else
242
+ puts "ERROR: Could not load source file: #{file}"
243
+ exit 7
244
+ end
245
+ else
246
+ puts "No files passed."
247
+ puts `#{$0} -h`
248
+ exit 8
249
+ end
250
+ end
251
+
252
+
253
+ begin
254
+ if @options.show_source
255
+ puts "\n### SOURCE ###"
256
+ i = 0; puts @source.gsub(/^/) { "%3d: " % [i += 1] }
257
+ end
258
+ v "Compiling program code."
259
+ code = @compiler.compile(@source, @options.run_as_core)
260
+ v "Optimizing code" if @options.optimize
261
+ code = code.optimize(@optvars) if @options.optimize
262
+ if @options.compilation
263
+ puts "\n### COMPILAT ###"
264
+ i = 0; puts code.pretty_inspect.gsub(/^/) { "%3d: " % [i += 1] }
265
+ end
266
+ unless @options.dont_execute
267
+ begin
268
+ v "Executing program code."
269
+ p code.execute(@env)
270
+ rescue Exception => e
271
+ puts "ERROR: could not execute program code #=> #{}"
272
+ raise e
273
+ end
274
+ end
275
+ rescue Exception => e
276
+ puts "ERROR: could not compile program code #=> #{e}"
277
+ raise e
278
+ end
@@ -0,0 +1,157 @@
1
+ =begin
2
+ The MIT License
3
+
4
+ Copyright (c) 2007 Heinz N. 'Licenser' Gies
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Ruby Mush"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
+ =end
24
+
25
+
26
+ # AmberVM::ActsAsAmberVMType is a mixin that allows to quickly publish classes and types
27
+ # to the rVM interpreter without going through the hassle of defining each
28
+ # function on it's own and publisheing every varialbe that is watned.
29
+ #
30
+ # The function to call is ActsAsAmberVMTypeMethods::acts_as_amber_type.
31
+ #
32
+ # == Example
33
+ # class Test
34
+ # # Add the readers and writers for
35
+ # attr_accessor :var
36
+ # include AmberVM::ActsAsAmberVMType
37
+ # acts_as_amber_type
38
+ # register_variable :var
39
+ # register_function :to_s
40
+ # end
41
+ module AmberVM::ActsAsAmberVMType
42
+
43
+ # Called when included, loads the class methods and the instance methods needed.
44
+ def self.included(mod)
45
+ mod.extend(AmberVM::ActsAsAmberVMType::ActsAsAmberVMTypeMethods)
46
+ end
47
+
48
+
49
+ module ActsAsAmberVMTypeMethods
50
+ # This function sets up the class to be a registerd class for rVM.
51
+ # It also sets it up to allow the use of +register_variable+ and
52
+ # +register_function+.
53
+ def acts_as_amber_type
54
+ # registering as class
55
+ extend AmberVM::Plugin
56
+ plugin_host AmberVM::Classes
57
+ register_for self.class.to_s.gsub(/(\w)([A-Z])/,"\1_" + "\2".downcase).to_sym
58
+
59
+ #initializing empty functions and variables hashes
60
+ @functions = {}
61
+ @variables = {}
62
+
63
+ #including DSL functions
64
+ extend AmberVM::ActsAsAmberVMType::ActsAsAmberVMTypeInstanceMethods
65
+
66
+ #including methods in class
67
+ include AmberVM::ActsAsAmberVMType::ActsAsAmberVMTypeSingeltonMethods
68
+ end
69
+ end
70
+
71
+ module ActsAsAmberVMTypeSingeltonMethods
72
+ # This function will set up the variables for a rVM and replaces
73
+ # the current function with a shorter and faster one.
74
+ def variables
75
+ puts self.class
76
+ @variables = {}
77
+ #gets the variables hash from the Test class and maps it to a getter/setter Class
78
+ self.class.object_variables.each do |published_as, data|
79
+ name, writable = data
80
+ @variables[published_as.to_s] = AmberVM::Interpreter::VariableStorageCallback.new(self, name, writable)
81
+ end
82
+ #redefinces the variables method to remove overhead from mapping
83
+ instance_eval do
84
+ def variables
85
+ @variables
86
+ end
87
+ end
88
+
89
+ # Return the variables hash for the firs call.
90
+ @variables
91
+ end
92
+
93
+ # This function will set up the variables for a rVM and replaces
94
+ # the current function with a shorter and faster one.
95
+ def functions
96
+ # Copy the original functions hash so that changes to the instance
97
+ # wont't carry over to to other instances.
98
+ @functions = self.class.object_functions.dup
99
+
100
+ # Redefine the function method to speed up further accesses.
101
+ instance_eval do
102
+ def functions
103
+ @functions
104
+ end
105
+ end
106
+
107
+ # Return the functions hash for the first call.
108
+ @functions
109
+ end
110
+ end
111
+
112
+
113
+ # This module hods the instance methods for classes that are supposed to
114
+ # act as a rVM type.
115
+ #
116
+ # It includes +register_variable+ and +register_function+ to help setting up
117
+ # the class quickly.
118
+ module ActsAsAmberVMTypeInstanceMethods
119
+ # This registers a variable for the rVM interface, it allows the scripts
120
+ # to read and write them. If +writable+ is set this will be a read only
121
+ # variable. It alls an be published to rVM under a different name,
122
+ # by passing +published_as+.
123
+ def register_variable name, writable = true, published_as = name
124
+ @variables[published_as.to_s] = [name.to_sym, writable]
125
+ end
126
+
127
+ # This registers a variable for the rVM interface, it allows the scripts
128
+ # to read and write them. If +writable+ is set this will be a read only
129
+ # variable. It alls an be published to rVM under a different name,
130
+ # by passing +published_as+.
131
+ def register_function name, published_as = name
132
+ @functions[published_as.to_s] = Class.new(AmberVM::Functions::Function) do @name = name; end
133
+ class << @functions[published_as.to_s]
134
+ def execute params, env
135
+ env.read_var_val(:self).send(@name, *params)
136
+ end
137
+
138
+ def signature
139
+ [:any]
140
+ end
141
+ end
142
+ end
143
+
144
+ # Returns the hash of variables for to be used only internally by the
145
+ # ActsAsAmberVMTypeSingeltonMethods#variables function to set up the details.
146
+ def object_variables
147
+ @variables
148
+ end
149
+
150
+ # Returns the hash of variables for to be used only internally by the
151
+ # ActsAsAmberVMTypeSingeltonMethods#variables function to set up the details.
152
+ def object_functions
153
+ @functions
154
+ end
155
+ end
156
+
157
+ end
@@ -0,0 +1,36 @@
1
+ module AmberVM
2
+ module Classes
3
+ class Association < Hash
4
+ extend Plugin
5
+ plugin_host Classes
6
+ register_for :association
7
+ @@type = :association
8
+
9
+ def data_type
10
+ :list
11
+ end
12
+
13
+ def variables
14
+ @variables ||= {}
15
+ end
16
+
17
+
18
+ def functions
19
+ @functions ||= {
20
+ 'size' => AmberVM::Functions[:size],
21
+ 'length' => AmberVM::Functions[:size],
22
+ 'get' => AmberVM::Functions[:assoc_get],
23
+ 'set' => AmberVM::Functions[:assoc_set],
24
+ }
25
+ end
26
+
27
+ def initialize source= {}, sepperator = ' '
28
+ super()
29
+ if source.is_a?(::Hash) # Okay we've to hack here to get sure we get the /real/ String
30
+ self.merge! source
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,52 @@
1
+ module AmberVM
2
+ module Classes
3
+ class Block < AmberVM::Classes::Class
4
+ attr_accessor :code
5
+ register_for :block
6
+ def initialize code
7
+ super()
8
+ @type = :any
9
+ @code = code
10
+ end
11
+
12
+ def execute env
13
+ end
14
+
15
+ def execargs
16
+ true
17
+ end
18
+
19
+ class Variable_container
20
+ def initialize parent
21
+ @parent = parent
22
+ @data = {}
23
+ end
24
+
25
+ def [] k
26
+ @data[k] || @parent[k]
27
+ end
28
+
29
+ def []= k, v
30
+ @data[k] = v
31
+ end
32
+ end
33
+
34
+ def optimize variables = {}
35
+ #old_keys = Set.new(variables.keys)
36
+ code = @code.optimize variables
37
+ #(Set.new(variables.keys) - old_keys).each do |key|
38
+ # variables.delete(key)
39
+ #end
40
+ Block.new(code)
41
+ end
42
+
43
+ def call params, env, pos = nil
44
+ AmberVM::debug "Calling Block at #{pos}...(evn: #{env.pretty_inspect}, params: #{params})" if $DEBUG
45
+ env = AmberVM::Interpreter::Environment.new({:params => params||[]}, env)
46
+ return (catch :return do
47
+ @code.execute(env)
48
+ end).val
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,40 @@
1
+ module AmberVM
2
+ module Classes
3
+ class Boolean < AmberVM::Classes::Class
4
+ register_for :boolean
5
+
6
+ def data_type
7
+ :boolean
8
+ end
9
+
10
+ def hash
11
+ @value.hash
12
+ end
13
+
14
+ def eql?(o)
15
+ if o.is_a?(AmberVM::Classes::Boolean)
16
+ o.is_true? == is_true?
17
+ else
18
+ @value == o
19
+ end
20
+ end
21
+
22
+ def initialize value
23
+ super()
24
+ if value
25
+ if value.respond_to? :is_true?
26
+ @value = value.is_true?
27
+ else
28
+ @value = true
29
+ end
30
+ else
31
+ @value = false
32
+ end
33
+ end
34
+
35
+ def is_true?
36
+ @value
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,50 @@
1
+ module AmberVM
2
+ module Classes
3
+ class VMClass < AmberVM::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
+ AmberVM::debug "Executing object method #{method}." if $DEBUG
34
+ params.unshift self
35
+ env = AmberVM::Interpreter::Environment.new({:params => params||[], :locals => @variables, :functions => @functions}, env)
36
+ m.call(params, env)
37
+ end
38
+ end
39
+
40
+ def instance params, env
41
+ o = AmberVM::Classes::Object.new self
42
+ env = AmberVM::Interpreter::Environment.new({:params => params||[], :locals => @variables, :functions => @functions}, env)
43
+ o.obj_send(@initializer, params, env) #if @object_functions[@initializer]
44
+ AmberVM::debug "Creating instance of #{self}: #{o.inspect}." if $DEBUG
45
+ o
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,22 @@
1
+ module AmberVM
2
+ module Classes
3
+ class Error < AmberVM::Classes::Class
4
+ register_for :error
5
+ attr_accessor :value
6
+ @@type = :error
7
+ def initialize value, text = "This is an error!"
8
+ super()
9
+ @value = value.to_i
10
+ @text = text
11
+ end
12
+
13
+ def is_true?
14
+ false
15
+ end
16
+
17
+ def to_s
18
+ "##{@value} #{@text}"
19
+ end
20
+ end
21
+ end
22
+ end