haxor 0.1.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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +27 -0
  6. data/README.md +414 -0
  7. data/Rakefile +1 -0
  8. data/bin/hcc +21 -0
  9. data/bin/hld +38 -0
  10. data/bin/hvm +17 -0
  11. data/examples/build.sh +10 -0
  12. data/examples/guess-the-number.hax +100 -0
  13. data/haxor.gemspec +24 -0
  14. data/lib/haxor.rb +44 -0
  15. data/lib/haxor/compiler/component/arithmetic.rb +55 -0
  16. data/lib/haxor/compiler/component/base.rb +37 -0
  17. data/lib/haxor/compiler/component/data.rb +32 -0
  18. data/lib/haxor/compiler/component/jumps.rb +95 -0
  19. data/lib/haxor/compiler/component/logical.rb +43 -0
  20. data/lib/haxor/compiler/component/other.rb +21 -0
  21. data/lib/haxor/compiler/component/transfer.rb +29 -0
  22. data/lib/haxor/compiler/component/various.rb +33 -0
  23. data/lib/haxor/compiler/core.rb +134 -0
  24. data/lib/haxor/compiler/section.rb +6 -0
  25. data/lib/haxor/compiler/unit.rb +39 -0
  26. data/lib/haxor/consts.rb +28 -0
  27. data/lib/haxor/header.rb +40 -0
  28. data/lib/haxor/linker.rb +89 -0
  29. data/lib/haxor/token/base.rb +7 -0
  30. data/lib/haxor/token/cmd.rb +9 -0
  31. data/lib/haxor/token/data.rb +17 -0
  32. data/lib/haxor/token/int64.rb +17 -0
  33. data/lib/haxor/token/label.rb +23 -0
  34. data/lib/haxor/token/pointer.rb +13 -0
  35. data/lib/haxor/vm/core.rb +53 -0
  36. data/lib/haxor/vm/cpu/core.rb +129 -0
  37. data/lib/haxor/vm/cpu/unit/arithmetic.rb +92 -0
  38. data/lib/haxor/vm/cpu/unit/base.rb +46 -0
  39. data/lib/haxor/vm/cpu/unit/jumps.rb +123 -0
  40. data/lib/haxor/vm/cpu/unit/logical.rb +59 -0
  41. data/lib/haxor/vm/cpu/unit/transfer.rb +37 -0
  42. data/lib/haxor/vm/cpu/unit/various.rb +47 -0
  43. data/lib/haxor/vm/mem.rb +101 -0
  44. data/lib/haxor/vm/os.rb +115 -0
  45. data/lib/haxor/vm/stack.rb +31 -0
  46. data/lib/haxor/vm/subsystem.rb +16 -0
  47. data/media/memory.png +0 -0
  48. data/media/vm.png +0 -0
  49. metadata +122 -0
@@ -0,0 +1,59 @@
1
+ module Haxor
2
+ module Vm
3
+ module Cpu
4
+ module Unit
5
+ class Logical < Base
6
+ # 0x40
7
+ OP_AND = 0x40 # and a, b
8
+ OP_NEG = 0x41 # neg a
9
+ OP_NOT = 0x42 # not a
10
+ OP_OR = 0x43 # or a, b
11
+ OP_XOR = 0x44 # xor a, b
12
+ # 0x5f
13
+
14
+ def register
15
+ bind_opcode OP_AND, :op_and
16
+ bind_opcode OP_NEG, :op_neg
17
+ bind_opcode OP_NOT, :op_not
18
+ bind_opcode OP_OR, :op_or
19
+ bind_opcode OP_XOR, :op_xor
20
+ end
21
+
22
+ def op_and
23
+ a, b = operands
24
+ av = @vm.subsystem(:mem).read a
25
+ bv = @vm.subsystem(:mem).read b
26
+ v = av & bv
27
+ @vm.subsystem(:mem).write a, v
28
+ end
29
+
30
+ def op_neg
31
+ a = operand
32
+ av = @vm.subsystem(:mem).read a
33
+ @vm.subsystem(:mem).write a, -av
34
+ end
35
+
36
+ def op_not
37
+ a = operand
38
+ av = @vm.subsystem(:mem).read a
39
+ @vm.subsystem(:mem).write a, ~av
40
+ end
41
+
42
+ def op_or
43
+ a, b = operands
44
+ av = @vm.subsystem(:mem).read a
45
+ bv = @vm.subsystem(:mem).read b
46
+ @vm.subsystem(:mem).write a, (av | bv)
47
+ end
48
+
49
+ def op_xor
50
+ a, b = operands
51
+ av = @vm.subsystem(:mem).read a
52
+ bv = @vm.subsystem(:mem).read b
53
+ @vm.subsystem(:mem).write a, (av ^ bv)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,37 @@
1
+ module Haxor
2
+ module Vm
3
+ module Cpu
4
+ module Unit
5
+ class Transfer < Base
6
+ # 0x60
7
+ OP_MOV = 0x60 # mov a, b
8
+ OP_PUSH = 0x61 # push a
9
+ OP_POP = 0x62 # pop a
10
+ # 0x7f
11
+
12
+ def register
13
+ bind_opcode OP_MOV, :op_mov
14
+ bind_opcode OP_PUSH, :op_push
15
+ bind_opcode OP_POP, :op_pop
16
+ end
17
+
18
+ def op_mov
19
+ a, b = operands
20
+ v = @vm.subsystem(:mem).read b
21
+ @vm.subsystem(:mem).write a, v
22
+ end
23
+
24
+ def op_push
25
+ a = operand
26
+ @vm.subsystem(:stack).push a
27
+ end
28
+
29
+ def op_pop
30
+ a = operand
31
+ @vm.subsystem(:stack).pop a
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,47 @@
1
+ module Haxor
2
+ module Vm
3
+ module Cpu
4
+ module Unit
5
+ class Various < Base
6
+ # = 0x80
7
+ OP_LEA = 0x80 # lea a
8
+ OP_NOP = 0x81 # nop
9
+ OP_INT = 0x85 # int a
10
+ OP_SYSCALL = 0x86 # syscall
11
+ # 0x9f
12
+
13
+ def register
14
+ bind_opcode OP_LEA, :op_lea
15
+ bind_opcode OP_NOP, :op_nop
16
+ bind_opcode OP_INT, :op_int
17
+ bind_opcode OP_SYSCALL, :op_syscall
18
+ end
19
+
20
+ def op_lea
21
+ a, b = operands
22
+ @vm.subsystem(:mem).write a, b
23
+ end
24
+
25
+ def op_nop
26
+ # intentionally nothing here
27
+ end
28
+
29
+ def op_int
30
+ a = operand
31
+
32
+ @vm.subsystem(:stack).push 'ip'
33
+
34
+ av = @vm.subsystem(:mem).read a
35
+ ivt = Consts::IVT_ADDR + (av * 8)
36
+ handler = @vm.subsystem(:mem).read ivt
37
+ @vm.subsystem(:mem).write 'ip', handler
38
+ end
39
+
40
+ def op_syscall
41
+ @vm.subsystem(:os).syscall
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,101 @@
1
+ module Haxor
2
+ module Vm
3
+ class Mem < Subsystem
4
+ attr_accessor :memory
5
+
6
+ def initialize(bytes)
7
+ @memory = Array.new(bytes, 0).pack('C*')
8
+ @labels = {}
9
+ end
10
+
11
+ def size
12
+ @memory.size
13
+ end
14
+
15
+ def enlarge(bytes)
16
+ replace_region size, Array.new(bytes, 0).pack('C*')
17
+ end
18
+
19
+ # Adds label
20
+ #
21
+ # @param name [String] Name of label
22
+ # @param addr [Integer] Address in memory to point to
23
+ def add_label(name, addr)
24
+ fail if @labels.key? name
25
+ @labels[name] = addr
26
+ end
27
+
28
+ # Reads word from memory
29
+ #
30
+ # @param addr [String|Integer] Label or address in memory
31
+ # @return [Integer] Data stored under specified address
32
+ def read(addr)
33
+ @memory[resolve addr].unpack(Consts::WORD_UNPACK)[0]
34
+ end
35
+
36
+ # Writes word to memory
37
+ #
38
+ # @param addr [String|Integer] Label or address in memory
39
+ # @param value [Integer] Data to store under specified address
40
+ def write(addr, value)
41
+ @memory[resolve addr] = [value].pack(Consts::WORD_UNPACK)
42
+ end
43
+
44
+ def write_string(addr, value)
45
+ i = 0
46
+ value.each_char do |x|
47
+ write addr + i, x.ord
48
+ i += Consts::WORD_SIZE
49
+ end
50
+
51
+ write addr + i, 0
52
+ end
53
+
54
+ def replace_region(addr, data)
55
+ x = addr + data.size
56
+ @memory[addr...x] = data
57
+ end
58
+
59
+ # (see #read)
60
+ def dereference(addr)
61
+ read addr
62
+ end
63
+
64
+ # Reads data pointed by IP register and moves IP forward
65
+ #
66
+ # @return [Integer] Data stored under address pointed by IP
67
+ def next_word
68
+ data = read ip
69
+ move_ip Consts::WORD_SIZE
70
+ data
71
+ end
72
+
73
+ # TODO: BC
74
+ def next_cell
75
+ next_word
76
+ end
77
+
78
+ def ip
79
+ read 'ip'
80
+ end
81
+
82
+ def move_ip(step)
83
+ write 'ip', ip + step
84
+ end
85
+
86
+ def label(name)
87
+ @labels[addr]
88
+ end
89
+
90
+ private
91
+
92
+ def resolve(addr)
93
+ if addr.is_a? String
94
+ fail "Unknown label #{addr}." unless @labels.key? addr
95
+ addr = @labels[addr]
96
+ end
97
+ Range.new(addr, addr + Consts::WORD_SIZE, true)
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,115 @@
1
+ module Haxor
2
+ module Vm
3
+ class Os < Subsystem
4
+ TABLE = {
5
+ 0x01 => :sys_exit,
6
+ 0x02 => :sys_printf,
7
+ 0x03 => :sys_scanf,
8
+ 0x04 => :sys_rand
9
+ }
10
+
11
+ def syscall
12
+ func = subsystem(:mem).read 'sc'
13
+ send(TABLE[func])
14
+ end
15
+
16
+ def collect_string(addr)
17
+ i = 0
18
+ string = ''
19
+ loop do
20
+ char = @vm.subsystem(:mem).read(addr + i)
21
+ break if char == 0
22
+ string << char.ord
23
+
24
+ i += Consts::WORD_SIZE
25
+ end
26
+
27
+ string
28
+ end
29
+
30
+ def parse_format(fmt)
31
+ fmt = fmt.tr '^A-Za-z%', ''
32
+ fmt = fmt.gsub '%%', ''
33
+
34
+ types = []
35
+ last_char = nil
36
+ fmt.each_char do |char|
37
+ if last_char == '%'
38
+ if %w(b B d i o u x X).include? char
39
+ types << :integer
40
+ elsif %w(c s).include? char
41
+ types << :string
42
+ else
43
+ fail
44
+ end
45
+ end
46
+
47
+ last_char = char
48
+ end
49
+
50
+ types
51
+ end
52
+
53
+ def sys_exit
54
+ code = subsystem(:stack).pop_value
55
+ exit code
56
+ end
57
+
58
+ def sys_printf
59
+ fd = subsystem(:stack).pop_value
60
+
61
+ x = subsystem(:stack).pop_value
62
+ fmt = collect_string x
63
+ args = []
64
+ parse_format(fmt).each do |type|
65
+ case type
66
+ when :string
67
+ args << collect_string(subsystem(:stack).pop_value)
68
+ when :integer
69
+ args << subsystem(:stack).pop_value
70
+ else
71
+ fail
72
+ end
73
+ end
74
+
75
+ file = IO.new(fd, 'a')
76
+ file.write sprintf(fmt, *args)
77
+ end
78
+
79
+ def sys_scanf
80
+ fd = subsystem(:stack).pop_value
81
+ fmt = collect_string subsystem(:stack).pop_value
82
+ types = parse_format fmt
83
+
84
+ file = IO.new(fd, 'r')
85
+ result = file.scanf fmt
86
+
87
+ if result.size != types.size
88
+ subsystem(:mem).write 'sc', -1
89
+ return
90
+ end
91
+
92
+ types.each do |type|
93
+ value = result.shift
94
+
95
+ case type
96
+ when :string
97
+ subsystem(:mem).write_string subsystem(:stack).pop_value, value
98
+ when :integer
99
+ subsystem(:mem).write subsystem(:stack).pop_value, value
100
+ else
101
+ fail
102
+ end
103
+ end
104
+ end
105
+
106
+ def sys_rand
107
+ min = subsystem(:stack).pop_value
108
+ max = subsystem(:stack).pop_value
109
+
110
+ prng = Random.new
111
+ subsystem(:stack).push_value prng.rand(min..max)
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,31 @@
1
+ module Haxor
2
+ module Vm
3
+ class Stack < Subsystem
4
+ def push(addr)
5
+ value = @vm.subsystem(:mem).read addr
6
+ push_value value
7
+ end
8
+
9
+ def push_value(value)
10
+ sp = @vm.subsystem(:mem).read 'sp'
11
+ sp -= Consts::WORD_SIZE
12
+ @vm.subsystem(:mem).write 'sp', sp
13
+ @vm.subsystem(:mem).write sp, value
14
+ end
15
+
16
+ def pop(addr)
17
+ value = pop_value
18
+ @vm.subsystem(:mem).write addr, value
19
+ end
20
+
21
+ def pop_value
22
+ sp = @vm.subsystem(:mem).read 'sp'
23
+ value = @vm.subsystem(:mem).read sp
24
+ sp += Consts::WORD_SIZE
25
+ @vm.subsystem(:mem).write 'sp', sp
26
+
27
+ value
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ module Haxor
2
+ module Vm
3
+ class Subsystem
4
+ attr_accessor :vm
5
+
6
+ def register
7
+ # method called after registering to VM
8
+ end
9
+
10
+ # shortcut
11
+ def subsystem(id)
12
+ @vm.subsystem(id)
13
+ end
14
+ end
15
+ end
16
+ end
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haxor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Krzysztof Magosa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Please follow to GitHub repository for more information.
42
+ email:
43
+ - krzysztof@magosa.pl
44
+ executables:
45
+ - hcc
46
+ - hld
47
+ - hvm
48
+ extensions: []
49
+ extra_rdoc_files: []
50
+ files:
51
+ - ".gitignore"
52
+ - ".travis.yml"
53
+ - Gemfile
54
+ - LICENSE.txt
55
+ - README.md
56
+ - Rakefile
57
+ - bin/hcc
58
+ - bin/hld
59
+ - bin/hvm
60
+ - examples/build.sh
61
+ - examples/guess-the-number.hax
62
+ - haxor.gemspec
63
+ - lib/haxor.rb
64
+ - lib/haxor/compiler/component/arithmetic.rb
65
+ - lib/haxor/compiler/component/base.rb
66
+ - lib/haxor/compiler/component/data.rb
67
+ - lib/haxor/compiler/component/jumps.rb
68
+ - lib/haxor/compiler/component/logical.rb
69
+ - lib/haxor/compiler/component/other.rb
70
+ - lib/haxor/compiler/component/transfer.rb
71
+ - lib/haxor/compiler/component/various.rb
72
+ - lib/haxor/compiler/core.rb
73
+ - lib/haxor/compiler/section.rb
74
+ - lib/haxor/compiler/unit.rb
75
+ - lib/haxor/consts.rb
76
+ - lib/haxor/header.rb
77
+ - lib/haxor/linker.rb
78
+ - lib/haxor/token/base.rb
79
+ - lib/haxor/token/cmd.rb
80
+ - lib/haxor/token/data.rb
81
+ - lib/haxor/token/int64.rb
82
+ - lib/haxor/token/label.rb
83
+ - lib/haxor/token/pointer.rb
84
+ - lib/haxor/vm/core.rb
85
+ - lib/haxor/vm/cpu/core.rb
86
+ - lib/haxor/vm/cpu/unit/arithmetic.rb
87
+ - lib/haxor/vm/cpu/unit/base.rb
88
+ - lib/haxor/vm/cpu/unit/jumps.rb
89
+ - lib/haxor/vm/cpu/unit/logical.rb
90
+ - lib/haxor/vm/cpu/unit/transfer.rb
91
+ - lib/haxor/vm/cpu/unit/various.rb
92
+ - lib/haxor/vm/mem.rb
93
+ - lib/haxor/vm/os.rb
94
+ - lib/haxor/vm/stack.rb
95
+ - lib/haxor/vm/subsystem.rb
96
+ - media/memory.png
97
+ - media/vm.png
98
+ homepage: https://github.com/krzysztof-magosa/haxor
99
+ licenses:
100
+ - BSD-3
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.4.5.1
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Educational Assembly Language running on custom VM
122
+ test_files: []