Esempio n. 1
0
        private IEnumerable <AstConstantDeclaration> SplitConstantDeclaration(AstConstantDeclaration v)
        {
            v.Pattern.SetFlag(ExprFlags.IsDeclarationPattern, true);
            switch (v.Pattern)
            {
            case AstCompCallExpr cc when cc.Name.Name == "id":
                cc.AttachTo(v);
                v.Name = InferType(cc, null) as AstIdExpr;
                break;

            case AstIdExpr name:
                // ok, do nothing
                v.Name = name;
                break;

            case AstTupleExpr t:
                v.Name = new AstIdExpr(GetUniqueName(t.ToString()), false, t);

                // create new declarations for sub patterns
                var index = 0;
                foreach (var subPattern in t.Values)
                {
                    var init = new AstArrayAccessExpr(
                        new AstConstantRef(v, v.Initializer),
                        new AstNumberExpr(NumberData.FromBigInt(index), Location: v.Initializer));
                    var sub = new AstConstantDeclaration(subPattern, null, init, v.Documentation, null, Location: v);
                    sub.Scope = v.Scope;
                    sub.SetFlags(v.GetFlags());

                    yield return(sub);

                    index += 1;
                }

                v.Pattern = v.Name;
                break;

            default:
                ReportError(v.Pattern, $"Invalid pattern in variable declaration");
                break;
            }
        }
Esempio n. 2
0
        private IEnumerable <AstVariableDecl> SplitVariableDeclaration(AstVariableDecl v)
        {
            v.Pattern.SetFlag(ExprFlags.IsDeclarationPattern, true);
            switch (v.Pattern)
            {
            case AstCompCallExpr cc when cc.Name.Name == "id":
                cc.AttachTo(v);
                v.Name = InferType(cc, null) as AstIdExpr;
                break;

            case AstIdExpr name:
                // ok, do nothing
                v.Name = name;
                break;

            case AstTupleExpr t:
            {
                v.Name    = new AstIdExpr(GetUniqueName(t.ToString()), false, t);
                v.Pattern = v.Name;

                //var initClone = v.Initializer.Clone();
                //initClone.AttachTo(v);
                //initClone.SetFlag(ExprFlags.ValueRequired, true);
                //initClone = InferType(initClone, null);

                //AstVariableDecl CreateSub(int index, string name)
                //{
                //    var init = mCompiler.ParseExpression(
                //        $"@{name}(§init)",
                //        new Dictionary<string, AstExpression>
                //        {
                //                { "init", new AstVariableRef(v, v.Initializer) }
                //        });
                //    var sub = new AstVariableDecl(t.Values[index], null, init, Location: v);
                //    sub.Scope = v.Scope;
                //    sub.SetFlags(v.GetFlags());
                //    return sub;
                //}
                //if (initClone.Type is PointerType pt1 && pt1.TargetType is AnyType)
                //{
                //    // create new declarations for sub patterns
                //    yield return CreateSub(0, "ptr_of_any");
                //    yield return CreateSub(1, "type_info_of_any");
                //    break;
                //}
                //else if (initClone.Type is PointerType pt2 && pt2.TargetType is TraitType)
                //{
                //    // create new declarations for sub patterns
                //    yield return CreateSub(0, "ptr_of_trait");
                //    yield return CreateSub(1, "vtable_of_trait");
                //    break;
                //}
                //else
                //{
                // create new declarations for sub patterns
                var index = 0;
                foreach (var subPattern in t.Values)
                {
                    var init = new AstArrayAccessExpr(
                        new AstVariableRef(v, v.Initializer),
                        new AstNumberExpr(NumberData.FromBigInt(index), Location: v.Initializer));
                    var sub = new AstVariableDecl(subPattern, null, init, v.Mutable, v.Documentation, Location: v);
                    sub.Scope = v.Scope;
                    sub.SetFlags(v.GetFlags());

                    yield return(sub);

                    index += 1;
                }
                break;
                //}
            }

            default:
                ReportError(v.Pattern, $"Invalid pattern in variable declaration");
                break;
            }
        }
Esempio n. 3
0
        private void ComputeEnumMembers(AstEnumTypeExpr expr)
        {
            if (expr.MembersComputed)
            {
                return;
            }
            expr.MembersComputed = true;

            BigInteger value      = 0;
            var        usedValues = new Dictionary <BigInteger, AstEnumMemberNew>();

            foreach (var mem in expr.Members)
            {
                var memDecl = mem.Decl;

                if (!(memDecl.Pattern is AstIdExpr memName))
                {
                    ReportError(memDecl.Pattern, $"Only single names allowed");
                    continue;
                }

                if (memDecl.Directives != null)
                {
                    foreach (var dir in memDecl.Directives)
                    {
                        InferTypeAttributeDirective(dir, memDecl, memDecl.Scope);
                    }
                }

                if (memDecl.TypeExpr != null)
                {
                    memDecl.TypeExpr.AttachTo(memDecl);
                    memDecl.TypeExpr = ResolveTypeNow(memDecl.TypeExpr, out var t);
                    memDecl.Type     = t;

                    // @todo: check if type is valid as enum member, eg no void
                }

                if (memDecl.Initializer != null)
                {
                    memDecl.Initializer.AttachTo(memDecl);
                    memDecl.Initializer = InferType(memDecl.Initializer, expr.TagType);
                    ConvertLiteralTypeToDefaultType(memDecl.Initializer, expr.TagType);
                    memDecl.Initializer = CheckType(memDecl.Initializer, expr.TagType);

                    if (memDecl.Initializer.Type is IntType i)
                    {
                        if (memDecl.Initializer.IsCompTimeValue)
                        {
                            value = ((NumberData)memDecl.Initializer.Value).IntValue;
                            CheckValueRangeForType(i, memDecl.Initializer.Value, memDecl.Initializer);
                        }
                        else
                        {
                            ReportError(memDecl.Initializer, $"Value of enum member has to be an constant integer");
                        }
                    }
                }

                if (!expr.IsPolymorphic && expr.EnumType.IsCopy && (!memDecl.Type?.IsCopy ?? false))
                {
                    ReportError(memDecl, "Member is not copyable");
                }

                if (usedValues.TryGetValue(value, out var other))
                {
                    if (other.AssociatedType != mem.AssociatedType)
                    {
                        ReportError(memDecl,
                                    $"Member has value {value} which is already being used by another member with different type",
                                    ("Other member here:", other.Location));
                    }
                }
                else
                {
                    usedValues.Add(value, mem);
                }

                if (memDecl.Type != null)
                {
                    ComputeTypeMembers(memDecl.Type);
                }

                if (expr.IsFlags && memDecl.Initializer == null && value != 0 && !value.IsPowerOfTwo())
                {
                    ReportError(memDecl, $"Member would have a value of '{value}', but this is not a power of two, so please provide a custom value for this member");
                }
                mem.Value = NumberData.FromBigInt(value);

                if (expr.IsFlags)
                {
                    if (value == 0)
                    {
                        value += 1;
                    }
                    else if (value.IsPowerOfTwo())
                    {
                        value *= 2;
                    }
                }
                else
                {
                    value += 1;
                }
            }

            if (expr.IsReprC)
            {
                foreach (var mem in expr.Members)
                {
                    if (mem.AssociatedType != null)
                    {
                        ReportError(mem.Location, $"Member can't have an associated value in repr c enum");
                    }
                }
            }
        }