Beispiel #1
0
        public override TypeValidationResult CheckType()
        {
            string duplicateFunctionName = Definitions.Select(d => d.Name)
                                           .GroupBy(i => i)
                                           .Where(g => g.Count() > 1)
                                           .Select(t => t.Key)
                                           .FirstOrDefault();

            if (duplicateFunctionName != null)
            {
                return(TypeValidationResult.Invalid(Position, $"Program contains duplicate function name '{duplicateFunctionName}'"));
            }

            SymbolTable = new SymbolTable(Definitions);

            var mainFunctionType = SymbolTable.FunctionType("main");

            if (mainFunctionType == null)
            {
                return(TypeValidationResult.Invalid(Position, "Program must contain a function 'main'"));
            }

            Type = mainFunctionType.ReturnType;

            foreach (var definition in Definitions)
            {
                var result = definition.CheckType();
                if (result.HasError)
                {
                    return(result);
                }
            }
            return(TypeValidationResult.Valid(Type));
        }
Beispiel #2
0
        public override TypeValidationResult CheckType()
        {
            foreach (var actual in Actuals)
            {
                var result = actual.CheckType();
                if (result.HasError)
                {
                    return(result);
                }
            }

            var functionType = SymbolTable.FunctionType(Name);

            if (functionType == null)
            {
                return(TypeValidationResult.Invalid(Position, $"Function '{Name}' has no definition"));
            }

            if (functionType.CheckArgs(Actuals.Select(a => a.Type)) == false)
            {
                return(TypeValidationResult.Invalid(Position, $"Function {Name}{functionType} called with mismatched arguments {Name}{ActualsTypeString}"));
            }

            SymbolTable.AddCaller(Name, SymbolTable.CurrentFunction);
            Type = functionType.ReturnType;
            return(TypeValidationResult.Valid(Type));
        }
Beispiel #3
0
        public override TypeValidationResult CheckType()
        {
            SymbolTable.CurrentFunction = Name;

            var returnTypeResult = TypeDeclaration.CheckType();

            if (returnTypeResult.HasError)
            {
                return(returnTypeResult);
            }

            foreach (var formal in Formals)
            {
                var formalResult = formal.CheckType();
                if (formalResult.HasError)
                {
                    return(formalResult);
                }
            }

            string duplicateFormalName = Formals.Select(d => d.Name)
                                         .GroupBy(i => i)
                                         .Where(g => g.Count() > 1)
                                         .Select(t => t.Key)
                                         .FirstOrDefault();

            if (duplicateFormalName != null)
            {
                return(TypeValidationResult.Invalid(Position, $"Function '{Name}' has duplicate formal '{duplicateFormalName}'"));
            }

            var result = Body.CheckType();

            if (result.HasError)
            {
                return(result);
            }

            if (FunctionType.ReturnType.Equals(Body.Type) == false)
            {
                return(TypeValidationResult.Invalid(Position, $"Function '{Name}' has a return type '{FunctionType.ReturnType}', but its body has a type '{Body.Type}'"));
            }

            Type = FunctionType;
            return(TypeValidationResult.Valid(Type));
        }
Beispiel #4
0
        public override TypeValidationResult CheckType()
        {
            foreach (var print in Prints)
            {
                var printResult = print.CheckType();
                if (printResult.HasError)
                {
                    return(printResult);
                }
            }

            var result = Expr.CheckType();

            if (result.HasError)
            {
                return(result);
            }

            Type = result.Type;

            return(TypeValidationResult.Valid(Type));
        }
Beispiel #5
0
        public override TypeValidationResult CheckType()
        {
            var ifResult = IfExpr.CheckType();

            if (ifResult.HasError)
            {
                return(ifResult);
            }

            if (ifResult.Type.Equals(new BooleanType()) == false)
            {
                return(TypeValidationResult.Invalid(Position, "IfThenElseOperator must have a boolean if expression"));
            }

            var thenResult = ThenExpr.CheckType();

            if (thenResult.HasError)
            {
                return(thenResult);
            }

            var elseResult = ElseExpr.CheckType();

            if (elseResult.HasError)
            {
                return(elseResult);
            }

            if (thenResult.Type.Equals(elseResult.Type) == false)
            {
                return(TypeValidationResult.Invalid(Position, "IfThenElse, type of then and else expression must be the same"));
            }

            Type = thenResult.Type;
            return(TypeValidationResult.Valid(Type));
        }
Beispiel #6
0
 public override TypeValidationResult CheckType()
 {
     Type = PrimitiveType;
     return(TypeValidationResult.Valid(Type));
 }