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

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