tricu

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

native_source_map_fixture.py (4285B)


      1 #!/usr/bin/env python3
      2 """Focused Haskell-only native nested-map staging/build; no compiler source build."""
      3 import argparse
      4 import json
      5 import os
      6 from pathlib import Path
      7 import re
      8 from research_session import ResearchSession, ROOT
      9 
     10 parser = argparse.ArgumentParser(description=__doc__)
     11 parser.add_argument('tricu', type=Path)
     12 parser.add_argument('generation', type=Path)
     13 parser.add_argument('--directory', type=Path, required=True)
     14 args = parser.parse_args()
     15 generation = args.generation.resolve()
     16 if not json.loads((generation / 'status.json').read_text())['complete']:
     17     raise ValueError('incomplete generation')
     18 session = ResearchSession(args.tricu, args.directory, [], generation / 'build-stable.arboricx')
     19 source_cas = generation / 'cas'
     20 pin = (source_cas / 'cache/source-build/source_map').read_text().split('\t')[2]
     21 manifest = (source_cas / 'objects' / pin[:3] / pin).read_bytes()
     22 from native_library_migration import digest
     23 if digest('arboricx.module-manifest.v1', manifest) != pin:
     24     raise ValueError('corrupt map manifest')
     25 exports = {line.split('\t')[1]: line.split('\t')[3] for line in manifest.decode().splitlines()[1:]}
     26 tree = exports['sourceMapStage']
     27 target = session.store / 'objects' / tree[:3] / tree
     28 target.parent.mkdir(parents=True, exist_ok=True)
     29 if not target.exists(): os.link(source_cas / 'objects' / tree[:3] / tree, target)
     30 bundle = session.root / 'stage.arboricx'
     31 session.run([session.tricu, 'arboricx', 'export', '--store', session.store,
     32              '--target', tree, '--name', 'stage', '--output', bundle])
     33 output, _ = session.run([session.tricu, 'arboricx', 'import', '--store', session.store,
     34                         '--file', bundle])
     35 module = re.search(rb'Created module alias .* -> ([a-f0-9]{64})', output)[1].decode()
     36 overlay = session.root / 'overlay'
     37 map_bytes = (ROOT / 'demos/source-map/map.v1').read_text()
     38 # Stored IO execution expects the io envelope, not a raw native IO action.
     39 io_pin = (source_cas / 'cache/source-build/io').read_text().split('\t')[2]
     40 io_payload = (source_cas / 'objects' / io_pin[:3] / io_pin).read_bytes()
     41 if digest('arboricx.module-manifest.v1', io_payload) != io_pin:
     42     raise ValueError('corrupt io manifest')
     43 for pin in {io_pin, *[line.split('\t')[3] for line in io_payload.decode().splitlines()[1:]]}:
     44     target = session.store / 'objects' / pin[:3] / pin
     45     target.parent.mkdir(parents=True, exist_ok=True)
     46     if not target.exists(): os.link(source_cas / 'objects' / pin[:3] / pin, target)
     47 driver = session.workspace / 'stage_driver.tri'
     48 driver.write_text(f'!import {module} as M\n!import {io_pin} as I\n!export main\n'
     49     'main source overlay cas text = I.io (M.stage source overlay cas text)\n')
     50 driver_bundle = session.root / 'stage-driver.arboricx'
     51 session.compile(driver, ['main'], driver_bundle)
     52 output, _ = session.run([session.tricu, 'arboricx', 'import', '--store', session.store,
     53                         '--file', driver_bundle, '--indexed'])
     54 module = re.search(rb'Created module alias .* -> ([a-f0-9]{64})', output)[1].decode()
     55 session.run([session.tricu, 'arboricx', 'run', '--store', session.store, '--module', module,
     56     '--name', 'main', '--arg', str(ROOT), '--arg', str(overlay), '--arg', str(session.store),
     57     '--arg', map_bytes, '--io', '--unsafe-io', '--format', 'decode'])
     58 for name, path in [('base', 'demos/source-map/base.tri'),
     59                    ('prelude', 'demos/source-map/nested/prelude.tri'),
     60                    ('app', 'demos/source-map/nested/app.tri')]:
     61     staged = (overlay / (name + '.tri')).read_bytes()
     62     assert staged == (ROOT / path).read_bytes(), (name, 'native staging changed bytes')
     63     (session.workspace / (name + '.tri')).write_bytes(staged)
     64 app = session.root / 'app.arboricx'
     65 session.compile(session.workspace / 'app.tri', ['main'], app)
     66 output, _ = session.run([session.tricu, 'arboricx', 'import', '--store', session.store,
     67                         '--file', app, '--indexed'])
     68 module = re.search(rb'Created module alias .* -> ([a-f0-9]{64})', output)[1].decode()
     69 output, _ = session.run([session.tricu, 'arboricx', 'run', '--store', session.store,
     70                         '--module', module, '--name', 'main', '--format', 'number'])
     71 assert output == b'42', output
     72 print('Native nested map: exact staging bytes; portable main = 42; Haskell only')