From e1ceef73192f0300ff9b10ba9a16475fbebeaa5f Mon Sep 17 00:00:00 2001 From: kartofen Date: Fri, 30 Aug 2024 17:01:28 +0300 Subject: proper repl, stylistic changes, removed trailing whitespace --- src/value.c | 144 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 90 insertions(+), 54 deletions(-) (limited to 'src/value.c') diff --git a/src/value.c b/src/value.c index d7df858..54c0d20 100644 --- a/src/value.c +++ b/src/value.c @@ -5,14 +5,6 @@ #include "value.h" #include "lexer.h" -// TODO: -// - create VALUE_MANAGE_TABLE which manages -// both creation and destruction -// - check the buffer size in cons creation - -// FIX: -// - remove warning for void pointer cast at line 30 - #define NOT_IMPLEMENTED() die("Not Implemented. ABORTING") const char * const value_type_string[] = { @@ -21,7 +13,7 @@ const char * const value_type_string[] = { #define VALUE(_value) (_value)->value -#define FN(fn, ...) fn(buf, buf_sz, __VA_ARGS__) +#define FN(fn, ...) return fn(buf, buf_sz, __VA_ARGS__) #define VALUE_STRING_TABLE(X, v, buf, buf_sz) \ X(VALUE_NIL, FN(snprintf, "(nil)")) \ X(VALUE_ATOM, FN(snprintf, "%s", VALUE(v).atom)) \ @@ -44,23 +36,51 @@ const char * const value_type_string[] = { X(VALUE_PROC, if(NOREFS(v)) proc_destroy(&VALUE(v).proc)) \ X(VALUE_PROC_BUILTIN, (void)NOREFS(v)) -#define CASE_RETURN_APPLY(vtype, apply) \ - case vtype: return apply; -#define CASE_APPLY_BREAK(vtype, apply) \ - case vtype: apply; break; +#define CREATE(vtype, value) return value_create(vtype, value) +#define VALUE_FROM_TOKEN_TABLE(X, t) \ + X(TOKEN_INT, CREATE(VALUE_INT, &t->value.num)) \ + X(TOKEN_STR, \ + char *str = str_alloc_copy(t->value.str); \ + CREATE(VALUE_STR, &str)) \ + X(TOKEN_ID, \ + char *atom = str_alloc_copy(t->value.id); \ + CREATE(VALUE_ATOM, &atom)) + +#define CASE_APPLY(vtype, apply) \ + case vtype: ; apply; break; + +#define VALUE_MEMBER_TABLE(X) \ + X(VALUE_ATOM, atom) \ + X(VALUE_STR, str) \ + X(VALUE_INT, num) \ + X(VALUE_CONS, cons) \ + X(VALUE_PROC, proc) \ + X(VALUE_PROC_BUILTIN, proc_builtin) + + +static char *str_alloc_copy(char *src); static int cons_print(char *buf, size_t buf_sz, struct cons *cons); static int proc_print(char *buf, size_t buf_sz, struct proc *proc); -// static value_t proc_create(...); static void proc_destroy(struct proc *proc); + +#define MEMBER_COPY(vtype, member) \ + case vtype: memcpy(&_value->value.member, value, \ + sizeof(_value->value.member)); \ + break; + value_t value_create(enum value_type type, void *value) { value_t _value = malloc(sizeof(*_value)); _value->type = type; - if(value != NULL) - _value->value = *(union value_union *)value; + + switch(type) { + VALUE_MEMBER_TABLE(MEMBER_COPY); + default: break; + } + _value->refs = 1; return _value; @@ -69,35 +89,20 @@ value_t value_create(enum value_type type, void *value) void value_destroy(value_t value) { if(!value) return; - + switch(value->type) { - VALUE_DESTROY_TABLE(CASE_APPLY_BREAK, value); + VALUE_DESTROY_TABLE(CASE_APPLY, value); } if(value->refs == 0) free(value); } -#define STR_ALLOC_COPY(dest, str) do { \ - size_t len = strlen(str) + 1; \ - dest = malloc(len); \ - memcpy((dest), (str), len); \ - } while(0) - value_t value_from_token(struct token *token) -{ +{ switch(token->type) { - case TOKEN_ID: ; - char *atom = NULL; - STR_ALLOC_COPY(atom, token->value.id); - return value_create(VALUE_ATOM, &atom); - case TOKEN_STR: ; - char *str = NULL; - STR_ALLOC_COPY(str, token->value.str); - return value_create(VALUE_STR, &str); - case TOKEN_INT: - return value_create(VALUE_INT, &token->value); + VALUE_FROM_TOKEN_TABLE(CASE_APPLY, token) default: err("Cannot turn token '%s' to a value", token_type_string[token->type]); @@ -108,59 +113,90 @@ value_t value_from_token(struct token *token) value_t value_copy(value_t value) { if(!value) return value; - + value->refs++; - + if(value->type == VALUE_CONS) { value_copy(value->value.cons.left); value_copy(value->value.cons.right); } - + return value; } int value_string(value_t value, size_t buf_sz, char *buf) { if(!value) return snprintf(buf, buf_sz, "(empty)"); - + switch(value->type) { - VALUE_STRING_TABLE(CASE_RETURN_APPLY, value, buf, buf_sz) + VALUE_STRING_TABLE(CASE_APPLY, value, buf, buf_sz) } return 0; } +static char *str_alloc_copy(char *src) +{ + if(!src) return src; + + size_t len = strlen(src) + 1; + return memcpy(malloc(len), src, len); +} + static int cons_print(char *buf, size_t buf_sz, struct cons *cons) { - // TODO: check for size and off by one errors - int offset = 0; - buf[offset++] = '('; - offset += value_string(cons->left, buf_sz-offset, buf+offset); +#define HAS_SPACE if(offset < buf_sz) +#define SET_CHAR(ch) HAS_SPACE { buf[offset++] = ch; } +#define SET_VALUE_STRING(v) \ + HAS_SPACE { \ + offset += value_string(v, buf_sz-offset, buf+offset); \ + } /*else { \ + offset += value_string(v, 0, NULL); \ + } */ + + size_t offset = 0; + + SET_CHAR('('); + SET_VALUE_STRING(cons->left); value_t right = cons->right; while(right->type == VALUE_CONS) { - buf[offset++] = ' '; - offset += value_string(right->value.cons.left, - buf_sz-offset, buf+offset); + SET_CHAR(' '); + SET_VALUE_STRING(right->value.cons.left) right = right->value.cons.right; } if(right->type != VALUE_NIL) { - buf[offset++] = ' '; - buf[offset++] = '.'; - buf[offset++] = ' '; - offset += value_string(right, buf_sz-offset, buf+offset); + SET_CHAR(' '); + SET_CHAR('.'); + SET_CHAR(' '); + SET_VALUE_STRING(right); + } + + SET_CHAR(')'); + + SET_CHAR('\0') else { + if(buf_sz == 0) goto exit; + + char str[] = "...)"; + + if(buf_sz <= sizeof(str)) { + buf[0] = '\0'; + goto exit; + } + + memcpy(buf+buf_sz - sizeof(str), str, sizeof(str)); } - buf[offset++] = ')'; - return offset; +exit: + return (int)offset; } static int proc_print(char *buf, size_t buf_sz, struct proc *proc) { return 0; (void)buf; (void)buf_sz; - (void)proc; + (void)proc; NOT_IMPLEMENTED(); } -- cgit v1.2.3