/// <summary> /// Gets the type of the operation by searching on the rules hash. /// </summary> /// <returns>The operation type.</returns> /// <param name="op">Op.</param> /// <param name="t1">T1.</param> /// <param name="t2">T2.</param> public static GraphicFooType GetOperationType( Operators op, GraphicFooType t1, GraphicFooType t2) { if (rules [(int)t1, (int)t2] == null) { Console.WriteLine("No rule for [{1},{2}] is not found.", t1.ToString(), t2.ToString() ); // TODO return errors return(t1); } else if (!rules [(int)t1, (int)t2].ContainsKey(op)) { Console.WriteLine("Key \"{1}\" not found.", op.ToString()); // TODO return errors return(t1); } else { return((GraphicFooType)rules [(int)t1, (int)t2] [op]); } }
void IfHeader() { Expect((int)TokenEnum.If); Expect((int)TokenEnum.LeftParenthesis); Expression(); try { GraphicFooType type = Quadruple.typeStack.Pop(); if (Semantics.ExpectType(type, GraphicFooType.Boolean)) { string id = Quadruple.operandStack.Pop(); Quadruple.CreateGotoFalseQuadruple(id); Quadruple.PushJump(); } else { SemErr( (int)SemanticEnum.TypeMismatch, "expected boolean, found " + type ); } } catch (InvalidOperationException) { SynErr((int)TokenEnum.NoExpression); } Expect((int)TokenEnum.RightParenthesis); }
/// <summary> /// Validates the return type of a function. /// </summary> /// <returns>The return.</returns> /// <param name="procedureType">Procedure type.</param> /// <param name="returnVariable">Return variable.</param> public static SemanticEnum ValidateReturn( GraphicFooType procedureType, Variable returnVariable) { bool noReturn = (returnVariable == null); if (procedureType == GraphicFooType.Void) { if (!noReturn) { Console.WriteLine("Void functions can't return a type"); return(SemanticEnum.CantHaveReturn); } return(SemanticEnum.ValidReturn); } else { if (noReturn) { Console.WriteLine("Missing return type"); return(SemanticEnum.MissingReturnType); } bool match = (procedureType == returnVariable.type); if (!match) { Console.WriteLine("Return mismatch"); return(SemanticEnum.TypeMismatch); } return(SemanticEnum.ValidReturn); } }
/// <summary> /// Adds a temporary variable. /// </summary> /// <returns>The temporary variable.</returns> /// <param name="type">Type.</param> public Variable AddTemporaryVariable(GraphicFooType type) { string id = temporaryPrefix + temporaryVariables.GetCount(); Variable variable = new Variable(id, type); temporaryVariables.AddVariable(variable); return(variable); }
/// <summary> /// Adds a global temporary. /// </summary> /// <returns>The global temporary.</returns> /// <param name="type">Type.</param> public static Variable AddGlobalTemporary(GraphicFooType type) { string id = temporaryPrefix + globalTemporary.GetCount(); Variable variable = new Variable(id, type); globalTemporary.AddVariable(variable); return(variable); }
/// <summary> /// Creates an expression quadruple. /// </summary> /// <param name="operators">Operators.</param> private static void CreateExpressionQuadruple( Operators[] operators) { // Get index of fake bottom int index = (hierarchyStack.Count > 0) ? hierarchyStack.Peek() : 0; if (operatorStack.Count > index && operators.Contains(operatorStack.Peek())) { // Pop types GraphicFooType t2 = typeStack.Pop(); GraphicFooType t1 = typeStack.Pop(); if (t1 != GraphicFooType.Invalid && t2 != GraphicFooType.Invalid) { // Pop operands string id2 = operandStack.Pop(); string id1 = operandStack.Pop(); // Find variables Variable v1 = ProgramMemory.FindVariable(scope, id1); Variable v2 = ProgramMemory.FindVariable(scope, id2); // Pop operator Operators op = operatorStack.Pop(); // Check association rules GraphicFooType resultingType = AssociationRules.GetOperationType(op, t1, t2); // Create new temporary variable Variable temp; if (scope == null) { temp = ProgramMemory.AddGlobalTemporary(resultingType); } else { temp = scope.AddTemporaryVariable(resultingType); } // Push temp operandStack.Push(temp.name); typeStack.Push(temp.type); // Create quadruple Quadruple qudruple = new Quadruple( op, v1, v2, temp ); PushQuadruple(qudruple); } } }
/// <summary> /// Adds a constant. /// </summary> /// <returns>The constant.</returns> /// <param name="id">Identifier.</param> /// <param name="type">Type.</param> public static Variable AddConstant(string id, GraphicFooType type) { if (constants.Contains(id)) { return(constants.ReadVariable(id)); } Variable variable = new Variable(id, type); constants.AddVariable(variable); return(variable); }
/// <summary> /// Matches an expected type. /// </summary> /// <returns><c>true</c>, if type was expected, <c>false</c> otherwise.</returns> /// <param name="expected">Expected.</param> /// <param name="actual">Actual.</param> public static bool ExpectType( GraphicFooType expected, GraphicFooType actual) { bool match = (expected == actual); if (!match) { Console.WriteLine( "Type mismatch expected " + expected + ", found " + actual ); } return(match); }
/// <summary> /// Parser function that generates function call quadruples. /// While checking semantics. /// </summary> void CallFunction() { Expect((int)TokenEnum.Function); Expect((int)TokenEnum.Id); string id = GetLastTokenValue(); Expect((int)TokenEnum.LeftParenthesis); VariableBlock parameters = new VariableBlock(); if (StartOf((int)TokenEnum.String)) { Expression(); string paramId = Quadruple.operandStack.Pop(); GraphicFooType type = Quadruple.typeStack.Pop(); Variable parameter = new Variable(paramId, type); if (parameter.type == GraphicFooType.Invalid) { SemErr((int)SemanticEnum.Variable); } parameters.AddVariable(parameter); while (la.kind == (int)TokenEnum.Comma) { Get(); Expression(); paramId = Quadruple.operandStack.Pop(); type = Quadruple.typeStack.Pop(); parameter = new Variable(paramId, type); if (parameter.type == GraphicFooType.Invalid) { SemErr((int)SemanticEnum.Variable); } parameters.AddVariable(parameter); } } Expect((int)TokenEnum.RightParenthesis); Quadruple.CreateFunctionCallQuadruples(id, parameters); if (la.kind == (int)TokenEnum.Assignation) { Get(); Expect((int)TokenEnum.Id); string varId = GetLastTokenValue(); Quadruple.CreateReturnAssignationQuadruple(id, varId); } Expect((int)TokenEnum.Semicolon); }
/// <summary> /// Parses a type to a GraphicFooType. /// </summary> /// <returns>The type.</returns> /// <param name="type">Type.</param> protected GraphicFooType ParseType(string type) { try { // Return char and concat substring. type = char.ToUpper(type[0]) + type.Substring(1); GraphicFooType graphicFooType = (GraphicFooType)Enum.Parse(typeof(GraphicFooType), type); return(graphicFooType); } catch (IndexOutOfRangeException) { Console.WriteLine("String is empty"); return(GraphicFooType.Invalid); } catch (NullReferenceException) { Console.WriteLine("String is null"); return(GraphicFooType.Invalid); } catch (ArgumentException) { Console.WriteLine("Invalid Type"); return(GraphicFooType.Invalid); } }
/// <summary> /// Initializes a new instance of the <see cref="GraphicFoo.Procedure"/> class. /// </summary> /// <param name="name">Name.</param> /// <param name="rawType">Raw type.</param> /// <param name="parameters">Parameters.</param> public Procedure( string name, string rawType, VariableBlock parameters) { this.name = name; this.type = ParseType(rawType); this.index = Quadruple.quadruples.Count; this.end = -1; this.isMain = name == "main"; if (isMain) { VirtualMachine.startOfMain = index; } this.parameters = (parameters == null) ? new VariableBlock() : parameters; this.procedureVariables = new VariableBlock(); this.temporaryVariables = new VariableBlock(); }
/// <summary> /// Initializes a new instance of the <see cref="GraphicFoo.Variable"/> class. /// </summary> /// <param name="name">Name.</param> /// <param name="rawType">Raw type.</param> public Variable(string name, string rawType) { this.name = name; this.type = ParseType(rawType); }
/// <summary> /// Initializes a new instance of the <see cref="GraphicFoo.Variable"/> class. /// </summary> /// <param name="name">Name.</param> /// <param name="type">Type.</param> public Variable(string name, GraphicFooType type) { this.name = name; this.type = type; }