2001-11-20 Ravi Pratap <ravi@ximian.com>
[mono.git] / mcs / mcs / constant.cs
1 //
2 // constant.cs: Constant expressions and constant folding.
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.
8 //
9 //
10
11 namespace Mono.CSharp {
12
13         using System;
14         using System.Reflection;
15         using System.Reflection.Emit;
16         using System.Collections;
17
18
19         public class Constant : Expression {
20
21                 public readonly string     Name;
22                 public Expression Expr;
23                 public readonly string     ConstantType;
24                 public Attributes  OptAttributes;
25                 
26                 int        mod_flags;
27
28                 Location Location;
29                 FieldBuilder FieldBuilder;
30
31                 public const int AllowedModifiers =
32                         Modifiers.NEW |
33                         Modifiers.PUBLIC |
34                         Modifiers.PROTECTED |
35                         Modifiers.INTERNAL |
36                         Modifiers.PRIVATE;
37
38                 public Constant (string constant_type, string name, Expression expr, int mod_flags,
39                                  Attributes attrs, Location loc)
40                 {
41                         this.ConstantType = constant_type;
42                         this.Name = name;
43                         this.Expr = expr;
44                         this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
45                         this.Location = loc;
46                         OptAttributes = attrs;
47                 }
48
49                 public FieldAttributes FieldAttr {
50                         get {
51                                 return FieldAttributes.Literal | FieldAttributes.Static |
52                                         Modifiers.FieldAttr (mod_flags) ;
53                         }
54                 }
55
56                 public int ModFlags {
57                         get {
58                                 return mod_flags;
59                         }
60                 }
61
62                 public override Expression DoResolve (EmitContext ec)
63                 {
64                         // FIXME: implement
65                         return this;
66                 }
67
68                 public override void Emit (EmitContext ec)
69                 {
70                         throw new Exception ("Unimplemented");
71                 }
72                        
73                 /// <summary>
74                 ///   Defines the constant in the @parent
75                 /// </summary>
76                 public void Define (TypeContainer parent)
77                 {
78                         type = parent.LookupType (ConstantType, true);
79
80                         if (type == null)
81                                 return;
82                         
83                         if (!TypeManager.IsBuiltinType (type) && (!type.IsSubclassOf (TypeManager.enum_type))) {
84                                 Report.Error (-3, "Constant type is not valid (only system types are allowed)");
85                                 return;
86                         }
87                         
88                         FieldBuilder = parent.TypeBuilder.DefineField (Name, type, FieldAttr);
89                         
90                 }
91
92                 /// <summary>
93                 ///  Emits the field value by evaluating the expression
94                 /// </summary>
95                 public void EmitConstant (TypeContainer parent)
96                 {
97                         if (FieldBuilder == null)
98                                 return;
99                         
100                         EmitContext ec = new EmitContext (parent, null, type, ModFlags);
101
102                         Expr = Expression.Reduce (ec, Expr);
103
104                         if (!(Expr is Literal)) {
105                                 Report.Error (150, Location, "A constant value is expected");
106                                 return;
107                         }
108
109                         object val = ((Literal) Expr).GetValue ();
110
111                         FieldBuilder.SetConstant (val);
112
113                         TypeManager.RegisterField (FieldBuilder, val);
114                         
115                         return;
116                 }
117         }
118 }
119
120