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