Beispiel #1
0
        private void BuildRangeElement(DPattern node, Hints hints)
        {
            switch (node.NodeType)
            {
            case NodeType.IntegerPattern:
                cw.Push(((DIntegerPattern)node).Value);
                break;

            case NodeType.FloatPattern:
                cw.Push(((DFloatPattern)node).Value);
                break;

            case NodeType.BooleanPattern:
                cw.Push(((DBooleanPattern)node).Value);
                break;

            case NodeType.CharPattern:
                cw.Push(((DCharPattern)node).Value);
                break;

            case NodeType.StringPattern:
                cw.Push(((DStringPattern)node).Value.Value);
                break;

            case NodeType.NilPattern:
                cw.PushNil();
                break;

            default:
                AddError(CompilerError.PatternNotSupported, node.Location, node);
                break;
            }
        }
Beispiel #2
0
 private bool IsIrrefutable(DPattern node)
 {
     return(node.NodeType == NodeType.NamePattern ||
            node.NodeType == NodeType.WildcardPattern ||
            node is DAsPattern pas && IsIrrefutable(pas.Pattern) ||
            node is DAndPattern dand && IsIrrefutable(dand.Left) && IsIrrefutable(dand.Right) ||
            node is DOrPattern dor && IsIrrefutable(dor.Left) && IsIrrefutable(dor.Right));
 }
Beispiel #3
0
 private bool IsPureBinding(DPattern node)
 {
     foreach (var n in node.ListElements())
     {
         if (n.NodeType != NodeType.NamePattern && n.NodeType != NodeType.WildcardPattern)
         {
             return(false);
         }
     }
     return(true);
 }
Beispiel #4
0
        private void CheckPattern(DPattern e, int matchCount, int patternCount)
        {
            int c;

            if (matchCount > -1 && (c = e.GetElementCount()) > -1)
            {
                if (e.NodeType == NodeType.TuplePattern && matchCount != c)
                {
                    AddWarning(CompilerWarning.PatternNeverMatch, e.Location, e);
                }
                if (e.NodeType == NodeType.ArrayPattern && matchCount < c)
                {
                    AddWarning(CompilerWarning.PatternNeverMatch, e.Location, e);
                }
            }
        }
Beispiel #5
0
    //Main compilation switch with all patterns
    private void BuildPattern(DPattern node, Hints hints, CompilerContext ctx)
    {
        switch (node.NodeType)
        {
        case NodeType.NotPattern:
            var pt = ((DNotPattern)node).Pattern;
            PreinitPattern(pt, hints);
            BuildPattern(pt, hints, ctx);
            cw.Not();
            break;

        case NodeType.NamePattern:
            BuildName((DNamePattern)node, hints, ctx);
            break;

        case NodeType.IntegerPattern:
            cw.Push(((DIntegerPattern)node).Value);
            cw.Eq();
            break;

        case NodeType.StringPattern:
            Build(((DStringPattern)node).Value, Push, ctx);
            cw.Eq();
            break;

        case NodeType.FloatPattern:
            cw.Push(((DFloatPattern)node).Value);
            cw.Eq();
            break;

        case NodeType.CharPattern:
            cw.Push(((DCharPattern)node).Value);
            cw.Eq();
            break;

        case NodeType.BooleanPattern:
            cw.Push(((DBooleanPattern)node).Value);
            cw.Eq();
            break;

        case NodeType.TuplePattern:
            BuildSequence(node, ((DTuplePattern)node).Elements, hints, ctx);
            break;

        case NodeType.ArrayPattern:
            BuildSequence(node, ((DArrayPattern)node).Elements, hints, ctx);
            break;

        case NodeType.NilPattern:
            cw.PushNil();
            cw.Eq();
            break;

        case NodeType.RangePattern:
            BuildRange(ctx, (DRangePattern)node);
            break;

        case NodeType.WildcardPattern:
            cw.Pop();
            cw.Push(true);
            break;

        case NodeType.AsPattern:
            BuildAs((DAsPattern)node, hints, ctx);
            break;

        case NodeType.TypeTestPattern:
            PushTypeInfo(ctx, ((DTypeTestPattern)node).TypeName, node.Location);
            cw.TypeCheck();
            break;

        case NodeType.AndPattern:
            BuildAnd((DAndPattern)node, hints, ctx);
            break;

        case NodeType.OrPattern:
            BuildOr((DOrPattern)node, hints, ctx);
            break;

        case NodeType.MethodCheckPattern:
            BuildMethodCheck((DMethodCheckPattern)node);
            break;

        case NodeType.CtorPattern:
            BuildCtor((DCtorPattern)node, hints, ctx);
            break;

        case NodeType.LabelPattern:
            BuildLabel((DLabelPattern)node, hints, ctx);
            break;

        case NodeType.ComparisonPattern:
            BuildComparisonPattern((DComparisonPattern)node, hints, ctx);
            break;
        }
    }
