Releases: goplus/xgo
v1.2.1
highlights:
- The compilation speed of Go+ has been improved a lot. Compiling the complete Go+ tutorials (github.com/goplus/tutorial) has been increased by 50 times, and compiling all examples from the spx repository (github.com/goplus/spx) is also 10x faster.
features:
- cl: TypeAsParamsFunc/Method (#1706 goplus/gogen#367)
- cl: FuncAlias (#1705 #1719 #1722 #1729)
- cl: InitGopPkg optimization (#1715 goplus/gogen#333)
- cl: gox.GeneratedHeader set to Go+ (#1717)
- cl: TestYaptest use Gopo_xxx to make it more friendly (#1718 #1720)
- gop go/build/install/test/run: share importer (#1727 #1728 #1731)
- gengo: saveWithGopMod (#1721)
- gengo: support convert go+ files into go code (#1704)
ci/cd tools:
- ci: skip publish prerelease (#1712)
changes:
- parser: ParseFSFiles fix: support SaveAbsFile flag (#1724)
- cl: classfile: sorted workers (#1723)
- scanner: fix ... insertSemi (#1707 #1708 #1709)
Go+ Classfiles
Rob Pike once said that if he could only introduce one feature to Go, he would choose interface
instead of goroutine
. classfile
is as important to Go+ as interface
is to Go.
In the design philosophy of Go+, we do not recommend DSL
(Domain Specific Language). But SDF
(Specific Domain Friendliness) is very important. The Go+ philosophy about SDF
is:
Don't define a language for specific domain.
Abstract domain knowledge for it.
Go+ introduces classfile
to abstract domain knowledge.
Sound a bit abstract? Let's take web programming as an example. First let us initialize a hello project:
gop mod init hello
Then we have it reference a classfile called yap
as the HTTP Web Framework:
gop get github.com/goplus/yap@latest
We can use it to implement a static file server:
static "/foo", FS("public")
static "/" # Equivalent to static "/", FS("static")
run ":8080"
We can also add the ability to handle dynamic GET/POST requests:
static "/foo", FS("public")
static "/" # Equivalent to static "/", FS("static")
get "/p/:id", ctx => {
ctx.json {
"id": ctx.param("id"),
}
}
run ":8080"
Save this code to hello_yap.gox
file and execute:
mkdir -p yap/static yap/public # Static resources can be placed in these directories
gop mod tidy
gop run .
A simplest web program is running now. At this time, if you visit http://localhost:8080/p/123, you will get:
{"id":"123"}
Why is yap
so easy to use? How does it do it? Click here to learn more about the Go+ Classfiles mechanism and YAP HTTP Web Framework.
v1.2.0
v1.2.0-pre.2
features:
- typeparams cast (#1656 goplus/gogen#342 goplus/gogen#344)
- overload types (#1670 #1672 goplus/gogen#339 goplus/gogen#340)
- overload func/method/operators (#1631 #1642 #1675 #1676 #1677 goplus/gogen#355 goplus/gogen#356)
- classfile: add _test.gox (a classfile for testing) (#1662 #1666 #1667 goplus/gogen#348 goplus/gogen#349)
- classfile: support using multiple projects (#1651)
- classfile: support Main(app, workers...) (#1653)
- stringLitEx:
${expr}
(#1636 #1637 #1646) - cl: export classNameAndExt (#1612)
- cl: set debug mark
const _ = true
(#1647 #1649 #1650) - cl: add builtin function
echo
(#1648) - Go 1.22 support (#1629 #1633)
articles:
ci/cd tools:
- build and publish winget with goreleaser (#1614 #1616 #1617 #1621 #1655)
- build deb/rpm snap (#1625 #1655)
- build Go+ demo (in $GOPROOT/testdata directory) (#1619)
changes:
- parser: fix
ParseFSEntry
for new classfile tech (#1618) - parser: fix
ParseFSDir/ParseFSEntry
set class kind if file valid (#1634) - parser: fix
parse println x...
(#1644 #1659) - parser: ast.FuncDecl add IsClass for check set recv by class (#1620)
- cl preloadGopFile optimization (#1661)
- cl preloadGopFile bugfix: pkg.SetCurFile (#1669)
- cl: toType error return types.Invalid (#1628)
- cl: instantiate use gox pkg.Instantiate (#1654)
- cl newGmx bugfix: use classNameAndExt (#1610)
- cl: call gmxMainFunc only if no main func (#1648 #1658)
- cl: NewPackage preload Go+ first and then Go files (#1630)
- ast: fix Walk ast.File if NoPkgDecl (#1624)
- ast.Walk: support OverloadFuncDecl (#1671)
- format: gop fmt .gox bugfix (#1643)
- x/typesutil: fix checker.Files skip bad file (#1623)
- x/build: use modfile.ClassExt (#1664)
- iOverloadType/iSubstType (goplus/gogen#350 #1665)
- gox.Context (#1640 #1641 #1645)
Goodbye printf
For professional programmers, printf
is a very familiar function, and it can be found in basically every language. However, printf
is one of the most difficult functions for beginners to master:
age := 10
printf "age = %d\n", age
Here %d
means to format an integer value and \n
means a newline.
To simplify format information in most cases, Go+ introduces ${expr}
expressions in string literals:
age := 10
println "age = ${age}"
This is a bit like how you feel at the *nix
command line, right? To be more like it, we introduced a new builtin echo
as an alias for println
:
age := 10
echo "age = ${age}"
Go+ Classfiles
Rob Pike once said that if he could only introduce one feature to Go, he would choose interface
instead of goroutine
. classfile
is as important to Go+ as interface
is to Go.
In the design philosophy of Go+, we do not recommend DSL
(Domain Specific Language). But SDF
(Specific Domain Friendliness) is very important. The Go+ philosophy about SDF
is:
Don't define a language for specific domain.
Abstract domain knowledge for it.
Go+ introduces classfile
to abstract domain knowledge.
classfile: Unit Test
Go+ has a built-in classfile to simplify unit testing. This classfile has the file suffix _test.gox
.
Suppose you have a function named foo
:
func foo(v int) int {
return v * 2
}
Then you can create a foo_test.gox
file to test it (see unit-test/foo_test.gox):
if v := foo(50); v != 100 {
t.error "foo(50) ret: ${v}"
}
t.run "foo -10", t => {
if foo(-10) != -20 {
t.fatal "foo(-10) != -20"
}
}
You don't need to define a series of TestXXX
functions like Go, just write your test code directly.
If you want to run a subtest case, use t.run
.
yap: Yet Another Go/Go+ HTTP Web Framework
This classfile has the file suffix _yap.gox
.
Before using yap
, you need to add it to go.mod
by using go get
:
go get github.com/goplus/yap@latest
Find require github.com/goplus/yap
statement in go.mod
and add //gop:class
at the end of the line:
require github.com/goplus/yap v0.7.2 //gop:class
Router and Parameters
demo (hello_yap.gox):
get "/p/:id", ctx => {
ctx.json {
"id": ctx.param("id"),
}
}
run ":8080"
Static files
Static files server demo (staticfile_yap.gox):
static "/foo", FS("public")
static "/"
run ":8080"
YAP Template
demo (blog_yap.gox, article_yap.html):
get "/p/:id", ctx => {
ctx.yap "article", {
"id": ctx.param("id"),
}
}
run ":8080"
yaptest: HTTP Test Framework
This classfile has the file suffix _ytest.gox
.
Before using yaptest
, you need to add yap
to go.mod
:
require github.com/goplus/yap v0.7.2 //gop:class
demo to test your HTTP server (example_ytest.gox):
title := Var(string)
author := Var(string)
id := "123"
get "https://example.com/p/${id}"
ret 200
json {
"title": title,
"author": author,
}
echo "title:", title
echo "author:", author
spx: A Go+ 2D Game Engine for STEM education
This classfile has the file suffix .spx
. It is the earliest classfile in the world.
Before using spx
, you need to add it to go.mod
by using go get
:
go get github.com/goplus/spx@latest
It's also a built-in classfile so you don't need append //gop:class
after require github.com/goplus/spx
.
Through this example you can learn how to listen events and do somethings.
Here are some codes in Kai.spx:
onStart => {
say "Where do you come from?", 2
broadcast "1"
}
onMsg "2", => {
say "What's the climate like in your country?", 3
broadcast "3"
}
We call onStart
and onMsg
to listen events. onStart
is called when the program is started. And onMsg
is called when someone calls broadcast
to broadcast a message.
When the program starts, Kai says Where do you come from?
, and then broadcasts the message 1
. Who will recieve this message? Let's see codes in Jaime.spx:
onMsg "1", => {
say "I come from England.", 2
broadcast "2"
}
Yes, Jaime recieves the message 1
and says I come from England.
. Then he broadcasts the message 2
. Kai recieves it and says What's the climate like in your country?
.
The following procedures are very similar. In this way you can implement dialogues between multiple actors.
Overload Func/Method/Operators in Go+
Overload Funcs
Define overload func
in inline func literal
style (see overloadfunc1/add.gop):
func add = (
func(a, b int) int {
return a + b
}
func(a, b string) string {
return a + b
}
)
println add(100, 7)
println add("Hello", "World")
Define overload func
in ident
style (see overloadfunc2/mul.gop):
func mulInt(a, b int) int {
return a * b
}
func mulFloat(a, b float64) float64 {
return a * b
}
func mul = (
mulInt
mulFloat
)
println mul(100, 7)
println mul(1.2, 3.14)
Overload Methods
Define overload method
(see overloadmethod/method.gop):
type foo struct {
}
func (a *foo) mulInt(b int) *foo {
println "mulInt"
return a
}
func (a *foo) mulFoo(b *foo) *foo {
println "mulFoo"
return a
}
func (foo).mul = (
(foo).mulInt
(foo).mulFoo
)
var a, b *foo
var c = a.mul(100)
var d = a.mul(c)
Overload Unary Operators
Define overload unary operator
(see overloadop1/overloadop.gop):
type foo struct {
}
func -(a foo) (ret foo) {
println "-a"
return
}
func ++(a foo) {
println "a++"
}
var a foo
var b = -a
a++
Overload Binary Operators
Define overload binary operator
(see overloadop1/overloadop.gop):
type foo struct {
}
func (a foo) * (b foo) (ret foo) {
println "a * b"
return
}
func (a foo) != (b foo) bool {
println "a != b"
return true
}
var a, b foo
var c = a * b
var d = a != b
However, binary operator
usually need to support interoperability between multiple types. In this case it becomes more complex (see overloadop2/overloadop.gop):
type foo struct {
}
func (a foo) mulInt(b int) (ret foo) {
println "a * int"
return
}
func (a foo) mulFoo(b foo) (ret foo) {
println "a * b"
return
}
func intMulFoo(a int, b foo) (ret foo) {
println "int * b"
return
}
func (foo).* = (
(foo).mulInt
(foo).mulFoo
intMulFoo
)
var a, b foo
var c = a * 10
var d = a * b
var e = 10 * a
v1.2.0-pre.1
features:
- cl: classExt: support
_[class].gox
or.[class]
(#1606 goplus/mod#42) - cl: go.mod support
//gop:class
to import a classfile (#1607 goplus/mod#45) - cl: gop.mod: allow to define multiple projects (#1602 goplus/mod#39)
- cl: gop.mod: gop.mod is no longer a superset of go.mod (#1602 #1605)
- cl: support var document (eg. //go:embed) (#1597)
- cl: mixed overload (#1562)
- cl: fnType support TyTemplateRecvMethod overload funcs (#1584)
- cl: add typesRecorder for types check (#1564 #1568)
- cl: goxRecorder.call for overload func (#1586)
- cl: types record support command call for overload (#1594)
- cl: update gox support interface overload method (#1592)
- cl: types record for FuncLit (#1571)
- cl: record compileRangeStmt defined (#1569)
- cl: compileForPhraseStmt types record define kv (#1575)
- cl: compileComprehensionExpr types record define kv (#1577)
- cl: compileLambdaExpr types record define names (#1579 #1599)
changes:
- gop install: contains @ version use remote pkgpath (#1566 #1570)
- cl: fix initGopPkg GopPackage type (#1588)
- cl: add conf.RelativeBase and rm conf.WorkingDir/TargetDir/FileLineRoot (#1595 #1603)
- use the latest tag version and append it with "devel" to signify the binary installation via source code (#1574)
- make: fix bugs when checking if symbolic link path exists (#1581)
- mod: github.com/qiniu/x v1.13.2
- mod: golang.org/x/tools v0.16.1
- mod: github.com/goplus/mod v0.12.2
- mod: github.com/goplus/gox v1.13.2
- mod: github.com/goplus/c2go v0.7.19
classfile examples:
- https://github.com/goplus/yap/releases/tag/v0.5.0
- https://github.com/goplus/community
Router and Parameters
demo in Go+ classfile (hello_yap.gox):
get "/p/:id", ctx => {
ctx.json {
"id": ctx.param("id"),
}
}
handle "/", ctx => {
ctx.html `<html><body>Hello, <a href="/p/123">Yap</a>!</body></html>`
}
run ":8080"
YAP Template
demo in Go+ classfile (blog_yap.gox, article.yap):
get "/p/:id", ctx => {
ctx.yap "article", {
"id": ctx.param("id"),
}
}
run ":8080"
v1.1.13
new features:
- gop clean -t (#1549)
- support tinygo/gccgo: gocmd.Name use env GOP_GOCMD (#1550)
- standardize
//line
path (#1553 #1552 #1557) - cl/internal/typesutil: update TypeAndValue (#1545)
tinygo example:
GOP_GOCMD=tinygo gop run hello.gop
changes:
- gop.LoadDir fix: check mod valid (#1559)
- cl: commentFunc skip nil filename (#1547)
- cl: fix compileIdent check SelectorExpr in classfile (#1548)
- x/jsonrpc2: refactor stdio (#1558)
- x/typesutil: add tests (#1546)
- mod: github.com/goplus/gox v1.13.1
- mod: github.com/goplus/c2go 0.7.18
- mod: golang.org/x/tools 0.15.0
- mod: retract v1.1.12 (#1560)
v1.1.10
new features:
- code coverage of unit test (only support in Go1.20 or later) (#1510)
- gop go -ignore-notated-error (#1518)
- gop serve: run gop in langserver mode (#1522)
- gop/x/jsonrpc2 (#1519 #1522 #1525 #1526)
- gop/x/langserver (#1524 #1525 #1527)
- gop/parser: ParseFSEntry/ParseEntry (#1529)
- typesutil: ExprString (#1531)
- typesutil: DeleteObjects, CorrectTypesInfo (#1538)
- typesutil: Check support conf.Error (#1514 #1515 #1517)
- typesutil.Checker: config changed (use gop.mod) (#1528)
- typesutil/typeparams (#1533)
- modfetch.SetDebug (#1535)
- cl/internal/typesutil.NewTypeAndValue (#1532)
github actions:
- goplus/[email protected]: gop-version supports branch (goplus/setup-goplus#31)
changes:
- refactor: xxxError use Pos instead of Position (#1509)
- workflows: release-build use go-version 1.18 (#1511)
- gop/x/typesutil: Checker.Files always check go files (#1520)
- mv ClassFileExt: parser => cl (#1530)
- cl: preloadGopFile no change classfile ast (#1521)
- parser: fix parseGlobalStmts EOF check (#1512)
- parser: fix parsePrimaryExpr check literal value (#1513)
- mod: github.com/goplus/c2go v0.7.17
- mod: github.com/goplus/gox v1.13.0
- mod: github.com/goplus/mod v0.11.9
v1.1.9
new features:
- gop fmt -t: test if Go+ files are formatted or not (#1476)
- gop/ast: walk add Go+ expr and stmt (#1480)
- gop/ast: add FuncDecl.Shadow (#1490)
- gop/parser: parseGlobalStmts set main.FuncType.Pos (#1485)
- gop/parser: ParseExprFrom/ParseExpr (#1486)
- gop/x/typesutil.Checker (#1472 #1473 #1475 #1477 #1478 #1481 #1482 #1483 #1484 #1486 #1488 #1494 #1496 #1497 #1498 #1499 #1500 #1501 #1503)
- gop/env.Installed (#1471)
changes:
- gop/ast.File.Pos() fix (#1471)
- gop/parser: parsePrimaryExpr fix LiteralValue check (#1493)
- gox: newScope support start..end (#1491 goplus/gogen#294)
- gop: fix restore mod (#1502)
- update
gop_autogen.go
import style (#1489 goplus/gogen#293) - TestSpxPkgOverload (#1468, goplus/gogen#303)
- TestGenericTypeCompositeLit (#1495)
- mod: github.com/fsnotify/fsnotify v1.7.0
- mod: github.com/goplus/mod v0.11.8
- mod: github.com/goplus/gox v1.12.8
v1.1.8
new features:
- gop watch: when a Go+ file is changed it is transpiled to a Go file (#1424 #1425 #1427 #1437)
- gop doc: documentation for package or symbol (#1432 #1434 #1443 #1444 #1445 #1446)
- gop go -s -t: run
gop go
in single file mode & check mode (#1453 #1456 #1463) - classfile: getFields allow defining type before var (#1428)
github actions:
- goplus/setup-goplus@v1: downloading and caching a version of Go+ by version and adding to PATH
- marketplace: github.com/marketplace/actions/setup-goplus
- an example in production: github.com/goplus/tutorial/.../gop.yml
drafts:
changes:
- fix: type assignment error doesn't not dump position (#1429 #1430)
- cl fix: compileCallArgs recover check (#1457)
- cl fix: gmxSettings.getScheds check self for func setBodyHandler (#1459 #1460)
- gengo: dump error by dir (#1455)
- ast.File: NoEntrypoint => ShadowEntry (#1447)
- support go1.21 (#1433)
- mod: github.com/goplus/gox v1.12.5
- mod: github.com/goplus/mod v0.11.7
- mod: github.com/qiniu/x v1.13.1
- mod: golang.org/x/tools v0.14.0
v1.1.7
new features:
changes:
v1.1.6
incompatible changes:
- classfile: support multiple work-classes (#1380)
- classfile: register => import (#1404)
- classfile: rename .gopx => .gox (#1403)
- classfile: IsClass => ClassKind (#1404)
new features:
- classfile: support embed type (starExpr/selectorExpr) (#1386)
- classfile: field var support tag (#1393)
- classfile: support main.spx (#1404)
- compiler check untyped overflows for int128/uint128 (#1384)
changes: