/// <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); } }