haxor 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +101 -335
- data/bin/{hcc → hc} +1 -9
- data/bin/hvm +13 -8
- data/examples/build.sh +1 -1
- data/examples/guess-the-number.hax +65 -76
- data/lib/haxor.rb +2 -14
- data/lib/haxor/compiler/core.rb +249 -18
- data/lib/haxor/consts.rb +4 -17
- data/lib/haxor/linker.rb +12 -4
- data/lib/haxor/token/cmd.rb +29 -2
- data/lib/haxor/utils.rb +24 -0
- data/lib/haxor/vm/core.rb +6 -9
- data/lib/haxor/vm/cpu/core.rb +214 -83
- data/lib/haxor/vm/mem.rb +1 -36
- data/lib/haxor/vm/os.rb +7 -13
- data/lib/haxor/vm/stack.rb +4 -4
- data/media/memory.png +0 -0
- metadata +5 -19
- data/lib/haxor/compiler/component/arithmetic.rb +0 -45
- data/lib/haxor/compiler/component/base.rb +0 -41
- data/lib/haxor/compiler/component/data.rb +0 -32
- data/lib/haxor/compiler/component/jumps.rb +0 -83
- data/lib/haxor/compiler/component/logical.rb +0 -35
- data/lib/haxor/compiler/component/other.rb +0 -21
- data/lib/haxor/compiler/component/transfer.rb +0 -25
- data/lib/haxor/compiler/component/various.rb +0 -30
- data/lib/haxor/vm/cpu/unit/arithmetic.rb +0 -78
- data/lib/haxor/vm/cpu/unit/base.rb +0 -46
- data/lib/haxor/vm/cpu/unit/jumps.rb +0 -118
- data/lib/haxor/vm/cpu/unit/logical.rb +0 -59
- data/lib/haxor/vm/cpu/unit/transfer.rb +0 -37
- data/lib/haxor/vm/cpu/unit/various.rb +0 -47
- data/media/vm.png +0 -0
data/bin/{hcc → hc}
RENAMED
@@ -4,7 +4,7 @@ require_relative '../lib/haxor'
|
|
4
4
|
require 'optparse'
|
5
5
|
|
6
6
|
parser = OptionParser.new do |opts|
|
7
|
-
opts.banner = 'Usage:
|
7
|
+
opts.banner = 'Usage: hc [options] [file.hax]'
|
8
8
|
|
9
9
|
opts.on_tail('-h', '--help', 'Show this message') do
|
10
10
|
puts opts
|
@@ -28,12 +28,4 @@ end
|
|
28
28
|
source = File.absolute_path ARGV[0]
|
29
29
|
|
30
30
|
compiler = Haxor::Compiler::Core.new
|
31
|
-
compiler.register_unit Haxor::Compiler::Component::Arithmetic.new
|
32
|
-
compiler.register_unit Haxor::Compiler::Component::Data.new
|
33
|
-
compiler.register_unit Haxor::Compiler::Component::Jumps.new
|
34
|
-
compiler.register_unit Haxor::Compiler::Component::Logical.new
|
35
|
-
compiler.register_unit Haxor::Compiler::Component::Other.new
|
36
|
-
compiler.register_unit Haxor::Compiler::Component::Transfer.new
|
37
|
-
compiler.register_unit Haxor::Compiler::Component::Various.new
|
38
|
-
|
39
31
|
compiler.compile source
|
data/bin/hvm
CHANGED
@@ -26,11 +26,16 @@ if ARGV[0].nil?
|
|
26
26
|
exit
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
vm.
|
29
|
+
begin
|
30
|
+
vm = Haxor::Vm::Core.new
|
31
|
+
|
32
|
+
filename = ARGV[0]
|
33
|
+
# make life easier ;)
|
34
|
+
filename += '.e' if filename.end_with? '.hax'
|
35
|
+
|
36
|
+
vm.load_program filename
|
37
|
+
vm.execute
|
38
|
+
rescue => e
|
39
|
+
puts "An error occurred: #{e}."
|
40
|
+
exit 1
|
41
|
+
end
|
data/examples/build.sh
CHANGED
@@ -11,90 +11,79 @@ dw min, 1
|
|
11
11
|
dw max, 1000
|
12
12
|
|
13
13
|
section .bss
|
14
|
-
dw number
|
15
|
-
dw answer
|
16
|
-
dw tries
|
14
|
+
dw number
|
15
|
+
dw answer
|
16
|
+
dw tries
|
17
17
|
|
18
18
|
section .text
|
19
|
-
label bigger
|
20
|
-
mov sc, 02h
|
21
|
-
lea r01, bigger_msg
|
22
|
-
push r01
|
23
|
-
push 1
|
24
|
-
syscall
|
25
|
-
jmp question
|
26
19
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
jmp question
|
20
|
+
bigger:
|
21
|
+
addi $sc, $0, 01h
|
22
|
+
pushi bigger_msg
|
23
|
+
pushi 1
|
24
|
+
syscall
|
25
|
+
j question
|
34
26
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
syscall
|
42
|
-
jmp exit
|
27
|
+
smaller:
|
28
|
+
addi $sc, $0, 01h
|
29
|
+
pushi smaller_msg
|
30
|
+
pushi 1
|
31
|
+
syscall
|
32
|
+
j question
|
43
33
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
push 1
|
49
|
-
syscall
|
50
|
-
|
34
|
+
win:
|
35
|
+
addi $sc, $0, 01h
|
36
|
+
pushm tries
|
37
|
+
pushi win_msg
|
38
|
+
push 1
|
39
|
+
syscall
|
40
|
+
exiti 0
|
51
41
|
|
52
|
-
|
42
|
+
invalid_number:
|
43
|
+
addi $sc, $0, 01h
|
44
|
+
pushi invalid_msg
|
45
|
+
push 1
|
46
|
+
syscall
|
47
|
+
j question
|
53
48
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
push
|
58
|
-
|
59
|
-
syscall
|
49
|
+
main:
|
50
|
+
addi $sc, $0, 01h
|
51
|
+
pushi welcome_msg
|
52
|
+
push 1
|
53
|
+
syscall
|
60
54
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
pop number
|
55
|
+
generate:
|
56
|
+
addi $sc, $0, 01h
|
57
|
+
pushm max
|
58
|
+
pushm min
|
59
|
+
pushi generate_msg
|
60
|
+
pushi 1
|
61
|
+
syscall
|
62
|
+
addi $sc, $0, 03h
|
63
|
+
pushm max
|
64
|
+
pushm min
|
65
|
+
syscall
|
66
|
+
popm number
|
74
67
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
push r01
|
86
|
-
push 0
|
87
|
-
syscall
|
88
|
-
cmp sc, -1
|
89
|
-
je invalid_number
|
90
|
-
inc tries
|
68
|
+
question:
|
69
|
+
addi $sc, $0, 01h
|
70
|
+
pushi question_msg
|
71
|
+
pushi 1
|
72
|
+
syscall
|
73
|
+
addi $sc, $0, 02h
|
74
|
+
pushi answer
|
75
|
+
pushi answer_fmt
|
76
|
+
pushi 0
|
77
|
+
syscall
|
91
78
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
79
|
+
addi $5, $0, -1
|
80
|
+
beq $sc, $5, invalid_number
|
81
|
+
lw $6, $0, tries
|
82
|
+
addi $6, $6, 1
|
83
|
+
sw $0, tries, $6
|
96
84
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
85
|
+
lw $7, $0, number
|
86
|
+
lw $8, $0, answer
|
87
|
+
beq $7, $8, win
|
88
|
+
bgt $7, $8, bigger
|
89
|
+
blt $7, $8, smaller
|
data/lib/haxor.rb
CHANGED
@@ -3,9 +3,11 @@ require 'json'
|
|
3
3
|
require 'io/console'
|
4
4
|
require 'scanf'
|
5
5
|
require 'digest'
|
6
|
+
require 'ostruct'
|
6
7
|
|
7
8
|
require_relative 'haxor/consts'
|
8
9
|
require_relative 'haxor/header'
|
10
|
+
require_relative 'haxor/utils'
|
9
11
|
|
10
12
|
# vm
|
11
13
|
require_relative 'haxor/vm/core'
|
@@ -15,24 +17,10 @@ require_relative 'haxor/vm/stack'
|
|
15
17
|
require_relative 'haxor/vm/os'
|
16
18
|
require_relative 'haxor/vm/registers'
|
17
19
|
require_relative 'haxor/vm/cpu/core'
|
18
|
-
require_relative 'haxor/vm/cpu/unit/base'
|
19
|
-
require_relative 'haxor/vm/cpu/unit/logical'
|
20
|
-
require_relative 'haxor/vm/cpu/unit/arithmetic'
|
21
|
-
require_relative 'haxor/vm/cpu/unit/jumps'
|
22
|
-
require_relative 'haxor/vm/cpu/unit/various'
|
23
|
-
require_relative 'haxor/vm/cpu/unit/transfer'
|
24
20
|
|
25
21
|
# compiler
|
26
22
|
require_relative 'haxor/compiler/unit'
|
27
23
|
require_relative 'haxor/compiler/core'
|
28
|
-
require_relative 'haxor/compiler/component/base'
|
29
|
-
require_relative 'haxor/compiler/component/logical'
|
30
|
-
require_relative 'haxor/compiler/component/arithmetic'
|
31
|
-
require_relative 'haxor/compiler/component/jumps'
|
32
|
-
require_relative 'haxor/compiler/component/various'
|
33
|
-
require_relative 'haxor/compiler/component/transfer'
|
34
|
-
require_relative 'haxor/compiler/component/data'
|
35
|
-
require_relative 'haxor/compiler/component/other'
|
36
24
|
|
37
25
|
# linker
|
38
26
|
require_relative 'haxor/linker'
|
data/lib/haxor/compiler/core.rb
CHANGED
@@ -1,25 +1,85 @@
|
|
1
1
|
module Haxor
|
2
2
|
module Compiler
|
3
3
|
class Core
|
4
|
+
REG_ALIASES = {
|
5
|
+
'$sp' => Vm::Cpu::Core::REG_STACK,
|
6
|
+
'$ret' => Vm::Cpu::Core::REG_RETURN,
|
7
|
+
'$sc' => Vm::Cpu::Core::REG_SYSCALL
|
8
|
+
}
|
9
|
+
|
4
10
|
def initialize
|
5
11
|
@units = []
|
6
|
-
@cmds =
|
12
|
+
@cmds = []
|
7
13
|
@autolabel = 0
|
8
14
|
@prev_sections = []
|
9
15
|
|
10
|
-
|
16
|
+
init_cmds
|
11
17
|
end
|
12
18
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
19
|
+
def init_cmds
|
20
|
+
bind_cmd 'section', [:any], :cmd_section
|
21
|
+
bind_cmd 'dw', [:wildcard], :cmd_dw
|
22
|
+
bind_cmd 'resw', [:any], :cmd_resw
|
23
|
+
bind_cmd '#', [:wildcard], :cmd_rem
|
24
|
+
bind_cmd 'push', [:reg], :cmd_push
|
25
|
+
bind_cmd 'pushi', [:imm], :cmd_pushi
|
26
|
+
bind_cmd 'pushm', [:imm], :cmd_pushm
|
27
|
+
bind_cmd 'pop', [:reg], :cmd_pop
|
28
|
+
bind_cmd 'popm', [:imm], :cmd_popm
|
29
|
+
bind_cmd 'move', [:reg, :reg], :cmd_move
|
30
|
+
bind_cmd 'clear', [:reg], :cmd_clear
|
31
|
+
bind_cmd 'not', [:reg, :reg], :cmd_not
|
32
|
+
bind_cmd 'ret', [], :cmd_ret
|
33
|
+
|
34
|
+
bind_cmd 'b', [:imm], :cmd_b
|
35
|
+
bind_cmd 'bal', [:imm], :cmd_bal
|
36
|
+
bind_cmd 'bgt', [:reg, :reg, :imm], :cmd_bgt
|
37
|
+
bind_cmd 'blt', [:reg, :reg, :imm], :cmd_blt
|
38
|
+
bind_cmd 'bge', [:reg, :reg, :imm], :cmd_bge
|
39
|
+
bind_cmd 'ble', [:reg, :reg, :imm], :cmd_ble
|
40
|
+
bind_cmd 'blez', [:reg, :imm], :cmd_blez
|
41
|
+
bind_cmd 'bgtz', [:reg, :imm], :cmd_bgtz
|
42
|
+
bind_cmd 'beqz', [:reg, :imm], :cmd_beqz
|
43
|
+
|
44
|
+
bind_cmd 'nop', [], Vm::Cpu::Core::OP_NOP
|
45
|
+
bind_cmd 'add', [:reg, :reg, :reg], Vm::Cpu::Core::OP_ADD
|
46
|
+
bind_cmd 'addi', [:reg, :reg, :imm], Vm::Cpu::Core::OP_ADDI
|
47
|
+
bind_cmd 'sub', [:reg, :reg, :reg], Vm::Cpu::Core::OP_SUB
|
48
|
+
bind_cmd 'mult', [:reg, :reg, :reg], Vm::Cpu::Core::OP_MULT
|
49
|
+
bind_cmd 'div', [:reg, :reg, :reg], Vm::Cpu::Core::OP_DIV
|
50
|
+
bind_cmd 'mod', [:reg, :reg, :reg], Vm::Cpu::Core::OP_MOD
|
51
|
+
bind_cmd 'lw', [:reg, :reg, :imm], Vm::Cpu::Core::OP_LW
|
52
|
+
bind_cmd 'sw', [:reg, :imm, :reg], Vm::Cpu::Core::OP_SW
|
53
|
+
bind_cmd 'lui', [:reg, :imm], Vm::Cpu::Core::OP_LUI
|
54
|
+
bind_cmd 'and', [:reg, :reg, :reg], Vm::Cpu::Core::OP_AND
|
55
|
+
bind_cmd 'andi', [:reg, :reg, :imm], Vm::Cpu::Core::OP_ANDI
|
56
|
+
bind_cmd 'or', [:reg, :reg, :reg], Vm::Cpu::Core::OP_OR
|
57
|
+
bind_cmd 'ori', [:reg, :reg, :imm], Vm::Cpu::Core::OP_ORI
|
58
|
+
bind_cmd 'xor', [:reg, :reg, :reg], Vm::Cpu::Core::OP_XOR
|
59
|
+
bind_cmd 'nor', [:reg, :reg, :reg], Vm::Cpu::Core::OP_NOR
|
60
|
+
bind_cmd 'slt', [:reg, :reg, :reg], Vm::Cpu::Core::OP_SLT
|
61
|
+
bind_cmd 'slti', [:reg, :reg, :imm], Vm::Cpu::Core::OP_SLTI
|
62
|
+
bind_cmd 'slli', [:reg, :reg, :imm], Vm::Cpu::Core::OP_SLLI
|
63
|
+
bind_cmd 'srli', [:reg, :reg, :imm], Vm::Cpu::Core::OP_SRLI
|
64
|
+
bind_cmd 'sll', [:reg, :reg, :reg], Vm::Cpu::Core::OP_SLL
|
65
|
+
bind_cmd 'srl', [:reg, :reg, :reg], Vm::Cpu::Core::OP_SRL
|
66
|
+
bind_cmd 'beq', [:reg, :reg, :imm], Vm::Cpu::Core::OP_BEQ, [:rel_imm, :x8]
|
67
|
+
bind_cmd 'beql', [:reg, :reg, :imm], Vm::Cpu::Core::OP_BEQL, [:rel_imm, :x8]
|
68
|
+
bind_cmd 'bne', [:reg, :reg, :imm], Vm::Cpu::Core::OP_BNE, [:rel_imm, :x8]
|
69
|
+
bind_cmd 'bnel', [:reg, :reg, :imm], Vm::Cpu::Core::OP_BNEL, [:rel_imm, :x8]
|
70
|
+
bind_cmd 'j', [:imm], Vm::Cpu::Core::OP_J, [:x8]
|
71
|
+
bind_cmd 'jr', [:reg], Vm::Cpu::Core::OP_JR
|
72
|
+
bind_cmd 'jal', [:imm], Vm::Cpu::Core::OP_JAL, [:x8]
|
73
|
+
bind_cmd 'exiti', [:imm], Vm::Cpu::Core::OP_EXITI
|
74
|
+
bind_cmd 'syscall', [], Vm::Cpu::Core::OP_SYSCALL
|
17
75
|
end
|
18
76
|
|
19
|
-
def bind_cmd(cmd,
|
20
|
-
@cmds
|
21
|
-
|
22
|
-
|
77
|
+
def bind_cmd(cmd, args, opcode, opts = [])
|
78
|
+
@cmds << {
|
79
|
+
cmd: cmd,
|
80
|
+
args: args,
|
81
|
+
opcode: opcode,
|
82
|
+
opts: opts
|
23
83
|
}
|
24
84
|
end
|
25
85
|
|
@@ -27,6 +87,122 @@ module Haxor
|
|
27
87
|
@unit.section = name[1..-1].to_sym
|
28
88
|
end
|
29
89
|
|
90
|
+
def cmd_dw(*args)
|
91
|
+
add Token::Label.new(args[0])
|
92
|
+
|
93
|
+
if args.size == 1
|
94
|
+
add Token::Int64.new(0)
|
95
|
+
else
|
96
|
+
(1...args.size).each do |i|
|
97
|
+
begin
|
98
|
+
add Token::Int64.new(Integer(args[i]))
|
99
|
+
rescue
|
100
|
+
args[i][1...-1].each_char do |c|
|
101
|
+
add Token::Int64.new(c.ord)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def cmd_resw(*args)
|
109
|
+
(1..args[0].to_i).each do
|
110
|
+
add Token::Int64.new(0)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def cmd_rem(*)
|
115
|
+
end
|
116
|
+
|
117
|
+
def cmd_push(*args)
|
118
|
+
process_cmd 'addi', ['$sp', '$sp', '-' + Consts::WORD_SIZE.to_s]
|
119
|
+
process_cmd 'sw', ['$sp', '0', args[0]]
|
120
|
+
end
|
121
|
+
|
122
|
+
def cmd_pushi(*args)
|
123
|
+
process_cmd 'addi', ['$1', '$0', args[0]]
|
124
|
+
process_cmd 'addi', ['$sp', '$sp', '-' + Consts::WORD_SIZE.to_s]
|
125
|
+
process_cmd 'sw', ['$sp', '0', '$1']
|
126
|
+
end
|
127
|
+
|
128
|
+
def cmd_pushm(*args)
|
129
|
+
process_cmd 'lw', ['$1', '$0', args[0]]
|
130
|
+
process_cmd 'addi', ['$sp', '$sp', '-' + Consts::WORD_SIZE.to_s]
|
131
|
+
process_cmd 'sw', ['$sp', '0', '$1']
|
132
|
+
end
|
133
|
+
|
134
|
+
def cmd_pop(*args)
|
135
|
+
process_cmd 'lw', [args[0], '$sp', '0']
|
136
|
+
process_cmd 'addi', ['$sp', '$sp', Consts::WORD_SIZE.to_s]
|
137
|
+
end
|
138
|
+
|
139
|
+
def cmd_popm(*args)
|
140
|
+
process_cmd 'lw', ['$1', '$sp', '0']
|
141
|
+
process_cmd 'sw', ['$0', args[0], '$1']
|
142
|
+
process_cmd 'addi', ['$sp', '$sp', Consts::WORD_SIZE.to_s]
|
143
|
+
end
|
144
|
+
|
145
|
+
def cmd_move(*args)
|
146
|
+
process_cmd 'add', [args[0], args[1], '$0']
|
147
|
+
end
|
148
|
+
|
149
|
+
def cmd_clear(*args)
|
150
|
+
process_cmd 'add', [args[0], '$0', '$0']
|
151
|
+
end
|
152
|
+
|
153
|
+
def cmd_not(*args)
|
154
|
+
process_cmd 'nor', [args[0], args[1], '$0']
|
155
|
+
end
|
156
|
+
|
157
|
+
def cmd_ret(*_args)
|
158
|
+
process_cmd 'jr', ['$' + Vm::Cpu::Core::REG_RETURN.to_s]
|
159
|
+
end
|
160
|
+
|
161
|
+
def cmd_b(*args)
|
162
|
+
process_cmd 'beq', ['$0', '$0', args[0]]
|
163
|
+
end
|
164
|
+
|
165
|
+
def cmd_bal(*args)
|
166
|
+
process_cmd 'beql', ['$0', '$0', args[0]]
|
167
|
+
end
|
168
|
+
|
169
|
+
# branch is greater than
|
170
|
+
def cmd_bgt(*args)
|
171
|
+
process_cmd 'slt', ['$1', args[1], args[0]]
|
172
|
+
process_cmd 'bne', ['$1', '$0', args[2]]
|
173
|
+
end
|
174
|
+
|
175
|
+
# branch if less than
|
176
|
+
def cmd_blt(*args)
|
177
|
+
process_cmd 'slt', ['$1', args[0], args[1]]
|
178
|
+
process_cmd 'bne', ['$1', '$0', args[2]]
|
179
|
+
end
|
180
|
+
|
181
|
+
# branch is greater or equal
|
182
|
+
def cmd_bge(*args)
|
183
|
+
process_cmd 'slt', ['$1', args[0], args[1]]
|
184
|
+
process_cmd 'beq', ['$1', '$0', args[2]]
|
185
|
+
end
|
186
|
+
|
187
|
+
def cmd_ble(*args)
|
188
|
+
process_cmd 'slt', ['$1', args[1], args[0]]
|
189
|
+
process_cmd 'beq', ['$1', '$0', args[2]]
|
190
|
+
end
|
191
|
+
|
192
|
+
def cmd_blez(*args)
|
193
|
+
process_cmd 'slt', ['$1', '$0', args[0]]
|
194
|
+
process_cmd 'beq', ['$1', '$0', args[1]]
|
195
|
+
end
|
196
|
+
|
197
|
+
def cmd_bgtz(*args)
|
198
|
+
process_cmd 'slt', ['$1', '$0', args[0]]
|
199
|
+
process_cmd 'bne', ['$1', '$0', args[1]]
|
200
|
+
end
|
201
|
+
|
202
|
+
def cmd_beqz(*args)
|
203
|
+
process_cmd 'beq', [args[0], '$0', args[1]]
|
204
|
+
end
|
205
|
+
|
30
206
|
# this is ugly and must be reworked
|
31
207
|
def split_arguments(string)
|
32
208
|
inside_quotes = false
|
@@ -52,6 +228,23 @@ module Haxor
|
|
52
228
|
args.map!(&:strip).delete_if { |x| x.length == 0 }
|
53
229
|
end
|
54
230
|
|
231
|
+
def process_cmd(cmd, args)
|
232
|
+
@cmds.each do |item|
|
233
|
+
next if item[:cmd] != cmd
|
234
|
+
|
235
|
+
if item[:opcode].is_a? Symbol
|
236
|
+
send(item[:opcode], *args)
|
237
|
+
return
|
238
|
+
end
|
239
|
+
|
240
|
+
add_cmd item, args
|
241
|
+
return
|
242
|
+
end
|
243
|
+
|
244
|
+
puts cmd
|
245
|
+
fail
|
246
|
+
end
|
247
|
+
|
55
248
|
def compile(filename)
|
56
249
|
input = File.read(filename, encoding: 'ASCII-8BIT')
|
57
250
|
|
@@ -64,9 +257,11 @@ module Haxor
|
|
64
257
|
cmd = tmp[0]
|
65
258
|
args = split_arguments(tmp[1] || '')
|
66
259
|
|
67
|
-
|
68
|
-
|
69
|
-
|
260
|
+
if cmd[-1] == ':'
|
261
|
+
add Token::Label.new(cmd[0...-1])
|
262
|
+
else
|
263
|
+
process_cmd(cmd, args)
|
264
|
+
end
|
70
265
|
end
|
71
266
|
|
72
267
|
@unit.save(filename + '.u')
|
@@ -76,11 +271,47 @@ module Haxor
|
|
76
271
|
@unit.add token
|
77
272
|
end
|
78
273
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
274
|
+
# def resolve_arg(a, type)
|
275
|
+
# case type
|
276
|
+
# when :reg
|
277
|
+
# return a[1..-1].to_i
|
278
|
+
# when :imm
|
279
|
+
# return a.to_i
|
280
|
+
# else
|
281
|
+
# fail
|
282
|
+
# end
|
283
|
+
# end
|
284
|
+
|
285
|
+
def add_cmd(info, args = [])
|
286
|
+
registers = []
|
287
|
+
immediate = 0
|
288
|
+
info[:args].each_with_index do |type, index|
|
289
|
+
if type == :reg
|
290
|
+
if REG_ALIASES.key? args[index]
|
291
|
+
registers << REG_ALIASES[args[index]]
|
292
|
+
else
|
293
|
+
registers << args[index][1..-1].to_i
|
294
|
+
end
|
295
|
+
elsif type == :imm
|
296
|
+
begin
|
297
|
+
immediate = parse_number args[index]
|
298
|
+
rescue
|
299
|
+
immediate = args[index]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
registers.fill 0, registers.size...3
|
305
|
+
|
306
|
+
token = Token::Cmd.new
|
307
|
+
token.cmd = info[:opcode]
|
308
|
+
token.reg1 = registers[0]
|
309
|
+
token.reg2 = registers[1]
|
310
|
+
token.reg3 = registers[2]
|
311
|
+
token.imm = immediate
|
312
|
+
token.opts = info[:opts]
|
313
|
+
|
314
|
+
add token
|
84
315
|
end
|
85
316
|
|
86
317
|
def parse_number(value)
|