Started working on macro support. Macro-Definition are now plain, unparsed lines. Added Syntax-Highlighter options.

This commit is contained in:
2021-07-27 12:42:26 +02:00
parent f006199201
commit 6e683eb6a0
22 changed files with 1117 additions and 462 deletions
@@ -8,6 +8,7 @@ import de.platon42.intellij.plugins.m68k.asm.M68kIsa.mnemonics
object LexerUtil {
private val ASSIGNMENT_SEPARATORS = charArrayOf(' ', '\t', '=', ':')
private val TOKEN_SEPARATORS = charArrayOf(' ', '\t')
@JvmStatic
fun isAsmMnemonic(text: CharSequence) = mnemonics.contains(text.toString().lowercase())
@@ -28,6 +29,11 @@ object LexerUtil {
return text.length - text.indexOfAny(ASSIGNMENT_SEPARATORS)
}
@JvmStatic
fun pushbackAfterFirstToken(text: CharSequence): Int {
return text.length - text.indexOfAny(TOKEN_SEPARATORS)
}
@JvmStatic
fun pushbackLabelColons(text: CharSequence): Int {
return text.count { it == ':' }
@@ -38,7 +44,17 @@ object LexerUtil {
if (!lexer.eatOneWhitespace && lexer.lexerPrefs.spaceIntroducesComment) {
lexer.yybegin(_M68kLexer.WAITEOL)
}
lexer.eatOneWhitespace = false;
lexer.eatOneWhitespace = false
return TokenType.WHITE_SPACE
}
@JvmStatic
fun handleMacroLineEol(lexer: _M68kLexer): IElementType {
if (++lexer.macroLines > lexer.lexerPrefs.maxLinesPerMacro) {
lexer.yybegin(_M68kLexer.YYINITIAL)
return TokenType.BAD_CHARACTER
}
lexer.yybegin(_M68kLexer.MACROLINE)
return TokenType.WHITE_SPACE
}
}
@@ -13,6 +13,7 @@ import static de.platon42.intellij.plugins.m68k.lexer.LexerUtil.*;
%{
private M68kLexerPrefs lexerPrefs;
boolean eatOneWhitespace = false;
int macroLines = 0;
public M68kLexerPrefs getLexerPrefs()
{
@@ -38,10 +39,12 @@ WHITE_SPACE=\p{Blank}+
AREG=(a[0-6])
DREG=(d[0-7])
ASSIGNMENT=(([:letter:]|_)(([:letter:]|[:digit:])|_)*:?((\p{Blank}+equ\p{Blank}+)|(\p{Blank}+set\p{Blank}+)|\p{Blank}*=\p{Blank}*))
LOCAL_LABEL=(\.([:letter:]|_)(([:letter:]|[:digit:])|_)*:?)|(([:letter:]|_)(([:letter:]|[:digit:])|_)*\$:?)
LOCAL_LABEL_WC=(\.([:letter:]|_)(([:letter:]|[:digit:])|_)*:)|(([:letter:]|_)(([:letter:]|[:digit:])|_)*\$:)
GLOBAL_LABEL=(([:letter:]|_)(([:letter:]|[:digit:])|_)*:?:?)
GLOBAL_LABEL_WC=(([:letter:]|_)(([:letter:]|[:digit:])|_)*::?)
LOCAL_LABEL=(\.([:letter:]|_)([:letter:]|[:digit:]|_)*:?)|(([:letter:]|_)([:letter:]|[:digit:]|_)*\$:?)
LOCAL_LABEL_WC=(\.([:letter:]|_)([:letter:]|[:digit:]|_)*:)|(([:letter:]|_)([:letter:]|[:digit:]|_)*\$:)
GLOBAL_LABEL=(([:letter:]|_)([:letter:]|[:digit:]|_)*:?:?)
GLOBAL_LABEL_WC=(([:letter:]|_)([:letter:]|[:digit:]|_)*::?)
MACRO_DEF_LEFT=(([:letter:]|_)(([:letter:]|[:digit:]|_))*)\p{Blank}+macro\p{Blank}*
MACRO_END_TAG=\p{Blank}+endm\p{Blank}*[^;\r\n]*
//MNEMONIC=(([:letter:])+)
SYMBOL=(([:letter:]|_|\.)(([:letter:]|[:digit:]|[_\$]))*)
BONUSSYMBOL=(([:letter:]|_|\.)(([:letter:]|[:digit:]|[_\$\.\\]))*)
@@ -59,14 +62,16 @@ PLAINPARAM=(`([^`\\\r\n]|\\.)*`|'([^'\\\r\n]|\\.)*'|\"([^\"\\\r\n]|\\.)*\")|<([^
COMMENT=([;].*+)
HASH_COMMENT=([#;*].*+)
SKIP_TO_EOL=[^\r\n]+
PLAIN_MACRO_LINE=[^;\r\n]+
%state NOSOL,INSTRPART,ASMINSTR,ASMOPS,ASMOPS_OP,ASSIGNMENT,EXPR,EXPR_OP,MACROCALL,WAITEOL
%state NOSOL,INSTRPART,ASMINSTR,ASMOPS,ASMOPS_OP,ASSIGNMENT,EXPR,EXPR_OP,MACROCALL,WAITEOL,MACRODEF,MACROLINE,MACROTERMINATION,MACROWAITEOL
%%
<YYINITIAL> {
{WHITE_SPACE} { yybegin(NOSOL); eatOneWhitespace = false; return WHITE_SPACE; }
{EOL} { return WHITE_SPACE; }
{ASSIGNMENT} { yybegin(ASSIGNMENT); eatOneWhitespace = true; yypushback(pushbackAssignment(yytext())); return SYMBOLDEF; }
{MACRO_DEF_LEFT} { yybegin(MACRODEF); yypushback(pushbackAfterFirstToken(yytext())); return MACRO_NAME; }
{LOCAL_LABEL} { yybegin(INSTRPART); eatOneWhitespace = false; yypushback(pushbackLabelColons(yytext())); return LOCAL_LABEL_DEF; }
{GLOBAL_LABEL} { yybegin(INSTRPART); eatOneWhitespace = false; yypushback(pushbackLabelColons(yytext())); return GLOBAL_LABEL_DEF; }
@@ -78,6 +83,7 @@ SKIP_TO_EOL=[^\r\n]+
{EOL} { yybegin(YYINITIAL); return WHITE_SPACE; }
{LOCAL_LABEL_WC} { yybegin(INSTRPART); yypushback(pushbackLabelColons(yytext())); return LOCAL_LABEL_DEF; }
{GLOBAL_LABEL_WC} { yybegin(INSTRPART); yypushback(pushbackLabelColons(yytext())); return GLOBAL_LABEL_DEF; }
"macro" { yybegin(MACRODEF); return MACRO_TAG; }
{DIRECTIVE_KEYWORD} {
if(isAsmMnemonicWithSize(yytext())) { yybegin(ASMINSTR); yypushback(2); return MNEMONIC; }
if(isAsmMnemonic(yytext())) { yybegin(ASMINSTR); return MNEMONIC; }
@@ -288,4 +294,35 @@ SKIP_TO_EOL=[^\r\n]+
{SKIP_TO_EOL} { return COMMENT; }
}
// The macro mess starts here
<MACRODEF> {
{WHITE_SPACE} { return WHITE_SPACE; }
{EOL} { yybegin(MACROLINE); macroLines = 0; return WHITE_SPACE; }
"macro" { return MACRO_TAG; }
{MACRONAME} { return MACRO_NAME; }
{COMMENT} { yybegin(MACROWAITEOL); return COMMENT; }
}
<MACROLINE> {
{EOL} { return handleMacroLineEol(this); }
{MACRO_END_TAG} { yybegin(MACROTERMINATION); return MACRO_END_TAG; }
{PLAIN_MACRO_LINE} { return MACRO_LINE; }
{COMMENT} { yybegin(MACROWAITEOL); return COMMENT; }
}
<MACROTERMINATION> {
{WHITE_SPACE} { return WHITE_SPACE; }
{EOL} { yybegin(YYINITIAL); return EOL; }
{COMMENT} { yybegin(WAITEOL); return COMMENT; }
}
<MACROWAITEOL>
{
{EOL} { return handleMacroLineEol(this); }
{SKIP_TO_EOL} { return COMMENT; }
}
[^] { return BAD_CHARACTER; }
@@ -118,7 +118,7 @@
M68kFile ::= line*
private line ::= !<<eof>> statement (<<eof>>|EOL)
private line ::= !<<eof>> (MacroDefinition | statement) (<<eof>>|EOL)
statement ::= (Assignment
| PreprocessorDirective
@@ -170,6 +170,11 @@ AsmOp ::= MNEMONIC OperandSize?
PreprocessorDirective ::= Label? (DATA_DIRECTIVE | OTHER_DIRECTIVE)
PreprocessorOperands?
MacroPlainLine ::= MACRO_LINE
MacroNameDefinition ::= MACRO_NAME
MacroDefinition ::= ((MacroNameDefinition MACRO_TAG)|(MACRO_TAG MacroNameDefinition)) MacroPlainLine* MACRO_END_TAG {pin=1}
MacroCall ::= MACRO_INVOKATION PlainOperands?
AsmInstruction ::= AsmOp AsmOperands?
private Instruction ::= AsmInstruction | MacroCall
@@ -18,6 +18,9 @@ import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.GLOBAL_LABEL
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.LOCAL_LABEL
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.MACRO_CALL
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.MACRO_LINE
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.MACRO_NAME_DEF
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.MACRO_PREPROCESSOR
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.MNEMONIC
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.NUMBER
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.OTHER_PREPROCESSOR
@@ -26,8 +29,8 @@ import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.SPECIAL_REG
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.STACK_POINTER
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.STRING
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.SYMBOLDEF
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.SYMBOLREF
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.SYMBOL_DEF
import de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighter.Companion.SYMBOL_REF
import org.jetbrains.annotations.NonNls
import javax.swing.Icon
@@ -49,7 +52,7 @@ PIC_HEIGHT = 256
include "../includes/hardware/custom.i"
BLTHOGON MACRO ; macro definition
move.w #DMAF_SETCLR|DMAF_BLITHOG,dmacon(a5)
move.w #DMAF_SETCLR|DMAF_BLITHOG,dmacon(a5) ; hog!
ENDM
demo_init ; global label
@@ -99,9 +102,12 @@ hello: dc.b 'Hello World!',10,0
AttributesDescriptor("Local labels", LOCAL_LABEL),
AttributesDescriptor("Comma (separator)", SEPARATOR),
AttributesDescriptor("Colon", COLON),
AttributesDescriptor("Symbol definition", SYMBOLDEF),
AttributesDescriptor("Symbol reference", SYMBOLREF),
AttributesDescriptor("Symbol definition", SYMBOL_DEF),
AttributesDescriptor("Symbol reference", SYMBOL_REF),
AttributesDescriptor("Assembly mnemonic", MNEMONIC),
AttributesDescriptor("Macro name definition", MACRO_NAME_DEF),
AttributesDescriptor("Macro preprocessor directives", MACRO_PREPROCESSOR),
AttributesDescriptor("Macro line", MACRO_LINE),
AttributesDescriptor("Macro invocation", MACRO_CALL),
AttributesDescriptor("Data width: Byte/short", DATA_WIDTH_BS),
AttributesDescriptor("Data width: Word", DATA_WIDTH_W),
@@ -28,11 +28,14 @@ class M68kSyntaxHighlighter(val project: Project?) : SyntaxHighlighterBase() {
M68kTypes.COLON -> arrayOf(COLON)
M68kTypes.GLOBAL_LABEL_DEF -> arrayOf(GLOBAL_LABEL)
M68kTypes.LOCAL_LABEL_DEF -> arrayOf(LOCAL_LABEL)
M68kTypes.SYMBOLDEF -> arrayOf(SYMBOLDEF)
M68kTypes.SYMBOL -> arrayOf(SYMBOLREF)
M68kTypes.SYMBOLDEF -> arrayOf(SYMBOL_DEF)
M68kTypes.SYMBOL -> arrayOf(SYMBOL_REF)
M68kTypes.CURRENT_PC_SYMBOL, M68kTypes.PC -> arrayOf(PROGRAM_COUNTER)
M68kTypes.MNEMONIC -> arrayOf(MNEMONIC)
M68kTypes.MACRO_TAG, M68kTypes.MACRO_END_TAG -> arrayOf(MACRO_PREPROCESSOR)
M68kTypes.MACRO_LINE -> arrayOf(MACRO_LINE)
M68kTypes.MACRO_INVOKATION -> arrayOf(MACRO_CALL)
M68kTypes.MACRO_NAME -> arrayOf(MACRO_NAME_DEF)
M68kTypes.DATA_DIRECTIVE -> arrayOf(DATA_PREPROCESSOR)
M68kTypes.OTHER_DIRECTIVE, M68kTypes.EQU -> arrayOf(OTHER_PREPROCESSOR)
M68kTypes.OPSIZE_BS -> arrayOf(DATA_WIDTH_BS)
@@ -55,9 +58,12 @@ class M68kSyntaxHighlighter(val project: Project?) : SyntaxHighlighterBase() {
val LOCAL_LABEL = TextAttributesKey.createTextAttributesKey("MC68000_GLOBAL_LABEL", DefaultLanguageHighlighterColors.FUNCTION_DECLARATION)
val SEPARATOR = TextAttributesKey.createTextAttributesKey("MC68000_SEPARATOR", DefaultLanguageHighlighterColors.COMMA)
val COLON = TextAttributesKey.createTextAttributesKey("MC68000_COLON", DefaultLanguageHighlighterColors.DOT)
val SYMBOLDEF = TextAttributesKey.createTextAttributesKey("MC68000_SYMBOLDEF", DefaultLanguageHighlighterColors.CONSTANT)
val SYMBOLREF = TextAttributesKey.createTextAttributesKey("MC68000_SYMBOLREF", DefaultLanguageHighlighterColors.IDENTIFIER)
val SYMBOL_DEF = TextAttributesKey.createTextAttributesKey("MC68000_SYMBOLDEF", DefaultLanguageHighlighterColors.CONSTANT)
val SYMBOL_REF = TextAttributesKey.createTextAttributesKey("MC68000_SYMBOLREF", DefaultLanguageHighlighterColors.IDENTIFIER)
val MNEMONIC = TextAttributesKey.createTextAttributesKey("MC68000_MNEMONIC", DefaultLanguageHighlighterColors.FUNCTION_CALL)
val MACRO_PREPROCESSOR = TextAttributesKey.createTextAttributesKey("MC68000_MACRO_PREPROCESSOR", DefaultLanguageHighlighterColors.INSTANCE_METHOD)
val MACRO_NAME_DEF = TextAttributesKey.createTextAttributesKey("MC68000_MACRO_NAME_DEF", DefaultLanguageHighlighterColors.METADATA)
val MACRO_LINE = TextAttributesKey.createTextAttributesKey("MC68000_MACRO_LINE", DefaultLanguageHighlighterColors.METADATA)
val MACRO_CALL = TextAttributesKey.createTextAttributesKey("MC68000_MACRO_CALL", DefaultLanguageHighlighterColors.STATIC_METHOD)
val DATA_WIDTH_BS = TextAttributesKey.createTextAttributesKey("MC68000_DATA_WIDTH_BS", DefaultLanguageHighlighterColors.DOT)
val DATA_WIDTH_L = TextAttributesKey.createTextAttributesKey("MC68000_DATA_WIDTH_W", DefaultLanguageHighlighterColors.DOT)