/* * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "asm.h" #include "../Constants.h" const QSet SynEditASMHighlighter::Keywords { "aaa","aad","aam","adc","add","and","arpl","bound","bsf","bsr","bswap","bt","btc","btr","bts", "call","cbw","cdq","clc","cld","cli","clts","cmc","cmp","cmps","cmpsb","cmpsd","cmpsw", "cmpxchg","cwd","cwde","daa","das","dec","div","emms","enter","f2xm1","fabs","fadd","faddp","fbld", "fbstp","fchs","fclex","fcmovb","fcmovbe","fcmove","fcmovnb","fcmovnbe","fcmovne","fcmovnu", "fcmovu","fcom","fcomi","fcomip","fcomp","fcompp","fcos","fdecstp","fdiv","fdivp","fdivr", "fdivrp","femms","ffree","fiadd","ficom","ficomp","fidiv","fidivr","fild","fimul","fincstp", "finit","fist","fistp","fisub","fisubr","fld","fld1","fldcw","fldenv","fldl2e","fldl2t","fldlg2", "fldln2","fldpi","fldz","fmul","fmulp","fnclex","fninit","fnop","fnsave","fnstcw","fnstenv", "fnstsw","fpatan","fprem1","fptan","frndint","frstor","fsave","fscale","fsin","fsincos", "fsqrt","fst","fstcw","fstenv","fstp","fstsw","fsub","fsubp","fsubr","fsubrp","ftst", "fucom","fucomi","fucomip","fucomp","fucompp","fwait","fxch","fxtract","fyl2xp1","hlt","idiv", "imul","in","inc","ins","insb","insd","insw","int","into","invd","invlpg","iret","iretd","iretw", "ja","jae","jb","jbe","jc","jcxz","je","jecxz","jg","jge","jl","jle","jmp","jna","jnae","jnb","jnbe","jnc", "jne","jng","jnge","jnl","jnle","jno","jnp","jns","jnz","jo","jp","jpe","jpo","js","jz","lahf","lar","lds", "lea","leave","les","lfs","lgdt","lgs","lidt","lldt","lmsw","lock","lods","lodsb","lodsd","lodsw", "loop","loope","loopne","loopnz","loopz","lsl","lss","ltr","mov","movd","movq"," movs","movsb", "movsd","movsw","movsx","movzx","mul","neg","nop","not","or","out","outs","outsb","outsd","outsw", "packssdw","packsswb","packuswb","paddb","paddd","paddsb","paddsw","paddusb","paddusw", "paddw","pand","pandn","pavgusb","pcmpeqb","pcmpeqd","pcmpeqw","pcmpgtb","pcmpgtd","pcmpgtw", "pf2id","pfacc","pfadd","pfcmpeq","pfcmpge","pfcmpgt","pfmax","pfmin","pfmul","pfrcp", "pfrcpit1","pfrcpit2","pfrsqit1","pfrsqrt","pfsub","pfsubr","pi2fd","pmaddwd","pmulhrw", "pmulhw","pmullw","pop","popa","popad","popaw","popf","popfd","popfw","por","prefetch","prefetchw", "pslld","psllq","psllw","psrad","psraw","psrld","psrlq","psrlw","psubb","psubd","psubsb", "psubsw","psubusb","psubusw","psubw","punpckhbw","punpckhdq","punpckhwd","punpcklbw", "punpckldq","punpcklwd","push","pusha","pushad","pushaw","pushf","pushfd","pushfw","pxor", "rcl","rcr","rep","repe","repne","repnz","repz","ret","rol","ror","sahf","sal","sar","sbb","scas", "scasb","scasd","scasw","seta","setae","setb","setbe","setc","sete","setg","setge","setl","setle", "setna","setnae","setnb","setnbe","setnc","setne","setng","setnge","setnl","setnle","setno", "setnp","setns","setnz","seto","setp","setpo","sets","setz","sgdt","shl","shld","shr","shrd","sidt", "sldt","smsw","stc","std","sti","stos","stosb","stosd","stosw","str","sub","test","verr","verw", "wait","wbinvd","xadd","xchg","xlat","xlatb","xor" }; SynEditASMHighlighter::SynEditASMHighlighter() { mCommentAttribute = std::make_shared(SYNS_AttrComment); mCommentAttribute->setStyles(SynFontStyle::fsItalic); addAttribute(mCommentAttribute); mIdentifierAttribute = std::make_shared(SYNS_AttrIdentifier); addAttribute(mIdentifierAttribute); mKeywordAttribute = std::make_shared(SYNS_AttrReservedWord); mKeywordAttribute->setStyles(SynFontStyle::fsBold); addAttribute(mKeywordAttribute); mNumberAttribute = std::make_shared(SYNS_AttrNumber); addAttribute(mNumberAttribute); mWhitespaceAttribute = std::make_shared(SYNS_AttrSpace); addAttribute(mWhitespaceAttribute); mStringAttribute = std::make_shared(SYNS_AttrString); addAttribute(mStringAttribute); mSymbolAttribute = std::make_shared(SYNS_AttrSymbol); addAttribute(mSymbolAttribute); } PSynHighlighterAttribute SynEditASMHighlighter::numberAttribute() { return mNumberAttribute; } void SynEditASMHighlighter::CommentProc() { mTokenID = TokenKind::Comment; do { mRun++; } while (! (mLine[mRun]==0 || mLine[mRun] == '\r' || mLine[mRun]=='\n')); } void SynEditASMHighlighter::CRProc() { mTokenID = TokenKind::Space; mRun++; if (mLine[mRun] == '\n') mRun++; } void SynEditASMHighlighter::GreaterProc() { mRun++; mTokenID = TokenKind::Symbol; if (mLine[mRun] == '=') mRun++; } void SynEditASMHighlighter::IdentProc() { int start = mRun; while (isIdentChar(mLine[mRun])) { mRun++; } QString s = mLineString.mid(start,mRun-start); if (Keywords.contains(s)) { mTokenID = TokenKind::Key; } else { mTokenID = TokenKind::Identifier; } } void SynEditASMHighlighter::LFProc() { mTokenID = TokenKind::Space; mRun++; } void SynEditASMHighlighter::LowerProc() { mRun++; mTokenID = TokenKind::Symbol; if (mLine[mRun]=='=' || mLine[mRun]== '>') mRun++; } void SynEditASMHighlighter::NullProc() { mTokenID = TokenKind::Null; } void SynEditASMHighlighter::NumberProc() { mRun++; mTokenID = TokenKind::Number; while (true) { QChar ch = mLine[mRun]; if (!((ch>='0' && ch<='9') || (ch=='.') || (ch >= 'a' && ch<='f') || (ch=='h') || (ch >= 'A' && ch<='F') || (ch == 'H'))) break; mRun++; } } void SynEditASMHighlighter::SingleQuoteStringProc() { mTokenID = TokenKind::String; if ((mRun+2 < mLineString.size()) && (mLine[mRun + 1] == '\'') && (mLine[mRun + 2] == '\'')) mRun += 2; while (true) { if (mLine[mRun] == 0 || mLine[mRun] == '\r' || mLine[mRun] == '\n' || mLine[mRun] == '\'') break; mRun++; } if (mLine[mRun]!=0) mRun++; } void SynEditASMHighlighter::SlashProc() { mRun++; if (mLine[mRun] == '/') { mTokenID = TokenKind::Comment; while (true) { mRun++; if (mLine[mRun] == 0 || mLine[mRun] == '\r' || mLine[mRun] == '\n') break; } } else mTokenID = TokenKind::Symbol; } void SynEditASMHighlighter::SpaceProc() { mTokenID = TokenKind::Space; while (true) { mRun++; if (mLine[mRun] == 0 || mLine[mRun] == '\r' || mLine[mRun] == '\n') break; if (mLine[mRun] > 32) break; } } void SynEditASMHighlighter::StringProc() { mTokenID = TokenKind::String; if ((mRun+2 < mLineString.size()) && (mLine[mRun + 1] == '\"') && (mLine[mRun + 2] == '\"')) mRun += 2; while (true) { if (mLine[mRun] == 0 || mLine[mRun] == '\r' || mLine[mRun] == '\n') break; if (mLine[mRun] == '\"') break; mRun += 1; } if (mLine[mRun]!=0) mRun++; } void SynEditASMHighlighter::SymbolProc() { mRun++; mTokenID = TokenKind::Symbol; } void SynEditASMHighlighter::UnknownProc() { mRun++; mTokenID = TokenKind::Unknown; } bool SynEditASMHighlighter::eol() const { return mTokenID == TokenKind::Null; } QString SynEditASMHighlighter::languageName() { return "asm"; } SynHighlighterLanguage SynEditASMHighlighter::language() { return SynHighlighterLanguage::Asssembly; } QString SynEditASMHighlighter::getToken() const { return mLineString.mid(mTokenPos,mRun-mTokenPos); } PSynHighlighterAttribute SynEditASMHighlighter::getTokenAttribute() const { switch(mTokenID) { case TokenKind::Comment: return mCommentAttribute; case TokenKind::Identifier: return mIdentifierAttribute; case TokenKind::Key: return mKeywordAttribute; case TokenKind::Number: return mNumberAttribute; case TokenKind::Space: return mWhitespaceAttribute; case TokenKind::String: return mStringAttribute; case TokenKind::Symbol: return mSymbolAttribute; case TokenKind::Unknown: return mIdentifierAttribute; } return PSynHighlighterAttribute(); } SynTokenKind SynEditASMHighlighter::getTokenKind() { return mTokenID; } SynHighlighterTokenType SynEditASMHighlighter::getTokenType() { switch(mTokenID) { case TokenKind::Comment: return SynHighlighterTokenType::Comment; case TokenKind::Identifier: return SynHighlighterTokenType::Identifier; case TokenKind::Key: return SynHighlighterTokenType::Keyword; case TokenKind::Number: return SynHighlighterTokenType::Number; case TokenKind::Space: return SynHighlighterTokenType::Space; case TokenKind::String: return SynHighlighterTokenType::String; case TokenKind::Symbol: return SynHighlighterTokenType::Symbol; case TokenKind::Unknown: return SynHighlighterTokenType::Default; } return SynHighlighterTokenType::Default; } int SynEditASMHighlighter::getTokenPos() { return mTokenPos; } void SynEditASMHighlighter::next() { mTokenPos = mRun; switch(mLine[mRun].unicode()) { case 0: NullProc(); break; case '\n': LFProc(); break; case '\r': CRProc(); break; case '\"': StringProc(); break; case '\'': SingleQuoteStringProc(); break; case '>': GreaterProc(); break; case '<': LowerProc(); break; case '/': SlashProc(); break; case '#': case ';': CommentProc(); break; case '.': case ':': case '&': case '{': case '}': case '=': case '^': case '-': case '+': case '(': case ')': case '*': SymbolProc(); break; default: if (mLine[mRun]>='0' && mLine[mRun]<='9') { NumberProc(); } else if ((mLine[mRun]>='A' && mLine[mRun]<='Z') || (mLine[mRun]>='a' && mLine[mRun]<='z') || (mLine[mRun]=='_')) { IdentProc(); } else if (mLine[mRun]<=32) { SpaceProc(); } else { UnknownProc(); } } } void SynEditASMHighlighter::setLine(const QString &newLine, int lineNumber) { mLineString = newLine; mLine = mLineString.data(); mLineNumber = lineNumber; mRun = 0; next(); } SynHighlighterClass SynEditASMHighlighter::getClass() const { return SynHighlighterClass::CppHighlighter; } QString SynEditASMHighlighter::getName() const { return SYN_HIGHLIGHTER_CPP; } bool SynEditASMHighlighter::getTokenFinished() const { return true; } bool SynEditASMHighlighter::isLastLineCommentNotFinished(int /*state*/) const { return true; } bool SynEditASMHighlighter::isLastLineStringNotFinished(int /*state*/) const { return true; } SynRangeState SynEditASMHighlighter::getRangeState() const { return SynRangeState(); } void SynEditASMHighlighter::setState(const SynRangeState&) { } void SynEditASMHighlighter::resetState() { } QSet SynEditASMHighlighter::keywords() const { return Keywords; }