virsh
v1.1.0
Published
VIR Scripting Shell
Downloads
4
Readme
VIR Shell
An experiment, slow, everything might change, never use this
Try It
npx virsh
Goals
- Scriptable and Bash-like for simple executions
- Composable
- Interoperable with JavaScript Promises
- Optimized for small programs
TODOs
- Error handling is terrible. Good luck. It's a combination of uncacught parser-errors, and my own errors thrown with very little context.
- The grammar is overly-permissive. Some allowable stuff might be disallowed in future.
- I want to add automatic semicolon insertion (ASI) as a pre-processing step.
- Add currying, and auto-invocation e.g.
ls = func { 12 }; ls #12
Simple Expressions
Numbers
10
12.0
Strings
"Hello"
'Hello'
Boolean
true
false
Lists
Lists are created implicly whenever a comma is used to separate values:
1, 2, 3
To create a 1-item list, use a trailing comma in parentheses (1,)
.
Grab a single item with [...]
e.g.
l = 1, 2, 3;
l[0] == 1
Objects/Maps/Dicts
{
name: "Foo",
age: 19
}
Assignments
You do not need to declare variables. You just use them.
x = 10
y = "Hello"
Templates
Templates can use values from the current scope:
```
name = "Amber"
"Hello {name}"
```
Functions
Currently, you cannot define functions. You can call functions injected into your scope.
Call with a single arg.
$ range 10 [1, 2, 3, ..., 10]
You cannot invoke a function with zero args. You should instead return a calculated value.
Multiple args
$ range 10 11 [10, 11]
Generators
Iterations
For loops are not first-class constructs. They're just an remix of two primitives:
- function evaluation
- lazy/unbound function arguments
for i <- 1..10 {
i
}
The { i }
block is not bound, nor evaluated when it's passed as an argument to for
.
The invoked function is responsible for both binding the block to a Scope
, and evaluating the body.
Conditionals
Lazy evaluation gives you branching without special constructs or callbacks. If statements will evaluate one, or another arguments depending on the conditional.
Everything looks normal
cond = true if cond { "True" } else { "False" }
You can omit the
else
block:cond = true if cond { "True" } { "False" }
You can omit the brackets too:
cond = true if cond "True" "False"
User Defined Functions
Define user-defined functions with func
z = 1
y = func { x + z }
Call them with
y {x:2}
# 3
Under the hood, this is also a "hack". The defined function body is unbound and unevalated when the function is created. The body is evaluated when invoked later, but with a new scope.
The new scope is of a mix of the lexical scope when defined, and the dynamic scope when invoked.
Calling y {x:1}
causes any lexically bound x
values to be shadowed by the dynamically bound x
at call time.
Since z
is not shadowed, it resolves to 1
.
Horrors
with
statementssc = {name: 'jay'}; with sc { name }