Implemented AST, ensured bucket memory worked

This commit is contained in:
2024-09-10 20:19:11 +10:00
parent 81417e7f32
commit 5fd933a15e
13 changed files with 435 additions and 13 deletions

View File

@@ -1,2 +1,78 @@
#include "toy_ast.h"
void Toy_private_initAstBlock(Toy_Bucket** bucket, Toy_Ast** handle) {
(*handle) = (Toy_Ast*)Toy_partBucket(bucket, sizeof(Toy_Ast));
(*handle)->block.type = TOY_AST_BLOCK;
(*handle)->block.child = NULL;
(*handle)->block.next = NULL;
(*handle)->block.tail = NULL;
}
void Toy_private_appendAstBlock(Toy_Bucket** bucket, Toy_Ast** handle, Toy_Ast* child) {
//type check
//first, check if we're an empty head
if ((*handle)->block.child == NULL) {
(*handle)->block.child = child;
return; //NOTE: first call on an empty head skips any memory allocations
}
//run (or jump) until we hit the current tail
Toy_Ast* iter = (*handle)->block.tail ? (*handle)->block.tail : (*handle);
while(iter->block.next != NULL) {
iter = iter->block.next;
}
//append a new link to the chain
Toy_private_initAstBlock(bucket, &(iter->block.next));
//store the child in the new link, prep the tail pointer
iter->block.next->block.child = child;
(*handle)->block.tail = iter->block.next;
}
void Toy_private_emitAstValue(Toy_Bucket** bucket, Toy_Ast** handle, Toy_Value value) {
(*handle) = (Toy_Ast*)Toy_partBucket(bucket, sizeof(Toy_Ast));
(*handle)->value.type = TOY_AST_VALUE;
(*handle)->value.value = value;
}
//TODO: flag range checks
void Toy_private_emitAstUnary(Toy_Bucket** bucket, Toy_Ast** handle, Toy_AstFlag flag, Toy_Ast* child) {
(*handle) = (Toy_Ast*)Toy_partBucket(bucket, sizeof(Toy_Ast));
(*handle)->unary.type = TOY_AST_UNARY;
(*handle)->unary.flag = flag;
(*handle)->unary.child = child;
}
void Toy_private_emitAstBinary(Toy_Bucket** bucket, Toy_Ast** handle, Toy_AstFlag flag, Toy_Ast* left, Toy_Ast* right) {
(*handle) = (Toy_Ast*)Toy_partBucket(bucket, sizeof(Toy_Ast));
(*handle)->binary.type = TOY_AST_BINARY;
(*handle)->binary.flag = flag;
(*handle)->binary.left = left;
(*handle)->binary.right = right;
}
void Toy_private_emitAstGroup(Toy_Bucket** bucket, Toy_Ast** handle, Toy_Ast* child) {
(*handle) = (Toy_Ast*)Toy_partBucket(bucket, sizeof(Toy_Ast));
(*handle)->group.type = TOY_AST_GROUP;
(*handle)->group.child = child;
}
void Toy_private_emitAstPass(Toy_Bucket** bucket, Toy_Ast** handle) {
(*handle) = (Toy_Ast*)Toy_partBucket(bucket, sizeof(Toy_Ast));
(*handle)->pass.type = TOY_AST_PASS;
}
void Toy_private_emitAstError(Toy_Bucket** bucket, Toy_Ast** handle) {
(*handle) = (Toy_Ast*)Toy_partBucket(bucket, sizeof(Toy_Ast));
(*handle)->error.type = TOY_AST_ERROR;
}

View File

@@ -1,9 +1,108 @@
#pragma once
#include "toy_common.h"
#include "toy_memory.h"
#include "toy_value.h"
//each major type
typedef enum Toy_AstType {
TOY_AST_BLOCK,
TOY_AST_VALUE,
TOY_AST_UNARY,
TOY_AST_BINARY,
TOY_AST_GROUP,
TOY_AST_PASS,
TOY_AST_ERROR,
} Toy_AstType;
//flags are handled differently by different types
typedef enum Toy_AstFlag {
//binary flags
TOY_AST_FLAG_ADD,
TOY_AST_FLAG_SUBTRACT,
TOY_AST_FLAG_MULTIPLY,
TOY_AST_FLAG_DIVIDE,
TOY_AST_FLAG_MODULO,
TOY_AST_FLAG_COMPARE_EQUAL,
TOY_AST_FLAG_COMPARE_NOT,
TOY_AST_FLAG_COMPARE_LESS,
TOY_AST_FLAG_COMPARE_LESS_EQUAL,
TOY_AST_FLAG_COMPARE_GREATER,
TOY_AST_FLAG_COMPARE_GREATER_EQUAL,
TOY_AST_FLAG_AND,
TOY_AST_FLAG_OR,
//unary flags
TOY_AST_FLAG_NEGATE,
TOY_AST_FLAG_INCREMENT,
TOY_AST_FLAG_DECREMENT,
// TOY_AST_FLAG_TERNARY,
} Toy_AstFlag;
//the root AST type
typedef union Toy_Ast Toy_Ast;
void Toy_private_initAstBlock(Toy_Bucket** bucket, Toy_Ast** handle);
void Toy_private_appendAstBlock(Toy_Bucket** bucket, Toy_Ast** handle, 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, Toy_Ast* child);
void Toy_private_emitAstBinary(Toy_Bucket** bucket, Toy_Ast** handle,Toy_AstFlag flag, Toy_Ast* left, Toy_Ast* right);
void Toy_private_emitAstGroup(Toy_Bucket** bucket, Toy_Ast** handle, Toy_Ast* child);
void Toy_private_emitAstPass(Toy_Bucket** bucket, Toy_Ast** handle);
void Toy_private_emitAstError(Toy_Bucket** bucket, Toy_Ast** handle);
typedef struct Toy_AstBlock {
Toy_AstType type;
Toy_Ast* child; //begin encoding the line
Toy_Ast* next; //'next' is either an AstBlock or null
Toy_Ast* tail; //'tail' - either points to the tail of the current list, or null; only used by the head of a list as an optimisation
} Toy_AstBlock;
typedef struct Toy_AstValue {
Toy_AstType type;
Toy_Value value;
} Toy_AstValue;
typedef struct Toy_AstUnary {
Toy_AstType type;
Toy_AstFlag flag;
Toy_Ast* child;
} Toy_AstUnary;
typedef struct Toy_AstBinary {
Toy_AstType type;
Toy_Ast* left;
Toy_AstFlag flag;
Toy_Ast* right;
} Toy_AstBinary;
typedef struct Toy_AstGroup {
Toy_AstType type;
Toy_Ast* child;
} Toy_AstGroup;
typedef struct Toy_AstPass {
Toy_AstType type;
} Toy_AstPass;
typedef struct Toy_AstError {
Toy_AstType type;
//TODO: more data regarding the error
} Toy_AstError;
union Toy_Ast {
Toy_AstType type; //4
Toy_AstBlock block; //12
Toy_AstValue value; //12
Toy_AstUnary unary; //12
Toy_AstBinary binary; //16
Toy_AstGroup group; //8
Toy_AstPass pass; //4
Toy_AstError error; //4
}; //16

