260 likes | 409 Views
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].
E N D
SPINNERa 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]
Physical System Overview SPINNER program SPINNER compiler SPINscript SPIN
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; SPINscript challenge Expressiveness vs. complexity
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: ||
Simple createDiscs(6); setFile(“all”,“AelonsHarp”); setGain(“all”, 0.7); seek(1,2,4000); seek(6,-2,4000); wait(4000); Examples
Simple createDiscs(6); setFile(“all”,“AelonsHarp”); setGain(“all”, 0.7); seek(1,2,4000); seek(6,-2,4000); wait(4000); More Complicated //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); } Examples
Simulator Compiler Architecture Preprocessor SPINNER compiler SPINscript Lexer Parser SPIN SpinnerAST ANTLR SemanticAnalyzer Environment.java Interpreter
Environment.java Return type Return type Return type Return type Name Name Name Name Args Args Args Args Symbol Table Symbol Table Symbol Table Symbol Table Return type Name Args Body Symbol Table Function table Function Object Environment BuiltInFunctionTable UserDefinedFunctionTable MainSymbolTable CurrentSymbolTable Function table Variable Object Function Object Symbol table Type Name Value OuterSymbolTablePtr Array info etc.. InnerSymbolTables Variable Object Type Name Value AST Array info etc..
OuterSymbolTablePtr InnerSymbolTables D a 0 B b T Symbol Table Environment double a:=0; boolean b:=true if (a=0) { double a; boolean b; } while(b) { double c; boolean d; } MainSymbolTable CurrentSymbolTable
OuterSymbolTablePtr OuterSymbolTablePtr InnerSymbolTables InnerSymbolTables D D a a 0 0 B B b b T F Symbol Table Environment double a:=0; boolean b:=true if (a=0) { double a; boolean b; } while(b) { double c; boolean d; } MainSymbolTable CurrentSymbolTable
OuterSymbolTablePtr OuterSymbolTablePtr OuterSymbolTablePtr InnerSymbolTables InnerSymbolTables InnerSymbolTables D D D c a a 0 0 0 B B B d b b T F F Symbol Table Environment double a:=0; boolean b:=true if (a=0) { double a; boolean b; } while(b) { double c; boolean d; } MainSymbolTable CurrentSymbolTable
The Backend: Interpreter and Simulator Simulator Preprocessor SPINNER compiler SPINscript Lexer Parser SPIN ANTLR You are now here SemanticAnalyzer Interpreter
Example: t = 15.353 seconds -.06 rev/s .87 rev/s -.32 rev/s -.46 rev/s .12 rev/s .25 rev/s -95˚ -112˚ 78˚ -186˚ 42˚ 43˚ 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
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); }
|| branch 1 branch 3 setSpeed(3, 10,1000) setSpeed(2, -5,1000) setSpeed(1, 5,1000) paused branch 2 paused wait(5000) waitUntil(cond1) paused paused done Concurrency (1) • Double-pipe operator | | • Each parallel branch executes until completion or a wait/waitUntil statement is reached wait(1)
Concurrency (2) • Artist can treat discs independently • Disc behavior can now be easily defined by non-linear functions 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; … { 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); } } 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 Director-esque) • Concurrency modeling variations • Simulation optimization • Smart linear solver?
Thanks to our “TA” Questions?