Skip to content

Commit

Permalink
Fixed string interpolation in system commands, closes #81
Browse files Browse the repository at this point in the history
  • Loading branch information
odino committed Dec 28, 2018
1 parent 5e7d003 commit bc74829
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
8 changes: 8 additions & 0 deletions docs/syntax/system-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ x = $(cat /proc/$file)
echo(x) # processor: 0\nvendor_id: GenuineIntel...
```
and if you need `$` literals in your command, you
simply need to escape them with a `\`:
``` bash
$(echo $PWD) # "" since the ABS variable PWD doesn't exist
$(echo \$PWD) # "/go/src/github.com/abs-lang/abs"
```
Currently, commands need to be on their own line, meaning
that you will not be able to have additional code
on the same line. This will throw an error:
Expand Down
18 changes: 17 additions & 1 deletion evaluator/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -874,8 +874,24 @@ func evalHashIndexExpression(hash, index object.Object) object.Object {
}

func evalCommandExpression(cmd string, env *object.Environment) object.Object {
re := regexp.MustCompile("\\$([a-zA-Z_]{1,})")
// Match all strings preceded by
// a $ or a \$
re := regexp.MustCompile("(\\\\)?\\$([a-zA-Z_]{1,})")
cmd = re.ReplaceAllStringFunc(cmd, func(m string) string {
// If the string starts with a backslash,
// that's an escape, so we should replace
// it with the remaining portion of the match.
// \$VAR becomes $VAR
if string(m[0]) == "\\" {
return m[1:]
}

// If the string starts with $, then
// it's an interpolation. Let's
// replace $VAR with the variable
// named VAR in the ABS' environment.
// If the variable is not found, we
// just dump an empty string
v, ok := env.Get(m[1:])

if !ok {
Expand Down
1 change: 1 addition & 0 deletions evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,7 @@ func TestCommand(t *testing.T) {
{`$(echo -n "123")`, "123"},
{`$(echo -n hello world)`, "hello world"},
{`$(echo hello world | xargs echo -n)`, "hello world"},
{`$(echo \$CONTEXT)`, "abs"},
}

for _, tt := range tests {
Expand Down

0 comments on commit bc74829

Please sign in to comment.