haxor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []