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

Last change on this file since 133 was 133, checked in by ra33, 16 years ago

Turned search actions into search agents so they are run on a different thread

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