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.millscript.alert.Alerts;
25 import org.millscript.millscript.datatypes.SpiceClass;
26 import org.millscript.millscript.functions.SlotFunction;
27 import org.millscript.millscript.vm.Machine;
28
29 /**
30 * This class implements a <code>class</code> action. It generates the class
31 * object which can then be used in MillScript.
32 *
33 * @see org.millscript.millscript.syntax.SpiceClassSyntax
34 * @see org.millscript.millscript.expr.SpiceClassExpr
35 * @see org.millscript.millscript.functions.SpiceClassConstructorFunction
36 */
37 public final class SpiceClassAction extends Action {
38
39 /**
40 * The name of the class this class expression defines.
41 */
42 private final String className;
43
44 /**
45 * An array of the slot functions used to access each slot in this spice
46 * class. The elements in this array are used in conjunction with the
47 * relevant element in the slot initial value array.
48 */
49 private final SlotFunction[] slotFunctions;
50
51 /**
52 * An array of the slot initial value actions. These need to be passed to
53 * the class constructor function, as they can't be actioned until the
54 * class instance has been created. The elements in this array are used in
55 * conjunction with the relevant element in the slot initial value array.
56 */
57 private final Action[] slotInitialValues;
58
59 /**
60 * The action which returns the parent Spice class. This may be
61 * <code>null</code> in which case there is no parent.
62 */
63 private final Action parentAction;
64
65 /**
66 * Constructs a new <code>class</code> action.
67 *
68 * @param nm the name of the class we are defining
69 * @param pa the action for the parent Spice class
70 * @param sf an array of slot accessor functions
71 * @param i an array of slot inital value actions
72 */
73 public SpiceClassAction( final String nm, final Action pa, final SlotFunction[] sf, final Action[] i ) {
74 this.className = nm;
75 this.slotFunctions = sf;
76 this.slotInitialValues = i;
77 this.parentAction = pa;
78 }
79
80 /**
81 * @see org.millscript.millscript.action.Action#action(org.millscript.millscript.vm.Machine)
82 */
83 @Override
84 public void action( final Machine mc ) {
85 SpiceClass parent = null;
86 if ( parentAction != null ) {
87 int before = mc.getCount();
88 parentAction.act( mc );
89 int after = mc.getCount();
90 if ( after - before == 1 ) {
91 parent = mc.popSpiceClass();
92 } else {
93 throw(
94 Alerts.eval(
95 "Too many parent classes",
96 "A Spice class can only inherit from a single parent(at the moment)"
97 ).mishap()
98 );
99 }
100 }
101
102 mc.pushObject(
103 new SpiceClass( className, parent, slotFunctions, slotInitialValues )
104 );
105 }
106
107 }