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

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

Added Spell Checker
Added word count stats
Fixed some mail stuff

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