SPINNER a concurrent language for programming SPIN William Beaver Marc Eaddy Gaurav Khandpur Sangho Shin.
Download
Report
Transcript SPINNER a concurrent language for programming SPIN William Beaver Marc Eaddy Gaurav Khandpur Sangho Shin.
SPINNER
a concurrent language for programming SPIN
William Beaver
Marc Eaddy
Gaurav Khandpur
Sangho Shin
Outline
•
•
•
•
•
•
•
•
Motivation for SPINNER
Key Features
Examples
Compiler Design Overview
Simulator and Concurrency Complexity
Test Process
Lessons Learned
Closing
What is SPIN?
[video]
QuickTime™ and a
MPEG-4 Video decompressor
are needed to see this picture.
Physical System Overview
SPINNER
program
SPINNER
compiler
SPINscript
SPIN
SPINscript challenge
Expressiveness vs. complexity
• Spin disc 1 clockwise 10
revs in 10 sec
• Wait 5 secs
• Spin disc 4 at 3 rev/sec
• Wait 3 secs
• When disc 1 stops
– Spin disc 1
counterclockwise 3 revs in
3.25 sec
– Spin disc 3 clockwise 3 revs
in 3.25 secs
(Imagine a Loop!)
SPINscript challenge
Expressiveness vs. complexity
• Spin disc 1 clockwise 10
revs in 10 sec
• Wait 5 secs
• Spin disc 4 at 3 rev/sec
• Wait 3 secs
• When disc 1 stops
– Spin disc 1
counterclockwise 3 revs in
3.25 sec
– Spin disc 3 clockwise 3 revs
in 3.25 secs
(Imagine a Loop!)
1, 1-line 10 10000;
1, --wait-- 5000;
1, 4-speed 3.0 0;
1, --wait-- 3000;
1, --wait-- 2000;
1, 1-line 7 3250;
1, 3-line 12 3250;
1, --wait-- 3250;
Key SPINNER improvements
•
•
•
•
Concurrency model
SPIN state maintenance Query state
User defined functions/libraries
Typical language “stuff” (control flow,
variables, etc.)
• Increased expressiveness and control
SPINNER Syntax
•
•
•
•
•
•
•
•
Script like language: sequential from top (no Main)
Literals: double, boolean, string, null
Variables: double, boolean, array (no strings)
Operators: postfix incr/decr, unary not, *, / , %, +, -, <, >,
<=, >=, and, or
Function Definitions: type func func_name (args){}
Built-in functions: seek, setSpeed, getSpeed, getPosition,
wait, waitUntil, getTime, getSize, plus getter/setters for
audio parameters, disc setup, etc.
Import external function libraries
Control Flow: If/then/else, while, repeat/until, for, break
• Concurrency operator: ||
Examples
• Simple
createDiscs(6);
setFile(“all”,“AelonsHarp”);
setGain(“all”, 0.7);
seek(1,2,4000);
seek(6,-2,4000);
wait(4000);
Examples
• Simple
• More Complicated
createDiscs(6);
setFile(“all”,“AelonsHarp”);
setGain(“all”, 0.7);
seek(1,2,4000);
seek(6,-2,4000);
wait(4000);
//assume all setup done
for(i=1;i<=getDiscsSize();i++){
wait(i*1000);
seek(i, i*2, i*1000);
}
waitUntil(getSpeed(1)<=0);
for(i=getDiscsSize();i>0;i--){
wait(i*1000);
seek(i, i*2, i*1000);
}
Compiler Architecture
Preprocessor
SPINNER
compiler
Lexer
SPINscript
Parser
SpinnerAST
ANTLR
Semantic
Analyzer
Interpreter
Simulator
Environment.java
SPIN
Environment.java
Function table
Function Object
Environment
Return
type
Return
type
Return
type
Return
type
Name
Name
Name
Name
Args
Args
Args
Args Table
Symbol
Symbol
Table
Symbol
SymbolTable
Table
BuiltInFunctionTable
UserDefinedFunctionTable
MainSymbolTable
CurrentSymbolTable
Variable Object
Type
Name
Function Object
Value
Array info etc..
Name
Array info etc..
Symbol table
OuterSymbolTablePtr
InnerSymbolTables
Variable Object
Type
Function table
Value
Return type
Name
Args
Body
Symbol Table
AST
Symbol Table
double a:=0;
Environment
MainSymbolTable
boolean b:=true
CurrentSymbolTable
if (a=0) {
double a;
OuterSymbolTablePtr
boolean b;
InnerSymbolTables
}
while(b) {
double c;
boolean d;
}
D
a
0
B
b
T
Symbol Table
double a:=0;
Environment
MainSymbolTable
boolean b:=true
CurrentSymbolTable
if (a=0) {
double a;
OuterSymbolTablePtr
OuterSymbolTablePtr
boolean b;
InnerSymbolTables
InnerSymbolTables
D
a
0
D
a
0
B
b
T
B
b
F
}
while(b) {
double c;
boolean d;
}
Symbol Table
double a:=0;
Environment
MainSymbolTable
boolean b:=true
CurrentSymbolTable
if (a=0) {
double a;
OuterSymbolTablePtr
OuterSymbolTablePtr
boolean b;
InnerSymbolTables
InnerSymbolTables
D
a
0
D
a
0
B
b
T
B
b
F
}
while(b) {
double c;
OuterSymbolTablePtr
InnerSymbolTables
boolean d;
}
D
c
0
B
d
F
The Backend:
Interpreter and Simulator
Preprocessor
SPINNER
compiler
Lexer
SPINscript
Parser
ANTLR
Semantic
Analyzer
Interpreter
Simulator
You are now here
SPIN
Simulator.java
• Maintains the state of the n-discs at any point
in time during the simulation (“so you don’t
have to!”)
• Implements built-ins for setting/getting disc
speed, position, etc.
• Generates SPINscript code
Example: t = 15.353 seconds
-.06 rev/s .87 rev/s -.32 rev/s .12 rev/s -.46 rev/s .25 rev/s
-112˚
42˚
-95˚
43˚
-186˚
78˚
Simulating time and movement
• Simulation time marches forward by the
Interpreter calling wait(milliseconds)
• Simulator disc positions/angles updated
• waitUntil(cond) is “syntactic sugar”
while (!cond) {
wait(1);
}
Concurrency (1)
• Double-pipe operator | |
• Each parallel branch executes until
completion or a wait/waitUntil statement
is reached branch 1 ||
branch 3
setSpeed(1,
5,1000)
setSpeed(2,
-5,1000)
paused
branch 2
setSpeed(3,
10,1000)
paused
wait(5000)
waitUntil(cond1)
paused
paused
done
wait(1)
Concurrency (2)
• Artist can treat discs independently
• Disc behavior can now be easily defined
by non-linear functions
while(abs(getPosition(2)-getPosition(1))>=5)
{
setSpeed(1, sin(getTime())*10, 1000);
wait(1);
}
} || {
while(abs(getPosition(2)-getPosition(1))>=5)
{
setSpeed(2, cos(getTime())*10, 1000);
wait(1);
}
}
3434, 1-speed 40.0 1000.0;
3435, wait 1;
3435, 2-speed 50.0 1000.0;
3436, wait 1;
3436, 1-speed 60.0 1000.0;
3437, wait 1;
3437, 2-speed 0.0 1000.0;
3438, wait 1;
3438, 1-speed 10.0 1000.0;
3439, wait 1;
3439, 2-speed 20.0 1000.0;
3440, wait 1;
3440, 1-speed 30.0 1000.0;
3441, wait 1;
3441, 2-speed 40.0 1000.0;
3442, wait 1;
…
sin1_cos2.spinner (INPUT)
sin1_cos2.spin (OUTPUT)
{
Testing Techniques
• Lexer/Parser Testing
– Hand compile Spinner to AST, compare with Parser’s
AST
• Semantic Analyzer testing
– Write compiler breaking/accepting code.
• Interpreter Testing
– Write SPINNER for all valid expression types
• Simulator testing
– Test all built-in functions
• End to End testing
– Write Spinner code, hand compile to SPINscript
– Reverse engineer SPINscript to Spinner and compare
• Have mechanisms for jUnit style “instant” regression
verification.
Testing Details
• Sample Spinner programs:
correctLRM.spinner, incorrectLRM.spinner,
testAllBuiltIn.spinner,
testConcurrency.spinner, etc…
• Around 120 tests exercising language.
//test number 1001 = createDiscs and Get Discs size
createDiscs(6);
wait(1001);
if (getDiscsSize()=6) then { //pass
setGain(1,1);
} else {
//fail
setGain(1,0);
}
Lessons Learned
• Spend more time in language design.
• Think about testing/debugging in language
design.
• Tackle key language features as early as
possible. Save easy stuff for later.
• Have unit tests for difficult key systems before you
code them.
• Communication tools are great: cvs, twiki, etc.
• Meet more than once a week.
• Be sure you have access to target environment
for reverse engineering.
• Make sure target is well specified and understood.
Areas for improvement
• Interpreter algorithm is quite slow
– Still faster than doing coordinates manually
• Interaction with SPIN not seamless
– Moving files around
– Debugging visual output slow
• Simulator accuracy of target system
– Forced SPIN to take on SPINNER simulator
limitations rather than vice versa
Future Work
• Programming interfaces
– Direct manipulation?
– A Musical “score”? (Macromedia Directoresque)
• Concurrency modeling variations
• Simulation optimization
– Smart linear solver?
Thanks to our “TA”
Questions?