1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-24 23:40:27 +00:00

Refactor code. Separate code into different modules to

separate the minimum runtime from auxiliary functions.
Change makefile to allow building static libraries.
This commit is contained in:
Calvin Rose 2017-03-15 20:56:37 -04:00
parent 91f2766dd0
commit 9856142fef
25 changed files with 90 additions and 812 deletions

View File

@ -1,37 +1,63 @@
# TIL
# GST
CFLAGS=-std=c99 -Wall -Wextra -Wpedantic -g
TARGET=gst
######################################################
##### Set global variables for all gst Makefiles #####
######################################################
CFLAGS=-std=c99 -Wall -Wextra -Wpedantic -g -I./include
PREFIX=/usr/local
GST_TARGET=client/gst
GST_CORELIB=core/libgst.a
GST_AUXLIB=clibs/libgstaux.a
GST_HEADERS=$(addprefix include/gst/,\
vm.h ds.h value.h datatypes.h gc.h util.h gst.h stl.h thread.h)
# C sources
HEADERS=vm.h ds.h compile.h parse.h value.h datatypes.h gc.h util.h gst.h stl.h disasm.h thread.h
SOURCES=main.c parse.c value.c vm.c ds.c compile.c gc.c stl.c disasm.c thread.c
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
all: $(GST_TARGET)
all: $(TARGET)
###################################
##### The core vm and runtime #####
###################################
GST_CORE_SOURCES=$(addprefix core/,\
value.c vm.c ds.c gc.c thread.c)
GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES))
$(GST_CORELIB): $(GST_CORE_OBJECTS) $(GST_HEADERS)
ar rcs $(GST_CORELIB) $(GST_CORE_OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJECTS)
#################################
##### The auxiliary library #####
#################################
GST_AUX_SOURCES=$(addprefix clibs/,\
compile.c disasm.c parse.c stl.c)
GST_AUX_OBJECTS=$(patsubst %.c,%.o,$(GST_AUX_SOURCES))
$(GST_AUXLIB): $(GST_AUX_OBJECTS) $(GST_HEADERS)
ar rcs $(GST_AUXLIB) $(GST_AUX_OBJECTS)
%.o : %.c $(HEADERS)
##############################
##### The example client #####
##############################
GST_CLIENT_SOURCES=client/main.c
GST_CLIENT_OBJECTS=$(patsubst %.c,%.o,$(GST_CLIENT_SOURCES))
$(GST_TARGET): $(GST_CLIENT_OBJECTS) $(GST_HEADERS) $(GST_AUXLIB) $(GST_CORELIB)
$(CC) $(CFLAGS) -o $(GST_TARGET) $(GST_CLIENT_OBJECTS) $(GST_CORELIB) $(GST_AUXLIB)
# Compile all .c to .o
%.o : %.c $(GST_HEADERS)
$(CC) $(CFLAGS) -o $@ -c $<
install: $(TARGET)
cp $(TARGET) $(PREFIX)/bin
run: $(GST_TARGET)
./$(GST_TARGET)
debug: $(GST_TARGET)
gdb $(GST_TARGET)
valgrind: $(GST_TARGET)
valgrind ./$(GST_TARGET) --leak-check=full
clean:
rm $(TARGET) || true
rm $(OBJECTS) || true
run: $(TARGET)
./$(TARGET)
debug: $(TARGET)
gdb $(TARGET)
valgrind: $(TARGET)
valgrind ./$(TARGET) --leak-check=full
rm $(GST_TARGET) || true
rm $(GST_CORELIB) || true
rm $(GST_AUXLIB) || true
rm $(GST_CORE_OBJECTS) || true
rm $(GST_AUX_OBJECTS) || true
rm $(GST_CLIENT_OBJECTS) || true
.PHONY: clean install run debug valgrind

View File

