mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Docs now based on comments
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
# toy_common.h
|
# toy_common.h
|
||||||
|
|
||||||
This file is generally included in most header files within Toy, as it is where the `TOY_API` macro is defined. It also has some utilities intended for use only by the repl; as such, they won't be documented here.
|
This file is generally included in most header files within Toy, as it is where the TOY_API macro is defined. It also has some utilities intended for use only by the repl.
|
||||||
|
|
||||||
## Defined Macros
|
## Defined Macros
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ This definition of this macro is platform-dependant, and used to enable cross-pl
|
|||||||
|
|
||||||
### TOY_VERSION_MAJOR
|
### TOY_VERSION_MAJOR
|
||||||
|
|
||||||
The current major version of Toy. This value is embedded into the bytecode, and the interpreter will refuse to run bytecode with a major version that does not match it's own version.
|
The current major version of Toy. This value is embedded into the bytecode, and the interpreter will refuse to run bytecode with a major version that does not match it’s own version.
|
||||||
|
|
||||||
This value MUST fit into an unsigned char.
|
This value MUST fit into an unsigned char.
|
||||||
|
|
||||||
@@ -30,7 +31,6 @@ This value MUST fit into an unsigned char.
|
|||||||
|
|
||||||
The current build version of Toy. This value is embedded into the bytecode.
|
The current build version of Toy. This value is embedded into the bytecode.
|
||||||
|
|
||||||
This value is a string, which contains build information such as compilation date and time of the interpreter. When in verbose mode, the compiler will display a warning if the build version of the bytecode does not match the build version of the interpreter.
|
This evaluates to a c-string, which contains build information such as compilation date and time of the interpreter. When in verbose mode, the compiler will display a warning if the build version of the bytecode does not match the build version of the interpreter.
|
||||||
|
|
||||||
This macro may also be used to store information about forks of the Toy codebase.
|
|
||||||
|
|
||||||
|
This macro may also be used to store additonal information about forks of the Toy codebase.
|
||||||
|
|||||||
@@ -1,32 +1,30 @@
|
|||||||
|
|
||||||
# toy_compiler.h
|
# toy_compiler.h
|
||||||
|
|
||||||
This header defines the structure `Toy_Compiler`, which is used to transform abstract syntax trees into usable intermediate bytecode.
|
This header defines the compiler structure, which is used to transform abstract syntax trees into usable intermediate bytecode. There are two steps to generating bytecode - the writing step, and the collation step.
|
||||||
|
|
||||||
There are two steps to generating intermediate bytecode - the writing step, and the collation step.
|
|
||||||
|
|
||||||
During the writing step, the core of the program is generated, along with a series of literals representing the values within the program; these values are compressed and flattened into semi-unrecognizable forms. If the same literal is used multiple times in a program, such as a variable name, the name itself is replaced by a reference to the flattened literals within the cache.
|
During the writing step, the core of the program is generated, along with a series of literals representing the values within the program; these values are compressed and flattened into semi-unrecognizable forms. If the same literal is used multiple times in a program, such as a variable name, the name itself is replaced by a reference to the flattened literals within the cache.
|
||||||
|
|
||||||
During the collation step, everything from the core program's execution instructions, the flattened literals, the functions (which have their own sections and protocols within the bytecode) and version information (such as the macros defined in [toy_common.h](toy_common_h.md)) are all combined into a single buffer of bytes, known as bytecode. This bytecode can then be safely saved to a file or immediately executed.
|
During the collation step, everything from the core program’s execution instructions, the flattened literals, the functions (which have their own sections and protocols within the bytecode) and version information (such as the macros defined in toy_common.h) are all combined into a single buffer of bytes, known as bytecode. This bytecode can then be safely saved to a file or immediately executed.
|
||||||
|
|
||||||
Executing these functions out-of-order causes undefiend behaviour.
|
## Define Functions
|
||||||
|
|
||||||
## Defined Functions
|
Executing the following functions out-of-order causes undefiend behaviour.
|
||||||
|
|
||||||
### void Toy_initCompiler(Toy_Compiler* compiler)
|
### void Toy_initCompiler(Toy_Compiler* compiler)
|
||||||
|
|
||||||
This function initializes the given `Toy_Compiler`.
|
This function initializes the given compiler.
|
||||||
|
|
||||||
### void Toy_writeCompiler(Toy_Compiler* compiler, Toy_ASTNode* node)
|
### void Toy_writeCompiler(Toy_Compiler* compiler, Toy_ASTNode* node)
|
||||||
|
|
||||||
This function writes the given `node` argument to the compiler. During the writing step, this function may be called repeatedly, with a stream of results from `Toy_scanParser`, until `Toy_scanParser` returns `NULL`.
|
This function writes the given `node` argument to the compiler. During the writing step, this function may be called repeatedly, with a stream of results from `Toy_scanParser()`, until `Toy_scanParser()` returns `NULL`.
|
||||||
|
|
||||||
### void Toy_freeCompiler(Toy_Compiler* compiler)
|
|
||||||
|
|
||||||
This function frees a `Toy_Compiler`. Calling this on a compiler which has not been collated will free that compiler as expected - anything written to it will be lost.
|
|
||||||
|
|
||||||
### unsigned char* Toy_collateCompiler(Toy_Compiler* compiler, size_t* size)
|
### unsigned char* Toy_collateCompiler(Toy_Compiler* compiler, size_t* size)
|
||||||
|
|
||||||
This function returns a buffer of bytes, known as "bytecode", created from the given `Toy_Compiler`; it also stores the size of the bytecode in the variable pointed to by `size`.
|
This function returns a buffer of bytes, known as "bytecode", created from the given compiler; it also stores the size of the bytecode in the variable pointed to by `size`.
|
||||||
|
|
||||||
Calling `Toy_collateCompiler` multiple times on the same compiler will produce undefined behaviour.
|
Calling `Toy_collateCompiler()` multiple times on the same compiler will produce undefined behaviour.
|
||||||
|
|
||||||
|
### void Toy_freeCompiler(Toy_Compiler* compiler)
|
||||||
|
|
||||||
|
This function frees a compiler. Calling this on a compiler which has not been collated will free that compiler as expected - anything written to it will be lost.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
# toy_drive_system.h
|
# toy_drive_system.h
|
||||||
|
|
||||||
When accessing the file system through toy (such as with lib runner), it's best practice to utilize Toy's built-in drive system - this system (tries to) prevent malicious accessing of files outside of the designated folders. It does this by causing an error when a script tries to access a parent directory.
|
When accessing the file system through toy (such as with the runner library), it's best practice to utilize Toy's built-in drive system - this system (tries to) prevent malicious accessing of files outside of the designated folders. It does this by causing an error when a script tries to access a parent directory.
|
||||||
|
|
||||||
To use the drive system, first you must designate specific folders which can be accessed, like so:
|
To use the drive system, first you must designate specific folders which can be accessed, like so:
|
||||||
|
|
||||||
@@ -26,6 +27,10 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
This utility is intended mainly for libraries to use - as such, the core of Toy does not utilize it.
|
This utility is intended mainly for libraries to use - as such, the core of Toy does not utilize it.
|
||||||
|
|
||||||
|
### Implementation Details
|
||||||
|
|
||||||
|
The drive system uses a Toy's Dictionary structure to store the mappings between keys and values - this dictionary object is a static global which persists for the lifetime of the program.
|
||||||
|
|
||||||
## Defined Functions
|
## Defined Functions
|
||||||
|
|
||||||
### void Toy_initDriveSystem()
|
### void Toy_initDriveSystem()
|
||||||
@@ -44,7 +49,6 @@ This function sets a key-value pair in the drive system. It uses C strings, sinc
|
|||||||
|
|
||||||
This function, when given a string literal of the correct format, will return a new string literal containing the relative filepath to a specified file.
|
This function, when given a string literal of the correct format, will return a new string literal containing the relative filepath to a specified file.
|
||||||
|
|
||||||
The correct format is `drive:/path/to/filename`, where `drive` is a drive given to `Toy_setDrivePath()`.
|
The correct format is `drive:/path/to/filename`, where `drive` is a drive that was specified with `Toy_setDrivePath()`.
|
||||||
|
|
||||||
On failure, this function returns a null literal.
|
On failure, this function returns a null literal.
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
# toy_interpreter.h
|
# toy_interpreter.h
|
||||||
|
|
||||||
This header defines the structure `Toy_Interpreter`, which is the beating heart of Toy.
|
This header defines the interpreter structure, which is the beating heart of Toy.
|
||||||
|
|
||||||
The `Toy_Interpreter` is a stack-based, bytecode-driven interpreter with a number of customisation options, including "hooks"; native C functions wrapped in `Toy_Literal` instances, injected in order to give the Toy scripts access to libraries via the `import` keyword. The hooks, when invoked this way, can then inject further native functions into the interpreter's current scope. Exactly which hooks are made available varies by host program, but `standard` is the most commonly included one.
|
`Toy_Interpreter` is a stack-based, bytecode-driven interpreter with a number of customisation options, including "hooks"; native C functions wrapped in `Toy_Literal` instances, injected into the interpreter in order to give the Toy scripts access to libraries via the `import` keyword. The hooks, when invoked this way, can then inject further native functions into the interpreter's current scope. Exactly which hooks are made available varies by host program, but `standard` is the most commonly included one.
|
||||||
|
|
||||||
Another useful customisation feature is the ability to redicrect output from the `print` and `assert` keywords, as well as any internal errors that occur. This can allow you to add in a logging system, or even hook the `print` statement up to some kind of HUD.
|
Another useful customisation feature is the ability to redicrect output from the `print` and `assert` keywords, as well as any internal errors that occur. This can allow you to add in a logging system, or even hook the `print` statement up to some kind of HUD.
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ 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)
|
### 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.
|
This is the interface used by "hook functions" - that is, functions written in C which 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`.
|
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`.
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ Conventionally, when an alias is given, all of the functions should instead be i
|
|||||||
|
|
||||||
### void Toy_initInterpreter(Toy_Interpreter* interpreter)
|
### void Toy_initInterpreter(Toy_Interpreter* interpreter)
|
||||||
|
|
||||||
This function initializes the `Toy_Interpreter`. It allocates memory for internal systems such as the stack, and zeroes-out systems that have yet to be invoked. Internally, it also invokes `Toy_resetInterpreter` to initialize the environment.
|
This function initializes the interpreter. It allocates memory for internal systems such as the stack, and zeroes-out systems that have yet to be invoked. Internally, it also invokes `Toy_resetInterpreter` to initialize the environment.
|
||||||
|
|
||||||
### void Toy_runInterpreter(Toy_Interpreter* interpreter, const unsigned char* bytecode, size_t length)
|
### void Toy_runInterpreter(Toy_Interpreter* interpreter, const unsigned char* bytecode, size_t length)
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ Re-using a `Toy_Interpreter` instance without first resetting it is possible (th
|
|||||||
|
|
||||||
### void Toy_resetInterpreter(Toy_Interpreter* interpreter)
|
### void Toy_resetInterpreter(Toy_Interpreter* interpreter)
|
||||||
|
|
||||||
This function frees any environment that the scripts have built up, and generates a new one. It also injects several globally available functions:
|
This function frees any scopes that the scripts have built up, and generates a new one. It also injects several globally available functions:
|
||||||
|
|
||||||
* set
|
* set
|
||||||
* get
|
* get
|
||||||
@@ -63,13 +64,15 @@ This function frees a `Toy_Interpreter`, clearing all of the memory used within.
|
|||||||
|
|
||||||
### bool Toy_injectNativeFn(Toy_Interpreter* interpreter, const char* name, Toy_NativeFn func)
|
### bool Toy_injectNativeFn(Toy_Interpreter* interpreter, const char* name, Toy_NativeFn func)
|
||||||
|
|
||||||
This function will inject the given native function `func` into the `Toy_Interpreter`'s current scope, with the name passed as `name`. Both the name and function will be converted into literals internally before being stored. It will return true on success, otherwise it will return false.
|
This function will inject the given native function `func` into the `Toy_Interpreter`'s current scope, with the identifer as `name`. Both the name and function will be converted into literals internally before being stored. It will return true on success, otherwise it will return false.
|
||||||
|
|
||||||
The primary use of this function is within hooks.
|
The primary use of this function is within hooks.
|
||||||
|
|
||||||
### bool Toy_injectNativeHook(Toy_Interpreter* interpreter, const char* name, Toy_HookFn hook)
|
### bool Toy_injectNativeHook(Toy_Interpreter* interpreter, const char* name, Toy_HookFn hook)
|
||||||
|
|
||||||
This function will inject the given native function `hook` into the `Toy_Interpreter`'s hook cache, with the name passed in as `name`. Both the name and the function will be converted into literals internally before being stored. It will return true on success, otherwise it will return false.
|
This function will inject the given native function `hook` into the `Toy_Interpreter`'s hook cache, with the identifier as `name`. Both the name and the function will be converted into literals internally before being stored. It will return true on success, otherwise it will return false.
|
||||||
|
|
||||||
|
Hooks are invoked with the `import` keyword within Toy's scripts.
|
||||||
|
|
||||||
### bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_LiteralArray* arguments, Toy_LiteralArray* returns)
|
### bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_LiteralArray* arguments, Toy_LiteralArray* returns)
|
||||||
|
|
||||||
@@ -79,11 +82,11 @@ The literal `func` can be either a native function or a Toy function, but it won
|
|||||||
|
|
||||||
### bool Toy_callFn(Toy_Interpreter* interpreter, const char* name, Toy_LiteralArray* arguments, Toy_LiteralArray* returns)
|
### bool Toy_callFn(Toy_Interpreter* interpreter, const char* name, Toy_LiteralArray* arguments, Toy_LiteralArray* returns)
|
||||||
|
|
||||||
This utility function will find a `Toy_literal` within the `Toy_Interpreter`'s scope with a name that matches `name`, and will invoke it using `Toy_callLiteralFn` (passing in `arguments` and `returns` as expected).
|
This utility function will find a `Toy_literal` within the `Toy_Interpreter`'s scope with an identifier that matches `name`, and will invoke it using `Toy_callLiteralFn` (passing in `arguments` and `returns` as expected).
|
||||||
|
|
||||||
### bool Toy_parseIdentifierToValue(Toy_Interpreter* interpreter, Toy_Literal* literalPtr)
|
### bool Toy_parseIdentifierToValue(Toy_Interpreter* interpreter, Toy_Literal* literalPtr)
|
||||||
|
|
||||||
Sometimes, native functions will receive `Toy_Literal` identifiers instead of the values - the values can be retreived from the given interpreter's scope using the following pattern:
|
Sometimes, native functions will receive `Toy_Literal` identifiers instead of the values - the correct values can be retreived from the given interpreter's scope using the following pattern:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
Toy_Literal foobarIdn = foobar;
|
Toy_Literal foobarIdn = foobar;
|
||||||
@@ -102,6 +105,8 @@ static void printWrapper(const char* output) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note: The above is a very minor lie - in reality there are some preprocessor directives to allow the repl's `-n` flag to work.
|
||||||
|
|
||||||
### void Toy_setInterpreterAssert(Toy_Interpreter* interpreter, Toy_PrintFn assertOutput)
|
### void Toy_setInterpreterAssert(Toy_Interpreter* interpreter, Toy_PrintFn assertOutput)
|
||||||
|
|
||||||
This function sets the function called by the `assert` keyword on failure. By default, the following wrapper is used:
|
This function sets the function called by the `assert` keyword on failure. By default, the following wrapper is used:
|
||||||
@@ -121,4 +126,3 @@ static void errorWrapper(const char* output) {
|
|||||||
fprintf(stderr, "%s", output); //no newline
|
fprintf(stderr, "%s", output); //no newline
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
# toy_lexer.h
|
# toy_lexer.h
|
||||||
|
|
||||||
This header defines the structure `Toy_Lexer`, which can be bound to a piece of source code, and used to tokenize it within a parser.
|
This header defines the lexer and token structures, which can be bound to a piece of source code, and used to tokenize it within a parser.
|
||||||
|
|
||||||
## Defined Functions
|
## Defined Functions
|
||||||
|
|
||||||
@@ -8,3 +9,20 @@ This header defines the structure `Toy_Lexer`, which can be bound to a piece of
|
|||||||
|
|
||||||
This function initializes a lexer, binding it to the `source` parameter; the lexer is now ready to be passed to the parser.
|
This function initializes a lexer, binding it to the `source` parameter; the lexer is now ready to be passed to the parser.
|
||||||
|
|
||||||
|
### Toy_Token Toy_private_scanLexer(Toy_Lexer* lexer)
|
||||||
|
|
||||||
|
This function "scans" the lexer, returning a token to the parser.
|
||||||
|
|
||||||
|
Private functions are not intended for general use.
|
||||||
|
|
||||||
|
### void Toy_private_printToken(Toy_Token* token)
|
||||||
|
|
||||||
|
This function prints a given token to stdout.
|
||||||
|
|
||||||
|
Private functions are not intended for general use.
|
||||||
|
|
||||||
|
### void Toy_private_setComments(Toy_Lexer* lexer, bool enabled)
|
||||||
|
|
||||||
|
This function sets whether comments are allowed within source code. By default, comments are allowed, and are only disabled in the repl.
|
||||||
|
|
||||||
|
Private functions are not intended for general use.
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
|
|
||||||
# literal_array.h
|
# literal_array.h
|
||||||
|
|
||||||
This header defines the structure `Toy_LiteralArray`, which manages a series of `Toy_Literal` instances in sequential memory. The array does not take ownership of given literals, instead it makes an internal copy.
|
This header defines the array structure, which manages a series of `Toy_Literal` instances in sequential memory. The array does not take ownership of given literals, instead it makes an internal copy.
|
||||||
|
|
||||||
The array type is one of two fundemental data structures used throughout Toy - the other is the dictionary.
|
The array type is one of two fundemental data structures used throughout Toy - the other is the dictionary.
|
||||||
|
|
||||||
## Defined Functions
|
## Defined Functions
|
||||||
|
|
||||||
### void Toy_initLiteralArray(Toy_LiteralArray* array)
|
|
||||||
|
|
||||||
This function initializes a `Toy_LiteralArray` pointed to by `array`.
|
|
||||||
|
|
||||||
### void Toy_freeLiteralArray(Toy_LiteralArray* array)
|
### void Toy_freeLiteralArray(Toy_LiteralArray* array)
|
||||||
|
|
||||||
This function frees a `Toy_LiteralArray` pointed to by `array`. Every literal within is passed to `Toy_freeLiteral` before its memory is released.
|
This function frees a `Toy_LiteralArray` pointed to by `array`. Every literal within is passed to `Toy_freeLiteral()` before its memory is released.
|
||||||
|
|
||||||
### int Toy_pushLiteralArray(Toy_LiteralArray* array, Toy_Literal literal)
|
### int Toy_pushLiteralArray(Toy_LiteralArray* array, Toy_Literal literal)
|
||||||
|
|
||||||
@@ -36,3 +33,8 @@ This function returns the literal at the position represented by the integer lit
|
|||||||
|
|
||||||
If `index` is not an integer literal or is out of bounds, this function returns a null literal.
|
If `index` is not an integer literal or is out of bounds, this function returns a null literal.
|
||||||
|
|
||||||
|
### int Toy_private_findLiteralIndex(Toy_LiteralArray* array, Toy_Literal literal)
|
||||||
|
|
||||||
|
This function scans through the array, and returns the index of the first element that matches the given `literal`, otherwise it returns -1.
|
||||||
|
|
||||||
|
Private functions are not intended for general use.
|
||||||
|
|||||||
@@ -1,38 +1,50 @@
|
|||||||
|
|
||||||
# toy_literal_dictionary.h
|
# toy_literal_dictionary.h
|
||||||
|
|
||||||
This header defines the structure `Toy_LiteralDictionary`, which manages a series of `Toy_Literal` instances stored in a key-value hash map. The dictionary does not take ownership of given literals, instead it makes an internal copy.
|
This header defines the dictionary structure (as well as the private entry structure), which manages a series of `Toy_Literal` instances stored in a key-value hash map. The dictionary does not take ownership of given literals, instead it makes an internal copy.
|
||||||
|
|
||||||
The dictionary type is one of two fundemental data structures used throughout Toy - the other is the array.
|
The dictionary type is one of two fundemental data structures used throughout Toy - the other is the array.
|
||||||
|
|
||||||
|
## Defined Macros
|
||||||
|
|
||||||
|
### TOY_DICTIONARY_MAX_LOAD
|
||||||
|
|
||||||
|
If the contents of a dictionary exceeds this percentage of it's capacity, then a new buffer is created, the old contents are copied over one-by-one, and the original buffer is freed.
|
||||||
|
|
||||||
|
Since this process can be memory and time intensive, a configurable macro is used to allow for fine-grained control across the lang.
|
||||||
|
|
||||||
|
The current default value is `0.75`, representing 75% capacity.
|
||||||
|
|
||||||
## Defined Functions
|
## Defined Functions
|
||||||
|
|
||||||
### void Toy_initLiteralDictionary(Toy_LiteralDictionary* dictionary);
|
### void Toy_initLiteralDictionary(Toy_LiteralDictionary* dictionary)
|
||||||
|
|
||||||
This function initializes the `Toy_LiteralDictionary` pointed to by `dictionary`.
|
This function initializes the `Toy_LiteralDictionary` pointed to by `dictionary`.
|
||||||
|
|
||||||
### void Toy_freeLiteralDictionary(Toy_LiteralDictionary* dictionary);
|
### void Toy_freeLiteralDictionary(Toy_LiteralDictionary* dictionary)
|
||||||
|
|
||||||
This function frees a `Toy_LiteralDictionary` pointed to by `dictionary`. Every literal within is passed to `Toy_freeLiteral` before its memory is released.
|
This function frees a `Toy_LiteralDictionary` pointed to by `dictionary`. Every literal within is passed to `Toy_freeLiteral()` before its memory is released.
|
||||||
|
|
||||||
### void Toy_setLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key, Toy_Literal value);
|
### void Toy_setLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key, Toy_Literal value)
|
||||||
|
|
||||||
This function inserts the given key-value pair of literals into `dictionary`, creating it if it doesn't exist, or freeing and overwriting it if `key` is already present. This function may also expand the memory buffer if needed.
|
This function inserts the given key-value pair of literals into `dictionary`, creating it if it doesn't exist, or freeing and overwriting it if `key` is already present. This function may also expand the memory buffer if needed.
|
||||||
|
|
||||||
|
When expanding the memory buffer, a full copy of the existing dictionary's contents is created - this can be memory intensive.
|
||||||
|
|
||||||
Literal functions and opaques cannot be used as keys.
|
Literal functions and opaques cannot be used as keys.
|
||||||
|
|
||||||
### Toy_Literal Toy_getLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key);
|
### Toy_Literal Toy_getLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key)
|
||||||
|
|
||||||
This function returns the value of the literal within `dictionary` identified by `key`, or a null literal if it doesn't exist.
|
This function returns the value of the literal within `dictionary` identified by `key`, or a null literal if it doesn't exist.
|
||||||
|
|
||||||
Literal functions and opaques cannot be used as keys.
|
Literal functions and opaques cannot be used as keys.
|
||||||
|
|
||||||
### void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key);
|
### void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key)
|
||||||
|
|
||||||
This function removes the key-value pair of literals from `dictionary` identified by `key`, if it exists.
|
This function removes the key-value pair of literals from `dictionary` identified by `key`, if it exists.
|
||||||
|
|
||||||
Literal functions and opaques cannot be used as keys.
|
Literal functions and opaques cannot be used as keys.
|
||||||
|
|
||||||
### bool Toy_existsLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key);
|
### bool Toy_existsLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key)
|
||||||
|
|
||||||
This function returns true if the key-value pair identified by `key` exists within `dictionary`, otherwise it returns false.
|
This function returns true if the key-value pair identified by `key` exists within `dictionary`, otherwise it returns false.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
# toy_literal.h
|
# toy_literal.h
|
||||||
|
|
||||||
This header defines the structure `Toy_Literal`, which is used extensively throughout Toy to represent values of some kind.
|
This header defines the literal structure, 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.
|
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.
|
||||||
|
|
||||||
@@ -25,7 +26,9 @@ User data can be passed around within Toy as an opaque type - use the tag value
|
|||||||
* `TOY_LITERAL_OPAQUE`
|
* `TOY_LITERAL_OPAQUE`
|
||||||
* `TOY_LITERAL_ANY`
|
* `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.
|
These are the main 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.
|
||||||
|
|
||||||
|
Other type values are possible, but are only used internally.
|
||||||
|
|
||||||
## Defined Macros
|
## Defined Macros
|
||||||
|
|
||||||
@@ -45,7 +48,7 @@ The following macros are used to determine if a given literal, passed in as `val
|
|||||||
* `TOY_IS_TYPE(value)`
|
* `TOY_IS_TYPE(value)`
|
||||||
* `TOY_IS_OPAQUE(value)`
|
* `TOY_IS_OPAQUE(value)`
|
||||||
|
|
||||||
The following macros are used to cast a literal to a specific type to be used.
|
The following macros are used to cast a literal to a specific C type to be used.
|
||||||
|
|
||||||
* `TOY_AS_BOOLEAN(value)`
|
* `TOY_AS_BOOLEAN(value)`
|
||||||
* `TOY_AS_INTEGER(value)`
|
* `TOY_AS_INTEGER(value)`
|
||||||
@@ -98,13 +101,13 @@ The maximum length of a string in Toy, which is 4096 bytes by default. This can
|
|||||||
|
|
||||||
### TOY_HASH_I(lit)
|
### 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.
|
Identifiers are the names 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`.
|
This macro is only valid on `TOY_LITERAL_IDENTIFIER`.
|
||||||
|
|
||||||
### TOY_TYPE_PUSH_SUBTYPE(lit, subtype)
|
### 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.
|
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 returns the index of the newly pushed value within it's parent.
|
||||||
|
|
||||||
@@ -134,7 +137,7 @@ 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.
|
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.
|
Arrays or 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.
|
Functions and opaques are never equal to anything, while values with the type `TOY_LITERAL_ANY` are always equal.
|
||||||
|
|
||||||
@@ -161,3 +164,20 @@ 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.
|
This function is not thread safe - due to the loopy and recursive nature of printing compound values, this function uses some globally persistent variables.
|
||||||
|
|
||||||
|
### bool Toy_private_isTruthy(Toy_Literal x)
|
||||||
|
|
||||||
|
Utilized by the `TOY_IS_TRUTHY` macro.
|
||||||
|
|
||||||
|
Private functions are not intended for general use.
|
||||||
|
|
||||||
|
### bool Toy_private_toIdentifierLiteral(Toy_RefString* ptr)
|
||||||
|
|
||||||
|
Utilized by the `TOY_TO_IDENTIFIER_LITERAL` macro.
|
||||||
|
|
||||||
|
Private functions are not intended for general use.
|
||||||
|
|
||||||
|
### bool Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype)
|
||||||
|
|
||||||
|
Utilized by the `TOY_TYPE_PUSH_SUBTYPE` macro.
|
||||||
|
|
||||||
|
Private functions are not intended for general use.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
# toy_memory.h
|
# toy_memory.h
|
||||||
|
|
||||||
This header defines all of the memory management utilities. Any and all heap-based memory management goes through these utilities.
|
This header defines all of the memory management utilities. Any and all heap-based memory management goes through these utilities.
|
||||||
@@ -14,29 +15,23 @@ This macro calculates, in place, what size of memory should be allocated based o
|
|||||||
|
|
||||||
This macro calculates, in place, what size of memory should be allocated based on the previous size. It grows faster than `TOY_GROW_CAPACITY`.
|
This macro calculates, in place, what size of memory should be allocated based on the previous size. It grows faster than `TOY_GROW_CAPACITY`.
|
||||||
|
|
||||||
### TOY_ALLOCATE(type, count)
|
|
||||||
|
|
||||||
This macro wraps `Toy_reallocate`, which itself calls the allocator function. `type` is the type that will be allocated, and `count` is the number which will be needed (usually calculated with `TOY_GROW_CAPACITY`).
|
|
||||||
|
|
||||||
This returns a pointer of `type`.
|
|
||||||
|
|
||||||
### TOY_FREE(type, pointer)
|
### TOY_FREE(type, pointer)
|
||||||
|
|
||||||
This macro wraps `Toy_reallocate`, which itself calls the allocator function. `type` is the type that will be freed, and `pointer` is to what is being freed. This should only be used when a single element has been allocated, as opposed to an array.
|
This macro wraps `Toy_reallocate()`, which itself calls the allocator function. `type` is the type that will be freed, and `pointer` is to what is being freed. This should only be used when a single element has been allocated, as opposed to an array.
|
||||||
|
|
||||||
### TOY_FREE_ARRAY(type, pointer, oldCount)
|
### TOY_FREE_ARRAY(type, pointer, oldCount)
|
||||||
|
|
||||||
This macro wraps `Toy_reallocate`, which itself calls the allocator function. `type` is the type that will be freed, `pointer` is a reference to what is being freed, and `oldCount` is the size of the array being freed. This should only be used when an array has been allocated, as opposed to a single element.
|
This macro wraps `Toy_reallocate()`, which itself calls the allocator function. `type` is the type that will be freed, `pointer` is a reference to what is being freed, and `oldCount` is the size of the array being freed. This should only be used when an array has been allocated, as opposed to a single element.
|
||||||
|
|
||||||
### TOY_GROW_ARRAY(type, pointer, oldCount, count)
|
### TOY_GROW_ARRAY(type, pointer, oldCount, count)
|
||||||
|
|
||||||
This macro wraps `Toy_reallocate`, which itself calls the allocator function. `type` is the type that is being operated on, `pointer` is what is being resized, `oldCount` is the previous size of the array and `count` is the new size of the array (usually calculated with `TOY_GROW_CAPACITY`).
|
This macro wraps `Toy_reallocate()`, which itself calls the allocator function. `type` is the type that is being operated on, `pointer` is what is being resized, `oldCount` is the previous size of the array and `count` is the new size of the array (usually calculated with `TOY_GROW_CAPACITY`).
|
||||||
|
|
||||||
This returns a pointer of `type`.
|
This returns a pointer of `type`.
|
||||||
|
|
||||||
### TOY_SHRINK_ARRAY(type, pointer, oldCount, count)
|
### TOY_SHRINK_ARRAY(type, pointer, oldCount, count)
|
||||||
|
|
||||||
This macro wraps `Toy_reallocate`, which itself calls the allocator function. `type` is the type that is being operated on, `pointer` is what is being resized, `oldCount` is the previous size of the array and `count` is the new size of the array.
|
This macro wraps `Toy_reallocate()`, which itself calls the allocator function. `type` is the type that is being operated on, `pointer` is what is being resized, `oldCount` is the previous size of the array and `count` is the new size of the array.
|
||||||
|
|
||||||
This returns a pointer of `type`.
|
This returns a pointer of `type`.
|
||||||
|
|
||||||
@@ -66,5 +61,4 @@ This function wraps a call to the internal assigned memory allocator.
|
|||||||
|
|
||||||
This function sets the memory allocator, replacing the default memory allocator.
|
This function sets the memory allocator, replacing the default memory allocator.
|
||||||
|
|
||||||
This function also overwrites any given refstring memory allocator, see [toy_refstring.h](toy_refstring_h.md).
|
This function also overwrites any given refstring and reffunction memory allocators, see [toy_refstring.h](toy_refstring_h.md).
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
# toy_parser.h
|
# toy_parser.h
|
||||||
|
|
||||||
This header defines the structure `Toy_Parser` which, after being initialized with a `Toy_Lexer` produces a series of abstract syntax trees to be passed to the `Toy_Compiler`. The following is a utility function provided by [repl_tools.h](repl_tools_h.md), demonstrating how to use the parser.
|
This header defines the parser structure which, after being initialized with a lexer produces a series of abstract syntax trees to be passed to the compiler. The following is a utility function provided by [repl_tools.h](repl_tools_h.md), demonstrating how to use the parser.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
//generate bytecode from a given string
|
//generate bytecode from a given string
|
||||||
@@ -60,7 +61,7 @@ This function frees a `Toy_Parser` once its task is completed.
|
|||||||
|
|
||||||
### Toy_ASTNode* Toy_scanParser(Toy_Parser* parser)
|
### Toy_ASTNode* Toy_scanParser(Toy_Parser* parser)
|
||||||
|
|
||||||
This function returns an abstract syntax tree representing part of the program, or an error node. The abstract syntax tree must be passed to `Toy_writeCompiler` and/or `Toy_freeASTNode`.
|
This function returns an abstract syntax tree representing part of the program, or an error node. The abstract syntax tree must be passed to `Toy_writeCompiler()` and/or `Toy_freeASTNode()`.
|
||||||
|
|
||||||
This function should be called repeatedly until it returns `NULL`, indicating the end of the program.
|
This function should be called repeatedly until it returns `NULL`, indicating the end of the program.
|
||||||
|
|
||||||
@@ -69,4 +70,3 @@ This function should be called repeatedly until it returns `NULL`, indicating th
|
|||||||
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.
|
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.
|
Note: this function is *actually* defined in toy_ast_node.h, but documented here, because this is where it matters most.
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
# toy_reffunction.h
|
# toy_reffunction.h
|
||||||
|
|
||||||
This header defines the structure `Toy_RefFunction`, as well as all of the related utilities.
|
This header defines the Toy_RefFunction structure, as well as all of the related utilities.
|
||||||
|
|
||||||
See [toy_RefString](toy_refstring_h.md) for more information about the reference pattern.
|
See [Toy_RefString](toy_refstring_h.md) for more information about the reference pattern.
|
||||||
|
|
||||||
This module reserves the right to instead preform a deep copy when it sees fit (this is for future debugging purposes).
|
This module reserves the right to instead preform a deep copy when it sees fit (this is for future debugging purposes).
|
||||||
|
|
||||||
@@ -10,13 +11,13 @@ This module reserves the right to instead preform a deep copy when it sees fit (
|
|||||||
|
|
||||||
### typedef void* (*Toy_RefFunctionAllocatorFn)(void* pointer, size_t oldSize, size_t newSize)
|
### typedef void* (*Toy_RefFunctionAllocatorFn)(void* pointer, size_t oldSize, size_t newSize)
|
||||||
|
|
||||||
This interface conforms to Toy's memory API, and generally shouldn't be used.
|
This interface conforms to Toy's memory API, and generally shouldn't be used without a good reason.
|
||||||
|
|
||||||
## Defined Functions
|
## Defined Functions
|
||||||
|
|
||||||
### void Toy_setRefFunctionAllocatorFn(Toy_RefFunctionAllocatorFn)
|
### void Toy_setRefFunctionAllocatorFn(Toy_RefFunctionAllocatorFn)
|
||||||
|
|
||||||
This function conforms to and is invoked by Toy's memory API, and generally shouldn't be used.
|
This function conforms to and is invoked by Toy's memory API, and generally shouldn't be used without a good reason.
|
||||||
|
|
||||||
### Toy_RefFunction* Toy_createRefFunction(const void* data, size_t length)
|
### Toy_RefFunction* Toy_createRefFunction(const void* data, size_t length)
|
||||||
|
|
||||||
@@ -40,7 +41,8 @@ This function returns the length of the underlying bytecode of `refFunction`.
|
|||||||
|
|
||||||
This function increases the reference counter of `refFunction` by 1, before returning the given pointer.
|
This function increases the reference counter of `refFunction` by 1, before returning the given pointer.
|
||||||
|
|
||||||
|
This function reserves the right to create a deep copy where needed.
|
||||||
|
|
||||||
### Toy_RefFunction* Toy_deepCopyRefFunction(Toy_RefFunction* refFunction)
|
### Toy_RefFunction* Toy_deepCopyRefFunction(Toy_RefFunction* refFunction)
|
||||||
|
|
||||||
This function behaves identically to `Toy_copyRefFunction`, except that it explicitly preforms a deep copy of the internal memory. Using this function should be done carefully, as it incurs a performance penalty that negates the benefit of this module.
|
This function behaves identically to `Toy_copyRefFunction`, except that it explicitly forces a deep copy of the internal memory. Using this function should be done carefully, as it incurs a performance penalty that negates the benefit of this module.
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
# toy_refstring.h
|
# toy_refstring.h
|
||||||
|
|
||||||
This header defines the structure `Toy_RefString`, as well as all of the related utilities.
|
This header defines the structure `Toy_RefString`, as well as all of the related utilities.
|
||||||
@@ -15,13 +16,13 @@ This module reserves the right to instead preform a deep copy when it sees fit (
|
|||||||
|
|
||||||
### typedef void* (*Toy_RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize)
|
### typedef void* (*Toy_RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize)
|
||||||
|
|
||||||
This interface conforms to Toy's memory API, and generally shouldn't be used.
|
This interface conforms to Toy's memory API, and generally shouldn't be used without a good reason.
|
||||||
|
|
||||||
## Defined Functions
|
## Defined Functions
|
||||||
|
|
||||||
### void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn)
|
### void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn)
|
||||||
|
|
||||||
This function conforms to and is invoked by Toy's memory API, and generally shouldn't be used.
|
This function conforms to and is invoked by Toy's memory API, and generally shouldn't be used without a good reason.
|
||||||
|
|
||||||
### Toy_RefString* Toy_createRefString(const char* cstring)
|
### Toy_RefString* Toy_createRefString(const char* cstring)
|
||||||
|
|
||||||
@@ -49,9 +50,11 @@ This function returns the length of the underlying cstring of `refString`.
|
|||||||
|
|
||||||
This function increases the reference counter of `refString` by 1, before returning the given pointer.
|
This function increases the reference counter of `refString` by 1, before returning the given pointer.
|
||||||
|
|
||||||
|
This function reserves the right to create a deep copy where needed.
|
||||||
|
|
||||||
### Toy_RefString* Toy_deepCopyRefString(Toy_RefString* refString)
|
### Toy_RefString* Toy_deepCopyRefString(Toy_RefString* refString)
|
||||||
|
|
||||||
This function behaves identically to `Toy_copyRefString`, except that it explicitly preforms a deep copy of the internal memory. Using this function should be done carefully, as it incurs a performance penalty that negates the benefit of this module.
|
This function behaves identically to `Toy_copyRefString`, except that it explicitly forces a deep copy of the internal memory. Using this function should be done carefully, as it incurs a performance penalty that negates the benefit of this module.
|
||||||
|
|
||||||
### const char* Toy_toCString(Toy_RefString* refString)
|
### const char* Toy_toCString(Toy_RefString* refString)
|
||||||
|
|
||||||
@@ -64,4 +67,3 @@ This function returns true when the two refstrings are either the same refstring
|
|||||||
### bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring)
|
### bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring)
|
||||||
|
|
||||||
This function returns true when the `refString` contains the same value as the `cstring`. Otherwise it returns false.
|
This function returns true when the `refString` contains the same value as the `cstring`. Otherwise it returns false.
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
|
|
||||||
# toy_scope.h
|
# toy_scope.h
|
||||||
|
|
||||||
This header defines the `Toy_Scope` structure, which stores all of the variables used within a given block of code.
|
This header defines the scope structure, which stores all of the variables used within a given block of code.
|
||||||
|
|
||||||
Scopes are arranged into a linked list of ancestors, each of which is reference counted. When a scope is popped off the end of the chain, every ancestor scope has it's reference counter reduced by 1 and, if any reach 0, they are freed.
|
Scopes are arranged into a linked list of ancestors, each of which is reference counted. When a scope is popped off the end of the chain, every ancestor scope has it's reference counter reduced by 1 and, if any reach 0, they are freed.
|
||||||
|
|
||||||
|
This is also where Toy's type system lives.
|
||||||
|
|
||||||
## Defined Functions
|
## Defined Functions
|
||||||
|
|
||||||
### Toy_Scope* Toy_pushScope(Toy_Scope* scope)
|
### Toy_Scope* Toy_pushScope(Toy_Scope* scope)
|
||||||
@@ -18,6 +21,8 @@ This function frees the given `scope`, and returns it's ancestor.
|
|||||||
|
|
||||||
This function copies an existing scope, and returns the copy.
|
This function copies an existing scope, and returns the copy.
|
||||||
|
|
||||||
|
This copies the internal dictionaries, so it can be memory intensive.
|
||||||
|
|
||||||
### bool Toy_declareScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal type)
|
### bool Toy_declareScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal type)
|
||||||
|
|
||||||
This function declares a new variable `key` within `scope`, giving it the type of `type`.
|
This function declares a new variable `key` within `scope`, giving it the type of `type`.
|
||||||
@@ -43,4 +48,3 @@ This function returns true on success, otherwise it returns false.
|
|||||||
### Toy_Literal Toy_getScopeType(Toy_Scope* scope, Toy_Literal key)
|
### Toy_Literal Toy_getScopeType(Toy_Scope* scope, Toy_Literal key)
|
||||||
|
|
||||||
This function returns a new `Toy_Literal` representing the type of the variable named `key`.
|
This function returns a new `Toy_Literal` representing the type of the variable named `key`.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user