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

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

Refactored the way attribute value pairs work...
Moved static methods into attributeValuePairs class

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