@ -1,8 +1,8 @@
#include "compile.h"
#include "ds.h"
#include "value.h"
#include "vm.h"
#include "util.h"
#include <gst/compile.h>
#include <gst/ds.h>
#include <gst/value.h>
#include <gst/vm.h>
#include <gst/util.h>
/* During compilation, FormOptions are passed to ASTs
* as configuration options to allow for some optimizations. */

View File

@ -1,4 +1,4 @@
#include "disasm.h"
#include <gst/disasm.h>
/* Width of padded opcode names */
#define OP_WIDTH 20

View File

@ -1,9 +1,9 @@
#include "util.h"
#include "datatypes.h"
#include "ds.h"
#include "parse.h"
#include "value.h"
#include "vm.h"
#include <gst/util.h>
#include <gst/datatypes.h>
#include <gst/ds.h>
#include <gst/parse.h>
#include <gst/value.h>
#include <gst/vm.h>
static const char UNEXPECTED_CLOSING_DELIM[] = "Unexpected closing delimiter";

View File

@ -1,7 +1,7 @@
/* This implements a standard library in gst. Some of this
* will eventually be ported over to gst if possible */
#include "stl.h"
#include "gst.h"
#include <gst/stl.h>
#include <gst/gst.h>
/****/
/* Core */

View File

@ -1,7 +1,7 @@
#include <stdlib.h>
#include <stdio.h>
#include "gst.h"
#include "disasm.h"
#include <gst/gst.h>
#include <gst/disasm.h>
/* A simple repl for debugging */
void debug_repl(FILE *in, FILE *out) {

View File

@ -1,35 +0,0 @@
#ifndef COMPILE_H_9VXF71HY
#define COMPILE_H_9VXF71HY
#include "datatypes.h"
#include <setjmp.h>
typedef struct GstCompiler GstCompiler;
typedef struct GstScope GstScope;
/* Compilation state */
struct GstCompiler {
Gst *vm;
const char *error;
jmp_buf onError;
GstScope *tail;
GstArray *env;
GstBuffer *buffer;
};
/* Initialize the Compiler */
void gst_compiler(GstCompiler *c, Gst *vm);
/* Register an environment for compilation */
void gst_compiler_env(GstCompiler *c, GstValue env);
/* Register a global for the compilation environment. */
void gst_compiler_add_global(GstCompiler *c, const char *name, GstValue x);
/* Register a global c function for the compilation environment. */
void gst_compiler_add_global_cfunction(GstCompiler *c, const char *name, GstCFunction f);
/* Compile a function that evaluates the given form. */
GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form);
#endif /* end of include guard: COMPILE_H_9VXF71HY */

View File

View File

@ -1,7 +1,7 @@
#include "util.h"
#include "ds.h"
#include "value.h"
#include "vm.h"
#include <gst/util.h>
#include <gst/ds.h>
#include <gst/value.h>
#include <gst/vm.h>
/****/
/* Buffer functions */

View File

@ -1,7 +1,7 @@
#include "datatypes.h"
#include "gc.h"
#include "vm.h"
#include "util.h"
#include <gst/datatypes.h>
#include <gst/gc.h>
#include <gst/vm.h>
#include <gst/util.h>
/* The metadata header associated with an allocated block of memory */
#define gc_header(mem) ((GCMemoryHeader *)(mem) - 1)

View File

