From 652b2507187837369f31fa52180636141aa6b0f2 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Mon, 24 Apr 2017 18:09:23 -0400 Subject: [PATCH] Finish simple pretty printer in gst. Discovered memory leaks. Seems to have to do with improper marking of the stack and or the VM messes up the stack. --- core/ds.c | 29 +++++++++++++------------- core/ids.c | 28 ++++++++++++------------- core/stl.c | 8 +++++++- core/vm.c | 3 +-- libs/pp.gst | 59 +++++++++++++++++++++++++++++++++++++++-------------- 5 files changed, 79 insertions(+), 48 deletions(-) diff --git a/core/ds.c b/core/ds.c index 4e4c13a1..f6a69d06 100644 --- a/core/ds.c +++ b/core/ds.c @@ -276,21 +276,20 @@ void gst_object_put(Gst *vm, GstObject *o, GstValue key, GstValue value) { /* Find next key in an object. Returns nil if no next key. */ GstValue gst_object_next(GstObject *o, GstValue key) { - GstValue ret; - GstValue *bucket; - if (key.type == GST_NIL) - bucket = o->data - 2; - else - bucket = gst_object_find(o, key); - if (bucket && bucket[0].type != GST_NIL) { - GstValue *nextbucket, *end; - end = o->data + o->capacity; - for (nextbucket = bucket + 2; nextbucket < end; nextbucket += 2) { - if (nextbucket[0].type != GST_NIL) - return nextbucket[0]; - } + const GstValue *bucket, *end; + end = o->data + o->capacity; + if (key.type == GST_NIL) { + bucket = o->data; + } else { + bucket = gst_object_find(o, key); + if (!bucket || bucket[0].type == GST_NIL) + return gst_wrap_nil(); + bucket += 2; } - ret.type = GST_NIL; - return ret; + for (; bucket < end; bucket += 2) { + if (bucket[0].type != GST_NIL) + return bucket[0]; + } + return gst_wrap_nil(); } diff --git a/core/ids.c b/core/ids.c index f20b4cd4..bc9e6601 100644 --- a/core/ids.c +++ b/core/ids.c @@ -288,23 +288,21 @@ GstValue gst_struct_get(const GstValue *st, GstValue key) { /* Get the next key in a struct */ GstValue gst_struct_next(const GstValue *st, GstValue key) { - GstValue ret; - const GstValue *bucket; - if (key.type == GST_NIL) - bucket = st - 2; - else + const GstValue *bucket, *end; + end = st + gst_struct_capacity(st); + if (key.type == GST_NIL) { + bucket = st; + } else { bucket = gst_struct_find(st, key); - if (bucket && bucket[0].type != GST_NIL) { - const GstValue *nextbucket, *end; - end = st + gst_struct_capacity(st); - for (nextbucket = bucket + 2; nextbucket < end; nextbucket += 2) { - if (nextbucket[0].type != GST_NIL) - return nextbucket[0]; - } + if (!bucket || bucket[0].type == GST_NIL) + return gst_wrap_nil(); + bucket += 2; } - ret.type = GST_NIL; - return ret; - + for (; bucket < end; bucket += 2) { + if (bucket[0].type != GST_NIL) + return bucket[0]; + } + return gst_wrap_nil(); } /****/ diff --git a/core/stl.c b/core/stl.c index 1ba7d343..0c2efaf1 100644 --- a/core/stl.c +++ b/core/stl.c @@ -104,6 +104,11 @@ COMPARE_FUNCTION(greaterthaneq, gst_compare(lhs, rhs) >= 0) #undef COMPARE_FUNCTION +/* Boolean not */ +int gst_stl_not(Gst *vm) { + gst_c_return(vm, gst_wrap_boolean(!gst_truthy(gst_arg(vm, 0)))); +} + /****/ /* Core */ /****/ @@ -533,7 +538,7 @@ int gst_stl_open(Gst *vm) { /* Temporary */ /****/ -/* These functions should definitely be moved to a different module, remove, or +/* These functions should definitely be moved to a different module, removed, or * rewritten in gst when the language is complete enough. This is not to say * that functions in other section need not be moved. */ @@ -564,6 +569,7 @@ static const GstModuleItem const std_module[] = { {"=", gst_stl_equal}, {"<=", gst_stl_lessthaneq}, {">=", gst_stl_greaterthaneq}, + {"not", gst_stl_not}, {"length", gst_stl_length}, {"to-integer", gst_stl_to_int}, {"to-real", gst_stl_to_real}, diff --git a/core/vm.c b/core/vm.c index a7a66110..1b354dfd 100644 --- a/core/vm.c +++ b/core/vm.c @@ -38,7 +38,7 @@ int gst_continue(Gst *vm) { #define gst_assert(vm, cond, e) do {if (!(cond)){gst_error((vm), (e));}} while (0) /* Intialize local state */ - stack = vm->thread->data + vm->thread->count; + stack = gst_thread_stack(vm->thread); pc = gst_frame_pc(stack); /* Main interpreter loop */ @@ -291,7 +291,6 @@ int gst_continue(Gst *vm) { gst_frame_env(stack) = NULL; gst_thread_endframe(vm, vm->thread); stack = vm->thread->data + vm->thread->count; - gst_frame_args(stack) = 0; temp = gst_frame_callee(stack); if (temp.type == GST_FUNCTION) { pc = temp.data.function->def->byteCode; diff --git a/libs/pp.gst b/libs/pp.gst index 35526656..a6ded9d7 100644 --- a/libs/pp.gst +++ b/libs/pp.gst @@ -1,30 +1,59 @@ # Pretty print -# Reindent a function to be more deeply indented -(: reindent (fn [x] x)) +# Declare pretty print +(: pp nil) -# Pretty print an array -(: print-array (fn [a] +# Pretty print an array or tuple +(: print-seq (fn [start end a] (: parts []) - (: l (length a)) + (: len (length a)) (: i 0) - (while (< i l) - + (while (< i len) + (push parts (pp (rawget a i))) + (push parts " ") (: i (+ 1 i))) - (apply strcat "[ " parts))) + (if (> len 0) (pop parts)) + (push parts end) + (apply strcat start parts))) -(: handler { - "number" tostring +# Pretty print an object or struct +(: print-struct (fn [start end s] + (: parts []) + (: key (next s)) + (while (not (= key nil)) + (push parts (pp key)) + (push parts " ") + (push parts (pp (rawget s key))) + (push parts " ") + (: key (next s key))) + (if (> (length parts) 0) (pop parts)) + (push parts end) + (apply strcat start parts))) + +# Pretty + +(: handlers { + "real" tostring + "integer" tostring "nil" tostring "boolean" tostring "userdata" tostring "cfunction" tostring "function" tostring - "string" tostring # change to unquote string + "string" tostring "buffer" tostring - "array" tostring - "tuple" tostring - "object" tostring - "struct" tostring + "array" (fn [a] (print-seq "[" "]" a)) + "tuple" (fn [a] (print-seq "(" ")" a)) + "object" (fn [s] (print-struct "{" "}" s)) + "struct" (fn [s] (print-struct "#{" "}" s)) "thread" tostring }) + +# Define pretty print +(: pp (fn [x] + (: h (rawget handlers (type x))) + (h x))) + +(print (pp [1 {4 5 6 7} 2 3])) + +(print "DONE!")