예제 #1
0
        private void CheckTypeForSpecialization(AST.Type type)
        {
            type = type.Desugar();
            ClassTemplateSpecialization specialization;
            type = type.GetFinalPointee() ?? type;
            if (!type.TryGetDeclaration(out specialization))
                return;

            if (specialization.Ignore ||
                specialization.TemplatedDecl.TemplatedClass.Ignore ||
                specialization.IsIncomplete ||
                specialization.TemplatedDecl.TemplatedClass.IsIncomplete ||
                specialization is ClassTemplatePartialSpecialization ||
                specialization.Arguments.Any(a => UnsupportedTemplateArgument(specialization, a)))
                return;

            TypeMap typeMap;
            if (Context.TypeMaps.FindTypeMap(specialization, out typeMap))
            {
                var mappedTo = typeMap.CSharpSignatureType(new CSharpTypePrinterContext { Type = type });
                mappedTo = mappedTo.Desugar();
                mappedTo = (mappedTo.GetFinalPointee() ?? mappedTo);
                if (mappedTo.IsPrimitiveType() || mappedTo.IsPointerToPrimitiveType() || mappedTo.IsEnum())
                    return;
            }

            HashSet<ClassTemplateSpecialization> list;
            if (specializations.ContainsKey(specialization.TranslationUnit.Module))
                list = specializations[specialization.TranslationUnit.Module];
            else
                specializations[specialization.TranslationUnit.Module] =
                    list = new HashSet<ClassTemplateSpecialization>();
            list.Add(specialization);
        }
예제 #2
0
        private List <Parameter> RemoveOperatorParams(Function function)
        {
            var functionParams = new List <Parameter>(function.Parameters);

            if (!function.IsOperator ||
                (Context.Options.GeneratorKind != GeneratorKind.CLI &&
                 Context.Options.GeneratorKind != GeneratorKind.CSharp))
            {
                return(functionParams);
            }

            // C++ operators in a class have no class param unlike C#
            // but we need to be able to compare them to free operators.
            Parameter param = functionParams.Find(p => p.Kind == ParameterKind.Regular);

            if (param != null)
            {
                AST.Type type = param.Type.Desugar();
                type = (type.GetFinalPointee() ?? type).Desugar();
                Class @class;
                if (type.TryGetClass(out @class) &&
                    function.Namespace == @class)
                {
                    functionParams.Remove(param);
                }
            }

            return(functionParams);
        }
예제 #3
0
        /// <remarks>
        /// Checks if a given type is invalid, which can happen for a number of
        /// reasons: incomplete definitions, being explicitly ignored, or also
        /// by being a type we do not know how to handle.
        /// </remarks>
        bool HasInvalidType(AST.Type type, out string msg)
        {
            if (type == null)
            {
                msg = "null";
                return(true);
            }

            if (!IsTypeComplete(type))
            {
                msg = "incomplete";
                return(true);
            }

            if (IsTypeIgnored(type))
            {
                msg = "ignored";
                return(true);
            }

            var           arrayType = type as ArrayType;
            PrimitiveType primitive;

            if (arrayType != null && arrayType.SizeType == ArrayType.ArraySize.Constant &&
                !arrayType.Type.IsPrimitiveType(out primitive) &&
                !arrayType.Type.Desugar().IsPointerToPrimitiveType())
            {
                msg = "unsupported";
                return(true);
            }

            msg = null;
            return(false);
        }
예제 #4
0
        bool IsTypeIgnored(AST.Type type)
        {
            var checker = new TypeIgnoreChecker(Driver.TypeDatabase);

            type.Visit(checker);

            return(checker.IsIgnored);
        }
