Line 40... |
Line 40... |
|
|
def AddSymbol(self,name,stype,body=None):
|
def AddSymbol(self,name,stype,body=None):
|
"""
|
"""
|
Add the named global symbol to the list of symbols including its mandatory
|
Add the named global symbol to the list of symbols including its mandatory
|
type and an optional body.\n
|
type and an optional body.\n
|
Note: Symbols include memory names, variables, constants, functions,
|
Note: Symbols include memory names, variables, constants, defines,
|
parameters, inports, outports, ...
|
functions, parameters, inports, outports, ...
|
"""
|
"""
|
if self.IsSymbol(name):
|
if self.IsSymbol(name):
|
raise Exception('Program Bug -- name "%s" already exists is symbols' % name);
|
raise Exception('Program Bug -- name "%s" already exists is symbols' % name);
|
self.symbols['list'].append(name);
|
self.symbols['list'].append(name);
|
self.symbols['type'].append(stype);
|
self.symbols['type'].append(stype);
|
Line 381... |
Line 381... |
if firstToken['type'] != 'directive':
|
if firstToken['type'] != 'directive':
|
raise Exception('Program Bug triggered at %s' % firstToken['loc']);
|
raise Exception('Program Bug triggered at %s' % firstToken['loc']);
|
# Ensure the directive bodies are not too short.
|
# Ensure the directive bodies are not too short.
|
if (firstToken['value'] in ('.main','.interrupt',)) and not (len(rawTokens) > 1):
|
if (firstToken['value'] in ('.main','.interrupt',)) and not (len(rawTokens) > 1):
|
raise asmDef.AsmException('"%s" missing body at %s' % (firstToken['value'],firstToken['loc'],));
|
raise asmDef.AsmException('"%s" missing body at %s' % (firstToken['value'],firstToken['loc'],));
|
if (firstToken['value'] in ('.macro',)) and not (len(rawTokens) == 2):
|
if (firstToken['value'] in ('.define','.macro',)) and not (len(rawTokens) == 2):
|
raise asmDef.AsmException('body for "%s" directive must have exactly one argument at %s' % (firstToken['value'],firstToken['loc'],));
|
raise asmDef.AsmException('body for "%s" directive must have exactly one argument at %s' % (firstToken['value'],firstToken['loc'],));
|
if (firstToken['value'] in ('.constant','.function','.memory','.variable',)) and not (len(rawTokens) >= 3):
|
if (firstToken['value'] in ('.constant','.function','.memory','.variable',)) and not (len(rawTokens) >= 3):
|
raise asmDef.AsmException('body for "%s" directive too short at %s' % (firstToken['value'],firstToken['loc'],));
|
raise asmDef.AsmException('body for "%s" directive too short at %s' % (firstToken['value'],firstToken['loc'],));
|
# Ensure the main body ends in a ".jump".
|
|
lastToken = rawTokens[-1];
|
|
if firstToken['value'] == '.main':
|
|
if (lastToken['type'] != 'macro') or (lastToken['value'] != '.jump'):
|
|
raise asmDef.AsmException('.main body does not end in ".jump" at %s' % lastToken['loc']);
|
|
# Ensure functions and interrupts end in a ".jump" or ".return".
|
|
if firstToken['value'] in ('.function','.interrupt',):
|
|
if (lastToken['type'] != 'macro') or (lastToken['value'] not in ('.jump','.return',)):
|
|
raise asmDef.AsmException('Last entry in ".function" or ".interrupt" must be a ".jump" or ".return" at %s' % lastToken['loc']);
|
|
# Ensure no macros and no instructions in non-"functions".
|
# Ensure no macros and no instructions in non-"functions".
|
# Byproduct: No labels allowed in non-"functions".
|
# Byproduct: No labels allowed in non-"functions".
|
if firstToken['value'] not in ('.function','.interrupt','.main',):
|
if firstToken['value'] not in ('.function','.interrupt','.main',):
|
for token in rawTokens[2:]:
|
for token in rawTokens[2:]:
|
if (token['type'] == 'macro'):
|
if (token['type'] == 'macro'):
|
Line 436... |
Line 427... |
allowableTypes = ('RAM','ROM','constant','inport','outport','outstrobe','parameter','variable',);
|
allowableTypes = ('RAM','ROM','constant','inport','outport','outstrobe','parameter','variable',);
|
ixFirst = 1 if token['value'] in self.MacrosWithSpecialFirstSymbol else 0;
|
ixFirst = 1 if token['value'] in self.MacrosWithSpecialFirstSymbol else 0;
|
for arg in token['argument'][ixFirst:]:
|
for arg in token['argument'][ixFirst:]:
|
if arg['type'] == 'symbol':
|
if arg['type'] == 'symbol':
|
self.CheckSymbolToken(arg['value'],allowableTypes,arg['loc']);
|
self.CheckSymbolToken(arg['value'],allowableTypes,arg['loc']);
|
|
# Ensure the main body ends in a ".jump".
|
|
lastToken = rawTokens[-1];
|
|
if firstToken['value'] == '.main':
|
|
if (lastToken['type'] != 'macro') or (lastToken['value'] != '.jump'):
|
|
raise asmDef.AsmException('.main body does not end in ".jump" at %s' % lastToken['loc']);
|
|
# Ensure functions and interrupts end in a ".jump" or ".return".
|
|
if firstToken['value'] in ('.function','.interrupt',):
|
|
if (lastToken['type'] != 'macro') or (lastToken['value'] not in ('.jump','.return',)):
|
|
raise asmDef.AsmException('Last entry in ".function" or ".interrupt" must be a ".jump" or ".return" at %s' % lastToken['loc']);
|
|
|
################################################################################
|
################################################################################
|
#
|
#
|
# fill in symbols, etc. in the list of raw tokens.
|
# fill in symbols, etc. in the list of raw tokens.
|
#
|
#
|
Line 448... |
Line 448... |
def ByteList(self,rawTokens,limit=False):
|
def ByteList(self,rawTokens,limit=False):
|
"""
|
"""
|
Return either (1) a list comprised of a single token which may not be a
|
Return either (1) a list comprised of a single token which may not be a
|
byte or (2) a list comprised of multiple tokens, each of which is a single
|
byte or (2) a list comprised of multiple tokens, each of which is a single
|
byte.\n
|
byte.\n
|
Note: This is called by FillRawTokens.
|
Note: This is called by FillRawTokens.\n
|
|
Note: Multi-value lists must be single-byte values (i.e., in the range -128 to 255)
|
"""
|
"""
|
if len(rawTokens) > 1:
|
if len(rawTokens) > 1:
|
limit = True;
|
limit = True;
|
values = list();
|
values = list();
|
try:
|
|
for token in rawTokens:
|
for token in rawTokens:
|
if token['type'] == 'value':
|
if token['type'] == 'symbol':
|
v = token['value'];
|
ix = self.symbols['list'].index(token['value']);
|
if type(v) == int:
|
symbolType = self.symbols['type'][ix];
|
if limit and not (-128 <= v < 256):
|
if symbolType != 'constant':
|
raise Exception('Program Bug -- unexpected out-of-range value');
|
raise asmDef.AsmException('Illegal symbol "%s" at %s' % (token['value'],token['loc'],));
|
values.append(v);
|
value = self.symbols['body'][ix];
|
|
elif token['type'] == 'value':
|
|
value = token['value'];
|
else:
|
else:
|
for v in token['value']:
|
raise asmDef.AsmException('Illegal token "%s" with value "%s" at %s' % (token['type'],token['value'],token['loc'],));
|
if not (-128 <= v < 256):
|
if type(value) == int:
|
raise Exception('Program Bug -- unexpected out-of-range value');
|
value = [value];
|
values.append(v);
|
|
else:
|
else:
|
raise asmDef.AsmException('Illegal token "%s" at %s:%d:%d', (token['type'],token['loc']));
|
limit = True;
|
except:
|
for v in value:
|
raise asmDef.AsmException('Out-of-range token "%s" at %s:%d:%d', (token['type'],token['loc']));
|
if limit and not (-128 <= v < 256):
|
|
raise asmDef.AsmException('Out-of-rarnge value "%d" at %s' % (v,token['loc'],))
|
|
values.append(v);
|
return values;
|
return values;
|
|
|
def ExpandSymbol(self,token,singleValue):
|
def ExpandSymbol(self,token,singleValue):
|
"""
|
"""
|
Convert the token for a symbol into a token for its specific type.
|
Convert the token for a symbol into a token for its specific type.
|
Line 594... |
Line 597... |
raise asmDef.AsmException('Symbol "%s" already defined at %s' % (secondToken['value'],secondToken['loc'],));
|
raise asmDef.AsmException('Symbol "%s" already defined at %s' % (secondToken['value'],secondToken['loc'],));
|
# Perform syntax-specific processing.
|
# Perform syntax-specific processing.
|
if firstToken['value'] == '.constant':
|
if firstToken['value'] == '.constant':
|
byteList = self.ByteList(rawTokens[2:]);
|
byteList = self.ByteList(rawTokens[2:]);
|
self.AddSymbol(secondToken['value'],'constant',body=byteList);
|
self.AddSymbol(secondToken['value'],'constant',body=byteList);
|
|
# Process ".define" directive
|
|
elif firstToken['value'] == '.define':
|
|
self.AddSymbol(secondToken['value'],'define');
|
# Process ".function" definition.
|
# Process ".function" definition.
|
elif firstToken['value'] == '.function':
|
elif firstToken['value'] == '.function':
|
self.AddSymbol(secondToken['value'],'function',self.ExpandTokens(rawTokens[2:]));
|
self.AddSymbol(secondToken['value'],'function',self.ExpandTokens(rawTokens[2:]));
|
# Process ".interrupt" definition.
|
# Process ".interrupt" definition.
|
elif firstToken['value'] == '.interrupt':
|
elif firstToken['value'] == '.interrupt':
|
Line 751... |
Line 757... |
if callName not in self.functionEvaluation['list']:
|
if callName not in self.functionEvaluation['list']:
|
if not self.IsSymbol(callName):
|
if not self.IsSymbol(callName):
|
raise asmDef.AsmException('Function "%s" not defined for function "%s"' % (callName,self.functionEvaluation['list'][ix],));
|
raise asmDef.AsmException('Function "%s" not defined for function "%s"' % (callName,self.functionEvaluation['list'][ix],));
|
ixName = self.symbols['list'].index(callName);
|
ixName = self.symbols['list'].index(callName);
|
if self.symbols['type'][ixName] != 'function':
|
if self.symbols['type'][ixName] != 'function':
|
raise asmDef.AsmException('Function "%s" called by "%s" is not a function', (callName, self.functionEvaluation['list'][ix],));
|
raise asmDef.AsmException('Function "%s" called by "%s" is not a function' % (callName, self.functionEvaluation['list'][ix],));
|
self.functionEvaluation['list'].append(callName);
|
self.functionEvaluation['list'].append(callName);
|
self.functionEvaluation['length'].append(self.symbols['body'][ixName]['length']);
|
self.functionEvaluation['length'].append(self.symbols['body'][ixName]['length']);
|
self.functionEvaluation['body'].append(self.symbols['body'][ixName]['tokens']);
|
self.functionEvaluation['body'].append(self.symbols['body'][ixName]['tokens']);
|
self.functionEvaluation['address'].append(nextStart);
|
self.functionEvaluation['address'].append(nextStart);
|
nextStart = nextStart + self.functionEvaluation['length'][-1];
|
nextStart = nextStart + self.functionEvaluation['length'][-1];
|
Line 1205... |
Line 1211... |
|
|
self.directives = dict();
|
self.directives = dict();
|
|
|
self.directives['list']= list();
|
self.directives['list']= list();
|
self.directives['list'].append('.constant');
|
self.directives['list'].append('.constant');
|
|
self.directives['list'].append('.define');
|
self.directives['list'].append('.function');
|
self.directives['list'].append('.function');
|
self.directives['list'].append('.interrupt');
|
self.directives['list'].append('.interrupt');
|
self.directives['list'].append('.macro');
|
self.directives['list'].append('.macro');
|
self.directives['list'].append('.main');
|
self.directives['list'].append('.main');
|
self.directives['list'].append('.memory');
|
self.directives['list'].append('.memory');
|