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

scanner: -> <> #1763

Merged
merged 1 commit into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2306,7 +2306,7 @@ func (p *parser) isCmd(x ast.Expr) bool {

func (p *parser) checkCmd(x ast.Expr) bool {
switch p.tok {
case token.IDENT, token.RARROW,
case token.IDENT, token.DRARROW,
token.STRING, token.CSTRING, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.RAT,
token.FUNC, token.GOTO, token.MAP, token.INTERFACE, token.CHAN, token.STRUCT:
return true
Expand Down Expand Up @@ -2469,14 +2469,14 @@ type tupleExpr struct {

func (p *parser) parseLambdaExpr(allowTuple, allowCmd, allowRangeExpr bool) (x ast.Expr, isTuple bool) {
var first = p.pos
if p.tok != token.RARROW {
if p.tok != token.DRARROW {
if allowRangeExpr {
x, isTuple = p.parseRangeExpr(true, allowCmd)
} else {
x, isTuple = p.parseBinaryExpr(false, token.LowestPrec+1, true, allowCmd)
}
}
if p.tok == token.RARROW { // =>
if p.tok == token.DRARROW { // =>
var rarrow = p.pos
var rhs []ast.Expr
var body *ast.BlockStmt
Expand Down
4 changes: 2 additions & 2 deletions printer/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
p.expr(x.Lhs[0])
p.print(blank)
}
p.print(token.RARROW, blank)
p.print(token.DRARROW, blank)
if x.RhsHasParen {
p.print(token.LPAREN)
p.exprList(token.NoPos, x.Rhs, 1, noIndent, token.NoPos, false)
Expand All @@ -1085,7 +1085,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
p.expr(x.Lhs[0])
p.print(blank)
}
p.print(token.RARROW, blank)
p.print(token.DRARROW, blank)
p.block(x.Body, 1)

case *ast.RangeExpr:
Expand Down
20 changes: 14 additions & 6 deletions scanner/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -918,9 +918,14 @@ scanAgain:
insertSemi = true
}
case '-':
tok = s.switch3(token.SUB, token.SUB_ASSIGN, '-', token.DEC)
if tok == token.DEC {
insertSemi = true
if s.ch == '>' { // ->
s.next()
tok = token.SRARROW
} else { // --, -=
tok = s.switch3(token.SUB, token.SUB_ASSIGN, '-', token.DEC)
if tok == token.DEC {
insertSemi = true
}
}
case '*':
tok = s.switch2(token.MUL, token.MUL_ASSIGN)
Expand Down Expand Up @@ -967,16 +972,19 @@ scanAgain:
case '^':
tok = s.switch2(token.XOR, token.XOR_ASSIGN)
case '<':
if s.ch == '-' {
if s.ch == '-' { // <-
s.next()
tok = token.ARROW
} else {
} else if s.ch == '>' { // <>
s.next()
tok = token.BIDIARROW
} else { // << <<=
tok = s.switch4(token.LSS, token.LEQ, '<', token.SHL, token.SHL_ASSIGN)
}
case '>':
tok = s.switch4(token.GTR, token.GEQ, '>', token.SHR, token.SHR_ASSIGN)
case '=':
tok = s.switch3(token.ASSIGN, token.EQL, '>', token.RARROW)
tok = s.switch3(token.ASSIGN, token.EQL, '>', token.DRARROW)
case '!':
tok = s.switch2(token.NOT, token.NEQ)
if tok == token.NOT {
Expand Down
30 changes: 13 additions & 17 deletions token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

// Package token defines constants representing the lexical tokens of the Go+
// programming language and basic operations on tokens (printing, predicates).
//
package token

import (
Expand Down Expand Up @@ -141,10 +140,15 @@ const (
TILDE // additional tokens, handled in an ad-hoc manner
additional_end

CSTRING = literal_beg // C"Hello"
RAT = literal_end // 123.5r
RARROW = operator_beg // =>
QUESTION = operator_end // ?
CSTRING = literal_beg // C"Hello"
RAT = literal_end // 123.5r
DRARROW = operator_beg // => (double right arrow)
QUESTION = operator_end // ?
SRARROW = additional_beg // -> (single right arrow)
BIDIARROW = additional_end // <> (bidirectional arrow)

// Deprecated: use DRARROW instead of RARROW
RARROW = DRARROW
)

var tokens = [...]string{
Expand Down Expand Up @@ -218,7 +222,9 @@ var tokens = [...]string{
SEMICOLON: ";",
COLON: ":",
QUESTION: "?",
RARROW: "=>",
DRARROW: "=>",
SRARROW: "->",
BIDIARROW: "<>",
TILDE: "~",

BREAK: "break",
Expand Down Expand Up @@ -257,7 +263,6 @@ var tokens = [...]string{
// token character sequence (e.g., for the token ADD, the string is
// "+"). For all other tokens the string corresponds to the token
// constant name (e.g. for the token IDENT, the string is "IDENT").
//
func (tok Token) String() string {
s := ""
if 0 <= tok && tok < Token(len(tokens)) {
Expand All @@ -274,7 +279,6 @@ func (tok Token) String() string {
// starting with precedence 1 up to unary operators. The highest
// precedence serves as "catch-all" precedence for selector,
// indexing, and other operator and delimiter tokens.
//
const (
LowestPrec = 0 // non-operators
UnaryPrec = 6
Expand All @@ -284,7 +288,6 @@ const (
// Precedence returns the operator precedence of the binary
// operator op. If op is not a binary operator, the result
// is LowestPrecedence.
//
func (op Token) Precedence() int {
switch op {
case LOR:
Expand All @@ -311,7 +314,6 @@ func init() {
}

// Lookup maps an identifier to its keyword token or IDENT (if not a keyword).
//
func Lookup(ident string) Token {
if tok, is_keyword := keywords[ident]; is_keyword {
return tok
Expand All @@ -323,41 +325,35 @@ func Lookup(ident string) Token {

// IsLiteral returns true for tokens corresponding to identifiers
// and basic type literals; it returns false otherwise.
//
func (tok Token) IsLiteral() bool {
return literal_beg <= tok && tok <= literal_end
}

// IsOperator returns true for tokens corresponding to operators and
// delimiters; it returns false otherwise.
//
func (tok Token) IsOperator() bool {
return operator_beg <= tok && tok <= operator_end || tok == TILDE
return operator_beg <= tok && tok <= operator_end || tok >= additional_beg && tok <= additional_end
}

// IsKeyword returns true for tokens corresponding to keywords;
// it returns false otherwise.
//
func (tok Token) IsKeyword() bool {
return keyword_beg < tok && tok < keyword_end
}

// IsExported reports whether name starts with an upper-case letter.
//
func IsExported(name string) bool {
return token.IsExported(name)
}

// IsKeyword reports whether name is a Go keyword, such as "func" or "return".
//
func IsKeyword(name string) bool {
return token.IsKeyword(name)
}

// IsIdentifier reports whether name is a Go identifier, that is, a non-empty
// string made up of letters, digits, and underscores, where the first character
// is not a digit. Keywords are not identifiers.
//
func IsIdentifier(name string) bool {
return token.IsIdentifier(name)
}