fixed a critical bug in resizing an array - damn residual code
improved array/map field set/iteration functions
This commit is contained in:
12
README.md
12
README.md
@@ -960,6 +960,18 @@ BEGIN {
|
|||||||
END { close("cat"); print "ENDED"; }
|
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
|
## Garbage Collection
|
||||||
|
|
||||||
The primary value management is reference counting based but `map` and `array` values are garbage-collected additionally.
|
The primary value management is reference counting based but `map` and `array` values are garbage-collected additionally.
|
||||||
|
|||||||
93
hawk.go
93
hawk.go
@@ -108,30 +108,30 @@ type ValArrayItr struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ValMapItr struct {
|
type ValMapItr struct {
|
||||||
c *C.hawk_val_map_itr_t
|
c C.hawk_val_map_itr_t
|
||||||
}
|
}
|
||||||
|
|
||||||
type BitMask C.hawk_bitmask_t
|
type BitMask C.hawk_bitmask_t
|
||||||
|
|
||||||
func deregister_instance(h *Hawk) {
|
func deregister_instance(h *Hawk) {
|
||||||
fmt.Printf ("DEREGISER INSTANCE %p\n", h)
|
//fmt.Printf ("DEREGISER INSTANCE %p\n", h)
|
||||||
for h.rtx_head != nil {
|
for h.rtx_head != nil {
|
||||||
//fmt.Printf ("DEREGISER CLOSING RTX %p\n", h.rtx_head)
|
//fmt.Printf ("DEREGISER CLOSING RTX %p\n", h.rtx_head)
|
||||||
h.rtx_head.Close()
|
h.rtx_head.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.c != nil {
|
if h.c != nil {
|
||||||
fmt.Printf ("CLOSING h.c\n")
|
//fmt.Printf ("CLOSING h.c\n")
|
||||||
C.hawk_close(h.c)
|
C.hawk_close(h.c)
|
||||||
h.c = nil
|
h.c = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.inst_no >= 0 {
|
if h.inst_no >= 0 {
|
||||||
fmt.Printf ("DELETING instance h\n")
|
//fmt.Printf ("DELETING instance h\n")
|
||||||
inst_table.delete_instance(h.inst_no)
|
inst_table.delete_instance(h.inst_no)
|
||||||
h.inst_no = -1
|
h.inst_no = -1
|
||||||
}
|
}
|
||||||
fmt.Printf ("END DEREGISER INSTANCE %p\n", h)
|
//fmt.Printf ("END DEREGISER INSTANCE %p\n", h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() (*Hawk, error) {
|
func New() (*Hawk, error) {
|
||||||
@@ -294,7 +294,7 @@ func (hawk *Hawk) chain_rtx(rtx *Rtx) {
|
|||||||
rtx.next = nil
|
rtx.next = nil
|
||||||
hawk.rtx_tail = rtx
|
hawk.rtx_tail = rtx
|
||||||
hawk.rtx_count++
|
hawk.rtx_count++
|
||||||
fmt.Printf(">>>> %d\n", hawk.rtx_count)
|
//fmt.Printf(">>>> %d\n", hawk.rtx_count)
|
||||||
hawk.rtx_mtx.Unlock()
|
hawk.rtx_mtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,13 +311,13 @@ func (hawk *Hawk) unchain_rtx(rtx *Rtx) {
|
|||||||
} else {
|
} else {
|
||||||
rtx.next.prev = rtx.prev
|
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.h = nil
|
||||||
rtx.next = nil
|
rtx.next = nil
|
||||||
rtx.prev = nil
|
rtx.prev = nil
|
||||||
hawk.rtx_count--
|
hawk.rtx_count--
|
||||||
fmt.Printf(">>>> %d\n", hawk.rtx_count)
|
//fmt.Printf(">>>> %d\n", hawk.rtx_count)
|
||||||
hawk.rtx_mtx.Unlock()
|
hawk.rtx_mtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ func (rtx* Rtx) Close() {
|
|||||||
rtx.h.unchain_rtx(rtx)
|
rtx.h.unchain_rtx(rtx)
|
||||||
|
|
||||||
for rtx.val_head != nil {
|
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()
|
rtx.val_head.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,7 +437,7 @@ func (rtx *Rtx) unchain_val(val *Val) {
|
|||||||
} else {
|
} else {
|
||||||
val.next.prev = val.prev
|
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.rtx = nil
|
||||||
val.next = nil
|
val.next = nil
|
||||||
@@ -568,8 +568,10 @@ func (rtx *Rtx) NewArrVal(init_capa int) (*Val, error) {
|
|||||||
|
|
||||||
func (val *Val) Close() {
|
func (val *Val) Close() {
|
||||||
if val.rtx != nil {
|
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)
|
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 })
|
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 i *C.hawk_val_arr_itr_t
|
||||||
var v *Val
|
var v *Val
|
||||||
var err error
|
var err error
|
||||||
i = C.hawk_rtx_getfirstarrvalitr(val.rtx.c, val.c, &itr.c)
|
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 })
|
v, err = val.rtx.make_val(func() *C.hawk_val_t { return itr.c.elem })
|
||||||
if err != nil { return nil }
|
if err != nil { return -1, nil }
|
||||||
return v;
|
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 i *C.hawk_val_arr_itr_t
|
||||||
var v *Val
|
var v *Val
|
||||||
var err error
|
var err error
|
||||||
i = C.hawk_rtx_getnextarrvalitr(val.rtx.c, val.c, &itr.c)
|
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 })
|
v, err = val.rtx.make_val(func() *C.hawk_val_t { return itr.c.elem })
|
||||||
if err != nil { return nil }
|
if err != nil { return -1, nil }
|
||||||
return v;
|
return int(itr.c.itr.idx), v;
|
||||||
}
|
}
|
||||||
|
|
||||||
func (val *Val) MapField(key string) (*Val, error) {
|
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 })
|
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..
|
kk = string_to_uchars(key)
|
||||||
//func (val *Val) SetMapField(key string, val *Val) error {
|
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 {
|
func (val *Val) String() string {
|
||||||
var s 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 {
|
func ucstr_to_rune_slice(str *C.hawk_uch_t) []rune {
|
||||||
return uchars_to_rune_slice(str, uintptr(C.hawk_count_ucstr(str)))
|
return uchars_to_rune_slice(str, uintptr(C.hawk_count_ucstr(str)))
|
||||||
}
|
}
|
||||||
|
|||||||
33
hawk_test.go
33
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())
|
t.Errorf("the returned value must be %s. but it was %s", hawk.VAL_MAP.String(), v.Type().String())
|
||||||
} else {
|
} else {
|
||||||
var f *hawk.Val
|
var f *hawk.Val
|
||||||
|
var kk string
|
||||||
|
var vv *hawk.Val
|
||||||
|
var itr hawk.ValMapItr
|
||||||
|
|
||||||
f = hawk.Must(v.MapField("hello"))
|
f = hawk.Must(v.MapField("hello"))
|
||||||
if f.Type() != hawk.VAL_STR {
|
if f.Type() != hawk.VAL_STR {
|
||||||
@@ -172,6 +175,24 @@ return x;
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("the value at the HELLO field must not be found. but it was %s", f.Type().String())
|
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 {
|
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())
|
t.Errorf("the value at the hello field must be a string. but it was %s", f.Type().String())
|
||||||
} else {
|
} else {
|
||||||
//var i int
|
var i int
|
||||||
var sv string
|
var sv string
|
||||||
var ff *hawk.Val
|
var ff *hawk.Val
|
||||||
var itr hawk.ValArrayItr
|
var itr hawk.ValArrayItr
|
||||||
@@ -209,10 +230,14 @@ return x;
|
|||||||
fmt.Printf("%d %v\n", i, hawk.Must(v.ArrayField(i)))
|
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 {
|
for ff != nil {
|
||||||
fmt.Printf("%d [%v]\n", itr.Index(), ff.String())
|
fmt.Printf("index=[%d] value=[%v]\n", i, ff.String())
|
||||||
ff = v.ArrayNextField(&itr)
|
i, ff = v.ArrayNextField(&itr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
hawk_oow_t bound = (pos >= arr->size)? pos: arr->size;
|
||||||
capa = HAWK_ALIGN_POW2(bound + 1, 64);
|
capa = HAWK_ALIGN_POW2(bound + 1, 64);
|
||||||
do { capa = arr->capa * 2; } while (capa <= bound);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
lib/parse.c
21
lib/parse.c
@@ -173,6 +173,10 @@ enum tok_t
|
|||||||
TOK_MBS,
|
TOK_MBS,
|
||||||
TOK_REX,
|
TOK_REX,
|
||||||
TOK_XNIL,
|
TOK_XNIL,
|
||||||
|
#if 0
|
||||||
|
TOK_HAWK_ARRAY,
|
||||||
|
TOK_HAWK_MAP,
|
||||||
|
#endif
|
||||||
|
|
||||||
__TOKEN_COUNT__
|
__TOKEN_COUNT__
|
||||||
};
|
};
|
||||||
@@ -7117,15 +7121,26 @@ retry:
|
|||||||
|
|
||||||
GET_CHAR_TO(hawk, c);
|
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,
|
/* this extended keyword is empty,
|
||||||
* not followed by a valid word */
|
* not followed by a valid word */
|
||||||
hawk_seterrnum(hawk, &(hawk)->tok.loc, HAWK_EXKWEM);
|
hawk_seterrnum(hawk, &(hawk)->tok.loc, HAWK_EXKWEM);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
else if (c == 'B' || c == 'b')
|
||||||
if (c == 'B' || c == 'b')
|
|
||||||
{
|
{
|
||||||
hawk_sio_lxc_t pc1 = hawk->sio.last;
|
hawk_sio_lxc_t pc1 = hawk->sio.last;
|
||||||
GET_CHAR_TO(hawk, c);
|
GET_CHAR_TO(hawk, c);
|
||||||
|
|||||||
@@ -211,6 +211,8 @@ function main()
|
|||||||
tap_ensure(a[0][40], nil, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(a[0][40], nil, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
#hawk::splice (a[0], 40, 1, @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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user