1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-16 10:19:55 +00:00

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.
This commit is contained in:
Calvin Rose 2017-04-24 18:09:23 -04:00
parent a54548eaa0
commit 652b250718
5 changed files with 79 additions and 48 deletions

View File

@ -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();
}

View File

@ -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();
}
/****/

View File

@ -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},

View File

@ -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;

View File

@ -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!")