docs: document remaining packages and simplify AST types (#45)
## Summary - Added doc comments across the codebase: `pkg/lambda`, `pkg/saccharine`, `pkg/codec`, `pkg/engine`, `pkg/iterator`, `pkg/set`, `pkg/convert`, `internal/registry`, and `cmd/lambda`. - Made lambda and saccharine expression structs use public fields instead of getters, matching `go/ast` conventions. - Removed superfluous constructors for saccharine and lambda expression/statement types in favor of struct literals. - Consolidated saccharine token constructors into a single `NewToken` function. - Removed the unused `trace` package. ## Test plan - [x] `go build ./...` passes. - [x] `go test ./...` passes. - [ ] Verify `go doc` output renders correctly for documented packages. Reviewed-on: #45 Co-authored-by: M.V. Hutz <git@maximhutz.me> Co-committed-by: M.V. Hutz <git@maximhutz.me>
This commit was merged in pull request #45.
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
// Package "saccharine" provides a simple language built on top of λ-calculus,
|
||||
// to facilitate productive coding using it.
|
||||
package saccharine
|
||||
|
||||
import (
|
||||
"git.maximhutz.com/max/lambda/pkg/codec"
|
||||
)
|
||||
|
||||
type Marshaler struct{}
|
||||
// A Codec is a [codec.Codec] that serializes Saccharine expressions.
|
||||
type Codec struct{}
|
||||
|
||||
func (m Marshaler) Decode(s string) (Expression, error) {
|
||||
// Decode parses a string as Saccharine source code. Returns an error
|
||||
// if it cannot.
|
||||
func (c Codec) Decode(s string) (Expression, error) {
|
||||
tokens, err := scan(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -17,8 +18,10 @@ func (m Marshaler) Decode(s string) (Expression, error) {
|
||||
return parse(tokens)
|
||||
}
|
||||
|
||||
func (m Marshaler) Encode(e Expression) (string, error) {
|
||||
// Encode turns a Saccharine expression into a string. Returns an error if it
|
||||
// cannot.
|
||||
func (c Codec) Encode(e Expression) (string, error) {
|
||||
return stringifyExpression(e), nil
|
||||
}
|
||||
|
||||
var _ codec.Codec[Expression] = (*Marshaler)(nil)
|
||||
var _ codec.Codec[Expression] = (*Codec)(nil)
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package saccharine
|
||||
|
||||
type Expression interface {
|
||||
IsExpression()
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------------------------- */
|
||||
|
||||
type Abstraction struct {
|
||||
Parameters []string
|
||||
Body Expression
|
||||
}
|
||||
|
||||
type Application struct {
|
||||
Abstraction Expression
|
||||
Arguments []Expression
|
||||
}
|
||||
|
||||
type Atom struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type Clause struct {
|
||||
Statements []Statement
|
||||
Returns Expression
|
||||
}
|
||||
|
||||
func (Abstraction) IsExpression() {}
|
||||
func (Application) IsExpression() {}
|
||||
func (Atom) IsExpression() {}
|
||||
func (Clause) IsExpression() {}
|
||||
|
||||
/** ------------------------------------------------------------------------- */
|
||||
|
||||
func NewAbstraction(parameter []string, body Expression) *Abstraction {
|
||||
return &Abstraction{Parameters: parameter, Body: body}
|
||||
}
|
||||
|
||||
func NewApplication(abstraction Expression, arguments []Expression) *Application {
|
||||
return &Application{Abstraction: abstraction, Arguments: arguments}
|
||||
}
|
||||
|
||||
func NewAtom(name string) *Atom {
|
||||
return &Atom{Name: name}
|
||||
}
|
||||
|
||||
func NewClause(statements []Statement, returns Expression) *Clause {
|
||||
return &Clause{Statements: statements, Returns: returns}
|
||||
}
|
||||
@@ -5,13 +5,12 @@ import (
|
||||
"fmt"
|
||||
|
||||
"git.maximhutz.com/max/lambda/pkg/iterator"
|
||||
"git.maximhutz.com/max/lambda/pkg/trace"
|
||||
)
|
||||
|
||||
type TokenIterator = iterator.Iterator[Token]
|
||||
type tokenIterator = iterator.Iterator[Token]
|
||||
|
||||
func parseRawToken(i *TokenIterator, expected TokenType) (*Token, error) {
|
||||
return iterator.Do(i, func(i *TokenIterator) (*Token, error) {
|
||||
func parseRawToken(i *tokenIterator, expected TokenType) (*Token, error) {
|
||||
return iterator.Do(i, func(i *tokenIterator) (*Token, error) {
|
||||
if tok, err := i.Next(); err != nil {
|
||||
return nil, err
|
||||
} else if tok.Type != expected {
|
||||
@@ -22,7 +21,7 @@ func parseRawToken(i *TokenIterator, expected TokenType) (*Token, error) {
|
||||
})
|
||||
}
|
||||
|
||||
func passSoftBreaks(i *TokenIterator) {
|
||||
func passSoftBreaks(i *tokenIterator) {
|
||||
for {
|
||||
if _, err := parseRawToken(i, TokenSoftBreak); err != nil {
|
||||
return
|
||||
@@ -30,8 +29,8 @@ func passSoftBreaks(i *TokenIterator) {
|
||||
}
|
||||
}
|
||||
|
||||
func parseToken(i *TokenIterator, expected TokenType, ignoreSoftBreaks bool) (*Token, error) {
|
||||
return iterator.Do(i, func(i *TokenIterator) (*Token, error) {
|
||||
func parseToken(i *tokenIterator, expected TokenType, ignoreSoftBreaks bool) (*Token, error) {
|
||||
return iterator.Do(i, func(i *tokenIterator) (*Token, error) {
|
||||
if ignoreSoftBreaks {
|
||||
passSoftBreaks(i)
|
||||
}
|
||||
@@ -40,15 +39,15 @@ func parseToken(i *TokenIterator, expected TokenType, ignoreSoftBreaks bool) (*T
|
||||
})
|
||||
}
|
||||
|
||||
func parseString(i *TokenIterator) (string, error) {
|
||||
func parseString(i *tokenIterator) (string, error) {
|
||||
if tok, err := parseToken(i, TokenAtom, true); err != nil {
|
||||
return "", trace.Wrap(err, "no variable (col %d)", i.Index())
|
||||
return "", fmt.Errorf("no variable (col %d): %w", i.Index(), err)
|
||||
} else {
|
||||
return tok.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
func parseBreak(i *TokenIterator) (*Token, error) {
|
||||
func parseBreak(i *tokenIterator) (*Token, error) {
|
||||
if tok, softErr := parseRawToken(i, TokenSoftBreak); softErr == nil {
|
||||
return tok, nil
|
||||
} else if tok, hardErr := parseRawToken(i, TokenHardBreak); hardErr == nil {
|
||||
@@ -58,13 +57,13 @@ func parseBreak(i *TokenIterator) (*Token, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func parseList[U any](i *TokenIterator, fn func(*TokenIterator) (U, error), minimum int) ([]U, error) {
|
||||
func parseList[U any](i *tokenIterator, fn func(*tokenIterator) (U, error), minimum int) ([]U, error) {
|
||||
results := []U{}
|
||||
|
||||
for {
|
||||
if u, err := fn(i); err != nil {
|
||||
if len(results) < minimum {
|
||||
return nil, trace.Wrap(err, "expected at least '%v' items, got only '%v'", minimum, len(results))
|
||||
return nil, fmt.Errorf("expected at least '%v' items, got only '%v': %w", minimum, len(results), err)
|
||||
}
|
||||
return results, nil
|
||||
} else {
|
||||
@@ -73,45 +72,45 @@ func parseList[U any](i *TokenIterator, fn func(*TokenIterator) (U, error), mini
|
||||
}
|
||||
}
|
||||
|
||||
func parseAbstraction(i *TokenIterator) (*Abstraction, error) {
|
||||
return iterator.Do(i, func(i *TokenIterator) (*Abstraction, error) {
|
||||
func parseAbstraction(i *tokenIterator) (*Abstraction, error) {
|
||||
return iterator.Do(i, func(i *tokenIterator) (*Abstraction, error) {
|
||||
if _, err := parseToken(i, TokenSlash, true); err != nil {
|
||||
return nil, trace.Wrap(err, "no function slash (col %d)", i.MustGet().Column)
|
||||
return nil, fmt.Errorf("no function slash (col %d): %w", i.MustGet().Column, err)
|
||||
} else if parameters, err := parseList(i, parseString, 0); err != nil {
|
||||
return nil, err
|
||||
} else if _, err = parseToken(i, TokenDot, true); err != nil {
|
||||
return nil, trace.Wrap(err, "no function dot (col %d)", i.MustGet().Column)
|
||||
return nil, fmt.Errorf("no function dot (col %d): %w", i.MustGet().Column, err)
|
||||
} else if body, err := parseExpression(i); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return NewAbstraction(parameters, body), nil
|
||||
return &Abstraction{Parameters: parameters, Body: body}, nil
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func parseApplication(i *TokenIterator) (*Application, error) {
|
||||
return iterator.Do(i, func(i *TokenIterator) (*Application, error) {
|
||||
func parseApplication(i *tokenIterator) (*Application, error) {
|
||||
return iterator.Do(i, func(i *tokenIterator) (*Application, error) {
|
||||
if _, err := parseToken(i, TokenOpenParen, true); err != nil {
|
||||
return nil, trace.Wrap(err, "no openning brackets (col %d)", i.MustGet().Column)
|
||||
return nil, fmt.Errorf("no openning brackets (col %d): %w", i.MustGet().Column, err)
|
||||
} else if expressions, err := parseList(i, parseExpression, 1); err != nil {
|
||||
return nil, err
|
||||
} else if _, err := parseToken(i, TokenCloseParen, true); err != nil {
|
||||
return nil, trace.Wrap(err, "no closing brackets (col %d)", i.MustGet().Column)
|
||||
return nil, fmt.Errorf("no closing brackets (col %d): %w", i.MustGet().Column, err)
|
||||
} else {
|
||||
return NewApplication(expressions[0], expressions[1:]), nil
|
||||
return &Application{Abstraction: expressions[0], Arguments: expressions[1:]}, nil
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func parseAtom(i *TokenIterator) (*Atom, error) {
|
||||
func parseAtom(i *tokenIterator) (*Atom, error) {
|
||||
if tok, err := parseToken(i, TokenAtom, true); err != nil {
|
||||
return nil, trace.Wrap(err, "no variable (col %d)", i.Index())
|
||||
return nil, fmt.Errorf("no variable (col %d): %w", i.Index(), err)
|
||||
} else {
|
||||
return NewAtom(tok.Value), nil
|
||||
return &Atom{Name: tok.Value}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func parseStatements(i *TokenIterator) ([]Statement, error) {
|
||||
func parseStatements(i *tokenIterator) ([]Statement, error) {
|
||||
statements := []Statement{}
|
||||
|
||||
//nolint:errcheck
|
||||
@@ -130,7 +129,7 @@ func parseStatements(i *TokenIterator) ([]Statement, error) {
|
||||
return statements, nil
|
||||
}
|
||||
|
||||
func parseClause(i *TokenIterator, braces bool) (*Clause, error) {
|
||||
func parseClause(i *tokenIterator, braces bool) (*Clause, error) {
|
||||
if braces {
|
||||
if _, err := parseToken(i, TokenOpenBrace, true); err != nil {
|
||||
return nil, err
|
||||
@@ -156,11 +155,11 @@ func parseClause(i *TokenIterator, braces bool) (*Clause, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return NewClause(stmts[:len(stmts)-1], last.Value), nil
|
||||
return &Clause{Statements: stmts[:len(stmts)-1], Returns: last.Value}, nil
|
||||
}
|
||||
|
||||
func parseExpression(i *TokenIterator) (Expression, error) {
|
||||
return iterator.Do(i, func(i *TokenIterator) (Expression, error) {
|
||||
func parseExpression(i *tokenIterator) (Expression, error) {
|
||||
return iterator.Do(i, func(i *tokenIterator) (Expression, error) {
|
||||
passSoftBreaks(i)
|
||||
|
||||
switch peek := i.MustGet(); peek.Type {
|
||||
@@ -178,8 +177,8 @@ func parseExpression(i *TokenIterator) (Expression, error) {
|
||||
})
|
||||
}
|
||||
|
||||
func parseLet(i *TokenIterator) (*LetStatement, error) {
|
||||
return iterator.Do(i, func(i *TokenIterator) (*LetStatement, error) {
|
||||
func parseLet(i *tokenIterator) (*LetStatement, error) {
|
||||
return iterator.Do(i, func(i *tokenIterator) (*LetStatement, error) {
|
||||
if parameters, err := parseList(i, parseString, 1); err != nil {
|
||||
return nil, err
|
||||
} else if _, err := parseToken(i, TokenAssign, true); err != nil {
|
||||
@@ -187,20 +186,20 @@ func parseLet(i *TokenIterator) (*LetStatement, error) {
|
||||
} else if body, err := parseExpression(i); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return NewLet(parameters[0], parameters[1:], body), nil
|
||||
return &LetStatement{Name: parameters[0], Parameters: parameters[1:], Body: body}, nil
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func parseDeclare(i *TokenIterator) (*DeclareStatement, error) {
|
||||
func parseDeclare(i *tokenIterator) (*DeclareStatement, error) {
|
||||
if value, err := parseExpression(i); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return NewDeclare(value), nil
|
||||
return &DeclareStatement{Value: value}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func parseStatement(i *TokenIterator) (Statement, error) {
|
||||
func parseStatement(i *tokenIterator) (Statement, error) {
|
||||
if let, letErr := parseLet(i); letErr == nil {
|
||||
return let, nil
|
||||
} else if declare, declErr := parseDeclare(i); declErr == nil {
|
||||
|
||||
60
pkg/saccharine/saccharine.go
Normal file
60
pkg/saccharine/saccharine.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Package saccharine defines the AST for the Saccharine language, a sugared
|
||||
// lambda calculus with let bindings and multi-statement clauses.
|
||||
package saccharine
|
||||
|
||||
// An Expression is a node in the Saccharine abstract syntax tree.
|
||||
// It is a sealed interface; only types in this package may implement it.
|
||||
type Expression interface {
|
||||
expression()
|
||||
}
|
||||
|
||||
// An Abstraction is a lambda expression with zero or more parameters.
|
||||
// A zero-parameter abstraction is treated as a thunk.
|
||||
type Abstraction struct {
|
||||
Parameters []string
|
||||
Body Expression
|
||||
}
|
||||
|
||||
// An Application applies an expression to zero or more arguments.
|
||||
type Application struct {
|
||||
Abstraction Expression
|
||||
Arguments []Expression
|
||||
}
|
||||
|
||||
// An Atom is a named variable.
|
||||
type Atom struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// A Clause is a sequence of statements followed by a return expression.
|
||||
type Clause struct {
|
||||
Statements []Statement
|
||||
Returns Expression
|
||||
}
|
||||
|
||||
func (Abstraction) expression() {}
|
||||
func (Application) expression() {}
|
||||
func (Atom) expression() {}
|
||||
func (Clause) expression() {}
|
||||
|
||||
// A Statement is a declaration within a Clause.
|
||||
// It is a sealed interface; only types in this package may implement it.
|
||||
type Statement interface {
|
||||
statement()
|
||||
}
|
||||
|
||||
// A LetStatement binds a name (with optional parameters) to an expression.
|
||||
type LetStatement struct {
|
||||
Name string
|
||||
Parameters []string
|
||||
Body Expression
|
||||
}
|
||||
|
||||
// A DeclareStatement evaluates an expression for its side effects within a
|
||||
// clause.
|
||||
type DeclareStatement struct {
|
||||
Value Expression
|
||||
}
|
||||
|
||||
func (LetStatement) statement() {}
|
||||
func (DeclareStatement) statement() {}
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"unicode"
|
||||
|
||||
"git.maximhutz.com/max/lambda/pkg/iterator"
|
||||
"git.maximhutz.com/max/lambda/pkg/trace"
|
||||
)
|
||||
|
||||
// isVariables determines whether a rune can be a valid variable.
|
||||
@@ -51,38 +50,38 @@ func scanToken(i *iterator.Iterator[rune]) (*Token, error) {
|
||||
|
||||
letter, err := i.Next()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "cannot produce next token")
|
||||
return nil, fmt.Errorf("cannot produce next token: %w", err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case letter == '(':
|
||||
return NewTokenOpenParen(index), nil
|
||||
return NewToken(TokenOpenParen, index), nil
|
||||
case letter == ')':
|
||||
return NewTokenCloseParen(index), nil
|
||||
return NewToken(TokenCloseParen, index), nil
|
||||
case letter == '.':
|
||||
return NewTokenDot(index), nil
|
||||
return NewToken(TokenDot, index), nil
|
||||
case letter == '\\':
|
||||
return NewTokenSlash(index), nil
|
||||
return NewToken(TokenSlash, index), nil
|
||||
case letter == '\n':
|
||||
return NewTokenSoftBreak(index), nil
|
||||
return NewToken(TokenSoftBreak, index), nil
|
||||
case letter == '{':
|
||||
return NewTokenOpenBrace(index), nil
|
||||
return NewToken(TokenOpenBrace, index), nil
|
||||
case letter == '}':
|
||||
return NewTokenCloseBrace(index), nil
|
||||
return NewToken(TokenCloseBrace, index), nil
|
||||
case letter == ':':
|
||||
if _, err := scanCharacter(i, '='); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return NewTokenAssign(index), nil
|
||||
return NewToken(TokenAssign, index), nil
|
||||
}
|
||||
case letter == ';':
|
||||
return NewTokenHardBreak(index), nil
|
||||
return NewToken(TokenHardBreak, index), nil
|
||||
case letter == '#':
|
||||
// Skip everything until the next newline or EOF.
|
||||
for !i.Done() {
|
||||
r, err := i.Next()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "error while parsing comment")
|
||||
return nil, fmt.Errorf("error while parsing comment: %w", err)
|
||||
}
|
||||
|
||||
if r == '\n' {
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
package saccharine
|
||||
|
||||
type Statement interface {
|
||||
IsStatement()
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------------------------- */
|
||||
|
||||
type LetStatement struct {
|
||||
Name string
|
||||
Parameters []string
|
||||
Body Expression
|
||||
}
|
||||
|
||||
type DeclareStatement struct {
|
||||
Value Expression
|
||||
}
|
||||
|
||||
func (LetStatement) IsStatement() {}
|
||||
func (DeclareStatement) IsStatement() {}
|
||||
|
||||
/** ------------------------------------------------------------------------- */
|
||||
|
||||
func NewLet(name string, parameters []string, body Expression) *LetStatement {
|
||||
return &LetStatement{Name: name, Parameters: parameters, Body: body}
|
||||
}
|
||||
|
||||
func NewDeclare(value Expression) *DeclareStatement {
|
||||
return &DeclareStatement{Value: value}
|
||||
}
|
||||
@@ -2,90 +2,80 @@ package saccharine
|
||||
|
||||
import "fmt"
|
||||
|
||||
// All tokens in the pseudo-lambda language.
|
||||
// A TokenType is an identifier for any token in the Saccharine language.
|
||||
type TokenType int
|
||||
|
||||
// All official tokens of the Saccharine language.
|
||||
const (
|
||||
TokenOpenParen TokenType = iota // Denotes the '(' token.
|
||||
TokenCloseParen // Denotes the ')' token.
|
||||
TokenOpenBrace // Denotes the '{' token.
|
||||
TokenCloseBrace // Denotes the '}' token.
|
||||
TokenHardBreak // Denotes the ';' token.
|
||||
TokenAssign // Denotes the ':=' token.
|
||||
TokenAtom // Denotes an alpha-numeric variable.
|
||||
TokenSlash // Denotes the '/' token.
|
||||
TokenDot // Denotes the '.' token.
|
||||
TokenSoftBreak // Denotes a new-line.
|
||||
// TokenOpenParen denotes the '(' token.
|
||||
TokenOpenParen TokenType = iota
|
||||
// TokenCloseParen denotes the ')' token.
|
||||
TokenCloseParen
|
||||
// TokenOpenBrace denotes the '{' token.
|
||||
TokenOpenBrace
|
||||
// TokenCloseBrace denotes the '}' token.
|
||||
TokenCloseBrace
|
||||
// TokenHardBreak denotes the ';' token.
|
||||
TokenHardBreak
|
||||
// TokenAssign denotes the ':=' token.
|
||||
TokenAssign
|
||||
// TokenAtom denotes an alpha-numeric variable.
|
||||
TokenAtom
|
||||
// TokenSlash denotes the '/' token.
|
||||
TokenSlash
|
||||
// TokenDot denotes the '.' token.
|
||||
TokenDot
|
||||
// TokenSoftBreak denotes a new-line.
|
||||
TokenSoftBreak
|
||||
)
|
||||
|
||||
// A representation of a token in source code.
|
||||
// A Token in the Saccharine language.
|
||||
type Token struct {
|
||||
Column int // Where the token begins in the source text.
|
||||
Type TokenType // What type the token is.
|
||||
Value string // The value of the token.
|
||||
}
|
||||
|
||||
func NewTokenOpenParen(column int) *Token {
|
||||
return &Token{Type: TokenOpenParen, Column: column, Value: "("}
|
||||
}
|
||||
|
||||
func NewTokenCloseParen(column int) *Token {
|
||||
return &Token{Type: TokenCloseParen, Column: column, Value: ")"}
|
||||
}
|
||||
|
||||
func NewTokenOpenBrace(column int) *Token {
|
||||
return &Token{Type: TokenOpenBrace, Column: column, Value: "{"}
|
||||
}
|
||||
|
||||
func NewTokenCloseBrace(column int) *Token {
|
||||
return &Token{Type: TokenCloseBrace, Column: column, Value: "}"}
|
||||
}
|
||||
|
||||
func NewTokenDot(column int) *Token {
|
||||
return &Token{Type: TokenDot, Column: column, Value: "."}
|
||||
}
|
||||
|
||||
func NewTokenHardBreak(column int) *Token {
|
||||
return &Token{Type: TokenHardBreak, Column: column, Value: ";"}
|
||||
}
|
||||
|
||||
func NewTokenAssign(column int) *Token {
|
||||
return &Token{Type: TokenAssign, Column: column, Value: ":="}
|
||||
}
|
||||
|
||||
func NewTokenSlash(column int) *Token {
|
||||
return &Token{Type: TokenSlash, Column: column, Value: "\\"}
|
||||
// NewToken creates a [Token] of the given type at the given column.
|
||||
// The token's value is derived from its [TokenType].
|
||||
func NewToken(typ TokenType, column int) *Token {
|
||||
return &Token{Type: typ, Column: column, Value: typ.Name()}
|
||||
}
|
||||
|
||||
// NewTokenAtom creates a [TokenAtom] with the given name at the given column.
|
||||
func NewTokenAtom(name string, column int) *Token {
|
||||
return &Token{Type: TokenAtom, Column: column, Value: name}
|
||||
}
|
||||
|
||||
func NewTokenSoftBreak(column int) *Token {
|
||||
return &Token{Type: TokenSoftBreak, Column: column, Value: "\\n"}
|
||||
}
|
||||
|
||||
// Name returns the type of the TokenType, as a string.
|
||||
func (t TokenType) Name() string {
|
||||
switch t {
|
||||
case TokenOpenParen:
|
||||
return "("
|
||||
case TokenCloseParen:
|
||||
return ")"
|
||||
case TokenOpenBrace:
|
||||
return "{"
|
||||
case TokenCloseBrace:
|
||||
return "}"
|
||||
case TokenHardBreak:
|
||||
return ";"
|
||||
case TokenAssign:
|
||||
return ":="
|
||||
case TokenAtom:
|
||||
return "ATOM"
|
||||
case TokenSlash:
|
||||
return "\\"
|
||||
case TokenDot:
|
||||
return "."
|
||||
case TokenAtom:
|
||||
return "ATOM"
|
||||
case TokenSoftBreak:
|
||||
return "\\n"
|
||||
case TokenHardBreak:
|
||||
return ";"
|
||||
default:
|
||||
panic(fmt.Errorf("unknown token type %v", t))
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the type of the Token, as a string.
|
||||
func (t Token) Name() string {
|
||||
return t.Type.Name()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user