tricu

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

ec97f34c89ead701af75053ea340ead1bb0fda13d83b474ca760c3aa359970fa.tri (8621B)


      1 !import prelude *
      2 !import parser *
      3 !import graph *
      4 !import source_program *
      5 !import source_resolve *
      6 !import source_ast *
      7 !import source_equations *
      8 !import source_index *
      9 !export *
     10 
     11 sourceFindDefinition definitions name = (let rec
     12   find definitions = (lazyList (_ : nothing)
     13     (definition rest : lazyBool (_ : just definition)
     14       (_ : find rest) (equal? (sourceDefinitionName definition) name)) definitions)
     15   in find definitions)
     16 
     17 -- Free-name collection returns located name AST nodes, so a missing-name
     18 -- diagnostic retains the original source position rather than a string key.
     19 sourceFreeList elements visit bound = concatMap (element : visit element bound) elements
     20 
     21 -- Pins see the surrounding scope, never the equation's captures. Keep pins
     22 -- before the body and retain repeated located occurrences in traversal order.
     23 sourceFreeEquations equations visit bound = (concatMap
     24   (equation : append
     25     (sourceFreeList (sourceEquationCollect (fst equation) sourceEquationPins) visit bound)
     26     (visit (snd equation)
     27       (append (reverse (sourceEquationCollect (fst equation) sourceEquationCaptures)) bound)))
     28   equations)
     29 
     30 sourceFreeOrdinary visit node bound = (case sourceAstKind node of
     31   ^sourceAstNameKind = lazyMaybe (_ : [node]) (_ : t)
     32     (sourceFindBinder bound (sourceAstPayload node))
     33   ^sourceAstApplyKind = append (visit (fst (sourceAstPayload node)) bound)
     34     (visit (snd (sourceAstPayload node)) bound)
     35   ^sourceAstLambdaKind = visit (snd (sourceAstPayload node))
     36     (pair (fst (sourceAstPayload node)) bound)
     37   ^sourceAstGroupKind = visit (sourceAstPayload node) bound
     38   ^sourceAstListKind = sourceFreeList (sourceAstPayload node) visit bound
     39   ^sourceAstLetKind = append (visit (sourceAstLetValue node) bound)
     40     (visit (sourceAstLetBody node) (pair (sourceAstLetName node) bound))
     41   ^sourceAstPipeKind = append (visit (sourceAstPipeLeft node) bound)
     42     (visit (sourceAstPipeRight node) bound)
     43   ^sourceAstDoKind = visit (sourceAstDoLower node) bound
     44   ^sourceAstEquationsKind = sourceFreeEquations (sourceAstPayload node) visit bound
     45   _ = t)
     46 
     47 sourceFreeNames node = sourceFreeVisit node t
     48 
     49 sourceCheckDuplicates definitions = (let rec
     50   walk definitions seen = (lazyList
     51       (_ : ok t t)
     52       (definition rest :
     53         lazyMaybe
     54           (_ : walk rest (pair definition seen))
     55           (prior : err
     56             (parserDiagnostic 30 (sourceDefinitionName definition)
     57               (sourceDefinitionName prior)
     58               (sourceDefinitionPosition definition) t)
     59             definition)
     60           (sourceFindDefinition seen (sourceDefinitionName definition)))
     61       definitions)
     62   in walk definitions t)
     63 
     64 sourceCheckNames names definitions environment = (let rec
     65   walk names = (lazyList
     66       (_ : ok t t)
     67       (node rest :
     68         lazyMaybe
     69           (_ : lazyMaybe
     70             (_ : err
     71               (parserDiagnostic 20 (sourceAstPayload node) t
     72                 (sourceAstStart node) t)
     73               node)
     74             (value : walk rest)
     75             (sourceFindExternal environment (sourceAstPayload node)))
     76           (definition : walk rest)
     77           (sourceFindDefinition definitions (sourceAstPayload node)))
     78       names)
     79   in walk names)
     80 
     81 sourceCheckDefinitionNames definitions environment = (let rec
     82   walk pending = (lazyList
     83       (_ : ok t t)
     84       (definition rest :
     85         lazyResult
     86           (diagnostic node : err diagnostic node)
     87           (ignored unused : walk rest)
     88           (lazyResult (diagnostic remainder : err diagnostic remainder)
     89             (_ unused : sourceCheckNames (sourceFreeNames (sourceDefinitionBody definition))
     90               definitions environment)
     91             (sourceEquationValidate (sourceDefinitionBody definition))))
     92       pending)
     93   in walk definitions)
     94 
     95 sourceCheckFinalNames final definitions environment =
     96   lazyMaybe
     97     (_ : ok t t)
     98     (expression : lazyResult (diagnostic remainder : err diagnostic remainder)
     99       (_ unused : sourceCheckNames (sourceFreeNames expression) definitions environment)
    100       (sourceEquationValidate expression))
    101     final
    102 
    103 sourceDependencyNames names definitions = (let rec
    104   walk names = (lazyList
    105       (_ : t)
    106       (node rest :
    107         lazyMaybe
    108           (_ : walk rest)
    109           (definition : pair (sourceAstPayload node) (walk rest))
    110           (sourceFindDefinition definitions (sourceAstPayload node)))
    111       names)
    112   in walk names)
    113 
    114 sourceDefinitionGraph definitions = (map
    115   (definition : pair (sourceDefinitionName definition)
    116     (sourceDependencyNames (sourceFreeNames (sourceDefinitionBody definition)) definitions))
    117   definitions)
    118 
    119 -- Validate each located free name and retain its local edge in the same pass.
    120 -- Do not deduplicate/reorder edges: their order determines cycle witnesses.
    121 -- A local definition wins over an external with the same spelling.
    122 sourceAnalyzeNamesUsing findDefinition findExternal names = (let rec
    123   walk names = (lazyList
    124     (_ : ok t t)
    125     (node rest : lazyMaybe
    126       (_ : lazyMaybe
    127         (_ : err (parserDiagnostic 20 (sourceAstPayload node) t
    128           (sourceAstStart node) t) node)
    129         (_ : walk rest)
    130         (findExternal (sourceAstPayload node)))
    131       (_ : lazyResult
    132         (diagnostic missing : err diagnostic missing)
    133         (dependencies unused : ok (pair (sourceAstPayload node) dependencies) t)
    134         (walk rest))
    135       (findDefinition (sourceAstPayload node))) names)
    136   in walk names)
    137 
    138 -- Equation validation still precedes names in each definition. Only after all
    139 -- definitions succeed may final-expression validation and graph sorting run.
    140 -- The reversed accumulator is constructor-only; reverse once on completion.
    141 sourceAnalyzeDefinitionsUsing findDefinition findExternal definitions = (let rec
    142   walk pending reversed = (lazyList
    143     (_ : ok (reverse reversed) t)
    144     (definition rest : lazyResult
    145       (diagnostic remainder : err diagnostic remainder)
    146       (_ unused : lazyResult
    147         (diagnostic missing : err diagnostic missing)
    148         (dependencies unused : walk rest
    149           (pair (pair (sourceDefinitionName definition) dependencies) reversed))
    150         (sourceAnalyzeNamesUsing findDefinition findExternal (sourceFreeNames (sourceDefinitionBody definition))))
    151       (sourceEquationValidate (sourceDefinitionBody definition))) pending)
    152   in walk definitions t)
    153 
    154 sourceOrderCycle definitions name =
    155   lazyMaybe
    156     (_ : parserDiagnostic 31 "acyclic" name t (pair name t))
    157     (definition : parserDiagnostic 31 "acyclic" name
    158       (sourceDefinitionPosition definition) (pair name t))
    159     (sourceFindDefinition definitions name)
    160 
    161 orderGateProgramUsing analyze environment program = (let definitions = sourceProgramDefinitions program in
    162   let proceed reply next = (lazyResult
    163     (diagnostic rest : err diagnostic rest) (value unused : next value) reply) in
    164   do proceed
    165     sourceCheckDuplicates definitions
    166     graph <- analyze definitions
    167     sourceCheckFinalNames (sourceProgramFinal program) definitions environment
    168     (lazyResult
    169       (cycle unused : err (sourceOrderCycle definitions cycle) t)
    170       (names unused : ok names t)
    171       (graphSort graph)))
    172 
    173 orderGateSource environment characters =
    174   parserMatchReply
    175     (diagnostic rest consumed committed : err diagnostic rest)
    176     (program rest consumed committed : orderGateProgram environment program)
    177     (parseGateProgram characters)
    178 
    179 
    180 sourceFreeVisit node bound = (case sourceAstKind node of
    181   ^sourceAstCaseKind = append
    182     (sourceFreeVisit (sourceAstCaseSubject node) bound)
    183     (sourceFreeVisit (sourceAstCaseMatcher node) bound)
    184   ^sourceAstRecKind = (let nested = pair (sourceAstLetName node) bound in
    185     append (sourceFreeVisit (sourceAstLetValue node) nested)
    186       (sourceFreeVisit (sourceAstLetBody node) nested))
    187   _ = sourceFreeOrdinary sourceFreeVisit node bound)
    188 
    189 sourceAnalyzeNames names definitions environment = sourceAnalyzeNamesUsing
    190   (sourceFindDefinition definitions) (sourceFindExternal environment) names
    191 sourceAnalyzeDefinitions definitions environment = sourceAnalyzeDefinitionsUsing
    192   (sourceFindDefinition definitions) (sourceFindExternal environment) definitions
    193 orderGateProgram environment program = orderGateProgramUsing
    194   (definitions : sourceAnalyzeDefinitions definitions environment) environment program
    195 
    196 -- Values (including definition bodies) are opaque to index construction.
    197 sourceDefinitionIndex definitions = sourceIndexBuild
    198   (map (definition : pair (sourceDefinitionName definition) definition) definitions)
    199 sourceAnalyzeIndexedDefinitions external definitions = sourceAnalyzeDefinitionsUsing
    200   (sourceIndexGet (sourceDefinitionIndex definitions)) (sourceIndexGet external) definitions