From 7f7a2fb4fb23433e7be3d6953725690c8ea958d2 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 31 Aug 2026 19:44:56 +0000 Subject: The objects returned to the user are now integer-based references, not actual pointers. This means the aplwc internals can update those pointers without the user noticing. FossilOrigin-Name: 654c7d0ec85da295a7fb6ed381500410686b280f342fa81a30481f5e9a20c58a --- src/lib/main.c | 107 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 77 insertions(+), 30 deletions(-) (limited to 'src/lib/main.c') diff --git a/src/lib/main.c b/src/lib/main.c index 03c31a5..454ad1c 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -1,22 +1,34 @@ #include "aplwc_internal.h" #include "boot.h" -enum aplwc_rc -aplwc_new(struct aplwc **p, struct aplwc_fns fns) +struct aplwc * +aplwc_new(struct aplwc_fns fns, enum aplwc_rc *rcp) { + enum aplwc_rc rc; struct aplwc *aplwc; size_t size; - if(fns.alloc == NULL) - return APLWC_OUT_OF_MEMORY; + aplwc = NULL; + if(fns.alloc == NULL){ + rc = APLWC_OUT_OF_MEMORY; + goto end; + } aplwc = fns.alloc(sizeof(*aplwc), sizeof(*aplwc), &size); - if(aplwc == NULL) - return APLWC_OUT_OF_MEMORY; - *p = aplwc; + if(aplwc == NULL){ + rc = APLWC_OUT_OF_MEMORY; + goto end; + } aplwc->fns = fns; memory_init(aplwc); - return aplwc_load_module(aplwc, "Boot", (const char *)boot_src, boot_src_len); + + rc = aplwc_load_module(aplwc, "Boot", (const char *)boot_src, boot_src_len); +end: + if(rc != APLWC_OK) + aplwc_destroy(aplwc); + if(rcp) + *rcp = rc; + return aplwc; } void @@ -71,18 +83,19 @@ aplwc_last_error(struct aplwc *aplwc) return aplwc->last_error; } -struct aplwc_line * -aplwc_read(struct aplwc *aplwc, const char *line) +AplwcLine +aplwc_read(struct aplwc *aplwc, const char *linestr) { struct string *text; struct token_list *tokens; - struct aplwc_line *ret; + struct aplwc_line *line; + AplwcLine ret; MEMPTRS(aplwc, 2); - ret = NULL; + aplwc_clear_line(&ret); - if((text = chars_to_string(aplwc, line, -1)) == NULL) + if((text = chars_to_string(aplwc, linestr, -1)) == NULL) goto end; MEMPTR(0, text); @@ -93,45 +106,55 @@ aplwc_read(struct aplwc *aplwc, const char *line) if((aplwc->last_error = check_tokens(tokens)) != APLWC_OK) goto end; - if((ret = memory_alloc_aplwc_line(aplwc)) == NULL) + if((line = memory_alloc_aplwc_line(aplwc)) == NULL) goto end; - ret->aplwc = aplwc; - ret->text = text; - ret->tokens = tokens; + line->aplwc = aplwc; + line->text = text; + line->tokens = tokens; + ret.ref = memory_root_new(aplwc, line); end: MEMPTRS_EXIT(aplwc); return ret; } void -aplwc_free_line(struct aplwc_line *line) +aplwc_free_line(AplwcLine line) { - if(line) - memory_free_root(line->aplwc, line); + memory_root_free(line.ref); } -struct aplwc_value * -aplwc_eval(struct aplwc_line *line) +AplwcValue +aplwc_eval(AplwcLine line) { - line->aplwc->last_error = APLWC_OK; - return eval_line(line); + AplwcValue value; + struct aplwc_line *l; + struct aplwc_value *v; + + aplwc_clear_value(&value); + l = memory_root_get(line.ref); + l->aplwc->last_error = APLWC_OK; + v = eval_line(l); + if(v) + value.ref = memory_root_new(line.ref.aplwc, v); + return value; } void -aplwc_free_value(struct aplwc_value *value) +aplwc_free_value(AplwcValue value) { - if(value) - memory_free_root(value->aplwc, value); + memory_root_free(value.ref); } const char * -aplwc_value_string(struct aplwc_value *value) +aplwc_value_string(AplwcValue value) { - assert(value != NULL); + struct aplwc_value *v; + assert(aplwc_valid_value(value)); - switch(value->tag){ + v = memory_root_get(value.ref); + switch(v->tag){ default: return "???"; } @@ -162,3 +185,27 @@ end: MEMPTRS_EXIT(aplwc); return aplwc_last_error(aplwc); } + +void +aplwc_clear_value(AplwcValue *v) +{ + clear_ref(&v->ref); +} + +void +aplwc_clear_line(AplwcLine *l) +{ + clear_ref(&l->ref); +} + +int +aplwc_valid_value(AplwcValue v) +{ + return valid_ref(v.ref); +} + +int +aplwc_valid_line(AplwcLine l) +{ + return valid_ref(l.ref); +} -- cgit v1.2.3