Slash breaks free from the 30-year-old POSIX sh standard embracing a more intuitive and familiar language for shell scripting.
Although still in its infancy, Slash is already somewhat useful! The script used to format the source code is this simple Slash script.
#!/bin/slash
loop file in (find -name "*.c" -o -name "*.h") {
clang-format -i -style=file $file
}
git clone --recurse-submodules git@github.com:LytixDev/slash.git
cd slash
make
./slash path_to_file
See Slash's advances compared to POSIX sh.
Slash is mostly a toy language made for fun by its creator and should be understood accordingly. However, there are some genuine improvements that could be made to the shell. The POSIX shell has numerous syntax oddities, an outdated spec and some general quirky behavior (word splitting and quoting, types, error handling, etc.). Slash addresses some of these.
The following is a small taste of what you can do using Slash.
In an interactive session, raw expressions are evaluated and printed out to the terminal. This means you can use Slash as a basic calculator without ever leaving the shell.
0xff + 1 # prints 256
0xff == 255 # prints 'true'
You want to do the same in POSIX sh? That would look something like:
echo $((0xff + 1))
echo [ $((0xff)) -eq 255 ] # prints 1 or 0
var system = (uname) # '(...)' is similar to the POSIX '$(...)'
if $system == "Linux" {
echo "well akthually youre using GNU/Linux!"
} elif $system == "Darwin" {
echo "Charles"
}
var names = ["Alice", "Bob", "Callum"]
loop name in $names {
if $name == "Callum" {
echo "Hello, enemy"
} else {
echo "Hello, friend"
}
}
Slash attempts to "keep all the good stuff" from POSIX sh while adding common language constructs found in general purpose scripting. One example of this is types. POSIX sh only has one type -- text. Slash embraces types, and makes interpreting text as other data types trivial:
(ls | grep "*.png" | wc -l) as num >= 50 && echo "Many images!"
Slash has first-class support for dynamic lists, maps and tuples. These feel and behave similar to Python's list, dictionary and tuple.
var primes = [2, 3, 5, 7, 11, 13]
var some_primes = $primes[1..4]
var social_credit_score = @[ "brage": 10, "eilor": 300 ] # map
var people = $social_credit_score.keys() # returns a tuple: ("brage", "eilor")
A semi scuffed document containing the context free grammar can be found here.
The lexer is ~600 lines, the parser is ~800 lines and the interpreter is around ~1000 lines. My goal is to keep the source code simple and hackable. The idea is that skilled programmer can understand and internalize the source code and make non trivial changes in an evening or so. The source code contains zero third party code other than linking with a C11 standard library.
pipelines
, I/O redirections
, globbing
etc. for-each loop
, match
statement etc.string
, number
, list
, map
, tuple
.The lexer takes heavy inspiration from this talk by Rob Pike. The rest of the interpreter takes inspiration from the book Crafting Interpreters by Robert Nystrom.
mail to nicolahb at stud dot ntnu dot no