Assembler { public static List<Instruction> processChanDirectives(List<Instruction> instructions, AssemblerConfig config) { List<Instruction> fixedAssembly = new ArrayList<>(); Pattern chanDirective = Pattern.compile("^\\h*#chan\\h+(?<channelname>[0-9A-Za-z]+)\\h*$"); for (Instruction instruction : instructions) { if (instruction.type == InstructionType.DIRECTIVE && instruction.directive != null) { Matcher chanDirectiveMatcher = chanDirective.matcher(instruction.directive); if (chanDirectiveMatcher.matches()) { String channelName = chanDirectiveMatcher.group("channelname"); Optional<IOPin> ioPinMatchingComment = config.getProcessor().getIopins().stream() .filter(p -> p.getChannel().equals(channelName)) .findFirst(); if (ioPinMatchingComment.isPresent()) { fixedAssembly.add(new Instruction(InstructionType.INSTRUCTION, instruction.label, opcodes.get("ldc"), (long) ioPinMatchingComment.get().getAddr(), null, instruction.comment, null, instruction.originalLine)); } else { throw new IllegalArgumentException("'" + channelName + "' was not found in the config."); } } } else { fixedAssembly.add(instruction); } } return fixedAssembly; } private  Assembler(); @Nullable static AssemblerConfig loadConfig(@Nullable Reader configReader); static List<String> assemble(@Nonnull String input, @Nullable AssemblerConfig config, @Nonnull PrintStream logger, boolean insertIOConfiguration); @Nonnull static List<Instruction> parseAssembly(@Nonnull String input); static List<Instruction> insertIOConfiguration(List<Instruction> instructions, AssemblerConfig config); static List<Instruction> processDollarLabelOperands(List<Instruction> instructions); static List<Instruction> processChanDirectives(List<Instruction> instructions, AssemblerConfig config); static List<Instruction> processDataDirectives(List<Instruction> instructions); static Assembly makeLabelMap(List<Instruction> instructions); static Map<String, Long> getConfigLabels(@Nonnull AssemblerConfig config); static Assembly patchLabels(Assembly assembly); static List<Byte> processIndirectInstruction(Instruction instruction); static List<Byte> processDirectInstructionWithLabelOperand(Instruction instruction, Map<String, Long> labelMap); static byte processDirectInstructionWithConstantOperand(Instruction instruction); static List<Instruction> prefix(Instruction instruction); static ParseTree parseExpression(String expression, Function<AssemblerExpressionParser, ParseTree> startRule); final static long maxInt; final static long minInt; final static Pattern inputComment; final static Pattern instructionPattern; final static Pattern directivePattern; final static Pattern dollarPattern; static Map<String, Opcode> opcodes; }
@Test public void testProcessChanDirectives() { List<Instruction> instructions = Arrays.asList( new Instruction(InstructionType.DIRECTIVE, null, null, null, null, null, "#chan sensor", 1), new Instruction(InstructionType.INSTRUCTION, "alabel", Assembler.opcodes.get("ajw"), -10L, null, null, null, 2), new Instruction(InstructionType.DIRECTIVE, null, null, null, null, null, "\t#chan\tsensor", 3), new Instruction(InstructionType.DIRECTIVE, "anotherlabel", null, null, null, "a comment", "\t#chan\tsensor", 4) ); List<Instruction> processedInstructions = Assembler.processChanDirectives(instructions, getSampleConfig()); checkInstructionEquality( new Instruction(InstructionType.INSTRUCTION, null, Assembler.opcodes.get("ldc"), 70L, null, null, null, 1), processedInstructions.get(0)); checkInstructionEquality( new Instruction(InstructionType.INSTRUCTION, "alabel", Assembler.opcodes.get("ajw"), -10L, null, null, null, 2), processedInstructions.get(1)); checkInstructionEquality( new Instruction(InstructionType.INSTRUCTION, null, Assembler.opcodes.get("ldc"), 70L, null, null, null, 3), processedInstructions.get(2)); checkInstructionEquality( new Instruction(InstructionType.INSTRUCTION, "anotherlabel", Assembler.opcodes.get("ldc"), 70L, null, "a comment", null, 4), processedInstructions.get(3)); }