mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Wrote value, chunk, memory sections, tested value
chunk and memory remain untested for now
This commit is contained in:
10
makefile
10
makefile
@@ -1,14 +1,14 @@
|
|||||||
|
#compiler settings
|
||||||
|
CFLAGS+=-std=c17 -pedantic -Werror
|
||||||
|
LIBS=-lm
|
||||||
|
|
||||||
#directories
|
#directories
|
||||||
export TOY_SOURCEDIR=source
|
export TOY_SOURCEDIR=source
|
||||||
export TOY_OUTDIR=out
|
export TOY_OUTDIR=out
|
||||||
export TOY_OBJDIR=obj
|
export TOY_OBJDIR=obj
|
||||||
|
|
||||||
#compiler settings
|
|
||||||
CFLAGS+=-std=c17 -pedantic -Werror
|
|
||||||
LIBS=-lm
|
|
||||||
|
|
||||||
#file names
|
#file names
|
||||||
TOY_SOURCEFILES=$(wildcard $(TOY_SOURCEDIR)/*.c)
|
export TOY_SOURCEFILES=$(wildcard $(TOY_SOURCEDIR)/*.c)
|
||||||
|
|
||||||
#targets
|
#targets
|
||||||
all: clean tests
|
all: clean tests
|
||||||
|
|||||||
24
source/toy_chunk.c
Normal file
24
source/toy_chunk.c
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#include "toy_chunk.h"
|
||||||
|
|
||||||
|
#include "toy_memory.h"
|
||||||
|
|
||||||
|
void Toy_initChunk(Toy_Chunk* chunk) {
|
||||||
|
chunk->count = 0;
|
||||||
|
chunk->capacity = 0;
|
||||||
|
chunk->code = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Toy_pushChunk(Toy_Chunk* chunk, uint8_t byte) {
|
||||||
|
if (chunk->count +1 > chunk->capacity) {
|
||||||
|
int oldCapacity = chunk->capacity;
|
||||||
|
chunk->capacity = TOY_GROW_CAPACITY(oldCapacity);
|
||||||
|
chunk->code = TOY_GROW_ARRAY(uint8_t, chunk->code, oldCapacity, chunk->capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk->code[chunk->count++] = byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Toy_freeChunk(Toy_Chunk* chunk) {
|
||||||
|
TOY_FREE_ARRAY(uint8_t, chunk->code, chunk->capacity);
|
||||||
|
Toy_initChunk(chunk);
|
||||||
|
}
|
||||||
13
source/toy_chunk.h
Normal file
13
source/toy_chunk.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "toy_common.h"
|
||||||
|
|
||||||
|
typedef struct Toy_Chunk {
|
||||||
|
int count;
|
||||||
|
int capacity;
|
||||||
|
uint8_t* code;
|
||||||
|
} Toy_Chunk;
|
||||||
|
|
||||||
|
TOY_API void Toy_initChunk(Toy_Chunk* chunk);
|
||||||
|
TOY_API void Toy_pushChunk(Toy_Chunk* chunk, uint8_t byte);
|
||||||
|
TOY_API void Toy_freeChunk(Toy_Chunk* chunk);
|
||||||
@@ -317,13 +317,13 @@ static void trim(char** s, int* l) { //util
|
|||||||
void Toy_private_printToken(Toy_Token* token) {
|
void Toy_private_printToken(Toy_Token* token) {
|
||||||
//print errors
|
//print errors
|
||||||
if (token->type == TOY_TOKEN_ERROR) {
|
if (token->type == TOY_TOKEN_ERROR) {
|
||||||
printf(TOY_CC_ERROR "Error\t%d\t%.*s\n" TOY_CC_RESET, token->line, token->length, token->lexeme);
|
printf(TOY_CC_ERROR "ERROR: \t%d\t%.*s\n" TOY_CC_RESET, token->line, token->length, token->lexeme);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//read pass token, even though it isn't generated
|
//read pass token, even though it isn't generated
|
||||||
if (token->type == TOY_TOKEN_PASS) {
|
if (token->type == TOY_TOKEN_PASS) {
|
||||||
printf(TOY_CC_NOTICE "Error\t%d\t%.*s\n" TOY_CC_RESET, token->line, token->length, token->lexeme);
|
printf(TOY_CC_NOTICE "PASS: \t%d\t%.*s\n" TOY_CC_RESET, token->line, token->length, token->lexeme);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
source/toy_memory.c
Normal file
22
source/toy_memory.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "toy_memory.h"
|
||||||
|
|
||||||
|
#include "toy_console_colors.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize) {
|
||||||
|
if (newSize == 0) {
|
||||||
|
free(pointer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* result = realloc(pointer, newSize);
|
||||||
|
|
||||||
|
if (result == NULL) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "[internal] ERROR: Memory allocation error (requested %d, replacing %d)\n" TOY_CC_RESET, (int)newSize, (int)oldSize);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
14
source/toy_memory.h
Normal file
14
source/toy_memory.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "toy_common.h"
|
||||||
|
|
||||||
|
#define TOY_GROW_CAPACITY(capacity) \
|
||||||
|
((capacity) < 8 ? 8 : (capacity) * 2)
|
||||||
|
|
||||||
|
#define TOY_GROW_ARRAY(type, pointer, oldSize, newSize) \
|
||||||
|
(type*)Toy_reallocate(pointer, sizeof(type)*oldSize, sizeof(type)*newSize)
|
||||||
|
|
||||||
|
#define TOY_FREE_ARRAY(type, pointer, oldSize) \
|
||||||
|
(type*)Toy_reallocate(pointer, sizeof(type)*oldSize, 0)
|
||||||
|
|
||||||
|
TOY_API void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize);
|
||||||
5
source/toy_opcodes.h
Normal file
5
source/toy_opcodes.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef enum Toy_OpcodeType {
|
||||||
|
TOY_OPCODE_RETURN,
|
||||||
|
} Toy_OpcodeType;
|
||||||
21
source/toy_value.c
Normal file
21
source/toy_value.c
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include "toy_value.h"
|
||||||
|
|
||||||
|
#include "toy_console_colors.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
bool Toy_private_isTruthy(Toy_Value value) {
|
||||||
|
//null is an error
|
||||||
|
if (TOY_VALUE_IS_NULL(value)) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "ERROR: 'null' is neither true nor false\n" TOY_CC_RESET);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//only 'false' is falsy
|
||||||
|
if (TOY_VALUE_IS_BOOLEAN(value)) {
|
||||||
|
return TOY_VALUE_AS_BOOLEAN(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//anything else is truthy
|
||||||
|
return true;
|
||||||
|
}
|
||||||
55
source/toy_value.h
Normal file
55
source/toy_value.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "toy_common.h"
|
||||||
|
|
||||||
|
typedef enum Toy_ValueType {
|
||||||
|
TOY_VALUE_NULL,
|
||||||
|
TOY_VALUE_BOOLEAN,
|
||||||
|
TOY_VALUE_INTEGER,
|
||||||
|
TOY_VALUE_FLOAT,
|
||||||
|
TOY_VALUE_STRING,
|
||||||
|
TOY_VALUE_ARRAY,
|
||||||
|
TOY_VALUE_DICTIONARY,
|
||||||
|
TOY_VALUE_FUNCTION,
|
||||||
|
TOY_VALUE_OPAQUE,
|
||||||
|
} Toy_ValueType;
|
||||||
|
|
||||||
|
typedef struct Toy_Value {
|
||||||
|
union {
|
||||||
|
bool boolean; //1
|
||||||
|
int integer; //4
|
||||||
|
float number; //4
|
||||||
|
//TODO: strings
|
||||||
|
//TODO: arrays
|
||||||
|
//TODO: dictonaries
|
||||||
|
//TODO: functions
|
||||||
|
//TODO: opaque
|
||||||
|
} as; //4
|
||||||
|
|
||||||
|
Toy_ValueType type; //4 bytes
|
||||||
|
} Toy_Value;
|
||||||
|
|
||||||
|
#define TOY_VALUE_IS_NULL(value) ((value).type == TOY_VALUE_NULL)
|
||||||
|
#define TOY_VALUE_IS_BOOLEAN(value) ((value).type == TOY_VALUE_BOOLEAN)
|
||||||
|
#define TOY_VALUE_IS_INTEGER(value) ((value).type == TOY_VALUE_INTEGER)
|
||||||
|
#define TOY_VALUE_IS_FLOAT(value) ((value).type == TOY_VALUE_FLOAT)
|
||||||
|
#define TOY_VALUE_IS_STRING(value) ((value).type == TOY_VALUE_STRING)
|
||||||
|
#define TOY_VALUE_IS_ARRAY(value) ((value).type == TOY_VALUE_ARRAY)
|
||||||
|
#define TOY_VALUE_IS_DICTIONARY(value) ((value).type == TOY_VALUE_DICTIONARY)
|
||||||
|
#define TOY_VALUE_IS_FUNCTION(value) ((value).type == TOY_VALUE_FUNCTION)
|
||||||
|
#define TOY_VALUE_IS_OPAQUE(value) ((value).type == TOY_VALUE_OPAQUE)
|
||||||
|
|
||||||
|
#define TOY_VALUE_AS_BOOLEAN(value) ((value).as.boolean)
|
||||||
|
#define TOY_VALUE_AS_INTEGER(value) ((value).as.integer)
|
||||||
|
#define TOY_VALUE_AS_FLOAT(value) ((value).as.number)
|
||||||
|
//TODO: more
|
||||||
|
|
||||||
|
#define TOY_VALUE_TO_NULL() ((Toy_Value){{ .integer = 0 }, TOY_VALUE_NULL})
|
||||||
|
#define TOY_VALUE_TO_BOOLEAN(value) ((Toy_Value){{ .boolean = value }, TOY_VALUE_BOOLEAN})
|
||||||
|
#define TOY_VALUE_TO_INTEGER(value) ((Toy_Value){{ .integer = value }, TOY_VALUE_INTEGER})
|
||||||
|
#define TOY_VALUE_TO_FLOAT(value) ((Toy_Value){{ .number = value }, TOY_VALUE_FLOAT})
|
||||||
|
//TODO: more
|
||||||
|
|
||||||
|
#define TOY_VALUE_IS_TRUTHY(value) Toy_private_isTruthy(value)
|
||||||
|
TOY_API bool Toy_private_isTruthy(Toy_Value value);
|
||||||
|
|
||||||
39
tests/cases/test_value.c
Normal file
39
tests/cases/test_value.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#include "toy_value.h"
|
||||||
|
#include "toy_console_colors.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
//test for the correct size
|
||||||
|
{
|
||||||
|
if (sizeof(Toy_Value) != 8) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "ERROR: 'Toy_Value' is an unexpected size in memory\n" TOY_CC_RESET);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//test creating a null
|
||||||
|
{
|
||||||
|
Toy_Value v = TOY_VALUE_TO_NULL();
|
||||||
|
|
||||||
|
if (!TOY_VALUE_IS_NULL(v)) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "ERROR: creating a 'null' value failed\n" TOY_CC_RESET);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//test creating values
|
||||||
|
{
|
||||||
|
Toy_Value t = TOY_VALUE_TO_BOOLEAN(true);
|
||||||
|
Toy_Value f = TOY_VALUE_TO_BOOLEAN(false);
|
||||||
|
|
||||||
|
if (!TOY_VALUE_IS_TRUTHY(t) || TOY_VALUE_IS_TRUTHY(f)) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "ERROR: 'boolean' value failed\n" TOY_CC_RESET);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -3,14 +3,15 @@ CFLAGS=-g -Wall -Werror -Wno-unused-parameter -Wno-unused-function -Wno-unused-v
|
|||||||
LIBS=-lm
|
LIBS=-lm
|
||||||
|
|
||||||
#directories
|
#directories
|
||||||
TEST_SOURCEDIR=../$(TOY_SOURCEDIR)
|
TEST_ROOTDIR=..
|
||||||
|
TEST_SOURCEDIR=$(TEST_ROOTDIR)/$(TOY_SOURCEDIR)
|
||||||
TEST_CASESDIR=cases
|
TEST_CASESDIR=cases
|
||||||
|
|
||||||
TEST_OUTDIR=out
|
TEST_OUTDIR=out
|
||||||
TEST_OBJDIR=obj
|
TEST_OBJDIR=obj
|
||||||
|
|
||||||
#file names
|
#file names
|
||||||
TEST_SOURCEFILES=$(wildcard $(TEST_SOURCEDIR)/*.c)
|
TEST_SOURCEFILES=$(addprefix $(TOY_ROOTDIR)/,$(TOY_SOURCEFILES))
|
||||||
TEST_CASESFILES=$(wildcard $(TEST_CASESDIR)/*.c)
|
TEST_CASESFILES=$(wildcard $(TEST_CASESDIR)/*.c)
|
||||||
|
|
||||||
#build the object files, compile the test cases, and run
|
#build the object files, compile the test cases, and run
|
||||||
@@ -39,7 +40,7 @@ $(TEST_OBJDIR)/%.o: $(TEST_CASESDIR)/%.c
|
|||||||
|
|
||||||
#final linking step (with extra flags to strip dead code)
|
#final linking step (with extra flags to strip dead code)
|
||||||
$(TEST_OUTDIR)/%.exe: $(TEST_OBJDIR)/%.o
|
$(TEST_OUTDIR)/%.exe: $(TEST_OBJDIR)/%.o
|
||||||
@$(CC) -o $@ $(shell find $(TEST_OBJDIR) -name '*.o') $(CFLAGS) $(LIBS) -Wl,--gc-sections
|
@$(CC) -o $@ $< $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_SOURCEFILES:.c=.o))) $(CFLAGS) $(LIBS) -Wl,--gc-sections
|
||||||
$@
|
$@
|
||||||
|
|
||||||
#util commands
|
#util commands
|
||||||
|
|||||||
Reference in New Issue
Block a user