@ -1,8 +1,8 @@
#include "datatypes.h"
#include "thread.h"
#include "vm.h"
#include "util.h"
#include "ds.h"
#include <gst/datatypes.h>
#include <gst/thread.h>
#include <gst/vm.h>
#include <gst/util.h>
#include <gst/ds.h>
/* Create a new thread */
GstThread *gst_thread(Gst *vm, GstValue callee, uint32_t capacity) {

View File

@ -1,7 +1,7 @@
#include "util.h"
#include "value.h"
#include "ds.h"
#include "vm.h"
#include <gst/util.h>
#include <gst/value.h>
#include <gst/ds.h>
#include <gst/vm.h>
#include <stdio.h>
/* Boolean truth definition */

View File

@ -1,9 +1,9 @@
#include "vm.h"
#include "util.h"
#include "value.h"
#include "ds.h"
#include "gc.h"
#include "thread.h"
#include <gst/vm.h>
#include <gst/util.h>
#include <gst/value.h>
#include <gst/ds.h>
#include <gst/gc.h>
#include <gst/thread.h>
/* Macros for errors in the vm */

View File

@ -1,217 +0,0 @@
#ifndef DATATYPES_H_PJJ035NT
#define DATATYPES_H_PJJ035NT
#include <stdint.h>
/* Max search depth for classes. */
#define GST_MAX_SEARCH_DEPTH 128
/* Verious types */
typedef enum GstType {
GST_NIL = 0,
GST_NUMBER,
GST_BOOLEAN,
GST_STRING,
GST_ARRAY,
GST_TUPLE,
GST_THREAD,
GST_BYTEBUFFER,
GST_FUNCTION,
GST_CFUNCTION,
GST_OBJECT,
GST_USERDATA
} GstType;
/* The state of the virtual machine */
typedef struct Gst Gst;
/* A general gst value type */
typedef struct GstValue GstValue;
/* All of the gst types */
typedef double GstNumber;
typedef uint8_t GstBoolean;
typedef struct GstFunction GstFunction;
typedef struct GstArray GstArray;
typedef struct GstBuffer GstBuffer;
typedef struct GstObject GstObject;
typedef struct GstThread GstThread;
typedef int (*GstCFunction)(Gst * vm);
/* Implementation details */
typedef struct GstUserdataHeader GstUserdataHeader;
typedef struct GstFuncDef GstFuncDef;
typedef struct GstFuncEnv GstFuncEnv;
/* Definitely implementation details */
typedef struct GstBucket GstBucket;
/* The general gst value type. Contains a large union and
* the type information of the value */
struct GstValue {
GstType type;
union {
GstBoolean boolean;
GstNumber number;
GstArray *array;
GstBuffer *buffer;
GstObject *object;
GstThread *thread;
GstValue *tuple;
GstCFunction cfunction;
GstFunction *function;
uint8_t *string;
char *cstring; /* Allias for ease of use from c */
/* Indirectly used union members */
uint16_t *u16p;
GstFuncEnv *env;
uint16_t hws[4];
uint8_t bytes[8];
void *pointer;
} data;
};
/* A lightweight thread in gst. Does not correspond to
* operating system threads. Used in coroutines. */
struct GstThread {
uint32_t count;
uint32_t capacity;
GstValue *data;
enum {
GST_THREAD_PENDING = 0,
GST_THREAD_ALIVE,
GST_TRHEAD_DEAD
} status;
};
/* A dynamic array type. Useful for implementing a stack. */
struct GstArray {
uint32_t count;
uint32_t capacity;
GstValue *data;
};
/* A bytebuffer type. Used as a mutable string or string builder. */
struct GstBuffer {
uint32_t count;
uint32_t capacity;
uint8_t *data;
};
/* The main Gst type, an obect. Objects are just hashtables with some meta
* information attached in the meta value */
struct GstObject {
uint32_t count;
uint32_t capacity;
GstBucket **buckets;
GstObject *meta;
};
/* Some function defintion flags */
#define GST_FUNCDEF_FLAG_VARARG 1
/* A function definition. Contains information need to instatiate closures. */
struct GstFuncDef {
uint32_t locals;
uint32_t arity; /* Not including varargs */
uint32_t literalsLen;
uint32_t byteCodeLen;
uint32_t flags;
GstValue *literals; /* Contains strings, FuncDefs, etc. */
uint16_t *byteCode;
};
/* A fuction environment */
struct GstFuncEnv {
GstThread *thread; /* When nil, index the local values */
uint32_t stackOffset; /* Used as environment size when off stack */
GstValue *values;
};
/* A function */
struct GstFunction {
GstFuncDef *def;
GstFuncEnv *env;
GstFunction *parent;
};
/* A hash table bucket in an object */
struct GstBucket {
GstValue key;
GstValue value;
GstBucket *next;
};
/* Contains information about userdata */
struct GstUserdataHeader {
uint32_t size;
GstObject *meta;
};
/* VM return status from c function */
#define GST_RETURN_OK 0
#define GST_RETURN_ERROR 1
#define GST_RETURN_CRASH 2
/* The VM state */
struct Gst {
/* Garbage collection */
void *blocks;
uint32_t memoryInterval;
uint32_t nextCollection;
uint32_t black : 1;
/* Thread */
GstThread *thread;
/* A GC root */
GstValue rootenv;
/* Return state */
const char *crash;
GstValue ret; /* Returned value from gst_start. Also holds errors. */
};
/* Bytecode */
enum GstOpCode {
GST_OP_ADD = 0, /* Addition */
GST_OP_SUB, /* Subtraction */
GST_OP_MUL, /* Multiplication */
GST_OP_DIV, /* Division */
GST_OP_MOD, /* Modulo division */
GST_OP_IDV, /* Integer division */
GST_OP_EXP, /* Exponentiation */
GST_OP_CCT, /* Concatenation */
GST_OP_NOT, /* Boolean invert */
GST_OP_NEG, /* Unary negation */
GST_OP_INV, /* Unary multiplicative inverse */
GST_OP_LEN, /* Length */
GST_OP_TYP, /* Type */
GST_OP_FLS, /* Load false */
GST_OP_TRU, /* Load true */
GST_OP_NIL, /* Load nil */
GST_OP_I16, /* Load 16 bit signed integer */
GST_OP_UPV, /* Load upvalue */
GST_OP_JIF, /* Jump if */
GST_OP_JMP, /* Jump */
GST_OP_SUV, /* Set upvalue */
GST_OP_CST, /* Load constant */
GST_OP_I32, /* Load 32 bit signed integer */
GST_OP_F64, /* Load 64 bit IEEE double */
GST_OP_MOV, /* Move value */
GST_OP_CLN, /* Create a closure */
GST_OP_EQL, /* Check equality */
GST_OP_LTN, /* Check less than */
GST_OP_LTE, /* Check less than or equal to */
GST_OP_ARR, /* Create array */
GST_OP_DIC, /* Create object */
GST_OP_TUP, /* Create tuple */
GST_OP_SET, /* Assocaitive set */
GST_OP_GET, /* Associative get */
GST_OP_ERR, /* Throw error */
GST_OP_TRY, /* Begin try block */
GST_OP_UTY, /* End try block */
GST_OP_RET, /* Return from function */
GST_OP_RTN, /* Return nil */
GST_OP_CAL, /* Call function */
GST_OP_TCL /* Tail call */
};
#endif

38
dict.h
View File

@ -1,38 +0,0 @@
#ifndef dict_h_INCLUDED
#define dict_h_INCLUDED
#include "datatypes.h"
/* Indicates object is implement as unsorted array of keypairs */
#define GST_OBJECT_FLAG_ISBAG (1 << 31)
/* Indicates object is immutable */
#define GST_OBJECT_IMMUTABLE (1 << 30)
/* Count at which the object goes from a linear search to a hash table */
#define GST_OBJECT_BAG_THRESHOLD 8
typedef struct GstDict GstDict;
struct GstDict {
uint32_t capacity;
uint32_t count;
uint32_t flags;
GstValue *data;
};
/* Initialize a dictionary */
GstDict *gst_dict(Gst *vm, uint32_t capacity);
/* Get item from dictionary */
GstValue gst_dict_get(GstDict *dict, GstValue key);
/* Get c string from object */
GstValue gst_dict_get_cstring(GstDict *dict, const char *key);
/* Add item to dictionary */
void gst_dict_put(Gst *vm, GstDict *dict, GstValue key, GstValue value);
/* Remove item from dictionary */
void gst_dict_remove(GstDict *dict, GstValue key);
#endif // dict_h_INCLUDED

View File

@ -1,17 +0,0 @@
#ifndef disasm_h_INCLUDED
#define disasm_h_INCLUDED
#include "datatypes.h"
#include <stdio.h>
/* Print disassembly for a given funciton */
void gst_dasm(FILE * out, uint16_t * byteCode, uint32_t len);
/* Print the disassembly for a function definition */
void gst_dasm_funcdef(FILE * out, GstFuncDef * def);
/* Print the disassembly for a function */
void gst_dasm_function(FILE * out, GstFunction * f);
#endif // disasm_h_INCLUDED

104
ds.h
View File

@ -1,104 +0,0 @@
#ifndef ds_h_INCLUDED
#define ds_h_INCLUDED
#include "datatypes.h"
/*
* Data type flags
*/
#define GST_DS_LOCKED 0x01
/****/
/* Buffer functions */
/****/
/* Create a new buffer */
GstBuffer *gst_buffer(Gst *vm, uint32_t capacity);
/* Ensure the buffer has enough capacity */
void gst_buffer_ensure(Gst *vm, GstBuffer *buffer, uint32_t capacity);
/* Get a value from the buffer */
int gst_buffer_get(GstBuffer *buffer, uint32_t index);
/* Push a value to the buffer */
void gst_buffer_push(Gst *vm, GstBuffer *buffer, uint8_t c);
/* Append a piece of memory to the buffer */
void gst_buffer_append(Gst *vm, GstBuffer *buffer, uint8_t *string, uint32_t length);
/* Convert the buffer to a string */
uint8_t *gst_buffer_to_string(Gst * vm, GstBuffer * buffer);
/* Define a push function for pushing a certain type to the buffer */
#define BUFFER_DEFINE(name, type) \
static void gst_buffer_push_##name(Gst * vm, GstBuffer * buffer, type x) { \
union { type t; uint8_t bytes[sizeof(type)]; } u; \
u.t = x; gst_buffer_append(vm, buffer, u.bytes, sizeof(type)); \
}
/****/
/* Array functions */
/****/
/* Create a new Array */
GstArray *gst_array(Gst *vm, uint32_t capacity);
/* Get a value of an array with bounds checking. Returns nil if
* outside bounds. */
GstValue gst_array_get(GstArray *array, uint32_t index);
/* Set a value in the array. Does bounds checking but will not grow
* or shrink the array */
int gst_array_set(GstArray *array, uint32_t index, GstValue x);
/* Ensure that the internal memory hash enough space for capacity items */
void gst_array_ensure(Gst *vm, GstArray *array, uint32_t capacity);
/* Set a value in an array. Will also append to the array if the index is
* greater than the current max index. */
void gst_array_push(Gst *vm, GstArray *array, GstValue x);
/* Pop the last item in the array, or return NIL if empty */
GstValue gst_array_pop(GstArray *array);
/* Look at the top most item of an Array */
GstValue ArrayPeek(GstArray *array);
/****/
/* Tuple functions */
/****/
/* Create an empty tuple. It is expected to be mutated right after
* creation. */
GstValue *gst_tuple(Gst *vm, uint32_t length);
/****/
/* Userdataa functions */
/****/
/* Create new userdata */
void *gst_userdata(Gst *vm, uint32_t size, GstObject *meta);
/****/
/* Object functions */
/****/
/* Create a new object */
GstObject *gst_object(Gst *vm, uint32_t capacity);
/* Get a value out of the object */
GstValue gst_object_get(GstObject *obj, GstValue key);
/* Get a value of of an object with a string key */
GstValue gst_object_get_cstring(GstObject *obj, const char *key);
/* Get a Value from the dictionary, but remove it at the same
* time. */
GstValue gst_object_remove(Gst *vm, GstObject *obj, GstValue key);
/* Put a value into the dictionary. Returns 1 if successful, 0 if out of memory.
* The VM pointer is needed for memory allocation. */
void gst_object_put(Gst *vm, GstObject *obj, GstValue key, GstValue value);
#endif // ds_h_INCLUDED

