#include #include #include "lkb-avm.h" #include "lkb-protocol.h" #include lkb_avm_list *empty_avm_list(int *tt, char *type); lkb_avm_list *insert_into_list(lkb_avm *first, lkb_avm_list *list, int type, lkb_avm_tag *tag, lkb_avm_tag *rtag, char *ltype); lkb_avm_list *convert_to_list(lkb_avm *fs); lkb_avm_list *empty_avm_list(int *tt, char *type) { lkb_avm_list *l; *tt = avm_list; l = calloc(sizeof(lkb_avm_list), 1); l->type = malloc(sizeof(char*) * (l->length+1)); l->type[0] = type?strdup(type):NULL; return l; } lkb_avm_list *insert_into_list(lkb_avm *first, lkb_avm_list *list, int type, lkb_avm_tag *tag, lkb_avm_tag *rtag, char *ltype) { list->length++; //printf("list now length %d\n", list->length); list->what = realloc(list->what, sizeof(int) * list->length); list->items = realloc(list->items, sizeof(void*) * list->length); list->tags = realloc(list->tags, sizeof(lkb_avm_tag*) * list->length); list->rtags = realloc(list->rtags, sizeof(lkb_avm_tag*) * list->length); list->type = realloc(list->type, sizeof(char*) * (list->length+1)); memmove(list->what+1, list->what, sizeof(int) * (list->length-1)); memmove(list->items+1, list->items, sizeof(void*) * (list->length-1)); memmove(list->tags+1, list->tags, sizeof(lkb_avm_tag*) * (list->length-1)); memmove(list->rtags+1, list->rtags, sizeof(lkb_avm_tag*) * (list->length-1)); memmove(list->type+1, list->type, sizeof(char*) * (list->length+1-1)); list->what[0] = type; list->items[0] = first; list->tags[0] = tag?lkb_tagdup(tag):0; list->rtags[0] = rtag?lkb_tagdup(rtag):0; if(!ltype)list->type[0] = NULL; else if(list->type[1] && !strcmp(list->type[1], ltype)) { list->type[0] = list->type[1]; list->type[1] = NULL; } else list->type[0] = strdup(ltype); return list; } lkb_avm_list *tagged_rest_list(lkb_avm *first, int ft, lkb_avm_tag *tag, lkb_avm_tag *rest, char *ltype) { int moo; lkb_avm_list *list = empty_avm_list(&moo, 0); return insert_into_list(first, list, ft, tag, rest, ltype); } lkb_avm_list *weird_rest_list(lkb_avm *first, int ft, lkb_avm_tag *tag, void *rest, int rt, lkb_avm_tag *rtag, char *ltype) { int moo; lkb_avm_list *list = empty_avm_list(&moo, 0); list->rest_weird = rest; list->rest_type = rt; //printf("weird-rest with rest %p, type %d, ltype %s\n", rest, rt, ltype); return insert_into_list(first, list, ft, tag, rtag, ltype); } extern char *first_feature, *rest_feature; extern char *current_path; is_non_empty_list(struct lkb_avm *fs) { lkb_avm *first, *rest; lkb_avm_tag *tag, *rtag; int ft, rt; if(fs->nattr != 2)return 0; // unusual-shaped lists should be displayed as AVMs, to avoid obscuring information first = find_attribute(fs, first_feature, &ft, &tag); rest = find_attribute(fs, rest_feature, &rt, &rtag); if((first || tag) && (rest || rtag))return 1; else return 0; } lkb_avm_list *convert_to_list(lkb_avm *fs) { lkb_avm *first, *rest; lkb_avm_tag *tag, *rtag; lkb_avm_list *ret; int ft, rt, moo; int list_type; //printf("called convert_to_list on %p at path %s\n", fs, current_path); first = find_attribute(fs, first_feature, &ft, &tag); rest = find_attribute(fs, rest_feature, &rt, &rtag); //printf("first %p, type %d, tag %p\n", first, ft, tag); //printf("rest %p, type %d, tag %p\n", rest, rt, rtag); if(!rest && rtag && (first || tag)) { //printf("INTERESTING: found a tagged rest list\n"); return tagged_rest_list(first, ft, tag, rtag, fs->type); } if(!rest && !rtag && (first || tag)) { fprintf(stderr, "Error: Found a *CONS* with first but no rest\n"); print_attribs(fs); return 0; //return insert_into_list(first, (lkb_avm_list*)empty_avm_list(&moo, fs->type), ft, tag, 0); } if(!(first || tag) || !rest) { printf("ERROR: *CONS* didn't have both first and rest\n"); print_attribs(fs); return 0; } if(rt != avm_list) { //printf("WARNING: `REST' of *CONS* wasn't a list,\n at path `%s'\n", current_path); //print_attribs(fs); return weird_rest_list(first, ft, tag, rest, rt, rtag, fs->type); } ret = insert_into_list(first, (lkb_avm_list*)rest, ft, tag, rtag, fs->type); return ret; }