From 32c92a6cd12afbae8763faf61b65b188493dcb90 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 18 Feb 2023 22:54:39 +1100 Subject: [PATCH] Wrote the docs for toy_literal.h --- c-api/toy_ast_node_h.md | 12 --- c-api/toy_interpreter_h.md | 20 +++++ c-api/toy_literal_h.md | 163 +++++++++++++++++++++++++++++++++++++ c-api/toy_parser_h.md | 8 +- index.md | 3 +- 5 files changed, 190 insertions(+), 16 deletions(-) delete mode 100644 c-api/toy_ast_node_h.md create mode 100644 c-api/toy_literal_h.md diff --git a/c-api/toy_ast_node_h.md b/c-api/toy_ast_node_h.md deleted file mode 100644 index 98a8764..0000000 --- a/c-api/toy_ast_node_h.md +++ /dev/null @@ -1,12 +0,0 @@ -# toy_ast_node.h - -This header defines the structure of the nodes used in the Abstract Syntax Tree, known as `Toy_ASTNode`. Most of what is defined here is intended for internal use, so is not documented here. - -This header doesn't need to be included directly, as it is included in [toy_parser.h](toy_parser_h.md). - -## Defined Functions - -### void Toy_freeASTNode(Toy_ASTNode* node) - -This function cleans up any valid instance of `Toy_ASTNode` pointer passed to it. It is most commonly used to clean up the values returned by `Toy_scanParser`, after they have been passsed to `Toy_writeCompiler`, or when the node is an error node. - diff --git a/c-api/toy_interpreter_h.md b/c-api/toy_interpreter_h.md index da3e499..88d4e10 100644 --- a/c-api/toy_interpreter_h.md +++ b/c-api/toy_interpreter_h.md @@ -8,10 +8,30 @@ Another useful customisation feature is the ability to redicrect output from the ## Defined Interfaces +Note: These interfaces are *actually* defined in [toy_literal.h](toy_literal_h.md) but are documented here, because this is where it matters most. + ### typedef void (*Toy_PrintFn)(const char*) This is the interface used by "print functions" - that is, functions used to print messages from the `print` and `assert` keywords, as well as internal interpreter errors. +### typedef int (*Toy_NativeFn)(struct Toy_Interpreter* interpreter, struct Toy_LiteralArray* arguments) + +This is the interface used by "native functions" - that is, functions written in C which can be called directly by Toy scripts. + +The arguments to the function are passed in as a `Toy_LiteralArray`. + +### typedef int (*Toy_HookFn)(struct Toy_Interpreter* interpreter, struct Toy_Literal identifier, struct Toy_Literal alias) + +This is the interface used by "hook functions" - that is, functions written in C whihc are invoked by using the `import` keyword, and are intended to inject other native functions into the current scope. While hook functions are capable of doing other things, this is greatly discouraged. + +The identifier of the library (its name) is passed in as a `Toy_Literal`, as is any given alias; if no alias is given, then `alias` will be a null literal. Here, the identifier is `standard`, while the alias is `std`. + +``` +import standard as std; +``` + +Conventionally, when an alias is given, all of the functions should instead be inserted into a `Toy_LiteralDictionary` which is then inserted into the scope with the alias as its identifier. + ## Defined Functions ### void Toy_initInterpreter(Toy_Interpreter* interpreter) diff --git a/c-api/toy_literal_h.md b/c-api/toy_literal_h.md new file mode 100644 index 0000000..627c165 --- /dev/null +++ b/c-api/toy_literal_h.md @@ -0,0 +1,163 @@ +# toy_literal.h + +This header defines the structure `Toy_Literal`, which is used extensively throughout Toy to represent values of some kind. + +The main way of interacting with literals is to use a macro of some kind, as the exact implementation of `Toy_Literal` has and will change based on the needs of Toy. + +User data can be passed around within Toy as an opaque type - use the tag value for determining what kind of opaque it is, or leave it as 0. + +## Defined Enums + +### Toy_LiteralType + +* `TOY_LITERAL_NULL` +* `TOY_LITERAL_BOOLEAN` +* `TOY_LITERAL_INTEGER` +* `TOY_LITERAL_FLOAT` +* `TOY_LITERAL_STRING` +* `TOY_LITERAL_ARRAY` +* `TOY_LITERAL_DICTIONARY` +* `TOY_LITERAL_FUNCTION` +* `TOY_LITERAL_FUNCTION_NATIVE` +* `TOY_LITERAL_FUNCTION_HOOK` +* `TOY_LITERAL_IDENTIFIER` +* `TOY_LITERAL_TYPE` +* `TOY_LITERAL_OPAQUE` +* `TOY_LITERAL_ANY` + +These are the main possible values of `Toy_LiteralType`, each of which represents a potential state of the `Toy_Literal` structure. Do not interact with a literal without determining its type with the `IS_*` macros first. + +## Defined Macros + +The following macros are used to determine if a given literal, passed in as `value`, is of a specific type. It should be noted that `TOY_IS_FUNCTION` will return false for native and hook functions. + +* `TOY_IS_NULL(value)` +* `TOY_IS_BOOLEAN(value)` +* `TOY_IS_INTEGER(value)` +* `TOY_IS_FLOAT(value)` +* `TOY_IS_STRING(value)` +* `TOY_IS_ARRAY(value)` +* `TOY_IS_DICTIONARY(value)` +* `TOY_IS_FUNCTION(value)` +* `TOY_IS_FUNCTION_NATIVE(value)` +* `TOY_IS_FUNCTION_HOOK(value)` +* `TOY_IS_IDENTIFIER(value)` +* `TOY_IS_TYPE(value)` +* `TOY_IS_OPAQUE(value)` + +The following macros are used to cast a literal to a specific type to be used. + +* `TOY_AS_BOOLEAN(value)` +* `TOY_AS_INTEGER(value)` +* `TOY_AS_FLOAT(value)` +* `TOY_AS_STRING(value)` +* `TOY_AS_ARRAY(value)` +* `TOY_AS_DICTIONARY(value)` +* `TOY_AS_FUNCTION(value)` +* `TOY_AS_FUNCTION_NATIVE(value)` +* `TOY_AS_FUNCTION_HOOK(value)` +* `TOY_AS_IDENTIFIER(value)` +* `TOY_AS_TYPE(value)` +* `TOY_AS_OPAQUE(value)` + +The following macros are used to create a new literal, with the given `value` as it's internal value. + +* `TOY_TO_NULL_LITERAL` - does not need parantheses +* `TOY_TO_BOOLEAN_LITERAL(value)` +* `TOY_TO_INTEGER_LITERAL(value)` +* `TOY_TO_FLOAT_LITERAL(value)` +* `TOY_TO_STRING_LITERAL(value)` +* `TOY_TO_ARRAY_LITERAL(value)` +* `TOY_TO_DICTIONARY_LITERAL(value)` +* `TOY_TO_FUNCTION_LITERAL(value, l)` - `l` represents the length of the bytecode passed as `value` +* `TOY_TO_FUNCTION_NATIVE_LITERAL(value)` +* `TOY_TO_FUNCTION_HOOK_LITERAL(value)` +* `TOY_TO_IDENTIFIER_LITERAL(value)` +* `TOY_TO_TYPE_LITERAL(value, c)` - `c` is the true of the type should be const +* `TOY_TO_OPAQUE_LITERAL(value, t)` - `t` is the integer tag + +## More Defined Macros + +The following macros are utilities used throughout Toy's internals, and are available for the user as well. + +### TOY_IS_TRUTHY(x) + +Returns true of the literal `x` is truthy, otherwise it returns false. + +Currently, every value is considered truthy except `false`, which is falsy and `null`, which is neither true or false. + +### TOY_AS_FUNCTION_BYTECODE_LENGTH(lit) + +Returns the length of a Toy function's bytecode. + +This macro is only valid on `TOY_LITERAL_FUNCTION`. + +### TOY_MAX_STRING_LENGTH + +The maximum length of a string in Toy, which is 4096 bytes by default. This can be changed at compile time, but the results of doing so are not officially supported. + +### TOY_HASH_I(lit) + +Identifiers are the names of of values within Toy; to speed up execution, their "hash value" is computed at compile time and stored within them. Use this to access it, if needed. + +This macro is only valid on `TOY_LITERAL_IDENTIFIER`. + +### TOY_TYPE_PUSH_SUBTYPE(lit, subtype) + +When building a complex type, such as the type of an array or dictionary, you may need to specify inner types. Use this to push a `subtype`. calling `Toy_freeLiteral` on the outermost type should clean up all inner types, as expected. + +This macro returns the index of the newly pushed value within it's parent. + +This macro is only valid on `TOY_LITERAL_TYPE`, for both `type` and `subtype`. + +### TOY_GET_OPAQUE_TAG(o) + +Returns the value of the opaque `o`'s tag. + +This macro is only valid on `TOY_LITERAL_OPAQUE`. + +## Defined Functions + +### void Toy_freeLiteral(Toy_Literal literal) + +This function frees the given literal's memory. Any internal pointers are now invalid. + +This function should be called on EVERY literal when it is no longer needed, regardless of type. + +### Toy_Literal Toy_copyLiteral(Toy_Literal original) + +This function returns a copy of the given literal. Literals should never be copied without this function, as it handles a lot of internal memory allocations. + +### bool Toy_literalsAreEqual(Toy_Literal lhs, Toy_Literal rhs) + +This checks to see if two given literals are equal. + +When an integer and a float are compared, the integer is cooerced into a float for the duration of the call. + +Arrays and dictionaries are equal only if their keys and values all equal. Likewise, types only equal if all subtypes are equal, in order. + +Functions and opaques are never equal to anything, while values with the type `TOY_LITERAL_ANY` are always equal. + +### int Toy_hashLiteral(Toy_Literal lit) + +This finds the hash of a literal, for various purposes. Different hashing algorithms are used for different types, and some types can't be hashed at all. + +types that can't be hashed are + +* all kinds of functions +* type +* opaque +* any + +In the case of identifiers, their hashes are precomputed on creation and are stored within the literal. + +### void Toy_printLiteral(Toy_Literal literal) + +This wraps a call to `Toy_printLiteralCustom`, with a printf-stdout wrapper as `printFn`. + +### void Toy_printLiteralCustom(Toy_Literal literal, PrintFn printFn) + +This function passes the string representation of `literal` to `printFn`. + +This function is not thread safe - due to the loopy and recursive nature of printing compound values, this function uses some globally persistent variables. + diff --git a/c-api/toy_parser_h.md b/c-api/toy_parser_h.md index 2471914..ac61774 100644 --- a/c-api/toy_parser_h.md +++ b/c-api/toy_parser_h.md @@ -48,8 +48,6 @@ const unsigned char* Toy_compileString(const char* source, size_t* size) { } ``` -This header also includes [toy_ast_node.h](toy_ast_node_h.md), so the `Toy_freeASTNode` function can also be used. - ## Defined Functions ### void Toy_initParser(Toy_Parser* parser, Toy_Lexer* lexer) @@ -66,3 +64,9 @@ This function returns an abstract syntax tree representing part of the program, This function should be called repeatedly until it returns `NULL`, indicating the end of the program. +### void Toy_freeASTNode(Toy_ASTNode* node) + +This function cleans up any valid instance of `Toy_ASTNode` pointer passed to it. It is most commonly used to clean up the values returned by `Toy_scanParser`, after they have been passsed to `Toy_writeCompiler`, or when the node is an error node. + +Note: this function is *actually* defined in toy_ast_node.h, but documented here, because this is where it matters most. + diff --git a/index.md b/index.md index f0fb569..af40ddf 100644 --- a/index.md +++ b/index.md @@ -69,14 +69,13 @@ print tally(); //3
* [repl_tools.h] -* [toy_ast_node.h](c-api/toy_ast_node_h.md) * [toy_common.h](c-api/toy_common_h.md) * [toy_compiler.h](c-api/toy_compiler_h.md) * [toy_interpreter.h](c-api/toy_interpreter_h.md) * [toy_lexer.h](c-api/toy_lexer_h.md) * [toy_literal_array.h] * [toy_literal_dictionary.h] -* [toy_literal.h] +* [toy_literal.h](c-api/toy_literal_h.md) * [toy_memory.h](c-api/toy_memory_h.md) * [toy_parser.h](c-api/toy_parser_h.md) * [toy_refstring.h](c-api/toy_refstring_h.md)