51
gc.h
View File

@ -1,51 +0,0 @@
#ifndef gc_h_INCLUDED
#define gc_h_INCLUDED
#include "datatypes.h"
/* Makr a value as reachable */
void gst_mark(Gst *vm, GstValue *x);
/* Iterate over all allocated memory, and free memory that is not
* marked as reachable. Flip the gc color flag for next sweep. */
void gst_sweep(Gst *vm);
/* Allocate a chunk memory that will be garbage collected. */
void *gst_alloc(Gst *vm, uint32_t size);
/* Allocate zeroed memory to be garbage collected */
void *gst_zalloc(Gst *vm, uint32_t size);
/* Run a collection */
void gst_collect(Gst *vm);
/* Run a collection if we have alloctaed enough memory since the last
collection */
void gst_maybe_collect(Gst *vm);
/* Clear all memory */
void gst_clear_memory(Gst *vm);
/* Separate memory container. This memory is not gced, but can be freed at once. This
* is used in the compiler and parser to prevent memory leaks on errors. */
typedef void *GstManagedMemory;
/* Initialize managed memory */
void gst_mm_init(GstManagedMemory *mm);
/* Allocate some managed memory */
void *gst_mm_alloc(GstManagedMemory *mm, uint32_t size);
/* Intialize zeroed managed memory */
void *gst_mm_zalloc(GstManagedMemory *mm, uint32_t size);
/* Free a memory block used in managed memory */
void gst_mm_free(GstManagedMemory *mm, void *block);
/* Free all memory in managed memory */
void gst_mm_clear(GstManagedMemory *mm);
/* Analog to realloc */
void *gst_mm_realloc(GstManagedMemory *mm, void *block, uint32_t nsize);
#endif

