source: trunk/org/expeditee/actions/Simple.java@ 4

Last change on this file since 4 was 4, checked in by davidb, 16 years ago

Starting source code to Expeditee

File size: 56.9 KB
Line 
1package org.expeditee.actions;
2
3import java.awt.Color;
4import java.awt.Point;
5import java.awt.event.InputEvent;
6import java.util.ArrayList;
7import java.util.LinkedList;
8import java.util.List;
9
10import org.expeditee.gui.AttributeUtils;
11import org.expeditee.gui.DisplayIO;
12import org.expeditee.gui.Frame;
13import org.expeditee.gui.FrameGraphics;
14import org.expeditee.gui.FrameIO;
15import org.expeditee.gui.FrameMouseActions;
16import org.expeditee.gui.FrameUtils;
17import org.expeditee.io.Conversion;
18import org.expeditee.items.Dot;
19import org.expeditee.items.Item;
20import org.expeditee.items.Line;
21import org.expeditee.items.Text;
22import org.expeditee.simple.BelowMinParametreCountException;
23import org.expeditee.simple.Context;
24import org.expeditee.simple.IncorrectParametreCountException;
25import org.expeditee.simple.IncorrectTypeException;
26import org.expeditee.simple.Pointers;
27import org.expeditee.simple.Primitives;
28import org.expeditee.simple.SBoolean;
29import org.expeditee.simple.SCharacter;
30import org.expeditee.simple.SInteger;
31import org.expeditee.simple.SPointer;
32import org.expeditee.simple.SPrimitive;
33import org.expeditee.simple.SReal;
34import org.expeditee.simple.SString;
35import org.expeditee.simple.SVariable;
36import org.expeditee.simple.UnitTestFailedException;
37import org.expeditee.stats.AgentStats;
38
39public class Simple {
40
41 private static final String DEFAULT_STRING = "$s.";
42
43 private static final String DEFAULT_BOOLEAN = "$b.";
44
45 private static final String DEFAULT_CHAR = "$c.";
46
47 private static final String DEFAULT_INTEGER = "$i.";
48
49 private static final String DEFAULT_REAL = "$r.";
50
51 private static final String DEFAULT_ITEM = "$ip.";
52
53 private static final String DEFAULT_FRAME = "$fp.";
54
55 private static final String EXIT_TEXT = "exitall";
56
57 private static enum Status {
58 Exit, OK, Break, Continue, Return, TrueIf, FalseIf;
59 };
60
61 private static final String BREAK_TEXT = "exitrepeat";
62
63 private static final String CONTINUE_TEXT = "nextrepeat";
64
65 private static final String RETURN_TEXT = "return";
66
67 private static final String LOOP_TEXT = "repeat";
68
69 private static final String TOKEN_SEPARATOR = " +";
70
71 private static final String RUN_FRAME_ACTION = "RunFrame";
72
73 /**
74 * Keeps track of how many simple programs are running. Used to check if
75 * simple should read in keyboard input. Or if the keyboard input should be
76 * handled normally by Expeditee.
77 */
78 private static int _programsRunning = 0;
79
80 public static void ProgramFinished() {
81 _programsRunning--;
82 }
83
84 private static LinkedList<Character> _KeyStrokes = new LinkedList<Character>();
85
86 public static void KeyStroke(char c) {
87 _KeyStrokes.add(c);
88 }
89
90 public static boolean isProgramRunning() {
91 return _programsRunning > 0;
92 }
93
94 public static void NewSimpleTest() {
95 Frame newSimpleTest = FrameIO.CreateFrame(DisplayIO.getCurrentFrame()
96 .getFramesetName(), "Test", null);
97 List<String> actions = new ArrayList<String>();
98 actions.add(RUN_FRAME_ACTION);
99 newSimpleTest.getTitle().setAction(actions);
100 FrameUtils.DisplayFrame(newSimpleTest, true);
101 FrameGraphics.DisplayMessage("New test created");
102 }
103
104 public static void NextTest() {
105 Frame next = DisplayIO.getCurrentFrame();
106 do {
107 next = FrameIO.LoadNext(next);
108 } while (next != null
109 && (next.getTitle() == null || !RUN_FRAME_ACTION
110 .equalsIgnoreCase(next.getTitle().getFirstAction())));
111 FrameUtils.DisplayFrame(next, true);
112 }
113
114 public static void PreviousTest() {
115 Frame prev = DisplayIO.getCurrentFrame();
116 do {
117 prev = FrameIO.LoadPrevious(prev);
118 } while (prev != null
119 && (prev.getTitle() == null || !RUN_FRAME_ACTION
120 .equalsIgnoreCase(prev.getTitle().getFirstAction())));
121
122 FrameUtils.DisplayFrame(prev, true);
123 }
124
125 public static void LastTest() {
126 Frame next = FrameIO.LoadLast();
127 Frame lastTest = null;
128 do {
129 // check if its a test frame
130 if (next != null
131 && next.getTitle() != null
132 && RUN_FRAME_ACTION.equalsIgnoreCase(next.getTitle()
133 .getFirstAction())) {
134 lastTest = next;
135 break;
136 }
137
138 next = FrameIO.LoadPrevious(next);
139 } while (next != null);
140
141 FrameUtils.DisplayFrame(lastTest, true);
142 }
143
144 public static void RunSimpleTests(String frameset) {
145 RunSimpleTests(frameset, false);
146 }
147
148 public static void RunSimpleTestsVerbose(String frameset) {
149 RunSimpleTests(frameset, true);
150 }
151
152 public static void RunSimpleTests(String frameset, boolean verbose) {
153 int testsPassed = 0;
154 int testsFailed = 0;
155
156 FrameIO.SaveFrame(DisplayIO.getCurrentFrame(), false);
157
158 FrameGraphics.DisplayMessage("Starting test suite: " + frameset,
159 Color.CYAN);
160
161 // Get the next number in the inf file for the frameset
162 int lastFrameNo = FrameIO.getLastNumber(frameset);
163
164 // Loop through all the valid frames in the frameset
165 for (int i = 1; i <= lastFrameNo; i++) {
166 String nextFrameName = frameset + i;
167 Frame nextFrame = FrameIO.LoadFrame(nextFrameName);
168 if (nextFrame != null) {
169 // Run the frames with the RunFrame action on the title
170 Text title = nextFrame.getTitle().copy();
171 List<String> actions = title.getAction();
172 if (actions != null && !title.isAnnotation()) {
173 if (actions.get(0).toLowerCase().equals("runframe")) {
174 try {
175 title.setLink(nextFrameName);
176 // TODO add the ability to run a setup frame
177 // which sets up variables to be used in all
178 // tests
179 AgentStats.reset();
180 _KeyStrokes.clear();
181 _programsRunning++;
182 RunFrameAndReportError(title, new Context());
183 _programsRunning--;
184 if (verbose)
185 FrameGraphics.DisplayMessage("Test passed: "
186 + title.toString(), Item.GREEN);
187 testsPassed++;
188 } catch (Exception e) {
189 testsFailed++;
190 _programsRunning--;
191 // Print out the reason for failed tests
192 FrameGraphics.LinkedErrorMessage(e.getMessage());
193 }
194 }
195 }
196 }
197 }
198
199 // Report the number of test passed and failed
200 FrameGraphics.DisplayMessage("Total tests: "
201 + (testsPassed + testsFailed), Color.CYAN);
202 if (testsPassed > 0)
203 FrameGraphics.DisplayMessage("Passed: " + testsPassed, Item.GREEN);
204 if (testsFailed > 0)
205 FrameGraphics.DisplayMessage("Failed: " + testsFailed, Color.RED);
206 }
207
208 public static void RunFrame(Item current) {
209 try {
210 FrameIO.SaveFrame(DisplayIO.getCurrentFrame(), true);
211
212 // an item without a link signals to run the current frame
213 if (current.getLink() == null) {
214 current = current.copy();
215 current.setLink(DisplayIO.getCurrentFrame().getFrameName());
216 }
217
218 _KeyStrokes.clear();
219
220 _programsRunning++;
221 Thread t = new Thread(current);
222 t.setPriority(Thread.MIN_PRIORITY);
223 t.start();
224 // _programsRunning--;
225 } catch (Exception e) {
226 // _programsRunning--;
227 }
228 }
229
230 private static void FlagError(Item item) {
231 item.setColor(Color.CYAN);
232 FrameUtils.DisplayFrame(item.getParent().getFrameName(), true);
233 FrameIO.SaveFrame(item.getParent());
234 }
235
236 /**
237 * Runs a simple code begining on a frame linked to by the specified item
238 * parametre.
239 *
240 * @param current
241 * the item that is linked to the frame to be run.
242 */
243 public static Status RunFrameAndReportError(Item current, Context context)
244 throws Exception {
245 // the item must link to a frame
246 if (current.getLink() == null) {
247 throw new Exception("Could not run unlinked item: "
248 + current.toString());
249 }
250
251 Frame child = FrameIO.LoadFrame(current.getAbsoluteLink());
252 AgentStats.FrameExecuted();
253
254 // if the frame could not be loaded
255 if (child == null) {
256 throw new Exception("Could not load item link: "
257 + current.toString());
258 }
259
260 // loop through non-title, non-name, non-annotation text items
261 List<Item> body = child.getItems();
262 Text item = null;
263 Status lastItemStatus = Status.OK;
264 for (Item i : body)
265 // Ignore items that arent statements
266 if (isStatement(i)) {
267 item = (Text) i;
268 AgentStats.ItemExecuted();
269 try {
270
271 lastItemStatus = RunItem(item, context, lastItemStatus);
272
273 if (lastItemStatus != Status.OK) {
274 if (lastItemStatus != Status.TrueIf
275 && lastItemStatus != Status.FalseIf) {
276 return lastItemStatus;
277 }
278 }
279 } catch (ArrayIndexOutOfBoundsException e) {
280 FlagError(item);
281 throw new Exception("Too few parametres: "
282 + item.toString());
283 } catch (NullPointerException e) {
284 FlagError(item);
285 throw new Exception("Null pointer exception: "
286 + item.toString());
287 } catch (RuntimeException e) {
288 FlagError(item);
289 throw new Exception(e.getMessage() + " " + item.toString());
290 } catch (Exception e) {
291 throw new Exception(e.getMessage());
292 }
293 }
294
295 // if no item was found
296 if (item == null)
297 throw new Exception("No code to be executed: " + current.toString());
298
299 return Status.OK;
300 }
301
302 private static boolean isStatement(Item i) {
303 if (!(i instanceof Text))
304 return false;
305
306 Frame frame = i.getParent();
307
308 if (i == frame.getTitle() || i == frame.getName() || i.isAnnotation()) {
309 return false;
310 }
311
312 return true;
313 }
314
315 /**
316 * This method should be modified to parse strings correctly
317 *
318 * @param statement
319 * @return
320 */
321 private static String[] parseStatement(String statement) {
322 return statement.split(TOKEN_SEPARATOR);
323 }
324
325 /**
326 * Runs a SIMPLE procedure statement.
327 *
328 * @param tokens
329 * the parsed Call statement.
330 * @param code
331 * the expeditee item containing the procedure call and the link
332 * to the frame with the procedure code.
333 * @param context
334 * the current context from which the procedure call is being
335 * made.
336 * @throws Exception
337 * when errors occur in running the procedure.
338 */
339 private static Status Call(String[] tokens, Text code, Context context)
340 throws Exception {
341 // Check that the call statement is linked
342 if (code.getLink() == null)
343 throw new Exception("Unlinked call statement: " + code.toString());
344
345 Frame procedure = FrameIO.LoadFrame(code.getAbsoluteLink());
346
347 // Add call to the start of the title if it doesnt exist
348 // This makes the call and signature tokens counts match
349 String procedureTitle = procedure.getTitle().getFirstLine();
350 if (!procedureTitle.toLowerCase().startsWith("call "))
351 procedureTitle = "call " + procedureTitle;
352
353 // Check that the calling statement matches the procedure
354 // signature
355 String[] procedureSignature = procedureTitle.split(TOKEN_SEPARATOR);
356
357 // Check for the right amount of parametres
358 if (procedureSignature.length < tokens.length)
359 throw new Exception("Call statement has too many parametres: "
360 + code.toString());
361 else if (procedureSignature.length > tokens.length)
362 throw new Exception("Call statement has too few parametres: "
363 + code.toString());
364 // else if (procedureSignature[1].equals(tokens[1]))
365 // throw new Exception("Call statement and procedure name dont match: "
366 // + code.toString());
367
368 // create the new context for the sub procedure
369 Context newContext = new Context();
370 // Check that the types/prefixes match
371 for (int i = 2; i < tokens.length; i++) {
372 // TODO allow for auto casting of primitives
373 if (tokens[i].substring(1, 2).equals(
374 procedureSignature[i].substring(1, 2))) {
375 // Add the variables to the new context
376 if (Primitives.isPrimitive(tokens[i])) {
377 try {
378 // try and get the value for the variable
379 SPrimitive p = context.getPrimitives().getVariable(
380 tokens[i]);
381 newContext.getPrimitives()
382 .add(procedureSignature[i], p);
383 } catch (Exception e) {
384 // If an exception occurs the variable doesnt
385 // exist in the current context
386 // So the variable must be added to both context
387 context.getPrimitives().add(tokens[i], new SString(""));
388 newContext.getPrimitives().add(procedureSignature[i],
389 new SString(""));
390 }
391 } else if (Pointers.isPointer(tokens[i])) {
392 try {
393 // try and get the value for the variable
394 SPointer p = context.getPointers().getVariable(
395 tokens[i]);
396 newContext.getPointers().add(procedureSignature[i], p);
397 } catch (Exception e) {
398 // If an exception occurs the variable doesnt
399 // exist in the current context
400 // So the variable must be added to both context
401 context.getPointers().setObject(tokens[i], null);
402 newContext.getPointers().setObject(
403 procedureSignature[i], null);
404 }
405 } else
406 throw new Exception("Unrecognised variable type: "
407 + tokens[i] + " in " + code.toString());
408 } else
409 throw new IncorrectTypeException(procedureSignature[i], i);
410 }
411
412 // Follow the link and Run the code for the procedure
413 Status result = RunFrameAndReportError(code, newContext);
414 // If a return statement ends the procedure then we accept this as
415 // normal execution
416 switch (result) {
417 case Return:
418 result = Status.OK;
419 break;
420 case Break:
421 throw new Exception(BREAK_TEXT + " statement without matching "
422 + LOOP_TEXT + " in " + code.toString());
423 case Continue:
424 throw new Exception("");
425 }
426
427 // Now copy the values from the procedure context into the
428 // current context
429 for (int i = 2; i < tokens.length; i++) {
430 try {
431 if (Primitives.isPrimitive(tokens[i])) {
432 // try and get the value for the variable
433 SVariable p = context.getPrimitives()
434 .getVariable(tokens[i]);
435 SVariable newP = newContext.getPrimitives().getVariable(
436 procedureSignature[i]);
437 p.setValue(newP);
438 } else {
439 // try and get the value for the variable
440 SVariable p = context.getPointers().getVariable(tokens[i]);
441 SVariable newP = newContext.getPointers().getVariable(
442 procedureSignature[i]);
443 p.setValue(newP);
444 }
445 } catch (Exception e) {
446 assert (false);
447 }
448 }
449
450 return result;
451 }
452
453 /**
454 * Runs a text item on a frame as a SIMPLE statement. The statement is
455 * parsed and if it is a recognised SIMPLE keyword or procedure the code is
456 * executed.
457 *
458 * @param code
459 * the item containing the code to be executed.
460 * @param context
461 * @return
462 * @throws Exception
463 */
464 private static Status RunItem(Text code, Context context,
465 Status lastItemStatus) throws Exception {
466 String codeText = code.getTextNoList();
467 // Comments without links are a no-op
468 if (codeText.startsWith("#") || codeText.startsWith("//")) {
469 if (code.getLink() == null)
470 return Status.OK;
471 else
472 return RunFrameAndReportError(code, context);
473 }
474
475 // Now check for code statements
476 codeText = codeText.trim();
477 String[] tokens = parseStatement(codeText.toLowerCase());
478 // At present only set statements can have literals so they
479 // are the only statements that we have to worry about string
480 // literals
481 assert (tokens.length > 0);
482 if (tokens[0].equals("call") && tokens.length >= 2) {
483 return Call(tokens, code, context);
484 // Check if the user wants to display a message
485 // Check for set statements
486 } else if (tokens[0].startsWith("set")) {
487 if (tokens[0].equals("set")) {
488 try {
489 // Check if we are setting variable to variable
490 if (tokens[2].startsWith(SVariable.prefix)
491 && tokens.length == 3) {
492 context.getPrimitives().set(tokens[1], tokens[2]);
493 return Status.OK;
494 }
495 // Otherwise we are setting a variable with a literal
496 else {
497 // check for strings enclosed in quotes
498 if (tokens[2].startsWith("\"")) {
499 if (tokens[tokens.length - 1].endsWith("\"")) {
500 context.getPrimitives().setValue(
501 tokens[1],
502 new SString(codeText.substring(codeText
503 .indexOf("\"") + 1, codeText
504 .length() - 1)));
505 return Status.OK;
506 } else
507 throw new Exception("Expected matching \" "
508 + code.toString());
509 // set a literal
510 } else if (tokens.length == 3) {
511 context.getPrimitives().setValue(tokens[1],
512 tokens[2]);
513 return Status.OK;
514 }
515 }
516 } catch (Exception e) {
517 throw new RuntimeException(e.getMessage());
518 }
519 } else if (tokens[0].startsWith("setitem")) {
520 if (tokens[0].equals("setitemposition")) {
521 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
522 // assertPrimitiveType(tokens[2], 2);
523 // assertPrimitiveType(tokens[3], 3);
524 Item item = (Item) context.getPointers().getVariable(
525 tokens[1]).getValue();
526 item.setPosition(context.getPrimitives().getVariable(
527 tokens[2]).integerValue().intValue(), context
528 .getPrimitives().getVariable(tokens[3])
529 .integerValue().intValue());
530 } else if (tokens[0].equals("setitemthickness")) {
531 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
532 // assertPrimitiveType(tokens[2], 2);
533 Item item = (Item) context.getPointers().getVariable(
534 tokens[1]).getValue();
535 item.setThickness(context.getPrimitives().getVariable(
536 tokens[2]).integerValue().intValue());
537 } else if (tokens[0].equals("setitemwidth")) {
538 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
539 // assertPrimitiveType(tokens[2], 2);
540 Item item = (Item) context.getPointers().getVariable(
541 tokens[1]).getValue();
542 item.setWidth(context.getPrimitives()
543 .getVariable(tokens[2]).integerValue().intValue());
544 } else if (tokens[0].equals("setitemsize")) {
545 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
546 // assertPrimitiveType(tokens[2], 2);
547 Item item = (Item) context.getPointers().getVariable(
548 tokens[1]).getValue();
549 item.setSize(context.getPrimitives().getVariable(tokens[2])
550 .integerValue().intValue());
551 } else if (tokens[0].equals("setitemlink")) {
552 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
553 // assertPrimitiveType(tokens[2], 2);
554 Item item = (Item) context.getPointers().getVariable(
555 tokens[1]).getValue();
556 item.setLink(context.getPrimitives().getVariable(tokens[2])
557 .stringValue());
558 } else if (tokens[0].equals("setitemfillcolor")) {
559 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
560 // assertPrimitiveType(tokens[2], 2);
561 Item item = (Item) context.getPointers().getVariable(
562 tokens[1]).getValue();
563 String stringColor = context.getPrimitives().getVariable(
564 tokens[2]).stringValue();
565 item.setBackgroundColor((Color) Conversion.Convert(
566 Color.class, stringColor));
567 } else if (tokens[0].equals("setitemcolor")) {
568 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
569 // assertPrimitiveType(tokens[2], 2);
570 Item item = (Item) context.getPointers().getVariable(
571 tokens[1]).getValue();
572 String stringColor = context.getPrimitives().getVariable(
573 tokens[2]).stringValue();
574 item.setColor((Color) Conversion.Convert(Color.class,
575 stringColor));
576 } else if (tokens[0].equals("setitemtext")) {
577 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
578 // assertPrimitiveType(tokens[2], 2);
579 String newText = context.getPrimitives().getVariable(
580 tokens[2]).stringValue();
581 Text textItem = (Text) context.getPointers().getVariable(
582 tokens[1]).getValue();
583 textItem.setText(newText);
584 } else
585 throw new Exception("Unsupported setItem command: "
586 + code.toString());
587 return Status.OK;
588 } else if (tokens[0].equals("setstrchar")) {
589 assertExactParametreCount(tokens, 3);
590 StringBuffer s = new StringBuffer(context.getPrimitives()
591 .getStringValue(tokens[1]));
592 int pos = (int) context.getPrimitives().getIntegerValue(
593 tokens[2]);
594 char newChar = context.getPrimitives().getCharacterValue(
595 tokens[3]);
596 while (pos > s.length()) {
597 s.append(newChar);
598 }
599 s.setCharAt(pos - 1, newChar);
600
601 context.getPrimitives().setValue(tokens[1],
602 new SString(s.toString()));
603 return Status.OK;
604 } else if (tokens[0].equals("setcharinitem")) {
605 assertExactParametreCount(tokens, 4);
606 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
607
608 int row = (int) context.getPrimitives().getIntegerValue(
609 tokens[3]) - 1;
610 int col = (int) context.getPrimitives().getIntegerValue(
611 tokens[4]) - 1;
612 char newChar = context.getPrimitives().getCharacterValue(
613 tokens[2]);
614 Text item = (Text) context.getPointers().getVariable(tokens[1])
615 .getValue();
616 List<String> itemText = item.getText();
617
618 while (row >= itemText.size()) {
619 StringBuffer sb = new StringBuffer();
620 for (int i = 0; i <= col; i++)
621 sb.append(newChar);
622 itemText.add(sb.toString());
623 }
624 StringBuffer sb = new StringBuffer(itemText.get(row));
625 while (sb.length() <= col)
626 sb.append(newChar);
627 sb.setCharAt(col, newChar);
628
629 // set the modified string
630 itemText.set(row, sb.toString());
631 item.setTextList(itemText);
632
633 return Status.OK;
634 }
635 } else if (tokens[0].startsWith("assert")) {
636 if (tokens[0].equals("asserttrue")) {
637 assertExactParametreCount(tokens, 1);
638 if (!context.getPrimitives().getBooleanValue(tokens[1]))
639 throw new UnitTestFailedException("true", "false");
640 return Status.OK;
641 } else if (tokens[0].equals("assertfalse")) {
642 assertExactParametreCount(tokens, 1);
643 if (context.getPrimitives().getBooleanValue(tokens[1]))
644 throw new UnitTestFailedException("false", "true");
645 return Status.OK;
646 } else if (tokens[0].equals("assertnull")) {
647 assertExactParametreCount(tokens, 1);
648 Object value = context.getPrimitives().getVariable(tokens[1])
649 .getValue();
650 if (value != null)
651 throw new UnitTestFailedException("null", value.toString());
652 return Status.OK;
653 } else if (tokens[0].equals("assertequals")) {
654 assertExactParametreCount(tokens, 2);
655 if (!context.getPrimitives().equalValues(tokens[1], tokens[2]))
656 throw new UnitTestFailedException(context.getPrimitives()
657 .getStringValue(tokens[1]), context.getPrimitives()
658 .getStringValue(tokens[2]));
659 return Status.OK;
660 } else if (tokens[0].equals("assertdefined")) {
661 assertExactParametreCount(tokens, 1);
662 if (!context.isDefined(tokens[1])) {
663 throw new UnitTestFailedException(tokens[1] + " exists",
664 "not defined");
665 }
666 return Status.OK;
667 }
668 } else if (tokens[0].startsWith("goto")) {
669 String frameNameVar = DEFAULT_STRING;
670 if (tokens.length > 1) {
671 assertExactParametreCount(tokens, 1);
672 frameNameVar = tokens[1];
673 }
674 String frameName = context.getPrimitives().getStringValue(
675 frameNameVar);
676 NavigationActions.Goto(frameName);
677 return Status.OK;
678 } else if (tokens[0].startsWith("get")) {
679 if (tokens[0].startsWith("getframe")) {
680 if (tokens[0].equals("getframevalue")) {
681 assertMinParametreCount(tokens, 4);
682 assertVariableType(tokens[1], 1, SPointer.framePrefix);
683
684 // Get the attribute to be searched for on the target frame
685 Frame targetFrame = (Frame) context.getPointers()
686 .getVariable(tokens[1]).getValue();
687 String targetAttribute = context.getPrimitives()
688 .getStringValue(tokens[2]).toLowerCase()
689 + ":";
690 Boolean found = false;
691 String value = "";
692 Text attributeItem = null;
693 Text valueItem = null;
694 // Begin the search
695 for (Text text : targetFrame.getBodyTextItems()) {
696 String s = text.getTextNoList().toLowerCase();
697 if (s.startsWith(targetAttribute)) {
698 attributeItem = text;
699 value = AttributeUtils.stripValue(s);
700 if (value.length() > 0) {
701 found = true;
702 }
703 break;
704 }
705 }
706 // Keep looking for a matching value nearby if we found an
707 // attribute without the value in the same item
708 if (!found && attributeItem != null) {
709 Point endPoint = attributeItem
710 .getEndParagraphPosition();
711
712 for (Text text : targetFrame.getBodyTextItems()) {
713 Point startPoint = text.getPosition();
714 if (Math.abs(startPoint.y - endPoint.y) < 10
715 && Math.abs(startPoint.x - endPoint.x) < 20) {
716 found = true;
717 valueItem = text;
718 value = text.getTextNoList();
719 break;
720 }
721 }
722 }
723
724 // Set the values of the output parametres
725 context.getPrimitives().setValue(tokens[3],
726 new SString(value));
727 context.getPrimitives().setValue(tokens[4],
728 new SBoolean(found));
729 if (tokens.length > 5) {
730 context.getPointers().setObject(tokens[5],
731 attributeItem);
732 if (tokens.length > 6) {
733 context.getPointers().setObject(tokens[6],
734 valueItem);
735 }
736 }
737
738 return Status.OK;
739 } else if (tokens[0].startsWith("getframename")) {
740 String frameNameVar = DEFAULT_STRING;
741 String frameVar = DEFAULT_FRAME;
742
743 if (tokens.length > 1) {
744 assertExactParametreCount(tokens, 2);
745 assertVariableType(tokens[1], 1, SPointer.framePrefix);
746 frameNameVar = tokens[2];
747 frameVar = tokens[1];
748 }
749 Frame frame = (Frame) context.getPointers().getVariable(
750 frameVar).getValue();
751 context.getPrimitives().setValue(frameNameVar,
752 frame.getFrameName());
753 return Status.OK;
754 }
755 } else if (tokens[0].startsWith("getcurrent")) {
756 if (tokens[0].equals("getcurrentframe")) {
757 assertMinParametreCount(tokens, 1);
758 assertVariableType(tokens[1], 1, SPointer.framePrefix);
759
760 Frame currentFrame = DisplayIO.getCurrentFrame();
761 context.getPointers().setObject(tokens[1], currentFrame);
762
763 // check if the user is also after the frameName
764 if (tokens.length > 2) {
765 context.getPrimitives().setValue(tokens[2],
766 new SString(currentFrame.getFrameName()));
767 }
768 return Status.OK;
769 }
770 } else if (tokens[0].startsWith("getitem")) {
771 if (tokens[0].equals("getitemposition")) {
772 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
773 // assertPrimitiveType(tokens[2], 2);
774 // assertPrimitiveType(tokens[3], 3);
775 Point pos = ((Item) context.getPointers().getVariable(
776 tokens[1]).getValue()).getPosition();
777 Integer x = pos.x;
778 Integer y = pos.y;
779 context.getPrimitives()
780 .setValue(tokens[2], new SInteger(x));
781 context.getPrimitives()
782 .setValue(tokens[3], new SInteger(y));
783 } else if (tokens[0].equals("getitemthickness")) {
784 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
785 // assertPrimitiveType(tokens[2], 2);
786 Float thickness = ((Item) context.getPointers()
787 .getVariable(tokens[1]).getValue()).getThickness();
788 context.getPrimitives().setValue(tokens[2],
789 new SReal(thickness));
790 } else if (tokens[0].equals("getitemwidth")) {
791 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
792 // assertPrimitiveType(tokens[2], 2);
793 Integer width = ((Item) context.getPointers().getVariable(
794 tokens[1]).getValue()).getWidth();
795 context.getPrimitives().setValue(tokens[2],
796 new SInteger(width));
797 } else if (tokens[0].equals("getitemsize")) {
798 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
799 // assertPrimitiveType(tokens[2], 2);
800 Integer size = ((Item) context.getPointers().getVariable(
801 tokens[1]).getValue()).getSize();
802 context.getPrimitives().setValue(tokens[2],
803 new SInteger(size));
804 } else if (tokens[0].equals("getitemlink")) {
805 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
806 // assertPrimitiveType(tokens[2], 2);
807 String link = ((Item) context.getPointers().getVariable(
808 tokens[1]).getValue()).getLink();
809 context.getPrimitives().setValue(tokens[2],
810 new SString(link));
811 } else if (tokens[0].equals("getitemfillcolor")) {
812 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
813 // assertPrimitiveType(tokens[2], 2);
814 Color itemColor = ((Item) context.getPointers()
815 .getVariable(tokens[1]).getValue())
816 .getPaintBackgroundColor();
817 String color = itemColor.getRed() + " "
818 + itemColor.getGreen() + " " + itemColor.getBlue();
819 context.getPrimitives().setValue(tokens[2],
820 new SString(color));
821 } else if (tokens[0].equals("getitemcolor")) {
822 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
823 // assertPrimitiveType(tokens[2], 2);
824 Color itemColor = ((Item) context.getPointers()
825 .getVariable(tokens[1]).getValue()).getPaintColor();
826 String color = itemColor.getRed() + " "
827 + itemColor.getGreen() + " " + itemColor.getBlue();
828 context.getPrimitives().setValue(tokens[2],
829 new SString(color));
830 } else if (tokens[0].equals("getitemtext")) {
831 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
832 Item item = ((Item) context.getPointers().getVariable(
833 tokens[1]).getValue());
834 context.getPrimitives().setValue(
835 tokens[2],
836 new SString((item instanceof Text) ? ((Text) item)
837 .getTextNoList() : ""));
838 } else
839 throw new Exception("Unsupported getItem command: "
840 + code.toString());
841
842 return Status.OK;
843 } else if (tokens[0].equals("getstrchar")) {
844 assertExactParametreCount(tokens, 3);
845 String s = context.getPrimitives().getStringValue(tokens[1]);
846 int pos = (int) context.getPrimitives().getIntegerValue(
847 tokens[2]);
848
849 context.getPrimitives().setValue(tokens[3],
850 new SCharacter(s.charAt(pos - 1)));
851 return Status.OK;
852 } else if (tokens[0].equals("getstrlength")) {
853 assertExactParametreCount(tokens, 2);
854 String s = context.getPrimitives().getStringValue(tokens[1]);
855
856 context.getPrimitives().setValue(tokens[2],
857 new SInteger(s.length()));
858 return Status.OK;
859 } else if (tokens[0].equals("getelapsedtime")) {
860 assertExactParametreCount(tokens, 1);
861 context.getPrimitives().setValue(tokens[1],
862 new SInteger(AgentStats.getMilliSecondsElapsed()));
863 return Status.OK;
864 }
865 } else if (tokens[0].equals("or")) {
866 for (int i = 1; i < tokens.length - 1; i++) {
867 if (Primitives.isPrimitive(tokens[i])) {
868 if (context.getPrimitives().getBooleanValue(tokens[i])) {
869 context.getPrimitives().setValue(
870 tokens[tokens.length - 1], new SBoolean(true));
871 return Status.OK;
872 }
873 }
874 }
875 context.getPrimitives().setValue(tokens[tokens.length - 1],
876 new SBoolean(false));
877 return Status.OK;
878 } else if (tokens[0].equals("and")) {
879 for (int i = 1; i < tokens.length - 1; i++) {
880 if (Primitives.isPrimitive(tokens[i])) {
881 if (!context.getPrimitives().getBooleanValue(tokens[i])) {
882 context.getPrimitives().setValue(
883 tokens[tokens.length - 1], new SBoolean(false));
884 return Status.OK;
885 }
886 }
887 }
888 context.getPrimitives().setValue(tokens[tokens.length - 1],
889 new SBoolean(true));
890 return Status.OK;
891 } else if (tokens[0].equals("messagelnitem")
892 || tokens[0].equals("messagelineitem")) {
893 String itemVar = DEFAULT_ITEM;
894
895 if (tokens.length > 1) {
896 assertExactParametreCount(tokens, 1);
897 itemVar = tokens[1];
898 assertVariableType(itemVar, 1, SPointer.itemPrefix);
899 }
900 Item message = (Item) context.getPointers().getVariable(itemVar)
901 .getValue();
902 try {
903 FrameGraphics.DisplayMessage(((Text) message).copy());
904 } catch (NullPointerException e) {
905 // Just ignore not text items!
906 FrameGraphics.DisplayMessage("null");
907 } catch (ClassCastException e) {
908 // Just ignore not text items!
909 FrameGraphics.DisplayMessage(message.toString());
910 } catch (Exception e) {
911 // Just ignore other errors
912 }
913 return Status.OK;
914 } else if (tokens[0].equals("messageln")
915 || tokens[0].equals("messageline")
916 || tokens[0].equals("errorln") || tokens[0].equals("errorline")) {
917 StringBuilder message = new StringBuilder();
918 if (tokens.length == 1) {
919 message.append(context.getPrimitives().getVariable(
920 DEFAULT_STRING).stringValue()
921 + " ");
922 } else {
923 for (int i = 1; i < tokens.length; i++) {
924 if (Primitives.isPrimitive(tokens[i])) {
925 message.append(context.getPrimitives().getVariable(
926 tokens[i]).stringValue()
927 + " ");
928 } else
929 throw new Exception("Illegal parametre: [" + tokens[i]
930 + "] in line " + code.toString());
931 }
932 }
933
934 if (tokens[0].equals("errorln") || tokens[0].equals("errorline"))
935 FrameGraphics.ErrorMessage(message.toString());
936 else
937 FrameGraphics.DisplayMessageAlways(message.toString());
938 return Status.OK;
939 } else if (tokens[0].startsWith("else")) {
940 // if the if statement was false then run the else statement
941 if (lastItemStatus == Status.FalseIf) {
942 // check if it is a one line if statment
943 if (tokens.length > 1) {
944 // put together the one line statement
945 StringBuilder statement = new StringBuilder();
946 for (int i = 1; i < tokens.length; i++)
947 statement.append(tokens[i]).append(' ');
948 // create a copy of the code item to run
949 Text copiedCode = code.copy();
950 copiedCode.setText(statement.toString());
951 return RunItem(copiedCode, context, Status.OK);
952 } else {
953 return RunFrameAndReportError(code, context);
954 }
955 } else if (lastItemStatus == Status.TrueIf) {
956 return Status.OK;
957 }
958 throw new RuntimeException("Else without matching If statement");
959 } else if (tokens[0].startsWith("if")) {
960 Boolean result = null;
961 int parametres = 1;
962 String variable = DEFAULT_ITEM;
963 String ifStatement = tokens[0];
964 // Set the default variable
965 if (tokens.length == 1) {
966 if (ifStatement.equals("if") || ifStatement.equals("ifnot"))
967 variable = DEFAULT_STRING;
968 else if (ifStatement.equals("ifzero")
969 || ifStatement.equals("ifnotzero"))
970 variable = DEFAULT_INTEGER;
971 } else {
972 variable = tokens[1];
973 }
974
975 if (ifStatement.equals("if")) {
976 result = context.getPrimitives().getBooleanValue(variable);
977 } else if (ifStatement.equals("ifnot")) {
978 result = !context.getPrimitives().getBooleanValue(variable);
979 } else if (ifStatement.equals("ifdefined")) {
980 result = context.isDefined(tokens[1]);
981 } else if (ifStatement.equals("ifnotdef")) {
982 result = !context.isDefined(tokens[1]);
983 } else if (ifStatement.equals("ifzero")) {
984 result = context.getPrimitives().getIntegerValue(variable) == 0;
985 } else if (ifStatement.equals("ifnotzero")) {
986 result = context.getPrimitives().getIntegerValue(variable) != 0;
987 } else if (tokens[0].equals("ifeq")) {
988 result = context.equalValues(tokens[1], tokens[2]);
989 parametres = 2;
990 } else if (tokens[0].equals("ifeqnocase")) {
991 result = context.getPrimitives().equalValuesNoCase(tokens[1],
992 tokens[2]);
993 parametres = 2;
994 } else if (tokens[0].equals("ifnoteqnocase")) {
995 result = !context.getPrimitives().equalValuesNoCase(tokens[1],
996 tokens[2]);
997 parametres = 2;
998 } else if (tokens[0].equals("ifnoteq")) {
999 result = !context.equalValues(tokens[1], tokens[2]);
1000 parametres = 2;
1001 } else if (tokens[0].equals("ifless")) {
1002 result = context.getPrimitives().compareValues(tokens[1],
1003 tokens[2]) < 0;
1004 parametres = 2;
1005 } else if (tokens[0].equals("ifgtr")) {
1006 result = context.getPrimitives().compareValues(tokens[1],
1007 tokens[2]) > 0;
1008 parametres = 2;
1009 } else if (tokens[0].equals("ifgeq")) {
1010 result = context.getPrimitives().compareValues(tokens[1],
1011 tokens[2]) >= 0;
1012 parametres = 2;
1013 } else if (tokens[0].equals("ifleq")) {
1014 result = context.getPrimitives().compareValues(tokens[1],
1015 tokens[2]) <= 0;
1016 parametres = 2;
1017 } else {
1018 // assertVariableType(variable, 1, SPointer.itemPrefix);
1019 if (ifStatement.equals("ifannotation")) {
1020 result = ((Item) context.getPointers()
1021 .getVariable(variable).getValue()).isAnnotation();
1022 } else if (ifStatement.equals("iflinked")) {
1023 result = ((Item) context.getPointers()
1024 .getVariable(variable).getValue()).getLink() != null;
1025 } else if (ifStatement.equals("ifactioned")) {
1026 result = ((Item) context.getPointers()
1027 .getVariable(variable).getValue()).getAction() != null;
1028 } else if (ifStatement.equals("ifnotactioned")) {
1029 result = ((Item) context.getPointers()
1030 .getVariable(variable).getValue()).getAction() == null;
1031 } else if (ifStatement.equals("ifbodytext")) {
1032 Item i = (Item) context.getPointers().getVariable(variable)
1033 .getValue();
1034 result = i instanceof Text && !i.isFrameName()
1035 && !i.isFrameTitle();
1036 } else if (ifStatement.equals("ifnotannotation")) {
1037 result = !((Item) context.getPointers().getVariable(
1038 variable).getValue()).isAnnotation();
1039 } else if (ifStatement.equals("ifnotlinked")) {
1040 result = ((Item) context.getPointers()
1041 .getVariable(variable).getValue()).getLink() == null;
1042 } else if (ifStatement.equals("ifnotbodytext")) {
1043 Item i = (Item) context.getPointers().getVariable(variable)
1044 .getValue();
1045 result = !(i instanceof Text) || i.isFrameName()
1046 || i.isFrameTitle();
1047 }
1048 }
1049
1050 if (result == null)
1051 throw new RuntimeException("Invalid If statement");
1052 // Now check if we need to run the code
1053 else if (result) {
1054 Status status;
1055 // check if it is a one line if statment
1056 if (tokens.length > parametres + 1) {
1057 // put together the one line statement
1058 StringBuilder statement = new StringBuilder();
1059 for (int i = parametres + 1; i < tokens.length; i++)
1060 statement.append(tokens[i]).append(' ');
1061 // create a copy of the code item to run
1062 Text copiedCode = code.copy();
1063 copiedCode.setText(statement.toString());
1064 status = RunItem(copiedCode, context, Status.OK);
1065 } else {
1066 status = RunFrameAndReportError(code, context);
1067 }
1068 if (status == Status.OK) {
1069 return Status.TrueIf;
1070 } else {
1071 return status;
1072 }
1073 }
1074 return Status.FalseIf;
1075
1076 } // Look for variable length methods
1077 else if (tokens[0].equals("attachitemtocursor")) {
1078 String itemVar = DEFAULT_ITEM;
1079
1080 if (tokens.length > 1) {
1081 assertExactParametreCount(tokens, 1);
1082 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1083 itemVar = tokens[1];
1084 }
1085 Item item = (Item) context.getPointers().getVariable(itemVar)
1086 .getValue();
1087 FrameMouseActions.pickup(item);
1088 return Status.OK;
1089 } else if (tokens[0].equals("attachstrtocursor")) {
1090 String stringVar = DEFAULT_STRING;
1091
1092 if (tokens.length > 1) {
1093 assertExactParametreCount(tokens, 1);
1094 stringVar = tokens[1];
1095 }
1096 String s = context.getPrimitives().getStringValue(stringVar);
1097 Frame frame = DisplayIO.getCurrentFrame();
1098 Text item = frame.createNewText(s);
1099 FrameMouseActions.pickup(item);
1100 // DisplayIO.repaint();
1101 return Status.OK;
1102 } else if (tokens[0].equals("additemtoframe")) {
1103 String itemVar = DEFAULT_ITEM;
1104 String frameVar = DEFAULT_FRAME;
1105
1106 if (tokens.length > 1) {
1107 assertExactParametreCount(tokens, 2);
1108 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1109 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1110 itemVar = tokens[2];
1111 frameVar = tokens[1];
1112 }
1113 Frame frame = (Frame) context.getPointers().getVariable(frameVar)
1114 .getValue();
1115 Item item = (Item) context.getPointers().getVariable(itemVar)
1116 .getValue();
1117 frame.addItem(item);
1118
1119 return Status.OK;
1120 } else if (tokens[0].equals("connectdots")) {
1121 assertMinParametreCount(tokens, 2);
1122 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1123 assertVariableType(tokens[2], 2, SPointer.itemPrefix);
1124 Dot dot1 = null;
1125 Dot dot2 = null;
1126 try {
1127 dot1 = (Dot) context.getPointers().getVariable(tokens[1])
1128 .getValue();
1129 } catch (Exception e) {
1130 throw new IncorrectTypeException("Dot", 1);
1131 }
1132 try {
1133 dot2 = (Dot) context.getPointers().getVariable(tokens[2])
1134 .getValue();
1135 } catch (Exception e) {
1136 throw new IncorrectTypeException("Dot", 2);
1137 }
1138 Frame frame = dot1.getParent();
1139 frame.addItem(new Line(dot1, dot2, frame.getNextItemID()));
1140 return Status.OK;
1141 } else if (tokens[0].equals("createitem")) {
1142 assertMinParametreCount(tokens, 4);
1143 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1144 assertVariableType(tokens[4], 4, SPointer.itemPrefix);
1145 Frame frame = (Frame) context.getPointers().getVariable(tokens[1])
1146 .getValue();
1147 Item newItem;
1148 int x = (int) context.getPrimitives().getIntegerValue(tokens[2]);
1149 int y = (int) context.getPrimitives().getIntegerValue(tokens[3]);
1150 // check for the option text and action for the new item
1151 if (tokens.length > 5) {
1152 String newText = context.getPrimitives().getStringValue(
1153 tokens[5]);
1154 String newAction = null;
1155 if (tokens.length > 6) {
1156 newAction = context.getPrimitives().getStringValue(
1157 tokens[6]);
1158 }
1159 newItem = frame.addText(x, y, newText, newAction);
1160 } else
1161 // create a point if the optional params are not provided
1162 newItem = frame.addDot(x, y);
1163 context.getPointers().setObject(tokens[4], newItem);
1164
1165 return Status.OK;
1166 } else if (tokens[0].equals("createframe")) {
1167
1168 String framesetName = DEFAULT_STRING;
1169 String frameVar = DEFAULT_FRAME;
1170
1171 if (tokens.length > 1) {
1172 assertMinParametreCount(tokens, 2);
1173 assertVariableType(tokens[2], 2, SPointer.framePrefix);
1174 framesetName = tokens[1];
1175 frameVar = tokens[2];
1176 }
1177
1178 if (tokens.length > 3) {
1179 context.createFrame(framesetName, frameVar, tokens[3]);
1180 } else
1181 context.createFrame(framesetName, frameVar, null);
1182
1183 return Status.OK;
1184 } else if (tokens[0].equals("closeframe")) {
1185 String frameVar = DEFAULT_FRAME;
1186
1187 if (tokens.length > 1) {
1188 assertVariableType(tokens[1], 1, SPointer.framePrefix);
1189 frameVar = tokens[1];
1190 }
1191
1192 if (tokens.length > 2) {
1193 // assertPrimitiveType(tokens[3], 3);
1194 context.closeFrame(frameVar, tokens[3]);
1195 } else
1196 context.closeFrame(frameVar, null);
1197
1198 return Status.OK;
1199 } else if (tokens[0].equals("readframe")
1200 || tokens[0].equals("openframe")) {
1201
1202 String frameName = DEFAULT_STRING;
1203 String frameVar = DEFAULT_FRAME;
1204
1205 if (tokens.length > 1) {
1206 assertMinParametreCount(tokens, 2);
1207 assertVariableType(tokens[2], 2, SPointer.framePrefix);
1208 frameName = tokens[1];
1209 frameVar = tokens[2];
1210 // assertPrimitiveType(frameName, 1);
1211 }
1212
1213 if (tokens.length > 3) {
1214 // assertPrimitiveType(tokens[3], 3);
1215 context.readFrame(frameName, frameVar, tokens[3]);
1216 } else
1217 context.readFrame(frameName, frameVar, null);
1218
1219 return Status.OK;
1220 } else if (tokens[0].equals("readkbdcond")) {
1221
1222 String nextCharVarName = DEFAULT_CHAR;
1223 String wasCharVarName = DEFAULT_BOOLEAN;
1224
1225 if (tokens.length > 1) {
1226 assertMinParametreCount(tokens, 2);
1227 assertVariableType(tokens[2], 2, SPointer.framePrefix);
1228 nextCharVarName = tokens[1];
1229 wasCharVarName = tokens[2];
1230 }
1231
1232 Character nextChar = _KeyStrokes.poll();
1233 boolean hasChar = nextChar != null;
1234 context.getPrimitives().setValue(wasCharVarName,
1235 new SBoolean(hasChar));
1236 if (hasChar)
1237 context.getPrimitives().setValue(nextCharVarName,
1238 new SCharacter(nextChar));
1239
1240 return Status.OK;
1241 } else if (tokens[0].equals("openwritefile")) {
1242 assertVariableType(tokens[1], 1, SString.prefix);
1243 assertVariableType(tokens[2], 2, SPointer.filePrefix);
1244
1245 if (tokens.length > 3) {
1246 assertVariableType(tokens[3], 3, SBoolean.prefix);
1247 context.openWriteFile(tokens[1], tokens[2], tokens[3]);
1248 } else
1249 context.openWriteFile(tokens[1], tokens[2]);
1250
1251 return Status.OK;
1252 } else if (tokens[0].equals("writefile")
1253 || tokens[0].equals("writelinefile")
1254 || tokens[0].equals("writelnfile")) {
1255 assertVariableType(tokens[1], 1, SPointer.filePrefix);
1256
1257 StringBuilder textToWrite = new StringBuilder();
1258 if (tokens.length == 1) {
1259 textToWrite.append(context.getPrimitives().getVariable(
1260 DEFAULT_STRING).stringValue()
1261 + " ");
1262 } else {
1263 for (int i = 2; i < tokens.length; i++) {
1264 if (Primitives.isPrimitive(tokens[i])) {
1265 textToWrite.append(context.getPrimitives().getVariable(
1266 tokens[i]).stringValue());
1267 } else
1268 throw new Exception("Illegal parametre: " + tokens[i]
1269 + " in " + code.toString());
1270 }
1271 }
1272
1273 if (!tokens[0].equals("writefile"))
1274 textToWrite.append('\n');
1275 context.writeFile(tokens[1], textToWrite.toString());
1276
1277 return Status.OK;
1278 } else if (tokens[0].equals("concatstr")) {
1279 assertMinParametreCount(tokens, 3);
1280 String resultVar = tokens[tokens.length - 1];
1281
1282 StringBuilder sb = new StringBuilder();
1283 // loop through all the strings concatenating them
1284 for (int i = 1; i < tokens.length - 1; i++) {
1285 // assertPrimitiveType(tokens[i], i);
1286 sb.append(context.getPrimitives().getStringValue(tokens[i]));
1287 }
1288 context.getPrimitives().setValue(resultVar,
1289 new SString(sb.toString()));
1290 return Status.OK;
1291 } else if (tokens[0].equals("convstrlower")) {
1292 assertExactParametreCount(tokens, 1);
1293 // assertPrimitiveType(tokens[1], 1);
1294 context.getPrimitives().setValue(
1295 tokens[1],
1296 new SString(context.getPrimitives().getStringValue(
1297 tokens[1]).toLowerCase()));
1298 return Status.OK;
1299 } else if (tokens[0].equals("convstrupper")) {
1300 assertExactParametreCount(tokens, 1);
1301 // assertPrimitiveType(tokens[1], 1);
1302 context.getPrimitives().setValue(
1303 tokens[1],
1304 new SString(context.getPrimitives().getStringValue(
1305 tokens[1]).toUpperCase()));
1306 return Status.OK;
1307 } else if (tokens[0].equals("countcharsinstr")) {
1308 assertExactParametreCount(tokens, 3);
1309 String s = context.getPrimitives().getStringValue(tokens[1]);
1310 String pattern = context.getPrimitives().getStringValue(tokens[2]);
1311 int count = countCharsInString(s, pattern);
1312 context.getPrimitives().setValue(tokens[3], new SInteger(count));
1313 return Status.OK;
1314 } else if (tokens[0].equals("countcharsinitem")) {
1315 assertExactParametreCount(tokens, 3);
1316 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1317 Item item = (Item) context.getPointers().getVariable(tokens[1])
1318 .getValue();
1319 String pattern = context.getPrimitives().getStringValue(tokens[2]);
1320 int count = 0;
1321 if (item instanceof Text)
1322 count = countCharsInString(((Text) item).getTextNoList(),
1323 pattern);
1324 context.getPrimitives().setValue(tokens[3], new SInteger(count));
1325 return Status.OK;
1326 } else if (tokens[0].equals("parseframename")) {
1327 assertExactParametreCount(tokens, 4);
1328 String frameName = context.getPrimitives()
1329 .getStringValue(tokens[1]);
1330 String frameSet = "";
1331 int frameNo = -1;
1332 boolean success = true;
1333 try {
1334 frameSet = Conversion.getFrameset(frameName, false);
1335 frameNo = Conversion.getFrameNumber(frameName);
1336 } catch (Exception e) {
1337 success = false;
1338 }
1339 // assertPrimitiveType(tokens[2], 2);
1340 context.getPrimitives().setValue(tokens[2], new SBoolean(success));
1341
1342 // assertPrimitiveType(tokens[3], 3);
1343 context.getPrimitives().setValue(tokens[3], new SString(frameSet));
1344
1345 // assertPrimitiveType(tokens[4], 4);
1346 context.getPrimitives().setValue(tokens[4], new SInteger(frameNo));
1347
1348 return Status.OK;
1349 } else if (tokens[0].equals("parsestr")) {
1350 assertMinParametreCount(tokens, 2);
1351 // assertPrimitiveType(tokens[1], 1);
1352 // assertPrimitiveType(tokens[2], 2);
1353
1354 String s = context.getPrimitives().getStringValue(tokens[1]);
1355
1356 String separator = context.getPrimitives()
1357 .getStringValue(tokens[2]);
1358
1359 String[] split = s.split(separator, tokens.length - 4);
1360
1361 if (tokens.length > 3) {
1362 // assertPrimitiveType(tokens[3], 3);
1363 int count = split.length;
1364 // if the string is not blank and its got a remainder then
1365 // decrease the count by 1 to account for the remainder
1366 if (split.length != 0 && split.length > tokens.length - 5)
1367 count--;
1368
1369 context.getPrimitives()
1370 .setValue(tokens[3], new SInteger(count));
1371
1372 if (tokens.length > 4) {
1373 // Set the remainder string
1374 // assertPrimitiveType(tokens[4], 4);
1375 if (split.length < tokens.length - 4)
1376 context.getPrimitives().setValue(tokens[4],
1377 new SString());
1378 else
1379 context.getPrimitives().setValue(tokens[4],
1380 new SString(split[split.length - 1]));
1381
1382 // Set the strings for each of the vars
1383 if (tokens.length > 5) {
1384 for (int i = 5; i < tokens.length; i++) {
1385 // assertPrimitiveType(tokens[i], i);
1386 if (split.length < i - 4)
1387 context.getPrimitives().setValue(tokens[i],
1388 new SString());
1389 else
1390 context.getPrimitives().setValue(tokens[i],
1391 new SString(split[i - 5]));
1392 }
1393 }
1394 }
1395 }
1396 return Status.OK;
1397 } else if (tokens[0].equals("stripstr")) {
1398 assertExactParametreCount(tokens, 2);
1399 String s = context.getPrimitives().getStringValue(tokens[1]);
1400 String charsToStrip = context.getPrimitives().getStringValue(
1401 tokens[2]);
1402 for (int i = 0; i < charsToStrip.length(); i++)
1403 s = s.replaceAll(charsToStrip.substring(i, i + 1), "");
1404 context.getPrimitives().setValue(tokens[1], new SString(s));
1405 return Status.OK;
1406 } else if (tokens[0].equals("subststr")) {
1407 assertExactParametreCount(tokens, 3);
1408 String oldString = context.getPrimitives()
1409 .getStringValue(tokens[2]);
1410 String newString = context.getPrimitives()
1411 .getStringValue(tokens[3]);
1412 String result = context.getPrimitives().getStringValue(tokens[1]);
1413 result = result.replaceAll(oldString, newString);
1414 context.getPrimitives().setValue(tokens[1], new SString(result));
1415 return Status.OK;
1416 } else if (tokens[0].equals("substr")) {
1417 assertExactParametreCount(tokens, 4);
1418 int startPos = (int) context.getPrimitives().getIntegerValue(
1419 tokens[2]) - 1;
1420 int length = (int) context.getPrimitives().getIntegerValue(
1421 tokens[3]);
1422 String s = context.getPrimitives().getStringValue(tokens[1]);
1423 String result;
1424 if (startPos + length < s.length())
1425 result = s.substring(startPos, startPos + length);
1426 else
1427 result = s.substring(startPos);
1428 context.getPrimitives().setValue(tokens[4], new SString(result));
1429 return Status.OK;
1430 } else if (tokens[0].equals("pause")) {
1431 String lengthVar = DEFAULT_REAL;
1432
1433 if (tokens.length > 1) {
1434 assertExactParametreCount(tokens, 1);
1435 lengthVar = tokens[1];
1436 }
1437
1438 double time = context.getPrimitives().getDoubleValue(lengthVar);
1439 for (int i = 0; i < time * 10; i++) {
1440 Thread.yield();
1441 Thread.sleep(100);
1442 }
1443 return Status.OK;
1444 } else if (tokens[0].equals("glidecursorto")) {
1445 assertMinParametreCount(tokens, 2);
1446 int finalX = (int) context.getPrimitives().getIntegerValue(
1447 tokens[1]);
1448 int finalY = (int) context.getPrimitives().getIntegerValue(
1449 tokens[2]);
1450 int milliseconds = 1000;
1451 if (tokens.length > 3)
1452 milliseconds = (int) (context.getPrimitives().getDoubleValue(
1453 tokens[3]) * 1000);
1454
1455 int initialX = DisplayIO.getMouseX();
1456 int initialY = DisplayIO.getMouseY();
1457
1458 final int timeInterval = 40;
1459
1460 int deltaX = (int) (finalX - initialX);
1461 int deltaY = (int) (finalY - initialY);
1462
1463 int intervals = milliseconds / timeInterval;
1464 for (double i = 0; i < intervals; i++) {
1465 int newX = initialX + (int) (deltaX * i / intervals);
1466 int newY = initialY + (int) (deltaY * i / intervals);
1467 Thread.yield();
1468 Thread.sleep(timeInterval);
1469 DisplayIO.setCursorPosition(newX, newY);
1470 // DisplayIO.repaint();
1471 }
1472 // Thread.yield();
1473 Thread.sleep(milliseconds % timeInterval);
1474 DisplayIO.setCursorPosition(finalX, finalY);
1475 return Status.OK;
1476 }
1477 // Now look for fixed parametre statements
1478 else if (tokens.length == 1) {
1479 if (tokens[0].equals(EXIT_TEXT)) {
1480 return Status.Exit;
1481 } else if (tokens[0].equals(LOOP_TEXT)) {
1482 Status status = Status.OK;
1483 // Keep looping until break or exit occurs
1484 while (status == Status.OK || status == Status.Continue)
1485 status = RunFrameAndReportError(code, context);
1486 if (status == Status.Continue || status == Status.Break)
1487 status = Status.OK;
1488 return status;
1489 } else if (tokens[0].equals(CONTINUE_TEXT)) {
1490 return Status.Continue;
1491 } else if (tokens[0].equals(BREAK_TEXT)) {
1492 return Status.Break;
1493 } else if (tokens[0].equals(RETURN_TEXT)) {
1494 return Status.Return;
1495 } else if (tokens[0].equals("pressleftbutton")) {
1496 DisplayIO.pressMouse(InputEvent.BUTTON1_MASK);
1497 return Status.OK;
1498 } else if (tokens[0].equals("pressmiddlebutton")) {
1499 DisplayIO.pressMouse(InputEvent.BUTTON2_MASK);
1500 return Status.OK;
1501 } else if (tokens[0].equals("pressrightbutton")) {
1502 DisplayIO.pressMouse(InputEvent.BUTTON3_MASK);
1503 return Status.OK;
1504 } else if (tokens[0].equals("releaseleftbutton")) {
1505 DisplayIO.releaseMouse(InputEvent.BUTTON1_MASK);
1506 return Status.OK;
1507 } else if (tokens[0].equals("releasemiddlebutton")) {
1508 DisplayIO.releaseMouse(InputEvent.BUTTON2_MASK);
1509 return Status.OK;
1510 } else if (tokens[0].equals("releaserightbutton")) {
1511 DisplayIO.releaseMouse(InputEvent.BUTTON3_MASK);
1512 return Status.OK;
1513 } else if (tokens[0].equals("clickleftbutton")) {
1514 DisplayIO.clickMouse(InputEvent.BUTTON1_MASK);
1515 return Status.OK;
1516 } else if (tokens[0].equals("clickmiddlebutton")) {
1517 DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
1518 return Status.OK;
1519 } else if (tokens[0].equals("clickrightbutton")) {
1520 DisplayIO.clickMouse(InputEvent.BUTTON3_MASK);
1521 return Status.OK;
1522 } else if (tokens[0].equals("repaint")) {
1523 DisplayIO.repaint();
1524 return Status.OK;
1525 }
1526
1527 if (tokens[0].equals("add")) {
1528 context.getPrimitives().add(DEFAULT_INTEGER);
1529 } else if (tokens[0].equals("subtract")) {
1530 context.getPrimitives().subtract(DEFAULT_INTEGER);
1531 } else
1532 throw new RuntimeException("Invalid statement:");
1533 return Status.OK;
1534 } else if (tokens.length == 2) {
1535 if (tokens[0].equals("closewritefile")) {
1536 assertVariableType(tokens[1], 1, SPointer.filePrefix);
1537 context.closeWriteFile(tokens[1]);
1538
1539 return Status.OK;
1540 }
1541
1542 if (Primitives.isPrimitive(tokens[1])) {
1543 if (tokens[0].equals("add")) {
1544 context.getPrimitives().add(tokens[1]);
1545 } else if (tokens[0].equals("subtract")) {
1546 context.getPrimitives().subtract(tokens[1]);
1547 } else
1548 throw new RuntimeException("Invalid statement:");
1549 return Status.OK;
1550 }
1551 } else if (tokens.length == 3) {
1552 if (tokens[0].equals("foreach")) {
1553 assertVariableType(tokens[1], 1, SPointer.itemPrefix);
1554 assertVariableType(tokens[2], 2, SPointer.framePrefix);
1555 Frame currFrame = (Frame) context.getPointers().getVariable(
1556 tokens[2]).getValue();
1557 // Create the ip variable
1558 for (Item i : currFrame.getItems()) {
1559 context.getPointers().setObject(tokens[1], i);
1560 Status status = RunFrameAndReportError(code, context);
1561 // check if we need to exit this loop because of
1562 // statements in
1563 // the code that was run
1564 if (status == Status.Exit || status == Status.Return)
1565 return status;
1566 else if (status == Status.Break)
1567 return Status.OK;
1568 }
1569 return Status.OK;
1570 }
1571
1572 if (Primitives.isPrimitive(tokens[1])
1573 && Primitives.isPrimitive(tokens[2])) {
1574 if (tokens[0].equals("movecursorto")) {
1575 assertExactParametreCount(tokens, 2);
1576 int x = (int) context.getPrimitives().getIntegerValue(
1577 tokens[1]);
1578 int y = (int) context.getPrimitives().getIntegerValue(
1579 tokens[2]);
1580 DisplayIO.setCursorPosition(x, y);
1581 return Status.OK;
1582 } else if (tokens[0].equals("not")) {
1583 context.getPrimitives().not(tokens[1], tokens[2]);
1584 } else if (tokens[0].equals("exp")) {
1585 context.getPrimitives().exp(tokens[1], tokens[2]);
1586 } else if (tokens[0].equals("log")) {
1587 context.getPrimitives().log(tokens[1], tokens[2]);
1588 } else if (tokens[0].equals("log10")) {
1589 context.getPrimitives().log10(tokens[1], tokens[2]);
1590 } else if (tokens[0].equals("sqrt")) {
1591 context.getPrimitives().sqrt(tokens[1], tokens[2]);
1592 } else if (tokens[0].equals("add")) {
1593 context.getPrimitives().add(tokens[1], tokens[2]);
1594 } else if (tokens[0].equals("subtract")) {
1595 context.getPrimitives().subtract(tokens[1], tokens[2]);
1596 } else if (tokens[0].equals("multiply")) {
1597 context.getPrimitives().multiply(tokens[1], tokens[2]);
1598 } else if (tokens[0].equals("divide")) {
1599 context.getPrimitives().divide(tokens[1], tokens[2]);
1600 } else
1601 throw new RuntimeException("Invalid statement:");
1602 return Status.OK;
1603 }
1604 } else if (tokens.length == 4) {
1605 if (Primitives.isPrimitive(tokens[1])
1606 && Primitives.isPrimitive(tokens[2])
1607 && Primitives.isPrimitive(tokens[3])) {
1608 if (tokens[0].equals("add")) {
1609 context.getPrimitives()
1610 .add(tokens[1], tokens[2], tokens[3]);
1611 } else if (tokens[0].equals("subtract")) {
1612 context.getPrimitives().subtract(tokens[1], tokens[2],
1613 tokens[3]);
1614 } else if (tokens[0].equals("divide")) {
1615 context.getPrimitives().divide(tokens[1], tokens[2],
1616 tokens[3]);
1617 } else if (tokens[0].equals("multiply")) {
1618 context.getPrimitives().multiply(tokens[1], tokens[2],
1619 tokens[3]);
1620 } else if (tokens[0].equals("modulo")) {
1621 context.getPrimitives().modulo(tokens[1], tokens[2],
1622 tokens[3]);
1623 } else if (tokens[0].equals("power")) {
1624 context.getPrimitives().power(tokens[1], tokens[2],
1625 tokens[3]);
1626 } else
1627 throw new Exception("Statement not found: " + tokens[0]
1628 + " in " + code.toString());
1629 return Status.OK;
1630 }
1631 }
1632 throw new RuntimeException("Unknown statement: ");
1633 }
1634
1635 public static int countCharsInString(String s, String pattern) {
1636 String newString = s;
1637 int count = -1;
1638 do {
1639 count++;
1640 s = newString;
1641 newString = s.replaceFirst(pattern, "");
1642 } while (s.length() != newString.length());
1643
1644 return count;
1645 }
1646
1647 public static void assertVariableType(String varName, int no, String type)
1648 throws Exception {
1649 if (!varName.startsWith(type))
1650 throw new IncorrectTypeException(type, no);
1651 }
1652
1653 /*
1654 * public static void assertPrimitiveType(String varName, int no) throws
1655 * Exception { if (!Primitives.isPrimitive(varName)) throw new
1656 * IncorrectTypeException("primitive", no); }
1657 */
1658
1659 public static void assertMinParametreCount(String[] tokens,
1660 int minParametres) throws Exception {
1661 if (tokens.length - 1 < minParametres)
1662 throw new BelowMinParametreCountException(minParametres);
1663 }
1664
1665 public static void assertExactParametreCount(String[] tokens,
1666 int parametreCount) throws Exception {
1667 if (tokens.length - 1 != parametreCount)
1668 throw new IncorrectParametreCountException(parametreCount);
1669 }
1670}
Note: See TracBrowser for help on using the repository browser.