コード例 #1
0
        public FormalParamSymbol AddFormalParam(IdentToken token, Type type, ParameterBuilder parameterInfo)
        {
            FormalParamSymbol result = new FormalParamSymbol(token, type, parameterInfo);

            symbolTable.Peek().Add(token.value, result);
            return(result);
        }
コード例 #2
0
//		// [?]  Namespace = Ident {'.' Ident}.
//		public bool IsNamespace(out string ns)
//		{
//			ns = "";
//
//			IdentToken id = token as IdentToken;
//			if (!CheckIdent()) return false;
//
//			StringBuilder sb = new StringBuilder(id.value);
//			while (CheckSpecialSymbol(".")) {
//				sb.Append(".");
//				id = token as IdentToken;
//				if (!CheckIdent()) Error("Очаквам идентификатор");
//				sb.Append(id.value);
//			}
//			ns = sb.ToString();
//
//			return true;
//		}

        // [3] FieldDecl = Type (Ident | Ident '[' Number ']' ) ';'.
        // [4] MethodDecl = (Type | 'void') Ident '(' [Type Ident {',' Type Ident}] ')' Block.
        public bool IsFieldDeclOrMethodDecl()
        {
            IdentToken name;
            IdentToken paramName;
            List <FormalParamSymbol> formalParams = new List <FormalParamSymbol>();
            List <Type> formalParamTypes          = new List <Type>();
            Type        paramType;
            long        arraySize = 0;
            Type        type;

            if (!IsType(out type))
            {
                return(false);
            }
            name = token as IdentToken;
            if (!CheckIdent())
            {
                Error("Очаквам идентификатор");
            }
            if (CheckSpecialSymbol("["))
            {
                arraySize = ((NumberToken)token).value;
                if (!CheckNumber())
                {
                    Error("Очаквам цяло число");
                }
                if (!CheckSpecialSymbol("]"))
                {
                    Error("Очаквам специален символ ']'");
                }

                type = type.MakeArrayType();
            }
            else if (CheckSpecialSymbol("("))
            {
                // Семантична грешка - редеклариран ли е методът повторно?
                if (symbolTable.ExistCurrentScopeSymbol(name.value))
                {
                    Error("Метода {0} е редеклариран", name, name.value);
                }
                // Emit
                MethodSymbol methodToken = symbolTable.AddMethod(name, type, formalParams.ToArray(), null);
                symbolTable.BeginScope();

                while (IsType(out paramType))
                {
                    paramName = token as IdentToken;
                    if (!CheckIdent())
                    {
                        Error("Очаквам идентификатор");
                    }
                    // Семантична грешка - редеклариран ли е формалният параметър повторно?
                    if (symbolTable.ExistCurrentScopeSymbol(paramName.value))
                    {
                        Error("Формалния параметър {0} е редеклариран", paramName, paramName.value);
                    }
                    FormalParamSymbol formalParam = symbolTable.AddFormalParam(paramName, paramType, null);
                    formalParams.Add(formalParam);
                    formalParamTypes.Add(paramType);
                    if (!CheckSpecialSymbol(","))
                    {
                        break;
                    }
                }
                if (!CheckSpecialSymbol(")"))
                {
                    Error("Очаквам специален символ ')'");
                }

                methodToken.methodInfo = emit.AddMethod(name.value, type, formalParamTypes.ToArray());
                for (int i = 0; i < formalParams.Count; i++)
                {
                    formalParams[i].parameterInfo = emit.AddParam(formalParams[i].value, i + 1, formalParamTypes[i]);
                }
                methodToken.formalParams = formalParams.ToArray();

                if (!IsBlock(false))
                {
                    Error("Очаквам блок");
                }

                symbolTable.EndScope();

                return(true);
            }

            if (!CheckSpecialSymbol(";"))
            {
                Error("Очаквам специален символ ';'");
            }

            // Семантична грешка - редекларирано ли е полето повторно?
            if (symbolTable.ExistCurrentScopeSymbol(name.value))
            {
                Error("Полето {0} е редекларирано", name, name.value);
            }
            if (type == typeof(void))
            {
                Error("Полето {0} не може да е от тип void", name, name.value);
            }

            // Emit (field)
            symbolTable.AddField(name, emit.AddField(name.value, type, arraySize));

            return(true);
        }
コード例 #3
0
        // [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);
        }
コード例 #4
0
        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);
        }