53 lines
3.1 KiB
Text
Vendored
53 lines
3.1 KiB
Text
Vendored
our-basic CHANGELOG -- calog's modifications to upstream MY-BASIC
|
|
================================================================
|
|
|
|
Every change below is marked in-source with the comment tag "[calog fork]".
|
|
Baseline: ourBasic.c.upstream (pristine upstream MY-BASIC). Run
|
|
diff ourBasic.c.upstream ourBasic.c
|
|
to see the full patch set.
|
|
|
|
Concurrency
|
|
- The _mb_allocated allocation counter was changed from `volatile` to `_Atomic`,
|
|
so independent interpreters (one per calog context thread) can be created and
|
|
destroyed concurrently without racing the counter. Execution already runs
|
|
unlocked; only lifecycle is serialized, in the adapter.
|
|
|
|
Memory
|
|
- A my-basic routine (lambda) popped as a refused/errored native argument is now
|
|
disposed on the error path so its scope is not leaked. (In the adapter's
|
|
arg-marshal loop, src/mybasic/mybasicAdapter.c.)
|
|
|
|
First-class routines -- the reason for the fork
|
|
- Bare-def-as-value: in _calc_expression, a routine identifier NOT followed by
|
|
'(' now pushes the routine as an operand (a first-class value) instead of
|
|
raising "Open bracket expected". A script can now pass a `def` (or a lambda) to
|
|
a native and store it in a variable -- required for cross-engine callbacks
|
|
(pubsub / timer / export). It mirrors the array-index branch beside it; calls,
|
|
recursion, and closures are unchanged.
|
|
- mb_eval_routine_cold(): a new public entry (declared in ourBasic.h) that invokes
|
|
a routine value from an IDLE interpreter -- one with no live call frame. It
|
|
supplies the last AST node as a clean return landing and passes arguments
|
|
directly. calog uses it to fire script callbacks that were registered earlier
|
|
and delivered when the interpreter is otherwise idle.
|
|
|
|
Constraint: a callback must be a TOP-LEVEL def/lambda (persistent scope); a routine
|
|
local to a function would dangle once that function returns -- the same rule every
|
|
engine's closures follow.
|
|
|
|
Bare-name resolution for dynamic functions
|
|
- mb_dynamic_func_handler / mb_set_dynamic_func_handler(): a new hook (a field on
|
|
mb_interpreter_t plus its setter, declared in ourBasic.h). In _calc_expression,
|
|
where a bare identifier called like a function -- foo(args) -- that is not a
|
|
variable/routine/collection would raise "Invalid identifier usage", the interpreter
|
|
now first offers the (uppercased) name to the registered handler. The handler
|
|
returns MB_FUNC_OK (handled -- the result is left in the running intermediate
|
|
value), MB_FUNC_IGNORE (unknown -- the normal error is then raised), or an error
|
|
code; the pending argument list is left untouched on IGNORE. calog uses it to
|
|
resolve a bare name to a broker export, so exportedFn(args) works without an
|
|
explicit calogCall -- the same convenience the hook engines have. (The adapter
|
|
resolves case-insensitively, since my-basic uppercases identifiers at parse time.)
|
|
|
|
Verified: full calog `make test` (28 binaries, 0 failed) plus the my-basic engine
|
|
suite (testMyBasic / testEngineMyBasic / testPolyglot / testLoad / testTask),
|
|
ASan/UBSan-clean, with def and lambda callbacks firing via timer/pubsub/export and
|
|
cross-engine (a Lua task calling a my-basic def).
|