public void Visit(ComparisonOperation node) { node.LeftOperand.Accept(this); node.RightOperand.Accept(this); if (node.LeftOperand.StaticType.Text != "Int" || node.RightOperand.StaticType.Text != "Int") { errors.Add(SemanticError.InvalidUseOfOperator(node, node.LeftOperand.StaticType, node.RightOperand.StaticType)); } if (!scope.IsDefinedType("Bool", out node.StaticType)) { errors.Add(SemanticError.NotDeclaredType(new TypeNode(node.Line, node.Column, "Bool"))); } }
public void Visit(WhileNode node) { node.Condition.Accept(this); node.Body.Accept(this); if (node.Condition.StaticType.Text != "Bool") { errors.Add(SemanticError.CannotConvert(node.Condition, node.Condition.StaticType, scope.GetType("Bool"))); } if (!scope.IsDefinedType("Object", out node.StaticType)) { errors.Add(SemanticError.NotDeclaredType(new TypeNode(node.Line, node.Column, "Object"))); } }
public void Visit(AssignmentNode node) { node.ExpressionRight.Accept(this); if (!scope.IsDefined(node.ID.Text, out TypeInfo type)) { errors.Add(SemanticError.NotDeclaredVariable(node.ID)); } if (!(node.ExpressionRight.StaticType <= type)) { errors.Add(SemanticError.CannotConvert(node, node.ExpressionRight.StaticType, type)); } node.StaticType = node.ExpressionRight.StaticType; }
public void Visit(EqualNode node) { node.LeftOperand.Accept(this); node.RightOperand.Accept(this); if (node.LeftOperand.StaticType.Text != node.RightOperand.StaticType.Text || !(new string[3] { "Bool", "Int", "String" }.Contains(node.LeftOperand.StaticType.Text))) { errors.Add(SemanticError.InvalidUseOfOperator(node, node.LeftOperand.StaticType, node.RightOperand.StaticType)); } if (!scope.IsDefinedType("Bool", out node.StaticType)) { errors.Add(SemanticError.NotDeclaredType(new TypeNode(node.Line, node.Column, "Bool"))); } }
public void Visit(AttributeNode node) { node.AssignExp.Accept(this); var typeAssignExp = node.AssignExp.StaticType; if (!scope.IsDefinedType(node.Formal.Type.Text, out TypeInfo typeDeclared)) { errors.Add(SemanticError.NotDeclaredType(node.Formal.Type)); } if (!(typeAssignExp <= typeDeclared)) { errors.Add(SemanticError.CannotConvert(node.Formal.Type, typeAssignExp, typeDeclared)); } scope.Define(node.Formal.Id.Text, typeDeclared); }
public void Visit(CaseNode node) { node.ExpressionCase.Accept(this); int branchSelected = -1; var typeExp0 = node.ExpressionCase.StaticType; var typeExpK = scope.GetType(node.Branches[0].Formal.Type.Text); for (int i = 0; i < node.Branches.Count; ++i) { if (!scope.IsDefinedType(node.Branches[i].Formal.Type.Text, out TypeInfo type)) { errors.Add(SemanticError.NotDeclaredType(node.Branches[i].Formal.Type)); } var typeK = scope.GetType(node.Branches[i].Formal.Type.Text); var scopeBranch = scope.CreateChild(); scopeBranch.Define(node.Branches[i].Formal.Id.Text, typeK); node.Branches[i].Expression.Accept(new SecondSemanticVisit(scopeBranch, errors)); typeExpK = node.Branches[i].Expression.StaticType; if (branchSelected == -1 && typeExp0 <= typeK) { branchSelected = i; } if (i == 0) { node.StaticType = node.Branches[0].Expression.StaticType; } node.StaticType = SemanticAlgorithm.LowerCommonAncestor(node.StaticType, typeExpK); } node.BranchSelected = branchSelected; if (node.BranchSelected == -1) { errors.Add(SemanticError.NotMatchedBranch(node)); } }
public void Visit(ArithmeticOperationNode node) { node.LeftOperand.Accept(this); node.RightOperand.Accept(this); if (node.LeftOperand.StaticType.Text != node.RightOperand.StaticType.Text) { errors.Add(SemanticError.InvalidUseOfOperator(node, node.LeftOperand.StaticType, node.RightOperand.StaticType)); } else if (node.LeftOperand.StaticType.Text != "Int" || node.RightOperand.StaticType.Text != "Int") { errors.Add(SemanticError.InvalidUseOfOperator(node)); } else if (!scope.IsDefinedType("Int", out node.StaticType)) { errors.Add(SemanticError.NotDeclaredType(new TypeNode(node.Line, node.Column, "Int"))); } }
public void Visit(MethodNode node) { if (!scope.IsDefinedType(node.TypeReturn.Text, out TypeInfo typeReturn)) { errors.Add(SemanticError.NotDeclaredType(node.TypeReturn)); } node.TypeReturn = new TypeNode(node.TypeReturn.Line, node.TypeReturn.Column, typeReturn.Text); TypeInfo[] typeArgs = new TypeInfo[node.Arguments.Count]; for (int i = 0; i < node.Arguments.Count; ++i) { if (!scope.IsDefinedType(node.Arguments[i].Type.Text, out typeArgs[i])) { errors.Add(SemanticError.NotDeclaredType(node.Arguments[i].Type)); } } scope.Define(node.Id.Text, typeArgs, typeReturn); }
public void Visit(ProgramNode node) { if (!SemanticAlgorithm.TopologicalSort(node.Classes, errors)) { return; } node.Classes.ForEach(cclass => scope.AddType(cclass.TypeClass.Text, new TypeInfo(cclass.TypeClass.Text, scope.GetType(cclass.TypeInherit.Text), cclass))); int idMain = -1; for (int i = 0; i < node.Classes.Count; ++i) { if (node.Classes[i].TypeClass.Text == "Main") { idMain = i; } } if (idMain == -1) { errors.Add(SemanticError.NotFoundClassMain()); return; } bool mainOK = false; foreach (var item in node.Classes[idMain].FeatureNodes) { if (item is MethodNode) { var method = item as MethodNode; if (method.Id.Text == "main" && method.Arguments.Count == 0) { mainOK = true; } } } if (!mainOK) { errors.Add(SemanticError.NotFoundMethodmain(node.Classes[idMain])); } foreach (var cclass in node.Classes) { if (!scope.IsDefinedType(cclass.TypeInherit.Text, out TypeInfo type)) { errors.Add(SemanticError.NotDeclaredType(cclass.TypeInherit)); return; } if (new List <string> { "Bool", "Int", "String" }.Contains(type.Text)) { errors.Add(SemanticError.NotInheritsOf(cclass, type)); return; } cclass.Accept(this); } }