Files
cell/compare_aot.ce
2026-02-17 03:33:21 -06:00

114 lines
2.8 KiB
Plaintext

// compare_aot.ce — compile a .ce/.cm file via both paths and compare results
//
// Usage:
// cell --dev compare_aot.ce <file.ce>
var build = use('build')
var fd_mod = use('fd')
var os = use('os')
var json = use('json')
var show = function(v) {
if (v == null) return "null"
return json.encode(v)
}
if (length(args) < 1) {
print('usage: cell --dev compare_aot.ce <file>')
return
}
var file = args[0]
if (!fd_mod.is_file(file)) {
if (!ends_with(file, '.ce') && fd_mod.is_file(file + '.ce'))
file = file + '.ce'
else if (!ends_with(file, '.cm') && fd_mod.is_file(file + '.cm'))
file = file + '.cm'
else {
print('file not found: ' + file)
return
}
}
var abs = fd_mod.realpath(file)
// Shared compilation front-end
var tokenize = use('tokenize')
var parse_mod = use('parse')
var fold = use('fold')
var mcode_mod = use('mcode')
var streamline_mod = use('streamline')
var src = text(fd_mod.slurp(abs))
var tok = tokenize(src, abs)
var ast = parse_mod(tok.tokens, src, abs, tokenize)
var folded = fold(ast)
var compiled = mcode_mod(folded)
var optimized = streamline_mod(compiled)
// Shared env for both paths — only non-intrinsic runtime functions.
// Intrinsics (starts_with, ends_with, logical, some, every, etc.) live on
// the stoned global and are found via GETINTRINSIC/cell_rt_get_intrinsic.
var env = stone({
log: log,
fallback: fallback,
parallel: parallel,
race: race,
sequence: sequence,
use
})
// --- Interpreted (mach VM) ---
var result_interp = null
var interp_ok = false
var run_interp = function() {
print('--- interpreted ---')
var mcode_json = json.encode(optimized)
var mach_blob = mach_compile_mcode_bin(abs, mcode_json)
result_interp = mach_load(mach_blob, env)
interp_ok = true
print('result: ' + show(result_interp))
} disruption {
interp_ok = true
print('(disruption escaped from interpreted run)')
}
run_interp()
// --- Native (AOT via QBE) ---
var result_native = null
var native_ok = false
var run_native = function() {
print('\n--- native ---')
var dylib_path = build.compile_native_ir(optimized, abs, null)
print('dylib: ' + dylib_path)
var handle = os.dylib_open(dylib_path)
if (!handle) {
print('failed to open dylib')
return
}
result_native = os.native_module_load(handle, env)
native_ok = true
print('result: ' + show(result_native))
} disruption {
native_ok = true
print('(disruption escaped from native run)')
}
run_native()
// --- Comparison ---
print('\n--- comparison ---')
var s_interp = show(result_interp)
var s_native = show(result_native)
if (interp_ok && native_ok) {
if (s_interp == s_native) {
print('MATCH')
} else {
print('MISMATCH')
print(' interp: ' + s_interp)
print(' native: ' + s_native)
}
} else {
if (!interp_ok) print('interpreted run failed')
if (!native_ok) print('native run failed')
}