Releases: goplus/xgo
v0.6.60
Commands
qexp
Usage: qexp [-outdir <outRootDir>] <goPkgPath>
-outdir string
optional set export lib path, default is $GoPlusRoot/lib path.
- Add supporting
-outdir <outRootDir>
flag. - Export constants and variables.
Thanks contribution of visualfc ([email protected]).
qgo
- Format go code
gop_autogen.go
after code generation. - Skip to build _xxx directories.
Thanks contribution of visualfc ([email protected]), tsingbx.
qrun
- Skip to build _xxx.gop files.
Thanks contribution of tsingbx.
qfmt
- Support qfmt from stdin.
Thanks contribution of go-wyvern.
TypeCast
b := []byte("Hello")
println(b)
Flow control
- goto label
- break [label]
- continue [label]
Thanks contribution of JessonChan ([email protected]).
Builtin
delete(mapData, key)
Thanks contribution of JessonChan ([email protected]).
Miscs
- ast.File: Rename HasUnnamed into NoEntrypoint.
- Increase code coverage to 88%+.
Thanks contribution of wangkuiyi ([email protected]), xushiwei ([email protected]).
v0.6.50
Commands
qrun
Enhancement: run <gopSrcFile>
as a Go+ script. See qrun for more detail.
Thanks contribution of jiangz222 ([email protected]).
qfmt
Format Go+ packages, similar to go fmt
. See qfmt for more detail.
Usage: qfmt [flags] [path ...]
-w write result to (source) file instead of stdout
Thanks contribution of visualfc ([email protected]), damonchen.
qexp
Generate a Go+ package that wraps a Go package automatically. See qexp for more detail.
Usage: qexp <goPkgPath>
Thanks contribution of xushiwei ([email protected]), visualfc ([email protected]).
Unix shebang
You can use Go+ programs as shell scripts now. For example:
#!/usr/bin/env qrun
println("Hello, Go+")
println(1r << 129)
println(1/3r + 2/7r*2)
arr := [1, 3, 5, 7, 11, 13, 17, 19]
println(arr)
println([x*x for x <- arr, x > 3])
m := {"Hi": 1, "Go+": 2}
println(m)
println({v: k for k, v <- m})
println([k for k, _ <- m])
println([v for v <- m])
Go tutorial/20-Unix-Shebang/shebang to get the source code.
Thanks contribution of jiangz222 ([email protected]).
Playground
All playgrounds support Go+ code formatting now.
- Playground based on GopherJS: https://qiniu.github.io/goplus-play/
- Playground based on Docker: https://play.goplus.org/
Thanks contribution of visualfc ([email protected]), qiukeren ([email protected]).
For loop
Thanks contribution of JessonChan ([email protected])
sum := 0
x := 0
for _, x = range [1, 3, 5, 7, 11, 13, 17] {
if x > 3 {
sum += x
}
}
println("sum(5,7,11,13,17):", sum)
Flow control
- fallthrough
Thanks contribution of JessonChan ([email protected])
Miscs
- Enrich pre-commit hooks and call them from Travis CI.
- Call gofmt at git commit time.
Thanks contribution of wangkuiyi.
v0.6.40
Playground
Playground based on Docker (See https://github.com/qiniu/goplus-www/tree/master/playground):
Playground based on GopherJS (See https://github.com/qiniu/goplus-play):
Thanks contribution of qiukeren ([email protected]), visualfc ([email protected]).
For loop
Thanks contribution of JessonChan ([email protected])
fns := make([]func() int, 3)
sum := 0
for _, x := range [1, 3, 5, 7, 11, 13, 17] {
if x > 3 {
sum += x
}
}
println("sum(5,7,11,13,17):", sum)
sum = 0
for i, x := range [3, 15, 777] {
v := x
fns[i] = func() int {
return v
}
}
println("values:", fns[0](), fns[1](), fns[2]())
sum = 0
arr := [1, 3, 5, 7, 11, 13, 17]
i := 10
for i = 0; i < len(arr); i++ {
if arr[i] > 3 {
sum += arr[i]
}
}
println("sum(5,7,11,13,17):", sum)
Inc/DecStmt
Thanks contribution of JessonChan ([email protected])
a, b := 2, 3
a++
b--
println(a, b)
v0.6.30
Rational number: bigint, bigrat, bigfloat
We introduce rational number as native Go+ types. We use -r suffix as a rational constant. For example, (1r << 200) means a big int whose value is equal to 2200. And 4/5r means the rational constant 4/5.
a := 1r << 65 // bigint, large than int64
b := 4/5r // bigrat
c := b - 1/3r + 3 * 1/2r
println(a, b, c)
Import go packages
Now we support importing constants/variables of Go packages.
Thanks contribution of visualfc ([email protected]).
Contributing
The Go+ project welcomes all contributors. We appreciate your help!
Here are list of Go+ Contributors. We award an email account ([email protected]) for every contributor. And we suggest you commit code by using this email account:
git config --global user.email [email protected]
What does a contributor of Go+
means? He must meet one of the following conditions:
- At least one pull request of a full feature implemention.
- At least three pull requests of feature enhancements.
- At least ten pull requests of any kind issues.
v0.6.20
Commands
qrun [-debug] [-prof] <qlangSrcDir>
- qrun -debug
<gopSrcDir>
: print debug information - qrun -prof
<gopSrcDir>
: do profile and generate profile report
Error handling
We reinvent error handling specification in Go+. We call them ErrWrap expressions
:
expr! // panic if err
expr? // return if err
expr?:defval // use defval if err
How to use them? Here is an example:
import (
"strconv"
)
func add(x, y string) (int, error) {
return strconv.Atoi(x)? + strconv.Atoi(y)?, nil
}
func addSafe(x, y string) int {
return strconv.Atoi(x)?:0 + strconv.Atoi(y)?:0
}
println(`add("100", "23"):`, add("100", "23")!)
sum, err := add("10", "abc")
println(`add("10", "abc"):`, sum, err)
println(`addSafe("10", "abc"):`, addSafe("10", "abc"))
The output of this example is:
add("100", "23"): 123
add("10", "abc"): 0 strconv.Atoi: parsing "abc": invalid syntax
===> errors stack:
main.add("10", "abc")
/Users/xsw/goplus/tutorial/15-ErrWrap/err_wrap.gop:6 strconv.Atoi(y)?
addSafe("10", "abc"): 10
Compared to corresponding Go code, It is clear and more readable.
And the most interesting thing is, the return error contains the full error stack. When we got an error, it is very easy to position what the root cause is.
How these ErrWrap expressions
work? See Error Handling for more information.
History Version (qlang)
v0.6.10
v0.6.03
Commands
qrun [-asm] [-quiet] <qlangSrcDir>
qgo [-test] <qlangSrcDir>
New features:
- qrun -quiet
<qlangSrcDir>
: don't generate any log. - qgo -test
<qlangSrcDir>
: converts qlang packages into Go packages, and then callgo run <qlangSrcDir>/qlang_autogen.go
andqrun -quiet <qlangSrcDir>
to compare their output. If output is not equal, the testcase fails.
Func & closure
Bug fixed:
- Now qgo generates correct Go codes for functions/closures.
Tutorial qgo -test
v0.6.02
Commands
qrun [-asm] <qlangSrcDir>
qgo <qlangSrcDir>
New features:
- qgo converts qlang packages into Go packages, recursively.
- qrun generates asm code when -asm switch specified.
Bugs:
- qgo may generate incorrect Go codes when closures exist.
Func & closure
Now support passing function pointers as parameters.
func bar(f func(string, ...interface{}) (int, error)) {
f("Hello, %v!\n", "qlang")
}
barVar := func(f func(string, ...interface{}) (int, error)) {
f("Hello, %v!\n", "qlang")
}
bar(printf)
barVar(printf)
String, map, array & slice
Now support indexing/slicing string/map/array.
x := []float64{1, 3.4, 5}
y := map[string]float64{"Hello": 1, "xsw": 3.4}
x[1], y["xsw"] = 1.7, 2.8
title := "Hello,world!" + "2020-05-27"
println(title[:len(title)-len("2006-01-02")], len(x), x[1:])
Builtin & typecast
a := make([]int, uint64(2))
a = append(a, 1, 2, 3)
println(a, "len:", len(a), "cap:", cap(a))
b := make([]int, 0, uint16(4))
c := [1, 2, 3]
b = append(b, c...)
println(b, "len:", len(b), "cap:", cap(b))
v0.6.01
Commands
qrun <qlangSrcDir>
- qrun run a qlang program from specified directory. It acts like
go run <golagSrcDir>/*.go
Variable & operator
x := 123.1 - 3i
y, z := 1, 123
s := "Hello"
println(s + " complex")
println(x - 1, y * z)
Condition
x := 0
if t := false; t {
x = 3
} else {
x = 5
}
x = 0
switch s := "Hello"; s {
default:
x = 7
case "world", "hi":
x = 5
case "xsw":
x = 3
}
v := "Hello"
switch {
case v == "xsw":
x = 3
case v == "Hello", v == "world":
x = 5
default:
x = 7
}
Import go package
import (
"fmt"
"strings"
)
x := strings.NewReplacer("?", "!").Replace("hello, world???")
fmt.Println("x:", x)
Func & closure
import (
"fmt"
"strings"
)
func foo(x string) string {
return strings.NewReplacer("?", "!").Replace(x)
}
func printf(format string, args ...interface{}) (n int, err error) {
n, err = fmt.Printf(format, args...)
return
}
x := "qlang"
fooVar := func(prompt string) (n int, err error) {
n, err = fmt.Println(prompt + x)
return
}
printfVar := func(format string, args ...interface{}) (n int, err error) {
n, err = fmt.Printf(format, args...)
return
}
Map, array & slice
x := []float64{1, 3.4, 5}
y := map[string]float64{"Hello": 1, "xsw": 3.4}
a := [...]float64{1, 3.4, 5}
b := [...]float64{1, 3: 3.4, 5}
c := []float64{2: 1.2, 3, 6: 4.5}
Map literal
x := {"Hello": 1, "xsw": 3.4} // map[string]float64
y := {"Hello": 1, "xsw": "qlang"} // map[string]interface{}
z := {"Hello": 1, "xsw": 3} // map[string]int
empty := {} // map[string]interface{}
Slice literal
x := [1, 3.4] // []float64
y := [1] // []int
z := [1+2i, "xsw"] // []interface{}
a := [1, 3.4, 3+4i] // []complex128
b := [5+6i] // []complex128
c := ["xsw", 3] // []interface{}
empty := [] // []interface{}
List/Map comprehension
a := [x * x for x <- [1, 3, 5, 7, 11]]
b := [x * x for x <- [1, 3, 5, 7, 11], x > 3]
c := [i + v for i, v <- [1, 3, 5, 7, 11], i%2 == 1]
d := [k + "," + s for k, s <- {"Hello": "xsw", "Hi": "qlang"}]
arr := [1, 2, 3, 4, 5, 6]
e := [[a, b] for a <- arr, a < b for b <- arr, b > 2]
x := {x: i for i, x <- [1, 3, 5, 7, 11]}
y := {x: i for i, x <- [1, 3, 5, 7, 11], i%2 == 1}
z := {v: k for k, v <- {1: "Hello", 3: "Hi", 5: "xsw", 7: "qlang"}, k > 3}
For loop
sum := 0
for x <- [1, 3, 5, 7, 11, 13, 17], x > 3 {
sum += x
}