00001 package edu.ksu.cis.bandera.spin;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import java.io.*;
00036 import java.util.Vector;
00037 import java.util.StringTokenizer;
00038 import java.util.List;
00039 import java.util.LinkedList;
00040
00041 import edu.ksu.cis.bandera.bir.*;
00042 import edu.ksu.cis.bandera.checker.*;
00043 import edu.ksu.cis.bandera.util.*;
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 public class SpinTrans extends AbstractExprSwitch implements BirConstants, Checker {
00063 TransSystem system;
00064 PrintWriter out;
00065 SpinTypeName namer;
00066
00067
00068 int indentLevel = 0;
00069 boolean inDefine = false;
00070 boolean newLine = true;
00071
00072 boolean resetTemp = false;
00073 Transformation currentTrans;
00074 int actionNum;
00075
00076 SpinOptions options;
00077 boolean ranVerifier = false;
00078 String panOutput;
00079
00080 static String ccName = "gcc";
00081
00082
00083 public static final String normal = "NORMAL_CASE";
00084
00085
00086
00087
00088 private boolean isVerbose = true;
00089 private String outputDir = "."+File.separator;
00090 SpinTrans(TransSystem system, SpinOptions options, PrintWriter out) {
00091 this.system = system;
00092 this.out = out;
00093 this.namer = new SpinTypeName();
00094 this.options = (options == null) ? new SpinOptions() : options;
00095 }
00096
00097
00098
00099
00100 String actionId() {
00101 int locNum = currentTrans.getFromLoc().getId();
00102 int transNum = currentTrans.getFromLoc().getOutTrans().indexOf(
00103 currentTrans);
00104 return locNum + " " + transNum + " " + actionNum;
00105 }
00106
00107
00108
00109
00110 String actionIdWithCommas() {
00111 int locNum = currentTrans.getFromLoc().getId();
00112 int transNum = currentTrans.getFromLoc().getOutTrans().indexOf(
00113 currentTrans);
00114 return locNum + "," + transNum + "," + actionNum;
00115 }
00116
00117
00118
00119
00120 CaseNode applyTo(Expr expr) {
00121 expr.apply(this);
00122 return (CaseNode) getResult();
00123 }
00124 public void caseAddExpr(AddExpr expr) {
00125 translateBinaryOp(expr.getOp1(), expr.getOp2(), " + ");
00126 }
00127 public void caseAndExpr(AndExpr expr) {
00128 translateBinaryOp(expr.getOp1(), expr.getOp2(), " && ");
00129 }
00130
00131
00132
00133
00134
00135
00136 public void caseArrayExpr(ArrayExpr expr) {
00137 TreeNode arrayTree = applyTo(expr.getArray());
00138 TreeNode indexTree = applyTo(expr.getIndex());
00139 TreeNode result = arrayTree.compose(indexTree, null);
00140 Vector leafCases = result.getLeafCases(new Vector());
00141 for (int i = 0; i < leafCases.size(); i++) {
00142 Case leafCase = (Case) leafCases.elementAt(i);
00143 ExprNode leaf = (ExprNode) leafCase.node;
00144
00145 leafCase.insertTrap(leaf.expr2 + " >= " + leaf.expr1 + ".length",
00146 "ArrayIndexOutOfBoundsException",true);
00147 if (! nonNegative(expr.getIndex()))
00148 leafCase.insertTrap(leaf.expr2 + " < 0", "ArrayIndexOutOfBoundsException",
00149 true);
00150 leaf.update(leaf.expr1 + ".element[" + leaf.expr2 + "]");
00151 }
00152 setResult(result);
00153 }
00154
00155
00156
00157
00158 public void caseAssertAction(AssertAction assertAction) {
00159 CaseNode condTree = (CaseNode) applyTo(assertAction.getCondition());
00160 Vector leaves = condTree.getLeaves(new Vector());
00161
00162 for (int i = 0; i < leaves.size(); i++) {
00163 ExprNode leaf = (ExprNode) leaves.elementAt(i);
00164 leaf.update("assert(" + leaf.expr1 + ");");
00165 }
00166 printStatement(condTree.getCase(normal));
00167 }
00168
00169
00170
00171
00172 public void caseAssignAction(AssignAction assign) {
00173 TreeNode rhsTree = applyTo(assign.getRhs());
00174 TreeNode lhsTree = applyTo(assign.getLhs());
00175 CaseNode result = (CaseNode) lhsTree.compose(rhsTree, null);
00176 Vector leafCases = result.getLeafCases(new Vector());
00177 for (int i = 0; i < leafCases.size(); i++) {
00178 Case leafCase = (Case) leafCases.elementAt(i);
00179 ExprNode leaf = (ExprNode) leafCase.node;
00180 Type rhsType = assign.getRhs().getType();
00181 Type lhsType = assign.getLhs().getType();
00182
00183 if (! rhsType.isSubtypeOf(lhsType)) {
00184
00185
00186 if (lhsType.isKind(RANGE) &&
00187 ! lhsType.containsValue(assign.getRhs())) {
00188 Range range = (Range) lhsType;
00189 leafCase.insertTrap(leaf.expr2 + " < " +
00190 range.getFromVal(), "RangeLimitException",
00191 false);
00192 leafCase.insertTrap(leaf.expr2 + " > " +
00193 range.getToVal(), "RangeLimitException", false);
00194 }
00195
00196
00197 if (lhsType.isKind(REF) &&
00198 ! (assign.getRhs() instanceof NullExpr)) {
00199 String trapDesc = "ClassCastException";
00200 StateVarVector lhsTargets =
00201 ((Ref) lhsType).getTargets();
00202 StateVarVector rhsTargets =
00203 ((Ref) rhsType).getTargets();
00204 for (int j = 0; j < rhsTargets.size(); j++)
00205 if (! lhsTargets.contains(
00206 rhsTargets.elementAt(j))) {
00207 String check =
00208 "_collect(" + leaf.expr2 + ") == " +
00209 refIndex(rhsTargets.elementAt(j));
00210 leafCase.insertTrap(check, "ClassCastException",
00211 true);
00212 }
00213 }
00214 }
00215 leaf.update(leaf.expr1 + " = " + leaf.expr2 + ";");
00216 }
00217 printStatement(result.getCase(normal));
00218 }
00219 public void caseBoolLit(BoolLit expr) {
00220 setResult(specialize("" + expr.getValue()));
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 public void caseChooseExpr(ChooseExpr expr) {
00233 Vector choices = expr.getChoices();
00234 println("if");
00235 for (int i = 0; i < choices.size(); i++) {
00236 Expr choice = (Expr) choices.elementAt(i);
00237 ExprNode leaf = (ExprNode) applyTo(choice).getCase(normal);
00238 println(":: _temp_ = " + leaf.expr1 + "; printf(\"BIR? " +
00239 actionNum + " " + i + "\\n\"); ");
00240 }
00241 println("fi;");
00242 resetTemp = true;
00243 setResult(specialize("_temp_"));
00244 }
00245 public void caseConstant(Constant expr) {
00246 setResult(specialize(expr.getName()));
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256 public void caseDerefExpr(DerefExpr expr) {
00257 TreeNode result = applyTo(expr.getTarget());
00258 StateVarVector targets =
00259 ((Ref) expr.getTarget().getType()).getTargets();
00260 Vector leafCases = result.getLeafCases(new Vector());
00261 for (int i = 0; i < leafCases.size(); i++) {
00262 Case leafCase = (Case) leafCases.elementAt(i);
00263 ExprNode leaf = (ExprNode) leafCase.node;
00264 CaseNode caseNode = new CaseNode();
00265
00266 for (int j = 0; j < targets.size(); j++) {
00267 StateVar target = targets.elementAt(j);
00268 String prom = target.getName();
00269
00270 if (target.getType().isKind(COLLECTION))
00271 prom += ".instance[_index(" + leaf.expr1 + ")]";
00272 String cond = "(_collect(" + leaf.expr1 + ") == " +
00273 refIndex(target) + ")";
00274 caseNode.addCase(cond, prom);
00275 }
00276
00277 String cond = "(_collect(" + leaf.expr1 + ") == 0)";
00278 caseNode.addTrapCase(cond, "NullPointerException", true);
00279 leafCase.replace(caseNode);
00280 }
00281 setResult(result);
00282 }
00283
00284
00285
00286
00287
00288
00289
00290 public void caseDivExpr(DivExpr expr) {
00291 TreeNode e1Tree = applyTo(expr.getOp1());
00292 TreeNode e2Tree = applyTo(expr.getOp2());
00293 TreeNode result = e1Tree.compose(e2Tree, null);
00294 Vector leafCases = result.getLeafCases(new Vector());
00295 for (int i = 0; i < leafCases.size(); i++) {
00296 Case leafCase = (Case) leafCases.elementAt(i);
00297 ExprNode leaf = (ExprNode) leafCase.node;
00298 leafCase.insertTrap(leaf.expr2 + " == 0", "ArithmeticException",
00299 true);
00300 leaf.update("(" + leaf.expr1 + " / " + leaf.expr2 + ")");
00301 }
00302 setResult(result);
00303 }
00304 public void caseEqExpr(EqExpr expr) {
00305 translateBinaryOp(expr.getOp1(), expr.getOp2(), " == ");
00306 }
00307
00308
00309
00310
00311
00312 public void caseInstanceOfExpr(InstanceOfExpr expr) {
00313 TreeNode result = applyTo(expr.getRefExpr());
00314 StateVarVector targets = expr.getRefType().getTargets();
00315 Vector leafCases = result.getLeafCases(new Vector());
00316 for (int i = 0; i < leafCases.size(); i++) {
00317 Case leafCase = (Case) leafCases.elementAt(i);
00318 ExprNode leaf = (ExprNode) leafCase.node;
00319 CaseNode caseNode = new CaseNode();
00320 String elseCond = "! (";
00321 for (int j = 0; j < targets.size(); j++) {
00322 StateVar target = targets.elementAt(j);
00323 String cond = "(_collect(" + leaf.expr1 + ") == " +
00324 refIndex(target) + ")";
00325 caseNode.addCase(cond, "1");
00326 if (j > 0)
00327 elseCond += " || ";
00328 elseCond += cond;
00329 }
00330 elseCond += ")";
00331 caseNode.addCase(elseCond, "0");
00332 leafCase.replace(caseNode);
00333 }
00334 setResult(result);
00335 }
00336 public void caseIntLit(IntLit expr) {
00337 setResult(specialize("" + expr.getValue()));
00338 }
00339 public void caseLeExpr(LeExpr expr) {
00340 translateBinaryOp(expr.getOp1(), expr.getOp2(), " <= ");
00341 }
00342
00343
00344
00345
00346 public void caseLengthExpr(LengthExpr expr) {
00347 TreeNode result = applyTo(expr.getArray());
00348 Vector leaves = result.getLeaves(new Vector());
00349 for (int i = 0; i < leaves.size(); i++) {
00350 ExprNode leaf = (ExprNode) leaves.elementAt(i);
00351 leaf.update(leaf.expr1 + ".length");
00352 }
00353 setResult(result);
00354 }
00355
00356
00357
00358
00359 public void caseLockAction(LockAction lockAction) {
00360 CaseNode lockTree = (CaseNode) applyTo(lockAction.getLockExpr());
00361 String opName =
00362 "_" + LockAction.operationName(lockAction.getOperation());
00363
00364 if (lockAction.isWait())
00365 opName += "_" + lockAction.getThread().getId();
00366 Lock lockType = (Lock) lockAction.getLockExpr().getType();
00367
00368 if (lockType.isReentrant() &&
00369 ! lockAction.isLockAction(NOTIFY | NOTIFYALL))
00370 opName += "_R";
00371 Vector leaves = lockTree.getLeaves(new Vector());
00372 for (int i = 0; i < leaves.size(); i++) {
00373 ExprNode leaf = (ExprNode) leaves.elementAt(i);
00374
00375 leaf.update(opName + "(" + leaf.expr1 + "," +
00376 actionIdWithCommas() + ");");
00377 }
00378 printStatement(lockTree.getCase(normal));
00379 }
00380
00381
00382
00383
00384 public void caseLockTest(LockTest lockTest) {
00385 TreeNode lockTree;
00386 Vector leaves;
00387 switch (lockTest.getOperation()) {
00388 case LOCK_AVAILABLE:
00389 String opName = "_lockAvailable";
00390
00391 if (((Lock) lockTest.getLockExpr().getType()).isReentrant())
00392 opName += "_R";
00393 lockTree = applyTo(lockTest.getLockExpr());
00394 leaves = lockTree.getLeaves(new Vector());
00395 for (int i = 0; i < leaves.size(); i++) {
00396 ExprNode leaf = (ExprNode) leaves.elementAt(i);
00397 leaf.update(opName + "(" + leaf.expr1 + ")");
00398 }
00399 setResult(lockTree);
00400 return;
00401 case HAS_LOCK:
00402
00403 setResult(specialize("true"));
00404 return;
00405 case WAS_NOTIFIED:
00406 lockTree = applyTo(lockTest.getLockExpr());
00407 leaves = lockTree.getLeaves(new Vector());
00408 for (int i = 0; i < leaves.size(); i++) {
00409 ExprNode leaf = (ExprNode) leaves.elementAt(i);
00410 leaf.update("_wasNotified_" +
00411 lockTest.getThread().getId() + "(" +
00412 leaf.expr1 + ")");
00413 }
00414 setResult(lockTree);
00415 return;
00416 }
00417 }
00418 public void caseLtExpr(LtExpr expr) {
00419 translateBinaryOp(expr.getOp1(), expr.getOp2(), " < ");
00420 }
00421 public void caseMulExpr(MulExpr expr) {
00422 translateBinaryOp(expr.getOp1(), expr.getOp2(), " * ");
00423 }
00424 public void caseNeExpr(NeExpr expr) {
00425 translateBinaryOp(expr.getOp1(), expr.getOp2(), " != ");
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 public void caseNewArrayExpr(NewArrayExpr expr) {
00435 StateVar target = expr.getCollection();
00436 int size = ((Collection) target.getType()).getSize().getValue();
00437 int locNum = currentTrans.getFromLoc().getId();
00438 int transNum = currentTrans.getFromLoc().getOutTrans().indexOf(
00439 currentTrans);
00440
00441 println("_allocate(" + target.getName() + "," +
00442 refIndex(target) + "," + size + "," + locNum + "," +
00443 transNum + "," + actionNum + ");");
00444 Array type = (Array)((Collection) target.getType()).getBaseType();
00445 int maxLength = type.getSize().getValue();
00446
00447
00448
00449
00450 CaseNode setLength = applyTo(expr.getLength());
00451 Vector leafCases = setLength.getLeafCases(new Vector());
00452 for (int i = 0; i < leafCases.size(); i++) {
00453 Case leafCase = (Case) leafCases.elementAt(i);
00454 ExprNode leaf = (ExprNode) leafCase.node;
00455 leafCase.insertTrap(leaf.expr1 + " > " + maxLength, "ArraySizeLimitException",
00456 false);
00457 leaf.update(target.getName() +
00458 ".instance[_index(_temp_)].length = " +
00459 leaf.expr1 + "; printf(\"BIR? " + actionNum +
00460 " %d\\n\"," + leaf.expr1 + ");");
00461 }
00462
00463 printStatement(setLength.getCase(normal));
00464 resetTemp = true;
00465 setResult(specialize("_temp_"));
00466 }
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 public void caseNewExpr(NewExpr expr) {
00479 StateVar target = expr.getCollection();
00480 int size = ((Collection) target.getType()).getSize().getValue();
00481 int locNum = currentTrans.getFromLoc().getId();
00482 int transNum = currentTrans.getFromLoc().getOutTrans().indexOf(
00483 currentTrans);
00484
00485 println("_allocate(" + target.getName() + "," +
00486 refIndex(target) + "," + size + "," + locNum + "," +
00487 transNum + "," + actionNum + ");");
00488 resetTemp = true;
00489 setResult(specialize("_temp_"));
00490 }
00491 public void caseNotExpr(NotExpr expr) {
00492 translateUnaryOp(expr.getOp(), "! ");
00493 }
00494 public void caseNullExpr(NullExpr expr) {
00495 setResult(specialize("0"));
00496 }
00497 public void caseOrExpr(OrExpr expr) {
00498 translateBinaryOp(expr.getOp1(), expr.getOp2(), " || ");
00499 }
00500
00501
00502
00503
00504
00505
00506 public void casePrintAction(PrintAction printAction) {
00507 if (printAction.getPrintItems().size() > 0) {
00508 String format = "BIR|";
00509 String params = "";
00510 Vector printItems = printAction.getPrintItems();
00511 for (int i = 0; i < printItems.size(); i++) {
00512 Object item = printItems.elementAt(i);
00513 if (item instanceof String)
00514 format += item;
00515 else {
00516 format += "%d";
00517 CaseNode varTree = (CaseNode) applyTo((Expr) item);
00518 params +=
00519 "," + ((ExprNode) varTree.getCase(normal)).expr1;
00520 }
00521 }
00522 println("printf(\"" + format + "\\n\"" + params + "); ");
00523 }
00524 }
00525
00526
00527
00528
00529 public void caseRecordExpr(RecordExpr expr) {
00530 TreeNode result = applyTo(expr.getRecord());
00531 String field = expr.getField().getName();
00532 Vector leaves = result.getLeaves(new Vector());
00533 for (int i = 0; i < leaves.size(); i++) {
00534 ExprNode leaf = (ExprNode) leaves.elementAt(i);
00535 leaf.update(leaf.expr1 + "." + field);
00536 }
00537 setResult(result);
00538 }
00539 public void caseRefExpr(RefExpr expr) {
00540 setResult(specialize("_ref(" + refIndex(expr.getTarget()) + ",0)"));
00541 }
00542 public void caseRemExpr(RemExpr expr) {
00543 TreeNode e1Tree = applyTo(expr.getOp1());
00544 TreeNode e2Tree = applyTo(expr.getOp2());
00545 TreeNode result = e1Tree.compose(e2Tree, null);
00546 Vector leafCases = result.getLeafCases(new Vector());
00547 for (int i = 0; i < leafCases.size(); i++) {
00548 Case leafCase = (Case) leafCases.elementAt(i);
00549 ExprNode leaf = (ExprNode) leafCase.node;
00550 leafCase.insertTrap(leaf.expr2 + " == 0", "ArithmeticException",
00551 true);
00552 leaf.update("(" + leaf.expr1 + " % " + leaf.expr2 + ")");
00553 }
00554 setResult(result);
00555 }
00556 public void caseStateVar(StateVar expr) {
00557 setResult(specialize(expr.getName()));
00558 }
00559 public void caseSubExpr(SubExpr expr) {
00560 translateBinaryOp(expr.getOp1(), expr.getOp2(), " - ");
00561 }
00562
00563
00564
00565
00566 public void caseThreadAction(ThreadAction threadAction) {
00567 String opName =
00568 ThreadAction.operationName(threadAction.getOperation());
00569 int threadId = threadAction.getThreadArg().getId();
00570 println("_" + opName + "Thread_" + threadId + ";");
00571 }
00572
00573
00574
00575
00576 public void caseThreadLocTest(ThreadLocTest threadLocTest) {
00577 String threadName = threadLocTest.getThread().getName();
00578 int threadId = 1 + threadLocTest.getThread().getId();
00579 String locLabel = locLabel(threadLocTest.getLocation());
00580
00581 String test = threadName + "[" + threadId + "]@" + locLabel;
00582 setResult(specialize(test));
00583 }
00584
00585
00586
00587
00588 public void caseThreadTest(ThreadTest threadTest) {
00589 switch (threadTest.getOperation()) {
00590 case THREAD_TERMINATED:
00591 String opName = ThreadTest.operationName(
00592 threadTest.getOperation());
00593 int threadId = threadTest.getThreadArg().getId();
00594
00595 String test = "_" + opName + "_" + threadId;
00596 setResult(specialize(test));
00597 return;
00598 }
00599 }
00600 public String check() {
00601 String systemName = system.getName();
00602 String promFilename = systemName + ".prom";
00603 String trailFilename = promFilename + ".trail";
00604
00605 if (options.ApplyNeverClaim) {
00606
00607 String ltlFilename = systemName + ".ltl";
00608 File ltlFile = new File(ltlFilename);
00609 if (!ltlFile.exists())
00610 throw new RuntimeException("Cannot find LTL file: "+ltlFile.getAbsolutePath());
00611
00612 try {
00613 String neverClaim = BanderaUtil.exec("spin -F " + ltlFilename, true);
00614 PrintWriter pw = new PrintWriter(new FileWriter(systemName + ".nvr"));
00615 pw.print(neverClaim);
00616 pw.flush();
00617 pw.close();
00618 } catch (Exception e)
00619 {
00620 throw new RuntimeException("Cannot produce file '"+systemName+"',");
00621 }
00622 }
00623
00624 File sourceFile = new File(promFilename);
00625 if (!sourceFile.exists())
00626 throw new RuntimeException("Cannot find SPIN source file: " + sourceFile.getAbsolutePath());
00627
00628
00629
00630
00631
00632
00633
00634
00635 StringBuffer output = new StringBuffer();
00636
00637 try {
00638 output.append(BanderaUtil.exec("spin -a " + promFilename, isVerbose));
00639 if (!(new File("pan.c")).exists()) throw new RuntimeException();
00640 } catch (Exception e) {
00641 cleanMess();
00642 throw new RuntimeException("Could not produce pan.c file!");
00643 }
00644
00645 try {
00646 output.append(BanderaUtil.exec(ccName + " -O3 " + options.compileOptions2() + " -o pan.exe pan.c", isVerbose));
00647 if (!(new File("pan.exe")).exists()) throw new RuntimeException();
00648 } catch (Exception e) {
00649 cleanMess();
00650 throw new RuntimeException("Could not compile pan.c!");
00651 }
00652
00653 String panOutput;
00654 try {
00655
00656 panOutput = BanderaUtil.exec("pan.exe " + options.panOptions(), isVerbose);
00657 output.append(panOutput);
00658 } catch (Exception e)
00659 {
00660 try {
00661 cleanMess();
00662 } catch (Exception exx){}
00663 throw new RuntimeException("Failed to run pan.exe!");
00664 }
00665 cleanMess();
00666
00667 if (panOutput.indexOf("error : max search depth too small") >= 0) {
00668 throw new RuntimeException("Verifier search depth exceeded!");
00669 } else if (panOutput.indexOf("error : out of memory") >= 0) {
00670 throw new RuntimeException("Verifier ran out of memory!");
00671 } else if (panOutput.indexOf("error : VECTORSZ is too small") >= 0) {
00672 throw new RuntimeException("Verifier vector exceeded!");
00673 } else if (panOutput.indexOf("Search not completed") >= 0 && panOutput.indexOf("pan: wrote") < 0) {
00674
00675 throw new RuntimeException("Verifier cannot complete its run:"+System.getProperty("line.separator")+panOutput);
00676 }
00677
00678 try {
00679 BanderaUtil.moveFile(trailFilename, outputDir);
00680 } catch (Exception e)
00681 {
00682 throw new RuntimeException("Cannot move the counter example trail into the output directory!");
00683 }
00684
00685 return output.toString();
00686 }
00687 private void cleanMess()
00688 {
00689
00690 String systemName = system.getName();
00691 String ltlFilename = systemName + ".ltl";
00692 String nvrFilename = systemName + ".nvr";
00693 String promFilename = systemName + ".prom";
00694 String birFilename = systemName + ".bir";
00695 String trailFilename = promFilename + ".trail";
00696
00697 if (!".".equals(outputDir) && !("."+File.separator).equals(outputDir))
00698 {
00699 new File(outputDir+birFilename).delete();
00700 new File(outputDir+ltlFilename).delete();
00701 new File(outputDir+nvrFilename).delete();
00702 new File(outputDir+promFilename).delete();
00703 new File(outputDir+trailFilename).delete();
00704 new File(outputDir+"pan.exe").delete();
00705 new File(outputDir+"pan.b").delete();
00706 new File(outputDir+"pan.c").delete();
00707 new File(outputDir+"pan.h").delete();
00708 new File(outputDir+"pan.m").delete();
00709 new File(outputDir+"pan.t").delete();
00710 }
00711 BanderaUtil.moveFile(birFilename, outputDir);
00712 BanderaUtil.moveFile(ltlFilename, outputDir);
00713 BanderaUtil.moveFile(nvrFilename, outputDir);
00714 BanderaUtil.moveFile(promFilename, outputDir);
00715 BanderaUtil.moveFile(trailFilename, outputDir);
00716 BanderaUtil.moveFile("pan.exe", outputDir);
00717 BanderaUtil.moveFile("pan.b", outputDir);
00718 BanderaUtil.moveFile("pan.c", outputDir);
00719 BanderaUtil.moveFile("pan.h", outputDir);
00720 BanderaUtil.moveFile("pan.m", outputDir);
00721 BanderaUtil.moveFile("pan.t", outputDir);
00722 }
00723
00724 static String currentDir() {
00725 return System.getProperty("user.dir");
00726 }
00727 public void defaultCase(Object obj) {
00728 throw new RuntimeException("Trans type not handled: " + obj);
00729 }
00730
00731
00732
00733
00734 void definitions() {
00735 Vector definitions = system.getDefinitions();
00736
00737
00738 for (int i = 0; i < definitions.size(); i++) {
00739 Definition def = (Definition) definitions.elementAt(i);
00740 if (def instanceof Constant)
00741 println("#define " + def.getName() + " " + def.getDef());
00742 }
00743
00744 Vector types = system.getTypes();
00745 for (int i = 0; i < types.size(); i++) {
00746 Type type = (Type) types.elementAt(i);
00747
00748 if (type.isKind(BOOL | RANGE | LOCK | ENUMERATED | REF)) {
00749 println("/* " + type.typeName() + " = " + type + " */");
00750 print("#define " + type.typeName() + " ");
00751 type.apply(namer, this);
00752 println((String) namer.getResult());
00753
00754 if (type.isKind(ENUMERATED)) {
00755 Enumerated enum = (Enumerated) type;
00756 for (int j = 0; j < enum.getEnumeratedSize(); j++) {
00757 String name = enum.getNameOf(
00758 enum.getFirstElement() + j);
00759 if (name != null)
00760 println("#define " + name + " " +
00761 (enum.getFirstElement() + j));
00762 }
00763 }
00764 }
00765 }
00766
00767
00768
00769 for (int i = 0; i < types.size(); i++) {
00770 Type type = (Type) types.elementAt(i);
00771 if (! type.isKind(BOOL | RANGE | LOCK | ENUMERATED | REF)) {
00772 println("/* " + type.typeName() + " = " + type + " */");
00773 print("typedef " + type.typeName() + " ");
00774 type.apply(namer, this);
00775 println((String) namer.getResult());
00776 }
00777 }
00778 println();
00779 }
00780
00781
00782
00783 public List getCounterExample() {
00784 String systemName = system.getName();
00785 String baseName = outputDir + systemName;
00786 String promFilename = baseName + ".prom";
00787 String trailFilename = promFilename + ".trail";
00788
00789 File trail = new File(trailFilename);
00790 if (!trail.exists())
00791 {
00792 return null;
00793
00794
00795
00796
00797 }
00798
00799 String output = BanderaUtil.exec("spin -t " + promFilename, true);
00800 BufferedReader reader = new BufferedReader(new StringReader(output));
00801 LinkedList ll = new LinkedList();
00802 String ln = System.getProperty("line.separator");
00803 try {
00804 String line;
00805 do {
00806 line = reader.readLine();
00807 if (line != null && line.trim().startsWith("BIR")) ll.add(line.trim());
00808 } while (line != null);
00809 } catch (Exception e)
00810 {
00811 }
00812 return ll;
00813 }
00814
00815
00816
00817
00818
00819
00820
00821 String getSimpleResult() {
00822 TreeNode result = ((CaseNode) getResult()).getCase(normal);
00823 if (result instanceof ExprNode)
00824 return ((ExprNode) result).expr1;
00825 else
00826 throw new RuntimeException("Result not simple: " + result);
00827 }
00828 public SpinOptions getSpinOptions() {
00829 return options;
00830 }
00831
00832
00833
00834
00835
00836
00837
00838 boolean guardPresent(Transformation trans) {
00839 Expr guard = trans.getGuard();
00840 if (guard == null)
00841 return false;
00842 if (guard instanceof BoolLit)
00843 return ! ((BoolLit) guard).getValue();
00844 if ((guard instanceof LockTest) &&
00845 ((LockTest) guard).getOperation() == HAS_LOCK)
00846 return false;
00847 return true;
00848 }
00849
00850
00851
00852
00853 void header() {
00854 ThreadVector threadVector = system.getThreads();
00855
00856 println("/* Promela for transition system: " +
00857 system.getName() + " */");
00858 println();
00859
00860
00861 println("/* Lock operations */");
00862 println("#define LOCK 0");
00863 println("typedef lock_ {\n chan lock = [1] of { bit };\n byte owner;\n};");
00864 println("typedef lock_RW {\n chan lock = [1] of { bit };\n byte owner;\n int waiting;\n byte count;\n};");
00865 println("typedef lock_W {\n chan lock = [1] of { bit };\n byte owner;\n int waiting;\n};");
00866 println("typedef lock_R {\n chan lock = [1] of { bit };\n byte owner;\n byte count;\n};");
00867
00868
00869 println("#define _lock(sync,locNum,transNum,actionNum) \\");
00870 println(" sync.lock?LOCK; sync.owner = _pid ");
00871 println("#define _lock_R(sync,locNum,transNum,actionNum) \\");
00872 println(" if \\");
00873 println(" :: sync.owner == _pid -> sync.count++; \\");
00874 println(" :: else -> sync.lock?LOCK; sync.owner = _pid; \\");
00875 println(" fi ");
00876
00877 println("#define _unlock(sync,locNum,transNum,actionNum) \\");
00878 println(" sync.owner = 0; sync.lock!LOCK ");
00879 println("#define _unlock_R(sync,locNum,transNum,actionNum) \\");
00880 println(" if \\");
00881 println(" :: sync.count > 0 -> sync.count--; \\");
00882 println(" :: else -> sync.owner = 0; sync.lock!LOCK; \\");
00883 println(" fi ");
00884
00885 println("#define _lockAvailable(sync) \\");
00886 println(" nempty(sync.lock)");
00887 println("#define _lockAvailable_R(sync) \\");
00888 println(" (nempty(sync.lock) || sync.owner == _pid) ");
00889
00890 println("#define _unwait(sync,locNum,transNum,actionNum) \\");
00891 println(" sync.lock?LOCK; sync.owner = _pid ");
00892 println("#define _unwait_R(sync,locNum,transNum,actionNum) \\");
00893 println(" sync.lock?LOCK; sync.owner = _pid; sync.count = _temp_; _temp_ = 0 ");
00894
00895 println("#define _notifyAll(sync,locNum,transNum,actionNum) \\");
00896 println(" if \\");
00897 println(" :: sync.owner == _pid -> sync.waiting = 0; \\");
00898 println(" :: else -> printf(\"BIR: locNum transNum actionNum IllegalMonitorStateException\\n\"); assert(0); \\");
00899 println(" fi ");
00900
00901 println("#define _notify(sync,locNum,transNum,actionNum) \\");
00902 println(" if \\");
00903 for (int i = 0; i < threadVector.size(); i++) {
00904 int thread = (1 << i);
00905 println(" :: (sync.owner == _pid) && (sync.waiting & " +
00906 thread + ") -> sync.waiting = sync.waiting & " +
00907 ~ thread + " ; printf(\"BIR? %d " + i + "\",actionNum); \\");
00908 }
00909 println(
00910 " :: (sync.owner == _pid) && (sync.waiting == 0) -> printf(\"BIR? %d " +
00911 threadVector.size() + "\\n\",actionNum); \\");
00912 println(" :: else -> printf(\"BIR: locNum transNum actionNum IllegalMonitorStateException\\n\"); assert(0); \\");
00913 println(" fi ");
00914
00915 for (int i = 0; i < threadVector.size(); i++) {
00916 int thread = (1 << i);
00917
00918 println("#define _wait_" + i + "(sync,locNum,transNum,actionNum) \\");
00919 println(" if \\");
00920 println(
00921 " :: sync.owner == _pid -> sync.waiting = sync.waiting | " +
00922 thread + "; \\");
00923 println(" sync.owner = 0; sync.lock!LOCK; \\");
00924 println(" :: else -> printf(\"BIR: locNum transNum actionNum IllegalMonitorStateException\\n\"); assert(0); \\");
00925 println(" fi ");
00926 println("#define _wait_" + i + "_R(sync,locNum,transNum,actionNum) \\");
00927 println(" if \\");
00928 println(
00929 " :: sync.owner == _pid -> sync.waiting = sync.waiting | " +
00930 thread + "; \\");
00931 println(" _temp_ = sync.count; sync.count = 0; sync.owner = 0; sync.lock!LOCK; \\");
00932 println(" :: else -> printf(\"BIR: locNum transNum actionNum IllegalMonitorStateException\\n\"); assert(0); \\");
00933 println(" fi ");
00934
00935 println("#define _wasNotified_" + i + "(sync) \\");
00936 println(" !(sync.waiting & " + thread + ") ");
00937
00938
00939 if (! threadVector.elementAt(i).isMain()) {
00940 println("#define _startThread_" + i + " \\");
00941 println(" _threadActive_" + i +
00942 " = true; _threadStart_" + i + "!LOCK");
00943 println("#define _beginThread_" + i + " \\");
00944 println(" _threadStart_" + i + "?LOCK");
00945 println("#define _joinThread_" + i + " \\");
00946 println(" skip");
00947 println("#define _exitThread_" + i + " \\");
00948 println(" _threadActive_" + i + " = 0; goto endtop_" + i);
00949 println("#define _threadTerminated_" + i + " \\");
00950 println(" (_threadActive_" + i + " == 0)");
00951 }
00952 }
00953
00954
00955 println();
00956 println("/* Reference operations */");
00957 println("#define _collect(r) (r >> 8)");
00958 println("#define _index(r) (r & 255)");
00959 println("#define _ref(c,i) ((c << 8) | i)");
00960
00961
00962
00963 println("#define _allocate(collection,refindex,maxsize,locNum,transNum,actionNum) \\");
00964 println(" do \\");
00965 println(" :: collection.inuse[_i_] -> \\");
00966 println(" _i_ = _i_ + 1; \\");
00967 println(" if \\");
00968 println(" :: _i_ == maxsize -> printf(\"BIR: locNum transNum actionNum CollectionSizeLimitException\\n\"); limit_exception = 1; _i_ = 0; goto endtrap; \\");
00969 println(" :: else \\");
00970 println(" fi; \\");
00971 println(" :: else -> \\");
00972 println(" collection.inuse[_i_] = 1; \\");
00973 println(" _temp_ = _ref(refindex,_i_); \\");
00974 println(" _i_ = 0; \\");
00975 println(" break; \\");
00976 println(" od ");
00977 println();
00978 println("#define TRAP 1");
00979 println();
00980 }
00981
00982
00983
00984
00985 void initBlock() {
00986 ThreadVector threadVector = system.getThreads();
00987 println("init {");
00988 indentLevel = 2;
00989 println("atomic {");
00990 indentLevel++;
00991 StateVarVector stateVarVector = system.getStateVars();
00992
00993
00994 SpinTypeInit initializer = new SpinTypeInit(this, out);
00995 for (int i = 0; i < stateVarVector.size(); i++) {
00996 StateVar var = stateVarVector.elementAt(i);
00997 var.getType().apply(initializer, var);
00998 }
00999
01000
01001
01002 for (int i = 0; i < threadVector.size(); i++) {
01003 BirThread thread = threadVector.elementAt(i);
01004 println("assert(run " + thread.getName() + "() == " +
01005 (1 + thread.getId()) + ");");
01006 }
01007 indentLevel--;
01008 println("}");
01009
01010
01011
01012
01013
01014 if (!options.getResourceBounded())
01015 println("assert(! limit_exception);");
01016 indentLevel = 0;
01017 println("}");
01018
01019 }
01020
01021
01022
01023
01024
01025
01026 boolean isIfBranch(TransVector outTrans) {
01027 if (outTrans.size() != 2)
01028 return false;
01029 Expr guard1 = outTrans.elementAt(0).getGuard();
01030 Expr guard2 = outTrans.elementAt(1).getGuard();
01031 if (guard1 == null || guard2 == null)
01032 return false;
01033 if ((guard1 instanceof NotExpr) &&
01034 ((NotExpr) guard1).getOp().equals(guard2))
01035 return true;
01036 if ((guard2 instanceof NotExpr) &&
01037 ((NotExpr) guard2).getOp().equals(guard1))
01038 return true;
01039 return false;
01040 }
01041 public boolean isVerbose() { return isVerbose; }
01042
01043
01044
01045
01046
01047
01048
01049 static String locLabel(Location loc) {
01050 if (loc.getOutTrans().size() == 0)
01051 return "endloc_" + loc.getId();
01052 else
01053 return "loc_" + loc.getId();
01054 }
01055
01056
01057
01058
01059
01060
01061
01062 static String locLabel(Location loc1, int branch, Location loc2) {
01063 return "loc_" + loc1.getId() + "_" + branch + "_" + loc2.getId();
01064 }
01065
01066
01067
01068
01069
01070 boolean nonNegative(Expr expr) {
01071 if (expr instanceof ConstExpr)
01072 return ((ConstExpr) expr).getValue() >= 0;
01073 if (expr.getType() instanceof Range) {
01074 Range type = (Range) expr.getType();
01075 return (type.getFromVal().getValue() >= 0);
01076 }
01077 return false;
01078 }
01079 static int parseInt(String s) {
01080 try {
01081 int result = Integer.parseInt(s);
01082 return result;
01083 } catch (NumberFormatException e) {
01084 throw new RuntimeException("Integer didn't parse: " + s);
01085 }
01086 }
01087
01088
01089
01090
01091
01092
01093
01094
01095 public BirTrace parseOutput() {
01096 return new BirTrace(system, getCounterExample());
01097 }
01098
01099
01100
01101
01102
01103
01104
01105 void predicates() {
01106 println("/* Predicates */");
01107 Vector preds = system.getPredicates();
01108 for (int i = 0; i < preds.size(); i++) {
01109 Expr pred = (Expr) preds.elementAt(i);
01110 String name = system.predicateName(pred);
01111 inDefine = true;
01112 println("#define " + name + " ");
01113 indentLevel = 1;
01114
01115 printGuard(applyTo(pred).getCase(normal));
01116 inDefine = false;
01117 println("");
01118 indentLevel = 0;
01119 }
01120 println("");
01121 }
01122
01123
01124
01125
01126 void print(String s) {
01127 if (newLine) {
01128 for (int i = 0; i < indentLevel; i++)
01129 out.print(" ");
01130 newLine = false;
01131 }
01132 out.print(s);
01133 }
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 void printGuard(TreeNode tree) {
01152 if (tree instanceof ExprNode) {
01153 ExprNode node = (ExprNode) tree;
01154 print(node.expr1);
01155 } else if (tree instanceof TrapNode) {
01156 TrapNode node = (TrapNode) tree;
01157 print("TRAP");
01158 } else {
01159 CaseNode node = (CaseNode) tree;
01160 print("( ");
01161 for (int i = 0; i < node.size(); i++) {
01162 Case c = node.elementAt(i);
01163 indentLevel++;
01164 println("( " + c.cond);
01165 print("&& ");
01166 indentLevel++;
01167 printGuard(c.node);
01168 indentLevel--;
01169 print(" )");
01170 indentLevel--;
01171 if (i < node.size() - 1) {
01172 println();
01173 print("|| ");
01174 }
01175 }
01176 println(" )");
01177 }
01178 }
01179 void println() {
01180 if (inDefine)
01181 out.print("\\");
01182 out.println();
01183 newLine = true;
01184 }
01185 void println(String s) {
01186 print(s);
01187 println();
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207 void printStatement(TreeNode tree) {
01208 if (tree instanceof ExprNode) {
01209 ExprNode node = (ExprNode) tree;
01210 println(node.expr1);
01211 } else if (tree instanceof TrapNode) {
01212 TrapNode node = (TrapNode) tree;
01213 print(" printf(\"BIR: " + actionId() + " " + node.desc +
01214 "\\n\"); ");
01215
01216 if (node.fatal)
01217 println("assert(0);");
01218 else
01219 println("limit_exception = 1; goto endtrap;");
01220 } else {
01221 CaseNode node = (CaseNode) tree;
01222 println("if ");
01223 for (int i = 0; i < node.size(); i++) {
01224 Case c = node.elementAt(i);
01225
01226 String cond = (i < node.size() - 1) ? c.cond : "else";
01227 println(":: " + cond + " -> ");
01228 indentLevel++;
01229 printStatement(c.node);
01230 indentLevel--;
01231 }
01232 println("fi; ");
01233 }
01234 }
01235
01236
01237
01238
01239 void property() {
01240 if (options.ApplyNeverClaim)
01241 println("#include \"" + system.getName() + ".nvr\"");
01242 }
01243
01244
01245
01246
01247
01248 int refIndex(StateVar target) {
01249 return 1 + system.refAnyType().getTargets().indexOf(target);
01250 }
01251
01252
01253
01254
01255
01256
01257
01258 void resetDeadVariables(Location fromLoc, Location toLoc) {
01259 StateVarVector liveBefore = fromLoc.getLiveVars();
01260 StateVarVector liveAfter = toLoc.getLiveVars();
01261 if (liveBefore != null && liveAfter != null)
01262 for (int i = 0; i < liveBefore.size(); i++)
01263 if (liveAfter.indexOf(liveBefore.elementAt(i)) == -1) {
01264
01265 StateVar var = liveBefore.elementAt(i);
01266 var.apply(this);
01267 print(getSimpleResult() + " = ");
01268 var.getInitVal().apply(this);
01269 println(getSimpleResult() + ";");
01270 }
01271 }
01272
01273
01274
01275
01276
01277 SpinTrans run() {
01278 header();
01279 definitions();
01280 stateVariables();
01281 transitions();
01282 predicates();
01283 property();
01284 return this;
01285 }
01286
01287
01288
01289
01290
01291
01292
01293
01294 public String runSpin() {
01295 return check();
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348 }
01349 public void setVerbose(boolean v) { isVerbose = v; }
01350
01351
01352
01353
01354 TreeNode specialize(String expr) {
01355 return new CaseNode(new Case(normal, new ExprNode(expr)));
01356 }
01357
01358
01359
01360
01361 void stateVariables() {
01362
01363
01364 println("bool limit_exception = 0;");
01365 println("byte _i_ = 0;");
01366
01367
01368
01369 ThreadVector threads = system.getThreads();
01370 for (int i = 0; i < threads.size(); i++) {
01371 if (! threads.elementAt(i).isMain()) {
01372 println("chan _threadStart_" + i + " = [1] of { bit };");
01373 println("bit _threadActive_" + i + ";");
01374 }
01375 }
01376 println();
01377
01378
01379 StateVarVector stateVarVector = system.getStateVars();
01380 for (int i = 0; i < stateVarVector.size(); i++) {
01381 StateVar var = stateVarVector.elementAt(i);
01382 var.getType().apply(namer, null);
01383 String refIndex = " ";
01384
01385 if (var.getType().isKind(RECORD | ARRAY | COLLECTION))
01386 refIndex += "/* ref index = " + refIndex(var) + " */";
01387 println((String) namer.getResult() + " " + var.getName() +
01388 ";" + refIndex);
01389 }
01390 println();
01391 }
01392
01393
01394
01395
01396
01397
01398
01399
01400 void transitions() {
01401 ThreadVector threadVector = system.getThreads();
01402 for (int i = 0; i < threadVector.size(); i++) {
01403 BirThread thread = threadVector.elementAt(i);
01404 println("proctype " + thread.getName() + "() { ");
01405
01406 println(" int _temp_;");
01407
01408 if (! thread.isMain())
01409 println("endtop_" + i + ":\n _beginThread_" + i + ";");
01410
01411
01412 LocVector threadLocVector = thread.getLocations();
01413 for (int j = 0; j < threadLocVector.size(); j++)
01414 translateLocation(threadLocVector.elementAt(j));
01415
01416
01417 println("endtrap:");
01418
01419
01420
01421 if (options.getResourceBounded()) {
01422 println(" if");
01423 println(" :: limit_exception -> goto endtrap;");
01424 println(" :: !limit_exception -> 0;");
01425 println(" fi;");
01426 } else {
01427 println(" 0;");
01428 }
01429 println("}");
01430 println();
01431 }
01432 initBlock();
01433 }
01434
01435
01436
01437
01438
01439
01440
01441
01442 public static SpinTrans translate(TransSystem system) {
01443 return translate(system, null);
01444 }
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456 public static SpinTrans translate(TransSystem system, SpinOptions options) {
01457 return translate(system, options, ".");
01458 }
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468 public static SpinTrans translate(TransSystem system, SpinOptions options, PrintWriter out) {
01469 return (new SpinTrans(system, options, out)).run();
01470 }
01471 public static SpinTrans translate(TransSystem system, SpinOptions options, String outputDir) {
01472 try {
01473 if (outputDir == null || "".equals(outputDir)) outputDir = "."+File.separator; else
01474 if (!outputDir.endsWith(File.separator)) outputDir = outputDir + File.separator;
01475
01476
01477 File sourceFile = new File(system.getName() + ".prom");
01478 FileOutputStream streamOut = new FileOutputStream(sourceFile);
01479 PrintWriter writerOut = new PrintWriter(streamOut);
01480 SpinTrans result = translate(system, options, writerOut);
01481 result.outputDir = outputDir;
01482 writerOut.close();
01483 return result;
01484 } catch (IOException e) {
01485 throw new RuntimeException("Could not produce SPIN file: " + e);
01486 }
01487 }
01488
01489
01490
01491
01492 void translateBinaryOp(Expr e1, Expr e2, String op) {
01493 TreeNode e1Tree = applyTo(e1);
01494 TreeNode e2Tree = applyTo(e2);
01495
01496 TreeNode result = e1Tree.compose(e2Tree, null);
01497 Vector leaves = result.getLeaves(new Vector());
01498 for (int i = 0; i < leaves.size(); i++) {
01499 ExprNode leaf = (ExprNode) leaves.elementAt(i);
01500 leaf.update("(" + leaf.expr1 + op + leaf.expr2 + ")");
01501 }
01502 setResult(result);
01503 }
01504
01505
01506
01507
01508 public void translateLocation(Location loc) {
01509 if (! loc.isVisible())
01510 return;
01511 println(locLabel(loc) + ":");
01512 indentLevel++;
01513 TransVector outTrans = loc.getOutTrans();
01514
01515 if (outTrans.size() == 1)
01516 translateSequence(outTrans.elementAt(0), 0);
01517 else if (outTrans.size() == 0)
01518 println("0;");
01519 else {
01520 println("if");
01521 for (int i = 0; i < outTrans.size(); i++) {
01522 print(":: ");
01523 indentLevel++;
01524 translateSequence(outTrans.elementAt(i), i);
01525 indentLevel--;
01526 }
01527 println("fi;");
01528 }
01529 indentLevel--;
01530 }
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550 void translateSeq(LocVector locSet, Transformation trans,
01551 int branch, boolean supressGuard) {
01552
01553 translateTrans(trans, supressGuard);
01554
01555
01556
01557 if (trans.getToLoc().isVisible()) {
01558 resetDeadVariables(locSet.firstElement(), trans.getToLoc());
01559 println("goto " + locLabel(trans.getToLoc()) + ";");
01560 }
01561
01562
01563
01564
01565 else if (locSet.contains(trans.getToLoc()))
01566 println("goto " + locLabel(locSet.firstElement(), branch,
01567 trans.getToLoc()) + ";");
01568
01569
01570 else {
01571 locSet.addElement(trans.getToLoc());
01572
01573
01574
01575
01576 if (trans.getToLoc().getInTrans().size() > 1)
01577 println( locLabel(locSet.firstElement(), branch,
01578 trans.getToLoc()) + ":");
01579 TransVector successors = trans.getToLoc().getOutTrans();
01580
01581 if (successors.size() == 1)
01582 translateSeq(locSet, successors.elementAt(0), branch,
01583 false);
01584
01585 else if (isIfBranch(successors)) {
01586 println("if");
01587 print(":: ");
01588 indentLevel++;
01589 translateSeq(locSet, successors.elementAt(0), branch,
01590 false);
01591 indentLevel--;
01592 print(":: else -> ");
01593 indentLevel++;
01594 translateSeq(locSet, successors.elementAt(1), branch, true);
01595 indentLevel--;
01596 println("fi;");
01597 } else {
01598 println("if");
01599 for (int i = 0; i < successors.size(); i++) {
01600 print(":: ");
01601 indentLevel++;
01602 translateSeq(locSet, successors.elementAt(i),
01603 branch, false);
01604 indentLevel--;
01605 }
01606 println("fi;");
01607 }
01608 }
01609 }
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619 void translateSequence(Transformation trans, int branch) {
01620 Location startLoc = trans.getFromLoc();
01621 println("atomic { ");
01622 indentLevel++;
01623 translateSeq(new LocVector(startLoc), trans, branch, false);
01624 indentLevel--;
01625 println("}");
01626 }
01627
01628
01629
01630
01631
01632 void translateTrans(Transformation trans, boolean supressGuard) {
01633
01634 currentTrans = trans;
01635 actionNum = 0;
01636
01637 if (! supressGuard && guardPresent(trans)) {
01638 printGuard(applyTo(trans.getGuard()).getCase(normal));
01639 println("-> ");
01640 }
01641 ActionVector actions = trans.getActions();
01642
01643 for (int i = 0; i < actions.size(); i++) {
01644 actionNum = i + 1;
01645 println("printf(\"BIR: " + actionId() + " OK\\n\"); ");
01646 actions.elementAt(i).apply(this);
01647 }
01648
01649 if (resetTemp) {
01650 println("_temp_ = 0;");
01651 resetTemp = false;
01652 }
01653 }
01654
01655
01656
01657
01658 void translateUnaryOp(Expr e, String op) {
01659 TreeNode result = applyTo(e);
01660 Vector leaves = result.getLeaves(new Vector());
01661
01662 for (int i = 0; i < leaves.size(); i++) {
01663 ExprNode leaf = (ExprNode) leaves.elementAt(i);
01664 leaf.update("(" + op + leaf.expr1 + ")");
01665 }
01666 setResult(result);
01667 }
01668 }