package org.reasm.m68k.source; import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; import org.reasm.commons.source.BlockDirective; import org.reasm.commons.source.BlockParser; import org.reasm.commons.source.Parser; import org.reasm.commons.source.Syntax; import com.google.common.collect.ImmutableMap; /** * The parser for M68000 family assembler source files. * * @author Francis Gagné */ @Immutable public final class M68KParser extends Parser { /** The syntax rules for the M68000 family assembly language. */ @Nonnull public static final Syntax SYNTAX; static { final int[] invalidIdentifierCodePoints = new int[] { '!', // logical NOT operator; "strictly different from" operator //'"', // string delimiter; allowed in identifiers, except as the first character //'#', // start of immediate data; allowed in identifiers, except as the first character //'$', // prefix for hexadecimal integer literals; allowed in identifiers, except as the first character '%', // modulo operator; prefix for binary integer literals '&', // bitwise AND operator; logical AND operator //'\'', // string delimiter; allowed in identifiers, except as the first character '(', // grouping left parenthesis; start of function call argument list ')', // grouping right parenthesis; end of function call argument list '*', // multiplication operator; part of index register scale specification '+', // addition operator; unary plus operator ',', // operand separator, argument separator '-', // subtraction operator; negation operator; part of register range specification //'.', // pseudo object member accessor (actually part of the symbol name) '/', // division operator; part of register list specification ':', // end of label; conditional operator, second part ';', // start of comment '<', // "less than" operator; "less than or equal to" operator; "different from" operator; bit shift left operator '=', // "equal to" operator; "strictly equal to" operator; "strictly different from" operator; "less than or equal to" operator; "greater than or equal to" operator '>', // "greater than" operator; "greater than or equal to" operator; "different from" operator; bit shift right operator '?', // conditional operator, first part //'@', // prefix for local symbols (part of the symbol name) '[', // start of array indexer '\\', // prefix for reference to a macro argument ']', // end of array indexer '^', // bitwise XOR operator //'`', // not assigned '{', // start of bit field specification '|', // bitwise OR operator; logical OR operator '}', // end of bit field specification '~', // bitwise NOT operator }; final int[] invalidIdentifierInitialCodePoints = new int[] { '"', '#', '$', '\'' }; SYNTAX = new Syntax(invalidIdentifierCodePoints, invalidIdentifierInitialCodePoints); } @Nonnull private static final ImmutableMap<BlockDirective, BlockParser> BLOCKS; static { final ImmutableMap.Builder<BlockDirective, BlockParser> blocks = ImmutableMap.builder(); blocks.put(M68KBlockDirectives.DO, BlockParsers.DO); blocks.put(M68KBlockDirectives.FOR, BlockParsers.FOR); blocks.put(M68KBlockDirectives.IF, BlockParsers.IF); blocks.put(M68KBlockDirectives.MACRO, BlockParsers.MACRO); blocks.put(M68KBlockDirectives.NAMESPACE, BlockParsers.NAMESPACE); blocks.put(M68KBlockDirectives.OBJ, BlockParsers.OBJ); blocks.put(M68KBlockDirectives.PHASE, BlockParsers.PHASE); blocks.put(M68KBlockDirectives.REPT, BlockParsers.REPT); blocks.put(M68KBlockDirectives.TRANSFORM, BlockParsers.TRANSFORM); blocks.put(M68KBlockDirectives.WHILE, BlockParsers.WHILE); BLOCKS = blocks.build(); } /** The single instance of the {@link M68KParser} class. */ @Nonnull public static final M68KParser INSTANCE = new M68KParser(); private M68KParser() { super(SYNTAX, M68KBlockDirectives.MAP, BLOCKS, M68KLogicalLineFactory.INSTANCE, M68KBlockDirectiveLineFactory.INSTANCE); } @Override public final String undecorateMnemonic(String mnemonic) { mnemonic = super.undecorateMnemonic(mnemonic); // If the mnemonic has a size attribute, remove it. final int indexOfPeriod = mnemonic.indexOf('.'); if (indexOfPeriod != -1) { mnemonic = mnemonic.substring(0, indexOfPeriod); } return mnemonic; } }