Beispiel #6
0
        private bool CanFollow(DPattern now, DPattern prev)
        {
            switch (prev.NodeType)
            {
            case NodeType.NamePattern:
            {
                var nm = (DNamePattern)prev;
                if (!nm.IsConstructor)
                {
                    return(false);
                }
                if (now.NodeType == NodeType.NamePattern)
                {
                    var nmn = (DNamePattern)now;
                    return(!nmn.IsConstructor || nmn.Name != nm.Name);
                }
                return(true);
            }

            case NodeType.WildcardPattern: return(false);

            case NodeType.AsPattern:
                return(CanFollow(now, ((DAsPattern)prev).Pattern));

            case NodeType.TuplePattern:
            case NodeType.ArrayPattern:
            {
                var prevSeq = (DSequencePattern)prev;

                if (now.NodeType == NodeType.TuplePattern || now.NodeType == NodeType.ArrayPattern)
                {
                    var nowTuple = (DSequencePattern)now;

                    if (nowTuple.Elements.Count != prevSeq.Elements.Count)
                    {
                        return(true);
                    }

                    return(CanFollow(nowTuple.Elements, prevSeq.Elements));
                }
                else if (now.NodeType == NodeType.StringPattern)
                {
                    var str = (DStringPattern)now;

                    if ((prevSeq.NodeType == NodeType.TuplePattern && prevSeq.Elements.Count != str.Value.Value.Length) ||
                        (prevSeq.NodeType == NodeType.ArrayPattern && prevSeq.Elements.Count > str.Value.Value.Length))
                    {
                        return(true);
                    }

                    return(CanFollow(str, prevSeq));
                }
                else
                {
                    return(true);
                }
            }

            case NodeType.LabelPattern:
            {
                if (now.NodeType != NodeType.LabelPattern)
                {
                    return(true);
                }
                return(((DLabelPattern)prev).Label != ((DLabelPattern)now).Label ||
                       CanFollow(((DLabelPattern)now).Pattern, ((DLabelPattern)prev).Pattern));
            }

            case NodeType.OrPattern:
            {
                if (now.NodeType != NodeType.OrPattern)
                {
                    return(true);
                }
                var andNow  = (DOrPattern)now;
                var andPrev = (DOrPattern)prev;
                return(CanFollow(andNow.Left, andPrev.Left) && CanFollow(andNow.Right, andPrev.Right));
            }

            case NodeType.AndPattern:
            {
                if (now.NodeType != NodeType.AndPattern)
                {
                    return(true);
                }
                var andNow  = (DAndPattern)now;
                var andPrev = (DAndPattern)prev;
                return(CanFollow(andNow.Left, andPrev.Left) && CanFollow(andNow.Right, andPrev.Right));
            }

            case NodeType.RangePattern:
            {
                if (now.NodeType != NodeType.RangePattern)
                {
                    return(true);
                }
                var rngNow  = (DRangePattern)now;
                var rngPrev = (DRangePattern)prev;
                return(!rngNow.From.Equals(rngPrev.From) || !rngNow.To.Equals(rngPrev.To));
            }

            case NodeType.NilPattern:
                return(now.NodeType != NodeType.NilPattern);

            case NodeType.StringPattern:
            {
                var prevStr = (DStringPattern)prev;
                if (now.NodeType == NodeType.StringPattern)
                {
                    var str = (DStringPattern)now;
                    return(str.Value.Value != prevStr.Value.Value);
                }
                else if (now.NodeType == NodeType.TuplePattern)
                {
                    var tup = (DTuplePattern)now;
                    if (tup.Elements.Count != prevStr.Value.Value.Length)
                    {
                        return(true);
                    }
                    return(CanFollow(prevStr, tup));
                }
                else if (now.NodeType == NodeType.ArrayPattern)
                {
                    var arr = (DArrayPattern)now;
                    if (arr.Elements.Count > prevStr.Value.Value.Length)
                    {
                        return(true);
                    }
                    return(CanFollow(prevStr, arr));
                }
                else
                {
                    return(true);
                }
            }

            case NodeType.IntegerPattern:
                return(now.NodeType != NodeType.IntegerPattern ||
                       ((DIntegerPattern)now).Value != ((DIntegerPattern)prev).Value);

            case NodeType.FloatPattern:
                return(now.NodeType != NodeType.FloatPattern ||
                       ((DFloatPattern)now).Value != ((DFloatPattern)prev).Value);

            case NodeType.CharPattern:
                return(now.NodeType != NodeType.CharPattern ||
                       ((DCharPattern)now).Value != ((DCharPattern)prev).Value);;

            case NodeType.BooleanPattern:
                return(now.NodeType != NodeType.BooleanPattern ||
                       ((DBooleanPattern)now).Value != ((DBooleanPattern)prev).Value);;

            case NodeType.TypeTestPattern:
            {
                if (now.NodeType != NodeType.TypeTestPattern)
                {
                    return(true);
                }
                return(!((DTypeTestPattern)prev).TypeName.IsPossibleEquality(((DTypeTestPattern)now).TypeName));
            }

            case NodeType.MethodCheckPattern:
            {
                if (now.NodeType != NodeType.MethodCheckPattern)
                {
                    return(true);
                }
                return(((DMethodCheckPattern)prev).Name != ((DMethodCheckPattern)now).Name);
            }

            case NodeType.CtorPattern:
            {
                if (now.NodeType != NodeType.CtorPattern)
                {
                    return(true);
                }

                var prevc = (DCtorPattern)prev;
                var nowc  = (DCtorPattern)now;

                if (prevc.Constructor != nowc.Constructor)
                {
                    return(true);
                }

                if (prevc.Arguments == null || prevc.Arguments.Count == 0)
                {
                    return(false);
                }

                if (prevc.Arguments.Count != nowc.Arguments.Count)
                {
                    return(true);
                }

                for (var i = 0; i < prevc.Arguments.Count; i++)
                {
                    if (CanFollow((DPattern)nowc.Arguments[i], (DPattern)prevc.Arguments[i]))
                    {
                        return(true);
                    }
                }

                return(false);
            }

            default: throw Ice();
            }
        }
