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

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

A whole day of big changes.
Adding the ability to have Text at the end of Lines.
Also a lot of refactoring to improve the quality of code relating to constraints and lines

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