From d60a176094cfd4456d72316ccd52a231119281a3 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy <mmstickman@gmail.com> Date: Sun, 12 Mar 2017 15:37:35 -0400 Subject: [PATCH] Update README & Add More Examples --- README.md | 192 ++++++++++++++++++++++++++++++++++++++++- SYNTAX.md | 104 ---------------------- examples/else_if.ion | 37 ++++++++ examples/else_if.out | 3 + examples/fibonacci.ion | 18 ++++ examples/fibonacci.out | 19 ++++ examples/while.ion | 14 +++ examples/while.out | 9 ++ 8 files changed, 291 insertions(+), 105 deletions(-) delete mode 100644 SYNTAX.md create mode 100644 examples/fibonacci.ion create mode 100644 examples/fibonacci.out diff --git a/README.md b/README.md index b5d812ca..8a25fdd0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#ion +# Ion Shell Ion is the underlying library for shells and command execution in Redox, as well as the default shell. @@ -7,3 +7,193 @@ Redox, as well as the default shell. [](https://coveralls.io/github/redox-os/ion?branch=master) [](https://crates.io/crates/ion-shell) +## Shell Syntax + +### Defining Variables + +The `let` keyword is utilized to create local variables within the shell. The `export` keyword performs +a similar action, only setting the variable globally as an environment variable for the operating system. + +```ion +// TODO: Ion Shell does not yet implement stderr redirection. +let git_branch = $(git rev-parse --abbrev-ref HEAD 2> /dev/null) +``` + +If the command is executed without any arguments, it will simply list all available variables. + +### Dropping Variables + +To drop a value from the shell, the `drop` keyword may be used: + +```ion +drop git_branch +``` + +### Variable Arithmetic + +The `let` command also supports basic arithmetic. + +```ion +let a = 1 +echo $a +let a += 4 +echo $a +let a *= 10 +echo $a +let a /= 2 +echo $a +let a -= 5 +echo $a +``` + +### Export + +The `export` command works similarly to the `let` command, but instead of defining a local variable, it defines a global variable that other processes can access. + +```ion +export PATH = "~/.cargo/bin:${PATH}" +``` + +### Export Arithmetic + +The `export` command also supports basic arithmetic. + +```ion +export a = 1 +echo $a +export a += 4 +echo $a +export a *= 10 +echo $a +export a /= 2 +echo $a +export a -= 5 +echo $a +``` + +### Aliases + +The `alias` command is used to set an alias for running other commands under a different name. The most common usages of the `alias` keyword are to shorten the keystrokes required to run a command and it's specific arguments, and to rename a command to something more familiar. + +```ion +alias ls = 'exa' +``` + +If the command is executed without any arguments, it will simply list all available aliases. + +The `unalias` command performs the reverse of `alias` in that it drops the value from existence. + +```ion +unalias ls +``` + +### Commands + +Commands may be written line by line or altogether on the same line with semicolons separating them. + +```ion +command arg1 arg2 arg3 +command arg1 arg2 arg3 +command arg1 arg2 arg3; command arg1 arg2 arg3; command arg1 arg2 arg3 +``` + +### Pipelines & Redirections + +It's currently only possible to pipe and redirect the standard output of one command to another command. + +```ion +command arg1 | other_command | another_command arg2 +command arg1 > file +``` + +### Conditional Operators + +The Ion shell supports the `&&` and `||` operators in the same manner as the Bash shell. The `&&` operator +executes the following command if the previous command exited with a successful exit status. The `||` +operator performs the reverse -- executing if the previous command exited in failure. + +```ion +test -e .git && echo Git directory exists || echo Git directory does not exist +``` + +### If Conditions + +It is also possible to perform more advanced conditional expressions using the `if`, `else if`, and `else` keywords. + +```ion +let a = 5; +if test $a -lt 5 + echo "a < 5" +else if test $a -eq 5 + echo "a == 5" +else + echo "a > 5" +end +``` + +### While Loops + +While loops will evaluate a supplied expression for each iteration and execute all the contained statements if it +evaluates to a successful exit status. + +```ion +let a = 1 +while test $a -lt 100 + echo $a + let a += 1 +end +``` + +### For Loops + +For loops, on the other hand, will take a variable followed by a list of values or a range expression, and +iterate through all contained statements until all values have been exhausted. + +```ion +# Obtaining Values From a Subshell +for a in $(seq 1 10) + echo $a +end + +# Values Provided Directly +for a in 1 2 3 4 5 + echo $a +end + +# Exclusive Range +for a in 1..11 + echo $a +end + +# Inclusive Range +for a in 1...10 + echo $a +end +``` + +### Functions + +Functions in the Ion shell are defined with a name along with a set of variables. The function +will check if the corrent number of arguments were supplied and execute if all arguments +were given. + +```ion +fn fib n + if test $n -le 1 + echo $n + else + let output = 1 + let previous = 1 + for index in 2..$n + let temp = $output + let output += $previous + let previous = $temp + end + echo $output + end +end + +for i in 1..20 + fib $i +end +``` \ No newline at end of file diff --git a/SYNTAX.md b/SYNTAX.md deleted file mode 100644 index e34924da..00000000 --- a/SYNTAX.md +++ /dev/null @@ -1,104 +0,0 @@ -# ion Syntax Reference - -## Current Syntax - -### Commands -- `arg0 arg1 "arg 2"` will call the command `arg0` with three arguments, the executable path, `arg1`, and `arg 2` - -### Builtins -- `help` will list all builtins -- `help builtin` will display the syntax and description of the `builtin` command - -### Variables -- `let variable=value` will set a variable to `value` -- `$variable` will be placed inline as a single argument, so `touch $variable` would try to create a file `some value` -- `drop variable` will delete the variable called `variable` -- `let` will list all variables - -### Conditionals -- `if left comparison right` will begin a comparison block - - `left` and `right` are single arguments, they may be a variable like `$variable` or a value like `2` or `"some value"` - - The available comparisons are `==`, `!=`, `>`, `>=`, `<`, and `<=` -- `else` will invert the comparison block -- `end` will end the comparison block - -### Functions -Use the `fn` keyword to define functions: -``` -fn function - echo "Hello, Ion!" -end -``` -And use the function name to call it: -``` -ion:# function -Hello, Ion! -``` -You can also create function with arguments: -``` -fn print_two_strings first second - echo $first $second -end -``` -To call the function you can use the function name followed by the arguments: -``` -ion:# print_two_strings "Foo" "Bar" -Foo Bar -``` - -### Piping -- `echo foo | cat | xargs touch` will pipe the output from one process to another. - -### Redirection -- `echo foo > bar` will write "foo" to a file named "bar". -- `cat < foo` will write the contents of a file named "foo" to the console. -- `cat < foo > bar` will write the contents of a file named "foo" to a file named "bar". - -## Proposed Syntax - -A LR(k) grammar. This is a rough brainstorm and is somewhat out of sync with the examples: -``` -statement: - LET IDENT SET expr - | IF expr DELSTART statement* DELEND -expr: - # comparations - expr EQ expr = eq - | expr NEQ expr = not_eq - | expr LT expr = less_than - | expr GT expr = greater_than - | expr LEQ expr = less_than_or_eq - | expr GEQ expr = greater_than_or_eq - # operators - | expr PLUS expr = add - | expr MINUS expr = sub - | expr MUL expr = mul - | expr DIV expr = div - # control - | IF expr DELSTART expr DELEND ELSE DELSTART expr DELEND = if_else - # misc - | statement* SEMICOLON expr = block - # const - | STR(a) = str - | NUM(a) = num - ... -``` - -Examples: - -``` -let home = "~"; - -if home == pwd - echo "home sweet home" -end - -// let's define a new cmd - -fn my_cmd a b - echo a + b -end - -mycmd 2 4 // 6 -``` - diff --git a/examples/else_if.ion b/examples/else_if.ion index 4e75c01b..39350059 100644 --- a/examples/else_if.ion +++ b/examples/else_if.ion @@ -1,3 +1,5 @@ +# Single Else If Condition + if test 1 -gt 5 echo one else if test 1 -eq 1 @@ -5,3 +7,38 @@ else if test 1 -eq 1 else echo three end + +# Multiple Else Conditions + +let a = 4 +if test $a -eq 1 + echo one +else if test $a -eq 2 + echo two +else if test $a -eq 3 + echo three +else if test $a -eq 4 + echo four +else + echo five +end + +# Nested Else If Conditions + +let a = 5 +let b = 10 + +if test $a -gt 10 + echo "a > 10" +else if test $a -lt 10 + echo "a < 10" + if test $a -gt $b + echo "a > b" + else if test $a -eq $b + echo "a == b" + else + echo "a < b" + end +else + echo "a == 10" +end diff --git a/examples/else_if.out b/examples/else_if.out index f719efd4..ff414bd7 100644 --- a/examples/else_if.out +++ b/examples/else_if.out @@ -1 +1,4 @@ two +four +a < 10 +a < b diff --git a/examples/fibonacci.ion b/examples/fibonacci.ion new file mode 100644 index 00000000..6a41ae0b --- /dev/null +++ b/examples/fibonacci.ion @@ -0,0 +1,18 @@ +fn fib n + if test $n -le 1 + echo $n + else + let output = 1 + let previous = 1 + for index in 2..$n + let temp = $output + let output += $previous + let previous = $temp + end + echo $output + end +end + +for i in 1..20 + fib $i +end diff --git a/examples/fibonacci.out b/examples/fibonacci.out new file mode 100644 index 00000000..7d0da546 --- /dev/null +++ b/examples/fibonacci.out @@ -0,0 +1,19 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 +144 +233 +377 +610 +987 +1597 +2584 +4181 diff --git a/examples/while.ion b/examples/while.ion index 8bd808f3..22707283 100644 --- a/examples/while.ion +++ b/examples/while.ion @@ -1,5 +1,19 @@ +# Simple While Loop + let a = 1 while test $a -lt 10 echo $a let a += 1 end + +# While Loop With If Conditions + +let a = 1 +while test $a -lt 10 + if test $a -eq 5 + echo found 5 + else + echo $a + end + let a += 1 +end diff --git a/examples/while.out b/examples/while.out index 07193989..3ee7080e 100644 --- a/examples/while.out +++ b/examples/while.out @@ -7,3 +7,12 @@ 7 8 9 +1 +2 +3 +4 +found 5 +6 +7 +8 +9 -- GitLab