asmformatter.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2003-2005 by David Saxton                               *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "asmformatter.h"
00012 #include "core/ktlconfig.h"
00013 #include "picinfo12bit.h"
00014 #include "picinfo14bit.h"
00015 #include "picinfo16bit.h"
00016 
00017 static QString extractComment( const QString & line)
00018 {
00019         int pos = line.find( ';');
00020         
00021         if(pos == -1) return "";
00022         
00023         return line.right( line.length() - pos);
00024 }
00025 
00026 //BEGIN class AsmFormatter
00027 AsmFormatter::AsmFormatter() {}
00028 
00029 AsmFormatter::~AsmFormatter() {}
00030 
00031 
00032 QString AsmFormatter::tidyAsm( QStringList lines)
00033 {
00034         // Update our indentation values from config
00035         m_indentAsmName = KTLConfig::indentAsmName();
00036         m_indentAsmData = KTLConfig::indentAsmData();
00037         m_indentEqu = KTLConfig::indentEqu();
00038         m_indentEquValue = KTLConfig::indentEquValue();
00039         m_indentComment = m_indentEquComment = KTLConfig::indentComment();
00040         
00041         QStringList::iterator end = lines.end();
00042         for(QStringList::iterator slit = lines.begin(); slit != end; ++slit)
00043         {
00044                 switch(lineType(*slit))
00045                 {
00046                 case Other:
00047                         break;
00048                 case Equ:
00049                         *slit = tidyEqu( *slit);
00050                         break;
00051                 case Instruction:
00052                         *slit = tidyInstruction( *slit);
00053                         break;
00054                 }
00055         }
00056         
00057         QString code;
00058         
00059         for(QStringList::iterator slit = lines.begin(); slit != end; ++slit)
00060                 code.append( *slit + '\n');
00061         
00062         return code;
00063 }
00064 
00065 void AsmFormatter::pad( QString & text, int length)
00066 {
00067         int padLength = length - text.length();
00068 
00069         if(padLength <= 0) return;
00070 
00071         QString pad;
00072         pad.fill( ' ', padLength);
00073         text += pad;
00074 }
00075 
00076 
00077 QString AsmFormatter::tidyInstruction( const QString & oldLine)
00078 {
00079         InstructionParts parts( oldLine);
00080         QString line;
00081         
00082         if(!parts.label().isEmpty()) line = parts.label() + ' ';
00083         pad( line, m_indentAsmName);
00084         
00085         if(!parts.operand().isEmpty()) line += parts.operand() + ' ';
00086         pad( line, m_indentAsmData);
00087         
00088         if(!parts.operandData().isEmpty()) line += parts.operandData();
00089         pad( line, m_indentComment);
00090         
00091         if(parts.comment().isEmpty())
00092         {
00093                 // Remove any whitespace at the end if we're not padding out a comment
00094                 while(!line.isEmpty() && line[ line.length() - 1 ].isSpace())
00095                         line.remove( line.length() -1, 1);
00096         } else line += parts.comment();
00097 
00098         return line;
00099 }
00100 
00101 
00102 QString AsmFormatter::tidyEqu( const QString & oldLine)
00103 {
00104         QString comment = extractComment( oldLine);
00105         QString code = oldLine;
00106         code.remove( comment);
00107         code = code.simplifyWhiteSpace();
00108 
00109         QStringList parts = QStringList::split(' ', code);
00110 
00111         QString pad0, pad1, pad2;
00112         pad0.fill(' ', m_indentEqu - (*parts.at(0)).length());
00113         pad1.fill(' ', m_indentEquValue - m_indentEqu - (*parts.at(1)).length());
00114         pad2.fill(' ', m_indentEquComment - m_indentEquValue - m_indentEqu - (*parts.at(2)).length());
00115 
00116         code = *parts.at(0) + pad0;
00117         code += *parts.at(1) + pad1;
00118         code += *parts.at(2);
00119 
00120         if(!comment.isEmpty()) {
00121                 code += pad2;
00122                 code += comment;
00123         }
00124         
00125         return code;
00126 }
00127 
00128 AsmFormatter::LineType AsmFormatter::lineType( QString line)
00129 {
00130         line = line.simplifyWhiteSpace();
00131 
00132         line.remove(extractComment(line));
00133 
00134         QStringList parts = QStringList::split(' ', line);
00135         QStringList::iterator end = parts.end();
00136 
00137         for(QStringList::iterator it = parts.begin(); it != end; ++it) {
00138                 if((*it).lower() == "equ") return Equ;
00139         }
00140 
00141         InstructionParts instructionParts(line);
00142 
00143         if(!instructionParts.operand().isEmpty()) return Instruction;
00144 
00145         return Other;
00146 }
00147 //END class AsmFormatter
00148 
00149 
00150 
00151 //BEGIN class InstructionParts
00152 InstructionParts::InstructionParts(QString line)
00153 {
00154         m_comment = extractComment(line);
00155         line.remove(m_comment);
00156 
00157         line = line.simplifyWhiteSpace();
00158         QStringList parts = QStringList::split(' ', line);
00159 
00160         bool foundOperand = false;
00161         QStringList::iterator end = parts.end();
00162 
00163         for(QStringList::iterator it = parts.begin(); it != end; ++it) {
00164                 if(foundOperand) {
00165                         // Already found the operand, so anything else must be the operand
00166                         // data.
00167                         if(m_operandData.isEmpty()) m_operandData = *it;
00168                         else m_operandData += ' ' + *it;
00169                         
00170                         continue;
00171                 }
00172                 
00173                 if(PicAsm12bit::self()->operandList().contains((*it).upper()) || PicAsm14bit::self()->operandList().contains((*it).upper()) || PicAsm16bit::self()->operandList().contains((*it).upper())) {
00174                         m_operand = *it;
00175                         foundOperand = true;
00176                 } else {
00177                         // Must be a label
00178                         m_label = *it;
00179                 }
00180         }
00181 }
00182 //END class InstructionParts
00183 

Generated on Tue May 8 17:05:27 2007 for KTechLab by  doxygen 1.5.1