Beispiel #7
0
        private void PreinitPattern(DPattern node, Hints hints)
        {
            switch (node.NodeType)
            {
            case NodeType.NamePattern:
                PreinitName((DNamePattern)node, hints);
                break;

            case NodeType.IntegerPattern:
                break;

            case NodeType.StringPattern:
                break;

            case NodeType.FloatPattern:
                break;

            case NodeType.CharPattern:
                break;

            case NodeType.BooleanPattern:
                break;

            case NodeType.TuplePattern:
                PreinitSequence(((DTuplePattern)node).Elements, hints);
                break;

            case NodeType.ArrayPattern:
                PreinitSequence(((DArrayPattern)node).Elements, hints);
                break;

            case NodeType.NilPattern:
                break;

            case NodeType.RangePattern:
                break;

            case NodeType.WildcardPattern:
                break;

            case NodeType.AsPattern:
                PreinitAs((DAsPattern)node, hints);
                break;

            case NodeType.TypeTestPattern:
                break;

            case NodeType.AndPattern:
                PreinitAnd((DAndPattern)node, hints);
                break;

            case NodeType.OrPattern:
                PreinitOr((DOrPattern)node, hints);
                break;

            case NodeType.MethodCheckPattern:
                break;

            case NodeType.CtorPattern:
                PreinitCtor((DCtorPattern)node, hints);
                break;

            case NodeType.LabelPattern:
                PreinitLabel((DLabelPattern)node, hints);
                break;
            }
        }
Beispiel #8
0
        private void BuildSequence(DPattern node, List <DNode> elements, Hints hints, CompilerContext ctx)
        {
            var onlyLabels = true;

            for (var i = 0; i < elements.Count; i++)
            {
                if (elements[i].NodeType != NodeType.LabelPattern)
                {
                    onlyLabels = false;
                    break;
                }
            }

            var skip = cw.DefineLabel();
            var ok   = cw.DefineLabel();

            if (!onlyLabels)
            {
                cw.Dup();         //2 objs
                cw.HasMember(GetMemberNameId(Builtins.Len));
                cw.Brfalse(skip); //1 obj left to pop
            }

            cw.Dup();         //2 objs
            cw.HasMember(GetMemberNameId(Builtins.Get));
            cw.Brfalse(skip); //1 obj left to pop

            if (!onlyLabels)
            {
                cw.Dup(); //2 objs
                cw.Len();
                cw.Push(elements.Count);
                if (node.NodeType == NodeType.TuplePattern || node.NodeType == NodeType.CtorPattern)
                {
                    cw.Eq();
                }
                else
                {
                    cw.GtEq();
                }
                cw.Brfalse(skip); //1 obj left to pop
            }

            for (var i = 0; i < elements.Count; i++)
            {
                cw.Dup(); //2 objs
                var e = elements[i];

                if (e.NodeType == NodeType.LabelPattern)
                {
                    BuildLabel((DLabelPattern)e, hints, ctx);
                }
                else
                {
                    cw.Get(i);
                    BuildPattern((DPattern)e, hints, ctx);
                }

                cw.Brfalse(skip); //1 obj left to pop
            }

            cw.Pop(); //0 objs
            cw.Push(true);
            cw.Br(ok);
            cw.MarkLabel(skip);
            cw.Pop(); //0 objs
            cw.Push(false);
            cw.MarkLabel(ok);
            cw.Nop();
        }