// numexpr := addexpr ((PLUS|MINUS) addexpr)* private NumberExpression ParseNumberExpression() { NumberExpression operand1 = ParseAddExpression(); AsmToken nextToken = lexer.PeekNextToken(); while (nextToken.Type == AsmTokenType.PLUS || nextToken.Type == AsmTokenType.MINUS) { lexer.ConsumeToken(); NumberExpression operand2 = ParseAddExpression(); if (nextToken.Type == AsmTokenType.PLUS) { operand1 = new NumberOperationExpression(operand1, NumberOperationType.Addition, operand2); } else if (nextToken.Type == AsmTokenType.MINUS) { operand1 = new NumberOperationExpression(operand1, NumberOperationType.Subtraction, operand2); } nextToken = lexer.PeekNextToken(); } return operand1; }
// Param type : Address | Bit | FlagCondition | Flags | IOPortRegister | // Indexed | InterruptMode | Number | Register | Register16 | RegisterIndirect // opcodeparam := *OPENINGPAR numexpr CLOSINGPAR | *BIT | *FLAGCONDITION | *FLAGS | *OPENINGPAR REGISTER CLOSINGPAR | // *OPENINGPAR REGISTER16 (PLUS|MINUS) numexpr CLOSINGPAR | *INTERRUPTMODE | *numexpr | *REGISTER | *REGISTER16 | *OPENINGPAR REGISTER16 CLOSINGPAR private void ParseOpcodeParam() { AsmToken nextToken = lexer.PeekNextToken(); if (nextToken.Type == AsmTokenType.BIT) { AsmToken bitToken = lexer.GetNextToken(); InstructionLineParam bitParam = new InstructionLineParam() { Type = InstructionLineParamType.Bit, Bit = AsmLexer.ParseBitToken(bitToken.Text) }; bitParam.Tokens.Add(bitToken); prgLine.OpCodeParameters.Add(bitParam); } else if (nextToken.Type == AsmTokenType.FLAGCONDITION) { AsmToken flagConditionToken = lexer.GetNextToken(); InstructionLineParam flagConditionParam = new InstructionLineParam() { Type = InstructionLineParamType.FlagCondition, FlagCondition = AsmLexer.ParseFlagConditionToken(flagConditionToken.Text) }; flagConditionParam.Tokens.Add(flagConditionToken); prgLine.OpCodeParameters.Add(flagConditionParam); } else if (nextToken.Type == AsmTokenType.FLAGS) { AsmToken flagsToken = lexer.GetNextToken(); InstructionLineParam flagsParam = new InstructionLineParam() { Type = InstructionLineParamType.Flags }; flagsParam.Tokens.Add(flagsToken); prgLine.OpCodeParameters.Add(flagsParam); } else if (nextToken.Type == AsmTokenType.INTERRUPTMODE) { AsmToken interruptModeToken = lexer.GetNextToken(); InstructionLineParam interruptModeParam = new InstructionLineParam() { Type = InstructionLineParamType.InterruptMode, InterruptMode = AsmLexer.ParseInterruptModeToken(interruptModeToken.Text) }; interruptModeParam.Tokens.Add(interruptModeToken); prgLine.OpCodeParameters.Add(interruptModeParam); } else if (nextToken.Type == AsmTokenType.REGISTER) { AsmToken registerToken = lexer.GetNextToken(); InstructionLineParam registerParam = new InstructionLineParam() { Type = InstructionLineParamType.Register, Register = AsmLexer.ParseRegisterToken(registerToken.Text) }; registerParam.Tokens.Add(registerToken); prgLine.OpCodeParameters.Add(registerParam); } else if (nextToken.Type == AsmTokenType.REGISTER16) { AsmToken register16Token = lexer.GetNextToken(); InstructionLineParam register16Param = new InstructionLineParam() { Type = InstructionLineParamType.Register16, Register16 = AsmLexer.ParseRegister16Token(register16Token.Text) }; register16Param.Tokens.Add(register16Token); prgLine.OpCodeParameters.Add(register16Param); } else if (nextToken.Type == AsmTokenType.OPENINGPAR) { lexer.StartTokenList(); InstructionLineParam resultLineParam = null; lexer.ConsumeToken(); nextToken = lexer.PeekNextToken(); if (nextToken.Type == AsmTokenType.REGISTER) { AsmToken registerToken = lexer.GetNextToken(); InstructionLineParam registerParam = new InstructionLineParam() { Type = InstructionLineParamType.IOPortRegister, Register = AsmLexer.ParseRegisterToken(registerToken.Text) }; resultLineParam = registerParam; prgLine.OpCodeParameters.Add(registerParam); } else if (nextToken.Type == AsmTokenType.REGISTER16) { AsmToken register16Token = lexer.GetNextToken(); Register16 register16 = AsmLexer.ParseRegister16Token(register16Token.Text); nextToken = lexer.PeekNextToken(); if (nextToken.Type == AsmTokenType.PLUS || nextToken.Type == AsmTokenType.MINUS) { AsmToken operatorToken = lexer.GetNextToken(); NumberExpression numberExpression = ParseNumberExpression(); NumberExpression displacementExpression = null; if (operatorToken.Type == AsmTokenType.PLUS) { displacementExpression = numberExpression; } else if (operatorToken.Type == AsmTokenType.MINUS) { displacementExpression = new NumberOperationExpression( new NumberOperand(0), NumberOperationType.Subtraction, numberExpression); } InstructionLineParam indexedParam = new InstructionLineParam() { Type = InstructionLineParamType.Indexed, Register16 = register16, NumberExpression = displacementExpression }; resultLineParam = indexedParam; prgLine.OpCodeParameters.Add(indexedParam); } else { InstructionLineParam register16Param = new InstructionLineParam() { Type = InstructionLineParamType.RegisterIndirect, Register16 = register16 }; resultLineParam = register16Param; prgLine.OpCodeParameters.Add(register16Param); } } else { NumberExpression numberExpression = ParseNumberExpression(); InstructionLineParam numberParam = new InstructionLineParam() { Type = InstructionLineParamType.Address, NumberExpression = numberExpression }; resultLineParam = numberParam; prgLine.OpCodeParameters.Add(numberParam); } nextToken = lexer.PeekNextToken(); if (nextToken.Type == AsmTokenType.CLOSINGPAR) { lexer.ConsumeToken(); } else { throw new Exception(String.Format("Line {0} : Expecting closing parenthesis ) at column {1} instead of {2} : {3}", lineNumber, nextToken.StartIndex, nextToken.Type.ToString(), nextToken.Text)); } ((List<AsmToken>)resultLineParam.Tokens).AddRange(lexer.EndTokenList()); } else { lexer.StartTokenList(); NumberExpression numberExpression = ParseNumberExpression(); InstructionLineParam numberParam = new InstructionLineParam() { Type = InstructionLineParamType.Number, NumberExpression = numberExpression }; prgLine.OpCodeParameters.Add(numberParam); ((List<AsmToken>)numberParam.Tokens).AddRange(lexer.EndTokenList()); } }
// addexpr := operand (MULTIPLY operand)* private NumberExpression ParseAddExpression() { NumberExpression operand1 = ParseOperandExpression(); AsmToken nextToken = lexer.PeekNextToken(); while (nextToken.Type == AsmTokenType.MULTIPLY) { lexer.ConsumeToken(); NumberExpression operand2 = ParseOperandExpression(); operand1 = new NumberOperationExpression(operand1, NumberOperationType.Multiplication, operand2); nextToken = lexer.PeekNextToken(); } return operand1; }