예제 #5
0
        private bool CheckDefaultParametersForAmbiguity(Function function, Function overload)
        {
            List <Parameter> functionParams = RemoveOperatorParams(function);
            List <Parameter> overloadParams = RemoveOperatorParams(overload);

            var commonParameters = Math.Min(functionParams.Count, overloadParams.Count);

            var i = 0;

            for (; i < commonParameters; ++i)
            {
                AST.Type funcType = functionParams[i].Type.GetMappedType(
                    TypeMaps, Options.GeneratorKind);
                AST.Type overloadType = overloadParams[i].Type.GetMappedType(
                    TypeMaps, Options.GeneratorKind);

                AST.Type funcPointee     = funcType.GetFinalPointee() ?? funcType;
                AST.Type overloadPointee = overloadType.GetFinalPointee() ?? overloadType;

                if (((funcPointee.IsPrimitiveType() || overloadPointee.IsPrimitiveType()) &&
                     !funcType.Equals(overloadType)) ||
                    !funcPointee.Equals(overloadPointee))
                {
                    return(false);
                }
            }

            for (; i < functionParams.Count; ++i)
            {
                var funcParam = functionParams[i];
                if (!funcParam.HasDefaultValue)
                {
                    return(false);
                }
            }

            for (; i < overloadParams.Count; ++i)
            {
                var overloadParam = overloadParams[i];
                if (!overloadParam.HasDefaultValue)
                {
                    return(false);
                }
            }

            if (functionParams.Count > overloadParams.Count)
            {
                overload.ExplicitlyIgnore();
            }
            else
            {
                function.ExplicitlyIgnore();
            }

            return(true);
        }
예제 #6
0
파일: Declaration.cs 프로젝트: bencz/Beryl
        public Declaration(Position position, string name, SymbolKind kind, AST.Type type)
            : base(position)
        {
            _name = name;

            _kind = kind;

            _type = type;
            _type.Parent = this;
        }
예제 #7
0
파일: Declaration.cs 프로젝트: bencz/Beryl
        public Declaration(Position position, string name, SymbolKind kind, AST.Type type) :
            base(position)
        {
            _name = name;

            _kind = kind;

            _type        = type;
            _type.Parent = this;
        }
예제 #8
0
 public void AddField(string name, AST.Type type)
 {
     if (!Fields.ContainsKey(name))
     {
         Fields.Add(name, type);
     }
     else
     {
         throw new Exception("Sorry, but there is another field with the same name :(");
     }
 }
예제 #9
0
 public void AddMethod(string name, AST.Type returnType)
 {
     if (!Methods.ContainsKey(name))
     {
         Methods.Add(name, new Method(returnType));
     }
     else
     {
         throw new Exception("Method already exists!");
     }
 }
예제 #10
0
 public void AddVariable(string name, AST.Type type)
 {
     if (!Variables.ContainsKey(name))
     {
         Variables.Add(name, type);
     }
     else
     {
         throw new Exception("Variable name and stuff and there is one...");
     }
 }
예제 #11
0
 public void AddParam(string name, AST.Type type)
 {
     if (!Parameters.ContainsKey(name))
     {
         Parameters.Add(name, type);
     }
     else
     {
         throw new Exception("Parameter name exists already...");
     }
 }
예제 #12
0
 private void CheckForInternalSpecialization(Declaration container, AST.Type type)
 {
     ASTUtils.CheckTypeForSpecialization(type, container,
                                         specialization =>
     {
         if (!specializations.Contains(specialization))
         {
             internalSpecializations.Add(specialization);
             CheckLayoutFields(specialization);
         }
     }, Context.TypeMaps, true);
 }
예제 #13
0
파일: Parser.cs 프로젝트: SuNNjek/ParseTest
        private Ast Declaration()
        {
            if (!IsType(_tokenStream.Current))
            {
                return(null);
            }

            AST.Type        type  = new AST.Type(_tokenStream.Consume());
            IdentifierToken ident = _tokenStream.Take <IdentifierToken>();

            return(new VariableDeclaration(ident, type));
        }
예제 #14
0
        private bool CheckDefaultParametersForAmbiguity(Function function, Function overload)
        {
            var commonParameters = Math.Min(function.Parameters.Count, overload.Parameters.Count);

            var i = 0;

            for (; i < commonParameters; ++i)
            {
                AST.Type funcType     = GetFinalType(function.Parameters[i]);
                AST.Type overloadType = GetFinalType(overload.Parameters[i]);

                AST.Type funcPointee     = funcType.GetFinalPointee() ?? funcType;
                AST.Type overloadPointee = overloadType.GetFinalPointee() ?? overloadType;

                if (((funcPointee.IsPrimitiveType() || overloadPointee.IsPrimitiveType()) &&
                     !funcType.Equals(overloadType)) ||
                    !funcPointee.Equals(overloadPointee))
                {
                    return(false);
                }
            }

            for (; i < function.Parameters.Count; ++i)
            {
                var funcParam = function.Parameters[i];
                if (!funcParam.HasDefaultValue)
                {
                    return(false);
                }
            }

            for (; i < overload.Parameters.Count; ++i)
            {
                var overloadParam = overload.Parameters[i];
                if (!overloadParam.HasDefaultValue)
                {
                    return(false);
                }
            }

            if (function.Parameters.Count > overload.Parameters.Count)
            {
                overload.ExplicitlyIgnore();
            }
            else
            {
                function.ExplicitlyIgnore();
            }

            return(true);
        }
예제 #15
0
 private void CheckForInternalSpecialization(Declaration container, AST.Type type)
 {
     ASTUtils.CheckTypeForSpecialization(type, container,
                                         s =>
     {
         if (!specializations.Contains(s))
         {
             internalSpecializations.Add(s);
             foreach (var f in s.Fields)
             {
                 f.Visit(this);
             }
         }
     }, Context.TypeMaps, true);
 }
예제 #16
0
        public FunctionDeclaration(Position position, string name, AST.Type type, ParameterDeclaration[] parameters, Expression body) :
            base(position, name, SymbolKind.Function, type)
        {
            _parameters = parameters;
            foreach (ParameterDeclaration parameter in _parameters)
            {
                parameter.Parent = this;
            }

            // body MAY be null for predefined functions
            _body = body;
            if (_body != null)
            {
                _body.Parent = this;
            }
        }
        public bool CompareTypes(AST.Type t1, AST.Type t2)
        {
            if (t1.GetType() != t2.GetType())
            {
                return(false);
            }

            if (t1 is ObjectType to1 && t2 is ObjectType to2)
            {
                if (to1.Name != to2.Name)
                {
                    return(false);
                }
            }

            return(true);
        }
 public void AddMethodVariable(string className, string methodName, string varName, AST.Type type)
 {
     program.classTables[className].Methods[methodName].AddVariable(varName, type);
 }
예제 #19
0
 public VariableDeclaration(Position position, string name, AST.Type type) :
     base(position, name, SymbolKind.Variable, type)
 {
 }
예제 #20
0
        static bool IsTypeComplete(AST.Type type)
        {
            var checker = new TypeCompletionChecker();

            return(type.Visit(checker));
        }
예제 #21
0
 public abstract void Visit(AST.Type visitable);
예제 #22
0
 public override void Visit(AST.Type visitable)
 {
     WriteIndentantion(true).AppendLine($"Type: {visitable.Token.Value}");
     _indentLevel--;
 }
예제 #23
0
 public ParameterDeclaration(Position position, string name, AST.Type type) :
     base(position, name, SymbolKind.Parameter, type)
 {
 }
예제 #24
0
 public ConstantDeclaration(Position position, string name, AST.Type type, Expression expression) :
     base(position, name, SymbolKind.Constant, type)
 {
     _expression        = expression;
     _expression.Parent = this;
 }
 public void AddField(string className, string fieldName, AST.Type type)
 {
     program.classTables[className].AddField(fieldName, type);
 }
예제 #26
0
 public LiteralNode(object value, AST.Type type)
 {
     Value = value; Type = type;
 }
