asmrb 0.0.2 → 0.0.2.1
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 +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
|
|