14
gst.h
View File

@ -1,14 +0,0 @@
#ifndef gst_h_INCLUDED
#define gst_h_INCLUDED
#include "util.h"
#include "datatypes.h"
#include "vm.h"
#include "parse.h"
#include "compile.h"
#include "value.h"
#include "stl.h"
#include "thread.h"
#include "ds.h"
#endif // gst_h_INCLUDED

40
parse.h
View File

@ -1,40 +0,0 @@
#ifndef PARSE_H_ONYWMADW
#define PARSE_H_ONYWMADW
#include "datatypes.h"
typedef struct GstParser GstParser;
typedef struct GstParseState GstParseState;
/* Holds the parsing state */
struct GstParser {
Gst *vm;
const char *error;
GstParseState *data;
GstValue value;
uint32_t count;
uint32_t cap;
uint32_t index;
uint32_t flags;
uint32_t quoteCount;
enum {
GST_PARSER_PENDING = 0,
GST_PARSER_FULL,
GST_PARSER_ERROR
} status;
};
/* Some parser flags */
#define GST_PARSER_FLAG_INCOMMENT 1
#define GST_PARSER_FLAG_EXPECTING_COMMENT 2
/* Initialize a parser */
void gst_parser(GstParser *p, Gst *vm);
/* Parse a c style string. Returns number of bytes read */
int gst_parse_cstring(GstParser *p, const char *string);
/* Parse a gst string. Returns number of bytes read */
int gst_parse_string(GstParser *p, uint8_t *string);
#endif /* end of include guard: PARSE_H_ONYWMADW */

