From bdc4b0d9ea0d5413ecf78ee08d5812a2228813c7 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 12 Nov 2025 17:06:12 +0900 Subject: [PATCH] fixed a critical bug in resizing an array - damn residual code improved array/map field set/iteration functions --- README.md | 12 +++++++ hawk.go | 93 ++++++++++++++++++++++++++++++++++------------------ hawk_test.go | 33 ++++++++++++++++--- lib/arr.c | 9 +++-- lib/htb.c | 76 +++++++++++++++++++++--------------------- lib/parse.c | 25 +++++++++++--- lib/rbt.c | 84 +++++++++++++++++++++++------------------------ lib/run.c | 8 ++--- t/h-001.hawk | 28 ++++++++-------- 9 files changed, 226 insertions(+), 142 deletions(-) diff --git a/README.md b/README.md index aec9a57d..0f174381 100644 --- a/README.md +++ b/README.md @@ -960,6 +960,18 @@ BEGIN { END { close("cat"); print "ENDED"; } ``` +```awk +BEGIN { + cmd = "sort"; + data = hawk::array("hello", "world", "two-way pipe", "testing"); + + for (i = 1; i <= length(data); i++) print data[i] |& cmd; + close(cmd, "to"); + + while ((cmd |& getline line) > 0) print line; + close(cmd); +} +``` ## Garbage Collection The primary value management is reference counting based but `map` and `array` values are garbage-collected additionally. diff --git a/hawk.go b/hawk.go index 305ec801..b5367f25 100644 --- a/hawk.go +++ b/hawk.go @@ -108,30 +108,30 @@ type ValArrayItr struct { } type ValMapItr struct { - c *C.hawk_val_map_itr_t + c C.hawk_val_map_itr_t } type BitMask C.hawk_bitmask_t func deregister_instance(h *Hawk) { -fmt.Printf ("DEREGISER INSTANCE %p\n", h) +//fmt.Printf ("DEREGISER INSTANCE %p\n", h) for h.rtx_head != nil { //fmt.Printf ("DEREGISER CLOSING RTX %p\n", h.rtx_head) h.rtx_head.Close() } if h.c != nil { -fmt.Printf ("CLOSING h.c\n") +//fmt.Printf ("CLOSING h.c\n") C.hawk_close(h.c) h.c = nil } if h.inst_no >= 0 { -fmt.Printf ("DELETING instance h\n") +//fmt.Printf ("DELETING instance h\n") inst_table.delete_instance(h.inst_no) h.inst_no = -1 } -fmt.Printf ("END DEREGISER INSTANCE %p\n", h) +//fmt.Printf ("END DEREGISER INSTANCE %p\n", h) } func New() (*Hawk, error) { @@ -294,7 +294,7 @@ func (hawk *Hawk) chain_rtx(rtx *Rtx) { rtx.next = nil hawk.rtx_tail = rtx hawk.rtx_count++ -fmt.Printf(">>>> %d\n", hawk.rtx_count) +//fmt.Printf(">>>> %d\n", hawk.rtx_count) hawk.rtx_mtx.Unlock() } @@ -311,13 +311,13 @@ func (hawk *Hawk) unchain_rtx(rtx *Rtx) { } else { rtx.next.prev = rtx.prev } -fmt.Printf("head %p tail %p\n", hawk.rtx_tail, hawk.rtx_tail) +//fmt.Printf("head %p tail %p\n", hawk.rtx_tail, hawk.rtx_tail) rtx.h = nil rtx.next = nil rtx.prev = nil hawk.rtx_count-- -fmt.Printf(">>>> %d\n", hawk.rtx_count) +//fmt.Printf(">>>> %d\n", hawk.rtx_count) hawk.rtx_mtx.Unlock() } @@ -347,7 +347,7 @@ func (rtx* Rtx) Close() { rtx.h.unchain_rtx(rtx) for rtx.val_head != nil { -fmt.Printf ("****** DEREGISER CLOSING VAL %p\n", rtx.val_head) +//fmt.Printf ("****** DEREGISER CLOSING VAL %p\n", rtx.val_head) rtx.val_head.Close() } @@ -437,7 +437,7 @@ func (rtx *Rtx) unchain_val(val *Val) { } else { val.next.prev = val.prev } -fmt.Printf("head %p tail %p\n", rtx.val_tail, rtx.val_tail) +//fmt.Printf("head %p tail %p\n", rtx.val_tail, rtx.val_tail) val.rtx = nil val.next = nil @@ -568,8 +568,10 @@ func (rtx *Rtx) NewArrVal(init_capa int) (*Val, error) { func (val *Val) Close() { if val.rtx != nil { - C.hawk_rtx_refdownval(val.rtx.c, val.c) + var rtx *C.hawk_rtx_t + rtx = val.rtx.c // store this field as unchain_val() resets it to nil val.rtx.unchain_val(val) + C.hawk_rtx_refdownval(rtx, val.c) } } @@ -654,26 +656,33 @@ func (val *Val) ArrayField(index int) (*Val, error) { return val.rtx.make_val(func() *C.hawk_val_t { return v }) } -func (val *Val) ArrayFirstField(itr *ValArrayItr) *Val { +func (val *Val) ArraySetField(index int, v *Val) error { + var vv *C.hawk_val_t + vv = C.hawk_rtx_setarrvalfld(val.rtx.c, val.c, C.hawk_ooi_t(index), v.c) + if vv == nil { return val.rtx.make_errinfo() } + return nil +} + +func (val *Val) ArrayFirstField(itr *ValArrayItr) (int, *Val) { var i *C.hawk_val_arr_itr_t var v *Val var err error i = C.hawk_rtx_getfirstarrvalitr(val.rtx.c, val.c, &itr.c) - if i == nil { return nil } + if i == nil { return -1, nil } v, err = val.rtx.make_val(func() *C.hawk_val_t { return itr.c.elem }) - if err != nil { return nil } - return v; + if err != nil { return -1, nil } + return int(itr.c.itr.idx), v; } -func (val *Val) ArrayNextField(itr *ValArrayItr) *Val { +func (val *Val) ArrayNextField(itr *ValArrayItr) (int, *Val) { var i *C.hawk_val_arr_itr_t var v *Val var err error i = C.hawk_rtx_getnextarrvalitr(val.rtx.c, val.c, &itr.c) - if i == nil { return nil } + if i == nil { return -1, nil } v, err = val.rtx.make_val(func() *C.hawk_val_t { return itr.c.elem }) - if err != nil { return nil } - return v; + if err != nil { return -1, nil } + return int(itr.c.itr.idx), v; } func (val *Val) MapField(key string) (*Val, error) { @@ -685,13 +694,41 @@ func (val *Val) MapField(key string) (*Val, error) { return val.rtx.make_val(func() *C.hawk_val_t { return v }) } -//func (val *Val) SetArrayField(index int, val *Val) error { -// -//} +func (val *Val) MapSetField(key string, v *Val) error { + var vv *C.hawk_val_t + var kk []C.hawk_uch_t -// TODO: map traversal.. -//func (val *Val) SetMapField(key string, val *Val) error { -//} + kk = string_to_uchars(key) + vv = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), v.c) + if vv == nil { return val.rtx.make_errinfo() } + return nil +} + +func (val *Val) MapFirstField(itr *ValMapItr) (string, *Val) { + var i *C.hawk_val_map_itr_t + var k string + var v *Val + var err error + i = C.hawk_rtx_getfirstmapvalitr(val.rtx.c, val.c, &itr.c) + if i == nil { return "", nil } + k = string(uchars_to_rune_slice((*C.hawk_uch_t)(itr.c.pair.key.ptr), uintptr(itr.c.pair.key.len))) + v, err = val.rtx.make_val(func() *C.hawk_val_t { return (*C.hawk_val_t)(itr.c.pair.val.ptr) }) + if err != nil { return "", nil } + return k, v; +} + +func (val *Val) MapNextField(itr *ValMapItr) (string, *Val) { + var i *C.hawk_val_map_itr_t + var k string + var v *Val + var err error + i = C.hawk_rtx_getnextmapvalitr(val.rtx.c, val.c, &itr.c) + if i == nil { return "", nil } + k = string(uchars_to_rune_slice((*C.hawk_uch_t)(itr.c.pair.key.ptr), uintptr(itr.c.pair.key.len))) + v, err = val.rtx.make_val(func() *C.hawk_val_t { return (*C.hawk_val_t)(itr.c.pair.val.ptr) }) + if err != nil { return "", nil } + return k, v; +} func (val *Val) String() string { var s string @@ -723,12 +760,6 @@ func (t ValType) String() string { // ----------------------------------------------------------- -func (itr *ValArrayItr) Index() int { - return int(itr.c.itr.idx) -} - -// ----------------------------------------------------------- - func ucstr_to_rune_slice(str *C.hawk_uch_t) []rune { return uchars_to_rune_slice(str, uintptr(C.hawk_count_ucstr(str))) } diff --git a/hawk_test.go b/hawk_test.go index e60e82d5..ad15168a 100644 --- a/hawk_test.go +++ b/hawk_test.go @@ -156,6 +156,9 @@ return x; t.Errorf("the returned value must be %s. but it was %s", hawk.VAL_MAP.String(), v.Type().String()) } else { var f *hawk.Val + var kk string + var vv *hawk.Val + var itr hawk.ValMapItr f = hawk.Must(v.MapField("hello")) if f.Type() != hawk.VAL_STR { @@ -172,6 +175,24 @@ return x; if err == nil { t.Errorf("the value at the HELLO field must not be found. but it was %s", f.Type().String()) } + + fmt.Printf("== DUMPING MAP ==\n") + kk, vv = v.MapFirstField(&itr) + for vv != nil { + fmt.Printf("key=[%s] value=[%v]\n", kk, vv.String()) + kk, vv = v.MapNextField(&itr) + } + + fmt.Printf("== CHANGING MAP ==\n") + v.MapSetField("666.666", hawk.Must(rtx.NewValFromFlt(66666.66666))) + v.MapSetField("hello", hawk.Must(rtx.NewValFromStr("all stars"))) + + fmt.Printf("== DUMPING MAP ==\n") + kk, vv = v.MapFirstField(&itr) + for vv != nil { + fmt.Printf("key=[%s] value=[%v]\n", kk, vv.String()) + kk, vv = v.MapNextField(&itr) + } } } @@ -194,7 +215,7 @@ return x; if f.Type() != hawk.VAL_STR { t.Errorf("the value at the hello field must be a string. but it was %s", f.Type().String()) } else { - //var i int + var i int var sv string var ff *hawk.Val var itr hawk.ValArrayItr @@ -209,10 +230,14 @@ return x; fmt.Printf("%d %v\n", i, hawk.Must(v.ArrayField(i))) } */ - ff = v.ArrayFirstField(&itr) + fmt.Printf("== CHANGING ARRAY ==\n") + v.ArraySetField(88, hawk.Must(rtx.NewValFromStr("eighty eight"))) + v.ArraySetField(77, hawk.Must(rtx.NewValFromStr("seventy seventy"))) + fmt.Printf("== DUMPING ARRAY ==\n") + i, ff = v.ArrayFirstField(&itr) for ff != nil { - fmt.Printf("%d [%v]\n", itr.Index(), ff.String()) - ff = v.ArrayNextField(&itr) + fmt.Printf("index=[%d] value=[%v]\n", i, ff.String()) + i, ff = v.ArrayNextField(&itr) } } } diff --git a/lib/arr.c b/lib/arr.c index 9eb3d986..659a2068 100644 --- a/lib/arr.c +++ b/lib/arr.c @@ -258,7 +258,7 @@ hawk_oow_t hawk_arr_search (hawk_arr_t* arr, hawk_oow_t pos, const void* dptr, h if (arr->style->comper(arr, DPTR(arr->slot[i]), DLEN(arr->slot[i]), dptr, dlen) == 0) return i; } - hawk_gem_seterrnum (arr->gem, HAWK_NULL, HAWK_ENOENT); + hawk_gem_seterrnum(arr->gem, HAWK_NULL, HAWK_ENOENT); return HAWK_ARR_NIL; } @@ -277,7 +277,7 @@ hawk_oow_t hawk_arr_rsearch (hawk_arr_t* arr, hawk_oow_t pos, const void* dptr, } } - hawk_gem_seterrnum (arr->gem, HAWK_NULL, HAWK_ENOENT); + hawk_gem_seterrnum(arr->gem, HAWK_NULL, HAWK_ENOENT); return HAWK_ARR_NIL; } @@ -321,7 +321,6 @@ hawk_oow_t hawk_arr_insert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo { hawk_oow_t bound = (pos >= arr->size)? pos: arr->size; capa = HAWK_ALIGN_POW2(bound + 1, 64); - do { capa = arr->capa * 2; } while (capa <= bound); } } @@ -345,7 +344,7 @@ hawk_oow_t hawk_arr_insert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo /* the buffer is not still enough after resizing */ if (arr->style->freeer) arr->style->freeer(arr, DPTR(slot), DLEN(slot)); hawk_gem_freemem(arr->gem, slot); - hawk_gem_seterrnum (arr->gem, HAWK_NULL, HAWK_EBUFFULL); + hawk_gem_seterrnum(arr->gem, HAWK_NULL, HAWK_EBUFFULL); return HAWK_ARR_NIL; } } @@ -372,7 +371,7 @@ hawk_oow_t hawk_arr_update (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo if (pos >= arr->size) { - hawk_gem_seterrnum (arr->gem, HAWK_NULL, HAWK_EINVAL); + hawk_gem_seterrnum(arr->gem, HAWK_NULL, HAWK_EINVAL); return HAWK_ARR_NIL; } diff --git a/lib/htb.c b/lib/htb.c index acfcf9f5..70470738 100644 --- a/lib/htb.c +++ b/lib/htb.c @@ -74,14 +74,14 @@ HAWK_INLINE pair_t* hawk_htb_allocpair (hawk_htb_t* htb, void* kptr, hawk_oow_t KPTR(n) = n + 1; /* if kptr is HAWK_NULL, the inline copier does not fill * the actual key area */ - if (kptr) HAWK_MEMCPY (KPTR(n), kptr, KTOB(htb,klen)); + if (kptr) HAWK_MEMCPY(KPTR(n), kptr, KTOB(htb,klen)); } else { KPTR(n) = kcop(htb, kptr, klen); if (KPTR(n) == HAWK_NULL) { - hawk_gem_freemem (htb->gem, n); + hawk_gem_freemem(htb->gem, n); return HAWK_NULL; } } @@ -98,16 +98,16 @@ HAWK_INLINE pair_t* hawk_htb_allocpair (hawk_htb_t* htb, void* kptr, hawk_oow_t VPTR(n) = (hawk_uint8_t*)VPTR(n) + HAWK_ALIGN_POW2(KTOB(htb,klen), HAWK_SIZEOF_VOID_P); /* if vptr is HAWK_NULL, the inline copier does not fill * the actual value area */ - if (vptr) HAWK_MEMCPY (VPTR(n), vptr, VTOB(htb,vlen)); + if (vptr) HAWK_MEMCPY(VPTR(n), vptr, VTOB(htb,vlen)); } else { - VPTR(n) = vcop (htb, vptr, vlen); + VPTR(n) = vcop(htb, vptr, vlen); if (VPTR(n) != HAWK_NULL) { if (htb->style->freeer[HAWK_HTB_KEY] != HAWK_NULL) - htb->style->freeer[HAWK_HTB_KEY] (htb, KPTR(n), KLEN(n)); - hawk_gem_freemem (htb->gem, n); + htb->style->freeer[HAWK_HTB_KEY](htb, KPTR(n), KLEN(n)); + hawk_gem_freemem(htb->gem, n); return HAWK_NULL; } } @@ -118,10 +118,10 @@ HAWK_INLINE pair_t* hawk_htb_allocpair (hawk_htb_t* htb, void* kptr, hawk_oow_t HAWK_INLINE void hawk_htb_freepair (hawk_htb_t* htb, pair_t* pair) { if (htb->style->freeer[HAWK_HTB_KEY] != HAWK_NULL) - htb->style->freeer[HAWK_HTB_KEY] (htb, KPTR(pair), KLEN(pair)); + htb->style->freeer[HAWK_HTB_KEY](htb, KPTR(pair), KLEN(pair)); if (htb->style->freeer[HAWK_HTB_VAL] != HAWK_NULL) - htb->style->freeer[HAWK_HTB_VAL] (htb, VPTR(pair), VLEN(pair)); - hawk_gem_freemem (htb->gem, pair); + htb->style->freeer[HAWK_HTB_VAL](htb, VPTR(pair), VLEN(pair)); + hawk_gem_freemem(htb->gem, pair); } static HAWK_INLINE pair_t* change_pair_val (hawk_htb_t* htb, pair_t* pair, void* vptr, hawk_oow_t vlen) @@ -133,7 +133,7 @@ static HAWK_INLINE pair_t* change_pair_val (hawk_htb_t* htb, pair_t* pair, void* * No value replacement occurs. */ if (htb->style->keeper != HAWK_NULL) { - htb->style->keeper (htb, vptr, vlen); + htb->style->keeper(htb, vptr, vlen); } } else @@ -152,14 +152,14 @@ static HAWK_INLINE pair_t* change_pair_val (hawk_htb_t* htb, pair_t* pair, void* { if (ovlen == vlen) { - if (vptr) HAWK_MEMCPY (VPTR(pair), vptr, VTOB(htb,vlen)); + if (vptr) HAWK_MEMCPY(VPTR(pair), vptr, VTOB(htb,vlen)); } else { /* need to reconstruct the pair */ pair_t* p = hawk_htb_allocpair(htb, KPTR(pair), KLEN(pair), vptr, vlen); if (HAWK_UNLIKELY(!p)) return HAWK_NULL; - hawk_htb_freepair (htb, pair); + hawk_htb_freepair(htb, pair); return p; } } @@ -174,7 +174,7 @@ static HAWK_INLINE pair_t* change_pair_val (hawk_htb_t* htb, pair_t* pair, void* /* free up the old value */ if (htb->style->freeer[HAWK_HTB_VAL] != HAWK_NULL) { - htb->style->freeer[HAWK_HTB_VAL] (htb, ovptr, ovlen); + htb->style->freeer[HAWK_HTB_VAL](htb, ovptr, ovlen); } } @@ -262,18 +262,18 @@ hawk_htb_t* hawk_htb_open (hawk_gem_t* gem, hawk_oow_t xtnsize, hawk_oow_t capa, if (hawk_htb_init(htb, gem, capa, factor, kscale, vscale) <= -1) { - hawk_gem_freemem (gem, htb); + hawk_gem_freemem(gem, htb); return HAWK_NULL; } - HAWK_MEMSET (htb + 1, 0, xtnsize); + HAWK_MEMSET(htb + 1, 0, xtnsize); return htb; } void hawk_htb_close (hawk_htb_t* htb) { hawk_htb_fini (htb); - hawk_gem_freemem (htb->gem, htb); + hawk_gem_freemem(htb->gem, htb); } int hawk_htb_init (hawk_htb_t* htb, hawk_gem_t* gem, hawk_oow_t capa, int factor, int kscale, int vscale) @@ -294,14 +294,14 @@ int hawk_htb_init (hawk_htb_t* htb, hawk_gem_t* gem, hawk_oow_t capa, int factor if (factor > 100) factor = 100; /* do not zero out the extension */ - HAWK_MEMSET (htb, 0, HAWK_SIZEOF(*htb)); + HAWK_MEMSET(htb, 0, HAWK_SIZEOF(*htb)); htb->gem = gem; htb->bucket = hawk_gem_allocmem(gem, capa * HAWK_SIZEOF(pair_t*)); if (HAWK_UNLIKELY(!htb->bucket)) return -1; /*for (i = 0; i < capa; i++) htb->bucket[i] = HAWK_NULL;*/ - HAWK_MEMSET (htb->bucket, 0, capa * HAWK_SIZEOF(pair_t*)); + HAWK_MEMSET(htb->bucket, 0, capa * HAWK_SIZEOF(pair_t*)); htb->factor = factor; htb->scale[HAWK_HTB_KEY] = (kscale < 1)? 1: kscale; @@ -318,8 +318,8 @@ int hawk_htb_init (hawk_htb_t* htb, hawk_gem_t* gem, hawk_oow_t capa, int factor void hawk_htb_fini (hawk_htb_t* htb) { - hawk_htb_clear (htb); - hawk_gem_freemem (htb->gem, htb->bucket); + hawk_htb_clear(htb); + hawk_gem_freemem(htb->gem, htb->bucket); } const style_t* hawk_htb_getstyle (const hawk_htb_t* htb) @@ -361,7 +361,7 @@ pair_t* hawk_htb_search (const hawk_htb_t* htb, const void* kptr, hawk_oow_t kle pair = NEXT(pair); } - hawk_gem_seterrnum (htb->gem, HAWK_NULL, HAWK_ENOENT); + hawk_gem_seterrnum(htb->gem, HAWK_NULL, HAWK_ENOENT); return HAWK_NULL; } @@ -372,7 +372,7 @@ static HAWK_INLINE int reorganize (hawk_htb_t* htb) if (htb->style->sizer) { - new_capa = htb->style->sizer (htb, htb->capa + 1); + new_capa = htb->style->sizer(htb, htb->capa + 1); /* if no change in capacity, return success * without reorganization */ @@ -397,7 +397,7 @@ static HAWK_INLINE int reorganize (hawk_htb_t* htb) } /*for (i = 0; i < new_capa; i++) new_buck[i] = HAWK_NULL;*/ - HAWK_MEMSET (new_buck, 0, new_capa * HAWK_SIZEOF(pair_t*)); + HAWK_MEMSET(new_buck, 0, new_capa * HAWK_SIZEOF(pair_t*)); for (i = 0; i < htb->capa; i++) { @@ -416,7 +416,7 @@ static HAWK_INLINE int reorganize (hawk_htb_t* htb) } } - hawk_gem_freemem (htb->gem, htb->bucket); + hawk_gem_freemem(htb->gem, htb->bucket); htb->bucket = new_buck; htb->capa = new_capa; htb->threshold = htb->capa * htb->factor / 100; @@ -443,14 +443,14 @@ static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, { next = NEXT(pair); - if (htb->style->comper (htb, KPTR(pair), KLEN(pair), kptr, klen) == 0) + if (htb->style->comper(htb, KPTR(pair), KLEN(pair), kptr, klen) == 0) { /* found a pair with a matching key */ switch (opt) { case UPSERT: case UPDATE: - p = change_pair_val (htb, pair, vptr, vlen); + p = change_pair_val(htb, pair, vptr, vlen); if (p == HAWK_NULL) { /* error in changing the value */ @@ -473,7 +473,7 @@ static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, case INSERT: /* return failure */ - hawk_gem_seterrnum (htb->gem, HAWK_NULL, HAWK_EEXIST); + hawk_gem_seterrnum(htb->gem, HAWK_NULL, HAWK_EEXIST); return HAWK_NULL; } } @@ -484,7 +484,7 @@ static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, if (opt == UPDATE) { - hawk_gem_seterrnum (htb->gem, HAWK_NULL, HAWK_ENOENT); + hawk_gem_seterrnum(htb->gem, HAWK_NULL, HAWK_ENOENT); return HAWK_NULL; } @@ -500,7 +500,7 @@ static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, HAWK_ASSERT (pair == HAWK_NULL); - pair = hawk_htb_allocpair (htb, kptr, klen, vptr, vlen); + pair = hawk_htb_allocpair(htb, kptr, klen, vptr, vlen); if (HAWK_UNLIKELY(!pair)) return HAWK_NULL; /* error */ NEXT(pair) = htb->bucket[hc]; @@ -512,23 +512,23 @@ static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, pair_t* hawk_htb_upsert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen) { - return insert (htb, kptr, klen, vptr, vlen, UPSERT); + return insert(htb, kptr, klen, vptr, vlen, UPSERT); } pair_t* hawk_htb_ensert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen) { - return insert (htb, kptr, klen, vptr, vlen, ENSERT); + return insert(htb, kptr, klen, vptr, vlen, ENSERT); } pair_t* hawk_htb_insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen) { - return insert (htb, kptr, klen, vptr, vlen, INSERT); + return insert(htb, kptr, klen, vptr, vlen, INSERT); } pair_t* hawk_htb_update (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen) { - return insert (htb, kptr, klen, vptr, vlen, UPDATE); + return insert(htb, kptr, klen, vptr, vlen, UPDATE); } pair_t* hawk_htb_cbsert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, cbserter_t cbserter, void* ctx) @@ -608,7 +608,7 @@ int hawk_htb_delete (hawk_htb_t* htb, const void* kptr, hawk_oow_t klen) htb->bucket[hc] = NEXT(pair); else NEXT(prev) = NEXT(pair); - hawk_htb_freepair (htb, pair); + hawk_htb_freepair(htb, pair); htb->size--; return 0; @@ -618,7 +618,7 @@ int hawk_htb_delete (hawk_htb_t* htb, const void* kptr, hawk_oow_t klen) pair = NEXT(pair); } - hawk_gem_seterrnum (htb->gem, HAWK_NULL, HAWK_ENOENT); + hawk_gem_seterrnum(htb->gem, HAWK_NULL, HAWK_ENOENT); return -1; } @@ -634,7 +634,7 @@ void hawk_htb_clear (hawk_htb_t* htb) while (pair != HAWK_NULL) { next = NEXT(pair); - hawk_htb_freepair (htb, pair); + hawk_htb_freepair(htb, pair); htb->size--; pair = next; } @@ -717,13 +717,13 @@ pair_t* hawk_htb_getnextpair (hawk_htb_t* htb, hawk_htb_itr_t* itr) hawk_oow_t hawk_htb_dflhash (const hawk_htb_t* htb, const void* kptr, hawk_oow_t klen) { hawk_oow_t h; - HAWK_HASH_BYTES (h, kptr, klen); + HAWK_HASH_BYTES(h, kptr, klen); return h ; } int hawk_htb_dflcomp (const hawk_htb_t* htb, const void* kptr1, hawk_oow_t klen1, const void* kptr2, hawk_oow_t klen2) { - if (klen1 == klen2) return HAWK_MEMCMP (kptr1, kptr2, KTOB(htb,klen1)); + if (klen1 == klen2) return HAWK_MEMCMP(kptr1, kptr2, KTOB(htb,klen1)); /* it just returns 1 to indicate that they are different. */ return 1; } diff --git a/lib/parse.c b/lib/parse.c index 63aa2a91..17b1ce64 100644 --- a/lib/parse.c +++ b/lib/parse.c @@ -173,6 +173,10 @@ enum tok_t TOK_MBS, TOK_REX, TOK_XNIL, +#if 0 + TOK_HAWK_ARRAY, + TOK_HAWK_MAP, +#endif __TOKEN_COUNT__ }; @@ -953,7 +957,7 @@ static int parse_progunit (hawk_t* hawk) int once; if (hawk->opt.depth.s.incl > 0 && - hawk->parse.depth.incl >= hawk->opt.depth.s.incl) + hawk->parse.depth.incl >= hawk->opt.depth.s.incl) { hawk_seterrnum(hawk, &hawk->ptok.loc, HAWK_EINCLTD); return -1; @@ -5779,7 +5783,7 @@ oops: } #if defined(HAWK_ENABLE_FUN_AS_VALUE) -static hawk_nde_t* parse_fun_as_value (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc, hawk_fun_t* funptr) +static hawk_nde_t* parse_fun_as_value (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc, hawk_fun_t* funptr) { hawk_nde_fun_t* nde; @@ -7117,15 +7121,26 @@ retry: GET_CHAR_TO(hawk, c); - if (c != HAWK_T('_') && !hawk_is_ooch_alpha(c)) +#if 0 + if (c == '[' || c == '{') /* syntatic sugar for array/map composition */ + { + int tt; + ADD_TOKEN_CHAR(hawk, tok, '@'); + ADD_TOKEN_CHAR(hawk, tok, c); + tt = (c == '['? TOK_HAWK_ARRAY: TOK_HAWK_MAP); + SET_TOKEN_TYPE(hawk, tok, tt); + GET_CHAR(hawk); + } + else +#endif + if (c != '_' && !hawk_is_ooch_alpha(c)) { /* this extended keyword is empty, * not followed by a valid word */ hawk_seterrnum(hawk, &(hawk)->tok.loc, HAWK_EXKWEM); return -1; } - - if (c == 'B' || c == 'b') + else if (c == 'B' || c == 'b') { hawk_sio_lxc_t pc1 = hawk->sio.last; GET_CHAR_TO(hawk, c); diff --git a/lib/rbt.c b/lib/rbt.c index 11b16769..f89640e3 100644 --- a/lib/rbt.c +++ b/lib/rbt.c @@ -81,14 +81,14 @@ HAWK_INLINE hawk_rbt_pair_t* hawk_rbt_allocpair ( else if (kcop == HAWK_RBT_COPIER_INLINE) { KPTR(pair) = pair + 1; - if (kptr) HAWK_MEMCPY (KPTR(pair), kptr, KTOB(rbt,klen)); + if (kptr) HAWK_MEMCPY(KPTR(pair), kptr, KTOB(rbt,klen)); } else { KPTR(pair) = kcop(rbt, kptr, klen); if (KPTR(pair) == HAWK_NULL) { - hawk_gem_freemem (rbt->gem, pair); + hawk_gem_freemem(rbt->gem, pair); return HAWK_NULL; } } @@ -103,7 +103,7 @@ HAWK_INLINE hawk_rbt_pair_t* hawk_rbt_allocpair ( VPTR(pair) = pair + 1; if (kcop == HAWK_RBT_COPIER_INLINE) VPTR(pair) = (hawk_oob_t*)VPTR(pair) + HAWK_ALIGN_POW2(KTOB(rbt,klen), HAWK_SIZEOF_VOID_P); - if (vptr) HAWK_MEMCPY (VPTR(pair), vptr, VTOB(rbt,vlen)); + if (vptr) HAWK_MEMCPY(VPTR(pair), vptr, VTOB(rbt,vlen)); } else { @@ -111,8 +111,8 @@ HAWK_INLINE hawk_rbt_pair_t* hawk_rbt_allocpair ( if (VPTR(pair) != HAWK_NULL) { if (rbt->style->freeer[HAWK_RBT_KEY]) - rbt->style->freeer[HAWK_RBT_KEY] (rbt, KPTR(pair), KLEN(pair)); - hawk_gem_freemem (rbt->gem, pair); + rbt->style->freeer[HAWK_RBT_KEY](rbt, KPTR(pair), KLEN(pair)); + hawk_gem_freemem(rbt->gem, pair); return HAWK_NULL; } } @@ -123,10 +123,10 @@ HAWK_INLINE hawk_rbt_pair_t* hawk_rbt_allocpair ( HAWK_INLINE void hawk_rbt_freepair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair) { if (rbt->style->freeer[HAWK_RBT_KEY]) - rbt->style->freeer[HAWK_RBT_KEY] (rbt, KPTR(pair), KLEN(pair)); + rbt->style->freeer[HAWK_RBT_KEY](rbt, KPTR(pair), KLEN(pair)); if (rbt->style->freeer[HAWK_RBT_VAL]) - rbt->style->freeer[HAWK_RBT_VAL] (rbt, VPTR(pair), VLEN(pair)); - hawk_gem_freemem (rbt->gem, pair); + rbt->style->freeer[HAWK_RBT_VAL](rbt, VPTR(pair), VLEN(pair)); + hawk_gem_freemem(rbt->gem, pair); } static hawk_rbt_style_t style[] = @@ -198,24 +198,24 @@ hawk_rbt_t* hawk_rbt_open (hawk_gem_t* gem, hawk_oow_t xtnsize, int kscale, int if (HAWK_UNLIKELY(hawk_rbt_init(rbt, gem, kscale, vscale) <= -1)) { - hawk_gem_freemem (gem, rbt); + hawk_gem_freemem(gem, rbt); return HAWK_NULL; } - HAWK_MEMSET (rbt + 1, 0, xtnsize); + HAWK_MEMSET(rbt + 1, 0, xtnsize); return rbt; } void hawk_rbt_close (hawk_rbt_t* rbt) { hawk_rbt_fini (rbt); - hawk_gem_freemem (rbt->gem, rbt); + hawk_gem_freemem(rbt->gem, rbt); } int hawk_rbt_init (hawk_rbt_t* rbt, hawk_gem_t* gem, int kscale, int vscale) { /* do not zero out the extension */ - HAWK_MEMSET (rbt, 0, HAWK_SIZEOF(*rbt)); + HAWK_MEMSET(rbt, 0, HAWK_SIZEOF(*rbt)); rbt->gem = gem; rbt->scale[HAWK_RBT_KEY] = (kscale < 1)? 1: kscale; @@ -243,7 +243,7 @@ int hawk_rbt_init (hawk_rbt_t* rbt, hawk_gem_t* gem, int kscale, int vscale) void hawk_rbt_fini (hawk_rbt_t* rbt) { - hawk_rbt_clear (rbt); + hawk_rbt_clear(rbt); } const hawk_rbt_style_t* hawk_rbt_getstyle (const hawk_rbt_t* rbt) @@ -400,13 +400,13 @@ static void adjust (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair) if (pair == tmp2) { pair = x_par; - rotate (rbt, pair, leftwise); + rotate(rbt, pair, leftwise); x_par = pair->parent; } x_par->color = HAWK_RBT_BLACK; x_par->parent->color = HAWK_RBT_RED; - rotate (rbt, x_par->parent, !leftwise); + rotate(rbt, x_par->parent, !leftwise); } } } @@ -420,7 +420,7 @@ static hawk_rbt_pair_t* change_pair_val (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, * No value replacement occurs. */ if (rbt->style->keeper != HAWK_NULL) { - rbt->style->keeper (rbt, vptr, vlen); + rbt->style->keeper(rbt, vptr, vlen); } } else @@ -439,7 +439,7 @@ static hawk_rbt_pair_t* change_pair_val (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, { if (ovlen == vlen) { - if (vptr) HAWK_MEMCPY (VPTR(pair), vptr, VTOB(rbt,vlen)); + if (vptr) HAWK_MEMCPY(VPTR(pair), vptr, VTOB(rbt,vlen)); } else { @@ -469,7 +469,7 @@ static hawk_rbt_pair_t* change_pair_val (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, if (pair == rbt->root) rbt->root = p; - hawk_rbt_freepair (rbt, pair); + hawk_rbt_freepair(rbt, pair); return p; } } @@ -484,7 +484,7 @@ static hawk_rbt_pair_t* change_pair_val (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, /* free up the old value */ if (rbt->style->freeer[HAWK_RBT_VAL]) { - rbt->style->freeer[HAWK_RBT_VAL] (rbt, ovptr, ovlen); + rbt->style->freeer[HAWK_RBT_VAL](rbt, ovptr, ovlen); } } @@ -556,7 +556,7 @@ static hawk_rbt_pair_t* insert (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, vo } x_new->parent = x_par; - adjust (rbt, x_new); + adjust(rbt, x_new); } rbt->root->color = HAWK_RBT_BLACK; @@ -566,23 +566,23 @@ static hawk_rbt_pair_t* insert (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, vo hawk_rbt_pair_t* hawk_rbt_upsert (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen) { - return insert (rbt, kptr, klen, vptr, vlen, UPSERT); + return insert(rbt, kptr, klen, vptr, vlen, UPSERT); } hawk_rbt_pair_t* hawk_rbt_ensert (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen) { - return insert (rbt, kptr, klen, vptr, vlen, ENSERT); + return insert(rbt, kptr, klen, vptr, vlen, ENSERT); } hawk_rbt_pair_t* hawk_rbt_insert (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen) { - return insert (rbt, kptr, klen, vptr, vlen, INSERT); + return insert(rbt, kptr, klen, vptr, vlen, INSERT); } hawk_rbt_pair_t* hawk_rbt_update (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, void* vptr, hawk_oow_t vlen) { - return insert (rbt, kptr, klen, vptr, vlen, UPDATE); + return insert(rbt, kptr, klen, vptr, vlen, UPDATE); } hawk_rbt_pair_t* hawk_rbt_cbsert (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, cbserter_t cbserter, void* ctx) @@ -673,7 +673,7 @@ hawk_rbt_pair_t* hawk_rbt_cbsert (hawk_rbt_t* rbt, void* kptr, hawk_oow_t klen, } x_new->parent = x_par; - adjust (rbt, x_new); + adjust(rbt, x_new); } rbt->root->color = HAWK_RBT_BLACK; @@ -695,7 +695,7 @@ static void adjust_for_delete (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, hawk_rbt_ { tmp->color = HAWK_RBT_BLACK; par->color = HAWK_RBT_RED; - rotate_left (rbt, par); + rotate_left(rbt, par); tmp = par->right; } @@ -713,7 +713,7 @@ static void adjust_for_delete (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, hawk_rbt_ if (!IS_NIL(rbt,tmp->left)) tmp->left->color = HAWK_RBT_BLACK; tmp->color = HAWK_RBT_RED; - rotate_right (rbt, tmp); + rotate_right(rbt, tmp); tmp = par->right; } @@ -722,7 +722,7 @@ static void adjust_for_delete (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, hawk_rbt_ if (tmp->right->color == HAWK_RBT_RED) tmp->right->color = HAWK_RBT_BLACK; - rotate_left (rbt, par); + rotate_left(rbt, par); pair = rbt->root; } } @@ -734,7 +734,7 @@ static void adjust_for_delete (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, hawk_rbt_ { tmp->color = HAWK_RBT_BLACK; par->color = HAWK_RBT_RED; - rotate_right (rbt, par); + rotate_right(rbt, par); tmp = par->left; } @@ -752,7 +752,7 @@ static void adjust_for_delete (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, hawk_rbt_ if (!IS_NIL(rbt,tmp->right)) tmp->right->color = HAWK_RBT_BLACK; tmp->color = HAWK_RBT_RED; - rotate_left (rbt, tmp); + rotate_left(rbt, tmp); tmp = par->left; } tmp->color = par->color; @@ -760,7 +760,7 @@ static void adjust_for_delete (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, hawk_rbt_ if (tmp->left->color == HAWK_RBT_RED) tmp->left->color = HAWK_RBT_BLACK; - rotate_right (rbt, par); + rotate_right(rbt, par); pair = rbt->root; } } @@ -806,14 +806,14 @@ static void delete_pair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair) if (y == pair) { if (y->color == HAWK_RBT_BLACK && !IS_NIL(rbt,x)) - adjust_for_delete (rbt, x, parent); + adjust_for_delete(rbt, x, parent); - hawk_rbt_freepair (rbt, y); + hawk_rbt_freepair(rbt, y); } else { if (y->color == HAWK_RBT_BLACK && !IS_NIL(rbt,x)) - adjust_for_delete (rbt, x, parent); + adjust_for_delete(rbt, x, parent); if (pair->parent) { @@ -833,7 +833,7 @@ static void delete_pair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair) if (pair->left->parent == pair) pair->left->parent = y; if (pair->right->parent == pair) pair->right->parent = y; - hawk_rbt_freepair (rbt, pair); + hawk_rbt_freepair(rbt, pair); } rbt->size--; @@ -853,10 +853,10 @@ static void delete_pair (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair) hawk_oow_t seqno = itr->_prot_seqno; /* TODO: this is slow. devise a way to get the next pair safely without traversal */ - hawk_rbt_getfirstpair (rbt, itr); + hawk_rbt_getfirstpair(rbt, itr); while (itr->pair && itr->_prot_seqno < seqno) { - hawk_rbt_getnextpair (rbt, itr); + hawk_rbt_getnextpair(rbt, itr); } itr->_prot_updated = 1; @@ -875,14 +875,14 @@ int hawk_rbt_delete (hawk_rbt_t* rbt, const void* kptr, hawk_oow_t klen) pair = hawk_rbt_search(rbt, kptr, klen); if (!pair) return -1; - delete_pair (rbt, pair); + delete_pair(rbt, pair); return 0; } void hawk_rbt_clear (hawk_rbt_t* rbt) { /* TODO: improve this */ - while (!IS_NIL(rbt,rbt->root)) delete_pair (rbt, rbt->root); + while (!IS_NIL(rbt,rbt->root)) delete_pair(rbt, rbt->root); } #if 0 @@ -891,15 +891,15 @@ static HAWK_INLINE hawk_rbt_walk_t walk_recursively ( { if (!IS_NIL(rbt,pair->left)) { - if (walk_recursively (rbt, walker, ctx, pair->left) == HAWK_RBT_WALK_STOP) + if (walk_recursively(rbt, walker, ctx, pair->left) == HAWK_RBT_WALK_STOP) return HAWK_RBT_WALK_STOP; } - if (walker (rbt, pair, ctx) == HAWK_RBT_WALK_STOP) return HAWK_RBT_WALK_STOP; + if (walker(rbt, pair, ctx) == HAWK_RBT_WALK_STOP) return HAWK_RBT_WALK_STOP; if (!IS_NIL(rbt,pair->right)) { - if (walk_recursively (rbt, walker, ctx, pair->right) == HAWK_RBT_WALK_STOP) + if (walk_recursively(rbt, walker, ctx, pair->right) == HAWK_RBT_WALK_STOP) return HAWK_RBT_WALK_STOP; } diff --git a/lib/run.c b/lib/run.c index ccf82137..c731409f 100644 --- a/lib/run.c +++ b/lib/run.c @@ -3292,9 +3292,9 @@ static HAWK_INLINE int delete_indexed (hawk_rtx_t* rtx, hawk_val_t* vv, hawk_nde #endif if (vtype == HAWK_VAL_MAP) - hawk_map_delete (map, str, len); + hawk_map_delete(map, str, len); else - hawk_arr_uplete (arr, idx, 1); /* no reindexing by compaction. keep the place unset */ + hawk_arr_uplete(arr, idx, 1); /* no reindexing by compaction. keep the place unset */ if (str && str != idxbuf) hawk_rtx_freemem(rtx, str); return 0; @@ -3340,7 +3340,7 @@ static int run_delete (hawk_rtx_t* rtx, hawk_nde_delete_t* nde) print typename(a), length(a); } */ - hawk_map_clear (((hawk_val_map_t*)val)->map); + hawk_map_clear(((hawk_val_map_t*)val)->map); } break; @@ -3352,7 +3352,7 @@ static int run_delete (hawk_rtx_t* rtx, hawk_nde_delete_t* nde) } else { - hawk_arr_clear (((hawk_val_arr_t*)val)->arr); + hawk_arr_clear(((hawk_val_arr_t*)val)->arr); } break; diff --git a/t/h-001.hawk b/t/h-001.hawk index d9fded71..1357aae3 100644 --- a/t/h-001.hawk +++ b/t/h-001.hawk @@ -193,24 +193,26 @@ function main() a[10] = "good"; a[0][40] = "bye" a[0][0] = "farewell" - tap_ensure (hawk::typename(a), "array", @SCRIPTNAME, @SCRIPTLINE); - tap_ensure (hawk::typename(a[0]), "array", @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(hawk::typename(a), "array", @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(hawk::typename(a[0]), "array", @SCRIPTNAME, @SCRIPTLINE); call_by_ref_3(a[9]); - tap_ensure (a[10], "good", @SCRIPTNAME, @SCRIPTLINE); - tap_ensure (a[9], "hello world", @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(a[10], "good", @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(a[9], "hello world", @SCRIPTNAME, @SCRIPTLINE); call_by_ref_3(a[10]); - tap_ensure (a[10], "hello world", @SCRIPTNAME, @SCRIPTLINE); - tap_ensure (a[9], "hello world", @SCRIPTNAME, @SCRIPTLINE); - tap_ensure (a[0][40], "bye", @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(a[10], "hello world", @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(a[9], "hello world", @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(a[0][40], "bye", @SCRIPTNAME, @SCRIPTLINE); call_by_ref_3(a[0][40]); - tap_ensure (a[0][40], "hello world", @SCRIPTNAME, @SCRIPTLINE); - tap_ensure (length(a[0]), 2, @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(a[0][40], "hello world", @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(length(a[0]), 2, @SCRIPTNAME, @SCRIPTLINE); delete a[0][40]; - tap_ensure (length(a[0]), 1, @SCRIPTNAME, @SCRIPTLINE); - tap_ensure (a[0][0], "farewell", @SCRIPTNAME, @SCRIPTLINE); - tap_ensure (a[0][40], nil, @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(length(a[0]), 1, @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(a[0][0], "farewell", @SCRIPTNAME, @SCRIPTLINE); + tap_ensure(a[0][40], nil, @SCRIPTNAME, @SCRIPTLINE); #hawk::splice (a[0], 40, 1, @SCRIPTNAME, @SCRIPTLINE); - #tap_ensure (length(a[0]), 40, @SCRIPTNAME, @SCRIPTLINE); + #tap_ensure(length(a[0]), 40, @SCRIPTNAME, @SCRIPTLINE); + a[199] = 9999; + tap_ensure(a[199], 9999, @SCRIPTNAME, @SCRIPTLINE); }