Example #1
0
 public override void CheckTypes(ErrorHandler errorHandler)
 {
     if (!Length.CanConvertTo(PrimTypeName.INT, errorHandler))
     {
         errorHandler.AddMessage(Severity.Error, $"Cannot use type {Length.GetExprType(errorHandler)} as array indexer", Token);
     }
     if (!DefaultValue.CanConvertTo(Type, errorHandler))
     {
         errorHandler.AddMessage(Severity.Error, $"Cannot use type {DefaultValue.GetExprType(errorHandler)} to initialize an array of {Type}", Token);
     }
 }
Example #2
0
        public override void CheckTypes(ErrorHandler errorHandler)
        {
            if (Op == UnaryOp.MIN && !Expr.CanConvertTo(PrimTypeName.FLOAT, errorHandler) && !Expr.CanConvertTo(PrimTypeName.INT, errorHandler))
            {
                errorHandler.AddMessage(Severity.Error, $"Cannot use pre-operator '-' with type {Expr.GetExprType(errorHandler)}", Token);
            }

            if (Op == UnaryOp.NEG && !Expr.CanConvertTo(PrimTypeName.BOOL, errorHandler))
            {
                errorHandler.AddMessage(Severity.Error, $"Cannot use pre-operator '!' with type {Expr.GetExprType(errorHandler)}", Token);
            }
        }
Example #3
0
        public override void CheckTypes(ErrorHandler errorHandler)
        {
            if (TargetNode != null)
            {
                return;
            }

            var viableCandidates = new List <FnDecl>();

            var args = Args.ToList();

            foreach (var decl in TargetNodeCandidates)
            {
                var parameters = decl.Parameters.ToList();
                if (parameters.Count != args.Count)
                {
                    continue;
                }
                bool success = false;
                for (int i = 0; i < parameters.Count; i++)
                {
                    if (!args[i].CanConvertTo(parameters[i].Type, errorHandler))
                    {
                        break;
                    }
                    success = true;
                }

                if (!success)
                {
                    continue;
                }

                viableCandidates.Add(decl);
            }

            if (viableCandidates.Count == 0)
            {
                errorHandler.AddMessage(Severity.Error, $"No overload of function {Token.Value} with matching parameters found", Token);
            }
            else if (viableCandidates.Count > 1)
            {
                errorHandler.AddMessage(Severity.Error, $"Multiple overloads of function {Token.Value} with the same parameter types found", Token);
            }
            else
            {
                TargetNode = viableCandidates[0];
            }
        }
Example #4
0
        public override bool CanConvertTo(Type type, ErrorHandler errorHandler)
        {
            bool success = true;
            Type elType;

            if (type is ArrayType arrayType)
            {
                elType = arrayType.Type;
            }
            else
            {
                return(false);
            }

            foreach (var expr in Data)
            {
                if (!expr.CanConvertTo(elType, errorHandler))
                {
                    errorHandler.AddMessage(Severity.Error, $"Cannot use expression of type {expr.GetExprType(errorHandler)} in array of {elType}", Token);
                    success = false;
                }
            }

            return(success);
        }
Example #5
0
 public override void CheckTypes(ErrorHandler errorHandler)
 {
     if (!(Right.TargetNode is DeclStmt))
     {
         errorHandler.AddMessage(Severity.Error, $"Cannot find member {Right.Token.Value} in struct {Left.GetExprType(errorHandler)}", Right.Token);
     }
 }
Example #6
0
 public override void CheckTypes(ErrorHandler errorHandler)
 {
     Body.CheckTypes(errorHandler);
     if (!Condition.CanConvertTo(PrimTypeName.BOOL, errorHandler))
     {
         errorHandler.AddMessage(Severity.Error, $"For loop condition is not a boolean", Token);
     }
 }
Example #7
0
 public override void CheckTypes(ErrorHandler errorHandler)
 {
     Value.CheckTypes(errorHandler);
     if (!Value.CanConvertTo(Type, errorHandler))
     {
         errorHandler.AddMessage(Severity.Error, $"Incorrect initializer type for variable of type {Type}", Token);
     }
 }
Example #8
0
        public override void CheckTypes(ErrorHandler errorHandler)
        {
            Type type = LHS.GetTypeInfo();

            if (!RHS.CanConvertTo(type, errorHandler))
            {
                errorHandler.AddMessage(Severity.Error, $"Cannot assign value of type {RHS.GetExprType(errorHandler)} to variable of type {type}", Token);
            }
        }
