Document the public API in libakgl's Doxygen style
Adds a Doxyfile in the shape libakgl uses -- fifteen deliberate lines, including WARN_IF_UNDOCUMENTED and WARN_AS_ERROR=FAIL_ON_WARNINGS -- and fills in the 70 public declarations that had no doc block, bringing include/akbasic to 114 of 114. libakgl is the model rather than libakstdlib. Measured before starting: libakgl documents 122 of 122 public declarations and libakstdlib 3 of 25, and libakstdlib's Doxyfile is the unedited doxygen default, PROJECT_NAME = "My Project" and an empty INPUT. So the house standard is libakgl's, down to the boilerplate phrasing for the recurring parameters -- "Object to initialize, inspect, or modify", "Output destination populated by the function", "`NULL` on success, otherwise an error context owned by the caller". Worth knowing what the gate actually gates. EXTRACT_ALL=YES suppresses doxygen's undocumented-entity warnings, so the rule it enforces is that a *partial* block is an error: document one @param and you must document them all. Verified by deleting a @param and confirming a non-zero exit, then restoring it. Full coverage is therefore a convention this commit adopts rather than something the tool made me do. Where a contract is non-obvious the block says so rather than restating the signature: math_plus explains why it alone mutates its left operand, new_unary notes that hanging the operand on .right is what makes the parser miscount a negative literal argument, leaf_to_string warns that an assignment renders with an empty operator, and stop_waiting records that a verb nobody is waiting for is tolerated. Each cross-references its TODO.md section 6 item. Also records in TODO.md that this repository has no CI, which libakgl and libakstdlib both have -- so ctest, the sanitizer build, coverage and this new doxygen gate are all run by hand today. ctest 61/61; doxygen Doxyfile exits 0; no warnings under -Wall -Wextra. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-Authored-By: Andrew Kesterson <andrew@aklabs.net>
This commit is contained in:
@@ -104,32 +104,120 @@ typedef struct akbasic_Runtime
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_init(akbasic_Runtime *obj, akbasic_TextSink *sink);
|
||||
|
||||
/** @brief Reset the per-line state without disturbing the program or variables. */
|
||||
/**
|
||||
* @brief Reset the per-line state without disturbing the program or variables.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_zero(akbasic_Runtime *obj);
|
||||
|
||||
/**
|
||||
* @brief Push a new scope, taking one from the pool.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_ENVIRONMENT When the environment pool is exhausted.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_new_environment(akbasic_Runtime *obj);
|
||||
/**
|
||||
* @brief Pop the active scope and release it back to the pool.
|
||||
*
|
||||
* The reference never releases, which its garbage collector papers over. Here
|
||||
* the pool is finite, so an unreleased scope shows up as exhaustion later.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_ENVIRONMENT When the active scope is the root.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_prev_environment(akbasic_Runtime *obj);
|
||||
|
||||
/** @brief Report a BASIC error on the current line, in the reference's format. */
|
||||
/**
|
||||
* @brief Report a BASIC error on the current line, in the reference's format.
|
||||
*
|
||||
* Writes `? <line> : <CLASS> <message>` through the sink. The message is expected
|
||||
* to end in a newline and the sink adds another, which is why an error line in
|
||||
* the golden corpus is followed by a blank one -- that is the contract, not an
|
||||
* accident.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param errclass Which error class to name in the line.
|
||||
* @param message Text to append; conventionally ends in a newline.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` or `message` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_error(akbasic_Runtime *obj, akbasic_ErrorClass errclass, const char *message);
|
||||
|
||||
/** @brief Write text, mirroring the reference's Write(). */
|
||||
/**
|
||||
* @brief Write text through the sink, mirroring the reference's Write().
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param text Text to emit.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` or `text` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_write(akbasic_Runtime *obj, const char *text);
|
||||
/** @brief Write text and a newline, mirroring the reference's Println(). */
|
||||
/**
|
||||
* @brief Write text and a newline, mirroring the reference's Println().
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param text Text to emit.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` or `text` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_println(akbasic_Runtime *obj, const char *text);
|
||||
|
||||
/**
|
||||
* @brief Change the execution mode, announcing READY when entering the REPL.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param mode One of the AKBASIC_MODE_* values.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_set_mode(akbasic_Runtime *obj, int mode);
|
||||
|
||||
/** @brief Evaluate one AST leaf, drawing scratch values from the environment. */
|
||||
/**
|
||||
* @brief Evaluate one AST leaf, drawing scratch values from the environment.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param expr Leaf to evaluate.
|
||||
* @param dest Output destination populated by the function; points into the per-line value pool.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When any argument is NULL.
|
||||
* @throws AKBASIC_ERR_BOUNDS When the per-line value pool is exhausted.
|
||||
* @throws AKBASIC_ERR_UNDEFINED When the leaf names a verb, function or label that does not exist.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_evaluate(akbasic_Runtime *obj, akbasic_ASTLeaf *expr, akbasic_Value **dest);
|
||||
|
||||
/** @brief Evaluate a leaf only when it is a command a REPL may run immediately. */
|
||||
/**
|
||||
* @brief Evaluate a leaf only when it is a verb a REPL may run without a line number.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param expr Leaf to consider.
|
||||
* @param dest Output destination populated by the function; NULL when the leaf was not immediate.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When any argument is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_interpret_immediate(akbasic_Runtime *obj, akbasic_ASTLeaf *expr, akbasic_Value **dest);
|
||||
|
||||
/** @brief Evaluate a leaf unless the environment is skipping forward to a verb. */
|
||||
/**
|
||||
* @brief Evaluate a leaf unless the environment is skipping forward to a verb.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param expr Leaf to evaluate.
|
||||
* @param dest Output destination populated by the function.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When any argument is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_interpret(akbasic_Runtime *obj, akbasic_ASTLeaf *expr, akbasic_Value **dest);
|
||||
|
||||
/** @brief Call a user-defined function or subroutine. */
|
||||
/**
|
||||
* @brief Call a user-defined function or subroutine.
|
||||
*
|
||||
* A single-expression DEF evaluates and returns. A multi-line one hands control
|
||||
* to its own scope and runs until RETURN pops back out, which is why this can
|
||||
* execute an arbitrary number of source lines.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param expr The call leaf, carrying the function name and its arguments.
|
||||
* @param dest Output destination populated by the function.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_KEY When no such function is defined.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_user_function(akbasic_Runtime *obj, akbasic_ASTLeaf *expr, akbasic_Value **dest);
|
||||
|
||||
/**
|
||||
@@ -137,16 +225,38 @@ akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_user_function(akbasic_Runtime
|
||||
*
|
||||
* One call reads or runs at most one source line. It never blocks beyond a
|
||||
* single readline on the sink, and it always returns.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_step(akbasic_Runtime *obj);
|
||||
|
||||
/**
|
||||
* @brief Step until the runtime quits or `maxsteps` steps have elapsed.
|
||||
*
|
||||
* This is the entry point an embedding host calls once per frame. A bounded
|
||||
* budget is what keeps a script with an infinite loop from taking the host's
|
||||
* frame rate with it.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param maxsteps Step ceiling; zero or negative means unbounded.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_run(akbasic_Runtime *obj, int maxsteps);
|
||||
|
||||
/** @brief Point the runtime at an input stream and choose a starting mode. */
|
||||
/**
|
||||
* @brief Choose a starting mode and decide what happens when a program ends.
|
||||
*
|
||||
* Starting in AKBASIC_MODE_REPL returns to the REPL when a program finishes;
|
||||
* anything else quits.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param mode One of the AKBASIC_MODE_* values.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_start(akbasic_Runtime *obj, int mode);
|
||||
|
||||
/**
|
||||
@@ -173,12 +283,60 @@ akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_load(akbasic_Runtime *obj, co
|
||||
|
||||
/* --- Internal API: exposed for the scanner, parser and verb handlers only. --- */
|
||||
|
||||
/**
|
||||
* @brief Take an unused variable from the runtime's pool.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param dest Output destination populated by the function.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_BOUNDS When every variable slot is in use.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_new_variable(akbasic_Runtime *obj, akbasic_Variable **dest);
|
||||
/**
|
||||
* @brief Take an unused function definition from the runtime's pool.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param dest Output destination populated by the function.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_BOUNDS When every function slot is in use.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_new_function(akbasic_Runtime *obj, akbasic_FunctionDef **dest);
|
||||
/**
|
||||
* @brief File one already-scanned source line under its line number.
|
||||
*
|
||||
* Hosts should prefer akbasic_runtime_load(), which scans as well.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param lineno Line number to file it under.
|
||||
* @param code Source text, with any line number already stripped.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_BOUNDS When the number or the line length is out of range.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_store_line(akbasic_Runtime *obj, int64_t lineno, const char *code);
|
||||
/**
|
||||
* @brief Execute the next line of the stored program.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_process_line_run(akbasic_Runtime *obj);
|
||||
/**
|
||||
* @brief Read one line from the sink and file it, without executing it.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_process_line_runstream(akbasic_Runtime *obj);
|
||||
/**
|
||||
* @brief Read one line from the sink and either run it or file it.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_runtime_process_line_repl(akbasic_Runtime *obj);
|
||||
/**
|
||||
* @brief The nearest non-empty line before the current one.
|
||||
* @param obj Runtime to inspect.
|
||||
* @return That line's number, or the current one when there is nothing before it.
|
||||
*/
|
||||
int64_t akbasic_runtime_find_previous_lineno(akbasic_Runtime *obj);
|
||||
|
||||
#endif // _AKBASIC_RUNTIME_H_
|
||||
|
||||
Reference in New Issue
Block a user