예제 #1
0
        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;
        }
예제 #2
0
        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.");
            }
        }
예제 #3
0
        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;
        }
예제 #4
0
파일: WhileNode.cs 프로젝트: frankcs/tiger
        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;
        }
예제 #5
0
파일: BreakNode.cs 프로젝트: frankcs/tiger
        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;
        }
예제 #6
0
        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;
        }
예제 #7
0
        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;
        }
예제 #8
0
 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);
     }
 }
예제 #9
0
        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.");
                }
            }
        }
예제 #10
0
        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;
        }
예제 #11
0
        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);
                }
            }
        }