Fixed the issue with colons in ident

This commit is contained in:
Leon Mika 2024-05-04 11:35:31 +10:00
parent 78720eeb5b
commit 0dc9fd3c32
5 changed files with 35 additions and 27 deletions

View file

@ -2,6 +2,7 @@ package ucl
import (
"io"
"strings"
"github.com/alecthomas/participle/v2"
"github.com/alecthomas/participle/v2/lexer"
@ -12,11 +13,19 @@ type astLiteral struct {
Int *int `parser:"| @Int"`
}
type astHashKey struct {
Literal *astLiteral `parser:"@@"`
Ident *string `parser:"| @Ident"`
Var *string `parser:"| DOLLAR @Ident"`
Sub *astPipeline `parser:"| LP @@ RP"`
type astIdentNames struct {
Ident string `parser:"@Ident"`
ColonParts []string `parser:"( COLON @Ident )*"`
}
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 {
@ -41,7 +50,7 @@ type astMaybeSub struct {
type astCmdArg struct {
Literal *astLiteral `parser:"@@"`
Ident *string `parser:"| @Ident"`
Ident *astIdentNames `parser:"| @@"`
Var *string `parser:"| DOLLAR @Ident"`
MaybeSub *astMaybeSub `parser:"| LP @@ RP"`
ListOrHash *astListOrHash `parser:"| @@"`
@ -83,7 +92,7 @@ var scanner = lexer.MustStateful(lexer.Rules{
{"RC", `\}`, nil},
{"NL", `[;\n][; \n\t]*`, nil},
{"PIPE", `\|`, nil},
{"Ident", `[-]*[a-zA-Z_:][\w-:]*`, nil},
{"Ident", `[-]*[a-zA-Z_][\w-]*`, nil},
},
})
var parser = participle.MustBuild[astScript](participle.Lexer(scanner),

View file

@ -334,10 +334,11 @@ func foreachBuiltin(ctx context.Context, args macroArgs) (object, error) {
}
}
}
case hashObject:
for k, v := range t {
case hashable:
err := t.Each(func(k string, v object) error {
last, err = args.evalBlock(ctx, blockIdx, []object{strObject(k), v}, true)
if err != nil {
return err
})
if errors.As(err, &breakErr) {
if !breakErr.isCont {
return breakErr.ret, nil
@ -346,8 +347,6 @@ func foreachBuiltin(ctx context.Context, args macroArgs) (object, error) {
return nil, err
}
}
}
}
return last, nil
}

View file

@ -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) {
switch {
case ast.Name.Ident != nil:
name := *ast.Name.Ident
name := ast.Name.Ident.String()
// Regular command
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)
}
for _, arg := range ast.Args {
if ident := arg.Ident; ident != nil && (*ident)[0] == '-' {
if ident := arg.Ident; ident != nil && ident.String()[0] == '-' {
// Arg switch
if kwargs == nil {
kwargs = make(map[string]*listObject)
}
argsPtr = &listObject{}
kwargs[(*ident)[1:]] = argsPtr
kwargs[ident.String()[1:]] = argsPtr
} else {
ae, err := e.evalArg(ctx, ec, arg)
if err != nil {
@ -153,7 +153,7 @@ func (e evaluator) evalArg(ctx context.Context, ec *evalCtx, n astCmdArg) (objec
case n.Literal != nil:
return e.evalLiteral(ctx, ec, n.Literal)
case n.Ident != nil:
return strObject(*n.Ident), nil
return strObject(n.Ident.String()), nil
case n.Var != nil:
if v, ok := ec.getVar(*n.Var); ok {
return v, nil

View file

@ -194,7 +194,7 @@ func (ma macroArgs) identIs(ctx context.Context, n int, expectedIdent string) bo
return false
}
return *lit == expectedIdent
return lit.String() == expectedIdent
}
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
if lit != nil {
ma.argShift += 1
return *lit, true
return lit.String(), true
}
return "", false
}

View file

@ -465,20 +465,20 @@ func TestBuiltins_Map(t *testing.T) {
proc makeUpper { |x| $x | toUpper }
map ["a" "b" "c"] (proc { |x| makeUpper $x })
`, want: "[A B C]\n"},
`, want: "A\nB\nC\n"},
{desc: "map list 2", expr: `
set makeUpper (proc { |x| $x | toUpper })
map ["a" "b" "c"] $makeUpper
`, want: "[A B C]\n"},
`, want: "A\nB\nC\n"},
{desc: "map list with pipe", expr: `
set makeUpper (proc { |x| $x | toUpper })
["a" "b" "c"] | map $makeUpper
`, want: "[A B C]\n"},
`, want: "A\nB\nC\n"},
{desc: "map list with block", expr: `
map ["a" "b" "c"] { |x| toUpper $x }
`, want: "[A B C]\n"},
`, want: "A\nB\nC\n"},
{desc: "map list with stream", expr: `
set makeUpper (proc { |x| toUpper $x })