source: trunk/src/org/expeditee/actions/Simple.java@ 121

Last change on this file since 121 was 121, checked in by bjn8, 16 years ago

Added invalidation for graphics... biiiig commit. LOts of effeciency improvements - now can animate

File size: 89.0 KB
Line 
1
2package org.expeditee.actions;
3
4import java.awt.Color;
5import java.awt.Point;
6import java.awt.event.InputEvent;
7import java.awt.geom.Point2D;
8import java.io.BufferedReader;
9import java.io.InputStreamReader;
10import java.util.ArrayList;
11import java.util.Collection;
12import java.util.HashMap;
13import java.util.LinkedList;
14import java.util.List;
15import java.util.Map;
16import java.util.Random;
17
18import org.expeditee.agents.DefaultAgent;
19import org.expeditee.agents.DisplayTree;
20import org.expeditee.agents.WriteTree;
21import org.expeditee.gui.AttributeUtils;
22import org.expeditee.gui.DisplayIO;
23import org.expeditee.gui.Frame;
24import org.expeditee.gui.FrameGraphics;
25import org.expeditee.gui.FrameIO;
26import org.expeditee.gui.FrameKeyboardActions;
27import org.expeditee.gui.FrameMouseActions;
28import org.expeditee.gui.FrameUtils;
29import org.expeditee.gui.FreeItems;
30import org.expeditee.gui.MessageBay;
31import org.expeditee.io.Conversion;
32import org.expeditee.items.Dot;
33import org.expeditee.items.Item;
34import org.expeditee.items.ItemUtils;
35import org.expeditee.items.Line;
36import org.expeditee.items.Text;
37import org.expeditee.items.Item.HighlightMode;
38import org.expeditee.simple.AboveMaxParametreCountException;
39import org.expeditee.simple.BelowMinParametreCountException;
40import org.expeditee.simple.Context;
41import org.expeditee.simple.IncorrectParametreCountException;
42import org.expeditee.simple.IncorrectTypeException;
43import org.expeditee.simple.Pointers;
44import org.expeditee.simple.Primitives;
45import org.expeditee.simple.SBoolean;
46import org.expeditee.simple.SCharacter;
47import org.expeditee.simple.SInteger;
48import org.expeditee.simple.SPointer;
49import org.expeditee.simple.SPrimitive;
50import org.expeditee.simple.SReal;
51import org.expeditee.simple.SString;
52import org.expeditee.simple.SVariable;
53import org.expeditee.simple.UnitTestFailedException;
54import org.expeditee.stats.AgentStats;
55import org.expeditee.stats.SessionStats;
56
57public class Simple implements Runnable {
58
59 private static final String DEFAULT_STRING = "$s.";
60
61 private static final String DEFAULT_BOOLEAN = "$b.";
62
63 private static final String DEFAULT_CHAR = "$c.";
64
65 private static final String DEFAULT_INTEGER = "$i.";
66
67 private static final String DEFAULT_REAL = "$r.";
68
69 private static final String DEFAULT_ITEM = "$ip.";
70
71 private static final String DEFAULT_FRAME = "$fp.";
72
73 private static final String DEFAULT_ASSOCIATION = "$ap.";
74
75 private static final String EXIT_TEXT = "exitall";
76
77 private static enum Status {
78 Exit, OK, Break, Continue, Return, TrueIf, FalseIf;
79 };
80
81 private static final String BREAK2_TEXT = "exitrepeat";
82
83 private static final String BREAK_TEXT = "break";
84
85 private static final String CONTINUE2_TEXT = "nextrepeat";
86
87 private static final String CONTINUE_TEXT = "continue";
88
89 private static final String RETURN_TEXT = "return";
90
91 private static final String LOOP_TEXT = "repeat";
92
93 private static final String TOKEN_SEPARATOR = " +";
94
95 public static final String RUN_FRAME_ACTION = "runframe";
96
97 public static final String DEBUG_FRAME_ACTION = "debugframe";
98
99 /**
100 * Keeps track of how many simple programs are running. Used to check if
101 * simple should read in keyboard input. Or if the keyboard input should be
102 * handled normally by Expeditee.
103 */
104 private static int _programsRunning = 0;
105
106 /**
107 * This flag is set to true if Simple should hijack keyboard input from
108 * Expeditee
109 */
110 private static boolean _consumeKeyboardInput = false;
111
112 public static void ProgramFinished() {
113 _programsRunning--;
114 _stop = false;
115 }
116
117 private static LinkedList<Character> _KeyStrokes = new LinkedList<Character>();
118
119 private static boolean _stop;
120
121 private static boolean _step;
122
123 private static int _stepPause = -1;
124
125 private static Color _stepColor;
126
127 private static boolean _nextStatement;
128
129 public static void KeyStroke(char c) {
130 _KeyStrokes.add(c);
131 }
132
133 public static boolean isProgramRunning() {
134 return _programsRunning > 0;
135 }
136
137 public static boolean consumeKeyboardInput() {
138 return _consumeKeyboardInput && _programsRunning > 0;
139 }
140
141 public static void NewSimpleTest() {
142 Frame newSimpleTest = FrameIO.CreateFrame(DisplayIO.getCurrentFrame()
143 .getFramesetName(), "Test", null);
144 List<String> actions = new ArrayList<String>();
145 actions.add(RUN_FRAME_ACTION);
146 newSimpleTest.getTitleItem().setActions(actions);
147 FrameUtils.DisplayFrame(newSimpleTest, true);
148 MessageBay.displayMessage("New test created");
149 }
150
151 public static void NextTest() {
152 Frame next = DisplayIO.getCurrentFrame();
153 do {
154 next = FrameIO.LoadNext(next);
155 } while (next != null && next.isTestFrame());
156 FrameUtils.DisplayFrame(next, true);
157 }
158
159 public static void PreviousTest() {
160 Frame prev = DisplayIO.getCurrentFrame();
161 do {
162 prev = FrameIO.LoadPrevious(prev);
163 } while (prev != null && prev.isTestFrame());
164
165 FrameUtils.DisplayFrame(prev, true);
166 }
167
168 public static void LastTest() {
169 Frame next = FrameIO.LoadLast();
170 Frame lastTest = null;
171 do {
172 // check if its a test frame
173 if (next != null && next.isTestFrame()) {
174 lastTest = next;
175 break;
176 }
177
178 next = FrameIO.LoadPrevious(next);
179 } while (next != null);
180
181 FrameUtils.DisplayFrame(lastTest, true);
182 }
183
184 public static void RunSimpleTests(String frameset) {
185 RunSimpleTests(frameset, false, true);
186 }
187
188 public static void RunSimpleTestsVerbose(String frameset) {
189 RunSimpleTests(frameset, true, true);
190 }
191
192 private String _frameset;
193
194 private static boolean _verbose = false;
195
196 public Simple(String frameset, boolean verbose) {
197 _frameset = frameset;
198 _verbose = verbose;
199 }
200
201 public void run() {
202 runSuite();
203 }
204
205 public boolean runSuite() {
206 int testsPassed = 0;
207 int testsFailed = 0;
208
209 FrameIO.SaveFrame(DisplayIO.getCurrentFrame(), false);
210 MessageBay.displayMessage("Starting test suite: " + _frameset,
211 Color.CYAN);
212
213 // Get the next number in the inf file for the _frameset
214 int lastFrameNo = FrameIO.getLastNumber(_frameset);
215
216 // Loop through all the valid frames in the _frameset
217 for (int i = 1; i <= lastFrameNo; i++) {
218 String nextFrameName = _frameset + i;
219 Frame nextFrame = FrameIO.LoadFrame(nextFrameName);
220 if (nextFrame == null)
221 continue;
222 Text frameTitle = nextFrame.getTitleItem();
223 if (frameTitle == null)
224 continue;
225 // Run the frames with the RunFrame action on the title
226 Text title = frameTitle.copy();
227 List<String> actions = title.getAction();
228 if (actions == null || title.isAnnotation())
229 continue;
230 if (actions.get(0).toLowerCase().equals("runframe")) {
231 boolean passed = true;
232 String errorMessage = null;
233 try {
234 title.setLink(nextFrameName);
235 // TODO add the ability to run a setup frame
236 // which sets up variables to be used in all
237 // tests
238 AgentStats.reset();
239 _KeyStrokes.clear();
240 _programsRunning++;
241 Context context = new Context();
242 RunFrameAndReportError(title, context);
243 _programsRunning--;
244 // if the throws exception annotation is on the frame then
245 // it passes only if an exception is thrown
246 if (title.getParentOrCurrentFrame().hasAnnotation(
247 "ThrowsException")) {
248 errorMessage = "Expected exception " + title.toString();
249 passed = false;
250 }
251 } catch (Exception e) {
252 _programsRunning--;
253 if (!title.getParentOrCurrentFrame().hasAnnotation(
254 "ThrowsException")) {
255 errorMessage = e.getMessage();
256 passed = false;
257 }
258 }
259 if (passed) {
260 if (_verbose)
261 MessageBay.displayMessage("Test passed: "
262 + title.toString(), Item.GREEN);
263 testsPassed++;
264 } else {
265 testsFailed++;
266 // Print out the reason for failed tests
267 MessageBay.linkedErrorMessage(errorMessage);
268 if (Simple._stop) {
269 Simple._stop = false;
270 return false;
271 }
272 }
273 }
274 }
275 // The statement below assumes there are no other programs running at
276 // the same time
277 assert (_programsRunning == 0);
278 // Report the number of test passed and failed
279 MessageBay.displayMessage("Total tests: "
280 + (testsPassed + testsFailed), Color.CYAN);
281 if (testsPassed > 0)
282 MessageBay.displayMessage("Passed: " + testsPassed, Item.GREEN);
283 if (testsFailed > 0)
284 MessageBay.displayMessage("Failed: " + testsFailed, Color.RED);
285 // Remove items from the cursor...
286 FreeItems.getInstance().clear();
287
288 return testsFailed == 0;
289 }
290
291 /**
292 * Runs a suite of tests stored in a given frameset.
293 *
294 * @param frameset
295 * @param verbose
296 * @param newThread
297 * false if tests should be run on the current frame
298 */
299 public static void RunSimpleTests(String frameset, boolean verbose,
300 boolean newThread) {
301 _stop = false;
302 Simple testSuite = new Simple(frameset, verbose);
303 if (newThread) {
304 Thread t = new Thread(testSuite);
305 t.setPriority(Thread.MIN_PRIORITY);
306 t.start();
307 } else {
308 assert (testSuite.runSuite());
309 }
310
311 }
312
313 private static void RunFrame(Text current, boolean acceptKeyboardInput,
314 boolean step, int pause, Color color) {
315 try {
316 DisplayIO.addToBack(current.getParent());
317
318 _stepColor = color == null ? Color.green : color;
319 _stepColor = new Color(_stepColor.getRed(), _stepColor.getGreen(),
320 _stepColor.getBlue(), 50);
321 _stepPause = pause;
322 _step = step;
323 _consumeKeyboardInput = acceptKeyboardInput;
324 FrameIO.SaveFrame(DisplayIO.getCurrentFrame(), true);
325
326 // an item without a link signals to run the current frame
327 if (current.getLink() == null) {
328 // Make a copy but hide it
329 current = current.copy();
330 current.setLink(DisplayIO.getCurrentFrame().getName());
331 }
332
333 _KeyStrokes.clear();
334
335 Thread t = new Thread(current);
336 t.setPriority(Thread.MIN_PRIORITY);
337 t.start();
338 } catch (Exception e) {
339 }
340 }
341
342 public static void RunFrame(Text current, boolean acceptKeyboardInput) {
343 RunFrame(current, acceptKeyboardInput, false, 0, null);
344 }
345
346 public static void RunFrame(Text current) {
347 RunFrame(current, false);
348 }
349
350 /**
351 * At present programs which accept keyboard input can not be debugged.
352 *
353 * @param current
354 * @param pause
355 */
356 public static void DebugFrame(Text current, float pause, Color color) {
357 if (isProgramRunning()) {
358 stop();
359 }
360 RunFrame(current, false, true, Math.round(pause * 1000), color);
361 }
362
363 /**
364 * At present programs which accept keyboard input can not be debugged.
365 *
366 * @param current
367 * @param pause
368 * the time to pause between
369 */
370 public static void DebugFrame(Text current, float pause) {
371 DebugFrame(current, pause, null);
372 }
373
374 public static void DebugFrame(Text current) {
375 DebugFrame(current, -1.0F, null);
376 }
377
378 private static void FlagError(Item item) {
379 FrameUtils.DisplayFrame(item.getParent().getName(), true);
380 item.setHighlightMode(HighlightMode.Normal);
381 item.setHighlightColor(Color.CYAN);
382 FrameIO.SaveFrame(item.getParent());
383 }
384
385 /**
386 * Runs a simple code begining on a frame linked to by the specified item
387 * parametre.
388 *
389 * @param current
390 * the item that is linked to the frame to be run.
391 */
392 public static Status RunFrameAndReportError(Item current, Context context)
393 throws Exception {
394 // the item must link to a frame
395 if (current.getLink() == null) {
396 throw new Exception("Could not run unlinked item: "
397 + current.toString());
398 }
399
400 Frame child = FrameIO.LoadFrame(current.getAbsoluteLink());
401
402 // Create frame variables for each linked annotation item on the frame
403 // which has a single word of text corresponding to the variable name
404 for (Text text : child.getAnnotationItems()) {
405 String link = text.getAbsoluteLink();
406 if (link == null)
407 continue;
408 Frame frame = FrameIO.LoadFrame(link);
409 if (frame == null)
410 continue;
411 // Now save the frame as a variable
412 String varName = text.getText().substring(1).trim();
413 if (varName.indexOf(' ') > 0)
414 continue;
415 context.getPointers().setObject(SPointer.framePrefix + varName,
416 frame);
417 context.getPointers().setObject(SPointer.itemPrefix + varName,
418 frame.getTitleItem());
419 context.getPrimitives().add(SString.prefix + varName,
420 new SString(frame.getName()));
421 }
422
423 if (_step) {
424 if (child != DisplayIO.getCurrentFrame()) {
425 DisplayIO.setCurrentFrame(child);
426 }
427 DisplayIO.addToBack(child);
428 }
429
430 AgentStats.FrameExecuted();
431
432 // if the frame could not be loaded
433 if (child == null) {
434 throw new Exception("Could not load item link: "
435 + current.toString());
436 }
437
438 // loop through non-title, non-name, text items
439 List<Text> body = child.getBodyTextItems(false);
440
441 // if no item was found
442 if (body.size() == 0)
443 throw new Exception("No code to be executed: " + current.toString());
444
445 Status lastItemStatus = Status.OK;
446 for (Text item : body) {
447 AgentStats.ItemExecuted();
448 try {
449 Color oldColor = item.getBackgroundColor();
450 if (_step) {
451 pause(item);
452 }
453 lastItemStatus = RunItem(item, context, lastItemStatus);
454 if (_step) {
455 if (item.getLink() == null) {
456 item.setBackgroundColor(oldColor);
457 } else {
458 item.setHighlightMode(Item.HighlightMode.None);
459 }
460 }
461
462 if (lastItemStatus != Status.OK) {
463 if (lastItemStatus != Status.TrueIf
464 && lastItemStatus != Status.FalseIf) {
465 if (_step) {
466 DisplayIO.removeFromBack();
467 }
468 return lastItemStatus;
469 }
470 }
471 } catch (ArrayIndexOutOfBoundsException e) {
472 FlagError(item);
473 throw new Exception("Too few parametres: " + item.toString());
474 } catch (NullPointerException e) {
475 FlagError(item);
476 throw new Exception("Null pointer exception: "
477 + item.toString());
478 } catch (RuntimeException e) {
479 FlagError(item);
480 throw new Exception(e.getMessage() + " " + item.toString());
481 } catch (Exception e) {
482 throw new Exception(e.getMessage());
483 }
484 }
485
486 if (_step) {
487 DisplayIO.removeFromBack();
488 if (DisplayIO.getCurrentFrame() != current.getParent())
489 DisplayIO.setCurrentFrame(current.getParent());
490 }
491
492 return Status.OK;
493 }
494
495 /**
496 * @param item
497 * @param oldColor
498 * @throws Exception
499 * @throws InterruptedException
500 */
501 private static void pause(Text item) throws Exception, InterruptedException {
502 if (!_step)
503 return;
504
505 Color oldColor = item.getBackgroundColor();
506 item.setBackgroundColor(_stepColor);
507 item.setHighlightMode(Item.HighlightMode.None);
508
509 // Make sure we are on the frame with this item
510 Frame parent = item.getParentOrCurrentFrame();
511 if (!parent.equals(DisplayIO.getCurrentFrame())) {
512 DisplayIO.setCurrentFrame(parent);
513 }
514
515 FrameGraphics.Repaint();
516
517 int timeRemaining;
518 if (_stepPause < 0)
519 timeRemaining = Integer.MAX_VALUE;
520 else
521 timeRemaining = _stepPause;
522
523 while (timeRemaining > 0 && !_nextStatement) {
524 if (_stop) {
525 item.setBackgroundColor(oldColor);
526 item.setHighlightMode(HighlightMode.Normal, _stepColor);
527 throw new Exception("Program terminated");
528 }
529 Thread.sleep(DefaultAgent.TIMER_RESOLUTION);
530 timeRemaining -= DefaultAgent.TIMER_RESOLUTION;
531 }
532 _nextStatement = false;
533 // Turn off the highlighting
534 item.setBackgroundColor(oldColor);
535 }
536
537 private static void pause(double time) throws Exception {
538 for (int i = 0; i < time * 10; i++) {
539 if (_stop) {
540 throw new Exception("Program terminated");
541 }
542 Thread.yield();
543 Thread.sleep(100);
544 }
545 }
546
547 /**
548 * This method should be modified to parse strings correctly
549 *
550 * @param statement
551 * @return
552 */
553 private static String[] parseStatement(Text code) throws Exception {
554 String statement = code.getText().trim();
555 ArrayList<String> tokens = new ArrayList<String>();
556
557 // At the moment annotation items are ignored by the interpreter
558 // // Check special annotation tags for programs
559 // if (statement.length() > 0 && statement.charAt(0) == '@') {
560 // statement = statement.toLowerCase();
561 // // Flags the next unit test as being required to throw an exception
562 // if (statement.equals("@throwsexception")) {
563 // code.getParentOrCurrentFrame().setThrowsException(true);
564 // }
565 // return null;
566 // }
567
568 for (int i = 0; i < statement.length(); i++) {
569 char c = statement.charAt(i);
570 // ignore spaces
571 if (c != ' ') {
572 int startOfToken = i;
573 if (c == '\"') {
574 int endOfToken = statement.length() - 1;
575 // find the end of the string literal
576 while (statement.charAt(endOfToken) != '\"')
577 endOfToken--;
578 if (endOfToken > startOfToken) {
579 tokens.add(statement.substring(startOfToken,
580 endOfToken + 1));
581 } else {
582 throw new RuntimeException("Expected matching \" ");
583 }
584 break;
585 } else if (c == '#' || c == '/') {
586 break;
587 } else {
588 // read in a normal token
589 while (++i < statement.length()
590 && statement.charAt(i) != ' ')
591 ;
592 tokens.add(statement.substring(startOfToken, i)
593 .toLowerCase());
594 }
595 }
596 }
597
598 String[] a = new String[tokens.size()];
599 a = tokens.toArray(a);
600 code.setProcessedText(a);
601 return a;
602 }
603
604 /**
605 * Runs a SIMPLE procedure statement.
606 *
607 * @param tokens
608 * the parsed Call statement.
609 * @param code
610 * the expeditee item containing the procedure call and the link
611 * to the frame with the procedure code.
612 * @param context
613 * the current context from which the procedure call is being
614 * made.
615 * @throws Exception
616 * when errors occur in running the procedure.
617 */
618 private static Status Call(String[] tokens, Item code, Context context)
619 throws Exception {
620 // Check that the call statement is linked
621 if (code.getLink() == null)
622 throw new Exception("Unlinked call statement: " + code.toString());
623
624 Frame procedure = FrameIO.LoadFrame(code.getAbsoluteLink());
625
626 // Add call to the start of the title if it doesnt exist
627 // This makes the call and signature tokens counts match
628 String procedureTitle = procedure.getTitleItem().getFirstLine();
629 if (!procedureTitle.toLowerCase().startsWith("call "))
630 procedureTitle = "call " + procedureTitle;
631
632 // Check that the calling statement matches the procedure
633 // signature
634 String[] procedureSignature = procedureTitle.split(TOKEN_SEPARATOR);
635
636 // Check for the right amount of parametres
637 if (procedureSignature.length < tokens.length)
638 throw new Exception("Call statement has too many parametres: "
639 + code.toString());
640 else if (procedureSignature.length > tokens.length)
641 throw new Exception("Call statement has too few parametres: "
642 + code.toString());
643 // else if (procedureSignature[1].equals(tokens[1]))
644 // throw new Exception("Call statement and procedure name dont match: "
645 // + code.toString());
646
647 // create the new context for the sub procedure
648 Context newContext = new Context();
649 // Check that the types/prefixes match
650 for (int i = 2; i < tokens.length; i++) {
651 // TODO allow for auto casting of primitives
652 if (tokens[i].substring(1, 2).equals(
653 procedureSignature[i].substring(1, 2))) {
654 // Add the variables to the new context
655 if (Primitives.isPrimitive(tokens[i])) {
656 try {
657 // try and get the value for the variable
658 SPrimitive p = context.getPrimitives().getVariable(
659 tokens[i]);
660 newContext.getPrimitives()
661 .add(procedureSignature[i], p);
662 } catch (Exception e) {
663 // If an exception occurs the variable doesnt
664 // exist in the current context
665 // So the variable must be added to both context
666 context.getPrimitives().add(tokens[i], new SString(""));
667 newContext.getPrimitives().add(procedureSignature[i],
668 new SString(""));
669 }
670 } else if (Pointers.isPointer(tokens[i])) {
671 try {
672 // try and get the value for the variable
673 SPointer p = context.getPointers().getVariable(
674 tokens[i]);
675 newContext.getPointers().add(procedureSignature[i], p);
676 } catch (Exception e) {
677 // If an exception occurs the variable doesnt
678 // exist in the current context
679 // So the variable must be added to both context
680 context.getPointers().setObject(tokens[i], null);
681 newContext.getPointers().setObject(
682 procedureSignature[i], null);
683 }
684 } else
685 throw new Exception("Unrecognised variable type: "
686 + tokens[i] + " in " + code.toString());
687 } else
688 throw new IncorrectTypeException(procedureSignature[i], i);
689 }
690
691 // Follow the link and Run the code for the procedure
692 Status result = RunFrameAndReportError(code, newContext);
693 // If a return statement ends the procedure then we accept this as
694 // normal execution
695 switch (result) {
696 case Return:
697 result = Status.OK;
698 break;
699 case Break:
700 throw new Exception(BREAK_TEXT + " statement without matching "
701 + LOOP_TEXT + " in " + code.toString());
702 case Continue:
703 throw new Exception("");
704 }
705
706 // Now copy the values from the procedure context into the
707 // current context
708 for (int i = 2; i < tokens.length; i++) {
709 try {
710 if (Primitives.isPrimitive(tokens[i])) {
711 // try and get the value for the variable
712 SVariable p = context.getPrimitives()
713 .getVariable(tokens[i]);
714 SVariable newP = newContext.getPrimitives().getVariable(
715 procedureSignature[i]);
716 p.setValue(newP);
717 } else {
718 // try and get the value for the variable
719 SVariable p = context.getPointers().getVariable(tokens[i]);
720 SVariable newP = newContext.getPointers().getVariable(
721 procedureSignature[i]);
722 p.setValue(newP);
723 }
724 } catch (Exception e) {
725 assert (false);
726 }
727 }
728
729 return result;
730 }
731
732 /**
733 * Runs a text item on a frame as a SIMPLE statement. The statement is
734 * parsed and if it is a recognised SIMPLE keyword or procedure the code is
735 * executed.
736 *
737 * @param code
738 * the item containing the code to be executed.
739 * @param context
740 * @return
741 * @throws Exception
742 */
743 private static Status RunItem(Text code, Context context,
744 Status lastItemStatus) throws Exception {
745 if (_stop) {
746 throw new Exception("Program terminated");
747 }
748
749 String[] tokens = code.getProcessedText();
750
751 if (tokens == null) {
752 tokens = parseStatement(code);
753 }
754
755 // Annotation items are ignored after parsing running options
756 if (tokens == null) {
757 return Status.OK;
758 // Comments without links are ignored
759 } else if (tokens.length == 0) {
760 if (code.getLink() == null)
761 return Status.OK;
762 else
763 return RunFrameAndReportError(code, context);
764 }
765
766 // At present only set statements can have literals so they
767 // are the only statements that we have to worry about string
768 // literals
769 if (tokens[0].equals("call") && tokens.length >= 2) {
770 return Call(tokens, code, context);
771 // Check if the user wants to display a message
772 // Check for set statements
773 } else if (tokens[0].startsWith("search")) {
774 if (tokens[0].equals("searchstr")) {
775 assertExactParametreCount(tokens, 5);
776 String searchStr = context.getPrimitives().getStringValue(
777 tokens[1]);
778 String pattern = context.getPrimitives().getStringValue(
779 tokens[2]);
780 String[] result = searchStr.split(pattern, 2);
781 boolean bFound = result.length > 1;
782 context.getPrimitives().setValue(tokens[3],
783 new SBoolean(bFound));
784 if (bFound) {
785 context.getPrimitives().setValue(tokens[4],
786 new SInteger(result[0].length() + 1));
787 context.getPrimitives().setValue(tokens[5],
788 new SInteger(searchStr.length() - result[1].length()));
789 }
790 }else if (tokens[0].equals("searchitem")) {
791 assertExactParametreCount(tokens, 5);
792 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
793 Text searchItem = (Text)context.getPointers().getVariable(tokens[1]).getValue();
794 String searchStr = searchItem.getText();
795 String pattern = context.getPrimitives().getStringValue(
796 tokens[2]);
797 String[] result = searchStr.split(pattern, 2);
798 boolean bFound = result.length > 1;
799 context.getPrimitives().setValue(tokens[3],
800 new SBoolean(bFound));
801 if (bFound) {
802// context.getPrimitives().setValue(tokens[4],
803// new SInteger(1));
804 context.getPrimitives().setValue(tokens[4],
805 new SInteger(result[0].length() + 1));
806// context.getPrimitives().setValue(tokens[6],
807// new SInteger(1));
808 context.getPrimitives().setValue(tokens[5],
809 new SInteger(searchStr.length() - result[1].length()));
810 }
811 }
812 } else if (tokens[0].startsWith("set")) {
813 if (tokens[0].equals("set")) {
814 try {
815 // Check if we are setting variable to variable
816 if (tokens[2].startsWith(SVariable.prefix)
817 && tokens.length == 3) {
818 context.getPrimitives().set(tokens[1], tokens[2]);
819 }
820 // Otherwise we are setting a variable with a literal
821 else {
822 // check for strings enclosed in quotes
823 if (tokens[2].startsWith("\"")) {
824 context.getPrimitives().setValue(
825 tokens[1],
826 new SString(tokens[2].substring(1,
827 tokens[2].length() - 1)));
828 // set a literal
829 } else if (tokens.length == 3) {
830 context.getPrimitives().setValue(tokens[1],
831 tokens[2]);
832 }
833 }
834 } catch (Exception e) {
835 throw new RuntimeException(e.getMessage());
836 }
837 } else if (tokens[0].equals("setassociation")) {
838 assertExactParametreCount(tokens, 3);
839
840 Map<String, String> map = (Map<String, String>) context
841 .getPointers().getVariable(tokens[1]).getValue();
842 String attribute = context.getPrimitives().getStringValue(
843 tokens[2]);
844 String value = context.getPrimitives()
845 .getStringValue(tokens[3]);
846 map.put(attribute, value);
847 } else if (tokens[0].equals("setframevalue")) {
848 assertMinParametreCount(tokens, 3);
849 assertVariableType(tokens[1], 1, SPointer.framePrefix);
850
851 // Get the attribute to be searched for on the target frame
852 Frame targetFrame = (Frame) context.getPointers().getVariable(
853 tokens[1]).getValue();
854 String targetAttribute = context.getPrimitives()
855 .getStringValue(tokens[2]).toLowerCase()
856 + ":";
857 String value = context.getPrimitives()
858 .getStringValue(tokens[3]);
859 Boolean found = false;
860 Text attributeItem = null;
861 Item valueItem = null;
862 // Begin the search
863 for (Text text : targetFrame.getBodyTextItems(true)) {
864 String s = text.getText().toLowerCase();
865
866 if (s.startsWith(targetAttribute)) {
867 attributeItem = text;
868 AttributeUtils.replaceValue(attributeItem, value);
869 found = true;
870 break;
871 }
872 }
873 // Keep looking for a matching value nearby if we found an
874 // attribute without the value in the same item
875 if (!found && attributeItem != null) {
876 Point2D.Float endPoint = attributeItem
877 .getEndParagraphPosition();
878
879 for (Text text : targetFrame.getBodyTextItems(true)) {
880 Point startPoint = text.getPosition();
881 if (Math.abs(startPoint.y - endPoint.y) < 10
882 && Math.abs(startPoint.x - endPoint.x) < 20) {
883 found = true;
884 valueItem = text;
885 text.setText(value);
886 break;
887 }
888 }
889 }
890
891 // Set the values of the output parametres
892 if (tokens.length > 4) {
893 context.getPrimitives().setValue(tokens[4],
894 new SBoolean(found));
895 if (tokens.length > 5) {
896 context.getPointers().setObject(tokens[5],
897 attributeItem);
898 if (tokens.length > 6) {
899 context.getPointers().setObject(tokens[6],
900 valueItem);
901 }
902 }
903 }
904 } else if (tokens[0].startsWith("setitem")) {
905 if (tokens[0].equals("setitemposition")) {
906 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
907 // assertPrimitiveType(tokens[2], 2);
908 // assertPrimitiveType(tokens[3], 3);
909 Item item = (Item) context.getPointers().getVariable(
910 tokens[1]).getValue();
911 item.setPosition(context.getPrimitives().getVariable(
912 tokens[2]).integerValue().intValue(), context
913 .getPrimitives().getVariable(tokens[3])
914 .integerValue().intValue());
915 } else if (tokens[0].equals("setitemthickness")) {
916 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
917 // assertPrimitiveType(tokens[2], 2);
918 Item item = (Item) context.getPointers().getVariable(
919 tokens[1]).getValue();
920 item.setThickness(context.getPrimitives().getVariable(
921 tokens[2]).integerValue().intValue());
922 } else if (tokens[0].equals("setitemwidth")) {
923 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
924 // assertPrimitiveType(tokens[2], 2);
925 Item item = (Item) context.getPointers().getVariable(
926 tokens[1]).getValue();
927 item.setWidth(context.getPrimitives()
928 .getVariable(tokens[2]).integerValue().intValue());
929 } else if (tokens[0].equals("setitemsize")) {
930 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
931 // assertPrimitiveType(tokens[2], 2);
932 Item item = (Item) context.getPointers().getVariable(
933 tokens[1]).getValue();
934 item.setSize(context.getPrimitives().getVariable(tokens[2])
935 .integerValue().intValue());
936 } else if (tokens[0].equals("setitemlink")) {
937 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
938 // assertPrimitiveType(tokens[2], 2);
939 Item item = (Item) context.getPointers().getVariable(
940 tokens[1]).getValue();
941 item.setLink(context.getPrimitives().getVariable(tokens[2])
942 .stringValue());
943 } else if (tokens[0].equals("setitemdata")) {
944 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
945 // assertPrimitiveType(tokens[2], 2);
946 Item item = (Item) context.getPointers().getVariable(
947 tokens[1]).getValue();
948 item.setData(context.getPrimitives().getVariable(tokens[2])
949 .stringValue());
950 } else if (tokens[0].equals("setitemaction")) {
951 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
952 // assertPrimitiveType(tokens[2], 2);
953 Item item = (Item) context.getPointers().getVariable(
954 tokens[1]).getValue();
955 item.setAction(context.getPrimitives().getVariable(
956 tokens[2]).stringValue());
957 } else if (tokens[0].equals("setitemfillcolor")) {
958 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
959 // assertPrimitiveType(tokens[2], 2);
960 Item item = (Item) context.getPointers().getVariable(
961 tokens[1]).getValue();
962 String stringColor = context.getPrimitives().getVariable(
963 tokens[2]).stringValue();
964 item.setBackgroundColor((Color) Conversion.Convert(
965 Color.class, stringColor));
966 } else if (tokens[0].equals("setitemcolor")) {
967 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
968 // assertPrimitiveType(tokens[2], 2);
969 Item item = (Item) context.getPointers().getVariable(
970 tokens[1]).getValue();
971 String stringColor = context.getPrimitives().getVariable(
972 tokens[2]).stringValue();
973 item.setColor((Color) Conversion.Convert(Color.class,
974 stringColor));
975 } else if (tokens[0].equals("setitemtext")) {
976 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
977 // assertPrimitiveType(tokens[2], 2);
978 String newText = context.getPrimitives().getVariable(
979 tokens[2]).stringValue();
980 Text textItem = (Text) context.getPointers().getVariable(
981 tokens[1]).getValue();
982 textItem.setText(newText);
983 } else
984 throw new Exception("Unsupported setItem command: "
985 + code.toString());
986 } else if (tokens[0].equals("setstrchar")) {
987 assertExactParametreCount(tokens, 3);
988 StringBuffer s = new StringBuffer(context.getPrimitives()
989 .getStringValue(tokens[1]));
990 int pos = (int) context.getPrimitives().getIntegerValue(
991 tokens[2]);
992 char newChar = context.getPrimitives().getCharacterValue(
993 tokens[3]);
994 while (pos > s.length()) {
995 s.append(newChar);
996 }
997 s.setCharAt(pos - 1, newChar);
998
999 context.getPrimitives().setValue(tokens[1],
1000 new SString(s.toString()));
1001 } else if (tokens[0].equals("setcharinitem")) {
1002 assertExactParametreCount(tokens, 4);
1003 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1004
1005 int row = (int) context.getPrimitives().getIntegerValue(
1006 tokens[3]) - 1;
1007 int col = (int) context.getPrimitives().getIntegerValue(
1008 tokens[4]) - 1;
1009 char newChar = context.getPrimitives().getCharacterValue(
1010 tokens[2]);
1011 Text item = (Text) context.getPointers().getVariable(tokens[1])
1012 .getValue();
1013 List<String> itemText = item.getTextList();
1014
1015 while (row >= itemText.size()) {
1016 StringBuffer sb = new StringBuffer();
1017 for (int i = 0; i <= col; i++)
1018 sb.append(newChar);
1019 itemText.add(sb.toString());
1020 }
1021 StringBuffer sb = new StringBuffer(itemText.get(row));
1022 while (sb.length() <= col)
1023 sb.append(newChar);
1024 sb.setCharAt(col, newChar);
1025
1026 // set the modified string
1027 itemText.set(row, sb.toString());
1028 item.setTextList(itemText);
1029 }
1030 } else if (tokens[0].startsWith("assert")) {
1031 if (tokens[0].equals("asserttrue")) {
1032 assertExactParametreCount(tokens, 1);
1033 if (!context.getPrimitives().getBooleanValue(tokens[1]))
1034 throw new UnitTestFailedException("true", "false");
1035 } else if (tokens[0].equals("assertfalse")) {
1036 assertExactParametreCount(tokens, 1);
1037 if (context.getPrimitives().getBooleanValue(tokens[1]))
1038 throw new UnitTestFailedException("false", "true");
1039 } else if (tokens[0].equals("assertfail")) {
1040 assertExactParametreCount(tokens, 0);
1041 throw new UnitTestFailedException("pass", "fail");
1042 } else if (tokens[0].equals("assertnull")) {
1043 assertExactParametreCount(tokens, 1);
1044 Object value = context.getPrimitives().getVariable(tokens[1])
1045 .getValue();
1046 if (value != null)
1047 throw new UnitTestFailedException("null", value.toString());
1048 } else if (tokens[0].equals("assertnotnull")) {
1049 assertExactParametreCount(tokens, 1);
1050 Object value = context.getPrimitives().getVariable(tokens[1])
1051 .getValue();
1052 if (value == null)
1053 throw new UnitTestFailedException("not null", "null");
1054 } else if (tokens[0].equals("assertdefined")) {
1055 assertExactParametreCount(tokens, 1);
1056 if (!context.isDefined(tokens[1]))
1057 throw new UnitTestFailedException("defined", "not defined");
1058 } else if (tokens[0].equals("assertnotdefined")) {
1059 assertExactParametreCount(tokens, 1);
1060 if (context.isDefined(tokens[1]))
1061 throw new UnitTestFailedException("defined", "not defined");
1062 } else if (tokens[0].equals("assertequals")) {
1063 assertExactParametreCount(tokens, 2);
1064 if (!context.getPrimitives().equalValues(tokens[1], tokens[2]))
1065 throw new UnitTestFailedException(context.getPrimitives()
1066 .getStringValue(tokens[1]), context.getPrimitives()
1067 .getStringValue(tokens[2]));
1068 } else if (tokens[0].equals("assertdefined")) {
1069 assertExactParametreCount(tokens, 1);
1070 if (!context.isDefined(tokens[1])) {
1071 throw new UnitTestFailedException(tokens[1] + " exists",
1072 "not defined");
1073 }
1074 }
1075 } else if (tokens[0].startsWith("goto")) {
1076 String frameNameVar = DEFAULT_STRING;
1077 if (tokens.length > 1) {
1078 assertExactParametreCount(tokens, 1);
1079 frameNameVar = tokens[1];
1080 }
1081 String frameName = context.getPrimitives().getStringValue(
1082 frameNameVar);
1083 NavigationActions.Goto(frameName);
1084 } else if (tokens[0].startsWith("get")) {
1085 if (tokens[0].startsWith("getframe")) {
1086 if (tokens[0].equals("getframevalue")) {
1087 assertMinParametreCount(tokens, 3);
1088 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1089
1090 // Get the attribute to be searched for on the target frame
1091 Frame targetFrame = (Frame) context.getPointers()
1092 .getVariable(tokens[1]).getValue();
1093 String targetAttribute = context.getPrimitives()
1094 .getStringValue(tokens[2]).toLowerCase()
1095 + ":";
1096 Boolean found = false;
1097 String value = "";
1098 Text attributeItem = null;
1099 Item valueItem = null;
1100 // Begin the search
1101 for (Text text : targetFrame.getBodyTextItems(true)) {
1102 String s = text.getText().toLowerCase();
1103 if (s.startsWith(targetAttribute)) {
1104 attributeItem = text;
1105 value = AttributeUtils.getValue(s);
1106 if (value.length() > 0) {
1107 found = true;
1108 }
1109 break;
1110 }
1111 }
1112 // Keep looking for a matching value nearby if we found an
1113 // attribute without the value in the same item
1114 if (!found && attributeItem != null) {
1115 Point2D.Float endPoint = attributeItem
1116 .getEndParagraphPosition();
1117
1118 for (Text text : targetFrame.getBodyTextItems(true)) {
1119 Point startPoint = text.getPosition();
1120 if (Math.abs(startPoint.y - endPoint.y) < 10
1121 && Math.abs(startPoint.x - endPoint.x) < 20) {
1122 found = true;
1123 valueItem = text;
1124 value = text.getText();
1125 break;
1126 }
1127 }
1128 }
1129
1130 // Set the values of the output parametres
1131 context.getPrimitives().setValue(tokens[3],
1132 new SString(value));
1133 if (tokens.length > 4) {
1134 context.getPrimitives().setValue(tokens[4],
1135 new SBoolean(found));
1136 if (tokens.length > 5) {
1137 context.getPointers().setObject(tokens[5],
1138 attributeItem);
1139 if (tokens.length > 6) {
1140 context.getPointers().setObject(tokens[6],
1141 valueItem);
1142 }
1143 }
1144 }
1145 } else if (tokens[0].startsWith("getframename")) {
1146 String frameNameVar = DEFAULT_STRING;
1147 String frameVar = DEFAULT_FRAME;
1148
1149 if (tokens.length > 1) {
1150 assertExactParametreCount(tokens, 2);
1151 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1152 frameNameVar = tokens[2];
1153 frameVar = tokens[1];
1154 }
1155 Frame frame = (Frame) context.getPointers().getVariable(
1156 frameVar).getValue();
1157 context.getPrimitives().setValue(frameNameVar,
1158 frame.getName());
1159 } else if (tokens[0].startsWith("getframefilepath")) {
1160 assertExactParametreCount(tokens, 2);
1161 String frameName = context.getPrimitives().getStringValue(
1162 tokens[1]);
1163 String path = FrameIO.LoadFrame(frameName).path;
1164 String filePath = FrameIO.getFrameFullPathName(path,
1165 frameName);
1166 context.getPrimitives().setValue(tokens[2], filePath);
1167 } else if (tokens[0].equals("getframelog")) {
1168 assertExactParametreCount(tokens, 1);
1169 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1170
1171 String log = SessionStats.getFrameEventList();
1172 Text t;
1173
1174 t = (Text) context.getPointers().getVariable(tokens[1])
1175 .getValue();
1176 t.setText(log);
1177 } else if (tokens[0].equals("getframeitemcount")) {
1178 String frameVar = DEFAULT_FRAME;
1179 String countVar = DEFAULT_INTEGER;
1180 if (tokens.length > 1) {
1181 assertExactParametreCount(tokens, 2);
1182 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1183 frameVar = tokens[1];
1184 countVar = tokens[2];
1185 }
1186 Frame frame = (Frame) context.getPointers().getVariable(
1187 frameVar).getValue();
1188 Integer count = frame.getItems(true).size();
1189 context.getPrimitives().setValue(countVar,
1190 new SInteger(count));
1191 }
1192 } else if (tokens[0].equals("getassociation")) {
1193 assertMinParametreCount(tokens, 3);
1194 Map map = (Map) context.getPointers().getVariable(tokens[1])
1195 .getValue();
1196 String attribute = context.getPrimitives().getStringValue(
1197 tokens[2]);
1198 String newValue = map.get(attribute).toString();
1199 context.getPrimitives().setValue(tokens[3], newValue);
1200 } else if (tokens[0].startsWith("getcurrent")) {
1201 if (tokens[0].equals("getcurrentframe")) {
1202 assertMinParametreCount(tokens, 1);
1203 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1204
1205 Frame currentFrame = DisplayIO.getCurrentFrame();
1206 context.getPointers().setObject(tokens[1], currentFrame);
1207
1208 // check if the user is also after the frameName
1209 if (tokens.length > 2) {
1210 context.getPrimitives().setValue(tokens[2],
1211 new SString(currentFrame.getName()));
1212 }
1213 } else if (tokens[0].equals("getcurrentitem")) {
1214 assertMinParametreCount(tokens, 1);
1215 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1216
1217 Item currentItem = FrameUtils.getCurrentItem();
1218
1219 context.getPointers().setObject(tokens[1], currentItem);
1220
1221 // check if the user is also after line position
1222 if (currentItem != null && currentItem instanceof Text
1223 && tokens.length > 2) {
1224 Text text = (Text) currentItem;
1225 int cursorLinePos = text
1226 .getLinePosition(FrameMouseActions.getY());
1227 context.getPrimitives().setValue(tokens[2],
1228 new SInteger(cursorLinePos + 1));
1229 if (tokens.length > 3) {
1230 int cursorCharPos = text.getCharPosition(
1231 cursorLinePos, DisplayIO.getMouseX())
1232 .getCharIndex();
1233 context.getPrimitives().setValue(tokens[3],
1234 new SInteger(cursorCharPos + 1));
1235 }
1236 }
1237 }
1238 } else if (tokens[0].startsWith("getitem")) {
1239 if (tokens[0].equals("getitemposition")) {
1240 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1241 // assertPrimitiveType(tokens[2], 2);
1242 // assertPrimitiveType(tokens[3], 3);
1243 Point pos = ((Item) context.getPointers().getVariable(
1244 tokens[1]).getValue()).getPosition();
1245 Integer x = pos.x;
1246 Integer y = pos.y;
1247 context.getPrimitives()
1248 .setValue(tokens[2], new SInteger(x));
1249 context.getPrimitives()
1250 .setValue(tokens[3], new SInteger(y));
1251 } else if (tokens[0].equals("getitemthickness")) {
1252 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1253 // assertPrimitiveType(tokens[2], 2);
1254 Float thickness = ((Item) context.getPointers()
1255 .getVariable(tokens[1]).getValue()).getThickness();
1256 context.getPrimitives().setValue(tokens[2],
1257 new SReal(thickness));
1258 } else if (tokens[0].equals("getitemwidth")) {
1259 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1260 // assertPrimitiveType(tokens[2], 2);
1261 Integer width = ((Item) context.getPointers().getVariable(
1262 tokens[1]).getValue()).getWidth();
1263 context.getPrimitives().setValue(tokens[2],
1264 new SInteger(width));
1265 } else if (tokens[0].equals("getitemsize")) {
1266 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1267 // assertPrimitiveType(tokens[2], 2);
1268 Integer size = (int) ((Item) context.getPointers()
1269 .getVariable(tokens[1]).getValue()).getSize();
1270 context.getPrimitives().setValue(tokens[2],
1271 new SInteger(size));
1272 } else if (tokens[0].equals("getitemlink")) {
1273 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1274 // assertPrimitiveType(tokens[2], 2);
1275 String link = ((Item) context.getPointers().getVariable(
1276 tokens[1]).getValue()).getLink();
1277 context.getPrimitives().setValue(tokens[2],
1278 new SString(link));
1279 } else if (tokens[0].equals("getitemdata")) {
1280 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1281 Collection<String> dataList = ((Item) context.getPointers()
1282 .getVariable(tokens[1]).getValue()).getData();
1283 String data = "";
1284 if (dataList.size() > 0)
1285 data = dataList.iterator().next();
1286 context.getPrimitives().setValue(tokens[2],
1287 new SString(data));
1288 } else if (tokens[0].equals("getitemaction")) {
1289 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1290 Collection<String> dataList = ((Item) context.getPointers()
1291 .getVariable(tokens[1]).getValue()).getAction();
1292 String action = "";
1293 if (dataList.size() > 0)
1294 action = dataList.iterator().next();
1295 context.getPrimitives().setValue(tokens[2],
1296 new SString(action));
1297 } else if (tokens[0].equals("getitemfillcolor")) {
1298 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1299 // assertPrimitiveType(tokens[2], 2);
1300 Color itemColor = ((Item) context.getPointers()
1301 .getVariable(tokens[1]).getValue())
1302 .getPaintBackgroundColor();
1303 String color = itemColor.getRed() + " "
1304 + itemColor.getGreen() + " " + itemColor.getBlue();
1305 context.getPrimitives().setValue(tokens[2],
1306 new SString(color));
1307 } else if (tokens[0].equals("getitemcolor")) {
1308 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1309 // assertPrimitiveType(tokens[2], 2);
1310 Color itemColor = ((Item) context.getPointers()
1311 .getVariable(tokens[1]).getValue()).getPaintColor();
1312 String color = itemColor.getRed() + " "
1313 + itemColor.getGreen() + " " + itemColor.getBlue();
1314 context.getPrimitives().setValue(tokens[2],
1315 new SString(color));
1316 } else if (tokens[0].equals("getitemtext")) {
1317 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1318 Item item = ((Item) context.getPointers().getVariable(
1319 tokens[1]).getValue());
1320 context.getPrimitives().setValue(
1321 tokens[2],
1322 new SString((item instanceof Text) ? ((Text) item)
1323 .getText() : ""));
1324 } else
1325 throw new Exception("Unsupported getItem command: "
1326 + code.toString());
1327 } else if (tokens[0].equals("getstrchar")) {
1328 assertExactParametreCount(tokens, 3);
1329 String s = context.getPrimitives().getStringValue(tokens[1]);
1330 int pos = (int) context.getPrimitives().getIntegerValue(
1331 tokens[2]);
1332
1333 context.getPrimitives().setValue(tokens[3],
1334 new SCharacter(s.charAt(pos - 1)));
1335 } else if (tokens[0].equals("getstrlength")) {
1336 assertExactParametreCount(tokens, 2);
1337 String s = context.getPrimitives().getStringValue(tokens[1]);
1338
1339 context.getPrimitives().setValue(tokens[2],
1340 new SInteger(s.length()));
1341 } else if (tokens[0].equals("getelapsedtime")) {
1342 assertExactParametreCount(tokens, 1);
1343 context.getPrimitives().setValue(tokens[1],
1344 new SInteger(AgentStats.getMilliSecondsElapsed()));
1345 } else if (tokens[0].equals("getlastnumberinframeset")) {
1346 String framesetNameVar = DEFAULT_STRING;
1347 String countVar = DEFAULT_INTEGER;
1348 if (tokens.length > 1) {
1349 assertMinParametreCount(tokens, 2);
1350 framesetNameVar = tokens[1];
1351 countVar = tokens[2];
1352 }
1353 String frameset = context.getPrimitives().getStringValue(
1354 framesetNameVar);
1355 long count = FrameIO.getLastNumber(frameset);
1356 context.getPrimitives().setValue(countVar, new SInteger(count));
1357 } else if (tokens[0].equals("getlistofframesets")) {
1358 String stringVar = DEFAULT_ITEM;
1359 if (tokens.length > 1) {
1360 assertMinParametreCount(tokens, 1);
1361 stringVar = tokens[1];
1362 }
1363 context.getPrimitives().setValue(stringVar,
1364 FrameIO.getFramesetList());
1365 } else if (tokens[0].equals("getsessionstats")) {
1366 assertExactParametreCount(tokens, 1);
1367 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1368
1369 String stats = SessionStats.getCurrentStats();
1370 Text t = (Text) context.getPointers().getVariable(tokens[1])
1371 .getValue();
1372 t.setText(stats);
1373 } else if (tokens[0].equals("getrandominteger")) {
1374 assertExactParametreCount(tokens, 3);
1375 int lowerBound = (int) context.getPrimitives().getIntegerValue(
1376 tokens[1]);
1377 int upperBound = (int) context.getPrimitives().getIntegerValue(
1378 tokens[2]);
1379 Random random = new Random();
1380 long result = Math.abs(random.nextInt())
1381 % (upperBound - lowerBound) + lowerBound;
1382 context.getPrimitives().setValue(tokens[3],
1383 new SInteger(result));
1384 } else if (tokens[0].equals("getrandomreal")) {
1385 assertExactParametreCount(tokens, 3);
1386 double lowerBound = context.getPrimitives().getDoubleValue(
1387 tokens[1]);
1388 double upperBound = context.getPrimitives().getDoubleValue(
1389 tokens[2]);
1390 Random random = new Random();
1391 double result = random.nextDouble() * (upperBound - lowerBound)
1392 + lowerBound;
1393 context.getPrimitives().setValue(tokens[3], new SReal(result));
1394 } else if (tokens[0].equals("getrandomtextitem")) {
1395 assertExactParametreCount(tokens, 2);
1396 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1397 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1398 List<Text> items = ((Frame) context.getPointers().getVariable(
1399 tokens[1]).getValue()).getBodyTextItems(false);
1400 Random random = new Random();
1401 int itemIndex = random.nextInt(items.size());
1402 context.getPointers()
1403 .setObject(tokens[2], items.get(itemIndex));
1404 }
1405 } else if (tokens[0].equals("or")) {
1406 for (int i = 1; i < tokens.length - 1; i++) {
1407 if (Primitives.isPrimitive(tokens[i])) {
1408 if (context.getPrimitives().getBooleanValue(tokens[i])) {
1409 context.getPrimitives().setValue(
1410 tokens[tokens.length - 1], new SBoolean(true));
1411 return Status.OK;
1412 }
1413 }
1414 }
1415 context.getPrimitives().setValue(tokens[tokens.length - 1],
1416 new SBoolean(false));
1417 } else if (tokens[0].equals("and")) {
1418 for (int i = 1; i < tokens.length - 1; i++) {
1419 if (Primitives.isPrimitive(tokens[i])) {
1420 if (!context.getPrimitives().getBooleanValue(tokens[i])) {
1421 context.getPrimitives().setValue(
1422 tokens[tokens.length - 1], new SBoolean(false));
1423 return Status.OK;
1424 }
1425 }
1426 }
1427 context.getPrimitives().setValue(tokens[tokens.length - 1],
1428 new SBoolean(true));
1429 } else if (tokens[0].equals("messagelnitem")
1430 || tokens[0].equals("messagelineitem")) {
1431 String itemVar = DEFAULT_ITEM;
1432
1433 if (tokens.length > 1) {
1434 assertExactParametreCount(tokens, 1);
1435 itemVar = tokens[1];
1436 assertVariableType(itemVar, 1, SPointer.itemPrefix);
1437 }
1438 Item message = (Item) context.getPointers().getVariable(itemVar)
1439 .getValue();
1440 try {
1441 MessageBay.displayMessage(((Text) message).copy());
1442 } catch (NullPointerException e) {
1443 MessageBay.displayMessage("null");
1444 } catch (ClassCastException e) {
1445 // Just ignore not text items!
1446 MessageBay.displayMessage(message.toString());
1447 } catch (Exception e) {
1448 // Just ignore other errors
1449 }
1450 } else if (tokens[0].equals("messageln")
1451 || tokens[0].equals("messageline")
1452 || tokens[0].equals("messagelnnospaces")
1453 || tokens[0].equals("messagelinenospaces")
1454 || tokens[0].equals("errorln") || tokens[0].equals("errorline")) {
1455 String message = getMessage(tokens, context, code.toString(),
1456 tokens[0].endsWith("nospaces") ? "" : " ", 1);
1457
1458 if (tokens[0].equals("errorln") || tokens[0].equals("errorline"))
1459 MessageBay.errorMessage(message);
1460 else
1461 MessageBay.displayMessageAlways(message);
1462 } else if (tokens[0].equals("typeatrate")) {
1463 assertMinParametreCount(tokens, 1);
1464 double delay = context.getPrimitives().getDoubleValue(tokens[1]);
1465 String s = getMessage(tokens, context, code.toString(), " ", 2);
1466 for (int i = 0; i < s.length(); i++) {
1467 FrameKeyboardActions.processChar(s.charAt(i), false);
1468 Thread.sleep((int) (delay * 1000));
1469 }
1470 } else if (tokens[0].equals("type") || tokens[0].equals("typenospaces")) {
1471
1472 String s = getMessage(tokens, context, code.toString(), tokens[0]
1473 .equals("type") ? " " : "", 1);
1474 for (int i = 0; i < s.length(); i++) {
1475 FrameKeyboardActions.processChar(s.charAt(i), false);
1476 Thread.sleep(25);
1477 }
1478 } else if (tokens[0].equals("runstring")) {
1479 String codeText = getMessage(tokens, context, code.toString(), " ",
1480 1);
1481 Text dynamicCode = new Text(codeText);
1482 RunItem(dynamicCode, context, Status.OK);
1483 } else if (tokens[0].equals("runoscommand")) {
1484 String command = getMessage(tokens, context, code.toString(), " ",
1485 1);
1486 Runtime.getRuntime().exec(command);
1487 } else if (tokens[0].equals("executeoscommand")) {
1488 String command = getMessage(tokens, context, code.toString(), " ",
1489 1);
1490 try {
1491 Process p = Runtime.getRuntime().exec(command);
1492 MessageBay.displayMessage(command, Color.darkGray);
1493
1494 BufferedReader stdInput = new BufferedReader(
1495 new InputStreamReader(p.getInputStream()));
1496 BufferedReader stdError = new BufferedReader(
1497 new InputStreamReader(p.getErrorStream()));
1498 String message = "";
1499 while ((message = stdInput.readLine()) != null) {
1500 MessageBay.displayMessage(message);
1501 }
1502 while ((message = stdError.readLine()) != null) {
1503 MessageBay.errorMessage(message);
1504 }
1505 } catch (Exception e) {
1506 throw new RuntimeException(e.getMessage());
1507 }
1508 } else if (tokens[0].startsWith("else")) {
1509 // if the if statement was false then run the else statement
1510 if (lastItemStatus == Status.FalseIf) {
1511 // check if it is a one line if statment
1512 if (tokens.length > 1) {
1513 // put together the one line statement
1514 StringBuilder statement = new StringBuilder();
1515 for (int i = 1; i < tokens.length; i++)
1516 statement.append(tokens[i]).append(' ');
1517 // create a copy of the code item to run
1518 Text copiedCode = code.copy();
1519 copiedCode.setText(statement.toString());
1520 return RunItem(copiedCode, context, Status.OK);
1521 } else {
1522 return RunFrameAndReportError(code, context);
1523 }
1524 } else if (lastItemStatus == Status.TrueIf) {
1525 return Status.OK;
1526 }
1527 throw new RuntimeException("Else without matching If statement");
1528 } else if (tokens[0].startsWith("if")) {
1529 Boolean result = null;
1530 int parametres = 1;
1531 String variable = DEFAULT_ITEM;
1532 String ifStatement = tokens[0];
1533 // Set the default variable
1534 if (tokens.length == 1) {
1535 if (ifStatement.equals("if") || ifStatement.equals("ifnot"))
1536 variable = DEFAULT_STRING;
1537 else if (ifStatement.equals("ifzero")
1538 || ifStatement.equals("ifnotzero"))
1539 variable = DEFAULT_INTEGER;
1540 } else {
1541 variable = tokens[1];
1542 }
1543
1544 if (ifStatement.equals("if")) {
1545 result = context.getPrimitives().getBooleanValue(variable);
1546 } else if (ifStatement.equals("ifnot")) {
1547 result = !context.getPrimitives().getBooleanValue(variable);
1548 } else if (ifStatement.equals("ifdefined")) {
1549 result = context.isDefined(tokens[1]);
1550 } else if (ifStatement.equals("ifnotdef")) {
1551 result = !context.isDefined(tokens[1]);
1552 } else if (ifStatement.equals("ifzero")) {
1553 result = context.getPrimitives().getIntegerValue(variable) == 0;
1554 } else if (ifStatement.equals("ifnotzero")) {
1555 result = context.getPrimitives().getIntegerValue(variable) != 0;
1556 } else if (tokens[0].equals("ifeq")) {
1557 result = context.equalValues(tokens[1], tokens[2]);
1558 parametres = 2;
1559 } else if (tokens[0].equals("ifeqnocase")) {
1560 result = context.getPrimitives().equalValuesNoCase(tokens[1],
1561 tokens[2]);
1562 parametres = 2;
1563 } else if (tokens[0].equals("ifnoteqnocase")) {
1564 result = !context.getPrimitives().equalValuesNoCase(tokens[1],
1565 tokens[2]);
1566 parametres = 2;
1567 } else if (tokens[0].equals("ifnoteq")) {
1568 result = !context.equalValues(tokens[1], tokens[2]);
1569 parametres = 2;
1570 } else if (tokens[0].equals("ifless")) {
1571 result = context.getPrimitives().compareValues(tokens[1],
1572 tokens[2]) < 0;
1573 parametres = 2;
1574 } else if (tokens[0].equals("ifgtr")) {
1575 result = context.getPrimitives().compareValues(tokens[1],
1576 tokens[2]) > 0;
1577 parametres = 2;
1578 } else if (tokens[0].equals("ifgeq")) {
1579 result = context.getPrimitives().compareValues(tokens[1],
1580 tokens[2]) >= 0;
1581 parametres = 2;
1582 } else if (tokens[0].equals("ifleq")) {
1583 result = context.getPrimitives().compareValues(tokens[1],
1584 tokens[2]) <= 0;
1585 parametres = 2;
1586 } else if (tokens[0].equals("ifexistingframe")) {
1587 result = FrameIO.canAccessFrame(context.getPrimitives()
1588 .getStringValue(tokens[1]));
1589 } else if (tokens[0].equals("ifexistingframeset")) {
1590 String framesetName = context.getPrimitives().getStringValue(
1591 tokens[1]);
1592 result = FrameIO.canAccessFrameset(framesetName);
1593 } else {
1594 // assertVariableType(variable, 1, SPointer.itemPrefix);
1595 if (ifStatement.equals("ifannotation")) {
1596 result = ((Item) context.getPointers()
1597 .getVariable(variable).getValue()).isAnnotation();
1598 } else if (ifStatement.equals("iflinked")) {
1599 result = ((Item) context.getPointers()
1600 .getVariable(variable).getValue()).getLink() != null;
1601 } else if (ifStatement.equals("ifactioned")) {
1602 result = ((Item) context.getPointers()
1603 .getVariable(variable).getValue()).getAction() != null;
1604 } else if (ifStatement.equals("ifnotactioned")) {
1605 result = ((Item) context.getPointers()
1606 .getVariable(variable).getValue()).getAction() == null;
1607 } else if (ifStatement.equals("ifbodytext")) {
1608 Item i = (Item) context.getPointers().getVariable(variable)
1609 .getValue();
1610 result = i instanceof Text && !i.isFrameName()
1611 && !i.isFrameTitle();
1612 } else if (ifStatement.equals("ifnotannotation")) {
1613 result = !((Item) context.getPointers().getVariable(
1614 variable).getValue()).isAnnotation();
1615 } else if (ifStatement.equals("ifnotlinked")) {
1616 result = ((Item) context.getPointers()
1617 .getVariable(variable).getValue()).getLink() == null;
1618 } else if (ifStatement.equals("ifnotbodytext")) {
1619 Item i = (Item) context.getPointers().getVariable(variable)
1620 .getValue();
1621 result = !(i instanceof Text) || i.isFrameName()
1622 || i.isFrameTitle();
1623 }
1624 }
1625
1626 if (result == null)
1627 throw new RuntimeException("Invalid If statement");
1628 // Now check if we need to run the code
1629 else if (result) {
1630 Status status;
1631 // check if it is a one line if statment
1632 if (tokens.length > parametres + 1) {
1633 // put together the one line statement
1634 StringBuilder statement = new StringBuilder();
1635 for (int i = parametres + 1; i < tokens.length; i++)
1636 statement.append(tokens[i]).append(' ');
1637 // create a copy of the code item to run
1638 Text copiedCode = code.copy();
1639 copiedCode.setText(statement.toString());
1640 status = RunItem(copiedCode, context, Status.OK);
1641 } else {
1642 status = RunFrameAndReportError(code, context);
1643 }
1644 if (status == Status.OK) {
1645 return Status.TrueIf;
1646 } else {
1647 return status;
1648 }
1649 }
1650 return Status.FalseIf;
1651 } // Look for variable length methods
1652 else if (tokens[0].equals("attachitemtocursor")) {
1653 String itemVar = DEFAULT_ITEM;
1654
1655 if (tokens.length > 1) {
1656 assertExactParametreCount(tokens, 1);
1657 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1658 itemVar = tokens[1];
1659 }
1660 Item item = (Item) context.getPointers().getVariable(itemVar)
1661 .getValue();
1662 item
1663 .setPosition(FrameMouseActions.MouseX,
1664 FrameMouseActions.MouseY);
1665 FrameMouseActions.pickup(item);
1666 } else if (tokens[0].equals("attachstrtocursor")) {
1667 String stringVar = DEFAULT_STRING;
1668
1669 if (tokens.length > 1) {
1670 assertExactParametreCount(tokens, 1);
1671 stringVar = tokens[1];
1672 }
1673 String s = context.getPrimitives().getStringValue(stringVar);
1674 Frame frame = DisplayIO.getCurrentFrame();
1675 Item item = frame.createNewText(s);
1676 item
1677 .setPosition(FrameMouseActions.MouseX,
1678 FrameMouseActions.MouseY);
1679 FrameMouseActions.pickup(item);
1680 } else if (tokens[0].equals("additemtoframe")) {
1681 String itemVar = DEFAULT_ITEM;
1682 String frameVar = DEFAULT_FRAME;
1683
1684 if (tokens.length > 1) {
1685 assertExactParametreCount(tokens, 2);
1686 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1687 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1688 itemVar = tokens[2];
1689 frameVar = tokens[1];
1690 }
1691 Frame frame = (Frame) context.getPointers().getVariable(frameVar)
1692 .getValue();
1693 Item item = (Item) context.getPointers().getVariable(itemVar)
1694 .getValue();
1695 frame.addItem(item);
1696 } else if (tokens[0].equals("connectdots")) {
1697 assertMinParametreCount(tokens, 2);
1698 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1699 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1700 Item dot1 = null;
1701 Item dot2 = null;
1702 try {
1703 dot1 = (Item) context.getPointers().getVariable(tokens[1])
1704 .getValue();
1705 } catch (Exception e) {
1706 throw new IncorrectTypeException("Dot", 1);
1707 }
1708 try {
1709 dot2 = (Item) context.getPointers().getVariable(tokens[2])
1710 .getValue();
1711 } catch (Exception e) {
1712 throw new IncorrectTypeException("Dot", 2);
1713 }
1714 Frame frame = dot1.getParent();
1715 frame.addItem(new Line(dot1, dot2, frame.getNextItemID()));
1716 } else if (tokens[0].equals("createitem")
1717 || tokens[0].equals("createtext")) {
1718 assertMinParametreCount(tokens, 4);
1719 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1720 assertVariableType(tokens[4], 4, SPointer.itemPrefix);
1721 Frame frame = (Frame) context.getPointers().getVariable(tokens[1])
1722 .getValue();
1723 Item newItem;
1724 int x = (int) context.getPrimitives().getIntegerValue(tokens[2]);
1725 int y = (int) context.getPrimitives().getIntegerValue(tokens[3]);
1726 // check for the option text and action for the new item
1727 if (tokens.length > 5) {
1728 String newText = context.getPrimitives().getStringValue(
1729 tokens[5]);
1730 String newAction = null;
1731 if (tokens.length > 6) {
1732 newAction = context.getPrimitives().getStringValue(
1733 tokens[6]);
1734 }
1735 newItem = frame.addText(x, y, newText, newAction);
1736 } else {
1737 if (tokens[0].equals("createtext")) {
1738 newItem = frame.createNewText();
1739 newItem.setPosition(x, y);
1740 } else {
1741 // create a point if the optional params are not provided
1742 newItem = frame.addDot(x, y);
1743 }
1744 }
1745 context.getPointers().setObject(tokens[4], newItem);
1746 } else if (tokens[0].equals("deleteitem")) {
1747 assertMinParametreCount(tokens, 1);
1748 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1749 Item item = (Item) context.getPointers().getVariable(tokens[1])
1750 .getValue();
1751 item.delete();
1752 } else if (tokens[0].equals("deleteframe")) {
1753 assertMinParametreCount(tokens, 1);
1754 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1755 Frame frame = (Frame) context.getPointers().getVariable(tokens[1])
1756 .getValue();
1757 String errorMessage = "Error deleting " + frame.getName();
1758 boolean success = false;
1759 try {
1760 success = FrameIO.DeleteFrame(frame);
1761 if (!success && _verbose)
1762 MessageBay.warningMessage(errorMessage);
1763 } catch (Exception e) {
1764 // If an exception is thrown then success is false
1765 if (_verbose) {
1766 MessageBay.warningMessage(errorMessage
1767 + (e.getMessage() != null ? ". " + e.getMessage()
1768 : ""));
1769 }
1770 }
1771 if (tokens.length > 2) {
1772 context.getPrimitives().setValue(tokens[2],
1773 new SBoolean(success));
1774 }
1775 } else if (tokens[0].equals("deleteframeset")) {
1776 assertMinParametreCount(tokens, 1);
1777 String framesetName = context.getPrimitives().getStringValue(
1778 tokens[1]);
1779 boolean success = FrameIO.DeleteFrameset(framesetName);
1780 if (!success && _verbose) {
1781 MessageBay.warningMessage("Error deleting " + framesetName);
1782 }
1783 if (tokens.length > 2) {
1784 context.getPrimitives().setValue(tokens[2],
1785 new SBoolean(success));
1786 }
1787 } else if (tokens[0].equals("copyitem")) {
1788 assertMinParametreCount(tokens, 2);
1789 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1790 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1791 Item item = (Item) context.getPointers().getVariable(tokens[1])
1792 .getValue();
1793 Item copy = item.copy();
1794 context.getPointers().setObject(tokens[2], copy);
1795 } else if (tokens[0].equals("copyframeset")) {
1796 assertMinParametreCount(tokens, 2);
1797 String framesetToCopy = context.getPrimitives().getStringValue(
1798 tokens[1]);
1799 String copiedFrameset = context.getPrimitives().getStringValue(
1800 tokens[2]);
1801 boolean success = FrameIO.CopyFrameset(framesetToCopy,
1802 copiedFrameset);
1803 if (!success && _verbose)
1804 MessageBay.warningMessage("Error copying " + framesetToCopy);
1805 if (tokens.length > 3) {
1806 context.getPrimitives().setValue(tokens[3],
1807 new SBoolean(success));
1808 }
1809 } else if (tokens[0].equals("copyframe")) {
1810 assertMinParametreCount(tokens, 2);
1811 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1812 assertVariableType(tokens[2], 2, SPointer.framePrefix);
1813 Frame frameToCopy = (Frame) context.getPointers().getVariable(
1814 tokens[1]).getValue();
1815 FrameIO.SuspendCache();
1816 Frame freshCopy = FrameIO.LoadFrame(frameToCopy.getName());
1817 // Change the frameset if one was provided
1818 if (tokens.length > 3) {
1819 String destinationFrameset = context.getPrimitives()
1820 .getStringValue(tokens[3]);
1821 freshCopy.setFrameset(destinationFrameset);
1822 }// Otherwise add it to the end of this frameset
1823 freshCopy.setFrameNumber(FrameIO.getLastNumber(freshCopy
1824 .getFramesetName()) + 1);
1825 context.getPointers().setObject(tokens[2], freshCopy);
1826 String fileContents = FrameIO.ForceSaveFrame(freshCopy);
1827 FrameIO.ResumeCache();
1828 // Need to add the new copy to the cache in case it is edited by
1829 // other simple statements
1830 FrameIO.addToCache(freshCopy);
1831 boolean success = fileContents != null;
1832 if (!success && _verbose)
1833 MessageBay.warningMessage("Error copying "
1834 + frameToCopy.getName());
1835 if (tokens.length > 4) {
1836 context.getPrimitives().setValue(tokens[4],
1837 new SBoolean(success));
1838 }
1839 } else if (tokens[0].equals("createframe")) {
1840
1841 String framesetName = DEFAULT_STRING;
1842 String frameVar = DEFAULT_FRAME;
1843
1844 if (tokens.length > 1) {
1845 assertMinParametreCount(tokens, 2);
1846 assertVariableType(tokens[2], 2, SPointer.framePrefix);
1847 framesetName = tokens[1];
1848 frameVar = tokens[2];
1849 }
1850
1851 if (tokens.length > 3) {
1852 context.createFrame(framesetName, frameVar, tokens[3]);
1853 } else
1854 context.createFrame(framesetName, frameVar, null);
1855 } else if (tokens[0].equals("closeframe")) {
1856 String frameVar = DEFAULT_FRAME;
1857
1858 if (tokens.length > 1) {
1859 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1860 frameVar = tokens[1];
1861 }
1862
1863 if (tokens.length > 2) {
1864 // assertPrimitiveType(tokens[3], 3);
1865 context.closeFrame(frameVar, tokens[3]);
1866 } else
1867 context.closeFrame(frameVar, null);
1868 } else if (tokens[0].equals("readframe")
1869 || tokens[0].equals("openframe")) {
1870
1871 String frameName = DEFAULT_STRING;
1872 String frameVar = DEFAULT_FRAME;
1873
1874 if (tokens.length > 1) {
1875 assertMinParametreCount(tokens, 2);
1876 assertVariableType(tokens[2], 2, SPointer.framePrefix);
1877 frameName = tokens[1];
1878 frameVar = tokens[2];
1879 // assertPrimitiveType(frameName, 1);
1880 }
1881
1882 if (tokens.length > 3) {
1883 // assertPrimitiveType(tokens[3], 3);
1884 context.readFrame(frameName, frameVar, tokens[3]);
1885 } else
1886 context.readFrame(frameName, frameVar, null);
1887 } else if (tokens[0].equals("readkbdcond")) {
1888
1889 String nextCharVarName = DEFAULT_CHAR;
1890 String wasCharVarName = DEFAULT_BOOLEAN;
1891
1892 if (tokens.length > 1) {
1893 assertMinParametreCount(tokens, 2);
1894 assertVariableType(tokens[2], 2, SPointer.framePrefix);
1895 nextCharVarName = tokens[1];
1896 wasCharVarName = tokens[2];
1897 }
1898
1899 Character nextChar = _KeyStrokes.poll();
1900 boolean hasChar = nextChar != null;
1901 context.getPrimitives().setValue(wasCharVarName,
1902 new SBoolean(hasChar));
1903 if (hasChar)
1904 context.getPrimitives().setValue(nextCharVarName,
1905 new SCharacter(nextChar));
1906 } else if (tokens[0].equals("createassociation")) {
1907
1908 String associationVar = DEFAULT_ASSOCIATION;
1909
1910 if (tokens.length > 0) {
1911 assertVariableType(tokens[1], 2, SPointer.associationPrefix);
1912 associationVar = tokens[1];
1913 }
1914 Map<String, String> newMap = new HashMap<String, String>();
1915 context.getPointers().setObject(associationVar, newMap);
1916 } else if (tokens[0].equals("deleteassociation")) {
1917
1918 String associationVar = DEFAULT_ASSOCIATION;
1919
1920 if (tokens.length > 0) {
1921 assertVariableType(tokens[1], 2, SPointer.associationPrefix);
1922 associationVar = tokens[1];
1923 }
1924 context.getPointers().delete(associationVar);
1925 } else if (tokens[0].equals("openreadfile")) {
1926 assertVariableType(tokens[1], 1, SString.prefix);
1927 assertVariableType(tokens[2], 2, SPointer.filePrefix);
1928
1929 if (tokens.length > 3) {
1930 assertVariableType(tokens[3], 3, SBoolean.prefix);
1931 context.openReadFile(tokens[1], tokens[2], tokens[3]);
1932 } else
1933 context.openReadFile(tokens[1], tokens[2]);
1934 } else if (tokens[0].equals("readlinefile")
1935 || tokens[0].equals("readlnfile")) {
1936 assertVariableType(tokens[1], 1, SPointer.filePrefix);
1937
1938 if (tokens.length > 3) {
1939 assertVariableType(tokens[3], 3, SBoolean.prefix);
1940 context.readLineFile(tokens[1], tokens[2], tokens[3]);
1941 } else
1942 context.readLineFile(tokens[1], tokens[2]);
1943 } else if (tokens[0].equals("readitemfile")) {
1944 assertVariableType(tokens[1], 1, SPointer.filePrefix);
1945 assertVariableType(tokens[2], 1, SPointer.itemPrefix);
1946
1947 if (tokens.length > 3) {
1948 assertVariableType(tokens[3], 3, SBoolean.prefix);
1949 context.readItemFile(tokens[1], tokens[2], tokens[3]);
1950 } else
1951 context.readItemFile(tokens[1], tokens[2]);
1952 } else if (tokens[0].equals("openwritefile")) {
1953 assertVariableType(tokens[1], 1, SString.prefix);
1954 assertVariableType(tokens[2], 2, SPointer.filePrefix);
1955
1956 if (tokens.length > 3) {
1957 assertVariableType(tokens[3], 3, SBoolean.prefix);
1958 context.openWriteFile(tokens[1], tokens[2], tokens[3]);
1959 } else
1960 context.openWriteFile(tokens[1], tokens[2]);
1961 } else if (tokens[0].equals("writefile")
1962 || tokens[0].equals("writelinefile")
1963 || tokens[0].equals("writelnfile")) {
1964 assertVariableType(tokens[1], 1, SPointer.filePrefix);
1965
1966 StringBuffer textToWrite = new StringBuffer();
1967 if (tokens.length == 1) {
1968 textToWrite.append(context.getPrimitives().getVariable(
1969 DEFAULT_STRING).stringValue()
1970 + " ");
1971 } else {
1972 for (int i = 2; i < tokens.length; i++) {
1973 if (Primitives.isPrimitive(tokens[i])) {
1974 textToWrite.append(context.getPrimitives().getVariable(
1975 tokens[i]).stringValue());
1976 } else
1977 throw new Exception("Illegal parametre: " + tokens[i]
1978 + " in " + code.toString());
1979 }
1980 }
1981
1982 if (!tokens[0].equals("writefile"))
1983 textToWrite.append(Text.LINE_SEPARATOR);
1984 context.writeFile(tokens[1], textToWrite.toString());
1985 } else if (tokens[0].equals("displayframeset")) {
1986 assertMinParametreCount(tokens, 1);
1987 String framesetName = context.getPrimitives().getStringValue(
1988 tokens[1]);
1989 int lastFrameNo = FrameIO.getLastNumber(framesetName);
1990 int firstFrameNo = 0;
1991 double pause = 0.0;
1992 // get the first and last frames to display if they were proided
1993 if (tokens.length > 2) {
1994 firstFrameNo = (int) context.getPrimitives().getIntegerValue(
1995 tokens[2]);
1996 if (tokens.length > 3) {
1997 lastFrameNo = (int) context.getPrimitives()
1998 .getIntegerValue(tokens[3]);
1999 if (tokens.length > 4) {
2000 pause = context.getPrimitives().getDoubleValue(
2001 tokens[4]);
2002 }
2003 }
2004 }
2005 Runtime runtime = Runtime.getRuntime();
2006 // Display the frames
2007 for (int i = firstFrameNo; i <= lastFrameNo; i++) {
2008 Frame frame = FrameIO.LoadFrame(framesetName + i);
2009 if (frame != null) {
2010 double thisFramesPause = pause;
2011 // check for change in delay for this frame only
2012 Item pauseItem = ItemUtils.FindTag(frame.getItems(),
2013 "@DisplayFramePause:");
2014 if (pauseItem != null) {
2015 try {
2016 // attempt to read in the delay value
2017 thisFramesPause = Double.parseDouble(ItemUtils
2018 .StripTag(
2019 ((Text) pauseItem).getFirstLine(),
2020 "@DisplayFramePause"));
2021 } catch (NumberFormatException nfe) {
2022 }
2023 }
2024 DisplayIO.setCurrentFrame(frame);
2025 pause(thisFramesPause);
2026
2027 long freeMemory = runtime.freeMemory();
2028 if (freeMemory < DisplayTree.GARBAGE_COLLECTION_THRESHOLD) {
2029 runtime.gc();
2030 MessageBay
2031 .displayMessage("Force Garbage Collection!");
2032 }
2033 }
2034 }
2035 } else if (tokens[0].equals("createframeset")) {
2036 String framesetName = DEFAULT_STRING;
2037 String successVar = null;
2038 if (tokens.length > 1) {
2039 framesetName = tokens[1];
2040 if (tokens.length > 2)
2041 successVar = tokens[2];
2042 }
2043 context.createFrameset(framesetName, successVar);
2044 } else if (tokens[0].equals("writetree")) {
2045 assertMinParametreCount(tokens, 3);
2046 assertVariableType(tokens[1], 1, SPointer.framePrefix);
2047 Frame source = (Frame) context.getPointers().getVariable(tokens[1])
2048 .getValue();
2049 String format = context.getPrimitives().getStringValue(tokens[2]);
2050 String fileName = context.getPrimitives().getStringValue(tokens[3]);
2051 WriteTree wt = new WriteTree(format, fileName);
2052 if (wt.initialise(source)) {
2053 wt.setStartFrame(source);
2054 wt.run();
2055 }
2056 } else if (tokens[0].equals("concatstr")) {
2057 assertMinParametreCount(tokens, 3);
2058 String resultVar = tokens[tokens.length - 1];
2059
2060 StringBuilder sb = new StringBuilder();
2061 // loop through all the strings concatenating them
2062 for (int i = 1; i < tokens.length - 1; i++) {
2063 // assertPrimitiveType(tokens[i], i);
2064 sb.append(context.getPrimitives().getStringValue(tokens[i]));
2065 }
2066 context.getPrimitives().setValue(resultVar,
2067 new SString(sb.toString()));
2068 } else if (tokens[0].equals("convstrlower")) {
2069 assertExactParametreCount(tokens, 1);
2070 // assertPrimitiveType(tokens[1], 1);
2071 context.getPrimitives().setValue(
2072 tokens[1],
2073 new SString(context.getPrimitives().getStringValue(
2074 tokens[1]).toLowerCase()));
2075 } else if (tokens[0].equals("convstrupper")) {
2076 assertExactParametreCount(tokens, 1);
2077 // assertPrimitiveType(tokens[1], 1);
2078 context.getPrimitives().setValue(
2079 tokens[1],
2080 new SString(context.getPrimitives().getStringValue(
2081 tokens[1]).toUpperCase()));
2082 } else if (tokens[0].equals("countcharsinstr")) {
2083 assertExactParametreCount(tokens, 3);
2084 String s = context.getPrimitives().getStringValue(tokens[1]);
2085 String pattern = context.getPrimitives().getStringValue(tokens[2]);
2086 int count = countCharsInString(s, pattern);
2087 context.getPrimitives().setValue(tokens[3], new SInteger(count));
2088 } else if (tokens[0].equals("countcharsinitem")) {
2089 assertExactParametreCount(tokens, 3);
2090 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
2091 Item item = (Item) context.getPointers().getVariable(tokens[1])
2092 .getValue();
2093 String pattern = context.getPrimitives().getStringValue(tokens[2]);
2094 int count = 0;
2095 if (item instanceof Text)
2096 count = countCharsInString(((Text) item).getText(), pattern);
2097 context.getPrimitives().setValue(tokens[3], new SInteger(count));
2098 } else if (tokens[0].equals("clearframe")) {
2099 String frameVar = DEFAULT_FRAME;
2100 if (tokens.length > 1) {
2101 assertMinParametreCount(tokens, 1);
2102 assertVariableType(tokens[1], 1, SPointer.framePrefix);
2103 frameVar = tokens[1];
2104 }
2105 boolean success = true;
2106 try {
2107 Frame frameToClear = (Frame) context.getPointers().getVariable(
2108 frameVar).getValue();
2109 frameToClear.clear(false);
2110 assert (frameToClear.getItems().size() <= 1);
2111 } catch (Exception e) {
2112 success = false;
2113 }
2114 if (tokens.length > 2) {
2115 assertExactParametreCount(tokens, 2);
2116 context.getPrimitives().setValue(tokens[2],
2117 new SBoolean(success));
2118 }
2119 } else if (tokens[0].equals("parseframename")) {
2120 assertExactParametreCount(tokens, 4);
2121 String frameName = context.getPrimitives()
2122 .getStringValue(tokens[1]);
2123 String frameSet = "";
2124 int frameNo = -1;
2125 boolean success = true;
2126 try {
2127 frameSet = Conversion.getFramesetName(frameName, false);
2128 frameNo = Conversion.getFrameNumber(frameName);
2129 } catch (Exception e) {
2130 success = false;
2131 if (_verbose)
2132 MessageBay.warningMessage("Error parsing " + frameName);
2133 }
2134 // assertPrimitiveType(tokens[2], 2);
2135 context.getPrimitives().setValue(tokens[2], new SBoolean(success));
2136
2137 // assertPrimitiveType(tokens[3], 3);
2138 context.getPrimitives().setValue(tokens[3], new SString(frameSet));
2139
2140 // assertPrimitiveType(tokens[4], 4);
2141 context.getPrimitives().setValue(tokens[4], new SInteger(frameNo));
2142 } else if (tokens[0].equals("parsestr")) {
2143 assertMinParametreCount(tokens, 2);
2144 // assertPrimitiveType(tokens[1], 1);
2145 // assertPrimitiveType(tokens[2], 2);
2146
2147 String s = context.getPrimitives().getStringValue(tokens[1]);
2148
2149 String separator = context.getPrimitives()
2150 .getStringValue(tokens[2]);
2151
2152 String[] split = s.split(separator, tokens.length - 4);
2153
2154 if (tokens.length > 3) {
2155 // assertPrimitiveType(tokens[3], 3);
2156 int count = split.length;
2157 // if the string is not blank and its got a remainder then
2158 // decrease the count by 1 to account for the remainder
2159 if (split.length != 0 && split.length > tokens.length - 5)
2160 count--;
2161
2162 context.getPrimitives()
2163 .setValue(tokens[3], new SInteger(count));
2164
2165 if (tokens.length > 4) {
2166 // Set the remainder string
2167 // assertPrimitiveType(tokens[4], 4);
2168 if (split.length < tokens.length - 4)
2169 context.getPrimitives().setValue(tokens[4],
2170 new SString());
2171 else
2172 context.getPrimitives().setValue(tokens[4],
2173 new SString(split[split.length - 1]));
2174
2175 // Set the strings for each of the vars
2176 if (tokens.length > 5) {
2177 for (int i = 5; i < tokens.length; i++) {
2178 // assertPrimitiveType(tokens[i], i);
2179 if (split.length < i - 4)
2180 context.getPrimitives().setValue(tokens[i],
2181 new SString());
2182 else
2183 context.getPrimitives().setValue(tokens[i],
2184 new SString(split[i - 5]));
2185 }
2186 }
2187 }
2188 }
2189 } else if (tokens[0].equals("stripstr")) {
2190 assertExactParametreCount(tokens, 2);
2191 String s = context.getPrimitives().getStringValue(tokens[1]);
2192 String charsToStrip = context.getPrimitives().getStringValue(
2193 tokens[2]);
2194 for (int i = 0; i < charsToStrip.length(); i++)
2195 s = s.replaceAll(charsToStrip.substring(i, i + 1), "");
2196 context.getPrimitives().setValue(tokens[1], new SString(s));
2197 } else if (tokens[0].equals("subststr")) {
2198 assertExactParametreCount(tokens, 3);
2199 String oldString = context.getPrimitives()
2200 .getStringValue(tokens[2]);
2201 String newString = context.getPrimitives()
2202 .getStringValue(tokens[3]);
2203 String result = context.getPrimitives().getStringValue(tokens[1]);
2204 result = result.replaceAll(oldString, newString);
2205 context.getPrimitives().setValue(tokens[1], new SString(result));
2206 } else if (tokens[0].equals("substr")) {
2207 assertExactParametreCount(tokens, 4);
2208 int startPos = (int) context.getPrimitives().getIntegerValue(
2209 tokens[2]) - 1;
2210 int length = (int) context.getPrimitives().getIntegerValue(
2211 tokens[3]);
2212 String s = context.getPrimitives().getStringValue(tokens[1]);
2213 String result;
2214 if (startPos + length < s.length())
2215 result = s.substring(startPos, startPos + length);
2216 else
2217 result = s.substring(startPos);
2218 context.getPrimitives().setValue(tokens[4], new SString(result));
2219 } else if (tokens[0].equals("pause")) {
2220 String lengthVar = DEFAULT_REAL;
2221
2222 if (tokens.length > 1) {
2223 assertExactParametreCount(tokens, 1);
2224 lengthVar = tokens[1];
2225 }
2226
2227 pause(context.getPrimitives().getDoubleValue(lengthVar));
2228 } else if (tokens[0].equals("glidecursorto")) {
2229 assertMinParametreCount(tokens, 2);
2230 int finalX = (int) context.getPrimitives().getIntegerValue(
2231 tokens[1]);
2232 int finalY = (int) context.getPrimitives().getIntegerValue(
2233 tokens[2]);
2234 int milliseconds = 1000;
2235 if (tokens.length > 3)
2236 milliseconds = (int) (context.getPrimitives().getDoubleValue(
2237 tokens[3]) * 1000);
2238
2239 int initialX = DisplayIO.getMouseX();
2240 int initialY = FrameMouseActions.getY();
2241
2242 final int timeInterval = 40;
2243
2244 int deltaX = (int) (finalX - initialX);
2245 int deltaY = (int) (finalY - initialY);
2246
2247 int intervals = milliseconds / timeInterval;
2248 for (double i = 0; i < intervals; i++) {
2249 int newX = initialX + (int) (deltaX * i / intervals);
2250 int newY = initialY + (int) (deltaY * i / intervals);
2251 Thread.yield();
2252 Thread.sleep(timeInterval);
2253 DisplayIO.setCursorPosition(newX, newY);
2254 // DisplayIO.repaint();
2255 }
2256 // Thread.yield();
2257 Thread.sleep(milliseconds % timeInterval);
2258 DisplayIO.setCursorPosition(finalX, finalY);
2259 } else if (tokens[0].equals("glideitemto")) {
2260 assertMinParametreCount(tokens, 3);
2261 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
2262 Item item = (Item) context.getPointers().getVariable(tokens[1])
2263 .getValue();
2264 int finalX = (int) context.getPrimitives().getIntegerValue(
2265 tokens[2]);
2266 int finalY = (int) context.getPrimitives().getIntegerValue(
2267 tokens[3]);
2268
2269 // DisplayIO.setCursorPosition(item.getX(), item.getY());
2270 // FrameMouseActions.pickup(item);
2271
2272 int milliseconds = 1000;
2273 if (tokens.length > 4)
2274 milliseconds = (int) (context.getPrimitives().getDoubleValue(
2275 tokens[4]) * 1000);
2276
2277 int initialX = item.getX();
2278 int initialY = item.getY();
2279 // int initialX = DisplayIO.getMouseX();
2280 // int initialY = DisplayIO.getMouseY();
2281
2282 final int timeInterval = 40;
2283
2284 int deltaX = (int) (finalX - initialX);
2285 int deltaY = (int) (finalY - initialY);
2286
2287 int intervals = milliseconds / timeInterval;
2288 for (double i = 0; i < intervals; i++) {
2289 int newX = initialX + (int) (deltaX * i / intervals);
2290 int newY = initialY + (int) (deltaY * i / intervals);
2291 Thread.yield();
2292 Thread.sleep(timeInterval);
2293 // DisplayIO.setCursorPosition(newX, newY);
2294
2295 item.setPosition(newX, newY);
2296 FrameGraphics.Repaint();
2297 }
2298 // Thread.yield();
2299 Thread.sleep(milliseconds % timeInterval);
2300 item.setPosition(finalX, finalY);
2301 // DisplayIO.setCursorPosition(finalX, finalY);
2302 FrameMouseActions.anchor(item);
2303 FreeItems.getInstance().clear();
2304 FrameGraphics.Repaint();
2305 // FrameMouseActions.updateCursor();
2306 }
2307 // Now look for fixed parametre statements
2308 else if (tokens[0].equals(EXIT_TEXT)) {
2309 return Status.Exit;
2310 } else if (tokens[0].equals(LOOP_TEXT)) {
2311 Status status = Status.OK;
2312 // Keep looping until break or exit occurs
2313 while (status == Status.OK || status == Status.Continue) {
2314 status = RunFrameAndReportError(code, context);
2315 pause(code);
2316 }
2317 if (status == Status.Continue || status == Status.Break)
2318 status = Status.OK;
2319 return status;
2320 } else if (tokens[0].equals(CONTINUE_TEXT)
2321 || tokens[0].equals(CONTINUE2_TEXT)) {
2322 return Status.Continue;
2323 } else if (tokens[0].equals(BREAK_TEXT)
2324 || tokens[0].equals(BREAK2_TEXT)) {
2325 return Status.Break;
2326 } else if (tokens[0].equals(RETURN_TEXT)) {
2327 return Status.Return;
2328 } else if (tokens[0].equals("pressleftbutton")) {
2329 assertExactParametreCount(tokens, 0);
2330 DisplayIO.pressMouse(InputEvent.BUTTON1_MASK);
2331 } else if (tokens[0].equals("pressmiddlebutton")) {
2332 assertExactParametreCount(tokens, 0);
2333 DisplayIO.pressMouse(InputEvent.BUTTON2_MASK);
2334 } else if (tokens[0].equals("pressrightbutton")) {
2335 assertExactParametreCount(tokens, 0);
2336 DisplayIO.pressMouse(InputEvent.BUTTON3_MASK);
2337 } else if (tokens[0].equals("releaseleftbutton")) {
2338 assertExactParametreCount(tokens, 0);
2339 DisplayIO.releaseMouse(InputEvent.BUTTON1_MASK);
2340 } else if (tokens[0].equals("releasemiddlebutton")) {
2341 assertExactParametreCount(tokens, 0);
2342 DisplayIO.releaseMouse(InputEvent.BUTTON2_MASK);
2343 } else if (tokens[0].equals("releaserightbutton")) {
2344 assertExactParametreCount(tokens, 0);
2345 DisplayIO.releaseMouse(InputEvent.BUTTON3_MASK);
2346 } else if (tokens[0].equals("clickleftbutton")) {
2347 assertExactParametreCount(tokens, 0);
2348 DisplayIO.clickMouse(InputEvent.BUTTON1_MASK);
2349 } else if (tokens[0].equals("clickmiddlebutton")) {
2350 assertExactParametreCount(tokens, 0);
2351 DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
2352 } else if (tokens[0].equals("clickrightbutton")) {
2353 assertExactParametreCount(tokens, 0);
2354 DisplayIO.clickMouse(InputEvent.BUTTON3_MASK);
2355 } else if (tokens[0].equals("repaint")) {
2356 assertExactParametreCount(tokens, 0);
2357 FrameGraphics.Repaint();
2358 } else if (tokens[0].equals("add")) {
2359 assertMaxParametreCount(tokens, 3);
2360 switch (tokens.length) {
2361 case 1:
2362 context.getPrimitives().add(DEFAULT_INTEGER);
2363 break;
2364 case 2:
2365 context.getPrimitives().add(tokens[1]);
2366 break;
2367 case 3:
2368 context.getPrimitives().add(tokens[2], tokens[1]);
2369 break;
2370 case 4:
2371 context.getPrimitives().add(tokens[1], tokens[2], tokens[3]);
2372 break;
2373 default:
2374 assert (false);
2375 }
2376 } else if (tokens[0].equals("subtract")) {
2377 assertMaxParametreCount(tokens, 3);
2378 switch (tokens.length) {
2379 case 1:
2380 context.getPrimitives().subtract(DEFAULT_INTEGER);
2381 break;
2382 case 2:
2383 context.getPrimitives().subtract(tokens[1]);
2384 break;
2385 case 3:
2386 context.getPrimitives().subtract(tokens[2], tokens[1]);
2387 break;
2388 case 4:
2389 context.getPrimitives().subtract(tokens[1], tokens[2],
2390 tokens[3]);
2391 break;
2392 default:
2393 assert (false);
2394 }
2395 } else if (tokens[0].equals("multiply")) {
2396 assertMinParametreCount(tokens, 2);
2397 assertMaxParametreCount(tokens, 3);
2398 switch (tokens.length) {
2399 case 3:
2400 context.getPrimitives().multiply(tokens[2], tokens[1]);
2401 break;
2402 case 4:
2403 context.getPrimitives().multiply(tokens[1], tokens[2],
2404 tokens[3]);
2405 break;
2406 default:
2407 assert (false);
2408 }
2409 } else if (tokens[0].equals("divide")) {
2410 assertMinParametreCount(tokens, 2);
2411 assertMaxParametreCount(tokens, 3);
2412 switch (tokens.length) {
2413 case 3:
2414 context.getPrimitives().divide(tokens[2], tokens[1]);
2415 break;
2416 case 4:
2417 context.getPrimitives().divide(tokens[1], tokens[2], tokens[3]);
2418 break;
2419 default:
2420 assert (false);
2421 }
2422 } else if (tokens[0].equals("modulo")) {
2423 assertExactParametreCount(tokens, 3);
2424 context.getPrimitives().modulo(tokens[1], tokens[2], tokens[3]);
2425 } else if (tokens[0].equals("power")) {
2426 assertExactParametreCount(tokens, 3);
2427 context.getPrimitives().power(tokens[1], tokens[2], tokens[3]);
2428 } else if (tokens[0].equals("not")) {
2429 assertExactParametreCount(tokens, 2);
2430 context.getPrimitives().not(tokens[1], tokens[2]);
2431 } else if (tokens[0].equals("exp")) {
2432 assertExactParametreCount(tokens, 2);
2433 context.getPrimitives().exp(tokens[1], tokens[2]);
2434 } else if (tokens[0].equals("log")) {
2435 assertExactParametreCount(tokens, 2);
2436 context.getPrimitives().log(tokens[2], tokens[2]);
2437 } else if (tokens[0].equals("log10")) {
2438 assertExactParametreCount(tokens, 2);
2439 context.getPrimitives().log10(tokens[1], tokens[2]);
2440 } else if (tokens[0].equals("sqrt")) {
2441 assertExactParametreCount(tokens, 2);
2442 context.getPrimitives().sqrt(tokens[1], tokens[2]);
2443 } else if (tokens[0].equals("closewritefile")) {
2444 assertVariableType(tokens[1], 1, SPointer.filePrefix);
2445 context.closeWriteFile(tokens[1]);
2446 } else if (tokens[0].equals("closereadfile")) {
2447 assertVariableType(tokens[1], 1, SPointer.filePrefix);
2448 context.closeReadFile(tokens[1]);
2449 } else if (tokens[0].startsWith("foreach")) {
2450 if (tokens[0].equals("foreachassociation")) {
2451 assertExactParametreCount(tokens, 3);
2452 assertVariableType(tokens[1], 1, SPointer.associationPrefix);
2453 Map<String, String> map = (Map<String, String>) context
2454 .getPointers().getVariable(tokens[1]).getValue();
2455 for (Map.Entry entry : map.entrySet()) {
2456 String value = entry.getValue().toString();
2457 String key = entry.getKey().toString();
2458 context.getPrimitives().setValue(tokens[2], key);
2459 context.getPrimitives().setValue(tokens[3], value);
2460 Status status = RunFrameAndReportError(code, context);
2461 pause(code);
2462 // check if we need to exit this loop because of
2463 // statements in the code that was run
2464 if (status == Status.Exit || status == Status.Return)
2465 return status;
2466 else if (status == Status.Break)
2467 break;
2468 }
2469 } else {
2470 Class itemType = Object.class;
2471 String type = tokens[0].substring("foreach".length());
2472 // Check the type of foreach loop
2473 // and set the item type to iterate over
2474 if (type.equals("dot")) {
2475 itemType = Dot.class;
2476 } else if (type.equals("text")) {
2477 itemType = Text.class;
2478 } else if (type.equals("line")) {
2479 itemType = Line.class;
2480 } else if (type.equals("item") || type.equals("")) {
2481 itemType = Object.class;
2482 } else {
2483 throw new RuntimeException("Invalid ForEach loop type");
2484 }
2485
2486 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
2487 assertVariableType(tokens[1], 1, SPointer.framePrefix);
2488 Frame currFrame = (Frame) context.getPointers().getVariable(
2489 tokens[1]).getValue();
2490 // Create the ip variable
2491 Item frameTitle = currFrame.getTitleItem();
2492
2493 for (Item i : currFrame.getItems()) {
2494 if (i == frameTitle)
2495 continue;
2496 if (!(itemType.isInstance(i)))
2497 continue;
2498
2499 context.getPointers().setObject(tokens[2], i);
2500 Status status = RunFrameAndReportError(code, context);
2501 pause(code);
2502 // check if we need to exit this loop because of
2503 // statements in the code that was run
2504 if (status == Status.Exit || status == Status.Return)
2505 return status;
2506 else if (status == Status.Break)
2507 return Status.OK;
2508 }
2509 }
2510 } else if (tokens[0].equals("movecursorto")) {
2511 assertExactParametreCount(tokens, 2);
2512 int x = (int) context.getPrimitives().getIntegerValue(tokens[1]);
2513 int y = (int) context.getPrimitives().getIntegerValue(tokens[2]);
2514 DisplayIO.setCursorPosition(x, y);
2515 } else {
2516 throw new RuntimeException("Unknown statement");
2517 }
2518 return Status.OK;
2519 }
2520
2521 public static int countCharsInString(String s, String pattern) {
2522 String newString = s;
2523 int count = -1;
2524 do {
2525 count++;
2526 s = newString;
2527 newString = s.replaceFirst(pattern, "");
2528 } while (s.length() != newString.length());
2529
2530 return count;
2531 }
2532
2533 public static void assertVariableType(String varName, int no, String type)
2534 throws Exception {
2535 if (!varName.startsWith(type))
2536 throw new IncorrectTypeException(type, no);
2537 }
2538
2539 /*
2540 * public static void assertPrimitiveType(String varName, int no) throws
2541 * Exception { if (!Primitives.isPrimitive(varName)) throw new
2542 * IncorrectTypeException("primitive", no); }
2543 */
2544
2545 public static void assertMinParametreCount(String[] tokens,
2546 int minParametres) throws Exception {
2547 if (tokens.length - 1 < minParametres)
2548 throw new BelowMinParametreCountException(minParametres);
2549 }
2550
2551 public static void assertExactParametreCount(String[] tokens,
2552 int parametreCount) throws Exception {
2553 if (tokens.length - 1 != parametreCount)
2554 throw new IncorrectParametreCountException(parametreCount);
2555 }
2556
2557 public static void assertMaxParametreCount(String[] tokens,
2558 int parametreCount) throws Exception {
2559 if (tokens.length - 1 > parametreCount)
2560 throw new AboveMaxParametreCountException(parametreCount);
2561 }
2562
2563 private static String getMessage(String[] tokens, Context context,
2564 String code, String separator, int firstStringIndex)
2565 throws Exception {
2566 StringBuilder message = new StringBuilder();
2567 if (tokens.length == firstStringIndex) {
2568 message.append(context.getPrimitives().getVariable(DEFAULT_STRING)
2569 .stringValue());
2570 } else {
2571 for (int i = firstStringIndex; i < tokens.length; i++) {
2572 if (Primitives.isPrimitive(tokens[i])) {
2573 message.append(context.getPrimitives().getVariable(
2574 tokens[i]).stringValue()
2575 + separator);
2576 } else
2577 throw new Exception("Illegal parametre: [" + tokens[i]
2578 + "] in line " + code);
2579 }
2580 }
2581 return message.toString();
2582 }
2583
2584 public static void stop() {
2585 _stop = true;
2586 }
2587
2588 public static void nextStatement() {
2589 _nextStatement = true;
2590 }
2591
2592 public static void ProgramStarted() {
2593 _programsRunning++;
2594 AgentStats.reset();
2595 MessageBay.displayMessage("Running SimpleProgram...", Color.BLUE);
2596 }
2597
2598 public static boolean isVerbose() {
2599 return _verbose;
2600 }
2601}
Note: See TracBrowser for help on using the repository browser.