asmrb 0.0.0

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 (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/asm.rb +251 -0
  3. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 792de4bbafddedb38b68b7d00165beafd20cb176
4
+ data.tar.gz: 8a7a97aead79fdd91dad623865cd0341a984bcb9
5
+ SHA512:
6
+ metadata.gz: 3459ccc9f2b3610cbb3fa2b3fe1a4bfaa317f4c2f1276de722be47dbd2fa326d9dcf83fcf224196785df33f277974a66617d4710e1f83b7cb6ff72b124106cae
7
+ data.tar.gz: f2ddfc22f474096eca16109ad2da68a8341997dd018f94dc191f71e0c8f40e3a3acdf5b95f15e2d58e432de3d07efbdddc19f36cdac9ad036b7ebf5bb3e8a5b3
data/lib/asm.rb ADDED
@@ -0,0 +1,251 @@
1
+ require 'colorize'
2
+ require 'pry'
3
+
4
+ class Asm
5
+ attr_reader :variables, :function, :stack, :name
6
+
7
+ def initialize
8
+ @@function = []
9
+ @variables = { }
10
+ @program = []
11
+ @labels = {}
12
+ @stack = []
13
+ @name = "undefined"
14
+ end
15
+
16
+ def new_var(dest)
17
+ eval("def #{dest}; #{@variables[dest]}; end")
18
+ end
19
+
20
+ def refvar(val)
21
+ val.is_a?(Symbol) ? @variables[val] : val
22
+ end
23
+
24
+ def req_args(func,amount)
25
+ raise Exception.new "[#{func}]: require #{amount} args to compare." if @stack.length < amount
26
+ end
27
+
28
+ OPS = {
29
+ "rdu" => lambda { | ops |
30
+ e = eval "@stack.reduce(&:#{ops})"
31
+ @stack.push e
32
+ },
33
+
34
+ "add" => lambda { | a , b |
35
+ @stack.push(refvar(a) + refvar(b))
36
+ },
37
+
38
+ "sub" => lambda { | a , b |
39
+ @stack.push(refvar(a) - refvar(b))
40
+ },
41
+
42
+ "mul" => lambda { | a , b |
43
+ @stack.push(refvar(a) * refvar(b))
44
+ },
45
+
46
+ "div" => lambda { | a , b |
47
+ @stack.push(refvar(a) / refvar(b))
48
+ },
49
+
50
+ "incr" => lambda { |dest, incval = 1|
51
+ @variables[dest] += incval
52
+ },
53
+
54
+ "decr" => lambda { |dest, decrval = 1|
55
+ @variables[dest] -= decrval
56
+ },
57
+
58
+ "mov" => lambda { | src , dest |
59
+ @variables[dest] =
60
+ src.is_a?(Symbol) ?
61
+ @variables[src] : src
62
+ #new_var dest
63
+ },
64
+
65
+ "jlt" => lambda { |less, more|
66
+ req_args "jlt", 2
67
+ @@pc = @labels[name] if @stack[@stack.length - 1] < @stack[@stack.length - 2]
68
+ @stack.drop 2
69
+ },
70
+
71
+ "jge" => lambda { |name|
72
+ req_args "jge", 1
73
+ x = @stack.pop
74
+ y = @stack.pop
75
+ @@pc = @labels[name] if x >= y
76
+ },
77
+
78
+ "lt" => lambda { |a, b|
79
+ req_args "lt", 2
80
+ @stack.push (a > b)
81
+ },
82
+
83
+
84
+ "jmp" => lambda { |name|
85
+ @@pc = @labels[name]
86
+ },
87
+
88
+ "pop" => lambda {|val|
89
+ @variables[val] = @stack.pop
90
+ #new_var val
91
+ },
92
+
93
+ "push" => lambda {|src|
94
+ @stack.push(
95
+ src.is_a?(Symbol) ? @variables[src] : src )
96
+ },
97
+
98
+ "arg" => lambda { |*args|
99
+ if @stack.length != args.length
100
+ raise Exception.new "require: #{args}"
101
+ else
102
+ args.reverse.each do | arg |
103
+ @variables[arg] = @stack.pop
104
+ end
105
+ end
106
+ },
107
+
108
+ "req" => lambda {|amount|
109
+ raise Exception.new "require #{amount} #{ pluralize(amount, "argument") }." if @stack.length != amount
110
+ },
111
+
112
+ "dbg" => lambda {
113
+ puts @stack
114
+ },
115
+
116
+ "func" => lambda {|&block|
117
+ @stack.push block
118
+ },
119
+
120
+ "call" => lambda {|fname|
121
+ _method = method(fname)
122
+ if _method.parameters.length > 0
123
+ args = []
124
+ _method.parameters.length.times do
125
+ args.push @stack.pop
126
+ end
127
+ invoke = _method.call(args)
128
+ else
129
+ invoke = _method.call
130
+ end
131
+ #binding.pry
132
+ @stack.push invoke if !invoke.nil?
133
+ },
134
+
135
+ "exit" => lambda {
136
+ exit
137
+ }
138
+
139
+ #and so on
140
+ }
141
+
142
+ def create_label(lbl)
143
+ @labels[lbl] = @program.length-1
144
+ end
145
+
146
+ def method_missing(name, *args)
147
+
148
+ sname = name.to_s
149
+
150
+ if OPS.keys.include?(sname)
151
+ @program << [sname, args]
152
+
153
+ # TESTING FEATURE:
154
+ elsif @@function.include?(name)
155
+ @program << [sname, @@function[name].execute]
156
+
157
+ else
158
+
159
+ case sname
160
+
161
+ when "label"
162
+ create_label args.first
163
+
164
+ when "defn"
165
+ @name = args.first
166
+ create_label args.first
167
+
168
+ else
169
+ return name
170
+
171
+ end
172
+ end
173
+ end
174
+
175
+ def load_program(&block)
176
+ self.instance_exec(&block)
177
+ end
178
+
179
+ def execute(debug=false)
180
+ puts "function: #{@name}".white
181
+ begin
182
+ @@pc = 0
183
+ until(@@pc == @program.length)
184
+ # get instruction:
185
+ instr = @program[@@pc]
186
+ puts "#{instr}".light_green if debug
187
+ # execute proc:
188
+ self.instance_exec(*instr[1], &OPS[instr[0]])
189
+ #binding.pry if debug
190
+ @@pc += 1
191
+ end
192
+ @stack.last
193
+ rescue Exception => e
194
+ debug e, instr
195
+ end
196
+ end
197
+
198
+ def debug(e,instr)
199
+ # error scope:
200
+ debug_start = @@pc >= 1 ? @@pc - 1 : 0
201
+ debug_end = @@pc <= @program.length - 2 ?
202
+ @@pc + 2
203
+ : @program.length < 4 ? @program.length : @@pc + 4
204
+
205
+ # ranging...
206
+ (debug_start..debug_end).each do | i |
207
+ line = " #{i+1}: #{@program[i]}"
208
+ color = i != @@pc ? :light_green : :magenta
209
+ puts line.colorize color
210
+ end
211
+
212
+ puts "\nline #{@@pc+1}: #{ops_info(instr[0])}: #{e.message}".colorize(:magenta)
213
+ #puts e.backtrace
214
+
215
+ # test via pry:
216
+ binding.pry
217
+ end
218
+
219
+ def ops_info(name)
220
+ parameters = []
221
+ OPS[name].parameters.each {|pair| parameters << pair.last }
222
+ "#{name} [#{parameters.join(', ')}]"
223
+ end
224
+
225
+ def arguments(args=[])
226
+ args.each do | arg |
227
+ @stack << arg
228
+ end
229
+ end
230
+
231
+ def invoke(args=[],debug=false)
232
+ arguments args
233
+ execute debug
234
+ end
235
+
236
+ def clear
237
+ @variables = { }
238
+ @stack = []
239
+ end
240
+
241
+ def self.assemble (&block)
242
+ Asm.new.assemble &block
243
+ end
244
+
245
+ def assemble(&block)
246
+ load_program(&block)
247
+ self.dup
248
+ end
249
+ end
250
+
251
+
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asmrb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - The Trung
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-31 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Inteprete your assembly style code inside ruby.
14
+ email: deulamco@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/asm.rb
20
+ homepage: http://github.com/thetrung/asmrb.git
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubyforge_project:
40
+ rubygems_version: 2.4.5
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: assembly-like DSL in ruby
44
+ test_files: []
45
+ has_rdoc: