예제 #1
0
func main() {

	var L *lua.State

	L = lua.NewState()
	defer L.Close()
	L.OpenLibs()

	// just to show we can catch the panic
	defer func() {
		fmt.Println("done")
		if x := recover(); x != nil {
			fmt.Printf("run time panic: %v", x)
		}
	}()

	// we can still catch the panic without this,
	// but it allows us to do some custom recovery
	currentPanicf := L.AtPanic(nil)
	currentPanicf = L.AtPanic(currentPanicf)
	newPanic := func(L1 *lua.State) int {
		fmt.Println("I AM PANICKING!!!")
		return currentPanicf(L1)
	}
	L.AtPanic(newPanic)

	//force a panic
	L.PushNil()
	L.Call(0, 0)
}
예제 #2
0
// Push a Go value 'val' of type 't' on the Lua stack.
func GoToLua(L *lua.State, t reflect.Type, val reflect.Value) {
	if t == nil {
		t = val.Type()
	}
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	switch t.Kind() {
	case reflect.Float64:
	case reflect.Float32:
		{
			L.PushNumber(val.Float())
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
		{
			L.PushNumber(float64(val.Int()))
		}
	case reflect.Uint, reflect.Uint8:
		{
			L.PushNumber(float64(val.Uint()))
		}
	case reflect.String:
		{
			L.PushString(val.String())
		}
	case reflect.Bool:
		{
			L.PushBoolean(val.Bool())
		}
	case reflect.Slice:
		{
			makeValueProxy(L, val, SLICE_META)
		}
	case reflect.Map:
		{
			makeValueProxy(L, val, MAP_META)
		}
	case reflect.Struct:
		{
			makeValueProxy(L, val, STRUCT_META)
		}
	default:
		{
			// fmt.Println("unhandled go type",t,t.Kind())
			if val.IsNil() {
				L.PushNil()
			} else {
				makeValueProxy(L, val, INTERFACE_META)
			}
		}
	}
}
예제 #3
0
// copy a Go slice to a Lua table
func CopySliceToTable(L *lua.State, vslice reflect.Value) int {
	if vslice.IsValid() && vslice.Type().Kind() == reflect.Slice {
		n := vslice.Len()
		L.CreateTable(n, 0)
		for i := 0; i < n; i++ {
			L.PushInteger(i + 1)
			GoToLua(L, nil, vslice.Index(i))
			L.SetTable(-3)
		}
		return 1
	} else {
		L.PushNil()
		L.PushString("not a slice!")
	}
	return 2
}
예제 #4
0
// copy a Go map to a Lua table
func CopyMapToTable(L *lua.State, vmap reflect.Value) int {
	if vmap.IsValid() && vmap.Type().Kind() == reflect.Map {
		n := vmap.Len()
		L.CreateTable(0, n)
		for _, key := range vmap.MapKeys() {
			val := vmap.MapIndex(key)
			GoToLua(L, nil, key)
			GoToLua(L, nil, val)
			L.SetTable(-3)
		}
		return 1
	} else {
		L.PushNil()
		L.PushString("not a map!")
	}
	return 2
}
예제 #5
0
func copyMapToTable(L *lua.State) int {
	vmap := valueOf(unwrapProxy(L, 1))
	if vmap.IsValid() && vmap.Type().Kind() == reflect.Map {
		n := vmap.Len()
		L.CreateTable(0, n)
		for _, key := range vmap.MapKeys() {
			GoToLua(L, nil, key)
			GoToLua(L, nil, vmap.MapIndex(key))
			L.SetTable(-3)
		}
		return 1
	} else {
		L.PushNil()
		L.PushString("not a map!")
	}
	return 2
}
예제 #6
0
// return the Lua table at 'idx' as a copied Go map. If 't' is nil then the map
// type is map[string]interface{}
func CopyTableToMap(L *lua.State, t reflect.Type, idx int) interface{} {
	if t == nil {
		t = reflect.TypeOf(tmap)
	}
	te, tk := t.Elem(), t.Key()
	m := reflect.MakeMap(t)
	L.PushNil()
	if idx < 0 {
		idx--
	}
	for L.Next(idx) != 0 {
		// key at -2, value at -1
		key := valueOf(LuaToGo(L, tk, -2))
		val := valueOf(LuaToGo(L, te, -1))
		m.SetMapIndex(key, val)
		L.Pop(1)
	}
	return m.Interface()
}
예제 #7
0
func CopyTableToStruct(L *lua.State, t reflect.Type, idx int) interface{} {
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	s := reflect.New(t) // T -> *T
	ref := s.Elem()
	L.PushNil()
	if idx < 0 {
		idx--
	}
	for L.Next(idx) != 0 {
		key := L.ToString(-2)
		f := ref.FieldByName(key)
		if f.IsValid() {
			val := valueOf(LuaToGo(L, f.Type(), -1))
			f.Set(val)
		}
		L.Pop(1)
	}
	return s.Interface()
}
예제 #8
0
// Push a Go value 'val' of type 't' on the Lua stack.
// If we haven't been given a concrete type, use the type of the value
// and unbox any interfaces.
func GoToLua(L *lua.State, t reflect.Type, val reflect.Value) {
	proxify := true
	if t == nil {
		t = val.Type()
		if t.Kind() == reflect.Interface { // unbox interfaces!
			val = valueOf(val.Interface())
			t = val.Type()
		}
		proxify = false
	}
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	switch t.Kind() {
	case reflect.Float64:
	case reflect.Float32:
		{
			L.PushNumber(val.Float())
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
		{
			L.PushNumber(float64(val.Int()))
		}
	case reflect.Uint, reflect.Uint8:
		{
			L.PushNumber(float64(val.Uint()))
		}
	case reflect.String:
		{
			L.PushString(val.String())
		}
	case reflect.Bool:
		{
			L.PushBoolean(val.Bool())
		}
	case reflect.Slice:
		{
			if proxify {
				makeValueProxy(L, val, SLICE_META)
			} else {
				CopySliceToTable(L, val)
			}
		}
	case reflect.Map:
		{
			if proxify {
				makeValueProxy(L, val, MAP_META)
			} else {
				CopyMapToTable(L, val)
			}
		}
	case reflect.Struct:
		{
			makeValueProxy(L, val, STRUCT_META)
		}
	default:
		{
			if val.IsNil() {
				L.PushNil()
			} else {
				makeValueProxy(L, val, INTERFACE_META)
			}
		}
	}
}