4
4
import os
5
5
from sicxe import *
6
6
7
+ # A class to indicate assembly error
7
8
class AssembleError (BaseException ):
8
9
pass
9
10
11
+ # class to store info of each source statements
10
12
class Line :
11
13
def __init__ (self , assembly , lineno ):
12
14
self .src = assembly
@@ -23,9 +25,11 @@ def __str__(self):
23
25
def __repr__ (self ):
24
26
return str (self )
25
27
28
+ # split the source statement into several tokens
26
29
def tokenize (self ):
27
30
return self .assembly .split ()
28
31
32
+ # return a tuple for assembly listing
29
33
def listing_tuple (self ):
30
34
locfmt = ""
31
35
codefmt = ""
@@ -36,6 +40,7 @@ def listing_tuple(self):
36
40
codefmt = codefmt % self .code
37
41
return (self .lineno , locfmt , self .src .expandtabs (8 ), codefmt )
38
42
43
+ # class to store each program info
39
44
class Program :
40
45
def __init__ (self , source ):
41
46
self .source = os .path .basename (source )
@@ -49,13 +54,15 @@ def __init__(self, source):
49
54
self .symtab = PRELOAD_SYMTAB .copy ()
50
55
self .base = - 1
51
56
57
+ # print error message indicating the line number and throw the error
52
58
def error (self , msg , line = None ):
53
59
if line == None :
54
60
line = self .current_line ()
55
61
print ("\n %s:%s" % (self .source , str (line .lineno )) + " " + str (line ))
56
62
print ("Error : " + msg + '\n ' )
57
63
raise AssembleError
58
64
65
+ # assemble the program
59
66
def assemble (self ):
60
67
for line in self .content :
61
68
program .lineno += 1
@@ -75,6 +82,7 @@ def assemble(self):
75
82
else :
76
83
program .error ("Except a directive, opcde or label." )
77
84
85
+ # write assembly listing to file
78
86
def listing (self , filename ):
79
87
stmt_len = len (max (self .content , key = lambda stmt : len (stmt .src )).src ) + 10
80
88
fmt = "\n %%-8s%%-8s%%-%ds%%-10s" % stmt_len
@@ -83,9 +91,11 @@ def listing(self, filename):
83
91
for line in self .content :
84
92
f .write (fmt % line .listing_tuple ())
85
93
94
+ # get current line
86
95
def current_line (self ):
87
96
return self .content [self .lineno - 1 ]
88
97
98
+ # output object file
89
99
def output (self , file_name ):
90
100
with open (file_name , "w" ) as f :
91
101
f .write ("H%-6s%06X%06X" % (self .name , self .start_addr , self .LOCCTR - self .start_addr ))
@@ -145,7 +155,6 @@ def output(self, file_name):
145
155
f .write ("\n M%06X%02X" % (line .loc + 1 , 5 ))
146
156
f .write ("\n E%06X" % self .start_exec )
147
157
148
-
149
158
def handler_START (program , tokens ):
150
159
if "START" in tokens :
151
160
# validate format
@@ -254,6 +263,7 @@ def handler_NOBASE(program, tokens):
254
263
"NOBASE" : handler_NOBASE ,
255
264
}
256
265
266
+ # fill the instructions which referencing foward symbols
257
267
def fill_forward (fwd_lst , addr , program ):
258
268
for line , ref , reftype in fwd_lst :
259
269
if reftype == REF_OP :
@@ -285,8 +295,6 @@ def fill_forward(fwd_lst, addr, program):
285
295
else :
286
296
program .error ("no enough length to hold the displacement, try format 4." , line )
287
297
288
-
289
-
290
298
def has_directives (program , tokens ):
291
299
for token in tokens :
292
300
if token in DIRTAB :
0 commit comments