11
stl.h
View File

@ -1,11 +0,0 @@
#ifndef stl_h_INCLUDED
#define stl_h_INCLUDED
#include "datatypes.h"
#include "compile.h"
/* Load the standard library */
void gst_stl_load(GstCompiler *c);
#endif // stl_h_INCLUDED

View File

@ -1,47 +0,0 @@
#ifndef thread_h_INCLUDED
#define thread_h_INCLUDED
#include "datatypes.h"
/* Get the current stack frame */
#define gst_thread_stack(t) ((t)->data + (t)->count)
/* Create a new thread */
GstThread *gst_thread(Gst *vm, GstValue callee, uint32_t capacity);
/* Ensure that the thread has enough EXTRA capacity */
void gst_thread_ensure_extra(Gst *vm, GstThread *thread, uint32_t extra);
/* Push a value on the current stack frame*/
void gst_thread_push(Gst *vm, GstThread *thread, GstValue x);
/* Push n nils onto the stack */
void gst_thread_pushnil(Gst *vm, GstThread *thread, uint32_t n);
/* Package up extra args after and including n into tuple at n*/
void gst_thread_tuplepack(Gst *vm, GstThread *thread, uint32_t n);
/* Expand a callee on the stack frame to its delegate function. This means that
* objects and userdata that have a "call" attribut in their class will be
* replaced with their delegate function. Call this before pushing any
* arguments to the stack. Returns the new stack. */
GstValue *gst_thread_expand_callable(Gst *vm, GstThread *thread, GstValue callee);
/* Push a stack frame to a thread, with space for arity arguments. Returns the new
* stack. */
GstValue *gst_thread_beginframe(Gst *vm, GstThread *thread, GstValue callee, uint32_t arity);
/* After pushing arguments to a stack frame created with gst_thread_beginframe, call this
* to finalize the frame before starting a function call. */
void gst_thread_endframe(Gst *vm, GstThread *thread);
/* Pop a stack frame from the thread. Returns the new stack frame, or
* NULL if there are no more frames */
GstValue *gst_thread_popframe(Gst *vm, GstThread *thread);
/* Move the current stack frame over its parent stack frame, allowing
* for primitive tail calls. Return new stack. */
GstValue *gst_thread_tail(Gst *vm, GstThread *thread);
#endif // thread_h_INCLUDED

