Exemple #1
0
func (l langType) LangType(t types.Type, retInitVal bool, errorInfo string) string {
	if pogo.IsValidInPogo(t, errorInfo) {
		switch t.(type) {
		case *types.Basic:
			switch t.(*types.Basic).Kind() {
			case types.Bool, types.UntypedBool:
				if retInitVal {
					return "false"
				}
				return "Bool"
			case types.String, types.UntypedString:
				if retInitVal {
					return `""`
				}
				return "String"
			case types.Float64, types.Float32, types.UntypedFloat:
				if retInitVal {
					return "0.0"
				}
				return "Float"
			case types.Complex64, types.Complex128, types.UntypedComplex:
				if retInitVal {
					return "new Complex(0.0,0.0)"
				}
				return "Complex"
			case types.Int, types.Int8, types.Int16, types.Int32, types.UntypedRune,
				types.Uint8, types.Uint16, types.Uint, types.Uint32: // NOTE: untyped integers default to Int without a warning
				if retInitVal {
					return "0"
				}
				return "Int"
			case types.Int64, types.Uint64:
				if retInitVal {
					return "GOint64.make(0,0)"
				}
				return "GOint64"
			case types.UntypedInt: // TODO: investigate further the situations in which this warning is generated
				pogo.LogWarning(errorInfo, "Haxe", fmt.Errorf("haxe.LangType() types.UntypedInt is ambiguous"))
				return "UNTYPED_INT" // NOTE: if this value were ever to be used, it would cause a Haxe compilation error
			case types.UnsafePointer:
				if retInitVal {
					return "new UnsafePointer(null)" // TODO is this correct? or should it be null
				}
				return "UnsafePointer"
			case types.Uintptr: // Uintptr sometimes used as an integer type, sometimes as a container for another type
				if retInitVal {
					return "null"
				}
				return "Dynamic"
			default:
				pogo.LogWarning(errorInfo, "Haxe", fmt.Errorf("haxe.LangType() unrecognised basic type, Dynamic assumed"))
				if retInitVal {
					return "null"
				}
				return "Dynamic"
			}
		case *types.Interface:
			if retInitVal {
				return `null`
			}
			return "Interface"
		case *types.Named:
			return l.LangType(t.(*types.Named).Underlying(), retInitVal, errorInfo)
		case *types.Chan:
			if retInitVal {
				return "new Channel<" + l.LangType(t.(*types.Chan).Elem(), false, errorInfo) + ">(1)"
			}
			return "Channel<" + l.LangType(t.(*types.Chan).Elem(), false, errorInfo) + ">"
		case *types.Map:
			if retInitVal {
				return "new Map<" + l.LangType(t.(*types.Map).Key(), false, errorInfo) + "," +
					l.LangType(t.(*types.Map).Elem(), false, errorInfo) + ">()"
			}
			return "Map<" + l.LangType(t.(*types.Map).Key(), false, errorInfo) + "," +
				l.LangType(t.(*types.Map).Elem(), false, errorInfo) + ">"
		case *types.Slice:
			if retInitVal {
				return "new Slice(new Pointer(new Array<" + l.LangType(t.(*types.Slice).Elem(), false, errorInfo) +
					">()),0,0" + ")"
			}
			return "Slice"
		case *types.Array: // TODO consider using Vector rather than Array, if faster and can be made to work
			if retInitVal {
				return "{var _v=new Array<" +
					l.LangType(t.(*types.Array).Elem(), false, errorInfo) +
					fmt.Sprintf(">();for(_vi in 0...%d){_v[_vi]=%s;}; _v;}",
						t.(*types.Array).Len(), l.LangType(t.(*types.Array).Elem(), true, errorInfo))

			}
			return "Array<" + l.LangType(t.(*types.Array).Elem(), false, errorInfo) + ">"
		case *types.Struct: // TODO as this is fixed-length, should it be a Vector, like types.Array ?
			// TODO consider if it is possible to change from Array<Dynamic> to individual named elements - requires considerable work to do this
			if retInitVal {
				ret := "{var _v=new Array<Dynamic>();_v=["
				for ele := 0; ele < t.(*types.Struct).NumFields(); ele++ {
					if ele != 0 {
						ret += ","
					}
					ret += l.LangType(t.(*types.Struct).Field(ele).Type().Underlying(), true, errorInfo)
				}
				return ret + "]; _v;}"
			}
			return "Array<Dynamic>"
		case *types.Tuple: // what is returned by a call and some other instructions, not in the Go language spec!
			tup := t.(*types.Tuple)
			switch tup.Len() {
			case 0:
				return ""
			case 1:
				return l.LangType(tup.At(0).Type().Underlying(), retInitVal, errorInfo)
			default:
				ret := "{"
				for ele := 0; ele < tup.Len(); ele++ {
					if ele != 0 {
						ret += ","
					}
					ret += pogo.MakeId("r"+fmt.Sprintf("%d", ele)) +
						":" + l.LangType(tup.At(ele).Type().Underlying(), retInitVal, errorInfo)
				}
				return ret + "}"
			}
		case *types.Pointer:
			if retInitVal {
				// NOTE pointer declarations create endless recursion for self-referencing structures unless initialized with null
				return "null" //rather than: + l.LangType(t.(*types.Pointer).Elem(), retInitVal, errorInfo) + ")"
			}
			return "Pointer"
		case *types.Signature:
			if retInitVal {
				return "null"
			}
			ret := "Closure"
			return ret
		default:
			rTyp := reflect.TypeOf(t).String()
			if rTyp == "*ssa.opaqueType" { // NOTE the type for map itterators, not in the Go language spec!
				if retInitVal { // use dynamic type, brief tests seem OK, but may not always work on static hosts
					return "null"
				}
				return "Dynamic"
			}
			pogo.LogError(errorInfo, "Haxe",
				fmt.Errorf("haxe.LangType() internal error, unhandled non-basic type: %s", rTyp))
		}
	}
	return "UNKNOWN_LANGTYPE" // this should generate a Haxe compiler error
}
Exemple #2
0
func (l langType) LangType(t types.Type, retInitVal bool, errorInfo string) string {
	if pogo.IsValidInPogo(t, errorInfo) {
		switch t.(type) {
		case *types.Basic:
			switch t.(*types.Basic).Kind() {
			case types.Bool, types.UntypedBool:
				if retInitVal {
					return "false"
				}
				return "Bool"
			case types.String, types.UntypedString:
				if retInitVal {
					return `""`
				}
				return "String"
			case types.Float64, types.Float32, types.UntypedFloat:
				if retInitVal {
					return "0.0"
				}
				return "Float"
			case types.Complex64, types.Complex128, types.UntypedComplex:
				if retInitVal {
					return "new Complex(0.0,0.0)"
				}
				return "Complex"
			case types.Int, types.Int8, types.Int16, types.Int32, types.UntypedRune,
				types.Uint8, types.Uint16, types.Uint, types.Uint32: // NOTE: untyped runes default to Int without a warning
				if retInitVal {
					return "0"
				}
				return "Int"
			case types.Int64, types.Uint64:
				if retInitVal {
					return "GOint64.ofInt(0)"
				}
				return "GOint64"
			case types.UntypedInt: // TODO: investigate further the situations in which this warning is generated
				if retInitVal {
					return "0"
				}
				return "UNTYPED_INT" // NOTE: if this value were ever to be used, it would cause a Haxe compilation error
			case types.UnsafePointer:
				if retInitVal {
					return "null" // NOTE ALL pointers are unsafe
				}
				return "Pointer"
			case types.Uintptr: // Uintptr sometimes used as an integer type, sometimes as a container for another type
				if retInitVal {
					return "null"
				}
				return "Dynamic"
			default:
				pogo.LogWarning(errorInfo, "Haxe", fmt.Errorf("haxe.LangType() unrecognised basic type, Dynamic assumed"))
				if retInitVal {
					return "null"
				}
				return "Dynamic"
			}
		case *types.Interface:
			if retInitVal {
				return `null`
			}
			return "Interface"
		case *types.Named:
			haxeName := getHaxeClass(t.(*types.Named).String())
			//fmt.Println("DEBUG Go named type -> Haxe type :", t.(*types.Named).String(), "->", haxeName)
			if haxeName != "" {
				if retInitVal {
					return `null` // NOTE code to the right does not work in openfl/flash: `Type.createEmptyInstance(` + haxeName + ")"
				}
				return haxeName
			}
			return l.LangType(t.(*types.Named).Underlying(), retInitVal, errorInfo)
		case *types.Chan:
			if retInitVal {
				return "new Channel(1)" //waa: <" + l.LangType(t.(*types.Chan).Elem(), false, errorInfo) + ">(1)"
			}
			return "Channel" //was: <" + l.LangType(t.(*types.Chan).Elem(), false, errorInfo) + ">"
		case *types.Map:
			if retInitVal {
				k := t.(*types.Map).Key().Underlying()
				kv := l.LangType(k, true, errorInfo)
				e := t.(*types.Map).Elem().Underlying()
				ev := "null" // TODO review, required for encode/gob to stop recursion
				if _, isMap := e.(*types.Map); !isMap {
					ev = l.LangType(e, true, errorInfo)
				}
				return "new GOmap(" + kv + "," + ev + ")"
			}
			return "GOmap"
		case *types.Slice:
			if retInitVal {
				return "new Slice(Pointer.make(" +
					"Object.make(0)" +
					"),0,0,0," + "1" + arrayOffsetCalc(t.(*types.Slice).Elem().Underlying()) + ")"
			}
			return "Slice"
		case *types.Array:
			if retInitVal {
				return fmt.Sprintf("Object.make(%d)", haxeStdSizes.Sizeof(t))
			}
			return "Object"
		case *types.Struct:
			if retInitVal {
				return fmt.Sprintf("Object.make(%d)", haxeStdSizes.Sizeof(t.(*types.Struct).Underlying()))
			}
			return "Object"
		case *types.Tuple: // what is returned by a call and some other instructions, not in the Go language spec!
			tup := t.(*types.Tuple)
			switch tup.Len() {
			case 0:
				return ""
			case 1:
				return l.LangType(tup.At(0).Type().Underlying(), retInitVal, errorInfo)
			default:
				ret := "{"
				for ele := 0; ele < tup.Len(); ele++ {
					if ele != 0 {
						ret += ","
					}
					ret += pogo.MakeID("r"+fmt.Sprintf("%d", ele)) + ":"
					if !retInitVal {
						ret += "Null<"
					}
					ret += l.LangType(tup.At(ele).Type().Underlying(), retInitVal, errorInfo)
					if !retInitVal {
						ret += ">"
					}
				}
				return ret + "}"
			}
		case *types.Pointer:
			if retInitVal {
				// NOTE pointer declarations create endless recursion for self-referencing structures unless initialized with null
				return "null" //rather than: + l.LangType(t.(*types.Pointer).Elem(), retInitVal, errorInfo) + ")"
			}
			return "Pointer"
		case *types.Signature:
			if retInitVal {
				return "null"
			}
			ret := "Closure"
			return ret
		default:
			rTyp := reflect.TypeOf(t).String()
			if rTyp == "*ssa.opaqueType" { // NOTE the type for map itterators, not in the Go language spec!
				if retInitVal { // use dynamic type, brief tests seem OK, but may not always work on static hosts
					return "null"
				}
				return "Dynamic"
			}
			pogo.LogError(errorInfo, "Haxe",
				fmt.Errorf("haxe.LangType() internal error, unhandled non-basic type: %s", rTyp))
		}
	}
	return "UNKNOWN_LANGTYPE" // this should generate a Haxe compiler error
}