Skip to content

Releases: goplus/gop

v1.3.0-pre.2

06 Sep 00:31
370a8e4
Compare
Choose a tag to compare
v1.3.0-pre.2 Pre-release
Pre-release

highlights:

docs:

changes:

  • mod: rollback golang.org/x/tools v0.22.0 => v0.19.0 (#1966)
  • mod: github.com/goplus/llgo v0.9.7
  • cl: fix slicelit for assignStmt/returnStmt (#1959)
  • cl: fix compositeLit for assignStmt (#1960)
  • cl: fix compileCompositeLitEx struct for sliceLit/mapLit (#1961)

v1.3.0-pre.1

15 Jul 15:14
43ecd08
Compare
Choose a tag to compare
v1.3.0-pre.1 Pre-release
Pre-release

highlights:

features:

changes:

  • cl: GetFileClassType: fix isProj must check name is main (#1862)
  • cl: preloadFile ast.OverloadFuncDecl handle error (#1865)
  • cl: record def for ast.OverloadFuncDecl (#1866)
  • cl: Go+ overload func support pos (#1868)
  • cl: fix record ast.OverloadFuncDecl has funcLit only (#1869)
  • cl: support declared function in classfile's overload decl (#1875)
  • cl: _testgop (to be continued (#1888)
  • x/typesutil:modify info.Overloads to point to the overload decl (#1872)
  • gop/ast: fix (*ast.File).End check shadow no entry (#1860)
  • update env.MainVersion to 1.3 (#1928 #1930)
  • testdata => demo (#1920)
  • cmd/chore (#1885)
  • publish (docker): remove gopfmt from the baked Docker image (#1934)
  • publish (goreleaser): remove gopfmt (#1932)
  • make test: make cmd/TestInstallInNonGitRepo not affected by actual major.minor versions (#1937)
  • make test: fix cmd/TestInstallInNonGitRepo/install_with_VERSION_file (#1930)
  • goreleaser: remove gopfmt (#1932)
  • mod: github.com/goplus/gogen v1.16.0
  • mod: github.com/goplus/llgo v0.9.1
  • mod: github.com/goplus/mod v0.13.12
  • mod: golang.org/x/tools v0.22.0

v1.2.6

12 Apr 19:30
4fdc568
Compare
Choose a tag to compare

highlights:

  • Improve compilation speed through disk cache, especially under windows (#1827, gogen@v1.15.2).
  • Go+ now supports static methods. This allows Go+ classfile to provide "global functions", such as T.new or T.start, without introducing a separate file.
  • Times loop: for :N { ... }. Previously you had to use for range :N { ... }.
  • Pkgsite: Beta version of https://pkg.gop.dev/ is released.

features:

ci/cd tools:

  • official Docker image (#1819 #1841)
  • change build artifacts name (#1838)
  • cover Go 1.22 in test (#1836)
  • update macOS version to "macos-latest" (#1844)

changes:

  • gop: NewDefaultConf: useCacheFile param; conf.UpdateCache (#1827)
  • cl: compileExpr/compileExprLHS panic code error (#1832)
  • cl: correct anonymous overloaded function naming (#1833)
  • cl, printer: set astFnClassfname shadow and not to print (#1853)
  • cl, gop: export GetFileClassType (#1852)
  • cl: gmxProject.hasMain (#1817)
  • mod: github.com/goplus/c2go v0.7.26
  • mod: github.com/goplus/gogen v1.15.2
  • mod: github.com/goplus/mod v0.13.10
  • mod: github.com/qiniu/x v1.13.10

v1.2.5

09 Mar 15:05
f6596aa
Compare
Choose a tag to compare

highlights:

  • operator ${name}: You can customize the semantics of ${name}. For example, in .gsh classfile, ${name} means os.Getenv("<name>"), and in .yap classfile, ${name} means ctx.Param("<name>").
  • The web framework YAP released v0.8.0. It introduces YAP classfile v2 which is particularly simple and easy to use. See blow for details.

features:

  • classfile: generate gameClass.Main() (#1814)
  • classfile: this.Sprite.Main(...) or this.Game.MainEntry(...) (#1794)
  • classfile: this.Classfname() (#1794 #1797)
  • classfile: gsh exec (#1757)
  • cl: ${name} - operator Gop_Env (#1776 #1806 #1810)
  • cl: binaryOp ->, <> (#1763 #1764 #1766)
  • cl: compileCompositeLit: support type-inter for map (#1756)
  • cl: rec.Scope - record types scope (#1759 #1767 #1772 #1774)
  • cl: types record check selection/index expr is addressable (#1785 #1788)
  • cl: don't define GopPackage for main package (#1796)
  • cl: astFnClassfname, astEmptyEntrypoint (#1811 #1812)
  • format interface{}: rm newline (#1761 #1769 #1791)
  • x/typesutil: add conf.IgnoreFuncBodies (#1783)
  • x/typesutil: add conf.UpdateGoTypesOverload (#1793)
  • qiniu/x/stringutil (#1777 #1778 #1779)

ci/cd tools:

  • check goreleaser file lists (#1802)
  • ci: compatible with version difference of patch release (#1804 #1808)

changes:

  • rename github.com/goplus/gox => github.com/goplus/gogen (#1798)
  • cl: inMainPkg (#1789)
  • cl: isGoxTestFile (#1790)
  • cl: for..range body use vblock for new scope (#1760)
  • cl: gogen new api case/typeCase/commCase (#1762)
  • cl: commentStmt: fix ast.GenDecl pos (#1768)
  • cl: commentStmt: skip noPos (#1794)
  • cl: TestErrStringLit (#1799)
  • parser: fix StringLit extra check (#1782)
  • ast: walk add *IndexListExpr (#1773)
  • ast: fix forPhrase.end (#1775)
  • x/typesutil: check for need goinfo (#1784)
  • x/typesutil: TestTypeAndValue, TestConvErr (#1800)
  • mod: github.com/goplus/c2go v0.7.25
  • mod: github.com/goplus/gogen v1.15.1
  • mod: github.com/goplus/mod v0.13.9
  • mod: github.com/qiniu/x v1.13.9
  • mod: golang.org/x/tools v0.19.0

YAP released v0.8.0. It introducesYAP classfile v2 which is particularly simple and easy to use. Let’s compare YAP in Go, YAP classfile v1 and YAP classfile v2.

Router and Parameters

demo in Go (hello.go):

import "github.com/goplus/yap"

func main() {
	y := yap.New()
	y.GET("/", func(ctx *yap.Context) {
		ctx.TEXT(200, "text/html", `<html><body>Hello, YAP!</body></html>`)
	})
	y.GET("/p/:id", func(ctx *yap.Context) {
		ctx.JSON(200, yap.H{
			"id": ctx.Param("id"),
		})
	})
	y.Run("localhost:8080")
}

demo in YAP classfile v1 (main.yap):

get "/", ctx => {
	ctx.html `<html><body>Hello, YAP!</body></html>`
}
get "/p/:id", ctx => {
	ctx.json {
		"id": ctx.param("id"),
	}
}

run "localhost:8080"

demo in YAP classfile v2 (get.yap, get_p_#id.yap):

html `<html><body>Hello, YAP!</body></html>`
json {
	"id": ${id},
}

YAP Template

demo in Go (blog.go, article_yap.html):

import (
	"os"

	"github.com/goplus/yap"
)

y := yap.New(os.DirFS("."))

y.GET("/p/:id", func(ctx *yap.Context) {
	ctx.YAP(200, "article", yap.H{
		"id": ctx.Param("id"),
	})
})

y.Run(":8080")

demo in YAP classfile v1 (main.yap, article_yap.html):

get "/p/:id", ctx => {
	ctx.yap "article", {
		"id": ctx.param("id"),
	}
}

run ":8888"

demo in YAP classfile v2 (get_p_#id.yap, article_yap.html):

yap "article", {
	"id": ${id},
}

See yap: Yet Another HTTP Web Framework for more details.

v1.2.2

17 Feb 15:44
a710792
Compare
Choose a tag to compare

highlights:

  • classfiles: One language can change the whole world. Go+ is a "DSL" for all domains. It introduces classfile to abstract domain knowledge. See Go+ Classfiles.
  • gsh as builtin classfile: It means now you can write shell script in Go+. It supports all shell commands. You don't need a go.mod file, just enter gop run XXX.gsh directly to run. See gsh: Go+ DevOps Tools.
  • Go+ module documents on pkg.go.dev: All Go+ modules can appear on pkg.go.dev without any differences as Go modules. Derived from Go and easy to build large projects from its good engineering foundation (vscode plugin, language server, debugger, code coverage, module, documentation, etc.), Go+ is ready for large projects.

features:

  • cl: support Gop_Exec (#1736 #1737 #1741 #1744)
  • cl: mayBuiltin new/delete (#1735)
  • cl: commentFunc set //line before doc (#1738 #1746)
  • cl: gmxMainFunc: force remove //line comments for main func (#1742 #1743)
  • parser: ParseEntries (#1749)
  • gop: NewDefaultConf: add (noTestFile bool) param (#1745)
  • gop run: support build dir (#1748)
  • classfile: .gsh as builtin classfile (#1749)
  • classfile: _test.gox add App.M() (#1753)
  • document: classfile (#1750 #1751 #1752)

changes:

v1.2.1

12 Feb 11:13
3717421
Compare
Choose a tag to compare

highlights:

features:

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

01 Feb 12:02
311ab9c
Compare
Choose a tag to compare

features:

articles:

ci/cd tools:

  • check upload result, test upload to winget/fury (#1689)

changes:

  • gop get: use modload.AddRequire with hasProj (#1693)
  • parser: check # to lineComment (#1687)
  • cl: gox.InitThisGopPkg, TestGopxNoFunc (#1690)
  • cl: compileIdent bugfix: clCommandWithoutArgs (#1690)

v1.2.0-pre.2

28 Jan 13:33
5db9564
Compare
Choose a tag to compare
v1.2.0-pre.2 Pre-release
Pre-release

features:

articles:

ci/cd tools:

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.

Screen Shot1 Screen Shot2

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

07 Jan 22:07
c6539a5
Compare
Choose a tag to compare
v1.2.0-pre.1 Pre-release
Pre-release

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:

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

25 Nov 02:59
23dcc4f
Compare
Choose a tag to compare

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)