View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2004 Open World Ltd
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.expr;
23  
24  import org.millscript.millscript.action.Action;
25  import org.millscript.millscript.action.AssignAction;
26  import org.millscript.millscript.action.AssignAlienAction;
27  import org.millscript.millscript.action.AssignGlobalAction;
28  import org.millscript.millscript.action.AssignLocalAction;
29  import org.millscript.millscript.alert.Alerts;
30  import org.millscript.millscript.vm.CompilerState;
31  
32  /**
33   * This class implements an assign expression. This expression will never return
34   * any results.
35   *
36   * @see org.millscript.millscript.syntax.AssignSyntax
37   * @see ApplyUpdaterExpr
38   * @see AssignAlienAction
39   * @see AssignGlobalAction
40   * @see AssignLocalAction
41   */
42  public final class AssignExpr extends Expr< AssignAction > implements ZeroResults {
43  
44      /**
45       * Returns an expression to assign the result of the right hand side
46       * expression to the result of the left hand side expression. This is
47       * required to handle the situation where the left hand side is a function,
48       * and we have to apply the updater for the function, rather than assign to
49       * it.
50       *
51       * @param   l   the expression to assign to, this should be an
52       *              {@link ApplyExpr} or {@link NameExpr}
53       * @param   r   the expression to assign from
54       * @return  an {@link ApplyUpdaterExpr} if the left hand side is an
55       *          {@link ApplyExpr}, otherwise an {@link AssignExpr}
56       */
57      public static Expr make( final Expr l, final Expr r ) {
58          if ( l instanceof ApplyExpr ) {
59              Expr fun = ((ApplyExpr)l).getFun();
60              Expr args = ((ApplyExpr)l).getArgs();
61              return new ApplyUpdaterExpr( fun, args, r );
62          } else if ( l instanceof NameExpr ) {
63              return new AssignExpr( (NameExpr) l, r );
64          } else {
65              throw(
66                  Alerts.compile(
67                      "Illegal expression on left hand side of assignment",
68                      "Only single name expressions are allowed(at the moment!)"
69                  ).
70                  culprit( "left hand side", l ).
71                  culprit( "right hand side", r ).
72                  mishap()
73              );
74          }
75      }
76  
77      /**
78       * The left hand side expression, which we will assign to.
79       */
80      private final NameExpr lhs;
81  
82      /**
83       * The right hand side expression, generating a single result to assign
84       * from.
85       */
86      private final Expr< ? > rhs;
87  
88      /**
89       * Creates a new assign expression for the specified name and value
90       * expressions.
91       *
92       * @param   l   the name expression to assign to
93       * @param   r   the value expression to assign from, which should return a
94       *              single result
95       */
96      public AssignExpr( final NameExpr l, final Expr< ? > r ) {
97          lhs = l;
98          rhs = CheckExpr.make( r );
99      }
100 
101     /**
102      * @see org.millscript.millscript.expr.Expr#compileIt()
103      */
104     @Override
105     public AssignAction compileIt() {
106         Ident id = lhs.getIdent();
107         if ( id instanceof LocalIdent ) {
108             Action rhsc = rhs.compile();
109             if ( id.isAlien() ) {
110                 return new AssignAlienAction( id, rhsc );
111             } else {
112                 return new AssignLocalAction( id, rhsc );
113             }
114         } else if ( id instanceof GlobalIdent ) {
115             return new AssignGlobalAction( id, rhs.compile() );
116         } else {
117             throw(
118                 Alerts.fault( "Unknown ident type" ).mishap()
119             );
120         }
121     }
122 
123     /**
124      * @see org.millscript.millscript.expr.Expr#resolve(org.millscript.millscript.vm.CompilerState)
125      */
126     @Override
127     public void resolve( final CompilerState state ) {
128         this.lhs.resolve( state );
129         this.rhs.resolve( state );
130     }
131 
132     /**
133      * @see org.millscript.millscript.expr.Expr#showComponents(int)
134      */
135     @Override
136     void showComponents( final int n ) {
137         this.lhs.show( n );
138         this.rhs.show( n );
139     }
140 
141 }