scasm 0.1.0 → 0.1.1
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.
- data/.gitignore +1 -0
- data/examples/data.scasm +1 -0
- data/examples/loop.scasm +3 -0
- data/examples/macro.scasm +6 -0
- data/examples/readme1.scasm +7 -0
- data/lib/scasm/assembler.rb +32 -53
- data/lib/scasm/version.rb +1 -1
- data/test/test_assembler.rb +0 -20
- metadata +54 -30
data/.gitignore
CHANGED
data/examples/data.scasm
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
data 1, 16, 64, 65535
|
data/examples/loop.scasm
ADDED
data/lib/scasm/assembler.rb
CHANGED
@@ -5,7 +5,7 @@ require 'scasm/value'
|
|
5
5
|
|
6
6
|
module SCASM
|
7
7
|
|
8
|
-
class Assembler <
|
8
|
+
class Assembler < Object
|
9
9
|
def initialize
|
10
10
|
@stmts = []
|
11
11
|
@relocations = []
|
@@ -17,11 +17,13 @@ class Assembler < BasicObject
|
|
17
17
|
|
18
18
|
def assemble
|
19
19
|
resolve_labels
|
20
|
-
io =
|
20
|
+
io = StringIO.new
|
21
21
|
@stmts.each { |stmt| stmt.assemble io }
|
22
22
|
io.string
|
23
23
|
end
|
24
24
|
|
25
|
+
## Statements
|
26
|
+
|
25
27
|
def inst opsym, a, b
|
26
28
|
a = parse_value a
|
27
29
|
b = parse_value b
|
@@ -29,22 +31,25 @@ class Assembler < BasicObject
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def label name
|
32
|
-
|
34
|
+
raise "label names must be strings" unless name.is_a? String
|
33
35
|
@stmts << Label.new(name)
|
34
36
|
end
|
35
37
|
|
36
|
-
def
|
37
|
-
|
38
|
+
def data *words
|
39
|
+
@stmts << Data.new(words)
|
38
40
|
end
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
+
# Add a method for each instruction
|
43
|
+
BASIC_OPCODES.each do |opsym,opcode|
|
44
|
+
define_method(opsym) { |a,b| inst opsym, a, b }
|
42
45
|
end
|
43
46
|
|
44
|
-
|
45
|
-
|
47
|
+
EXTENDED_OPCODES.each do |opsym,opcode|
|
48
|
+
define_method(opsym) { |a| inst opsym, a, nil }
|
46
49
|
end
|
47
50
|
|
51
|
+
## Values
|
52
|
+
|
48
53
|
def pop
|
49
54
|
Pop.new
|
50
55
|
end
|
@@ -69,32 +74,6 @@ class Assembler < BasicObject
|
|
69
74
|
O.new
|
70
75
|
end
|
71
76
|
|
72
|
-
def imem imm
|
73
|
-
ImmediateMemory.new imm
|
74
|
-
end
|
75
|
-
|
76
|
-
def imm imm
|
77
|
-
Immediate.new imm
|
78
|
-
end
|
79
|
-
|
80
|
-
def l name
|
81
|
-
::Kernel.raise "label names must be strings" unless name.is_a? ::String
|
82
|
-
ImmediateLabel.new(name).tap { |x| @relocations << x }
|
83
|
-
end
|
84
|
-
|
85
|
-
def data *words
|
86
|
-
@stmts << Data.new(words)
|
87
|
-
end
|
88
|
-
|
89
|
-
# Add a method for each instruction
|
90
|
-
BASIC_OPCODES.each do |opsym,opcode|
|
91
|
-
define_method(opsym) { |a,b| inst opsym, a, b }
|
92
|
-
end
|
93
|
-
|
94
|
-
EXTENDED_OPCODES.each do |opsym,opcode|
|
95
|
-
define_method(opsym) { |a| inst opsym, a, nil }
|
96
|
-
end
|
97
|
-
|
98
77
|
# Add a constant for each register
|
99
78
|
REGISTERS.each do |regsym,regnum|
|
100
79
|
const_set regsym, regsym
|
@@ -124,41 +103,41 @@ private
|
|
124
103
|
end
|
125
104
|
|
126
105
|
@relocations.each do |x|
|
127
|
-
addr = label_addrs[x.name] or
|
106
|
+
addr = label_addrs[x.name] or raise "undefined label #{x.name.inspect}"
|
128
107
|
x.resolve addr
|
129
108
|
end
|
130
109
|
end
|
131
110
|
|
132
|
-
#
|
111
|
+
# Create explicit Values from the shorthand syntax
|
133
112
|
def parse_value x
|
134
113
|
case x
|
135
|
-
when Value,
|
114
|
+
when Value, NilClass
|
136
115
|
x
|
137
|
-
when
|
116
|
+
when Array
|
138
117
|
x1, x2, = x
|
139
|
-
if x1.is_a?
|
118
|
+
if x1.is_a? Symbol and x2 == nil
|
140
119
|
# [reg]
|
141
|
-
|
142
|
-
elsif x1.is_a?
|
120
|
+
RegisterMemory.new x1
|
121
|
+
elsif x1.is_a? Symbol and x2.is_a? Integer
|
143
122
|
# [reg, imm]
|
144
|
-
|
145
|
-
elsif x1.is_a?
|
123
|
+
OffsetRegisterMemory.new x1, x2
|
124
|
+
elsif x1.is_a? Integer
|
146
125
|
# [imm]
|
147
|
-
|
126
|
+
ImmediateMemory.new x1
|
148
127
|
else
|
149
|
-
|
128
|
+
fail "invalid memory access syntax"
|
150
129
|
end
|
151
|
-
when
|
130
|
+
when Symbol
|
152
131
|
# register
|
153
|
-
|
154
|
-
when
|
132
|
+
Register.new x
|
133
|
+
when String
|
155
134
|
# label
|
156
|
-
|
157
|
-
when
|
135
|
+
ImmediateLabel.new(x).tap { |v| @relocations << v }
|
136
|
+
when Integer
|
158
137
|
# immediate
|
159
|
-
|
138
|
+
Immediate.new x
|
160
139
|
else
|
161
|
-
|
140
|
+
raise "unexpected value class #{x.class}"
|
162
141
|
end
|
163
142
|
end
|
164
143
|
end
|
data/lib/scasm/version.rb
CHANGED
data/test/test_assembler.rb
CHANGED
@@ -34,13 +34,6 @@ class AssemblerTest < Test::Unit::TestCase
|
|
34
34
|
0x1c61,
|
35
35
|
]
|
36
36
|
|
37
|
-
check <<-EOS
|
38
|
-
set reg(A), reg(B)
|
39
|
-
set reg(C), reg(X)
|
40
|
-
set reg(Y), reg(Z)
|
41
|
-
set reg(I), reg(J)
|
42
|
-
EOS
|
43
|
-
|
44
37
|
check <<-EOS
|
45
38
|
set A, B
|
46
39
|
set C, X
|
@@ -51,13 +44,11 @@ class AssemblerTest < Test::Unit::TestCase
|
|
51
44
|
|
52
45
|
def test_regmem
|
53
46
|
expect [0x0cb1]
|
54
|
-
check "set regmem(X), reg(X)"
|
55
47
|
check "set [X], X"
|
56
48
|
end
|
57
49
|
|
58
50
|
def test_iregmem
|
59
51
|
expect [0x0d31, 0x002a]
|
60
|
-
check 'set iregmem(X, 42), reg(X)'
|
61
52
|
check 'set [X,42], X'
|
62
53
|
end
|
63
54
|
|
@@ -83,21 +74,17 @@ class AssemblerTest < Test::Unit::TestCase
|
|
83
74
|
|
84
75
|
def test_imem
|
85
76
|
expect [0x7801, 0x1000]
|
86
|
-
check 'set reg(A), imem(0x1000)'
|
87
77
|
check 'set A, [0x1000]'
|
88
78
|
end
|
89
79
|
|
90
80
|
def test_imm
|
91
81
|
expect [0xfc01]
|
92
|
-
check "set reg(A), imm(31)"
|
93
82
|
check "set A, 31"
|
94
83
|
|
95
84
|
expect [0x7c01, 0x0020]
|
96
|
-
check "set reg(A), imm(32)"
|
97
85
|
check "set A, 32"
|
98
86
|
|
99
87
|
expect [0x7df1, 0xffff, 0x0020]
|
100
|
-
check "set imm(65535), imm(32)"
|
101
88
|
check "set 65535, 32"
|
102
89
|
end
|
103
90
|
|
@@ -108,13 +95,6 @@ class AssemblerTest < Test::Unit::TestCase
|
|
108
95
|
0x7dc1, 0x0001,
|
109
96
|
]
|
110
97
|
|
111
|
-
check <<-EOS
|
112
|
-
set reg(A), imm(13)
|
113
|
-
label 'loop'
|
114
|
-
add reg(A), imm(1)
|
115
|
-
set pc, l('loop')
|
116
|
-
EOS
|
117
|
-
|
118
98
|
check <<-EOS
|
119
99
|
set A, 13
|
120
100
|
label 'loop'
|
metadata
CHANGED
@@ -1,36 +1,47 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: scasm
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Rich Lane
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2012-04-05 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: trollop
|
16
|
-
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
24
|
none: false
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
22
32
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
email:
|
33
|
+
version_requirements: *id001
|
34
|
+
description: ""
|
35
|
+
email:
|
27
36
|
- rlane@club.cc.cmu.edu
|
28
|
-
executables:
|
37
|
+
executables:
|
29
38
|
- scasm
|
30
39
|
- scasm-disassemble
|
31
40
|
extensions: []
|
41
|
+
|
32
42
|
extra_rdoc_files: []
|
33
|
-
|
43
|
+
|
44
|
+
files:
|
34
45
|
- .gitignore
|
35
46
|
- Gemfile
|
36
47
|
- LICENSE
|
@@ -38,6 +49,10 @@ files:
|
|
38
49
|
- Rakefile
|
39
50
|
- bin/scasm
|
40
51
|
- bin/scasm-disassemble
|
52
|
+
- examples/data.scasm
|
53
|
+
- examples/loop.scasm
|
54
|
+
- examples/macro.scasm
|
55
|
+
- examples/readme1.scasm
|
41
56
|
- examples/spec.scasm
|
42
57
|
- lib/scasm/assembler.rb
|
43
58
|
- lib/scasm/isa.rb
|
@@ -49,28 +64,37 @@ files:
|
|
49
64
|
- test/test_assembler.rb
|
50
65
|
homepage: https://github.com/rlane/scasm
|
51
66
|
licenses: []
|
67
|
+
|
52
68
|
post_install_message:
|
53
69
|
rdoc_options: []
|
54
|
-
|
70
|
+
|
71
|
+
require_paths:
|
55
72
|
- lib
|
56
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
74
|
none: false
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
83
|
none: false
|
64
|
-
requirements:
|
65
|
-
- -
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
68
91
|
requirements: []
|
92
|
+
|
69
93
|
rubyforge_project:
|
70
94
|
rubygems_version: 1.8.17
|
71
95
|
signing_key:
|
72
96
|
specification_version: 3
|
73
97
|
summary: A Ruby DSL for DCPU-16 assembly code
|
74
|
-
test_files:
|
98
|
+
test_files:
|
75
99
|
- test/foo.scasm
|
76
100
|
- test/test_assembler.rb
|