unit.tri (6351B)
1 !import prelude * 2 !import parser * 3 !import source_order * 4 !import source_compile * 5 !import source_program * 6 !import source_resolve * 7 !import source_ast * 8 !import source_stable * 9 !import source_index * 10 !export * 11 12 -- Build definition bindings in stable dependency order, including unused 13 -- definitions. The reducer may defer normalization of unused body trees. 14 -- Association-list entrypoints extend at the head; both representations resolve 15 -- compiled locals before supplied external bindings. 16 sourceCompileDefinition environment definition = (lazyResult 17 (diagnostic remainder : err diagnostic remainder) 18 (core unused : sourceCompileCore core) 19 (resolveGateAst environment (sourceDefinitionBody definition))) 20 21 -- Both environments use the same ordered traversal and failure protocol. 22 -- The index extends persistently; the list facade retains its original append. 23 sourceCompileOrderedUsing findDefinition compileDefinition extend names external = (let rec 24 walk pending environment compiled = (lazyList 25 (_ : ok compiled t) 26 (name rest : lazyMaybe 27 (_ : err (parserDiagnostic 33 name t t t) name) 28 (definition : lazyResult 29 (diagnostic remainder : err diagnostic remainder) 30 (tree unused : walk rest (extend name tree environment) 31 (pair (pair name tree) compiled)) 32 (compileDefinition environment definition)) 33 (findDefinition name)) pending) 34 in walk names external t) 35 sourceCompileOrderedWith compileDefinition names definitions external = sourceCompileOrderedUsing 36 (sourceFindDefinition definitions) 37 (compiled definition : compileDefinition (append compiled external) definition) 38 (name tree compiled : pair (pair name tree) compiled) names t 39 40 sourceCompileOrdered names definitions external = 41 sourceCompileOrderedWith sourceCompileDefinition names definitions external 42 43 -- Explicit selection: a local `main` wins, otherwise the final expression, 44 -- otherwise a missing-root diagnostic. Definitions are ordered first. 45 sourceSelectProgram external program compiled = 46 lazyMaybe 47 (_ : lazyMaybe 48 (_ : err (parserDiagnostic 32 "main" t t t) t) 49 (expression : 50 lazyResult 51 (diagnostic remainder : err diagnostic remainder) 52 (core unused : sourceCompileCore core) 53 (resolveGateAst (append compiled external) expression)) 54 (sourceProgramFinal program)) 55 (tree : ok tree t) 56 (sourceFindExternal compiled "main") 57 58 -- The reusable single-unit boundary also returns compiled definitions in 59 -- stable dependency order. Values remain raw trees, not compiler-private ASTs. 60 compileGateProgramOutput external characters = 61 parserMatchReply 62 (diagnostic remainder consumed committed : err diagnostic remainder) 63 (program remainder consumed committed : (do stableBind 64 ordered <- orderGateProgram external program 65 compiled <- sourceCompileOrdered ordered (sourceProgramDefinitions program) external 66 root <- sourceSelectProgram external program compiled 67 ok (pair root (reverse compiled)) t)) 68 (parseGateProgram characters) 69 70 -- Public single-unit boundary. Keep the environment explicit: it contains 71 -- already-resolved (name, tree) bindings, not paths or import directives. 72 -- The selected root and dependency-ordered definitions are returned together; 73 -- parsing, ordering and compilation failures retain their structured replies. 74 compileSource environment sourceCharacters = 75 compileGateProgramOutput environment sourceCharacters 76 77 -- Module units have explicit exports, not an implicit `main` or final value. 78 -- This entrypoint shares the ordinary parser, orderer, resolver and reference 79 -- backend, but rejects a final expression instead of requiring a root. 80 sourceModuleCheckShadows imports definitions = (let rec 81 walk remaining = (lazyList 82 (_ : ok t t) 83 (binding rest : lazyMaybe 84 (_ : walk rest) 85 (definition : err 86 (parserDiagnostic 46 (fst binding) (fst binding) 87 (sourceDefinitionPosition definition) t) t) 88 (sourceFindDefinition definitions (fst binding))) remaining) 89 in walk imports) 90 91 compileModuleDefinitionsUsing compileProgram environment characters = 92 parserMatchReply 93 (diagnostic remainder consumed committed : err diagnostic remainder) 94 (program remainder consumed committed : 95 lazyMaybe 96 (_ : (do stableBind 97 sourceModuleCheckShadows environment (sourceProgramDefinitions program) 98 compiled <- compileProgram environment program 99 ok (reverse compiled) t)) 100 (expression : err 101 (parserDiagnostic 42 "definitions only" t 102 (sourceAstStart expression) t) expression) 103 (sourceProgramFinal program)) 104 (parseGateProgram characters) 105 106 compileModuleDefinitionsWith orderProgram compileDefinition = compileModuleDefinitionsUsing 107 (environment program : do stableBind 108 ordered <- orderProgram environment program 109 sourceCompileOrderedWith compileDefinition ordered (sourceProgramDefinitions program) environment) 110 111 -- The native stable path shares one external index between ordering and 112 -- resolution, then inserts each compiled local without inspecting its value. 113 sourceCompileStableModuleProgram environment program = (let external = sourceIndexBuild environment in 114 do stableBind 115 ordered <- orderStableProgramWith 116 (orderGateProgramUsing (sourceAnalyzeIndexedDefinitions external)) environment program 117 sourceCompileOrderedUsing (sourceIndexGet (sourceDefinitionIndex (sourceProgramDefinitions program))) 118 (sourceCompileStableDefinitionWith (resolveStableGateAstWithLookup sourceIndexGet)) 119 sourceIndexPut ordered external) 120 121 -- Backend selection is explicit. Existing entrypoints retain optimized trees. 122 compileModuleDefinitions environment characters = 123 compileModuleDefinitionsWith orderGateProgram sourceCompileDefinition environment characters 124 compileStableModuleDefinitions environment characters = 125 compileModuleDefinitionsUsing sourceCompileStableModuleProgram environment characters 126 127 -- Preserve the established gate API: callers interested only in the root 128 -- do not have to inspect (or force) the compiled definition environment. 129 compileGateProgram external characters = 130 lazyResult 131 (diagnostic remainder : err diagnostic remainder) 132 (output unused : ok (fst output) t) 133 (compileGateProgramOutput external characters) 134