summaryrefslogtreecommitdiff
path: root/src/lib/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/main.c')
-rw-r--r--src/lib/main.c107
1 files changed, 77 insertions, 30 deletions
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);
+}