Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.3.0-pre.2 #1978

Merged
merged 77 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
00a83df
Update README.md
xushiwei Jul 15, 2024
99585e7
build(deps): bump github.com/goplus/llgo from 0.9.1 to 0.9.2
dependabot[bot] Jul 18, 2024
b77efe8
Merge pull request #1939 from goplus/dependabot/go_modules/github.com…
xushiwei Jul 18, 2024
89aa897
llgo demo: use llgo v0.9.2
xushiwei Jul 19, 2024
aa7b0e0
Merge pull request #1940 from xushiwei/q
xushiwei Jul 19, 2024
f9ba0a8
How Go+ simplifies Go's expressions
xushiwei Jul 22, 2024
f54ad8d
Merge pull request #1941 from xushiwei/q
xushiwei Jul 22, 2024
b642d7b
Update README.md
xushiwei Jul 22, 2024
d94d2c9
How Go+ simplifies Go's expressions: classfile
xushiwei Jul 22, 2024
36a8062
Merge pull request #1942 from xushiwei/q
xushiwei Jul 22, 2024
b2fbf46
mini spec
xushiwei Jul 24, 2024
a8d9634
Merge pull request #1943 from xushiwei/q
xushiwei Jul 24, 2024
1b71ff6
literals
xushiwei Jul 24, 2024
8dd9138
Merge pull request #1944 from xushiwei/q
xushiwei Jul 24, 2024
1a8a169
spec: types
xushiwei Jul 24, 2024
b216119
Merge pull request #1945 from xushiwei/q
xushiwei Jul 24, 2024
06338f1
spec: pointer/map type
xushiwei Jul 25, 2024
488846a
Merge pull request #1946 from xushiwei/q
xushiwei Jul 25, 2024
78366a3
spec: operators
xushiwei Jul 25, 2024
ad20f9f
Merge pull request #1947 from xushiwei/q
xushiwei Jul 25, 2024
7cba00b
Update and rename mini-spec.md to spec-stem.md
xushiwei Jul 25, 2024
d53be20
mv spec-stem.md => spec-mini.md
xushiwei Jul 25, 2024
b3f8825
Merge pull request #1948 from xushiwei/q
xushiwei Jul 25, 2024
bb91b2e
build(deps): bump github.com/goplus/llgo from 0.9.2 to 0.9.3
dependabot[bot] Jul 26, 2024
49b3a44
spec mini: Constants/Variables
xushiwei Jul 27, 2024
5e12443
Merge pull request #1949 from goplus/dependabot/go_modules/github.com…
xushiwei Jul 27, 2024
2f2c737
Merge pull request #1950 from xushiwei/q
xushiwei Jul 27, 2024
67ad0f2
Constant/variable expressions
xushiwei Jul 28, 2024
7856bd7
Merge pull request #1952 from xushiwei/q
xushiwei Jul 28, 2024
d21c7ff
README: spec mini
xushiwei Jul 28, 2024
17f37f5
Merge pull request #1953 from xushiwei/q
xushiwei Jul 28, 2024
8a90d0f
spec: Slice literals
xushiwei Jul 29, 2024
09ec827
Merge pull request #1955 from xushiwei/q
xushiwei Jul 29, 2024
7aaaf76
spec: map literals
xushiwei Jul 29, 2024
80bb0e2
Merge pull request #1956 from xushiwei/q
xushiwei Jul 29, 2024
9d60585
README: Go+ Full Specification
xushiwei Jul 29, 2024
6033472
Merge pull request #1957 from xushiwei/q
xushiwei Jul 29, 2024
1df5069
build(deps): bump github.com/goplus/llgo from 0.9.3 to 0.9.4
dependabot[bot] Jul 30, 2024
43deb05
Merge pull request #1958 from goplus/dependabot/go_modules/github.com…
xushiwei Jul 31, 2024
73e7568
cl: fix slicelit for assignStmt/returnStmt
visualfc Jul 31, 2024
5ce3b8d
Merge pull request #1959 from visualfc/fixslicelit
xushiwei Jul 31, 2024
c1e28d5
cl: fix compositeLit for assignStmt
visualfc Aug 1, 2024
e3757c5
Merge pull request #1960 from visualfc/fixmaplit
xushiwei Aug 1, 2024
066ca57
cl: fix compileCompositeLitEx struct for sliceLit/mapLit
visualfc Aug 3, 2024
37cf612
Merge pull request #1961 from visualfc/fixcomposite
xushiwei Aug 7, 2024
a0e7cfe
build(deps): bump github.com/goplus/llgo from 0.9.4 to 0.9.5
dependabot[bot] Aug 7, 2024
e023b0c
Merge pull request #1963 from goplus/dependabot/go_modules/github.com…
xushiwei Aug 7, 2024
3f122b3
build(deps): bump github.com/goplus/llgo from 0.9.5 to 0.9.6
dependabot[bot] Aug 8, 2024
06a9786
Merge pull request #1965 from goplus/dependabot/go_modules/github.com…
xushiwei Aug 9, 2024
2ad7df1
rollback golang.org/x/tools v0.22.0 => v0.19.0
xushiwei Aug 9, 2024
131bb56
Merge pull request #1966 from xushiwei/q
xushiwei Aug 9, 2024
d64d3b9
stmt: todo
xushiwei Aug 14, 2024
d2a06fa
Merge pull request #1967 from xushiwei/q
xushiwei Aug 14, 2024
8e88a9b
mini spec: Expression/IncDec/Empty statements
xushiwei Aug 15, 2024
c08b947
Merge pull request #1968 from xushiwei/q
xushiwei Aug 15, 2024
059f754
assign stmt
xushiwei Aug 20, 2024
dba2a7c
Merge pull request #1969 from xushiwei/q
xushiwei Aug 20, 2024
e7c35cb
if stmt
xushiwei Aug 21, 2024
1cb7838
Merge pull request #1970 from xushiwei/q
xushiwei Aug 21, 2024
dbf5d67
spec: for stmt
xushiwei Aug 25, 2024
17ff401
Merge pull request #1971 from xushiwei/q
xushiwei Aug 25, 2024
4251b20
switch/break/continue/fallthrough/goto stmt
xushiwei Aug 26, 2024
8712c84
Merge pull request #1972 from xushiwei/q
xushiwei Aug 26, 2024
6839725
Go+ new slogan
xushiwei Aug 26, 2024
33fc296
Merge pull request #1973 from xushiwei/q
xushiwei Aug 26, 2024
b21b19d
Update README.md
xushiwei Aug 26, 2024
06943d6
spec: return/defer stmt
xushiwei Aug 30, 2024
beab5a2
Merge pull request #1974 from xushiwei/q
xushiwei Aug 30, 2024
a5fec8c
Update README.md
xushiwei Aug 31, 2024
a43577b
build(deps): bump github.com/goplus/llgo from 0.9.6 to 0.9.7
dependabot[bot] Sep 2, 2024
b36c39b
Merge pull request #1975 from goplus/dependabot/go_modules/github.com…
xushiwei Sep 2, 2024
a6dbd4d
mini spec: builtin append/copy
xushiwei Sep 5, 2024
30531d9
Merge pull request #1976 from xushiwei/q
xushiwei Sep 5, 2024
dc46561
mini spec: builtin clear
xushiwei Sep 5, 2024
bf2dd08
Merge pull request #1977 from xushiwei/q
xushiwei Sep 5, 2024
26ee535
Update README.md
xushiwei Sep 5, 2024
5f10778
Update README.md
xushiwei Sep 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

