added hawk_rtx_getarrvaltally().
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Val methods being worked on
This commit is contained in:
@@ -9,7 +9,6 @@ import "weak"
|
|||||||
|
|
||||||
type Instance struct {
|
type Instance struct {
|
||||||
c *C.hawk_t // c object
|
c *C.hawk_t // c object
|
||||||
//g *Hawk // go object
|
|
||||||
g weak.Pointer[Hawk] // go object
|
g weak.Pointer[Hawk] // go object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
93
hawk.go
93
hawk.go
@@ -86,8 +86,26 @@ type Val struct {
|
|||||||
prev *Val
|
prev *Val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ValType int
|
||||||
|
const (
|
||||||
|
VAL_NIL ValType = C.HAWK_VAL_NIL
|
||||||
|
VAL_CHAR ValType = C.HAWK_VAL_CHAR
|
||||||
|
VAL_BCHR ValType = C.HAWK_VAL_BCHR
|
||||||
|
VAL_INT ValType = C.HAWK_VAL_INT
|
||||||
|
VAL_FLT ValType = C.HAWK_VAL_FLT
|
||||||
|
VAL_STR ValType = C.HAWK_VAL_STR
|
||||||
|
VAL_MBS ValType = C.HAWK_VAL_MBS
|
||||||
|
VAL_FUN ValType = C.HAWK_VAL_FUN
|
||||||
|
VAL_MAP ValType = C.HAWK_VAL_MAP
|
||||||
|
VAL_ARR ValType = C.HAWK_VAL_ARR
|
||||||
|
VAL_REX ValType = C.HAWK_VAL_REX
|
||||||
|
VAL_REF ValType = C.HAWK_VAL_REF
|
||||||
|
VAL_BOB ValType = C.HAWK_VAL_BOB
|
||||||
|
)
|
||||||
|
|
||||||
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 {
|
||||||
@@ -269,6 +287,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)
|
||||||
hawk.rtx_mtx.Unlock()
|
hawk.rtx_mtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +310,7 @@ fmt.Printf("head %p tail %p\n", hawk.rtx_tail, hawk.rtx_tail)
|
|||||||
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)
|
||||||
hawk.rtx_mtx.Unlock()
|
hawk.rtx_mtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,13 +566,19 @@ func (val *Val) Close() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*func (val* Val) ToByte() (byte, error) {
|
func (val *Val) Type() ValType {
|
||||||
|
var x C.int
|
||||||
|
x = C.hawk_rtx_getvaltype(val.rtx.c, val.c)
|
||||||
|
return ValType(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (val* Val) ToRune() (rune, error) {
|
/*func (val *Val) ToByte() (byte, error) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (val *Val) ToRune() (rune, error) {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
func (val* Val) ToInt() (int, error) {
|
func (val *Val) ToInt() (int, error) {
|
||||||
var v C.hawk_int_t
|
var v C.hawk_int_t
|
||||||
var x C.int
|
var x C.int
|
||||||
|
|
||||||
@@ -562,7 +588,7 @@ func (val* Val) ToInt() (int, error) {
|
|||||||
return int(v), nil
|
return int(v), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (val* Val) ToFlt() (float64, error) {
|
func (val *Val) ToFlt() (float64, error) {
|
||||||
var v float64
|
var v float64
|
||||||
var x C.int
|
var x C.int
|
||||||
|
|
||||||
@@ -573,7 +599,7 @@ func (val* Val) ToFlt() (float64, error) {
|
|||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (val* Val) ToStr() (string, error) {
|
func (val *Val) ToStr() (string, error) {
|
||||||
var out C.hawk_rtx_valtostr_out_t
|
var out C.hawk_rtx_valtostr_out_t
|
||||||
var ptr *C.hawk_ooch_t
|
var ptr *C.hawk_ooch_t
|
||||||
var len C.hawk_oow_t
|
var len C.hawk_oow_t
|
||||||
@@ -591,7 +617,7 @@ func (val* Val) ToStr() (string, error) {
|
|||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (val* Val) ToByteArr() ([]byte, error) {
|
func (val *Val) ToByteArr() ([]byte, error) {
|
||||||
var ptr *C.hawk_bch_t
|
var ptr *C.hawk_bch_t
|
||||||
var len C.hawk_oow_t
|
var len C.hawk_oow_t
|
||||||
var v []byte
|
var v []byte
|
||||||
@@ -605,6 +631,61 @@ func (val* Val) ToByteArr() ([]byte, error) {
|
|||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (val *Val) ArrayTally() int {
|
||||||
|
var v C.hawk_ooi_t
|
||||||
|
// TODO: if not array .. panic or return -1 or 0?
|
||||||
|
v = C.hawk_rtx_getarrvaltally(val.rtx.c, val.c)
|
||||||
|
return int(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: function get the first index and last index or the capacity
|
||||||
|
// function to traverse?
|
||||||
|
func (val *Val) ArrayField(index int) (*Val, error) {
|
||||||
|
var v *C.hawk_val_t
|
||||||
|
v = C.hawk_rtx_getarrvalfld(val.rtx.c, val.c, C.hawk_ooi_t(index))
|
||||||
|
if v == nil { return nil, val.rtx.make_errinfo() }
|
||||||
|
return val.rtx.make_val(func() *C.hawk_val_t { return v })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (val *Val) MapField(key string) (*Val, error) {
|
||||||
|
var v *C.hawk_val_t
|
||||||
|
var uc []C.hawk_uch_t
|
||||||
|
uc = string_to_uchars(key)
|
||||||
|
v = C.hawk_rtx_getmapvalfld(val.rtx.c, val.c, &uc[0], C.hawk_oow_t(len(uc)))
|
||||||
|
if v == nil { return nil, val.rtx.make_errinfo() }
|
||||||
|
return val.rtx.make_val(func() *C.hawk_val_t { return v })
|
||||||
|
}
|
||||||
|
|
||||||
|
//func (val *Val) SetArrayField(index int, val *Val) error {
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
|
// TODO: map traversal..
|
||||||
|
//func (val *Val) SetMapField(key string, val *Val) error {
|
||||||
|
//}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
|
||||||
|
var val_type []string = []string{
|
||||||
|
VAL_NIL: "NIL",
|
||||||
|
VAL_CHAR: "CHAR",
|
||||||
|
VAL_BCHR: "BCHR",
|
||||||
|
VAL_INT: "INT",
|
||||||
|
VAL_FLT: "FLT",
|
||||||
|
VAL_STR: "STR",
|
||||||
|
VAL_MBS: "MBS",
|
||||||
|
VAL_FUN: "FUN",
|
||||||
|
VAL_MAP: "MAP",
|
||||||
|
VAL_ARR: "ARR",
|
||||||
|
VAL_REX: "REX",
|
||||||
|
VAL_REF: "REF",
|
||||||
|
VAL_BOB: "BOB",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ValType) String() string {
|
||||||
|
return val_type[t]
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
||||||
|
|
||||||
func ucstr_to_rune_slice(str *C.hawk_uch_t) []rune {
|
func ucstr_to_rune_slice(str *C.hawk_uch_t) []rune {
|
||||||
|
|||||||
176
hawk_test.go
176
hawk_test.go
@@ -14,53 +14,65 @@ func exit_with_error(msg string, err error) {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func make_hawk() (*hawk.Hawk, error) {
|
func make_hawk(script string) (*hawk.Hawk, error) {
|
||||||
var h *hawk.Hawk
|
var h *hawk.Hawk
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
h, err = hawk.New()
|
h, err = hawk.New()
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
|
|
||||||
err = h.ParseText(`function x(a1, a2, a3) {
|
err = h.ParseText(script)
|
||||||
for (i = 0; i < 10; i++) {
|
if err != nil {
|
||||||
printf("hello, world [%d] [%s] [%s]\n", a1, a2, a3);
|
h.Close()
|
||||||
##if (i == 3) sys::sleep(1);
|
return nil, err
|
||||||
}
|
}
|
||||||
##return "welcome to the jungle 999";
|
|
||||||
return 1.9923;
|
|
||||||
}`)
|
|
||||||
if err != nil { return nil, err }
|
|
||||||
|
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func run_hawk(h *hawk.Hawk, id int, wg *sync.WaitGroup) {
|
func run_hawk(h *hawk.Hawk, id int, t *testing.T, wg *sync.WaitGroup) {
|
||||||
var r *hawk.Rtx
|
var rtx *hawk.Rtx
|
||||||
var v *hawk.Val
|
var v *hawk.Val
|
||||||
//var ret string
|
//var ret string
|
||||||
var ret []byte //float64
|
var ret []byte //float64
|
||||||
|
var i int
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
r, err = h.NewRtx(fmt.Sprintf("%d", id))
|
rtx, err = h.NewRtx(fmt.Sprintf("%d", id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
t.Errorf("failed to create rtx id[%d] - %s", id, err.Error())
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err = r.Call("x",
|
v, err = rtx.Call("x",
|
||||||
hawk.Must(r.NewVal/*FromInt*/(id + 10)),
|
hawk.Must(rtx.NewVal/*FromInt*/(id + 10)),
|
||||||
hawk.Must(r.NewVal([]byte{'A',66,67,68,69})),
|
hawk.Must(rtx.NewVal([]byte{'A',66,67,68,69})),
|
||||||
hawk.Must(r.NewVal/*FromStr*/("this is cool")))
|
hawk.Must(rtx.NewVal/*FromStr*/("this is cool")))
|
||||||
if err != nil { exit_with_error("rtx call", err) }
|
if err != nil {
|
||||||
|
t.Errorf("failed to invoke function 'x' for rtx id[%d] - %s", id, err.Error())
|
||||||
|
rtx.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ret, err = v.ToByteArr()
|
ret, err = v.ToByteArr()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to get return value - %s\n", err.Error())
|
t.Errorf("failed to get return value for rtx id[%d] - %s", id, err.Error())
|
||||||
} else {
|
rtx.Close()
|
||||||
fmt.Printf("RET[%d] => [%v]\n", id, ret)
|
return
|
||||||
}
|
}
|
||||||
|
fmt.Printf("RET[%d] => [%v]\n", id, ret)
|
||||||
|
|
||||||
r.Close()
|
// check if ValCount() returns the right number of values created explicitly
|
||||||
|
i = rtx.ValCount()
|
||||||
|
if i != 3 { t.Errorf("the number of val objects for rtx id[%d] must be 3. but %d was returned", id, i) }
|
||||||
|
|
||||||
|
rtx.Close()
|
||||||
|
|
||||||
|
// it's safe to all ValCount() after Close() has been called.
|
||||||
|
i = rtx.ValCount()
|
||||||
|
if i != 0 { t.Errorf("the number of val objects for rtx id[%d] must be 0. but %d was returned", id, i) }
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test1(t *testing.T) {
|
func Test1(t *testing.T) {
|
||||||
@@ -71,22 +83,130 @@ func Test1(t *testing.T) {
|
|||||||
|
|
||||||
debug.SetGCPercent(100) // enable normal GC
|
debug.SetGCPercent(100) // enable normal GC
|
||||||
|
|
||||||
h, err = make_hawk()
|
h, err = make_hawk(`function x(a1, a2, a3) {
|
||||||
if err != nil { exit_with_error("Failed to make hawk", err) }
|
for (i = 0; i < 10; i++) {
|
||||||
|
printf("hello, world [%d] [%s] [%s]\n", a1, a2, a3);
|
||||||
|
##if (i == 3) sys::sleep(1);
|
||||||
|
}
|
||||||
|
##return "welcome to the jungle 999";
|
||||||
|
return 1.9923;
|
||||||
|
}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to make hawk - %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for i = 0; i < 10; i++ {
|
for i = 0; i < 10; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go run_hawk(h, i, &wg)
|
go run_hawk(h, i, t, &wg)
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
fmt.Printf ("%d RTX objects\n", h.RtxCount())
|
// when rtx objects are all closed, the counter must drop to 0
|
||||||
h.Close()
|
i = h.RtxCount()
|
||||||
h = nil
|
if i != 0 { t.Errorf("the number of rtx objects must be 0. but %d was returned", i) }
|
||||||
|
|
||||||
|
h.Close()
|
||||||
|
|
||||||
|
h = nil
|
||||||
fmt.Printf ("== END of run ==\n")
|
fmt.Printf ("== END of run ==\n")
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
runtime.Gosched()
|
runtime.Gosched()
|
||||||
time.Sleep(1000 * time.Millisecond) // give finalizer time to print
|
time.Sleep(1000 * time.Millisecond) // give finalizer time to print
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test2(t *testing.T) {
|
||||||
|
var h *hawk.Hawk
|
||||||
|
var rtx *hawk.Rtx
|
||||||
|
var err error
|
||||||
|
|
||||||
|
debug.SetGCPercent(100) // enable normal GC
|
||||||
|
|
||||||
|
h, err = make_hawk(`function get_map(s) {
|
||||||
|
@local x
|
||||||
|
x["hello"] = s
|
||||||
|
x[99] = "donkey is running"
|
||||||
|
x["what"] = "rankey gankey"
|
||||||
|
x[1.239] = @b"nice value"
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
function get_arr(s) {
|
||||||
|
@local x;
|
||||||
|
x = hawk::array(s, (s %% s), 10, 20.99);
|
||||||
|
for (i in x) print i, x[i];
|
||||||
|
return x;
|
||||||
|
}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to make hawk - %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rtx, err = h.NewRtx("test2")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create rtx - %s", err.Error())
|
||||||
|
} else {
|
||||||
|
var v *hawk.Val
|
||||||
|
|
||||||
|
v, err = rtx.Call("get_map", hawk.Must(rtx.NewValFromStr("hawk flies")))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to call get_map - %s", err.Error())
|
||||||
|
} else {
|
||||||
|
if v.Type() != hawk.VAL_MAP {
|
||||||
|
t.Errorf("the returned value must be %s. but it was %s", hawk.VAL_MAP.String(), v.Type().String())
|
||||||
|
} else {
|
||||||
|
var f *hawk.Val
|
||||||
|
|
||||||
|
f = hawk.Must(v.MapField("hello"))
|
||||||
|
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 sv string
|
||||||
|
sv = hawk.Must(f.ToStr())
|
||||||
|
if sv != "hawk flies" {
|
||||||
|
t.Errorf("the value for the hello field must be 'hawk flies'. but it was %s", sv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err = v.MapField("HELLO")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("the value at the HELLO field must not be found. but it was %s", f.Type().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err = rtx.Call("get_arr", hawk.Must(rtx.NewValFromStr("hawk flies")))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to call get_arr - %s", err.Error())
|
||||||
|
} else {
|
||||||
|
if v.Type() != hawk.VAL_ARR {
|
||||||
|
t.Errorf("the returned value must be %s. but it was %s", hawk.VAL_ARR.String(), v.Type().String())
|
||||||
|
} else {
|
||||||
|
var sz int
|
||||||
|
var f *hawk.Val
|
||||||
|
|
||||||
|
sz = v.ArrayTally()
|
||||||
|
if sz != 4 {
|
||||||
|
t.Errorf("the returned value must have 4 elements. but it had %d elements", sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
f = hawk.Must(v.ArrayField(2))
|
||||||
|
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 sv string
|
||||||
|
sv = hawk.Must(f.ToStr())
|
||||||
|
if sv != "hawk flieshawk flies" {
|
||||||
|
t.Errorf("the value for the hello field must be 'hawk flieshawk flies'. but it was %s", sv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Close()
|
||||||
|
|
||||||
|
runtime.GC()
|
||||||
|
runtime.Gosched()
|
||||||
|
time.Sleep(1000 * time.Millisecond) // give finalizer time to print
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3373,6 +3373,11 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_getarrvalfld (
|
|||||||
hawk_ooi_t index
|
hawk_ooi_t index
|
||||||
);
|
);
|
||||||
|
|
||||||
|
HAWK_EXPORT hawk_ooi_t hawk_rtx_getarrvaltally (
|
||||||
|
hawk_rtx_t* rtx,
|
||||||
|
hawk_val_t* arr
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The hawk_rtx_makerefval() function creates a reference value.
|
* The hawk_rtx_makerefval() function creates a reference value.
|
||||||
* \return value on success, #HAWK_NULL on failure
|
* \return value on success, #HAWK_NULL on failure
|
||||||
|
|||||||
@@ -1444,6 +1444,14 @@ hawk_val_t* hawk_rtx_getarrvalfld (hawk_rtx_t* rtx, hawk_val_t* arr, hawk_ooi_t
|
|||||||
return HAWK_ARR_DPTR(_arr, index);
|
return HAWK_ARR_DPTR(_arr, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hawk_ooi_t hawk_rtx_getarrvaltally (hawk_rtx_t* rtx, hawk_val_t* arr)
|
||||||
|
{
|
||||||
|
hawk_arr_t* _arr;
|
||||||
|
HAWK_ASSERT (HAWK_RTX_GETVALTYPE(rtx, arr) == HAWK_VAL_ARR);
|
||||||
|
_arr = ((hawk_val_arr_t*)arr)->arr;
|
||||||
|
return HAWK_ARR_TALLY(_arr);
|
||||||
|
}
|
||||||
|
|
||||||
hawk_val_t* hawk_rtx_makerefval (hawk_rtx_t* rtx, int id, hawk_val_t** adr)
|
hawk_val_t* hawk_rtx_makerefval (hawk_rtx_t* rtx, int id, hawk_val_t** adr)
|
||||||
{
|
{
|
||||||
hawk_val_ref_t* val;
|
hawk_val_ref_t* val;
|
||||||
|
|||||||
Reference in New Issue
Block a user