Example #9
0
 public override void CheckTypes(ErrorHandler errorHandler)
 {
     if (!Condition.CanConvertTo(PrimTypeName.BOOL, errorHandler))
     {
         errorHandler.AddMessage(Severity.Error, $"Condition must be a boolean", Token);
     }
     Body.CheckTypes(errorHandler);
     ElseBody?.CheckTypes(errorHandler);
 }
Example #10
0
        public override void CheckTypes(ErrorHandler errorHandler)
        {
            if (typesChecked)
            {
                return;
            }
            typesChecked = true;
            var targetType = base.GetTypeInfo();

            if (!(targetType is ArrayType))
            {
                errorHandler.AddMessage(Severity.Error, $"{Token.Value} is not an array type", Token);
            }

            if (!Index.CanConvertTo(PrimTypeName.INT, errorHandler))
            {
                errorHandler.AddMessage(Severity.Error, "Array indexer must be an integer", Token);
            }
        }
Example #11
0
 public override void CheckTypes(ErrorHandler errorHandler)
 {
     if (Value == null)
     {
         return;
     }
     if (!Value.CanConvertTo(TargetFn.Type, errorHandler))
     {
         errorHandler.AddMessage(Severity.Error, $"Function {TargetFn.Token.Value} must return type {TargetFn.Type}, tried to return {Value.GetExprType(errorHandler)}", Token);
     }
 }
Example #12
0
 public override void CheckTypes(ErrorHandler errorHandler)
 {
     if (DefaultValue == null)
     {
         return;
     }
     if (!DefaultValue.CanConvertTo(Type, errorHandler))
     {
         errorHandler.AddMessage(Severity.Error, $"Invalid initializer type for function parameter {Token.Value} of type {Type}", Token);
     }
 }
Example #13
0
        public override void ResolveNames(Scope scope, ErrorHandler errorHandler)
        {
            Value?.ResolveNames(scope, errorHandler);
            FnDecl target = scope.FindFn();

            if (target == null)
            {
                errorHandler.AddMessage(Severity.Error, $"return statement is not inside a function", Token);
            }
            TargetFn = target;
        }
Example #14
0
        public void ResolveStructMember(Expr beforePoint, ErrorHandler errorHandler)
        {
            Type typeBeforePoint = new PrimType(PrimTypeName.BOOL);

            if (beforePoint is FnCall fnc)
            {
                fnc.CheckTypes(errorHandler);
                typeBeforePoint = fnc.TargetNode.Type;
            }
            else if (beforePoint is Var v)
            {
                typeBeforePoint = v.GetTypeInfo();
            }
            else if (beforePoint is PointExpr pex)
            {
                return; // it should have been already resolved
            }
            if (!(typeBeforePoint is StructType type))
            {
                errorHandler.AddMessage(Severity.Error, $"Expected struct type, got {typeBeforePoint}", Token);
                return;
            }

            var statement = type.TargetNode.Body.Statements.FirstOrDefault(stmt =>
            {
                if (stmt is DeclStmt decl)
                {
                    return(decl.Token.Value == Token.Value);
                }

                return(false);
            });

            if (statement == null)
            {
                errorHandler.AddMessage(Severity.Error, $"Struct {type.TargetNode.Token.Value} does not contain a member called {Token.Value}", Token);
            }

            TargetNode = statement;
        }
