protoverse

A metaverse protocol
git clone git://jb55.com/protoverse
Log | Files | Refs | README | LICENSE

commit 49f17958c9de9ec29319a5b9535787ae095e05db
parent 47355cd44417f352f51b41a039c937ee2c077eac
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 28 Jun 2020 16:32:51 -0700

group/children parsing wip

Diffstat:
MMakefile | 2+-
Mparse.c | 257++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Mparse.h | 8+++++---
Mprotoverse.c | 9+++++----
Mtypedefs.h | 1+
5 files changed, 233 insertions(+), 44 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ -CFLAGS = -O1 -g -std=c89 -Wall -Wextra -Werror -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement +CFLAGS = -Wno-error=unused-function -O1 -g -std=c89 -Wall -Wextra -Werror -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement OBJS = io.o parse.o diff --git a/parse.c b/parse.c @@ -4,6 +4,7 @@ #include <string.h> #include <ctype.h> #include <stdlib.h> +#include <assert.h> #define tokdebug printf @@ -190,6 +191,11 @@ static int push_int(struct cursor *cursor, int i) return push_data(cursor, (u8*)&i, sizeof(i)); } +static int push_u16(struct cursor *cursor, u16 i) +{ + return push_data(cursor, (u8*)&i, sizeof(i)); +} + static void print_spaces(int n) { int i; @@ -323,8 +329,8 @@ static int pull_number(struct cursor *cursor, u8 **start) cursor->err = TE_NUM_CHAR; cursor->err_data.c = c; return 0; - } - + } + chars++; if (!ok) { @@ -445,6 +451,11 @@ static int pull_symbol(struct cursor *cursor, u8 **start) return chars; } +static void init_cell(struct cell *cell) +{ + memset(cell, 0, sizeof(*cell)); +} + static int read_and_push_atom(struct cursor *cursor, struct cursor *tokens) { struct tok_str str; @@ -620,7 +631,6 @@ static int pull_token(struct cursor *tokens, return 1; } -/* static void print_token_data(union token *token, enum token_type type) { switch (type) { @@ -667,7 +677,6 @@ static void print_current_token(struct cursor *tokens) print_token_data(&token, type); printf("\n"); } -*/ /* * PARSING @@ -930,76 +939,252 @@ static int parse_group(struct cursor *tokens) } */ -static int parse_room(struct cursor *tokens, + +static int parse_cell(struct cursor *tokens, struct cursor *attributes, - struct cell *cell) + struct cursor *cells, + u16 *index); + +static int push_cell(struct cursor *cells, struct cell *cell, u16 *cell_index) { + int index; int ok; - struct cursor temp; - struct cursor cell_attr_inds; - int attr_inds[2] = {0}; - int i; - make_cursor((u8*)cell->attributes, - (u8*)cell->attributes + sizeof(cell->attributes), - &cell_attr_inds); + index = cursor_index(cells, sizeof(cell)); + if (index > 0xFFFF) { + /* TODO: actual error message here */ + printf("push_cell_child overflow\n"); + return 0; + } + + ok = push_data(cells, (u8*)cell, sizeof(*cell)); + if (!ok) return 0; - cell_attr_inds.p += cell->n_attributes * sizeof(cell->attributes[0]); + if (cell_index) + *cell_index = index; - copy_cursor(tokens, &temp); + return 1; +} + +static int push_child_cell(struct cursor *cells, struct cell *parent, struct cell *child) +{ + int ok; + u16 index; + struct cursor child_inds; + + ok = push_cell(cells, child, &index); + if (!ok) return 0; + + make_cursor((u8*)parent->children, + (u8*)parent->children + sizeof(parent->children), + &child_inds); - ok = parse_symbol(&temp, "room"); + ok = push_u16(&child_inds, index); if (!ok) return 0; + parent->n_children++; + + return 1; +} + +static struct cell *get_cell(struct cursor *cells, u16 index) +{ + struct cell *p; + + p = (struct cell *)cells->start; + p = &p[index]; + + if ((u8*)p > (u8*)cells->end) + return NULL; + + return p; +} + +static int parse_cell_attrs(struct cursor *tokens, struct cursor *attributes, struct cursor *cells, u16 *index) +{ + struct cursor cell_attr_inds; + struct cell *child_cell; + struct cell cell; + u16 child_cell_index; + int attr_inds[2] = {0}; + int i, ok; + + init_cell(&cell); + + make_cursor((u8*)cell.attributes, + (u8*)cell.attributes + sizeof(cell.attributes), + &cell_attr_inds); + + cell_attr_inds.p += cell.n_attributes * sizeof(cell.attributes[0]); + /* 0 attributes returns 1, 1 attrs returns 2, etc 0 is a real error, an attribute push overflow */ - ok = parse_attributes(&temp, attributes, attr_inds); + ok = parse_attributes(tokens, attributes, attr_inds); if (!ok) return 0; for (i = attr_inds[0]; i <= attr_inds[1]; i++) { ok = push_int(&cell_attr_inds, i); + cell.n_attributes++; + if (!ok) return 0; + } + + /* Optional child cell */ + ok = parse_cell(tokens, attributes, cells, &child_cell_index); + if (ok) { + child_cell = get_cell(cells, child_cell_index); + ok = push_child_cell(cells, &cell, child_cell); if (!ok) return 0; } - /* parse_object(tokens, cell); */ + ok = push_cell(cells, &cell, index); + if (!ok) return 0; return 1; } - -static int parse_cell(struct cursor *tokens, - struct cursor *attributes, - struct cell *cell) +static int parse_cell_by_name(struct cursor *tokens, + struct cursor *attributes, + struct cursor *cells, + u16 *index, + const char *name, + enum cell_type type) { int ok; - /* ok = parse_group(tokens, cell); */ - /* if (ok) return 1; */ + struct cursor temp; + struct cell *cell; + u16 ind; - ok = parse_room(tokens, attributes, cell); - if (ok) return 1; + copy_cursor(tokens, &temp); - /* ok = parse_object(tokens, cell); */ + ok = parse_symbol(&temp, name); + if (!ok) return 0; - return 0; + ok = parse_cell_attrs(&temp, attributes, cells, &ind); + if (!ok) return 0; + + cell = get_cell(cells, ind); + + if (index) + *index = ind; + + if (!cell) return 0; + cell->type = type; + + copy_cursor(&temp, tokens); + + return 1; } -int parse_cells(struct cursor *tokens, struct cursor *attributes) + +static int parse_room(struct cursor *tokens, + struct cursor *attributes, + struct cursor *cells, + u16 *index) +{ + return parse_cell_by_name(tokens, attributes, cells, index, "room", C_SPACE); +} + +static int parse_group(struct cursor *tokens, + struct cursor *attributes, + struct cursor *cells, + u16 *index) { - struct cell cell; int ok; + int ncells = 0 +; + struct cursor temp; + struct cell group, child_cell; - memset(&cell, 0, sizeof(cell)); + init_cell(&group); + init_cell(&child_cell); + + copy_cursor(tokens, &temp); + + ok = parse_symbol(&temp, "group"); + if (!ok) return 0; while (1) { - ok = parse_open(tokens); - if (!ok) return 0; + printf("parsing group cell\n"); + ok = parse_cell(&temp, attributes, cells, NULL); + if (!ok) break; - ok = parse_cell(tokens, attributes, &cell); + ok = push_child_cell(cells, &group, &child_cell); if (!ok) return 0; - ok = parse_close(tokens); - if (!ok) return 0; + ncells++; } + printf("ncells %d\n", ncells); + + if (ncells == 0) + return 0; + + group.type = C_GROUP; + + ok = push_cell(cells, &group, index); + if (!ok) return 0; + + copy_cursor(&temp, tokens); + + return ncells; +} + +static int parse_object(struct cursor *tokens, + struct cursor *attributes, + struct cursor *cells, + u16 *index) +{ + return parse_cell_by_name(tokens, attributes, cells, index, "table", C_OBJECT); +} + +static int parse_cell(struct cursor *tokens, + struct cursor *attributes, + struct cursor *cells, + u16 *index) +{ + int ok; + ok = parse_open(tokens); + if (!ok) return 0; + + ok = parse_group(tokens, attributes, cells, index); + if (ok) { + printf("got parse_group\n"); + goto close; + } + + ok = parse_room(tokens, attributes, cells, index); + if (ok) { + printf("got parse_room\n"); + goto close; + } + + ok = parse_object(tokens, attributes, cells, index); + if (ok) { + printf("got parse_object\n"); + goto close; + } + + return 0; +close: + print_current_token(tokens); + ok = parse_close(tokens); + printf("parse_close cell %d\n", ok); + if (!ok) return 0; + + /* ok = parse_object(tokens, cell); */ + + return 1; +} + +int parse_cells(struct cursor *tokens, + struct cursor *attributes, + struct cursor *cells) +{ + int ok; + + + ok = parse_cell(tokens, attributes, cells, NULL); + if (!ok) return 0; + return 1; } diff --git a/parse.h b/parse.h @@ -5,6 +5,7 @@ #include "typedefs.h" #define MAX_ATTRIBUTES 24 +#define MAX_CHILDREN 24 enum token_error { TE_OK, @@ -96,9 +97,10 @@ struct attribute { }; struct cell { - int attributes[MAX_ATTRIBUTES]; + u16 attributes[MAX_ATTRIBUTES]; + u16 children[MAX_CHILDREN]; int n_attributes; - struct cell *child; + int n_children; const char *name; const char *id; @@ -109,7 +111,7 @@ struct cell { void make_cursor(u8 *start, u8 *end, struct cursor *cursor); int tokenize_cells(unsigned char *buf, int buf_size, struct cursor *tokens); -int parse_cells(struct cursor *tokens, struct cursor *attributes); +int parse_cells(struct cursor *tokens, struct cursor *attributes, struct cursor *cells); void print_token_error(struct cursor *cursor); #endif /* PROTOVERSE_PARSE_H */ diff --git a/protoverse.c b/protoverse.c @@ -8,17 +8,18 @@ int main(int argc, const char *argv[]) { static u8 file_buf[4096]; static u8 token_buf[2048]; static u8 attrs_buf[4096]; + static u8 cells_buf[sizeof(struct cell) * 1024]; struct cursor tokens; struct cursor attributes; + struct cursor cells; size_t count; const char *space; int ok; - make_cursor(attrs_buf, attrs_buf + sizeof(attrs_buf), - &attributes); - + make_cursor(cells_buf, cells_buf + sizeof(cells_buf), &cells); + make_cursor(attrs_buf, attrs_buf + sizeof(attrs_buf), &attributes); make_cursor(token_buf, token_buf + sizeof(token_buf), &tokens); space = argc == 2 ? argv[1] : "satoshis-citadel.space"; @@ -39,7 +40,7 @@ int main(int argc, const char *argv[]) { assert(tokens.p == token_buf); - ok = parse_cells(&tokens, &attributes); + ok = parse_cells(&tokens, &attributes, &cells); if (!ok) { print_token_error(&tokens); } diff --git a/typedefs.h b/typedefs.h @@ -3,6 +3,7 @@ #define PROTOVERSE_TYPEDEFS_H typedef unsigned char u8; +typedef unsigned short u16; #endif /* PROTOVERSE_TYPEDEFS_H */