Shiny

Shiny is a simple interpreted scripting language with aspects similar to Lua, Ruby and Perl. Anyone familiar with C derivative languages should find Shiny easy to pick up.

source

an example up front

This is a little script I use to dump radio streams from an RSS feed supplied by my ISP.

#!/home/sean/bin/shiny

assert args.exists 2 "missing find parameter"
find: args[2]

# rss is pulled in by cron
rss: io.slurp '/home/sean/.radio.rss'

# grab the first channel only
items: rss.replace re/^.*<channel>(.*)<\/channel>.*$/gsm '%(a)s'

# extract an xml tag
search: function
    txt: in tag: in a: 'unknown'
    txt.match re/<%(tag)s>\s*(.*?)\s*<\/%(tag)s>/sm
    out a
end

# cycle through radio stations searching name and description fields
each items.find re/<item>(.*?)<\/item>/sm item
    name: search item 'title'
    link: search item 'link'
    desc: search item 'description'
    if name.match re/%(find)s/i or desc.match re/%(find)s/i
        print "%s\n\t%s\n\t%s" name desc link
    end
end

Data Types

Variables

Variables can be any string that does not clash with a core key word. They must begin with a letter [a-zA-Z], optionally followed by letters, digits, or underscores [a-zA-Z0-9_]*. The colon (:) is used to assign data to a variable. Data typing is dynamic.

> x: 3.14
> y: 'hello world'

Variables are created in the local scope by default, unless prefixed with one or more scope or object identifiers.

> global.x: 3.14

Numbers

Numbers are all floating point (real). The common infix arithmetic can be used with C-like precedence:

> print 1+2/3
1.67

A math library is available:

> x: -42
> print math.abs x
42
> print x.abs
42

For efficiency reasons, numbers are not true objects in Shiny, but they are treated as pseudo objects when assigned to a variable. The second dot (.) notation above implicity treats the math library functions as the x numeric variable's methods.

Numbers are passed by value.

Math Library Functions

More to come.

Strings

Strings may be specified using relatively standard single or double quote notation. Single quotes (') return a literal string unmodified except for any backslash () escaped single quotes. Double quotes (") replace most backslash () escape codes common to C type languages, and also perform automatic string formatting for percent sign (%) escape sequences, like those used by the C sprintf function.

> x: 'hello world'
> y: "multi\nline\ntext"
> z: "a formatted string with number '%d' and sub-string '%s'" 3.14 x

Like Numbers, Strings are pseudo objects. A string library is available to manipulate them.

> print string.length x
11
> print x.length
11

Strings are passed by value.

String Library Functions

More to come.

Regex

Regular Expressions are used with various string library functions. They are specified using an re/pattern/flags notation, with Perl compatible syntax and modifier flags.

> x: 'hello world'
> print x.replace re/[aeiou]+/ '_'
h_llo world
> print x.split re/\s+/
object 152684360
 0: hello
 1: world
> if x.match re/hello/ print 'yes!' else print 'no!' end
yes!

Sub-strings matched in parentheses during regex execution are exposed as variables in the local scope, and named a, b, c and so on.

> x.match re/(\w+)\s+(\w+)/
> print a
hello
> print b
world

Regex are passed by value.

Functions

Functions are just closures assigned to a variable name.

say_hi: function
   print 'hi!'
end

Functions can import arguments with the in key word. Arguments are supplied to functions by placing them inline after the function call separated only by white space, without parentheses or commas.

say_hi_to: function
   print "hi %s!" in
end

say_hi_to 'tom'

One important point to note is that the argument syntax generally disallows optional arguments except where data type differentiation is used. Functions that accept a variable number of arguments are still possible when an explicit argument count is supplied, or when an object is passed with named variables.

Functions can return zero or one value with the out key word:

max_value: function
   a: in b: in
   if a > b
      out a
   else
      out b
   end
end

print max_value 1 2

A function has a local variable scope. All variables up the scope chain, from local to any caller(s) to global, are directly visible to a function by name for reading only. To write to a variable outside the local scope, a spcific scope prefix must still be used.

Functions are passed by reference.

Objects

Objects are closures too, created like persistent functions. They use a prototype framework to create new objects either directly or by cloning. Any functions defined inside an object are automatically methods, which can reference their parent object with the this key word.

Create a raw object from the default super prototype:

x: object
   greet: 'hi'
   function say_hi
      print greet
   end
end

x.say_hi

Create a object derived from another, either as a simple copy:

y: copy x

..or as an extendable copy (like inheritance):

y: object extend x
   greet 'hello there'
end

y.say_hi

Objects can also be used as an associative array:

array: { a: 1 b: 2 c: 'three' }

Object methods and variables can be referenced using the dot (.) notation, or with familiar square brackets ([]) array access notation. These are the same:

print y.greet
print y['greet']

Objects are passed by reference.

Super Prototype

More to come.

Control Structures

All control structures and code blocks end with e end key word.

if else

if condition [or|and condition [...]]
   block
else
   block
end

while

while  condition [or|and condition [...]]
   block
end

for

for start stop step var
   block
end

each

each iterable var
   block
end

each pair iterable key var
   block
end

Other Key Words

print

The key word print writes a single argument to stdout with a trailing line break.

bye

The key word bye exits Shiny.

type

The key word type takes a single argument and returns the data type as a string.

> x: 42
> print type x
number

assert

The key word assert takes a condition argument and an error message. If the condition is false, the error message is written to stderr and Shiny exits.

Other Libraries

io

The io library exists to do simple I/O.

System Calls

Or shell commands. Any string delimited by back ticks () is automatically executed in the system shell environment, and the result returned as a string. Back ticked strings perform all the same formating as double quoted (") strings.

> print `ls -al`
total 52
-rw-r--r-- 1 sean sean    55 2008-11-30 02:28 Makefile
-rw-r--r-- 1 sean sean 47379 2008-11-30 02:28 shiny.c

eof