mirror of
https://github.com/antirez/aocla
synced 2025-01-13 20:01:40 +01:00
make-tuple and a few memory fixes.
This commit is contained in:
parent
b4e37ec848
commit
2a0dd067d3
1 changed files with 23 additions and 1 deletions
24
aocla.c
24
aocla.c
|
@ -496,9 +496,13 @@ obj *deepCopy(obj *o) {
|
||||||
/* This function performs a deep copy of the object if it has a refcount > 1.
|
/* 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 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
|
* 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) {
|
obj *getUnsharedObject(obj *o) {
|
||||||
if (o->refcount > 1) {
|
if (o->refcount > 1) {
|
||||||
|
release(o);
|
||||||
return deepCopy(o);
|
return deepCopy(o);
|
||||||
} else {
|
} else {
|
||||||
return o;
|
return o;
|
||||||
|
@ -570,6 +574,12 @@ obj *stackPeek(aoclactx *ctx, size_t offset) {
|
||||||
return ctx->stack[ctx->stacklen-1-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. */
|
/* Show the current content of the stack. */
|
||||||
#define STACK_SHOW_MAX_ELE 10
|
#define STACK_SHOW_MAX_ELE 10
|
||||||
void stackShow(aoclactx *ctx) {
|
void stackShow(aoclactx *ctx) {
|
||||||
|
@ -1026,6 +1036,7 @@ int procCat(aoclactx *ctx) {
|
||||||
obj *src = stackPop(ctx);
|
obj *src = stackPop(ctx);
|
||||||
obj *dst = stackPeek(ctx,0);
|
obj *dst = stackPeek(ctx,0);
|
||||||
dst = getUnsharedObject(dst);
|
dst = getUnsharedObject(dst);
|
||||||
|
stackSet(ctx,0,dst);
|
||||||
|
|
||||||
if (src->type & (OBJ_TYPE_STRING|OBJ_TYPE_SYMBOL)) {
|
if (src->type & (OBJ_TYPE_STRING|OBJ_TYPE_SYMBOL)) {
|
||||||
dst->str.ptr = myrealloc(dst->str.ptr,dst->str.len+src->str.len+1);
|
dst->str.ptr = myrealloc(dst->str.ptr,dst->str.len+src->str.len+1);
|
||||||
|
@ -1041,6 +1052,16 @@ int procCat(aoclactx *ctx) {
|
||||||
return 0;
|
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. */
|
/* Show the current stack. Useful for debugging. */
|
||||||
int procShowStack(aoclactx *ctx) {
|
int procShowStack(aoclactx *ctx) {
|
||||||
stackShow(ctx);
|
stackShow(ctx);
|
||||||
|
@ -1074,6 +1095,7 @@ void loadLibrary(aoclactx *ctx) {
|
||||||
addProc(ctx,"get@",procListGetAt,NULL);
|
addProc(ctx,"get@",procListGetAt,NULL);
|
||||||
addProc(ctx,"showstack",procShowStack,NULL);
|
addProc(ctx,"showstack",procShowStack,NULL);
|
||||||
addProc(ctx,"cat",procCat,NULL);
|
addProc(ctx,"cat",procCat,NULL);
|
||||||
|
addProc(ctx,"make-tuple",procMakeTuple,NULL);
|
||||||
|
|
||||||
/* Since the point of this interpreter to be a short and understandable
|
/* Since the point of this interpreter to be a short and understandable
|
||||||
* programming example, we implement as much as possible in Aocla itself
|
* programming example, we implement as much as possible in Aocla itself
|
||||||
|
|
Loading…
Reference in a new issue