feat(zig): native Arboricx bundle parser and C ABI
This commit is contained in:
29
src/Main.hs
29
src/Main.hs
@@ -1,6 +1,7 @@
|
||||
module Main where
|
||||
|
||||
import ContentStore (initContentStore, loadEnvironment, resolveExportTarget)
|
||||
import ContentStore (initContentStore, loadEnvironment, loadTerm, resolveExportTarget)
|
||||
import System.Exit (die)
|
||||
import Server (runServer)
|
||||
import Eval (evalTricu, mainResult, result)
|
||||
import FileEval
|
||||
@@ -32,6 +33,7 @@ data TricuArgs
|
||||
| Export { hash :: String, exportNameOpt :: String, outFile :: FilePath, names :: [String] }
|
||||
| Import { inFile :: FilePath }
|
||||
| Serve { host :: String, port :: Int }
|
||||
| ExportDag { target :: String, outFile :: FilePath }
|
||||
deriving (Show, Data, Typeable)
|
||||
|
||||
replMode :: TricuArgs
|
||||
@@ -112,10 +114,21 @@ serveMode = Serve
|
||||
&= explicit
|
||||
&= name "server"
|
||||
|
||||
exportDagMode :: TricuArgs
|
||||
exportDagMode = ExportDag
|
||||
{ target = def &= help "Stored term name or hash to export as a DAG node table."
|
||||
&= name "t" &= typ "NAME_OR_HASH"
|
||||
, outFile = def &= help "Optional output file path. Defaults to stdout."
|
||||
&= name "o" &= typ "FILE"
|
||||
}
|
||||
&= help "Export a term's Merkle DAG as a topologically-sorted node table for host embedding."
|
||||
&= explicit
|
||||
&= name "export-dag"
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
let versionStr = "tricu Evaluator and REPL " ++ showVersion version
|
||||
cmdArgsParsed <- cmdArgs $ modes [replMode, evaluateMode, decodeMode, compileMode, exportMode, importMode, serveMode]
|
||||
cmdArgsParsed <- cmdArgs $ modes [replMode, evaluateMode, decodeMode, compileMode, exportMode, importMode, serveMode, exportDagMode]
|
||||
&= help "tricu: Exploring Tree Calculus"
|
||||
&= program "tricu"
|
||||
&= summary versionStr
|
||||
@@ -191,6 +204,18 @@ main = do
|
||||
putStrLn $ " GET /bundle/name/:name -- convenience endpoint"
|
||||
putStrLn $ " Content-Type: application/vnd.arboricx.bundle"
|
||||
runServer hostStr portNum
|
||||
ExportDag { target = targetName, outFile = dagOutFile } -> do
|
||||
conn <- initContentStore
|
||||
maybeTerm <- loadTerm conn targetName
|
||||
close conn
|
||||
case maybeTerm of
|
||||
Nothing -> die $ "Term not found: " ++ targetName
|
||||
Just term -> do
|
||||
let (rootIdx, nodes) = exportDag term
|
||||
output = unlines $ show rootIdx : map (\(tag, refs) -> unwords (tag : map show refs)) nodes
|
||||
if null dagOutFile
|
||||
then putStr output
|
||||
else writeFile dagOutFile output
|
||||
|
||||
runTricu :: String -> String
|
||||
runTricu = formatT TreeCalculus . runTricuT
|
||||
|
||||
@@ -12,6 +12,7 @@ import System.Console.CmdArgs (Data, Typeable)
|
||||
|
||||
import qualified Data.ByteString as BS
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Set as Set
|
||||
import qualified Data.Text as T
|
||||
|
||||
-- Tree Calculus Types
|
||||
@@ -296,3 +297,41 @@ decodeResult tc =
|
||||
|| n == 9
|
||||
|| n == 10
|
||||
|| n == 13
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- DAG node-table export (for host-language kernel embedding)
|
||||
-- ---------------------------------------------------------------------------
|
||||
|
||||
-- | Export a term's Merkle DAG as a topologically-sorted node table.
|
||||
-- Children appear before parents so all index references are forward.
|
||||
-- Returns (root index, list of (tag, [child_indices])).
|
||||
exportDag :: T -> (Int, [(String, [Int])])
|
||||
exportDag term =
|
||||
let (root, acc, _) = collectDag term [] Set.empty
|
||||
-- acc is in reverse post-order (children first, root last)
|
||||
ordered = reverse acc
|
||||
idxMap = Map.fromList [(h, i) | (i, (h, _)) <- zip [0..] ordered]
|
||||
rootIdx = idxMap Map.! root
|
||||
lines_ = map (formatNode idxMap . snd) ordered
|
||||
in (rootIdx, lines_)
|
||||
where
|
||||
collectDag :: T -> [(MerkleHash, Node)] -> Set.Set MerkleHash -> (MerkleHash, [(MerkleHash, Node)], Set.Set MerkleHash)
|
||||
collectDag Leaf acc seen =
|
||||
let h = nodeHash NLeaf
|
||||
in if Set.member h seen then (h, acc, seen) else (h, (h, NLeaf) : acc, Set.insert h seen)
|
||||
collectDag (Stem t) acc seen =
|
||||
let (ch, acc', seen') = collectDag t acc seen
|
||||
node = NStem ch
|
||||
h = nodeHash node
|
||||
in if Set.member h seen' then (h, acc', seen') else (h, (h, node) : acc', Set.insert h seen')
|
||||
collectDag (Fork l r) acc seen =
|
||||
let (lh, acc', seen') = collectDag l acc seen
|
||||
(rh, acc'', seen'') = collectDag r acc' seen'
|
||||
node = NFork lh rh
|
||||
h = nodeHash node
|
||||
in if Set.member h seen'' then (h, acc'', seen'') else (h, (h, node) : acc'', Set.insert h seen'')
|
||||
|
||||
formatNode :: Map.Map MerkleHash Int -> Node -> (String, [Int])
|
||||
formatNode _ NLeaf = ("leaf", [])
|
||||
formatNode idxMap (NStem ch) = ("stem", [idxMap Map.! ch])
|
||||
formatNode idxMap (NFork l r) = ("fork", [idxMap Map.! l, idxMap Map.! r])
|
||||
|
||||
Reference in New Issue
Block a user