Skip to content

Commit

Permalink
支持 a := fn(b) => c
Browse files Browse the repository at this point in the history
  • Loading branch information
lollipopkit committed Oct 24, 2022
1 parent 26b1df9 commit 842b043
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 8 deletions.
26 changes: 21 additions & 5 deletions LANG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ print(a) // 1
**尽量**使用 `shy` 关键字,这会提高程序运行速度(因为不需要全局寻找变量)。
`LK` 中已经声明的变量可以再次声明,这时会在其作用域内覆盖原来的值。

```js
// 等同于 `shy a = 1`
a := 1
```
去除使用 `shy` 关键字,还可以使用 `:=` 进行声明。

```js
a, b = 1
print(a, b) // 1 nil
Expand All @@ -72,16 +78,15 @@ print(a, b) // 1 nil

## 函数
```js
// 支持以变量方式声明函数
// 和变量一致,`shy` 表示局部函数
shy add2 = fn (a, b) {
rt a + b
}
print(add2(1, 2)) // 3
```
支持以变量方式声明函数。
和变量一致,`shy` 表示局部函数

// `...` 为变长参数,表明0个或更多个参数
// 可以使用 `{...}` 来构造参数列表
// 再使用 `for in` 获取每一个参数
```js
fn addN(...) {
sum = 0
for _, i in {...} {
Expand All @@ -91,7 +96,18 @@ fn addN(...) {
}
addN(1, 2, 3, 4, 5) // 15
```
`...` 为变长参数,表明0个或更多个参数。
可以使用 `{...}` 来构造参数列表,再使用 `for in` 获取每一个参数。

```js
a := fn(b) => 3 ^ b, 2 ^ b
print(a(2))

shy a = fn(b) {rt 3 ^ b, 2 ^ b}
print(a(2))
```
两个 `a` 函数声明的作用一致。
`=>` 后返回值只能有一行。

## 循环
```js
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ if http.listen(':8080', handle) != nil {
- [x] 三元操作符 `a ? b : c`
- [x] `a == nil ? b : a` -> `a ?? b`
- [x] `shy a = b` -> `a := b`
- [x] `shy a = fn(b) {rt c}` -> `shy a = fn(b) => c`
- [x] Table
- [x] key为StringExp,而不是NameExp
- [x] 构造方式:`=` -> `:`, eg: `{a = 'a'}` -> `{a: 'a'}`
Expand Down
3 changes: 3 additions & 0 deletions compiler/lexer/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ func (self *Lexer) NextToken() (line, kind int, token string) {
if self.test("==") {
self.next(2)
return self.line, TOKEN_OP_EQ, "=="
} else if self.test("=>") {
self.next(2)
return self.line, TOKEN_OP_ARROW, "=>"
} else {
self.next(1)
return self.line, TOKEN_OP_ASSIGN, "="
Expand Down
9 changes: 7 additions & 2 deletions compiler/lexer/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ const (
TOKEN_OP_BXOR = TOKEN_OP_WAVE
TOKEN_KW_CLASS = iota - 4
TOKEN_OP_QUESTION
TOKEN_OP_NILCOALESCING // ??
TOKEN_OP_ASSIGNSHY // :=
// ??
TOKEN_OP_NILCOALESCING
// :=
TOKEN_OP_ASSIGNSHY
// =>
TOKEN_OP_ARROW
)

var tokenNames = map[int]string{
Expand Down Expand Up @@ -119,6 +123,7 @@ var tokenNames = map[int]string{
TOKEN_OP_QUESTION: "?",
TOKEN_OP_NILCOALESCING: "??",
TOKEN_OP_ASSIGNSHY: ":=",
TOKEN_OP_ARROW: "=>",
}

func tokenName(token int) string {
Expand Down
8 changes: 8 additions & 0 deletions compiler/parser/parse_exp.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ func parseFuncDefExp(lexer *Lexer) *FuncDefExp {
lexer.NextTokenOfKind(TOKEN_SEP_LPAREN) // (
parList, isVararg := _parseParList(lexer) // [parlist]
lexer.NextTokenOfKind(TOKEN_SEP_RPAREN) // )
if lexer.LookAhead() == TOKEN_OP_ARROW {
lexer.NextToken() // ->
return &FuncDefExp{line, line, parList, isVararg, &Block{
Stats: []Stat{},
RetExps: parseExpList(lexer),
LastLine: line,
}}
}
lexer.NextTokenOfKind(TOKEN_SEP_LCURLY) // {
block := parseBlock(lexer) // block
lastLine, _ := lexer.NextTokenOfKind(TOKEN_SEP_RCURLY) // }
Expand Down
6 changes: 5 additions & 1 deletion compiler/parser/parse_stat.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,11 @@ func parseAssignStat(lexer *Lexer, var0 Exp) Stat {
expList := parseExpList(lexer) // explist
strExps := make([]string, len(expList))
for i, exp := range varList {
strExps[i] = exp.(*NameExp).Name
name, ok := exp.(*NameExp)
if !ok {
panic("invalid assignment")
}
strExps[i] = name.Name
}
return &LocalVarDeclStat{lexer.Line(), strExps, expList}
}
Expand Down
4 changes: 4 additions & 0 deletions test/basic.lk
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ while true {
long = nil
}

// 等于 `shy a = fn(b) {rt 3 ^ b, 2 ^ b}
a := fn(b) => 3 ^ b, 2 ^ b
func(a(2))

func('' and true and 1 ? 'support ternary exp' : 'unreachable')
func(6 ~/ 2, 6 & 2, 6 / 2)
func(_VERSION, math.pi)
Expand Down

0 comments on commit 842b043

Please sign in to comment.