A dirt simple scripting language, meant to be a toy and not much more.
-
NO bloat
With extremely limited syntax and built-in functionality, it's incredibly lightweight and staightforward to implement in a real programming language. Also, the compiler for Ursla is written in Ursla, so no additional porting is required.
-
NO tokenizing / NO syntax trees / NO safety nets
By having only single character operators, there's little need for tokenizing code as a first step. Also, the grammar was designed to be easy to compile (by hand, without a compiler compiler) and only requires a lookahead in one or two spots.
-
NO "short circuiting" of logical expressions
Sure it means the expressions are evaluated in full every time, but execution time will be constant!
-
NO base-10 integer literals, only hexidecimal
This sounds horrible and I assure you it is, but at least you can spell out funny words in your numbers (ex.
+deadbeef
). Just make sure numbers starting with a-f are prefixed with a+
or it's a syntax error :( -
NO whitespace
Space or newline character indicate the end of a statement and that's it, so you don't have to decide how to space things.
-
NO string, map, or boolean types -- only integer, data, and array
Enjoy the charm of more primitive primitives.
-
NO classes
Who needs 'em when you have fun and completely unenforced coding patterns.
-
NO for-loops or other super useful constructs that are widely offered, loved, and depended on
Why would I bother to implement these things when there aren't even base-10 numbers.
:out{ $\85 }
out("hello world")
:out{ $\85 }
:array{ $\89 }
:set{ $\8c }
:fibonacci_number(n){
?n=0{ $0 }
:a:0
:b:1
?n>1{
:c:a+b
:a:b
:b:c
:n:n-1
}^
$b
}
:fibonacci_sequence(n){
:seq:array(n)
:i:0
?i<n{
set(seq,i,fibonacci_number(i))
:i:i+1
}^
$seq
}
out(fibonacci_sequence(10))
Construct | Description |
---|---|
?x{ ... } |
if then |
?x{ ... }:{ ... } |
if then else |
?x{ ... }:?y{ ... } |
if then else-if |
?x{ ... }^ |
while repeat |
?{ !x }:{ !x ... } |
try throw catch |
+ff , 100 , -1 |
integer literal (hexadecimal) |
"hello world" |
ascii data literal |
`foo.png` |
file data literal |
,x,y,z |
array literal |
\80 |
built-in operation by code |
(...) |
expression group |
:x |
declare variable |
:x:y |
set variable |
:x{ ... } |
function definition |
:x(a,b,c){ ... } |
function definition with arguments |
$x |
return from function call |
x(a,b,c) |
function call |
x&y , x|y , x^y , ~x |
logical operations |
x<y , x>y , x=y |
comparison operations |
x+y , x-y , x*y , x/y , x%y , -x |
arithmetic operations |
Name | Description |
---|---|
is(x,y) |
is x physically the same thing as y |
weak(x) |
get an untracked reference to x, to avoid circular references that simple reference counting can't handle |
hash(x) |
get hash code for x |
time() |
get milliseconds elapsed since start of program |
in() |
read input as data |
out(x) |
write text representation of x to output |
pack(x,y,m) |
pack masked bits from y into x, at mask position |
unpack(x,m) |
unpack masked bits from x |
data(n) |
allocate data (bytes) of length n |
array(n) |
allocate array of length n |
len(x) |
get length of data/array x |
get(x,i) |
get element at position i in data/array x |
set(x,i,y) |
set element at position i in data/array x, to y |
copy(x,y,xi,yi,n) |
copy elements from data/array y to x |
load(k) |
load data from persistent storage |
save(k,x) |
save data to persistent storage |