View File

@@ -37,6 +37,7 @@ NOTE: you need both font AND background for these to work
#define TOY_CC_BACK_WHITE "47m"
//useful
#define TOY_CC_DEBUG TOY_CC_FONT_BLUE TOY_CC_BACK_BLACK
#define TOY_CC_NOTICE TOY_CC_FONT_GREEN TOY_CC_BACK_BLACK
#define TOY_CC_WARN TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK
#define TOY_CC_ERROR TOY_CC_FONT_RED TOY_CC_BACK_BLACK
@@ -67,6 +68,7 @@ NOTE: you need both font AND background for these to work
#define TOY_CC_BACK_WHITE
//useful
#define TOY_CC_DEBUG TOY_CC_FONT_BLUE TOY_CC_BACK_BLACK
#define TOY_CC_NOTICE TOY_CC_FONT_GREEN TOY_CC_BACK_BLACK
#define TOY_CC_WARN TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK
#define TOY_CC_ERROR TOY_CC_FONT_RED TOY_CC_BACK_BLACK

View File

@@ -261,7 +261,7 @@ Toy_Token Toy_private_scanLexer(Toy_Lexer* lexer) {
case '/': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_OPERATOR_DIVIDE_ASSIGN : TOY_TOKEN_OPERATOR_DIVIDE);
case '%': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_OPERATOR_MODULO_ASSIGN : TOY_TOKEN_OPERATOR_MODULO);
case '!': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_OPERATOR_COMPARE_NOT : TOY_TOKEN_OPERATOR_INVERT);
case '!': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_OPERATOR_COMPARE_NOT : TOY_TOKEN_OPERATOR_NEGATE);
case '=': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_OPERATOR_COMPARE_EQUAL : TOY_TOKEN_OPERATOR_ASSIGN);
case '<': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_OPERATOR_COMPARE_LESS_EQUAL : TOY_TOKEN_OPERATOR_COMPARE_LESS);

View File

@@ -24,6 +24,15 @@
TOY_API void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize);
//immobile "bucket" memory structure for custom allocators
#define TOY_BUCKET_INIT(type, bucket, capacity) \
Toy_initBucket(&(bucket), sizeof(type)*(capacity))
#define TOY_BUCKET_PART(type, bucket) \
(type*)Toy_partBucket(&(bucket), sizeof(type))
#define TOY_BUCKET_FREE(bucket) \
Toy_freeBucket(&(bucket))
typedef struct Toy_Bucket {
struct Toy_Bucket* next;
void* contents;
@@ -34,13 +43,3 @@ typedef struct Toy_Bucket {
TOY_API void Toy_initBucket(Toy_Bucket** bucketHandle, size_t capacity);
TOY_API void* Toy_partBucket(Toy_Bucket** bucketHandle, size_t space);
TOY_API void Toy_freeBucket(Toy_Bucket** bucketHandle);
#define TOY_BUCKET_INIT(type, bucket, capacity) \
Toy_initBucket(&(bucket), sizeof(type)*(capacity))
#define TOY_BUCKET_PART(type, bucket) \
Toy_partBucket(&(bucket), sizeof(type))
#define TOY_BUCKET_FREE(bucket) \
Toy_freeBucket(&(bucket))

View File

@@ -1,6 +1,8 @@
#pragma once
typedef enum Toy_OpcodeType {
//
TOY_OPCODE_PASS,
TOY_OPCODE_ERROR,
TOY_OPCODE_EOF,

0
source/toy_parser.c Normal file
View File

0
source/toy_parser.h Normal file
View File

View File

@@ -84,7 +84,7 @@ typedef enum Toy_TokenType {
//other operators
TOY_TOKEN_OPERATOR_AND,
TOY_TOKEN_OPERATOR_OR,
TOY_TOKEN_OPERATOR_INVERT,
TOY_TOKEN_OPERATOR_NEGATE,
TOY_TOKEN_OPERATOR_QUESTION,
TOY_TOKEN_OPERATOR_COLON,

View File

@@ -14,7 +14,7 @@ typedef enum Toy_ValueType {
TOY_VALUE_OPAQUE,
} Toy_ValueType;
//4 bytes in size
//8 bytes in size
typedef struct Toy_Value {
union {
bool boolean; //1