make-tuple and a few memory fixes.

This commit is contained in:
antirez 2023-01-31 12:57:11 +01:00
parent b4e37ec848
commit 2a0dd067d3

24
aocla.c
View file

@ -496,9 +496,13 @@ obj *deepCopy(obj *o) {
/* This function performs a deep copy of the object if it has a refcount > 1.
* The copy is returned. Otherwise if refcount is 1, the function returns
* the same object we passed as argument. This is useful when we want to
* modify a shared object. */
* modify a shared object.
*
* When the function returns a copy, the reference count of the original
* object is decremented, as the object logically lost one reference. */
obj *getUnsharedObject(obj *o) {
if (o->refcount > 1) {
release(o);
return deepCopy(o);
} else {
return o;
@ -570,6 +574,12 @@ obj *stackPeek(aoclactx *ctx, size_t offset) {
return ctx->stack[ctx->stacklen-1-offset];
}
/* Like stack peek, but instead of returning the object sets it. */
void stackSet(aoclactx *ctx, size_t offset, obj *o) {
assert(ctx->stacklen > offset);
ctx->stack[ctx->stacklen-1-offset] = o;
}
/* Show the current content of the stack. */
#define STACK_SHOW_MAX_ELE 10
void stackShow(aoclactx *ctx) {
@ -1026,6 +1036,7 @@ int procCat(aoclactx *ctx) {
obj *src = stackPop(ctx);
obj *dst = stackPeek(ctx,0);
dst = getUnsharedObject(dst);
stackSet(ctx,0,dst);
if (src->type & (OBJ_TYPE_STRING|OBJ_TYPE_SYMBOL)) {
dst->str.ptr = myrealloc(dst->str.ptr,dst->str.len+src->str.len+1);
@ -1041,6 +1052,16 @@ int procCat(aoclactx *ctx) {
return 0;
}
// Turns the list on the stack into a tuple.
int procMakeTuple(aoclactx *ctx) {
if (checkStackType(ctx,1,OBJ_TYPE_LIST)) return 1;
obj *l = stackPop(ctx);
l = getUnsharedObject(l);
l->type = OBJ_TYPE_TUPLE;
stackPush(ctx,l);
return 0;
}
/* Show the current stack. Useful for debugging. */
int procShowStack(aoclactx *ctx) {
stackShow(ctx);
@ -1074,6 +1095,7 @@ void loadLibrary(aoclactx *ctx) {
addProc(ctx,"get@",procListGetAt,NULL);
addProc(ctx,"showstack",procShowStack,NULL);
addProc(ctx,"cat",procCat,NULL);
addProc(ctx,"make-tuple",procMakeTuple,NULL);
/* Since the point of this interpreter to be a short and understandable
* programming example, we implement as much as possible in Aocla itself