package main import ( "runtime" "unsafe" ) var irResults []string var importRegistry map[string]*TCPackage func ensureImportRegistry() { if importRegistry == nil { importRegistry = map[string]*TCPackage{} } } //export moxie_compile_to_ir func moxie_compile_to_ir(srcPtr unsafe.Pointer, srcLen int32, namePtr unsafe.Pointer, nameLen int32, triplePtr unsafe.Pointer, tripleLen int32) int32 { runtime.InitCShared() src := unsafe.Slice((*byte)(srcPtr), srcLen) name := string(unsafe.Slice((*byte)(namePtr), nameLen)) triple := string(unsafe.Slice((*byte)(triplePtr), tripleLen)) ir := CompileToIR(src, name, triple) idx := int32(len(irResults)) irResults = append(irResults, ir) return idx } //export moxie_compile_ir_len func moxie_compile_ir_len(h int32) int32 { runtime.InitCShared() if h < 0 || int(h) >= len(irResults) { return 0 } return int32(len(irResults[h])) } //export moxie_compile_ir_copy func moxie_compile_ir_copy(h int32, dst unsafe.Pointer, cap int32) int32 { runtime.InitCShared() if h < 0 || int(h) >= len(irResults) { return 0 } ir := irResults[h] n := int32(len(ir)) if n > cap { n = cap } if n > 0 { buf := unsafe.Slice((*byte)(dst), n) copy(buf, ir[:n]) } return n } //export moxie_compile_ir_free func moxie_compile_ir_free(h int32) { runtime.InitCShared() if h >= 0 && int(h) < len(irResults) { irResults[h] = "" } } //export moxie_register_package func moxie_register_package(pathPtr unsafe.Pointer, pathLen int32, namePtr unsafe.Pointer, nameLen int32) { runtime.InitCShared() ensureImportRegistry() path := string(unsafe.Slice((*byte)(pathPtr), pathLen)) name := string(unsafe.Slice((*byte)(namePtr), nameLen)) importRegistry[path] = NewTCPackage(path, name) } //export moxie_register_func func moxie_register_func(pkgPathPtr unsafe.Pointer, pkgPathLen int32, namePtr unsafe.Pointer, nameLen int32, sigPtr unsafe.Pointer, sigLen int32) { runtime.InitCShared() ensureImportRegistry() pkgPath := string(unsafe.Slice((*byte)(pkgPathPtr), pkgPathLen)) name := string(unsafe.Slice((*byte)(namePtr), nameLen)) sigDesc := string(unsafe.Slice((*byte)(sigPtr), sigLen)) pkg := importRegistry[pkgPath] if pkg == nil { return } sig := parseSignatureDesc(sigDesc) pkg.Scope().Insert(NewTCFunc(pkg, name, sig)) } //export moxie_register_var func moxie_register_var(pkgPathPtr unsafe.Pointer, pkgPathLen int32, namePtr unsafe.Pointer, nameLen int32, typDescPtr unsafe.Pointer, typDescLen int32) { runtime.InitCShared() ensureImportRegistry() pkgPath := string(unsafe.Slice((*byte)(pkgPathPtr), pkgPathLen)) name := string(unsafe.Slice((*byte)(namePtr), nameLen)) typDesc := string(unsafe.Slice((*byte)(typDescPtr), typDescLen)) pkg := importRegistry[pkgPath] if pkg == nil { return } typ := parseTypeDesc(typDesc) pkg.Scope().Insert(NewTCVar(pkg, name, typ)) } //export moxie_register_iface func moxie_register_iface(pkgPathPtr unsafe.Pointer, pkgPathLen int32, namePtr unsafe.Pointer, nameLen int32, methodsPtr unsafe.Pointer, methodsLen int32) { runtime.InitCShared() ensureImportRegistry() pkgPath := string(unsafe.Slice((*byte)(pkgPathPtr), pkgPathLen)) name := string(unsafe.Slice((*byte)(namePtr), nameLen)) methodsDesc := string(unsafe.Slice((*byte)(methodsPtr), methodsLen)) pkg := importRegistry[pkgPath] if pkg == nil { return } var methods []*IfaceMethod if methodsDesc != "" { parts := splitSemicolon(methodsDesc) for _, p := range parts { eqIdx := -1 for i := 0; i < len(p); i++ { if p[i] == '=' { eqIdx = i break } } if eqIdx < 0 { continue } mname := p[:eqIdx] msig := parseSignatureDesc(p[eqIdx+1:]) methods = append(methods, NewTCIfaceMethod(mname, msig)) } } iface := NewTCInterface(methods, nil) iface.Complete() tn := NewTypeName(pkg, name, iface) pkg.Scope().Insert(tn) } func splitSemicolon(s string) []string { var parts []string start := 0 for i := 0; i < len(s); i++ { if s[i] == ';' { parts = append(parts, s[start:i]) start = i + 1 } } parts = append(parts, s[start:]) return parts } //export moxie_clear_imports func moxie_clear_imports() { runtime.InitCShared() ensureImportRegistry() importRegistry = map[string]*TCPackage{} } func parseTypeDesc(desc string) Type { switch desc { case "bool": return Typ[Bool] case "int8": return Typ[Int8] case "int16": return Typ[Int16] case "int32", "int": return Typ[Int32] case "int64": return Typ[Int64] case "uint8", "byte": return Typ[Uint8] case "uint16": return Typ[Uint16] case "uint32", "uint": return Typ[Uint32] case "uint64": return Typ[Uint64] case "float32": return Typ[Float32] case "float64": return Typ[Float64] case "string": return Typ[TCString] case "ptr": return Typ[UnsafePointer] case "error": errorSig := NewSignature(nil, nil, NewTuple(NewTCVar(nil, "", Typ[TCString])), false) errorIface := NewTCInterface([]*IfaceMethod{NewTCIfaceMethod("Error", errorSig)}, nil) errorIface.Complete() return errorIface case "interface{}": emptyIface := NewTCInterface(nil, nil) emptyIface.Complete() return emptyIface } if len(desc) > 2 && desc[0] == '[' && desc[1] == ']' { elem := parseTypeDesc(desc[2:]) if b, ok := elem.(*Basic); ok && b.kind == Uint8 { return Typ[TCString] } return NewSlice(elem) } if len(desc) > 1 && desc[0] == '*' { return NewPointer(parseTypeDesc(desc[1:])) } return Typ[Int32] } func parseSignatureDesc(desc string) *Signature { // format: "param1,param2->result1,result2" or "param1,param2" (void) or "->result" (no params) arrow := -1 for i := 0; i < len(desc)-1; i++ { if desc[i] == '-' && desc[i+1] == '>' { arrow = i break } } var paramStr, resultStr string if arrow >= 0 { paramStr = desc[:arrow] resultStr = desc[arrow+2:] } else { paramStr = desc } var params []*TCVar if paramStr != "" { parts := splitComma(paramStr) for _, p := range parts { params = append(params, NewTCVar(nil, "", parseTypeDesc(p))) } } var results []*TCVar if resultStr != "" { parts := splitComma(resultStr) for _, r := range parts { results = append(results, NewTCVar(nil, "", parseTypeDesc(r))) } } var pTuple, rTuple *Tuple if len(params) > 0 { pTuple = NewTuple(params...) } if len(results) > 0 { rTuple = NewTuple(results...) } return NewSignature(nil, pTuple, rTuple, false) } func splitComma(s string) []string { var parts []string start := 0 for i := 0; i < len(s); i++ { if s[i] == ',' { parts = append(parts, s[start:i]) start = i + 1 } } parts = append(parts, s[start:]) return parts } func main() {}