commit 49f17958c9de9ec29319a5b9535787ae095e05db
parent 47355cd44417f352f51b41a039c937ee2c077eac
Author: William Casarin <jb55@jb55.com>
Date: Sun, 28 Jun 2020 16:32:51 -0700
group/children parsing wip
Diffstat:
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 */