1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-22 05:03:16 +00:00

Work on basic stl. Add _ binding to repl for last value

This commit is contained in:
Calvin Rose 2017-03-09 13:49:46 -05:00
parent ca0f8939ef
commit 169e3de5a7
14 changed files with 180 additions and 37 deletions

View File

@ -6,8 +6,8 @@ TARGET=interp
PREFIX=/usr/local
# C sources
HEADERS=vm.h ds.h compile.h parse.h value.h datatypes.h gc.h util.h gst.h
SOURCES=main.c parse.c value.c vm.c ds.c compile.c gc.c
HEADERS=vm.h ds.h compile.h parse.h value.h datatypes.h gc.h util.h gst.h stl.h
SOURCES=main.c parse.c value.c vm.c ds.c compile.c gc.c stl.c
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
all: $(TARGET)

View File

@ -1320,6 +1320,8 @@ GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form) {
/* Clear all but root scope */
if (c->tail)
c->tail->parent = NULL;
if (c->error == NULL)
c->error = "unknown error";
return NULL;
}
/* Create a scope */

View File

@ -18,7 +18,8 @@ typedef enum GstType {
GST_BYTEBUFFER,
GST_FUNCTION,
GST_CFUNCTION,
GST_OBJECT
GST_OBJECT,
GST_USERDATA
} GstType;
/* The state of the virtual machine */
@ -38,6 +39,7 @@ typedef struct GstThread GstThread;
typedef int (*GstCFunction)(Gst * vm);
/* Implementation details */
typedef struct GstUserdataHeader GstUserdataHeader;
typedef struct GstFuncDef GstFuncDef;
typedef struct GstFuncEnv GstFuncEnv;
@ -104,13 +106,13 @@ struct GstObject {
uint32_t capacity;
GstBucket **buckets;
uint32_t flags;
GstValue meta;
GstObject *meta;
};
/* Some function defintion flags */
#define GST_FUNCDEF_FLAG_VARARG 1
/* A function defintion. Contains information need to instatiate closures. */
/* A function definition. Contains information need to instatiate closures. */
struct GstFuncDef {
uint32_t locals;
uint32_t arity; /* Not including varargs */
@ -142,6 +144,12 @@ struct GstBucket {
GstBucket *next;
};
/* Contains information about userdata */
struct GstUserdataHeader {
uint32_t size;
GstObject *meta;
};
/* A stack frame in the VM */
struct GstStackFrame {
GstValue callee;

14
ds.c
View File

@ -156,6 +156,20 @@ GstValue *gst_tuple(Gst *vm, uint32_t length) {
return tuple;
}
/****/
/* Userdata functions */
/****/
/* Create new userdata */
void *gst_userdata(Gst *vm, uint32_t size, GstObject *meta) {
char *data = gst_alloc(vm, sizeof(GstUserdataHeader) + size);
GstUserdataHeader *header = (GstUserdataHeader *)data;
void *user = data + sizeof(GstUserdataHeader);
header->size = size;
header->meta = meta;
return user;
}
/****/
/* Dictionary functions */
/****/

8
ds.h
View File

@ -67,13 +67,19 @@ GstValue ArrayPeek(GstArray *array);
/****/
/* Tuple functions */
/* These really don't do all that much */
/****/
/* 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 */
/****/

10
gc.c
View File

@ -153,6 +153,16 @@ void gst_mark(Gst *vm, GstValue *x) {
}
}
break;
case GST_USERDATA:
if (gc_header(x->data.string - sizeof(GstUserdataHeader))->color != vm->black) {
GstUserdataHeader *userHeader = (GstUserdataHeader *)x->data.string - 1;
gc_header(userHeader)->color = vm->black;
GstValue temp;
temp.type = GST_OBJECT;
temp.data.object = userHeader->meta;
gst_mark(vm, &temp);
}
}
}

1
gst.h
View File

@ -7,5 +7,6 @@
#include "parse.h"
#include "compile.h"
#include "value.h"
#include "stl.h"
#endif // gst_h_INCLUDED

