asmrb 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/lib/asmrb.rb +106 -30
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d8918ef5cf8db67f71ead50fbe2f1d21573fd41
|
4
|
+
data.tar.gz: cbc7c9a2fe7fe641910ad92ea511bcf1bbaed323
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2737586b1ad6e86ee190a2395b9ba3c95ea0cea7d9cb70487e8625862e97706fd930c9dada8f1ce9fd3ca4f8ae5b0963da4952c24c6073e02e037f2e46054a7
|
7
|
+
data.tar.gz: f5f84ac83bec2eb3bb232856c1d5393f5dce5d92f628953e7fecf98ed707b3be0b1aa350da6c98fc659878e9d3c04450bf710c910e25c2ca06d74b68b951d64a
|
data/lib/asmrb.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
|
+
require 'benchmark'
|
1
2
|
require 'colorize'
|
2
3
|
require 'pry'
|
3
4
|
|
4
5
|
class Asm
|
5
|
-
attr_reader :variables, :
|
6
|
+
attr_reader :variables, :stack, :name, :is_debug, :result
|
7
|
+
attr_writer :is_debug
|
6
8
|
|
7
|
-
def initialize
|
8
|
-
@@function = []
|
9
|
+
def initialize(&block)
|
9
10
|
@variables = { }
|
10
11
|
@program = []
|
11
12
|
@labels = {}
|
12
13
|
@stack = []
|
14
|
+
@result = nil
|
15
|
+
@is_debug = false
|
13
16
|
@name = "undefined"
|
17
|
+
assemble &block
|
14
18
|
end
|
15
19
|
|
16
20
|
def new_var(dest)
|
@@ -83,6 +87,7 @@ class Asm
|
|
83
87
|
|
84
88
|
"jmp" => lambda { |name|
|
85
89
|
@@pc = @labels[name]
|
90
|
+
new_title "[#{name}]" #if @@pc != @program.length-1
|
86
91
|
},
|
87
92
|
|
88
93
|
"pop" => lambda {|val|
|
@@ -96,8 +101,8 @@ class Asm
|
|
96
101
|
},
|
97
102
|
|
98
103
|
"arg" => lambda { |*args|
|
99
|
-
if @stack.length
|
100
|
-
raise Exception.new "require
|
104
|
+
if @stack.length < args.length
|
105
|
+
raise Exception.new "require (#{args.join(', ')}) on stack: #{@stack}"
|
101
106
|
else
|
102
107
|
args.reverse.each do | arg |
|
103
108
|
@variables[arg] = @stack.pop
|
@@ -110,13 +115,21 @@ class Asm
|
|
110
115
|
},
|
111
116
|
|
112
117
|
"dbg" => lambda {
|
113
|
-
puts @stack
|
118
|
+
puts "#{@stack} > #{@program[@@pc][0]}".light_green
|
119
|
+
binding.pry
|
114
120
|
},
|
115
121
|
|
116
122
|
"func" => lambda {|&block|
|
117
123
|
@stack.push block
|
118
124
|
},
|
119
125
|
|
126
|
+
"ivok" => lambda { |obj, f |
|
127
|
+
req_args "ivok",1 # obj.send(:func, args)
|
128
|
+
args = @stack.pop # should be [ 1, 2, 3 ]
|
129
|
+
result = @variables[obj].send(f, args)
|
130
|
+
@stack.push result
|
131
|
+
},
|
132
|
+
|
120
133
|
"call" => lambda {|fname|
|
121
134
|
_method = method(fname)
|
122
135
|
if _method.parameters.length > 0
|
@@ -141,6 +154,7 @@ class Asm
|
|
141
154
|
|
142
155
|
def create_label(lbl)
|
143
156
|
@labels[lbl] = @program.length-1
|
157
|
+
#binding.pry
|
144
158
|
end
|
145
159
|
|
146
160
|
def method_missing(name, *args)
|
@@ -150,10 +164,6 @@ class Asm
|
|
150
164
|
if OPS.keys.include?(sname)
|
151
165
|
@program << [sname, args]
|
152
166
|
|
153
|
-
# TESTING FEATURE:
|
154
|
-
elsif @@function.include?(name)
|
155
|
-
@program << [sname, @@function[name].execute]
|
156
|
-
|
157
167
|
else
|
158
168
|
|
159
169
|
case sname
|
@@ -177,43 +187,71 @@ class Asm
|
|
177
187
|
end
|
178
188
|
|
179
189
|
def execute(debug=false)
|
180
|
-
|
190
|
+
new_line
|
191
|
+
puts "#{@stack} > #{@name}".yellow if debug
|
181
192
|
begin
|
182
193
|
@@pc = 0
|
183
194
|
until(@@pc == @program.length)
|
184
195
|
# get instruction:
|
185
196
|
instr = @program[@@pc]
|
186
|
-
puts "#{instr}".light_green if debug
|
197
|
+
puts "#{@@pc}: #{instr[0]} #{instr[1]}".light_green if debug
|
187
198
|
# execute proc:
|
188
199
|
self.instance_exec(*instr[1], &OPS[instr[0]])
|
189
200
|
#binding.pry if debug
|
190
201
|
@@pc += 1
|
191
202
|
end
|
192
|
-
@stack.last
|
203
|
+
@result = @stack.last
|
204
|
+
clear
|
193
205
|
rescue Exception => e
|
194
206
|
debug e, instr
|
195
207
|
end
|
208
|
+
new_line
|
209
|
+
@result
|
210
|
+
end
|
211
|
+
|
212
|
+
def fast_execute(*args)
|
213
|
+
arguments args
|
214
|
+
@@pc = 0
|
215
|
+
until(@@pc == @program.length)
|
216
|
+
# execute proc:
|
217
|
+
self.instance_exec(*@program[@@pc][1],
|
218
|
+
&OPS[@program[@@pc][0]])
|
219
|
+
@@pc += 1
|
220
|
+
end
|
221
|
+
@result = @stack.last
|
222
|
+
clear
|
223
|
+
return @result
|
224
|
+
end
|
225
|
+
|
226
|
+
def new_title(title)
|
227
|
+
puts "\n::#{title}" if is_debug
|
228
|
+
end
|
229
|
+
|
230
|
+
def new_line
|
231
|
+
puts "\n----------------------" if is_debug
|
196
232
|
end
|
197
233
|
|
198
234
|
def debug(e,instr)
|
235
|
+
puts "\n--------[BUG]---------"
|
236
|
+
|
199
237
|
# error scope:
|
200
238
|
debug_start = @@pc >= 1 ? @@pc - 1 : 0
|
201
|
-
|
202
|
-
|
203
|
-
|
239
|
+
|
240
|
+
debug_end = @@pc <= (@program.length - 2) ?
|
241
|
+
@@pc + 1 : @@pc
|
204
242
|
|
205
243
|
# ranging...
|
206
244
|
(debug_start..debug_end).each do | i |
|
207
|
-
|
208
|
-
|
209
|
-
|
245
|
+
|
246
|
+
instr = @program[i]
|
247
|
+
color = i != @@pc ? :light_green : :magenta
|
248
|
+
puts "#{i}: #{instr[0]} #{instr[1]}".colorize color #if !instr.nil?
|
210
249
|
end
|
211
250
|
|
212
|
-
puts "\
|
213
|
-
#puts e.backtrace
|
251
|
+
puts "\nat line #{@@pc}: #{ops_info(@program[@@pc][0])} has #{e.message}".colorize(:magenta)
|
214
252
|
|
215
253
|
# test via pry:
|
216
|
-
binding.pry
|
254
|
+
binding.pry if is_debug
|
217
255
|
end
|
218
256
|
|
219
257
|
def ops_info(name)
|
@@ -228,9 +266,9 @@ class Asm
|
|
228
266
|
end
|
229
267
|
end
|
230
268
|
|
231
|
-
def invoke(args
|
269
|
+
def invoke(*args)
|
232
270
|
arguments args
|
233
|
-
execute
|
271
|
+
execute is_debug
|
234
272
|
end
|
235
273
|
|
236
274
|
def clear
|
@@ -238,14 +276,52 @@ class Asm
|
|
238
276
|
@stack = []
|
239
277
|
end
|
240
278
|
|
241
|
-
def self.assemble (&block)
|
242
|
-
Asm.new.assemble &block
|
243
|
-
end
|
244
|
-
|
245
279
|
def assemble(&block)
|
246
280
|
load_program(&block)
|
247
|
-
self.dup
|
281
|
+
eval "$#{@name} = self.dup"
|
282
|
+
eval "$#{@name}"
|
248
283
|
end
|
249
|
-
end
|
250
284
|
|
285
|
+
#primitive fac: that will overflow
|
286
|
+
def self.fac(acc, n)
|
287
|
+
if(n > 0)
|
288
|
+
fac(
|
289
|
+
(acc * n),
|
290
|
+
(n - 1))
|
291
|
+
else
|
292
|
+
acc
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def self.compare_speed
|
297
|
+
# recursive fac:
|
298
|
+
Asm.assemble do
|
299
|
+
defn :factorial
|
300
|
+
arg acc, n
|
301
|
+
push 1
|
302
|
+
push n
|
303
|
+
|
304
|
+
jge :cont
|
305
|
+
push acc
|
306
|
+
jmp :exit
|
251
307
|
|
308
|
+
label :cont
|
309
|
+
mul acc, n
|
310
|
+
sub n, 1
|
311
|
+
jmp :factorial
|
312
|
+
|
313
|
+
label :exit
|
314
|
+
|
315
|
+
#dbg
|
316
|
+
end
|
317
|
+
|
318
|
+
$factorial.is_debug = false
|
319
|
+
|
320
|
+
puts "Asm version vs primitive factorial (both recursive):".light_green
|
321
|
+
Benchmark.bm do |x|
|
322
|
+
x.report { $factorial.invoke 1, 8000 }
|
323
|
+
x.report { fac 1, 8000 }
|
324
|
+
end
|
325
|
+
puts "Run: 1 -> 8710, which is primitive version limitation".light_green
|
326
|
+
end
|
327
|
+
end
|