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

Bash-style interpolation in strings, closes #169 #280

Merged
merged 1 commit into from
Sep 8, 2019
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ if !res.ok {
ip = res.json().ip
total = ip.split(".").map(int).sum()
if total > 100 {
echo("The sum of [%s] is a large number, %s.", ip, total)
echo("The sum of [$ip] is a large number, $total.")
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ if !res.ok {
ip = res.json().ip
total = ip.split(".").map(int).sum()
if total > 100 {
echo("The sum of [%s] is a large number, %s.", ip, total)
echo("The sum of [$ip] is a large number, $total.")
}
```

Expand Down
19 changes: 19 additions & 0 deletions docs/types/string.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,25 @@ To test for the existence of substrings within strings use the `in` operator:
"xyz" in "string" # false
```

## Interpolation

You can also replace parts of the string with variables
declared within your program using the `$` symbol:

``` bash
file = "/etc/hosts"
x = "File name is: $file"
echo(x) # "File name is: /etc/hosts"
```

If you need `$` literals in your command, you
simply need to escape them with a `\`:

``` bash
"$non_existing_var" # "" since the ABS variable 'non_existing_var' doesn't exist
"\$non_existing_var" # "$non_existing_var"
```

## Special characters embedded in strings

Double and single quoted strings behave differently if the string contains
Expand Down
2 changes: 1 addition & 1 deletion evaluator/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
return NULL

case *ast.StringLiteral:
return &object.String{Token: node.Token, Value: node.Value}
return &object.String{Token: node.Token, Value: util.InterpolateStringVars(node.Value, env)}

case *ast.Boolean:
return nativeBoolToBooleanObject(node.Value)
Expand Down
16 changes: 16 additions & 0 deletions evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,22 @@ func TestStringWriters(t *testing.T) {
}
}

func TestStringInterpolation(t *testing.T) {
tests := []struct {
input string
expected string
}{
{`a = "123"; "abc$a"`, "abc123"},
{`a = "123"; "abc\$a"`, "abc$a"},
{`a = "123"; "$$a$$a$$a"`, "$123$123$123"},
}

for _, tt := range tests {
evaluated := testEval(tt.input)
testStringObject(t, evaluated, tt.expected)
}
}

func TestForInExpressions(t *testing.T) {
tests := []struct {
input string
Expand Down
2 changes: 1 addition & 1 deletion examples/ip-sum.abs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ if !res.ok {
ip = res.json().ip
total = ip.split(".").map(int).sum()
if total > 100 {
echo("The sum of [%s] is a large number, %s.", ip, total)
echo("The sum of [$ip] is a large number, $total.")
}
4 changes: 2 additions & 2 deletions scripts/release.abs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ if !rm.ok {

version = `cat ./main.go | grep "var Version"`
version = version.slice(15, len(version) - 1)
echo("Running builds for version %s, confirm by typing \"y\"".fmt(version))
echo("Running builds for version $version, confirm by typing \"y\"")
selection = stdin()

if selection != "y" {
Expand All @@ -63,7 +63,7 @@ if selection != "y" {

for platform in platforms {
goos, goarch = platform.split("/")
output_name = "builds/abs-%s-%s-%s".fmt(version, goos, goarch)
output_name = "builds/abs-$version-$goos-$goarch"
entry_point = "main.go"

if goos == "windows" {
Expand Down