Added cons manipulating functions and improved exs efficiency slightly

master
Avril 6 years ago
parent d72c20acae
commit e944b75a4f

@ -18,16 +18,28 @@ typedef struct cons {
struct cons* cdr;
} list_t;
#define SET_PARSE_NIL (1<<0)
#define SET_PARSE_QUOTE (1<<1)
#define SET_PARSE_ESCAPE (1<<2)
#define SET_PARSE_INSENSITIVE (1<<3)
enum _se_type {
SE_NIL=0,
SE_STRING,
SE_LIST,
};
#define SET_PARSE_NIL (1<<0) //Parse `NIL' as null pointer
#define SET_PARSE_QUOTE (1<<1) //Parse "string quotes"
#define SET_PARSE_ESCAPE (1<<2) //Parse "escape \" sequences \""
#define SET_PARSE_INSENSITIVE (1<<3) //PARSE ALL AS UPPERCASE
#define SET_NO_WRAP (1<<4) //Interpret "(one two three)" as (one two three) instead of ((one two three))
#define SETP_DEFAULT (SET_PARSE_QUOTE | SET_PARSE_ESCAPE)
#define SETP_LISP (SETP_DEFAULT | SET_PARSE_INSENSITIVE | SET_PARSE_NIL)
#define se_parsed(s) se_parse((s), SET_DEFAULT)
list_t* se_parse(const char* sexpr, unsigned int flags); //Parse string into list.
void se_free(list_t* list); //Free whole list.
void se_print(FILE* fp, const list_t* list); //Print list to fp, if fp is NULL, print to stdout.
enum _se_type se_typeof(list_t* cons); //Get type of cons's car value.
list_t* se_new(char* from, int dupe); //Create new cons.
#define se_newd(f) se_new((f), 1)
list_t* se_last(list_t* list); //Get last non-nil cons.
#endif /* _LIBSE_H */

@ -177,17 +177,17 @@ exString* exs_where(exString* from, exsp_where func, void* data)
void exs_selectip(exString* str, exsp_select func, void* data)
{
exString* out = exs_select(str,func,data);
exs_reset(str);
exs_append(str, *out);
exs_free(out);
free(GETOPT(str));
*str = *out;
free(out);
}
void exs_whereip(exString* str, exsp_where func, void* data)
{
exString* out = exs_where(str,func,data);
exs_reset(str);
exs_append(str, *out);
exs_free(out);
free(GETOPT(str));
*str = *out;
free(out);
}
void exs_reset(exString *str)

@ -132,16 +132,23 @@ int se_valid(const char* str)
char *ns = EXS(s);
int ret = *ns && !(*ns=='(' && memcmp(ns, ns+1, strlen(ns)-1)==0);
exs_free(s);
return ret;
}
list_t* se_last(list_t *list)
{
if(list->cdr) return se_last(list->cdr);
else return list;
}
list_t* se_parse(const char* str, unsigned int flags)
{
if(!str) return NULL;
int lp=0,tst=0;
if(*str=='(')
if(*str=='(' && !(flags & SET_NO_WRAP))
str+=1;
else if( (tst=nows(str))>0)
return se_parse(str+tst, flags);
@ -157,6 +164,8 @@ static int _se_add_quotes(const char* inp)
case ' ':
case ')':
case '(':
case '\t':
case '\r':
return 1;
default: break;
}
@ -175,6 +184,7 @@ void _se_append(exString *out, const char* thing)
{
switch(*thing)
{
case '\n':
case '\"':
exs_appendc(str, '\\');
default:break;
@ -224,7 +234,73 @@ void se_print(FILE* fp, const list_t* list)
void se_free(list_t* list)
{
if(list->cdr) se_free(list->cdr);
if(list->ptr && list->car.alloced)
free(list->ptr);
if(list->ptr) {
if(list->car.alloced) {
if(list->car.sexpr)
se_free((list_t*)list->ptr);
else
free(list->ptr);
}
}
free(list);
}
enum _se_type se_typeof(list_t* list)
{
if(!list->ptr) return SE_NIL;
else if(list->car.sexpr) return SE_LIST;
else return SE_STRING;
}
static list_t* _se_new(void* car, enum _se_type type, int dupe)
{
list_t* m = malloc(sizeof(list_t));
memset(m,0,sizeof(list_t));
void* _car = car;
if(car) {
switch(type)
{
case SE_STRING:
if(dupe) {
char* dup = strdup((char*)car);
m->ptr = dup;
m->car.size = strlen(dup);
m->car.alloced = 1;
}
else {
m->ptr = car;
m->car.size = strlen(car);
}
break;
case SE_LIST:
if(dupe) { //TODO: Clone alloced cars?
list_t* cr = malloc(sizeof(list_t));
list_t* or = cr;
list_t* car = _car;
memcpy(cr, car, sizeof(list_t));
while(car->cdr) {
cr->cdr = malloc(sizeof(list_t));
memcpy(cr->cdr, car->cdr, sizeof(list_t));
cr->cdr->car.alloced = 0;
car = car->cdr;
cr = cr->cdr;
}
m->ptr = or;
m->car.size = sizeof(list_t);
m->car.alloced = 1;
}
else {
m->ptr = car;
m->car.size = sizeof(list_t);
}
break;
default: break;
}
}
return m;
}
list_t* se_new(char* str, int dupe)
{
return _se_new(str, SE_STRING, dupe); //We don't need the list part.
}

@ -69,9 +69,26 @@ void test_parse()
exs_free(buf);
}
void test_make()
{
list_t* l = se_new("Hello", 1);
l->cdr = se_new("world", 1);
list_t* n = se_parse("(I love you)", SETP_DEFAULT | SET_NO_WRAP);
se_last((((l->cdr->cdr = n)->cdr = se_parse("((((very)) much))", SETP_DEFAULT))
->cdr = se_parse("((\\\n more parsing))", SETP_DEFAULT))
->cdr = se_parse("((AND EVEN (M (O (R (E))))) !!!)", SETP_DEFAULT))->cdr = se_parse("(test test test!)", SETP_DEFAULT);
se_print(NULL, l);
printf("\n");
se_free(l);
}
int main()
{
// test_exs();
test_parse();
test_make();
return 0;
}

Loading…
Cancel
Save