</div>

Our vision is to **enable everyone to create production-level applications**.
Our vision is to **enable everyone to become a builder of the digital world**.

#### Easy to learn

Expand All @@ -46,13 +46,14 @@ For more details, see [Quick Start](doc/docs.md).

## Key Features of Go+

* Approaching natural language expression and intuitive (see [Command Style Code](#command-style-code)).
* Fully compatible with [Go](https://github.com/golang/go) and can mix Go/Go+ code in the same package (see [Go/Go+ Hybrid Programming](doc/docs.md#gogo-hybrid-programming)).
* Integrating with the C ecosystem including Python and providing limitless possibilities (see [Support for C/C++ and Python](#support-for-cc-and-python)).
* Approaching natural language expression and intuitive (see [How Go+ simplifies Go's expressions](#how-go-simplifies-gos-expressions)).
* Smallest but Turing-complete syntax set in best practices (see [Go+ Specification for STEM Education](doc/spec-mini.md)).
* Fully compatible with [Go](https://github.com/golang/go) and can mix Go/Go+ code in the same package (see [Go+ Full Specification](doc/spec.md) and [Go/Go+ Hybrid Programming](doc/docs.md#gogo-hybrid-programming)).
* Integrating with the C ecosystem including Python and providing limitless possibilities based on [LLGo](https://github.com/goplus/llgo) (see [Support for C/C++ and Python](#support-for-cc-and-python)).
* Does not support DSL (Domain-Specific Languages), but supports SDF (Specific Domain Friendliness) (see [Go+ Classfiles](#go-classfiles)).


## Command Style Code
## How Go+ simplifies Go's expressions

Different from the function call style of most languages, Go+ recommends command style code:

Expand All @@ -68,6 +69,20 @@ echo "Hello world"

For more discussion on coding style, see https://tutorial.goplus.org/hello-world.

Code style is just the first step. We have made many efforts to make the code more intuitive and closer to natural language expression. These include:

| Go code | Go+ code | Note |
| ---- | ---- | ---- |
| package main<br><br>import "fmt"<br><br>func main() {<br>&nbsp;&nbsp;&nbsp;&nbsp;fmt.Println("Hi")<br>} | import "fmt"<br><br>fmt.Println("Hi")<br> | Program structure: Go+ allows omitting `package main` and `func main` |
| fmt.Println("Hi") | echo("Hi") | More builtin functions: It simplifies the expression of the most common tasks |
| fmt.Println("Hi") | echo "Hi" | Command-line style code: It reduces the number of parentheses in the code as much as possible, making it closer to natural language |
| a := []int{1, 2, 3} | a := [1, 2, 3] | List literals |
| a := map[string]int{<br>&nbsp;&nbsp;&nbsp;&nbsp;"Monday": 1,<br>&nbsp;&nbsp;&nbsp;&nbsp;"Tuesday": 2,<br>} | a := {<br>&nbsp;&nbsp;&nbsp;&nbsp;"Monday": 1,<br>&nbsp;&nbsp;&nbsp;&nbsp;"Tuesday": 2,<br>} | Mapping literals |
| OnStart(func() {<br>&nbsp;&nbsp;&nbsp;&nbsp;...<br>}) | onStart => {<br>&nbsp;&nbsp;&nbsp;&nbsp;...<br>} | Lambda expressions |
| type Rect struct {<br>&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp; float64<br>&nbsp;&nbsp;&nbsp;&nbsp;Height float64<br>}<br><br>func (this *Rect) Area() float64 { <br>&nbsp;&nbsp;&nbsp;&nbsp;return this.Width * this.Height<br>} | var (<br>&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp; float64<br>&nbsp;&nbsp;&nbsp;&nbsp;Height float64<br>)<br><br>func Area() float64 { <br>&nbsp;&nbsp;&nbsp;&nbsp;return Width * Height<br>} | [Go+ Classfiles](doc/classfile.md): We can express OOP with global variables and functions. |

For more details, see [Go+ Specification for STEM Education](doc/spec-mini.md).


## Support for C/C++ and Python

Expand Down Expand Up @@ -100,7 +115,7 @@ module YourModulePath

go 1.21 // llgo 1.0

require github.com/goplus/llgo v0.9.1
require github.com/goplus/llgo v0.9.7
```

Based on LLGo, Go+ can support importing libraries written in C/C++ and Python.
Expand Down
129 changes: 129 additions & 0 deletions cl/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4122,3 +4122,132 @@ func _() {
}
`)
}

func TestSliceLitAssign(t *testing.T) {
gopClTest(t, `
var n = 1
var a []any = [10, 3.14, 200]
n, a = 100, [10, 3.14, 200]
echo a, n
`, `package main

import "fmt"

var n = 1
var a []interface{} = []interface{}{10, 3.14, 200}

func main() {
n, a = 100, []interface{}{10, 3.14, 200}
fmt.Println(a, n)
}
`)
}

func TestSliceLitReturn(t *testing.T) {
gopClTest(t, `
func anyslice() (int, []any) {
return 100, [10, 3.14, 200]
}
n, a := anyslice()
echo n, a
`, `package main

import "fmt"

func anyslice() (int, []interface{}) {
return 100, []interface{}{10, 3.14, 200}
}
func main() {
n, a := anyslice()
fmt.Println(n, a)
}
`)
}

func TestCompositeLitAssign(t *testing.T) {
gopClTest(t, `
var a map[any]any = {10: "A", 3.14: "B", 200: "C"}
var b map[any]string = {10: "A", 3.14: "B", 200: "C"}
echo a
echo b
var n int
n, a = 1, {10: "A", 3.14: "B", 200: "C"}
echo a, n
n, b = 1, {10: "A", 3.14: "B", 200: "C"}
echo b, n
`, `package main

import "fmt"

var a map[interface{}]interface{} = map[interface{}]interface{}{10: "A", 3.14: "B", 200: "C"}
var b map[interface{}]string = map[interface{}]string{10: "A", 3.14: "B", 200: "C"}

func main() {
fmt.Println(a)
fmt.Println(b)
var n int
n, a = 1, map[interface{}]interface{}{10: "A", 3.14: "B", 200: "C"}
fmt.Println(a, n)
n, b = 1, map[interface{}]string{10: "A", 3.14: "B", 200: "C"}
fmt.Println(b, n)
}
`)
}

func TestCompositeLitStruct(t *testing.T) {
gopClTest(t, `
type T struct {
s []any
m map[any]any
fn func(int) int
}

echo &T{[10, 3.14, 200], {10: "A", 3.14: "B", 200: "C"}, (x => x)}
echo &T{s: [10, 3.14, 200], m: {10: "A", 3.14: "B", 200: "C"}, fn: (x => x)}
`, `package main

import "fmt"

type T struct {
s []interface{}
m map[interface{}]interface{}
fn func(int) int
}

func main() {
fmt.Println(&T{[]interface{}{10, 3.14, 200}, map[interface{}]interface{}{10: "A", 3.14: "B", 200: "C"}, func(x int) int {
return x
}})
fmt.Println(&T{s: []interface{}{10, 3.14, 200}, m: map[interface{}]interface{}{10: "A", 3.14: "B", 200: "C"}, fn: func(x int) int {
return x
}})
}
`)
}

func TestCompositeLitEx(t *testing.T) {
gopClTest(t, `
var a [][]any = {[10, 3.14, 200], [100, 200]}
var m map[any][]any = {10: [10, 3.14, 200]}
var f map[any]func(int) int = {10: x => x}

echo a
echo m
echo f
`, `package main

import "fmt"

var a [][]interface{} = [][]interface{}{[]interface{}{10, 3.14, 200}, []interface{}{100, 200}}
var m map[interface{}][]interface{} = map[interface{}][]interface{}{10: []interface{}{10, 3.14, 200}}
var f map[interface{}]func(int) int = map[interface{}]func(int) int{10: func(x int) int {
return x
}}

func main() {
fmt.Println(a)
fmt.Println(m)
fmt.Println(f)
}
`)
}
27 changes: 27 additions & 0 deletions cl/error_msg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1071,3 +1071,30 @@ func (foo).++ = (
)
`)
}

func TestCompositeLitError(t *testing.T) {
codeErrorTest(t, `bar.gop:2:22: cannot use 3.14 (type untyped float) as type int in slice literal`, `
var a [][]int = {[10,3.14,200],[100,200]}
echo a
`)
codeErrorTest(t, `bar.gop:2:17: cannot use lambda literal as type int in assignment`, `
var a []int = {(x => x)}
echo a
`)
codeErrorTest(t, `bar.gop:2:35: cannot use x (type int) as type string in return argument`, `
var a []func(int) string = {(x => x)}
echo a
`)
codeErrorTest(t, `bar.gop:2:27: cannot use lambda literal as type int in assignment to "A"`, `
var a map[any]int = {"A": x => x}
`)
codeErrorTest(t, `bar.gop:2:45: cannot use x (type int) as type string in return argument`, `
var a map[any]func(int) string = {"A": x => x}
`)
codeErrorTest(t, `bar.gop:2:24: cannot use lambda literal as type int in field value`, `
var a = struct{v int}{(x => x)}
`)
codeErrorTest(t, `bar.gop:2:27: cannot use lambda literal as type int in field value to v`, `
var a = struct{v int}{v: (x => x)}
`)
}
92 changes: 67 additions & 25 deletions cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -853,8 +853,11 @@ retry:
typ = t.Underlying()
goto retry
}
src := ctx.LoadExpr(toNode)
return nil, ctx.newCodeErrorf(lambda.Pos(), "cannot use lambda literal as type %v in %v to %v", ftyp, flag, src)
var to string
if toNode != nil {
to = " to " + ctx.LoadExpr(toNode)
}
return nil, ctx.newCodeErrorf(lambda.Pos(), "cannot use lambda literal as type %v in %v%v", ftyp, flag, to)
}

func compileLambda(ctx *blockCtx, lambda ast.Expr, sig *types.Signature) {
Expand Down Expand Up @@ -1065,30 +1068,68 @@ func checkCompositeLitElts(elts []ast.Expr) (kind int) {
return compositeLitVal
}

func compileCompositeLitElts(ctx *blockCtx, elts []ast.Expr, kind int, expected *kvType) {
func compileCompositeLitElts(ctx *blockCtx, elts []ast.Expr, kind int, expected *kvType) error {
for _, elt := range elts {
if kv, ok := elt.(*ast.KeyValueExpr); ok {
if key, ok := kv.Key.(*ast.CompositeLit); ok && key.Type == nil {
compileCompositeLit(ctx, key, expected.Key(), false)
} else {
compileExpr(ctx, kv.Key)
}
if val, ok := kv.Value.(*ast.CompositeLit); ok && val.Type == nil {
compileCompositeLit(ctx, val, expected.Elem(), false)
} else {
compileExpr(ctx, kv.Value)
err := compileCompositeLitElt(ctx, kv.Value, expected.Elem(), clLambaAssign, kv.Key)
if err != nil {
return err
}
} else {
if kind == compositeLitKeyVal {
ctx.cb.None()
}
if val, ok := elt.(*ast.CompositeLit); ok && val.Type == nil {
compileCompositeLit(ctx, val, expected.Elem(), false)
} else {
compileExpr(ctx, elt)
err := compileCompositeLitElt(ctx, elt, expected.Elem(), clLambaAssign, nil)
if err != nil {
return err
}
}
}
return nil
}

func compileCompositeLitElt(ctx *blockCtx, e ast.Expr, typ types.Type, flag clLambaFlag, toNode ast.Node) error {
switch v := unparen(e).(type) {
case *ast.LambdaExpr, *ast.LambdaExpr2:
sig, err := checkLambdaFuncType(ctx, v, typ, flag, toNode)
if err != nil {
return err
}
compileLambda(ctx, v, sig)
case *ast.SliceLit:
compileSliceLit(ctx, v, typ)
case *ast.CompositeLit:
compileCompositeLit(ctx, v, typ, false)
default:
compileExpr(ctx, v)
}
return nil
}

func unparen(x ast.Expr) ast.Expr {
if e, ok := x.(*ast.ParenExpr); ok {
return e.X
}
return x
}

func compileStructLit(ctx *blockCtx, elts []ast.Expr, t *types.Struct, typ types.Type, src *ast.CompositeLit) error {
for idx, elt := range elts {
if idx >= t.NumFields() {
return ctx.newCodeErrorf(elt.Pos(), "too many values in %v{...}", typ)
}
err := compileCompositeLitElt(ctx, elt, t.Field(idx).Type(), clLambaField, nil)
if err != nil {
return err
}
}
ctx.cb.StructLit(typ, len(elts), false, src)
return nil
}

func compileStructLitInKeyVal(ctx *blockCtx, elts []ast.Expr, t *types.Struct, typ types.Type, src *ast.CompositeLit) error {
Expand All @@ -1105,15 +1146,9 @@ func compileStructLitInKeyVal(ctx *blockCtx, elts []ast.Expr, t *types.Struct, t
if rec := ctx.recorder(); rec != nil {
rec.Use(name, t.Field(idx))
}
switch expr := kv.Value.(type) {
case *ast.LambdaExpr, *ast.LambdaExpr2:
sig, err := checkLambdaFuncType(ctx, expr, t.Field(idx).Type(), clLambaField, kv.Key)
if err != nil {
return err
}
compileLambda(ctx, expr, sig)
default:
compileExpr(ctx, kv.Value)
err := compileCompositeLitElt(ctx, kv.Value, t.Field(idx).Type(), clLambaField, kv.Key)
if err != nil {
return err
}
}
ctx.cb.StructLit(typ, len(elts)<<1, true, src)
Expand Down Expand Up @@ -1194,12 +1229,21 @@ func compileCompositeLitEx(ctx *blockCtx, v *ast.CompositeLit, expected types.Ty
typ, underlying = expected, tu
}
}
if t, ok := underlying.(*types.Struct); ok && kind == compositeLitKeyVal {
if err := compileStructLitInKeyVal(ctx, v.Elts, t, typ, v); err != nil {
if t, ok := underlying.(*types.Struct); ok {
var err error
if kind == compositeLitKeyVal {
err = compileStructLitInKeyVal(ctx, v.Elts, t, typ, v)
} else {
err = compileStructLit(ctx, v.Elts, t, typ, v)
}
if err != nil {
return err
}
} else {
compileCompositeLitElts(ctx, v.Elts, kind, &kvType{underlying: underlying})
err := compileCompositeLitElts(ctx, v.Elts, kind, &kvType{underlying: underlying})
if err != nil {
return err
}
n := len(v.Elts)
if isMap(underlying) {
if kind == compositeLitVal && n > 0 {
Expand All @@ -1214,8 +1258,6 @@ func compileCompositeLitEx(ctx *blockCtx, v *ast.CompositeLit, expected types.Ty
ctx.cb.SliceLitEx(typ, n<<kind, kind == compositeLitKeyVal, v)
case *types.Array:
ctx.cb.ArrayLitEx(typ, n<<kind, kind == compositeLitKeyVal, v)
case *types.Struct:
ctx.cb.StructLit(typ, n, false, v) // key-val mode handled by compileStructLitInKeyVal
default:
return ctx.newCodeErrorf(v.Pos(), "invalid composite literal type %v", typ)
}
Expand Down
Loading