public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); report.Assert(this, TypeNode.ReturnType != TypeInfo.Void, "Invalid type for array."); report.Assert(this, LengthExpression.ReturnType == TypeInfo.Int, "Array length must be an int."); var type = scope.ResolveType(TypeNode.TypeName); var arrayType = (type is AliasTypeInfo) ? ((AliasTypeInfo)type).TargetType : type; if (TypeInfo.IsNull(arrayType)) { report.AddError(this, "Unknown type: {0}", TypeNode.TypeName); } else if (!((arrayType is ArrayTypeInfo || (arrayType is AliasTypeInfo && ((AliasTypeInfo)arrayType).TargetType is ArrayTypeInfo)))) { report.AddError(this, "The type {0} is not an array.", TypeNode.TypeName); } else { report.Assert(this, ((ArrayTypeInfo)arrayType).TargetType == InitExpression.ReturnType, "Initialization expression and array types do not match ({0},{1})", InitExpression.ReturnType, TypeNode.ReturnType); } ReturnType = arrayType; }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { // Delegated to the FunctionDeclarationNodes: // - Add every function declaration inside this block to the current scope. // - Create a child scope for every function. base.CheckSemantics(scope, report); var names = new HashSet <string>(); foreach (FunctionDeclarationNode declarationNode in Children) { if (!report.Assert(declarationNode, !names.Contains(declarationNode.FunctionName), "Duplicate function names in the same function block.")) { return; // TODO: return? } names.Add(declarationNode.FunctionName); } // - Check the semantics of the bodies of the functions. // - Verify that the function bodies return the right type. foreach (FunctionDeclarationNode declarationNode in Children) { var varOrFunction = scope.ResolveVarOrFunction(declarationNode.FunctionName); if (!(varOrFunction is FunctionInfo)) { continue; } declarationNode.FunctionBody.CheckSemantics(declarationNode.FunctionScope, report); report.Assert(declarationNode, declarationNode.FunctionBody.ReturnType == declarationNode.FunctionReturnType, "Function return type does not match declared type."); } }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); report.Assert(IfCondition, IfCondition.ReturnType == TypeInfo.Int, "The condition of an if expression must return an integer value."); report.Assert(ThenExpression, ThenExpression.ReturnType == TypeInfo.Void, "The body of an if-then expression must not return a value."); ReturnType = TypeInfo.Void; }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); report.Assert(ConditionExpression, ConditionExpression.ReturnType == TypeInfo.Int, "The while condition must return an int."); report.Assert(BodyExpression, BodyExpression.ReturnType == TypeInfo.Void, "The while expression must not return a value."); ReturnType = TypeInfo.Void; }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); var current = (ASTNode)Parent; while (current != null) { if (current is ForNode || current is WhileNode) { EnclosingForOrWhile = (FlowControlNode)current; break; } if (current is FunctionDeclarationNode || current is ProgramNode) { break; } if (current is ExpressionSequenceNode) { ((ExpressionSequenceNode)current).HasBreak = true; } current = current.Parent as ASTNode; } report.Assert(this, EnclosingForOrWhile != null, "Invalid break."); ReturnType = TypeInfo.Void; }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); report.Assert(this, LeftOperand.ReturnType == TypeInfo.Int && RightOperand.ReturnType == TypeInfo.Int, "Both operands must be integers."); ReturnType = TypeInfo.Int; }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); report.Assert(this, LeftOperand.ReturnType == RightOperand.ReturnType, "Equality comparisons are only allowed between elements of the same type."); ReturnType = TypeInfo.Int; }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); if (report.Assert(this, !scope.IsDefinedInCurrentScopeAsType(NewTypeNode.TypeName), "Type {0} is already defined in the current scope.", NewTypeNode.TypeName)) { scope.DefineArray(NewTypeNode.TypeName, TargetTypeNode.TypeName); } }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); if (report.Assert(this, !scope.IsDefinedInCurrentScopeAsType(NewTypeNode.TypeName), "Type {0} is already defined in the current scope.", NewTypeNode.TypeName)) { var record = scope.DefineRecord(NewTypeNode.TypeName); for (int i = 1; i < Children.Count; i++) { var currentMember = Children[i]; var currentMemberTypeName = ((currentMember as ASTNode).Children[0] as TypeIDNode).TypeName; var couldAddMember = record.AddMember(currentMember.Text, currentMemberTypeName); report.Assert(this, couldAddMember, "Record members must have different names."); } } }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); var type = scope.ResolveType(TypeNode.Text); if (report.Assert(TypeNode, !TypeInfo.IsNull(type), "Type {0} does not exist in the current scope.", TypeNode.Text) && report.Assert(TypeNode, type is RecordTypeInfo, "Type {0} is not a record.", TypeNode.Text) && report.Assert(this, (Children.Count - 1) / 2 == ((RecordTypeInfo)type).Fields.Count, "Invalid amount of fields.")) { var rtype = (RecordTypeInfo)type; for (int i = 1; i < Children.Count; i += 2) { string fieldName = Children[i].Text; var initExpr = (ASTNode)Children[i + 1]; report.Assert((ASTNode)Children[i], rtype.Fields[fieldName] == initExpr.ReturnType, "Field init expression type and field type do not match."); } } ReturnType = type; }
public override void CheckSemantics(Semantic.Scope scope, Semantic.ErrorReporter report) { base.CheckSemantics(scope, report); Parameters = new Dictionary <string, TypeInfo>(); if (Children == null) { return; } for (int i = 0; i < Children.Count; i++) { var paramTypeName = ((TypeIDNode)((ASTNode)Children[i]).Children[0]).TypeName; if (report.Assert(Children[i] as ASTNode, !Parameters.ContainsKey(Children[i].Text), "There is already a parameter named {0} on the function.", Children[i].Text)) { var resolvedType = scope.ResolveType(paramTypeName); report.Assert(Children[i] as ASTNode, !TypeInfo.IsNull(resolvedType), "Type {0} does not exist in the current context.", paramTypeName); Parameters.Add(Children[i].Text, resolvedType); } } }