00001 #include "nasal.h"
00002 #include "data.h"
00003
00004 static struct VecRec* newvecrec(struct VecRec* old)
00005 {
00006 int i, oldsz = old ? old->size : 0, newsz = 1 + ((oldsz*3)>>1);
00007 struct VecRec* vr = naAlloc(sizeof(struct VecRec) + sizeof(naRef) * newsz);
00008 if(oldsz > newsz) oldsz = newsz;
00009 vr->alloced = newsz;
00010 vr->size = oldsz;
00011 for(i=0; i<oldsz; i++)
00012 vr->array[i] = old->array[i];
00013 return vr;
00014 }
00015
00016 static void resize(struct naVec* v)
00017 {
00018 struct VecRec* vr = newvecrec(v->rec);
00019 naGC_swapfree((void*)&(v->rec), vr);
00020 }
00021
00022 void naVec_gcclean(struct naVec* v)
00023 {
00024 naFree(v->rec);
00025 v->rec = 0;
00026 }
00027
00028 naRef naVec_get(naRef v, int i)
00029 {
00030 if(IS_VEC(v)) {
00031 struct VecRec* r = PTR(v).vec->rec;
00032 if(r) {
00033 if(i < 0) i += r->size;
00034 if(i >= 0 && i < r->size) return r->array[i];
00035 }
00036 }
00037 return naNil();
00038 }
00039
00040 void naVec_set(naRef vec, int i, naRef o)
00041 {
00042 if(IS_VEC(vec)) {
00043 struct VecRec* r = PTR(vec).vec->rec;
00044 if(r && i >= r->size) return;
00045 r->array[i] = o;
00046 }
00047 }
00048
00049 int naVec_size(naRef v)
00050 {
00051 if(IS_VEC(v)) {
00052 struct VecRec* r = PTR(v).vec->rec;
00053 return r ? r->size : 0;
00054 }
00055 return 0;
00056 }
00057
00058 int naVec_append(naRef vec, naRef o)
00059 {
00060 if(IS_VEC(vec)) {
00061 struct VecRec* r = PTR(vec).vec->rec;
00062 while(!r || r->size >= r->alloced) {
00063 resize(PTR(vec).vec);
00064 r = PTR(vec).vec->rec;
00065 }
00066 r->array[r->size] = o;
00067 return r->size++;
00068 }
00069 return 0;
00070 }
00071
00072 void naVec_setsize(naRef vec, int sz)
00073 {
00074 int i;
00075 struct VecRec* v = PTR(vec).vec->rec;
00076 struct VecRec* nv = naAlloc(sizeof(struct VecRec) + sizeof(naRef) * sz);
00077 nv->size = sz;
00078 nv->alloced = sz;
00079 for(i=0; i<sz; i++)
00080 nv->array[i] = (v && i < v->size) ? v->array[i] : naNil();
00081 naGC_swapfree((void*)&(PTR(vec).vec->rec), nv);
00082 }
00083
00084 naRef naVec_removelast(naRef vec)
00085 {
00086 naRef o;
00087 if(IS_VEC(vec)) {
00088 struct VecRec* v = PTR(vec).vec->rec;
00089 if(!v || v->size == 0) return naNil();
00090 o = v->array[v->size - 1];
00091 v->size--;
00092 if(v->size < (v->alloced >> 1))
00093 resize(PTR(vec).vec);
00094 return o;
00095 }
00096 return naNil();
00097 }