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

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

Fixed a bunch of problems with rectangles and resizing the window, as well as adding some more unit tests etc.

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