1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.millscript.millscript.action;
23
24 import org.millscript.commons.alert.Alert;
25 import org.millscript.commons.alert.AlertOrigin;
26 import org.millscript.commons.alert.EscapeException;
27 import org.millscript.millscript.alert.Alerts;
28 import org.millscript.millscript.alert.Phases;
29 import org.millscript.millscript.vm.Machine;
30
31 /**
32 * This class represents the base class of all actions in MillScript. As such
33 * all actions must extend this class, or one of it's sub-classes. An action
34 * is the result of compiling an expression and is the final stage of
35 * compilation.
36 *
37 * @see org.millscript.millscript.expr.Expr
38 * @see org.millscript.millscript.syntax.Syntax
39 */
40 public abstract class Action implements AlertOrigin {
41
42 /**
43 * This originating line number in the origin, where this action was
44 * compiled from.
45 */
46 private int lineNumber = -1;
47
48 /**
49 * The origin of the expression this action was compiled from.
50 */
51 private String origin = null;
52
53 /**
54 * This method wraps <code>action</code>, to perform general purpose
55 * exception handling. Generally this method would be called to perform
56 * an action, rather than <code>action</code> directly.
57 *
58 * @param mc the machine to perform this action on
59 */
60 public final void act( final Machine mc ) {
61 try {
62 action( mc );
63 } catch ( EscapeException ex ) {
64
65 throw ex;
66 } catch ( Alert ex ) {
67
68 throw(
69 ex.decorate( mc ).origin( this ).setPhase( Phases.EVAL ).remishap()
70 );
71 } catch ( Exception ex ) {
72
73
74 final Alert alert = Alerts.eval(
75 "An exception has aborted execution",
76 null
77 );
78
79 alert.culprit( "exception", ex );
80
81 String reason = ex.getMessage();
82 if ( reason != null ) {
83 alert.culprit( "reason", reason );
84 }
85
86
87 throw(
88 alert.decorate( mc ).origin( this ).setParentThrowable( ex ).mishap()
89 );
90 }
91 }
92
93 /**
94 * Returns the last object pushed onto the stack, after performing this
95 * action. This is the equivalent of performing the <code>act</code> method
96 * and poping a result off the machine's stack.
97 *
98 * @param mc the machine to perform this action on
99 * @return the object poped off the machines stack after performing this
100 * action
101 */
102 public final Object act1( final Machine mc ) {
103 act( mc );
104 return mc.popObject();
105 }
106
107 /**
108 * Performs this action, on the specified machine. This method must be
109 * implemented in sub-classes to perform the required actions.
110 *
111 * @param mc the machine to perform this action on
112 */
113 public abstract void action( final Machine mc );
114
115 /**
116 * @see org.millscript.commons.alert.AlertOrigin#getLineNumber()
117 */
118 public int getLineNumber() {
119 return lineNumber;
120 }
121
122 /**
123 * @see org.millscript.commons.alert.AlertOrigin#getOrigin()
124 */
125 public String getOrigin() {
126 return origin;
127 }
128
129 /**
130 * Returns the boolean value of the last object pushed onto the stack,
131 * after performing this action. This is roughly equivalent to the
132 * <code>act1</code> method, but it requires that the last value on the
133 * stack is a <code>Boolean</code>.
134 *
135 * @param mc the machine to perform this action on
136 * @return the boolean value of the last object on the stack
137 */
138 public final boolean predAct( final Machine mc ) {
139 act( mc );
140 Object x = mc.popObject();
141 if ( x instanceof Boolean ) {
142 return ((Boolean)x).booleanValue();
143 } else {
144 throw(
145 Alerts.eval( "Predicate returned non-boolean", null ).culprit( "object", x ).mishap()
146 );
147 }
148 }
149
150 /**
151 * @see org.millscript.commons.alert.AlertOrigin#setContext(java.lang.String, int)
152 */
153 public final void setContext( final String fname, final int ln ) {
154 this.origin = fname;
155 this.lineNumber = ln;
156 }
157
158 /**
159 * @see org.millscript.commons.alert.AlertOrigin#setLineNumber(int)
160 */
161 public void setLineNumber( final int n ) {
162 this.lineNumber = n;
163 }
164
165 /**
166 * @see org.millscript.commons.alert.AlertOrigin#setOrigin(java.lang.String)
167 */
168 public void setOrigin( final String o ) {
169 this.origin = o;
170 }
171
172 }