Skip to content

Commit

Permalink
Merge pull request #1631 from xushiwei/overload
Browse files Browse the repository at this point in the history
Overload
  • Loading branch information
xushiwei committed Jan 15, 2024
2 parents d3f76ce + 139118c commit b07c375
Show file tree
Hide file tree
Showing 9 changed files with 378 additions and 32 deletions.
100 changes: 73 additions & 27 deletions ast/ast_gop.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,43 @@ import (

// -----------------------------------------------------------------------------

// OverloadFuncDecl node represents an overload function declaration:
//
// `func name = (overloadFuncs)`
// `func (T).nameOrOp = (overloadFuncs)`
//
// here overloadFunc represents
//
// `func(params) {...}`
// `funcName`
// `(*T).methodName`
type OverloadFuncDecl struct {
Doc *CommentGroup // associated documentation; or nil
Func token.Pos // position of "func" keyword
Recv *FieldList // receiver (methods); or nil (functions)
Name *Ident // function/method name
Assign token.Pos // position of token "="
Lparen token.Pos // position of "("
Funcs []Expr // overload functions. here `Expr` can be *FuncLit, *Ident or *SelectorExpr
Rparen token.Pos // position of ")"
Operator bool // is operator or not
IsClass bool // recv set by class
}

// Pos - position of first character belonging to the node.
func (p *OverloadFuncDecl) Pos() token.Pos {
return p.Func
}

// End - position of first character immediately after the node.
func (p *OverloadFuncDecl) End() token.Pos {
return p.Rparen + 1
}

func (*OverloadFuncDecl) declNode() {}

// -----------------------------------------------------------------------------

// A SliceLit node represents a slice literal.
type SliceLit struct {
Lbrack token.Pos // position of "["
Expand All @@ -30,12 +67,12 @@ type SliceLit struct {
Incomplete bool // true if (source) expressions are missing in the Elts list
}

// Pos - position of first character belonging to the node
// Pos - position of first character belonging to the node.
func (p *SliceLit) Pos() token.Pos {
return p.Lbrack
}

// End - position of first character immediately after the node
// End - position of first character immediately after the node.
func (p *SliceLit) End() token.Pos {
return p.Rbrack + 1
}
Expand All @@ -44,20 +81,20 @@ func (*SliceLit) exprNode() {}

// -----------------------------------------------------------------------------

// ErrWrapExpr represents `expr!`, `expr?` or `expr?: defaultValue`
// ErrWrapExpr represents `expr!`, `expr?` or `expr?: defaultValue`.
type ErrWrapExpr struct {
X Expr
Tok token.Token // ! or ?
TokPos token.Pos
Default Expr // can be nil
}

// Pos - position of first character belonging to the node
// Pos - position of first character belonging to the node.
func (p *ErrWrapExpr) Pos() token.Pos {
return p.X.Pos()
}

// End - position of first character immediately after the node
// End - position of first character immediately after the node.
func (p *ErrWrapExpr) End() token.Pos {
if p.Default != nil {
return p.Default.End()
Expand All @@ -69,13 +106,16 @@ func (*ErrWrapExpr) exprNode() {}

// -----------------------------------------------------------------------------

// LambdaExpr represents
// `(x, y, ...) => exprOrExprTuple`
// `x => exprOrExprTuple`
// `=> exprOrExprTuple`
// LambdaExpr represents one of the following expressions:
//
// `(x, y, ...) => exprOrExprTuple`
// `x => exprOrExprTuple`
// `=> exprOrExprTuple`
//
// here exprOrExprTuple represents
// `expr`
// `(expr1, expr2, ...)`
//
// `expr`
// `(expr1, expr2, ...)`
type LambdaExpr struct {
First token.Pos
Lhs []*Ident
Expand All @@ -86,10 +126,11 @@ type LambdaExpr struct {
RhsHasParen bool
}

// LambdaExpr2 represents
// `(x, y, ...) => { ... }`
// `x => { ... }`
// `=> { ... }`
// LambdaExpr2 represents one of the following expressions:
//
// `(x, y, ...) => { ... }`
// `x => { ... }`
// `=> { ... }`
type LambdaExpr2 struct {
First token.Pos
Lhs []*Ident
Expand All @@ -98,18 +139,22 @@ type LambdaExpr2 struct {
LhsHasParen bool
}

// Pos - position of first character belonging to the node.
func (p *LambdaExpr) Pos() token.Pos {
return p.First
}

// End - position of first character immediately after the node.
func (p *LambdaExpr) End() token.Pos {
return p.Last
}

// Pos - position of first character belonging to the node.
func (p *LambdaExpr2) Pos() token.Pos {
return p.First
}

// End - position of first character immediately after the node.
func (p *LambdaExpr2) End() token.Pos {
return p.Body.End()
}
Expand All @@ -119,7 +164,7 @@ func (*LambdaExpr2) exprNode() {}

// -----------------------------------------------------------------------------

// ForPhrase represents `for k, v <- container, cond`
// ForPhrase represents `for k, v <- container, cond` phrase.
type ForPhrase struct {
For token.Pos // position of "for" keyword
Key, Value *Ident // Key may be nil
Expand All @@ -138,11 +183,12 @@ func (p *ForPhrase) End() token.Pos { return p.X.End() }

func (p *ForPhrase) exprNode() {}

// ComprehensionExpr represents
// `[vexpr for k1, v1 <- container1, cond1 ...]` or
// `{vexpr for k1, v1 <- container1, cond1 ...}` or
// `{kexpr: vexpr for k1, v1 <- container1, cond1 ...}` or
// `{for k1, v1 <- container1, cond1 ...}` or
// ComprehensionExpr represents one of the following expressions:
//
// `[vexpr for k1, v1 <- container1, cond1 ...]` or
// `{vexpr for k1, v1 <- container1, cond1 ...}` or
// `{kexpr: vexpr for k1, v1 <- container1, cond1 ...}` or
// `{for k1, v1 <- container1, cond1 ...}` or
type ComprehensionExpr struct {
Lpos token.Pos // position of "[" or "{"
Tok token.Token // token.LBRACK '[' or token.LBRACE '{'
Expand All @@ -151,12 +197,12 @@ type ComprehensionExpr struct {
Rpos token.Pos // position of "]" or "}"
}

// Pos - position of first character belonging to the node
// Pos - position of first character belonging to the node.
func (p *ComprehensionExpr) Pos() token.Pos {
return p.Lpos
}

// End - position of first character immediately after the node
// End - position of first character immediately after the node.
func (p *ComprehensionExpr) End() token.Pos {
return p.Rpos + 1
}
Expand All @@ -171,12 +217,12 @@ type ForPhraseStmt struct {
Body *BlockStmt
}

// Pos - position of first character belonging to the node
// Pos - position of first character belonging to the node.
func (p *ForPhraseStmt) Pos() token.Pos {
return p.For
}

// End - position of first character immediately after the node
// End - position of first character immediately after the node.
func (p *ForPhraseStmt) End() token.Pos {
return p.Body.End()
}
Expand All @@ -194,15 +240,15 @@ type RangeExpr struct {
Expr3 Expr // step (or max) of composite elements; or nil
}

// Pos - position of first character belonging to the node
// Pos - position of first character belonging to the node.
func (p *RangeExpr) Pos() token.Pos {
if p.First != nil {
return p.First.Pos()
}
return p.To
}

// End - position of first character immediately after the node
// End - position of first character immediately after the node.
func (p *RangeExpr) End() token.Pos {
if p.Expr3 != nil {
return p.Expr3.End()
Expand Down
13 changes: 13 additions & 0 deletions parser/_testdata/overload1/overload.gop
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
func foo = (
func(a, b float64) float64 {
return a + b
}
func(a, b string) string {
return a + b
}
)

func bar = (
addComplex
(T).add
)
94 changes: 94 additions & 0 deletions parser/_testdata/overload1/parser.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

file overload.gop
ast.OverloadFuncDecl:
Name:
ast.Ident:
Name: foo
Funcs:
ast.FuncLit:
Type:
ast.FuncType:
Params:
ast.FieldList:
List:
ast.Field:
Names:
ast.Ident:
Name: a
ast.Ident:
Name: b
Type:
ast.Ident:
Name: float64
Results:
ast.FieldList:
List:
ast.Field:
Type:
ast.Ident:
Name: float64
Body:
ast.BlockStmt:
List:
ast.ReturnStmt:
Results:
ast.BinaryExpr:
X:
ast.Ident:
Name: a
Op: +
Y:
ast.Ident:
Name: b
ast.FuncLit:
Type:
ast.FuncType:
Params:
ast.FieldList:
List:
ast.Field:
Names:
ast.Ident:
Name: a
ast.Ident:
Name: b
Type:
ast.Ident:
Name: string
Results:
ast.FieldList:
List:
ast.Field:
Type:
ast.Ident:
Name: string
Body:
ast.BlockStmt:
List:
ast.ReturnStmt:
Results:
ast.BinaryExpr:
X:
ast.Ident:
Name: a
Op: +
Y:
ast.Ident:
Name: b
ast.OverloadFuncDecl:
Name:
ast.Ident:
Name: bar
Funcs:
ast.Ident:
Name: addComplex
ast.SelectorExpr:
X:
ast.ParenExpr:
X:
ast.Ident:
Name: T
Sel:
ast.Ident:
Name: add
11 changes: 11 additions & 0 deletions parser/_testdata/overload2/overload2.gop
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
func (T).* = (
mul1
mul2
)

func (T).add = (
add1
func(a, b T) T {
return a + b
}
)
Loading

0 comments on commit b07c375

Please sign in to comment.