Commit fe5c60db authored by Chris Müller's avatar Chris Müller
Browse files

Add symbollist based on binary trees

parent 53ae27be
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Default symbols // Default symbols
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static struct value* global_symbollist = NULL;
struct value* True = NULL; struct value* True = NULL;
struct value* False = NULL; struct value* False = NULL;
struct value* Emptylist = NULL; struct value* Emptylist = NULL;
...@@ -54,19 +56,61 @@ alloc_value(void) ...@@ -54,19 +56,61 @@ alloc_value(void)
struct value* value = GC_MALLOC(sizeof(struct value)); struct value* value = GC_MALLOC(sizeof(struct value));
if(value == NULL) { if(value == NULL) {
failure("Boehm GC: out of memory in value allocation"); failure("Boehm GC: can not allocate a value (out of memory)");
} }
return value; return value;
} }
struct value*
alloc_symbol(const byte_t* symbol_value)
{
size_t size = strlen(symbol_value) + 1;
byte_t* symbol_string = GC_MALLOC(sizeof(byte_t) * size);
if(symbol_string == NULL)
failure("Boehm GC: can not allocate a symbol (out of memory)");
else
memcpy(symbol_string, symbol_value, size);
struct value* value = alloc_value();
value->tag = SYMBOL;
value->symbol_value = symbol_string;
return value;
}
struct value* struct value*
symbol(const byte_t* symbol_value) symbol(const byte_t* symbol_value)
{ {
struct value* v = alloc_value(); struct value* node = global_symbollist;
v->tag = SYMBOL;
v->symbol_value = symbol_value; if(IS_NULL(node)) {
return v; global_symbollist = SYMBOL_ENTRY(alloc_symbol(symbol_value), Emptylist, Emptylist);
return HEAD(global_symbollist);
}
while(TRUE) {
const byte_t* current = HEAD(node)->symbol_value;
if(strcmp(current, symbol_value) > 0) {
if(IS_NULL(SYMBOL_LEFT(node))) {
SYMBOL_LEFT(node) = SYMBOL_ENTRY(alloc_symbol(symbol_value), Emptylist, Emptylist);
return HEAD(SYMBOL_LEFT(node));
} else
node = SYMBOL_LEFT(node);
} else if (strcmp(current, symbol_value) < 0) {
if(IS_NULL(SYMBOL_RIGHT(node))) {
SYMBOL_RIGHT(node) = SYMBOL_ENTRY(alloc_symbol(symbol_value), Emptylist, Emptylist);
return HEAD(SYMBOL_RIGHT(node));
} else
node = SYMBOL_RIGHT(node);
} else {
return HEAD(node);
}
}
return Emptylist;
} }
struct value* struct value*
...@@ -135,7 +179,7 @@ tuple(size_t size, ...) ...@@ -135,7 +179,7 @@ tuple(size_t size, ...)
v->tuple.data = GC_MALLOC(sizeof(struct value*) * size); v->tuple.data = GC_MALLOC(sizeof(struct value*) * size);
if(v->tuple.data == NULL) if(v->tuple.data == NULL)
failure("Boehm GC: Out of memory in tuple allocation"); failure("Boehm GC: can not allocate tuple (out of memory)");
va_list args; va_list args;
va_start(args, size); va_start(args, size);
...@@ -193,6 +237,8 @@ initialize(void) ...@@ -193,6 +237,8 @@ initialize(void)
Emptylist = alloc_value(); Emptylist = alloc_value();
Emptylist->tag = EMPTYLIST; Emptylist->tag = EMPTYLIST;
global_symbollist = Emptylist;
Quote = symbol("quote"); Quote = symbol("quote");
Define = symbol("define"); Define = symbol("define");
Let = symbol("let"); Let = symbol("let");
...@@ -391,7 +437,7 @@ lex_char(byte_t** begin, byte_t* buffer, size_t buffer_size) ...@@ -391,7 +437,7 @@ lex_char(byte_t** begin, byte_t* buffer, size_t buffer_size)
buffer++; buffer++;
p++; p++;
} else } else
failure("Bufferoverflow in raw string literal"); failure("Bufferoverflow in character literal");
} }
*buffer = '\0'; *buffer = '\0';
...@@ -524,7 +570,7 @@ NO_BUFFER_APPEND: ...@@ -524,7 +570,7 @@ NO_BUFFER_APPEND:
buffer++; buffer++;
p++; p++;
} else } else
failure("Bufferoverflow in symbol scanning"); failure("Bufferoverflow in string scanning");
} }
RETURN_TOKEN: RETURN_TOKEN:
...@@ -735,6 +781,13 @@ cherry_read(byte_t** src, byte_t* buffer, size_t buffer_size) ...@@ -735,6 +781,13 @@ cherry_read(byte_t** src, byte_t* buffer, size_t buffer_size)
return val; return val;
} }
// ----------------------------------------------------------------------------
// runtime utils
// ----------------------------------------------------------------------------
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// compile // compile
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -743,6 +796,7 @@ cherry_read(byte_t** src, byte_t* buffer, size_t buffer_size) ...@@ -743,6 +796,7 @@ cherry_read(byte_t** src, byte_t* buffer, size_t buffer_size)
struct closure* struct closure*
cherry_compile(struct value* ast, struct value* env) cherry_compile(struct value* ast, struct value* env)
{ {
return NULL; return NULL;
} }
......
...@@ -121,17 +121,25 @@ struct value* cons(struct value* head, struct value* tail); ...@@ -121,17 +121,25 @@ struct value* cons(struct value* head, struct value* tail);
#define list3(A, B, C) cons(A, cons(B, cons(C, emptylist))) #define list3(A, B, C) cons(A, cons(B, cons(C, emptylist)))
#define list4(A, B, C, D) cons(A, cons(B, cons(C, cons(D, emptylist)))) #define list4(A, B, C, D) cons(A, cons(B, cons(C, cons(D, emptylist))))
#define SYMBOL_ENTRY(sym, left, right) \
cons(sym, cons(left, right))
#define SYMBOL_LEFT(node) HEAD(TAIL(node))
#define SYMBOL_RIGHT(node) TAIL(TAIL(node))
struct closure { struct closure {
struct value* (*execute)(struct closure* self); struct value* (*execute)(struct closure* self);
struct value* env; struct value* args;
}; };
#define IS_CONTINUATION(closure) (((struct closure*) closure)->execute != NULL)
#define EXECUTE(obj) (((struct closure*) obj)->execute((struct closure*)obj)) #define EXECUTE(obj) (((struct closure*) obj)->execute((struct closure*)obj))
void cherry_initialize(void); void cherry_initialize(void);
struct value* cherry_read(byte_t** begin, byte_t* buffer, size_t buffer_size); struct value* cherry_read(byte_t** begin, byte_t* buffer, size_t buffer_size);
struct closure* cherry_compile(struct value* ast, struct value* env); struct closure* cherry_compile(struct value* ast, struct value* env);
struct value* cherry_eval(struct closure* code); struct value* cherry_eval(struct closure* code);
void cherry_write(FILE* out, struct value* v); void cherry_write(FILE* out, struct value* v);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment