public LocalVarSymbol AddLocalVar(IdentToken token, LocalBuilder localBuilder) { LocalVarSymbol result = new LocalVarSymbol(token, localBuilder); symbolTable.Peek().Add(token.value, result); return(result); }
// [8] Statement = [Location '='] Expression ';' | // 'if' '(' Expression ')' Statement ['else' Statement] | // 'while' '(' Expression ')' Statement | // 'return' [Expression] ';' | // 'break' ';' | // 'continue' ';' | // Block. public bool IsStatement() { Type type; LocationInfo location; if (IsLocation(out location)) { FieldSymbol fs = location.id as FieldSymbol; if (fs != null) { if (CheckSpecialSymbol("=")) { if (!IsExpression(null, out type)) { Error("Очаквам израз"); } if (!CheckSpecialSymbol(";")) { Error("Очаквам специален символ ';'"); } // Emit if (location.isArray) { if (!AssignableTypes(fs.fieldInfo.FieldType.GetElementType(), type)) { Error("Несъвместими типове", location.id); } emit.AddAssignCast(fs.fieldInfo.FieldType.GetElementType(), type); emit.AddArrayAssigment(fs.fieldInfo); } else { if (!AssignableTypes(fs.fieldInfo.FieldType, type)) { Error("Несъвместими типове", location.id); } emit.AddAssignCast(fs.fieldInfo.FieldType, type); emit.AddFieldAssigment(fs.fieldInfo); } return(true); } } LocalVarSymbol lvs = location.id as LocalVarSymbol; if (lvs != null) { if (CheckSpecialSymbol("=")) { if (!IsExpression(null, out type)) { Error("Очаквам израз"); } if (!CheckSpecialSymbol(";")) { Error("Очаквам специален символ ';'"); } // Emit if (!AssignableTypes(lvs.localVariableInfo.LocalType, type)) { Error("Несъвместими типове", location.id); } emit.AddAssignCast(lvs.localVariableInfo.LocalType, type); emit.AddLocalVarAssigment(lvs.localVariableInfo); return(true); } } FormalParamSymbol fps = location.id as FormalParamSymbol; if (fps != null) { if (CheckSpecialSymbol("=")) { if (!IsExpression(null, out type)) { Error("Очаквам израз"); } if (!CheckSpecialSymbol(";")) { Error("Очаквам специален символ ';'"); } // Emit if (!AssignableTypes(fps.paramType, type)) { Error("Несъвместими типове", location.id); } emit.AddAssignCast(fps.paramType, type); emit.AddParameterAssigment(fps.parameterInfo); return(true); } } if (!IsExpression(location, out type)) { Error("Неочакван вид идентификатор", location.id); } if (!CheckSpecialSymbol(";")) { Error("Очаквам специален символ ';'"); } // Emit if (type != typeof(void)) { emit.AddPop(); } } else if (IsExpression(null, out type)) { if (!CheckSpecialSymbol(";")) { Error("Очаквам специален символ ';'"); } // Emit if (type != typeof(void)) { emit.AddPop(); } } else if (CheckKeyword("if")) { // 'if' '(' Expression ')' Statement ['else' Statement] if (!CheckSpecialSymbol("(")) { Error("Очаквам специален символ '('"); } if (!IsExpression(null, out type)) { Error("Очаквам израз"); } if (!AssignableTypes(typeof(System.Boolean), type)) { Error("Типа на изразът трябва да е Boolean"); } if (!CheckSpecialSymbol(")")) { Error("Очаквам специален символ ')'"); } // Emit Label labelElse = emit.GetLabel(); emit.AddCondBranch(labelElse); if (!IsStatement()) { Error("Очаквам Statement"); } if (CheckKeyword("else")) { // Emit Label labelEnd = emit.GetLabel(); emit.AddBranch(labelEnd); emit.MarkLabel(labelElse); if (!IsStatement()) { Error("Очаквам Statement"); } // Emit emit.MarkLabel(labelEnd); } else { // Emit emit.MarkLabel(labelElse); } } else if (CheckKeyword("while")) { // 'while' '(' Expression ')' Statement // Emit Label labelContinue = emit.GetLabel(); Label labelBreak = emit.GetLabel(); breakStack.Push(labelBreak); continueStack.Push(labelContinue); emit.MarkLabel(labelContinue); if (!CheckSpecialSymbol("(")) { Error("Очаквам специален символ '('"); } if (!IsExpression(null, out type)) { Error("Очаквам израз"); } if (!AssignableTypes(typeof(System.Boolean), type)) { Error("Типа на изразът трябва да е Boolean"); } if (!CheckSpecialSymbol(")")) { Error("Очаквам специален символ ')'"); } // Emit emit.AddCondBranch(labelBreak); if (!IsStatement()) { Error("Очаквам Statement"); } // Emit emit.AddBranch(labelContinue); emit.MarkLabel(labelBreak); breakStack.Pop(); continueStack.Pop(); } else if (CheckKeyword("return")) { Type retType = emit.GetMethodReturnType(); if (retType != typeof(void)) { IsExpression(null, out type); if (!AssignableTypes(retType, type)) { Error("Типа на резултата трябва да е съвместим с типа на метода"); } } if (!CheckSpecialSymbol(";")) { Error("Очаквам специален символ ';'"); } // Emit emit.AddReturn(); } else if (CheckKeyword("break")) { if (!CheckSpecialSymbol(";")) { Error("Очаквам специален символ ';'"); } // Emit emit.AddBranch((Label)breakStack.Peek()); } else if (CheckKeyword("continue")) { if (!CheckSpecialSymbol(";")) { Error("Очаквам специален символ ';'"); } // Emit emit.AddBranch((Label)continueStack.Peek()); } else if (IsBlock(true)) { // } else { return(false); } return(true); }
public bool IsSimpleExpr(LocationInfo location, out Type type) { Type type1; SpecialSymbolToken opToken; IncDecOps incDecOp = IncDecOps.None; if (location != null) { opToken = null; } else { opToken = token as SpecialSymbolToken; if (CheckSpecialSymbol("++")) { incDecOp = IncDecOps.PreInc; } else if (CheckSpecialSymbol("--")) { incDecOp = IncDecOps.PreDec; } if (!IsLocation(out location) && incDecOp != IncDecOps.None) { Error("Очаквам променлива, аргумент или поле"); } } if (incDecOp == IncDecOps.None) { opToken = token as SpecialSymbolToken; if (CheckSpecialSymbol("++")) { incDecOp = IncDecOps.PostInc; } else if (CheckSpecialSymbol("--")) { incDecOp = IncDecOps.PostDec; } } if (location != null) { FieldSymbol fs = location.id as FieldSymbol; if (fs != null) { if (location.isArray) { type = fs.fieldInfo.FieldType.GetElementType(); } else { type = fs.fieldInfo.FieldType; } // Emit if (location.isArray) { if (incDecOp == IncDecOps.None) { emit.AddGetArray(fs.fieldInfo); } else { emit.AddIncArray(fs.fieldInfo, incDecOp); } } else { emit.AddGetField(fs.fieldInfo); emit.AddIncField(fs.fieldInfo, incDecOp); } return(true); } LocalVarSymbol lvs = location.id as LocalVarSymbol; if (lvs != null) { type = lvs.localVariableInfo.LocalType; // Emit emit.AddGetLocalVar(lvs.localVariableInfo); emit.AddIncLocalVar(lvs.localVariableInfo, incDecOp); return(true); } FormalParamSymbol fps = location.id as FormalParamSymbol; if (fps != null) { type = fps.paramType; // Emit emit.AddGetParameter(fps.parameterInfo); emit.AddIncParameter(fps.parameterInfo, incDecOp); return(true); } MethodSymbol ms = location.id as MethodSymbol; if (ms != null) { // '(' [Expression {',' Expression}] ')'. List <Type> actualParamTypes = new List <Type>(); int i = 0; if (!CheckSpecialSymbol("(")) { Error("Очаквам специален символ '('"); } while (IsExpression(null, out type1)) { actualParamTypes.Add(type1); if (!AssignableTypes(ms.formalParams[i].paramType, type1)) { Error("Типа на фомалния параметър {0} и типа на актуалния параметър {1} не са съвместими", location.id, i, i); } emit.AddAssignCast(ms.formalParams[i].paramType, type1); if (!CheckSpecialSymbol(",")) { break; } i++; } if (!CheckSpecialSymbol(")")) { Error("Очаквам специален символ ')' expected"); } if (ms.formalParams.Length != actualParamTypes.Count) { Error("Броя на актуалните параметри не е равен на броя на формалните параметри"); } // Emit emit.AddMethodCall(ms.methodInfo); type = ms.returnType; return(true); } ExternalMethodSymbol ems = location.id as ExternalMethodSymbol; if (ems != null) { // '(' [Expression {',' Expression}] ')'. List <Type> actualParamTypes = new List <Type>(); if (!CheckSpecialSymbol("(")) { Error("Очаквам специален символ '('"); } while (IsExpression(null, out type1)) { actualParamTypes.Add(type1); if (!CheckSpecialSymbol(",")) { break; } } if (!CheckSpecialSymbol(")")) { Error("Очаквам специален символ ')'"); } // Emit int lastIx = location.id.value.LastIndexOf(Type.Delimiter); string memberName; string typeName; if (lastIx > 0) { memberName = location.id.value.Substring(lastIx + 1); typeName = location.id.value.Substring(0, lastIx); } else { memberName = location.id.value; typeName = ""; } MethodInfo bestMethodInfo = ems.methodInfo[0].DeclaringType.GetMethod(memberName, BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Standard, actualParamTypes.ToArray(), new ParameterModifier[actualParamTypes.Count]); if (bestMethodInfo == null) { Error("Няма подходяща комбинация от типове на параметрите за метода {0}", location.id, ems.value); } emit.AddMethodCall(bestMethodInfo); type = bestMethodInfo.ReturnType; return(true); } type = null; Error("Неочакван тип на символ в таблицата на символите (вътрешна грешка)"); } else if (CheckSpecialSymbol("(")) { if (IsType(out type)) { if (!CheckSpecialSymbol(")")) { Error("Очаквам специален символ ')'"); } if (!IsSimpleExpr(null, out type1)) { Error("Очаквам израз"); } //Emit emit.AddCast(type, type1); } else { if (!IsExpression(null, out type)) { Error("Очаквам израз"); } if (!CheckSpecialSymbol(")")) { Error("Очаквам специален символ ')'"); } } } else if (CheckSpecialSymbol("-") || CheckSpecialSymbol("~") || CheckSpecialSymbol("!")) { if (!IsSimpleExpr(null, out type)) { Error("Очаквам прост израз"); } // Emit emit.AddUnaryOp(opToken.value); } else if (IsLiteral(out type)) { // } else { type = null; return(false); } return(true); }