コード例 #1
0
        public LocalVarSymbol AddLocalVar(IdentToken token, LocalBuilder localBuilder)
        {
            LocalVarSymbol result = new LocalVarSymbol(token, localBuilder);

            symbolTable.Peek().Add(token.value, result);
            return(result);
        }
コード例 #2
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);
        }
コード例 #3
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);
        }