For a long time I have been using this little program misnamed netshortcut. It’s a little command line that pops when you press a key-combination; commands that it supports are configured into a rules file using a rudimentary declarative language that evolved ‘as-appropriate’. Read more about it here
http://www.thinkingms.com/pensieve/homepage/work/netshortcut/netshortcut.htm
While I had been using NS for a while, there was this growing frustration that it could be made to do more things – if it had a better designed language underlying it. This frustration continued for a long time, until sometime early last year I got to working it out. I had lots of help from Sid, against whom I would bounce the creations of my genius.
Today the notebook in which we had worked out our plans resurfaced after a year. I didn’t want to loose this stuff again, though it was going to be an embarrassment for the future – and hence this blog entry.
I remember Sid saying that is some south american there are a sort of monkeys that have really long tails that hang down branches when they sit. And I say “so?”. And he says ‘So maybe you can use that idea in your language’. I ponder that for a while and then figure that I won’t be so useful. I hindsight, maybe Sid was right after all…
So here is the language, in wonderfully non formal description -
<pattern> {
do ( <args> ) { <code> }
is { <value> }
comment <string>
def <ident> {
render <password | list | text>
include <filename>
alias <pattern> <name>
code { <code> }
<one or more pattern blocks>
}
That’s it. All programs have to begin in some scope, so this language’s global scope is same as the scope that corresponding to the inside of an def <ident> { <this is the global scope> }.
Remember that this language is fundamentally declarative is used primarily as metdata for a command line. The standing idea was the code blocks inside do() {} and is {} would be handled by a regular programming language that allowed interpreter hosting – the idea was to go with ruby then.
There is also the notion that braces can be eliminated except for do and is blocks. If a var does not have a do or is block is its value is simple returned back up the tree.
Here is a definition for supporting invoking the browser to do a google search. The user at the NS command line would type something like this –
gg <what to search for>
Imagine we have a file called library.rb that has
def browser(url)
# invoke browser with specified url
end
def urlEncode(value)
#return a urlEncoded version of value
This will be the NS rules file –
include “library.rb”
gg {
do (arg ) { browser(“www.google.com?q=#{arg}”) }
comment “Search Google”
def arg {
* {
is { urlEncode(value) }
Note that ‘value’ that is passed to the urlEncode() is a special variable that holds the value of the current match (* matches to anything).
Now this does look a little clunky (and yes unintuitive) but with the defaults and with some braces reduction it would look like this –
gg do(arg){ browser(“www.google.com?q=#{urlEncode(arg)}”) } comment “Search Google”
Neat?
The language actually allows for a LOT of flexibility for controlling what gets executed for what the user types, what comments are displayed, how the UI gets rendered etc. I cant really describel all of that here, but this is the essence -
- The lowest do() {} block that is satisfied is executed wrt a command.
- The is{} block at any level computes a value that may serve as a argument value to a do block higher up the tree.
- The code {} blocks are executed in pre-order (when going down the tree)
- The do(){} and is{} blocks are executed in post-order after the command is completed.
- Any {} other than for do, is and code can be skipped. Doing so reduces the rest of the line to the scope of the starting instruction’s block.
The new NS is also to support a notion of setting scope. You use
@ <rest of command here>
to set scope. For example, if you are going to be doing a lot of google searches, you do a
@ gg
And from that point on whatever you type at the command line will the value of the arg parameter of the do(){} of the gg pattern.
I have not really go down to implementing this yet.
Someday…
Remember Me
a@href@title, strike
Powered by: newtelligence dasBlog 2.0.7226.0
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2008, Roshan James
E-mail