예제 #27
0
 public TypeRefNode(AST.Type type, bool?abi = null)
 {
     Type = type; Abi = abi;
 }
 public void AddMethod(string className, string methodName, AST.Type returnType)
 {
     program.classTables[className].AddMethod(methodName, returnType);
 }
        public bool TypeChecking(Node tree, string currentClass, string currentMethod)
        {
            switch (tree)
            {
            case MethodBody methodBody:
            {
                foreach (var stm in methodBody.Statements)
                {
                    TypeChecking(stm, currentClass, currentMethod);
                }
                if (symbolTable.GetMethodReturnType(currentClass, currentMethod).GetType() != TypeOf(methodBody.ReturnExpression, currentClass, currentMethod).GetType())
                {
                    throw new Exception("Wrong return type");
                }
                else
                {
                    return(true);
                }
            }

            case BlockStatement blockStm:
            {
                bool result = false;
                foreach (var stm in blockStm.Statements)
                {
                    result = TypeChecking(stm, currentClass, currentMethod);
                }
                return(result);
            }

            case IfElseBlock ifElse:
            {
                if (!(TypeOf(ifElse.Expression, currentClass, currentMethod) is AST.Boolean))
                {
                    throw new Exception("Sorry but an if statement awaits a boolean :(");
                }
                else
                {
                    bool a = TypeChecking(ifElse.FalseBranch, currentClass, currentMethod);
                    bool b = TypeChecking(ifElse.TrueBranch, currentClass, currentMethod);
                    return(a && b);
                }
            }

            case WhileBlock whileBlock:
            {
                if (!(TypeOf(whileBlock.Expression, currentClass, currentMethod) is AST.Boolean))
                {
                    throw new Exception("While type stupid");
                }
                else
                {
                    return(TypeChecking(whileBlock.Statement, currentClass, currentMethod));
                }
            }

            case VarAssignment varAss:
            {
                AST.Type varType = symbolTable.GetVarType(currentClass, currentMethod, varAss.Id);
                if (varType.GetType() != TypeOf(varAss.Expression, currentClass, currentMethod).GetType())
                {
                    throw new Exception("Variable Assignment type is shit");
                }
                else
                {
                    return(true);
                }
            }

            case ArrayAssignment arrAss:
            {
                if (!(TypeOf(arrAss.Index, currentClass, currentMethod) is Int) || !(TypeOf(arrAss.Value, currentClass, currentMethod) is Int))
                {
                    throw new Exception("???");
                }
                else
                {
                    return(true);
                }
            }

            case Print print:
            {
                if (TypeOf(print.Expression, currentClass, currentMethod) is AST.Int)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            case Write write:
            {
                if (TypeOf(write.Expression, currentClass, currentMethod) is AST.IntegerLit)
                {
                    return(true);
                }
                else
                {
                    //throw new Exception("Write is shit");
                    return(true);
                }
            }

            default: throw new Exception("No thingy matched");
            }
        }
        public AST.Type TypeOf(Expression exp, string currentClass, string currentMethod)
        {
            switch (exp)
            {
            case Identifier id:
            {
                return(symbolTable.GetVarType(currentClass, currentMethod, id.Name));
            }

            case And and:
            {
                AST.Type left  = TypeOf(and.Left, currentClass, currentMethod);
                AST.Type right = TypeOf(and.Right, currentClass, currentMethod);

                if (left.GetType() != right.GetType())
                {
                    throw new Exception("Binary operator type fail and shit");
                }
                else
                {
                    return(new AST.Boolean());
                }
            }

            case Plus plus:
            {
                AST.Type left  = TypeOf(plus.Left, currentClass, currentMethod);
                AST.Type right = TypeOf(plus.Right, currentClass, currentMethod);

                if (left.GetType() != right.GetType())
                {
                    throw new Exception("Binary operator type fail and shit");
                }
                else
                {
                    return(new Int());
                }
            }

            case Minus minus:
            {
                AST.Type left  = TypeOf(minus.Left, currentClass, currentMethod);
                AST.Type right = TypeOf(minus.Right, currentClass, currentMethod);

                if (left.GetType() != right.GetType())
                {
                    throw new Exception("Binary operator type fail and shit");
                }
                else
                {
                    return(new Int());
                }
            }

            case Times times:
            {
                AST.Type left  = TypeOf(times.Left, currentClass, currentMethod);
                AST.Type right = TypeOf(times.Right, currentClass, currentMethod);

                if (left.GetType() != right.GetType())
                {
                    throw new Exception("Binary operator type fail and shit");
                }
                else
                {
                    return(new Int());
                }
            }

            case Division division:
            {
                AST.Type left  = TypeOf(division.Left, currentClass, currentMethod);
                AST.Type right = TypeOf(division.Right, currentClass, currentMethod);

                if (left.GetType() != right.GetType())
                {
                    throw new Exception("Binary operator type fail and shit");
                }
                else
                {
                    return(new Int());
                }
            }

            case LessThan lt:
            {
                AST.Type left  = TypeOf(lt.Left, currentClass, currentMethod);
                AST.Type right = TypeOf(lt.Right, currentClass, currentMethod);

                if (left.GetType() != right.GetType())
                {
                    throw new Exception("Binary operator type fail and shit");
                }
                else
                {
                    return(new AST.Boolean());
                }
            }

            case GreaterThan gt:
            {
                AST.Type left  = TypeOf(gt.Left, currentClass, currentMethod);
                AST.Type right = TypeOf(gt.Right, currentClass, currentMethod);

                if (left.GetType() != right.GetType())
                {
                    throw new Exception("Binary operator type fail and shit");
                }
                else
                {
                    return(new AST.Boolean());
                }
            }

            case ArrayAccess arrAcc:
            {
                return(TypeOf(arrAcc.Val, currentClass, currentMethod));
            }

            case ArrayLength arrlength:
            {
                if (!(TypeOf(arrlength.Exp, currentClass, currentMethod) is IntArray))
                {
                    throw new Exception(arrlength.Exp + " is not an array");
                }
                else
                {
                    return(new Int());
                }
            }

            case MethodCall methodCall:
            {
                ObjectType expType;
                if (TypeOf(methodCall.Exp, currentClass, currentMethod) is ObjectType ot)
                {
                    expType = ot;
                }
                else
                {
                    throw new Exception("This method does not exist... Sorry bro");
                }

                if (!symbolTable.ExistsMethod(expType.Name, methodCall.MethodName))
                {
                    throw new Exception("Method does not exist");
                }
                AST.Type[] paramTypes = symbolTable.GetMethodParam(expType.Name, methodCall.MethodName);
                int        i          = 0;

                if (methodCall.Parameters == null)
                {
                    return(symbolTable.GetMethodReturnType(expType.Name, methodCall.MethodName));
                }

                foreach (var par in methodCall.Parameters)
                {
                    if (!CompareTypes(TypeOf(par, currentClass, currentMethod), paramTypes[i]))
                    {
                        throw new Exception("Parameters type error");
                    }
                    i++;
                }

                methodCall.EnhancedName = expType.Name + "$" + methodCall.MethodName;

                return(symbolTable.GetMethodReturnType(expType.Name, methodCall.MethodName));
            }

            case Read read:
            {
                return(new AST.Boolean());
            }

            case BooleanLit booleanLit:
            {
                return(new AST.Boolean());
            }

            case IntegerLit intLit:
            {
                return(new Int());
            }

            case This th:
            {
                return(new ObjectType(currentClass));        // TODO
            }

            case ArrayInstantiation arrInst:
            {
                TypeOf(arrInst.Length, currentClass, currentMethod);
                return(new AST.IntArray());
            }

            case ObjectInstantiation objInst:
            {
                return(new ObjectType(objInst.ObjectId));
            }

            case Not not:
            {
                TypeOf(not.Exp, currentClass, currentMethod);
                return(new AST.Boolean());
            }

            case Parent par:
            {
                return(TypeOf(par.Exp, currentClass, currentMethod));
            }
            }

            return(null);
        }
 public void AddMethodParameter(string className, string methodName, string parameterName, AST.Type type)
 {
     program.classTables[className].Methods[methodName].AddParam(parameterName, type);
 }