86
util.h
View File

@ -1,86 +0,0 @@
#ifndef util_h_INCLUDED
#define util_h_INCLUDED
/* String utils */
#define gst_string_raw(s) ((uint32_t *)(s) - 2)
#define gst_string_length(s) (gst_string_raw(s)[0])
#define gst_string_hash(s) (gst_string_raw(s)[1])
/* Tuple utils */
#define gst_tuple_raw(t) ((uint32_t *)(t) - 2)
#define gst_tuple_length(t) (gst_tuple_raw(t)[0])
#define gst_tuple_hash(t) (gst_tuple_raw(t)[1])
/* Memcpy for moving memory */
#ifndef gst_memcpy
#include <string.h>
#define gst_memcpy memcpy
#endif
/* Allocation */
#ifndef gst_raw_alloc
#include <stdlib.h>
#define gst_raw_alloc malloc
#endif
/* Zero allocation */
#ifndef gst_raw_calloc
#include <stdlib.h>
#define gst_raw_calloc calloc
#endif
/* Realloc */
#ifndef gst_raw_realloc
#include <stdlib.h>
#define gst_raw_realloc realloc
#endif
/* Free */
#ifndef gst_raw_free
#include <stdlib.h>
#define gst_raw_free free
#endif
/* Null */
#ifndef NULL
#define NULL ((void *)0)
#endif
/* Stack frame manipulation */
/* Size of stack frame in number of values */
#define GST_FRAME_SIZE 5
/* Macros for referencing a stack frame given a stack */
#define gst_frame_callee(s) (*(s - 1))
#define gst_frame_size(s) ((s - 2)->data.hws[0])
#define gst_frame_prevsize(s) ((s - 2)->data.hws[1])
#define gst_frame_errloc(s) ((s - 2)->data.hws[2])
#define gst_frame_ret(s) ((s - 2)->data.hws[3])
#define gst_frame_pc(s) ((s - 3)->data.u16p)
#define gst_frame_errjmp(s) ((s - 4)->data.u16p)
#define gst_frame_env(s) ((s - 5)->data.env)
/* C function helpers */
/* Return in a c function */
#define gst_c_return(vm, x) do { (vm)->ret = (x); return GST_RETURN_OK; } while (0)
/* Throw error from a c function */
#define gst_c_throw(vm, e) do { (vm)->ret = (e); return GST_RETURN_ERROR; } while (0)
/* Throw c string error from a c function */
#define gst_c_throwc(vm, e) gst_c_throw((vm), gst_load_cstring((vm), (e)))
/* Assert from a c function */
#define gst_c_assert(vm, cond, e) do {if (cond) gst_c_throw((vm), (e)); } while (0)
/* What to do when out of memory */
#ifndef GST_OUT_OF_MEMORY
#include <stdlib.h>
#include <stdio.h>
#define GST_OUT_OF_MEMORY do { printf("out of memory.\n"); exit(1); } while (0)
#endif
#endif // util_h_INCLUDED

