コード例 #1
0
        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);
        }
コード例 #2
0
ファイル: TypeInfo.cs プロジェクト: vorov2/dyalect
 public TypeInfo(DTypeDeclaration dec, UnitInfo unit) => (Declaration, Unit) = (dec, unit);
コード例 #3
0
ファイル: Builder.Types.cs プロジェクト: vorov2/dyalect
    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);
    }