Creating a script interpreter using C#

J

jkimbler

As part of our QA of hardware and firmware for the company I work for,
we need to automate some testing of devices and firmware. Since not
everybody here knows C#, I'm looking to create a new scripting
language that makes writing automated tests simpler. Really, I'm
looking to kind of abstract the power of the C# language into a
simpler language that's easier to learn. The script files would be
interpreted by a script interpreter written in C#. This interpreter
would do the background work of connecting to the devices, storing
variables, comparing values, hitting the database, etc. and return a
log that proves pass or fail of the test.

I know that it's beyond the scope of explaining this in a newgroup.

I'm wondering if anyone can point me to examples, articles, books,
etc. on creating a new scripting language/script interpreter in .NET?
I've been all over the Internet looking for examples of this and
haven't found anything really useful.

Thank you.

-Joe
 
N

Nicholas Paldino [.NET/C# MVP]

Joe,

You could do this, but honestly, why? There are many languages for
..NET, even dynamic/scripting languages (python and javascript can be used by
..NET as well as a few others I am sure I am forgetting).

And even if you didn't want to use a .NET language, you could use the
Active Scripting engine to use VBScript or Javascript, or create a new
language for Active Scripting.

There is a whole bunch of work out there that is done already, and
writing something like a script interpreter is not a trivial task. Instead
of getting bogged down in the details, I would analyze the dynamic/scripting
languages that the runtime currently supports, and use one of them.
 
J

jkimbler

Joe,

    You could do this, but honestly, why?  There are many languages for
.NET, even dynamic/scripting languages (python and javascript can be used by
.NET as well as a few others I am sure I am forgetting).

    And even if you didn't want to use a .NET language, you could use the
Active Scripting engine to use VBScript or Javascript, or create a new
language for Active Scripting.

    There is a whole bunch of work out there that is done already, and
writing something like a script interpreter is not a trivial task.  Instead
of getting bogged down in the details, I would analyze the dynamic/scripting
languages that the runtime currently supports, and use one of them.

--
          - Nicholas Paldino [.NET/C# MVP]
          - (e-mail address removed)




As part of our QA of hardware and firmware for the company I work for,
we need to automate some testing of devices and firmware.  Since not
everybody here knows C#, I'm looking to create a new scripting
language that makes writing automated tests simpler.  Really, I'm
looking to kind of abstract the power of the C# language into a
simpler language that's easier to learn.  The script files would be
interpreted by a script interpreter written in C#.  This interpreter
would do the background work of connecting to the devices, storing
variables, comparing values, hitting the database, etc. and return a
log that proves pass or fail of the test.
I know that it's beyond the scope of explaining this in a newgroup.
I'm wondering if anyone can point me to examples, articles, books,
etc. on creating a new scripting language/script interpreter in .NET?
I've been all over the Internet looking for examples of this and
haven't found anything really useful.
Thank you.
-Joe- Hide quoted text -

- Show quoted text -

Nicholas:

At some point, someone was really fed up with all the alternatives out
there and created TCl because none of the alternatives fit what they
wanted to do. Then, after TCl, someone looked at that and said,
"That's not for me either." They went on to create one of the many
other languages you speak of.

I don't mean to sound like a jerk...and seriously, thank you for the
reply. Unfortunately, this is the pad answer I always see in forums
and Usenet and isn't very helpful. The fact that I'm asking the
question would denote that I have a reason for wanting or needing to
do it...and that I hopefully have weighed the alternatives and found
this to be the best avenue to complete the work assigned to me.

Respectfully,

Joe
 
C

Chris Shepherd

jkimbler said:
and Usenet and isn't very helpful. *The fact that I'm asking the
question would denote that I have a reason for wanting or needing to
do it...and that I hopefully have weighed the alternatives* and found
this to be the best avenue to complete the work assigned to me.

To be fair, using my arbitrary subjective math, about 95% of the time this is
absolutely untrue of posters, and it may be the reason you get the answers you
get. The vast majority of the time people would respond to Nicholas' post with
surprise that these framework features were present.


Chris.
 
N

Nicholas Paldino [.NET/C# MVP]

While you state that it means you have a reason (which I am not
questioning), you said that it implies that you "hopefully" have weighed the
alternatives. I really can't make any assumptions about what you have or
have not done.

However, I do know that there is a very large list of languages (static,
dynamic, and scripted) that currently target the .NET runtime. Doing a
google search on "clr languages" brings me to this (which is a link posted
in the first result):

http://blogs.ugidotnet.org/nettools/articles/8060.aspx

And here is another:

http://www.dotnetpowered.com/languages.aspx

I count 56 different languages in the first link alone. That's a whole
bunch of languages, with a whole bunch of features, and with all due
respect, what you are doing probably is not so special or unique that it
wouldn't be facilitated by at least ONE of these languages.

In the event that there isn't any option out there which suits your
needs, then you should probably check out Joe Pobar's blog, specifically,
this post, which gives a primer on targeting the CLR for a dynamic language
of your own:

http://blogs.msdn.com/joelpob/archive/2005/07/01/434728.aspx

You should also check out Jim HuuUnin's blog as well, which has a number
of entries on targeting the CLR with dynamic languages:

http://blogs.msdn.com/hugunin/default.aspx


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Joe,

You could do this, but honestly, why? There are many languages for
.NET, even dynamic/scripting languages (python and javascript can be used
by
.NET as well as a few others I am sure I am forgetting).

And even if you didn't want to use a .NET language, you could use the
Active Scripting engine to use VBScript or Javascript, or create a new
language for Active Scripting.

There is a whole bunch of work out there that is done already, and
writing something like a script interpreter is not a trivial task. Instead
of getting bogged down in the details, I would analyze the
dynamic/scripting
languages that the runtime currently supports, and use one of them.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)




As part of our QA of hardware and firmware for the company I work for,
we need to automate some testing of devices and firmware. Since not
everybody here knows C#, I'm looking to create a new scripting
language that makes writing automated tests simpler. Really, I'm
looking to kind of abstract the power of the C# language into a
simpler language that's easier to learn. The script files would be
interpreted by a script interpreter written in C#. This interpreter
would do the background work of connecting to the devices, storing
variables, comparing values, hitting the database, etc. and return a
log that proves pass or fail of the test.
I know that it's beyond the scope of explaining this in a newgroup.
I'm wondering if anyone can point me to examples, articles, books,
etc. on creating a new scripting language/script interpreter in .NET?
I've been all over the Internet looking for examples of this and
haven't found anything really useful.
Thank you.
-Joe- Hide quoted text -

- Show quoted text -

Nicholas:

At some point, someone was really fed up with all the alternatives out
there and created TCl because none of the alternatives fit what they
wanted to do. Then, after TCl, someone looked at that and said,
"That's not for me either." They went on to create one of the many
other languages you speak of.

I don't mean to sound like a jerk...and seriously, thank you for the
reply. Unfortunately, this is the pad answer I always see in forums
and Usenet and isn't very helpful. The fact that I'm asking the
question would denote that I have a reason for wanting or needing to
do it...and that I hopefully have weighed the alternatives and found
this to be the best avenue to complete the work assigned to me.

Respectfully,

Joe
 
C

Chris Dunaway

As part of our QA of hardware and firmware for the company I work for,
we need to automate some testing of devices and firmware. Since not
everybody here knows C#, I'm looking to create a new scripting
language that makes writing automated tests simpler. Really, I'm
looking to kind of abstract the power of the C# language into a
simpler language that's easier to learn. The script files would be
interpreted by a script interpreter written in C#. This interpreter
would do the background work of connecting to the devices, storing
variables, comparing values, hitting the database, etc. and return a
log that proves pass or fail of the test.

I know that it's beyond the scope of explaining this in a newgroup.

I'm wondering if anyone can point me to examples, articles, books,
etc. on creating a new scripting language/script interpreter in .NET?
I've been all over the Internet looking for examples of this and
haven't found anything really useful.

Thank you.

-Joe

If you can lay your hands on a copy of the February 2008 issue of MSDN
magazine, there is an article in there about creating your own
language compiler for .Net.

It was written by Joel Pobar.

Chris
 
J

jkimbler

Nicholas:
    ...and with all due
respect, what you are doing probably is not so special or unique that it
wouldn't be facilitated by at least ONE of these languages.

Fair enough statement. I'd buy that. However, please understand what
I'm trying to do. We want to be able to automate testing. Very few
of our testers are also coders. As such OOP is probably out of their
league without significant training. What I'm trying to do is to take
all the code needed to open up an optical connection to our device and
boil it down to:

ConnectToDevice;

All the properties, settings, ect to configure the script engine would
be in an XML file that they really never have to touch. The tester
doesn't need to know that objects are instanced, properties are set,
methods are called, and events are raised. They just know that if
they put "ConnectToDevice;" in the script file, when the engine gets
to that line it will open the device. If they want to write a value
to the device:

WriteToDevice MaximumRPM, 14;

The XML file would map "MaximumRPM" to a specific address in the
device. If they want to get the current value for the temp out of the
device and write it in a test log:

var myOutput;
ReadFromDevice CurrentTemp, myOutput
WriteToLog "Current Temp: " + myOutput
Sleep 5 # wait 5 minutes
ReadFromDevice CurrentTemp, myOutput
WriteToLog "Current Temp: " + myOutput

That kind of stuff. It's not about creating a MORE POWERFUL
language. It's about creating a simpler language as a gateway to a
more powerful language. It's about abstracting the C# language so
that writing and executing test plans is quicker, and the learning
curve for a new employee is very fast.

I also know that this can be done with scores of "switch" statements,
if/else, and such. I'm looking for information to make sure that if
we go this route, I want to learn from those who have been down this
road so I can start with the most stable foundation as I can. That
way...6 months to a year down the road I'm not saying, "If I had it to
do over again I would have done it this way..."

Again...I didn't mean to insult you. I did look at the link in your
original post. I just think those options still require more
programming knowledge then the solution I'm looking at creating. We
want the testers to focus on coming up with new test senarios, writing
plans against them, and executing them as quickly as possible, and
allowing regression to be much faster and automated.

I will look closer at the CLR targeted dynamic languages as you
recomend. Thanks again for your time.

-Joe
 
J

jkimbler

If you can lay your hands on a copy of the February 2008 issue of MSDN
magazine, there is an article in there about creating your own
language compiler for .Net.

It was written by Joel Pobar.

Chris- Hide quoted text -

- Show quoted text -

Read it yesterday. It's a possibility, but I really don't need a
"compiler" as such. It is interesting. Another article in there
about test Windows Forms with the UI Automation Library (pg. 115-121)
which will be good for testing the GUI side of things.

-Joe
 
A

Arne Vajhøj

jkimbler said:
As part of our QA of hardware and firmware for the company I work for,
we need to automate some testing of devices and firmware. Since not
everybody here knows C#, I'm looking to create a new scripting
language that makes writing automated tests simpler. Really, I'm
looking to kind of abstract the power of the C# language into a
simpler language that's easier to learn. The script files would be
interpreted by a script interpreter written in C#. This interpreter
would do the background work of connecting to the devices, storing
variables, comparing values, hitting the database, etc. and return a
log that proves pass or fail of the test.

I know that it's beyond the scope of explaining this in a newgroup.

I'm wondering if anyone can point me to examples, articles, books,
etc. on creating a new scripting language/script interpreter in .NET?
I've been all over the Internet looking for examples of this and
haven't found anything really useful.

I think the only easy way of doing that is to use a scanner and
parser generator.

It is used for compilers but are even easier to use for
interpreters.

Arne
 
N

Nicholas Paldino [.NET/C# MVP]

For what you described, I think you really should just expose your .NET
objects as COM objects which would wrap up all the calls (for example, have
a method which will connect to the device) and then just call it through VB
script. You could easily get away with this, I think using that approach.
VB script isn't really that hard.

The issue here is more about consolidating your code in a manner which
reduces the number of operations for the people scripting. That's easy
enough to do, and it's not really a scripting issue, right? You just have
to package it all up in a way that is consumable through an already existing
scripting language.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Nicholas:
...and with all due
respect, what you are doing probably is not so special or unique that it
wouldn't be facilitated by at least ONE of these languages.

Fair enough statement. I'd buy that. However, please understand what
I'm trying to do. We want to be able to automate testing. Very few
of our testers are also coders. As such OOP is probably out of their
league without significant training. What I'm trying to do is to take
all the code needed to open up an optical connection to our device and
boil it down to:

ConnectToDevice;

All the properties, settings, ect to configure the script engine would
be in an XML file that they really never have to touch. The tester
doesn't need to know that objects are instanced, properties are set,
methods are called, and events are raised. They just know that if
they put "ConnectToDevice;" in the script file, when the engine gets
to that line it will open the device. If they want to write a value
to the device:

WriteToDevice MaximumRPM, 14;

The XML file would map "MaximumRPM" to a specific address in the
device. If they want to get the current value for the temp out of the
device and write it in a test log:

var myOutput;
ReadFromDevice CurrentTemp, myOutput
WriteToLog "Current Temp: " + myOutput
Sleep 5 # wait 5 minutes
ReadFromDevice CurrentTemp, myOutput
WriteToLog "Current Temp: " + myOutput

That kind of stuff. It's not about creating a MORE POWERFUL
language. It's about creating a simpler language as a gateway to a
more powerful language. It's about abstracting the C# language so
that writing and executing test plans is quicker, and the learning
curve for a new employee is very fast.

I also know that this can be done with scores of "switch" statements,
if/else, and such. I'm looking for information to make sure that if
we go this route, I want to learn from those who have been down this
road so I can start with the most stable foundation as I can. That
way...6 months to a year down the road I'm not saying, "If I had it to
do over again I would have done it this way..."

Again...I didn't mean to insult you. I did look at the link in your
original post. I just think those options still require more
programming knowledge then the solution I'm looking at creating. We
want the testers to focus on coming up with new test senarios, writing
plans against them, and executing them as quickly as possible, and
allowing regression to be much faster and automated.

I will look closer at the CLR targeted dynamic languages as you
recomend. Thanks again for your time.

-Joe
 
B

Barry Kelly

jkimbler said:
As part of our QA of hardware and firmware for the company I work for,
we need to automate some testing of devices and firmware. Since not
everybody here knows C#, I'm looking to create a new scripting
language that makes writing automated tests simpler. Really, I'm
looking to kind of abstract the power of the C# language into a
simpler language that's easier to learn. The script files would be
interpreted by a script interpreter written in C#. This interpreter
would do the background work of connecting to the devices, storing
variables, comparing values, hitting the database, etc. and return a
log that proves pass or fail of the test.

I've read your other replies in this thread that predate my reply. I
know you've read about writing a compiler for .NET. Writing a modern
scripting language (as opposed to something like classic BASIC with line
numbers, or DOS-style batch scripting) is just like writing a compiler
for the lexical analysis and parsing stages. There's lots of other
references online for those bits, and they're pretty simple once you get
the ideas right, so I won't go into them in detail. The difference comes
in what you do with the parse tree when you're done.

There's two simple approaches:

1) Create a visitor, acting much like a code generator, which recurses
over the tree and executes the syntax tree's nodes using program state.

So if you have source that looks like this (completely hypothetical
language but hopefully easily understood):

read a
if a == 42 then
print "you picked the magic number"
fi
for i = 1 to a do
print "blah"
od

.... you might then create a tree which looks a bit like this (using Lisp
s-exprs to denote trees as lists of lists):

(statement-list
(read a)
(if (= a 42) // predicate part
(statement-list // true part
(print "you picked the magic number"))
(null-statement) // false part
)
(for i 1 a // variable from to
(statement-list // body
(print "blah"))
)
)

If you then have a visitor (perhaps following the visitor pattern, maybe
the nodes in the above tree are different classes), you should perform
different actions on each node. Imagine a general 'interpret' method
which took a node of the above tree as input, and returned the 'return
value', i.e. the evaluated value of the tree, as output (also assuming
the interpret method has access to world / stack scopes, maybe as a
Stack<Dictionary<string,string>> or whatever you like, to map variable
names to values):

case node of
read:
Console.ReadLine()
store return value in variable named in node
return null (or maybe the value read, depending on
language semantics)
if:
recurse into predicate and save return value
if return value is true then recurse into true-part
otherwise recurse into false-part
statement-list:
iterate through each statement and recurse into each
in turn
null-statement:
return null (do nothing)
for:
check 'to' >= 'from' value, if not then return
set loop variable to 'from' value
1. recurse into body
2. increment loop variable
3. check loop variable <= 'to' value; if not then return
4. go to step 1
print:
recurse into argument and Console.WriteLine return value
=:
evaluate (recurse) first and second arguments and
return result of comparison
<literal>:
return value of literal (like '42', etc.)
<variable>:
return value of variable, looking it up in scope stack
// etc.
esac // end of 'case'

2. A higher-performance approach, and actually simpler in some cases, is
to generate code for a stack machine while recursing through the tree.
It's usually simpler when you need multiple return-value semantics;
consider how you'd need to interpret a 'break out of loop' command in
the 'for' node using the tree evaluation above.

With System.Reflection.Emit, it's pretty trivial to encode most logic.
However, writing a simple stack machine which works with more general,
'scripting style' variant variables is very easy.

The code generator looks pretty similar to the evaluation visitor
pattern above, except this time you're not evaluating and returning
values, but instead writing out stack commands to perform the work. So,
the above method from the evaluator visitor might look a bit like this
instead for code generation:

case node of
read:
push appropriate scope variable onto stack
push name of variable
generate call to Console.ReadLine()
call the 'SetValue' method on the scope
(following the normal IL technique for calling instance methods)
if:
recurse into predicate
create label IfFalse
(e.g. see ILGenerator.DefineLabel in MSDN docs)
generate 'jump if false' to IfFalse label
recurse into true-part
create label AfterIf
generate unconditional jump to AfterIf
mark label IfFalse
(e.g. see ILGenerator.MarkLabel)
recurse into false-part
mark label AfterIf
statement-list:
iterate through each statement and recurse into each
in turn
null-statement:
return (do nothing)
for:
create labels LoopTop, LoopCheck and AfterLoop
create a 'loop frame', with references to these labels,
and push it onto a 'loop stack' available to the code
generator, if you want to support 'continue' and 'break'
statements; these guys would be implemented with jumps
to the above labels.
generate code to set loop variable to initial value
generate jump to LoopCheck
mark label LoopTop
recurse into body
mark label LoopCheck
generate code to jump to LoopTop if variable still
<= 'to' value
mark label AfterLoop
pop loop frame (if any)
print:
recurse into argument
generate call to Console.WriteLine
=:
recurse into first
recurse into second
generate call to your comparison method
<literal>:
generate code to push literal onto stack
<variable>:
generate code to load variable value onto stack
// etc.
esc // end of 'case'

I hope the above sketch gives you some ideas to work with.

-- Barry
 
H

henon

Nicholas:


Fair enough statement. I'd buy that. However, please understand what
I'm trying to do. We want to be able to automate testing. Very few
of our testers are also coders. As such OOP is probably out of their
league without significant training. What I'm trying to do is to take
all the code needed to open up an optical connection to our device and
boil it down to:

ConnectToDevice;

I'd go for IronPython or IronRuby, the latter beeing not complete yet
but would be the better choice if it were complete.
You can build your own DSL very easily in those languages, because
they do not require pedantic syntax. For instance
in Ruby you can skip parentheses and semicolons for a method call like
this:

DoSomething param1, param2

I like this simplicity and there are enough examples out there where
people used Ruby for DSLs for non-programmers. The most prominent one
is a submarine robot control API for submarine biologists.

hth,
-- henon
www.eqqon.com
 
N

Nicholas Paldino [.NET/C# MVP]

Indeed, this would simplify things even more. It's just a matter of
packaging everything into succinct calls that will simplify the whole
process for those doing the coding.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top