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.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 }