asmrb 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|