tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

source_lowering_models.py (4992B)


      1 """Independent regression models/cases retained from retired batch workflows.
      2 
      3 Probe templates are test data, not a preparation CLI. Model unit tests do not
      4 validate an edited compiler. No historical Git objects or reference workspaces
      5 are required to import these helpers.
      6 """
      7 from dataclasses import dataclass
      8 
      9 
     10 import json
     11 
     12 
     13 from pathlib import Path
     14 
     15 
     16 import random
     17 
     18 
     19 from source_resolution_models import ROOT, sha, n, LEAF, TRUE, pair, tree_list, result, expect, chars, diagnostic
     20 
     21 
     22 from source_foundations_models import Node
     23 
     24 
     25 from source_order import field
     26 
     27 
     28 DRIVER='''!import prelude as B
     29 !import source_stable as S
     30 !import source_compile as C
     31 !import source_unit as U
     32 !import source_ast as A
     33 !export bracket
     34 !export eliminate
     35 !export run
     36 !export apply
     37 !export assembly
     38 !export demand
     39 !export wrong
     40 bracket rows = B.map S.stableBracket rows
     41 eliminate rows = B.map S.stableEliminate rows
     42 run rows = B.map C.sourceRunTerm rows
     43 apply rows = B.map (row : S.stableTermApply (B.fst row) (B.fst (B.snd row)) (B.snd (B.snd row))) rows
     44 name text = A.sourceAstNode 2 text 7 8
     45 defs = [(B.pair (name "a") 11) (B.pair (name "b") 12)]
     46 assembly _ = U.sourceCompileOrderedWith
     47   (env definition : B.ok (B.pair (B.snd definition) env) 999)
     48   ["b" "a"] defs [(B.pair "b" 99)]
     49 spin x = spin x
     50 demand x = [
     51   (U.sourceCompileOrderedWith (spin x) [] (spin x) (spin x))
     52   (U.sourceModuleCheckShadows [] (spin x))
     53   (U.sourceCompileOrderedWith (_ _ : B.err 77 9)
     54     (B.pair "a" (spin x)) defs (spin x))
     55   (C.sourceRunTerm (C.sourceTermApply
     56     (C.sourceTermVariable 3 7) (spin x) (spin x)))
     57   (C.sourceTermKind (S.stableEliminate (A.sourceAstNode 1 (spin x) 7 (spin x))))
     58   (U.sourceSelectProgram (spin x) (spin x) [(B.pair "main" 23)])]
     59 wrong _ = t
     60 '''
     61 
     62 
     63 K=b'\1\0';I=pair(b'\1'+K,LEAF)
     64 
     65 
     66 K=b'\1\0';I=pair(b'\1'+K,LEAF)
     67 
     68 
     69 @dataclass(frozen=True)
     70 class Term:
     71     kind:int
     72     payload:object=LEAF
     73     location:bytes=n(7)
     74     def tree(self):
     75         p=n(self.payload) if self.kind==2 else pair(*(x.tree() for x in self.payload)) if self.kind==3 else self.payload
     76         return pair(n(self.kind),pair(p,self.location))
     77 
     78 
     79 def app(left,right,location):return Term(3,(left,right),location)
     80 
     81 
     82 def folded(left,right,location):
     83     if left.kind==right.kind==1:
     84         if left.payload==LEAF:return Term(1,b'\1'+right.payload,location)
     85         if left.payload[0]==1:return Term(1,pair(left.payload[1:],right.payload),location)
     86     return app(left,right,location)
     87 
     88 
     89 def bracket(term):
     90     k,p,l=term.kind,term.payload,term.location
     91     if k==1:return folded(Term(1,K,l),term,l)
     92     if k==2:return Term(1,I,l) if p==0 else folded(Term(1,K,l),Term(2,p-1,l),l)
     93     if k==3:
     94         return folded(folded(Term(1,LEAF,l),folded(Term(1,LEAF,l),bracket(p[0]),l),l),bracket(p[1]),l)
     95     return term
     96 
     97 
     98 def eliminate(node):
     99     k,p,l=node.kind,node.payload,node.start
    100     if k==1:return Term(1,LEAF,l)
    101     if k==2:return Term(2,p,l)
    102     if k==3:return folded(eliminate(p[0]),eliminate(p[1]),l)
    103     if k==4:return bracket(eliminate(p))
    104     if k in (5,6,7):return Term(1,p,l)
    105     if k==8:
    106         tail=Term(1,LEAF,l)
    107         for head in reversed(p):tail=app(app(Term(1,LEAF,l),eliminate(head),l),tail,l)
    108         return tail
    109     return Term(4,node.tree(),l)
    110 
    111 
    112 class Bad(Exception):
    113     def __init__(self,result):self.result=result
    114 
    115 
    116 def tc_apply(function,argument):
    117     if function==LEAF:return b'\1'+argument
    118     if function[0]==1:return pair(function[1:],argument)
    119     left,right=field(function,0),field(function,1)
    120     if left==LEAF:return right
    121     if left[0]==1:return tc_apply(tc_apply(left[1:],argument),tc_apply(right,argument))
    122     if argument==LEAF:return field(left,0)
    123     if argument[0]==1:return tc_apply(field(left,1),argument[1:])
    124     return tc_apply(tc_apply(right,field(argument,0)),field(argument,1))
    125 
    126 
    127 def run_result(term):
    128     def go(term):
    129         if term.kind==1:return term.payload
    130         if term.kind==3:return tc_apply(go(term.payload[0]),go(term.payload[1]))
    131         raise Bad(result(False,diagnostic(22 if term.kind==2 else 23,LEAF,n(term.payload if term.kind==2 else term.kind),term.location),term.tree()))
    132     try:return result(True,go(term))
    133     except Bad as bad:return bad.result
    134 
    135 
    136 def specimens():
    137     rng=random.Random(746);serial=0
    138     def term(depth):
    139         nonlocal serial
    140         serial+=1;l=n(serial)
    141         k=rng.choice([1,2,3,4] if depth else [1,2,4])
    142         return Term(k, (term(depth-1),term(depth-1)) if k==3 else rng.randrange(4) if k==2 else rng.choice([LEAF,K,pair(LEAF,LEAF)]),l)
    143     terms=[term(3) for _ in range(120)]
    144     def core(depth):
    145         nonlocal serial
    146         serial+=1;l=n(serial)
    147         k=rng.choice([1,2,3,4,5,6,7,8,99] if depth else [1,2,5,6,7,99])
    148         p=(core(depth-1),core(depth-1)) if k==3 else core(depth-1) if k==4 else [core(depth-1) for _ in range(rng.randrange(3))] if k==8 else rng.randrange(4) if k==2 else rng.choice([LEAF,K,pair(LEAF,LEAF)])
    149         return Node(k,p,l,n(serial+1))
    150     cores=[core(4) for _ in range(120)]
    151     return terms,cores