123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749 |
- package core
- import (
- "time"
- "math"
- "regexp"
- "reflect"
- "math/big"
- "kumachan/standalone/qt"
- "kumachan/standalone/ctn"
- "kumachan/standalone/util/pseudounion"
- )
- var pseudoUnionTagReflectType = reflect.TypeOf(pseudounion.Tag(0))
- func ToObject[T any] (v T) Object {
- return MakeObject(v, nil)
- }
- func MakeObject(v interface{}, h RuntimeHandle) Object {
- if ((v == nil) || (v == struct{}{})) {
- v = Object(nil)
- }
- if o, is_object := v.(Object); is_object {
- return o
- }
- var o = (func() ObjectImpl {
- switch V := v.(type) {
- // Primitive
- // Bool
- case bool:
- return Bool(V)
- // Int
- case *big.Int:
- return Int { V }
- case int:
- return Int { big.NewInt(int64(V)) }
- // Float
- case float64:
- return Float(V)
- // Bytes
- case [] byte:
- return Bytes(V)
- // String
- case string:
- return String(V)
- // Char
- case int32: // = rune
- return Char(V)
- // RegExp
- case *regexp.Regexp:
- return RegExp { V }
- // Time
- case time.Time:
- return Time(V)
- // File:
- case File:
- return V
- // Error
- case error:
- return Error { V }
- // Reflect
- // ReflectType
- case ReflectType:
- return V
- // ReflectValue
- case ReflectValue:
- return V
- // Rx
- // Observable
- case Observable:
- return V
- // Subject
- case Subject:
- return V
- // Interface and Lambda (Object)
- // Interface
- case Interface:
- return V
- // Lambda (Object)
- case Lambda:
- return V
- // Container (Object)
- // List (Object)
- case List:
- return V
- // Seq
- case Seq:
- return V
- // Queue
- case Queue:
- return V
- // Heap
- case Heap:
- return V
- // Set
- case Set:
- return V
- // Map
- case Map:
- return V
- // GUI
- // Action
- case Action:
- return V
- // Widget
- case Widget:
- return V
- // Signal
- case Signal:
- return V
- // Events
- case Events:
- return V
- // Prop
- case Prop:
- return V
- // Union (Object)
- case Union:
- return V
- // check for mistake
- case reflect.Value:
- panic("invalid argument")
- default:
- var rv = reflect.ValueOf(v)
- var rt = rv.Type()
- // Enum (int)
- if rt.Kind() == reflect.Int {
- var v = rv.Convert(reflect.TypeOf(int(0))).Interface().(int)
- return Enum(v)
- }
- // Union (ctn.Maybe)
- if _, ok := ctn.ReflectTypeMatchMaybe(rt); ok {
- if inner_rv, ok := ctn.ReflectMaybeValue(rv); ok {
- var inner_v = inner_rv.Interface()
- return Union {
- Index: OkIndex,
- Object: MakeObject(inner_v, h),
- }
- } else {
- return Union { Index: NgIndex }
- }
- }
- // Record (ctn.Pair)
- if _, _, ok := ctn.ReflectTypeMatchPair(rt); ok {
- var a_rv, b_rv = ctn.ReflectPairUnpack(rv)
- var a_v = a_rv.Interface()
- var b_v = b_rv.Interface()
- var a = MakeObject(a_v, h)
- var b = MakeObject(b_v, h)
- return Record {
- Objects: [] Object { a, b },
- }
- }
- // Union (pseudo-union)
- if rt.Kind() == reflect.Struct {
- if rt.NumField() >= 1 {
- if rt.Field(0).Type == pseudoUnionTagReflectType {
- var index = int(rv.Field(0).Int())
- var object_rv = rv.Field(index)
- var object_v = object_rv.Interface()
- var object = MakeObject(object_v, h)
- return Union {
- Index: (index - 1),
- Object: object,
- }
- }}
- // Record (struct)
- var n = rt.NumField()
- var objects = make([] Object, n)
- for i := 0; i < n; i += 1 {
- var field_rv = rv.Field(i)
- var field_v = field_rv.Interface()
- objects[i] = MakeObject(field_v, h)
- }
- return Record { objects }
- }
- // Container (generic)
- // List (generic)
- if rt.Kind() == reflect.Slice {
- var n = rv.Len()
- var nodes = make([] ListNode, n)
- for i := 0; i < n; i += 1 {
- var item_rv = rv.Index(i)
- var item_v = item_rv.Interface()
- nodes[i].Value = MakeObject(item_v, h)
- }
- return NodesToList(nodes)
- }
- // Interface and Lambda (generic)
- // Lambda (generic)
- if isLambdaFuncReflectType(rt) {
- var get_in_rv func(Object)([] reflect.Value)
- if rt.NumIn() == 0 {
- get_in_rv = func(_ Object) ([] reflect.Value) {
- return nil
- }
- } else if rt.NumIn() == 1 {
- get_in_rv = func(arg Object) ([] reflect.Value) {
- var arg_ptr, arg_rv = reflectNew(rt.In(0))
- ConvertObject(arg, arg_ptr, h)
- return [] reflect.Value { arg_rv }
- }
- } else if rt.NumIn() == 2 {
- get_in_rv = func(arg Object) ([] reflect.Value) {
- var a_ptr, a_rv = reflectNew(rt.In(0))
- var b_ptr, b_rv = reflectNew(rt.In(1))
- var r = (*arg).(Record) // ctn.Pair
- ConvertObject(r.Objects[0], a_ptr, h)
- ConvertObject(r.Objects[1], b_ptr, h)
- return [] reflect.Value { a_rv, b_rv }
- }
- } else {
- panic("something went wrong")
- }
- var call = func(arg Object) Object {
- var in_rv = get_in_rv(arg)
- var out_rv = rv.Call(in_rv)
- var out = out_rv[0].Interface()
- return MakeObject(out, h)
- }
- var l = Lambda { call }
- if rt.Name() == "" {
- return l
- } else {
- if rt.NumIn() == 0 {
- return CraftSamInterface(l.Call(nil))
- } else {
- return CraftSamInterface(Obj(l))
- }
- }
- }
- panic("unsupported value type: " + rt.String())
- } })()
- return &o
- }
- func FromObject[T any] (o Object) T {
- var t T
- var p = &t
- ConvertObject(o, p, nil)
- return t
- }
- func ConvertObject(o Object, p interface{}, h RuntimeHandle) {
- if o == nil {
- return
- }
- if _, is_empty_struct := p.(*struct{}); is_empty_struct {
- panic("cannot assign non-nil object to struct{}")
- }
- if o_ptr, is_object_ptr := p.(*Object); is_object_ptr {
- *o_ptr = o
- return
- }
- { var o = *o
- switch P := p.(type) {
- // Primitive
- // Bool
- case *(bool):
- *P = bool(o.(Bool))
- // Int
- case *(*big.Int):
- *P = o.(Int).Value
- case *(int):
- *P = clampTo32Int(o.(Int).Value)
- // Float
- case *(float64):
- *P = float64(o.(Float))
- // Bytes
- case *([] byte):
- *P = o.(Bytes)
- // String
- case *(string):
- *P = string(o.(String))
- // Char
- case *(int32): // = rune
- *P = int32(o.(Char))
- // RegExp
- case *(*regexp.Regexp):
- *P = o.(RegExp).Value
- // Time
- case *(time.Time):
- *P = time.Time(o.(Time))
- // File
- case *(File):
- *P = o.(File)
- // Error
- case *(error):
- *P = o.(Error).Value
- // Reflect
- // ReflectType
- case *(ReflectType):
- *P = o.(ReflectType)
- // ReflectValue
- case *(ReflectValue):
- *P = o.(ReflectValue)
- // Rx
- // Observable
- case *(Observable):
- *P = o.(Observable)
- // Subject
- case *(Subject):
- *P = o.(Subject)
- // Interface and Lambda (Object)
- // Interface
- case *(Interface):
- *P = o.(Interface)
- // Lambda (Object)
- case *(Lambda):
- *P = o.(Lambda)
- // Container (Object)
- // List (Object)
- case *(List):
- *P = o.(List)
- // Seq
- case *(Seq):
- *P = o.(Seq)
- // Queue
- case *(Queue):
- *P = o.(Queue)
- // Heap
- case *(Heap):
- *P = o.(Heap)
- // Set
- case *(Set):
- *P = o.(Set)
- // Map
- case *(Map):
- *P = o.(Map)
- // GUI
- // Action
- case *(Action):
- *P = o.(Action)
- // Widget
- case *(Widget):
- *P = o.(Widget)
- // Signal
- case *(Signal):
- *P = o.(Signal)
- // Events
- case *(Events):
- *P = o.(Events)
- // Prop
- case *(Prop):
- *P = o.(Prop)
- // Union (Object)
- case *(Union):
- *P = o.(Union)
- default:
- var ptr_rv = reflect.ValueOf(p)
- // check for mistake
- if ptr_rv.Kind() != reflect.Ptr {
- panic("invalid argument")
- }
- var rv = ptr_rv.Elem()
- var rt = rv.Type()
- // Enum (int)
- if rt.Kind() == reflect.Int {
- var v = int(o.(Enum))
- rv.Set(reflect.ValueOf(v).Convert(rt))
- return
- }
- // Union (ctn.Maybe)
- if inner_rt, ok := ctn.ReflectTypeMatchMaybe(rt); ok {
- var u = o.(Union)
- if u.Index == OkIndex {
- var inner_ptr, inner_rv = reflectNew(inner_rt)
- ConvertObject(u.Object, inner_ptr, h)
- rv.Set(ctn.ReflectJust(inner_rv))
- } else if u.Index == NgIndex {
- rv.Set(ctn.ReflectNothing(inner_rt))
- } else {
- panic("something went wrong")
- }
- return
- }
- // Record (ctn.Pair)
- if a_rt, b_rt, ok := ctn.ReflectTypeMatchPair(rt); ok {
- var r = o.(Record)
- var a_ptr, a_rv = reflectNew(a_rt)
- var b_ptr, b_rv = reflectNew(b_rt)
- ConvertObject(r.Objects[0], a_ptr, h)
- ConvertObject(r.Objects[1], b_ptr, h)
- rv.Set(ctn.ReflectMakePair(a_rv, b_rv))
- return
- }
- // Union (pseudo-union)
- if rt.Kind() == reflect.Struct {
- if rt.NumField() >= 1 {
- if rt.Field(0).Type == pseudoUnionTagReflectType {
- var u = o.(Union)
- var i = (u.Index + 1)
- var object_ptr_rv = rv.Field(i).Addr()
- var object_ptr = object_ptr_rv.Interface()
- rv.Field(0).SetInt(int64(i))
- ConvertObject(u.Object, object_ptr, h)
- return
- }}
- // Record (struct)
- var r = o.(Record)
- var n = len(r.Objects)
- for i := 0; i < n; i += 1 {
- var field_ptr_rv = rv.Field(i).Addr()
- var field_ptr = field_ptr_rv.Interface()
- ConvertObject(r.Objects[i], field_ptr, h)
- }
- return
- }
- // Container (generic)
- // List (generic)
- if rt.Kind() == reflect.Slice {
- var l = o.(List)
- var slice_rv = reflect.MakeSlice(rt, 0, 0)
- l.ForEach(func(el_obj Object) {
- var el_ptr_rv = reflect.New(rt.Elem())
- var el_ptr = el_ptr_rv.Interface()
- ConvertObject(el_obj, el_ptr, h)
- var el_rv = el_ptr_rv.Elem()
- slice_rv = reflect.Append(slice_rv, el_rv)
- })
- rv.Set(slice_rv)
- return
- }
- // Interface and Lambda (generic)
- // Lambda (generic)
- if isLambdaFuncReflectType(rt) {
- var l = (func() Lambda {
- if rt.Name() == "" {
- return o.(Lambda)
- } else {
- if h == nil {
- panic("SAM conversion without RuntimeHandle")
- }
- var I = o.(Interface)
- if rt.NumIn() == 0 {
- return getSamInterfaceValueAsLambda(I, h)
- } else {
- return getSamInterfaceLambda(I, h)
- }
- }
- })()
- var get_arg_obj func([] reflect.Value) Object
- if rt.NumIn() == 0 {
- get_arg_obj = func(_ ([] reflect.Value)) Object {
- return nil
- }
- } else if rt.NumIn() == 1 {
- get_arg_obj = func(in ([] reflect.Value)) Object {
- var in0_v = in[0].Interface()
- return MakeObject(in0_v, h)
- }
- } else if rt.NumIn() == 2 {
- get_arg_obj = func(in ([] reflect.Value)) Object {
- var in0_v = in[0].Interface()
- var in1_v = in[1].Interface()
- var a = MakeObject(in0_v, h)
- var b = MakeObject(in1_v, h)
- var pair = [] Object { a, b }
- var o = ObjectImpl(Record { pair })
- return &o
- }
- } else {
- panic("something went wrong")
- }
- var out_rt = rt.Out(0)
- var f_rv = reflect.MakeFunc(rt, func(in ([] reflect.Value)) ([] reflect.Value) {
- var arg = get_arg_obj(in)
- var ret = l.Call(arg)
- var out_ptr, out_rv = reflectNew(out_rt)
- ConvertObject(ret, out_ptr, h)
- var out = [] reflect.Value { out_rv }
- return out
- })
- rv.Set(f_rv)
- return
- }
- panic("unsupported pointer type: " + rt.String())
- } }
- }
- func MakeNativeFunction(v interface{}) NativeFunction {
- var rv = reflect.ValueOf(v)
- var rt = rv.Type()
- if !((rt.Kind() == reflect.Func) && !(rt.IsVariadic())) {
- panic("invalid argument")
- }
- return NativeFunction(func(args ([] Object), ctx ([] Object), h RuntimeHandle) Object {
- var num_in = rt.NumIn()
- var num_out = rt.NumOut()
- var in = make([] reflect.Value, num_in)
- for i := 0; i < num_in; i += 1 {
- var in_t = rt.In(i)
- if i < len(args) {
- var arg = args[i]
- var arg_ptr, arg_rv = reflectNew(in_t)
- ConvertObject(arg, arg_ptr, h)
- in[i] = arg_rv
- } else {
- var j = (i - len(args))
- if j < len(ctx) {
- var item = ctx[j]
- var item_ptr, item_rv = reflectNew(in_t)
- ConvertObject(item, item_ptr, h)
- in[i] = item_rv
- } else {
- in[i] = reflect.ValueOf(h)
- }
- }
- }
- var out = rv.Call(in)
- if num_out == 0 {
- return nil
- } else if num_out == 1 {
- var out_v = out[0].Interface()
- return MakeObject(out_v, h)
- } else {
- panic("invalid argument")
- }
- })
- }
- func retrieveObject[T any] (o Observable, h RuntimeHandle, k func(T)(Observable)) Observable {
- return Observable(func(pub DataPublisher) {
- var ctx, ob = pub.useInheritedContext()
- pub.run(o, ctx, awaitNoexceptObserver(ob, h, func(obj Object) {
- pub.run(k(FromObject[T](obj)), ctx, ob)
- }))
- })
- }
- func retrieveObjectInChildContext[T any] (parent *context, o Observable, h RuntimeHandle, k func(T,*context,func())(Observable)) Observable {
- return Observable(func(pub DataPublisher) {
- var _, ob = pub.useInheritedContext()
- var ctx, dispose = parent.createChild()
- pub.run(o, ctx, awaitNoexceptObserver(ob, h, func(obj Object) {
- pub.run(k(FromObject[T](obj), ctx, dispose), ctx, ob)
- }))
- })
- }
- func doSync(k func()) Observable {
- return Observable(func(pub DataPublisher) {
- pub.SyncReturn(func() (Object, error) {
- k()
- return nil, nil
- })
- })
- }
- func doSync1[T any] (k func()(T)) Observable {
- return Observable(func(pub DataPublisher) {
- pub.SyncReturn(func() (Object, error) {
- var t = k()
- return ToObject(t), nil
- })
- })
- }
- func doSync2[T any] (k func()(T,func())) Observable {
- return Observable(func(pub DataPublisher) {
- pub.SyncReturn(func() (Object, error) {
- var t, c = k()
- pub.context.registerCleaner(c)
- return ToObject(t), nil
- })
- })
- }
- func onSync(k func()(func(qt.Pkg,func()))) Observable {
- return Observable(func(pub DataPublisher) {
- var pkg, dispose = qt.CreatePkg()
- pub.context.registerCleaner(dispose)
- k()(pkg, func() {
- pub.observer.value(nil)
- })
- })
- }
- func onSync1[T any] (k func()(func(qt.Pkg,func(T)))) Observable {
- return Observable(func(pub DataPublisher) {
- var pkg, dispose = qt.CreatePkg()
- pub.context.registerCleaner(dispose)
- k()(pkg, func(v T) {
- pub.observer.value(ToObject(v))
- })
- })
- }
- func reflectNew(t reflect.Type) (interface{}, reflect.Value) {
- var ptr_rv = reflect.New(t)
- var ptr = ptr_rv.Interface()
- var rv = ptr_rv.Elem()
- return ptr, rv
- }
- func isLambdaFuncReflectType(t reflect.Type) bool {
- return (t.Kind() == reflect.Func) &&
- !(t.IsVariadic()) &&
- (t.NumIn() == 0 || t.NumIn() == 1 || t.NumIn() == 2) &&
- (t.NumOut() == 1)
- }
- func getSamInterfaceLambda(I Interface, h RuntimeHandle) Lambda {
- if len(I.DispatchTable.Methods) == 1 && len(I.DispatchTable.Children) == 0 {
- return (*(CallFirstMethod(I, h))).(Lambda)
- } else {
- panic("expect SAM interface but got non-SAM interface")
- }
- }
- func getSamInterfaceValueAsLambda(I Interface, h RuntimeHandle) Lambda {
- if len(I.DispatchTable.Methods) == 1 && len(I.DispatchTable.Children) == 0 {
- var value = CallFirstMethod(I, h)
- return Lambda { func(_ Object) Object {
- return value
- }}
- } else {
- panic("expect SAM interface but got non-SAM interface")
- }
- }
- var maxInt32 = big.NewInt(math.MaxInt32)
- var minInt32 = big.NewInt(math.MinInt32)
- func clampTo32Int(n *big.Int) int {
- if n.Cmp(maxInt32) > 0 {
- return math.MaxInt32
- } else if n.Cmp(minInt32) < 0 {
- return math.MinInt32
- } else {
- return int(n.Int64())
- }
- }
- func ObjInt(n int) Object {
- return ObjIntFromInt64(int64(n))
- }
- func ObjIntFromBigInt(n *big.Int) Object {
- return Obj(Int { n })
- }
- func ObjIntFromInt64(n int64) Object {
- return Obj(Int { big.NewInt(n) })
- }
- func ObjBool(p bool) Object {
- return Obj(Bool(p))
- }
- func ObjFloat(x float64) Object {
- return Obj(Float(x))
- }
- func ObjString(s string) Object {
- return Obj(String(s))
- }
- func ObjBytes(b ([] byte)) Object {
- return Obj(Bytes(b))
- }
- func ObjPair(a Object, b Object) Object {
- return Obj(Record { Objects: [] Object { a, b } })
- }
- func ObjList(l ([] Object)) Object {
- var buf ListBuilder
- for _, item := range l {
- buf.Append(item)
- }
- return Obj(buf.Collect())
- }
- func ObjQueue(q ctn.Queue[Object]) Object {
- return Obj(Queue(q))
- }
- func ObjTime(t time.Time) Object {
- return Obj(Time(t))
- }
- func ObjTimeNow() Object {
- return ObjTime(time.Now())
- }
- func ObjFile(path string) Object {
- return Obj(File { path })
- }
- func GetBool(o Object) bool {
- return bool((*o).(Bool))
- }
- func GetInt(o Object) int {
- return clampTo32Int((*o).(Int).Value)
- }
- func GetIntAsRawBigInt(o Object) *big.Int {
- return (*o).(Int).Value
- }
- func GetFloat(o Object) float64 {
- return float64((*o).(Float))
- }
- func GetChar(o Object) rune {
- return int32((*o).(Char))
- }
- func GetString(o Object) string {
- return string((*o).(String))
- }
- func GetBytes(o Object) ([] byte) {
- return ([] byte)((*o).(Bytes))
- }
- func GetError(o Object) error {
- return (*o).(Error).Value
- }
- func GetPair(o Object) (Object, Object) {
- return FromObject[ctn.Pair[Object,Object]](o)()
- }
- func GetList(o Object) List {
- return (*o).(List)
- }
- func GetSeq(o Object) Seq {
- return (*o).(Seq)
- }
- func GetQueue(o Object) ctn.Queue[Object] {
- return ctn.Queue[Object]((*o).(Queue))
- }
- func GetHeap(o Object) ctn.Heap[Object] {
- return ctn.Heap[Object]((*o).(Heap))
- }
- func GetSet(o Object) ctn.Set[Object] {
- return ctn.Set[Object]((*o).(Set))
- }
- func GetMap(o Object) ctn.Map[Object,Object] {
- return ctn.Map[Object,Object]((*o).(Map))
- }
- func GetTime(o Object) time.Time {
- return time.Time((*o).(Time))
- }
- func GetFile(o Object) File {
- return (*o).(File)
- }
- func GetObservable(o Object) Observable {
- return (*o).(Observable)
- }
- func GetWidget(o Object) Widget {
- return (*o).(Widget)
- }
- func YieldObservables(o ...Observable) func(func(Observable)) {
- return func(yield func(Observable)) {
- for _, o := range o {
- yield(o)
- }
- }
- }
- func ListToPair(o Object) Object {
- var l = GetList(o)
- a, l, ok1 := l.Shifted()
- b, l, ok2 := l.Shifted()
- if !(ok1 && ok2) { panic("invalid argument") }
- return ObjPair(a, b)
- }
- func QueueToPair(o Object) Object {
- var q = GetQueue(o)
- a, q, ok1 := q.Shifted()
- b, q, ok2 := q.Shifted()
- if !(ok1 && ok2) { panic("invalid argument") }
- return ObjPair(a, b)
- }
|