tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

native_source_map_fixture.py (4457B)


      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 shutil
      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 status = json.loads((generation / 'status.json').read_text())
     17 if status.get('produced_io_version', 1) != 2:
     18     parser.error('current probe requires a v2 generation; use its frozen probe/runtime for v1')
     19 if not status['complete']:
     20     raise ValueError('incomplete generation')
     21 session = ResearchSession(args.tricu, args.directory, [], generation / 'build-stable.arboricx')
     22 source_cas = generation / 'cas'
     23 pin = (source_cas / 'cache/source-build/source_map').read_text().split('\t')[2]
     24 manifest = (source_cas / 'objects' / pin[:3] / pin).read_bytes()
     25 from native_library_migration import digest
     26 if digest('arboricx.module-manifest.v1', manifest) != pin:
     27     raise ValueError('corrupt map manifest')
     28 exports = {line.split('\t')[1]: line.split('\t')[3] for line in manifest.decode().splitlines()[1:]}
     29 tree = exports['sourceMapStage']
     30 target = session.store / 'objects' / tree[:3] / tree
     31 target.parent.mkdir(parents=True, exist_ok=True)
     32 if not target.exists(): shutil.copyfile(source_cas / 'objects' / tree[:3] / tree, target)
     33 bundle = session.root / 'stage.arboricx'
     34 session.run([session.tricu, 'arboricx', 'export', '--store', session.store,
     35              '--target', tree, '--name', 'stage', '--output', bundle])
     36 output, _ = session.run([session.tricu, 'arboricx', 'import', '--store', session.store,
     37                         '--file', bundle])
     38 module = re.search(rb'Created module alias .* -> ([a-f0-9]{64})', output)[1].decode()
     39 overlay = session.root / 'overlay'
     40 map_bytes = (ROOT / 'demos/source-map/map.v1').read_text()
     41 # Stored IO execution expects the io envelope, not a raw native IO action.
     42 io_pin = (source_cas / 'cache/source-build/compiler_io').read_text().split('\t')[2]
     43 io_payload = (source_cas / 'objects' / io_pin[:3] / io_pin).read_bytes()
     44 if digest('arboricx.module-manifest.v1', io_payload) != io_pin:
     45     raise ValueError('corrupt io manifest')
     46 for pin in {io_pin, *[line.split('\t')[3] for line in io_payload.decode().splitlines()[1:]]}:
     47     target = session.store / 'objects' / pin[:3] / pin
     48     target.parent.mkdir(parents=True, exist_ok=True)
     49     if not target.exists(): shutil.copyfile(source_cas / 'objects' / pin[:3] / pin, target)
     50 driver = session.workspace / 'stage_driver.tri'
     51 driver.write_text(f'!import {module} as M\n!import {io_pin} as I\n!export main\n'
     52     'main source overlay cas text = I.io (M.stage source overlay cas text)\n')
     53 driver_bundle = session.root / 'stage-driver.arboricx'
     54 session.compile(driver, ['main'], driver_bundle)
     55 output, _ = session.run([session.tricu, 'arboricx', 'import', '--store', session.store,
     56                         '--file', driver_bundle, '--indexed'])
     57 module = re.search(rb'Created module alias .* -> ([a-f0-9]{64})', output)[1].decode()
     58 session.run([session.tricu, 'arboricx', 'run', '--store', session.store, '--module', module,
     59     '--name', 'main', '--arg', str(ROOT), '--arg', str(overlay), '--arg', str(session.store),
     60     '--arg', map_bytes, '--io', '--format', 'decode'])
     61 for name, path in [('base', 'demos/source-map/base.tri'),
     62                    ('prelude', 'demos/source-map/nested/prelude.tri'),
     63                    ('app', 'demos/source-map/nested/app.tri')]:
     64     staged = (overlay / (name + '.tri')).read_bytes()
     65     assert staged == (ROOT / path).read_bytes(), (name, 'native staging changed bytes')
     66     (session.workspace / (name + '.tri')).write_bytes(staged)
     67 app = session.root / 'app.arboricx'
     68 session.compile(session.workspace / 'app.tri', ['main'], app)
     69 output, _ = session.run([session.tricu, 'arboricx', 'import', '--store', session.store,
     70                         '--file', app, '--indexed'])
     71 module = re.search(rb'Created module alias .* -> ([a-f0-9]{64})', output)[1].decode()
     72 output, _ = session.run([session.tricu, 'arboricx', 'run', '--store', session.store,
     73                         '--module', module, '--name', 'main', '--format', 'number'])
     74 assert output == b'42', output
     75 print('Native nested map: exact staging bytes; portable main = 42; Haskell only')