/// <summary> /// Creates a token out of a character group /// </summary> /// <param name="leftIdx">First index of the group</param> /// <param name="rightIdx">Last index of the group</param> /// <param name="charsInLine">Reference to the char array that contains the character group</param> private void MakeToken(int leftIdx, int rightIdx, ref char[] charsInLine) { // create a string from the character group string value = new string(charsInLine, leftIdx, rightIdx - leftIdx + 1); // token is a comment character group if (value.Contains("//")) { MakeToken(TokenType.LINE_COMMENT, value); } // token is an operator else if (OperatorsInfo.IsOperator(value)) { MakeToken(TokenType.OPERATOR, value); } // token is a register else if (IsRegister(leftIdx, rightIdx, ref charsInLine)) { MakeToken(TokenType.REGISTER, value); } // token is a variable assign keyword else if (value.ToLower().Equals("db")) { MakeToken(TokenType.VARIABLE_ASSIGN, value); } // token is a constant assign keyword else if (value.ToLower().Equals("const")) { MakeToken(TokenType.CONSTANT_ASSIGN, value); } // token is a ORG command keyword else if (value.ToLower().Equals("org")) { MakeToken(TokenType.ORIGIN, value); } // token is an identifier else if (!string.IsNullOrEmpty(value)) { MakeToken(TokenType.IDENTIFIER, value); } // token is null or empty // do nothing }
/// <summary> /// Parses the tokens provided by a lexer /// </summary> /// <param name="lexer"></param> private void ParseInstructions(Lexer lexer) { IFormatInstructions instruction; // iterate over every token while (lexer.MoveNext()) { Token currToken = lexer.CurrrentToken; // found a comment line if (currToken.Type == TokenType.LINE_COMMENT) { // ignore every token in that line while (lexer.CurrrentToken.Type != TokenType.NEW_LINE) { lexer.MoveNext(); } // now CurrentToken is a new Line } // found and origin else if (currToken.Type == TokenType.ORIGIN) { lexer.MoveNext(); // get the next token (address) associated with the ORG Token address = lexer.CurrrentToken; AddInstruction(new OriginCmd(currToken, address)); } // found an operator else if (OperatorsInfo.IsOperator(currToken.Value)) { // make instruction MakeInstruction(lexer); } // found variable assign without name else if (currToken.Type == TokenType.VARIABLE_ASSIGN) { List <Token> variableList = new List <Token>(); // move lexer to first param lexer.MoveNext(); // add params to list while (lexer.CurrrentToken.Type != TokenType.NEW_LINE) { variableList.Add(lexer.CurrrentToken); lexer.MoveNext(); } // add instruction to list AddInstruction(new VariableAssign(currToken, null, variableList.ToArray())); variableList.Clear(); } // found constant assignment else if (currToken.Type == TokenType.CONSTANT_ASSIGN) { // move to name lexer.MoveNext(); Token name = lexer.CurrrentToken; // move to value lexer.MoveNext(); Token value = lexer.CurrrentToken; AddInstruction(new ConstantAssign(currToken, name, value)); } // found a possible label, variable name for db, or possible typo in an operator else if (currToken.Type == TokenType.IDENTIFIER) { // found db after identifier. if (lexer.PeekNext().Type == TokenType.VARIABLE_ASSIGN) { List <Token> paramList = new List <Token>(); // move lexer to db keyword lexer.MoveNext(); Token dbKeyword = lexer.CurrrentToken; // move lexer to first param lexer.MoveNext(); // add params to list while (lexer.CurrrentToken.Type != TokenType.NEW_LINE) { paramList.Add(lexer.CurrrentToken); // iterate lexer.MoveNext(); } instruction = new VariableAssign(dbKeyword, currToken, paramList.ToArray()); AddInstruction(instruction); } // found a colon after identifier this means it is a label else if (lexer.PeekNext().Type == TokenType.COLON) { Token labelName = lexer.CurrrentToken; // start label block // add current label to the instruction list AddInstruction(new Label(labelName)); } else { List <Token> paramList = new List <Token>(); Token invalidInstruction = lexer.CurrrentToken; lexer.MoveNext(); // add params to list while (lexer.CurrrentToken.Type != TokenType.NEW_LINE) { paramList.Add(lexer.CurrrentToken); lexer.MoveNext(); } AddInstruction(new InvalidInstruction(invalidInstruction, paramList.ToArray())); } } } }
/// <summary> /// Creates an instruction /// </summary> /// <param name="lexer">Lexer to be used</param> private void MakeInstruction(Lexer lexer) { // tmep list to store possible parameters Token[] tempList = new Token[3]; // holder of instruction IFormatInstructions instruction; // parameter count int parameters = 0; // current token Token currToken = lexer.CurrrentToken; switch (OperatorsInfo.GetInstructionFormat(currToken)) { case EInstructionFormat.FORMAT_1: // extract possible registers while (parameters < OperatorsInfo.GetNumberOfParams(currToken)) { lexer.MoveNext(); tempList[parameters] = lexer.CurrrentToken; parameters++; } instruction = new InstructionFormat1( currToken, tempList[0], tempList[1], tempList[2] ); AddInstruction(instruction); break; case EInstructionFormat.FORMAT_2: // extract possible registers while (parameters < OperatorsInfo.GetNumberOfParams(currToken)) { lexer.MoveNext(); tempList[parameters] = lexer.CurrrentToken; parameters++; } instruction = new InstructionFormat2( currToken, tempList[0], tempList[1] ); AddInstruction(instruction); break; case EInstructionFormat.FORMAT_3: // extract possible registers while (parameters < OperatorsInfo.GetNumberOfParams(currToken)) { lexer.MoveNext(); tempList[parameters] = lexer.CurrrentToken; parameters++; } instruction = new InstructionFormat3( currToken, tempList[0] ); AddInstruction(instruction); break; default: break; } }