z80-tools/src/com/maccasoft/tools/editor/Z80TokenMarker.java

286 wiersze
12 KiB
Java

/*
* Copyright (c) 2018 Marco Maccaferri and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.maccasoft.tools.editor;
public class Z80TokenMarker extends TokenMarker {
static {
keywords.put("ADC", TokenId.Instruction);
keywords.put("ADD", TokenId.Instruction);
keywords.put("AND", TokenId.Instruction);
keywords.put("BIT", TokenId.Instruction);
keywords.put("CALL", TokenId.Instruction);
keywords.put("CCF", TokenId.Instruction);
keywords.put("CP", TokenId.Instruction);
keywords.put("CPD", TokenId.Instruction);
keywords.put("CPDR", TokenId.Instruction);
keywords.put("CPI", TokenId.Instruction);
keywords.put("CPIR", TokenId.Instruction);
keywords.put("CPL", TokenId.Instruction);
keywords.put("DAA", TokenId.Instruction);
keywords.put("DEC", TokenId.Instruction);
keywords.put("DI", TokenId.Instruction);
keywords.put("DJNZ", TokenId.Instruction);
keywords.put("EI", TokenId.Instruction);
keywords.put("EX", TokenId.Instruction);
keywords.put("EXX", TokenId.Instruction);
keywords.put("HALT", TokenId.Instruction);
keywords.put("IM", TokenId.Instruction);
keywords.put("INC", TokenId.Instruction);
keywords.put("IN", TokenId.Instruction);
keywords.put("INI", TokenId.Instruction);
keywords.put("IND", TokenId.Instruction);
keywords.put("INIR", TokenId.Instruction);
keywords.put("INDR", TokenId.Instruction);
keywords.put("JR", TokenId.Instruction);
keywords.put("JP", TokenId.Instruction);
keywords.put("LD", TokenId.Instruction);
keywords.put("LDI", TokenId.Instruction);
keywords.put("LDIR", TokenId.Instruction);
keywords.put("LDD", TokenId.Instruction);
keywords.put("LDDR", TokenId.Instruction);
keywords.put("NEG", TokenId.Instruction);
keywords.put("NOP", TokenId.Instruction);
keywords.put("OR", TokenId.Instruction);
keywords.put("OUT", TokenId.Instruction);
keywords.put("OUTI", TokenId.Instruction);
keywords.put("OUTD", TokenId.Instruction);
keywords.put("OTIR", TokenId.Instruction);
keywords.put("OTDR", TokenId.Instruction);
keywords.put("POP", TokenId.Instruction);
keywords.put("PUSH", TokenId.Instruction);
keywords.put("RES", TokenId.Instruction);
keywords.put("RET", TokenId.Instruction);
keywords.put("RETI", TokenId.Instruction);
keywords.put("RETN", TokenId.Instruction);
keywords.put("RL", TokenId.Instruction);
keywords.put("RLA", TokenId.Instruction);
keywords.put("RLC", TokenId.Instruction);
keywords.put("RLCA", TokenId.Instruction);
keywords.put("RLD", TokenId.Instruction);
keywords.put("RR", TokenId.Instruction);
keywords.put("RRA", TokenId.Instruction);
keywords.put("RRC", TokenId.Instruction);
keywords.put("RRCA", TokenId.Instruction);
keywords.put("RRD", TokenId.Instruction);
keywords.put("RST", TokenId.Instruction);
keywords.put("SBC", TokenId.Instruction);
keywords.put("SCF", TokenId.Instruction);
keywords.put("SET", TokenId.Instruction);
keywords.put("SLA", TokenId.Instruction);
keywords.put("SLL", TokenId.Instruction);
keywords.put("SRA", TokenId.Instruction);
keywords.put("SRL", TokenId.Instruction);
keywords.put("SUB", TokenId.Instruction);
keywords.put("XOR", TokenId.Instruction);
keywords.put("DB", TokenId.Directive2);
keywords.put("DD", TokenId.Directive2);
keywords.put("DS", TokenId.Directive2);
keywords.put("DW", TokenId.Directive2);
keywords.put("BYTE", TokenId.Directive2);
keywords.put("WORD", TokenId.Directive2);
keywords.put("TEXT", TokenId.Directive2);
keywords.put("INCLUDE", TokenId.Directive1);
keywords.put("INCBIN", TokenId.Directive1);
keywords.put("EQU", TokenId.Directive1);
keywords.put("ORG", TokenId.Directive2);
keywords.put("MACRO", TokenId.Directive1);
keywords.put("ENDM", TokenId.Directive1);
keywords.put("PROC", TokenId.Directive1);
keywords.put("ENDP", TokenId.Directive1);
keywords.put("SECTION", TokenId.Directive1);
keywords.put("ENDS", TokenId.Directive1);
keywords.put("IF", TokenId.Directive1);
keywords.put("ELSE", TokenId.Directive1);
keywords.put("ENDIF", TokenId.Directive1);
keywords.put("END", TokenId.Directive1);
keywords.put("ERROR", TokenId.Directive1);
keywords.put("WARNING", TokenId.Directive1);
keywords.put("FILL", TokenId.Directive1);
keywords.put("REPT", TokenId.Directive1);
keywords.put("IRP", TokenId.Directive1);
keywords.put("ONCE", TokenId.Directive1);
keywords.put(".DB", TokenId.Directive2);
keywords.put(".DD", TokenId.Directive2);
keywords.put(".DS", TokenId.Directive2);
keywords.put(".DW", TokenId.Directive2);
keywords.put(".BYTE", TokenId.Directive2);
keywords.put(".WORD", TokenId.Directive2);
keywords.put(".TEXT", TokenId.Directive2);
keywords.put(".INCLUDE", TokenId.Directive1);
keywords.put(".INCBIN", TokenId.Directive1);
keywords.put(".EQU", TokenId.Directive1);
keywords.put(".ORG", TokenId.Directive2);
keywords.put(".MACRO", TokenId.Directive1);
keywords.put(".ENDM", TokenId.Directive1);
keywords.put(".PROC", TokenId.Directive1);
keywords.put(".ENDP", TokenId.Directive1);
keywords.put(".SECTION", TokenId.Directive1);
keywords.put(".ENDS", TokenId.Directive1);
keywords.put(".IF", TokenId.Directive1);
keywords.put(".ELSE", TokenId.Directive1);
keywords.put(".ENDIF", TokenId.Directive1);
keywords.put(".END", TokenId.Directive1);
keywords.put(".ERROR", TokenId.Directive1);
keywords.put(".WARNING", TokenId.Directive1);
keywords.put(".FILL", TokenId.Directive1);
keywords.put(".REPT", TokenId.Directive1);
keywords.put(".IRP", TokenId.Directive1);
keywords.put("A", TokenId.Register);
keywords.put("B", TokenId.Register);
keywords.put("C", TokenId.Register);
keywords.put("D", TokenId.Register);
keywords.put("E", TokenId.Register);
keywords.put("F", TokenId.Register);
keywords.put("H", TokenId.Register);
keywords.put("L", TokenId.Register);
keywords.put("AF", TokenId.Register);
keywords.put("BC", TokenId.Register);
keywords.put("DE", TokenId.Register);
keywords.put("HL", TokenId.Register);
keywords.put("SP", TokenId.Register);
keywords.put("IX", TokenId.Register);
keywords.put("IY", TokenId.Register);
keywords.put("I", TokenId.Register);
keywords.put("R", TokenId.Register);
keywords.put("Z", TokenId.Flag);
keywords.put("NZ", TokenId.Flag);
keywords.put("C", TokenId.Flag);
keywords.put("NC", TokenId.Flag);
keywords.put("PO", TokenId.Flag);
keywords.put("PE", TokenId.Flag);
keywords.put("P", TokenId.Flag);
keywords.put("M", TokenId.Flag);
}
public Z80TokenMarker() {
}
@Override
public Token markTokens(String text, int offset) {
boolean backslash = false;
TokenId token = TokenId.Null;
firstToken = lastToken = null;
lastOffset = lastKeyword = 0;
int start = 0;
for (int i = start; i < text.length(); i++) {
int i1 = (i + 1);
char c = text.charAt(i);
if (c == '\\') {
backslash = !backslash;
continue;
}
switch (token) {
case Null:
switch (c) {
case '\'':
case '"':
doKeyword(text, i, c);
if (backslash) {
backslash = false;
}
else {
addToken(i - lastOffset, token);
token = c == '"' ? TokenId.StringLiteral1 : TokenId.StringLiteral2;
lastOffset = lastKeyword = i;
}
break;
case ';': {
backslash = false;
doKeyword(text, i, c);
addToken(i - lastOffset, token);
int mlength = text.indexOf('\n', i);
if (mlength == -1) {
mlength = text.length();
}
addToken(mlength - i, TokenId.Comment);
lastOffset = lastKeyword = i = mlength;
break;
}
case '$':
backslash = false;
doKeyword(text, i, c);
addToken(i - lastOffset, token);
int mlength = i + 1;
while (mlength < text.length() && isHexDigit(text.charAt(mlength))) {
mlength++;
}
if ((mlength - i) > 1) {
addToken(mlength - i, TokenId.NumberLiteral);
lastOffset = lastKeyword = i = mlength;
}
break;
default:
backslash = false;
if (!Character.isLetterOrDigit(c) && c != '_' && c != '.') {
doKeyword(text, i, c);
}
break;
}
break;
case StringLiteral1:
if (backslash) {
backslash = false;
}
else if (c == '"') {
addToken(i1 - lastOffset, token);
token = TokenId.Null;
lastOffset = lastKeyword = i1;
}
break;
case StringLiteral2:
if (backslash) {
backslash = false;
}
else if (c == '\'') {
addToken(i1 - lastOffset, token);
token = TokenId.Null;
lastOffset = lastKeyword = i1;
}
break;
default:
// Do nothing
break;
}
}
if (token == TokenId.Null) {
doKeyword(text, text.length(), '\0');
}
switch (token) {
case StringLiteral1:
case StringLiteral2:
addToken(text.length() - lastOffset, null);
token = null;
break;
default:
addToken(text.length() - lastOffset, token);
break;
}
return firstToken;
}
}