Go -> Haxe -> JS Java C# C++ C Python Lua

go2hx

Compile: Go -> Haxe -> Js, Lua, C#, C++, Java, C, Python

warning: heavily experimental still a ways to go before an alpha.

Come give feedback on what Go libraries you want supported!

Getting started

haxelib git go2hx https://github.com/go2hx/go2hx
haxelib run go2hx ./main.go

Shows percentage of tests passing out of total

Language features

go2hx supports a subset of language features that have not been extensively tested yet. It does not include any support for go routines, The list includes:

  • control flow statements for/if/range
  • all statements except statements relating to go routines, control-flows/branches/decls
  • all exprs conversion/literals/access

Standard library support

The standard library that has been rewritten in Haxe has partial support, It does not include any support for unsafe, embeds, testing, and cgo, The most supported libraries in order includes:

  • reflect
  • fmt
  • os
  • strings
  • strconv
  • math

Acknowledgement

A spiritual successor to Tardisgo written by Elliott Stoneham, The developer that has set the building blocks conceptually for this project, as well as a code contributor, with use of some of his code from Tardisgo.

Build from source

haxelib dev go2hx .

Look at Run.hx to see how the building occurs.

Comments
  • Go TypeSwitch

    Go TypeSwitch

    Currently can not use Abstracts as values for the "is" operator, blocked by needed compiler changes. https://github.com/HaxeFoundation/haxe/issues/2976

     x = Go.assert(((1 : Byte)));
    if ((x is UInt8)) { } else {
        panic("byte != uint8");
    };
    x = Go.assert(((2 : UInt8)));
    if ((x is Byte)) { } else {
        panic("uint8 != byte");
    };
    var rune32 = false;
    x = Go.assert(((3 : Rune)));
    if ((x is Int)) { } else if ((x is Int32)) {
        rune32 = true;
    } else {
        panic("rune != int and rune != int32");
    };
  • internal go type bug for signature

    internal go type bug for signature

    rnd/main.go

    package main
    
    func main() {
    	var x X
    	x.t()
    }
    
    type X int
    
    func (X) t() {
    }
    
    go run . ./rnd .
    

    Inside of check.json:

    {
          "hash": 0,
          "id": "Signature",
          "params": null,
          "recv": null,
          "results": null,
          "typeParams": [],
          "variadic": false
    }
    

    The fields stop being null if an arg is added to the t function.

    Can you try to replicate this @elliott5 it would be helpful.

  • Representation of Go pointers in go2hx

    Representation of Go pointers in go2hx

    All Haxe objects are of course pointers to the start of the contents of the object.

    But how to represent pointers to elements within an object, or elements within elements?

    I think a Go pointer type rendered in Haxe might contain two values:

    1. (a pointer to) the base object
    2. an array of indexes(into arrays) or field-names(for structures)

    So a pointer to Go element dingbat[4].foo.bar[26] would be{dingbat,[4,"foo","bar",26]} in Haxe (inside a Class of course).

    I fear Haxe reflection may be required to achieve this.

    I see @PXshadow may be ahead of me on this, due to his work on https://github.com/andyli/ptr.

  • Non linear benchmark when creating large buffers

    Non linear benchmark when creating large buffers

    package main
    
    import (
    	"bytes"
    	"fmt"
    	"time"
    )
    
    func main() {
    	const japanese = "日本語日本語日本語日"
    	var b bytes.Buffer
    	stamp := time.Now()
    	for i := 0; b.Len() < 5_000; i++ {
    		if i%100 == 0 {
    			b.WriteString(japanese)
    		} else {
    			b.WriteString("0123456789")
    		}
    	}
    	fmt.Println("elapsed:", time.Now().Sub(stamp).String())
    }
    

    5k:

    • Haxe: elapsed: 8.380918016s
    • Go: elapsed: 34.694µs

    10k:

    • Haxe: elapsed: 33.374898944s
    • Go: elapsed: 60.878µs

    The issue is very glaring when trying to run utf8 tests as Go has a wait time of less then a second for the init function and go2hx's Haxe code takes 4+ mins at least.

  • Go divide by zero behaviour

    Go divide by zero behaviour

    In Go, all integers panic when divided by zero. This is a different behaviour from Haxe.

    For floats & complexes, NaN should be returned. This means the code for complex number division in TardisGo was wrong (and so is wrong now in go2hx).

    Go has a specific test for divide-by-zero behaviour at https://golang.org/test/zerodivide.go

  • Access to native Haxe from go2hx Go

    Access to native Haxe from go2hx Go

    In GopherJS they have a specific js pseudo-Go module, see https://pkg.go.dev/github.com/gopherjs/gopherjs/js

    TardisGo also had a similar hx pseudo-Go module, see https://github.com/tardisgo/tardisgo/blob/e0dd9a7e46b597cdc4d310c8a677c2da7444008e/haxe/hx/hx.go

    So go2hx needs a similar pseudo-Go module. This will allow much of the reflect (and maybe other low-level) modules to be written in Go, and therefore able to reuse existing Go code from elsewhere.

    Originally posted by @elliott5 in https://github.com/PXshadow/go2hx/issues/8#issuecomment-796662137

  • Preface generated class and interface declarations with @:rtti

    Preface generated class and interface declarations with @:rtti

    I'm planning to fork this repo and write the prototype reflect module in the correct location.

    It would be really helpful to my testing @PXshadow if you could preface generated class and interface code with @:rtti.

    There will be more code generation tweaks required, if the prototype approach works.

  • first iteration of removing unneeded parts of reflect, and bringing b…

    first iteration of removing unneeded parts of reflect, and bringing b…

    This is the first version of a revamp for the reflect system, going to a full macro approach and as such @:rtti as well as typeName and other parts do not seem to be maintained. The main motiviation for a revamp is to make AnyInterface much more useful and deeply integrated with Reflect.

    It currently does not work at all at the moment and various places that @:rtti and other systems like type aliases and haxeClassPath have been removed.

    Some things need to be sorted as well, for instance:

    • How will the macro know the type when going into a function argument and having the type changed?
    • What system will be used for typeswitch?
    • Will anonymous functions now be correctly handled?

    List of changes

    • abstract Type -> class Type
    • abstract Kind -> @:enum abstract Kind
    • all golang func String() -> function toString() (haxe's equivlant https://api.haxe.org/Std.html#string)
    • remove @:rtti, typeName and is_pointer (can all be done via macros)
    • remove @:to function __promote() as it can be handled inside reflect
    • changed AnyInterface from value, typeName : String to value, type : Reflect.Type
    • removed all function typeName()
    • Removed fieldInfo as it isn't macro based.
    • Rewrote test harness in Go inside Rnd
  • GopherJS handling of goto

    GopherJS handling of goto

    I see from the part-generated code for goto in go2hx that you are thinking of using functions, that was my first thought too.

    As a cross-check, I thought it would be helpful to see how GopherJS did it...

    I took the example of a Go goto program from https://www.tutorialspoint.com/go/go_goto_statement.htm

    Set up GopherJS on a virtual machine (it now requires an old version of Go), and inspected what was generated.

    GopherJS uses a case statement to implement goto (but also for) ... so the Go code:

    func main() {
    	var a int = 10
    LOOP:
    	for a < 20 {
    		if a == 15 {
    			a = a + 1
    			goto LOOP
    		}
    		println("value of a:",a)
    		a++
    	}
    }
    

    ...generates this JS:

    	main = function() {
    		var a, $s;
    		/* */ $s = 0; s: while (true) { switch ($s) { case 0:
    		a = 10;
    		/* LOOP: */ case 1:
    		/* while (true) { */ case 2:
    			/* if (!(a < 20)) { break; } */ if(!(a < 20)) { $s = 3; continue; }
    			/* */ if (a === 15) { $s = 4; continue; }
    			/* */ $s = 5; continue;
    			/* if (a === 15) { */ case 4:
    				a = a + 1 >> 0;
    				/* goto LOOP */ $s = 1; continue;
    			/* } */ case 5:
    			console.log("value of a:", a);
    			a = a + (1) >> 0;
    		/* } */ $s = 2; continue; case 3:
    		$s = -1; return;
    		/* */ } return; }
    	};
    

    I hope that helps your thinking @PXshadow , let me know if you want to see other GopherJS examples.

  • front page instructions do not work for trivial program + should there be an

    front page instructions do not work for trivial program + should there be an "interp" target

    elliott@Elliotts-MacBook-Pro15-2 go2hx_june22 % haxelib run go2hx --interp ./main.go
    listening on local port: 6218
    Generated: golibs//Main.hx - 0.44kb
    haxe -cp golibs -lib go2hx --interp -m Main
    /usr/local/lib/haxe/lib/go2hx/git/stdgo/Go.hx:147: characters 10-25 : Too many arguments
    

    I don't think interp should even be an option now.

  • iota and methods on non-struct named types - example reflect.Kind

    iota and methods on non-struct named types - example reflect.Kind

    package main
    
    import "fmt"
    
    const (
    	Invalid Kind = iota
    	Bool
    	Int
    	Int8
    	Int16
    	Int32
    	Int64
    	Uint
    	Uint8
    	Uint16
    	Uint32
    	Uint64
    	Uintptr
    	Float32
    	Float64
    	Complex64
    	Complex128
    	String
    	UnsafePointer
    	Chan
    	Interface
    	Ptr
    	Slice
    	Array
    	Func
    	Map
    	Struct
    )
    
    type Kind int
    
    func (k Kind) String() string {
    	switch k {
    	case Bool:
    		return "bool"
    	case Int:
    		return "int"
    	case Int8:
    		return "int8"
    	case Int16:
    		return "int16"
    	case Int32:
    		return "int32"
    	case Int64:
    		return "int64"
    	case Uint:
    		return "uint"
    	case Uint8:
    		return "uint8"
    	case Uint16:
    		return "uint16"
    	case Uint32:
    		return "uint32"
    	case Uint64:
    		return "uint64"
    	case Uintptr:
    		return "uintptr"
    	case Float32:
    		return "float32"
    	case Float64:
    		return "float64"
    	case Complex64:
    		return "complex64"
    	case Complex128:
    		return "complex128"
    	case String:
    		return "string"
    	case UnsafePointer:
    		return "unsafe.Pointer"
    	case Chan:
    		return "chan"
    	case Interface:
    		return "interface"
    	case Ptr:
    		return "ptr"
    	case Slice:
    		return "slice"
    	case Array:
    		return "array"
    	case Func:
    		return "func"
    	case Map:
    		return "map"
    	case Struct:
    		return "struct"
    	default:
    		return "invalid"
    	}
    }
    
    func main() {
    	fmt.Println("Kind test harness")
    	for i := 0; i < 30; i++ {
    		k := Kind(i)
    		fmt.Println(i, k.String())
    	}
    }
    
    

    Does not compile on go2hx. Both because iota is not implemented; and because Go methods on non-struct named types are not implemented properly (no link between code and type).

  • Github action build failing for stdgo compile

    Github action build failing for stdgo compile

    Run npx haxe stdgo.hxml
    src/StdGo.hx:20: [unicode,unicode/utf8,unicode/utf16,math,math/bits,math/rand,sort,strings,flag,io,io/fs,testing/fstest,testing/iotest,testing/internal/testdeps,os,syscall,syscall/js,log,bytes,time,path,strconv,errors,runtime,log,encoding/base64,internal/oserror,encoding,bufio,regexp,regexp/syntax,encoding/binary,reflect,math/cmplx,sync/atomic,sync,internal/bytealg,internal/cpu]
    listening on local port: 6243
    nodejs server started
    child process exited: 2
    Error: Command failed with error 2
    Error: Process completed with exit code 1.
    

    It's especially annoying because most of the time rerunning the action again the 2nd run this issue does not show up. I think it's linked to memory usage but I'm not sure, any idea how to fix this would be appreciated.

    cc @elliott5

  • Should all tests using unsafe ptr conversions be skiped or worked on?

    Should all tests using unsafe ptr conversions be skiped or worked on?

    I'm working on strings and a few of the test methods use unsafe pointer conversions and usage for comparability I believe. It is advisable to simply skip these tests for now?

    cc @elliott5

  • multi var invalid order for setting the vars

    multi var invalid order for setting the vars

    func main() {
    	dc := 632
    	extra := 7
    	extraMask := 127
    	dc, fracc := dc>>extra, dc&extraMask
    	fmt.Println(dc, fracc)
    }
    
    function main():Void {
    	var _dc:GoInt = (632 : GoInt);
    	var _extra:GoInt = (7 : GoInt);
    	var _extraMask:GoInt = (127 : GoInt);
    	var _dc:GoInt = _dc >> _extra, _fracc:GoInt = _dc & _extraMask;
    	stdgo.fmt.Fmt.println(_dc, _fracc);
    }
    

    Haxe: 4, 4 Go: 4, 120

  • Jvm unit test errors

    Jvm unit test errors

    jvm|func0

    Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Lhaxe.jvm.Function; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [Lhaxe.jvm.Function; is in unnamed module of loader 'app')
            at github_com.go2hx.go4hx.rnd._Rnd.Rnd_Fields_.main(golibs/github_com/go2hx/go4hx/rnd/Rnd.hx:17)
            at github_com.go2hx.go4hx.rnd._Rnd.Rnd_Fields_.main(golibs/github_com/go2hx/go4hx/rnd/Rnd.hx:1)
    

    jvm|scope1

    Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Lgithub_com.go2hx.go4hx.rnd.Person; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [Lgithub_com.go2hx.go4hx.rnd.Person; is in unnamed module of loader 'app')
            at github_com.go2hx.go4hx.rnd._Rnd.Rnd_Fields_.main(golibs/github_com/go2hx/go4hx/rnd/Rnd.hx:37)
            at github_com.go2hx.go4hx.rnd._Rnd.Rnd_Fields_.main(golibs/github_com/go2hx/go4hx/rnd/Rnd.hx:1)
    

    Run commands:

    haxe rnd.hxml
    haxe -cp golibs extraParams.hxml -main github_com.go2hx.go4hx.rnd.Rnd --jvm runrnd.jar
    java -jar runrnd.jar
    
  • Go Only Codebase Feasibility In API Library

    Go Only Codebase Feasibility In API Library

    I'm working on a unified API library for a collection of niche internet services with the same underlying purpose.
    The goal is to make a compelling abstraction for using good services that suffer from unpredictable lifetimes, tooling & userbases.
    But this also dictates the codebase must be painlessly maintanable, concise and reusable - which is why I sought Haxe.
    That said, there is a great appeal to support more targets than Haxe officially allows, and Go is hard to leave out.
    Moreover, V is working to build Go support, and V appears an ambitious step forward from familiar stacks.

    I'm fond of this project and I think it should go it's novel path, and for me there's no hx2go to assess.
    Ultimately I'm looking to settle on a single accessible language that can be effortlessly ported to any ecosystem.
    Practically, most of the library is boilerplate binding APIs one-to-many, with few other functions for use in servers and web apps.
    In the short term, for this specific use case, how production dependable is go2hx, and would it sack any current Haxe targets?

GopherLua: VM and compiler for Lua in Go

GopherLua: VM and compiler for Lua in Go. GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal with Lua: Be a scripting lang

Jan 9, 2023
A Lua VM in Go

A Lua VM in pure Go go-lua is a port of the Lua 5.2 VM to pure Go. It is compatible with binary files dumped by luac, from the Lua reference implement

Jan 4, 2023
A Lua 5.3 VM and compiler written in Go.

DCLua - Go Lua Compiler and VM: This is a Lua 5.3 VM and compiler written in Go. This is intended to allow easy embedding into Go programs, with minim

Dec 12, 2022
Java properties scanner for Go

Overview Please run git pull --tags to update the tags. See below why. properties is a Go library for reading and writing properties files. It support

Jan 7, 2023
gpython is a python interpreter written in go "batteries not included"

gpython gpython is a part re-implementation / part port of the Python 3.4 interpreter to the Go language, "batteries not included". It includes: runti

Dec 28, 2022
Grumpy is a Python to Go source code transcompiler and runtime.

Grumpy: Go running Python Overview Grumpy is a Python to Go source code transcompiler and runtime that is intended to be a near drop-in replacement fo

Jan 7, 2023
Golang->Haxe->CPP/CSharp/Java/JavaScript transpiler

TARDIS Go -> Haxe transpiler Haxe -> C++ / C# / Java / JavaScript Project status: a non-working curiosity, development currently on-ice The advent of

Dec 30, 2022
🎀 a nice lil shell for lua people made with go and lua

Hilbish ?? a nice lil shell for lua people made with go and lua It is currently in a mostly beta state but is very much usable (I'm using it right now

Jan 3, 2023
LuaHelper is a High-performance lua plugin, Language Server Protocol for lua.
LuaHelper is a High-performance lua plugin, Language Server Protocol for lua.

LuaHelper is a High-performance lua plugin, Language Server Protocol for lua.

Dec 29, 2022
Aes for go and java; build go fo wasm and use wasm parse java response.

aes_go_wasm_java aes for go and java; build go fo wasm and use wasm parse java response. vscode setting config settings.json { "go.toolsEnvVars":

Dec 14, 2021
Update-java-ca-certificates - Small utility to convert the system trust store to a system Java KeyStore

update-java-ca-certificates This small utility takes care of creating a system-w

Dec 28, 2022
convert curl commands to Python, JavaScript, Go, PHP, R, Dart, Java, MATLAB, Rust, Elixir and more
convert curl commands to Python, JavaScript, Go, PHP, R, Dart, Java, MATLAB, Rust, Elixir and more

curlconverter curlconverter transpiles curl commands into programs in other programming languages. $ curlconverter --data "Hello, world!" example.com

Jan 2, 2023
Solutions to AlgoExpert Problems in Six Programming Languages: Python, Java, Go, C++, C#, JavaScript/TypeScript
Solutions to AlgoExpert Problems in Six Programming Languages: Python, Java, Go, C++, C#, JavaScript/TypeScript

Solutions to AlgoExpert Problems in Six Programming Languages: Python, Java, Go, C++, C#, JavaScript/TypeScript Discover solutions to AlgoExpert probl

Dec 11, 2022
High level go to Lua binder. Write less, do more.
High level go to Lua binder. Write less, do more.

Binder High level go to Lua binder. Write less, do more. Package binder allows to easily bind to Lua. Based on gopher-lua. Write less, do more! Killer

Oct 9, 2022
A Lua VM in Go

A Lua VM in pure Go go-lua is a port of the Lua 5.2 VM to pure Go. It is compatible with binary files dumped by luac, from the Lua reference implement

Dec 31, 2022
Go bindings for Lua C API - in progress

Go Bindings for the lua C API Simplest way to install: # go get github.com/aarzilli/golua/lua You can then try to run the examples: $ cd golua/_examp

Dec 28, 2022
GopherLua: VM and compiler for Lua in Go

GopherLua: VM and compiler for Lua in Go. GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal with Lua: Be a scripting lang

Dec 24, 2022
:tophat: Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support
:tophat: Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support

Web server with built-in support for QUIC, HTTP/2, Lua, Markdown, Pongo2, HyperApp, Amber, Sass(SCSS), GCSS, JSX, BoltDB (built-in, stores the databas

Jan 1, 2023
Go bindings for Lua C API - in progress

Go Bindings for the lua C API Simplest way to install: # go get github.com/aarzilli/golua/lua You can then try to run the examples: $ cd golua/_examp

Dec 28, 2022
A Lua VM in Go

A Lua VM in pure Go go-lua is a port of the Lua 5.2 VM to pure Go. It is compatible with binary files dumped by luac, from the Lua reference implement

Jan 8, 2023