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)); } }
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); }
// private void AddTrait(AstTraitTypeExpr trait) { mAllTraits.Add(trait); mUnresolvedTraits.Enqueue(trait); }
public virtual ReturnType VisitTraitTypeExpr(AstTraitTypeExpr expr, DataType data = default) => default;
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"); } } }
private AstTraitTypeExpr InstantiatePolyTrait(AstTraitTypeExpr decl, List <(CheezType type, object value)> args, ILocation location = null)
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); }