AmberVM 0.0.19

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