public override string VisitTraitTypeExpr(AstTraitTypeExpr trait, int data = 0)
        {
            if (trait.IsPolymorphic)
            {
                var sb = new StringBuilder();
                sb.Append($"trait(");
                sb.Append(string.Join(", ", trait.Parameters.Select(p => p.Accept(this))));
                sb.AppendLine(") {");

                foreach (var f in trait.Members)
                {
                    sb.AppendLine(f.Decl.Accept(this).Indent(4));
                }

                foreach (var f in trait.Functions)
                {
                    sb.AppendLine($"{f.Name} :: f.Accept(this)".Indent(4));
                }

                sb.Append("}");

                // polies
                if (trait.PolymorphicInstances?.Count > 0)
                {
                    sb.AppendLine();
                    sb.AppendLine($"// Polymorphic instances for {trait.Name}");
                    foreach (var pi in trait.PolymorphicInstances)
                    {
                        var args = string.Join(", ", pi.Parameters.Select(p => $"{p.Name.Accept(this)} = {p.Value}"));
                        sb.AppendLine($"// {args}".Indent(4));
                        sb.AppendLine(pi.Accept(this).Indent(4));
                    }
                }

                return(sb.ToString().Indent(data));
            }
            else
            {
                var sb = new StringBuilder();
                sb.AppendLine("trait {");

                foreach (var f in trait.Members)
                {
                    sb.AppendLine(f.Decl.Accept(this).Indent(4));
                }

                foreach (var f in trait.Functions)
                {
                    sb.AppendLine($"{f.Name} :: f.Accept(this)".Indent(4));
                }

                sb.Append("}");

                return(sb.ToString().Indent(data));
            }
        }
Example #2
0
        public override string VisitTraitTypeExpr(AstTraitTypeExpr trait, int data = 0)
        {
            var head = $"trait";

            if (trait.Parameters != null && trait.Parameters.Count > 0)
            {
                head += $"({string.Join(", ", trait.Parameters.Select(p => p.Accept(this)))})";
            }
            return(head);

            // var sb = new StringBuilder();
            // sb.AppendLine("trait {");

            // foreach (var f in trait.Members)
            //     sb.AppendLine(f.Decl.Accept(this).Indent(4));

            // foreach (var f in trait.Functions)
            //     sb.AppendLine($"{f.Name} :: f.Accept(this)".Indent(4));

            // sb.Append("}");

            // return sb.ToString().Indent(data);
        }
Example #3
0
        //

        private void AddTrait(AstTraitTypeExpr trait)
        {
            mAllTraits.Add(trait);
            mUnresolvedTraits.Enqueue(trait);
        }
Example #4
0
 public virtual ReturnType VisitTraitTypeExpr(AstTraitTypeExpr expr, DataType data         = default) => default;
Example #5
0
        private void ComputeTraitMembers(AstTraitTypeExpr trait)
        {
            if (trait.IsPolymorphic)
            {
                return;
            }
            if (trait.MembersComputed)
            {
                return;
            }
            trait.MembersComputed = true;

            trait.SubScope.DefineTypeSymbol("Self", new SelfType(trait.Value as CheezType));

            foreach (var v in trait.Members)
            {
                var decl = v.Decl;
                decl.TypeExpr.Scope = trait.SubScope;
                decl.TypeExpr       = ResolveTypeNow(decl.TypeExpr, out var type);
                decl.Type           = type;

                var res = trait.SubScope.DefineSymbol(decl);
                if (!res.ok)
                {
                    (string, ILocation)? detail = null;
                    if (res.other != null)
                    {
                        detail = ("Other declaration here:", res.other);
                    }
                    ReportError(decl.Name, $"A symbol with name '{decl.Name.Name}' already exists in current scope", detail);
                }
            }

            foreach (var f in trait.Functions)
            {
                f.Trait      = trait;
                f.Scope      = trait.SubScope;
                f.ConstScope = new Scope($"fn$ {f.Name}", f.Scope);
                f.SubScope   = new Scope($"fn {f.Name}", f.ConstScope);

                InferTypeFuncExpr(f);
                CheckForSelfParam(f);

                switch (f.SelfType)
                {
                case SelfParamType.None:
                case SelfParamType.Value:
                    f.ExcludeFromVTable = true;
                    break;
                }

                foreach (var p in f.Parameters)
                {
                    if (SizeOfTypeDependsOnSelfType(p.Type))
                    {
                        f.ExcludeFromVTable = true;
                    }
                }

                if (SizeOfTypeDependsOnSelfType(f.ReturnType))
                {
                    f.ExcludeFromVTable = true;
                }

                // TODO: for now don't allow default implemenation
                if (f.Body != null)
                {
                    ReportError(f.ParameterLocation, $"Trait functions can't have an implementation");
                }
            }
        }
Example #6
0
 private AstTraitTypeExpr InstantiatePolyTrait(AstTraitTypeExpr decl, List <(CheezType type, object value)> args, ILocation location = null)
Example #7
0
        private AstExpression InferTypeTraitTypeExpr(AstTraitTypeExpr expr)
        {
            if (expr.IsPolyInstance)
            {
            }
            else
            {
                expr.SubScope = new Scope("trait", expr.Scope);
                if (expr.Parent is AstConstantDeclaration c)
                {
                    expr.Name = c.Name.Name;
                }
            }

            // setup scopes and separate members
            foreach (var decl in expr.Declarations)
            {
                decl.Scope = expr.SubScope;

                switch (decl)
                {
                case AstConstantDeclaration con when con.Initializer is AstFuncExpr func:
                    func.Name = con.Name.Name;
                    expr.Functions.Add(func);
                    break;

                case AstConstantDeclaration con:
                    ReportError(con, $"Not supported yet");
                    break;

                case AstVariableDecl mem:
                    expr.Members.Add(new AstTraitMember(mem, false, expr.Members.Count));
                    break;
                }
            }

            if (expr.IsPolymorphic)
            {
                // @todo
                foreach (var p in expr.Parameters)
                {
                    p.Scope          = expr.Scope;
                    p.TypeExpr.Scope = expr.Scope;
                    p.TypeExpr       = ResolveTypeNow(p.TypeExpr, out var t);
                    p.Type           = t;

                    ValidatePolymorphicParameterType(p, p.Type);

                    expr.SubScope.DefineTypeSymbol(p.Name.Name, new PolyType(p.Name.Name, true));
                }

                expr.Type  = CheezType.Type;
                expr.Value = new GenericTraitType(expr);
                return(expr);
            }

            expr.Type  = CheezType.Type;
            expr.Value = new TraitType(expr);
            AddTrait(expr);
            // mTypesRequiredAtRuntimeQueue.Enqueue(expr.TraitType);
            return(expr);
        }