asmrb 0.0.2 → 0.0.2.1
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 +82 -48
- 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: f3068def65f664536adb24c11b82d0b7e63d6a85
|
4
|
+
data.tar.gz: 33f463277925245b25ef4f62fa78e4188c27b1c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3382c649f7a80fa31f28570003e5b56beaf8cc6c016bd3a94249cf1ffcc720d6d9b6622a9b5a1f44c4ec2c7acc17b4615846a42d71b369951d51ec3fce8d48ae
|
7
|
+
data.tar.gz: dfb30e2a85d3e595b34d36f4df32355946876811a7fd9bbdbad8976df6b8f3abd2d7c3fdcd97d19f358bfb1389413b4dc326dbca3a290e83dc588cdc1449ffe9
|
data/lib/asmrb.rb
CHANGED
@@ -3,18 +3,28 @@ require 'colorize'
|
|
3
3
|
require 'pry'
|
4
4
|
|
5
5
|
class Asm
|
6
|
-
attr_reader :variables, :stack, :name, :is_debug, :result
|
6
|
+
attr_reader :variables, :stack, :name, :is_debug, :result, :functions, :params
|
7
7
|
attr_writer :is_debug
|
8
8
|
|
9
9
|
def initialize(&block)
|
10
|
-
@
|
10
|
+
@functions = {}
|
11
|
+
new_scope
|
12
|
+
assemble &block
|
13
|
+
end
|
14
|
+
|
15
|
+
def export
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def new_scope
|
20
|
+
@variables = {}
|
11
21
|
@program = []
|
22
|
+
@params = 0
|
12
23
|
@labels = {}
|
13
24
|
@stack = []
|
14
25
|
@result = nil
|
15
26
|
@is_debug = false
|
16
|
-
@name = "
|
17
|
-
assemble &block
|
27
|
+
@name = "it"
|
18
28
|
end
|
19
29
|
|
20
30
|
def new_var(dest)
|
@@ -30,8 +40,9 @@ class Asm
|
|
30
40
|
end
|
31
41
|
|
32
42
|
OPS = {
|
43
|
+
|
33
44
|
"rdu" => lambda { | ops |
|
34
|
-
e = eval "@stack.reduce(
|
45
|
+
e = eval "@stack.reduce(:#{ops})"
|
35
46
|
@stack.push e
|
36
47
|
},
|
37
48
|
|
@@ -66,28 +77,32 @@ class Asm
|
|
66
77
|
#new_var dest
|
67
78
|
},
|
68
79
|
|
69
|
-
"jlt" => lambda { |less, more|
|
70
|
-
req_args "jlt", 2
|
71
|
-
@@pc = @labels[name] if @stack[@stack.length - 1] < @stack[@stack.length - 2]
|
72
|
-
@stack.drop 2
|
73
|
-
},
|
74
|
-
|
75
80
|
"jge" => lambda { |name|
|
76
81
|
req_args "jge", 1
|
77
|
-
|
78
|
-
y = @stack.pop
|
79
|
-
@@pc = @labels[name] if x >= y
|
82
|
+
@pc = @labels[name] if @stack.pop == :gt
|
80
83
|
},
|
81
84
|
|
82
|
-
"
|
83
|
-
req_args "
|
84
|
-
@stack.
|
85
|
+
"jlt" => lambda { |name|
|
86
|
+
req_args "jlt", 1
|
87
|
+
@pc = @labels[name] if @stack.pop == :lt
|
88
|
+
},
|
89
|
+
|
90
|
+
"jeq" => lambda { |name|
|
91
|
+
req_args "jeq", 1
|
92
|
+
@pc = @labels[name] if @stack.pop == :eq
|
93
|
+
},
|
94
|
+
|
95
|
+
"cmp" => lambda { |a, b|
|
96
|
+
a = refvar(a)
|
97
|
+
b = refvar(b)
|
98
|
+
@stack.push ( a > b ? :gt
|
99
|
+
: a == b ? :eq : :lt )
|
85
100
|
},
|
86
101
|
|
87
102
|
|
88
103
|
"jmp" => lambda { |name|
|
89
|
-
|
90
|
-
new_title "[#{name}]" #if
|
104
|
+
@pc = @labels[name]
|
105
|
+
new_title "[#{name}]" #if @pc != @program.length-1
|
91
106
|
},
|
92
107
|
|
93
108
|
"pop" => lambda {|val|
|
@@ -115,12 +130,30 @@ class Asm
|
|
115
130
|
},
|
116
131
|
|
117
132
|
"dbg" => lambda {
|
118
|
-
puts "#{@stack} > #{@program[
|
133
|
+
puts "#{@stack} > #{@program[@pc][0]}".light_green
|
119
134
|
binding.pry
|
120
135
|
},
|
121
136
|
|
122
|
-
"func" => lambda {
|
123
|
-
|
137
|
+
"func" => lambda {|name|
|
138
|
+
args = []
|
139
|
+
params = eval "$#{name}.params"
|
140
|
+
params.times do
|
141
|
+
args << @stack.pop
|
142
|
+
end
|
143
|
+
eval "$#{name}.is_debug = true" if @is_debug
|
144
|
+
o = eval "$#{name}.invoke #{args.join(',')}"
|
145
|
+
# for some reasons, this pointer is increased,
|
146
|
+
# after invoking the outside function.
|
147
|
+
# @@pc is belong to class, sync with all objects
|
148
|
+
# made with this class.
|
149
|
+
# while @pc is stick to instance that created
|
150
|
+
# by this class.
|
151
|
+
# which is why invoking other Asm, cause @@pc
|
152
|
+
# to increase, while @pc don't.
|
153
|
+
# to test this problem, uncomment below and rake test:
|
154
|
+
#@pc += 1
|
155
|
+
@stack.push o if !o.nil?
|
156
|
+
#binding.pry
|
124
157
|
},
|
125
158
|
|
126
159
|
"ivok" => lambda { |obj, f |
|
@@ -131,6 +164,7 @@ class Asm
|
|
131
164
|
},
|
132
165
|
|
133
166
|
"call" => lambda {|fname|
|
167
|
+
#binding.pry
|
134
168
|
_method = method(fname)
|
135
169
|
if _method.parameters.length > 0
|
136
170
|
args = []
|
@@ -158,11 +192,13 @@ class Asm
|
|
158
192
|
end
|
159
193
|
|
160
194
|
def method_missing(name, *args)
|
161
|
-
|
195
|
+
# :name => "name"
|
162
196
|
sname = name.to_s
|
163
197
|
|
164
198
|
if OPS.keys.include?(sname)
|
165
199
|
@program << [sname, args]
|
200
|
+
# get parameter amount:
|
201
|
+
@params = args.length if sname == "arg"
|
166
202
|
|
167
203
|
else
|
168
204
|
|
@@ -187,36 +223,37 @@ class Asm
|
|
187
223
|
end
|
188
224
|
|
189
225
|
def execute(debug=false)
|
190
|
-
new_line
|
226
|
+
new_line if debug
|
191
227
|
puts "#{@stack} > #{@name}".yellow if debug
|
192
228
|
begin
|
193
|
-
|
194
|
-
until(
|
229
|
+
@pc = 0
|
230
|
+
until(@pc == @program.length)
|
195
231
|
# get instruction:
|
196
|
-
instr = @program[
|
197
|
-
puts "#{
|
198
|
-
# execute proc:
|
232
|
+
instr = @program[@pc]
|
233
|
+
puts "#{@pc}: #{instr[0]} #{instr[1]}".light_green if debug
|
234
|
+
# execute proc: arg , proc
|
199
235
|
self.instance_exec(*instr[1], &OPS[instr[0]])
|
200
236
|
#binding.pry if debug
|
201
|
-
|
237
|
+
@pc += 1
|
202
238
|
end
|
239
|
+
#binding.pry
|
203
240
|
@result = @stack.last
|
204
241
|
clear
|
205
242
|
rescue Exception => e
|
206
243
|
debug e, instr
|
207
244
|
end
|
208
|
-
new_line
|
245
|
+
new_line if debug
|
209
246
|
@result
|
210
247
|
end
|
211
248
|
|
212
249
|
def fast_execute(*args)
|
213
250
|
arguments args
|
214
|
-
|
215
|
-
until(
|
251
|
+
@pc = 0
|
252
|
+
until(@pc == @program.length)
|
216
253
|
# execute proc:
|
217
|
-
self.instance_exec(*@program[
|
218
|
-
&OPS[@program[
|
219
|
-
|
254
|
+
self.instance_exec(*@program[@pc][1],
|
255
|
+
&OPS[@program[@pc][0]])
|
256
|
+
@pc += 1
|
220
257
|
end
|
221
258
|
@result = @stack.last
|
222
259
|
clear
|
@@ -228,28 +265,26 @@ class Asm
|
|
228
265
|
end
|
229
266
|
|
230
267
|
def new_line
|
231
|
-
puts "\n----------------------"
|
268
|
+
puts "\n----------------------"
|
232
269
|
end
|
233
270
|
|
234
271
|
def debug(e,instr)
|
235
272
|
puts "\n--------[BUG]---------"
|
236
273
|
|
237
274
|
# error scope:
|
238
|
-
debug_start =
|
275
|
+
debug_start = @pc >= 1 ? @pc - 1 : 0
|
239
276
|
|
240
|
-
debug_end =
|
241
|
-
|
277
|
+
debug_end = @pc <= (@program.length - 2) ?
|
278
|
+
@pc + 1 : @pc
|
242
279
|
|
243
280
|
# ranging...
|
244
281
|
(debug_start..debug_end).each do | i |
|
245
282
|
|
246
283
|
instr = @program[i]
|
247
|
-
color = i !=
|
284
|
+
color = i != @pc ? :light_green : :magenta
|
248
285
|
puts "#{i}: #{instr[0]} #{instr[1]}".colorize color #if !instr.nil?
|
249
286
|
end
|
250
|
-
|
251
|
-
puts "\nat line #{@@pc}: #{ops_info(@program[@@pc][0])} has #{e.message}".colorize(:magenta)
|
252
|
-
|
287
|
+
puts "\nat line #{@pc}: #{ops_info(@program[@pc][0])} has #{e.message}".colorize(:magenta) if !instr.nil?
|
253
288
|
# test via pry:
|
254
289
|
binding.pry if is_debug
|
255
290
|
end
|
@@ -278,7 +313,7 @@ class Asm
|
|
278
313
|
|
279
314
|
def assemble(&block)
|
280
315
|
load_program(&block)
|
281
|
-
eval "$#{@name} = self.
|
316
|
+
eval "$#{@name} = self.clone"
|
282
317
|
eval "$#{@name}"
|
283
318
|
end
|
284
319
|
|
@@ -298,10 +333,9 @@ class Asm
|
|
298
333
|
Asm.assemble do
|
299
334
|
defn :factorial
|
300
335
|
arg acc, n
|
301
|
-
|
302
|
-
push n
|
303
|
-
|
336
|
+
cmp n, 1
|
304
337
|
jge :cont
|
338
|
+
|
305
339
|
push acc
|
306
340
|
jmp :exit
|
307
341
|
|