Fixed the issue with colons in ident
This commit is contained in:
parent
78720eeb5b
commit
0dc9fd3c32
23
ucl/ast.go
23
ucl/ast.go
|
@ -2,6 +2,7 @@ package ucl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/alecthomas/participle/v2"
|
"github.com/alecthomas/participle/v2"
|
||||||
"github.com/alecthomas/participle/v2/lexer"
|
"github.com/alecthomas/participle/v2/lexer"
|
||||||
|
@ -12,11 +13,19 @@ type astLiteral struct {
|
||||||
Int *int `parser:"| @Int"`
|
Int *int `parser:"| @Int"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type astHashKey struct {
|
type astIdentNames struct {
|
||||||
Literal *astLiteral `parser:"@@"`
|
Ident string `parser:"@Ident"`
|
||||||
Ident *string `parser:"| @Ident"`
|
ColonParts []string `parser:"( COLON @Ident )*"`
|
||||||
Var *string `parser:"| DOLLAR @Ident"`
|
}
|
||||||
Sub *astPipeline `parser:"| LP @@ RP"`
|
|
||||||
|
func (ai *astIdentNames) String() string {
|
||||||
|
sb := strings.Builder{}
|
||||||
|
sb.WriteString(ai.Ident)
|
||||||
|
for _, p := range ai.ColonParts {
|
||||||
|
sb.WriteRune(':')
|
||||||
|
sb.WriteString(p)
|
||||||
|
}
|
||||||
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type astElementPair struct {
|
type astElementPair struct {
|
||||||
|
@ -41,7 +50,7 @@ type astMaybeSub struct {
|
||||||
|
|
||||||
type astCmdArg struct {
|
type astCmdArg struct {
|
||||||
Literal *astLiteral `parser:"@@"`
|
Literal *astLiteral `parser:"@@"`
|
||||||
Ident *string `parser:"| @Ident"`
|
Ident *astIdentNames `parser:"| @@"`
|
||||||
Var *string `parser:"| DOLLAR @Ident"`
|
Var *string `parser:"| DOLLAR @Ident"`
|
||||||
MaybeSub *astMaybeSub `parser:"| LP @@ RP"`
|
MaybeSub *astMaybeSub `parser:"| LP @@ RP"`
|
||||||
ListOrHash *astListOrHash `parser:"| @@"`
|
ListOrHash *astListOrHash `parser:"| @@"`
|
||||||
|
@ -83,7 +92,7 @@ var scanner = lexer.MustStateful(lexer.Rules{
|
||||||
{"RC", `\}`, nil},
|
{"RC", `\}`, nil},
|
||||||
{"NL", `[;\n][; \n\t]*`, nil},
|
{"NL", `[;\n][; \n\t]*`, nil},
|
||||||
{"PIPE", `\|`, nil},
|
{"PIPE", `\|`, nil},
|
||||||
{"Ident", `[-]*[a-zA-Z_:][\w-:]*`, nil},
|
{"Ident", `[-]*[a-zA-Z_][\w-]*`, nil},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
var parser = participle.MustBuild[astScript](participle.Lexer(scanner),
|
var parser = participle.MustBuild[astScript](participle.Lexer(scanner),
|
||||||
|
|
|
@ -334,18 +334,17 @@ func foreachBuiltin(ctx context.Context, args macroArgs) (object, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case hashObject:
|
case hashable:
|
||||||
for k, v := range t {
|
err := t.Each(func(k string, v object) error {
|
||||||
last, err = args.evalBlock(ctx, blockIdx, []object{strObject(k), v}, true)
|
last, err = args.evalBlock(ctx, blockIdx, []object{strObject(k), v}, true)
|
||||||
if err != nil {
|
return err
|
||||||
if errors.As(err, &breakErr) {
|
})
|
||||||
if !breakErr.isCont {
|
if errors.As(err, &breakErr) {
|
||||||
return breakErr.ret, nil
|
if !breakErr.isCont {
|
||||||
}
|
return breakErr.ret, nil
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ func (e evaluator) evalPipeline(ctx context.Context, ec *evalCtx, n *astPipeline
|
||||||
func (e evaluator) evalCmd(ctx context.Context, ec *evalCtx, currentPipe object, ast *astCmd) (object, error) {
|
func (e evaluator) evalCmd(ctx context.Context, ec *evalCtx, currentPipe object, ast *astCmd) (object, error) {
|
||||||
switch {
|
switch {
|
||||||
case ast.Name.Ident != nil:
|
case ast.Name.Ident != nil:
|
||||||
name := *ast.Name.Ident
|
name := ast.Name.Ident.String()
|
||||||
|
|
||||||
// Regular command
|
// Regular command
|
||||||
if cmd := ec.lookupInvokable(name); cmd != nil {
|
if cmd := ec.lookupInvokable(name); cmd != nil {
|
||||||
|
@ -117,14 +117,14 @@ func (e evaluator) evalInvokable(ctx context.Context, ec *evalCtx, currentPipe o
|
||||||
argsPtr.Append(currentPipe)
|
argsPtr.Append(currentPipe)
|
||||||
}
|
}
|
||||||
for _, arg := range ast.Args {
|
for _, arg := range ast.Args {
|
||||||
if ident := arg.Ident; ident != nil && (*ident)[0] == '-' {
|
if ident := arg.Ident; ident != nil && ident.String()[0] == '-' {
|
||||||
// Arg switch
|
// Arg switch
|
||||||
if kwargs == nil {
|
if kwargs == nil {
|
||||||
kwargs = make(map[string]*listObject)
|
kwargs = make(map[string]*listObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
argsPtr = &listObject{}
|
argsPtr = &listObject{}
|
||||||
kwargs[(*ident)[1:]] = argsPtr
|
kwargs[ident.String()[1:]] = argsPtr
|
||||||
} else {
|
} else {
|
||||||
ae, err := e.evalArg(ctx, ec, arg)
|
ae, err := e.evalArg(ctx, ec, arg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -153,7 +153,7 @@ func (e evaluator) evalArg(ctx context.Context, ec *evalCtx, n astCmdArg) (objec
|
||||||
case n.Literal != nil:
|
case n.Literal != nil:
|
||||||
return e.evalLiteral(ctx, ec, n.Literal)
|
return e.evalLiteral(ctx, ec, n.Literal)
|
||||||
case n.Ident != nil:
|
case n.Ident != nil:
|
||||||
return strObject(*n.Ident), nil
|
return strObject(n.Ident.String()), nil
|
||||||
case n.Var != nil:
|
case n.Var != nil:
|
||||||
if v, ok := ec.getVar(*n.Var); ok {
|
if v, ok := ec.getVar(*n.Var); ok {
|
||||||
return v, nil
|
return v, nil
|
||||||
|
|
|
@ -194,7 +194,7 @@ func (ma macroArgs) identIs(ctx context.Context, n int, expectedIdent string) bo
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return *lit == expectedIdent
|
return lit.String() == expectedIdent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ma *macroArgs) shiftIdent(ctx context.Context) (string, bool) {
|
func (ma *macroArgs) shiftIdent(ctx context.Context) (string, bool) {
|
||||||
|
@ -205,7 +205,7 @@ func (ma *macroArgs) shiftIdent(ctx context.Context) (string, bool) {
|
||||||
lit := ma.ast.Args[ma.argShift].Ident
|
lit := ma.ast.Args[ma.argShift].Ident
|
||||||
if lit != nil {
|
if lit != nil {
|
||||||
ma.argShift += 1
|
ma.argShift += 1
|
||||||
return *lit, true
|
return lit.String(), true
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
|
@ -465,20 +465,20 @@ func TestBuiltins_Map(t *testing.T) {
|
||||||
proc makeUpper { |x| $x | toUpper }
|
proc makeUpper { |x| $x | toUpper }
|
||||||
|
|
||||||
map ["a" "b" "c"] (proc { |x| makeUpper $x })
|
map ["a" "b" "c"] (proc { |x| makeUpper $x })
|
||||||
`, want: "[A B C]\n"},
|
`, want: "A\nB\nC\n"},
|
||||||
{desc: "map list 2", expr: `
|
{desc: "map list 2", expr: `
|
||||||
set makeUpper (proc { |x| $x | toUpper })
|
set makeUpper (proc { |x| $x | toUpper })
|
||||||
|
|
||||||
map ["a" "b" "c"] $makeUpper
|
map ["a" "b" "c"] $makeUpper
|
||||||
`, want: "[A B C]\n"},
|
`, want: "A\nB\nC\n"},
|
||||||
{desc: "map list with pipe", expr: `
|
{desc: "map list with pipe", expr: `
|
||||||
set makeUpper (proc { |x| $x | toUpper })
|
set makeUpper (proc { |x| $x | toUpper })
|
||||||
|
|
||||||
["a" "b" "c"] | map $makeUpper
|
["a" "b" "c"] | map $makeUpper
|
||||||
`, want: "[A B C]\n"},
|
`, want: "A\nB\nC\n"},
|
||||||
{desc: "map list with block", expr: `
|
{desc: "map list with block", expr: `
|
||||||
map ["a" "b" "c"] { |x| toUpper $x }
|
map ["a" "b" "c"] { |x| toUpper $x }
|
||||||
`, want: "[A B C]\n"},
|
`, want: "A\nB\nC\n"},
|
||||||
{desc: "map list with stream", expr: `
|
{desc: "map list with stream", expr: `
|
||||||
set makeUpper (proc { |x| toUpper $x })
|
set makeUpper (proc { |x| toUpper $x })
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue