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

Last change on this file since 465 was 465, checked in by davidb, 11 years ago

Status enum made public. Some tidying up of text/spelling in comments

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