Event-driven and Concurrent Programming in 2 ACP Based Language Extensions Lecture at University of...
-
Upload
leonard-short -
Category
Documents
-
view
217 -
download
0
Transcript of Event-driven and Concurrent Programming in 2 ACP Based Language Extensions Lecture at University of...
Event-driven and Concurrent Programming
in 2 ACP Based Language ExtensionsLecture at University of Amsterdam
Department Theory of Computer Science18 April 2011
André van Delft, Rijswijk
andre.vandelft (a) gmail.comhttp://code.google.com/p/scriptic/
http://code.google.com/p/subscript/
1
OverviewScriptic• History• ACP vs Scriptic • Examples• Case study: Document Processing • Implementation
Subscript• Scala based• Differences with Scriptic• Examples• Syntax
2
History• 1956 Kleene: formal automata >> a*b, regular expressions.
• 1960 Backus Naur Form
• 1960 Compiler-compiler >> Yacc
• 1962 Simula: OO, parallelism, simulation time
• 1971 Hans Bekič “an algebra of processes”
• 1973 Campbell and Haberman: path expressions
• 1978 Van den Bos: Input Tool Model (ITM)
• 1979 Campbell, Kolstad: Path Pascal
• 1978 Hoare: Communicating Sequential Processes (CSP)
• 1980 Milner: Calculus of Communicating Systems (CCS)
• 1982 Bergstra, Klop Algebra of Communicating Processes (ACP
• 1987 Van Delft: ITM >> Scriptic-Pascal, Modula-2, C, C++, Java
3
Example: Hello World
Java
public class HelloWorldApp { public static void main (String args[]) { System.out.println("Hello World!"); } Scriptic
public class HelloWorldApp { public static scripts main (String args[]) = {System.out.println( "Hello World!")} }
4
Hello World, continued
show(String s) = {System.out.print(s)}
hello = show("Hello ")
world = show("World!")
test1 = hello ; world
test2 = hello + world
test3 = hello & world
5
Interleaving and Iterationsshow(String s) = int i: for(i=0; i<s.length(); i++); {System.out.print(s.charAt(i))}
test3 = hello & world // World! Hello
show(String s) = int i: for(i=0; i<s.length(); i++)& private: {System.out.print(s.charAt(i))}
6
Optionality and Iterations(- + x); y // optionally x; then y(..; x); y // zero or more x; then y(x; ..); y // once or more x; then y x; ..; y // one or more x, separated by y
parameterList = r("(");(-+parameters);r(")")parameters = parameter; .. ;r(", ")
parameterList = "(" (.parameters) ")"parameters = parameter..","
7
Constructs ComparedACP Scriptic
+ • ║ interrupt, disrupt ; + & # /
δ ε () -
a b {…} {*…*} {. … .}
X = a•X + b a*b ∑i ∏i ║i . .. ... while for break pass
a|b = c a,b = {…};(x+y)
s(i)|r(i) c<-->(int i) = {…}
s(1)║ ∑i r(i) c<-(1) & int i: c->(i?)
Time, priorities duration, priority
Process creation <…>
&& || | % - ~ {…}< >{…}
if (b) x else y
switch(v)(case 1:x default:y)
{: … :} {? success=… ?}8
Example: a Queue Simulation (1)live = days(5) || servers(10)
waitTime(double d) = {duration=d:}
hours (int i) = waitTime(i*HOUR)
times (int i) = while(pass<i)
Servers (int n) = times(n)
& server(pass+1)
server (int i) = ...; serveCustomer(i)
Days (int n) = times(n); day(pass)
day (int i) = workingDay(i) && hours(24); theDayEnds(i)
workingDay (int i) = hours (9); createCustomers
|| hours(17); theShopCloses
createCustomers = ...; waitTime(randomNegExp(3*MINUTE));
<customer(pass)>
9
Example: a Queue Simulation (2)customer(int c) = double d=FromJava.elapsedTime(): customerEnters(c); getServed(c); customerLeaves(c, d) serveCustomer(int s), getServed(int c) = {duration=randomNegExp(30*MINUTE): trace(" customer "+c+" is served by "+s)} theShopCloses = {:trace("the shop closes"); report():}theDayEnds(int i) = {:trace("day "+i+" ends "); report():} customerEnters(int i) = {:trace("customer "+i+" enters“):}customerLeaves(int i) = {:trace("customer "+i+" leaves“):}
10
Example: a Lookup Applicaton (1)private void searchButton_actionPerformed() {
showSearchingText(); new Thread() { public void run() { searchInDatabase(); SwingUtilities.invokeLater( new Runnable() { public void run() { showSearchResults(); } } ); } }.start();}
11
Example: a Lookup Applicaton (2)searchSequence = searchCommand; showSearchingText; searchInDatabase; showSearchResults
searchCommand = action(searchButton)
showSearchingText = @swing: {showSearchingText()}showSearchResults = @swing: {showSearchResults()}
searchInDatabase = {* searchInDatabase() *}
12
Example: a Lookup Applicaton (3)
searchCommand = action(searchButton) + vkey(searchTF, KeyEvent.VK_ENTER!)
cancelCommand = action(cancelButton) + vkey(searchTF, KeyEvent.VK_ESCAPE!)
exitCommand = action(exitButton) + windowClosing(this)
13
Example: a Lookup Applicaton (4)exit = exitCommand; @swing: while(!confirmExit())
cancelSearch = cancelCommand; @swing: {showCanceledText()}
live = searchSequences || exit
searchSequences = ...; searchSequence
searchSequence = searchCommand; (searchAction / cancelSearch) searchAction = showSearchingText; searchInDatabase; showSearchResults
14
Event-handling scripts (1)public class KeyEventHolder { public KeyEvent event;}public class AnchorKeyListener implements KeyListener {
public KeyEventHolder pressed = new KeyEventHolder();public KeyEventHolder released = new KeyEventHolder();public KeyEventHolder typed = new KeyEventHolder();public void keyPressed(KeyEvent e) {
pressed.event=e; FromJava.doCodeAtAnchor(pressed);
} ...} key(Component comp, char k) = ( AnchorKeyListener a = new AnchorKeyListener() : @swing: {comp.addKeyListener(a)} < @a.pressed: {. k=a.pressed.event.getKeyChar(); k!!?? .} > @swing: {comp.removeKeyListener(a)} )
15
Event-handling scripts (2)action(JButton button) =
( AnchorActionListener a = new AnchorActionListener() :
@swing: {button.addActionListener(a); button.setEnabled(true)}
< @a: {. .}
> @swing: {button.removeActionListener(a);
if (button.getActionListeners().length==0)
{button.setEnabled(false);}}
)
16
@swing:public class SwingCodeInvoker implements CodeInvokerSynchronous, CodeInvokerAsynchronous {
public void invokeSynchronously(Runnable r) throws Exception {SwingUtilities.invokeAndWait(r);
}public void invokeAsynchronously(Runnable r) throws Exception {
SwingUtilities.invokeLater(r);}
}
public class Scripts {
public static SwingCodeInvoker swing = new SwingCodeInvoker();
…}
17
Example: Game of Life (1)
18
live = canvasOperations || mouseInput || speedChanges || exit
Example: Game of Life (2)
randomizeCmd = action(randomizeButton) + key('r' !) clearCmd = action( clearButton) + key('c' !) stepCmd = action( stepButton) + key(' ' !)multiStepStartCmd = action( startButton) + key('\n'!) multiStepStopCmd = action( stopButton) + key('\n'!) exitCmd = action( exitButton) + key('x' !) + windowClosing(this)
exit = exitCmd; boolean doExit: @swing: {doExit = confirmExit()}; while (! doExit)
key(char c) = key(this, c?!)
19
Example: Game of Life (3)
canvasOperations = ...;
( (..;singleStep); multiStep
|| clear
|| randomize)
do1Step = {*canvas.calculateGeneration()*};
@swing: {:canvas.repaint():}
randomize = randomizeCmd; @swing: {:canvas.doRandomize():}
clear = clearCmd; @swing: {:canvas.doClear():}
singleStep = stepCmd; do1Step
multiStep = multiStepStartCmd;
( ...; do1Step; {*sleep()*}
/ multiStepStopCmd )
20
Example: Game of Life (4) speedChanges = ...; speedChange speedChange = speedKeyInput + speedButtonInput + speedSliderInput
speedKeyInput = char c: ( for(c='0'; c<='9'; c++) + private c: key(c!); setSpeed(numKey2Speed(c)) ) speedButtonInput = if (speed()>minSpeed()) speedDecButton + if (speed()<maxSpeed()) speedIncButton speedDecButton = action(minSpeedButton); setSpeed(minSpeed()) + action( slowerButton); setSpeed(speed()-1) speedIncButton = action(maxSpeedButton); setSpeed(maxSpeed()) + action( fasterButton); setSpeed(speed()+1)
speedSliderInput = stateChange(speedSlider); setSpeed(speedSlider.getValue())
setSpeed(int s) = @swing: {:setSpeed(s):} 21
Example: Game of Life (5) mouseInput = mousePressInput & mouseDragInput
mousePressInput = ( ...; MouseEvent me: mousePress(canvas, me?); {:canvas.mouseDownToggle(me):} )
mouseDragInput = ( ...; MouseEvent me: mouseDrag (canvas, me?); {:canvas.mouseDragToggle(me):} )
When critical to catch all events:
mousePressInput = ( AnchorMouseListener a = new AnchorMouseListener(): @swing : { canvas.addMouseListener(a)} < @a.pressed: {...canvas.mouseDownToggle(a.pressed.event)...} > @swing : { canvas.removeMouseListener(a)} )
mouseDragInput = …
22
Case study: Document Processing (1)
• 25 communication protocols, multiple editions
• 106 pages documentation: MS Word• Store as XML; from there create HTML+Java• Many tables• Structure consistent, but…• Typo’s
23
Case study: Document Processing (2)
• Old flow: .doc .txt patched.txt sh+Perl+Java .xml
• New flow: .doc .odt patched.odt Scriptic .xml
24
Case study: Document Processing (3)error(String s) = {:error(s):}fail (String s) = error(s); () nonEmptyLine = anyText; endOfLine emptyLine = endOfLine someEmptyLines = ..; endOfLine someLines = ..; anyLinesomeLinesAndTables = ..; anyLineOrTable
someTables = ..; anyTable someTableRows = ..; anyTableRow someTableCells = ..; anyTableCell anyLineOrTable = anyLine + anyTable anyTable = startOfTable; someTableRows; endOfTable anyTableRow = startOfTableRow; someTableCells; endOfTableRow anyTableCell = startOfTableCell; someLinesAndTables; endOfTableCell
25
Case study: Document Processing (4)// parse a table row with exactly the given strings in the cells
tableRow(String[] rowTexts)
= startOfTableRow;
( while (pass<rowTexts.length); tableCell_text(rowTexts[pass]));
endOfTableRow
// parse a table cell; in case the cellText is an output parameter, it may be built
// from multiple lines these lines then are concatenated with a space as separator
tableCell_text(String cellText)
= startOfTableCell;
line(cellText?!);
if (cellText?) (
String s: ( ..; line(s?); {:cellText = concatenateTrimmed(cellText,s):})
);
endOfTableCell
// parse a table cell containing a number;
tableCell_number(int n) = startOfTableCell; number(n?!); endOfLine; endOfTableCell
text_oneOf(String[] allowedStrings, String s) =
int i:
for (i=0; i<allowedStrings.length; i++)
+ String ls = allowedStrings[i]: text(ls); {:s=ls:}
26
Case study: Document Processing (5)
text_YesOrNo(boolean isYes) = if ( isYes || isYes?) (text("Yes"); {:isYes= true:}) + if (!isYes || isYes?) (text("No" ); {:isYes=false:}) footnote(int n, String s) = footnoteDeclarationPrefix(n?!); line(s?); (..; String s1: line(s1?); {:s=concatenateTrimmed(s,s1.trim()):}) footnoteReference(int n) = in( "(",n?!,")" )
// Parse a Yes/No table cell with an optional footnote
tableCell_YesOrNo(boolean b, int fn) = startOfTableCell; text_YesOrNo(b?!); (- + footnoteReference(fn?)); endOfLine; endOfTableCell
27
Case study: Document Processing (6) wordSequencesForPointsLinesAndAreasTable =
startOfTable;
tableRow(wordSequencesForPointsLinesAndAreasTableHeaderRowTitles);
(
startOfTableRow;
(
tableCell_text(typeOfPointLineArea?);
wordSequenceTableCell;
tableCell_text(applicableTransmitTable?);
messageUseTableCell
||
tableCell_text("");
startOfTableCell; text("followed by additional");
delimitedStrings(msgs?, "/", "sequences"); line("sequences");
endOfTableCell;
tableCell_text("");
messageUseTableCell
);
endOfTableRow;
..
);
endOfTable 28
Case study: Document Processing (7)[prio 1](line=13) <text>, ws, ends line, value = “TNumber, Objective"[prio 0](line=13) <END_OF_TABLE_CELL>, ws[prio 0](line=12) <START_OF_TABLE_CELL>, ws[prio 3](line=13) <text>, ws, value = "M"5-4-J22.0-1 J22.0I WORD: Unexpected input at line 13, position: 1M for P2 JU; T for nonP2 JU ^Expected:[prio 11] <regexp>, ws, value = "\Q-\E[ \t]*" <> "(\s*\Q-\E[ \t]*).*"[prio 11] <regexp>, ws, value = "\QDefault =\E[ \t]*" <> "(\s*\QDefault =\E[ \t]*).*"[prio 11] <regexp>, ws, value = "\Q(Default =\E[ \t]*" <> "(\s*\Q(Default =\E[ \t]*).*"[prio 10] <regexp>, ws, value = "\Q(\E[ \t]*(.+?)\Q)\E" <> "(\s*\Q(\E[ \t]*(.+?)\Q)\E).*" >> ?[prio 10] <regexp>, ws, value = "\Q(\E[ \t]*(\d+)\Q)\E[ \t]*" <> "(\s*)\E[ \t]*).*" >> ?[prio 5] <number>, ws[prio 3] <text>, ws, ends line, value = ""[prio 3] <text>, ws, value = "For"[prio 3] <text>, ws, value = "if"[prio 3] <text>, ws, value = "Otherwise"[prio 3] <text>, ws, value = "."[prio 3] <text>, ws, value = "M"[prio 3] <text>, ws, value = "M*"[prio 3] <text>, ws, value = "T"[prio 3] <text>, ws, value = "T*"[prio 0] <END_OF_TABLE_CELL>, ws
29
Case study: Document Processing (8)
Conclusions• Fast parser development– Input now as easy as output– 50% of time spent on correcting typos in input docs
• More input structure recognized• Clear error messages• Fast operation• Good integration with ODF, Java, JAXB, Ant etc• A few compiler problems• No run-time problems• Disambiguation needs attention
30
Implementation - Compilermain(String args[]) = {System.out.print ("Hello ")}; {System.out.println("world!")}
public static void main(String args[]) {
FromJava.mainscript().startScript(null, main_template(), new Object[] {args });
}
private static NodeTemplate main_template() {
if(main_template != null) {return main_template;}
else {
main_template = NodeTemplate.makeNodeTemplate(
"", "T", "main", "([Ljava/lang/String;)", "T__main_code",
9, (short)0, (short)1,
new Object[][] {
new Object[] {new int[] { 12, 0, 10, 7, 10, 26}, new int[] {10,7,4}},
new Object[] {new int[] { 59, 0, 10, 29, 11, 59}, new int[] {10, 59}},
new Object[] {new int[] {123, 1, 10, 29, 10, 59} },
new Object[] {new int[] {123, 1, 11, 29, 11, 59} },
}
});
return main_template;
}
}
public static void T__main_code(Node node, int i) {
switch(i) {
case 0: System.out.print("Hello "); return;
case 1: System.out.println("world!"); break;}
}
31
Implementation - VM
32
Implementation - Notes
• Based on ITM implementation, 1982• Compiler: complicated• VM: 100k, fast• VM: Just Java• VM: No extra threads• VM: Could be bugfree…
33
Subscript on Scala
• Available on JVM+DotNet• Functional programming• Multiple Inheritance-like• No more “static” items• Syntactic sugar: less semicolons, parentheses• Gaining momentum• Extendible compiler
34
Subscript vs Scriptic
• simplified syntax for old functionality• simplified semantics for process communication• simplified support for 'forcing' parameters• removed language features for discrete event
simulations• allow for plug-in support for discrete event simulations,
parallel execution etc• syntactic sugar for very concise specifications• support for more flavours of parallelism + other concepts• unambiguous language definition
35
Differences
36
Scriptic SubScriptsuccess, duration, priority, pass here
() - δ η ε ν τ ╙ ·‖
{a}< x >{d} @a,†b: x
(a;..);b a..;b
x = a + b + c + d x =+ a b c d
{methodCall()} methodCall
s(1) s,1
action(buttonA) + key(‘x’!) buttonA + ‘x’
<== ==> <==> <= =>
Exception handling
Ambiguities in language definition Precise language definition (TBD)
Sieve of Eratosthenes
37
object Eratosthenes { public scripts
main(args: Array[String]) = generator(2, 1000000) ==> (..==>sieve) ==[toPrint,]==> printer
generator(start,end:Int) = for(i<-start to end) <=i
printer = ..=>i:Int? println,i
sieve = =>p:Int? toPrint<=p; ..=>i:Int? if (i%p!=0) <=i
<==>i:Int = η toPrint<=,=>i:Int = η}
Example: a Lookup Applicaton (5)
searchCommand = searchButton + KeyEvent.VK_ENTER , searchTFcancelCommand = cancelButton + KeyEvent.VK_ESCAPE, searchTF exitCommand = exitButton + windowClosing
exit = exitCommand @swing: while (!confirmExit
cancelSearch = cancelCommand @swing: showCanceledText
live = searchSequences || exit
searchSequences = ...searchSequence
searchSequence = searchCommand; searchAction / cancelSearch
searchAction = showSearchingText searchInDB showSearchResults
3838
Syntax (1)subScriptCode = "scripts" operatorModifiers; ..scriptDefinition
scriptDefinition = scriptDefinitionLHS; ";" + ("+="+"=") scriptExpression
scriptDefinitionLHS = scriptHeader + "===" (scriptHeader..) scriptHeader = scriptName; (."..") optionalParameters.."," scriptName + doubleArrow optionalParameters
scriptName = identifier + "_"optionalParameters = . "(" formalParameters ")"formalParameters = .; formalParameter .. ","formalParameter = identifier ":" type .formalOutputMarkerformalOutputMarker = "?" + "??"scriptExpression = operatorModifiers scriptExpression(10)
39
Syntax (2)scriptExpression(i:Int) = if (i>=0) (scriptExpression(i-1) .. operator(i))
else scriptTerm
operator(i:Int) =+ i matches (
case 10 ==> if newLineSignificant newLine else δ
case 9 ==> ";"
case 8 ==> "||" "|" "||·" "|·"
"|+" "|;" "|/"
"||+" "||;" "||/"
"|+|" "|;|" "|/|"
case 7 ==> "&&" "&" "&&·" "&·"
case 6 ==> "==" "<==" "==>" "<==>“
"==·" "<==·" "==>·" "<==>·“
case 5 ==> "+"
case 4 ==> "/" "%" "/#" "%#" "/#/" "%#%"
case 3 ==> "#“
case 2 ==> " " "╙“‖ case 1 ==> "·"
case 0 ==> if commasOmittable δ else ε
)
40
Syntax (3)scriptTerm =;+variableDeclaration
privateDeclaration
ternary
"try" simpleTerm (catchClause %# finallyClause)
"if" valueExpression simpleTerm ."else" simpleTerm
ternary = unary . "?" ternary . ":" ternary
unary = ..(directive+unaryOperator); simpleTerm
directive = "@" (directivePart ..",") ":“
directivePart = . "†"; . "#"; scalaCode
unaryOperator =+ "!" "-" "~" "*" "**“
simpleTerm =;+ simpleValueLedTerm
codeFragment
throwTerm
whileTerm
forTerm
specialTerm
"(" scriptExpression ")"
arrow . actualParameters
41
Syntax (4)doubleArrow =+ "<-->" "<==>"arrow =+ "<-“ "->" "<-*" "*->“ "?->" "<=" "=>" "<=*“ "*=>“ "?=>“
actualParameters = simpleActualParameters + classicActualParameters ."??" valueExpression
simpleActualParameters = simpleActualParameter..parameterSeparatorclassicActualParameters = "(" ( .; actualParameter.."," ) ")“parameterSeparator = "," + if commasOmittable ε
simpleActualParameter = simpleValueExpression . actualOutputMarkeractualParameter = valueExpression . actualOutputMarker
actualOutputMarker = . ":" type; "?" + "??" valueExpression specialTerm =+ "δ" "ε" "η" "μ" "ν" "τ" "." ".." "..." "break“identifiers = identifier..",“variableDeclaration = "val" identifiers "=" simpleValueExpression + "var" identifiers (":" type %# "=" simpleValueExpression)
42
Syntax (5)
privateDeclaration = "private"; identifier..",“
simpleValueLedTerm = simpleValueExpression; (.actualOutputMarker) ..parameterSeparator simpleValueExpression + arrow . actualParameters + "match" "(" scriptCaseClauses ")"
simpleValueExpression = "_“ + literal + "{=" scalaExpression "=}“ + "new" (classTemplate + templateBody) + ( "here" + currentInstanceExpression + identifier ."." currentInstanceExpression) (.. "." identifier) (. classicActualParameters)
currentInstanceExpression = "this" + "super" "." identifier
43
Syntax (6)codeFragment = ;+
"{" scalaCode "}“
"{*" scalaCode "*}“
"{?" scalaCode "?}“
"{!" scalaCode "!}“
"{." scalaCode ".}“
"{.." scalaCode "..}“
"{..." scalaCode ; "...}" + "..}"
whileTerm = "while" valueExpression
throwTerm = "throw" valueExpression
forTerm = "for"; "(" enumerators ")" + "{" enumerators "}“
catchClause = "catch" "(" (scriptCaseClause..) ")“
scriptCaseClause =;;
"case" pattern
. "if" valueExpression
("=>" + "*=>") scriptExpression
finallyClause = "finally" "{" scalaCode "}“
valueExpression = parenthesizedExpression + simpleValueExpression
parenthesizedExpression = "(" scalaExpression ")"
44