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 {
|
||||
c *C.hawk_t // c object
|
||||
//g *Hawk // go object
|
||||
g weak.Pointer[Hawk] // go object
|
||||
}
|
||||
|
||||
|
||||
81
hawk.go
81
hawk.go
@@ -86,8 +86,26 @@ type Val struct {
|
||||
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
|
||||
|
||||
|
||||
func deregister_instance(h *Hawk) {
|
||||
fmt.Printf ("DEREGISER INSTANCE %p\n", h)
|
||||
for h.rtx_head != nil {
|
||||
@@ -269,6 +287,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)
|
||||
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.prev = nil
|
||||
hawk.rtx_count--
|
||||
fmt.Printf(">>>> %d\n", hawk.rtx_count)
|
||||
hawk.rtx_mtx.Unlock()
|
||||
}
|
||||
|
||||
@@ -546,6 +566,12 @@ func (val *Val) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
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) ToByte() (byte, error) {
|
||||
}
|
||||
|
||||
@@ -605,6 +631,61 @@ func (val* Val) ToByteArr() ([]byte, error) {
|
||||
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 {
|
||||
|
||||
174
hawk_test.go
174
hawk_test.go
@@ -14,53 +14,65 @@ func exit_with_error(msg string, err error) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func make_hawk() (*hawk.Hawk, error) {
|
||||
func make_hawk(script string) (*hawk.Hawk, error) {
|
||||
var h *hawk.Hawk
|
||||
var err error
|
||||
|
||||
h, err = hawk.New()
|
||||
if err != nil { return nil, err }
|
||||
|
||||
err = h.ParseText(`function x(a1, a2, a3) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
printf("hello, world [%d] [%s] [%s]\n", a1, a2, a3);
|
||||
##if (i == 3) sys::sleep(1);
|
||||
err = h.ParseText(script)
|
||||
if err != nil {
|
||||
h.Close()
|
||||
return nil, err
|
||||
}
|
||||
##return "welcome to the jungle 999";
|
||||
return 1.9923;
|
||||
}`)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func run_hawk(h *hawk.Hawk, id int, wg *sync.WaitGroup) {
|
||||
var r *hawk.Rtx
|
||||
func run_hawk(h *hawk.Hawk, id int, t *testing.T, wg *sync.WaitGroup) {
|
||||
var rtx *hawk.Rtx
|
||||
var v *hawk.Val
|
||||
//var ret string
|
||||
var ret []byte //float64
|
||||
var i int
|
||||
var err error
|
||||
|
||||
defer wg.Done()
|
||||
|
||||
r, err = h.NewRtx(fmt.Sprintf("%d", id))
|
||||
rtx, err = h.NewRtx(fmt.Sprintf("%d", id))
|
||||
if err != nil {
|
||||
t.Errorf("failed to create rtx id[%d] - %s", id, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
v, err = r.Call("x",
|
||||
hawk.Must(r.NewVal/*FromInt*/(id + 10)),
|
||||
hawk.Must(r.NewVal([]byte{'A',66,67,68,69})),
|
||||
hawk.Must(r.NewVal/*FromStr*/("this is cool")))
|
||||
if err != nil { exit_with_error("rtx call", err) }
|
||||
v, err = rtx.Call("x",
|
||||
hawk.Must(rtx.NewVal/*FromInt*/(id + 10)),
|
||||
hawk.Must(rtx.NewVal([]byte{'A',66,67,68,69})),
|
||||
hawk.Must(rtx.NewVal/*FromStr*/("this is cool")))
|
||||
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()
|
||||
if err != nil {
|
||||
fmt.Printf("failed to get return value - %s\n", err.Error())
|
||||
} else {
|
||||
fmt.Printf("RET[%d] => [%v]\n", id, ret)
|
||||
t.Errorf("failed to get return value for rtx id[%d] - %s", id, err.Error())
|
||||
rtx.Close()
|
||||
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) {
|
||||
@@ -71,22 +83,130 @@ func Test1(t *testing.T) {
|
||||
|
||||
debug.SetGCPercent(100) // enable normal GC
|
||||
|
||||
h, err = make_hawk()
|
||||
if err != nil { exit_with_error("Failed to make hawk", err) }
|
||||
h, err = make_hawk(`function x(a1, a2, a3) {
|
||||
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++ {
|
||||
wg.Add(1)
|
||||
go run_hawk(h, i, &wg)
|
||||
go run_hawk(h, i, t, &wg)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
fmt.Printf ("%d RTX objects\n", h.RtxCount())
|
||||
h.Close()
|
||||
h = nil
|
||||
// when rtx objects are all closed, the counter must drop to 0
|
||||
i = h.RtxCount()
|
||||
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")
|
||||
runtime.GC()
|
||||
runtime.Gosched()
|
||||
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_EXPORT hawk_ooi_t hawk_rtx_getarrvaltally (
|
||||
hawk_rtx_t* rtx,
|
||||
hawk_val_t* arr
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_rtx_makerefval() function creates a reference value.
|
||||
* \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);
|
||||
}
|
||||
|
||||
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_ref_t* val;
|
||||
|
||||
Reference in New Issue
Block a user