diff --git a/.github/workflows/wa.yml b/.github/workflows/wa.yml index 749fa2c908337a0205763a9e6fa2a13c186263e2..e43d03f41d48d4bbe1119ed4ec7bfec764ec6dcb 100644 --- a/.github/workflows/wa.yml +++ b/.github/workflows/wa.yml @@ -40,6 +40,7 @@ jobs: - run: go install - run: wa -h + - run: wa hello.wa - run: wa run _examples/hello - run: wa run _examples/prime diff --git a/hello.wa b/hello.wa index 2059fbb78362b4dfea9d7dfadd2249baf3d7c067..e29361ef715974d6575a56875579537cb6483c12 100644 --- a/hello.wa +++ b/hello.wa @@ -1,5 +1,11 @@ # 版权 @2019 凹语言 作者。保留所有权利。 fn main() { - println("老凹,吃了吗") + println("凹凹,吃了吗") + println(answer()) +} + +fn answer() => (x:int) { + x = 40 + 2 + return } diff --git a/internal/parser/parser.go b/internal/parser/parser.go index 4df41c51b4b0659c0406055fe45b411f3f4e67d5..74bb09f597681a7814958001029d46b4ea44cb97 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -816,6 +816,7 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [ var list []ast.Expr for { list = append(list, p.parseVarType(ellipsisOk)) + // 开头的 Ident 列表, 遇到非 ',' 时结束 if p.tok != token.COMMA { break } @@ -825,11 +826,18 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [ } } + // 解析可选的 ':' + var colonPos token.Pos + if p.tok == token.COLON { + colonPos = p.pos + p.next() + } + // analyze case if typ := p.tryVarType(ellipsisOk); typ != nil { // IdentifierList Type idents := p.makeIdentList(list) - field := &ast.Field{Names: idents, Type: typ} + field := &ast.Field{Names: idents, ColonPos: colonPos, Type: typ} params = append(params, field) // Go spec: The scope of an identifier denoting a function // parameter or result variable is the function body. @@ -841,8 +849,12 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [ p.next() for p.tok != token.RPAREN && p.tok != token.EOF { idents := p.parseIdentList() + if p.tok == token.COLON { + colonPos = p.pos + p.next() + } typ := p.parseVarType(ellipsisOk) - field := &ast.Field{Names: idents, Type: typ} + field := &ast.Field{Names: idents, ColonPos: colonPos, Type: typ} params = append(params, field) // Go spec: The scope of an identifier denoting a function // parameter or result variable is the function body. @@ -856,6 +868,12 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [ return } + // 缺少类型信息 + if colonPos != token.NoPos { + p.errorExpected(p.pos, "type") + return + } + // Type { "," Type } (anonymous parameters) params = make([]*ast.Field, len(list)) for i, typ := range list {