hack_assembler 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.
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class AInstructionTest < Minitest::Test
4
+ def test_that_it_converts_zero
5
+ bytecode = AInstruction.translate('@0')
6
+ assert_equal '0000000000000000', bytecode
7
+ end
8
+
9
+ def test_that_it_converts_a_positive_value
10
+ bytecode = AInstruction.translate('@4')
11
+ assert_equal '0000000000000100', bytecode
12
+ end
13
+
14
+ def test_that_it_raises_parser_error_on_symbol
15
+ assert_raises(ParserError) { AInstruction.translate('@ERR') }
16
+ end
17
+
18
+ def test_that_it_raises_parser_error_on_missing_value
19
+ assert_raises(ParserError) { AInstruction.translate('@') }
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ class AssemblerTest < Minitest::Test
4
+ def test_translates_a_and_c_instructions
5
+ source_code = "@4\n" << "0;JMP\n"
6
+ bytecode = Assembler.translate(source_code)
7
+ assert_equal "0000000000000100\n" << "1110101010000111\n", bytecode
8
+ end
9
+
10
+ def test_ignores_comments
11
+ source_code = "// A comment\n" << "@4\n" << "// Another comment\n"
12
+ bytecode = Assembler.translate(source_code)
13
+ assert_equal "0000000000000100\n", bytecode
14
+ end
15
+
16
+ def test_ignores_empty_lines
17
+ source_code = "\n@4\n\n"
18
+ bytecode = Assembler.translate(source_code)
19
+ assert_equal "0000000000000100\n", bytecode
20
+ end
21
+
22
+ def test_ignores_indentation_and_trailing_spaces
23
+ source_code = " @4 \n"
24
+ bytecode = Assembler.translate(source_code)
25
+ assert_equal "0000000000000100\n", bytecode
26
+ end
27
+ end
@@ -0,0 +1,44 @@
1
+ require 'test_helper'
2
+
3
+ class CInstructionTest < Minitest::Test
4
+ def test_translation_of_unconditional_jump
5
+ bytecode = CInstruction.translate('0;JMP')
6
+ assert_equal '1110101010000111', bytecode
7
+ end
8
+
9
+ def test_translation_of_assignment
10
+ bytecode = CInstruction.translate('A=M+1')
11
+ assert_equal '1111110111100000', bytecode
12
+ end
13
+
14
+ def test_that_bad_instruction_raises_error
15
+ assert_raises(ParserError) { CInstruction.translate(';JMP') }
16
+ end
17
+
18
+ def test_that_computation_translator_writes_on_output
19
+ bytecode = nil
20
+ ComputationTranslator.stub(:translate, '0000000') do
21
+ bytecode = CInstruction.translate('0;JMP')
22
+ end
23
+
24
+ assert_equal '1110000000000111', bytecode
25
+ end
26
+
27
+ def test_that_destination_translator_writes_on_output
28
+ bytecode = nil
29
+ DestinationTranslator.stub(:translate, '111') do
30
+ bytecode = CInstruction.translate('0;JMP')
31
+ end
32
+
33
+ assert_equal '1110101010111111', bytecode
34
+ end
35
+
36
+ def test_that_jump_translator_writes_on_output
37
+ bytecode = nil
38
+ JumpTranslator.stub(:translate, '000') do
39
+ bytecode = CInstruction.translate('0;JMP')
40
+ end
41
+
42
+ assert_equal '1110101010000000', bytecode
43
+ end
44
+ end
@@ -0,0 +1,115 @@
1
+ require 'test_helper'
2
+
3
+ class ComputationTranslatorTest < Minitest::Test
4
+ def test_that_it_raises_error_on_unknown_code
5
+ assert_raises(ParserError) { ComputationTranslator.translate('X') }
6
+ end
7
+
8
+ def test_that_it_converts_single_register_code_for_a
9
+ assert_equal '0110000', ComputationTranslator.translate('A')
10
+ end
11
+
12
+ def test_that_it_converts_single_register_code_for_m
13
+ assert_equal '1110000', ComputationTranslator.translate('M')
14
+ end
15
+
16
+ def test_that_it_converts_one_constant
17
+ assert_equal '0111111', ComputationTranslator.translate('1')
18
+ end
19
+
20
+ def test_that_it_converts_minus_one_constant
21
+ assert_equal '0111010', ComputationTranslator.translate('-1')
22
+ end
23
+
24
+ def test_that_it_converts_d_register
25
+ assert_equal '0001100', ComputationTranslator.translate('D')
26
+ end
27
+
28
+ def test_that_it_converts_not_d_register
29
+ assert_equal '0001101', ComputationTranslator.translate('!D')
30
+ end
31
+
32
+ def test_that_it_converts_not_a_register
33
+ assert_equal '0110001', ComputationTranslator.translate('!A')
34
+ end
35
+
36
+ def test_that_it_converts_not_m_register
37
+ assert_equal '1110001', ComputationTranslator.translate('!M')
38
+ end
39
+
40
+ def test_that_it_converts_minus_d_register
41
+ assert_equal '0001111', ComputationTranslator.translate('-D')
42
+ end
43
+
44
+ def test_that_it_converts_minus_a_register
45
+ assert_equal '0110011', ComputationTranslator.translate('-A')
46
+ end
47
+
48
+ def test_that_it_converts_minus_m_register
49
+ assert_equal '1110011', ComputationTranslator.translate('-M')
50
+ end
51
+
52
+ def test_that_it_converts_d_register_plus_one
53
+ assert_equal '0011111', ComputationTranslator.translate('D+1')
54
+ end
55
+
56
+ def test_that_it_converts_a_register_plus_one
57
+ assert_equal '0110111', ComputationTranslator.translate('A+1')
58
+ end
59
+
60
+ def test_that_it_converts_m_register_plus_one
61
+ assert_equal '1110111', ComputationTranslator.translate('M+1')
62
+ end
63
+
64
+ def test_that_it_converts_d_register_minus_one
65
+ assert_equal '0001110', ComputationTranslator.translate('D-1')
66
+ end
67
+
68
+ def test_that_it_converts_a_register_minus_one
69
+ assert_equal '0110010', ComputationTranslator.translate('A-1')
70
+ end
71
+
72
+ def test_that_it_converts_m_register_minus_one
73
+ assert_equal '1110010', ComputationTranslator.translate('M-1')
74
+ end
75
+
76
+ def test_that_it_converts_d_register_plus_a_register
77
+ assert_equal '0000010', ComputationTranslator.translate('D+A')
78
+ end
79
+
80
+ def test_that_it_converts_d_register_plus_m_register
81
+ assert_equal '1000010', ComputationTranslator.translate('D+M')
82
+ end
83
+
84
+ def test_that_it_converts_d_register_minus_a_register
85
+ assert_equal '0010011', ComputationTranslator.translate('D-A')
86
+ end
87
+
88
+ def test_that_it_converts_d_register_minus_m_register
89
+ assert_equal '1010011', ComputationTranslator.translate('D-M')
90
+ end
91
+
92
+ def test_that_it_converts_a_register_minus_d_register
93
+ assert_equal '0000111', ComputationTranslator.translate('A-D')
94
+ end
95
+
96
+ def test_that_it_converts_m_register_minus_d_register
97
+ assert_equal '1000111', ComputationTranslator.translate('M-D')
98
+ end
99
+
100
+ def test_that_it_converts_d_register_and_a_register
101
+ assert_equal '0000000', ComputationTranslator.translate('D&A')
102
+ end
103
+
104
+ def test_that_it_converts_d_register_and_m_register
105
+ assert_equal '1000000', ComputationTranslator.translate('D&M')
106
+ end
107
+
108
+ def test_that_it_converts_d_register_or_a_register
109
+ assert_equal '0010101', ComputationTranslator.translate('D|A')
110
+ end
111
+
112
+ def test_that_it_converts_d_register_or_m_register
113
+ assert_equal '1010101', ComputationTranslator.translate('D|M')
114
+ end
115
+ end
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ class DestinationTranslatorTest < Minitest::Test
4
+ def test_that_it_raises_error_on_unknown_code
5
+ assert_raises(ParserError) { DestinationTranslator.translate('ADZ') }
6
+ end
7
+
8
+ def test_that_it_translates_null_destination_code
9
+ assert_equal '000', DestinationTranslator.translate(nil)
10
+ end
11
+
12
+ def test_that_it_translates_m_destination_code
13
+ assert_equal '001', DestinationTranslator.translate('M')
14
+ end
15
+
16
+ def test_that_it_translates_d_destination_code
17
+ assert_equal '010', DestinationTranslator.translate('D')
18
+ end
19
+
20
+ def test_that_it_translates_md_destination_code
21
+ assert_equal '011', DestinationTranslator.translate('MD')
22
+ end
23
+
24
+ def test_that_it_translates_a_destination_code
25
+ assert_equal '100', DestinationTranslator.translate('A')
26
+ end
27
+
28
+ def test_that_it_translates_am_destination_code
29
+ assert_equal '101', DestinationTranslator.translate('AM')
30
+ end
31
+
32
+ def test_that_it_translates_ad_destination_code
33
+ assert_equal '110', DestinationTranslator.translate('AD')
34
+ end
35
+
36
+ def test_that_it_translates_amd_destination_code
37
+ assert_equal '111', DestinationTranslator.translate('AMD')
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class HackAssemblerTest < Minitest::Test
4
+ def test_that_it_has_a_version_number
5
+ refute_nil ::HackAssembler::VERSION
6
+ end
7
+ end
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ class JumpTranslatorTest < Minitest::Test
4
+ def test_that_it_raises_error_on_unknown_code
5
+ assert_raises(ParserError) { JumpTranslator.translate('ERR') }
6
+ end
7
+
8
+ def test_that_it_translates_null_code
9
+ assert_equal '000', JumpTranslator.translate(nil)
10
+ end
11
+
12
+ def test_that_it_translates_unconditional_jump_code
13
+ assert_equal '111', JumpTranslator.translate('JMP')
14
+ end
15
+
16
+ def test_that_it_translates_greater_than_zero_jump_code
17
+ assert_equal '001', JumpTranslator.translate('JGT')
18
+ end
19
+
20
+ def test_that_it_translates_equals_zero_jump_code
21
+ assert_equal '010', JumpTranslator.translate('JEQ')
22
+ end
23
+
24
+ def test_that_it_translates_greater_or_equals_zero_jump_code
25
+ assert_equal '011', JumpTranslator.translate('JGE')
26
+ end
27
+
28
+ def test_that_it_translates_less_than_zero_jump_code
29
+ assert_equal '100', JumpTranslator.translate('JLT')
30
+ end
31
+
32
+ def test_that_it_translates_not_equals_zero_jump_code
33
+ assert_equal '101', JumpTranslator.translate('JNE')
34
+ end
35
+
36
+ def test_that_it_translates_less_or_equals_zero_jump_code
37
+ assert_equal '110', JumpTranslator.translate('JLE')
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'hack_assembler'
3
+
4
+ require 'minitest/autorun'
5
+
6
+ include HackAssembler
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hack_assembler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Federico Rebora
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-24 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
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Assembler that takes .hack code and converts it to Hack machine ASM
56
+ email:
57
+ - ufinii@gmail.com
58
+ executables:
59
+ - hack_assembler
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - Pong.asm
68
+ - PongL.asm
69
+ - README.md
70
+ - Rakefile
71
+ - bin/hack_assembler
72
+ - hack2asm.gemspec
73
+ - lib/hack_assembler.rb
74
+ - lib/hack_assembler/a_instruction.rb
75
+ - lib/hack_assembler/assembler.rb
76
+ - lib/hack_assembler/c_instruction.rb
77
+ - lib/hack_assembler/computation_translator.rb
78
+ - lib/hack_assembler/destination_translator.rb
79
+ - lib/hack_assembler/jump_translator.rb
80
+ - lib/hack_assembler/parser_error.rb
81
+ - lib/hack_assembler/version.rb
82
+ - out.hack
83
+ - test/a_instruction_test.rb
84
+ - test/assembler_test.rb
85
+ - test/c_instruction_test.rb
86
+ - test/computation_translator_test.rb
87
+ - test/destination_translator_test.rb
88
+ - test/hack2asm_test.rb
89
+ - test/jump_translator_test.rb
90
+ - test/test_helper.rb
91
+ homepage: ''
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.4.5
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Converts .hack files to .asm
115
+ test_files:
116
+ - test/a_instruction_test.rb
117
+ - test/assembler_test.rb
118
+ - test/c_instruction_test.rb
119
+ - test/computation_translator_test.rb
120
+ - test/destination_translator_test.rb
121
+ - test/hack2asm_test.rb
122
+ - test/jump_translator_test.rb
123
+ - test/test_helper.rb