示例#1
0
    /// <summary>
    /// Function called when a <see cref="CREATE_FUNCTION"/> block is found.
    /// Verifies that the definition structure of a function is correct.
    /// Creates a <see cref="Function"/> object based on the definition.
    /// Called by <see cref="PROGRAM"/>.
    /// </summary>
    void CREATE_FUNCTION()
    {
        Expect(9);         // "function"
        SemanticCubeUtilities.DataTypes functionType = TYPE_FUNC();
        Expect(1);         // id
        string   functionName = t.val;
        Function newFunction  = new Function(functionName, functionType);

        try { QuadrupleManager.EnterFunction(newFunction); }
        catch (Exception e) { SemErr(e.Message); }

        Expect(10);                                          // '('

        if (la.kind == 13 || la.kind == 14 || la.kind == 15) // "text" || "number" || "bool"
        {
            SemanticCubeUtilities.DataTypes parameterType = TYPE_VAR();
            Expect(1);             // id
            string parameterName = t.val;
            try { QuadrupleManager.CreateFunction_LoadParameter(functionName, new Variable(parameterName, parameterType)); }
            catch (Exception e) { SemErr(e.Message); }
            while (la.kind == 11)               // ','
            {
                Get();
                parameterType = TYPE_VAR();
                Expect(1);                 // id
                parameterName = t.val;
                try { QuadrupleManager.CreateFunction_LoadParameter(functionName, new Variable(parameterName, parameterType)); }
                catch (Exception e) { SemErr(e.Message); }
            }
        }
        Expect(12);           // ')'
        Expect(7);            // '{'
        while (la.kind == 16) // "var"
        // add variables to the local variables directory
        {
            var localVariable = CREATE_VAR();
            try { QuadrupleManager.CreateFunction_LoadLocalVariable(functionName, localVariable); }
            catch (Exception e) { SemErr(e.Message); }
        }

        try { FunctionDirectory.GetFunction(newFunction.GetName()).SetQuadrupleStart(QuadrupleManager.GetCounter()); }
        catch (Exception e) { SemErr(e.Message); }

        while (StartOf(1))
        {
            INSTRUCTION();
        }

        Expect(8);         // '}'
        try
        {
            QuadrupleManager.ExitFunction();             // releases local variable and generates quadruple 'endProc'
        }
        catch (Exception e) { SemErr(e.Message); }
    }