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; } }
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)); }
private bool IsPureBinding(DPattern node) { foreach (var n in node.ListElements()) { if (n.NodeType != NodeType.NamePattern && n.NodeType != NodeType.WildcardPattern) { return(false); } } return(true); }
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); } } }
//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; } }
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(); } }
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; } }
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(); }