mirror of
https://github.com/janet-lang/janet
synced 2025-01-12 08:30:26 +00:00
Remove lots of headers. Add parse c function.
This commit is contained in:
parent
70478a410b
commit
c3d65cb91d
6
Makefile
6
Makefile
@ -8,7 +8,7 @@ PREFIX=/usr/local
|
|||||||
GST_TARGET=client/gst
|
GST_TARGET=client/gst
|
||||||
GST_CORELIB=core/libgst.a
|
GST_CORELIB=core/libgst.a
|
||||||
GST_INTERNAL_HEADERS=$(addprefix core/, cache.h)
|
GST_INTERNAL_HEADERS=$(addprefix core/, cache.h)
|
||||||
GST_HEADERS=$(addprefix include/gst/, gst.h stl.h compile.h disasm.h parse.h)
|
GST_HEADERS=$(addprefix include/gst/, gst.h)
|
||||||
|
|
||||||
all: $(GST_TARGET)
|
all: $(GST_TARGET)
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ all: $(GST_TARGET)
|
|||||||
##### The core vm and runtime #####
|
##### The core vm and runtime #####
|
||||||
###################################
|
###################################
|
||||||
GST_CORE_SOURCES=$(addprefix core/,\
|
GST_CORE_SOURCES=$(addprefix core/,\
|
||||||
compile.c disasm.c parse.c stl.c ids.c util.c\
|
compile.c parse.c stl.c ids.c util.c\
|
||||||
value.c vm.c ds.c gc.c thread.c serialize.c)
|
value.c vm.c ds.c gc.c thread.c serialize.c)
|
||||||
GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES))
|
GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES))
|
||||||
|
|
||||||
@ -49,6 +49,6 @@ clean:
|
|||||||
rm vgcore.* || true
|
rm vgcore.* || true
|
||||||
|
|
||||||
test: $(GST_TARGET)
|
test: $(GST_TARGET)
|
||||||
gsttests/basic.gst
|
$(GST_TARGET) gsttests/basic.gst
|
||||||
|
|
||||||
.PHONY: clean install run debug valgrind
|
.PHONY: clean install run debug valgrind
|
||||||
|
@ -23,9 +23,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/parse.h>
|
|
||||||
#include <gst/compile.h>
|
|
||||||
#include <gst/stl.h>
|
|
||||||
|
|
||||||
/* Use readline support for now */
|
/* Use readline support for now */
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
@ -38,9 +35,6 @@ int debug_compile_and_run(Gst *vm, GstValue ast, GstValue last) {
|
|||||||
/* Try to compile generated AST */
|
/* Try to compile generated AST */
|
||||||
gst_compiler(&c, vm);
|
gst_compiler(&c, vm);
|
||||||
gst_compiler_usemodule(&c, "std");
|
gst_compiler_usemodule(&c, "std");
|
||||||
gst_compiler_usemodule(&c, "std.io");
|
|
||||||
gst_compiler_usemodule(&c, "std.parse");
|
|
||||||
gst_compiler_usemodule(&c, "std.compile");
|
|
||||||
gst_compiler_global(&c, "_", last);
|
gst_compiler_global(&c, "_", last);
|
||||||
func = gst_wrap_function(gst_compiler_compile(&c, ast));
|
func = gst_wrap_function(gst_compiler_compile(&c, ast));
|
||||||
/* Check for compilation errors */
|
/* Check for compilation errors */
|
||||||
@ -147,8 +141,7 @@ int main(int argc, const char **argv) {
|
|||||||
|
|
||||||
gst_init(&vm);
|
gst_init(&vm);
|
||||||
gst_stl_load(&vm);
|
gst_stl_load(&vm);
|
||||||
gst_parse_load(&vm);
|
|
||||||
gst_compile_load(&vm);
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
const char *filename;
|
const char *filename;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/compile.h>
|
|
||||||
|
|
||||||
/* During compilation, FormOptions are passed to ASTs
|
/* During compilation, FormOptions are passed to ASTs
|
||||||
* as configuration options to allow for some optimizations. */
|
* as configuration options to allow for some optimizations. */
|
||||||
@ -1210,34 +1209,3 @@ GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form) {
|
|||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***/
|
|
||||||
/* Stl */
|
|
||||||
/***/
|
|
||||||
|
|
||||||
/* Compile a value */
|
|
||||||
static int gst_stl_compile(Gst *vm) {
|
|
||||||
GstFunction *ret;
|
|
||||||
GstValue std;
|
|
||||||
GstCompiler c;
|
|
||||||
gst_compiler(&c, vm);
|
|
||||||
std = gst_table_get(vm->modules, gst_string_cv(vm, "std"));
|
|
||||||
gst_compiler_globals(&c, std);
|
|
||||||
gst_compiler_globals(&c, gst_arg(vm, 1));
|
|
||||||
gst_compiler_nilglobals(&c, gst_arg(vm, 2));
|
|
||||||
ret = gst_compiler_compile(&c, gst_arg(vm, 0));
|
|
||||||
if (!ret)
|
|
||||||
gst_c_throw(vm, c.error);
|
|
||||||
gst_c_return(vm, gst_wrap_function(ret));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The module stuff */
|
|
||||||
static const GstModuleItem gst_compile_module[] = {
|
|
||||||
{"compile", gst_stl_compile},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Load compiler library */
|
|
||||||
void gst_compile_load(Gst *vm) {
|
|
||||||
gst_module(vm, "std.compile", gst_compile_module);
|
|
||||||
}
|
|
||||||
|
194
core/disasm.c
194
core/disasm.c
@ -1,194 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 Calvin Rose
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
|
||||||
* deal in the Software without restriction, including without limitation the
|
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gst/disasm.h>
|
|
||||||
|
|
||||||
/* Width of padded opcode names */
|
|
||||||
#define OP_WIDTH 20
|
|
||||||
|
|
||||||
/* Print various register and arguments to instructions */
|
|
||||||
static void dasm_print_slot(FILE *out, uint16_t index) { fprintf(out, "%d ", index); }
|
|
||||||
static void dasm_print_i16(FILE *out, int16_t number) { fprintf(out, "#%d ", number); }
|
|
||||||
static void dasm_print_i32(FILE *out, int32_t number) { fprintf(out, "#%d ", number); }
|
|
||||||
static void dasm_print_f64(FILE *out, double number) { fprintf(out, "#%f ", number); }
|
|
||||||
static void dasm_print_literal(FILE *out, uint16_t index) { fprintf(out, "(%d) ", index); }
|
|
||||||
static void dasm_print_upvalue(FILE *out, uint16_t level, uint16_t index) {
|
|
||||||
fprintf(out, "<%d, %d> ", level, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print the name of the argument but pad it */
|
|
||||||
static void dasm_print_arg(FILE *out, const char *name) {
|
|
||||||
uint32_t i = 0;
|
|
||||||
char c;
|
|
||||||
while ((c = *name++)) {
|
|
||||||
putc(c, out);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
for (; i < OP_WIDTH; ++i)
|
|
||||||
fputc(' ', out);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print instructions that take a fixed number of arguments */
|
|
||||||
static uint32_t dasm_fixed_op(FILE *out, const uint16_t *current,
|
|
||||||
const char * name, uint32_t size) {
|
|
||||||
uint32_t i;
|
|
||||||
dasm_print_arg(out, name);
|
|
||||||
for (i = 1; i <= size; ++i)
|
|
||||||
dasm_print_slot(out, current[i]);
|
|
||||||
return size + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print instructions that take a variable number of arguments */
|
|
||||||
static uint32_t dasm_varg_op(FILE *out, const uint16_t *current,
|
|
||||||
const char * name, uint32_t extra) {
|
|
||||||
uint32_t i, argCount;
|
|
||||||
dasm_print_arg(out, name);
|
|
||||||
for (i = 0; i < extra; ++i) {
|
|
||||||
dasm_print_slot(out, current[i + 1]);
|
|
||||||
}
|
|
||||||
argCount = current[extra + 1];
|
|
||||||
if (extra)
|
|
||||||
fprintf(out, ": "); /* Argument separator */
|
|
||||||
for (i = 0; i < argCount; ++i) {
|
|
||||||
dasm_print_slot(out, current[i + extra + 2]);
|
|
||||||
}
|
|
||||||
return argCount + extra + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print the disassembly for a function definition */
|
|
||||||
void gst_dasm_funcdef(FILE *out, GstFuncDef *def) {
|
|
||||||
gst_dasm(out, def->byteCode, def->byteCodeLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print the disassembly for a function */
|
|
||||||
void gst_dasm_function(FILE *out, GstFunction *f) {
|
|
||||||
gst_dasm(out, f->def->byteCode, f->def->byteCodeLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disassemble some bytecode and display it as opcode + arguments assembly */
|
|
||||||
void gst_dasm(FILE *out, uint16_t *byteCode, uint32_t len) {
|
|
||||||
uint16_t *current = byteCode;
|
|
||||||
uint16_t *end = byteCode + len;
|
|
||||||
|
|
||||||
while (current < end) {
|
|
||||||
switch (*current) {
|
|
||||||
default:
|
|
||||||
current += dasm_fixed_op(out, current, "unknown", 0);
|
|
||||||
break;
|
|
||||||
case GST_OP_FLS:
|
|
||||||
current += dasm_fixed_op(out, current, "loadFalse", 1);
|
|
||||||
break;
|
|
||||||
case GST_OP_TRU:
|
|
||||||
current += dasm_fixed_op(out, current, "loadTrue", 1);
|
|
||||||
break;
|
|
||||||
case GST_OP_NIL:
|
|
||||||
current += dasm_fixed_op(out, current, "loadNil", 1);
|
|
||||||
break;
|
|
||||||
case GST_OP_I16:
|
|
||||||
dasm_print_arg(out, "loadInt16");
|
|
||||||
dasm_print_slot(out, current[1]);
|
|
||||||
dasm_print_i16(out, ((int16_t *)current)[2]);
|
|
||||||
current += 3;
|
|
||||||
break;
|
|
||||||
case GST_OP_UPV:
|
|
||||||
dasm_print_arg(out, "loadUpValue");
|
|
||||||
dasm_print_slot(out, current[1]);
|
|
||||||
dasm_print_upvalue(out, current[2], current[3]);
|
|
||||||
current += 4;
|
|
||||||
break;
|
|
||||||
case GST_OP_JIF:
|
|
||||||
dasm_print_arg(out, "jumpIf");
|
|
||||||
dasm_print_slot(out, current[1]);
|
|
||||||
dasm_print_i32(out, ((int32_t *)(current + 2))[0]);
|
|
||||||
current += 4;
|
|
||||||
break;
|
|
||||||
case GST_OP_JMP:
|
|
||||||
dasm_print_arg(out, "jump");
|
|
||||||
dasm_print_i32(out, ((int32_t *)(current + 1))[0]);
|
|
||||||
current += 3;
|
|
||||||
break;
|
|
||||||
case GST_OP_SUV:
|
|
||||||
dasm_print_arg(out, "setUpValue");
|
|
||||||
dasm_print_slot(out, current[1]);
|
|
||||||
dasm_print_upvalue(out, current[2], current[3]);
|
|
||||||
current += 4;
|
|
||||||
break;
|
|
||||||
case GST_OP_CST:
|
|
||||||
dasm_print_arg(out, "loadLiteral");
|
|
||||||
dasm_print_slot(out, current[1]);
|
|
||||||
dasm_print_literal(out, current[2]);
|
|
||||||
current += 3;
|
|
||||||
break;
|
|
||||||
case GST_OP_I32:
|
|
||||||
dasm_print_arg(out, "loadInt32");
|
|
||||||
dasm_print_slot(out, current[1]);
|
|
||||||
dasm_print_i32(out, ((int32_t *)(current + 2))[0]);
|
|
||||||
current += 4;
|
|
||||||
break;
|
|
||||||
case GST_OP_F64:
|
|
||||||
dasm_print_arg(out, "loadFloat64");
|
|
||||||
dasm_print_slot(out, current[1]);
|
|
||||||
dasm_print_f64(out, ((double *)(current + 2))[0]);
|
|
||||||
current += 6;
|
|
||||||
break;
|
|
||||||
case GST_OP_MOV:
|
|
||||||
current += dasm_fixed_op(out, current, "move", 2);
|
|
||||||
break;
|
|
||||||
case GST_OP_CLN:
|
|
||||||
dasm_print_arg(out, "makeClosure");
|
|
||||||
dasm_print_slot(out, current[1]);
|
|
||||||
dasm_print_literal(out, current[2]);
|
|
||||||
current += 3;
|
|
||||||
break;
|
|
||||||
case GST_OP_ARR:
|
|
||||||
current += dasm_varg_op(out, current, "array", 1);
|
|
||||||
break;
|
|
||||||
case GST_OP_DIC:
|
|
||||||
current += dasm_varg_op(out, current, "table", 1);
|
|
||||||
break;
|
|
||||||
case GST_OP_TUP:
|
|
||||||
current += dasm_varg_op(out, current, "tuple", 1);
|
|
||||||
break;
|
|
||||||
case GST_OP_RET:
|
|
||||||
current += dasm_fixed_op(out, current, "return", 1);
|
|
||||||
break;
|
|
||||||
case GST_OP_RTN:
|
|
||||||
current += dasm_fixed_op(out, current, "returnNil", 0);
|
|
||||||
break;
|
|
||||||
case GST_OP_PSK:
|
|
||||||
current += dasm_varg_op(out, current, "pushArgs", 0);
|
|
||||||
break;
|
|
||||||
case GST_OP_PAR:
|
|
||||||
current += dasm_fixed_op(out, current, "pushSeq", 1);
|
|
||||||
break;
|
|
||||||
case GST_OP_CAL:
|
|
||||||
current += dasm_fixed_op(out, current, "call", 2);
|
|
||||||
break;
|
|
||||||
case GST_OP_TCL:
|
|
||||||
current += dasm_fixed_op(out, current, "tailCall", 1);
|
|
||||||
break;
|
|
||||||
case GST_OP_TRN:
|
|
||||||
current += dasm_fixed_op(out, current, "transfer", 3);
|
|
||||||
}
|
|
||||||
fprintf(out, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
185
core/parse.c
185
core/parse.c
@ -21,39 +21,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/parse.h>
|
|
||||||
|
|
||||||
static const char UNEXPECTED_CLOSING_DELIM[] = "Unexpected closing delimiter";
|
static const char UNEXPECTED_CLOSING_DELIM[] = "Unexpected closing delimiter";
|
||||||
|
|
||||||
/* The type of a ParseState */
|
|
||||||
typedef enum ParseType {
|
|
||||||
PTYPE_FORM,
|
|
||||||
PTYPE_STRING,
|
|
||||||
PTYPE_TOKEN
|
|
||||||
} ParseType;
|
|
||||||
|
|
||||||
/* Contain a parse state that goes on the parse stack */
|
|
||||||
struct GstParseState {
|
|
||||||
ParseType type;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
uint8_t endDelimiter;
|
|
||||||
GstArray *array;
|
|
||||||
} form;
|
|
||||||
struct {
|
|
||||||
GstBuffer *buffer;
|
|
||||||
uint32_t count;
|
|
||||||
uint32_t accum;
|
|
||||||
enum {
|
|
||||||
STRING_STATE_BASE,
|
|
||||||
STRING_STATE_ESCAPE,
|
|
||||||
STRING_STATE_ESCAPE_UNICODE,
|
|
||||||
STRING_STATE_ESCAPE_HEX
|
|
||||||
} state;
|
|
||||||
} string;
|
|
||||||
} buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Handle error in parsing */
|
/* Handle error in parsing */
|
||||||
#define p_error(p, e) ((p)->error = (e), (p)->status = GST_PARSER_ERROR)
|
#define p_error(p, e) ((p)->error = (e), (p)->status = GST_PARSER_ERROR)
|
||||||
|
|
||||||
@ -429,7 +399,7 @@ static int form_state(GstParser *p, uint8_t c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle a character */
|
/* Handle a character */
|
||||||
static void dispatch_char(GstParser *p, uint8_t c) {
|
void gst_parse_byte(GstParser *p, uint8_t c) {
|
||||||
int done = 0;
|
int done = 0;
|
||||||
++p->index;
|
++p->index;
|
||||||
/* Dispatch character to state */
|
/* Dispatch character to state */
|
||||||
@ -464,7 +434,7 @@ int gst_parse_cstring(GstParser *p, const char *string) {
|
|||||||
return 0;
|
return 0;
|
||||||
while ((p->status == GST_PARSER_PENDING || p->status == GST_PARSER_ROOT)
|
while ((p->status == GST_PARSER_PENDING || p->status == GST_PARSER_ROOT)
|
||||||
&& (string[bytesRead] != '\0')) {
|
&& (string[bytesRead] != '\0')) {
|
||||||
dispatch_char(p, string[bytesRead++]);
|
gst_parse_byte(p, string[bytesRead++]);
|
||||||
}
|
}
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
@ -476,16 +446,11 @@ int gst_parse_string(GstParser *p, const uint8_t *string) {
|
|||||||
return 0;
|
return 0;
|
||||||
for (i = 0; i < gst_string_length(string); ++i) {
|
for (i = 0; i < gst_string_length(string); ++i) {
|
||||||
if (p->status != GST_PARSER_PENDING && p->status != GST_PARSER_ROOT) break;
|
if (p->status != GST_PARSER_PENDING && p->status != GST_PARSER_ROOT) break;
|
||||||
dispatch_char(p, string[i]);
|
gst_parse_byte(p, string[i]);
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse a single byte */
|
|
||||||
void gst_parse_byte(GstParser *p, uint8_t byte) {
|
|
||||||
dispatch_char(p, byte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if a parser has a value that needs to be handled. If
|
/* Check if a parser has a value that needs to be handled. If
|
||||||
* so, the parser will not parse any more input until that value
|
* so, the parser will not parse any more input until that value
|
||||||
* is consumed. */
|
* is consumed. */
|
||||||
@ -512,147 +477,3 @@ void gst_parser(GstParser *p, Gst *vm) {
|
|||||||
p->status = GST_PARSER_ROOT;
|
p->status = GST_PARSER_ROOT;
|
||||||
p->value.type = GST_NIL;
|
p->value.type = GST_NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GC mark a parser */
|
|
||||||
static void gst_stl_parser_mark(Gst *vm, void *data, uint32_t len) {
|
|
||||||
uint32_t i;
|
|
||||||
GstParser *p = (GstParser *) data;
|
|
||||||
if (len != sizeof(GstParser))
|
|
||||||
return;
|
|
||||||
gst_mark_mem(vm, p->data);
|
|
||||||
gst_mark_value(vm, p->value);
|
|
||||||
for (i = 0; i < p->count; ++i) {
|
|
||||||
GstParseState *ps = p->data + i;
|
|
||||||
switch (ps->type) {
|
|
||||||
case PTYPE_FORM:
|
|
||||||
gst_mark_value(vm, gst_wrap_array(ps->buf.form.array));
|
|
||||||
break;
|
|
||||||
case PTYPE_STRING:
|
|
||||||
case PTYPE_TOKEN:
|
|
||||||
gst_mark_value(vm, gst_wrap_buffer(ps->buf.string.buffer));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***/
|
|
||||||
/* Stl functions */
|
|
||||||
/***/
|
|
||||||
|
|
||||||
/* Parse filetype */
|
|
||||||
static const GstUserType gst_stl_parsetype = {
|
|
||||||
"std.parser",
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&gst_stl_parser_mark
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Create a parser */
|
|
||||||
static int gst_stl_parser(Gst *vm) {
|
|
||||||
GstParser *p = gst_userdata(vm, sizeof(GstParser), &gst_stl_parsetype);
|
|
||||||
gst_parser(p, vm);
|
|
||||||
gst_c_return(vm, gst_wrap_userdata(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Consume a value from the parser */
|
|
||||||
static int gst_stl_parser_consume(Gst *vm) {
|
|
||||||
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
|
||||||
if (p == NULL)
|
|
||||||
gst_c_throwc(vm, "expected parser");
|
|
||||||
if (p->status == GST_PARSER_ERROR)
|
|
||||||
gst_c_return(vm, gst_string_cv(vm, p->error));
|
|
||||||
if (!gst_parse_hasvalue(p))
|
|
||||||
gst_c_throwc(vm, "parser has no pending value");
|
|
||||||
gst_c_return(vm, gst_parse_consume(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the parser has a value to consume */
|
|
||||||
static int gst_stl_parser_hasvalue(Gst *vm) {
|
|
||||||
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
|
||||||
if (p == NULL)
|
|
||||||
gst_c_throwc(vm, "expected parser");
|
|
||||||
gst_c_return(vm, gst_wrap_boolean(gst_parse_hasvalue(p)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse a single byte. Returns if the byte was successfully parsed. */
|
|
||||||
static int gst_stl_parser_byte(Gst *vm) {
|
|
||||||
GstInteger b;
|
|
||||||
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
|
||||||
if (p == NULL)
|
|
||||||
gst_c_throwc(vm, "expected parser");
|
|
||||||
if (!gst_check_integer(vm, 1, &b))
|
|
||||||
gst_c_throwc(vm, "expected integer");
|
|
||||||
if (p->status == GST_PARSER_PENDING || p->status == GST_PARSER_ROOT) {
|
|
||||||
dispatch_char(p, b);
|
|
||||||
gst_c_return(vm, gst_wrap_boolean(1));
|
|
||||||
} else {
|
|
||||||
gst_c_return(vm, gst_wrap_boolean(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse a string or buffer. Returns nil if the entire char array is parsed,
|
|
||||||
* otherwise returns the remainder of what could not be parsed. */
|
|
||||||
static int gst_stl_parser_charseq(Gst *vm) {
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t len;
|
|
||||||
const uint8_t *data;
|
|
||||||
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
|
||||||
if (p == NULL)
|
|
||||||
gst_c_throwc(vm, "expected parser");
|
|
||||||
if (!gst_chararray_view(gst_arg(vm, 1), &data, &len))
|
|
||||||
gst_c_throwc(vm, "expected string/buffer");
|
|
||||||
for (i = 0; i < len; ++i) {
|
|
||||||
if (p->status != GST_PARSER_PENDING && p->status != GST_PARSER_ROOT) break;
|
|
||||||
dispatch_char(p, data[i]);
|
|
||||||
}
|
|
||||||
if (i == len) {
|
|
||||||
/* No remainder */
|
|
||||||
gst_c_return(vm, gst_wrap_nil());
|
|
||||||
} else {
|
|
||||||
/* We have remaining characters */
|
|
||||||
gst_c_return(vm, gst_wrap_string(gst_string_b(vm, data + i, len - i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get status of parser */
|
|
||||||
static int gst_stl_parser_status(Gst *vm) {
|
|
||||||
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
|
||||||
const char *cstr;
|
|
||||||
if (p == NULL)
|
|
||||||
gst_c_throwc(vm, "expected parser");
|
|
||||||
switch (p->status) {
|
|
||||||
case GST_PARSER_ERROR:
|
|
||||||
cstr = "error";
|
|
||||||
break;
|
|
||||||
case GST_PARSER_FULL:
|
|
||||||
cstr = "full";
|
|
||||||
break;
|
|
||||||
case GST_PARSER_PENDING:
|
|
||||||
cstr = "pending";
|
|
||||||
break;
|
|
||||||
case GST_PARSER_ROOT:
|
|
||||||
cstr = "root";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cstr = "unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gst_c_return(vm, gst_string_cv(vm, cstr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The module */
|
|
||||||
static const GstModuleItem gst_parser_module[] = {
|
|
||||||
{"parser", gst_stl_parser},
|
|
||||||
{"parse-byte", gst_stl_parser_byte},
|
|
||||||
{"parse-consume", gst_stl_parser_consume},
|
|
||||||
{"parse-hasvalue", gst_stl_parser_hasvalue},
|
|
||||||
{"parse-charseq", gst_stl_parser_charseq},
|
|
||||||
{"parse-status", gst_stl_parser_status},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Load the module */
|
|
||||||
void gst_parse_load(Gst *vm) {
|
|
||||||
gst_module(vm, "std.parse", gst_parser_module);
|
|
||||||
}
|
|
||||||
|
@ -513,9 +513,6 @@ const char *gst_serialize_impl(
|
|||||||
write_int(x.data.integer);
|
write_int(x.data.integer);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
/*case GST_CFUNCTION:*/
|
|
||||||
/* TODO */
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
259
core/stl.c
259
core/stl.c
@ -21,11 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/parse.h>
|
|
||||||
#include <gst/compile.h>
|
|
||||||
#include <gst/stl.h>
|
|
||||||
|
|
||||||
#include <gst/disasm.h>
|
|
||||||
|
|
||||||
static const char GST_EXPECTED_INTEGER[] = "expected integer";
|
static const char GST_EXPECTED_INTEGER[] = "expected integer";
|
||||||
static const char GST_EXPECTED_STRING[] = "expected string";
|
static const char GST_EXPECTED_STRING[] = "expected string";
|
||||||
@ -682,12 +677,6 @@ int gst_stl_namespace_set(Gst *vm) {
|
|||||||
/* Get the table or struct associated with a given namespace */
|
/* Get the table or struct associated with a given namespace */
|
||||||
int gst_stl_namespace_get(Gst *vm) {
|
int gst_stl_namespace_get(Gst *vm) {
|
||||||
return gst_callc(vm, gst_stl_get, 2, gst_wrap_table(vm->modules), gst_arg(vm, 0));
|
return gst_callc(vm, gst_stl_get, 2, gst_wrap_table(vm->modules), gst_arg(vm, 0));
|
||||||
/*GstValue name = gst_arg(vm, 0);*/
|
|
||||||
/*GstValue check;*/
|
|
||||||
/*if (name.type != GST_STRING)*/
|
|
||||||
/*gst_c_throwc(vm, "expected string");*/
|
|
||||||
/*check = gst_table_get(vm->modules, name);*/
|
|
||||||
/*gst_c_return(vm, check);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
@ -808,49 +797,10 @@ int gst_stl_close(Gst *vm) {
|
|||||||
gst_c_return(vm, gst_wrap_nil());
|
gst_c_return(vm, gst_wrap_nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Functions in the io module */
|
|
||||||
static const GstModuleItem io_dat[] = {
|
|
||||||
{"open", gst_stl_open},
|
|
||||||
{"slurp", gst_stl_slurp},
|
|
||||||
{"read", gst_stl_read},
|
|
||||||
{"write", gst_stl_write},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Load the io module */
|
|
||||||
void gst_stlio_load(Gst *vm) {
|
|
||||||
/* Load the normal c functions */
|
|
||||||
gst_module_mutable(vm, "std.io", io_dat);
|
|
||||||
/* Wrap stdin and stdout */
|
|
||||||
FILE **inp = gst_userdata(vm, sizeof(FILE *), &gst_stl_filetype);
|
|
||||||
FILE **outp = gst_userdata(vm, sizeof(FILE *), &gst_stl_filetype);
|
|
||||||
*inp = stdin;
|
|
||||||
*outp = stdout;
|
|
||||||
gst_module_put(vm, "std.io", "stdin", gst_wrap_userdata(inp));
|
|
||||||
gst_module_put(vm, "std.io", "stdout", gst_wrap_userdata(outp));
|
|
||||||
}
|
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
/* Temporary */
|
/* Temporary */
|
||||||
/****/
|
/****/
|
||||||
|
|
||||||
/* These functions should definitely be moved to a different module, removed, or
|
|
||||||
* rewritten in gst when the language is complete enough. This is not to say
|
|
||||||
* that functions in other section need not be moved. */
|
|
||||||
|
|
||||||
/* Print disassembly for a function */
|
|
||||||
int gst_stl_dasm(Gst *vm) {
|
|
||||||
GstValue x = gst_arg(vm, 0);
|
|
||||||
if (x.type == GST_FUNCTION) {
|
|
||||||
printf("%c[31m===== Begin Disassembly =====\n", 27);
|
|
||||||
gst_dasm_function(stdout, x.data.function);
|
|
||||||
printf("===== End Disassembly =====%c[0m\n", 27);
|
|
||||||
} else {
|
|
||||||
gst_c_throwc(vm, "expected function");
|
|
||||||
}
|
|
||||||
return GST_RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Force garbage collection */
|
/* Force garbage collection */
|
||||||
int gst_stl_gcollect(Gst *vm) {
|
int gst_stl_gcollect(Gst *vm) {
|
||||||
gst_collect(vm);
|
gst_collect(vm);
|
||||||
@ -923,6 +873,184 @@ int gst_stl_debugp(Gst *vm) {
|
|||||||
gst_c_return(vm, gst_wrap_string(gst_buffer_to_string(vm, buf)));
|
gst_c_return(vm, gst_wrap_string(gst_buffer_to_string(vm, buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***/
|
||||||
|
/* Parsing */
|
||||||
|
/***/
|
||||||
|
|
||||||
|
/* GC mark a parser */
|
||||||
|
static void gst_stl_parser_mark(Gst *vm, void *data, uint32_t len) {
|
||||||
|
uint32_t i;
|
||||||
|
GstParser *p = (GstParser *) data;
|
||||||
|
if (len != sizeof(GstParser))
|
||||||
|
return;
|
||||||
|
gst_mark_mem(vm, p->data);
|
||||||
|
gst_mark_value(vm, p->value);
|
||||||
|
for (i = 0; i < p->count; ++i) {
|
||||||
|
GstParseState *ps = p->data + i;
|
||||||
|
switch (ps->type) {
|
||||||
|
case PTYPE_FORM:
|
||||||
|
gst_mark_value(vm, gst_wrap_array(ps->buf.form.array));
|
||||||
|
break;
|
||||||
|
case PTYPE_STRING:
|
||||||
|
case PTYPE_TOKEN:
|
||||||
|
gst_mark_value(vm, gst_wrap_buffer(ps->buf.string.buffer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse filetype */
|
||||||
|
static const GstUserType gst_stl_parsetype = {
|
||||||
|
"std.parser",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&gst_stl_parser_mark
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create a parser */
|
||||||
|
static int gst_stl_parser(Gst *vm) {
|
||||||
|
GstParser *p = gst_userdata(vm, sizeof(GstParser), &gst_stl_parsetype);
|
||||||
|
gst_parser(p, vm);
|
||||||
|
gst_c_return(vm, gst_wrap_userdata(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Consume a value from the parser */
|
||||||
|
static int gst_stl_parser_consume(Gst *vm) {
|
||||||
|
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
||||||
|
if (p == NULL)
|
||||||
|
gst_c_throwc(vm, "expected parser");
|
||||||
|
if (p->status == GST_PARSER_ERROR)
|
||||||
|
gst_c_return(vm, gst_string_cv(vm, p->error));
|
||||||
|
if (!gst_parse_hasvalue(p))
|
||||||
|
gst_c_throwc(vm, "parser has no pending value");
|
||||||
|
gst_c_return(vm, gst_parse_consume(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the parser has a value to consume */
|
||||||
|
static int gst_stl_parser_hasvalue(Gst *vm) {
|
||||||
|
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
||||||
|
if (p == NULL)
|
||||||
|
gst_c_throwc(vm, "expected parser");
|
||||||
|
gst_c_return(vm, gst_wrap_boolean(gst_parse_hasvalue(p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse a single byte. Returns if the byte was successfully parsed. */
|
||||||
|
static int gst_stl_parser_byte(Gst *vm) {
|
||||||
|
GstInteger b;
|
||||||
|
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
||||||
|
if (p == NULL)
|
||||||
|
gst_c_throwc(vm, "expected parser");
|
||||||
|
if (!gst_check_integer(vm, 1, &b))
|
||||||
|
gst_c_throwc(vm, "expected integer");
|
||||||
|
if (p->status == GST_PARSER_PENDING || p->status == GST_PARSER_ROOT) {
|
||||||
|
gst_parse_byte(p, b);
|
||||||
|
gst_c_return(vm, gst_wrap_boolean(1));
|
||||||
|
} else {
|
||||||
|
gst_c_return(vm, gst_wrap_boolean(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse a string or buffer. Returns nil if the entire char array is parsed,
|
||||||
|
* otherwise returns the remainder of what could not be parsed. */
|
||||||
|
static int gst_stl_parser_charseq(Gst *vm) {
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t len;
|
||||||
|
const uint8_t *data;
|
||||||
|
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
||||||
|
if (p == NULL)
|
||||||
|
gst_c_throwc(vm, "expected parser");
|
||||||
|
if (!gst_chararray_view(gst_arg(vm, 1), &data, &len))
|
||||||
|
gst_c_throwc(vm, "expected string/buffer");
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
if (p->status != GST_PARSER_PENDING && p->status != GST_PARSER_ROOT) break;
|
||||||
|
gst_parse_byte(p, data[i]);
|
||||||
|
}
|
||||||
|
if (i == len) {
|
||||||
|
/* No remainder */
|
||||||
|
gst_c_return(vm, gst_wrap_nil());
|
||||||
|
} else {
|
||||||
|
/* We have remaining characters */
|
||||||
|
gst_c_return(vm, gst_wrap_string(gst_string_b(vm, data + i, len - i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get status of parser */
|
||||||
|
static int gst_stl_parser_status(Gst *vm) {
|
||||||
|
GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype);
|
||||||
|
const char *cstr;
|
||||||
|
if (p == NULL)
|
||||||
|
gst_c_throwc(vm, "expected parser");
|
||||||
|
switch (p->status) {
|
||||||
|
case GST_PARSER_ERROR:
|
||||||
|
cstr = "error";
|
||||||
|
break;
|
||||||
|
case GST_PARSER_FULL:
|
||||||
|
cstr = "full";
|
||||||
|
break;
|
||||||
|
case GST_PARSER_PENDING:
|
||||||
|
cstr = "pending";
|
||||||
|
break;
|
||||||
|
case GST_PARSER_ROOT:
|
||||||
|
cstr = "root";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cstr = "unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gst_c_return(vm, gst_string_cv(vm, cstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse a string */
|
||||||
|
static int gst_stl_parse(Gst *vm) {
|
||||||
|
uint32_t len, i;
|
||||||
|
GstParser p;
|
||||||
|
const uint8_t *data;
|
||||||
|
if (!gst_chararray_view(gst_arg(vm, 0), &data, &len))
|
||||||
|
gst_c_throwc(vm, "expected string/buffer to parse");
|
||||||
|
gst_parser(&p, vm);
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
if (p.status != GST_PARSER_PENDING && p.status != GST_PARSER_ROOT) break;
|
||||||
|
gst_parse_byte(&p, data[i]);
|
||||||
|
}
|
||||||
|
switch (p.status) {
|
||||||
|
case GST_PARSER_ERROR:
|
||||||
|
gst_c_throwc(vm, p.error);
|
||||||
|
break;
|
||||||
|
case GST_PARSER_FULL:
|
||||||
|
gst_c_return(vm, p.value);
|
||||||
|
break;
|
||||||
|
case GST_PARSER_PENDING:
|
||||||
|
case GST_PARSER_ROOT:
|
||||||
|
gst_c_throwc(vm, "unexpected end of source");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gst_c_throwc(vm, "unknown error parsing");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***/
|
||||||
|
/* Compilation */
|
||||||
|
/***/
|
||||||
|
|
||||||
|
/* Compile a value */
|
||||||
|
static int gst_stl_compile(Gst *vm) {
|
||||||
|
GstFunction *ret;
|
||||||
|
GstValue std;
|
||||||
|
GstCompiler c;
|
||||||
|
gst_compiler(&c, vm);
|
||||||
|
std = gst_table_get(vm->modules, gst_string_cv(vm, "std"));
|
||||||
|
gst_compiler_globals(&c, std);
|
||||||
|
gst_compiler_globals(&c, gst_arg(vm, 1));
|
||||||
|
gst_compiler_nilglobals(&c, gst_arg(vm, 2));
|
||||||
|
ret = gst_compiler_compile(&c, gst_arg(vm, 0));
|
||||||
|
if (!ret)
|
||||||
|
gst_c_throw(vm, c.error);
|
||||||
|
gst_c_return(vm, gst_wrap_function(ret));
|
||||||
|
}
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
/* Bootstraping */
|
/* Bootstraping */
|
||||||
/****/
|
/****/
|
||||||
@ -946,6 +1074,22 @@ static const GstModuleItem std_module[] = {
|
|||||||
{"blshift", gst_stl_blshift},
|
{"blshift", gst_stl_blshift},
|
||||||
{"brshift", gst_stl_brshift},
|
{"brshift", gst_stl_brshift},
|
||||||
{"bnot", gst_stl_bnot},
|
{"bnot", gst_stl_bnot},
|
||||||
|
/* IO */
|
||||||
|
{"open", gst_stl_open},
|
||||||
|
{"slurp", gst_stl_slurp},
|
||||||
|
{"read", gst_stl_read},
|
||||||
|
{"write", gst_stl_write},
|
||||||
|
/* Parsing */
|
||||||
|
{"parser", gst_stl_parser},
|
||||||
|
{"parse-byte", gst_stl_parser_byte},
|
||||||
|
{"parse-consume", gst_stl_parser_consume},
|
||||||
|
{"parse-hasvalue", gst_stl_parser_hasvalue},
|
||||||
|
{"parse-charseq", gst_stl_parser_charseq},
|
||||||
|
{"parse-status", gst_stl_parser_status},
|
||||||
|
{"parse-status", gst_stl_parser_status},
|
||||||
|
{"parse", gst_stl_parse},
|
||||||
|
/* Compile */
|
||||||
|
{"compile", gst_stl_compile},
|
||||||
/* Other */
|
/* Other */
|
||||||
{"not", gst_stl_not},
|
{"not", gst_stl_not},
|
||||||
{"length", gst_stl_length},
|
{"length", gst_stl_length},
|
||||||
@ -988,7 +1132,6 @@ static const GstModuleItem std_module[] = {
|
|||||||
{"funcenv", gst_stl_funcenv},
|
{"funcenv", gst_stl_funcenv},
|
||||||
{"funcdef", gst_stl_funcdef},
|
{"funcdef", gst_stl_funcdef},
|
||||||
{"funcparent", gst_stl_funcparent},
|
{"funcparent", gst_stl_funcparent},
|
||||||
{"dasm", gst_stl_dasm},
|
|
||||||
{"gcollect", gst_stl_gcollect},
|
{"gcollect", gst_stl_gcollect},
|
||||||
{"debugp", gst_stl_debugp},
|
{"debugp", gst_stl_debugp},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
@ -996,6 +1139,16 @@ static const GstModuleItem std_module[] = {
|
|||||||
|
|
||||||
/* Load all libraries */
|
/* Load all libraries */
|
||||||
void gst_stl_load(Gst *vm) {
|
void gst_stl_load(Gst *vm) {
|
||||||
gst_stlio_load(vm);
|
/* Load the normal c functions */
|
||||||
gst_module(vm, "std", std_module);
|
gst_module_mutable(vm, "std", std_module);
|
||||||
|
/* Wrap stdin and stdout */
|
||||||
|
FILE **inp = gst_userdata(vm, sizeof(FILE *), &gst_stl_filetype);
|
||||||
|
FILE **outp = gst_userdata(vm, sizeof(FILE *), &gst_stl_filetype);
|
||||||
|
FILE **errp = gst_userdata(vm, sizeof(FILE *), &gst_stl_filetype);
|
||||||
|
*inp = stdin;
|
||||||
|
*outp = stdout;
|
||||||
|
*errp = stderr;
|
||||||
|
gst_module_put(vm, "std", "stdin", gst_wrap_userdata(inp));
|
||||||
|
gst_module_put(vm, "std", "stdout", gst_wrap_userdata(outp));
|
||||||
|
gst_module_put(vm, "std", "stderr", gst_wrap_userdata(outp));
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 Calvin Rose
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
|
||||||
* deal in the Software without restriction, including without limitation the
|
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMPILE_H_9VXF71HY
|
|
||||||
#define COMPILE_H_9VXF71HY
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
typedef struct GstCompiler GstCompiler;
|
|
||||||
typedef struct GstScope GstScope;
|
|
||||||
|
|
||||||
/* Compilation state */
|
|
||||||
struct GstCompiler {
|
|
||||||
Gst *vm;
|
|
||||||
GstValue error;
|
|
||||||
jmp_buf onError;
|
|
||||||
GstScope *tail;
|
|
||||||
GstBuffer *buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Initialize the Compiler */
|
|
||||||
void gst_compiler(GstCompiler *c, Gst *vm);
|
|
||||||
|
|
||||||
/* Add many globals */
|
|
||||||
void gst_compiler_globals(GstCompiler *c, GstValue env);
|
|
||||||
|
|
||||||
/* Register a global for the compilation environment. */
|
|
||||||
void gst_compiler_global(GstCompiler *c, const char *name, GstValue x);
|
|
||||||
|
|
||||||
/* Use a module */
|
|
||||||
void gst_compiler_usemodule(GstCompiler *c, const char *modulename);
|
|
||||||
|
|
||||||
/* Compile a function that evaluates the given form. */
|
|
||||||
GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form);
|
|
||||||
|
|
||||||
/* Load the library */
|
|
||||||
void gst_compile_load(Gst *vm);
|
|
||||||
|
|
||||||
#endif /* end of include guard: COMPILE_H_9VXF71HY */
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 Calvin Rose
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
|
||||||
* deal in the Software without restriction, including without limitation the
|
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef disasm_h_INCLUDED
|
|
||||||
#define disasm_h_INCLUDED
|
|
||||||
|
|
||||||
#include <gst/gst.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
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
/* String utils */
|
/* String utils */
|
||||||
#define gst_string_raw(s) ((uint32_t *)(s) - 2)
|
#define gst_string_raw(s) ((uint32_t *)(s) - 2)
|
||||||
@ -161,6 +162,10 @@ typedef struct GstFuncEnv GstFuncEnv;
|
|||||||
typedef union GstValueUnion GstValueUnion;
|
typedef union GstValueUnion GstValueUnion;
|
||||||
typedef struct GstModuleItem GstModuleItem;
|
typedef struct GstModuleItem GstModuleItem;
|
||||||
typedef struct GstUserType GstUserType;
|
typedef struct GstUserType GstUserType;
|
||||||
|
typedef struct GstParser GstParser;
|
||||||
|
typedef struct GstParseState GstParseState;
|
||||||
|
typedef struct GstCompiler GstCompiler;
|
||||||
|
typedef struct GstScope GstScope;
|
||||||
|
|
||||||
/* C Api data types */
|
/* C Api data types */
|
||||||
struct GstModuleItem {
|
struct GstModuleItem {
|
||||||
@ -312,6 +317,62 @@ struct Gst {
|
|||||||
GstValue ret; /* Returned value from gst_start. */
|
GstValue ret; /* Returned value from gst_start. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* The type of a ParseState */
|
||||||
|
typedef enum ParseType {
|
||||||
|
PTYPE_FORM,
|
||||||
|
PTYPE_STRING,
|
||||||
|
PTYPE_TOKEN
|
||||||
|
} ParseType;
|
||||||
|
|
||||||
|
/* Contain a parse state that goes on the parse stack */
|
||||||
|
struct GstParseState {
|
||||||
|
ParseType type;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint8_t endDelimiter;
|
||||||
|
GstArray *array;
|
||||||
|
} form;
|
||||||
|
struct {
|
||||||
|
GstBuffer *buffer;
|
||||||
|
uint32_t count;
|
||||||
|
uint32_t accum;
|
||||||
|
enum {
|
||||||
|
STRING_STATE_BASE,
|
||||||
|
STRING_STATE_ESCAPE,
|
||||||
|
STRING_STATE_ESCAPE_UNICODE,
|
||||||
|
STRING_STATE_ESCAPE_HEX
|
||||||
|
} state;
|
||||||
|
} string;
|
||||||
|
} buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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 quoteCount;
|
||||||
|
enum {
|
||||||
|
GST_PARSER_PENDING = 0,
|
||||||
|
GST_PARSER_FULL,
|
||||||
|
GST_PARSER_ERROR,
|
||||||
|
GST_PARSER_ROOT
|
||||||
|
} status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Compilation state */
|
||||||
|
struct GstCompiler {
|
||||||
|
Gst *vm;
|
||||||
|
GstValue error;
|
||||||
|
jmp_buf onError;
|
||||||
|
GstScope *tail;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
};
|
||||||
|
|
||||||
/* Bytecode */
|
/* Bytecode */
|
||||||
enum GstOpCode {
|
enum GstOpCode {
|
||||||
GST_OP_FLS, /* Load false */
|
GST_OP_FLS, /* Load false */
|
||||||
@ -456,6 +517,28 @@ const char *gst_deserialize(
|
|||||||
|
|
||||||
const char *gst_serialize(Gst *vm, GstBuffer *buffer, GstValue x);
|
const char *gst_serialize(Gst *vm, GstBuffer *buffer, GstValue x);
|
||||||
|
|
||||||
|
/***/
|
||||||
|
/* Parsing */
|
||||||
|
/***/
|
||||||
|
|
||||||
|
void gst_parser(GstParser *p, Gst *vm);
|
||||||
|
int gst_parse_cstring(GstParser *p, const char *string);
|
||||||
|
int gst_parse_string(GstParser *p, const uint8_t *string);
|
||||||
|
void gst_parse_byte(GstParser *p, uint8_t byte);
|
||||||
|
int gst_parse_hasvalue(GstParser *p);
|
||||||
|
GstValue gst_parse_consume(GstParser *p);
|
||||||
|
|
||||||
|
/***/
|
||||||
|
/* Compilation */
|
||||||
|
/***/
|
||||||
|
|
||||||
|
void gst_compiler(GstCompiler *c, Gst *vm);
|
||||||
|
void gst_compiler_nilglobals(GstCompiler *c, GstValue env);
|
||||||
|
void gst_compiler_globals(GstCompiler *c, GstValue env);
|
||||||
|
void gst_compiler_global(GstCompiler *c, const char *name, GstValue x);
|
||||||
|
void gst_compiler_usemodule(GstCompiler *c, const char *modulename);
|
||||||
|
GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form);
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
/* GC */
|
/* GC */
|
||||||
/****/
|
/****/
|
||||||
@ -488,6 +571,12 @@ GstValue gst_arg(Gst *vm, uint32_t index);
|
|||||||
void gst_set_arg(Gst *vm, uint32_t index, GstValue x);
|
void gst_set_arg(Gst *vm, uint32_t index, GstValue x);
|
||||||
uint32_t gst_count_args(Gst *vm);
|
uint32_t gst_count_args(Gst *vm);
|
||||||
|
|
||||||
|
/***/
|
||||||
|
/* Stl */
|
||||||
|
/***/
|
||||||
|
|
||||||
|
void gst_stl_load(Gst *vm);
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
/* C Api */
|
/* C Api */
|
||||||
/****/
|
/****/
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 Calvin Rose
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
|
||||||
* deal in the Software without restriction, including without limitation the
|
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PARSE_H_ONYWMADW
|
|
||||||
#define PARSE_H_ONYWMADW
|
|
||||||
|
|
||||||
#include <gst/gst.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 quoteCount;
|
|
||||||
enum {
|
|
||||||
GST_PARSER_PENDING = 0,
|
|
||||||
GST_PARSER_FULL,
|
|
||||||
GST_PARSER_ERROR,
|
|
||||||
GST_PARSER_ROOT
|
|
||||||
} status;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 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, const uint8_t *string);
|
|
||||||
|
|
||||||
/* Parse a single byte */
|
|
||||||
void gst_parse_byte(GstParser *p, uint8_t byte);
|
|
||||||
|
|
||||||
/* Check if a parser has a value that needs to be handled. If
|
|
||||||
* so, the parser will not parse any more input until that value
|
|
||||||
* is consumed. */
|
|
||||||
int gst_parse_hasvalue(GstParser *p);
|
|
||||||
|
|
||||||
/* Gets a value from the parser */
|
|
||||||
GstValue gst_parse_consume(GstParser *p);
|
|
||||||
|
|
||||||
/* Load the parsing library */
|
|
||||||
void gst_parse_load(Gst *vm);
|
|
||||||
|
|
||||||
#endif /* end of include guard: PARSE_H_ONYWMADW */
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017 Calvin Rose
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
|
||||||
* deal in the Software without restriction, including without limitation the
|
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef stl_h_INCLUDED
|
|
||||||
#define stl_h_INCLUDED
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
|
||||||
|
|
||||||
/* Load the standard library */
|
|
||||||
void gst_stl_load(Gst *vm);
|
|
||||||
|
|
||||||
#endif // stl_h_INCLUDED
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user