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>
This commit is contained in:
@@ -33,28 +33,162 @@ typedef struct akbasic_Parser
|
||||
akbasic_Runtime *runtime;
|
||||
} akbasic_Parser;
|
||||
|
||||
/**
|
||||
* @brief Bind a parser to a runtime.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param runtime The runtime whose active environment holds the token stream.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKERR_NULLPOINTER When `obj` or `runtime` is NULL.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_init(akbasic_Parser *obj, akbasic_Runtime *runtime);
|
||||
/**
|
||||
* @brief Reset the token and leaf cursors for a fresh line.
|
||||
* @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_parser_zero(akbasic_Parser *obj);
|
||||
|
||||
/** @brief Parse one statement from the token stream. */
|
||||
/**
|
||||
* @brief Parse one statement from the token stream.
|
||||
*
|
||||
* A line can hold more than one statement, so callers loop on
|
||||
* akbasic_parser_is_at_end().
|
||||
*
|
||||
* @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_SYNTAX When the tokens do not parse.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_parse(akbasic_Parser *obj, akbasic_ASTLeaf **dest);
|
||||
|
||||
/**
|
||||
* @brief True when the token stream for this line is spent.
|
||||
* @param obj Parser to inspect; a NULL or unbound parser is at the end.
|
||||
* @return `true` when there is nothing left to parse.
|
||||
*/
|
||||
bool akbasic_parser_is_at_end(akbasic_Parser *obj);
|
||||
|
||||
/* --- Internal API: the grammar rules, reachable from src/parser_commands.c. --- */
|
||||
|
||||
/**
|
||||
* @brief Grammar rule: a verb and its rval, or an assignment.
|
||||
*
|
||||
* A verb with its own parse path in the dispatch table delegates to it; anything
|
||||
* else takes an expression as its rval, and a line that is not a verb at all
|
||||
* falls through to assignment().
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param dest Output destination populated by the function; the leaf this rule produced.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_SYNTAX When the tokens do not match the rule.
|
||||
* @throws AKBASIC_ERR_BOUNDS When the per-line leaf pool is exhausted.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_command(akbasic_Parser *obj, akbasic_ASTLeaf **dest);
|
||||
/**
|
||||
* @brief Grammar rule: `IDENTIFIER = expression`, or a bare expression.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param dest Output destination populated by the function; the leaf this rule produced.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_SYNTAX When the tokens do not match the rule.
|
||||
* @throws AKBASIC_ERR_BOUNDS When the per-line leaf pool is exhausted.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_assignment(akbasic_Parser *obj, akbasic_ASTLeaf **dest);
|
||||
/**
|
||||
* @brief Grammar rule: the top of the expression chain.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param dest Output destination populated by the function; the leaf this rule produced.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_SYNTAX When the tokens do not match the rule.
|
||||
* @throws AKBASIC_ERR_BOUNDS When the per-line leaf pool is exhausted.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_expression(akbasic_Parser *obj, akbasic_ASTLeaf **dest);
|
||||
/**
|
||||
* @brief Grammar rule: a comparison between two subtractions.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param dest Output destination populated by the function; the leaf this rule produced.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_SYNTAX When the tokens do not match the rule.
|
||||
* @throws AKBASIC_ERR_BOUNDS When the per-line leaf pool is exhausted.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_relation(akbasic_Parser *obj, akbasic_ASTLeaf **dest);
|
||||
/**
|
||||
* @brief Grammar rule: a literal, an identifier, or a parenthesised expression.
|
||||
*
|
||||
* An identifier with a type suffix also consumes an array subscript list when
|
||||
* one follows it.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param dest Output destination populated by the function; the leaf this rule produced.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_SYNTAX When the tokens do not match the rule.
|
||||
* @throws AKBASIC_ERR_BOUNDS When the per-line leaf pool is exhausted.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_primary(akbasic_Parser *obj, akbasic_ASTLeaf **dest);
|
||||
/**
|
||||
* @brief Grammar rule: comma-separated expressions joined through `.right`.
|
||||
*
|
||||
* With `requireparens` false and no opening paren this still builds a list,
|
||||
* which is how DATA and READ take a bare comma-separated series.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param arglisttype Marks the list as function arguments or array subscripts.
|
||||
* @param requireparens When true, parentheses are mandatory and unbalanced ones are an error.
|
||||
* @param dest Output destination populated by the function; NULL when parens were required and absent.
|
||||
* @return `NULL` on success, otherwise an error context owned by the caller.
|
||||
* @throws AKBASIC_ERR_SYNTAX When `arglisttype` is wrong or a paren is unbalanced.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_argument_list(akbasic_Parser *obj, akbasic_TokenType arglisttype, bool requireparens, akbasic_ASTLeaf **dest);
|
||||
|
||||
/**
|
||||
* @brief Take the next leaf from the active environment's per-line 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 the line has already used all its leaves.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_new_leaf(akbasic_Parser *obj, akbasic_ASTLeaf **dest);
|
||||
/**
|
||||
* @brief Consume the next token when it is any of the given types.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param types Token types to accept.
|
||||
* @param count How many entries `types` holds.
|
||||
* @return `true` when a token was consumed.
|
||||
*/
|
||||
bool akbasic_parser_match(akbasic_Parser *obj, const akbasic_TokenType *types, int count);
|
||||
|
||||
/**
|
||||
* @brief Consume the next token when it is of one given type.
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param type Token type to accept.
|
||||
* @return `true` when a token was consumed.
|
||||
*/
|
||||
bool akbasic_parser_match1(akbasic_Parser *obj, akbasic_TokenType type);
|
||||
|
||||
/**
|
||||
* @brief The next token, without consuming it.
|
||||
* @param obj Parser to inspect.
|
||||
* @return The next token, or NULL at the end of the line.
|
||||
*/
|
||||
akbasic_Token *akbasic_parser_peek(akbasic_Parser *obj);
|
||||
/**
|
||||
* @brief The token just consumed.
|
||||
* @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_SYNTAX When nothing has been consumed yet.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_previous(akbasic_Parser *obj, akbasic_Token **dest);
|
||||
/**
|
||||
* @brief Raise a parse error naming the token the parser stopped on.
|
||||
*
|
||||
* Always returns an error; it never succeeds. The reference also dumps a stack
|
||||
* trace here, which is not reproduced -- an interpreter library does not print
|
||||
* the host's stack, and the akerr trace already carries it.
|
||||
*
|
||||
* @param obj Object to initialize, inspect, or modify.
|
||||
* @param message What was expected, appended to the position.
|
||||
* @return An error context owned by the caller; never `NULL`.
|
||||
* @throws AKBASIC_ERR_SYNTAX Always.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *akbasic_parser_error(akbasic_Parser *obj, const char *message);
|
||||
|
||||
#endif // _AKBASIC_PARSER_H_
|
||||
|
||||
Reference in New Issue
Block a user