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

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

Heaps of changes!!!!
Added circles...
Better drawing of lines etc etc

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