/// <summary> /// Function that receives two <see cref="SemanticCubeUtilities.DataTypes"/> and a <see cref="SemanticCubeUtilities.Operators"/> /// and returns the resulting data type of combining the given types with the given operator. /// Called by <see cref="QuadrupleManager"/> to get the resulting data type of two operands /// and an operator. /// </summary> /// <param name="typeOne"></param> /// <param name="typeTwo"></param> /// <param name="op"></param> /// <returns> /// A <see cref="SemanticCubeUtilities.DataTypes"/> type. /// </returns> public static SemanticCubeUtilities.DataTypes AnalyzeSemantics(SemanticCubeUtilities.DataTypes typeOne, SemanticCubeUtilities.DataTypes typeTwo, SemanticCubeUtilities.Operators op) { // handle the negative operator as a special case since it only uses one operand if (op == SemanticCubeUtilities.Operators.negative) { if (Cube.TryGetValue(new TypeTypeOperator(typeOne, typeTwo, op), out SemanticCubeUtilities.DataTypes resultType)) { return(resultType); } else { return(SemanticCubeUtilities.DataTypes.invalidDataType); } } if (typeOne.Equals(SemanticCubeUtilities.DataTypes.invalidDataType) || typeTwo.Equals(SemanticCubeUtilities.DataTypes.invalidDataType) || op.Equals(SemanticCubeUtilities.Operators.invalidOperator)) { return(SemanticCubeUtilities.DataTypes.invalidDataType); } SemanticCubeUtilities.DataTypes type; if (Cube.TryGetValue(new TypeTypeOperator(typeOne, typeTwo, op), out type)) { return(type); } else { throw new Exception(String.Format("The specified key <{0},{1},{2}> was not found in the Semantic Cube", typeOne, typeTwo, op)); } }
/// <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); } }
/// <summary> /// Function called when a <see cref="CreateVariable"/> block is found in either /// a global or a local scope of the program. /// Called by <see cref="PROGRAM"/> and <see cref="CREATE_FUNCTION"/>. /// </summary> /// <returns>The <see cref="Variable"/> object created.</returns> Variable CREATE_VAR() { Expect(16); // "var" SemanticCubeUtilities.DataTypes varType = TYPE_VAR(); Expect(1); // id string varName = t.val; Variable newVar = new Variable(varName, varType); Expect(17); // ';' return(newVar); }
/// <summary> /// Get a default value given a <see cref="SemanticCubeUtilities.DataTypes"/> value. /// Called by methods that initialize memory addresses to set a default value. /// </summary> /// <param name="dt"></param> /// <returns>Default value for the corresponding type</returns> public static object GetDefaultValueFromType(SemanticCubeUtilities.DataTypes dt) { if (dt == SemanticCubeUtilities.DataTypes.number) { return(0); } else if (dt == SemanticCubeUtilities.DataTypes.boolean) { return(false); } else if (dt == SemanticCubeUtilities.DataTypes.text) { return(""); } return(null); }
/// <summary> /// Gets the next available memory address for each scope and <see cref="SemanticCubeUtilities.DataTypes"/> value. /// Called by <see cref="QuadrupleManager"/> to allot a space in memory to a value. /// </summary> /// <param name="scope"></param> /// <param name="type"></param> /// <returns>A memory address.</returns> public static int GetNextAvailable(MemoryScope scope, SemanticCubeUtilities.DataTypes type) { switch (scope) { case MemoryScope.global: switch (type) { case SemanticCubeUtilities.DataTypes.number: if (currentGlobalIntAddress <= highestGlobalIntAddress) { return(currentGlobalIntAddress); } break; case SemanticCubeUtilities.DataTypes.text: if (currentGlobalStringAddress <= highestGlobalStringAddress) { return(currentGlobalStringAddress); } break; case SemanticCubeUtilities.DataTypes.boolean: if (currentGlobalBoolAddress <= highestGlobalBoolAddress) { return(currentGlobalBoolAddress); } break; default: break; } break; case MemoryScope.temporary: switch (type) { case SemanticCubeUtilities.DataTypes.number: if (currentTempIntAddress <= highestTempIntAddress) { return(currentTempIntAddress); } break; case SemanticCubeUtilities.DataTypes.text: if (currentTempStringAddress <= highestTempStringAddress) { return(currentTempStringAddress); } break; case SemanticCubeUtilities.DataTypes.boolean: if (currentTempBoolAddress <= highestTempBoolAddress) { return(currentTempBoolAddress); } break; default: break; } break; case MemoryScope.constant: switch (type) { case SemanticCubeUtilities.DataTypes.number: if (currentConstantIntAddress <= highestConstantIntAddress) { return(currentConstantIntAddress); } break; case SemanticCubeUtilities.DataTypes.text: if (currentConstantStringAddress <= highestConstantStringAddress) { return(currentConstantStringAddress); } break; case SemanticCubeUtilities.DataTypes.boolean: if (currentConstantBoolAddress <= highestConstantBoolAddress) { return(currentConstantBoolAddress); } break; default: break; } break; case MemoryScope.local: if (currentLocalAddress <= highestLocalAddress) { return(currentLocalAddress); } break; default: break; } return(-1); }
/// <summary> /// Constructor for function. /// </summary> /// <param name="name"></param> /// <param name="returnType"></param> public Function(string name, SemanticCubeUtilities.DataTypes returnType) { this.name = name; this.returnType = returnType; }
/// <summary> /// Variable constructor. A variable must have a name and a data type. /// </summary> /// <param name="name"></param> /// <param name="dataType"></param> public Variable(String name, SemanticCubeUtilities.DataTypes dataType) { this.name = name; this.dataType = dataType; }
/// <summary> /// Sets <see cref="DataTypeTwo"/>'s value. /// </summary> /// <param name="DataType"></param> public void SetDataTypeTwo(SemanticCubeUtilities.DataTypes DataType) { DataTypeTwo = DataType; }
/// <summary> /// Sets <see cref="DataTypeOne"/>'s value. /// </summary> /// <param name="DataType"></param> public void SetDataTypeOne(SemanticCubeUtilities.DataTypes DataType) { DataTypeOne = DataType; }
public TypeTypeOperator(SemanticCubeUtilities.DataTypes DataTypeOne, SemanticCubeUtilities.DataTypes DataTypeTwo, SemanticCubeUtilities.Operators Operator) { this.DataTypeOne = DataTypeOne; this.DataTypeTwo = DataTypeTwo; this.Operator = Operator; }