mirror of
https://github.com/janet-lang/janet
synced 2024-12-26 00:10:27 +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:
parent
a54548eaa0
commit
652b250718
25
core/ds.c
25
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. */
|
/* Find next key in an object. Returns nil if no next key. */
|
||||||
GstValue gst_object_next(GstObject *o, GstValue key) {
|
GstValue gst_object_next(GstObject *o, GstValue key) {
|
||||||
GstValue ret;
|
const GstValue *bucket, *end;
|
||||||
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;
|
end = o->data + o->capacity;
|
||||||
for (nextbucket = bucket + 2; nextbucket < end; nextbucket += 2) {
|
if (key.type == GST_NIL) {
|
||||||
if (nextbucket[0].type != GST_NIL)
|
bucket = o->data;
|
||||||
return nextbucket[0];
|
} else {
|
||||||
|
bucket = gst_object_find(o, key);
|
||||||
|
if (!bucket || bucket[0].type == GST_NIL)
|
||||||
|
return gst_wrap_nil();
|
||||||
|
bucket += 2;
|
||||||
}
|
}
|
||||||
|
for (; bucket < end; bucket += 2) {
|
||||||
|
if (bucket[0].type != GST_NIL)
|
||||||
|
return bucket[0];
|
||||||
}
|
}
|
||||||
ret.type = GST_NIL;
|
return gst_wrap_nil();
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
core/ids.c
26
core/ids.c
@ -288,23 +288,21 @@ GstValue gst_struct_get(const GstValue *st, GstValue key) {
|
|||||||
|
|
||||||
/* Get the next key in a struct */
|
/* Get the next key in a struct */
|
||||||
GstValue gst_struct_next(const GstValue *st, GstValue key) {
|
GstValue gst_struct_next(const GstValue *st, GstValue key) {
|
||||||
GstValue ret;
|
const GstValue *bucket, *end;
|
||||||
const GstValue *bucket;
|
|
||||||
if (key.type == GST_NIL)
|
|
||||||
bucket = st - 2;
|
|
||||||
else
|
|
||||||
bucket = gst_struct_find(st, key);
|
|
||||||
if (bucket && bucket[0].type != GST_NIL) {
|
|
||||||
const GstValue *nextbucket, *end;
|
|
||||||
end = st + gst_struct_capacity(st);
|
end = st + gst_struct_capacity(st);
|
||||||
for (nextbucket = bucket + 2; nextbucket < end; nextbucket += 2) {
|
if (key.type == GST_NIL) {
|
||||||
if (nextbucket[0].type != GST_NIL)
|
bucket = st;
|
||||||
return nextbucket[0];
|
} else {
|
||||||
|
bucket = gst_struct_find(st, key);
|
||||||
|
if (!bucket || bucket[0].type == GST_NIL)
|
||||||
|
return gst_wrap_nil();
|
||||||
|
bucket += 2;
|
||||||
}
|
}
|
||||||
|
for (; bucket < end; bucket += 2) {
|
||||||
|
if (bucket[0].type != GST_NIL)
|
||||||
|
return bucket[0];
|
||||||
}
|
}
|
||||||
ret.type = GST_NIL;
|
return gst_wrap_nil();
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
@ -104,6 +104,11 @@ COMPARE_FUNCTION(greaterthaneq, gst_compare(lhs, rhs) >= 0)
|
|||||||
|
|
||||||
#undef COMPARE_FUNCTION
|
#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 */
|
/* Core */
|
||||||
/****/
|
/****/
|
||||||
@ -533,7 +538,7 @@ int gst_stl_open(Gst *vm) {
|
|||||||
/* Temporary */
|
/* 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
|
* rewritten in gst when the language is complete enough. This is not to say
|
||||||
* that functions in other section need not be moved. */
|
* that functions in other section need not be moved. */
|
||||||
|
|
||||||
@ -564,6 +569,7 @@ static const GstModuleItem const std_module[] = {
|
|||||||
{"=", gst_stl_equal},
|
{"=", gst_stl_equal},
|
||||||
{"<=", gst_stl_lessthaneq},
|
{"<=", gst_stl_lessthaneq},
|
||||||
{">=", gst_stl_greaterthaneq},
|
{">=", gst_stl_greaterthaneq},
|
||||||
|
{"not", gst_stl_not},
|
||||||
{"length", gst_stl_length},
|
{"length", gst_stl_length},
|
||||||
{"to-integer", gst_stl_to_int},
|
{"to-integer", gst_stl_to_int},
|
||||||
{"to-real", gst_stl_to_real},
|
{"to-real", gst_stl_to_real},
|
||||||
|
@ -38,7 +38,7 @@ int gst_continue(Gst *vm) {
|
|||||||
#define gst_assert(vm, cond, e) do {if (!(cond)){gst_error((vm), (e));}} while (0)
|
#define gst_assert(vm, cond, e) do {if (!(cond)){gst_error((vm), (e));}} while (0)
|
||||||
|
|
||||||
/* Intialize local state */
|
/* Intialize local state */
|
||||||
stack = vm->thread->data + vm->thread->count;
|
stack = gst_thread_stack(vm->thread);
|
||||||
pc = gst_frame_pc(stack);
|
pc = gst_frame_pc(stack);
|
||||||
|
|
||||||
/* Main interpreter loop */
|
/* Main interpreter loop */
|
||||||
@ -291,7 +291,6 @@ int gst_continue(Gst *vm) {
|
|||||||
gst_frame_env(stack) = NULL;
|
gst_frame_env(stack) = NULL;
|
||||||
gst_thread_endframe(vm, vm->thread);
|
gst_thread_endframe(vm, vm->thread);
|
||||||
stack = vm->thread->data + vm->thread->count;
|
stack = vm->thread->data + vm->thread->count;
|
||||||
gst_frame_args(stack) = 0;
|
|
||||||
temp = gst_frame_callee(stack);
|
temp = gst_frame_callee(stack);
|
||||||
if (temp.type == GST_FUNCTION) {
|
if (temp.type == GST_FUNCTION) {
|
||||||
pc = temp.data.function->def->byteCode;
|
pc = temp.data.function->def->byteCode;
|
||||||
|
59
libs/pp.gst
59
libs/pp.gst
@ -1,30 +1,59 @@
|
|||||||
# Pretty print
|
# Pretty print
|
||||||
|
|
||||||
# Reindent a function to be more deeply indented
|
# Declare pretty print
|
||||||
(: reindent (fn [x] x))
|
(: pp nil)
|
||||||
|
|
||||||
# Pretty print an array
|
# Pretty print an array or tuple
|
||||||
(: print-array (fn [a]
|
(: print-seq (fn [start end a]
|
||||||
(: parts [])
|
(: parts [])
|
||||||
(: l (length a))
|
(: len (length a))
|
||||||
(: i 0)
|
(: i 0)
|
||||||
(while (< i l)
|
(while (< i len)
|
||||||
|
(push parts (pp (rawget a i)))
|
||||||
|
(push parts " ")
|
||||||
(: i (+ 1 i)))
|
(: i (+ 1 i)))
|
||||||
(apply strcat "[ " parts)))
|
(if (> len 0) (pop parts))
|
||||||
|
(push parts end)
|
||||||
|
(apply strcat start parts)))
|
||||||
|
|
||||||
(: handler {
|
# Pretty print an object or struct
|
||||||
"number" tostring
|
(: 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
|
"nil" tostring
|
||||||
"boolean" tostring
|
"boolean" tostring
|
||||||
"userdata" tostring
|
"userdata" tostring
|
||||||
"cfunction" tostring
|
"cfunction" tostring
|
||||||
"function" tostring
|
"function" tostring
|
||||||
"string" tostring # change to unquote string
|
"string" tostring
|
||||||
"buffer" tostring
|
"buffer" tostring
|
||||||
"array" tostring
|
"array" (fn [a] (print-seq "[" "]" a))
|
||||||
"tuple" tostring
|
"tuple" (fn [a] (print-seq "(" ")" a))
|
||||||
"object" tostring
|
"object" (fn [s] (print-struct "{" "}" s))
|
||||||
"struct" tostring
|
"struct" (fn [s] (print-struct "#{" "}" s))
|
||||||
"thread" tostring
|
"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!")
|
||||||
|
Loading…
Reference in New Issue
Block a user