2001-11-28 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 readonly string     ConstantType;
23                 public Expression Expr;
24                 public Attributes  OptAttributes;
25                 
26                 int mod_flags;
27                 Location Location;
28                 public FieldBuilder FieldBuilder;
29
30                 public const int AllowedModifiers =
31                         Modifiers.NEW |
32                         Modifiers.PUBLIC |
33                         Modifiers.PROTECTED |
34                         Modifiers.INTERNAL |
35                         Modifiers.PRIVATE;
36
37                 public Constant (string constant_type, string name, Expression expr, int mod_flags,
38                                  Attributes attrs, Location loc)
39                 {
40                         this.ConstantType = constant_type;
41                         this.Name = name;
42                         this.Expr = expr;
43                         this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
44                         this.Location = loc;
45                         OptAttributes = attrs;
46                 }
47
48                 public FieldAttributes FieldAttr {
49                         get {
50                                 return FieldAttributes.Literal | FieldAttributes.Static |
51                                         Modifiers.FieldAttr (mod_flags) ;
52                         }
53                 }
54
55                 public int ModFlags {
56                         get {
57                                 return mod_flags;
58                         }
59                 }
60
61                 public override Expression DoResolve (EmitContext ec)
62                 {
63                         // FIXME: implement
64                         return this;
65                 }
66
67                 public override void Emit (EmitContext ec)
68                 {
69                         throw new Exception ("Unimplemented");
70                 }
71                        
72                 /// <summary>
73                 ///   Defines the constant in the @parent
74                 /// </summary>
75                 public void Define (TypeContainer parent)
76                 {
77                         type = parent.LookupType (ConstantType, true);
78
79                         if (type == null)
80                                 return;
81                         
82                         if (!TypeManager.IsBuiltinType (type) && (!type.IsSubclassOf (TypeManager.enum_type))) {
83                                 Report.Error (-3, "Constant type is not valid (only system types are allowed)");
84                                 return;
85                         }
86                         
87                         FieldBuilder = parent.TypeBuilder.DefineField (Name, type, FieldAttr);
88                 }
89
90                 /// <summary>
91                 ///  Emits the field value by evaluating the expression
92                 /// </summary>
93                 public void EmitConstant (TypeContainer parent)
94                 {
95                         if (FieldBuilder == null)
96                                 return;
97                         
98                         EmitContext ec = new EmitContext (parent, null, type, ModFlags);
99
100                         Expr = Expression.Reduce (ec, Expr);
101
102                         if (!(Expr is Literal)) {
103                                 Report.Error (150, Location, "A constant value is expected");
104                                 return;
105                         }
106
107                         object val = ((Literal) Expr).GetValue ();
108
109                         FieldBuilder.SetConstant (val);
110
111                         TypeManager.RegisterField (FieldBuilder, val);
112                         
113                         return;
114                 }
115         }
116 }
117
118