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.VarAction;
26 import org.millscript.millscript.action.VarAlienAction;
27 import org.millscript.millscript.action.VarGlobalAction;
28 import org.millscript.millscript.action.VarLocalAction;
29 import org.millscript.millscript.alert.Alerts;
30 import org.millscript.millscript.vm.CompilerState;
31
32 import java.util.Stack;
33
34 /**
35 * This class implements a variable declaration expression. This can declare
36 * new variables and constants.
37 *
38 * @see org.millscript.millscript.syntax.VarSyntax
39 * @see VarAlienAction
40 * @see VarGlobalAction
41 * @see VarLocalAction
42 */
43 public final class VarExpr extends Expr< VarAction > {
44
45 /**
46 * Boolean flag indicating if this new variable is a constant or not.
47 */
48 private final boolean isConst;
49
50 /**
51 * The new variable name expression.
52 */
53 private final NameExpr name;
54
55 /**
56 * The new variables value expression.
57 */
58 private final Expr< ? > value;
59
60 /**
61 * Creates a new variable expression, to declare a variable/constant, with
62 * the specified name and value. The value expression must return a single
63 * result.
64 *
65 * @param isconst <code>true</code> if this expression declares a new
66 * constant, <code>false</code> otherwise.
67 * @param a the name expression for the declared variable
68 * @param b the value expression for the declared variable
69 */
70 public VarExpr( final boolean isconst, final NameExpr a, final Expr< ? > b ) {
71 isConst = isconst;
72 name = a;
73 value = CheckExpr.make( b );
74 }
75
76 /**
77 * @see org.millscript.millscript.expr.Expr#compileIt()
78 */
79 @Override
80 public VarAction compileIt() {
81 Action v = value.compile();
82 Ident id = name.getIdent();
83 if ( id instanceof GlobalIdent ) {
84 return new VarGlobalAction( id, v );
85 } else if ( id instanceof LocalIdent ) {
86 if ( id.isAlien() ) {
87 return new VarAlienAction( id, v );
88 } else {
89 return new VarLocalAction( id, v );
90 }
91 } else {
92 throw(
93 Alerts.fault( "Unknown type of ident" ).mishap()
94 );
95 }
96 }
97
98 /**
99 * Returns the declared variables name expression.
100 *
101 * @return a {@link NameExpr} for the declared variables name.
102 */
103 NameExpr getVar() {
104 return name;
105 }
106
107 /**
108 * @see org.millscript.millscript.expr.Expr#resolve(org.millscript.millscript.vm.CompilerState)
109 */
110 @Override
111 public void resolve( final CompilerState state ) {
112
113
114
115 if ( state.getIsProtected( name.getName() ) ) {
116 throw(
117 Alerts.compile(
118 "Trying to redeclare a protected variable",
119 "Most built-ins are protected against accidental assignment"
120 ).culprit( "name", name.getName() ).mishap()
121 );
122 }
123
124 Stack< Expr > scopes = state.getScopes();
125
126 if ( scopes.size() == 0 ) {
127
128 name.declareGlobal( state, isConst );
129 } else {
130
131
132 if ( scopes.peek() instanceof Block ) {
133
134
135 Block b = (Block)scopes.peek();
136 b.setIsUsed();
137 }
138 scopes.push( name );
139 name.declareLocal( isConst );
140 }
141 this.value.resolve( state );
142 }
143
144 /**
145 * @see org.millscript.millscript.expr.Expr#showComponents(int)
146 */
147 @Override
148 void showComponents( final int n ) {
149 this.name.show( n );
150 this.value.show( n );
151 }
152
153 }