Example #15
0
        public override void CheckTypes(ErrorHandler errorHandler)
        {
            LHS.CheckTypes(errorHandler);
            RHS.CheckTypes(errorHandler);
            bool canApply   = true;
            var  intType    = new PrimType(PrimTypeName.INT);
            var  floatType  = new PrimType(PrimTypeName.FLOAT);
            var  boolType   = new PrimType(PrimTypeName.BOOL);
            var  stringType = new PrimType(PrimTypeName.STRING);

            if (Op == BinaryOp.ADD && !CanBothConvertTo(stringType, errorHandler) &&
                !CanBothConvertTo(intType, errorHandler) && !CanBothConvertTo(floatType, errorHandler))
            {
                canApply = false;
            }
            if ((Op == BinaryOp.AND || Op == BinaryOp.OR) && !CanBothConvertTo(boolType, errorHandler))
            {
                canApply = false;
            }
            if ((Op == BinaryOp.DIV || Op == BinaryOp.MUL || Op == BinaryOp.SUB) &&
                !CanBothConvertTo(intType, errorHandler) && !CanBothConvertTo(floatType, errorHandler))
            {
                canApply = false;
            }
            if (Op == BinaryOp.MOD && !CanBothConvertTo(intType, errorHandler))
            {
                canApply = false;
            }
            if ((Op == BinaryOp.L || Op == BinaryOp.LE || Op == BinaryOp.G || Op == BinaryOp.GE || Op == BinaryOp.NE ||
                 Op == BinaryOp.EQ) && !CanBothConvertTo(boolType, errorHandler))
            {
                canApply = false;
            }
            if ((Op == BinaryOp.B_AND || Op == BinaryOp.B_NOT || Op == BinaryOp.B_OR || Op == BinaryOp.B_SHL ||
                 Op == BinaryOp.B_SHR || Op == BinaryOp.B_XOR) && !CanBothConvertTo(intType, errorHandler))
            {
                canApply = false;
            }

            if (!canApply)
            {
                errorHandler.AddMessage(Severity.Error, $"Cannot apply operator {OpName(Op)} to operands of types {LHS.GetExprType(errorHandler)} ans {RHS.GetExprType(errorHandler)}", OpToken);
            }
        }
Example #16
0
        public override void ResolveNames(Scope scope, ErrorHandler errorHandler)
        {
            var curScope = scope;

            while (curScope != null)
            {
                if (curScope.Owner is WhileLoop wloop)
                {
                    TargetNode = wloop;
                    return;
                }

                if (curScope.Owner is ForLoop floop)
                {
                    TargetNode = floop;
                    return;
                }
                curScope = curScope.Parent;
            }
            errorHandler.AddMessage(Severity.Error, "Break statement not in loop body", Token);
        }
Example #17
0
        public override bool CanConvertTo(Type type, ErrorHandler errorHandler)
        {
            if (!(type is StructType))
            {
                return(false);
            }

            var target         = ((StructType)type).TargetNode;
            var required       = new Dictionary <string, DeclStmt>();
            var requiredFilled = new Dictionary <string, bool>();
            var optional       = new List <DeclAssignStmt>();

            foreach (var stmt in target.Body.Statements)
            {
                if (stmt is DeclAssignStmt das)
                {
                    optional.Add(das);
                }
                else if (stmt is DeclStmt ds)
                {
                    required.Add(ds.Token.Value, ds);
                    requiredFilled.Add(ds.Token.Value, false);
                }
            }

            bool success         = true;
            var  pastIdentifiers = new List <string>();

            foreach (var stmt in Statements)
            {
                if (pastIdentifiers.Contains(stmt.Token.Value))
                {
                    errorHandler.AddMessage(Severity.Error, $"Duplicate struct member {stmt.Token.Value}", Token);
                    success = false;
                }
                pastIdentifiers.Add(stmt.Token.Value);
                var optionalStmt = optional.FirstOrDefault(opt => opt.Token.Value == stmt.Token.Value);
                if (optionalStmt != null)
                {
                    if (!stmt.Data.CanConvertTo(optionalStmt.Type, errorHandler))
                    {
                        errorHandler.AddMessage(Severity.Error, $"Cannot use type {GetExprType(errorHandler)} for member {optionalStmt.Token.Value} of type {optionalStmt.Type}", Token);
                        success = false;
                    }
                    continue;
                }

                if (required.ContainsKey(stmt.Token.Value))
                {
                    requiredFilled[stmt.Token.Value] = true;
                    if (!stmt.Data.CanConvertTo(required[stmt.Token.Value].Type, errorHandler))
                    {
                        errorHandler.AddMessage(Severity.Error, $"Cannot use type {GetExprType(errorHandler)} for member {required[stmt.Token.Value].Token.Value} of type {required[stmt.Token.Value].Type}", Token);
                        success = false;
                    }
                    continue;
                }
                errorHandler.AddMessage(Severity.Error, $"Unknown member {stmt.Token.Value} for struct {target.Token.Value}", Token);
                success = false;
            }

            foreach (var filled in requiredFilled)
            {
                if (!filled.Value)
                {
                    errorHandler.AddMessage(Severity.Error,
                                            $"Missing required member {filled.Key} for struct {target.Token.Value}", Token);
                    success = false;
                }
            }

            return(success);
        }