Skip to content

Commit

Permalink
Merge 2bcbff0 into 4f406f8
Browse files Browse the repository at this point in the history
  • Loading branch information
odino committed Feb 19, 2019
2 parents 4f406f8 + 2bcbff0 commit b787037
Show file tree
Hide file tree
Showing 27 changed files with 1,361 additions and 190 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: repl
run:
docker run -tiv $$(pwd):/go/src/github.com/abs-lang/abs --name abs --rm abs
docker run -ti -v $$(pwd):/go/src/github.com/abs-lang/abs -v /home/`whoami`/.abs_history:/root/.abs_history --name abs --rm abs
fmt:
go fmt ./...
build:
Expand Down
2 changes: 1 addition & 1 deletion docs/installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ MACHINE_TYPE=$(uname -m)
if [ "${MACHINE_TYPE}" = 'x86_64' ]; then
ARCH="amd64"
fi
VERSION=1.1.0
VERSION=1.2.0

echo "Trying to detect the details of your architecture."
echo ""
Expand Down
137 changes: 135 additions & 2 deletions docs/introduction/how-to-run-abs-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,28 @@ Afterwards, you can run ABS scripts with:
``` bash
$ abs path/to/scripts.abs
```
You can also run an executable abs script directly from bash
using a bash shebang line at the top of the script file.

