private void SecondParse() { Token token = null; while ((token = lexer.NextToken()).type != TokenType.EOF) { // Console.WriteLine ( token ); switch (token.type) { case TokenType.FUNC: isFuncActive = true; currentFunc = script.funcTable.GetFuncByName(lexer.NextToken().value); currentParamIndex = 0; break; case TokenType.CLOSE_BRACE: isFuncActive = false; if (currentFunc.name == XASMLexer.Keyworkd_Main) { script.instrStream.instrs [instrStreamSize].opCode = OpCode.Exit; script.instrStream.instrs [instrStreamSize].opCount = 1; script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.INT, intLiteral = 0 }); } else { script.instrStream.instrs [instrStreamSize].opCode = OpCode.Ret; script.instrStream.instrs [instrStreamSize].opCount = 0; script.instrStream.instrs [instrStreamSize].opList = null; } // Console.WriteLine ( $"添加 {script.instrStream.instrs [ instrStreamSize ]} {instrStreamSize} {lexer.LexerPosition}" ); instrStreamSize++; break; case TokenType.PARAM: var paramNameToken = lexer.NextToken(); int stackIndex = -(currentFunc.localDataSize + 2 + (currentParamIndex + 1)); // +2 因为从-2 开始(-1保留) +1 因为参数在返回地址的下面 if (script.symbolTable.AddSymbol(paramNameToken.value, 1, stackIndex, currentFunc.index) == -1) { throw new SyntaxError( string.Format(Messages.ERROR_MSG_FUNC_PARAM_DUPLICATE_DEFINITION, paramNameToken.value), token.span.Start.Line, token.span.Start.Column); } currentParamIndex++; break; case TokenType.INSTR: InstrLookup currentInstrLookup = null; if (!instrLookupTable.GetInstrByMnemonic(token.value, out currentInstrLookup)) { throw new SyntaxError( string.Format(Messages.ERROR_MSG_INSTR_NOT_FOUND, token.value), token.span.Start.Line, token.span.Start.Column); } script.instrStream.instrs [instrStreamSize].opCode = currentInstrLookup.opCode; script.instrStream.instrs [instrStreamSize].opCount = currentInstrLookup.opCount; for (int i = 0; i < currentInstrLookup.opCount; i++) { OpFlagType currentOpFlagType = currentInstrLookup.opList [i]; Token instrParamToken = lexer.NextToken(); // Console.WriteLine ( $"指令参数{i}: {instrParamToken}" ); switch (instrParamToken.type) { case TokenType.INT: if ((currentOpFlagType & OpFlagType.INT) == OpFlagType.INT) { script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.INT, intLiteral = int.Parse(instrParamToken.value) }); } else { throw new SyntaxError( string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM, token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column); } break; case TokenType.FLOAT: if ((currentOpFlagType & OpFlagType.FLOAT) == OpFlagType.FLOAT) { script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.FLOAT, floatLiteral = float.Parse(instrParamToken.value) }); } else { throw new SyntaxError( string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM, token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column); } break; case TokenType.STRING: if ((currentOpFlagType & OpFlagType.STRING) == OpFlagType.STRING) { int stringTableIdx = script.stringTable.AddString(instrParamToken.value); script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.STRING, stringTableIndex = stringTableIdx }); } else { throw new SyntaxError( string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM, token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column); } break; case TokenType.REG_RETVAL: if ((currentOpFlagType & OpFlagType.REG) == OpFlagType.REG) { script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.REG, reg = 0 }); } else { throw new SyntaxError( string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM, token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column); } break; case TokenType.IDENT: if ((currentOpFlagType & OpFlagType.FUNC_NAME) == OpFlagType.FUNC_NAME) { FuncNode func = script.funcTable.GetFuncByName(instrParamToken.value); if (func != null) { script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.FUNC_INDEX, funcIndex = func.index }); } else { throw new SyntaxError( string.Format(Messages.ERROR_MSG_FUNC_NOT_FOUND, instrParamToken.value), token.span.Start.Line, token.span.Start.Column); } } if ((currentOpFlagType & OpFlagType.LINE_LABEL) == OpFlagType.LINE_LABEL) { LabelNode labelNode = script.labelTable.GetLabelByIdent(instrParamToken.value, currentFunc.index); if (labelNode != null) { script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.INSTR_INDEX, instrIndex = labelNode.targetIndex }); } else { throw new SyntaxError( string.Format(Messages.ERROR_MSG_LABEL_NOT_FOUND, instrParamToken.value), token.span.Start.Line, token.span.Start.Column); } } if ((currentOpFlagType & OpFlagType.MEM_REF) == OpFlagType.MEM_REF) { SymbolNode symbolNode = script.symbolTable.GetSymbolByIdent(instrParamToken.value, currentFunc.index); // 如果该变量不是函数作用域内定义的,则查找全局变量 if (symbolNode == null) { symbolNode = script.symbolTable.GetSymbolByIdent(instrParamToken.value, -1); } if (symbolNode == null) { throw new SyntaxError( string.Format(Messages.ERROR_MSG_VAR_NOT_FOUND, instrParamToken.value), token.span.Start.Line, token.span.Start.Column); } int baseIndex = symbolNode.stackIndex; char symbolNextChar = lexer.PeekChar(1); if (symbolNextChar != char.MinValue) { // 非数组成员 if (symbolNextChar != XASMLexer.Open_Bracket) { // 验证非数组定义 if (symbolNode.size > 1) { throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_START_ERROR, token.span.Start.Line, token.span.Start.Column); } script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.ABS_STACK_INDEX, stackIndex = baseIndex }); } else { // 验证数组定义 if (symbolNode.size <= 1) { throw new SyntaxError( string.Format(Messages.ERROR_MSG_VAR_TYPE_IS_NOT_A_ARRAY, instrParamToken.value), token.span.Start.Line, token.span.Start.Column); } // 左中括号 lexer.NextToken(); // 数组索引参数 Token arrayIndexParamToken = lexer.NextToken(); // 数组索引是常数 if (arrayIndexParamToken.type == TokenType.INT) { int offset = int.Parse(arrayIndexParamToken.value); if (offset >= symbolNode.size) { throw new SyntaxError( string.Format(Messages.ERROR_MSG_INDEX_OUT_OF_BOUNDS, arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column); } script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.ABS_STACK_INDEX, stackIndex = baseIndex >= 0 ? baseIndex + offset : baseIndex - offset }); } // 数组索引是变量 else if (arrayIndexParamToken.type == TokenType.IDENT) { SymbolNode offsetSymbolNode = script.symbolTable.GetSymbolByIdent(arrayIndexParamToken.value, currentFunc.index); // 如果该变量不是函数作用域内定义的,则查找全局变量 if (offsetSymbolNode == null) { symbolNode = script.symbolTable.GetSymbolByIdent(arrayIndexParamToken.value, -1); } if (offsetSymbolNode == null) { throw new SyntaxError( string.Format(Messages.ERROR_MSG_VAR_NOT_FOUND, arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column); } // 不支持数组作为数组的索引 if (offsetSymbolNode.size > 1) { throw new SyntaxError( string.Format(Messages.ERROR_MSG_VAR_ARRAY_INDEX_TYPE_NOT_SUPPORT, arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column); } script.instrStream.instrs [instrStreamSize].opList.Add(new Op { type = OpType.REL_STACK_INDEX, stackIndex = offsetSymbolNode.stackIndex }); // 右中括号 if (lexer.NextToken().type != TokenType.CLOSE_BRACKET) { throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_END_ERROR, token.span.Start.Line, token.span.Start.Column); } } else { throw new SyntaxError( string.Format(Messages.ERROR_MSG_VAR_ARRAY_INDEX_TYPE_NOT_SUPPORT, arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column); } } } else { throw new SyntaxError(Messages.ERROR_MSG_INVALID_TOKEN, token.span.Start.Line, token.span.Start.Column); } } break; default: throw new SyntaxError( string.Format(Messages.ERROR_MSG_INVALID_PARAM_TYPE, instrParamToken.value), token.span.Start.Line, token.span.Start.Column); break; } // 指令参数之间的逗号分隔符 if (i < currentInstrLookup.opCount - 1) { if (lexer.NextToken().type != TokenType.COMMA) { throw new SyntaxError(Messages.ERROR_MSG_INSTR_PARAM_MISS_COMMA, token.span.Start.Line, token.span.Start.Column); } } } // 每条指令以换行符结束 if (lexer.NextToken().type != TokenType.NEWLINE) { throw new SyntaxError(Messages.ERROR_MSG_INSTR_END_MISMATCH, token.span.Start.Line, token.span.Start.Column); } // Console.WriteLine ( $"添加 {script.instrStream.instrs [ instrStreamSize ]} {instrStreamSize} {lexer.LexerPosition}" ); instrStreamSize++; break; // End Of TokenType.INSTR } // End Of switch ( token.Type ) // SkipToNextLine??? } // End Of While }
public static void SetOpType(int instrIndex, int opIndex, OpFlagType opFlagType) { instrTable [instrIndex].opList [opIndex] = opFlagType; }