source_equation_cases.py (7884B)
1 """Independent source/diagnostic expectations shared by compiler entrypoint tests.""" 2 import json 3 4 def quoted(value): 5 return json.dumps(value, ensure_ascii=False) 6 7 8 def position(source, needle, occurrence=1, shift=0): 9 offset = -1 10 for _ in range(occurrence): 11 offset = source.index(needle, offset + 1) 12 offset += shift 13 line = source[:offset].count("\n") + 1 14 column = offset - source.rfind("\n", 0, offset) 15 return f"(pair {line} (pair {column} {offset}))" 16 17 18 cases = [] 19 20 21 def good(name, source, value, environment="[]"): 22 cases.append((name, source, f"(ok {value} t)", environment, True)) 23 24 25 def bad(name, source, code, expected, found, needle=None, occurrence=1, shift=0): 26 location = position(source, needle, occurrence, shift) if needle else "t" 27 cases.append((name, source, 28 f"(err (parserDiagnostic {code} {expected} {found} {location} t) t)", 29 "[]", True)) 30 31 32 good("Leaf", "f t = 23\nf _ = 24\nmain = f t", "23") 33 good("Stem", "f (t x) = x\nf _ = 24\nmain = f (t 23)", "23") 34 good("Fork", "f (t x y) = [x y]\nf _ = []\nmain = f (t 23 24)", "[23 24]") 35 good("Pair", "f (x, y) = [y x]\nf _ = []\nmain = f (t 23 24)", "[24 23]") 36 good("Whole", "f all{x, y} = all\nf _ = t\nmain = f (t 23 24)", "(t 23 24)") 37 good("WholeSpace", "f all {t x} = all\nf _ = t\nmain = f (t 23)", "(t 23)") 38 good("NestedWhole", "f outer{t inner{t x} y} = [outer inner x y]\nf _ = []\nmain = f (t (t 23) 24)", "[(t (t 23) 24) (t 23) 23 24]") 39 good("NestedSibling", "f ((t (t x)), (y, z)) = [x y z]\nf _ = []\nmain = f (t (t (t 23)) (t 24 25))", "[23 24 25]") 40 good("Nil", "f [] = 23\nf _ = 24\nmain = f []", "23") 41 good("Cons", "f [x | xs] = [x xs]\nf _ = []\nmain = f [23 24]", "[23 [24]]") 42 good("ExactList", "f [x y] = [y x]\nf _ = []\nmain = f [23 24]", "[24 23]") 43 good("ListMiss", "f [x y] = 23\nf _ = 24\nmain = f [23 24 25]", "24") 44 good("WholeList", "f all{[x | xs]} = [all x xs]\nf _ = []\nmain = f [23 24]", "[[23 24] 23 [24]]") 45 good("WholeWildcard", "f all{_} = all\nmain = f 23", "23") 46 good("Number", "f 23 = 24\nf _ = 25\nmain = f 23", "24") 47 good("String", 'f "a\\nb" = 24\nf _ = 25\nmain = f "a\\nb"', "24") 48 good("False", "f t = 23\nf (t t) = 24\nf _ = 25\nmain = f t", "23") 49 good("True", "f t = 23\nf (t t) = 24\nf _ = 25\nmain = f (t t)", "24") 50 good("InvalidBoolStem", "f t = 23\nf (t t) = 24\nf _ = 25\nmain = f (t 23)", "25") 51 good("InvalidBoolFork", "f t = 23\nf (t t) = 24\nf _ = 25\nmain = f (t t t)", "25") 52 good("TwoArgs", "f t child = child\nf _ _ = 24\nmain = f t 23", "23") 53 good("Partial", "f t x = x\nf _ _ = 24\npartial = f t\nmain = partial 23", "23") 54 good("Closure", "f (t x) = y : [x y]\nf _ = y : [t y]\nmain = f (t 23) 24", "[23 24]") 55 good("CaptureShadow", "x = 99\nf x = x\nmain = f 23", "23") 56 good("FailedCapture", "f (x, t) = x\nf _ = 24\nmain = f (t 23 99)", "24") 57 good("Ordered", "f x = 23\nf t = 24\nf _ = 25\nmain = f t", "23") 58 good("BodyNoFallthrough", 'f t = err "body" t\nf _ = 24\nmain = f t', '(err "body" t)', '[(pair "err" err)]') 59 good("PinForward", "f ^expected = 23\nf _ = 24\nexpected = 25\nmain = f 25", "23") 60 good("PinMiss", "expected = 25\nf ^expected = 23\nf _ = 24\nmain = f 26", "24") 61 good("QualifiedPin", "f ^Outer.value = 23\nf _ = 24\nmain = f 25", "23", '[(pair "Outer.value" 25)]') 62 good("LocalLet", "main = let\n f t = 23\n f _ = 24\n g x = f x\nin g t", "23") 63 good("LocalWhere", "main = g t where\n f t = 23\n f _ = 24\n g x = f x", "23") 64 good("LocalPin", "main = let expected = 25 in let\n f ^expected = 23\n f _ = 24\nin f expected", "23") 65 good("LocalClosure", "main = (outer : let\n f (t x) = y : [outer x y]\n f _ = y : [outer t y]\nin f (t 23) 24) 25", "[25 23 24]") 66 good("InlineLet", "main = let f x = x in f 23", "23") 67 good("InlineWhere", "main = f 23 where f x = x", "23") 68 good("CommentGroup", "f t = 23\n-- same group\n\nf _ = 24\nmain = f t", "23") 69 good("BlockComment", "f t = 23\n|-same group-|\nf _ = 24\nmain = f t", "23") 70 good("DeeperBody", "f t = (x : x)\n 23\nf _ = 24\nmain = f t", "23") 71 good("NestedLet", "main = let\n f t = let\n g t = 23\n g _ = 24\n in g t\n f _ = 25\nin f t", "23") 72 good("LocalOuterShadow", "f x = 23\nmain = let f x = f x in f t", "23") 73 good("LocalEarlierPin", "main = let\n expected = 25\n f ^expected = 23\n f _ = 24\nin f 25", "23") 74 good("PatternBodyDependency", "f (t x) = helper x\nf _ = 24\nmain = f (t 23)\nhelper x = x", "23") 75 76 good("ZeroIsLeaf", "f 0 = 23\nf _ = 24\nmain = f t", "23") 77 good("MultilineTreePattern", "f (t\n x\n y) = [x y]\nf _ = []\nmain = f (t 23 24)", "[23 24]") 78 good("MultilinePairPattern", "f (x\n ,\n y) = [x y]\nf _ = []\nmain = f (t 23 24)", "[23 24]") 79 good("NestedPinScope", "f (t x) = let\n g ^x = 23\n g _ = 24\nin g x\nf _ = 25\nmain = f (t 26)", "23") 80 81 worker = ("worker self t = 0\nworker self (t x) = 0\n" 82 "worker self whole{x, y} = self whole\nworker _ _ = 0\n" 83 "loop input = y worker input\n") 84 good("LazyLater", worker + "f t = 23\nf x = loop x\nmain = f t", "23", '[(pair "y" y)]') 85 good("LazyEarlier", worker + "f (t x y) = loop (t x y)\nf _ = 23\nmain = f t", "23", '[(pair "y" y)]') 86 good("UnreachedPin", worker + "main = (outer : let expected = loop outer in let\n f t ^expected = 24\n f _ _ = 23\nin f (t 99) t) (t 23 24)", "23", '[(pair "y" y)]') 87 88 bad("DuplicateCapture", "f x x = x\nmain = f t t", 48, '"unique capture"', '"x"', "x", 2) 89 bad("WholeDuplicate", "f x{x} = x\nmain = f t", 48, '"unique capture"', '"x"', "x", 2) 90 bad("PinCollision", "x = 25\nf x ^x = x\nf _ _ = t\nmain = f t t", 48, '"pin outside equation captures"', '"x"', "^x", shift=1) 91 bad("PinLaterCapture", "x = 25\nf ^x x = x\nf _ _ = t\nmain = f t t", 48, '"pin outside equation captures"', '"x"', "^x", shift=1) 92 bad("Catchall", "f t = 23\nmain = f t", 48, '"final irrefutable equation"', "t", "23") 93 bad("Arity", "f t x = x\nf _ = 23\nmain = t", 48, '"consistent arity"', "1", "23") 94 bad("Redefinition", "f t = 23\nf _ = 24\ng x = x\nf _ = 25\nmain = t", 30, '"f"', '"f"', "f _", 2) 95 bad("ZeroArity", "f = 23\nf = 24\nmain = t", 30, '"f"', '"f"', "f =", 2) 96 bad("LocalRedefinition", "main = let\n f x = x\n g x = x\n f x = x\nin t", 30, '"f"', '"f"', "f x", 2) 97 bad("LocalForward", "main = let\n f x = g x\n g x = x\nin f t", 20, '"g"', "t", "g x") 98 bad("LocalSelf", "main = let\n f x = f x\nin f t", 20, '"f"', "t", "f x", 2) 99 bad("MissingPin", "f ^missing = 23\nf _ = 24\nmain = f t", 20, '"missing"', "t", "missing") 100 bad("EmptyWhole", "f all{} = 23\nf _ = 24\nmain = t", 48, '"pattern"', "23", "}") 101 bad("TooManyChildren", "f (t x y z) = 23\nf _ = 24\nmain = t", 48, '"at most two tree children"', "4", ")") 102 bad("EmptyPrefix", "f [|tail] = 23\nf _ = 24\nmain = t", 48, '"nonempty list prefix"', "11", "=") 103 bad("WildcardNoCapture", "f _ = _\nmain = f t", 20, '"_"', "t", "_", 2) 104 bad("LetIndent", "main = let\nf x = x\nin f t", 40, '"indented local block"', "2", "f x") 105 bad("WhereIndent", "main = f t where\nf x = x", 40, '"indented local block"', "2", "f x") 106 bad("AnnotatedGroup", "f x@missing = x\nf y = y\nmain = t", 30, '"f"', '"f"', "f y") 107 bad("DuplicateBeforeMissing", "f x x = missing\nmain = t", 48, '"unique capture"', '"x"', "x", 2) 108 bad("ArityBeforeMissing", "f t x = missing\nf _ = t\nmain = t", 48, '"consistent arity"', "1", "f _ = t", shift=6) 109 bad("CatchallBeforeMissing", "f t = missing\nmain = t", 48, '"final irrefutable equation"', "t", "missing") 110 bad("LocalDuplicateBeforeMissing", "main = let\n f x x = missing\nin t", 48, '"unique capture"', '"x"', "x", 2) 111 # The source syntax really checks values and original locations, rather than 112 # merely succeeding for everything. Both controls must return false. 113 cases.append(("WrongValue", cases[0][1], "(ok 99 t)", "[]", False)) 114 missing = "f ^missing = 23\nf _ = 24\nmain = f t" 115 cases.append(("WrongLocation", missing, 116 '(err (parserDiagnostic 20 "missing" t (pair 1 (pair 5 4)) t) t)', "[]", False))