Added CONTRIBUTING.md

Also renamed 'handles' throughout the project for consistency.

Some meta files also had their file extensions added.
This commit is contained in:
2024-10-05 06:04:17 +10:00
parent 29f5647e31
commit d19a90f9bd
20 changed files with 415 additions and 287 deletions

View File

@@ -1,3 +0,0 @@
Add these to the docs somewhere:
double pointers are referred to as handles

129
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,129 @@
# Welcome to the Toy Programming Language
I'm extremely appreciative to have people contribute their time and expertise towards this project. Before I get into the details, let me give some high level goals:
* Toy is intended to work as an embedded scripting language inside a game engine, tentatively titled "Box".
* Toy's goal is to allow for a great degree of modability for any games developed with the Box engine.
* As such, using Toy itself should be easy for novice and veteran coders.
* Toy is developed with a focus on speed, efficient resource management, and portability.
* Toy should be a source of fun for everyone working on and using it.
# Where to Start
First, the main development branch of Toy is 'v2', with the branches 'v1' and 'v1-docs' kept for reference.
v2 is a ground-up rewrite, with additions, changes and deletions to the language that make sense. If you want to discuss the direction things are going, the [Discussions Tab](https://github.com/Ratstail91/Toy/discussions) is perfect for that.
The [Issue Tracker](https://github.com/Ratstail91/Toy/issues) is a good place to see what tasks and issues are currently waiting to be addressed. The [toy.h](https://github.com/Ratstail91/Toy/blob/v2/source/toy.h) source file is a quick way to see what building blocks are available in the source code. There are also a number of comments prepended with `TODO:` scattered throughout the source code, as reminders of planned features.
The [test cases](https://github.com/Ratstail91/Toy/tree/v2/tests/cases), which test individual parts of the code in isolation, can be a good way to see how those parts are used. Likewise, the [REPL](https://github.com/Ratstail91/Toy/tree/v2/repl) shows a practical usage of Toy.
*v2 is under heavy development, and as such may not be in a working state yet. Your patience and feedback can help, but missing features such as a documentation website are coming, eventually.*
# Building Blocks
These data structures should be as independent as they can be, but there are some dependencies:
```mermaid
graph TB
Toy_Value ---> Toy_Stack
Toy_Array
Toy_Bucket ---> Toy_String
Toy_Value ---> Toy_Table
```
*TODO: Toy_Value will eventually depend on other structures, includeing those shown here, once the related features are implemented in v2.*
In addition, [toy_common.h](https://github.com/Ratstail91/Toy/blob/v2/source/toy_common.h) grants platform portability and version info, while [toy_console_colors.h](https://github.com/Ratstail91/Toy/blob/v2/source/toy_console_colors.h) provides string constants as macros that help with console output (where supported).
# Coding Habits
Here's a few coding habits that I use to keep the source code consistent. While I'd prefer contributors to follow these, breaking these guidelines are ok if you need to.
## Testing The Language
When adding a new piece of code, it must be thoroughly tested via a [test case](https://github.com/Ratstail91/Toy/tree/v2/tests/cases). If it has multiple features, they should be tested individually, and in combination with each other. Any kind of corner case which can cause an issue on any supported platform must be resolved (I'm happy to help with this, if needed).
This is probably the most important habit listed here. While I'm not too fussy as to how the tests are written, they do need to prove that the code works flawlessly. Toy is intended to be used by others (potentially many others), so please write simple and straight forward tests to ensure correctness.
## Tabs, 4 Characters Wide
I use tabs over spaces, with a width of 4. I don't have a linter, please don't make me use one.
## Error Messages
Fatal errors have this general format:
```c
fprintf(stderr, TOY_CC_ERROR "ERROR: [Info]\n" TOY_CC_RESET);
exit(-1);
```
The use of `fprintf()` will ensure the error is written to the console, and allows extra information to be printed - just replace `[Info]` with the relevant output. These kinds of fatal errors are intended to catch issues with the language itself, rather than errors in the Toy scripts.
In the test cases, the `exit(-1)` is instead replaced with `return -1` to allow `main()` to clean up that test set, and run others if needed.
## Naming Things
To ensure integrating Toy as an external library is easy, any functions that are intended for use should be:
* Marked with the macro `TOY_API`
* Prepended with `Toy_`
* Be named with lowerCamelCase
* Begin their name with a verb
Likewise, publicly visible structures should be:
* Prepended with `Toy_`
* Be named with UpperCamelCase
If you use a macro, ensure it is all uppercase, and prepended with `TOY_`. If there's a function that is exposed, but is intended to be used within a macro, prepending its name with `Toy_private_` is a good idea.
e.g.
```c
#include "toy_common.h"
typedef struct Toy_Thing {
int member;
} Toy_Thing;
TOY_API void Toy_useThing();
#define TOY_USE_OTHER_THING() Toy_private_useOtherThing()
TOY_API void Toy_private_useOtherThing();
```
## Data Type Sizes
Within `toy_common.h`, the macro `TOY_BITNESS` is defined as either 32 or 64, depending on if Toy is compiled for 32 or 64 bit platforms (if it doesn't recognise a platform, it is set to -1).
Most, if not all the structures within Toy where memory layout is important have some comments indicating their sizes in memory based on bitness. These comments are only a guide, and should NOT be taken as gospel, but they're useful for thinking about how the data is laid out in memory. Spaces are used to line them up.
```c
//Copied from toy_stack.h
typedef struct Toy_Stack { //32 | 64 BITNESS
unsigned int capacity; //4 | 4
unsigned int count; //4 | 4
char data[]; //- | -
} Toy_Stack; //8 | 8
```
## Single and Double Pointers
Double pointers are used quite often, especially when a function performs some kind of operation on a structure itself, rather than just its data. I refer to these as "handles", and are usually named as such.
## Directories
The directories in the repository's root have certain intended uses. If you find a folder which is empty except for a file named `.gitkeep`, leave it be, as that file is simply used to retain that directory within git for later use.
| Directory | Intended Use |
| --- | --- |
| .github | Meta information used by GitHub, such as CI workflows and issue templates. |
| .notes | General storage for any kind of scratch notes or reminders, or random bits of source code that aren't needed. Rough ideas and plans are usually found here, but may be outdated. |
| lib | The source directory for various libraries external to Toy, but which can be made available by the host and accessed with the `import` keyword. |
| scripts | Storage for various example scripts written in Toy that can be loaded and executed by the repl. |
| source | The source directory for the core of the Toy programming language. |
| tests | The source directory for the testing systems. Within, `cases/` is used for test cases, `benchmarks/` for benchmarking, etc. |
| tools | The source directory for various external tools. |

View File

View File

@@ -39,10 +39,12 @@ To build and run the test cases under gdb, run `make tests-gdb`.
# License
This source code is covered by the zlib license (see [LICENSE](LICENSE)).
This source code is covered by the zlib license (see [LICENSE.md](LICENSE.md)).
# Contributors and Special Thanks
For a guide on how you can contribute, see [CONTRIBUTING.md](CONTRIBUTING.md).
@hiperiondev - v1 Disassembler, v1 porting support and feedback
@add00 - v1 Library support
@gruelingpine185 - Unofficial v1 MacOS support

View File

@@ -1,17 +1,17 @@
#include "toy_ast.h"
void Toy_private_initAstBlock(Toy_Bucket** bucket, Toy_Ast** handle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast));
void Toy_private_initAstBlock(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_BLOCK;
tmp->block.child = NULL;
tmp->block.next = NULL;
tmp->block.tail = NULL;
(*handle) = tmp;
(*astHandle) = tmp;
}
void Toy_private_appendAstBlock(Toy_Bucket** bucket, Toy_Ast* block, Toy_Ast* child) {
void Toy_private_appendAstBlock(Toy_Bucket** bucketHandle, Toy_Ast* block, Toy_Ast* child) {
//first, check if we're an empty head
if (block->block.child == NULL) {
block->block.child = child;
@@ -26,72 +26,72 @@ void Toy_private_appendAstBlock(Toy_Bucket** bucket, Toy_Ast* block, Toy_Ast* ch
}
//append a new link to the chain
Toy_private_initAstBlock(bucket, &(iter->block.next));
Toy_private_initAstBlock(bucketHandle, &(iter->block.next));
//store the child in the new link, prep the tail pointer
iter->block.next->block.child = child;
block->block.tail = iter->block.next;
}
void Toy_private_emitAstValue(Toy_Bucket** bucket, Toy_Ast** handle, Toy_Value value) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast));
void Toy_private_emitAstValue(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Value value) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_VALUE;
tmp->value.value = value;
(*handle) = tmp;
(*astHandle) = tmp;
}
void Toy_private_emitAstUnary(Toy_Bucket** bucket, Toy_Ast** handle, Toy_AstFlag flag) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast));
void Toy_private_emitAstUnary(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_AstFlag flag) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_UNARY;
tmp->unary.flag = flag;
tmp->unary.child = *handle;
tmp->unary.child = *astHandle;
(*handle) = tmp;
(*astHandle) = tmp;
}
void Toy_private_emitAstBinary(Toy_Bucket** bucket, Toy_Ast** handle, Toy_AstFlag flag, Toy_Ast* right) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast));
void Toy_private_emitAstBinary(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_AstFlag flag, Toy_Ast* right) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_BINARY;
tmp->binary.flag = flag;
tmp->binary.left = *handle; //left-recursive
tmp->binary.left = *astHandle; //left-recursive
tmp->binary.right = right;
(*handle) = tmp;
(*astHandle) = tmp;
}
void Toy_private_emitAstGroup(Toy_Bucket** bucket, Toy_Ast** handle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast));
void Toy_private_emitAstGroup(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_GROUP;
tmp->group.child = (*handle);
tmp->group.child = (*astHandle);
(*handle) = tmp;
(*astHandle) = tmp;
}
void Toy_private_emitAstPass(Toy_Bucket** bucket, Toy_Ast** handle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast));
void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_PASS;
(*handle) = tmp;
(*astHandle) = tmp;
}
void Toy_private_emitAstError(Toy_Bucket** bucket, Toy_Ast** handle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast));
void Toy_private_emitAstError(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_ERROR;
(*handle) = tmp;
(*astHandle) = tmp;
}
void Toy_private_emitAstEnd(Toy_Bucket** bucket, Toy_Ast** handle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast));
void Toy_private_emitAstEnd(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_END;
(*handle) = tmp;
(*astHandle) = tmp;
}

