aboutsummaryrefslogtreecommitdiff
path: root/src/value.c
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2024-08-30 17:01:28 +0300
committerkartofen <mladenovnasko0@gmail.com>2024-08-30 17:01:28 +0300
commite1ceef73192f0300ff9b10ba9a16475fbebeaa5f (patch)
tree0cb2bc5336a522b965c1d171b433044591721e20 /src/value.c
parentde3a062bfc206bf0373f96f4f6cc8c74ffcbab48 (diff)
proper repl, stylistic changes, removed trailing whitespace
Diffstat (limited to 'src/value.c')
-rw-r--r--src/value.c144
1 files changed, 90 insertions, 54 deletions
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();
}