Beispiel #1
0
        protected bool Equals(ResolvableType other)
        {
            if (_type != null && other._type != null)
                return _type.Equals(other._type);

            return Name.Equals(other.Name);
        }
Beispiel #2
0
        public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic)
        {
            // TODO should be unified with RppFuncCall and rethink how types for closures are figureout.
            // we should use constraints and type inference only, not this kind of hacks when we check target
            // closure signature and use types from there

            // Skip closures because they may have missing types
            _arguments = NodeUtils.AnalyzeWithPredicate(scope, _arguments, node => !(node is RppClosure), diagnostic);

            Type.Resolve(scope);

            RType targetType = Type.Value;

            if (NeedToInferGenericArguments(targetType))
            {
                RType inferredTargetType;
                Constructor = FindGenericConstructor(targetType, out inferredTargetType);
                Type = new ResolvableType(inferredTargetType);
            }
            else
            {
                Constructor = FindConstructor(targetType);
            }

            _arguments = RppFuncCall.ReplaceUndefinedClosureTypesIfNeeded(_arguments, Constructor.Parameters, new List<RType>());
            NodeUtils.AnalyzeWithPredicate(scope, _arguments, node => node is RppClosure, diagnostic);

            return this;
        }
Beispiel #3
0
        public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic)
        {
            RType thisType = scope.GetEnclosingType();
            if (thisType == null)
            {
                throw new Exception("Can't find enclosing type for this");
            }

            Type = new ResolvableType(thisType);
            return this;
        }
Beispiel #4
0
        public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic)
        {
            if (TargetType == null)
            {
                throw new Exception("TargetType should be specified before anaylyze is called");
            }

            RType classType = TargetType;
            // TODO It's kinda weird to have resolution here and not in the scope, because similar
            // lookup is done for methods
            while (classType != null && Field == null)
            {
                Field = classType.Fields.FirstOrDefault(f => f.Name == Name);
                if (Field != null)
                {
                    break;
                }

                classType = classType.BaseType;
            }

            if (Field == null)
            {
                var functions = scope.LookupFunction(Name);
                if (functions.Any(f => f.Parameters.IsEmpty()))
                {
                    RppFuncCall funcCall = new RppFuncCall(Name, Collections.NoExprs);
                    return funcCall.Analyze(scope, diagnostic);
                }

                throw SemanticExceptionFactory.ValueIsNotMember(Token, TargetType.ToString());
            }

            Debug.Assert(classType != null, "obj != null");

            Type = new ResolvableType(Field.Type);

            return this;
        }
Beispiel #5
0
        public override IRppNode Analyze(SymbolTable scope, Diagnostic diagnostic)
        {
            Value = (IRppExpr) Value.Analyze(scope, diagnostic);
            RppVar declIn = new RppVar(MutabilityFlag.MfVal, "<in>", Value.Type, Value);
            declIn.Analyze(scope, diagnostic);

            CaseClauses = NodeUtils.Analyze(scope, CaseClauses, diagnostic);

            Type = CheckCommonType(CaseClauses, Token).AsResolvable();
            RppVar declOut = new RppVar(MutabilityFlag.MfVar, "<out>", Type, new RppDefaultExpr(Type));

            RppId declInId = new RppId("<in>", declIn);
            declInId.Analyze(scope, diagnostic);
            RppId declOutId = new RppId("<out>", declOut);

            RppMatchingContext ctx = new RppMatchingContext();
            var ifC = Create(declInId, declOutId, CaseClauses, ctx);
            var expr = new RppBlockExpr(List<IRppNode>(declIn, ifC)) {Exitable = true};

            SymbolTable matchScope = new SymbolTable(scope);
            RppBlockExpr matchBlock = new RppBlockExpr(List<IRppNode>(declOut, expr, declOutId));
            return matchBlock.Analyze(matchScope, diagnostic);
        }
Beispiel #6
0
 protected RppPop()
 {
     Type = ResolvableType.NothingTy;
 }
Beispiel #7
0
        public static IRppExpr ReplaceUndefinedClosureTypesIfNeeded([NotNull] IRppExpr expr, ResolvableType targetType, IList<RType> genericArgs)
        {
            if (expr is RppClosure)
            {
                RppClosure closure = (RppClosure) expr;
                var hasUndefinedClosureBinding = closure.Bindings.Any(b => b.Type.IsUndefined());
                if (targetType.IsDefined() && hasUndefinedClosureBinding)
                {
                    RType type = targetType.Value;

                    if (genericArgs.NonEmpty())
                    {
                        // Substitute generics parameters with specified generic arguments
                        // def func[A,U]()...
                        // func[Int, Float]()...
                        // Function1[!!A, !!U] -> Function1[Int, Float]
                        type = type.MakeGenericType(genericArgs.ToArray());
                    }

                    IReadOnlyCollection<RType> genericArguments = type.GenericArguments;

                    List<IRppParam> newBindings =
                        genericArguments.Zip(closure.Bindings,
                            (varTypeGenArg, binding) => binding.CloneWithNewType(varTypeGenArg)).ToList();
                    return new RppClosure(newBindings, closure.Expr);
                }
            }

            return expr;
        }
Beispiel #8
0
 public RppAsInstanceOf(IRppExpr value, ResolvableType type)
 {
     Value = value;
     Type = type;
 }
Beispiel #9
0
 public RppField(MutabilityFlag mutabilityFlag, string name, HashSet<ObjectModifier> modifiers, ResolvableType type, IRppExpr initExpr)
     : base(mutabilityFlag, name, type, initExpr)
 {
     Modifiers = modifiers;
     IsLocalSemantic = false;
 }