View File

@@ -110,14 +110,14 @@ union Toy_Ast { //32 | 64 BITNESS
Toy_AstEnd end; //4 | 4
}; //16 | 32
void Toy_private_initAstBlock(Toy_Bucket** bucket, Toy_Ast** handle);
void Toy_private_appendAstBlock(Toy_Bucket** bucket, Toy_Ast* block, Toy_Ast* child);
void Toy_private_initAstBlock(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_appendAstBlock(Toy_Bucket** bucketHandle, Toy_Ast* block, Toy_Ast* child);
void Toy_private_emitAstValue(Toy_Bucket** bucket, Toy_Ast** handle, Toy_Value value);
void Toy_private_emitAstUnary(Toy_Bucket** bucket, Toy_Ast** handle, Toy_AstFlag flag);
void Toy_private_emitAstBinary(Toy_Bucket** bucket, Toy_Ast** handle,Toy_AstFlag flag, Toy_Ast* right);
void Toy_private_emitAstGroup(Toy_Bucket** bucket, Toy_Ast** handle);
void Toy_private_emitAstValue(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Value value);
void Toy_private_emitAstUnary(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_AstFlag flag);
void Toy_private_emitAstBinary(Toy_Bucket** bucketHandle, Toy_Ast** astHandle,Toy_AstFlag flag, Toy_Ast* right);
void Toy_private_emitAstGroup(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstPass(Toy_Bucket** bucket, Toy_Ast** handle);
void Toy_private_emitAstError(Toy_Bucket** bucket, Toy_Ast** handle);
void Toy_private_emitAstEnd(Toy_Bucket** bucket, Toy_Ast** handle);
void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstError(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstEnd(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);

View File

@@ -97,7 +97,7 @@ typedef enum ParsingPrecedence {
PREC_PRIMARY,
} ParsingPrecedence;
typedef Toy_AstFlag (*ParsingRule)(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root);
typedef Toy_AstFlag (*ParsingRule)(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
typedef struct ParsingTuple {
ParsingPrecedence precedence;
@@ -105,12 +105,12 @@ typedef struct ParsingTuple {
ParsingRule infix;
} ParsingTuple;
static void parsePrecedence(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root, ParsingPrecedence precRule);
static void parsePrecedence(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle, ParsingPrecedence precRule);
static Toy_AstFlag atomic(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root);
static Toy_AstFlag unary(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root);
static Toy_AstFlag binary(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root);
static Toy_AstFlag group(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root);
static Toy_AstFlag atomic(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
static Toy_AstFlag unary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
static Toy_AstFlag binary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
static Toy_AstFlag group(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
//precedence definitions
static ParsingTuple parsingRulesetTable[] = {
@@ -214,18 +214,18 @@ static ParsingTuple parsingRulesetTable[] = {
{PREC_NONE,NULL,NULL},// TOY_TOKEN_EOF,
};
static Toy_AstFlag atomic(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
static Toy_AstFlag atomic(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
switch(parser->previous.type) {
case TOY_TOKEN_NULL:
Toy_private_emitAstValue(bucket, root, TOY_VALUE_TO_NULL());
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_NULL());
return TOY_AST_FLAG_NONE;
case TOY_TOKEN_LITERAL_TRUE:
Toy_private_emitAstValue(bucket, root, TOY_VALUE_TO_BOOLEAN(true));
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_BOOLEAN(true));
return TOY_AST_FLAG_NONE;
case TOY_TOKEN_LITERAL_FALSE:
Toy_private_emitAstValue(bucket, root, TOY_VALUE_TO_BOOLEAN(false));
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_BOOLEAN(false));
return TOY_AST_FLAG_NONE;
case TOY_TOKEN_LITERAL_INTEGER: {
@@ -241,7 +241,7 @@ static Toy_AstFlag atomic(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** roo
int value = 0;
sscanf(buffer, "%d", &value);
Toy_private_emitAstValue(bucket, root, TOY_VALUE_TO_INTEGER(value));
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_INTEGER(value));
return TOY_AST_FLAG_NONE;
}
@@ -258,173 +258,173 @@ static Toy_AstFlag atomic(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** roo
float value = 0;
sscanf(buffer, "%f", &value);
Toy_private_emitAstValue(bucket, root, TOY_VALUE_TO_FLOAT(value));
Toy_private_emitAstValue(bucketHandle, rootHandle, TOY_VALUE_TO_FLOAT(value));
return TOY_AST_FLAG_NONE;
}
default:
printError(parser, parser->previous, "Unexpected token passed to atomic precedence rule");
Toy_private_emitAstError(bucket, root);
Toy_private_emitAstError(bucketHandle, rootHandle);
return TOY_AST_FLAG_NONE;
}
}
static Toy_AstFlag unary(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
static Toy_AstFlag unary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
//'subtract' can only be applied to numbers and groups, while 'negate' can only be applied to booleans and groups
//this function takes the libery of peeking into the uppermost node, to see if it can apply this to it
if (parser->previous.type == TOY_TOKEN_OPERATOR_SUBTRACT) {
bool connectedDigit = parser->previous.lexeme[1] >= '0' && parser->previous.lexeme[1] <= '9'; //BUGFIX: '- 1' should not be optimised into a negative
parsePrecedence(bucket, parser, root, PREC_UNARY);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_UNARY);
//negative numbers
if ((*root)->type == TOY_AST_VALUE && TOY_VALUE_IS_INTEGER((*root)->value.value) && connectedDigit) {
(*root)->value.value = TOY_VALUE_TO_INTEGER( -TOY_VALUE_AS_INTEGER((*root)->value.value) );
if ((*rootHandle)->type == TOY_AST_VALUE && TOY_VALUE_IS_INTEGER((*rootHandle)->value.value) && connectedDigit) {
(*rootHandle)->value.value = TOY_VALUE_TO_INTEGER( -TOY_VALUE_AS_INTEGER((*rootHandle)->value.value) );
}
else if ((*root)->type == TOY_AST_VALUE && TOY_VALUE_IS_FLOAT((*root)->value.value) && connectedDigit) {
(*root)->value.value = TOY_VALUE_TO_FLOAT( -TOY_VALUE_AS_FLOAT((*root)->value.value) );
else if ((*rootHandle)->type == TOY_AST_VALUE && TOY_VALUE_IS_FLOAT((*rootHandle)->value.value) && connectedDigit) {
(*rootHandle)->value.value = TOY_VALUE_TO_FLOAT( -TOY_VALUE_AS_FLOAT((*rootHandle)->value.value) );
}
else {
//actually emit the negation node
Toy_private_emitAstUnary(bucket, root, TOY_AST_FLAG_NEGATE);
Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_NEGATE);
}
}
else if (parser->previous.type == TOY_TOKEN_OPERATOR_NEGATE) {
parsePrecedence(bucket, parser, root, PREC_UNARY);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_UNARY);
//inverted booleans
if ((*root)->type == TOY_AST_VALUE && TOY_VALUE_IS_BOOLEAN((*root)->value.value)) {
(*root)->value.value = TOY_VALUE_TO_BOOLEAN( !TOY_VALUE_AS_BOOLEAN((*root)->value.value) );
if ((*rootHandle)->type == TOY_AST_VALUE && TOY_VALUE_IS_BOOLEAN((*rootHandle)->value.value)) {
(*rootHandle)->value.value = TOY_VALUE_TO_BOOLEAN( !TOY_VALUE_AS_BOOLEAN((*rootHandle)->value.value) );
}
else {
//actually emit the negation node
Toy_private_emitAstUnary(bucket, root, TOY_AST_FLAG_NEGATE);
Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_NEGATE);
}
}
else {
printError(parser, parser->previous, "Unexpected token passed to unary precedence rule");
Toy_private_emitAstError(bucket, root);
Toy_private_emitAstError(bucketHandle, rootHandle);
}
return TOY_AST_FLAG_NONE;
}
static Toy_AstFlag binary(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
static Toy_AstFlag binary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
//infix must advance
advance(parser);
switch(parser->previous.type) {
//arithmetic
case TOY_TOKEN_OPERATOR_ADD: {
parsePrecedence(bucket, parser, root, PREC_TERM + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_TERM + 1);
return TOY_AST_FLAG_ADD;
}
case TOY_TOKEN_OPERATOR_SUBTRACT: {
parsePrecedence(bucket, parser, root, PREC_TERM + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_TERM + 1);
return TOY_AST_FLAG_SUBTRACT;
}
case TOY_TOKEN_OPERATOR_MULTIPLY: {
parsePrecedence(bucket, parser, root, PREC_FACTOR + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_FACTOR + 1);
return TOY_AST_FLAG_MULTIPLY;
}
case TOY_TOKEN_OPERATOR_DIVIDE: {
parsePrecedence(bucket, parser, root, PREC_FACTOR + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_FACTOR + 1);
return TOY_AST_FLAG_DIVIDE;
}
case TOY_TOKEN_OPERATOR_MODULO: {
parsePrecedence(bucket, parser, root, PREC_FACTOR + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_FACTOR + 1);
return TOY_AST_FLAG_MODULO;
}
//assignment
case TOY_TOKEN_OPERATOR_ASSIGN: {
parsePrecedence(bucket, parser, root, PREC_ASSIGNMENT + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_ASSIGNMENT + 1);
return TOY_AST_FLAG_ASSIGN;
}
case TOY_TOKEN_OPERATOR_ADD_ASSIGN: {
parsePrecedence(bucket, parser, root, PREC_ASSIGNMENT + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_ASSIGNMENT + 1);
return TOY_AST_FLAG_ADD_ASSIGN;
}
case TOY_TOKEN_OPERATOR_SUBTRACT_ASSIGN: {
parsePrecedence(bucket, parser, root, PREC_ASSIGNMENT + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_ASSIGNMENT + 1);
return TOY_AST_FLAG_SUBTRACT_ASSIGN;
}
case TOY_TOKEN_OPERATOR_MULTIPLY_ASSIGN: {
parsePrecedence(bucket, parser, root, PREC_ASSIGNMENT + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_ASSIGNMENT + 1);
return TOY_AST_FLAG_MULTIPLY_ASSIGN;
}
case TOY_TOKEN_OPERATOR_DIVIDE_ASSIGN: {
parsePrecedence(bucket, parser, root, PREC_ASSIGNMENT + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_ASSIGNMENT + 1);
return TOY_AST_FLAG_DIVIDE_ASSIGN;
}
case TOY_TOKEN_OPERATOR_MODULO_ASSIGN: {
parsePrecedence(bucket, parser, root, PREC_ASSIGNMENT + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_ASSIGNMENT + 1);
return TOY_AST_FLAG_MODULO_ASSIGN;
}
//comparison
case TOY_TOKEN_OPERATOR_COMPARE_EQUAL: {
parsePrecedence(bucket, parser, root, PREC_COMPARISON + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_COMPARISON + 1);
return TOY_AST_FLAG_COMPARE_EQUAL;
}
case TOY_TOKEN_OPERATOR_COMPARE_NOT: {
parsePrecedence(bucket, parser, root, PREC_COMPARISON + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_COMPARISON + 1);
return TOY_AST_FLAG_COMPARE_NOT;
}
case TOY_TOKEN_OPERATOR_COMPARE_LESS: {
parsePrecedence(bucket, parser, root, PREC_COMPARISON + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_COMPARISON + 1);
return TOY_AST_FLAG_COMPARE_LESS;
}
case TOY_TOKEN_OPERATOR_COMPARE_LESS_EQUAL: {
parsePrecedence(bucket, parser, root, PREC_COMPARISON + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_COMPARISON + 1);
return TOY_AST_FLAG_COMPARE_LESS_EQUAL;
}
case TOY_TOKEN_OPERATOR_COMPARE_GREATER: {
parsePrecedence(bucket, parser, root, PREC_COMPARISON + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_COMPARISON + 1);
return TOY_AST_FLAG_COMPARE_GREATER;
}
case TOY_TOKEN_OPERATOR_COMPARE_GREATER_EQUAL: {
parsePrecedence(bucket, parser, root, PREC_COMPARISON + 1);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_COMPARISON + 1);
return TOY_AST_FLAG_COMPARE_GREATER_EQUAL;
}
default:
printError(parser, parser->previous, "Unexpected token passed to binary precedence rule");
Toy_private_emitAstError(bucket, root);
Toy_private_emitAstError(bucketHandle, rootHandle);
return TOY_AST_FLAG_NONE;
}
}
static Toy_AstFlag group(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
static Toy_AstFlag group(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
//groups are ()
if (parser->previous.type == TOY_TOKEN_OPERATOR_PAREN_LEFT) {
parsePrecedence(bucket, parser, root, PREC_GROUP);
parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP);
consume(parser, TOY_TOKEN_OPERATOR_PAREN_RIGHT, "Expected ')' at end of group");
//Toy_AstGroup is omitted from generation, as an optimisation
// Toy_private_emitAstGroup(bucket, root);
// Toy_private_emitAstGroup(bucketHandle, rootHandle);
}
else {
printError(parser, parser->previous, "Unexpected token passed to grouping precedence rule");
Toy_private_emitAstError(bucket, root);
Toy_private_emitAstError(bucketHandle, rootHandle);
}
return TOY_AST_FLAG_NONE;
@@ -435,7 +435,7 @@ static ParsingTuple* getParsingRule(Toy_TokenType type) {
}
//grammar rules
static void parsePrecedence(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root, ParsingPrecedence precRule) {
static void parsePrecedence(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle, ParsingPrecedence precRule) {
//'step over' the token to parse
advance(parser);
@@ -444,11 +444,11 @@ static void parsePrecedence(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** r
if (prefix == NULL) {
printError(parser, parser->previous, "Expected expression");
Toy_private_emitAstError(bucket, root);
Toy_private_emitAstError(bucketHandle, rootHandle);
return;
}
prefix(bucket, parser, root);
prefix(bucketHandle, parser, rootHandle);
//infix rules are left-recursive
while (precRule <= getParsingRule(parser->current.type)->precedence) {
@@ -456,20 +456,20 @@ static void parsePrecedence(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** r
if (infix == NULL) {
printError(parser, parser->previous, "Expected operator");
Toy_private_emitAstError(bucket, root);
Toy_private_emitAstError(bucketHandle, rootHandle);
return;
}
Toy_Ast* ptr = NULL;
Toy_AstFlag flag = infix(bucket, parser, &ptr);
Toy_AstFlag flag = infix(bucketHandle, parser, &ptr);
//finished
if (flag == TOY_AST_FLAG_NONE) {
(*root) = ptr;
(*rootHandle) = ptr;
return;
}
Toy_private_emitAstBinary(bucket, root, flag, ptr);
Toy_private_emitAstBinary(bucketHandle, rootHandle, flag, ptr);
}
//can't assign below a certain precedence
@@ -478,22 +478,22 @@ static void parsePrecedence(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** r
}
}
static void makeExpr(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
parsePrecedence(bucket, parser, root, PREC_ASSIGNMENT);
static void makeExpr(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
parsePrecedence(bucketHandle, parser, rootHandle, PREC_ASSIGNMENT);
}
static void makeExprStmt(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
static void makeExprStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
//check for empty lines
if (match(parser, TOY_TOKEN_OPERATOR_SEMICOLON)) {
Toy_private_emitAstPass(bucket, root);
Toy_private_emitAstPass(bucketHandle, rootHandle);
return;
}
makeExpr(bucket, parser, root);
makeExpr(bucketHandle, parser, rootHandle);
consume(parser, TOY_TOKEN_OPERATOR_SEMICOLON, "Expected ';' at the end of expression statement");
}
static void makeStmt(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
static void makeStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
//block
//print
//assert
@@ -506,47 +506,47 @@ static void makeStmt(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
//import
//default
makeExprStmt(bucket, parser, root);
makeExprStmt(bucketHandle, parser, rootHandle);
}
static void makeDeclarationStmt(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
static void makeDeclarationStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
// //variable declarations
// if (match(parser, TOY_TOKEN_KEYWORD_VAR)) {
// makeVariableDeclarationStmt(bucket, parser, root);
// makeVariableDeclarationStmt(bucketHandle, parser, rootHandle);
// }
// //function declarations
// else if (match(parser, TOY_TOKEN_KEYWORD_FUNCTION)) {
// makeFunctionDeclarationStmt(bucket, parser, root);
// makeFunctionDeclarationStmt(bucketHandle, parser, rootHandle);
// }
//otherwise
// else {
makeStmt(bucket, parser, root);
makeStmt(bucketHandle, parser, rootHandle);
// }
}
static void makeBlockStmt(Toy_Bucket** bucket, Toy_Parser* parser, Toy_Ast** root) {
static void makeBlockStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
//begin the block
Toy_private_initAstBlock(bucket, root);
Toy_private_initAstBlock(bucketHandle, rootHandle);
//read a series of statements into the block
while (!match(parser, TOY_TOKEN_EOF)) {
//process the grammar rules
Toy_Ast* stmt = NULL;
makeDeclarationStmt(bucket, parser, &stmt);
makeDeclarationStmt(bucketHandle, parser, &stmt);
//if something went wrong
if (parser->panic) {
synchronize(parser);
Toy_Ast* err = NULL;
Toy_private_emitAstError(bucket, &err);
Toy_private_appendAstBlock(bucket, *root, err);
Toy_private_emitAstError(bucketHandle, &err);
Toy_private_appendAstBlock(bucketHandle, *rootHandle, err);
continue;
}
Toy_private_appendAstBlock(bucket, *root, stmt);
Toy_private_appendAstBlock(bucketHandle, *rootHandle, stmt);
}
}
@@ -557,18 +557,18 @@ void Toy_bindParser(Toy_Parser* parser, Toy_Lexer* lexer) {
advance(parser);
}
Toy_Ast* Toy_scanParser(Toy_Bucket** bucket, Toy_Parser* parser) {
Toy_Ast* root = NULL;
Toy_Ast* Toy_scanParser(Toy_Bucket** bucketHandle, Toy_Parser* parser) {
Toy_Ast* rootHandle = NULL;
//check for EOF
if (match(parser, TOY_TOKEN_EOF)) {
Toy_private_emitAstEnd(bucket, &root);
return root;
Toy_private_emitAstEnd(bucketHandle, &rootHandle);
return rootHandle;
}
makeBlockStmt(bucket, parser, &root);
makeBlockStmt(bucketHandle, parser, &rootHandle);
return root;
return rootHandle;
}
void Toy_resetParser(Toy_Parser* parser) {

View File

@@ -17,5 +17,5 @@ typedef struct Toy_Parser {
} Toy_Parser;
TOY_API void Toy_bindParser(Toy_Parser* parser, Toy_Lexer* lexer);
TOY_API Toy_Ast* Toy_scanParser(Toy_Bucket** bucket, Toy_Parser* parser);
TOY_API Toy_Ast* Toy_scanParser(Toy_Bucket** bucketHandle, Toy_Parser* parser);
TOY_API void Toy_resetParser(Toy_Parser* parser);

View File

@@ -27,60 +27,60 @@ void Toy_freeStack(Toy_Stack* stack) {
free(stack);
}
void Toy_pushStack(Toy_Stack** stack, Toy_Value value) {
void Toy_pushStack(Toy_Stack** stackHandle, Toy_Value value) {
//don't go overboard - limit to 1mb of capacity used
if ((*stack)->count >= 1024 * 1024 / sizeof(Toy_Value)) {
if ((*stackHandle)->count >= 1024 * 1024 / sizeof(Toy_Value)) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Stack overflow\n" TOY_CC_RESET);
exit(-1);
}
//expand the capacity if needed
if ((*stack)->count + 1 > (*stack)->capacity) {
while ((*stack)->count + 1 > (*stack)->capacity) {
(*stack)->capacity = (*stack)->capacity < MIN_CAPACITY ? MIN_CAPACITY : (*stack)->capacity * 2;
if ((*stackHandle)->count + 1 > (*stackHandle)->capacity) {
while ((*stackHandle)->count + 1 > (*stackHandle)->capacity) {
(*stackHandle)->capacity = (*stackHandle)->capacity < MIN_CAPACITY ? MIN_CAPACITY : (*stackHandle)->capacity * 2;
}
unsigned int newCapacity = (*stack)->capacity;
unsigned int newCapacity = (*stackHandle)->capacity;
(*stack) = realloc((*stack), newCapacity * sizeof(Toy_Value) + sizeof(Toy_Stack));
(*stackHandle) = realloc((*stackHandle), newCapacity * sizeof(Toy_Value) + sizeof(Toy_Stack));
if ((*stack) == NULL) {
if ((*stackHandle) == NULL) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to reallocate a 'Toy_Stack' of %d capacity (%d space in memory)\n" TOY_CC_RESET, (int)newCapacity, (int)(newCapacity * sizeof(Toy_Value) + sizeof(Toy_Stack)));
exit(1);
}
}
//Note: "pointer arithmetic in C/C++ is type-relative"
((Toy_Value*)((*stack) + 1))[(*stack)->count++] = value;
((Toy_Value*)((*stackHandle) + 1))[(*stackHandle)->count++] = value;
}
Toy_Value Toy_peekStack(Toy_Stack** stack) {
if ((*stack)->count == 0) {
Toy_Value Toy_peekStack(Toy_Stack** stackHandle) {
if ((*stackHandle)->count == 0) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Stack underflow\n" TOY_CC_RESET);
exit(-1);
}
return ((Toy_Value*)((*stack) + 1))[(*stack)->count - 1];
return ((Toy_Value*)((*stackHandle) + 1))[(*stackHandle)->count - 1];
}
Toy_Value Toy_popStack(Toy_Stack** stack) {
if ((*stack)->count == 0) {
Toy_Value Toy_popStack(Toy_Stack** stackHandle) {
if ((*stackHandle)->count == 0) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Stack underflow\n" TOY_CC_RESET);
exit(-1);
}
//shrink if possible
if ((*stack)->count > MIN_CAPACITY && (*stack)->count < (*stack)->capacity / 4) {
(*stack)->capacity /= 2;
unsigned int newCapacity = (*stack)->capacity;
if ((*stackHandle)->count > MIN_CAPACITY && (*stackHandle)->count < (*stackHandle)->capacity / 4) {
(*stackHandle)->capacity /= 2;
unsigned int newCapacity = (*stackHandle)->capacity;
(*stack) = realloc((*stack), (*stack)->capacity * sizeof(Toy_Value) + sizeof(Toy_Stack));
(*stackHandle) = realloc((*stackHandle), (*stackHandle)->capacity * sizeof(Toy_Value) + sizeof(Toy_Stack));
if ((*stack) == NULL) {
if ((*stackHandle) == NULL) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to reallocate a 'Toy_Stack' of %d capacity (%d space in memory)\n" TOY_CC_RESET, (int)newCapacity, (int)(newCapacity * sizeof(Toy_Value) + sizeof(Toy_Stack)));
exit(1);
}
}
return ((Toy_Value*)((*stack) + 1))[--(*stack)->count];
return ((Toy_Value*)((*stackHandle) + 1))[--(*stackHandle)->count];
}

View File

@@ -12,6 +12,6 @@ typedef struct Toy_Stack { //32 | 64 BITNESS
TOY_API Toy_Stack* Toy_allocateStack();
TOY_API void Toy_freeStack(Toy_Stack* stack);
TOY_API void Toy_pushStack(Toy_Stack** stack, Toy_Value value);
TOY_API Toy_Value Toy_peekStack(Toy_Stack** stack);
TOY_API Toy_Value Toy_popStack(Toy_Stack** stack);
TOY_API void Toy_pushStack(Toy_Stack** stackHandle, Toy_Value value);
TOY_API Toy_Value Toy_peekStack(Toy_Stack** stackHandle);
TOY_API Toy_Value Toy_popStack(Toy_Stack** stackHandle);

View File

@@ -35,14 +35,14 @@ static void decrementRefCount(Toy_String* str) {
}
//exposed functions
Toy_String* Toy_createString(Toy_Bucket** bucket, const char* cstring) {
Toy_String* Toy_createString(Toy_Bucket** bucketHandle, const char* cstring) {
int length = strlen(cstring);
return Toy_createStringLength(bucket, cstring, length);
return Toy_createStringLength(bucketHandle, cstring, length);
}
Toy_String* Toy_createStringLength(Toy_Bucket** bucket, const char* cstring, int length) {
Toy_String* ret = (Toy_String*)Toy_partitionBucket(bucket, sizeof(Toy_String) + length + 1); //TODO: compensate for partitioning more space than bucket capacity
Toy_String* Toy_createStringLength(Toy_Bucket** bucketHandle, const char* cstring, int length) {
Toy_String* ret = (Toy_String*)Toy_partitionBucket(bucketHandle, sizeof(Toy_String) + length + 1); //TODO: compensate for partitioning more space than bucket capacity
ret->type = TOY_STRING_LEAF;
ret->length = length;
@@ -53,7 +53,7 @@ Toy_String* Toy_createStringLength(Toy_Bucket** bucket, const char* cstring, int
return ret;
}
Toy_String* Toy_copyString(Toy_Bucket** bucket, Toy_String* str) {
Toy_String* Toy_copyString(Toy_Bucket** bucketHandle, Toy_String* str) {
if (str->refCount == 0) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't copy a string with refcount of zero\n" TOY_CC_RESET);
exit(-1);
@@ -62,12 +62,12 @@ Toy_String* Toy_copyString(Toy_Bucket** bucket, Toy_String* str) {
return str;
}
Toy_String* Toy_deepCopyString(Toy_Bucket** bucket, Toy_String* str) {
Toy_String* Toy_deepCopyString(Toy_Bucket** bucketHandle, Toy_String* str) {
if (str->refCount == 0) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't deep copy a string with refcount of zero\n" TOY_CC_RESET);
exit(-1);
}
Toy_String* ret = (Toy_String*)Toy_partitionBucket(bucket, sizeof(Toy_String) + str->length + 1); //TODO: compensate for partitioning more space than bucket capacity
Toy_String* ret = (Toy_String*)Toy_partitionBucket(bucketHandle, sizeof(Toy_String) + str->length + 1); //TODO: compensate for partitioning more space than bucket capacity
//
ret->type = TOY_STRING_LEAF;
@@ -79,13 +79,13 @@ Toy_String* Toy_deepCopyString(Toy_Bucket** bucket, Toy_String* str) {
return ret;
}
Toy_String* Toy_concatString(Toy_Bucket** bucket, Toy_String* left, Toy_String* right) {
Toy_String* Toy_concatString(Toy_Bucket** bucketHandle, Toy_String* left, Toy_String* right) {
if (left->refCount == 0 || right->refCount == 0) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't concatenate a string with refcount of zero\n" TOY_CC_RESET);
exit(-1);
}
Toy_String* ret = (Toy_String*)Toy_partitionBucket(bucket, sizeof(Toy_String));
Toy_String* ret = (Toy_String*)Toy_partitionBucket(bucketHandle, sizeof(Toy_String));
ret->type = TOY_STRING_NODE;
ret->length = left->length + right->length;

View File

@@ -27,13 +27,13 @@ typedef struct Toy_String { //32 | 64 BITNESS
} as; //8 | 16
} Toy_String; //24 | 32
TOY_API Toy_String* Toy_createString(Toy_Bucket** bucket, const char* cstring);
TOY_API Toy_String* Toy_createStringLength(Toy_Bucket** bucket, const char* cstring, int length);
TOY_API Toy_String* Toy_createString(Toy_Bucket** bucketHandle, const char* cstring);
TOY_API Toy_String* Toy_createStringLength(Toy_Bucket** bucketHandle, const char* cstring, int length);
TOY_API Toy_String* Toy_copyString(Toy_Bucket** bucket, Toy_String* str);
TOY_API Toy_String* Toy_deepCopyString(Toy_Bucket** bucket, Toy_String* str);
TOY_API Toy_String* Toy_copyString(Toy_Bucket** bucketHandle, Toy_String* str);
TOY_API Toy_String* Toy_deepCopyString(Toy_Bucket** bucketHandle, Toy_String* str);
TOY_API Toy_String* Toy_concatString(Toy_Bucket** bucket, Toy_String* left, Toy_String* right);
TOY_API Toy_String* Toy_concatString(Toy_Bucket** bucketHandle, Toy_String* left, Toy_String* right);
TOY_API void Toy_freeString(Toy_String* str);

View File

@@ -9,46 +9,46 @@
#define MIN_CAPACITY 16
//utils
static void probeAndInsert(Toy_Table** table, Toy_Value key, Toy_Value value) {
static void probeAndInsert(Toy_Table** tableHandle, Toy_Value key, Toy_Value value) {
//make the entry
unsigned int probe = Toy_hashValue(key) % (*table)->capacity;
unsigned int probe = Toy_hashValue(key) % (*tableHandle)->capacity;
Toy_TableEntry entry = (Toy_TableEntry){ .key = key, .value = value, .psl = 0 };
//probe
while (true) {
//if we're overriding an existing value
if (TOY_VALUE_IS_EQUAL((*table)->data[probe].key, key)) {
(*table)->data[probe] = entry;
if (TOY_VALUE_IS_EQUAL((*tableHandle)->data[probe].key, key)) {
(*tableHandle)->data[probe] = entry;
//TODO: benchmark the psl optimisation
(*table)->minPsl = entry.psl < (*table)->minPsl ? entry.psl : (*table)->minPsl;
(*table)->maxPsl = entry.psl > (*table)->maxPsl ? entry.psl : (*table)->maxPsl;
(*tableHandle)->minPsl = entry.psl < (*tableHandle)->minPsl ? entry.psl : (*tableHandle)->minPsl;
(*tableHandle)->maxPsl = entry.psl > (*tableHandle)->maxPsl ? entry.psl : (*tableHandle)->maxPsl;
return;
}
//if this spot is free, insert and return
if (TOY_VALUE_IS_NULL((*table)->data[probe].key)) {
(*table)->data[probe] = entry;
if (TOY_VALUE_IS_NULL((*tableHandle)->data[probe].key)) {
(*tableHandle)->data[probe] = entry;
(*table)->count++;
(*tableHandle)->count++;
//TODO: benchmark the psl optimisation
(*table)->minPsl = entry.psl < (*table)->minPsl ? entry.psl : (*table)->minPsl;
(*table)->maxPsl = entry.psl > (*table)->maxPsl ? entry.psl : (*table)->maxPsl;
(*tableHandle)->minPsl = entry.psl < (*tableHandle)->minPsl ? entry.psl : (*tableHandle)->minPsl;
(*tableHandle)->maxPsl = entry.psl > (*tableHandle)->maxPsl ? entry.psl : (*tableHandle)->maxPsl;
return;
}
//if the new entry is "poorer", insert it and shift the old one
if ((*table)->data[probe].psl < entry.psl) {
Toy_TableEntry tmp = (*table)->data[probe];
(*table)->data[probe] = entry;
if ((*tableHandle)->data[probe].psl < entry.psl) {
Toy_TableEntry tmp = (*tableHandle)->data[probe];
(*tableHandle)->data[probe] = entry;
entry = tmp;
}
//adjust and continue
probe = (probe + 1) % (*table)->capacity;
probe = (probe + 1) % (*tableHandle)->capacity;
entry.psl++;
}
}
@@ -97,86 +97,86 @@ void Toy_freeTable(Toy_Table* table) {
free(table);
}
void Toy_insertTable(Toy_Table** table, Toy_Value key, Toy_Value value) {
void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value) {
if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques
fprintf(stderr, TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET);
exit(-1); //TODO: #127
}
//expand the capacity
if ((*table)->count > (*table)->capacity * 0.8) {
(*table) = adjustTableCapacity(*table, (*table)->capacity * 2);
if ((*tableHandle)->count > (*tableHandle)->capacity * 0.8) {
(*tableHandle) = adjustTableCapacity((*tableHandle), (*tableHandle)->capacity * 2);
}
probeAndInsert(table, key, value);
probeAndInsert(tableHandle, key, value);
}
Toy_Value Toy_lookupTable(Toy_Table** table, Toy_Value key) {
Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key) {
if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques
fprintf(stderr, TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET);
exit(-1); //TODO: #127
}
//lookup
unsigned int probe = Toy_hashValue(key) % (*table)->capacity;
unsigned int probe = Toy_hashValue(key) % (*tableHandle)->capacity;
while (true) {
//found the entry
if (TOY_VALUE_IS_EQUAL((*table)->data[probe].key, key)) {
return (*table)->data[probe].value;
if (TOY_VALUE_IS_EQUAL((*tableHandle)->data[probe].key, key)) {
return (*tableHandle)->data[probe].value;
}
//if its an empty slot
if (TOY_VALUE_IS_NULL((*table)->data[probe].key)) {
if (TOY_VALUE_IS_NULL((*tableHandle)->data[probe].key)) {
return TOY_VALUE_TO_NULL();
}
//adjust and continue
probe = (probe + 1) % (*table)->capacity;
probe = (probe + 1) % (*tableHandle)->capacity;
}
}
void Toy_removeTable(Toy_Table** table, Toy_Value key) {
void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key) {
if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques
fprintf(stderr, TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET);
exit(-1); //TODO: #127
}
//lookup
unsigned int probe = Toy_hashValue(key) % (*table)->capacity;
unsigned int probe = Toy_hashValue(key) % (*tableHandle)->capacity;
unsigned int wipe = probe; //wiped at the end
while (true) {
//found the entry
if (TOY_VALUE_IS_EQUAL((*table)->data[probe].key, key)) {
if (TOY_VALUE_IS_EQUAL((*tableHandle)->data[probe].key, key)) {
break;
}
//if its an empty slot
if (TOY_VALUE_IS_NULL((*table)->data[probe].key)) {
if (TOY_VALUE_IS_NULL((*tableHandle)->data[probe].key)) {
return;
}
//adjust and continue
probe = (probe + 1) % (*table)->capacity;
probe = (probe + 1) % (*tableHandle)->capacity;
}
//shift along the later entries
for (unsigned int i = (*table)->minPsl; i < (*table)->maxPsl; i++) {
unsigned int p = (probe + i + 0) % (*table)->capacity; //prev
unsigned int u = (probe + i + 1) % (*table)->capacity; //current
for (unsigned int i = (*tableHandle)->minPsl; i < (*tableHandle)->maxPsl; i++) {
unsigned int p = (probe + i + 0) % (*tableHandle)->capacity; //prev
unsigned int u = (probe + i + 1) % (*tableHandle)->capacity; //current
(*table)->data[p] = (*table)->data[u];
(*table)->data[p].psl--;
(*tableHandle)->data[p] = (*tableHandle)->data[u];
(*tableHandle)->data[p].psl--;
//if you hit something where it should be, or nothing at all, stop
if (TOY_VALUE_IS_NULL((*table)->data[u].key) || (*table)->data[p].psl == 0) {
if (TOY_VALUE_IS_NULL((*tableHandle)->data[u].key) || (*tableHandle)->data[p].psl == 0) {
wipe = u;
break;
}
}
//finally, wipe the removed entry
(*table)->data[wipe] = (Toy_TableEntry){ .key = TOY_VALUE_TO_NULL(), .value = TOY_VALUE_TO_NULL(), .psl = 0 };
(*table)->count--;
(*tableHandle)->data[wipe] = (Toy_TableEntry){ .key = TOY_VALUE_TO_NULL(), .value = TOY_VALUE_TO_NULL(), .psl = 0 };
(*tableHandle)->count--;
}

View File

@@ -22,6 +22,6 @@ typedef struct Toy_Table { //32 | 64 BITNESS
TOY_API Toy_Table* Toy_allocateTable();
TOY_API void Toy_freeTable(Toy_Table* table);
TOY_API void Toy_insertTable(Toy_Table** table, Toy_Value key, Toy_Value value);
TOY_API Toy_Value Toy_lookupTable(Toy_Table** table, Toy_Value key);
TOY_API void Toy_removeTable(Toy_Table** table, Toy_Value key);
TOY_API void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value);
TOY_API Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key);
TOY_API void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key);

View File

@@ -57,12 +57,12 @@ int test_sizeof_ast_32bit() {
return -err;
}
int test_type_emission(Toy_Bucket** bucket) {
int test_type_emission(Toy_Bucket** bucketHandle) {
//emit value
{
//emit to an AST
Toy_Ast* ast = NULL;
Toy_private_emitAstValue(bucket, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
//check if it worked
if (
@@ -79,8 +79,8 @@ int test_type_emission(Toy_Bucket** bucket) {
{
//build the AST
Toy_Ast* ast = NULL;
Toy_private_emitAstValue(bucket, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstUnary(bucket, &ast, TOY_AST_FLAG_NEGATE);
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstUnary(bucketHandle, &ast, TOY_AST_FLAG_NEGATE);
//check if it worked
if (
@@ -100,9 +100,9 @@ int test_type_emission(Toy_Bucket** bucket) {
//build the AST
Toy_Ast* ast = NULL;
Toy_Ast* right = NULL;
Toy_private_emitAstValue(bucket, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucket, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstBinary(bucket, &ast, TOY_AST_FLAG_ADD, right);
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstBinary(bucketHandle, &ast, TOY_AST_FLAG_ADD, right);
//check if it worked
if (
@@ -124,10 +124,10 @@ int test_type_emission(Toy_Bucket** bucket) {
//build the AST
Toy_Ast* ast = NULL;
Toy_Ast* right = NULL;
Toy_private_emitAstValue(bucket, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucket, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstBinary(bucket, &ast, TOY_AST_FLAG_ADD, right);
Toy_private_emitAstGroup(bucket, &ast);
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstBinary(bucketHandle, &ast, TOY_AST_FLAG_ADD, right);
Toy_private_emitAstGroup(bucketHandle, &ast);
//check if it worked
if (
@@ -150,19 +150,19 @@ int test_type_emission(Toy_Bucket** bucket) {
{
//initialize the root block
Toy_Ast* block = NULL;
Toy_private_initAstBlock(bucket, &block);
Toy_private_initAstBlock(bucketHandle, &block);
//loop over the ast emissions, appending each one as you go
for (int i = 0; i < 5; i++) {
//build the AST
Toy_Ast* ast = NULL;
Toy_Ast* right = NULL;
Toy_private_emitAstValue(bucket, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucket, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstBinary(bucket, &ast, TOY_AST_FLAG_ADD, right);
Toy_private_emitAstGroup(bucket, &ast);
Toy_private_emitAstValue(bucketHandle, &ast, TOY_VALUE_TO_INTEGER(42));
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_TO_INTEGER(69));
Toy_private_emitAstBinary(bucketHandle, &ast, TOY_AST_FLAG_ADD, right);
Toy_private_emitAstGroup(bucketHandle, &ast);
Toy_private_appendAstBlock(bucket, block, ast);
Toy_private_appendAstBlock(bucketHandle, block, ast);
}
//check if it worked
@@ -216,9 +216,9 @@ int main() {
#endif
{
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
res = test_type_emission(&bucket);
Toy_freeBucket(&bucket);
Toy_Bucket* bucketHandle = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
res = test_type_emission(&bucketHandle);
Toy_freeBucket(&bucketHandle);
if (res == 0) {
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
}

View File

@@ -9,12 +9,12 @@
#include <string.h>
//tests
int test_bytecode_header(Toy_Bucket** bucket) {
int test_bytecode_header(Toy_Bucket** bucketHandle) {
//simple test to ensure the header looks right
{
//setup
Toy_Ast* ast = NULL;
Toy_private_emitAstPass(bucket, &ast);
Toy_private_emitAstPass(bucketHandle, &ast);
//run
Toy_Bytecode bc = Toy_compileBytecode(ast);
@@ -49,7 +49,7 @@ int test_bytecode_header(Toy_Bucket** bucket) {
return 0;
}
int test_bytecode_from_source(Toy_Bucket** bucket) {
int test_bytecode_from_source(Toy_Bucket** bucketHandle) {
{
//setup
const char* source = "(1 + 2) * (3 + 4);";
@@ -58,7 +58,7 @@ int test_bytecode_from_source(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
Toy_Bytecode bc = Toy_compileBytecode(ast);

View File

@@ -4,18 +4,18 @@
#include <stdio.h>
//utils
Toy_Ast* makeAstFromSource(Toy_Bucket** bucket, const char* source) {
Toy_Ast* makeAstFromSource(Toy_Bucket** bucketHandle, const char* source) {
Toy_Lexer lexer;
Toy_bindLexer(&lexer, source);
Toy_Parser parser;
Toy_bindParser(&parser, &lexer);
return Toy_scanParser(bucket, &parser);
return Toy_scanParser(bucketHandle, &parser);
}
//tests
int test_simple_empty_parsers(Toy_Bucket** bucket) {
int test_simple_empty_parsers(Toy_Bucket** bucketHandle) {
//simple parser setup and cleanup
{
//raw source code and lexer
@@ -27,7 +27,7 @@ int test_simple_empty_parsers(Toy_Bucket** bucket) {
Toy_Parser parser;
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//check if it worked
if (
@@ -50,7 +50,7 @@ int test_simple_empty_parsers(Toy_Bucket** bucket) {
Toy_Parser parser;
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//check if it worked
if (
@@ -75,7 +75,7 @@ int test_simple_empty_parsers(Toy_Bucket** bucket) {
Toy_Parser parser;
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
Toy_Ast* iter = ast;
@@ -98,10 +98,10 @@ int test_simple_empty_parsers(Toy_Bucket** bucket) {
return 0;
}
int test_values(Toy_Bucket** bucket) {
int test_values(Toy_Bucket** bucketHandle) {
//test boolean true
{
Toy_Ast* ast = makeAstFromSource(bucket, "true;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "true;");
//check if it worked
if (
@@ -119,7 +119,7 @@ int test_values(Toy_Bucket** bucket) {
//test boolean false (just to be safe)
{
Toy_Ast* ast = makeAstFromSource(bucket, "false;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "false;");
//check if it worked
if (
@@ -137,7 +137,7 @@ int test_values(Toy_Bucket** bucket) {
//test integer
{
Toy_Ast* ast = makeAstFromSource(bucket, "42;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "42;");
//check if it worked
if (
@@ -155,7 +155,7 @@ int test_values(Toy_Bucket** bucket) {
//test float
{
Toy_Ast* ast = makeAstFromSource(bucket, "3.1415;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "3.1415;");
//check if it worked
if (
@@ -173,7 +173,7 @@ int test_values(Toy_Bucket** bucket) {
//test integer with separators
{
Toy_Ast* ast = makeAstFromSource(bucket, "1_234_567_890;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "1_234_567_890;");
//check if it worked
if (
@@ -191,7 +191,7 @@ int test_values(Toy_Bucket** bucket) {
//test float with separators
{
Toy_Ast* ast = makeAstFromSource(bucket, "3.141_592_65;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "3.141_592_65;");
//check if it worked
if (
@@ -210,10 +210,10 @@ int test_values(Toy_Bucket** bucket) {
return 0;
}
int test_unary(Toy_Bucket** bucket) {
int test_unary(Toy_Bucket** bucketHandle) {
//test unary boolean negation (!true)
{
Toy_Ast* ast = makeAstFromSource(bucket, "!true;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "!true;");
//check if it worked
if (
@@ -231,7 +231,7 @@ int test_unary(Toy_Bucket** bucket) {
//test unary boolean negation (!false, just to be safe)
{
Toy_Ast* ast = makeAstFromSource(bucket, "!false;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "!false;");
//check if it worked
if (
@@ -249,7 +249,7 @@ int test_unary(Toy_Bucket** bucket) {
//test unary integer negation
{
Toy_Ast* ast = makeAstFromSource(bucket, "-42;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "-42;");
//check if it worked
if (
@@ -267,7 +267,7 @@ int test_unary(Toy_Bucket** bucket) {
//test unary float negation
{
Toy_Ast* ast = makeAstFromSource(bucket, "-3.1415;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "-3.1415;");
//check if it worked
if (
@@ -285,7 +285,7 @@ int test_unary(Toy_Bucket** bucket) {
//ensure unary negation doesn't occur with a group
{
Toy_Ast* ast = makeAstFromSource(bucket, "-(42);");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "-(42);");
//check if it worked
if (
@@ -301,7 +301,7 @@ int test_unary(Toy_Bucket** bucket) {
//ensure unary negation doesn't occur with a space
{
Toy_Ast* ast = makeAstFromSource(bucket, "- 42;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "- 42;");
//check if it worked
if (
@@ -318,10 +318,10 @@ int test_unary(Toy_Bucket** bucket) {
return 0;
}
int test_binary(Toy_Bucket** bucket) {
int test_binary(Toy_Bucket** bucketHandle) {
//test binary add (term); also covers subtract
{
Toy_Ast* ast = makeAstFromSource(bucket, "1 + 2;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "1 + 2;");
//check if it worked
if (
@@ -348,7 +348,7 @@ int test_binary(Toy_Bucket** bucket) {
//test binary multiply (factor); also covers divide and modulo
{
Toy_Ast* ast = makeAstFromSource(bucket, "3 * 5;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "3 * 5;");
//check if it worked
if (
@@ -375,7 +375,7 @@ int test_binary(Toy_Bucket** bucket) {
//test binary assign (using numbers for now, as identifiers aren't coded yet)
{
Toy_Ast* ast = makeAstFromSource(bucket, "1 = 2;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "1 = 2;");
//check if it worked
if (
@@ -402,7 +402,7 @@ int test_binary(Toy_Bucket** bucket) {
//test binary compare (equality)
{
Toy_Ast* ast = makeAstFromSource(bucket, "42 == 69;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "42 == 69;");
//check if it worked
if (
@@ -430,10 +430,10 @@ int test_binary(Toy_Bucket** bucket) {
return 0;
}
int test_precedence(Toy_Bucket** bucket) {
int test_precedence(Toy_Bucket** bucketHandle) {
//test term-factor precedence
{
Toy_Ast* ast = makeAstFromSource(bucket, "1 * 2 + 3 * 4;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "1 * 2 + 3 * 4;");
//check if it worked
if (
@@ -474,7 +474,7 @@ int test_precedence(Toy_Bucket** bucket) {
//test left-recrusive precedence
{
Toy_Ast* ast = makeAstFromSource(bucket, "1 + 2 + 3 + 4 + 5 + 6;");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "1 + 2 + 3 + 4 + 5 + 6;");
//check if it worked
if (
@@ -531,7 +531,7 @@ int test_precedence(Toy_Bucket** bucket) {
//test group precedence
{
Toy_Ast* ast = makeAstFromSource(bucket, "(1 + 2) * (3 + 4);");
Toy_Ast* ast = makeAstFromSource(bucketHandle, "(1 + 2) * (3 + 4);");
//check if it worked
if (

View File

@@ -10,12 +10,12 @@
#include <string.h>
//tests
int test_routine_header_and_values(Toy_Bucket** bucket) {
int test_routine_header_and_values(Toy_Bucket** bucketHandle) {
//simple test to ensure the header looks right with an empty ast
{
//setup
Toy_Ast* ast = NULL;
Toy_private_emitAstPass(bucket, &ast);
Toy_private_emitAstPass(bucketHandle, &ast);
//run
void* buffer = Toy_compileRoutine(ast);
@@ -64,7 +64,7 @@ int test_routine_header_and_values(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
void* buffer = Toy_compileRoutine(ast);
@@ -113,7 +113,7 @@ int test_routine_header_and_values(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
void* buffer = Toy_compileRoutine(ast);
@@ -166,7 +166,7 @@ int test_routine_header_and_values(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
void* buffer = Toy_compileRoutine(ast);
@@ -219,7 +219,7 @@ int test_routine_header_and_values(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
void* buffer = Toy_compileRoutine(ast);
@@ -273,7 +273,7 @@ int test_routine_header_and_values(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
void* buffer = Toy_compileRoutine(ast);
@@ -321,11 +321,11 @@ int test_routine_header_and_values(Toy_Bucket** bucket) {
return 0;
}
// int test_routine_unary(Toy_Bucket** bucket) {
// int test_routine_unary(Toy_Bucket** bucketHandle) {
// //Nothing produces a unary instruction yet
// }
int test_routine_binary(Toy_Bucket** bucket) {
int test_routine_binary(Toy_Bucket** bucketHandle) {
//produce a simple algorithm
{
//setup
@@ -335,7 +335,7 @@ int test_routine_binary(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
void* buffer = Toy_compileRoutine(ast);
@@ -401,7 +401,7 @@ int test_routine_binary(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
void* buffer = Toy_compileRoutine(ast);
@@ -467,7 +467,7 @@ int test_routine_binary(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
void* buffer = Toy_compileRoutine(ast);
@@ -533,7 +533,7 @@ int test_routine_binary(Toy_Bucket** bucket) {
Toy_bindLexer(&lexer, source);
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
//run
void* buffer = Toy_compileRoutine(ast);

View File

@@ -9,21 +9,21 @@
#include <string.h>
//utils
Toy_Bytecode makeBytecodeFromSource(Toy_Bucket** bucket, const char* source) {
Toy_Bytecode makeBytecodeFromSource(Toy_Bucket** bucketHandle, const char* source) {
Toy_Lexer lexer;
Toy_bindLexer(&lexer, source);
Toy_Parser parser;
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
Toy_Bytecode bc = Toy_compileBytecode(ast);
return bc;
}
//tests
int test_setup_and_teardown(Toy_Bucket** bucket) {
int test_setup_and_teardown(Toy_Bucket** bucketHandle) {
//basic init & quit
{
//generate bytecode for testing
@@ -35,7 +35,7 @@ int test_setup_and_teardown(Toy_Bucket** bucket) {
Toy_Parser parser;
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
Toy_Bytecode bc = Toy_compileBytecode(ast);
@@ -73,7 +73,7 @@ int test_setup_and_teardown(Toy_Bucket** bucket) {
return 0;
}
int test_simple_execution(Toy_Bucket** bucket) {
int test_simple_execution(Toy_Bucket** bucketHandle) {
//test execution
{
//generate bytecode for testing
@@ -85,7 +85,7 @@ int test_simple_execution(Toy_Bucket** bucket) {
Toy_Parser parser;
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
Toy_Bytecode bc = Toy_compileBytecode(ast);
@@ -117,7 +117,7 @@ int test_simple_execution(Toy_Bucket** bucket) {
return 0;
}
int test_opcode_not_equal(Toy_Bucket** bucket) {
int test_opcode_not_equal(Toy_Bucket** bucketHandle) {
//testing a specific opcode; '!=' is compressed into a single word, so lets check it works
{
//generate bytecode for testing
@@ -129,7 +129,7 @@ int test_opcode_not_equal(Toy_Bucket** bucket) {
Toy_Parser parser;
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
Toy_Bytecode bc = Toy_compileBytecode(ast);