File indexing completed on 2024-04-14 05:36:55

0001 /***************************************************************************
0002  *   Copyright (C) 2003-2005 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "asmformatter.h"
0012 #include "picinfo12bit.h"
0013 #include "picinfo14bit.h"
0014 #include "picinfo16bit.h"
0015 
0016 #include <ktlconfig.h>
0017 
0018 static QString extractComment(const QString &line)
0019 {
0020     int pos = line.indexOf(';');
0021 
0022     if (pos == -1)
0023         return "";
0024 
0025     return line.right(line.length() - pos);
0026 }
0027 
0028 // BEGIN class AsmFormatter
0029 AsmFormatter::AsmFormatter()
0030 {
0031 }
0032 
0033 AsmFormatter::~AsmFormatter()
0034 {
0035 }
0036 
0037 QString AsmFormatter::tidyAsm(QStringList lines)
0038 {
0039     // Update our indentation values from config
0040     m_indentAsmName = KTLConfig::indentAsmName();
0041     m_indentAsmData = KTLConfig::indentAsmData();
0042     m_indentEqu = KTLConfig::indentEqu();
0043     m_indentEquValue = KTLConfig::indentEquValue();
0044     m_indentComment = m_indentEquComment = KTLConfig::indentComment();
0045 
0046     QStringList::iterator end = lines.end();
0047     for (QStringList::iterator slit = lines.begin(); slit != end; ++slit) {
0048         switch (lineType(*slit)) {
0049         case Other:
0050             break;
0051 
0052         case Equ:
0053             *slit = tidyEqu(*slit);
0054             break;
0055 
0056         case Instruction:
0057             *slit = tidyInstruction(*slit);
0058             break;
0059         }
0060     }
0061 
0062     QString code;
0063 
0064     for (QStringList::iterator slit = lines.begin(); slit != end; ++slit)
0065         code.append(*slit + '\n');
0066 
0067     return code;
0068 }
0069 
0070 void AsmFormatter::pad(QString &text, int length)
0071 {
0072     int padLength = length - text.length();
0073     if (padLength <= 0)
0074         return;
0075 
0076     QString pad;
0077     pad.fill(' ', padLength);
0078     text += pad;
0079 }
0080 
0081 QString AsmFormatter::tidyInstruction(const QString &oldLine)
0082 {
0083     InstructionParts parts(oldLine);
0084     QString line;
0085 
0086     if (!parts.label().isEmpty())
0087         line = parts.label() + ' ';
0088     pad(line, m_indentAsmName);
0089 
0090     if (!parts.operand().isEmpty())
0091         line += parts.operand() + ' ';
0092     pad(line, m_indentAsmData);
0093 
0094     if (!parts.operandData().isEmpty())
0095         line += parts.operandData();
0096     pad(line, m_indentComment);
0097 
0098     if (parts.comment().isEmpty()) {
0099         // Remove any whitespace at the end if we're not padding out a comment
0100         while (!line.isEmpty() && line[line.length() - 1].isSpace())
0101             line.remove(line.length() - 1, 1);
0102     } else
0103         line += parts.comment();
0104 
0105     return line;
0106 }
0107 
0108 QString AsmFormatter::tidyEqu(const QString &oldLine)
0109 {
0110     QString comment = extractComment(oldLine);
0111     QString code = oldLine;
0112     code.remove(comment);
0113     code = code.simplified();
0114 
0115     QStringList parts = code.split(' ', Qt::SkipEmptyParts); // QStringList::split( ' ', code ); // 2018.12.01
0116 
0117     QString pad0, pad1, pad2;
0118     pad0.fill(' ', m_indentEqu - (parts.at(0)).length());
0119     pad1.fill(' ', m_indentEquValue - m_indentEqu - (parts.at(1)).length());
0120     pad2.fill(' ', m_indentEquComment - m_indentEquValue - m_indentEqu - (parts.at(2)).length());
0121 
0122     code = parts.at(0) + pad0;
0123     code += parts.at(1) + pad1;
0124     code += parts.at(2);
0125     if (!comment.isEmpty()) {
0126         code += pad2;
0127         code += comment;
0128     }
0129 
0130     return code;
0131 }
0132 
0133 AsmFormatter::LineType AsmFormatter::lineType(QString line)
0134 {
0135     line = line.simplified();
0136 
0137     line.remove(extractComment(line));
0138 
0139     QStringList parts = line.split(' ', Qt::SkipEmptyParts); // QStringList::split( ' ', line ); // 2018.12.01
0140     QStringList::iterator end = parts.end();
0141     for (QStringList::iterator it = parts.begin(); it != end; ++it) {
0142         if ((*it).toLower() == "equ")
0143             return Equ;
0144     }
0145 
0146     InstructionParts instructionParts(line);
0147     if (!instructionParts.operand().isEmpty())
0148         return Instruction;
0149 
0150     return Other;
0151 }
0152 // END class AsmFormatter
0153 
0154 // BEGIN class InstructionParts
0155 InstructionParts::InstructionParts(QString line)
0156 {
0157     m_comment = extractComment(line);
0158     line.remove(m_comment);
0159 
0160     line = line.simplified();
0161     QStringList parts = line.split(' ', Qt::SkipEmptyParts); // QStringList::split( ' ', line ); // 2018.12.01
0162 
0163     bool foundOperand = false;
0164     QStringList::iterator end = parts.end();
0165     for (QStringList::iterator it = parts.begin(); it != end; ++it) {
0166         if (foundOperand) {
0167             // Already found the operand, so anything else must be the operand
0168             // data.
0169 
0170             if (m_operandData.isEmpty())
0171                 m_operandData = *it;
0172             else
0173                 m_operandData += ' ' + *it;
0174 
0175             continue;
0176         }
0177 
0178         if (PicAsm12bit::self()->operandList().contains((*it).toUpper()) || PicAsm14bit::self()->operandList().contains((*it).toUpper()) || PicAsm16bit::self()->operandList().contains((*it).toUpper())) {
0179             m_operand = *it;
0180             foundOperand = true;
0181         } else {
0182             // Must be a label
0183             m_label = *it;
0184         }
0185     }
0186 }
0187 // END class InstructionParts