commit ee953c868624dae99f0ba9b9630484e0dce1f4a8
parent ac654e95e69881d76b7c17d60cfe00c1707bc294
Author: William Casarin <jb55@jb55.com>
Date: Thu, 12 Aug 2021 09:05:00 -0700
better room descriptions
Diffstat:
6 files changed, 335 insertions(+), 162 deletions(-)
diff --git a/satoshis-citadel.space b/satoshis-citadel.space
@@ -1,10 +1,13 @@
-(space (shape rectangle)
+(room (shape rectangle)
(condition "clean")
(condition "shiny")
(material "solid gold")
(name "Satoshi's Den")
(width 10) (depth 10) (height 100)
(group
+ (table (name "hardy")
+ (material "rock")
+ (object (name "pencil")))
(table (id welcome-desk)
(name "welcome desk")
(material "marble")
@@ -12,7 +15,27 @@
(condition "new")
(width 1) (depth 2) (height 1)
(location center)
- (light (name "desk")))
+ (group
+ (light (name "desk"))
+ (obj (name "chessboard")
+ (group
+ (obj (p "a1") (color "white") (material "marble") (name "rook"))
+ (obj (p "b1") (color "white") (material "marble") (name "knight"))
+ (obj (p "c1") (color "white") (material "marble") (name "bishop"))
+ (obj (p "d1") (color "white") (material "marble") (name "queen"))
+ (obj (p "e1") (color "white") (material "marble") (name "king"))
+ (obj (p "f1") (color "white") (material "marble") (name "bishop"))
+ (obj (p "g1") (color "white") (material "marble") (name "knight"))
+ (obj (p "h1") (color "white") (material "marble") (name "rook"))
+ (obj (p "a8") (color "black") (material "marble") (name "rook"))
+ (obj (p "b8") (color "black") (material "marble") (name "knight"))
+ (obj (p "c8") (color "black") (material "marble") (name "bishop"))
+ (obj (p "d8") (color "black") (material "marble") (name "queen"))
+ (obj (p "e8") (color "black") (material "marble") (name "king"))
+ (obj (p "f8") (color "black") (material "marble") (name "bishop"))
+ (obj (p "g8") (color "black") (material "marble") (name "knight"))
+ (obj (p "h8") (color "black") (material "marble") (name "rook"))
+ ))))
(chair (id a))
(chair (id b))
diff --git a/src/describe.c b/src/describe.c
@@ -12,15 +12,13 @@
static int push_sized_word(struct cursor *strs, const char *str, int len)
{
- int ok;
-
if (strs->p-1 >= strs->start && !isspace(*(strs->p-1))) {
- ok = cursor_push_str(strs, " ");
- if (!ok) return 0;
+ if (!cursor_push_str(strs, " "))
+ return 0;
}
- ok = push_sized_str(strs, str, len);
- if (!ok) return 0;
+ if (!push_sized_str(strs, str, len))
+ return 0;
return 1;
}
@@ -51,7 +49,7 @@ static int push_adjective(struct cursor *strs, struct attribute *attr)
static int is_adjective(struct attribute *attr)
{
- return attr->type == A_CONDITION;
+ return attr->type == A_CONDITION || attr->type == A_COLOR;
}
static int count_adjectives(struct describe *desc)
@@ -147,7 +145,8 @@ static int push_named(struct describe *desc)
int name_len;
int ok;
- cell_name(&desc->parsed->attributes, desc->cell, &name, &name_len);
+ cell_attr_str(&desc->parsed->attributes, desc->cell, &name, &name_len,
+ A_NAME);
if (name_len == 0)
return 1;
@@ -239,15 +238,22 @@ static int describe_amount(struct describe *desc, int nobjs)
static int describe_object_name(struct cursor *strs, struct cursor *attrs, struct cell *cell)
{
- int ok;
const char *name;
int name_len;
- cell_name(attrs, cell, &name, &name_len);
- if (name_len > 0) {
- ok = push_sized_word(strs, name, name_len);
- if (!ok) return 0;
- }
+ cell_attr_str(attrs, cell, &name, &name_len, A_COLOR);
+ if (name_len > 0 && !push_sized_word(strs, name, name_len))
+ return 0;
+
+ /*
+ cell_attr_str(attrs, cell, &name, &name_len, A_MATERIAL);
+ if (name_len > 0 && !push_sized_word(strs, name, name_len))
+ return 0;
+ */
+
+ cell_attr_str(attrs, cell, &name, &name_len, A_NAME);
+ if (name_len > 0 && !push_sized_word(strs, name, name_len))
+ return 0;
if (cell->type == C_OBJECT) {
if (cell->obj_type == O_OBJECT)
@@ -258,118 +264,162 @@ static int describe_object_name(struct cursor *strs, struct cursor *attrs, struc
return push_word(strs, cell_type_str(cell->type));
}
-static int describe_group(struct describe *desc)
+static int describe_group_children(struct cell *parent, struct describe *desc)
{
- int i, ok, nobjs;
- struct cell *cell;
-
- nobjs = desc->cell->n_children;
-
- ok = describe_amount(desc, nobjs);
-
- ok = push_word(desc->strs, "object");
- if (!ok) return 0;
-
- if (nobjs > 1) {
- ok = cursor_push_str(desc->strs, "s:");
- if (!ok) return 0;
- }
- else {
- cursor_push_str(desc->strs, ":");
- if (!ok) return 0;
- }
+ int i;
+ struct cell *child;
- ok = push_word(desc->strs, "a");
- if (!ok) return 0;
+ if (!push_word(desc->strs, "a"))
+ return 0;
- for (i = 0; i < nobjs; i++) {
- cell = get_cell(&desc->parsed->cells,
- desc->cell->children[i]);
- assert(cell);
+ for (i = 0; i < parent->n_children; i++) {
+ child = get_cell(&desc->parsed->cells, parent->children[i]);
+ assert(child);
if (i > 0) {
- if (i == nobjs-1) {
- ok = push_word(desc->strs, "and");
- if (!ok) return 0;
+ if (i == parent->n_children-1) {
+ if (!push_word(desc->strs, "and"))
+ return 0;
}
- else if (i != nobjs-1) {
- ok = cursor_push_str(desc->strs, ",");
- if (!ok) return 0;
+ else if (i != parent->n_children-1) {
+ if (!cursor_push_str(desc->strs, ","))
+ return 0;
}
}
- ok = describe_object_name(desc->strs, &desc->parsed->attributes, cell);
- if (!ok) return 0;
+ if (!describe_object_name(desc->strs, &desc->parsed->attributes, child))
+ return 0;
}
return 1;
}
-static int describe_object(struct describe *desc)
+static int describe_group(struct describe *desc)
{
- if (!push_word(desc->strs, "a"))
+ if (!describe_amount(desc, desc->cell->n_children))
return 0;
+ if (!push_word(desc->strs, "object"))
+ return 0;
+
+ if (desc->cell->n_children > 1) {
+ if (!cursor_push_str(desc->strs, "s:"))
+ return 0;
+ }
+ else {
+ if (!cursor_push_str(desc->strs, ":"))
+ return 0;
+ }
+
+ return describe_group_children(desc->cell, desc);
+}
+
+static int describe_object(struct describe *desc)
+{
return describe_object_name(desc->strs, &desc->parsed->attributes,
desc->cell);
}
-int describe_cell(struct cell *cell, struct parser *parsed, struct cursor *strbuf)
+int describe_cell(struct describe *desc)
{
- struct describe desc;
-
- desc.cell = cell;
- desc.parsed = parsed;
- desc.strs = strbuf;
-
- switch (cell->type) {
+ switch (desc->cell->type) {
case C_ROOM:
- return describe_area(&desc, "room");
+ return describe_area(desc, "room");
case C_SPACE:
- return describe_area(&desc, "space");
+ return describe_area(desc, "space");
case C_GROUP:
- return describe_group(&desc);
+ return describe_group(desc);
case C_OBJECT:
- return describe_object(&desc);
+ if (!push_word(desc->strs, "a"))
+ return 0;
+
+ return describe_object(desc);
}
return 1;
}
-
-int describe_cells(struct cell *cell, struct parser *parsed, struct cursor *strs, int max_depth, int depth)
+static int describe_cell_name(struct describe *desc)
{
- int ok;
+ if (desc->cell->type == C_OBJECT)
+ return describe_object(desc);
- if (depth > max_depth)
- return 1;
+ return push_word(desc->strs, cell_type_str(desc->cell->type));
+}
- ok = describe_cell(cell, parsed, strs);
- if (!ok) return 0;
+static int describe_cell_children(struct describe *desc);
- ok = cursor_push_str(strs, ".\n");
- if (!ok) return 0;
+static int describe_cell_children_rest(struct describe desc)
+{
+ int i;
+ struct cell *parent = desc.cell;
- if (cell->n_children == 0)
- return 1;
+ for (i = 0; i < parent->n_children; i++) {
+ desc.cell = get_cell(&desc.parsed->cells, parent->children[i]);
- if (cell->type == C_ROOM || cell->type == C_SPACE) {
- if (!push_word(strs, "It contains"))
+ if (desc.cell->n_children > 0 && !describe_cell_children(&desc))
return 0;
- cell = get_cell(&parsed->cells, cell->children[0]);
- return describe_cells(cell, parsed, strs, max_depth, depth+1);
}
return 1;
}
+static int describe_cell_children_group(struct describe desc)
+{
+ struct cell *child;
+
+ if (desc.cell->n_children == 1 &&
+ (child = get_cell(&desc.parsed->cells, desc.cell->children[0])) &&
+ child->type == C_GROUP) {
+ desc.cell = child;
+ return describe_cell_children_group(desc);
+ }
+
+ if (!describe_group_children(desc.cell, &desc))
+ return 0;
+
+ if (!cursor_push_byte(desc.strs, '\n'))
+ return 0;
+
+ return describe_cell_children_rest(desc);
+}
+
+static int describe_cell_children(struct describe *desc)
+{
+ if (!push_word(desc->strs, "The"))
+ return 0;
+
+ if (!describe_cell_name(desc))
+ return 0;
+
+ if (!push_word(desc->strs, "contains"))
+ return 0;
+
+ return describe_cell_children_group(*desc);
+}
+
+int describe_cells(struct describe *desc)
+{
+ if (!describe_cell(desc))
+ return 0;
+
+ if (!cursor_push_str(desc->strs, ".\n"))
+ return 0;
+
+ if (desc->cell->n_children == 0)
+ return 1;
+
+ return describe_cell_children(desc);
+}
+
int describe(struct parser *parser, u16 root_cell)
{
- static char strbuf[2048];
+ static char strbuf[4096*32];
struct cursor strs;
struct cell *cell;
+ struct describe desc;
strbuf[0] = 0;
@@ -377,7 +427,11 @@ int describe(struct parser *parser, u16 root_cell)
make_cursor((u8*)strbuf, (u8*)strbuf + sizeof(strbuf), &strs);
- describe_cells(cell, parser, &strs, 10, 0);
+ desc.cell = cell;
+ desc.parsed = parser;
+ desc.strs = &strs;
+
+ describe_cells(&desc);
printf("\n\ndescription\n-----------\n\n%s\n", strbuf);
diff --git a/src/describe.h b/src/describe.h
@@ -11,7 +11,7 @@ struct describe {
};
int describe(struct parser *parser, u16 root_cell);
-int describe_cell(struct cell *cell, struct parser *parsed, struct cursor *strbuf);
-int describe_cells(struct cell *cell, struct parser *parsed, struct cursor *strs, int max_depth, int depth);
+int describe_cell(struct describe *desc);
+int describe_cells(struct describe *desc);
#endif
diff --git a/src/parse.c b/src/parse.c
@@ -43,6 +43,7 @@ union token {
#ifdef DEBUG
+#endif
static const char *attr_type_str(enum attribute_type type)
{
switch (type) {
@@ -52,16 +53,17 @@ static const char *attr_type_str(enum attribute_type type)
case A_ID: return "id";
case A_LOCATION: return "location";
case A_MATERIAL: return "material";
+ case A_COLOR: return "color";
case A_NAME: return "name";
case A_SHAPE: return "shape";
case A_TYPE: return "type";
case A_WIDTH: return "width";
case A_STATE: return "state";
+ case A_DATA: return "data";
}
return "unknown";
}
-#endif
static const char *token_error_string(enum token_error err)
{
@@ -93,13 +95,14 @@ static void init_token_cursor(struct token_cursor *cursor)
memset(&cursor->err_data, 0, sizeof(cursor->err_data));
}
-struct attribute *get_attr(struct cursor *attributes, u16 index)
+struct attribute *get_attr(struct cursor *attributes, int index)
{
return (struct attribute*)index_cursor(attributes, index,
sizeof(struct attribute));
}
/*
+*/
static const char *shape_str(enum shape shape)
{
switch (shape) {
@@ -142,7 +145,6 @@ static void print_attributes(struct cursor *attributes, struct cell *cell)
print_attribute(attr);
}
}
-*/
void print_cell(struct cursor *attributes, struct cell *cell)
{
@@ -154,14 +156,14 @@ void print_cell(struct cursor *attributes, struct cell *cell)
return;
}
- cell_name(attributes, cell, &name, &name_len);
+ cell_attr_str(attributes, cell, &name, &name_len, A_NAME);
printf("%.*s%s%s ", name_len, name, name_len > 0?" ":"",
cell->type == C_OBJECT
? object_type_str(cell->obj_type)
: cell_type_str(cell->type));
- /* print_attributes(attributes, cell); */
+ //print_attributes(attributes, cell);
}
@@ -228,9 +230,8 @@ static int push_token_data(struct token_cursor *tokens,
#ifdef DEBUG
struct tok_str *str;
#endif
- int ok;
- ok = cursor_push_byte(&tokens->c, token);
- if (!ok) return 0;
+ if (!cursor_push_byte(&tokens->c, token))
+ return 0;
switch (token) {
@@ -258,8 +259,11 @@ static int push_token_data(struct token_cursor *tokens,
tokdebug("sym %.*s", str->len, str->data);
}
#endif
- ok = cursor_push(&tokens->c, token_data, token_data_size);
- if (!ok) return 0;
+ if (!cursor_push(&tokens->c, token_data, token_data_size)) {
+ printf("hmm? %d\n", token_data_size);
+ cursor_print_around(&tokens->c, 10);
+ return 0;
+ }
#ifdef DEBUG
printf("\n");
#endif
@@ -489,8 +493,8 @@ static int read_and_push_atom(struct token_cursor *cursor, struct token_cursor *
if (ok) {
str.len = ok;
str.data = start;
- ok = push_symbol(tokens, str);
- if (!ok) {
+ if (!push_symbol(tokens, str)) {
+ cursor_print_around(&tokens->c, 10);
printf("read_and_push_atom identifier push overflow\n");
return 0;
}
@@ -725,10 +729,9 @@ static int parse_stringy_token(struct token_cursor *tokens,
enum token_type type)
{
union token token;
- int ok;
- ok = pull_token(tokens, &token, type);
- if (!ok) return 0;
+ if (!pull_token(tokens, &token, type))
+ return 0;
str->data = token.str.data;
str->len = token.str.len;
@@ -768,7 +771,7 @@ static int parse_number(struct token_cursor *tokens, union number *number)
}
-struct cell *get_cell(struct cursor *cells, u16 index)
+struct cell *get_cell(struct cursor *cells, int index)
{
return (struct cell*)index_cursor(cells, index,
sizeof(struct cell));
@@ -782,11 +785,10 @@ static int symbol_eq(struct tok_str *a, const char *b, int b_len)
static int parse_symbol(struct token_cursor *tokens, const char *match)
{
- int ok;
struct tok_str str;
- ok = pull_symbol_token(tokens, &str);
- if (!ok) return 0;
+ if (!pull_symbol_token(tokens, &str))
+ return 0;
if (!symbol_eq(&str, match, strlen(match)))
return 0;
@@ -837,23 +839,43 @@ static int parse_str_attr(struct token_cursor *tokens,
{
struct token_cursor temp;
struct tok_str str;
- int ok;
+ struct bufstr *bufstr;
assert(tok_type == T_NUMBER || tok_type == T_SYMBOL || tok_type == T_STRING);
copy_token_cursor(tokens, &temp);
- ok = parse_symbol(&temp, sym);
- if (!ok) return 0;
+ if (sym == NULL) {
+ if (!pull_symbol_token(&temp, &str))
+ return 0;
- ok = parse_stringy_token(&temp, &str, tok_type);
- if (!ok) return 0;
+ attr->data.data_attr.sym.ptr = (char*)str.data;
+ attr->data.data_attr.sym.len = str.len;
- attr->data.str.ptr = (char*)str.data;
- attr->data.str.len = str.len;
+ bufstr = &attr->data.data_attr.str;
+ } else {
+ if (!parse_symbol(&temp, sym))
+ return 0;
+ bufstr = &attr->data.str;
+ }
+
+ if (!parse_stringy_token(&temp, &str, tok_type))
+ return 0;
+
+ bufstr->ptr = (char*)str.data;
+ bufstr->len = str.len;
attr->type = type;
- tokdebug("attribute %s %.*s\n", sym, str.len, str.data);
+#ifdef DEBUG
+ if (sym == NULL)
+ tokdebug("attribute %.*s %.*s\n",
+ attr->data.data_attr.sym.len,
+ attr->data.data_attr.sym.ptr,
+ str.len,
+ str.data);
+ else
+ tokdebug("attribute %s %.*s\n", sym, str.len, str.data);
+#endif
copy_token_cursor(&temp, tokens);
@@ -891,18 +913,28 @@ static int parse_size(struct token_cursor *tokens, struct attribute *attr)
return 1;
}
-int cell_name(struct cursor *attributes, struct cell *cell, const char** name, int *len)
+static struct bufstr *attr_bufstr(struct attribute *attr)
+{
+ if (attr->type == A_DATA)
+ return &attr->data.data_attr.str;
+ return &attr->data.str;
+}
+
+int cell_attr_str(struct cursor *attributes, struct cell *cell,
+ const char** name, int *len, enum attribute_type type)
{
int i;
struct attribute *attr;
+ struct bufstr *bufstr;
*len = 0;
*name = "";
for (i = 0; i < cell->n_attributes; i++) {
attr = get_attr(attributes, cell->attributes[i]);
- if (attr->type == A_NAME) {
- *name = attr->data.str.ptr;
- *len = attr->data.str.len;
+ if (attr->type == type) {
+ bufstr = attr_bufstr(attr);
+ *name = bufstr->ptr;
+ *len = bufstr->len;
return 1;
}
}
@@ -910,6 +942,14 @@ int cell_name(struct cursor *attributes, struct cell *cell, const char** name, i
return 0;
}
+const char *cell_name(struct cursor *attributes, struct cell *cell, int *len)
+{
+ const char *name = NULL;
+ if (!cell_attr_str(attributes, cell, &name, len, A_NAME))
+ return NULL;
+ return name;
+}
+
static int parse_attribute(struct token_cursor *tokens, struct attribute *attr)
{
int ok;
@@ -934,6 +974,9 @@ static int parse_attribute(struct token_cursor *tokens, struct attribute *attr)
ok = parse_str_attr(&temp, attr, "material", A_MATERIAL, T_STRING);
if (ok) goto close;
+ ok = parse_str_attr(&temp, attr, "color", A_COLOR, T_STRING);
+ if (ok) goto close;
+
/* TODO: parse multiple conditions */
ok = parse_str_attr(&temp, attr, "condition", A_CONDITION, T_STRING);
if (ok) goto close;
@@ -944,6 +987,9 @@ static int parse_attribute(struct token_cursor *tokens, struct attribute *attr)
ok = parse_str_attr(&temp, attr, "state", A_STATE, T_SYMBOL);
if (ok) goto close;
+ ok = parse_str_attr(&temp, attr, NULL, A_DATA, T_STRING);
+ if (ok) goto close;
+
ok = parse_size(&temp, attr);
if (ok) goto close;
@@ -1010,7 +1056,7 @@ static int parse_group(struct cursor *tokens)
*/
-static int push_cell(struct cursor *cells, struct cell *cell, u16 *cell_index)
+static int push_cell(struct cursor *cells, struct cell *cell, int *cell_index)
{
int index;
int ok;
@@ -1041,7 +1087,7 @@ static void copy_parser(struct parser *from, struct parser *to)
copy_cursor(&from->attributes, &to->attributes);
}
-static int push_cell_child(struct cell *parent, u16 child_ind)
+static int push_cell_child(struct cell *parent, int child_ind)
{
int ok;
struct cursor child_inds;
@@ -1085,11 +1131,11 @@ const char *cell_type_str(enum cell_type type)
return "unknown";
}
-static int parse_cell_attrs(struct parser *parser, u16 *index, struct cell *cell)
+static int parse_cell_attrs(struct parser *parser, int *index, struct cell *cell)
{
struct cursor cell_attr_inds;
struct cell *child_cell;
- u16 child_cell_index;
+ int child_cell_index;
int attr_inds[2] = {0};
int i, ok;
@@ -1116,11 +1162,11 @@ static int parse_cell_attrs(struct parser *parser, u16 *index, struct cell *cell
tokdebug("optional child cell in parse_cell_attrs\n");
ok = parse_cell(parser, &child_cell_index);
if (ok) {
- child_cell = get_cell(&parser->cells, child_cell_index);
- if (!child_cell) return 0;
+ if (!(child_cell = get_cell(&parser->cells, child_cell_index)))
+ return 0l
tokdebug("parse_cell_attrs push child cell\n");
- ok = push_cell_child(cell, child_cell_index);
- if (!ok) return 0;
+ if (!push_cell_child(cell, child_cell_index))
+ return 0;
}
else {
@@ -1134,14 +1180,14 @@ static int parse_cell_attrs(struct parser *parser, u16 *index, struct cell *cell
}
static int parse_cell_by_name(struct parser *parser,
- u16 *index,
+ int *index,
const char *name,
enum cell_type type)
{
int ok;
struct parser backtracked;
struct cell cell;
- u16 ind;
+ int ind;
init_cell(&cell);
@@ -1163,21 +1209,20 @@ static int parse_cell_by_name(struct parser *parser,
return 1;
}
-static int parse_space(struct parser *parser, u16 *index)
+static int parse_space(struct parser *parser, int *index)
{
return parse_cell_by_name(parser, index, "space", C_SPACE);
}
-static int parse_room(struct parser *parser, u16 *index)
+static int parse_room(struct parser *parser, int *index)
{
return parse_cell_by_name(parser, index, "room", C_ROOM);
}
-static int parse_group(struct parser *parser, u16 *index)
+static int parse_group(struct parser *parser, int *index)
{
- int ok;
int ncells = 0;
- u16 child_ind;
+ int child_ind;
struct parser backtracked;
struct cell group;
@@ -1187,12 +1232,12 @@ static int parse_group(struct parser *parser, u16 *index)
copy_parser(parser, &backtracked);
- ok = parse_symbol(&backtracked.tokens, "group");
- if (!ok) return 0;
+ if (!parse_symbol(&backtracked.tokens, "group"))
+ return 0;
while (1) {
- ok = parse_cell(&backtracked, &child_ind);
- if (!ok) break;
+ if (!parse_cell(&backtracked, &child_ind))
+ break;
child_cell = get_cell(&backtracked.cells, child_ind);
if (child_cell == NULL) {
@@ -1201,8 +1246,8 @@ static int parse_group(struct parser *parser, u16 *index)
}
tokdebug("group child cell type %s\n", cell_type_str(child_cell->type));
- ok = push_cell_child(&group, child_ind);
- if (!ok) return 0;
+ if (!push_cell_child(&group, child_ind))
+ return 0;
ncells++;
}
@@ -1214,8 +1259,8 @@ static int parse_group(struct parser *parser, u16 *index)
group.type = C_GROUP;
- ok = push_cell(&backtracked.cells, &group, index);
- if (!ok) return 0;
+ if (!push_cell(&backtracked.cells, &group, index))
+ return 0;
copy_parser(&backtracked, parser);
@@ -1232,25 +1277,25 @@ static struct object_def object_defs[] = {
{"chair", O_CHAIR},
{"door", O_DOOR},
{"light", O_LIGHT},
- {"object", O_OBJECT},
+ {"obj", O_OBJECT},
};
-static int parse_object(struct parser *parser, u16 *index)
+static int parse_object(struct parser *parser, int *index)
{
- int ok, i;
+ int i;
struct parser backtracked;
struct tok_str str;
struct object_def *def;
struct cell cell;
- u16 ind;
+ int ind;
init_cell(&cell);
cell.type = C_OBJECT;
copy_parser(parser, &backtracked);
- ok = pull_symbol_token(&backtracked.tokens, &str);
- if (!ok) return 0;
+ if (!pull_symbol_token(&backtracked.tokens, &str))
+ return 0;
for (i = 0; i < ARRAY_SIZE(object_defs); i++) {
def = &object_defs[i];
@@ -1261,10 +1306,9 @@ static int parse_object(struct parser *parser, u16 *index)
}
}
- ok = parse_cell_attrs(&backtracked, &ind, &cell);
- if (!ok) return 0;
+ if (!parse_cell_attrs(&backtracked, &ind, &cell))
+ return 0;
- assert(ind < 10);
if (index)
*index = ind;
@@ -1273,7 +1317,7 @@ static int parse_object(struct parser *parser, u16 *index)
return 1;
}
-int parse_cell(struct parser *parser, u16 *index)
+int parse_cell(struct parser *parser, int *index)
{
int ok;
struct parser backtracked;
@@ -1328,7 +1372,7 @@ int init_parser(struct parser *parser)
int ok;
int attrs_size = sizeof(struct attribute) * 1024;
- int tokens_size = 2048;
+ int tokens_size = 2048*32;
int cells_size = sizeof(struct cell) * 1024;
int memsize = attrs_size + tokens_size + cells_size;
@@ -1356,7 +1400,7 @@ int free_parser(struct parser *parser)
return 1;
}
-int parse_buffer(struct parser *parser, u8 *file_buf, int len, u16 *root)
+int parse_buffer(struct parser *parser, u8 *file_buf, int len, int *root)
{
int ok;
@@ -1377,7 +1421,7 @@ int parse_buffer(struct parser *parser, u8 *file_buf, int len, u16 *root)
}
-int parse_file(struct parser *parser, const char *filename, u16 *root, u8 *buf,
+int parse_file(struct parser *parser, const char *filename, int *root, u8 *buf,
u32 bufsize)
{
int count, ok;
diff --git a/src/parse.h b/src/parse.h
@@ -42,12 +42,14 @@ enum attribute_type {
A_NAME,
A_MATERIAL,
A_CONDITION,
+ A_COLOR,
A_WIDTH,
A_DEPTH,
A_HEIGHT,
A_LOCATION,
A_SHAPE,
A_STATE,
+ A_DATA,
};
enum cell_state {
@@ -81,11 +83,19 @@ union number {
double fdouble;
};
+struct bufstr {
+ const char *ptr;
+ int len;
+};
+
+struct data_attr {
+ struct bufstr str;
+ struct bufstr sym;
+};
+
union attr_data {
- struct {
- const char *ptr;
- int len;
- } str;
+ struct bufstr str;
+ struct data_attr data_attr;
enum shape shape;
union number number;
};
@@ -132,18 +142,19 @@ struct parser {
struct cursor cells;
};
-int parse_buffer(struct parser *parser, u8 *file_buf, int len, u16 *root);
-int parse_file(struct parser *parser, const char *filename, u16 *root, u8 *buf, u32 bufsize);
+int parse_buffer(struct parser *parser, u8 *file_buf, int len, int *root);
+int parse_file(struct parser *parser, const char *filename, int *root, u8 *buf, u32 bufsize);
int init_parser(struct parser *parser);
int free_parser(struct parser *parser);
void print_cell(struct cursor *attributes, struct cell *cell);
int tokenize_cells(unsigned char *buf, int buf_size, struct token_cursor *tokens);
-int parse_cell(struct parser *parser, u16 *index);
+int parse_cell(struct parser *parser, int *index);
void print_token_error(struct token_cursor *cursor);
const char *cell_type_str(enum cell_type);
const char *object_type_str(enum object_type);
-int cell_name(struct cursor *attributes, struct cell *cell, const char** name, int *len);
-struct cell *get_cell(struct cursor *cells, u16 index);
-struct attribute *get_attr(struct cursor *attributes, u16 index);
+struct cell *get_cell(struct cursor *cells, int index);
+struct attribute *get_attr(struct cursor *attributes, int index);
+int cell_attr_str(struct cursor *attributes, struct cell *cell, const char** name, int *len, enum attribute_type type);
+const char *cell_name(struct cursor *attributes, struct cell *cell, int *len);
#endif /* PROTOVERSE_PARSE_H */
diff --git a/src/protoverse.c b/src/protoverse.c
@@ -41,7 +41,43 @@ static void print_all_cells(struct parser *parser)
}
*/
-static int print_cell_tree(struct parser *parser, u16 root, int depth)
+static int match_selector(struct cursor *attrs, struct cell *cell, const char *query)
+{
+ const char *str;
+ int str_len;
+ int query_len = strlen(query);
+
+ if (!cell_attr_str(attrs, cell, &str, &str_len, A_NAME))
+ return 0;
+ if (query_len == str_len && !memcmp(str, query, str_len))
+ return 1;
+ if (!cell_attr_str(attrs, cell, &str, &str_len, A_ID))
+ return 0;
+ if (query_len == str_len && !memcmp(str, query, str_len))
+ return 1;
+
+ return 0;
+}
+
+static int cell_selector(struct parser *parser, u32 root, const char *query)
+{
+ int res;
+ int i;
+ struct cell *cell = get_cell(&parser->cells, root);
+
+ if ((res = match_selector(&parser->attributes, cell, query)))
+ return root;
+
+ for (i = 0; i < cell->n_children; i++) {
+ //cell = get_cell(&parser->cells, cell->children[i]);
+ if ((res = cell_selector(parser, cell->children[i], query)))
+ return res;
+ }
+
+ return 0;
+}
+
+static int print_cell_tree(struct parser *parser, u32 root, int depth)
{
int i;
@@ -110,7 +146,7 @@ int main(int argc, const char *argv[])
unsigned char *wasm_data;
struct parser parser;
struct protoverse_server server;
- u16 root;
+ int root, found;
int ok;
int retval;
size_t len;
@@ -121,7 +157,7 @@ int main(int argc, const char *argv[])
cmd = argv[1];
if (streq(cmd, "parse")) {
- if (argc != 3)
+ if (argc < 3)
return usage();
ok = init_parser(&parser);
if (!ok) {
@@ -135,6 +171,11 @@ int main(int argc, const char *argv[])
return 1;
}
+ if (argc > 3) {
+ if ((found = cell_selector(&parser, root, argv[3])))
+ root = found;
+ }
+
print_cell_tree(&parser, root, 0);
describe(&parser, root);