In this example the abs executable is linked to `/usr/local/bin/abs`
and the abs script `~/bin/remote.abs` has its execute permissions set.
```bash
$ cat ~/bin/remote.abs
#! /usr/local/bin/abs
# remote paths are <target>:<path>
from_path = arg(2)
to_path = arg(3)
if ! (from_path && to_path) {
if ! from_path {from_path = "<missing>"}
if ! to_path {to_path = "<missing>"}
echo("FROM: %s, TO: %s", from_path, to_path)
exit(1)
}
...
# the executable abs script above is in the PATH at ~/bin/remote.abs
$ remote.abs
FROM: <missing>, TO: <missing>
```
Scripts do not have to have a specific extension,
although it's recommended to use `.abs` as a
Expand Down Expand Up @@ -47,10 +69,121 @@ ERROR: not a function: STRING
⧐ ip
94.204.178.37
```
### REPL Command History
Interactive REPL sessions can restore and save the command
history to a history file containing a maximum number of command lines.
The prompt live history is restored from the history file when
the REPL starts and then saved again when the REPL exits. This way you
can navigate through the command lines from your previous sessions
by using the up and down arrow keys at the prompt.
+ Note well that the live prompt history will show duplicate command
lines, but the saved history will only contain a single command
when the previous command and the current command are the same.
The history file name and the maximum number of history lines are
configurable through
1) the ABS environment (set by the ABS init file; see below)
2) the OS environment
3) The default values are `ABS_HISTORY_FILE="~/.abs_history"`
and `ABS_MAX_HISTORY_LINES=1000`.
+ If you wish to suppress the command line history completely, just
set `ABS_MAX_HISTORY_LINES=0`. In this case the history file
will not be created.
For example:
```bash
$ export ABS_HISTORY_FILE="~/my_abs_hist"
$ export ABS_MAX_HISTORY_LINES=500
$ abs
Hello user, welcome to the ABS (1.1.0) programming language!
Type 'quit' when you are done, 'help' if you get lost!
⧐ pwd()
/home/user/git/abs
⧐ cd()
/home/user
⧐ echo("hello")
hello
⧐ quit
Adios!
$ cat ~/my_abs_hist`; echo
pwd()
cd()
echo("hello")
$
```
## ABS Init File
When the ABS interpreter starts running, it will load an optional
ABS script as its init file. The ABS init file path can be
configured via the OS environment variable `ABS_INIT_FILE`. The
default value is `ABS_INIT_FILE=~/.absrc`.
If the `ABS_INIT_FILE` exists, it will be evaluated before the
interpreter begins in both interactive REPL or script modes.
The result of all expressions evaluated in the init file become
part of the ABS global environment which are available to command
line expressions or script programs.
Also, note that the `ABS_INTERACTIVE` global environment variable
is pre-set to `true` or `false` so that the init file can determine
which mode is running. This is useful if you wish to set the ABS REPL
command line prompt or history configuration variables in the init file.
This will preset the prompt and history parameters for the interactive
REPL (see [REPL Command History](#REPL_Command_History) above).
### Configuring the ABS REPL Command Line Prompt
The ABS REPL command line prompt may be configured at start up using
`ABS_PROMPT_LIVE_PREFIX` and `ABS_PROMPT_PREFIX` variables from either
the ABS or OS environments. The default values are
`ABS_PROMPT_LIVE_PREFIX=false` and `ABS_PROMPT_PREFIX="⧐ "`.
REPL "static prompt" mode will be configured if `ABS_PROMPT_PREFIX`
contains no live prompt `template string` or if
`ABS_PROMPT_LIVE_PREFIX=false`. The `static prompt` will be the
value of the `ABS_PROMPT_PREFIX` string (if present) or the default
prompt `"⧐ "`. Static prompt mode is the default for the REPL.
REPL "live prompt" mode follows the current working directory
set by `cd()` when both `ABS_PROMPT_LIVE_PREFIX=true` and the
`ABS_PROMPT_PREFIX` variable contains a live prompt `template string`.
A live prompt `template string` may contain the following
named placeholders:
* `{user}`: the current userId
* `{host}`: the local hostname
* `{dir}`: the current working directory following `cd()`
For example, you can create a `bash`-style live prompt:
```bash
$ cat ~/.absrc
# ABS init script ~/.absrc
# For interactive REPL, override default prompt, history filename and size
if ABS_INTERACTIVE {
ABS_PROMPT_LIVE_PREFIX = true
ABS_PROMPT_PREFIX = "{user}@{host}:{dir}$ "
ABS_HISTORY_FILE = "~/.abs_hist"
ABS_MAX_HISTORY_LINES = 500
}
$ abs
Hello user, welcome to the ABS (1.1.0) programming language!
Type 'quit' when you are done, 'help' if you get lost!
user@hostname:~/git/abs$ cwd = cd()
user@hostname:~$ `ls .absrc`
.absrc
user@hostname:~$
```
Also see a `template ABS Init File` at [examples](https://github.com/abs-lang/abs/tree/master/examples/absrc.abs).
## Why is abs interpreted?
ABS' goal is to be a portable, pragmatic, coincise, simple language:
ABS' goal is to be a portable, pragmatic, concise, simple language:
great performance comes second.
With this in mind, we made a deliberate choice to avoid
Expand All @@ -64,4 +197,4 @@ it took to run a Bash script?
That's about it for this section!
You can now head over to read about ABS's syntax,
starting with [assignments](/syntax/assignments)!
starting with [assignments](/syntax/assignments)!
2 changes: 1 addition & 1 deletion docs/misc/technical-details.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ ERROR: type mismatch: NULL + NUMBER

## Roadmap

We're currently working on [1.2](https://github.com/abs-lang/abs/milestone/9).
We're currently working on [1.3](https://github.com/abs-lang/abs/milestone/10).

## Next

Expand Down
45 changes: 40 additions & 5 deletions docs/syntax/system-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Executing system commands is one of the most important features
of ABS, as it allows the mixing of conveniency of the shell with
the syntax of a modern programming language.

Commands are executed either with `$(command)` or `` `command` ``, which resemble Bash's syntax to execute commands in a subshell:
Commands are executed either with `$(command)` or `` `command` ``,
which resemble Bash's syntax to execute commands in a subshell:

``` bash
date = $(date) # "Sun Apr 1 04:30:59 +01 1995"
Expand Down Expand Up @@ -39,6 +40,41 @@ if `ls -la`.ok {
}
```
## Executing commands in background
Sometimes you might want to execute a command in
background, so that the script keeps executing
while the command is running. In order to do so,
you can simply add an `&` at the end of your script:
``` bash
`sleep 10 &`
echo("This will be printed right away!")
```
You might also want to check whether a command
is "done", by checking the boolean `.done` property:
``` bash
cmd = `sleep 10 &`
cmd.done # false
`sleep 11`
cmd.done # true
```
If, at some point, you want to wait for the command
to finish before running additional code, you can
use the `wait` method:
``` bash
cmd = `sleep 10 &`
echo("This will be printed right away!")
cmd.wait()
echo("This will be printed after 10s")
```
## Interpolation
You can also replace parts of the command with variables
declared within your program using the `$` symbol:
Expand All @@ -56,6 +92,8 @@ $(echo $PWD) # "" since the ABS variable PWD doesn't exist
$(echo \$PWD) # "/go/src/github.com/abs-lang/abs"
```
## Limitations
Currently, commands that use the `$()` syntax need to be
on their own line, meaning that you will not
be able to have additional code on the same line.
Expand All @@ -68,12 +106,9 @@ $(sleep 10); echo("hello world")
Note that this is currently a limitation that will likely
be removed in the future (see [#41](https://github.com/abs-lang/abs/issues/41)).
Commands are blocking and cannot be run in parallel, although
we're planning to support background execution in the future
(see [#70](https://github.com/abs-lang/abs/issues/70)).
Also note that, currently, the implementation of system commands
requires the `bash` executable to [be available on the system](https://github.com/abs-lang/abs/blob/5b5b0abf3115a5dd4dfe8485501f8765985ad0db/evaluator/evaluator.go#L696-L722).
On Windows, commands are executed through [cmd.exe](https://github.com/abs-lang/abs/blob/ee793641be09ad8572c3e913fef8468f69b0c0a2/evaluator/evaluator.go#L1101-L1103).
Future work will make it possible to select which shell to use,
as well as bypassing the shell altogether (see [#73](https://github.com/abs-lang/abs/issues/73)).
Expand Down
108 changes: 106 additions & 2 deletions docs/types/builtin-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,48 @@ type("") # "STRING"
type({}) # "HASH"
```
### cd() or cd(path)
Sets the current working directory to `homeDir` or the given `path`
in both Linux and Windows.
Note that the path may have a `'~/'` prefix which will be replaced
with `'homeDir/'`. Also, in Windows, any `'/'` path separator will be
replaced with `'\'` and path names are not case-sensitive.
Returns the `'/fully/expanded/path'` to the new current working directory and `path.ok`.
If `path.ok` is `false`, that means there was an error changing directory:
``` bash
path = cd()
path.ok # true
path # /home/user or C:\Users\user
here = pwd()
path = cd("/path/to/nowhere")
path.ok # false
path # 'chdir /path/to/nowhere: no such file or directory'
here == pwd() # true
cd("~/git/abs") # /home/user/git/abs or C:\Users\user\git\abs
cd("..") # /home/user/git or C:\Users\user\git
cd("/usr/local/bin") # /usr/local/bin
dirs = cd() && `ls`.lines()
len(dirs) # number of directories in homeDir
```
### pwd()
Returns the working directory where the script was started for -- equivalent
to `env("PWD")`:
Returns the path to the current working directory -- equivalent
to `env("PWD")`.
If executed from a script this will initially be the directory
containing the script.
To change the working directory, see `cd()`.
``` bash
pwd() # /go/src/github.com/abs-lang/abs
Expand Down Expand Up @@ -174,6 +212,72 @@ Halts the process for as many `ms` you specified:
sleep(1000) # sleeps for 1 second
```
### source(fileName) aka require(filename)
Evaluates the ABS script `fileName` in the context of the ABS global
environment. The results of any expressions in the file become
available to other commands in the REPL command line or to other
scripts in the current script execution chain.
This is most useful for creating `library functions` in a script
that can be used by many other scripts. Often the library functions
are loaded via the ABS Init File `~/.absrc`. See [ABS Init File](/introduction/how-to-run-abs-code).
For example:
```bash
$ cat ~/abs/lib/library.abs
# Useful function library ~/abs/lib/library.abs
adder = f(n, i) { n + i }
$ cat ~/.absrc
# ABS init file ~/.absrc
source("~/abs/lib/library.abs")
$ abs
Hello user, welcome to the ABS (1.2.0) programming language!
Type 'quit' when you are done, 'help' if you get lost!
⧐ adder(1, 2)
3
```
In addition to source file inclusion in scripts, you can also use
`source()` in the interactive REPL to load a script being
debugged. When the loaded script completes, the REPL command line
will have access to all variables and functions evaluated in the
script.
For example:
```bash
⧐ source("~/git/abs/tests/test-strings.abs")
...
=====================
>>> Testing split and join strings with expanded LFs:
s = split("a\nb\nc", "\n")
echo(s)
[a, b, c]
...
⧐ s
[a, b, c]
```
Note well that nested source files must not create a circular
inclusion condition. You can configure the intended source file
inclusion depth using the `ABS_SOURCE_DEPTH` OS or ABS environment
variables. The default is `ABS_SOURCE_DEPTH=10`. This will prevent
a panic in the ABS interpreter if there is an unintended circular
source inclusion.
For example an ABS Init File may contain:
```bash
ABS_SOURCE_DEPTH = 15
source("~/path/to/abs/lib")
```
This will limit the source inclusion depth to 15 levels for this
`source()` statement and will also apply to future `source()`
statements until changed.
## Next
That's about it for this section!
Expand Down
Loading

0 comments on commit b787037

Please sign in to comment.