private void Build(DTypeDeclaration node, Hints hints, CompilerContext ctx) { var typeId = unit.Types.Count; var unitId = unit.UnitIds.Count - 1; var ti = new TypeInfo(typeId, new UnitInfo(unitId, unit)); if (types.ContainsKey(node.Name)) { types.Remove(node.Name); AddError(CompilerError.TypeAlreadyDeclared, node.Location, node.Name); } types.Add(node.Name, ti); var td = new TypeDescriptor(node.Name, typeId, node.HasConstructors); unit.Types.Add(td); unit.TypeMap.Add(node.Name, td); if (node.HasConstructors) { var nh = hints.Remove(Push).Remove(ExpectPush); foreach (var c in node.Constructors) { Build(c, nh, ctx); } } PushIf(hints); }
public TypeInfo(DTypeDeclaration dec, UnitInfo unit) => (Declaration, Unit) = (dec, unit);
private void Build(DTypeDeclaration node, Hints hints, CompilerContext ctx) { if (!char.IsUpper(node.Name[0])) { AddError(CompilerError.TypeNameCamel, node.Location); } if (currentScope != globalScope) { AddError(CompilerError.TypesOnlyGlobalScope, node.Location); } var unitId = unit.UnitIds.Count - 1; var ti = new TypeInfo(node, new(unitId, unit.ExportList)); var typeVar = 0; if (types.ContainsKey(node.Name)) { types.Remove(node.Name); AddError(CompilerError.TypeAlreadyDeclared, node.Location, node.Name); } else { typeVar = AddVariable(node.Name, node.Location, VarFlags.Type | VarFlags.Const); cw.NewType(node.Name); cw.PopVar(typeVar); } types.Add(node.Name, ti); var nh = hints.Remove(Push); foreach (var c in node.Constructors) { Build(c, nh, ctx); } if (node.Mixins is not null) { var set = new HashSet <int>(); foreach (var m in node.Mixins) { if (m.Parent is null && m.Local == node.Name) { AddError(CompilerError.MixinSameAsType, node.Location, m.ToString()); } cw.PushVar(new ScopeVar(typeVar)); var code = PushTypeInfo(ctx, m, node.Location); if (set.Contains(code)) { AddError(CompilerError.MixinAlreadySpecified, node.Location, m.ToString()); } else { set.Add(code); } if (code < 0 && -code < Dy.Number) { AddError(CompilerError.InvalidMixin, node.Location, m.Local.ToString()); } cw.Mixin(); } } PushIf(hints); }