clean up cli

This commit is contained in:
2026-02-12 16:45:10 -06:00
parent 0ba2783b48
commit f901332c5b
5 changed files with 32 additions and 74 deletions

View File

@@ -48,12 +48,12 @@ cell_main: source/main.c libcell_runtime.dylib
# Regenerate .mach bytecode when any .cm source changes
.mach.stamp: $(MACH_SOURCES)
./cell --core . regen.cm
./cell --core . regen
@touch $@
# Force-regenerate all .mach bytecode files
regen:
./cell --core . regen.cm
./cell --core . regen
@touch .mach.stamp
# Create the cell shop directories

View File

@@ -1,5 +1,5 @@
// Hidden vars come from env:
// CLI mode (cell_init): os, args, core_path, shop_path, emit_qbe, dump_mach
// CLI mode (cell_init): os, args, core_path, shop_path
// Actor spawn (script_startup): os, json, nota, wota, actorsym, init, core_path, shop_path
// args[0] = script name, args[1..] = user args
var load_internal = os.load_internal
@@ -48,7 +48,6 @@ use_cache['fold'] = fold_mod
var mcode_mod = boot_load("mcode", boot_env)
use_cache['mcode'] = mcode_mod
var streamline_mod = null
var qbe_emit_mod = null
// Warn if any .cm source is newer than its .mach bytecode
function check_mach_stale() {
@@ -83,7 +82,7 @@ function check_mach_stale() {
}
if (length(stale) > 0) {
print("warning: bytecode is stale for: " + text(stale, ", ") + "\n")
print("run 'make regen' or './cell --core . regen.cm' to update\n")
print("run 'make regen' to update\n")
}
}
check_mach_stale()
@@ -145,30 +144,13 @@ function load_module(name, env) {
}
// Load optimization pipeline modules (needs analyze to be defined)
var qbe_macros = null
streamline_mod = load_module("streamline", boot_env)
use_cache['streamline'] = streamline_mod
if (emit_qbe) {
qbe_macros = load_module("qbe", boot_env)
qbe_emit_mod = load_module("qbe_emit", boot_env)
use_cache['qbe'] = qbe_macros
use_cache['qbe_emit'] = qbe_emit_mod
}
// Run AST through mcode pipeline → register VM
function run_ast(name, ast, env) {
var compiled = mcode_mod(ast)
var optimized = streamline_mod(compiled)
var qbe_il = null
if (emit_qbe) {
qbe_il = qbe_emit_mod(optimized, qbe_macros)
print(qbe_il)
return null
}
if (dump_mach) {
mach_dump_mcode(name, json.encode(optimized), env)
return null
}
return mach_eval_mcode(name, json.encode(optimized), env)
}
@@ -234,45 +216,26 @@ function load_engine(env) {
var program = null
var user_args = []
var _j = 0
var script_file = null
var script = null
var ast = null
if (args != null) {
// CLI mode — parse args
// CLI mode — always run as actor program (.ce)
program = args[0]
if (!program) {
print("error: no program specified\n")
disrupt
}
_j = 1
while (_j < length(args)) {
push(user_args, args[_j])
_j = _j + 1
}
// Resolve script file: try .cm then .ce in CWD then core_path
script_file = program
if (!ends_with(script_file, '.ce') && !ends_with(script_file, '.cm'))
script_file = program + '.cm'
if (!fd.is_file(script_file))
script_file = core_path + '/' + program + '.cm'
if (!fd.is_file(script_file))
script_file = program + '.ce'
if (!fd.is_file(script_file))
script_file = core_path + '/' + program + '.ce'
if (ends_with(script_file, '.ce')) {
// Actor script — delegate to engine
load_engine({
os: os, actorsym: actorsym,
init: {program: program, arg: user_args},
core_path: core_path, shop_path: shop_path, json: json,
analyze: analyze, run_ast_fn: run_ast
})
} else {
// Module script — run directly
script = text(fd.slurp(script_file))
ast = analyze(script, script_file)
run_ast(program, ast, {use: use_fn, args: user_args, json: json})
}
load_engine({
os: os, actorsym: actorsym,
init: {program: program, arg: user_args},
core_path: core_path, shop_path: shop_path, json: json,
analyze: analyze, run_ast_fn: run_ast
})
} else {
// Actor spawn mode — load engine.cm with full actor env
load_engine({

View File

@@ -728,7 +728,7 @@ function report_to_overling(msg)
var program = _cell.args.program
if (!program) {
log.error('No program specified. Usage: cell <program.ce> [args...]')
log.error('No program specified. Usage: cell <program> [args...]')
os.exit(1)
}
@@ -819,7 +819,7 @@ actor_mod.setname(_cell.args.program)
var prog = _cell.args.program
if (ends_with(prog, '.cm')) {
os.print(`error: ${prog} is a module (.cm), not an actor (.ce). Run it with: cell --core <path> ${prog}\n`)
os.print(`error: ${prog} is a module (.cm), not a program (.ce)\n`)
os.exit(1)
}
if (ends_with(prog, '.ce')) prog = text(prog, 0, -3)
@@ -868,6 +868,8 @@ $_.clock(_ => {
env.use = function(path) {
var ck = 'core/' + path
if (use_cache[ck]) return use_cache[ck]
var core_mod = use_core(path)
if (core_mod) return core_mod
return shop.use(path, pkg)
}
env.args = _cell.args.arg

View File

@@ -1,5 +1,5 @@
// regen.cm — regenerate .mach bytecode files
// Run with: ./cell --core . regen.cm
// regen.ce — regenerate .mach bytecode files
// Run with: ./cell --core . regen
var fd = use("fd")
var json = use("json")

View File

@@ -269,13 +269,11 @@ static int run_test_suite(size_t heap_size)
static void print_usage(const char *prog)
{
printf("Usage: %s [options] <script> [args...]\n\n", prog);
printf("Run a cell script (.ce actor or .cm module).\n\n");
printf("Usage: %s [options] <program> [args...]\n\n", prog);
printf("Run a cell program (.ce actor).\n\n");
printf("Options:\n");
printf(" --core <path> Set core path directly (overrides CELL_CORE)\n");
printf(" --shop <path> Set shop path (overrides CELL_SHOP)\n");
printf(" --emit-qbe Emit QBE IL (for native compilation)\n");
printf(" --dump-mach Dump MACH bytecode disassembly\n");
printf(" --test [heap_size] Run C test suite\n");
printf(" -h, --help Show this help message\n");
printf("\nEnvironment:\n");
@@ -307,24 +305,13 @@ int cell_init(int argc, char **argv)
}
/* Default: run script through bootstrap pipeline */
int emit_qbe = 0;
int dump_mach = 0;
int arg_start = 1;
const char *shop_override = NULL;
const char *core_override = NULL;
// Parse flags (order-independent)
while (arg_start < argc && argv[arg_start][0] == '-') {
if (strcmp(argv[arg_start], "--mcode") == 0) {
/* --mcode is now always on; accept and ignore for compat */
arg_start++;
} else if (strcmp(argv[arg_start], "--emit-qbe") == 0) {
emit_qbe = 1;
arg_start++;
} else if (strcmp(argv[arg_start], "--dump-mach") == 0) {
dump_mach = 1;
arg_start++;
} else if (strcmp(argv[arg_start], "--shop") == 0) {
if (strcmp(argv[arg_start], "--shop") == 0) {
if (arg_start + 1 >= argc) {
printf("ERROR: --shop requires a path argument\n");
return 1;
@@ -343,6 +330,11 @@ int cell_init(int argc, char **argv)
}
}
if (arg_start >= argc) {
print_usage(argv[0]);
return 1;
}
if (!find_cell_shop(shop_override, core_override)) return 1;
actor_initialize();
@@ -402,8 +394,9 @@ int cell_init(int argc, char **argv)
JS_SetPropertyStr(ctx, hidden_env, "core_path", JS_NewString(ctx, core_path));
JS_SetPropertyStr(ctx, hidden_env, "shop_path",
shop_path ? JS_NewString(ctx, shop_path) : JS_NULL);
JS_SetPropertyStr(ctx, hidden_env, "emit_qbe", JS_NewBool(ctx, emit_qbe));
JS_SetPropertyStr(ctx, hidden_env, "dump_mach", JS_NewBool(ctx, dump_mach));
/* TODO: remove after next 'make regen' — old bootstrap.mach reads these */
JS_SetPropertyStr(ctx, hidden_env, "emit_qbe", JS_FALSE);
JS_SetPropertyStr(ctx, hidden_env, "dump_mach", JS_FALSE);
JS_SetPropertyStr(ctx, hidden_env, "actorsym", JS_DupValue(ctx, cli_rt->actor_sym_ref.val));
JS_SetPropertyStr(ctx, hidden_env, "json", js_json_use(ctx));
JS_SetPropertyStr(ctx, hidden_env, "nota", js_nota_use(ctx));