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

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

Added forced Garbage collection to DisplayFrameset method

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