44
value.h
View File

@ -1,44 +0,0 @@
#ifndef VALUE_H_1RJPQKFM
#define VALUE_H_1RJPQKFM
#include "datatypes.h"
/* Check for boolean truthiness */
int gst_truthy(GstValue x);
/* Compare two gst values. All gst values are comparable and strictly
* ordered by default. Return 0 if equal, -1 if x is less than y, and
* 1 and x is greater than y. */
int gst_compare(GstValue x, GstValue y);
/* Returns if two values are equal. */
int gst_equals(GstValue x, GstValue y);
/* Get a value from an associative gst object. Can throw errors. */
const char *gst_get(GstValue ds, GstValue key, GstValue *out);
/* Set a value in an associative gst object. Can throw errors. */
const char *gst_set(Gst *vm, GstValue ds, GstValue key, GstValue value);
/* Load a c style string into a gst value (copies data) */
GstValue gst_load_cstring(Gst *vm, const char *string);
/* Simple hash function (djb2) */
uint32_t gst_string_calchash(const uint8_t *str);
/* C string hash version */
uint32_t gst_cstring_calchash(const uint8_t *str, uint32_t len);
/* Convert any gst value into a string */
uint8_t *gst_to_string(Gst *vm, GstValue x);
/* Generate a hash value for a gst object */
uint32_t gst_hash(GstValue x);
/* Get the class object of a value */
GstValue gst_get_class(GstValue x);
/* Set the class object of a value. Returns possible c error string */
const char *gst_set_class(GstValue obj, GstValue class);
#endif /* end of include guard: VALUE_H_1RJPQKFM */

44
vm.h
View File

@ -1,44 +0,0 @@
#ifndef VM_H_C4OZU8CQ
#define VM_H_C4OZU8CQ
#include "datatypes.h"
#include "value.h"
/* Initialize the VM */
void gst_init(Gst * vm);
/* Deinitialize the VM */
void gst_deinit(Gst * vm);
/* Start running the VM with a given entry point */
int gst_run(Gst *vm, GstValue func);
/* Start running the VM from where it left off. */
int gst_continue(Gst *vm);
/* Call a gst value */
int gst_call(Gst *vm, GstValue callee, uint32_t arity, GstValue *args);
/* Run garbage collection */
void gst_collect(Gst * vm);
/* Collect garbage if enough memory has been allocated since
* the previous collection */
void gst_maybe_collect(Gst * vm);
/* Allocate memory */
void * gst_alloc(Gst * vm, uint32_t amount);
/* Allocate zeroed memory */
void * gst_zalloc(Gst * vm, uint32_t amount);
/* Get an argument from the stack */
GstValue gst_arg(Gst * vm, uint16_t index);
/* Put a value on the stack */
void gst_set_arg(Gst * vm, uint16_t index, GstValue x);
/* Get the number of arguments on the stack */
uint16_t gst_count_args(Gst * vm);
#endif /* end of include guard: VM_H_C4OZU8CQ */