View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2004-2005 Kevin Rogers
4   // Copyright (C) 2005 Kevin Rogers
5   //
6   // This file is part of MillScript.
7   //
8   // MillScript is free software; you can redistribute it and/or modify it under
9   // the terms of the GNU General Public License as published by the Free
10  // Software Foundation; either version 2 of the License, or (at your option)
11  // any later version.
12  //
13  // MillScript is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  // more details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA  02111-1307  USA
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         // Push a new class object onto the stack.
102         mc.pushObject(
103             new SpiceClass( className, parent, slotFunctions, slotInitialValues )
104         );
105     }
106 
107 }