Beispiel #10
0
 public RppField(MutabilityFlag mutabilityFlag, string name, HashSet<ObjectModifier> modifiers, ResolvableType type)
     : base(mutabilityFlag, name, type, RppEmptyExpr.Instance)
 {
     Modifiers = modifiers;
     IsLocalSemantic = false;
 }
Beispiel #11
0
        private RppClass ParseObjectDef(HashSet<ObjectModifier> modifiers)
        {
            Expect(RppLexer.Id);
            string objectName = _lastToken.Text;

            RTypeName baseClassTypeName;
            IList<IRppExpr> baseClassArgs;
            IList<IRppNode> stats = ParseClassTemplateOpt(out baseClassTypeName, out baseClassArgs);

            ResolvableType baseClass = ResolvableType.AnyTy;
            if (baseClassTypeName != null)
            {
                baseClass = new ResolvableType(baseClassTypeName);
            }

            return new RppClass(ClassKind.Object, modifiers, objectName, Collections.NoFields, stats, Collections.NoVariantTypeParams,
                new RppBaseConstructorCall(baseClass, Collections.NoExprs));
        }
Beispiel #12
0
        private bool ParseBinding(out RppParam binding)
        {
            binding = null;
            if (!Require(RppLexer.Id))
            {
                return false;
            }

            string name = _lastToken.Text;

            ResolvableType type = ResolvableType.UndefinedTy;
            if (Require(RppLexer.OP_Colon))
            {
                RTypeName typeName;
                if (!ParseType(out typeName))
                {
                    RaiseSyntaxError("Type is expected");
                }

                type = new ResolvableType(typeName);
            }

            binding = new RppParam(name, type) {IsClosureBinding = true};
            return true;
        }
Beispiel #13
0
        // ClassDef ::= id [TypeParamClause] {Annotation} [AccessModifier] ClassParamClauses ClassTemplateOpt
        public RppClass ParseClassDef(HashSet<ObjectModifier> modifiers)
        {
            if (Require(RppLexer.Id))
            {
                string name = _lastToken.Text;
                IList<RppVariantTypeParam> typeParams = ParseTypeParams();
                IList<RppField> classParams = ParseClassParamClause();
                IList<IRppExpr> baseClassArgs;
                RTypeName baseClassTypeName;
                IList<IRppNode> nodes = ParseClassTemplateOpt(out baseClassTypeName, out baseClassArgs);

                ResolvableType baseClass = ResolvableType.AnyTy;
                if (baseClassTypeName != null)
                {
                    baseClass = new ResolvableType(baseClassTypeName);
                }

                return new RppClass(ClassKind.Class, modifiers, name, classParams, nodes, typeParams,
                    new RppBaseConstructorCall(baseClass, baseClassArgs));
            }

            RaiseSyntaxError("Expected identifier but got : ");
            return null;
        }
Beispiel #14
0
 public RppTypedPattern(IToken varid, RTypeName typeName)
 {
     Token = varid;
     Name = varid.Text;
     _resolvableType = new ResolvableType(typeName);
 }
 public RppConstructorPattern(ResolvableType typeName, IEnumerable<RppMatchPattern> patterns)
 {
     _type = typeName;
     _patterns = patterns.ToArray();
 }
Beispiel #16
0
 public RppThrow(IRppExpr expr)
 {
     Expr = expr;
     Type = ResolvableType.NothingTy;
 }
Beispiel #17
0
 public RppWhile(IRppExpr condition, IRppNode body)
 {
     Condition = condition;
     Body = body;
     Type = ResolvableType.UnitTy;
 }
Beispiel #18
0
        public RppClass(ClassKind kind, HashSet<ObjectModifier> modifiers, [NotNull] string name, [NotNull] IList<RppField> classParams,
            [NotNull] IEnumerable<IRppNode> classBody, [NotNull] IList<RppVariantTypeParam> typeParams, RppBaseConstructorCall baseConstructorCall) : base(name)
        {
            Kind = kind;
            BaseConstructorCall = baseConstructorCall;
            _classParams = classParams;
            // TODO all of this can be simplified, we don't need to separate body of class. We can just walk rpp nodes with visitors
            IEnumerable<IRppNode> rppNodes = classBody as IList<IRppNode> ?? classBody.ToList();
            _funcs = rppNodes.OfType<RppFunc>().Where(f => !f.IsConstructor).ToList();
            _funcs.ForEach(DefineFunc);
            var constrExprs = rppNodes.OfType<IRppExpr>().Where(n => !(n is RppField)).ToList();
            // TODO for some reason RppField is also IRppExpr, I think it shouldn't be
            _typeParams = typeParams;
            Modifiers = modifiers;

            _constructors = rppNodes.OfType<RppFunc>().Where(f => f.IsConstructor).ToList();

            _fields = _classParams.Where(param => param.MutabilityFlag != MutabilityFlag.MfUnspecified || IsCase).ToList();

            rppNodes.OfType<RppField>().ForEach(_fields.Add);

            var primaryConstructor = CreatePrimaryConstructor(constrExprs);
            _constructors.Add(primaryConstructor);

            CreateProperties();

            if (kind == ClassKind.Object)
            {
                string objectName = SymbolTable.GetObjectName(Name);
                ResolvableType instanceFieldType = new ResolvableType(new RTypeName(objectName));
                InstanceField = new RppField(MutabilityFlag.MfVal, "_instance", Collections.NoModifiers, instanceFieldType,
                    new RppNew(instanceFieldType, Collections.NoExprs));
                _fields.Add(InstanceField);
            }

            _nested = rppNodes.OfType<RppClass>().ToList();
        }
Beispiel #19
0
 public static RppNew New(ResolvableType type, IEnumerable<IRppExpr> args)
 {
     return new RppNew(type, args);
 }