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

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