17
main.c
View File

@ -3,24 +3,13 @@
#include "gst.h"
/* Simple printer for gst strings */
void string_put(FILE *out, uint8_t * string) {
static void string_put(FILE *out, uint8_t * string) {
uint32_t i;
uint32_t len = gst_string_length(string);
for (i = 0; i < len; ++i)
fputc(string[i], out);
}
/* Test c function */
int print(Gst *vm) {
uint32_t j, count;
count = gst_count_args(vm);
for (j = 0; j < count; ++j) {
string_put(stdout, gst_to_string(vm, gst_arg(vm, j)));
fputc('\n', stdout);
}
return GST_RETURN_OK;
}
/* A simple repl for debugging */
void debug_repl(FILE *in, FILE *out) {
char buffer[1024] = {0};
@ -71,7 +60,9 @@ void debug_repl(FILE *in, FILE *out) {
/* Try to compile generated AST */
gst_compiler(&c, &vm);
gst_compiler_add_global_cfunction(&c, "print", print);
gst_stl_load(&c);
/* Save last expression */
gst_compiler_add_global(&c, "_", vm.ret);
func.type = GST_FUNCTION;
func.data.function = gst_compiler_compile(&c, p.value);

14
parse.c
View File

@ -268,15 +268,17 @@ static int string_state(GstParser *p, uint8_t c) {
top->buf.string.state = STRING_STATE_ESCAPE;
} else if (c == '"') {
/* Load a quote form to get the string literal */
GstValue x, array;
GstValue x, tuplev;
GstValue *tuple;
x.type = GST_STRING;
x.data.string = gst_buffer_to_string(p->vm, top->buf.string.buffer);
array.type = GST_ARRAY;
array.data.array = gst_array(p->vm, 2);
gst_array_push(p->vm, array.data.array, gst_load_cstring(p->vm, "quote"));
gst_array_push(p->vm, array.data.array, x);
tuple = gst_tuple(p->vm, 2);
tuplev.type = GST_TUPLE;
tuplev.data.tuple = tuple;
tuple[0] = gst_load_cstring(p->vm, "quote");
tuple[1] = x;
parser_pop(p);
parser_append(p, array);
parser_append(p, tuplev);
} else {
gst_buffer_push(p->vm, top->buf.string.buffer, c);
}

61
stl.c
View File

@ -1,22 +1,50 @@
/* This implemets a standard library in gst. Some of this
* will eventually be ported over to gst if possible */
#include "stl.h"
#include "gst.h"
/****/
/* Misc */
/* Core */
/****/
/* Print values for inspection */
int print(Gst *vm) {
int gst_stl_print(Gst *vm) {
uint32_t j, count;
count = gst_count_args(vm);
for (j = 0; j < count; ++j) {
string_put(stdout, gst_to_string(vm, gst_arg(vm, j)));
uint32_t i;
uint8_t *string = gst_to_string(vm, gst_arg(vm, j));
uint32_t len = gst_string_length(string);
for (i = 0; i < len; ++i)
fputc(string[i], stdout);
fputc('\n', stdout);
}
return GST_RETURN_OK;
}
/* Get class value */
int gst_stl_getclass(Gst *vm) {
GstValue class = gst_get_class(gst_arg(vm, 0));
gst_c_return(vm, class);
}
/* Set class value */
int gst_stl_setclass(Gst *vm) {
GstValue x = gst_arg(vm, 0);
GstValue class = gst_arg(vm, 1);
const char *err = gst_set_class(x, class);
if (err != NULL)
gst_c_throwc(vm, err);
gst_c_return(vm, x);
}
/* Load core */
void gst_stl_load_core(GstCompiler *c) {
gst_compiler_add_global_cfunction(c, "print", gst_stl_print);
gst_compiler_add_global_cfunction(c, "get-class", gst_stl_getclass);
gst_compiler_add_global_cfunction(c, "set-class", gst_stl_setclass);
}
/****/
/* Parsing */
/****/
@ -39,6 +67,11 @@ int gst_stl_parse(Gst *vm) {
}
}
/* Load parsing */
void gst_stl_load_parse(GstCompiler *c) {
gst_compiler_add_global_cfunction(c, "parse", gst_stl_parse);
}
/****/
/* Compiling */
/****/
@ -54,22 +87,38 @@ int gst_stl_compile(Gst *vm) {
/* Check for environment variables */
if (env.type == GST_OBJECT) {
/* Iterate through environment, adding globals */
} else if (env.type != GST_NIL) {
} else if (env.type != GST_NIL) {
gst_c_throwc(vm, "invalid type for environment");
}
}
/* Prepare return value */
ret.type = GST_FUNCTION;
ret.data.function = gst_compiler_compile(&c, ast);
/* Check for errors */
if (c.error != NULL) {
if (c.error == NULL) {
gst_c_return(vm, ret);
} else {
gst_c_throwc(vm, c.error);
}
}
/* Load compilation */
void gst_stl_load_compile(GstCompiler *c) {
gst_compiler_add_global_cfunction(c, "compile", gst_stl_compile);
}
/****/
/* IO */
/****/
/* TODO - add userdata to allow for manipulation of FILE pointers. */
/****/
/* Bootstraping */
/****/
/* Load all libraries */
void gst_stl_load(GstCompiler *c) {
gst_stl_load_core(c);
gst_stl_load_parse(c);
gst_stl_load_compile(c);
}

11
stl.h Normal file
View File

@ -0,0 +1,11 @@
#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

10
util.h
View File

@ -3,13 +3,13 @@
/* String utils */
#define gst_string_raw(s) ((uint32_t *)(s) - 2)
#define gst_string_length(v) (gst_string_raw(v)[0])
#define gst_string_hash(v) (gst_string_raw(v)[1])
#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(s) ((uint32_t *)(s) - 2)
#define gst_tuple_length(v) (gst_tuple_raw(v)[0])
#define gst_tuple_hash(v) (gst_tuple_raw(v)[1])
#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

45
value.c
View File

@ -30,7 +30,7 @@ static uint8_t * number_to_string(Gst *vm, GstNumber x) {
uint8_t *data = gst_alloc(vm, SIZE + 2 * sizeof(uint32_t));
data += 2 * sizeof(uint32_t);
/* TODO - not depend on stdio */
snprintf((char *) data, SIZE, "%.17g", x);
snprintf((char *) data, SIZE, "%.21g", x);
gst_string_hash(data) = 0;
gst_string_length(data) = strlen((char *) data);
return data;
@ -149,6 +149,8 @@ uint8_t *gst_to_string(Gst *vm, GstValue x) {
return string_description(vm, "function", 8, x.data.pointer);
case GST_THREAD:
return string_description(vm, "thread", 6, x.data.pointer);
case GST_USERDATA:
return string_description(vm, "userdata", 8, x.data.pointer);
}
return NULL;
}
@ -463,3 +465,44 @@ const char *gst_set(Gst *vm, GstValue ds, GstValue key, GstValue value) {
}
return NULL;
}
/* Get the class object of a value */
GstValue gst_get_class(GstValue x) {
GstValue ret;
ret.type = GST_NIL;
switch (x.type) {
case GST_OBJECT:
if (x.data.object->meta != NULL) {
ret.type = GST_OBJECT;
ret.data.object = x.data.object->meta;
}
break;
case GST_USERDATA:
{
GstUserdataHeader *header = (GstUserdataHeader *)x.data.pointer - 1;
if (header->meta != NULL) {
ret.type = GST_OBJECT;
ret.data.object = header->meta;
}
}
break;
default:
break;
}
return ret;
}
/* Set the class object of a value. Returns possible c error string */
const char *gst_set_class(GstValue x, GstValue class) {
switch (x.type) {
case GST_OBJECT:
if (class.type != GST_OBJECT) return "class must be of type object";
/* TODO - check for class immutability */
x.data.object->meta = class.data.object;
break;
default:
return "cannot set class object";
}
return NULL;
}

View File

@ -29,4 +29,10 @@ 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 */