Merge
authorMarek Safar <marek.safar@gmail.com>
Mon, 8 Jul 2013 14:49:13 +0000 (16:49 +0200)
committerMarek Safar <marek.safar@gmail.com>
Mon, 8 Jul 2013 14:49:13 +0000 (16:49 +0200)
105 files changed:
mcs/class/Microsoft.CSharp/Assembly/AssemblyInfo.cs
mcs/class/Mono.CSharp/Mono.CSharp.dll.sources
mcs/class/PlayScript.Core/ArgumentError.play [new file with mode: 0644]
mcs/class/PlayScript.Core/Array.play [new file with mode: 0644]
mcs/class/PlayScript.Core/Assembly/AssemblyInfo.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/Boolean.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/DefinitionError.play [new file with mode: 0644]
mcs/class/PlayScript.Core/DeprecatedAttribute.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/EmbedAttribute.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/Error.play [new file with mode: 0644]
mcs/class/PlayScript.Core/EventAttribute.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/Extensions.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/FunctionExtensions.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/JSON.play [new file with mode: 0644]
mcs/class/PlayScript.Core/Makefile [new file with mode: 0644]
mcs/class/PlayScript.Core/Math.play [new file with mode: 0644]
mcs/class/PlayScript.Core/Namespace.play [new file with mode: 0644]
mcs/class/PlayScript.Core/Number.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Core.dll.sources [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/ConstantFieldAttribute.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/DynamicClassAttribute.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/NamespaceFieldAttribute.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/PlayScriptAttribute.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/RestArrayParameterAttribute.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime/BinaryOperator.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime/Binder.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime/IsPropertyBinder.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime/Operations.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/PlayScript.Runtime/Undefined.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/QName.play [new file with mode: 0644]
mcs/class/PlayScript.Core/RangeError.play [new file with mode: 0644]
mcs/class/PlayScript.Core/ReferenceError.play [new file with mode: 0644]
mcs/class/PlayScript.Core/RegExp.play [new file with mode: 0644]
mcs/class/PlayScript.Core/SWFAttribute.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/SecurityError.play [new file with mode: 0644]
mcs/class/PlayScript.Core/String.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/SyntaxError.play [new file with mode: 0644]
mcs/class/PlayScript.Core/TypeError.play [new file with mode: 0644]
mcs/class/PlayScript.Core/URIError.play [new file with mode: 0644]
mcs/class/PlayScript.Core/Vector.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/VerifyError.play [new file with mode: 0644]
mcs/class/PlayScript.Core/XML.play [new file with mode: 0644]
mcs/class/PlayScript.Core/XMLList.play [new file with mode: 0644]
mcs/class/PlayScript.Core/functions.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/int.cs [new file with mode: 0644]
mcs/class/PlayScript.Core/toplevel.play [new file with mode: 0644]
mcs/mcs/.gitignore
mcs/mcs/Makefile
mcs/mcs/assign.cs
mcs/mcs/class.cs
mcs/mcs/const.cs
mcs/mcs/constant.cs
mcs/mcs/context.cs
mcs/mcs/convert.cs
mcs/mcs/decl.cs
mcs/mcs/driver.cs
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/field.cs
mcs/mcs/generic.cs
mcs/mcs/ikvm.cs
mcs/mcs/import.cs
mcs/mcs/location.cs
mcs/mcs/mcs.csproj
mcs/mcs/mcs.exe.sources
mcs/mcs/membercache.cs
mcs/mcs/method.cs
mcs/mcs/modifiers.cs
mcs/mcs/module.cs
mcs/mcs/namespace.cs
mcs/mcs/parameter.cs
mcs/mcs/playscript.cs [new file with mode: 0644]
mcs/mcs/property.cs
mcs/mcs/ps-parser.jay [new file with mode: 0644]
mcs/mcs/ps-tokenizer.cs [new file with mode: 0644]
mcs/mcs/report.cs
mcs/mcs/statement.cs
mcs/mcs/typespec.cs
mcs/tests/Makefile
mcs/tests/test-ps-001.play [new file with mode: 0644]
mcs/tests/test-ps-002-2.play [new file with mode: 0644]
mcs/tests/test-ps-002.play [new file with mode: 0644]
mcs/tests/test-ps-003.play [new file with mode: 0644]
mcs/tests/test-ps-004.play [new file with mode: 0644]
mcs/tests/test-ps-005.play [new file with mode: 0644]
mcs/tests/test-ps-006-2.play [new file with mode: 0644]
mcs/tests/test-ps-006.play [new file with mode: 0644]
mcs/tests/test-ps-007.play [new file with mode: 0644]
mcs/tests/test-ps-008.play [new file with mode: 0644]
mcs/tests/test-ps-009-2.play [new file with mode: 0644]
mcs/tests/test-ps-009.play [new file with mode: 0644]
mcs/tests/test-ps-010.play [new file with mode: 0644]
mcs/tests/test-ps-011.play [new file with mode: 0644]
mcs/tests/test-ps-012.play [new file with mode: 0644]
mcs/tests/test-ps-013.play [new file with mode: 0644]
mcs/tests/test-ps-014.play [new file with mode: 0644]
mcs/tests/test-ps-015.play [new file with mode: 0644]
mcs/tests/test-ps-016.play [new file with mode: 0644]
mcs/tests/test-ps-017.play [new file with mode: 0644]
mcs/tests/test-ps-018.play [new file with mode: 0644]
mcs/tests/test-ps-019.play [new file with mode: 0644]
mcs/tests/test-ps-020.play [new file with mode: 0644]
mcs/tests/test-ps-021.play [new file with mode: 0644]
mcs/tests/test-ps-022.play [new file with mode: 0644]
mcs/tests/test-ps-023.play [new file with mode: 0644]

index 6c7a223682f3bb80972c7f8da736527dde0b8c33..606510322cdb86b68bc821c4886b61b14048575f 100644 (file)
@@ -59,3 +59,4 @@ using System.Runtime.InteropServices;
 
 [assembly: ComVisible (false)]
 
+[assembly: InternalsVisibleTo ("PlayScript.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
index 0bbd93782bad9ef8544de3ababc6b5860cc69dcb..1be26a9399d7f185ab6a9143c2c5bc07ef78c136 100644 (file)
@@ -55,4 +55,7 @@
 ../../build/common/Consts.cs
 ../../tools/monop/outline.cs
 ../../mcs/cs-parser.cs
+../../mcs/ps-parser.cs
+../../mcs/ps-tokenizer.cs
+../../mcs/playscript.cs
 Assembly/AssemblyInfo.cs
diff --git a/mcs/class/PlayScript.Core/ArgumentError.play b/mcs/class/PlayScript.Core/ArgumentError.play
new file mode 100644 (file)
index 0000000..05b5aff
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class ArgumentError extends Error {
+       
+               public function ArgumentError(message:String = "") {
+                       super(message);
+               }
+               
+       }
+
+}
diff --git a/mcs/class/PlayScript.Core/Array.play b/mcs/class/PlayScript.Core/Array.play
new file mode 100644 (file)
index 0000000..29b77d3
--- /dev/null
@@ -0,0 +1,93 @@
+//
+// Array.play
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+package {
+       public dynamic class Array
+       {
+               public static const CASEINSENSITIVE:uint = 1;
+               public static const DESCENDING:uint = 2;
+               public static const UNIQUESORT:uint = 4;
+               public static const RETURNINDEXEDARRAY:uint = 8;
+               public static const NUMERIC:uint = 16;
+
+               private static const DELETED:Object = new Object ();
+               
+               var vector:Vector.<Object>;
+
+               public function Array (numElements:int = 0)
+               {
+                       vector = new Vector.<Object> (numElements);
+               }
+
+               public function Array (...rest)
+               {
+                       vector = new Vector.<Object> (rest);
+               }
+
+               public function get length ():uint
+               {
+                       return vector.length;
+               }
+
+               public function set length (value:uint):void
+               {
+                       vector.length = value;
+               }
+               
+               // TODO:
+               //public function push (...rest):uint
+               //{
+               //      throw new System.NotImplementedException ();
+               //      // TODO: return vector.push (rest);
+               //}
+               
+
+               public function splice (startIndex:int = 0, deleteCount:uint = 4294967295 /*uint.MAX_VALUE*/, ...values):Array
+               {
+                       throw new System.NotImplementedException ();
+               }
+
+               //
+               // Extensions to AS3
+               //
+               public function push (value:Object):uint
+               {
+                       return vector.push (value);
+               }
+
+               internal function setValue (index:uint, value:Object):void
+               {
+                       vector.setValue (index, value);
+               }
+
+               internal function deleteValue (index:uint):void
+               {
+                       vector.setValue (index, DELETED);
+               }
+       }
+}
\ No newline at end of file
diff --git a/mcs/class/PlayScript.Core/Assembly/AssemblyInfo.cs b/mcs/class/PlayScript.Core/Assembly/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..a5057c7
--- /dev/null
@@ -0,0 +1,56 @@
+//
+// AssemblyInfo.cs
+//
+// Authors:
+//     Marek Safar (marek.safar@gmail.com)
+//
+// Copyright 2013 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("PlayScript.Core.dll")]
+[assembly: AssemblyDescription ("PlayScript.Core.dll")]
+[assembly: AssemblyDefaultAlias ("PlayScript.Core.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (false)]
+
+[assembly: ComVisible (false)]
+
diff --git a/mcs/class/PlayScript.Core/Boolean.cs b/mcs/class/PlayScript.Core/Boolean.cs
new file mode 100644 (file)
index 0000000..e49abc0
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+
+namespace _root
+{
+       public static class Boolean
+       {
+               public static string toString(this bool b) {
+                       return b ? "true" : "false";
+               }
+               
+               public static bool valueOf(this bool b) {
+                       return b;
+               }
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/DefinitionError.play b/mcs/class/PlayScript.Core/DefinitionError.play
new file mode 100644 (file)
index 0000000..57c9963
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class DefinitionError extends Error {
+       
+               public function DefinitionError(message:String = "") {
+                       super(message);
+               }
+               
+       }
+
+}
+
diff --git a/mcs/class/PlayScript.Core/DeprecatedAttribute.cs b/mcs/class/PlayScript.Core/DeprecatedAttribute.cs
new file mode 100644 (file)
index 0000000..d27f702
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+
+namespace _root
+{
+       [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
+       public class DeprecatedAttribute : Attribute
+       {
+               public DeprecatedAttribute()
+               {
+               }
+
+               public string message {get;set;}
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/EmbedAttribute.cs b/mcs/class/PlayScript.Core/EmbedAttribute.cs
new file mode 100644 (file)
index 0000000..ff8f7a9
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+
+namespace _root
+{
+       [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
+       public class EmbedAttribute : Attribute
+       {
+               public string source { get; set; }
+
+               public string mimeType { get; set; }
+
+               public string embedAsCFF { get; set; }
+
+               public string fontFamily { get; set; }
+
+               public string symbol { get; set; }
+
+               public EmbedAttribute (string _source = null)
+               {
+                       source = _source;
+               }
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/Error.play b/mcs/class/PlayScript.Core/Error.play
new file mode 100644 (file)
index 0000000..ddf53f5
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class Error extends System.Exception
+       {
+               //
+               // Internal
+               //
+
+               private var _errorID : int;
+
+               //
+               // Properties
+               //
+
+               public property errorID : int { get { return _errorID; } } 
+
+               public property message : String { get { return this.Message; } }
+
+               public property name : String { get { return GetType().Name; } }
+
+               //
+               // Methods
+               //
+
+               public function Error(message:String = "", id:int = 0) {
+                       super(message);
+                       _errorID = id;
+               }
+
+               public function getStackTrace():String {
+                       throw new System.NotImplementedException();
+//                     return null;
+               }
+
+               public function toString():String {
+                       return this.ToString();
+               }
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/EventAttribute.cs b/mcs/class/PlayScript.Core/EventAttribute.cs
new file mode 100644 (file)
index 0000000..d9d94b3
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+
+namespace _root
+{
+       [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
+       public class EventAttribute : Attribute
+       {
+               public string name { get; set; }
+
+               public string type { get; set; }
+
+               public EventAttribute ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/Extensions.cs b/mcs/class/PlayScript.Core/Extensions.cs
new file mode 100644 (file)
index 0000000..3bad9c3
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+using System.Collections;
+
+namespace _root
+{
+       public static class Extensions
+       {
+//             public static string toString(this object o) 
+//             {
+//                     return o.ToString ();
+//             }
+
+               public static string toLocaleString(this object o) 
+               {
+                       return o.ToString ();
+               }
+
+               public static bool hasOwnProperty(this object o, string name) 
+               {
+                       var t = o.GetType ();
+                       return t.GetProperty(name) != null || t.GetField(name) != null;
+               }
+
+               public static string toString(this uint o, int radix = 10) 
+               {
+                       return Convert.ToString (o, radix);
+               }
+
+               //
+               // IList extensions (for arrays, etc).
+               //
+
+//             public static int get_length(this IList list) 
+//             {
+//                     return list.Count;
+//             }
+
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/FunctionExtensions.cs b/mcs/class/PlayScript.Core/FunctionExtensions.cs
new file mode 100644 (file)
index 0000000..5674bc6
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+using System.Reflection;
+
+namespace _root {
+
+       public static class FunctionExtensions {
+
+               public static dynamic apply(this Delegate d, dynamic thisArg, Array argArray) {
+                       return d.DynamicInvoke(argArray != null ? argArray.ToArray() : null);
+               }
+
+               public static dynamic call(this Delegate d, dynamic thisArg, params object[] args) {
+                       return d.DynamicInvoke(args);
+               }
+
+               // this returns the number of arguments to the delegate method
+               public static int get_length(this Delegate d) {
+                       return d.Method.GetParameters().Length;
+               }
+
+       }
+
+
+}
diff --git a/mcs/class/PlayScript.Core/JSON.play b/mcs/class/PlayScript.Core/JSON.play
new file mode 100644 (file)
index 0000000..f9cea4a
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class JSON {
+       
+               public static function parse(text:String, reviver:Function = null):Object {
+                       throw new System.NotImplementedException();
+               }
+
+               public static function stringify(value:Object, replacer:* = null, space:* = null):String {
+                       throw new System.NotImplementedException();
+               }
+       
+       }
+
+}
diff --git a/mcs/class/PlayScript.Core/Makefile b/mcs/class/PlayScript.Core/Makefile
new file mode 100644 (file)
index 0000000..6a89812
--- /dev/null
@@ -0,0 +1,12 @@
+thisdir = class/PlayScript.Core
+include ../../build/rules.make
+
+LIBRARY = PlayScript.Core.dll
+LIBRARY_SNK = ../mono.snk
+LIBRARY_PACKAGE = none
+
+LIB_MCS_FLAGS = -d:DYNAMIC_SUPPORT -keyfile:$(LIBRARY_SNK) -delaysign -r:System.dll -r:System.Core.dll -r:System.Xml.dll -r:Microsoft.CSharp.dll -r:Mono.CSharp.dll
+
+NO_TEST = yes
+
+include ../../build/library.make
diff --git a/mcs/class/PlayScript.Core/Math.play b/mcs/class/PlayScript.Core/Math.play
new file mode 100644 (file)
index 0000000..d1e58d5
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class Math {
+               
+               //
+               // Constants
+               //
+
+               public static const E : Number = 2.71828182845905;
+
+               public static const LN10 : Number = 2.302585092994046;
+               
+               public static const LN2 : Number = 0.6931471805599453;
+
+               public static const LOG10E : Number = 0.4342944819032518;
+
+               public static const LOG2E : Number = 1.442695040888963387;
+
+               public static const PI : Number = 3.141592653589793;
+
+               public static const SQRT1_2 : Number = 0.7071067811865476;
+
+               public static const SQRT2 : Number = 1.4142135623730951;
+       
+               //
+               // Methods
+               //
+       
+               public static function abs(val:Number):Number {
+                       return System.Math.Abs(val);
+               }
+               
+               public static function acos(val:Number):Number {
+                       return System.Math.Acos(val);
+               }
+               
+               public static function asin(val:Number):Number {
+                       return System.Math.Asin(val);
+               }
+               
+               public static function atan(val:Number):Number {
+                       return System.Math.Atan(val);
+               }
+               
+               public static function atan2(y:Number, x:Number):Number {
+                       return System.Math.Atan2(y, x);
+               }
+               
+               public static function ceil(val:Number):Number {
+                       return System.Math.Ceiling(val);
+               }
+               
+               public static function cos(angleRadians:Number):Number {
+                       return System.Math.Cos(angleRadians);
+               }
+               
+               public static function exp(val:Number):Number {
+                       return System.Math.Exp(val);
+               }
+               
+               public static function floor(val:Number):Number {
+                       return System.Math.Floor(val);
+               }
+               
+               public static function log(val:Number):Number {
+                       return System.Math.Log(val);
+               }
+
+               public static function max(val1:Number, val2:Number):Number {
+                       return System.Math.Max(val1, val2);
+               }
+                               
+               public static function max(val1:Number, val2:Number, ... rest):Number {
+                       throw new System.NotImplementedException();
+               }
+
+               public static function min(val1:Number, val2:Number):Number {
+                       return System.Math.Min(val1, val2);
+               }
+                               
+               public static function min(val1:Number, val2:Number, ... rest):Number {
+                       throw new System.NotImplementedException();
+               }
+               
+               public static function pow(base:Number, pow:Number):Number {
+                       return System.Math.Pow(base, pow);
+               }
+
+               private static var sRandom:System.Random = new System.Random();
+
+               public static function random():Number {
+                       return sRandom.NextDouble();
+               }
+               
+               public static function round(val:Number):Number {
+                       return System.Math.Round(val);
+               }
+               
+               public static function sin(angleRadians:Number):Number {
+                       return System.Math.Sin(angleRadians);
+               }
+               
+               public static function sqrt(val:Number):Number {
+                       return System.Math.Sqrt(val);
+               }
+               
+               public static function tan(angleRadians:Number):Number {
+                       return System.Math.Tan(angleRadians);
+               }
+       
+       }
+
+}
diff --git a/mcs/class/PlayScript.Core/Namespace.play b/mcs/class/PlayScript.Core/Namespace.play
new file mode 100644 (file)
index 0000000..76475a0
--- /dev/null
@@ -0,0 +1,61 @@
+//
+// Namespace.play
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright 2013 Zynga Inc.
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public final class Namespace
+       {
+               private var prefix_value:String;
+               private var uri_value:String;
+
+               public function Namespace (prefix:*=null, uri:*=null)
+               {
+                       prefix_value = prefix;
+                       uri_value = uri;
+               }
+
+               //
+               // Properties
+               //
+               public function get prefix () : String
+               {
+                       return prefix_value;
+               }
+
+               public function get uri () : String
+               {
+                       return uri_value;
+               }
+
+               // 
+               // Methods
+               //
+               public function toString ():String
+               {
+                       throw new System.NotImplementedException();
+               }
+
+               public function valueOf ():Object
+               {
+                       throw new System.NotImplementedException();
+               }
+       }
+}
diff --git a/mcs/class/PlayScript.Core/Number.cs b/mcs/class/PlayScript.Core/Number.cs
new file mode 100644 (file)
index 0000000..f577355
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+namespace _root {
+
+       public static class Number {
+       
+               //
+               // Extension Methods
+               //
+       
+               public static string toExponential(this double d, uint fractionDigits) {
+                       throw new System.NotImplementedException();
+               }
+               
+               public static string toFixed(this double d, uint fractionDigits) {
+                       return d.ToString ( "F" + fractionDigits.ToString() );
+               }
+               
+               public static string toPrecision(this double d, uint precision) {
+                       throw new System.NotImplementedException();
+               }
+               
+               public static string toString(this double d) {
+                       return d.ToString();
+               }
+
+               public static string toString(this double d, double radix) {
+                       throw new System.NotImplementedException();
+               }
+               
+               public static double valueOf(this double d) {
+                       return d;
+               }
+
+               //
+               // Constants
+               //
+               
+               public const double MAX_VALUE = System.Double.MaxValue;
+                       
+               public const double MIN_VALUE = System.Double.MinValue;
+
+               public const double @NaN = System.Double.NaN;
+
+               public const double NEGATIVE_INFINITY = System.Double.NegativeInfinity;
+
+               public const double POSITIVE_INFINITY = System.Double.PositiveInfinity;
+       
+       }
+
+}
diff --git a/mcs/class/PlayScript.Core/PlayScript.Core.dll.sources b/mcs/class/PlayScript.Core/PlayScript.Core.dll.sources
new file mode 100644 (file)
index 0000000..d9963d3
--- /dev/null
@@ -0,0 +1,44 @@
+../../build/common/Consts.cs
+./Assembly/AssemblyInfo.cs
+./Array.play
+./Boolean.cs
+./DeprecatedAttribute.cs
+./EmbedAttribute.cs
+./EventAttribute.cs
+./Extensions.cs
+./FunctionExtensions.cs
+./functions.cs
+./int.cs
+./Number.cs
+./String.cs
+./ArgumentError.play
+./DefinitionError.play
+./Error.play
+./JSON.play
+./Math.play
+./Namespace.play
+./QName.play
+./RangeError.play
+./ReferenceError.play
+./RegExp.play
+./SecurityError.play
+./SyntaxError.play
+./SWFAttribute.cs
+./toplevel.play
+./TypeError.play
+./URIError.play
+./Vector.cs
+./VerifyError.play
+./XML.play
+./XMLList.play
+
+./PlayScript.Runtime/BinaryOperator.cs
+./PlayScript.Runtime/Binder.cs
+./PlayScript.Runtime/IsPropertyBinder.cs
+./PlayScript.Runtime/Operations.cs
+./PlayScript.Runtime/Undefined.cs
+./PlayScript.Runtime.CompilerServices/ConstantFieldAttribute.cs
+./PlayScript.Runtime.CompilerServices/DynamicClassAttribute.cs
+./PlayScript.Runtime.CompilerServices/NamespaceFieldAttribute.cs
+./PlayScript.Runtime.CompilerServices/PlayScriptAttribute.cs
+./PlayScript.Runtime.CompilerServices/RestArrayParameterAttribute.cs
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/ConstantFieldAttribute.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/ConstantFieldAttribute.cs
new file mode 100644 (file)
index 0000000..b35e254
--- /dev/null
@@ -0,0 +1,47 @@
+//
+// ConstantFieldAttribute.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace PlayScript.Runtime.CompilerServices
+{
+       [AttributeUsage (AttributeTargets.Field)]
+       public sealed class ConstantFieldAttribute : Attribute
+       {
+               public ConstantFieldAttribute ()
+               {
+               }
+               
+               public ConstantFieldAttribute (object value)
+               {
+                       Value = value;
+               }
+               
+               public object Value { get; private set; }
+       }
+}
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/DynamicClassAttribute.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/DynamicClassAttribute.cs
new file mode 100644 (file)
index 0000000..54af470
--- /dev/null
@@ -0,0 +1,37 @@
+//
+// DynamicClassAttribute.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace PlayScript.Runtime.CompilerServices
+{
+       [AttributeUsage (AttributeTargets.Class)]
+       public sealed class DynamicClassAttribute : Attribute
+       {
+       }
+}
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/NamespaceFieldAttribute.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/NamespaceFieldAttribute.cs
new file mode 100644 (file)
index 0000000..d5919fa
--- /dev/null
@@ -0,0 +1,43 @@
+//
+// NamespaceFieldAttribute.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace PlayScript.Runtime.CompilerServices
+{
+       [AttributeUsage (AttributeTargets.Field)]
+       public sealed class NamespaceFieldAttribute : Attribute
+       {
+               public NamespaceFieldAttribute (string uri)
+               {
+                       Uri = uri;
+               }
+               
+               public string Uri { get; private set; }
+       }
+}
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/PlayScriptAttribute.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/PlayScriptAttribute.cs
new file mode 100644 (file)
index 0000000..7fc04c9
--- /dev/null
@@ -0,0 +1,37 @@
+//
+// PlayScriptAttribute.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace PlayScript.Runtime.CompilerServices
+{
+       [AttributeUsage (AttributeTargets.Class)]
+       public sealed class PlayScriptAttribute : Attribute
+       {
+       }
+}
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/RestArrayParameterAttribute.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime.CompilerServices/RestArrayParameterAttribute.cs
new file mode 100644 (file)
index 0000000..959699d
--- /dev/null
@@ -0,0 +1,37 @@
+//
+// RestArrayAttribute.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace PlayScript.Runtime.CompilerServices
+{
+       [AttributeUsage (AttributeTargets.Parameter)]
+       public sealed class RestArrayParameterAttribute : Attribute
+       {
+       }
+}
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime/BinaryOperator.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime/BinaryOperator.cs
new file mode 100644 (file)
index 0000000..637fe28
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// BinaryOperator.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace PlayScript.Runtime
+{
+       public enum BinaryOperator
+       {
+               Multiply        = 1,
+               Division        = 2,
+               Modulus         = 3,
+               Addition        = 4,
+               Subtraction = 5,
+
+               LeftShift       = 10,
+               RightShift      = 11,
+               UnsignedRightShift      = 12,
+
+               LessThan        = 20,
+               GreaterThan     = 21,
+               LessThanOrEqual         = 22,
+               GreaterThanOrEqual      = 23,
+               Equality        = 24,
+               Inequality      = 25,
+
+               BitwiseAnd      = 30,
+               ExclusiveOr     = 31,
+               BitwiseOr       = 32,
+
+               LogicalAnd      = 40,
+               LogicalOr       = 41
+       }
+}
\ No newline at end of file
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime/Binder.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime/Binder.cs
new file mode 100644 (file)
index 0000000..89f2118
--- /dev/null
@@ -0,0 +1,195 @@
+//
+// Binder.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using Microsoft.CSharp.RuntimeBinder;
+
+namespace PlayScript.Runtime
+{
+       public static class Binder
+       {
+               static readonly ConditionalWeakTable<object, ConcurrentDictionary<string, object>> dynamic_classes = new ConditionalWeakTable<object, ConcurrentDictionary<string, object>> ();
+               
+               public static dynamic GetMember (object instance, Type context, object name)
+               {
+                       if (instance == null)
+                               throw GetNullObjectReferenceException ();
+                       
+                       var sname = GetName (name);
+
+                       ConcurrentDictionary<string, object> members;
+                       if (dynamic_classes.TryGetValue (instance, out members)) {
+                               object value;
+                               if (members.TryGetValue (sname, out value))
+                                       return value;
+                       }
+
+                       var binder = Microsoft.CSharp.RuntimeBinder.Binder.GetMember (CSharpBinderFlags.None, sname, context, new[] { CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null) });
+                       var callsite = CallSite<Func<CallSite, object, object>>.Create (binder);
+
+                       // TODO: Add caching to avoid expensive Resolve
+               return callsite.Target (callsite, instance);
+               }
+               
+               public static void SetMember (object instance, Type context, object name, object value)
+               {
+                       if (instance == null)
+                               throw GetNullObjectReferenceException ();
+
+                       //
+                       // Use index setter when name can be converted to number on array instances 
+                       //
+                       var array = instance as _root.Array;
+                       if (array != null) {
+                               var index = GetArrayIndex (name);
+                               if (index != null) {
+                                       array.setValue (index.Value, value);
+                                       return;
+                               }
+                       }                               
+
+                       var sname = GetName (name);
+
+                       var binder = Microsoft.CSharp.RuntimeBinder.Binder.SetMember (CSharpBinderFlags.None, sname, context,
+                               new[] { CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create (CSharpArgumentInfoFlags.None, null) });
+                       var callsite = CallSite<Func<CallSite, object, object, object>>.Create (binder);
+
+                       // TODO: Better handling
+                       try {
+                               // TODO: Add caching to avoid expensive Resolve
+                       callsite.Target (callsite, instance, value);
+               } catch (RuntimeBinderException) {      
+                               var members = dynamic_classes.GetOrCreateValue (instance);
+                                                       
+                               // TODO: Not thread safe
+                               members [sname] = value;
+                       }
+               }
+
+               public static bool HasProperty (object instance, Type context, object property)
+               {
+                       if (instance == null)
+                               throw GetNullObjectReferenceException ();
+
+                       //
+                       // Calling in operator on Array instance means something different
+                       //
+                       var array = instance as _root.Array;
+                       if (array != null) {
+                               var index = GetArrayIndex (property);
+                               if (index == null)
+                                       return false;
+
+                               return array.length > index;
+                       }
+
+                       var type = instance as Type;
+                       var sname = GetName (property);
+                       bool static_only;
+
+                       //
+                       // It's null when it's not static
+                       //
+                       if (type == null) {
+                               ConcurrentDictionary<string, object> members;
+                               if (dynamic_classes.TryGetValue (instance, out members) && members.ContainsKey (sname)) {
+                                       return true;
+                               }
+
+                               type = instance.GetType ();
+                               static_only = false;
+                       } else {
+                               static_only = true;
+                       }
+
+                       var binder = new IsPropertyBinder (sname, context, static_only);        
+                       
+                       var callsite = CallSite<Func<CallSite, Type, bool>>.Create (binder);
+
+                       // TODO: Better handling
+                       try {
+                               // TODO: Add caching to avoid expensive Resolve
+                       return callsite.Target (callsite, type);
+               } catch (RuntimeBinderException) {
+                       throw;
+                       }
+               }
+
+               public static bool DeleteProperty (object instance, object property)
+               {
+                       //
+                       // delete operator on Array instances
+                       //
+                       var array = instance as _root.Array;
+                       if (array != null) {
+                               var index = GetArrayIndex (property);
+                               if (index != null) {
+                                       array.deleteValue (index.Value);
+                               }
+
+                               return true;
+                       }
+
+                       ConcurrentDictionary<string, object> members;
+                       if (dynamic_classes.TryGetValue (instance, out members)) {
+                               var sname = GetName (property);
+
+                               object value;
+                               members.TryRemove (sname, out value);
+                       }
+
+                       return true;
+               }
+
+               static uint? GetArrayIndex (object value)
+               {
+                       try {
+                               return Convert.ToUInt32 (value);
+                       } catch {
+                               return null;
+                       }                       
+               }
+
+               static string GetName (object name)
+               {
+                       // TODO: Will be special token for null key enough?
+                       if (name == null)
+                               throw new NotImplementedException ("null name");
+                       
+                       return name.ToString ();
+               }
+
+               static Exception GetNullObjectReferenceException ()
+               {
+                       return new _root.Error ("Cannot access a property or method of a null object reference.", 1009);                        
+               }
+       }
+}
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime/IsPropertyBinder.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime/IsPropertyBinder.cs
new file mode 100644 (file)
index 0000000..f984251
--- /dev/null
@@ -0,0 +1,77 @@
+//
+// IsPropertyBinder.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Dynamic;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.CSharp.RuntimeBinder;
+using Compiler = Mono.CSharp;
+
+namespace PlayScript.Runtime
+{
+       class IsPropertyBinder : DynamicMetaObjectBinder
+       {
+               Type callingContext;
+               string name;
+               bool static_only;
+               
+               public IsPropertyBinder (string name, Type callingContext, bool staticOnly)
+               {
+                       this.name = name;
+                       this.callingContext = callingContext;
+                       this.static_only = staticOnly;
+               }
+               
+               public override DynamicMetaObject Bind (DynamicMetaObject target, DynamicMetaObject[] args)
+               {
+                       var ctx = DynamicContext.Create ();
+                       var context_type = ctx.ImportType (callingContext);
+                       var queried_type = ctx.ImportType ((Type) target.Value);
+                       var rc = new Compiler.ResolveContext (new RuntimeBinderContext (ctx, context_type), 0);
+
+                       var expr = Compiler.Expression.MemberLookup (rc, false, queried_type,
+                               name, 0, Compiler.Expression.MemberLookupRestrictions.ExactArity, Compiler.Location.Null);
+
+                       var pe = expr as Compiler.PropertyExpr;                 
+                       var result = pe != null && pe.IsStatic == static_only;
+
+                       var binder = new CSharpBinder (
+                               this, new Compiler.BoolConstant (ctx.CompilerContext.BuiltinTypes, result, Compiler.Location.Null), null);
+
+                       binder.AddRestrictions (target);
+                       return binder.Bind (ctx, callingContext);
+               }
+
+               public override Type ReturnType {
+                       get {
+                               return typeof (bool);
+                       }
+               }
+       }
+}
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime/Operations.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime/Operations.cs
new file mode 100644 (file)
index 0000000..10301a5
--- /dev/null
@@ -0,0 +1,125 @@
+//
+// Operations.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace PlayScript.Runtime
+{
+       public static class Operations
+       {
+               public static bool Comparison (BinaryOperator binaryOperator, object left, object right)
+               {
+                       if (right is int)
+                               return Comparison (binaryOperator, left, (int) right);
+
+                       return false;
+               }
+
+               public static bool Comparison (BinaryOperator binaryOperator, object left, int right)
+               {
+                       if (left is int) {
+                               var l = (int) left;
+                               switch (binaryOperator) {
+                               case BinaryOperator.Equality:
+                                       return l == right;
+                               case BinaryOperator.Inequality:
+                                       return l != right;
+                               case BinaryOperator.GreaterThan:
+                                       return l > right;
+                               case BinaryOperator.GreaterThanOrEqual:
+                                       return l >= right;
+                               case BinaryOperator.LessThan:
+                                       return l < right;
+                               case BinaryOperator.LessThanOrEqual:
+                                       return l <= right;
+                               default:
+                                       throw new NotImplementedException (binaryOperator.ToString ());
+                               }
+                       }
+
+                       // TODO: uint, string, double, etc
+
+                       return false;
+               }
+
+               public static bool Comparison (BinaryOperator binaryOperator, int left, object right)
+               {
+                       if (right is int) {
+                               var r = (int) right;
+                               switch (binaryOperator) {
+                               case BinaryOperator.Equality:
+                                       return left == r;
+                               case BinaryOperator.Inequality:
+                                       return left != r;
+                               case BinaryOperator.GreaterThan:
+                                       return left > r;
+                               case BinaryOperator.GreaterThanOrEqual:
+                                       return left >= r;
+                               case BinaryOperator.LessThan:
+                                       return left < r;
+                               case BinaryOperator.LessThanOrEqual:
+                                       return left <= r;
+                               default:
+                                       throw new NotImplementedException (binaryOperator.ToString ());
+                               }
+                       }
+
+                       // TODO: uint, string, double, etc
+
+                       return false;
+               }       
+
+               public static string Typeof (object instance)
+               {
+                       if (instance == null)
+                               return "object";
+
+                       if (instance is string)
+                               return "string";
+
+                       if (instance is int || instance is uint || instance is double)
+                               return "number";
+
+                       if (instance is bool)
+                               return "boolean";
+
+                       // TODO: Wrong, it has to be of a special type
+                       if (instance == Undefined.Value) 
+                               return "undefined";
+
+                       // TODO: Wrong, it has to be of a special type                  
+                       if (instance is _root.XML || instance is _root.XMLList)
+                               return "xml";
+                       
+                       if (instance is Delegate)
+                               return "function";
+                       
+                       return "object";
+               }
+       }                               
+}
diff --git a/mcs/class/PlayScript.Core/PlayScript.Runtime/Undefined.cs b/mcs/class/PlayScript.Core/PlayScript.Runtime/Undefined.cs
new file mode 100644 (file)
index 0000000..45349de
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// Undefined.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace PlayScript.Runtime
+{
+       static class Undefined
+       {
+               public static readonly object Value = new object ();
+       }
+}
\ No newline at end of file
diff --git a/mcs/class/PlayScript.Core/QName.play b/mcs/class/PlayScript.Core/QName.play
new file mode 100644 (file)
index 0000000..6532198
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class QName {
+       
+               //
+               // Properties
+               //
+               
+               public property localName : String { get { return mLocalName; } }
+
+               public property uri : String { get { return mUri; } }
+
+               //
+               // Methods 
+               //
+               
+               public function QName(uri:String, localName:String) {
+                       mUri = uri;
+                       mLocalName = localName;
+               }
+               
+               public function toString():String {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function valueOf():Object {
+                       throw new System.NotImplementedException();
+               }
+
+               private var mUri:String;
+               private var mLocalName:String;
+       
+       }
+
+}
diff --git a/mcs/class/PlayScript.Core/RangeError.play b/mcs/class/PlayScript.Core/RangeError.play
new file mode 100644 (file)
index 0000000..b2d97d2
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class RangeError extends Error {
+       
+               public function RangeError(message:String = "") {
+                       super(message);
+               }
+               
+       }
+
+}
+
diff --git a/mcs/class/PlayScript.Core/ReferenceError.play b/mcs/class/PlayScript.Core/ReferenceError.play
new file mode 100644 (file)
index 0000000..bb2c3a3
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class ReferenceError extends Error {
+       
+               public function ReferenceError(message:String = "") {
+                       super(message);
+               }
+               
+       }
+
+}
diff --git a/mcs/class/PlayScript.Core/RegExp.play b/mcs/class/PlayScript.Core/RegExp.play
new file mode 100644 (file)
index 0000000..9ba88dc
--- /dev/null
@@ -0,0 +1,164 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+       import System.*;
+       import System.Text.RegularExpressions.*;
+
+       public class RegExp {
+       
+               //
+               // Properties
+               //
+               
+               public property dotall : Boolean { 
+                       get { return mDoTail;} 
+               }
+               public property extended : Boolean { 
+                       get { return mExtended;} 
+               }
+               public property global : Boolean { 
+                       get { return mGlobal;} 
+               }
+               public property ignoreCase : Boolean { 
+                       get { return (mRegex.Options & RegexOptions.IgnoreCase) != 0;} 
+               }
+               public property lastIndex : Number { 
+                       get { throw new NotImplementedException();} 
+               }
+               public property multiline : Boolean { 
+                       get { return (mRegex.Options & RegexOptions.Multiline) != 0;} 
+               }
+               
+               public property source : String { 
+                       get { return mSource;} 
+               }
+
+               //
+               // Methods
+               //
+                               
+               public function RegExp(re:String, flags:String) {
+                       var options:RegexOptions = RegexOptions.None;
+                       for (var i:int=0; i < flags.Length; i++) {
+                               switch (flags.charAt(i)) {
+                               case "m":
+                                       options |= RegexOptions.Multiline;
+                                       break;
+                               case "i":
+                                       options |= RegexOptions.IgnoreCase;
+                                       break;
+                               case "g":
+                                       mGlobal = true;
+                                       break;
+                               case "x":
+                                       mExtended = true;
+                                       break;
+                               case "s":
+                                       mDoTail = true;
+                                       break;
+                               default:
+                                       throw new NotImplementedException();
+                               }
+                       }
+
+                       mSource = re;
+                       mRegex = new Regex(re, options);
+               }
+
+               public function exec(str:String):Object {
+                       var m = mRegex.Match(str);
+                       if (m.Success) {
+                               var a:Array = [];
+                               // a.push(m.Value);
+                               for each (var g:Group in m.Groups) {
+                                       a.push(g.Value);
+                               }
+                               return a;
+                       } else
+                       {
+                               return null;
+                       }
+               }
+               
+               public function test(str:String):Boolean {
+                       throw new NotImplementedException();
+               }
+               
+               public function replace(str:String, replaceWith:String):String {
+                       return mRegex.Replace(str, replaceWith);
+               }
+               
+               public function search(str:String):int {
+                       var m = mRegex.Match(str);
+                       if (!m.Success) {
+                               return -1;
+                       }
+                       return m.Index;
+               }
+               
+               public function match(str:String):Array {
+                       var a:Array = null;
+                       var m = mRegex.Match(str);
+                       while (m.Success) {
+                               if (a == null) a = new Array();
+                               a.push( m.Value );
+                               m = m.NextMatch();
+                       }
+                       return a;
+               }
+               
+               public function split(str:String):Array
+               {
+                       var a:Array = new Array();
+
+                       var lastIndex:int = 0;
+
+                       var m = mRegex.Match(str);
+                       while (m.Success) {
+                       
+                               // get everything before the match
+                               var before:String = str.Substring(lastIndex, m.Index - lastIndex);
+                               
+                               a.push(before);
+                               
+                               // push all matching groups
+                               for (var i:int = 1; i < m.Groups.Count; i++)
+                               {
+                                       a.push(m.Groups[i].Value);
+                               }
+                               
+                               // set last index
+                               lastIndex = m.Index + m.Length;
+                               
+                               // next match
+                               m = m.NextMatch();
+                       }
+
+                       // push everything after last match
+                       var end:String = str.Substring(lastIndex, str.Length - lastIndex);
+                       a.push(end);
+                                                                       
+                       return a;
+               }
+               
+               var mRegex:Regex;
+               var mSource:String;
+               var mGlobal:Boolean;
+               var mExtended:Boolean;
+               var mDoTail:Boolean;
+       
+       }
+
+}
diff --git a/mcs/class/PlayScript.Core/SWFAttribute.cs b/mcs/class/PlayScript.Core/SWFAttribute.cs
new file mode 100644 (file)
index 0000000..c994e3b
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+
+namespace _root
+{
+       [AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
+       public class SWFAttribute : Attribute
+       {
+               public object width { get; set; }
+               public object height { get; set; }
+               public object frameRate { get; set; }
+               public object backgroundColor { get; set; }
+               public object quality {get;set;}
+               
+               public SWFAttribute ()
+               {
+               }
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/SecurityError.play b/mcs/class/PlayScript.Core/SecurityError.play
new file mode 100644 (file)
index 0000000..c596b30
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class SecurityError extends Error {
+       
+               public function SecurityError(message:String = "") {
+                       super(message);
+               }
+               
+       }
+
+}
+
diff --git a/mcs/class/PlayScript.Core/String.cs b/mcs/class/PlayScript.Core/String.cs
new file mode 100644 (file)
index 0000000..e84b77f
--- /dev/null
@@ -0,0 +1,186 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+using System.Text;
+
+namespace _root
+{
+       public static class String
+       {
+               public static int get_length(this string s) {
+                       return s.Length;
+               }
+
+               public static string charAt(this string s, double index = 0) {
+                       return s[ (int)index ].ToString();
+               }                               
+
+               public static int charCodeAt(this string s, double index) {
+                       return s[(int)index];
+               }
+
+               public static string concat(this string s, params object[] args) {
+                       foreach (object arg in args)
+                       {
+                               s += arg.ToString();
+                       }
+                       return s;
+               }
+
+               private static char objectToChar(object o)
+               {
+                       if (o is int) {
+                               return (char)(int)o;
+                       } else if (o is uint) {
+                               return (char)(uint)o;
+                       } else if (o is char) {
+                               return (char)o;
+                       } else {
+                               throw new NotImplementedException();
+                       }
+               }
+
+               public static string fromCharCode (params object[] charCodes)
+               {
+                       if (charCodes.Length == 1)
+                       {
+                               return new string(objectToChar(charCodes[0]), 1);
+                       }
+                       else
+                       {
+                               var chars = new char[charCodes.Length];
+                               for (int i=0; i < charCodes.Length; i++) {
+                                       chars[i] = objectToChar(charCodes[i]);
+                               }
+                               return new string(chars);
+                       }
+               }
+
+               public static int indexOf(this string s, string val, double startIndex = 0) {
+                       if (s == null) return -1;
+                       return s.IndexOf(val, (int)startIndex);
+               }
+                                               
+               public static int lastIndexOf(this string s, string val, double startIndex = 0x7FFFFFFF) {
+                       throw new NotImplementedException();
+               }
+                                               
+               public static int localeCompare(this string s, string other, params object[] values) {
+                       throw new NotImplementedException();
+               }
+
+               public static Array match(this string s, object pattern) {
+                       if (pattern is RegExp) {
+                               // pattern is a regexp
+                               var re = pattern as RegExp;
+                               return re.match(s);
+                       } else {
+                               // pattern is a string or other object
+                               throw new NotImplementedException();
+                       }
+               }
+
+               public static string replace (this string s, object pattern, object repl)
+               {
+                       if (pattern is RegExp) {
+                               // pattern is a regexp
+                               var re = pattern as RegExp;
+                               return re.replace(s, repl.ToString());
+                       } else {
+                               // pattern is a string or other object
+                               return s.Replace(pattern.ToString (), repl.ToString());
+                       }
+               }
+
+               public static int search(this string s, object pattern) {
+                       if (pattern is RegExp) {
+                               // pattern is a regexp
+                               var re = pattern as RegExp;
+                               return re.search(s);
+                       } else {
+                               // pattern is a string or other object
+                               return s.IndexOf(pattern.ToString ());
+                       }
+               }
+
+               public static string slice(this string s) {
+                       throw new NotImplementedException();
+               }
+
+               public static string slice(this string s, int startIndex) {
+                       return s.Substring(startIndex);
+               }
+
+               public static string slice(this string s, int startIndex, int endIndex) {
+                       return s.Substring(startIndex, endIndex - startIndex);
+               }
+
+               public static Array split (this string s, object delimiter, int limit = 0x7fffffff)
+               {
+                       if (limit != 0x7fffffff) {
+                               throw new NotImplementedException ();
+                       }
+
+                       if (delimiter is RegExp) {
+                               var re = delimiter as RegExp;
+                               return re.split(s);
+                       } else if (delimiter is string) {
+                               return new Array( s.Split(new string[] {(string)delimiter}, StringSplitOptions.None ));
+                       } else {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public static string substr(this string s, double startIndex = 0, double len = 0x7fffffff) {
+                       if (len == 0x7fffffff) {
+                               return s.Substring((int)startIndex);
+                       } else {
+                               // TODO: should this throw or be silent if length exceeded?
+                               return s.Substring((int)startIndex, (int)len);
+                       }
+               }
+
+               public static string substring(this string s, double startIndex = 0, double endIndex = 0x7fffffff) {
+                       if (endIndex == 0x7fffffff) {
+                               return s.Substring((int)startIndex);
+                       } else {
+                               // TODO: should this throw or be silent if length exceeded?
+                               return s.Substring((int)startIndex, (int)endIndex - (int)startIndex);
+                       }
+               }
+
+               public static string toLocaleLowerCase(this string s) {
+                       throw new NotImplementedException();
+               }
+
+               public static string toLocaleUpperCase(this string s) {
+                       throw new NotImplementedException();
+               }
+
+               public static string toLowerCase(this string s) {
+                       return s.ToLowerInvariant();
+               }
+
+               public static string toUpperCase(this string s) {
+                       return s.ToUpperInvariant();
+               }
+
+               public static string valueOf(this string s) {
+                       return s;
+               }
+
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/SyntaxError.play b/mcs/class/PlayScript.Core/SyntaxError.play
new file mode 100644 (file)
index 0000000..0c82410
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class SyntaxError extends Error {
+       
+               public function SyntaxError(message:String = "") {
+                       super(message);
+               }
+               
+       }
+
+}
+
diff --git a/mcs/class/PlayScript.Core/TypeError.play b/mcs/class/PlayScript.Core/TypeError.play
new file mode 100644 (file)
index 0000000..6a0c1c2
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class TypeError extends Error {
+       
+               public function TypeError(message:String = "") {
+                       super(message);
+               }
+               
+       }
+
+}
+
diff --git a/mcs/class/PlayScript.Core/URIError.play b/mcs/class/PlayScript.Core/URIError.play
new file mode 100644 (file)
index 0000000..27c36e8
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class URIError extends Error {
+       
+               public function URIError(message:String = "") {
+                       super(message);
+               }
+               
+       }
+
+}
+
diff --git a/mcs/class/PlayScript.Core/Vector.cs b/mcs/class/PlayScript.Core/Vector.cs
new file mode 100644 (file)
index 0000000..70e0e32
--- /dev/null
@@ -0,0 +1,120 @@
+//
+// Vector.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using PlayScript.Runtime.CompilerServices;
+
+namespace _root
+{
+       [DynamicClass]
+       public class Vector<T>
+       {
+               readonly List<T> list;
+               
+               public Vector (int length = 0, bool @fixed = false)
+               {
+                       list = new List<T> (length);
+                       this.@fixed = @fixed;
+               }
+
+               public Vector (params T[] values)
+               {
+                       list = new List<T> (values);
+               }
+
+               private Vector (List<T> list)
+               {
+                       this.list = list;
+               }
+               
+               public bool @fixed { get; set; } 
+               
+               public uint length {
+                       get {
+                               return (uint) list.Count;
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+               
+               public Vector<T> concat ([RestArrayParameter] Array args)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public Vector<T> concat (params T[] args)
+               {
+                       var res = new List<T> (list);
+                       res.AddRange (args);
+                       return new Vector<T> (res);
+               }
+
+               public int indexOf (T searchElement, int fromIndex)
+               {
+                       return list.IndexOf (searchElement, fromIndex);
+               }
+
+               public int lastIndexOf (T searchElement, int fromIndex = 0x7fffffff)
+               {
+                       return list.LastIndexOf (searchElement, fromIndex);                     
+               }
+               
+               public uint push (T value)
+               {
+                       list.Add (value);
+                       return length;
+               }
+
+               public uint unshift ([RestArrayParameter] Array args)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public uint unshift (params T[] args)
+               {
+                       list.InsertRange (0, args);
+                       return length;
+               }
+
+               internal void setValue (uint index, T value)
+               {
+                       if (index < length) {
+                               list [(int) index] = value;
+                               return;
+                       }
+
+//                     while (length < index - 1)
+//                             list.Add (default (T)); // TODO: Need better "invisible" value, perhaps DELETED?
+
+                       list.Add (value);
+               }               
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/VerifyError.play b/mcs/class/PlayScript.Core/VerifyError.play
new file mode 100644 (file)
index 0000000..0946ce7
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public class VerifyError extends Error {
+       
+               public function VerifyError(message:String = "") {
+                       super(message);
+               }
+               
+       }
+
+}
+
+
diff --git a/mcs/class/PlayScript.Core/XML.play b/mcs/class/PlayScript.Core/XML.play
new file mode 100644 (file)
index 0000000..57e2fe6
--- /dev/null
@@ -0,0 +1,282 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+       import System.*;
+       import System.Xml.*;
+
+       public class XML {
+       
+               var mElement:XmlElement;
+
+               //
+               // Properties
+               //
+               
+               public static property ignoreComments : Boolean {
+                       get { throw new System.NotImplementedException(); }
+                       set { throw new System.NotImplementedException(); }
+               }
+
+               public static property ignoreProcessingInstructions : Boolean {
+                       get { throw new System.NotImplementedException(); } 
+                       set { throw new System.NotImplementedException(); } 
+               }
+
+               public static property ignoreWhitespace : Boolean { 
+                       get { throw new System.NotImplementedException(); } 
+                       set { throw new System.NotImplementedException(); } 
+               }
+
+               public static property prettyIndent : int { 
+                       get { throw new System.NotImplementedException(); } 
+                       set { throw new System.NotImplementedException(); } 
+               }
+
+               public static property prettyPrinting : Boolean { 
+                       get { throw new System.NotImplementedException(); } 
+                       set { throw new System.NotImplementedException(); } 
+               }
+
+               //
+               // Methods
+               // 
+               
+               public function XML(value:Object) {
+/*             
+                       if (value is XmlElement) 
+                       {
+                               mElement = value as XmlElement;
+                       } else if (value is flash.utils.ByteArray) 
+                       {
+                               var ba:flash.utils.ByteArray = value as flash.utils.ByteArray;
+
+                               // read string from byte array
+                               ba.position = 0;
+                               var xmlString:String = ba.readAllUTF();
+
+                               // parse xml document from string
+                               var doc:XmlDocument = new XmlDocument();
+                               doc.LoadXml(xmlString);
+                               mElement = doc.DocumentElement;
+                       } else if (value is String)
+                       {
+                               // parse xml document from string
+                               var doc:XmlDocument = new XmlDocument();
+                               doc.LoadXml(value as String);
+                               mElement = doc.DocumentElement;
+                       }
+                       else
+                       {
+                               throw new System.NotImplementedException();
+                       }
+*/
+               }
+
+               internal function XML(value:XmlNode)
+               {
+                       // TODO: mElement = value;
+               }
+               
+               public function addNamespace(ns:Object):XML {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function appendChild(child:Object):XML {
+                       throw new System.NotImplementedException();
+               }
+               
+               /*
+               public function attribute(attributeName:String):XMLList {
+                       throw new System.NotImplementedException();
+               }*/
+
+               public function attribute(attributeName:String):String {
+                       return mElement.HasAttribute(attributeName) ? mElement.GetAttribute(attributeName) : null;
+               }
+
+               public function attributes():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function child(propertyName:Object):XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function childIndex():int {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function children():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function comments():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function contains(value:XML):Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function copy():XML {
+                       throw new System.NotImplementedException();
+               }
+               
+               public static function defaultSettings():Object {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function descendants():XMLList {
+                       throw new System.NotImplementedException();
+               }               
+               
+               public function descendants(name:Object):XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function elements():XMLList {
+                       return new XMLList(mElement.GetElementsByTagName("*"));
+               }               
+               
+               public function elements(name:String):XMLList {
+                       return new XMLList(mElement.GetElementsByTagName(name));
+               }
+               
+               public function hasComplexContent():Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function hasOwnProperty(p:String):Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function hasSimpleContent():Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function inScopeNamespaces():Array {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function insertChildAfter(child1:Object, child2:Object):* {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function insertChildBefore(child1:Object, child2:Object):* {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function length():int {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function localName():String {
+                       return mElement.LocalName;
+               }
+               
+               public function name():QName {
+                       return new QName(mElement.NamespaceURI, mElement.Name);
+               }
+               
+               public function @namespace(prefix:String = null):* {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function namespaceDeclarations():Array {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function nodeKind():String {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function normalize():XML {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function parent():* {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function prependChild(value:Object):XML {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function processingInstructions(name:String):XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function propertyIsEnumerable(p:String):Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function removeNamespace(ns:Namespace):XML {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function replace(propertyName:Object, value:XML):XML {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function setChildren(value:Object):XML {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function setLocalName(name:String):void {
+                       throw new System.NotImplementedException();             
+               }
+               
+               public function setName(name:String):void {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function setNamespace(ns:Namespace):void {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function setSettings(... rest):void {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function settings():Object {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function text():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function toJSON(k:String):* {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function toString():String {
+            throw new System.NotImplementedException();
+               }
+               
+               public function toXMLString():String {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function valueOf():Object {
+                       throw new System.NotImplementedException();
+               }
+       
+               public static implicit operator String (xml:XML) {
+                       throw new System.NotImplementedException();
+               }       
+       }
+
+}
diff --git a/mcs/class/PlayScript.Core/XMLList.play b/mcs/class/PlayScript.Core/XMLList.play
new file mode 100644 (file)
index 0000000..47e0b92
--- /dev/null
@@ -0,0 +1,180 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public /*final*/ dynamic class XMLList
+       {
+               public function XMLList (value:*=null)
+               {
+
+               }
+       }
+/*
+       import System.Xml.*;
+       import System.Collections.*;
+       import System.Collections.Generic.*;
+       import System.Linq.*;
+
+       public class XMLList implements IEnumerable.<XML> {
+       
+               var mList:List.<XML> = new List.<XML>();
+
+               //
+               // Methods
+               //
+               
+               public function XMLList(value:Object) {
+                       if (value == null) {
+                               // empty
+                       }
+                       else {
+                               throw new System.NotImplementedException();
+                       }
+               }
+
+               internal function XMLList(value:XmlNodeList)
+               {
+                       // create list of XML from node list
+
+                       for each ( var node:XmlNode in value) {
+                               if (node is XmlElement) {
+                                       mList.Add(new XML(node));
+                               }
+                       }
+               }
+
+               internal function XMLList ()
+               {               
+               }
+               
+               public function attribute(attributeName:String):String {
+                       if (mList.Count != 1)
+                               throw new System.NotImplementedException();
+                       
+                       return mList[0].attribute(attributeName);
+               }
+               
+               public function attributes():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function child(propertyName:Object):XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function children():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function comments():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function contains(value:XML):Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function copy():XMLList {
+                       throw new System.NotImplementedException();
+               }
+
+               public function descendants():XMLList {
+                       throw new System.NotImplementedException();
+               }
+                                               
+               public function descendants(name:Object):XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function elements():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function elements(name:String):XMLList {
+                       if (mList.Count == 0)
+                               return new XMLList();
+
+                       if (mList.Count != 1)
+                               throw new System.NotImplementedException();
+
+                       return mList[0].elements(name);
+               }
+               
+               public function hasComplexContent():Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function hasOwnProperty(p:String):Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function hasSimpleContent():Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function length():int {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function normalize():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function parent():Object {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function processingInstructions(name:String = "*"):XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function propertyIsEnumerable(p:String):Boolean {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function text():XMLList {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function toString():String {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function toXMLString():String {
+                       throw new System.NotImplementedException();
+               }
+               
+               public function valueOf():Object {
+                       throw new System.NotImplementedException();
+               }
+               
+               public indexer this(index:int):XML {
+                       get { throw new System.NotImplementedException(); }
+               }
+               
+               public static implicit operator String (list:XMLList) {
+                       throw new System.NotImplementedException();
+               }
+               
+               function IEnumerable.<XML>.GetEnumerator() : IEnumerator.<XML> {
+                       return mList.GetEnumerator();
+               }
+               
+               function IEnumerable.GetEnumerator() : IEnumerator { 
+                       return mList.GetEnumerator();
+               }
+       }
+*/
+}
diff --git a/mcs/class/PlayScript.Core/functions.cs b/mcs/class/PlayScript.Core/functions.cs
new file mode 100644 (file)
index 0000000..a528d12
--- /dev/null
@@ -0,0 +1,148 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+
+namespace _root
+{
+
+       //
+       // Conversions (must be in C# to avoid conflicts).
+       //
+
+       public static class String_fn
+       {
+               public static string String (object o)
+               {
+                       return o.ToString();
+               }
+
+               public static string String (string s)
+               {
+                       return s;
+               }
+
+               public static string String (int i)
+               {
+                       return i.ToString ();
+               }
+
+               public static string String (uint u)
+               {
+                       return u.ToString ();
+               }
+
+               public static string String (double d)
+               {
+                       return d.ToString ();
+               }
+
+               public static string String (bool b)
+               {
+                       return b.ToString ();
+               }
+
+       }
+
+       public static class Number_fn
+       {  
+               // Inlineable method
+               public static double Number (string s)
+               {
+                       double d;
+                       double.TryParse(s, out d);
+                       return d;
+               }
+
+       }
+
+       public static class int_fn
+       {  
+               // Inlineable method
+               public static int @int (string s)
+               {
+                       int i;
+                       int.TryParse(s, out i);
+                       return i;
+               }
+               
+       }
+
+       public static class uint_fn
+       {  
+
+               // Inlineable method
+               public static uint @uint (string s)
+               {
+                       uint u;
+                       uint.TryParse(s, out u);
+                       return u;
+               }
+
+       }
+
+       public static class Boolean_fn
+       {  
+
+               // Not inlinable.. but required to get correct results in flash.
+               public static bool Boolean (object d)
+               {
+                       if (d == null) return false;
+
+                       TypeCode tc = Type.GetTypeCode(d.GetType());
+                       switch (tc) {
+                       case TypeCode.Boolean:
+                               return (bool)d;
+                       case TypeCode.SByte:
+                               return (sbyte)d != 0;
+                       case TypeCode.Byte:
+                               return (byte)d != 0;
+                       case TypeCode.Int16:
+                               return (short)d != 0;
+                       case TypeCode.UInt16:
+                               return (ushort)d != 0;
+                       case TypeCode.Int32:
+                               return (int)d != 0;
+                       case TypeCode.UInt32:
+                               return (uint)d != 0;
+                       case TypeCode.Int64:
+                               return (long)d != 0;
+                       case TypeCode.UInt64:
+                               return (ulong)d != 0;
+                       case TypeCode.Single:
+                               return (float)d != 0.0f;
+                       case TypeCode.Double:
+                               return (double)d != 0.0;
+                       case TypeCode.Decimal:
+                               return (decimal)d != 0;
+                       case TypeCode.String:
+                               var s = (string)d;
+                               return !string.IsNullOrEmpty(s) && s != "0" && s != "false";
+                       case TypeCode.Empty:
+                               return false;
+                       case TypeCode.Object:
+                               return d != null;
+                       }
+                       return false;
+               }
+
+               // Inlineable method
+               public static bool Boolean (string s)
+               {
+                       throw new System.NotImplementedException();
+               }
+
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/int.cs b/mcs/class/PlayScript.Core/int.cs
new file mode 100644 (file)
index 0000000..cf003dc
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright 2013 Zynga Inc.
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+using System;
+
+namespace _root
+{
+       public static class @int
+       {
+               //
+               // Methods
+               //
+
+               public static string toExponential(this int i, uint fractionDigits) {
+                       throw new NotImplementedException();
+               }
+                       
+               public static string toFixed(this int i, uint fractionDigits) {
+                       throw new NotImplementedException();
+               }
+                       
+               public static string toPrecision(this int i, uint precision) {
+                       throw new NotImplementedException();
+               }
+                       
+               public static string toString(this int i) {
+                       throw new NotImplementedException();
+               }
+       
+               public static string toString(this int i, uint radix) {
+                       return Convert.ToString(i, (int)radix);
+               }
+                       
+               public static int valueOf(this int i) {
+                       return i;
+               }
+
+               //
+               // Constants
+               //
+                       
+               public const int MAX_VALUE  = 2147483647;
+
+               public const int MIN_VALUE = -2147483648;
+
+       }
+
+       public static class @uint
+       {
+               public const uint MAX_VALUE = System.UInt32.MaxValue;
+               public const uint MIN_VALUE = System.UInt32.MinValue;
+       }
+}
+
diff --git a/mcs/class/PlayScript.Core/toplevel.play b/mcs/class/PlayScript.Core/toplevel.play
new file mode 100644 (file)
index 0000000..b1a38c3
--- /dev/null
@@ -0,0 +1,119 @@
+//
+// toplevel.play
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright 2013 Zynga Inc.
+// Copyright (C) 2013 Xamarin, Inc (http://www.xamarin.com)
+//     
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//             
+//      Unless required by applicable law or agreed to in writing, software
+//      distributed under the License is distributed on an "AS IS" BASIS,
+//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//      See the License for the specific language governing permissions and
+//      limitations under the License.
+
+package {
+
+       public function isA(obj:*, cl:Class):Boolean {
+               throw new System.NotImplementedException();     
+       }
+
+       public function decodeURI(uri:String):String {
+               throw new System.NotImplementedException();     
+       }
+               
+       public function decodeURIComponent(uri:String):String {
+               throw new System.NotImplementedException();     
+       }
+               
+       public function encodeURI(uri:String):String {
+               throw new System.NotImplementedException();     
+       }
+               
+       public function encodeURIComponent(uri:String):String {
+               throw new System.NotImplementedException();     
+       }
+               
+       public function escape(str:String):String {
+               throw new System.NotImplementedException();     
+       }
+               
+       public function isFinite(num:Number):Boolean {
+               throw new System.NotImplementedException();     
+       }
+               
+       public function isNaN(num:Number):Boolean {
+               return System.Double.IsNaN(num);
+       }
+                       
+       public function isXMLName(str:String):Boolean {
+               throw new System.NotImplementedException();     
+       }
+               
+       public function parseFloat(str:String):Number {
+               if (!System.String.IsNullOrEmpty(str))
+               {
+                       return System.Double.Parse(str);
+               } else {
+                       return System.Double.NaN;
+               }
+       }
+
+       public static function trace(o:System.Object):void {
+//             System.Diagnostics.Debug.WriteLine(o);
+               System.Console.WriteLine(o);
+       }
+               
+       public static function trace(o1:System.Object, o2:System.Object):void {
+//             System.Diagnostics.Debug.WriteLine("{0}{1}", o1, o2);
+               System.Console.WriteLine("{0} {1}", o1, o2);
+       }
+
+       public static function trace(o1:System.Object, o2:System.Object, o3:System.Object):void {
+//             System.Diagnostics.Debug.WriteLine("{0}{1}{2}", o1, o2, o3);
+               System.Console.WriteLine("{0} {1} {2}", o1, o2, o3);
+       }
+
+       public static function trace(o1:System.Object, o2:System.Object, o3:System.Object, ...args):void {
+               var argsStr = System.String.Concat(args);
+//             System.Diagnostics.Debug.WriteLine("{0}{1}{2}{3}", o1, o2, o3, argsStr);
+               System.Console.WriteLine("{0} {1} {2} {3}", o1, o2, o3, argsStr);
+       }
+               
+       public function parseInt(str:String, radix:uint = 0):int {
+               if (radix != 0 && radix != 10) 
+                       throw new System.NotImplementedException();
+                       
+               return System.Int32.Parse(str); 
+       }
+               
+       public function unescape(str:String):String {
+               throw new System.NotImplementedException();
+       }
+
+       // Constants
+       public const undefined : * = PlayScript.Runtime.Undefined.Value;
+       public const Infinity : Number = System.Double.PositiveInfinity;
+       public const NaN : Number = System.Double.NaN;
+
+/*     
+       public function loadEmbed(baseObject:Object, fieldName:String):Object
+       {
+               // pass this off to C# code
+               return PlayScript.Player.LoadEmbed(baseObject, fieldName);
+       }
+
+       public function invokeStaticMethod(type:Class, methodName:String, args:Array):Object
+       {
+               // pass this off to C# code
+               return PlayScript.Player.InvokeStaticMethod(type, methodName, args);
+       }
+*/
+}
index 50b1dde31dc6ce019c89444d34f7ed80e2fbf59c..d2ba32927b98ca0786a631e22040e99e3052d1ba 100644 (file)
@@ -1,5 +1,5 @@
 y.output
-cs-parser.cs
+*-parser.cs
 ?mcs.user
 ?mcs.csproj.user
 mcs.csproj.user
index d2aa50e7a9c8371ae417511cb81057043950f723..82a75363f669312e2277c1d97ea533c25d1ba14a 100644 (file)
@@ -28,7 +28,7 @@ PROGRAM_INSTALL_DIR = $(mono_libdir)/mono/4.5
 
 PROGRAM_COMPILE = $(BOOT_COMPILE)
 
-BUILT_SOURCES = cs-parser.cs
+BUILT_SOURCES = cs-parser.cs ps-parser.cs
 
 CLEAN_FILES += y.output
 
index 61cb8e239275e94c9375e11e2958f804567b6f8d..f2ae0265717807d9bd78c7896ec42b6c7cb65b82 100644 (file)
@@ -392,9 +392,9 @@ namespace Mono.CSharp {
                        return System.Linq.Expressions.Expression.Assign (target_object, source_object);
                }
 #endif
-               protected virtual Expression ResolveConversions (ResolveContext ec)
+               protected virtual Expression ResolveConversions (ResolveContext rc)
                {
-                       source = Convert.ImplicitConversionRequired (ec, source, target.Type, source.Location);
+                       source = Convert.ImplicitConversionRequiredEnhanced (rc, source, target.Type, source.Location);
                        if (source == null)
                                return null;
 
@@ -565,13 +565,18 @@ namespace Mono.CSharp {
                                return null;
 
                        if (resolved == null) {
-                               var ctx = new FieldInitializerContext (mc, ec);
-                               resolved = base.DoResolve (ctx) as ExpressionStatement;
+                               resolved = ResolveInitializer (ec);
                        }
 
                        return resolved;
                }
 
+               protected virtual ExpressionStatement ResolveInitializer (ResolveContext rc)
+               {
+                       var ctx = new FieldInitializerContext (mc, rc);
+                       return base.DoResolve (ctx) as ExpressionStatement;
+               }
+
                public override void EmitStatement (EmitContext ec)
                {
                        if (resolved == null)
index 8343e82f2c70b01e417a979421c86ae94c695775..9a983536f6cf96a87f33e49742435bf7b20601f3 100644 (file)
@@ -19,6 +19,7 @@ using System.Security;
 using System.Security.Permissions;
 using System.Text;
 using System.Diagnostics;
+using System.Linq;
 using Mono.CompilerServices.SymbolWriter;
 
 #if NET_2_1
@@ -348,8 +349,13 @@ namespace Mono.CSharp
 
                public override string GetSignatureForError ()
                {
-                       if (Parent != null && Parent.MemberName != null) 
-                               return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError ();
+                       if (Parent != null && Parent.MemberName != null) {
+                               var parent = Parent.GetSignatureForError ();
+                               if (string.IsNullOrEmpty (parent))
+                                       return MemberName.GetSignatureForError ();
+
+                               return parent + "." + MemberName.GetSignatureForError ();
+                       }
 
                        return MemberName.GetSignatureForError ();
                }
@@ -675,6 +681,8 @@ namespace Mono.CSharp
                        }
                }
 
+               public bool IsPlayScriptType { get; set; }
+
                bool ITypeDefinition.IsTypeForwarder {
                        get {
                                return false;
@@ -1067,6 +1075,24 @@ namespace Mono.CSharp
                        type_bases = baseTypes;
                }
 
+               public void AddBaseType (FullNamedExpression baseType)
+               {
+                       if (type_bases == null)
+                               type_bases = new List<FullNamedExpression> ();
+
+                       type_bases.Add (baseType);
+               }
+
+               public virtual void AddBaseTypes (List<FullNamedExpression> baseTypes)
+               {
+                       if (type_bases == null) {
+                               type_bases = baseTypes;
+                               return;
+                       }
+
+                       type_bases.AddRange (baseTypes);
+               }
+
                /// <summary>
                ///   This function computes the Base class and also the
                ///   list of interfaces that the class or struct @c implements.
@@ -1228,6 +1254,11 @@ namespace Mono.CSharp
                        //
                        int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
 
+                       if (IsPlayScriptType && Parent is CompilationSourceFile) {
+                               // TODO: Package in this file could be missing
+                               Parent = Parent.Containers.First (l => l is PlayScript.Package).Containers[0];
+                       }
+
                        var parent_def = Parent as TypeDefinition;
                        if (parent_def == null) {
                                var sb = new StringBuilder ();
@@ -2549,22 +2580,28 @@ namespace Mono.CSharp
 
        public sealed class Class : ClassOrStruct
        {
-               const Modifiers AllowedModifiers =
-                       Modifiers.NEW |
-                       Modifiers.PUBLIC |
-                       Modifiers.PROTECTED |
-                       Modifiers.INTERNAL |
-                       Modifiers.PRIVATE |
-                       Modifiers.ABSTRACT |
-                       Modifiers.SEALED |
-                       Modifiers.STATIC |
-                       Modifiers.UNSAFE;
-
-               public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
+               public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs, bool playScriptType = false)
                        : base (parent, name, attrs, MemberKind.Class)
                {
+                       var allowed =
+                               Modifiers.NEW |
+                               Modifiers.PUBLIC |
+                               Modifiers.PROTECTED |
+                               Modifiers.INTERNAL |
+                               Modifiers.PRIVATE |
+                               Modifiers.ABSTRACT |
+                               Modifiers.SEALED |
+                               Modifiers.STATIC |
+                               Modifiers.UNSAFE;
+
                        var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
-                       this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, accmods, Location, Report);
+                       if (playScriptType) {
+                               IsPlayScriptType = true;
+                               allowed &= Modifiers.AccessibilityMask;
+                               allowed |= Modifiers.DYNAMIC | Modifiers.SEALED;
+                       }
+
+                       ModFlags = ModifiersExtensions.Check (allowed, mod, accmods, Location, Report);
                        spec = new TypeSpec (Kind, null, this, null, ModFlags);
                }
 
@@ -2670,7 +2707,13 @@ namespace Mono.CSharp
                        if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
                                Module.PredefinedAttributes.Extension.EmitAttribute (TypeBuilder);
 
-                       if (base_type != null && base_type.HasDynamicElement) {
+                       if (IsPlayScriptType) {
+                               if ((ModFlags & Modifiers.DYNAMIC) != 0) {
+                                       Module.PlayscriptAttributes.DynamicClass.EmitAttribute (TypeBuilder);
+                               } else {
+                                       Module.PlayscriptAttributes.PlayScript.EmitAttribute (TypeBuilder);
+                               }
+                       } else if (base_type != null && base_type.HasDynamicElement) {
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (TypeBuilder, base_type, Location);
                        }
                }
@@ -3086,8 +3129,8 @@ namespace Mono.CSharp
                readonly Modifiers explicit_mod_flags;
                public MethodAttributes flags;
 
-               public InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
-                       : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
+               public InterfaceMemberBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers defaultModifiers, MemberName name, Attributes attrs)
+                       : base (parent, type, mod, allowed_mod, defaultModifiers, name, attrs)
                {
                        IsInterface = parent.Kind == MemberKind.Interface;
                        IsExplicitImpl = (MemberName.ExplicitInterface != null);
@@ -3455,9 +3498,9 @@ namespace Mono.CSharp
                //
                // Returns full metadata method name
                //
-               public string GetFullName (MemberName name)
+               public override string GetFullName (MemberName name)
                {
-                       return GetFullName (name.Name);
+                       return GetFullName (base.GetFullName (name));
                }
 
                public string GetFullName (string name)
@@ -3625,6 +3668,20 @@ namespace Mono.CSharp
                        return true;
                }
 
+               //
+               // Returns full metadata method name
+               //
+               public virtual string GetFullName (MemberName name)
+               {
+                       if (name.Left != null) {
+                               StringBuilder sb = new StringBuilder ();
+                               name.CreateMetadataName (sb);
+                               return sb.ToString ();
+                       }
+
+                       return name.Name;
+               }
+
                public override string GetSignatureForDocumentation ()
                {
                        return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename;
index eef90b34603c80175df19f75373cc6c0502e6b62..77802ccdd5bdc76bfe5061313f6402d20c94a2db 100644 (file)
@@ -9,6 +9,8 @@
 // Copyright 2003-2008 Novell, Inc.
 //
 
+using System;
+
 #if STATIC
 using IKVM.Reflection;
 #else
@@ -120,6 +122,9 @@ namespace Mono.CSharp {
                public ConstSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo fi, Modifiers mod, Expression value)
                        : base (declaringType, definition, memberType, fi, mod)
                {
+                       if (value == null)
+                               throw new ArgumentNullException ("value");
+
                        this.value = value;
                }
 
index 397d72c9a4ae7653be65733999a337aaf1567695..ddc8b3b24387c75d222dbbf77771ec5dad775137 100644 (file)
@@ -376,6 +376,11 @@ namespace Mono.CSharp {
                        // It exists only as hint not to call Resolve on constants
                        return true;
                }
+
+               public override Constant ResolveAsPlayScriptConstant (ResolveContext rc)
+               {
+                       return this;
+               }
        }
 
        public abstract class IntegralConstant : Constant
@@ -2094,7 +2099,7 @@ namespace Mono.CSharp {
                        }
 
                        // Exlude internal compiler types
-                       if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
+                       if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic && targetType.BuiltinType != BuiltinTypeSpec.Type.Object)
                                return null;
 
                        if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
index f636ffdb0a004740dad6eacb846f872068f3f54b..cc943a22e904d0bebb7842cc40ec9f77a9cc08df 100644 (file)
@@ -457,6 +457,12 @@ namespace Mono.CSharp
                        }
                }
 
+               public bool IsPlayScriptType {
+                       get {
+                               return CurrentType.MemberDefinition.IsPlayScriptType;
+                       }
+               }
+
                public bool IsStatic {
                        get {
                                return MemberContext.IsStatic;
index bfbfe0374955c5e6fc33957e3ecd2527d8594a99..3aef1cb4321a84f185ae73a9048715e4a82a6e88 100644 (file)
@@ -336,9 +336,9 @@ namespace Mono.CSharp {
                                // from the null literal to any reference-type.
                                //
                                if (expr_type == InternalType.NullLiteral) {
-                                       // Exlude internal compiler types
+                                       // Exclude internal compiler types
                                        if (target_type.Kind == MemberKind.InternalCompilerType)
-                                               return target_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
+                                               return target_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic || target_type.BuiltinType == BuiltinTypeSpec.Type.Object;
 
                                        return TypeSpec.IsReferenceType (target_type);
                                }
@@ -363,6 +363,9 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
+                               if (expr_type.BuiltinType == BuiltinTypeSpec.Type.Object)
+                                       return target_type.BuiltinType == BuiltinTypeSpec.Type.Object || target_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
+
                                break;
                        }
 
@@ -1471,6 +1474,22 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               public static Expression ImplicitConversionRequiredEnhanced (ResolveContext rc, Expression source, TypeSpec targetType, Location loc)
+               {
+                       Expression e = ImplicitConversion (rc, source, targetType, loc);
+                       if (e != null)
+                               return e;
+
+                       if (rc.IsPlayScriptType) {
+                               e = PlayScript.Convert.ImplicitConversion (source, targetType);
+                               if (e != null)
+                                       return e;
+                       }
+
+                       source.Error_ValueCannotBeConverted (rc, targetType, false);
+                       return null;
+               }
+
                /// <summary>
                ///   Performs the explicit numeric conversions
                ///
index e7f27aa7d626a32151675707335df0dc6312ff5f..bc3f9174fca71de2351e527a58d529c2fb685576 100644 (file)
@@ -112,6 +112,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public virtual string LookupName {
+                       get {
+                               return Name;
+                       }
+               }
+
                public void CreateMetadataName (StringBuilder sb)
                {
                        if (Left != null)
@@ -137,7 +143,7 @@ namespace Mono.CSharp {
                        return Left.GetSignatureForDocumentation () + "." + s;
                }
 
-               public string GetSignatureForError ()
+               public virtual string GetSignatureForError ()
                {
                        string s = TypeParameters == null ? null : "<" + TypeParameters.GetSignatureForError () + ">";
                        s = Name + s;
@@ -1289,4 +1295,54 @@ namespace Mono.CSharp {
        {
                TypeSpec MemberType { get; }
        }
+
+       class AliasMemberDefinition : IMemberDefinition
+       {
+               readonly string name;
+               readonly IMemberDefinition original;
+
+               public AliasMemberDefinition (string name, IMemberDefinition original)
+               {
+                       this.name = name;
+                       this.original = original;
+               }
+
+               public bool? CLSAttributeValue {
+                       get {
+                               return original.CLSAttributeValue;
+                       }
+               }
+
+               public string Name {
+                       get {
+                               return name;
+                       }
+               }
+
+               public bool IsImported {
+                       get {
+                               return original.IsImported;
+                       }
+               }
+
+               public string[] ConditionalConditions ()
+               {
+                       return original.ConditionalConditions ();
+               }
+
+               public ObsoleteAttribute GetAttributeObsolete ()
+               {
+                       return original.GetAttributeObsolete ();
+               }
+
+               public void SetIsAssigned ()
+               {
+                       original.SetIsAssigned ();
+               }
+
+               public void SetIsUsed ()
+               {
+                       original.SetIsUsed ();
+               }
+       }
 }
index 45c9719ea6a51b987ade77acc0da32e5fa0b18b5..17bc2a2444efebe6dc3a001594635efd5fbe3ecf 100644 (file)
@@ -166,8 +166,13 @@ namespace Mono.CSharp
                        var file = new CompilationSourceFile (module, sourceFile);
                        module.AddTypeContainer (file);
 
-                       CSharpParser parser = new CSharpParser (reader, file, report, session);
-                       parser.parse ();
+                       if (sourceFile.IsPlayScript) {
+                               var parser = new PlayScript.PlayScriptParser (reader, file, report, session);
+                               parser.parse ();
+                       } else {
+                               var parser = new CSharpParser (reader, file, report, session);
+                               parser.parse ();
+                       }
                }
                
                public static int Main (string[] args)
index a15f16ca2599b29652b15db152d1d13c0251e290..b0162f9563538e872397bd9096f0c407933d29e3 100644 (file)
@@ -238,6 +238,11 @@ namespace Mono.CSharp {
                        return null;
                }
 
+               public virtual Constant ResolveAsPlayScriptConstant (ResolveContext rc)
+               {
+                       return null;
+               }
+
                public static void ErrorIsInaccesible (IMemberContext rc, string member, Location loc)
                {
                        rc.Module.Compiler.Report.Error (122, loc, "`{0}' is inaccessible due to its protection level", member);
@@ -732,7 +737,8 @@ namespace Mono.CSharp {
                        None = 0,
                        InvocableOnly = 1,
                        ExactArity = 1 << 2,
-                       ReadAccess = 1 << 3
+                       ReadAccess = 1 << 3,
+                       PlayScriptConversion = 1 << 4
                }
 
                //
@@ -3210,7 +3216,7 @@ namespace Mono.CSharp {
                                }
 
                                InstanceExpression = new This (loc);
-                               if (this is FieldExpr && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
+                               if (this is FieldExpr && rc.CurrentBlock != null && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
                                        using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
                                                InstanceExpression = InstanceExpression.Resolve (rc);
                                        }
@@ -4624,12 +4630,19 @@ namespace Mono.CSharp {
                                        continue;
                                }
 
-                               if (p_mod != Parameter.Modifier.PARAMS) {
-                                       p_mod = (pd.FixedParameters[i].ModFlags & ~Parameter.Modifier.PARAMS) | (cpd.FixedParameters[i].ModFlags & Parameter.Modifier.PARAMS);
+                               if ((p_mod & Parameter.Modifier.VariableArgumentsMask) == 0) {
+                                       p_mod = (pd.FixedParameters[i].ModFlags & ~Parameter.Modifier.VariableArgumentsMask) |
+                                               (cpd.FixedParameters[i].ModFlags & Parameter.Modifier.VariableArgumentsMask);
                                        pt = ptypes [i];
                                } else if (!params_expanded_form) {
                                        params_expanded_form = true;
-                                       pt = ((ElementTypeSpec) pt).Element;
+
+                                       var array = pt as ArrayContainer;
+                                       if (array != null)
+                                               pt = array.Element;
+                                       else
+                                               pt = ec.Module.PlayscriptTypes.Object;
+
                                        i -= 2;
                                        continue;
                                }
@@ -4660,9 +4673,12 @@ namespace Mono.CSharp {
                                //
                                // It can be applicable in expanded form (when not doing exact match like for delegates)
                                //
-                               if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0 && (restrictions & Restrictions.CovariantDelegate) == 0) {
+                               if (score != 0 && (p_mod & Parameter.Modifier.VariableArgumentsMask) != 0 && (restrictions & Restrictions.CovariantDelegate) == 0) {
                                        if (!params_expanded_form) {
-                                               pt = ((ElementTypeSpec) pt).Element;
+                                               if (p_mod == Parameter.Modifier.PARAMS)
+                                                       pt = ((ArrayContainer) pt).Element;
+                                               else
+                                                       pt = ec.Module.PlayscriptTypes.Object;
                                        }
 
                                        if (score > 0)
@@ -4686,9 +4702,14 @@ namespace Mono.CSharp {
                        //
                        // When params parameter has no argument it will be provided later if the method is the best candidate
                        //
-                       if (arg_count + 1 == pd.Count && (cpd.FixedParameters [arg_count].ModFlags & Parameter.Modifier.PARAMS) != 0)
+                       // ActionScript has different logic for params style arguments when argument count matches. It still
+                       // created an Array with 1 element even if argument type is convertible to array
+                       //
+                       if ((arg_count + 1 == pd.Count && cpd.HasParams) ||
+                               (arg_count > 0 && arg_count == param_count && pd.FixedParameters[param_count - 1].ModFlags == Parameter.Modifier.RestArray))
                                params_expanded_form = true;
 
+
                        //
                        // Restore original arguments for dynamic binder to keep the intention of original source code
                        //
@@ -5270,18 +5291,22 @@ namespace Mono.CSharp {
                        ArrayInitializer params_initializers = null;
                        bool has_unsafe_arg = pm.MemberType.IsPointer;
                        int arg_count = args == null ? 0 : args.Count;
+                       bool playscript_params = false;
 
                        for (; a_idx < arg_count; a_idx++, ++a_pos) {
                                a = args[a_idx];
-                               if (p_mod != Parameter.Modifier.PARAMS) {
+                               if ((p_mod & Parameter.Modifier.VariableArgumentsMask) == 0) {
                                        p_mod = pd.FixedParameters[a_idx].ModFlags;
                                        pt = ptypes[a_idx];
                                        has_unsafe_arg |= pt.IsPointer;
 
-                                       if (p_mod == Parameter.Modifier.PARAMS) {
-                                               if (chose_params_expanded) {
-                                                       params_initializers = new ArrayInitializer (arg_count - a_idx, a.Expr.Location);
-                                                       pt = TypeManager.GetElementType (pt);
+                                       if (chose_params_expanded && (p_mod & Parameter.Modifier.VariableArgumentsMask) != 0) {
+                                               params_initializers = new ArrayInitializer (arg_count - a_idx, a.Expr.Location);
+                                               if (p_mod == Parameter.Modifier.PARAMS) {
+                                                       pt = ((ArrayContainer) pt).Element;
+                                               } else {
+                                                       playscript_params = true;
+                                                       pt = ec.Module.PlayscriptTypes.Object;
                                                }
                                        }
                                }
@@ -5379,8 +5404,14 @@ namespace Mono.CSharp {
                                        args = new Arguments (1);
 
                                pt = ptypes[pd.Count - 1];
-                               pt = TypeManager.GetElementType (pt);
-                               has_unsafe_arg |= pt.IsPointer;
+                               var array = pt as ArrayContainer;
+                               if (array != null) {
+                                       pt = array.Element;
+                                       has_unsafe_arg |= pt.IsPointer;
+                               } else {
+                                       playscript_params = true;
+                               }
+
                                params_initializers = new ArrayInitializer (0, loc);
                        }
 
@@ -5388,8 +5419,13 @@ namespace Mono.CSharp {
                        // Append an array argument with all params arguments
                        //
                        if (params_initializers != null) {
-                               args.Add (new Argument (
-                                       new ArrayCreation (new TypeExpression (pt, loc), params_initializers, loc).Resolve (ec)));
+                               Expression array_init;
+                               if (playscript_params)
+                                       array_init = new PlayScript.ArrayCreation (params_initializers);
+                               else
+                                       array_init = new ArrayCreation (new TypeExpression (pt, loc), params_initializers, loc);
+
+                               args.Add (new Argument (array_init.Resolve (ec)));
                                arg_count++;
                        }
 
@@ -6008,7 +6044,6 @@ namespace Mono.CSharp {
                        Error_TypeArgumentsCannotBeUsed (ec, "field", GetSignatureForError (), loc);
                }
        }
-
        
        //
        // Expression that evaluates to a Property.
@@ -6016,7 +6051,7 @@ namespace Mono.CSharp {
        // This is not an LValue because we need to re-write the expression. We
        // can not take data from the stack and store it.
        //
-       sealed class PropertyExpr : PropertyOrIndexerExpr<PropertySpec>
+       public sealed class PropertyExpr : PropertyOrIndexerExpr<PropertySpec>
        {
                Arguments arguments;
 
@@ -6275,13 +6310,22 @@ namespace Mono.CSharp {
                        return this;
                }
 
+               public override Constant ResolveAsPlayScriptConstant (ResolveContext rc)
+               {
+                       var prop = best_candidate.MemberDefinition as PlayScript.IConstantProperty;
+                       if (prop != null)
+                               return prop.Initializer.ResolveAsPlayScriptConstant (rc);
+
+                       return null;
+               }
+
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
                        Error_TypeArgumentsCannotBeUsed (ec, "property", GetSignatureForError (), loc);
                }
        }
 
-       abstract class PropertyOrIndexerExpr<T> : MemberExpr, IDynamicAssign where T : PropertySpec
+       public abstract class PropertyOrIndexerExpr<T> : MemberExpr, IDynamicAssign where T : PropertySpec
        {
                // getter and setter can be different for base calls
                MethodSpec getter, setter;
index f4d1e7fcb11d586e3dbb4ecd156980f3f0e2bc40..1902b2053067cd9199ed752776835aa0f32d966e 100644 (file)
@@ -2279,20 +2279,24 @@ namespace Mono.CSharp
 
                        LeftShift       = 5 | ShiftMask,
                        RightShift      = 6 | ShiftMask,
+                       UnsignedRightShift      = 7 | ShiftMask,  // PlayScript Unsigned Right Shift
 
-                       LessThan        = 7 | ComparisonMask | RelationalMask,
-                       GreaterThan     = 8 | ComparisonMask | RelationalMask,
-                       LessThanOrEqual         = 9 | ComparisonMask | RelationalMask,
-                       GreaterThanOrEqual      = 10 | ComparisonMask | RelationalMask,
-                       Equality        = 11 | ComparisonMask | EqualityMask,
-                       Inequality      = 12 | ComparisonMask | EqualityMask,
+                       LessThan        = 8 | ComparisonMask | RelationalMask,
+                       GreaterThan     = 9 | ComparisonMask | RelationalMask,
+                       LessThanOrEqual         = 10 | ComparisonMask | RelationalMask,
+                       GreaterThanOrEqual      = 11 | ComparisonMask | RelationalMask,
+                       Equality        = 12 | ComparisonMask | EqualityMask,
+                       Inequality      = 13 | ComparisonMask | EqualityMask,
+                       ReferenceEquality       = 14 | ComparisonMask | EqualityMask,  // PlayScript Reference Equality
+                       ReferenceInequality     = 15 | ComparisonMask | EqualityMask,  // PlayScript Reference Inequality
 
-                       BitwiseAnd      = 13 | BitwiseMask,
-                       ExclusiveOr     = 14 | BitwiseMask,
-                       BitwiseOr       = 15 | BitwiseMask,
 
-                       LogicalAnd      = 16 | LogicalMask,
-                       LogicalOr       = 17 | LogicalMask,
+                       BitwiseAnd      = 16 | BitwiseMask,
+                       ExclusiveOr     = 17 | BitwiseMask,
+                       BitwiseOr       = 18 | BitwiseMask,
+
+                       LogicalAnd      = 19 | LogicalMask,
+                       LogicalOr       = 20 | LogicalMask,
 
                        //
                        // Operator masks
@@ -2400,6 +2404,9 @@ namespace Mono.CSharp
                        case Operator.RightShift:
                                s = ">>";
                                break;
+                       case Operator.UnsignedRightShift:
+                               s = ">>>";
+                               break;
                        case Operator.LessThan:
                                s = "<";
                                break;
@@ -2415,9 +2422,15 @@ namespace Mono.CSharp
                        case Operator.Equality:
                                s = "==";
                                break;
+                       case Operator.ReferenceEquality:
+                               s = "===";
+                               break;
                        case Operator.Inequality:
                                s = "!=";
                                break;
+                       case Operator.ReferenceInequality:
+                               s = "!==";
+                               break;
                        case Operator.BitwiseAnd:
                                s = "&";
                                break;
@@ -3332,8 +3345,15 @@ namespace Mono.CSharp
                Expression DoResolveCore (ResolveContext ec, Expression left_orig, Expression right_orig)
                {
                        Expression expr = ResolveOperator (ec);
-                       if (expr == null)
+                       if (expr == null) {
+                               if (ec.IsPlayScriptType) {
+                                       expr = PlayScript.BinaryOperators.ResolveOperator (ec, this, left_orig, right_orig);
+                                       if (expr != null)
+                                               return expr;
+                               }
+
                                Error_OperatorCannotBeApplied (ec, left_orig, right_orig);
+                       }
 
                        if (left == null || right == null)
                                throw new InternalErrorException ("Invalid conversion");
@@ -3791,7 +3811,7 @@ namespace Mono.CSharp
                                        if (TypeSpec.IsReferenceType (r))
                                                return this;
 
-                                       if (r.Kind == MemberKind.InternalCompilerType)
+                                       if (r.Kind == MemberKind.InternalCompilerType && r.BuiltinType != BuiltinTypeSpec.Type.Object)
                                                return null;
                                }
 
@@ -3813,7 +3833,7 @@ namespace Mono.CSharp
                                        if (TypeSpec.IsReferenceType (l))
                                                return this;
 
-                                       if (l.Kind == MemberKind.InternalCompilerType)
+                                       if (l.Kind == MemberKind.InternalCompilerType && l.BuiltinType != BuiltinTypeSpec.Type.Object)
                                                return null;
                                }
 
@@ -6540,7 +6560,7 @@ namespace Mono.CSharp
                        }
                        
                        if (type is TypeParameterSpec)
-                               return DoEmitTypeParameter (ec);
+                               return DoEmitTypeParameter (ec);                        
 
                        ec.MarkCallEntry (loc);
                        ec.Emit (OpCodes.Newobj, method);
@@ -8619,7 +8639,7 @@ namespace Mono.CSharp
                        const MemberKind dot_kinds = MemberKind.Class | MemberKind.Struct | MemberKind.Delegate | MemberKind.Enum |
                                MemberKind.Interface | MemberKind.TypeParameter | MemberKind.ArrayType;
 
-                       return (type.Kind & dot_kinds) != 0 || type.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
+                       return (type.Kind & dot_kinds) != 0 || type.BuiltinType == BuiltinTypeSpec.Type.Dynamic || type.BuiltinType == BuiltinTypeSpec.Type.Object;
                }
 
                public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
@@ -8635,7 +8655,7 @@ namespace Mono.CSharp
                        //
                        using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
                                if (sn != null) {
-                                       expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity);
+                                       expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity | MemberLookupRestrictions.PlayScriptConversion);
 
                                        //
                                        // Resolve expression which does have type set as we need expression type
@@ -8762,6 +8782,27 @@ namespace Mono.CSharp
                                if (member_lookup != null)
                                        break;
 
+                               if (expr_type.IsDynamicClass && !rc.IsRuntimeBinder) {
+                                       me = expr as MemberExpr;
+                                       if (me != null)
+                                               me.ResolveInstanceExpression (rc, null);
+
+                                       //
+                                       // Run defined assigned checks on expressions resolved with
+                                       // disabled flow-analysis
+                                       //
+/*
+                                       if (sn != null) {
+                                               var vr = expr as VariableReference;
+                                               if (vr != null)
+                                                       vr.VerifyAssigned (rc);
+                                       }
+*/
+                                       Arguments args = new Arguments (1);
+                                       args.Add (new Argument (new StringLiteral (rc.BuiltinTypes, Name, loc)));
+                                       return new PlayScript.DynamicClassMemberAccess (expr, args, loc);
+                               }
+
                                lookup_arity = 0;
                                restrictions &= ~MemberLookupRestrictions.InvocableOnly;
                                errorMode = true;
@@ -9163,6 +9204,10 @@ namespace Mono.CSharp
                                return new IndexerExpr (indexers, type, this);
                        }
 
+                       if (type.IsDynamicClass) {
+                               return new PlayScript.DynamicClassMemberAccess (this);
+                       }
+
                        if (type != InternalType.ErrorType) {
                                ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
                                        type.GetSignatureForError ());
@@ -10460,6 +10505,13 @@ namespace Mono.CSharp
                                                ErrorIsInaccesible (ec, member.GetSignatureForError (), loc);
                                                return null;
                                        }
+
+                                       if (t.IsDynamicClass) {
+                                               Arguments args = new Arguments (1);
+                                               args.Add (new Argument (new StringLiteral (ec.BuiltinTypes, Name, loc)));
+                                               target = new PlayScript.DynamicClassMemberAccess (ec.CurrentInitializerVariable, args, loc);
+                                               return base.DoResolve (ec);
+                                       }
                                }
 
                                if (member == null) {
@@ -10697,6 +10749,11 @@ namespace Mono.CSharp
 
                                        if (!is_collection_initialization) {
                                                if (element_names.Contains (element_initializer.Name)) {
+                                                       if (ec.IsPlayScriptType) {
+                                                               initializers.RemoveAt (i--);
+                                                               continue;
+                                                       }
+
                                                        ec.Report.Error (1912, element_initializer.Location,
                                                                "An object initializer includes more than one member `{0}' initialization",
                                                                element_initializer.Name);
index 95c561980abe079514c970b633f938c634e139f8..fb165284d3021390dc5e1297e24270f05c552ac6 100644 (file)
@@ -255,7 +255,8 @@ namespace Mono.CSharp
                                Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute", GetSignatureForError ());
                        }
 
-                       ConstraintChecker.Check (this, member_type, type_expr.Location);
+                       if (type_expr != null)
+                               ConstraintChecker.Check (this, member_type, type_expr.Location);
 
                        base.Emit ();
                }
@@ -285,7 +286,7 @@ namespace Mono.CSharp
        //
        public class FieldSpec : MemberSpec, IInterfaceMemberSpec
        {
-               FieldInfo metaInfo;
+               protected FieldInfo metaInfo;
                TypeSpec memberType;
 
                public FieldSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo info, Modifiers modifiers)
@@ -333,6 +334,14 @@ namespace Mono.CSharp
                        return metaInfo;
                }
 
+               public void SetMetaInfo (FieldInfo info)
+               {
+                       if (this.metaInfo != null)
+                               throw new InternalErrorException ("MetaInfo reset");
+
+                       this.metaInfo = info;
+               }
+
                public override MemberSpec InflateMember (TypeParameterInflator inflator)
                {
                        var fs = (FieldSpec) base.InflateMember (inflator);
@@ -627,7 +636,7 @@ namespace Mono.CSharp
                        }
 
                        FieldBuilder = Parent.TypeBuilder.DefineField (
-                               Name, member_type.GetMetaInfo (), required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags));
+                               GetFullName (MemberName), member_type.GetMetaInfo (), required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags));
 
                        spec = new FieldSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags);
 
index 88771a8d4e196e74d8917da5157a27aead7b88a5..21dcbd9480dbecd7f284e39ff06a4fab5054ce40 100644 (file)
@@ -428,6 +428,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               bool ITypeDefinition.IsPlayScriptType {
+                       get {
+                               return false;
+                       }
+               }
+
                public bool IsMethodTypeParameter {
                        get {
                                return spec.IsMethodOwned;
index 12894a0cc7506b1fe7a761833534f999d80e744f..56f2bfaa3ffca936f60e0e497a53603f04a88e8a 100644 (file)
@@ -381,7 +381,7 @@ namespace Mono.CSharp
                        // For now the "default config" is harcoded into the compiler
                        // we can move this outside later
                        //
-                       var default_references = new List<string> (4);
+                       var default_references = new List<string> (8);
 
                        default_references.Add ("System.dll");
                        default_references.Add ("System.Xml.dll");
@@ -389,6 +389,8 @@ namespace Mono.CSharp
 
                        if (corlib != null && corlib.GetName ().Version.Major >= 4) {
                                default_references.Add ("Microsoft.CSharp.dll");
+
+                               default_references.Add ("PlayScript.Core");
                        }
 
                        return default_references.ToArray ();
index 3576f28a7b72c92d5a159fdb0cf163ed0e719a68..f7d452b05c04fd1bda48cd802a6f3737ef76142b 100644 (file)
@@ -6,7 +6,7 @@
 // Dual licensed under the terms of the MIT X11 or GNU GPL
 //
 // Copyright 2009-2011 Novell, Inc
-// Copyright 2011-2012 Xamarin, Inc (http://www.xamarin.com)
+// Copyright 2011-2013 Xamarin, Inc (http://www.xamarin.com)
 //
 
 using System;
@@ -123,6 +123,7 @@ namespace Mono.CSharp
                protected readonly ModuleContainer module;
 
                public static readonly string CompilerServicesNamespace = "System.Runtime.CompilerServices";
+               public static readonly string PlayScriptCompilerNamespace = "PlayScript.Runtime.CompilerServices";
 
                protected MetadataImporter (ModuleContainer module)
                {
@@ -204,6 +205,16 @@ namespace Mono.CSharp
                                                return new ConstSpec (declaringType, definition, field_type, fi, mod, dc);
                                }
 
+                               if (field_type == module.PlayscriptTypes.Namespace.TypeSpec) {
+                                       var attributes = CustomAttributeData.GetCustomAttributes (fi);
+
+                                       var data = FindAttribute (attributes, "NamespaceFieldAttribute", PlayScriptCompilerNamespace);
+                                       if (data != null) {
+                                               string value = data.ConstructorArguments[0].Value as string;
+                                               return new PlayScript.NamespaceFieldSpec (declaringType, definition, field_type, fi, mod, value);
+                                       }
+                               }
+
                                mod |= Modifiers.READONLY;
                        } else {
                                var req_mod = fi.GetRequiredCustomModifiers ();
@@ -498,10 +509,15 @@ namespace Mono.CSharp
                                } else {
                                        types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p));
 
-                                       if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
-                                               if (HasAttribute (CustomAttributeData.GetCustomAttributes (p), "ParamArrayAttribute", "System")) {
+                                       if (i >= pi.Length - 2) {
+                                               var ti = types[i];
+
+                                               if (ti is ArrayContainer && HasAttribute (CustomAttributeData.GetCustomAttributes (p), "ParamArrayAttribute", "System")) {
                                                        mod = Parameter.Modifier.PARAMS;
                                                        is_params = true;
+                                               } else if (ti == module.PlayscriptTypes.Array.TypeSpec && HasAttribute (CustomAttributeData.GetCustomAttributes (p), "RestArrayParameterAttribute", PlayScriptCompilerNamespace)) {
+                                                       mod = Parameter.Modifier.RestArray;
+                                                       is_params = true;
                                                }
                                        }
 
@@ -634,7 +650,24 @@ namespace Mono.CSharp
                        }
 
                        PropertySpec spec = null;
-                       if (!param.IsEmpty) {
+                       ImportedMemberDefinition imd = new ImportedMemberDefinition (pi, type, this);
+
+                       if (param.IsEmpty) {
+                               if (get != null && set == null && declaringType.MemberDefinition.IsPlayScriptType) {
+                                       var attributes = CustomAttributeData.GetCustomAttributes (pi);
+
+                                       var data = FindAttribute (attributes, "ConstantFieldAttribute", PlayScriptCompilerNamespace);
+                                       if (data != null) {
+                                               var pc = new PlayScript.ImportedPropertyConstant (pi, type, this);
+                                               if (data.ConstructorArguments.Count == 1) {
+                                                       pc.Initializer = Constant.CreateConstantFromValue (type,
+                                                               data.ConstructorArguments[0].Value, Location.Null);
+                                               }
+
+                                               imd = pc;
+                                       }
+                               }
+                       } else {
                                if (is_valid_property) {
                                        var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember ();
                                        if (index_name == null) {
@@ -673,7 +706,7 @@ namespace Mono.CSharp
                        }
 
                        if (spec == null)
-                               spec = new PropertySpec (MemberKind.Property, declaringType, new ImportedMemberDefinition (pi, type, this), type, pi, mod);
+                               spec = new PropertySpec (MemberKind.Property, declaringType, imd, type, pi, mod);
 
                        if (!is_valid_property) {
                                spec.IsNotCSharpCompatible = true;
@@ -899,8 +932,21 @@ namespace Mono.CSharp
                                        bts.SetDefinition (definition, type, mod);
                        }
 
-                       if (spec == null)
+                       if (spec == null) {
+                               if (kind == MemberKind.Class && declaringType == null) {
+                                       var attributes = CustomAttributeData.GetCustomAttributes (type);
+                                       // TODO: Add assembly level attribute to speed this up?
+
+                                       if (HasAttribute (attributes, "DynamicClassAttribute", PlayScriptCompilerNamespace)) {
+                                               definition.IsPlayScriptType = true;
+                                               mod |= Modifiers.DYNAMIC;
+                                       } else if (HasAttribute (attributes, "PlayScriptAttribute", PlayScriptCompilerNamespace)) {
+                                               definition.IsPlayScriptType = true;
+                                       }
+                               }
+
                                spec = new TypeSpec (kind, declaringType, definition, type, mod);
+                       }
 
                        import_cache.Add (type, spec);
 
@@ -989,17 +1035,22 @@ namespace Mono.CSharp
                // they can be assembly specific therefore we do check based on names only
                //
                public static bool HasAttribute (IList<CustomAttributeData> attributesData, string attrName, string attrNamespace)
+               {
+                       return FindAttribute (attributesData, attrName, attrNamespace) != null;
+               }
+
+               static CustomAttributeData FindAttribute (IList<CustomAttributeData> attributesData, string attrName, string attrNamespace)
                {
                        if (attributesData.Count == 0)
-                               return false;
+                               return null;
 
                        foreach (var attr in attributesData) {
                                var dt = attr.Constructor.DeclaringType;
                                if (dt.Name == attrName && dt.Namespace == attrNamespace)
-                                       return true;
+                                       return attr;
                        }
 
-                       return false;
+                       return null;
                }
 
                void ImportTypeBase (TypeSpec spec, MetaType type)
@@ -1013,6 +1064,9 @@ namespace Mono.CSharp
                                else
                                        base_type = CreateType (type.BaseType);
 
+                               if (base_type == null && spec.MemberDefinition.IsPlayScriptType)
+                                       base_type = module.PlayscriptTypes.Object;
+
                                spec.BaseType = base_type;
                        }
 
@@ -1798,6 +1852,8 @@ namespace Mono.CSharp
                        }
                }
 
+               public bool IsPlayScriptType { get; set; }
+
                public override string Name {
                        get {
                                if (name == null) {
@@ -2221,6 +2277,12 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsPlayScriptType {
+                       get {
+                               return false;
+                       }
+               }
+
                public string Namespace {
                        get {
                                return null;
index 10afaa1cc263a97ef0ff931eaaa422d01a822619..229cc7d25959fdfc659988372aeeee43f1c6fc5d 100644 (file)
@@ -18,6 +18,12 @@ using System.Linq;
 
 namespace Mono.CSharp
 {
+       public enum SourceFileType 
+       {
+               CSharp = 0,
+               PlayScript
+       }
+       
        //
        //  This is one single source file.
        //
@@ -58,6 +64,7 @@ namespace Mono.CSharp
                public readonly string FullPathName;
                public readonly int Index;
                public bool AutoGenerated;
+               readonly SourceFileType FileType;
 
                SourceFileEntry file;
                byte[] algGuid, checksum;
@@ -68,6 +75,9 @@ namespace Mono.CSharp
                        this.Index = index;
                        this.Name = name;
                        this.FullPathName = path;
+
+                       if (name.EndsWith (".play", StringComparison.Ordinal) || name.EndsWith (".asx", StringComparison.Ordinal))
+                               FileType = SourceFileType.PlayScript;
                }
 
                public byte[] Checksum {
@@ -82,6 +92,12 @@ namespace Mono.CSharp
                        }
                }
 
+               public bool IsPlayScript {
+                       get {
+                               return FileType == SourceFileType.PlayScript;
+                       }
+               }
+
                public SourceFileEntry SourceFileEntry {
                        get {
                                return file;
index 3c7ae4027b61c58327cd5681d22016b6082a005c..062ad3c8204f450890c2fb338f5ef04e2c8d9f81 100644 (file)
     </Compile>\r
     <Compile Include="parameter.cs" />\r
     <Compile Include="pending.cs" />\r
+    <Compile Include="playscript.cs" />\r
     <Compile Include="property.cs" />\r
+    <Compile Include="ps-parser.cs" />\r
+    <Compile Include="ps-tokenizer.cs" />\r
     <Compile Include="reflection.cs" />\r
     <Compile Include="report.cs" />\r
     <Compile Include="settings.cs">\r
index dec804804cb83cf64747d4e8f9807ce2ac2f1151..c88502f8d9c59e30482fdd4b0603dfc2e56d5087 100644 (file)
@@ -6,6 +6,7 @@ assembly.cs
 async.cs
 attribute.cs
 cs-tokenizer.cs
+ps-tokenizer.cs
 cfold.cs
 class.cs
 codegen.cs
@@ -40,6 +41,7 @@ namespace.cs
 nullable.cs
 parameter.cs
 pending.cs
+playscript.cs
 property.cs
 reflection.cs
 report.cs
index 5da68dc735756cd4a7967f3ccb65a5eb04701cdd..102cda299f7ad901d2c88a3908bbc2e6d7032132 100644 (file)
@@ -280,7 +280,7 @@ namespace Mono.CSharp {
                {
                        // Explicit names cannot be looked-up but can be used for
                        // collision checking (no name mangling needed)
-                       if (imb.IsExplicitImpl)
+                       if (imb.IsExplicitImpl || imb.MemberName.Left != null)
                                AddMember (exlicitName, ms, false);
                        else
                                AddMember (ms);
@@ -901,7 +901,7 @@ namespace Mono.CSharp {
                        if (mc is Constructor)
                                return mc.IsStatic ? Constructor.TypeConstructorName : Constructor.ConstructorName;
 
-                       return mc.MemberName.Name;
+                       return mc.MemberName.LookupName;
                }
 
                //
index bda1909d2d6330b9e20e1210212a05926a512bec..748ff10d2d0f635cd07653334d5b00bc5c3f55a9 100644 (file)
@@ -47,9 +47,9 @@ namespace Mono.CSharp {
                protected ToplevelBlock block;
                protected MethodSpec spec;
 
-               public MethodCore (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod,
+               public MethodCore (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, Modifiers defaultModifiers,
                        MemberName name, Attributes attrs, ParametersCompiled parameters)
-                       : base (parent, type, mod, allowed_mod, name, attrs)
+                       : base (parent, type, mod, allowed_mod, defaultModifiers, name, attrs)
                {
                        this.parameters = parameters;
                }
@@ -535,7 +535,7 @@ namespace Mono.CSharp {
 
                protected MethodOrOperator (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name,
                                Attributes attrs, ParametersCompiled parameters)
-                       : base (parent, type, mod, allowed_mod, name, attrs, parameters)
+                       : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, parameters)
                {
                }
 
@@ -1522,7 +1522,7 @@ namespace Mono.CSharp {
        public class Constructor : MethodCore, IMethodData, IMethodDefinition
        {
                public ConstructorBuilder ConstructorBuilder;
-               public ConstructorInitializer Initializer;
+               public ExpressionStatement Initializer;
                SecurityType declarative_security;
                bool has_compliant_args;
                SourceMethodBuilder debug_builder;
@@ -1545,7 +1545,12 @@ namespace Mono.CSharp {
                public static readonly string TypeConstructorName = ".cctor";
 
                public Constructor (TypeDefinition parent, string name, Modifiers mod, Attributes attrs, ParametersCompiled args, Location loc)
-                       : base (parent, null, mod, AllowedModifiers, new MemberName (name, loc), attrs, args)
+                       : this (parent, name, mod, Modifiers.PRIVATE, attrs, args, loc)
+               {
+               }
+
+               public Constructor (TypeDefinition parent, string name, Modifiers mod, Modifiers defaultModifiers, Attributes attrs, ParametersCompiled args, Location loc)
+                       : base (parent, null, mod, AllowedModifiers, defaultModifiers, new MemberName (name, loc), attrs, args)
                {
                }
 
@@ -1582,9 +1587,11 @@ namespace Mono.CSharp {
                        if ((ModFlags & Modifiers.STATIC) != 0)
                                return parameters.IsEmpty;
 
-                       return parameters.IsEmpty &&
-                                       (Initializer is ConstructorBaseInitializer) &&
-                                       (Initializer.Arguments == null);
+                       if (!parameters.IsEmpty)
+                               return false;
+                       
+                       var init = Initializer as ConstructorBaseInitializer;
+                       return init != null && init.Arguments == null;
                }
 
                public override void Accept (StructuralVisitor visitor)
index f842410c7f74461ea15a897f31f603e66f414581..2cd17770bea57feeb13b3ac671780a4721f24bb5 100644 (file)
@@ -38,7 +38,8 @@ namespace Mono.CSharp
                VOLATILE  = 0x1000,
                UNSAFE    = 0x2000,
                ASYNC     = 0x4000,
-               TOP       = 0x8000,
+               DYNAMIC   = 0x8000, // Playscript only
+               TOP       = 0x10000,
 
                //
                // Compiler specific flags
@@ -111,6 +112,8 @@ namespace Mono.CSharp
                                s = "unsafe"; break;
                        case Modifiers.ASYNC:
                                s = "async"; break;
+                       case Modifiers.DYNAMIC:
+                               s = "dynamic"; break;
                        }
 
                        return s;
index 4eeb37d59fa723b135ab002a8072ca581a640446..45b211990558696993d807f8cd8386233b65b587 100644 (file)
@@ -127,6 +127,9 @@ namespace Mono.CSharp
                PredefinedAttributes predefined_attributes;
                PredefinedTypes predefined_types;
                PredefinedMembers predefined_members;
+               PlayScript.PredefinedAttributes playscript_attributes;
+               PlayScript.PredefinedTypes playscript_types;
+               PlayScript.PredefinedMembers playscript_members;
 
                public Binary.PredefinedOperator[] OperatorsBinaryEqualityLifted;
                public Binary.PredefinedOperator[] OperatorsBinaryLifted;
@@ -269,6 +272,24 @@ namespace Mono.CSharp
                        }
                }
 
+               internal PlayScript.PredefinedAttributes PlayscriptAttributes {
+                       get {
+                               return playscript_attributes;
+                       }
+               }
+
+               internal PlayScript.PredefinedTypes PlayscriptTypes {
+                       get {
+                               return playscript_types;
+                       }
+               }
+
+               internal PlayScript.PredefinedMembers PlayScriptMembers {
+                       get {
+                               return playscript_members;
+                       }
+               }
+
                internal Dictionary<TypeSpec, ReferenceContainer> ReferenceTypesCache {
                        get {
                                return reference_types;
@@ -563,6 +584,10 @@ namespace Mono.CSharp
 
                        OperatorsBinaryEqualityLifted = Binary.CreateEqualityLiftedOperatorsTable (this);
                        OperatorsBinaryLifted = Binary.CreateStandardLiftedOperatorsTable (this);
+
+                       playscript_attributes = new PlayScript.PredefinedAttributes (this);
+                       playscript_types = new PlayScript.PredefinedTypes (this);
+                       playscript_members = new PlayScript.PredefinedMembers (this);
                }
 
                public override bool IsClsComplianceRequired ()
index d9b6a602437dd66fccebd3e1346332485d452f77..a1cf4dcb7b6839ce2817ea8cacd91ec6473bfa71 100644 (file)
@@ -427,6 +427,24 @@ namespace Mono.CSharp {
                        return texpr;
                }
 
+               // TODO: REMOVE me
+               public ATypeNameExpression MakeTypeNameExpression (Location loc)
+               {
+                       string[] names = Name.Split (new[] { '.' });
+
+                       ATypeNameExpression exp = null;
+                       for (var i = 0; i < names.Length; i++) {
+                               var name = names[i];
+                               if (exp == null) {
+                                       exp = new SimpleName (name, loc);
+                               } else {
+                                       exp = new MemberAccess (exp, name, loc);
+                               }
+                       }
+
+                       return exp;
+               }
+
                //
                // Completes types with the given `prefix'
                //
@@ -821,6 +839,9 @@ namespace Mono.CSharp {
                        get {
                                return clauses;
                        }
+                       protected set {
+                               clauses = value;
+                       }
                }
 
                public override string[] ValidAttributeTargets {
@@ -831,7 +852,7 @@ namespace Mono.CSharp {
 
                #endregion
 
-               public void AddUsing (UsingNamespace un)
+               public void AddUsing (UsingNamespace un, bool forceAppend = false) // TODO: remove the change
                {
                        if (DeclarationFound){
                                Compiler.Report.Error (1529, un.Location, "A using clause must precede all other namespace elements except extern alias declarations");
@@ -880,6 +901,10 @@ namespace Mono.CSharp {
                public override void AddTypeContainer (TypeContainer tc)
                {
                        string name = tc.Basename;
+                       if (name == null) {
+                               containers.Add (tc);
+                               return;
+                       }
 
                        var mn = tc.MemberName;
                        while (mn.Left != null) {
index 69ae1cf839f2a8da9cd5352f0b2fa11521f27a8f..f0e6eb33a807629adfc00244415720cdf65efbbe 100644 (file)
@@ -216,10 +216,12 @@ namespace Mono.CSharp {
                        CallerMemberName = 1 << 4,
                        CallerLineNumber = 1 << 5,
                        CallerFilePath = 1 << 6,
+                       RestArray = 1 << 7,
 
                        RefOutMask = REF | OUT,
-                       ModifierMask = PARAMS | REF | OUT | This,
-                       CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath
+                       ModifierMask = PARAMS | REF | OUT | This | RestArray,
+                       CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath,
+                       VariableArgumentsMask = PARAMS | RestArray
                }
 
                static readonly string[] attribute_targets = new string[] { "param" };
@@ -303,6 +305,9 @@ namespace Mono.CSharp {
                        get {
                                return texpr;
                        }
+                       protected set {
+                               texpr = value;
+                       }
                }
 
                public override string[] ValidAttributeTargets {
@@ -604,6 +609,8 @@ namespace Mono.CSharp {
                                return "ref";
                        case Modifier.This:
                                return "this";
+                       case Modifier.RestArray:
+                               return "...";
                        default:
                                return "";
                        }
@@ -1058,7 +1065,7 @@ namespace Mono.CSharp {
                        int count = parameters.Length;
 
                        for (int i = 0; i < count; i++){
-                               has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
+                               has_params |= (parameters [i].ModFlags & Parameter.Modifier.VariableArgumentsMask) != 0;
                        }
                }
 
@@ -1320,35 +1327,49 @@ namespace Mono.CSharp {
        //
        public class DefaultParameterValueExpression : CompositeExpression
        {
+               bool resolved;
+
                public DefaultParameterValueExpression (Expression expr)
                        : base (expr)
                {
                }
 
-               protected override Expression DoResolve (ResolveContext rc)
-               {
-                       return base.DoResolve (rc);
-               }
-
                public void Resolve (ResolveContext rc, Parameter p)
                {
+                       if (resolved)
+                               return;
+
+                       resolved = true;
+
                        var expr = Resolve (rc);
                        if (expr == null)
                                return;
 
                        expr = Child;
 
-                       if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New) expr).IsDefaultStruct))) {
-                               rc.Report.Error (1736, Location,
-                                       "The expression being assigned to optional parameter `{0}' must be a constant or default value",
-                                       p.Name);
+                       if (!(expr is Constant || (expr is New && ((New) expr).IsDefaultStruct))) {
+                               if (rc.IsPlayScriptType) {
+                                       expr = expr.ResolveAsPlayScriptConstant (rc);
+                                       if (expr == null) {
+                                               rc.Report.ErrorPlayScript (1047, Location,
+                                                       "Parameter initializer is not a compile-time constant.");
 
-                               return;
+                                               return;
+                                       }
+                               } else if (!(expr is DefaultValueExpression)) {
+                                       rc.Report.Error (1736, Location,
+                                               "The expression being assigned to optional parameter `{0}' must be a constant or default value",
+                                               p.Name);
+
+                                       return;
+                               }
                        }
 
                        var parameter_type = p.Type;
-                       if (type == parameter_type)
+                       if (type == parameter_type) {
+                               this.expr = expr;
                                return;
+                       }
 
                        var res = Convert.ImplicitConversionStandard (rc, expr, parameter_type, Location);
                        if (res != null) {
diff --git a/mcs/mcs/playscript.cs b/mcs/mcs/playscript.cs
new file mode 100644 (file)
index 0000000..95dfdce
--- /dev/null
@@ -0,0 +1,1971 @@
+//
+// playscript.cs: PlayScript expressions and support
+//
+// Authors: Marek Safar (marek.safar@gmail.com)
+//
+// Dual licensed under the terms of the MIT X11 or Apache License, Version 2.0
+//
+// Copyright 2013 Zynga Inc.
+// Copyright 2013 Xamarin Inc
+//
+
+using System;
+using System.Collections.Generic;
+using Mono.CSharp;
+
+#if STATIC
+using IKVM.Reflection;
+using IKVM.Reflection.Emit;
+#else
+using System.Reflection;
+using System.Reflection.Emit;
+#endif
+
+namespace Mono.PlayScript
+{
+       public abstract class PlayScriptExpression : Expression
+       {
+               public override Expression CreateExpressionTree (ResolveContext ec)
+               {
+                       throw new NotImplementedException ("Expression trees conversion not implemented in PlayScript");
+               }
+       }
+
+       public abstract class CollectionInitialization : PlayScriptExpression
+       {
+               protected Expression ctor;
+               protected TemporaryVariableReference instance;
+               protected List<Invocation> inserts;
+
+               protected CollectionInitialization (ArrayInitializer initializer)
+               {
+                       this.Initializer = initializer;
+                       loc = Initializer.Location;
+               }
+
+               public ArrayInitializer Initializer { get; private set; }
+
+               protected List<Invocation> ResolveInitializations (ResolveContext rc, Expression instance, MethodSpec pushMethod)
+               {
+                       List<Invocation> all = new List<Invocation> (Initializer.Count);
+                       foreach (var expr in Initializer.Elements) {
+
+                               var call_args = new Arguments (1);
+                               call_args.Add (new Argument (expr));
+
+                               var mg = MethodGroupExpr.CreatePredefined (pushMethod, rc.CurrentType, loc);
+                               mg.InstanceExpression = instance;
+
+                               var inv = new Invocation (mg, call_args);
+                               inv.Resolve (rc);
+
+                               all.Add (inv);
+                       }
+
+                       return all;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       if (instance != null) {
+                               instance.EmitAssign (ec, ctor);
+                               foreach (var insert in inserts)
+                                       insert.EmitStatement (ec);
+
+                               instance.EmitLoad (ec);
+                       } else {
+                               ctor.Emit (ec);
+                       }
+               }
+       }
+
+       public class ArrayCreation : CollectionInitialization
+       {
+               public ArrayCreation (ArrayInitializer initializer)
+                       : base (initializer)
+               {
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       type = rc.Module.PlayscriptTypes.Array.Resolve ();
+                       if (type == null)
+                               return null;
+
+                       var count = Initializer.Elements == null ? 0 : Initializer.Count;
+
+                       var ctor_args = new Arguments (1);
+                       ctor_args.Add (new Argument (new IntLiteral (rc.BuiltinTypes, count, loc)));
+
+                       ctor = new New (new TypeExpression (type, loc), ctor_args, loc).Resolve (rc);
+
+                       if (count != 0) {
+                               instance = TemporaryVariableReference.Create (type, rc.CurrentBlock, loc);
+
+                               var push = rc.Module.PlayScriptMembers.ArrayPush.Resolve (loc);
+                               if (push == null)
+                                       return null;
+
+                               inserts = ResolveInitializations (rc, instance, push);
+                       }
+
+                       eclass = ExprClass.Value;
+                       return this;
+               }
+
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       class BinaryOperators
+       {
+               public static Expression ResolveOperator (ResolveContext rc, Binary op, Expression left, Expression right)
+               {
+                       string method, oper;
+                       switch (op.Oper) {
+                       case Binary.Operator.Equality:
+                               oper = "Equality";
+                               method = "Comparison";
+                               break;
+                       case Binary.Operator.Inequality:
+                               oper = "Inequality";
+                               method = "Comparison";
+                               break;
+                       case Binary.Operator.GreaterThan:
+                               oper = "GreaterThan";
+                               method = "Comparison";
+                               break;
+                       case Binary.Operator.GreaterThanOrEqual:
+                               oper = "GreaterThanOrEqual";
+                               method = "Comparison";
+                               break;
+                       case Binary.Operator.LessThan:
+                               oper = "LessThan";
+                               method = "Comparison";
+                               break;
+                       case Binary.Operator.LessThanOrEqual:
+                               oper = "LessThanOrEqual";
+                               method = "Comparison";
+                               break;
+                       default:
+                               throw new NotImplementedException ();
+                       }
+
+                       var loc = op.Location;
+
+                       var ps = new MemberAccess (new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "PlayScript", loc), "Runtime", loc);
+
+                       var args = new Arguments (3);
+                       args.Add (new Argument (new MemberAccess (new MemberAccess (ps, "BinaryOperator", loc), oper, loc)));
+                       args.Add (new Argument (left));
+                       args.Add (new Argument (right));
+
+
+                       //
+                       // ActionScript does not really care about types for this for example following cases are all valid
+                       // 1.0 == 1
+                       // "3" > null
+                       // We defer to runtime to do the complex coercion
+                       //
+                       return new Invocation (new MemberAccess (new TypeExpression (rc.Module.PlayscriptTypes.Operations.Resolve (), loc), method, loc), args).Resolve (rc);
+               }
+       }
+
+       public class NewVector : CollectionInitialization
+       {
+               FullNamedExpression elementType;
+
+               public NewVector (FullNamedExpression elementType, ArrayInitializer initializer, Location loc)
+                       : base (initializer)
+               {
+                       this.elementType = elementType;
+                       this.loc = loc;
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       var element = elementType.ResolveAsType (rc);
+                       type = rc.Module.PlayscriptTypes.Vector.Resolve ();
+                       if (type == null || element == null)
+                               return null;
+
+                       type = type.MakeGenericType (rc, new [] { element });
+
+                       var count = Initializer.Elements == null ? 0 : Initializer.Count;
+
+                       var ctor_args = new Arguments (1);
+                       ctor_args.Add (new Argument (new IntLiteral (rc.BuiltinTypes, count, loc)));
+
+                       ctor = new New (new TypeExpression (type, loc), ctor_args, loc).Resolve (rc);
+
+                       if (count != 0) {
+                               instance = TemporaryVariableReference.Create (type, rc.CurrentBlock, loc);
+
+                               var push = rc.Module.PlayScriptMembers.VectorPush.Resolve (loc);
+                               if (push == null)
+                                       return null;
+
+                               push = MemberCache.GetMember (type, push);
+       
+                               inserts = ResolveInitializations (rc, instance, push);
+                       }
+
+                       eclass = ExprClass.Value;
+                       return this;
+               }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class UntypedTypeExpression : TypeExpr
+       {
+               public UntypedTypeExpression (Location loc)
+               {
+                       this.loc = loc;
+               }
+
+               public override TypeSpec ResolveAsType (IMemberContext mc)
+               {
+                       //
+                       // An untyped variable is not the same as a variable of type Object.
+                       // The key difference is that untyped variables can hold the special value
+                       // undefined, while a variable of type Object cannot hold that value.
+                       // Also any conversion is done at runtime.
+                       //
+                       return mc.Module.Compiler.BuiltinTypes.Dynamic;
+               }
+       }
+
+       public class ObjectInitializer : PlayScriptExpression
+       {
+               public ObjectInitializer (List<Expression> initializer, Location loc)
+               {
+                       Initializer = initializer;
+                       this.loc = loc;
+               }
+
+               public List<Expression> Initializer { get; private set; }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       var type = new TypeExpression (rc.Module.PlayscriptTypes.Object, loc);
+
+                       var expr = Initializer == null ?
+                               new New (type, null, loc) :
+                               new NewInitialize (type, null, new CollectionOrObjectInitializers (Initializer, loc), loc);
+                       
+                       return expr.Resolve (rc);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class SuperBaseInitializer : CSharp.ConstructorBaseInitializer
+       {
+               public SuperBaseInitializer (Arguments args, Location loc)
+                       : base (args, loc)
+               {
+               }
+
+               protected override Expression DoResolve (ResolveContext ec)
+               {
+                       // TODO: PS1201: A super statement cannot occur after a this, super, return, or throw statement.
+
+                       return base.DoResolve (ec);
+               }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class Delete : ExpressionStatement
+       {
+               public Delete (Expression expr, Location l)
+               {
+                       this.Expression = expr;
+                       loc = l;
+               }
+
+               public Expression Expression { get; private set; }
+
+               public override Expression CreateExpressionTree (ResolveContext ec)
+               {
+                       throw new NotImplementedException ("Expression trees conversion not implemented in PlayScript");
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       var expr = Expression.Resolve (rc);
+
+                       var dcma = expr as DynamicClassMemberAccess;
+                       if (dcma != null) {
+                               var ms = rc.Module.PlayScriptMembers.BinderDeleteProperty.Resolve (loc);
+                               if (ms == null)
+                                       return null;
+
+                               var mg = MethodGroupExpr.CreatePredefined (ms, ms.DeclaringType, loc);
+                               var call_args = new Arguments (2);
+                               call_args.Add (new Argument (dcma.Instance));
+                               call_args.Add (dcma.Arguments [0]);
+
+                               return new Invocation (mg, call_args).Resolve (rc);
+                       }
+
+                       //
+                       // Fixed properties cannot be deleted but it can be used with delete operator
+                       //
+                       var pe = expr as PropertyExpr;
+                       if (pe != null) {
+                               rc.Report.WarningPlayScript (3601, loc, "The declared property `{0}' cannot be deleted. To free associated memory, set its value to null",
+                                       pe.GetSignatureForError ());
+
+                               expr = new BoolConstant (rc.BuiltinTypes, false, loc);
+                               return expr.Resolve (rc);
+                       }
+
+                       Expression = expr;
+                       eclass = ExprClass.Value;
+                       type = rc.BuiltinTypes.Bool;
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       Expression.Emit (ec);
+
+                       // Always returns true
+                       ec.EmitInt (1);
+               }
+
+               public override void EmitStatement (EmitContext ec)
+               {
+                       Expression.Emit (ec);
+                       if (Expression.Type.Kind != MemberKind.Void)
+                               ec.Emit (OpCodes.Pop);
+               }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class TypeOf : PlayScriptExpression
+       {               
+               public TypeOf (Expression expr, Location l)
+               {
+                       Expression = expr;
+                       loc = l;
+               }
+
+               public Expression Expression { get; private set; }
+                               
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       var expr = Expression.Resolve (rc);
+                       if (expr == null)
+                               return null;
+
+                       var ms = rc.Module.PlayScriptMembers.OperationsTypeof.Resolve (loc);
+                       if (ms == null)
+                               return null;
+
+                       var mg = MethodGroupExpr.CreatePredefined (ms, ms.DeclaringType, loc);
+                       var call_args = new Arguments (1);
+                       call_args.Add (new Argument (expr));
+
+                       return new Invocation (mg, call_args).Resolve (rc);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class RestArrayParameter : Parameter
+       {
+               PredefinedAttribute attr;
+
+               public RestArrayParameter (string name, Attributes attrs, Location loc)
+                       : base (null, name, Modifier.RestArray, attrs, loc)
+               {
+               }
+
+               public override TypeSpec Resolve (IMemberContext rc, int index)
+               {
+                       TypeExpression = new TypeExpression (rc.Module.PlayscriptTypes.Array.Resolve (), Location);
+                       attr = rc.Module.PlayscriptAttributes.RestArrayParameter;
+                       attr.Define ();
+
+                       return base.Resolve (rc, index);
+               }
+
+               public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, CSharp.PredefinedAttributes pa)
+               {
+                       base.ApplyAttributes (mb, cb, index, pa);
+
+                       attr.EmitAttribute (builder);
+               }
+       }
+
+       public class RegexLiteral : Constant, ILiteralConstant
+       {
+               readonly public string Regex;
+               readonly public string Options;
+
+               public RegexLiteral (string regex, string options, Location loc)
+                       : base (loc)
+               {
+                       Regex = regex;
+                       Options = options ?? "";
+               }
+
+               public override bool IsLiteral {
+                       get { return true; }
+               }
+
+               public override object GetValue ()
+               {
+                       return "/" + Regex + "/" + Options;
+               }
+               
+               public override string GetValueAsLiteral ()
+               {
+                       return GetValue () as String;
+               }
+               
+               public override long GetValueAsLong ()
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
+               {
+                       throw new NotSupportedException ();
+               }
+               
+               public override bool IsDefaultValue {
+                       get {
+                               return Regex == null && Options == "";
+                       }
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+               
+               public override bool IsNull {
+                       get {
+                               return IsDefaultValue;
+                       }
+               }
+
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
+               {
+                       return null;
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+/*
+                       if (rc.Target == Target.JavaScript) {
+                               type = rc.Module.PredefinedTypes.AsRegExp.Resolve();
+                               eclass = ExprClass.Value;
+                               return this;
+                       }
+*/
+                       var args = new Arguments(2);
+                       args.Add (new Argument(new StringLiteral(rc.BuiltinTypes, Regex, this.Location)));
+                       args.Add (new Argument(new StringLiteral(rc.BuiltinTypes, Options, this.Location)));
+
+                       return new New(new TypeExpression(rc.Module.PlayscriptTypes.RegExp.Resolve(), this.Location), 
+                                      args, this.Location).Resolve (rc);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+/*
+               public override void EmitJs (JsEmitContext jec)
+               {
+                       jec.Buf.Write (GetValue () as String, Location);
+               }
+*/
+#if FULL_AST
+               public char[] ParsedValue { get; set; }
+#endif
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class XmlLiteral : Constant, ILiteralConstant
+       {
+               readonly public string Xml;
+
+               public XmlLiteral (string xml, Location loc)
+                       : base (loc)
+               {
+                       Xml = xml;
+               }
+               
+               public override bool IsLiteral {
+                       get { return true; }
+               }
+               
+               public override object GetValue ()
+               {
+                       return Xml;
+               }
+               
+               public override string GetValueAsLiteral ()
+               {
+                       return GetValue () as String;
+               }
+               
+               public override long GetValueAsLong ()
+               {
+                       throw new NotSupportedException ();
+               }
+               
+               public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
+               {
+                       throw new NotSupportedException ();
+               }
+               
+               public override bool IsDefaultValue {
+                       get {
+                               return Xml == null;
+                       }
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+               
+               public override bool IsNull {
+                       get {
+                               return IsDefaultValue;
+                       }
+               }
+
+               public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
+               {
+                       return null;
+               }
+               
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       var args = new Arguments(1);
+                       args.Add (new Argument(new StringLiteral(rc.BuiltinTypes, Xml, this.Location)));
+
+                       return new New(new TypeExpression(rc.Module.PlayscriptTypes.Xml.Resolve(), this.Location), 
+                                      args, this.Location).Resolve (rc);
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+/*             
+               public override void EmitJs (JsEmitContext jec)
+               {
+                       jec.Buf.Write (GetValue () as String, Location);
+               }
+*/             
+#if FULL_AST
+               public char[] ParsedValue { get; set; }
+#endif
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class In : PlayScriptExpression
+       {
+               public In (Expression propertyExpr, Expression expression, Location loc)
+               {
+                       this.PropertyExpression = propertyExpr;
+                       this.Expression = expression;
+                       this.loc = loc;
+               }
+
+               public Expression Expression { get; private set; }
+
+               public Expression PropertyExpression { get; private set; }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       PropertyExpression = PropertyExpression.Resolve (rc);
+                       Expression = Expression.Resolve (rc);
+                       if (PropertyExpression == null || Expression == null)
+                               return null;
+
+                       if (Expression is MethodGroupExpr) {
+                               var res = new BoolConstant (rc.BuiltinTypes, false, Location);
+                               res.Resolve (rc);
+                               return res;
+                       }
+
+                       var ms = rc.Module.PlayScriptMembers.BinderHasProperty.Resolve (loc);
+                       if (ms == null)
+                               return null;
+
+                       var args = new Arguments (3);
+                       args.Add (new Argument (Expression));
+                       args.Add (new Argument (new CSharp.TypeOf (rc.CurrentType, loc)));
+                       args.Add (new Argument (PropertyExpression));
+
+                       var mg = MethodGroupExpr.CreatePredefined (ms, ms.DeclaringType, loc);
+                       return new Invocation (mg, args).Resolve (rc);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class AsLocalFunction : Statement {
+               
+               public string Name;
+               public AnonymousMethodExpression MethodExpr;
+               public BlockVariable VarDecl;
+
+               public AsLocalFunction (Location loc, string name, AnonymousMethodExpression methodExpr, BlockVariable varDecl)
+               {
+                       this.loc = loc;
+                       this.Name = name;
+                       this.MethodExpr = methodExpr;
+                       this.VarDecl = varDecl;
+               }
+
+               public override bool Resolve (BlockContext bc)
+               {
+                       return true;
+               }
+
+               protected override void CloneTo (CloneContext clonectx, Statement t)
+               {
+                       var target = (AsLocalFunction) t;
+
+                       target.Name = Name;
+                       target.MethodExpr = MethodExpr.Clone (clonectx) as AnonymousMethodExpression;
+                       target.VarDecl = VarDecl.Clone (clonectx) as BlockVariable;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+               }
+
+//             public override void EmitJs (JsEmitContext jec)
+//             {
+//                     jec.Buf.Write ("delete ", Location);
+//                     Expr.EmitJs (jec);
+//             }
+//             
+//             public override void EmitStatementJs (JsEmitContext jec)
+//             {
+//                     jec.Buf.Write ("\t", Location);
+//                     EmitJs (jec);
+//                     jec.Buf.Write (";\n");
+//             }
+               
+               public override Expression CreateExpressionTree (ResolveContext ec)
+               {
+                       throw new System.NotSupportedException ();
+               }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class UseNamespace : Statement
+       {
+               public UseNamespace (string ns, Location loc)
+               {
+                       Namespace = ns;
+                       this.loc = loc;
+               }
+
+               public string Namespace { get; private set; }
+
+               public override bool Resolve (BlockContext bc)
+               {
+                       // TODO: Implement by adding the name to BlockContext namespaces list. Then when 
+                       // doing the namespace lookup get the list and do search with prefixes from the list
+                       // It looks like once the name is added (used) it's never removed even if the scope
+                       // is different
+                       return true;
+               }
+               
+               public override bool ResolveUnreachable (BlockContext bc, bool warn)
+               {
+                       return true;
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       // Nothing, not even sequence point
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+               }
+               
+               protected override void CloneTo (CloneContext clonectx, Statement target)
+               {
+               }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       public class AsNonAssignStatementExpression : Statement
+       {
+               public Expression expr;
+               
+               public AsNonAssignStatementExpression (Expression expr)
+               {
+                       this.expr = expr;
+               }
+               
+               public Expression Expr {
+                       get {
+                               return expr;
+                       }
+               }
+
+               public override bool Resolve (BlockContext bc)
+               {
+                       if (!base.Resolve (bc))
+                               return false;
+
+                       expr = expr.Resolve (bc);
+
+                       return expr != null;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       if (!expr.IsSideEffectFree) {
+                               expr.EmitSideEffect (ec);
+                       }
+               }
+/*
+               protected override void DoEmitJs (JsEmitContext jec) 
+               {
+                       expr.EmitJs (jec);
+               }
+               
+               public override void EmitJs (JsEmitContext jec)
+               {
+                       DoEmitJs (jec);
+               }
+*/
+               protected override void CloneTo (CloneContext clonectx, Statement target)
+               {
+                       var t = target as AsNonAssignStatementExpression;
+                       t.expr = expr.Clone (clonectx);
+               }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+       }
+
+       /// <summary>
+       ///   Implementation of the ActionScript E4X xml query.
+       /// </summary>
+       public class AsXmlQueryExpression : Expression
+       {
+               protected Expression expr;
+               protected Expression query;
+               
+               public AsXmlQueryExpression (Expression expr, Expression query, Location l)
+               {
+                       this.expr = expr;
+                       this.query = query;
+                       loc = l;
+               }
+               
+               public Expression Expr {
+                       get {
+                               return expr;
+                       }
+               }
+
+               public Expression Query {
+                       get {
+                               return query;
+                       }
+               }
+
+               public override bool ContainsEmitWithAwait ()
+               {
+                       throw new NotSupportedException ();
+               }
+               
+               public override Expression CreateExpressionTree (ResolveContext ec)
+               {
+                       throw new NotSupportedException ("ET");
+               }
+               
+               protected override Expression DoResolve (ResolveContext ec)
+               {
+                       // TODO: Implement XML query expression.
+                       return null;
+               }
+               
+               protected override void CloneTo (CloneContext clonectx, Expression t)
+               {
+                       AsXmlQueryExpression target = (AsXmlQueryExpression) t;
+                       
+                       target.expr = expr.Clone (clonectx);
+                       target.query = query.Clone (clonectx);
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       throw new InternalErrorException ("Missing Resolve call");
+               }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+               
+       }
+
+       public class SimpleName : CSharp.SimpleName
+       {
+               public SimpleName (string name, Location loc)
+                       : base (name, loc)
+               {
+               }
+
+               // TODO: targs should be always null
+               public SimpleName (string name, TypeArguments targs, Location loc)
+                       : base (name, targs, loc)
+               {
+               }
+
+               public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
+               {
+                       int lookup_arity = Arity;
+                       bool errorMode = false;
+                       Expression e;
+                       Block current_block = rc.CurrentBlock;
+                       INamedBlockVariable variable = null;
+                       bool variable_found = false;
+
+                       //
+                       // Stage 1: binding to local variables or parameters
+                       //
+                       if (current_block != null && lookup_arity == 0) {
+                               if (current_block.ParametersBlock.TopBlock.GetLocalName (Name, current_block.Original, ref variable)) {
+                                       if (!variable.IsDeclared) {
+//                                             rc.Report.Warning (7156, 1, loc, "Use of local variable before declaration");
+                                               if (variable is LocalVariable) {
+                                                       var locVar = variable as LocalVariable;
+//                                                     if (locVar.Type == null && locVar.TypeExpr != null) {
+//                                                             locVar.DeclFlags |= LocalVariable.Flags.AsIgnoreMultiple;
+//                                                             locVar.Type = locVar.TypeExpr.ResolveAsType (rc);
+//                                                     }
+                                               }
+                                               e = variable.CreateReferenceExpression (rc, loc);
+                                               if (e != null) {
+                                                       if (Arity > 0)
+                                                               Error_TypeArgumentsCannotBeUsed (rc, "variable", Name, loc);
+
+                                                       return e;
+                                               }
+                                       } else {
+                                               e = variable.CreateReferenceExpression (rc, loc);
+                                               if (e != null) {
+                                                       if (Arity > 0)
+                                                               Error_TypeArgumentsCannotBeUsed (rc, "variable", Name, loc);
+
+                                                       return e;
+                                               }
+                                       }
+                               }
+                       }
+
+                               //
+                               // Stage 2: Lookup members if we are inside a type up to top level type for nested types
+                               //
+                               TypeSpec member_type = rc.CurrentType;
+                               for (; member_type != null; member_type = member_type.DeclaringType) {
+                                       e = MemberLookup (rc, errorMode, member_type, Name, lookup_arity, restrictions, loc);
+                                       if (e == null)
+                                               continue;
+
+                                       var me = e as MemberExpr;
+                                       if (me == null) {
+                                               // The name matches a type, defer to ResolveAsTypeStep
+                                               if (e is TypeExpr)
+                                                       break;
+
+                                               continue;
+                                       }
+
+                                       me = me.ResolveMemberAccess (rc, null, null);
+
+                                       if (Arity > 0) {
+                                               targs.Resolve (rc);
+                                               me.SetTypeArguments (rc, targs);
+                                       }
+
+                                       return me;
+                               }
+
+                       // Stage 3: Global names lookup
+                       e = LookupGlobalName (rc, Name + "_fn", restrictions) ?? LookupGlobalName (rc, "<Globals>", restrictions);
+                       if (e != null)
+                               return e;
+
+                       //
+                       // Stage 3: Lookup nested types, namespaces and type parameters in the context
+                       //
+                       if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
+                               if (IsPossibleTypeOrNamespace (rc)) {
+                                       if (variable != null) {
+                                               rc.Report.SymbolRelatedToPreviousError (variable.Location, Name);
+                                               rc.Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", Name);
+                                       }
+
+                                       var fne = ResolveAsTypeOrNamespace (rc);
+                                       if (fne != null && (restrictions & MemberLookupRestrictions.PlayScriptConversion) == 0) {
+                                               return new CSharp.TypeOf (fne, loc);
+                                       }
+
+                                       return fne;
+                               }
+                       }
+
+                       // TODO: Use C# rules too?
+
+                       // TODO: Handle errors
+                       throw new NotImplementedException ();
+               }
+
+               public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
+               {
+                       var fne = ResolveKnownTypes (mc);
+                       if (fne != null)
+                               return fne;
+
+                       return base.ResolveAsTypeOrNamespace (mc);
+               }
+
+               // TODO: Add ambiguity checks
+               // PS1000: var:Number:Number = 0; is ambiguous between local variable and global type
+               TypeExpression ResolveKnownTypes (IMemberContext mc)
+               {
+                       var types = mc.Module.Compiler.BuiltinTypes;
+                       switch (Name) {
+                       case "Object":
+                               return new TypeExpression (mc.Module.PlayscriptTypes.Object, loc);
+                       case "Boolean":
+                               return new TypeExpression (types.Bool, loc);
+                       case "Number":
+                               return new TypeExpression (types.Double, loc);
+                       case "String":
+                               return new TypeExpression (types.String, loc);
+                       case "Function":
+                               return new TypeExpression (types.Delegate, loc);
+                       case "Class":
+                               return new TypeExpression (types.Type, loc);
+                       default:
+                               return null;
+                       }
+               }
+
+               Expression LookupGlobalName (ResolveContext rc, string name, MemberLookupRestrictions restrictions)
+               {
+                       bool errorMode = false;
+
+                       FullNamedExpression fne = rc.LookupNamespaceOrType (name, 0, LookupMode.Normal, loc);
+                       if (fne == null || fne is Namespace) {
+                               return null;
+                       }
+
+                       TypeSpec member_type = fne.ResolveAsType (rc);
+                       if (member_type == null) {
+                               return null;
+                       }
+
+                       Expression e = MemberLookup (rc, errorMode, member_type, Name, Arity, restrictions, loc);
+                       if (e == null)
+                               return null;
+
+                       var me = e as MemberExpr;
+                       me = me.ResolveMemberAccess (rc, null, null);
+/*
+                       if (Arity > 0) {
+                               targs.Resolve (rc);
+                               me.SetTypeArguments (rc, targs);
+                       }
+*/
+
+                       return me;
+               }
+       }
+
+       public class QualifiedMemberAccess : MemberAccess
+       {
+               public QualifiedMemberAccess (string namespaceName, string identifier, Location l)
+                       : base (null, identifier, l)
+               {
+                       this.Namespace = namespaceName;
+               }
+
+               public string Namespace { get; private set; }
+
+               public override Expression LookupNameExpression (ResolveContext rc, MemberLookupRestrictions restrictions)
+               {
+/*
+                       expr = rc.LookupNamespaceAlias (Namespace);
+                       if (expr == null) {
+                               // TODO: New error code
+                               rc.Module.Compiler.Report.ErrorPlayScript (9999, loc, "Namespace `{0}' not found", Namespace);
+                               return null;
+                       }
+*/
+                       var expr_type = rc.CurrentType;
+                       var name = Namespace + "." + Name;
+                       var member_lookup = MemberLookup (rc, false, expr_type, name, 0, restrictions, loc);
+                       if (member_lookup != null)
+                               return member_lookup;
+
+                       // TODO: Implement correct rules for out of context namespaces
+                       throw new NotImplementedException ("Namespace global lookup");
+               }
+       }
+
+       public class NamespaceMemberName : MemberName
+       {
+               public NamespaceMemberName (string namespaceName, string name, Location loc)
+                       : base (new MemberName (namespaceName, loc), name, loc)
+               {
+               }
+
+               public override string LookupName {
+                       get {
+                               return Left.LookupName + "." + base.LookupName;
+                       }
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       return Left.GetSignatureForError () + "::" + Name;
+               }
+       }
+
+       public class NamespaceField : FieldBase
+       {
+               class NamespaceInitializer : FieldInitializer
+               {
+                       readonly NamespaceField field;
+
+                       public NamespaceInitializer (NamespaceField field, Expression value, Location loc)
+                               : base (field, value, loc)
+                       {
+                               this.field = field;
+                       }
+
+                       protected override ExpressionStatement ResolveInitializer (ResolveContext rc)
+                       {
+                               if (source == null)
+                                       return null;
+
+                               source = source.Resolve (rc);
+                               if (source == null)
+                                       return null;
+
+                               source = GetStringValue (rc, source);
+                               if (source == null) {
+                                       rc.Report.ErrorPlayScript (1171, loc, "A namespace initializer must be either a literal string or another namespace.");
+                                       return null;
+                               }
+
+                               var args = new Arguments (2);
+                               args.Add (new Argument (new NullLiteral (loc)));
+                               args.Add (new Argument (source));
+                               source = new New (new TypeExpression (field.MemberType, loc), args, loc);
+
+                               return base.ResolveInitializer (rc);
+                       }
+
+                       public static StringConstant GetStringValue (IMemberContext mc, Expression source)
+                       {
+                               var sc = source as StringConstant;
+                               if (sc != null)
+                                       return sc;
+
+                               var fe = source as FieldExpr;
+                               if (fe == null)
+                                       return null;
+
+                               var nf = fe.Spec as NamespaceFieldSpec;
+                               if (nf == null)
+                                       return null;
+
+                               return new StringConstant (mc.Module.Compiler.BuiltinTypes, nf.GetValue (), Location.Null);
+                       }
+               }
+
+               const Modifiers AllowedModifiers =
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE;
+
+               public NamespaceField (TypeDefinition parent, Modifiers mod, MemberName name, Expression initializer, Attributes attrs)
+                       : base (parent, null, mod, AllowedModifiers, name, attrs)
+               {
+                       Initializer = initializer;
+               }
+
+               public override bool Define ()
+               {
+                       if (!base.Define ())
+                               return false;
+
+                       ModFlags |= Modifiers.STATIC;
+
+                       FieldAttributes field_attr = FieldAttributes.InitOnly | ModifiersExtensions.FieldAttr (ModFlags);
+                       FieldBuilder = Parent.TypeBuilder.DefineField (GetFullName (MemberName), MemberType.GetMetaInfo (), field_attr);
+
+                       spec = new NamespaceFieldSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags);
+                       Parent.MemberCache.AddMember (spec);
+
+                       if (initializer != null) {
+                               Parent.PartialContainer.RegisterFieldForInitialization (this,  new NamespaceInitializer (this, initializer, Location));
+                       }
+
+                       return true;
+               }
+
+               public override void Emit ()
+               {
+                       base.Emit ();
+
+                       Module.PlayscriptAttributes.NamespaceField.EmitAttribute (FieldBuilder, GetValue ());
+               }
+
+               public string GetValue ()
+               {
+                       if (initializer == null)
+                               return null;
+
+                       var sc = NamespaceInitializer.GetStringValue (this, initializer);
+                       if (sc == null)
+                               return null;
+
+                       return sc.Value;
+               }
+
+               protected override bool ResolveMemberType ()
+               {
+                       member_type = Module.PlayscriptTypes.Namespace.Resolve ();
+                       return true;
+               }
+       }
+
+       class NamespaceFieldSpec : FieldSpec
+       {
+               string value;
+
+               public NamespaceFieldSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo info, Modifiers modifiers)
+                       : base (declaringType, definition, memberType, info, modifiers)
+               {
+               }
+
+               public NamespaceFieldSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo info, Modifiers modifiers, string value)
+                       : this (declaringType, definition, memberType, info, modifiers)
+               {
+                       this.value = value;
+               }
+
+               public string GetValue ()
+               {
+                       var def = MemberDefinition as NamespaceField;
+                       if (def != null)
+                               return def.GetValue ();
+
+                       return value;
+               }
+       }
+
+       interface IConstantProperty
+       {
+               Expression Initializer { get; }
+       }
+
+       class ImportedPropertyConstant : ImportedMemberDefinition, IConstantProperty
+       {
+               public ImportedPropertyConstant (MemberInfo member, TypeSpec type, MetadataImporter importer)
+                       : base (member, type, importer)
+               {
+               }
+
+               public Expression Initializer { get; set; }
+       }
+
+       public class ConstantField : FieldBase
+       {
+               public class Property : CSharp.Property, IConstantProperty
+               {
+                       public Property (TypeDefinition parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs)
+                               : base (parent, type, mod, name, attrs)
+                       {
+                       }
+
+                       public Expression Initializer { get; set; }
+
+                       public override void Emit ()
+                       {
+                               var rc = new ResolveContext (this);
+                               rc.CurrentBlock = Get.Block;
+
+                               var init = Initializer.Resolve (rc);
+                               if (init != null) {
+                                       init = CSharp.Convert.ImplicitConversionRequiredEnhanced (rc, init, member_type, Initializer.Location);
+                                       if (init == null)
+                                               return;
+                               }
+                                       
+                               var c = init as Constant;
+                               if (c == null) {
+                                       var set_field = new Field (Parent, new TypeExpression (Compiler.BuiltinTypes.Bool, Location), Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
+                                               new MemberName ("<" + GetFullName (MemberName) + ">__SetField", Location), null);
+
+                                       var lazy_field = new Field (Parent, type_expr, Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
+                                               new MemberName ("<" + GetFullName (MemberName) + ">__LazyField", Location), null);
+
+                                       set_field.Define ();
+                                       lazy_field.Define ();
+
+                                       Parent.AddField (set_field);
+                                       Parent.AddField (lazy_field);
+
+                                       // 
+                                       // if (!SetField) {
+                                       //   SetField = true;
+                                       //   LazyField = Initializer;
+                                       // }
+                                       //
+                                       var set_f_expr = new FieldExpr (set_field, Location);
+                                       var lazy_f_expr = new FieldExpr (lazy_field, Location);
+                                       if (!IsStatic) {
+                                               set_f_expr.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location);
+                                               lazy_f_expr.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location);
+                                       }
+
+                                       var expl = new ExplicitBlock (Get.Block, Location, Location);
+                                       Get.Block.AddScopeStatement (new If (new Unary (Unary.Operator.LogicalNot, set_f_expr, Location), expl, Location));
+
+                                       expl.AddStatement (new StatementExpression (new CompilerAssign (lazy_f_expr, init, Location)));
+                                       Get.Block.AddStatement (new Return (lazy_f_expr, Location));
+
+                                       Module.PlayscriptAttributes.ConstantField.EmitAttribute (PropertyBuilder);
+                               } else {
+                                       //
+                                       // Simple constant, just return a value
+                                       //
+                                       Get.Block.AddStatement (new Return (init, Location));
+
+                                       //
+                                       // Store compile time constant to attribute for easier import
+                                       //
+                                       Module.PlayscriptAttributes.ConstantField.EmitAttribute (this, PropertyBuilder, c);
+                               }
+
+                               base.Emit ();
+                       }
+               }
+
+               const Modifiers AllowedModifiers =
+                       Modifiers.STATIC |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE;
+
+               public ConstantField (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
+                       : base (parent, type, mod_flags, AllowedModifiers, name, attrs)
+               {
+               }
+
+               public override bool Define ()
+               {
+                       if (Initializer == null) {
+                               Report.WarningPlayScript (1111, Location, "The constant was not initialized.");
+                       }
+
+                       if (!base.Define ())
+                               return false;
+
+                       if (Parent is PackageGlobalContainer)
+                               ModFlags |= Modifiers.STATIC;
+
+                       var t = new TypeExpression (MemberType, TypeExpression.Location);
+                       var init = Initializer ?? new DefaultValueExpression (t, Location);
+
+                       var prop = new Property (Parent, t, ModFlags, MemberName, attributes);
+                       prop.Initializer = init;
+                       prop.Get = new Property.GetMethod (prop, 0, null, prop.Location);
+                       prop.Get.Block = new ToplevelBlock (Compiler, Location);
+
+                       if (!prop.Define ())
+                               return false;
+
+                       var idx = Parent.Members.IndexOf (this);
+                       Parent.Members[idx] = prop;
+
+                       if (declarators != null) {
+                               foreach (var d in declarators) {
+                                       init = d.Initializer ?? new DefaultValueExpression (t, Location);
+
+                                       prop = new Property (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), attributes);
+                                       prop.Initializer = init;
+
+                                       prop.Get = new Property.GetMethod (prop, 0, null, prop.Location);
+                                       prop.Get.Block = new ToplevelBlock (Compiler, Location); ;
+
+                                       prop.Define ();
+                                       Parent.PartialContainer.Members.Add (prop);
+                               }
+                       }
+
+                       return true;
+               }
+       }
+
+       public class FieldDeclarator : CSharp.FieldDeclarator
+       {
+               public FieldDeclarator (SimpleMemberName name, Expression initializer, FullNamedExpression typeExpr)
+                       : base (name, initializer)
+               {
+                       this.TypeExpression = typeExpr;
+               }
+
+               public FieldDeclarator (SimpleMemberName name, Expression initializer)
+                       : base (name, initializer)
+               {
+               }
+
+               public FullNamedExpression TypeExpression { get; private set; }
+
+               public override FullNamedExpression GetFieldTypeExpression (FieldBase field)
+               {
+                       return TypeExpression;
+               }
+       }
+
+       public class BlockVariableDeclarator : CSharp.BlockVariableDeclarator
+       {
+               public BlockVariableDeclarator (LocalVariable li, Expression initializer, FullNamedExpression typeExpr)
+                       : base (li, initializer)
+               {
+                       this.TypeExpression = typeExpr;
+               }
+
+               public BlockVariableDeclarator (LocalVariable li, Expression initializer)
+                       : base (li, initializer)
+               {
+               }
+
+               public FullNamedExpression TypeExpression { get; private set; }
+       }
+
+       public class E4XIndexer : PlayScriptExpression
+       {
+               public enum Operator
+               {
+                       Attribute,      // .@
+                       Namespace       // ::
+               }
+
+               readonly Operator oper;
+               readonly Arguments args;
+               Expression expr;
+
+               public E4XIndexer (Operator oper, Expression expr, Arguments args, Location loc)
+               {
+                       this.oper = oper;
+                       this.expr = expr;
+                       this.args = args;
+                       this.loc = loc;
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       switch (oper) {
+                       case Operator.Attribute:
+                               return MakeInvocation ("attribute").Resolve (rc);
+                       case Operator.Namespace:
+                               return MakeInvocation ("namespace").Resolve (rc);
+                       }
+
+                       throw new NotImplementedException ();
+               }
+
+               Expression MakeInvocation (string method)
+               {
+                       return new Invocation (new MemberAccess (expr, method, loc), args);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+       }
+
+       public class E4XOperator : PlayScriptExpression
+       {
+               public enum Operator
+               {
+                       Descendant,             // ..
+                       ChildAll,               // .*
+                       ChildAttribute, // .@
+                       DescendantAll,  // ..*
+                       Namespace               // ::
+               }
+
+               readonly Operator oper;
+               readonly string name;
+               Expression expr;
+               
+               public E4XOperator (Operator oper, Expression expr, string name, Location loc)
+               {
+                       this.oper = oper;
+                       this.expr = expr;
+                       this.name = name;
+                       this.loc = loc;
+               }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       switch (oper) {
+                       case Operator.ChildAll:
+                               return MakeInvocation (rc, "children").Resolve (rc);
+                       case Operator.DescendantAll:
+                               return MakeInvocation (rc, "descendants").Resolve (rc);
+                       case Operator.ChildAttribute:
+                               return MakeInvocation (rc, "attribute", name).Resolve (rc);
+                       case Operator.Descendant:
+                               return MakeInvocation (rc, "descendants", name).Resolve (rc);
+                       case Operator.Namespace:
+                               return MakeInvocation (rc, "namespace", name).Resolve (rc);
+                       }
+
+                       throw new NotImplementedException ();
+               }
+
+               Expression MakeInvocation (ResolveContext rc, string method, string arg = null)
+               {
+                       Arguments args = null;
+                       if (arg != null) {
+                               args = new Arguments (1);
+                               args.Add (new Argument (new StringLiteral (rc.BuiltinTypes, arg, loc)));
+                       }
+
+                       return new Invocation (new MemberAccess (expr, method, loc), args);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+       }
+
+       public enum AsForEachType
+       {
+               /// <summary>
+               /// Generate a normal cs foreach statement.
+               /// </summary>
+//             CSharpForEach,
+               /// <summary>
+               /// Generate an PlayScript for (var a in collection) statement.  Yields keys.
+               /// </summary>
+               ForEachKey,
+               /// <summary>
+               /// Generate an PlayScript for each (var a in collection) statement.  Yields values.
+               /// </summary>
+               ForEachValue
+       }
+
+       public class Foreach : CSharp.Foreach
+       {
+               public Foreach (Expression type, LocalVariable var, Expression expr, Statement stmt, Block body, AsForEachType asType, Location l)
+                       : base (type, var, expr, stmt, body, l)
+               {
+//                     asForEachType = asType;
+               }
+
+               public Foreach (FullNamedExpression varRef, Expression expr, Statement stmt, Block body, AsForEachType asType, Location l)
+                       : base (null, null, expr, stmt, body, l)
+               {
+//                     this.varRef = varRef;
+               }
+       }
+
+       public class UsingType : UsingNamespace
+       {
+               protected TypeSpec resolvedType;
+
+               public UsingType (ATypeNameExpression expr, Location loc)
+                       : base (expr, loc)
+               {
+               }
+
+               public override void Define (NamespaceContainer ctx)
+               {
+                       resolved = NamespaceExpression.ResolveAsTypeOrNamespace (ctx);
+                       if (resolved != null) {
+                               resolvedType = resolved.ResolveAsType (ctx);
+                       }
+               }
+
+               public TypeSpec ResolvedType
+               {
+                       get { return resolvedType; }
+               }
+       }
+
+       class DynamicClassMemberAccess : PlayScriptExpression, IAssignMethod
+       {
+               Expression invocation;
+
+               public DynamicClassMemberAccess (ElementAccess ea)
+                       : this (ea.Expr, ea.Arguments, ea.Location)
+               {
+               }
+
+               public DynamicClassMemberAccess (Expression instance, Arguments args, Location loc)
+               {
+                       this.Instance = instance;
+                       this.Arguments = args;
+                       this.loc = loc;
+               }
+
+               public Arguments Arguments { get; private set; }
+
+               public Expression Instance { get; private set; }
+
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       var ms = rc.Module.PlayScriptMembers.BinderGetMember.Resolve (loc);
+                       if (ms == null)
+                               return null;
+
+                       // TODO: Figure out what value = dc["a", "b"] is supposed to do
+
+                       var mg = MethodGroupExpr.CreatePredefined (ms, ms.DeclaringType, loc);
+                       var call_args = new Arguments (3);
+                       call_args.Add (new Argument (Instance));
+                       call_args.Add (new Argument (new CSharp.TypeOf (rc.CurrentType, loc)));
+                       call_args.Add (Arguments [0]);
+
+                       invocation = new Invocation (mg, call_args).Resolve (rc);
+                       if (invocation == null)
+                               return null;
+
+                       eclass = ExprClass.Variable;
+                       type = invocation.Type;
+                       return this;
+               }
+
+               public override Expression DoResolveLValue (ResolveContext rc, Expression rhs)
+               {
+                       var ms = rc.Module.PlayScriptMembers.BinderSetMember.Resolve (loc);
+                       if (ms == null)
+                               return null;
+
+                       // TODO: Figure out what dc["a", "b"] = value is supposed to do
+
+                       var mg = MethodGroupExpr.CreatePredefined (ms, ms.DeclaringType, loc);
+                       var call_args = new Arguments (3);
+                       call_args.Add (new Argument (Instance));
+                       call_args.Add (new Argument (new CSharp.TypeOf (rc.CurrentType, loc)));
+                       call_args.Add (Arguments [0]);
+                       call_args.Add (new Argument (rhs));
+
+                       invocation = new Invocation (mg, call_args).Resolve (rc);
+
+                       eclass = ExprClass.Variable;
+                       type = rhs.Type;
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       invocation.Emit (ec);
+               }
+
+               public void Emit (EmitContext ec, bool leave_copy)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound)
+               {
+                       if (leave_copy || isCompound)
+                               throw new NotImplementedException ();
+
+                       invocation.Emit (ec);
+               }
+       }
+
+       class Package : NamespaceContainer
+       {
+               static readonly MemberName DefaultPackageName = new MemberName (PredefinedTypes.RootNamespace, Location.Null);
+               TypeDefinition globals;
+
+               private Package (MemberName name, NamespaceContainer parent)
+                       : base (name, parent)
+               {
+               }
+
+               public static Package Create (MemberName name, NamespaceContainer parent)
+               {
+                       if (name == null)
+                               return new Package (DefaultPackageName, parent);
+
+                       return new Package (name, parent) {
+                               Usings = new List<UsingNamespace> () {
+                                       new UsingNamespace (new SimpleName (PredefinedTypes.RootNamespace, name.Location), name.Location)
+                               }
+                       };
+               }
+
+               public bool IsTopLevel {
+                       get {
+                               return MemberName == DefaultPackageName;
+                       }
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       if (IsTopLevel)
+                               return "";
+
+                       return base.GetSignatureForError ();
+               }
+
+               public TypeDefinition GetGlobalsTypeDefinition ()
+               {
+                       if (globals == null) {
+                               globals = new PackageGlobalContainer (this);
+                               AddTypeContainer (globals);
+                       }
+
+                       return globals;
+               }
+       }
+
+       class PackageGlobalContainer : CompilerGeneratedContainer
+       {
+               public PackageGlobalContainer (TypeContainer parent)
+                       : base (parent, new MemberName ("<Globals>"), Modifiers.PUBLIC | Modifiers.STATIC)
+               {
+               }
+       }
+
+       class PredefinedTypes
+       {
+               public readonly BuiltinTypeSpec Object;
+
+               public readonly PredefinedType Vector;
+               public readonly PredefinedType Array;
+               public readonly PredefinedType Error;
+               public readonly PredefinedType Function;
+               public readonly PredefinedType RegExp;
+               public readonly PredefinedType Xml;
+               public readonly PredefinedType Namespace;
+
+               public readonly PredefinedType Binder;
+               public readonly PredefinedType Operations;
+
+               //
+               // The namespace used for the root package.
+               //
+               public const string RootNamespace = "_root";
+
+               public PredefinedTypes (ModuleContainer module)
+               {
+                       Object = new BuiltinTypeSpec ("Object", BuiltinTypeSpec.Type.Object);
+                       Object.SetDefinition (module.Compiler.BuiltinTypes.Object);
+                       Object.Modifiers |= Modifiers.DYNAMIC;
+                       // TODO: Add toString to MemberCache which will map to ToString
+
+                       Array = new PredefinedType (module, MemberKind.Class, RootNamespace, "Array");
+                       Vector = new PredefinedType (module, MemberKind.Class, RootNamespace, "Vector", 1);
+                       Error = new PredefinedType (module, MemberKind.Class, RootNamespace, "Error");
+                       Function = new PredefinedType (module, MemberKind.Class, RootNamespace, "Function");
+                       RegExp = new PredefinedType (module, MemberKind.Class, RootNamespace, "RegExp");
+                       Xml = new PredefinedType (module, MemberKind.Class, RootNamespace, "XML");
+                       Namespace = new PredefinedType (module, MemberKind.Class, RootNamespace, "Namespace");
+
+                       Binder = new PredefinedType (module, MemberKind.Class, "PlayScript.Runtime", "Binder");
+                       Operations = new PredefinedType (module, MemberKind.Class, "PlayScript.Runtime", "Operations");
+
+                       // Define types which also used for comparisons early
+                       Array.Define ();
+               }
+       }
+
+       class PredefinedMembers
+       {
+               public readonly PredefinedMember<MethodSpec> ArrayPush;
+               public readonly PredefinedMember<MethodSpec> VectorPush;
+               public readonly PredefinedMember<MethodSpec> BinderGetMember;
+               public readonly PredefinedMember<MethodSpec> BinderSetMember;
+               public readonly PredefinedMember<MethodSpec> BinderHasProperty;
+               public readonly PredefinedMember<MethodSpec> BinderDeleteProperty;
+               public readonly PredefinedMember<MethodSpec> OperationsTypeof;
+
+               public PredefinedMembers (ModuleContainer module)
+               {
+                       var types = module.PredefinedTypes;
+                       var btypes = module.Compiler.BuiltinTypes;
+                       var ptypes = module.PlayscriptTypes;
+
+                       var tp = new TypeParameter (0, new MemberName ("T"), null, null, Variance.None);
+
+                       ArrayPush = new PredefinedMember<MethodSpec> (module, ptypes.Array, "push", btypes.Object);
+                       VectorPush = new PredefinedMember<MethodSpec> (module, ptypes.Vector, "push", new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null));
+                       BinderGetMember = new PredefinedMember<MethodSpec> (module, ptypes.Binder, "GetMember", btypes.Object, btypes.Type, btypes.Object);
+                       BinderSetMember = new PredefinedMember<MethodSpec> (module, ptypes.Binder, "SetMember", btypes.Object, btypes.Type, btypes.Object, btypes.Object);
+                       BinderDeleteProperty = new PredefinedMember<MethodSpec> (module, ptypes.Binder, "DeleteProperty", btypes.Object, btypes.Object);
+                       BinderHasProperty = new PredefinedMember<MethodSpec> (module, ptypes.Binder, "HasProperty", btypes.Object, btypes.Type, btypes.Object);
+                       OperationsTypeof = new PredefinedMember<MethodSpec> (module, ptypes.Operations, "Typeof", btypes.Object);
+               }
+       }
+
+       class PredefinedAttributes
+       {
+               public class PredefinedConstantAttribute : PredefinedAttribute
+               {
+                       PredefinedMember<MethodSpec> ctor_definition;
+
+                       public PredefinedConstantAttribute (ModuleContainer module, string ns, string name)
+                               : base (module, ns, name)
+                       {
+                       }
+
+                       public void EmitAttribute (IMemberContext mc, PropertyBuilder builder, Constant constant)
+                       {
+                               if (ctor_definition == null) {
+                                       if (!Define ())
+                                               return;
+
+                                       ctor_definition = new PredefinedMember<MethodSpec> (module, type, CSharp.MemberFilter.Constructor (
+                                               ParametersCompiled.CreateFullyResolved (module.Compiler.BuiltinTypes.Object)));
+                               }
+
+                               var ctor = ctor_definition.Get ();
+                               if (ctor == null)
+                                       return;
+
+                               AttributeEncoder encoder = new AttributeEncoder ();
+                               encoder.Encode (constant.Type);
+                               constant.EncodeAttributeValue (mc, encoder, ctor.Parameters.Types [0]);
+                               encoder.EncodeEmptyNamedArguments ();
+
+                               builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
+                       }
+               }
+
+               public class PredefinedNamespaceAttribute : PredefinedAttribute
+               {
+                       PredefinedMember<MethodSpec> ctor_definition;
+
+                       public PredefinedNamespaceAttribute (ModuleContainer module, string ns, string name)
+                               : base (module, ns, name)
+                       {
+                       }
+
+                       public void EmitAttribute (FieldBuilder builder, string value)
+                       {
+                               if (ctor_definition == null) {
+                                       if (!Define ())
+                                               return;
+
+                                       ctor_definition = new PredefinedMember<MethodSpec> (module, type, CSharp.MemberFilter.Constructor (
+                                               ParametersCompiled.CreateFullyResolved (module.Compiler.BuiltinTypes.String)));
+                               }
+
+                               var ctor = ctor_definition.Get ();
+                               if (ctor == null)
+                                       return;
+
+                               AttributeEncoder encoder = new AttributeEncoder ();
+                               encoder.Encode (value);
+                               encoder.EncodeEmptyNamedArguments ();
+
+                               builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
+                       }
+               }
+
+               public readonly PredefinedConstantAttribute ConstantField;
+               public readonly PredefinedNamespaceAttribute NamespaceField;
+               public readonly PredefinedAttribute DynamicClass;
+               public readonly PredefinedAttribute PlayScript;
+               public readonly PredefinedAttribute RestArrayParameter;
+
+               public PredefinedAttributes (ModuleContainer module)
+               {
+                       var ns = "PlayScript.Runtime.CompilerServices";
+                       ConstantField = new PredefinedConstantAttribute (module, ns, "ConstantFieldAttribute");
+                       NamespaceField = new PredefinedNamespaceAttribute (module, ns, "NamespaceFieldAttribute");
+                       DynamicClass = new PredefinedAttribute (module, ns, "DynamicClassAttribute");
+                       PlayScript = new PredefinedAttribute (module, ns, "PlayScriptAttribute");
+                       RestArrayParameter = new PredefinedAttribute (module, ns, "RestArrayParameterAttribute");
+               }
+       }
+
+       static class Convert
+       {
+               public static Expression ImplicitConversion (Expression expr, TypeSpec target)
+               {
+                       Expression e;
+
+                       e = ImplicitNumericConversion (expr, expr.Type, target);
+                       if (e != null)
+                               return e;
+
+                       return null;
+               }
+
+               static Expression ImplicitNumericConversion (Expression expr, TypeSpec expr_type, TypeSpec target_type)
+               {
+                       switch (expr_type.BuiltinType) {
+                       case BuiltinTypeSpec.Type.Int:
+                               //
+                               // From int to uint
+                               //
+                               switch (target_type.BuiltinType) {
+                               case BuiltinTypeSpec.Type.UInt:
+                                       return new ConvCast (expr, target_type, ConvCast.Mode.I4_U4);
+                               }
+
+                               break;
+
+                       case BuiltinTypeSpec.Type.UInt:
+                               //
+                               // From uint to int
+                               //
+                               switch (target_type.BuiltinType) {
+                               case BuiltinTypeSpec.Type.Int:
+                                       return new ConvCast (expr, target_type, ConvCast.Mode.U4_I4);
+                               }
+
+                               break;
+                       }
+
+                       return null;
+               }
+       }
+
+       sealed class ErrorMessage : AbstractMessage
+       {
+               public ErrorMessage (int code, Location loc, string message, List<string> extraInfo)
+                       : base (code, loc, message, extraInfo)
+               {
+               }
+
+               public ErrorMessage (AbstractMessage aMsg)
+                       : base (aMsg)
+               {
+               }
+
+               public override bool IsWarning {
+                       get {
+                               return false;
+                       }
+               }
+
+               public override string LanguagePrefix {
+                       get {
+                               return "PS";
+                       }
+               }
+
+               public override string MessageType {
+                       get {
+                               return "error";
+                       }
+               }
+       }
+
+       sealed class WarningMessage : AbstractMessage
+       {
+               public WarningMessage (int code, Location loc, string message, List<string> extra_info)
+                       : base (code, loc, message, extra_info)
+               {
+               }
+
+               public override bool IsWarning {
+                       get {
+                               return true;
+                       }
+               }
+
+               public override string MessageType {
+                       get {
+                               return "warning";
+                       }
+               }
+
+               public override string LanguagePrefix {
+                       get {
+                               return "PS";
+                       }
+               }
+       }
+}
index 06ffb0df7a442445586fee47023cb2e5f1af939d..fb8bb495964bec7c19b803149713e81f5fb3587a 100644 (file)
@@ -36,7 +36,7 @@ namespace Mono.CSharp
        public abstract class PropertyBasedMember : InterfaceMemberBase
        {
                public PropertyBasedMember (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
-                       : base (parent, type, mod, allowed_mod, name, attrs)
+                       : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs)
                {
                }
 
@@ -406,7 +406,7 @@ namespace Mono.CSharp
                }
 
                PropertyMethod get, set, first;
-               PropertyBuilder PropertyBuilder;
+               protected PropertyBuilder PropertyBuilder;
 
                public PropertyBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, Modifiers allowed_mod, MemberName name, Attributes attrs)
                        : base (parent, type, mod_flags, allowed_mod, name, attrs)
diff --git a/mcs/mcs/ps-parser.jay b/mcs/mcs/ps-parser.jay
new file mode 100644 (file)
index 0000000..35a0025
--- /dev/null
@@ -0,0 +1,8648 @@
+%{
+//
+// ps-parser.jay: The Parser for the PlayScript language
+// Authors: Miguel de Icaza (miguel@gnome.org)
+//          Ravi Pratap     (ravi@ximian.com)
+//          Marek Safar            (marek.safar@gmail.com)
+//          Ben Cooley     (bcooley@zynga.com)
+// Dual Licensed under the terms of the GNU GPL and the MIT X11 license
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004-2011 Novell, Inc
+// Copyright 2011-2012 Xamarin Inc.
+//
+
+using System.Text;
+using System.IO;
+using System;
+using System.Collections.Generic;
+using Mono.CSharp;
+using Linq = Mono.CSharp.Linq;
+using Enum = Mono.CSharp.Enum;
+using Attribute = Mono.CSharp.Attribute;
+using Delegate = Mono.CSharp.Delegate;
+using Nullable = Mono.CSharp.Nullable;
+
+namespace Mono.PlayScript
+{
+       /// <summary>
+       ///    The PlayScript Parser
+       /// </summary>
+       public class PlayScriptParser
+       {
+               [Flags]
+               enum ParameterModifierType
+               {
+                       Ref             = 1 << 1,
+                       Out             = 1 << 2,
+                       This    = 1 << 3,
+                       Params  = 1 << 4,
+                       Arglist = 1 << 5,
+                       DefaultValue = 1 << 6,
+                       
+                       All = Ref | Out | This | Params | Arglist | DefaultValue
+               }
+               
+               public const bool parsing_playscript = true;
+               
+               static readonly object ModifierNone = 0;
+
+               LocatedToken namespace_modifier;
+       
+//             const string RootNs = PredefinedTypes.RootNamespace;
+       
+               NamespaceContainer current_namespace;
+               NamespaceContainer prev_namespace;
+               NamespaceContainer private_namespace;
+               TypeContainer current_container;
+               TypeDefinition current_type;
+               PropertyBase current_property;
+               EventProperty current_event;
+               EventField current_event_field;
+               FieldBase current_field;
+               Constructor current_constructor;
+               
+               // Set by config params to enable/disable inclusion of methods, fields, consts, classes, structs, etc.
+               bool is_config_enabled = true;
+               
+               bool is_package_function = false;
+       
+               /// <summary>
+               ///   Current block is used to add statements as we find
+               ///   them.  
+               /// </summary>
+               Block      current_block;
+               
+               BlockVariable current_variable;
+
+               Delegate   current_delegate;
+               
+               AnonymousMethodExpression current_anonymous_method;
+
+               /// <summary>
+               ///   This is used by the unary_expression code to resolve
+               ///   a name against a parameter.  
+               /// </summary>
+               
+               // FIXME: This is very ugly and it's very hard to reset it correctly
+               // on all places, especially when some parameters are autogenerated.
+               ParametersCompiled current_local_parameters;
+
+               bool parsing_anonymous_method;
+               
+               bool async_block;
+
+               ///
+               /// An out-of-band stack.
+               ///
+               Stack<object> oob_stack;
+
+               ///
+               /// Controls the verbosity of the errors produced by the parser
+               ///
+               int yacc_verbose_flag;
+
+               /// 
+               /// Used by the interactive shell, flags whether EOF was reached
+               /// and an error was produced
+               ///
+               public bool UnexpectedEOF;
+
+               ///
+               /// The current file.
+               ///
+               readonly CompilationSourceFile file;
+
+               ///
+               /// Temporary Xml documentation cache.
+               /// For enum types, we need one more temporary store.
+               ///
+               string tmpComment;
+               string enumTypeComment;
+                       
+               /// Current attribute target
+               string current_attr_target;
+               
+               ParameterModifierType valid_param_mod;
+               
+               bool default_parameter_used;
+
+               /// When using the interactive parser, this holds the
+               /// resulting expression
+               public Class InteractiveResult;
+
+               // Current modifier namespace identifier
+               public string ns_modifier;
+
+               //
+               // Keeps track of global data changes to undo on parser error
+               //
+               public Undo undo;
+               
+               Stack<Linq.QueryBlock> linq_clause_blocks;
+
+               ModuleContainer module;
+               
+               readonly CompilerContext compiler;
+               readonly LanguageVersion lang_version;
+               readonly bool doc_support;
+               readonly CompilerSettings settings;
+               readonly Report report;
+               
+               //
+               // Instead of allocating carrier array everytime we
+               // share the bucket for very common constructs which can never
+               // be recursive
+               //
+               List<Parameter> parameters_bucket;
+               
+               //
+               // Full AST support members
+               //
+               LocationsBag lbag;
+               List<Tuple<Modifiers, Location>> mod_locations;
+%}
+
+%token EOF
+%token NONE   /* This token is never returned by our lexer */
+%token ERROR           // This is used not by the parser, but by the tokenizer.
+                       // do not remove.
+
+/*
+ *These are the C# keywords
+ */
+%token FIRST_KEYWORD
+%token ABSTRACT        
+%token AS
+%token ADD
+%token SUPER   
+%token BOOL
+%token BOOLEAN 
+%token BREAK   
+%token BYTE    
+%token CASE    
+%token CATCH
+%token CHAR    
+%token CHECKED 
+%token CLASS   
+%token CONST   
+%token CONTINUE        
+%token DECIMAL 
+%token DEFAULT 
+%token DELEGATE        
+%token DELETE
+%token DO      
+%token DOUBLE
+%token DOUBLE2
+%token DOUBLE3
+%token DOUBLE4
+%token DYNAMIC
+%token EACH    
+%token ELSE    
+%token ENUM    
+%token EVENT   
+%token EXPLICIT
+%token EXTENDS 
+%token FALSE
+%token FINAL   
+%token FINALLY 
+%token FIXED   
+%token FLOAT
+%token FLOAT2
+%token FLOAT3
+%token FLOAT4
+%token FOR     
+%token FOR_EACH        
+%token FUNCTION 
+%token FUNCTION_GET
+%token FUNCTION_SET
+%token GOTO    
+%token IF      
+%token IMPLICIT        
+%token IMPLEMENTS
+%token IMPORT
+%token IN
+%token INDEXER 
+%token INSTANCEOF
+%token INT     
+%token INTERFACE
+%token INTERNAL        
+%token IS      
+%token LOCK    
+%token LONG    
+%token NAMESPACE
+%token NATIVE  
+%token NEW     
+%token NULL    
+%token OBJECT  
+%token OPERATOR        
+%token OUT     
+%token OVERRIDE
+%token OVERLOAD
+%token PACKAGE
+%token PARAMS  
+%token PRIVATE
+%token PROPERTY        
+%token PROTECTED
+%token PUBLIC  
+%token READONLY        
+%token REF     
+%token RETURN  
+%token REMOVE
+%token SBYTE   
+%token SHORT   
+%token SIZEOF  
+%token STACKALLOC
+%token STATIC  
+%token STRING  
+%token STRUCT  
+%token SWITCH  
+%token THIS    
+%token THROW   
+%token TRUE    
+%token TRY     
+%token TYPEOF  
+%token UINT    
+%token ULONG   
+%token UNCHECKED
+%token UNSAFE
+%token USE     
+%token USHORT  
+%token USING   
+%token VAR
+%token VIRTUAL 
+%token VOID    
+%token VOLATILE
+%token WHERE
+%token WHILE   
+%token PARTIAL
+%token ARROW
+%token FROM
+%token FROM_FIRST
+%token JOIN
+%token ON
+%token EQUALS
+%token SELECT
+%token GROUP
+%token BY
+%token LET
+%token ORDERBY
+%token ASCENDING
+%token DESCENDING
+%token INTO
+%token INTERR_NULLABLE
+%token EXTERN
+%token ASYNC
+%token AWAIT
+
+/* C# keywords which are not really keywords */
+%token GET
+%token SET
+
+%left LAST_KEYWORD
+
+/* C# single character operators/punctuation. */
+%token OPEN_BRACE
+%token CLOSE_BRACE
+%token OPEN_BRACKET
+%token CLOSE_BRACKET
+%token OPEN_PARENS
+%token CLOSE_PARENS
+
+%token DOT
+%token DOT_AT
+%token DOT_STAR
+%token DOTDOT
+%token DOTDOT_AT
+%token DOTDOT_STAR
+%token DOTDOTDOT
+%token DOT_OPEN_PARENS
+%token CLOSE_PARENS_DOT
+%token COMMA
+%token COLON
+%token SEMICOLON
+%token TILDE
+
+%token PLUS
+%token MINUS
+%token BANG
+%token ASSIGN
+%token OP_LT
+%token OP_GT
+%token BITWISE_AND
+%token BITWISE_OR
+%token LOGICAL_AND_ASSIGN
+%token LOGICAL_OR_ASSIGN
+%token STAR
+%token PERCENT
+%token DIV
+%token CARRET
+%token INTERR
+
+/* C# multi-character operators. */
+%token DOUBLE_COLON
+%token OP_INC
+%token OP_DEC
+%token OP_SHIFT_LEFT
+%token OP_SHIFT_RIGHT
+%token OP_USHIFT_RIGHT
+%token OP_LE
+%token OP_GE
+%token OP_EQ
+%token OP_REF_EQ
+%token OP_NE
+%token OP_REF_NE
+%token OP_AND
+%token OP_OR
+%token OP_MULT_ASSIGN
+%token OP_DIV_ASSIGN
+%token OP_MOD_ASSIGN
+%token OP_ADD_ASSIGN
+%token OP_SUB_ASSIGN
+%token OP_SHIFT_LEFT_ASSIGN
+%token OP_SHIFT_RIGHT_ASSIGN
+%token OP_USHIFT_RIGHT_ASSIGN
+%token OP_AND_ASSIGN
+%token OP_XOR_ASSIGN
+%token OP_OR_ASSIGN
+%token OP_PTR
+%token OP_COALESCING
+%token OP_IN
+%token OP_AT
+
+/* Generics <,> tokens */
+%token OP_GENERICS_LT
+%token OP_GENERICS_LT_DECL
+%token OP_GENERICS_GT
+
+%token LITERAL
+
+%token IDENTIFIER
+%token IDENTIFIER_CONFIG
+%token OPEN_PARENS_LAMBDA
+%token OPEN_PARENS_CAST
+%token GENERIC_DIMENSION
+%token DEFAULT_COLON
+%token OPEN_BRACKET_EXPR
+%token OPEN_BRACE_INIT
+
+// Make the parser go into eval mode parsing (statements and compilation units).
+%token EVAL_STATEMENT_PARSER
+%token EVAL_COMPILATION_UNIT_PARSER
+%token EVAL_USING_DECLARATIONS_UNIT_PARSER
+
+%token DOC_SEE
+
+// 
+// This token is generated to trigger the completion engine at this point
+//
+%token GENERATE_COMPLETION
+
+//
+// This token is return repeatedly after the first GENERATE_COMPLETION
+// token is produced and before the final EOF
+//
+%token COMPLETE_COMPLETION
+
+/* Add precedence rules to solve dangling else s/r conflict */
+%nonassoc IF
+%nonassoc ELSE
+
+/* Define the operator tokens and their precedences */
+%right ASSIGN
+%right OP_COALESCING
+%right INTERR
+%left OP_OR
+%left OP_AND
+%left BITWISE_OR
+%left BITWISE_AND
+%left OP_SHIFT_LEFT OP_SHIFT_RIGHT
+%left PLUS MINUS
+%left STAR DIV PERCENT
+%right BANG CARRET UMINUS
+%nonassoc OP_INC OP_DEC
+%left OPEN_PARENS
+%left NEW
+%left OPEN_BRACKET OPEN_BRACE
+%left DOT
+
+%start compilation_unit
+%%
+
+compilation_unit
+       : outer_declaration opt_EOF
+         {
+               Lexer.check_incorrect_doc_comment ();
+         }
+       | interactive_parsing  { Lexer.CompleteOnEOF = false; } opt_EOF
+       | documentation_parsing
+       ;
+       
+outer_declaration
+       : opt_extern_alias_directives opt_package_directives
+       | opt_extern_alias_directives opt_package_directives package_declaration opt_attributes
+         {
+               if ($4 != null) {
+                       Attributes attrs = (Attributes) $4;
+                       report.Error (1730, attrs.Attrs [0].Location,
+                               "Assembly and module attributes must precede all other elements except using clauses and extern alias declarations");
+
+                       current_namespace.UnattachedAttributes = attrs;
+               }
+         }
+       | opt_extern_alias_directives opt_package_directives attribute_sections
+         {
+               module.AddAttributes ((Attributes) $3, current_namespace);
+         }
+       | error
+         {
+               if (yyToken == Token.EXTERN)
+                       report.Error (439, lexer.Location, "An extern alias declaration must precede all other elements");
+               else
+                       Error_SyntaxError (yyToken);
+         }
+       ;
+       
+opt_EOF
+       : /* empty */
+       | EOF
+       ;
+
+extern_alias_directives
+       : extern_alias_directive
+       | extern_alias_directives extern_alias_directive
+       ;
+
+extern_alias_directive
+       : EXTERN IDENTIFIER IDENTIFIER SEMICOLON
+         {
+               var lt = (LocatedToken) $2;
+               string s = lt.Value;
+               if (s != "alias") {
+                       syntax_error (lt.Location, "`alias' expected");
+               } else {
+                       if (lang_version == LanguageVersion.ISO_1)
+                               FeatureIsNotAvailable (lt.Location, "external alias");
+
+                       lt = (LocatedToken) $3;
+                       if (lt.Value == QualifiedAliasMember.GlobalAlias) {
+                               RootNamespace.Error_GlobalNamespaceRedefined (report, lt.Location);
+                       }
+                       
+                       var na = new UsingExternAlias (new SimpleMemberName (lt.Value, lt.Location), GetLocation ($1));
+                       current_namespace.AddUsing (na);
+                       
+                       lbag.AddLocation (na, GetLocation ($2), GetLocation ($4));
+               }
+         }
+       | EXTERN error
+         {
+               Error_SyntaxError (yyToken);
+         }
+       ;
+no_config_package_directive
+       : import_directive
+       | use_namespace_directive
+       ; 
+package_directive
+       : no_config_package_directive
+       | config_package_directive
+       ;
+
+config_package_directive
+       : IDENTIFIER_CONFIG 
+         {
+               var lt = (LocatedToken) $1;
+           is_config_enabled = file.IsConditionalDefined (lt.Value.Replace("::","_"));   
+         } 
+         no_config_package_directive
+         {
+               is_config_enabled = true;
+               $$ = $3;
+         }
+       | IDENTIFIER_CONFIG 
+         {
+               var lt = (LocatedToken) $1;
+           is_config_enabled = file.IsConditionalDefined (lt.Value.Replace("::","_"));   
+         } 
+         OPEN_BRACE opt_package_directives CLOSE_BRACE
+         {
+               is_config_enabled = true;
+               $$ = $4;
+         }
+       ; 
+   
+package_directives
+    : package_directive
+    | package_directives package_directive
+    ;
+
+use_namespace_directive
+       : use_namespace
+         {
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+       ;
+
+use_namespace
+       : USE NAMESPACE IDENTIFIER SEMICOLON
+       ;
+import_directive
+       : import_package
+         {
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+       ;
+
+import_package
+       : IMPORT namespace_or_type_expr
+         {
+           Lexer.AllowAutoSemiAfterToken(Token.DOT_STAR, true);
+         }
+         DOT_STAR SEMICOLON 
+         {
+           if (is_config_enabled) {
+                       var un = new UsingNamespace ((ATypeNameExpression) $2, GetLocation ($1));
+                       current_namespace.AddUsing (un);
+               
+                       lbag.AddLocation (un, GetLocation ($5));
+                       
+                   Lexer.AllowAutoSemiAfterToken(Token.DOT_STAR, false);
+               }
+         }     
+       | IMPORT typeof_type_expression SEMICOLON 
+         {
+           if (is_config_enabled) {
+                       var ut = new UsingType ((ATypeNameExpression) $2, GetLocation ($1));
+                       current_namespace.AddUsing (ut);
+               
+                       lbag.AddLocation (ut, GetLocation ($3));
+               }
+         }
+       | IMPORT IDENTIFIER ASSIGN namespace_or_type_expr SEMICOLON
+         {
+           if (is_config_enabled) {
+                       var lt = (LocatedToken) $2;
+                       if (lang_version != LanguageVersion.ISO_1 && lt.Value == "global") {
+                               report.Warning (440, 2, lt.Location,
+                                "An alias named `global' will not be used when resolving `global::'. The global namespace will be used instead");
+                       }
+
+                       var un = new UsingAliasNamespace (new SimpleMemberName (lt.Value, lt.Location), (ATypeNameExpression) $4, GetLocation ($1));
+                       current_namespace.AddUsing (un);
+               
+                       lbag.AddLocation (un, GetLocation ($3), GetLocation ($5));
+               }
+         }
+       | IMPORT error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = null;
+         }
+       ;
+
+//
+// Strictly speaking, namespaces don't have attributes but
+// we parse global attributes along with namespace declarations and then
+// detach them
+// 
+package_declaration
+       : opt_attributes PACKAGE 
+         {
+               Lexer.AutoSemiInsertion = false;
+         }
+         opt_package_name
+         {
+               Attributes attrs = (Attributes) $1;
+               var name = $4 as MemberName;
+//             if (name == null) {
+//                     name = new MemberName(RootNs);
+//             }
+/*             
+               if (attrs != null) {
+                       bool valid_global_attrs = true;
+                       if ((current_namespace.DeclarationFound || current_namespace != file)) {
+                               valid_global_attrs = false;
+                       } else {
+                               foreach (var a in attrs.Attrs) {
+                                       if (a.ExplicitTarget == "assembly" || a.ExplicitTarget == "module")
+                                               continue;
+                                               
+                                       valid_global_attrs = false;
+                                       break;
+                               }
+                       }
+                       
+                       if (!valid_global_attrs)
+                               report.Error (1671, name.Location, "A namespace declaration cannot have modifiers or attributes");
+               }
+       
+               module.AddAttributes (attrs, current_namespace);
+*/             
+           // Close the private package namespace (if it's active)
+               if (current_namespace == private_namespace) {
+                       if (private_namespace.Containers.Count > 0) {
+                               prev_namespace.AddTypeContainer(private_namespace);
+                               var priv_un = new UsingNamespace (
+                                       private_namespace.NS.MakeTypeNameExpression(GetLocation($1)), GetLocation ($1));
+                               prev_namespace.AddUsing(priv_un, true);
+                       }
+                       current_container = current_namespace = prev_namespace.Parent;
+                       prev_namespace = private_namespace = null; 
+               }
+               
+               var ns = Package.Create (name, current_namespace);
+               current_namespace.AddTypeContainer (ns);
+               current_container = current_namespace = ns;
+//             var un = new UsingNamespace (new SimpleName (RootNs, GetLocation ($1)), GetLocation ($1));
+//             current_namespace.AddUsing(un, true);
+         }
+         OPEN_BRACE
+         {
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+                       
+               Lexer.AutoSemiInsertion = true;
+         }
+         opt_package_statements_or_blocks CLOSE_BRACE
+         {
+               lbag.AddLocation (current_container, GetLocation ($2), GetLocation ($6), GetLocation ($8));
+/*       
+               if (current_namespace.Parent != null && current_namespace.Parent.Parent == null) { // Is this the top level package?
+                       var ns = new NamespaceContainer (new MemberName("__" + file.FileName.Replace(".","_")), current_namespace);
+                       prev_namespace = current_namespace;
+                       current_container = private_namespace = current_namespace = ns;
+           } else
+*/
+               {
+                       current_container = current_namespace = current_namespace.Parent;
+               }
+               
+               lexer.parsing_modifiers = false;
+         }
+         opt_package_statements_or_blocks
+         {
+           // Close the private package namespace (if it's active)
+               if (current_namespace == private_namespace) {
+/*
+                       if (private_namespace.Containers.Count > 0) {
+                               prev_namespace.AddTypeContainer(private_namespace);
+                               var priv_un = new UsingNamespace (
+                                       private_namespace.NS.MakeTypeNameExpression(GetLocation($1)), GetLocation ($1));
+                               prev_namespace.AddUsing(priv_un, true);
+                       }
+*/
+                       current_container = current_namespace = prev_namespace.Parent;
+                       prev_namespace = private_namespace = null; 
+               }
+         
+//             lbag.AddLocation (current_container, GetLocation ($2), GetLocation ($6), GetLocation ($11));
+         }
+       ;
+
+opt_package_name
+       : /* empty */
+       | package_name
+       ;
+
+package_name
+       : IDENTIFIER
+         {
+               var lt = (LocatedToken) $1;
+               $$ = new MemberName (lt.Value, lt.Location);
+         }
+       | package_name DOT IDENTIFIER
+         {
+               var lt = (LocatedToken) $3;
+               $$ = new MemberName ((MemberName) $1, lt.Value, lt.Location);           
+         }
+       | error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new MemberName ("<invalid>", lexer.Location);
+         }
+       ;
+
+opt_semicolon
+       : /* empty */
+       | SEMICOLON
+       ;
+
+opt_comma
+       : /* empty */
+       | COMMA
+       ;
+
+opt_package_statements_or_blocks
+       : opt_extern_alias_directives opt_package_statements
+       | OPEN_BRACE opt_package_statements_or_blocks CLOSE_BRACE
+       ;
+       
+opt_package_directives
+       : /* empty */
+       | package_directives
+       ;
+
+opt_extern_alias_directives
+       : /* empty */
+       | extern_alias_directives
+       ;
+
+opt_package_statements
+       : /* empty */
+       | package_statements
+       ;
+
+package_statements
+       : package_statement
+       | package_statements package_statement
+       ;
+
+package_statement
+       : no_config_package_statement
+       | config_package_statement
+       | attribute_sections CLOSE_BRACE {
+               current_namespace.UnattachedAttributes = (Attributes) $1;
+               report.Error (1518, lexer.Location, "Attributes must be attached to class, delegate, enum, interface or struct");
+               lexer.putback ('}');
+               is_config_enabled = true;               
+         }
+       ;
+
+no_config_package_statement
+       : type_declaration
+         {
+           if (is_config_enabled) {
+                       if ($1 != null) {
+                               TypeContainer ds = (TypeContainer)$1;
+
+                               if ((ds.ModFlags & (Modifiers.PRIVATE | Modifiers.PROTECTED)) != 0){
+                                       report.Error (1527, ds.Location, 
+                                       "Namespace elements cannot be explicitly declared as private, protected or protected internal");
+                               }
+
+                               // Here is a trick, for explicit attributes we don't know where they belong to until
+                               // we parse succeeding declaration hence we parse them as normal and re-attach them
+                               // when we know whether they are global (assembly:, module:) or local (type:).
+                               if (ds.OptAttributes != null) {
+                                       ds.OptAttributes.ConvertGlobalAttributes (ds, current_namespace, !current_namespace.DeclarationFound && current_namespace == file);
+                               }
+                       }
+                       current_namespace.DeclarationFound = true;
+               }
+         }
+       | method_declaration
+         {
+               if (is_config_enabled) {
+                       current_namespace.DeclarationFound = true;
+               }
+         }
+       | constant_declaration
+       | no_config_package_directive     
+       ;
+
+config_package_statement
+       : IDENTIFIER_CONFIG 
+         {
+               var lt = (LocatedToken) $1;
+           is_config_enabled = file.IsConditionalDefined (lt.Value.Replace("::","_"));           
+         }
+         no_config_package_statement
+         {
+           is_config_enabled = true;
+           $$ = $3;
+         }
+       | IDENTIFIER_CONFIG 
+         {
+               var lt = (LocatedToken) $1;
+           is_config_enabled = file.IsConditionalDefined (lt.Value.Replace("::","_"));   
+         } 
+         OPEN_BRACE opt_package_statements CLOSE_BRACE
+         {
+               is_config_enabled = true;
+               $$ = $4;
+         }       
+       ;
+
+type_declaration
+       : class_declaration     
+       | struct_declaration
+       | interface_declaration
+       | enum_declaration              
+       | delegate_declaration
+       ;
+               
+//
+// Enable this when we have handled all errors, because this acts as a generic fallback
+//
+//     | error {
+//             Console.WriteLine ("Token=" + yyToken);
+//             report.Error (1518, GetLocation ($1), "Expected class, struct, interface, enum or delegate");
+//       }
+       ;
+
+//
+// Attributes
+//
+
+opt_attributes
+       : /* empty */ 
+       | attribute_sections
+    ;
+attribute_sections
+       : attribute_section
+         {
+               var sect = $1 as List<Attribute>;
+               if (sect != null) {
+                       $$ = new Attributes (sect);
+               }
+         }
+       | attribute_sections attribute_section
+         {
+               Attributes attrs = $1 as Attributes;
+               var sect = $2 as List<Attribute>;
+               if (sect != null) {
+                       if (attrs == null)
+                               attrs = new Attributes (sect);
+                       else
+                               attrs.AddAttributes (sect);
+               }
+               $$ = attrs;
+         }
+       ;
+       
+attribute_section
+       : OPEN_BRACKET
+         {
+               lexer.parsing_attribute_section = true;
+         }
+         attribute_section_cont
+         {
+               lexer.parsing_attribute_section = false;
+               $$ = $3;
+         }
+       ;
+       
+attribute_section_cont
+       : attribute_target COLON
+         {
+               current_attr_target = (string) $1;
+               if (current_attr_target == "assembly" || current_attr_target == "module") {
+                       Lexer.check_incorrect_doc_comment ();
+               }
+         }
+         attribute_list opt_comma CLOSE_BRACKET
+         {
+               // when attribute target is invalid
+               if (current_attr_target == string.Empty)
+                       $$ = new List<Attribute> (0);
+               else
+                       $$ = $4;
+         
+               current_attr_target = null;
+               lexer.parsing_attribute_section = false;
+               lexer.AutoSemiInsertionAfter = 1;
+         }
+       | attribute_list opt_comma CLOSE_BRACKET
+         {
+               lexer.AutoSemiInsertionAfter = 1;
+               $$ = $1;
+         }
+       ;       
+
+attribute_target
+       : IDENTIFIER
+         {
+               var lt = (LocatedToken) $1;
+               $$ = CheckAttributeTarget (lt.Value, lt.Location);
+         }
+       | EVENT  { $$ = "event"; }
+       | RETURN { $$ = "return"; }
+       | error
+         {
+               if (yyToken == Token.IDENTIFIER) {
+                       Error_SyntaxError (yyToken);
+                       $$ = null;
+               } else {
+                       string name = GetTokenName (yyToken);
+                       $$ = CheckAttributeTarget (name, GetLocation ($1));
+               }
+         }
+       ;
+
+attribute_list
+       : attribute
+         {
+               $$ = new List<Attribute> (4) { (Attribute) $1 };
+         }
+       | attribute_list COMMA attribute
+         {
+               var attrs = (List<Attribute>) $1;
+               attrs.Add ((Attribute) $3);
+
+               $$ = attrs;
+         }
+       ;
+
+attribute
+       : attribute_name
+         {
+               ++lexer.parsing_block;
+         }
+         opt_attribute_arguments
+         {
+               --lexer.parsing_block;
+               
+               var tne = (ATypeNameExpression) $1;
+               if (tne.HasTypeArguments) {
+                       report.Error (404, tne.Location, "Attributes cannot be generic");
+               }
+
+               $$ = new Attribute (current_attr_target, tne, (Arguments[]) $3, GetLocation ($1), lexer.IsEscapedIdentifier (tne));
+         }
+       ;
+
+attribute_name
+       : namespace_or_type_expr
+       ;
+
+opt_attribute_arguments
+       : /* empty */   { $$ = null; }
+       | OPEN_PARENS attribute_arguments CLOSE_PARENS
+         {
+           lexer.AutoSemiInsertionAfter = 1;
+               $$ = $2;
+         }
+       ;
+
+
+attribute_arguments
+       : /* empty */           { $$ = null; } 
+       | positional_or_named_argument
+         {
+               Arguments a = new Arguments (4);
+               a.Add ((Argument) $1);
+               $$ = new Arguments [] { a, null };
+         }
+       | named_attribute_argument
+         {
+               Arguments a = new Arguments (4);
+               a.Add ((Argument) $1);  
+               $$ = new Arguments [] { null, a };
+         }
+    | attribute_arguments COMMA positional_or_named_argument
+         {
+               Arguments[] o = (Arguments[]) $1;
+               if (o [1] != null) {
+                       report.Error (1016, ((Argument) $3).Expr.Location, "Named attribute arguments must appear after the positional arguments");
+                       o [0] = new Arguments (4);
+               }
+               
+               Arguments args = ((Arguments) o [0]);
+               if (args.Count > 0 && !($3 is NamedArgument) && args [args.Count - 1] is NamedArgument)
+                       Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
+               
+               args.Add ((Argument) $3);
+         }
+    | attribute_arguments COMMA named_attribute_argument
+         {
+               Arguments[] o = (Arguments[]) $1;
+               if (o [1] == null) {
+                       o [1] = new Arguments (4);
+               }
+
+               ((Arguments) o [1]).Add ((Argument) $3);
+         }
+    ;
+
+positional_or_named_argument
+       : expression
+         {
+               $$ = new Argument ((Expression) $1);
+         }
+       | named_argument
+       ;
+
+named_attribute_argument
+       : IDENTIFIER ASSIGN
+         {
+               ++lexer.parsing_block;
+         }
+         expression
+         {
+               --lexer.parsing_block;
+               var lt = (LocatedToken) $1;
+               $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4);          
+               lbag.AddLocation ($$, GetLocation($2));
+         }
+       ;
+       
+named_argument
+       : identifier_inside_body COLON opt_named_modifier expression
+         {
+               if (lang_version <= LanguageVersion.V_3)
+                       FeatureIsNotAvailable (GetLocation ($1), "named argument");
+                       
+               // Avoid boxing in common case (no modifier)
+               var arg_mod = $3 == null ? Argument.AType.None : (Argument.AType) $3;
+                       
+               var lt = (LocatedToken) $1;
+               $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4, arg_mod);
+               lbag.AddLocation ($$, GetLocation($2));
+         }
+       ;
+       
+opt_named_modifier
+       : /* empty */   { $$ = null; }
+       | REF
+         { 
+               CheckIsPlayScript("ref parameters", GetLocation($1));
+               $$ = Argument.AType.Ref;
+         }
+       | OUT
+         { 
+               CheckIsPlayScript("out parameters", GetLocation($1));
+               $$ = Argument.AType.Out;
+         }
+       ;
+                 
+opt_class_member_declarations
+       : /* empty */
+       | class_member_declarations
+       ;
+
+class_member_declarations
+       : class_member_declaration
+         {
+               lexer.parsing_modifiers = true;
+         }
+       | class_member_declarations class_member_declaration
+         {
+               lexer.parsing_modifiers = true;
+         }
+       ;
+       
+class_member_declaration
+       : constant_declaration
+       | field_declaration
+       | method_declaration
+       | property_declaration
+       | namespace_declaration
+       | event_declaration
+       | indexer_declaration
+       | operator_declaration
+//     | constructor_declaration
+       | destructor_declaration
+       | type_declaration
+       | member_config_block
+       | config_member_declaration     
+       | attributes_without_members
+       | use_namespace_class_directive
+       | import_class_directive
+       | error
+         {
+               report.Error (1519, lexer.Location, "Unexpected symbol `{0}' in class, struct, or interface member declaration",
+                       GetSymbolName (yyToken));
+               $$ = null;
+               lexer.parsing_generic_declaration = false;
+         }
+       ;
+       
+use_namespace_class_directive
+       : opt_attributes
+         opt_modifiers
+         use_namespace_directive
+         {
+               if ($1 != null || (Modifiers) $2 != 0) {
+                       report.Error (7058, GetLocation($1 ?? $2), "Modifiers and attributes not allowed");
+               }
+         }
+       ;
+
+import_class_directive
+       : opt_attributes
+         opt_modifiers
+         import_directive
+         {
+               if ($1 != null || (Modifiers) $2 != 0) {
+                       report.Error (7058, GetLocation($1 ?? $2), "Modifiers and attributes not allowed");
+               }
+         }
+       ;
+
+config_member_declaration
+       : IDENTIFIER_CONFIG
+         {
+               var lt = (LocatedToken) $1;
+           is_config_enabled = file.IsConditionalDefined (lt.Value.Replace("::","_"));   
+         }
+         class_member_declaration
+         {
+           is_config_enabled = true;
+           $$ = $3;
+         }
+       ;
+         
+
+member_config_block
+       : IDENTIFIER_CONFIG 
+         {
+               var lt = (LocatedToken) $1;
+           is_config_enabled = file.IsConditionalDefined (lt.Value.Replace("::","_"));   
+         } 
+         OPEN_BRACE opt_class_member_declarations CLOSE_BRACE
+         {
+               is_config_enabled = true;
+               $$ = $4;
+         }
+       ;         
+
+struct_declaration
+       : opt_attributes
+         opt_modifiers
+         opt_partial
+         STRUCT
+         {
+               lexer.ConstraintsParsing = true;
+               lexer.AutoSemiInsertion = false;
+         }
+         type_declaration_name
+         {
+               bool is_partial = IsPartial($1) || $3 != null;
+               push_current_container (new Struct (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), is_partial);
+         }
+         opt_class_extends
+         opt_class_implements
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+
+               if ($10 != null)
+                       current_container.SetConstraints ((List<Constraints>) $10);
+
+               if (doc_support)
+                       current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
+
+               lbag.AddMember (current_container, mod_locations, GetLocation ($4));
+               
+               lexer.parsing_modifiers = true;
+               lexer.AutoSemiInsertion = true;
+         }
+         OPEN_BRACE
+         {
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               lexer.DynamicParsing = false;
+         }
+         opt_class_member_declarations CLOSE_BRACE
+         {
+               lexer.DynamicParsing = true;
+               --lexer.parsing_declaration;
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         opt_semicolon
+         {
+               lbag.AppendToMember (current_container, GetLocation ($12), GetLocation ($15), GetLocation ($17));
+               $$ = pop_current_class ();
+         }
+       | opt_attributes opt_modifiers opt_partial STRUCT error
+         {
+               Error_SyntaxError (yyToken);
+         }
+       ;
+
+namespace_declaration
+       : opt_attributes 
+         opt_modifiers
+         NAMESPACE IDENTIFIER opt_namespace_initializer SEMICOLON
+         {
+               var lt = (LocatedToken) $4;
+               var td = GetTypeDefinition (current_container);
+
+               var ns = new NamespaceField (td, (Modifiers) $2, CreateFullMemberName (lt), (Expression) $5, (Attributes) $1);
+               td.AddMember (ns);
+         }
+       ;
+
+opt_namespace_initializer
+       : /* empty */
+       | ASSIGN constant_initializer_expr 
+         {
+               $$ = $2;
+         }
+       ;
+       
+constant_declaration
+       : opt_attributes 
+         opt_modifiers
+         CONST IDENTIFIER COLON type
+         {
+               var lt = (LocatedToken) $4;
+               var td = GetTypeDefinition (current_container);
+               current_field = new ConstantField (td, (FullNamedExpression) $6, (Modifiers) $2, CreateFullMemberName (lt), (Attributes) $1);
+               if (is_config_enabled) {
+                       td.AddMember (current_field);
+               }
+               is_config_enabled = true;
+                               
+               $$ = current_field;
+         }
+         opt_field_initializer opt_field_declarators SEMICOLON
+         {
+               if (doc_support) {
+                       current_field.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+               
+               lbag.AddMember (current_field, mod_locations, GetLocation ($3), GetLocation ($10));
+               current_field = null;
+         }
+       ;
+
+constant_initializer_expr
+    : constant_expression
+    ;
+
+field_declaration
+       : opt_attributes
+         opt_modifiers
+         VAR IDENTIFIER COLON member_type
+         {
+               lexer.parsing_generic_declaration = false;
+
+               FullNamedExpression type = (FullNamedExpression) $6;
+               if (type.Type != null && type.Type.Kind == MemberKind.Void)
+                       report.Error (670, GetLocation ($6), "Fields cannot have void type");
+                       
+               var lt = (LocatedToken) $4;
+               current_field = new Field (current_type, type, (Modifiers) $2, CreateFullMemberName (lt), (Attributes) $1);
+               if (is_config_enabled) {
+                       current_type.AddField (current_field);
+               }
+               is_config_enabled = true;
+               $$ = current_field;
+         }
+         opt_field_initializer
+         opt_field_declarators
+         SEMICOLON
+         { 
+               if (doc_support) {
+                       current_field.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+                       
+               lbag.AddMember (current_field, mod_locations, GetLocation ($10));
+               $$ = current_field;
+               current_field = null;
+         }
+/*
+       | opt_attributes
+         opt_modifiers
+         FIXED IDENTIFIER COLON simple_type 
+         { 
+               if (lang_version < LanguageVersion.ISO_2)
+                       FeatureIsNotAvailable (GetLocation ($6), "fixed size buffers");
+
+               var lt = (LocatedToken) $4;
+               current_field = new FixedField (current_type, (FullNamedExpression) $6, (Modifiers) $2,
+                       new MemberName (lt.Value, lt.Location), (Attributes) $1);
+                       
+               if (is_config_enabled) {
+                       current_type.AddField (current_field);
+               }
+               is_config_enabled = true;
+         }
+         fixed_field_size opt_fixed_field_declarators SEMICOLON
+         {
+               if (doc_support) {
+                       current_field.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+           }
+
+               current_field.Initializer = (ConstInitializer) $8;          
+               lbag.AddMember (current_field, mod_locations, GetLocation ($10));
+               $$ = current_field;
+           current_field = null;
+         }
+       | opt_attributes
+         opt_modifiers
+         FIXED IDENTIFIER COLON simple_type error
+         SEMICOLON
+         {
+               report.Error (1641, GetLocation ($8), "A fixed size buffer field must have the array size specifier after the field name");
+         }
+*/
+       ;
+       
+opt_field_initializer
+       : /* empty */
+       | ASSIGN
+         {
+               ++lexer.parsing_block;
+               current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
+               start_block (GetLocation ($1));
+         }
+         variable_initializer
+         {
+               --lexer.parsing_block;
+               current_field.Initializer = (Expression) $3;
+               end_block (lexer.Location);
+               current_local_parameters = null;
+         }
+       ;
+       
+opt_field_declarators
+       : /* empty */
+       | field_declarators
+       ;
+       
+field_declarators
+       : field_declarator
+         {
+               current_field.AddDeclarator ((FieldDeclarator) $1);
+         }
+       | field_declarators field_declarator
+         {
+               current_field.AddDeclarator ((FieldDeclarator) $2);
+         }
+       ;
+       
+field_declarator
+       : COMMA IDENTIFIER COLON member_type
+         {
+               var lt = (LocatedToken) $2;
+               $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null, (FullNamedExpression) $4);
+               lbag.AddLocation ($$, GetLocation ($1));
+         }
+       | COMMA IDENTIFIER COLON member_type ASSIGN
+         {
+               ++lexer.parsing_block;
+         }
+         variable_initializer
+         {
+               --lexer.parsing_block;
+               var lt = (LocatedToken) $2;       
+               $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $7, (FullNamedExpression) $4);
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($5));
+         }
+       ;       
+
+variable_initializer
+       : expression
+       | error
+         {
+               // It has to be here for the parent to safely restore artificial block
+               Error_SyntaxError (yyToken);
+               $$ = null;
+         }
+       ;
+
+method_declaration
+       : method_header
+         {
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+
+               // Add it early in the case of body being eof for full ast
+               Method m = $1 as Method;
+               if (m != null) {
+                       async_block = (m.ModFlags & Modifiers.ASYNC) != 0;
+                       if (is_config_enabled) {
+                               current_type.AddMember (m);
+                       }
+                       is_config_enabled = true;
+               }
+               
+               Constructor c = $1 as Constructor;
+               if (c != null) {
+                       if (is_config_enabled) {
+                               current_type.AddConstructor (c);
+                       }
+                       is_config_enabled = true;
+                       current_constructor = c;
+               }
+               
+               if (is_package_function)
+                       lexer.DynamicParsing = false;
+                       
+         }
+         method_body
+         {
+               if (is_package_function)
+                       lexer.DynamicParsing = true;
+         
+               async_block = false;
+
+               if ($1 is Method) {
+               
+                       Method method = $1 as Method;
+                       
+                       if ($3 == null) {
+                               method.ParameterInfo.CheckParameters (method);
+       
+                               if ((method.ModFlags & Modifiers.ASYNC) != 0) {
+                                       report.Error (1994, method.Location, "`{0}': The async modifier can only be used with methods that have a body",
+                                               method.GetSignatureForError ());
+                               }
+                       } else {
+                               method.Block = (ToplevelBlock) $3;
+                               
+                               if (current_container.Kind == MemberKind.Interface) {
+                                       report.Error (531, method.Location, "`{0}': interface members cannot have a definition",
+                                               method.GetSignatureForError ());
+                               }
+                       }
+                       
+               } else if ($1 is Constructor) {
+               
+                       Constructor c = $1 as Constructor;
+                       
+                       if ($3 != null) {               
+                               c.Block = (ToplevelBlock) $3;
+                       }
+                       
+                       if (doc_support)
+                               c.DocComment = ConsumeStoredComment ();
+               
+               } else {
+               
+                       Property.PropertyMethod propMethod = $1 as Property.PropertyMethod;
+                       
+                       if ($3 != null) {
+                               propMethod.Block = (ToplevelBlock) $3;                  
+                       
+                               if (current_container.Kind == MemberKind.Interface) {
+                                       report.Error (531, propMethod.Block.StartLocation,
+                                               "`{0}': interface members cannot have a definition", propMethod.GetSignatureForError ());
+                               }
+                       }
+                       
+               }
+
+               current_local_parameters = null;
+               current_property = null;
+               current_constructor = null;
+               
+               // If this was a package function, pop the container xxxxx_fn class.
+               if (is_package_function) {
+                       pop_current_class();
+                       is_package_function = false;
+               }
+       
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+       ;
+
+method_header
+       : opt_attributes
+         opt_modifiers
+         FUNCTION
+         method_declaration_name OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.All;
+               
+               // If package level function, create a new package function class with 
+               // the name of the function plus "_fn".
+               if (current_container is NamespaceContainer) {
+                       MemberName methodName = (MemberName) $4;
+                       MemberName className = new MemberName(methodName.Name + "_fn", GetLocation($4));
+                       var fnClassModifiers = (Modifiers) $2 | Modifiers.PARTIAL | Modifiers.STATIC; // Allows overloads..
+                       push_current_container(new Class (current_container, className, fnClassModifiers, (Attributes) $1), GetLocation($3));
+                       is_package_function = true;
+               }
+               
+         }
+         opt_formal_parameter_list CLOSE_PARENS opt_method_return_type
+         {
+               lexer.ConstraintsParsing = true;
+         }
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+               valid_param_mod = 0;
+               MemberName name = (MemberName) $4;
+               current_local_parameters = (ParametersCompiled) $7;
+
+               var modifiers = (Modifiers) $2;
+               if (is_package_function) {
+                       modifiers |= Modifiers.STATIC;
+               }
+               
+               if (current_type != null && name.Name == current_type.MemberName.Name) {
+
+                       var c = new Constructor (current_type, name.Name, modifiers, Modifiers.PUBLIC, (Attributes) $1, current_local_parameters, name.Location);
+
+                       if ($11 != null) {
+                                       report.Error (7011, c.Location,
+                                               "`{0}': constructor can not have type constraints.",
+                                               c.GetSignatureForError ());
+                       }
+
+                       if ((modifiers & Modifiers.STATIC) != 0) {
+                               if ((modifiers & Modifiers.AccessibilityMask) != 0){
+                                       report.Error (515, c.Location,
+                                               "`{0}': static constructor cannot have an access modifier",
+                                               c.GetSignatureForError ());
+                               }
+                       }
+
+                       if (doc_support)
+                               c.DocComment = Lexer.consume_doc_comment ();
+                               
+                       lbag.AddMember (c, mod_locations, GetLocation ($5), GetLocation ($8));
+                       $$ = c;
+               
+               } else {
+
+//                     if (current_container.Kind == MemberKind.Class && name.ExplicitInterface == null &&
+//                             (modifiers & (Modifiers.NEW | Modifiers.SEALED | Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0)
+//                                     modifiers |= Modifiers.VIRTUAL;
+
+                       var ret_type = $9 as FullNamedExpression;
+                       
+                       if (ret_type == null) {
+                               report.Error (7012, GetLocation($8), "Method must specify a return type.");
+                               ret_type = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($8));
+                       }
+
+                       var method = Method.Create (current_type, ret_type, modifiers,
+                                            name, current_local_parameters, (Attributes) $1);
+
+                       if ($11 != null)
+                               method.SetConstraints ((List<Constraints>) $11);
+                                            
+                       if (doc_support)
+                               method.DocComment = Lexer.consume_doc_comment ();
+
+                       lbag.AddMember (method, mod_locations, GetLocation ($5), GetLocation ($8));
+                       $$ = method;
+                       
+               }
+         }
+       | opt_attributes
+         opt_modifiers
+         FUNCTION_GET method_declaration_name OPEN_PARENS  
+         {
+               valid_param_mod = ParameterModifierType.All;
+         }
+         opt_formal_parameter_list CLOSE_PARENS method_colon member_type
+         {
+               var type = (FullNamedExpression) $10;
+               var name = (MemberName) $4;
+               var modifiers = (Modifiers) $2;
+               var parameters = (ParametersCompiled) $7;               
+               
+               if (current_container.Kind == MemberKind.Class && name.ExplicitInterface == null &&
+                       (modifiers & (Modifiers.NEW | Modifiers.SEALED | Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0)
+                               modifiers |= Modifiers.VIRTUAL;
+
+               if (parameters != null && parameters.Count > 0)
+                       report.Error (7016, GetLocation ($10), "Property getter functions may not have parameters");
+
+               current_property = null;                
+                                               
+               MemberCore member;
+               if (current_type.DefinedNames.TryGetValue(name.Name, out member)) {
+                       current_property = member as Property;
+               }
+               
+               if (current_property == null) {
+                       current_property = new Property (current_type, type, modifiers, name, (Attributes) $1);
+                       if (is_config_enabled) {
+                               current_type.AddMember (current_property);
+                       }
+                       is_config_enabled = true;
+                       modifiers = (Modifiers) 0;
+               } else {
+//                     if (!type.Equals(current_property.TypeExpression)) {
+//                             report.Error (7002, GetLocation ($10), "Type of property getter and setter must match", current_property.GetSignatureForError ());
+//                     }
+                       if (current_property.Set != null && ModifiersExtensions.IsRestrictedModifier (current_property.ModFlags & Modifiers.AccessibilityMask, modifiers & Modifiers.AccessibilityMask)) {
+                               current_property.Set.ModFlags |= current_property.ModFlags & Modifiers.AccessibilityMask;
+                               current_property.ModFlags = (current_property.ModFlags & ~Modifiers.AccessibilityMask) | (modifiers & Modifiers.AccessibilityMask);
+                               modifiers = (Modifiers) 0;
+                       } else if ((modifiers & Modifiers.AccessibilityMask) == (current_property.ModFlags & Modifiers.AccessibilityMask)) {
+                               modifiers = (Modifiers) 0;
+                       }
+               }
+               
+               if (type.Type != null && type.Type.Kind == MemberKind.Void)
+                       report.Error (547, GetLocation ($10), "`{0}': property or indexer cannot have void type", current_property.GetSignatureForError ());                                    
+                       
+               if (current_property.Get != null) {
+                       report.Error (1007, GetLocation ($3), "Property accessor already defined");
+               }
+               
+               current_property.Get = new Property.GetMethod (current_property,
+                       modifiers & Modifiers.AccessibilityMask, (Attributes) $1, GetLocation ($3));
+         
+               lbag.AddMember (current_property, mod_locations, GetLocation ($10));
+               current_local_parameters = current_property.Get.ParameterInfo;
+               $$ = current_property.Get;
+         }
+    | opt_attributes
+         opt_modifiers
+         FUNCTION_SET method_declaration_name OPEN_PARENS  
+         {
+               valid_param_mod = ParameterModifierType.All;
+         }
+         opt_formal_parameter_list CLOSE_PARENS method_colon member_type
+         {
+               var void_type = (FullNamedExpression) $10;
+               var name = (MemberName) $4;
+               var modifiers = (Modifiers) $2;
+               var parameters = (ParametersCompiled) $7;
+               
+               if (current_container.Kind == MemberKind.Class && name.ExplicitInterface == null &&
+                       (modifiers & (Modifiers.NEW | Modifiers.SEALED | Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0)
+                               modifiers |= Modifiers.VIRTUAL;
+               
+               if (void_type.Type != null && void_type.Type.Kind != MemberKind.Void)
+                       report.Error (7003, GetLocation ($10), "Property setter function must not be of type void");                                    
+
+               current_property = null;
+                                               
+               MemberCore member;
+               if (current_type.DefinedNames.TryGetValue(name.Name, out member)) {
+                       current_property = member as Property;
+               }
+
+               FullNamedExpression type; 
+               
+               if (parameters == null || parameters.Count != 1 || parameters.FixedParameters.Length != parameters.Count) {
+                       report.Error (7001, GetLocation ($7), "Property setter must have a single parameter");
+                       type = new TypeExpression (compiler.BuiltinTypes.Int, GetLocation ($7));
+               } else {
+                       type = ((Parameter)parameters.FixedParameters[0]).TypeExpression;       
+               }
+                               
+               if (current_property == null) {
+                       current_property = new Property (current_type, type, modifiers, name, (Attributes) $1);
+                       if (is_config_enabled) {
+                               current_type.AddMember (current_property);
+                       }
+                       is_config_enabled = true;
+                       modifiers = (Modifiers) 0;                      
+               } else {
+//                     if (!type.Equals(current_property.TypeExpression)) {
+//                             report.Error (7002, GetLocation ($10), "Type of property getter and setter must match", current_property.GetSignatureForError ());
+//                     }
+                       if (current_property.Get != null && ModifiersExtensions.IsRestrictedModifier (current_property.ModFlags & Modifiers.AccessibilityMask, modifiers & Modifiers.AccessibilityMask)) {
+                               current_property.Get.ModFlags |= current_property.ModFlags & Modifiers.AccessibilityMask;
+                               current_property.ModFlags = (current_property.ModFlags & ~Modifiers.AccessibilityMask) | (modifiers & Modifiers.AccessibilityMask);
+                               modifiers = (Modifiers) 0;
+                       } else if ((modifiers & Modifiers.AccessibilityMask) == (current_property.ModFlags & Modifiers.AccessibilityMask)) {
+                               modifiers = (Modifiers) 0;
+                       }
+               }
+               
+               if (current_property.Set != null) {
+                       report.Error (1007, GetLocation ($3), "Property accessor already defined");
+               }
+               
+               current_property.Set = new Property.SetMethod (current_property, 
+                       modifiers & Modifiers.AccessibilityMask, (ParametersCompiled) $7, (Attributes) $1, GetLocation ($3));
+         
+               lbag.AddMember (current_property, mod_locations, GetLocation ($10));
+               current_local_parameters = parameters;
+               $$ = current_property.Set;
+         }
+       | opt_attributes
+         opt_modifiers
+         PARTIAL
+         FUNCTION
+         {
+               lexer.parsing_generic_declaration = true;
+         }
+         method_declaration_name
+         OPEN_PARENS
+         {
+               lexer.parsing_generic_declaration = false;
+               valid_param_mod = ParameterModifierType.All;
+         }
+         opt_formal_parameter_list CLOSE_PARENS COLON VOID
+         {
+               lexer.ConstraintsParsing = true;
+         }
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+               valid_param_mod = 0;
+
+               MemberName name = (MemberName) $6;
+               current_local_parameters = (ParametersCompiled) $9;
+
+               var modifiers = (Modifiers) $2;
+               modifiers |= Modifiers.PARTIAL;
+
+               if (name.ExplicitInterface == null && (modifiers & (Modifiers.NEW | Modifiers.SEALED | Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0)
+                       modifiers |= Modifiers.VIRTUAL;
+                       
+               var method = Method.Create (current_type, new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($12)),
+                                    modifiers, name, current_local_parameters, (Attributes) $1);
+
+               if ($14 != null)
+                       method.SetConstraints ((List<Constraints>) $14);
+
+               if (doc_support)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
+               StoreModifierLocation (Modifiers.PARTIAL, GetLocation ($3));
+               lbag.AddMember (method, mod_locations, GetLocation ($7), GetLocation ($10));
+               $$ = method;
+         }
+       | opt_attributes
+         opt_modifiers
+         FUNCTION
+         modifiers method_declaration_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS method_colon member_type
+         {
+               MemberName name = (MemberName) $5;
+               report.Error (1585, name.Location, 
+                       "Member modifier `{0}' must precede the member type and name", ModifiersExtensions.Name ((Modifiers) $4));
+
+               var method = Method.Create (current_type, (FullNamedExpression) $1,
+                                           0, name, (ParametersCompiled) $7, (Attributes) $1);
+
+               current_local_parameters = (ParametersCompiled) $7;
+
+               if (doc_support)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
+               $$ = method;
+         }
+       | opt_attributes
+         opt_modifiers
+         FUNCTION
+         method_declaration_name error
+         {
+               Error_SyntaxError (yyToken);
+               current_local_parameters = ParametersCompiled.Undefined;
+
+               MemberName name = (MemberName) $4;
+               var method = Method.Create (current_type, new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($4)), (Modifiers) $2,
+                                                                       name, current_local_parameters, (Attributes) $1);
+
+               if (doc_support)
+                       method.DocComment = Lexer.consume_doc_comment ();
+
+               $$ = method;
+         }
+       ;
+
+opt_method_return_type
+       : /* empty */
+       | method_colon member_type
+         {
+               $$ = $2;
+         }
+       ;
+
+method_colon
+       : COLON
+         {
+               if (current_container.Kind == MemberKind.Interface) 
+                       Lexer.AutoSemiInsertion = true;   
+         }
+       ;       
+
+method_body
+       : block
+       | SEMICOLON             
+         { 
+               // method body.
+               $$ = null; 
+         }
+       ;
+
+opt_formal_parameter_list
+       : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
+       | formal_parameter_list
+       ;
+       
+formal_parameter_list
+       : fixed_parameters
+         {
+               var pars_list = (List<Parameter>) $1;
+               $$ = new ParametersCompiled (pars_list.ToArray ());
+         } 
+       | fixed_parameters COMMA parameter_array
+         {
+               var pars_list = (List<Parameter>) $1;
+               pars_list.Add ((Parameter) $3);
+
+               $$ = new ParametersCompiled (pars_list.ToArray ()); 
+         }
+       | parameter_array COMMA error
+         {
+               if ($1 != null)
+                       report.Error (231, ((Parameter) $1).Location, "A params parameter must be the last parameter in a formal parameter list");
+
+               $$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } );                      
+         }
+       | fixed_parameters COMMA parameter_array COMMA error
+         {
+               if ($3 != null)
+                       report.Error (231, ((Parameter) $3).Location, "A params parameter must be the last parameter in a formal parameter list");
+
+               var pars_list = (List<Parameter>) $1;
+               pars_list.Add (new ArglistParameter (GetLocation ($3)));
+
+               $$ = new ParametersCompiled (pars_list.ToArray (), true);
+         }
+       | parameter_array 
+         {
+               $$ = new ParametersCompiled (new Parameter[] { (Parameter) $1 } );
+         }
+       | error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = ParametersCompiled.EmptyReadOnlyParameters;
+         }
+       ;
+
+fixed_parameters
+       : fixed_parameter       
+         {
+               parameters_bucket.Clear ();
+               Parameter p = (Parameter) $1;
+               parameters_bucket.Add (p);
+               
+               default_parameter_used = p.HasDefaultValue;
+               $$ = parameters_bucket;
+         }
+       | fixed_parameters COMMA fixed_parameter
+         {
+               var pars = (List<Parameter>) $1;
+               Parameter p = (Parameter) $3;
+               if (p != null) {
+                       if (p.HasExtensionMethodModifier)
+                               report.Error (1100, p.Location, "The parameter modifier `this' can only be used on the first parameter");
+                       else if (!p.HasDefaultValue && default_parameter_used)
+                               report.Error (1737, p.Location, "Optional parameter cannot precede required parameters");
+
+                       default_parameter_used |= p.HasDefaultValue;
+                       pars.Add (p);
+                       
+                       lbag.AddLocation (p, GetLocation ($2));
+               }
+               
+               $$ = $1;
+         }
+       ;
+
+fixed_parameter
+       : opt_attributes
+         opt_parameter_modifier
+         IDENTIFIER
+         COLON
+         parameter_type
+         {
+               var lt = (LocatedToken) $3;
+               $$ = new Parameter ((FullNamedExpression) $5, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
+         }
+       | attribute_sections error
+         {
+               Error_SyntaxError (yyToken);
+               Location l = GetLocation ($2);
+               $$ = new Parameter (null, null, Parameter.Modifier.NONE, (Attributes) $1, l);
+         }
+       | opt_attributes
+         opt_parameter_modifier
+         IDENTIFIER
+         COLON
+         error
+         {
+               Error_SyntaxError (yyToken);
+               Location l = GetLocation ($5);
+               var lt = (LocatedToken) $3;
+               $$ = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, GetLocation ($5)), lt.Value, (Parameter.Modifier) $2, (Attributes) $1, l);
+         }
+       | opt_attributes
+         opt_parameter_modifier
+         IDENTIFIER
+         COLON
+         parameter_type
+         ASSIGN
+         {
+               ++lexer.parsing_block;
+         }
+         constant_expression
+         {
+               --lexer.parsing_block;
+               if (lang_version <= LanguageVersion.V_3) {
+                       FeatureIsNotAvailable (GetLocation ($6), "optional parameter");
+               }
+               
+               Parameter.Modifier mod = (Parameter.Modifier) $2;
+               if (mod != Parameter.Modifier.NONE) {
+                       switch (mod) {
+                       case Parameter.Modifier.REF:
+                       case Parameter.Modifier.OUT:
+                               report.Error (1741, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter",
+                                       Parameter.GetModifierSignature (mod));
+                               break;
+                               
+                       case Parameter.Modifier.This:
+                               report.Error (1743, GetLocation ($2), "Cannot specify a default value for the `{0}' parameter",
+                                       Parameter.GetModifierSignature (mod));
+                               break;
+                       default:
+                               throw new NotImplementedException (mod.ToString ());
+                       }
+                               
+                       mod = Parameter.Modifier.NONE;
+               }
+               
+               if ((valid_param_mod & ParameterModifierType.DefaultValue) == 0)
+                       report.Error (1065, GetLocation ($6), "Optional parameter is not valid in this context");
+               
+               var lt = (LocatedToken) $3;
+               $$ = new Parameter ((FullNamedExpression) $5, lt.Value, mod, (Attributes) $1, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($6));
+               
+               if ($8 != null)
+                       ((Parameter) $$).DefaultValue = new DefaultParameterValueExpression ((Expression) $8);
+         }
+       ;
+
+opt_parameter_modifier
+       : /* empty */           { $$ = Parameter.Modifier.NONE; }
+       | parameter_modifiers
+       ;
+
+parameter_modifiers
+       : parameter_modifier
+         {
+               $$ = $1;
+         }
+       | parameter_modifiers parameter_modifier
+         {
+               Parameter.Modifier p2 = (Parameter.Modifier)$2;
+               Parameter.Modifier mod = (Parameter.Modifier)$1 | p2;
+               if (((Parameter.Modifier)$1 & p2) == p2) {
+                       Error_DuplicateParameterModifier (lexer.Location, p2);
+               } else {
+                       switch (mod & ~Parameter.Modifier.This) {
+                               case Parameter.Modifier.REF:
+                                       report.Error (1101, lexer.Location, "The parameter modifiers `this' and `ref' cannot be used altogether");
+                                       break;
+                               case Parameter.Modifier.OUT:
+                                       report.Error (1102, lexer.Location, "The parameter modifiers `this' and `out' cannot be used altogether");
+                                       break;
+                               default:
+                                       report.Error (1108, lexer.Location, "A parameter cannot have specified more than one modifier");
+                                       break;
+                       }
+               }
+               $$ = mod;
+         }
+       ;
+
+parameter_modifier
+       : REF
+         {
+               if ((valid_param_mod & ParameterModifierType.Ref) == 0)
+                       Error_ParameterModifierNotValid ("ref", GetLocation ($1));
+                       
+               $$ = Parameter.Modifier.REF;
+         }
+       | OUT
+         {
+               if ((valid_param_mod & ParameterModifierType.Out) == 0)
+                       Error_ParameterModifierNotValid ("out", GetLocation ($1));
+         
+               $$ = Parameter.Modifier.OUT;
+         }
+       | THIS
+         {
+               if ((valid_param_mod & ParameterModifierType.This) == 0)
+                       Error_ParameterModifierNotValid ("this", GetLocation ($1));
+
+               if (lang_version <= LanguageVersion.ISO_2)
+                       FeatureIsNotAvailable (GetLocation ($1), "extension methods");
+                               
+               $$ = Parameter.Modifier.This;
+         }
+       ;
+
+parameter_array
+       : opt_attributes DOTDOTDOT IDENTIFIER opt_rest_parameter_type
+         {
+               var lt = (LocatedToken) $3;
+               $$ = new RestArrayParameter (lt.Value, (Attributes) $1, lt.Location);
+         }
+       | opt_attributes DOTDOTDOT error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = null;
+         }
+       ;
+
+opt_rest_parameter_type
+       : /* empty */
+       | COLON IDENTIFIER
+         {
+               var lt = (LocatedToken) $2;
+
+               // TODO: Do I need to resolve the type for correct checking
+               if (lt.Value != "Array")
+                       report.ErrorPlayScript (1140, GetLocation ($2), "Parameters specified after the ...rest parameter definition keyword can only be an Array data type");        
+               }
+       ;
+       
+//arglist_modifier
+//     : ARGLIST
+//       {
+//             if ((valid_param_mod & ParameterModifierType.Arglist) == 0)
+//                     report.Error (1669, GetLocation ($1), "__arglist is not valid in this context");
+//       }
+//     ;
+
+property_declaration
+       : opt_attributes
+         opt_modifiers
+         PROPERTY member_declaration_name COLON member_type
+         {
+               if (doc_support)
+                       tmpComment = Lexer.consume_doc_comment ();
+         }
+         OPEN_BRACE
+         {
+               var type = (FullNamedExpression) $6;
+       
+               var modifiers = (Modifiers) $2;
+       
+               var name = (MemberName) $4;
+               
+               if (current_container.Kind == MemberKind.Class && name.ExplicitInterface == null && 
+                       (modifiers & (Modifiers.NEW | Modifiers.SEALED | Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0)
+                               modifiers |= Modifiers.VIRTUAL;
+               
+               current_property = new Property (current_type, type, modifiers,
+                       name, (Attributes) $1);
+                       
+               if (type.Type != null && type.Type.Kind == MemberKind.Void)
+                       report.Error (547, GetLocation ($3), "`{0}': property or indexer cannot have void type", current_property.GetSignatureForError ());                                     
+                       
+               if (is_config_enabled) {
+                       current_type.AddMember (current_property);
+               }
+               is_config_enabled = true;
+               lbag.AddMember (current_property, mod_locations, GetLocation ($8));
+               
+               lexer.PropertyParsing = true;
+         }
+         accessor_declarations 
+         {
+               lexer.PropertyParsing = false;
+               
+               if (doc_support)
+                       current_property.DocComment = ConsumeStoredComment ();                          
+         }
+         CLOSE_BRACE
+         {
+               CheckIsPlayScript("property", GetLocation($3));         
+                 
+               lbag.AppendToMember (current_property, GetLocation ($12));
+               current_property = null;
+         }
+       ;
+
+indexer_declaration
+       : opt_attributes opt_modifiers
+         INDEXER indexer_declaration_name OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.Params | ParameterModifierType.DefaultValue;
+         }
+         opt_formal_parameter_list CLOSE_PARENS COLON member_type OPEN_BRACE
+         {
+               valid_param_mod = 0;
+               var type = (FullNamedExpression) $10;
+
+               var modifiers = (Modifiers) $2;
+               
+               var name = (MemberName) $4;
+
+               if (current_container.Kind == MemberKind.Class && name.ExplicitInterface == null && 
+                       (modifiers & (Modifiers.NEW | Modifiers.SEALED | Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0)
+                               modifiers |= Modifiers.VIRTUAL;
+               
+               Indexer indexer = new Indexer (current_type, type, name, modifiers, (ParametersCompiled) $7, (Attributes) $1);
+                       
+               current_property = indexer;
+
+               if (is_config_enabled) {
+                       current_type.AddIndexer (indexer);
+               }
+               is_config_enabled = true;
+               lbag.AddMember (current_property, mod_locations, GetLocation ($5), GetLocation ($8));
+               
+               if (type.Type != null && type.Type.Kind == MemberKind.Void)
+                       report.Error (620, GetLocation ($3), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ());           
+
+               if (indexer.ParameterInfo.IsEmpty) {
+                       report.Error (1551, GetLocation ($5), "Indexers must have at least one parameter");
+               }
+
+               if (doc_support) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
+               lexer.PropertyParsing = true;
+         }
+         accessor_declarations 
+         {
+               lexer.PropertyParsing = false;
+         }
+         CLOSE_BRACE
+         {
+               CheckIsPlayScript("indexer", GetLocation($3));  
+         
+               if (current_property.AccessorFirst != null && current_property.AccessorFirst.Block == null)
+                       ((Indexer) current_property).ParameterInfo.CheckParameters (current_property);
+         
+               if (doc_support)
+                       current_property.DocComment = ConsumeStoredComment ();
+                       
+               lbag.AppendToMember (current_property, GetLocation ($12));
+               current_property = null;                
+         }
+       ;
+
+
+accessor_declarations
+       : get_accessor_declaration
+       | get_accessor_declaration accessor_declarations
+       | set_accessor_declaration
+       | set_accessor_declaration accessor_declarations
+       | error
+         {
+               if (yyToken == Token.CLOSE_BRACE) {
+                       report.Error (548, lexer.Location, "`{0}': property or indexer must have at least one accessor", current_property.GetSignatureForError ());
+               } else {
+                       if (yyToken == Token.SEMICOLON)
+                               report.Error (1597, lexer.Location, "Semicolon after method or accessor block is not valid");
+                       else
+                               report.Error (1014, GetLocation ($1), "A get or set accessor expected");
+               }
+         }
+       ;
+
+get_accessor_declaration
+       : opt_attributes opt_modifiers GET
+         {
+               if ($2 != ModifierNone && lang_version == LanguageVersion.ISO_1) {
+                       FeatureIsNotAvailable (GetLocation ($2), "access modifiers on properties");
+               }
+         
+               if (current_property.Get != null) {
+                       report.Error (1007, GetLocation ($3), "Property accessor already defined");
+               }
+               
+               if (current_property is Indexer) {
+                       current_property.Get = new Indexer.GetIndexerMethod (current_property, (Modifiers) $2, ((Indexer)current_property).ParameterInfo.Clone (),
+                               (Attributes) $1, GetLocation ($3));
+               } else {
+                       current_property.Get = new Property.GetMethod (current_property,
+                               (Modifiers) $2, (Attributes) $1, GetLocation ($3));
+               }       
+         
+               current_local_parameters = current_property.Get.ParameterInfo;    
+               lbag.AddMember (current_property.Get, mod_locations);
+               lexer.PropertyParsing = false;
+         }
+         accessor_body
+         {
+               if ($5 != null) {
+                       current_property.Get.Block = (ToplevelBlock) $5;                        
+               
+                       if (current_container.Kind == MemberKind.Interface) {
+                               report.Error (531, current_property.Get.Block.StartLocation,
+                                       "`{0}': interface members cannot have a definition", current_property.Get.GetSignatureForError ());
+                       }               
+               }
+         
+               current_local_parameters = null;
+               lexer.PropertyParsing = true;
+
+               if (doc_support)
+                       if (Lexer.doc_state == XmlCommentState.Error)
+                               Lexer.doc_state = XmlCommentState.NotAllowed;
+         }
+       ;
+
+set_accessor_declaration
+       : opt_attributes opt_modifiers SET 
+         {
+               if ($2 != ModifierNone && lang_version == LanguageVersion.ISO_1) {
+                       FeatureIsNotAvailable (GetLocation ($2), "access modifiers on properties");
+               }
+               
+               if (current_property.Set != null) {
+                       report.Error (1007, GetLocation ($3), "Property accessor already defined");
+               }
+         
+               if (current_property is Indexer) {
+                       current_property.Set = new Indexer.SetIndexerMethod (current_property, (Modifiers) $2,
+                               ParametersCompiled.MergeGenerated (compiler,
+                               ((Indexer)current_property).ParameterInfo, true, new Parameter (
+                                       current_property.TypeExpression, "value", Parameter.Modifier.NONE, null, GetLocation ($3)),
+                                       null),
+                               (Attributes) $1, GetLocation ($3));
+               } else {
+                       current_property.Set = new Property.SetMethod (current_property, (Modifiers) $2, 
+                               ParametersCompiled.CreateImplicitParameter (current_property.TypeExpression, GetLocation ($3)),
+                               (Attributes) $1, GetLocation ($3));
+               }
+               
+               current_local_parameters = current_property.Set.ParameterInfo;  
+               lbag.AddMember (current_property.Set, mod_locations);
+               lexer.PropertyParsing = false;
+         }
+         accessor_body
+         {
+               if ($5 != null) {               
+                       current_property.Set.Block = (ToplevelBlock) $5;
+               
+                       if (current_container.Kind == MemberKind.Interface) {
+                               report.Error (531, current_property.Set.Block.StartLocation,
+                                       "`{0}': interface members cannot have a definition", current_property.Set.GetSignatureForError ());
+                       }
+               }
+               
+               current_local_parameters = null;
+               lexer.PropertyParsing = true;
+
+               if (doc_support
+                       && Lexer.doc_state == XmlCommentState.Error)
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+         }
+       ;
+
+accessor_body
+       : block 
+       | SEMICOLON
+         {
+               // TODO: lbag
+               $$ = null;
+         }
+       | error
+         {
+               Error_SyntaxError (1043, yyToken, "Invalid accessor body");
+               $$ = null;
+         }
+       ;
+
+interface_declaration
+       : opt_attributes
+         opt_modifiers
+         opt_partial
+         INTERFACE
+         {
+               lexer.ConstraintsParsing = true;
+           Lexer.AutoSemiInsertion = false;
+         }
+         type_declaration_name
+         {
+           bool is_partial = IsPartial($1) || $3 != null;
+               push_current_container (new Interface (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1), is_partial);
+               lbag.AddMember (current_container, mod_locations, GetLocation ($4));            
+         }
+         opt_class_extends
+         opt_class_implements
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+
+               if ($10 != null)
+                       current_container.SetConstraints ((List<Constraints>) $10);
+
+               if (doc_support) {
+                       current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+               
+               lexer.parsing_modifiers = true;
+         }
+         OPEN_BRACE
+         {
+           Lexer.AutoSemiInsertion = true;
+         }
+         opt_interface_member_declarations CLOSE_BRACE
+         {
+               --lexer.parsing_declaration;      
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         opt_semicolon 
+         {
+           lbag.AppendToMember (current_container, GetLocation ($12), GetLocation ($15));
+               $$ = pop_current_class ();
+         }
+       | opt_attributes opt_modifiers opt_partial INTERFACE error
+         {
+               Error_SyntaxError (yyToken);      
+         }
+       ;
+
+opt_interface_member_declarations
+       : /* empty */
+       | interface_member_declarations
+       ;
+
+interface_member_declarations
+       : interface_member_declaration
+         {
+               lexer.parsing_modifiers = true;
+         }
+       | interface_member_declarations interface_member_declaration
+         {
+               lexer.parsing_modifiers = true;
+         }
+       ;
+
+interface_member_declaration
+       : constant_declaration
+         {
+               report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
+         }
+       | field_declaration
+         {
+               report.Error (525, GetLocation ($1), "Interfaces cannot contain fields or constants");
+         }
+       | method_declaration
+       | property_declaration
+       | event_declaration
+       | indexer_declaration
+       | operator_declaration
+         {
+               report.Error (567, GetLocation ($1), "Interfaces cannot contain operators");
+         }
+//     | constructor_declaration
+//       {
+//             report.Error (526, GetLocation ($1), "Interfaces cannot contain contructors");
+//       }
+       | type_declaration
+         {
+               report.Error (524, GetLocation ($1), "Interfaces cannot declare classes, structs, interfaces, delegates, or enumerations");
+         }
+       ;
+
+operator_declaration
+       : opt_attributes opt_modifiers operator_declarator 
+         {
+         }
+         operator_body
+         {
+               OperatorDeclaration decl = (OperatorDeclaration) $3;
+               if (decl != null) {
+                       var modifiers = (Modifiers) $2;
+                       
+//                     if (current_container.Kind == MemberKind.Class && 
+//                             (modifiers & (Modifiers.NEW | Modifiers.SEALED | Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) == 0)
+//                                     modifiers |= Modifiers.VIRTUAL;                 
+               
+                       if (current_local_parameters.Count < 1) {
+                       
+                               report.Error (7037, GetLocation ($1), "Invalid number of parameters for operator.");                    
+                       
+                       } else {
+                       
+                               Operator op = new Operator (
+                                       current_type, decl.optype, decl.ret_type, modifiers, 
+                                       current_local_parameters,
+                                       (ToplevelBlock) $5, (Attributes) $1, decl.location);
+                               
+                               if (op.Block == null)
+                                       op.ParameterInfo.CheckParameters (op);
+
+                               if (doc_support) {
+                                       op.DocComment = tmpComment;
+                                       Lexer.doc_state = XmlCommentState.Allowed;
+                               }
+
+                               // Note again, checking is done in semantic analysis
+                               if (is_config_enabled) {
+                                       current_type.AddOperator (op);
+                               }
+                               is_config_enabled = true;
+
+                               lbag.AddMember (op, mod_locations, lbag.GetLocations (decl));
+                       }
+               }
+               
+               current_local_parameters = null;
+         }
+       ;
+
+operator_body 
+       : block
+       | SEMICOLON { $$ = null; }
+       ; 
+
+operator_type
+       : type_expression_or_array
+       | VOID
+         {
+               report.Error (590, GetLocation ($1), "User-defined operators cannot return void");
+               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
+         }
+       ;
+
+operator_declarator
+       : OPERATOR overloadable_operator OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.DefaultValue;
+         }
+         opt_formal_parameter_list CLOSE_PARENS COLON operator_type 
+         {
+               CheckIsPlayScript("operator", GetLocation($1));           
+         
+               valid_param_mod = 0;
+
+               Location loc = GetLocation ($1);
+               Operator.OpType op = (Operator.OpType) $8;
+               current_local_parameters = (ParametersCompiled)$5;
+               
+               int p_count = current_local_parameters.Count;
+               if (p_count == 1) {
+                       if (op == Operator.OpType.Addition)
+                               op = Operator.OpType.UnaryPlus;
+                       else if (op == Operator.OpType.Subtraction)
+                               op = Operator.OpType.UnaryNegation;
+               }
+               
+               if (IsUnaryOperator (op)) {
+                       if (p_count == 2) {
+                               report.Error (1020, loc, "Overloadable binary operator expected");
+                       } else if (p_count != 1) {
+                               report.Error (1535, loc, "Overloaded unary operator `{0}' takes one parameter",
+                                       Operator.GetName (op));
+                       }
+               } else {
+                       if (p_count > 2) {
+                               report.Error (1534, loc, "Overloaded binary operator `{0}' takes two parameters",
+                                       Operator.GetName (op));
+                       } else if (p_count != 2) {
+                               report.Error (1019, loc, "Overloadable unary operator expected");
+                       }
+               }
+               
+               if (doc_support) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+
+               $$ = new OperatorDeclaration (op, (FullNamedExpression) $8, loc);
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($3), GetLocation ($6));
+         }
+       | conversion_operator_declarator
+       ;
+
+overloadable_operator
+// Unary operators:
+       : BANG   { $$ = Operator.OpType.LogicalNot; }
+        | TILDE  { $$ = Operator.OpType.OnesComplement; }  
+        | OP_INC { $$ = Operator.OpType.Increment; }
+        | OP_DEC { $$ = Operator.OpType.Decrement; }
+        | TRUE   { $$ = Operator.OpType.True; }
+        | FALSE  { $$ = Operator.OpType.False; }
+// Unary and binary:
+        | PLUS { $$ = Operator.OpType.Addition; }
+        | MINUS { $$ = Operator.OpType.Subtraction; }
+// Binary:
+        | STAR { $$ = Operator.OpType.Multiply; }
+        | DIV {  $$ = Operator.OpType.Division; }
+        | PERCENT { $$ = Operator.OpType.Modulus; }
+        | BITWISE_AND { $$ = Operator.OpType.BitwiseAnd; }
+        | BITWISE_OR { $$ = Operator.OpType.BitwiseOr; }
+        | CARRET { $$ = Operator.OpType.ExclusiveOr; }
+        | OP_SHIFT_LEFT { $$ = Operator.OpType.LeftShift; }
+        | OP_SHIFT_RIGHT { $$ = Operator.OpType.RightShift; }
+//TODO: really        | OP_USHIFT_RIGHT { $$ = Operator.OpType.AsURightShift; }
+        | OP_EQ { $$ = Operator.OpType.Equality; }
+        | OP_NE { $$ = Operator.OpType.Inequality; }
+        | OP_GT { $$ = Operator.OpType.GreaterThan; }
+        | OP_LT { $$ = Operator.OpType.LessThan; }
+        | OP_GE { $$ = Operator.OpType.GreaterThanOrEqual; }
+        | OP_LE { $$ = Operator.OpType.LessThanOrEqual; }
+//TODO:        | OP_IN { $$ = Operator.OpType.AsIn; }
+       ;
+
+conversion_operator_declarator
+       : IMPLICIT OPERATOR type OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.DefaultValue;
+         }
+         opt_formal_parameter_list CLOSE_PARENS
+         {
+               valid_param_mod = 0;
+
+               Location loc = GetLocation ($2);
+               current_local_parameters = (ParametersCompiled)$6;  
+                 
+               if (doc_support) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+
+               $$ = new OperatorDeclaration (Operator.OpType.Implicit, (FullNamedExpression) $3, loc);
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7));
+         }
+       | EXPLICIT OPERATOR type OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.DefaultValue;
+         }
+         opt_formal_parameter_list CLOSE_PARENS
+         {
+               valid_param_mod = 0;
+               
+               Location loc = GetLocation ($2);
+               current_local_parameters = (ParametersCompiled)$6;  
+                 
+               if (doc_support) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+
+               $$ = new OperatorDeclaration (Operator.OpType.Explicit, (FullNamedExpression) $3, loc);
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($4), GetLocation ($7));
+         }
+       | IMPLICIT error 
+         {
+               Error_SyntaxError (yyToken);
+               current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
+               $$ = new OperatorDeclaration (Operator.OpType.Implicit, null, GetLocation ($1));
+         }
+       | EXPLICIT error 
+         {
+               Error_SyntaxError (yyToken);
+               current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
+               $$ = new OperatorDeclaration (Operator.OpType.Explicit, null, GetLocation ($1));
+         }
+       ;
+
+//constructor_declaration
+//     : constructor_declarator
+//       constructor_body
+//       { 
+//             Constructor c = (Constructor) $1;
+//             c.Block = (ToplevelBlock) $2;
+//             
+//             if (doc_support)
+//                     c.DocComment = ConsumeStoredComment ();
+//
+//             current_local_parameters = null;
+//             if (doc_support)
+//                     Lexer.doc_state = XmlCommentState.Allowed;
+//       }
+//     ;
+//
+//constructor_declarator
+//     : opt_attributes
+//       opt_modifiers
+//       FUNCTION
+//       IDENTIFIER
+//       {
+//             if (doc_support) {
+//                     tmpComment = Lexer.consume_doc_comment ();
+//                     Lexer.doc_state = XmlCommentState.Allowed;
+//             }
+//             
+//             valid_param_mod = ParameterModifierType.All;
+//       }
+//       OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_constructor_type
+//       {
+//             valid_param_mod = 0;
+//             current_local_parameters = (ParametersCompiled) $7;
+//             
+//             var lt = (LocatedToken) $4;
+//             var mods = (Modifiers) $2;
+//             var c = new Constructor (current_type, lt.Value, mods, (Attributes) $1, current_local_parameters, lt.Location);
+//
+//             if (lt.Value != current_container.MemberName.Name) {
+//                     report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
+//             } else if ((mods & Modifiers.STATIC) != 0) {
+//                     if ((mods & Modifiers.AccessibilityMask) != 0){
+//                             report.Error (515, c.Location,
+//                                     "`{0}': static constructor cannot have an access modifier",
+//                                     c.GetSignatureForError ());
+//                     }
+//             }
+//
+//             current_type.AddConstructor (c);
+//             lbag.AddMember (c, mod_locations, GetLocation ($6), GetLocation ($8));
+//             $$ = c;
+//
+//             
+//              start block here, so possible anonymous methods inside
+//              constructor initializer can get correct parent block
+//             
+//             start_block (lexer.Location);
+//       }
+//       opt_constructor_initializer
+//       {
+//             if ($9 != null) {
+//                     var c = (Constructor) $8;
+//                     c.Initializer = (ConstructorInitializer) $9;
+//                     
+//                     if (c.IsStatic) {
+//                             report.Error (514, c.Location,
+//                                     "`{0}': static constructor cannot have an explicit `this' or `base' constructor call",
+//                                     c.GetSignatureForError ());
+//                     }
+//             }
+//
+//             $$ = $8;
+//       }
+//     ;
+//
+//constructor_body
+//     : block_prepared
+//     | SEMICOLON             { current_block = null; $$ = null; }
+//     ;
+//
+//opt_constructor_type
+//     : /* Empty */
+//     | COLON IDENTIFIER
+//       {
+//             var lt = (LocatedToken) $2;
+//             if (lt.Value != "void"){
+//                     report.Error (1525, GetLocation ($2), "Unexpected symbol expected 'void'");
+//             }         
+//       }
+//     ;
+//
+//opt_constructor_initializer
+//     : /* Empty */
+//     | constructor_initializer
+//     ;
+//
+//constructor_initializer
+//     : COLON SUPER OPEN_PARENS
+//       {
+//             ++lexer.parsing_block;
+//       }
+//       opt_argument_list CLOSE_PARENS
+//       {
+//             --lexer.parsing_block;
+//             $$ = new ConstructorBaseInitializer ((Arguments) $5, GetLocation ($2));
+//             lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6));
+//       }
+//     | COLON THIS OPEN_PARENS
+//       {
+//             ++lexer.parsing_block;
+//       }
+//       opt_argument_list CLOSE_PARENS
+//       {
+//             --lexer.parsing_block;
+//             $$ = new ConstructorThisInitializer ((Arguments) $5, GetLocation ($2));
+//             lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3), GetLocation ($6));
+//       }
+//     | COLON error
+//       {
+//             Error_SyntaxError (yyToken);      
+//             $$ = new ConstructorThisInitializer (null, GetLocation ($2));
+//             lbag.AddLocation ($$, GetLocation ($1));
+//       }
+//     | error
+//       {
+//             Error_SyntaxError (yyToken);
+//             $$ = null;
+//       }
+//     ;
+
+destructor_declaration
+       : opt_attributes opt_modifiers FUNCTION TILDE 
+         {
+               if (doc_support) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+               
+               current_local_parameters = ParametersCompiled.EmptyReadOnlyParameters;
+         }
+         IDENTIFIER OPEN_PARENS CLOSE_PARENS method_body
+         {
+               var lt = (LocatedToken) $6;
+               if (lt.Value != current_container.MemberName.Name){
+                       report.Error (574, lt.Location, "Name of destructor must match name of class");
+               } else if (current_container.Kind != MemberKind.Class){
+                       report.Error (575, lt.Location, "Only class types can contain destructor");
+               }
+               
+               Destructor d = new Destructor (current_type, (Modifiers) $2,
+                       ParametersCompiled.EmptyReadOnlyParameters, (Attributes) $1, lt.Location);
+               if (doc_support)
+                       d.DocComment = ConsumeStoredComment ();
+                 
+               d.Block = (ToplevelBlock) $9;
+               if (is_config_enabled) {
+                       current_type.AddMember (d);
+               }
+               is_config_enabled = true;
+               lbag.AddMember (d, mod_locations, GetLocation ($4), GetLocation ($7), GetLocation ($8));
+
+               current_local_parameters = null;
+         }
+       ;
+
+event_declaration
+       : opt_attributes
+         opt_modifiers
+         EVENT member_declaration_name COLON type 
+         {
+               current_event_field = new EventField (current_type, (FullNamedExpression) $6, (Modifiers) $2, (MemberName) $4, (Attributes) $1);
+               if (is_config_enabled) {
+                       current_type.AddMember (current_event_field);
+               }
+               is_config_enabled = true;
+               
+               if (current_event_field.MemberName.ExplicitInterface != null) {
+                       report.Error (71, current_event_field.Location, "`{0}': An explicit interface implementation of an event must use property syntax",
+                       current_event_field.GetSignatureForError ());
+               }
+               
+               $$ = current_event_field;
+         }
+         opt_event_initializer
+         opt_event_declarators
+         SEMICOLON
+         {
+               if (doc_support) {
+                       current_event_field.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+               
+               lbag.AddMember (current_event_field, mod_locations, GetLocation ($3), GetLocation ($10));
+               current_event_field = null;
+         }
+       | opt_attributes
+         opt_modifiers
+         EVENT member_declaration_name COLON type 
+         OPEN_BRACE
+         {
+               current_event = new EventProperty (current_type, (FullNamedExpression) $6, (Modifiers) $2, (MemberName) $4, (Attributes) $1);
+               if (is_config_enabled) {
+                       current_type.AddMember (current_event);
+               }
+               is_config_enabled = true;
+               lbag.AddMember (current_event, mod_locations, GetLocation ($3), GetLocation ($7));
+               
+               lexer.EventParsing = true;
+         }
+         event_accessor_declarations
+         {
+               if (current_container.Kind == MemberKind.Interface)
+                       report.Error (69, GetLocation ($7), "Event in interface cannot have add or remove accessors");
+         
+               lexer.EventParsing = false;
+         }
+         CLOSE_BRACE
+         {
+               if (doc_support) {
+                       current_event.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+               
+               lbag.AppendToMember (current_event, GetLocation ($10));
+               current_event = null;   
+               current_local_parameters = null;
+         }
+       ;
+       
+opt_event_initializer
+       : /* empty */
+       | ASSIGN
+         {
+               ++lexer.parsing_block;
+         }
+         event_variable_initializer
+         {
+               --lexer.parsing_block;
+               current_event_field.Initializer = (Expression) $3;
+         }
+       ;
+       
+opt_event_declarators
+       : /* empty */
+       | event_declarators
+       ;
+       
+event_declarators
+       : event_declarator
+         {
+               current_event_field.AddDeclarator ((FieldDeclarator) $1);
+         }
+       | event_declarators event_declarator
+         {
+               current_event_field.AddDeclarator ((FieldDeclarator) $2);
+         }
+       ;
+       
+event_declarator
+       : COMMA IDENTIFIER COLON member_type
+         {
+               var lt = (LocatedToken) $2;
+               $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), null, (FullNamedExpression) $4);
+               lbag.AddLocation ($$, GetLocation ($1));
+         }
+       | COMMA IDENTIFIER COLON member_type ASSIGN 
+         {
+               ++lexer.parsing_block;
+         }
+         event_variable_initializer
+         {
+               --lexer.parsing_block;
+               var lt = (LocatedToken) $2;       
+               $$ = new FieldDeclarator (new SimpleMemberName (lt.Value, lt.Location), (Expression) $7, (FullNamedExpression) $4);
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($5));
+         }
+       ;
+       
+event_variable_initializer
+       : {
+               if (current_container.Kind == MemberKind.Interface) {
+                       report.Error (68, lexer.Location, "`{0}': event in interface cannot have an initializer",
+                               current_event_field.GetSignatureForError ());
+               }
+               
+               if ((current_event_field.ModFlags & Modifiers.ABSTRACT) != 0) {
+                       report.Error (74, lexer.Location, "`{0}': abstract event cannot have an initializer",
+                               current_event_field.GetSignatureForError ());
+               }               
+         }
+         variable_initializer
+         {
+               $$ = $2;
+         }
+       ;
+       
+event_accessor_declarations
+       : add_accessor_declaration remove_accessor_declaration
+       | remove_accessor_declaration add_accessor_declaration
+       | add_accessor_declaration
+         {
+               report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors",
+                       current_event.GetSignatureForError ());
+         } 
+       | remove_accessor_declaration
+         {
+               report.Error (65, lexer.Location, "`{0}': event property must have both add and remove accessors",
+                       current_event.GetSignatureForError ());
+         }     
+       | error
+         { 
+               report.Error (1055, GetLocation ($1), "An add or remove accessor expected");
+               $$ = null;
+         }
+       ;
+
+add_accessor_declaration
+       : opt_attributes opt_modifiers ADD
+         {
+               if ($2 != ModifierNone) {
+                       report.Error (1609, GetLocation ($2), "Modifiers cannot be placed on event accessor declarations");
+               }
+               
+               current_event.Add = new EventProperty.AddDelegateMethod (current_event, (Attributes) $1, GetLocation ($3));
+               current_local_parameters = current_event.Add.ParameterInfo;
+               
+               lbag.AddMember (current_event.Add, mod_locations);
+               lexer.EventParsing = false;             
+         }
+         event_accessor_block
+         {
+               lexer.EventParsing = true;
+         
+               current_event.Add.Block = (ToplevelBlock) $5;
+               
+               if (current_container.Kind == MemberKind.Interface) {
+                       report.Error (531, current_event.Add.Block.StartLocation,
+                               "`{0}': interface members cannot have a definition", current_event.Add.GetSignatureForError ());
+               }
+               
+               current_local_parameters = null;
+         }
+       ;
+       
+remove_accessor_declaration
+       : opt_attributes opt_modifiers REMOVE
+         {
+               if ($2 != ModifierNone) {
+                       report.Error (1609, GetLocation ($2), "Modifiers cannot be placed on event accessor declarations");
+               }
+               
+               current_event.Remove = new EventProperty.RemoveDelegateMethod (current_event, (Attributes) $1, GetLocation ($3));
+               current_local_parameters = current_event.Remove.ParameterInfo;
+
+               lbag.AddMember (current_event.Remove, mod_locations);
+               lexer.EventParsing = false;             
+         }
+         event_accessor_block
+         {
+               lexer.EventParsing = true;
+         
+               current_event.Remove.Block = (ToplevelBlock) $5;
+               
+               if (current_container.Kind == MemberKind.Interface) {
+                       report.Error (531, current_event.Remove.Block.StartLocation,
+                               "`{0}': interface members cannot have a definition", current_event.Remove.GetSignatureForError ());
+               }
+               
+               current_local_parameters = null;
+         }
+       ;
+
+event_accessor_block
+       : opt_semicolon
+         {
+               report.Error (73, lexer.Location, "An add or remove accessor must have a body");
+               $$ = null;
+         }
+       | block;
+       ;
+
+attributes_without_members
+       : attribute_sections CLOSE_BRACE
+         {
+               current_type.UnattachedAttributes = (Attributes) $1;
+               report.Error (1519, GetLocation ($1), "An attribute is missing member declaration");
+               lexer.putback ('}');
+         }
+       ;
+         
+enum_declaration
+       : opt_attributes
+         opt_modifiers
+         ENUM type_declaration_name
+         opt_enum_base
+         {
+               if (doc_support)
+                       enumTypeComment = Lexer.consume_doc_comment ();
+         }
+         OPEN_BRACE
+         {
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+
+               MemberName name = (MemberName) $4;
+               if (name.IsGeneric) {
+                       report.Error (1675, name.Location, "Enums cannot have type parameters");
+               }
+               
+               push_current_container (new Enum (current_container, (FullNamedExpression) $5, (Modifiers) $2, name, (Attributes) $1), null);
+         }
+         opt_enum_member_declarations
+         {
+               // here will be evaluated after CLOSE_BLACE is consumed.
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         CLOSE_BRACE opt_semicolon
+         {
+               CheckIsPlayScript("enum", GetLocation($3));
+         
+               if (doc_support)
+                       current_container.DocComment = enumTypeComment;
+                       
+               --lexer.parsing_declaration;
+
+//                     if (doc_support)
+//                             em.DocComment = ev.DocComment;
+
+               lbag.AddMember (current_container, mod_locations, GetLocation ($3), GetLocation ($7), GetLocation ($11));
+               $$ = pop_current_class ();
+         }
+       ;
+
+opt_enum_base
+       : /* empty */
+       | COLON type
+        {
+               var te = $2 as TypeExpression;
+               if (te == null || !EnumSpec.IsValidUnderlyingType (te.Type)) {
+                       Enum.Error_1008 (GetLocation ($2), report);
+               }
+               $$ = $2;
+        }
+       | COLON error
+        {
+               Error_TypeExpected (GetLocation ($1));
+               $$ = null;
+        }
+       ;
+
+opt_enum_member_declarations
+       : /* empty */
+       | enum_member_declarations
+       | enum_member_declarations COMMA
+         {
+               lbag.AddLocation ($1, GetLocation ($2));
+         }
+       ;
+
+enum_member_declarations
+       : enum_member_declaration
+       | enum_member_declarations COMMA enum_member_declaration
+         {
+               lbag.AddLocation ($1, GetLocation ($2));
+               $$ = $3;
+         }
+       ;
+
+enum_member_declaration
+       : opt_attributes IDENTIFIER
+         {
+               var lt = (LocatedToken) $2;
+               var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
+               ((Enum) current_type).AddEnumMember (em);
+
+               if (doc_support) {
+                       em.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
+               $$ = em;
+         }
+       | opt_attributes IDENTIFIER
+         {
+               ++lexer.parsing_block;
+               if (doc_support) {
+                       tmpComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.NotAllowed;
+               }
+         }
+         ASSIGN constant_expression
+         { 
+               --lexer.parsing_block;
+               
+               var lt = (LocatedToken) $2;
+               var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
+               em.Initializer = new ConstInitializer (em, (Expression) $5, GetLocation ($4));
+               ((Enum) current_type).AddEnumMember (em);
+               
+               if (doc_support)
+                       em.DocComment = ConsumeStoredComment ();
+
+               $$ = em;
+         }
+       | opt_attributes IDENTIFIER error
+         {
+               Error_SyntaxError (yyToken);
+         
+               var lt = (LocatedToken) $2;
+               var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
+               ((Enum) current_type).AddEnumMember (em);
+
+               if (doc_support) {
+                       em.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+
+               $$ = em;
+         }
+       | attributes_without_members
+       ;
+
+delegate_declaration
+       : opt_attributes
+         opt_modifiers
+         DELEGATE
+         type_declaration_name
+         OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out | ParameterModifierType.Params | ParameterModifierType.DefaultValue;
+         }
+         opt_formal_parameter_list CLOSE_PARENS COLON member_type
+         {
+               valid_param_mod = 0;
+
+               ParametersCompiled p = (ParametersCompiled) $7;
+
+               Delegate del = new Delegate (current_container, (FullNamedExpression) $10, (Modifiers) $2, (MemberName) $4, p, (Attributes) $1);
+
+               p.CheckParameters (del);
+
+               current_container.AddTypeContainer (del);
+
+               current_delegate = del;
+               lexer.ConstraintsParsing = true;
+         }
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+         }
+         SEMICOLON
+         {
+               CheckIsPlayScript("delegate", GetLocation($3));
+               
+               if (doc_support) {
+                       current_delegate.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+         
+               if ($12 != null)
+                       current_delegate.SetConstraints ((List<Constraints>) $12);
+               lbag.AddMember (current_delegate, mod_locations, GetLocation ($3), GetLocation ($5), GetLocation ($8), GetLocation ($14));
+
+               $$ = current_delegate;
+
+               current_delegate = null;
+         }
+       ;
+
+opt_nullable
+       : /* empty */
+       | INTERR_NULLABLE
+         {
+               if (lang_version < LanguageVersion.ISO_2)
+                       FeatureIsNotAvailable (GetLocation ($1), "nullable types");
+         
+               $$ = ComposedTypeSpecifier.CreateNullable (GetLocation ($1));
+         }
+       ;
+
+namespace_or_type_expr
+       : member_name
+       | qualified_identifier IDENTIFIER opt_type_argument_list
+         {
+               var lt1 = (LocatedToken) $1;
+               var lt2 = (LocatedToken) $2;
+               
+               $$ = new QualifiedMemberAccess (lt1.Value, lt2.Value, lt1.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+member_name
+       : simple_name_expr
+       | namespace_or_type_expr DOT IDENTIFIER opt_type_argument_list
+         {
+           // member_name
+               var lt = (LocatedToken) $3;
+               $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+simple_name_expr
+       : IDENTIFIER opt_type_argument_list
+         {
+           // simple_name_expr
+               var lt = (LocatedToken) $1;
+               $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);
+         }
+       ;
+       
+//
+// Generics arguments  (any type, without attributes)
+//
+opt_type_argument_list
+       : /* empty */
+       | OP_GENERICS_LT type_arguments OP_GENERICS_GT
+         {
+               if (lang_version < LanguageVersion.ISO_2)
+                       FeatureIsNotAvailable (GetLocation ($1), "generics");     
+         
+               $$ = $2;
+         }
+       | OP_GENERICS_LT error
+         {
+               Error_TypeExpected (lexer.Location);
+               $$ = new TypeArguments ();
+         }
+       ;
+
+type_arguments
+       : type
+         {
+               TypeArguments type_args = new TypeArguments ();
+               type_args.Add ((FullNamedExpression) $1);
+               $$ = type_args;
+         }
+       | type_arguments COMMA type
+         {
+               TypeArguments type_args = (TypeArguments) $1;
+               type_args.Add ((FullNamedExpression) $3);
+               $$ = type_args;
+         }       
+       ;
+
+//
+// Generics parameters (identifiers only, with attributes), used in type or method declarations
+//
+type_declaration_name
+       : IDENTIFIER
+         {
+               lexer.parsing_generic_declaration = true;
+         }
+         opt_type_parameter_list
+         {
+               lexer.parsing_generic_declaration = false;
+               var lt = (LocatedToken) $1;
+               $$ = CreateFullMemberName (lt, (TypeParameters)$3);
+         }
+       ;
+
+member_declaration_name
+       : method_declaration_name
+         {
+               MemberName mn = (MemberName)$1;
+               if (mn.TypeParameters != null)
+                       syntax_error (mn.Location, string.Format ("Member `{0}' cannot declare type arguments",
+                               mn.GetSignatureForError ()));
+         }
+       ;
+
+method_declaration_name
+       : type_declaration_name
+/*     
+       | explicit_interface IDENTIFIER opt_type_parameter_list
+         {
+               lexer.parsing_generic_declaration = false;        
+               var lt = (LocatedToken) $2;
+               $$ = new MemberName (lt.Value, (TypeParameters) $3, (ATypeNameExpression) $1, lt.Location);
+         }
+*/
+       ;
+       
+indexer_declaration_name
+       : THIS
+         {
+               lexer.parsing_generic_declaration = false;        
+               $$ = new MemberName (TypeDefinition.DefaultIndexerName, GetLocation ($1));
+         }
+/*       
+       | explicit_interface THIS
+         {
+               lexer.parsing_generic_declaration = false;
+               $$ = new MemberName (TypeDefinition.DefaultIndexerName, null, (ATypeNameExpression) $1, GetLocation ($2));
+         }
+*/
+       ;
+/*
+explicit_interface
+       : IDENTIFIER opt_type_argument_list DOT
+         {
+               var lt = (LocatedToken) $1;
+               $$ = new CSharp.SimpleName (lt.Value, (TypeArguments) $2, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($3));
+         }
+//     | qualified_alias_member IDENTIFIER opt_type_argument_list DOT
+//       {
+//             var lt1 = (LocatedToken) $1;
+//             var lt2 = (LocatedToken) $2;
+//
+//             $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (TypeArguments) $3, lt1.Location);
+//             lbag.AddLocation ($$, GetLocation ($4));
+//       }
+       | explicit_interface IDENTIFIER opt_type_argument_list DOT
+         {
+               var lt = (LocatedToken) $2;
+               $$ = new MemberAccess ((ATypeNameExpression) $1, lt.Value, (TypeArguments) $3, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($4));
+         }
+       ;
+*/
+
+opt_type_parameter_list
+       : /* empty */
+       | OP_GENERICS_LT type_parameters OP_GENERICS_GT
+         {
+               if (lang_version < LanguageVersion.ISO_2)
+                       FeatureIsNotAvailable (GetLocation ($1), "generics");
+         
+               $$ = $2;
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
+         }
+       ;
+
+type_parameters
+       : type_parameter
+         {
+               var tparams = new TypeParameters ();
+               tparams.Add ((TypeParameter)$1);
+               $$ = tparams;
+         }
+       | type_parameters COMMA type_parameter
+         {
+               var tparams = (TypeParameters) $1;
+               tparams.Add ((TypeParameter)$3);
+               $$ = tparams;
+               lbag.AddLocation ($3, GetLocation ($3));
+         }       
+       ;
+
+type_parameter
+       : opt_attributes opt_type_parameter_variance IDENTIFIER
+         {
+               var lt = (LocatedToken)$3;
+               $$ = new TypeParameter (new MemberName (lt.Value, lt.Location), (Attributes)$1, (Variance) $2);
+         }
+       | error
+         {
+               if (GetTokenName (yyToken) == "type")
+                       report.Error (81, GetLocation ($1), "Type parameter declaration must be an identifier not a type");
+               else
+                       Error_SyntaxError (yyToken);
+                       
+               $$ = new TypeParameter (MemberName.Null, null, Variance.None);
+         }
+       ;
+
+//
+// All types where void is allowed
+//
+type_and_void
+       : type_expression_or_array
+       | VOID
+         {
+               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
+         }
+       ;
+       
+member_type
+       : type_and_void
+         {
+               lexer.parsing_generic_declaration = true;
+         }
+       ;
+       
+//
+// A type which does not allow `void' to be used
+//
+type
+       : type_expression_or_array
+       | VOID
+         {
+               Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
+               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
+         }     
+       ;
+       
+simple_type
+       : type_expression
+       | VOID
+         {
+               Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
+               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
+         }     
+       ;
+       
+parameter_type
+       : type_expression_or_array
+       | VOID
+         {
+               report.Error (1536, GetLocation ($1), "Invalid parameter type `void'");
+               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
+         }     
+       ;
+
+type_expression_or_array
+       : type_expression
+       | type_expression rank_specifiers
+         {
+               CheckIsPlayScript("arrays", GetLocation($2));
+               $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
+         }
+       ;
+       
+type_expression
+       : namespace_or_type_expr opt_nullable
+         {
+               if ($2 != null) {
+                       $$ = new ComposedCast ((ATypeNameExpression) $1, (ComposedTypeSpecifier) $2);
+               } else {
+//                     var sn = $1 as SimpleName;
+//                     if (sn != null)
+//                             $$ = ConvertAsType(sn, $1);
+//                     else
+                               $$ = $1;
+               }
+         }
+       | STAR
+         {
+               $$ = new UntypedTypeExpression (GetLocation ($1));
+         }
+//     | namespace_or_type_expr pointer_stars
+//       {
+//             $$ = new ComposedCast ((ATypeNameExpression) $1, (ComposedTypeSpecifier) $2);
+//       }
+       | builtin_types opt_nullable
+         {
+               if ($2 != null)
+                       $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
+         }
+//     | builtin_types pointer_stars
+//       {
+//             $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
+//       }
+//     | VOID pointer_stars
+//       {
+//             $$ = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)), (ComposedTypeSpecifier) $2);
+//       }
+       ;
+
+type_list
+       : base_type_name
+         {
+               var types = new List<FullNamedExpression> (2);
+               types.Add ((FullNamedExpression) $1);
+               $$ = types;
+         }
+       | type_list COMMA base_type_name
+         {
+               var types = (List<FullNamedExpression>) $1;
+               types.Add ((FullNamedExpression) $3);
+               $$ = types;
+         }
+       ;
+
+base_type_name
+       : type
+         {
+               if ($1 is ComposedCast) {
+                       report.Error (1521, GetLocation ($1), "Invalid base type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
+               }
+               $$ = $1;
+         }
+       ;
+       
+/*
+ * replaces all the productions for isolating the various
+ * simple types, but we need this to reuse it easily in variable_type
+ */
+builtin_types
+       : INT           { $$ = new TypeExpression (compiler.BuiltinTypes.Int, GetLocation ($1)); }
+       | UINT          { $$ = new TypeExpression (compiler.BuiltinTypes.UInt, GetLocation ($1)); }
+       ;
+
+//
+// Expressions, section 7.5
+//
+
+
+primary_expression
+       : primary_expression_or_type
+       | literal
+//     | array_creation_expression
+       | parenthesized_expression
+       | default_value_expression
+       | invocation_expression
+       | element_access
+       | this_access
+       | base_access
+       | post_increment_expression
+       | post_decrement_expression
+//     | object_or_delegate_creation_expression
+//     | anonymous_type_expression
+       | sizeof_expression
+       | checked_expression
+       | unchecked_expression
+       | new_expression
+//     | pointer_member_access
+       | anonymous_method_expression
+//     | undocumented_expressions
+       | array_creation
+       | object_initializer
+       | e4x_operators
+       ;
+
+primary_expression_or_type
+       : IDENTIFIER opt_type_argument_list
+         {
+           // primary_expression_or_type
+               var lt = (LocatedToken) $1;
+               $$ = new SimpleName (lt.Value, (TypeArguments)$2, lt.Location);   
+         }
+       | IDENTIFIER GENERATE_COMPLETION {
+               var lt = (LocatedToken) $1;
+              $$ = new CompletionSimpleName (MemberName.MakeName (lt.Value, null), lt.Location);
+         }
+       | member_access
+       ;
+
+literal
+       : boolean_literal
+       | LITERAL
+       | NULL                  { $$ = new NullLiteral (GetLocation ($1)); }
+       ;
+
+boolean_literal
+       : TRUE                  { $$ = new BoolLiteral (compiler.BuiltinTypes, true, GetLocation ($1)); }
+       | FALSE                 { $$ = new BoolLiteral (compiler.BuiltinTypes, false, GetLocation ($1)); }
+       ;
+
+
+//
+// Here is the trick, tokenizer may think that parens is a special but
+// parser is interested in open parens only, so we merge them.
+// Consider: if (a)foo ();
+//
+open_parens_any
+       : OPEN_PARENS
+       | OPEN_PARENS_CAST
+       ;
+
+// 
+// Use this production to accept closing parenthesis or 
+// performing completion
+//
+close_parens
+       : CLOSE_PARENS
+       | COMPLETE_COMPLETION
+       ;
+
+
+parenthesized_expression
+       : OPEN_PARENS expression CLOSE_PARENS
+         {
+               $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
+         }
+       | OPEN_PARENS expression COMPLETE_COMPLETION
+         {
+               $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1));
+         }
+       ;
+       
+member_access
+       : primary_expression DOT identifier_inside_body opt_type_argument_list
+         {
+               var lt = (LocatedToken) $3;
+               $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | builtin_types DOT identifier_inside_body opt_type_argument_list
+         {
+               var lt = (LocatedToken) $3;
+               $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | SUPER DOT IDENTIFIER opt_type_argument_list
+         {
+               var lt = (LocatedToken) $3;
+               $$ = new MemberAccess (new BaseThis (GetLocation ($1)), lt.Value, (TypeArguments) $4, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | qualified_identifier identifier_inside_body opt_type_argument_list
+         {
+               var lt1 = (LocatedToken) $1;
+               var lt2 = (LocatedToken) $2;
+
+               $$ = new QualifiedMemberAccess (lt1.Value, lt2.Value, lt1.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | primary_expression DOT GENERATE_COMPLETION {
+               $$ = new CompletionMemberAccess ((Expression) $1, null,GetLocation ($3));
+         }
+       | primary_expression DOT IDENTIFIER GENERATE_COMPLETION {
+               var lt = (LocatedToken) $3;
+               $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
+         }
+       | builtin_types DOT GENERATE_COMPLETION
+         {
+               $$ = new CompletionMemberAccess ((Expression) $1, null, lexer.Location);
+         }
+       | builtin_types DOT IDENTIFIER GENERATE_COMPLETION {
+               var lt = (LocatedToken) $3;
+               $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
+         }
+       ;
+
+e4x_operators
+       : primary_expression DOT_AT IDENTIFIER
+         {
+               var lt = (LocatedToken) $3;
+               var ma = new E4XOperator (E4XOperator.Operator.ChildAttribute, (Expression) $1, lt.Value, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+               $$ = ma;
+         }
+       | primary_expression DOT_STAR
+         {
+               var ma = new E4XOperator (E4XOperator.Operator.ChildAll, (Expression) $1, "any", GetLocation ($2));
+               lbag.AddLocation ($$, GetLocation ($2));
+               $$ = ma;
+         }
+       | primary_expression DOTDOT IDENTIFIER
+         {
+               var lt = (LocatedToken) $3;
+               var ma = new E4XOperator (E4XOperator.Operator.Descendant, (Expression) $1, lt.Value, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+               $$ = ma;
+         }
+       | primary_expression DOTDOT_STAR
+         {
+               var ma = new E4XOperator (E4XOperator.Operator.DescendantAll, (Expression) $1, "any", GetLocation ($2));
+               lbag.AddLocation ($$, GetLocation ($2));
+               $$ = ma;
+         }
+/*
+       | primary_expression DOUBLE_COLON IDENTIFIER
+         {
+               var lt = (LocatedToken) $3;
+               var ma = new E4XOperator (E4XOperator.Operator.Namespace, (Expression) $1, lt.Value, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+               $$ = ma;
+         }
+       | primary_expression DOUBLE_COLON OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET
+         {
+               var ea = new E4XIndexer (E4XIndexer.Operator.Namespace, (Expression) $1, (Arguments) $4, GetLocation ($3));
+               lbag.AddLocation (GetLocation ($3), GetLocation ($5));
+               $$ = ea;
+         }
+*/       
+       | primary_expression DOT_AT OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET
+         {
+               var ea = new E4XIndexer (E4XIndexer.Operator.Attribute, (Expression) $1, (Arguments) $4, GetLocation ($3));
+               lbag.AddLocation (GetLocation ($3), GetLocation ($5));
+               $$ = ea;
+         }       
+       | primary_expression DOT open_parens_any expression CLOSE_PARENS
+         {
+               var lt = (LocatedToken) $3;
+               var ma = new AsXmlQueryExpression ((Expression) $1, (Expression) $4, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+               $$ = ma;
+         }
+       ;
+
+invocation_expression
+       : SUPER open_parens_any opt_argument_list close_parens
+         {
+               if (current_constructor == null) {
+                       report.ErrorPlayScript (1007, GetLocation ($1), "A super statement can be used only inside class instance constructors");
+               } else {
+                       current_constructor.Initializer = EmptyExpressionStatement.Instance;
+               }
+
+               $$ = new SuperBaseInitializer ((Arguments) $3, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | builtin_types open_parens_any opt_argument_list close_parens
+         {
+               $$ = new Invocation ((Expression) $1, (Arguments) $3);
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }  
+       | primary_expression open_parens_any opt_argument_list close_parens
+         {
+               $$ = new Invocation ((Expression) $1, (Arguments) $3);
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | primary_expression open_parens_any argument_list error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Invocation ((Expression) $1, (Arguments) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+object_initializer
+       : init_open_brace opt_member_initializer_list init_close_brace
+         {
+               $$ = new ObjectInitializer ((List<Expression>) $2, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
+         }
+       ;
+
+init_open_brace
+       : OPEN_BRACE_INIT
+         {
+       oob_stack.Push (Lexer.AutoSemiInsertion);
+        Lexer.AutoSemiInsertion = false;
+         }
+       ;
+
+init_close_brace
+       : CLOSE_BRACE
+         {
+       Lexer.AutoSemiInsertion = (bool) oob_stack.Pop ();
+       if (Lexer.AutoSemiInsertion)
+                       Lexer.AllowAutoSemiAfterToken(Token.CLOSE_BRACE, true);
+         }
+       ;
+       
+init_close_brace_or_complete_completion
+       : CLOSE_BRACE
+         {
+       Lexer.AutoSemiInsertion = (bool) oob_stack.Pop ();
+       if (Lexer.AutoSemiInsertion)
+                       Lexer.AllowAutoSemiAfterToken(Token.CLOSE_BRACE, true);
+         }
+       | COMPLETE_COMPLETION
+       ;       
+
+opt_member_initializer_list
+       : /* empty */           { $$ = null; }
+       | member_initializer_list
+         {
+               $$ = $1;
+         }
+       ;
+
+member_initializer_list
+       : member_initializer
+         {
+               var a = new List<Expression> ();
+               a.Add ((Expression) $1);
+               $$ = a;
+         }
+       | member_initializer_list COMMA member_initializer
+         {
+               var a = (List<Expression>)$1;
+               a.Add ((Expression) $3);
+               $$ = a;
+         }
+       | member_initializer_list error {
+               Error_SyntaxError (yyToken);
+               $$ = $1;
+         }
+       ;
+
+member_initializer
+       : IDENTIFIER COLON initializer_value
+         {
+               var lt = (LocatedToken) $1;
+               $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | AWAIT ASSIGN initializer_value
+         {
+               var lt = (LocatedToken) Error_AwaitAsIdentifier ($1);
+               $$ = new ElementInitializer (lt.Value, (Expression)$3, lt.Location);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }       
+       | LITERAL COLON initializer_value
+         {
+               ILiteralConstant lit = $1 as ILiteralConstant;
+               string nm;              
+               if (lit is StringLiteral) {
+                       nm = ((StringLiteral)lit).Value;
+               } else {
+                       if (parsing_playscript || !(lit is IntLiteral || lit is DoubleLiteral || lit is BoolLiteral)) {
+                               report.Error (7019, GetLocation ($1), "Must be identifier or string literal");
+                               nm = "err";
+                        } else {
+                               nm = ((Constant)$1).GetValueAsLiteral();                         
+                        }
+               }
+         
+               $$ = new ElementInitializer (nm, (Expression)$3, GetLocation($1));
+               lbag.AddLocation ($$, GetLocation ($2));
+         } 
+       | GENERATE_COMPLETION 
+         {
+               $$ = new CompletionElementInitializer (null, GetLocation ($1));
+         }
+       /* | non_assignment_expression opt_COMPLETE_COMPLETION  {
+               CompletionSimpleName csn = $1 as CompletionSimpleName;
+               if (csn == null)
+                       $$ = new CollectionElementInitializer ((Expression)$1);
+               else
+                       $$ = new CompletionElementInitializer (csn.Prefix, csn.Location);
+         } 
+       | OPEN_BRACE expression_list CLOSE_BRACE
+         {
+               if ($2 == null)
+                       $$ = null;
+               else
+                       $$ = new CollectionElementInitializer ((List<Expression>)$2, GetLocation ($1));
+         } 
+       | OPEN_BRACE CLOSE_BRACE
+         {
+               report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
+               $$ = null;
+         } */  
+       ;
+
+initializer_value
+       : expression
+       ;
+
+opt_argument_list
+       : /* empty */           { $$ = null; }
+       | argument_list
+       ;
+
+argument_list
+       : argument_or_named_argument
+         { 
+               Arguments list = new Arguments (4);
+               list.Add ((Argument) $1);
+               $$ = list;
+         }
+       | argument_list COMMA argument
+         {
+               Arguments list = (Arguments) $1;
+               if (list [list.Count - 1] is NamedArgument)
+                       Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]);
+               
+               list.Add ((Argument) $3);
+               $$ = list;
+         }
+       | argument_list COMMA named_argument
+         {
+               Arguments list = (Arguments) $1;
+               NamedArgument a = (NamedArgument) $3;
+               for (int i = 0; i < list.Count; ++i) {
+                       NamedArgument na = list [i] as NamedArgument;
+                       if (na != null && na.Name == a.Name)
+                               report.Error (1740, na.Location, "Named argument `{0}' specified multiple times",
+                                       na.Name);
+               }
+               
+               list.Add (a);
+               $$ = list;
+         }
+       | argument_list COMMA error
+         {
+               lexer.putback (')'); // TODO: Wrong but what can I do
+               Error_SyntaxError (yyToken);
+               $$ = $1;
+         }
+       | COMMA error
+         {
+               report.Error (839, GetLocation ($1), "An argument is missing");
+               $$ = null;
+         }
+       ;
+
+argument
+       : expression
+         {
+               $$ = new Argument ((Expression) $1);
+         }
+       | non_simple_argument
+       ;
+
+argument_or_named_argument
+       : argument
+       | named_argument
+       ;
+
+non_simple_argument
+       : REF variable_reference 
+         { 
+               $$ = new Argument ((Expression) $2, Argument.AType.Ref);
+               lbag.AddLocation ($$, GetLocation ($1));
+         }
+       | OUT variable_reference 
+         { 
+               $$ = new Argument ((Expression) $2, Argument.AType.Out);
+               lbag.AddLocation ($$, GetLocation ($1));
+         }
+//     | ARGLIST OPEN_PARENS argument_list CLOSE_PARENS
+//       {
+//             $$ = new Argument (new Arglist ((Arguments) $3, GetLocation ($1)));
+//             lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+//       }
+//     | ARGLIST OPEN_PARENS CLOSE_PARENS
+//       {
+//             $$ = new Argument (new Arglist (GetLocation ($1)));
+//             lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
+//       }       
+       ;
+
+variable_reference
+       : expression
+       ;
+
+element_access
+       : primary_expression OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET  
+         {
+               $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
+               lbag.AddLocation ($$, GetLocation ($4));
+         }
+       | primary_expression OPEN_BRACKET_EXPR expression_list_arguments error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
+         }
+       | primary_expression OPEN_BRACKET_EXPR error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new ElementAccess ((Expression) $1, null, GetLocation ($2));
+         }
+       | builtin_types OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET       
+         {
+               $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
+               lbag.AddLocation ($$, GetLocation ($4));
+         }
+       | builtin_types OPEN_BRACKET_EXPR expression_list_arguments error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
+         }
+       | builtin_types OPEN_BRACKET_EXPR error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new ElementAccess ((Expression) $1, null, GetLocation ($2));
+         }       
+       ;
+
+expression_list
+       : expression
+         {
+               var list = new List<Expression> (4);
+               list.Add ((Expression) $1);
+               $$ = list;
+         }
+       | expression_list COMMA expression
+         {
+               var list = (List<Expression>) $1;
+               list.Add ((Expression) $3);
+               $$ = list;
+         }
+       | expression_list error {
+               Error_SyntaxError (yyToken);
+               $$ = $1;
+         }
+       ;
+       
+expression_list_arguments
+       : expression_list_argument
+         {
+               Arguments args = new Arguments (4);
+               args.Add ((Argument) $1);
+               $$ = args;
+         }
+       | expression_list_arguments COMMA expression_list_argument
+         {
+               Arguments args = (Arguments) $1;
+               if (args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
+                       Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
+         
+               args.Add ((Argument) $3);
+               $$ = args;        
+         }
+       ;
+       
+expression_list_argument
+       : expression
+         {
+               $$ = new Argument ((Expression) $1);
+         }
+       | named_argument
+       ;
+
+this_access
+       : THIS
+         {
+               $$ = new This (GetLocation ($1));
+         }
+       ;
+
+base_access
+       : SUPER OPEN_BRACKET_EXPR expression_list_arguments CLOSE_BRACKET
+         {
+               $$ = new ElementAccess (new BaseThis (GetLocation ($1)), (Arguments) $3, GetLocation ($2));
+               lbag.AddLocation ($$, GetLocation ($4));
+         }
+       | SUPER OPEN_BRACKET error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new ElementAccess (null, null, GetLocation ($2));
+         }
+       ;
+
+post_increment_expression
+       : primary_expression OP_INC
+         {
+               $$ = new UnaryMutator (UnaryMutator.Mode.PostIncrement, (Expression) $1, GetLocation ($2));
+         }
+       ;
+
+post_decrement_expression
+       : primary_expression OP_DEC
+         {
+               $$ = new UnaryMutator (UnaryMutator.Mode.PostDecrement, (Expression) $1, GetLocation ($2));
+         }
+       ;
+
+new_expression
+       : NEW type_expression opt_new_args
+         {
+               $$ = new New ((Expression) $2, (Arguments) $3, GetLocation ($1));
+//             lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
+         }
+       | NEW OP_LT type_expression OP_GT array_initializer
+         {
+               $$ = new NewVector ((FullNamedExpression) $3, (ArrayInitializer) $5, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }
+       ;
+
+opt_new_args
+       : /* empty */
+        {
+               $$ = null;
+        }
+       | OPEN_PARENS opt_argument_list CLOSE_PARENS
+         {
+               $$ = $2;
+         }
+       ;
+
+//anonymous_type_expression
+//     : NEW OPEN_BRACE anonymous_type_parameters_opt_comma CLOSE_BRACE
+//       {
+//             if (lang_version <= LanguageVersion.ISO_2)
+//                     FeatureIsNotAvailable (GetLocation ($1), "anonymous types");
+//
+//             $$ = new NewAnonymousType ((List<AnonymousTypeParameter>) $3, current_container, GetLocation ($1));
+//             
+//             // TODO: lbag comma location
+//             lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+//       }
+//     ;
+
+//anonymous_type_parameters_opt_comma
+//     : anonymous_type_parameters_opt
+//     | anonymous_type_parameters COMMA
+//     ;
+
+//anonymous_type_parameters_opt
+//     : { $$ = null; }
+//     | anonymous_type_parameters
+//     ;
+
+//anonymous_type_parameters
+//     : anonymous_type_parameter
+//       {
+//             var a = new List<AnonymousTypeParameter> (4);
+//             a.Add ((AnonymousTypeParameter) $1);
+//             $$ = a;
+//       }
+//     | anonymous_type_parameters COMMA anonymous_type_parameter
+//       {
+//             var a = (List<AnonymousTypeParameter>) $1;
+//             a.Add ((AnonymousTypeParameter) $3);
+//             $$ = a;
+//       }
+//     ;
+
+//anonymous_type_parameter
+//     : IDENTIFIER ASSIGN variable_initializer
+//       {
+//             var lt = (LocatedToken)$1;
+//             $$ = new AnonymousTypeParameter ((Expression)$3, lt.Value, lt.Location);
+//             lbag.AddLocation ($$, GetLocation ($2));
+//       }
+//     | IDENTIFIER
+//       {
+//             var lt = (LocatedToken)$1;
+//             $$ = new AnonymousTypeParameter (new SimpleName (lt.Value, lt.Location),
+//                     lt.Value, lt.Location);
+//       }
+//     | member_access
+//       {
+//             MemberAccess ma = (MemberAccess) $1;
+//             $$ = new AnonymousTypeParameter (ma, ma.Name, ma.Location);
+//       }
+//     | error
+//       {
+//             report.Error (746, lexer.Location,
+//                     "Invalid anonymous type member declarator. Anonymous type members must be a member assignment, simple name or member access expression");
+//             $$ = null;
+//       }
+//     ;
+
+//opt_rank_specifier
+//     : /* empty */
+//     | rank_specifiers
+//     ;
+
+rank_specifiers
+       : rank_specifier
+       | rank_specifier rank_specifiers
+         {
+               ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
+               $$ = $1;
+         }
+       ;
+
+rank_specifier
+       : OPEN_BRACKET CLOSE_BRACKET
+         {
+               $$ = ComposedTypeSpecifier.CreateArrayDimension (1, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | OPEN_BRACKET dim_separators CLOSE_BRACKET
+         {
+               $$ = ComposedTypeSpecifier.CreateArrayDimension ((int)$2, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($3));
+         }
+       ;
+
+dim_separators
+       : COMMA
+         {
+               $$ = 2;
+         }
+       | dim_separators COMMA
+         {
+               $$ = ((int) $1) + 1;
+         }
+       ;
+
+array_creation
+       : array_initializer
+         {
+               $$ = new ArrayCreation ((ArrayInitializer) $1);
+         }
+       ;
+
+array_initializer
+       : init_open_bracket init_close_bracket
+         {
+               $$ = new ArrayInitializer (null, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | init_open_bracket_expr variable_initializer_list opt_comma init_close_bracket
+         {
+               $$ = new ArrayInitializer ((List<Expression>) $2, GetLocation ($1));
+               if ($3 != null) {
+                       lbag.AddLocation ($$, GetLocation ($3), GetLocation ($4));
+               } else {
+                       lbag.AddLocation ($$, GetLocation ($4));
+               }
+         }
+       ;
+       
+init_open_bracket
+       : OPEN_BRACKET
+         {
+       oob_stack.Push (Lexer.AutoSemiInsertion);
+        Lexer.AutoSemiInsertion = false;
+         }
+       ;
+
+init_open_bracket_expr
+       : OPEN_BRACKET_EXPR
+         {
+       oob_stack.Push (Lexer.AutoSemiInsertion);
+        Lexer.AutoSemiInsertion = false;
+         }
+       ;
+
+init_close_bracket
+       : CLOSE_BRACKET
+         {
+       Lexer.AutoSemiInsertion = (bool) oob_stack.Pop ();
+         }
+       ;       
+       
+variable_initializer_list
+       : variable_initializer
+         {
+               var list = new List<Expression> (4);
+               list.Add ((Expression) $1);
+               $$ = list;
+         }
+       | variable_initializer_list COMMA variable_initializer
+         {
+               var list = (List<Expression>) $1;
+               list.Add ((Expression) $3);
+               $$ = list;
+         }
+       ;
+       
+typeof_type_expression
+       : type_and_void
+//     | unbound_type_name
+       | error
+        {
+               Error_TypeExpected (lexer.Location);
+               $$ = null;
+        }
+       ;
+/*     
+unbound_type_name
+       : identifier_inside_body generic_dimension
+         {  
+               var lt = (LocatedToken) $1;
+
+               $$ = new SimpleName (lt.Value, (int) $2, lt.Location);
+         }
+//     | qualified_alias_member identifier_inside_body generic_dimension
+//       {
+//             var lt1 = (LocatedToken) $1;
+//             var lt2 = (LocatedToken) $2;
+//
+//             $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, (int) $3, lt1.Location);
+//             lbag.AddLocation ($$, GetLocation ($2));
+//       }
+       | unbound_type_name DOT identifier_inside_body
+         {
+               var lt = (LocatedToken) $3;
+               
+               $$ = new MemberAccess ((Expression) $1, lt.Value, lt.Location);         
+         }
+       | unbound_type_name DOT identifier_inside_body generic_dimension
+         {
+               var lt = (LocatedToken) $3;
+               
+               $$ = new MemberAccess ((Expression) $1, lt.Value, (int) $4, lt.Location);               
+         }
+       | namespace_or_type_expr DOT identifier_inside_body generic_dimension
+         {
+               var tne = (ATypeNameExpression) $1;
+               if (tne.HasTypeArguments)
+                       Error_TypeExpected (GetLocation ($4));
+
+               var lt = (LocatedToken) $3;
+               $$ = new MemberAccess (tne, lt.Value, (int) $4, lt.Location);           
+         }
+       ;
+
+generic_dimension
+       : GENERIC_DIMENSION
+         {
+               if (lang_version < LanguageVersion.ISO_2)
+                       FeatureIsNotAvailable (GetLocation ($1), "generics");
+
+               $$ = $1;
+         }
+       ;
+*/
+
+qualified_identifier
+       : IDENTIFIER DOUBLE_COLON
+         {
+               $$ = $1;
+         }
+       ;
+
+sizeof_expression
+       : SIZEOF open_parens_any type CLOSE_PARENS
+         { 
+               CheckIsPlayScript("sizeof", GetLocation($1));     
+               $$ = new SizeOf ((Expression) $3, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | SIZEOF open_parens_any type error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new SizeOf ((Expression) $3, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;       
+
+checked_expression
+       : CHECKED open_parens_any expression CLOSE_PARENS
+         {
+               CheckIsPlayScript("checked", GetLocation($1));    
+               $$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | CHECKED error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new CheckedExpr (null, GetLocation ($1));
+         }
+       ;
+
+unchecked_expression
+       : UNCHECKED open_parens_any expression CLOSE_PARENS
+         {
+               CheckIsPlayScript("unchecked", GetLocation($1));          
+               $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | UNCHECKED error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new UnCheckedExpr (null, GetLocation ($1));
+         }
+       ;
+
+//pointer_member_access
+//     : primary_expression OP_PTR IDENTIFIER opt_type_argument_list
+//       {
+//             var lt = (LocatedToken) $3;
+//             $$ = new MemberAccess (new Indirection ((Expression) $1, GetLocation ($2)), lt.Value, (TypeArguments) $4, lt.Location);
+//       }
+//     ;
+
+anonymous_method_expression
+       : FUNCTION OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
+         }
+         opt_formal_parameter_list CLOSE_PARENS COLON member_type
+         {
+               valid_param_mod = 0;
+               start_anonymous (false, (ParametersCompiled) $4, (TypeExpr) $7, false, GetLocation ($1));
+         }
+         block
+         {
+               $$ = end_anonymous ((ParametersBlock) $9);
+         }
+       | ASYNC FUNCTION OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
+         }
+         opt_formal_parameter_list CLOSE_PARENS COLON member_type
+         {
+               valid_param_mod = 0;
+               start_anonymous (false, (ParametersCompiled) $5, (FullNamedExpression) $8, true, GetLocation ($1));
+         }
+         block
+         {
+               $$ = end_anonymous ((ParametersBlock) $10);
+         }
+       ;
+       
+local_function_statement
+       : FUNCTION IDENTIFIER OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
+         }
+         opt_formal_parameter_list CLOSE_PARENS COLON member_type
+         {
+               valid_param_mod = 0;
+               start_anonymous (false, (ParametersCompiled) $5, (FullNamedExpression) $8, false, GetLocation ($1));
+         }
+         block
+         {
+               var lt = (LocatedToken) $2;
+               var anonMethod = end_anonymous ((ParametersBlock) $10);
+               var li = new LocalVariable (current_block.ParametersBlock.TopBlock, lt.Value, lt.Location);
+
+/* TODO
+               var type = Delegate.CreateDelegateTypeExpression(compiler.BuiltinTypes, anonMethod.AsParameters, anonMethod.AsReturnType, GetLocation($1));
+               var decl = new BlockVariable(type, li);
+               decl.Initializer = anonMethod;
+               current_block.AddLocalName (li);
+               current_block.ParametersBlock.TopBlock.AddScopeStatement (decl);        
+               $$ = new AsLocalFunction(GetLocation($1), lt.Value, anonMethod, decl);
+*/
+         }
+       | ASYNC FUNCTION IDENTIFIER OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
+         }
+         opt_formal_parameter_list CLOSE_PARENS COLON member_type
+         {
+               valid_param_mod = 0;
+               start_anonymous (false, (ParametersCompiled) $6, (FullNamedExpression) $9, true, GetLocation ($1));
+         }
+         block
+         {
+           var lt = (LocatedToken) $3;
+               var anonMethod = end_anonymous ((ParametersBlock) $11);
+               var li = new LocalVariable (current_block.ParametersBlock.TopBlock, lt.Value, lt.Location);
+/* TODO
+               var type = Delegate.CreateDelegateTypeExpression(compiler.BuiltinTypes, anonMethod.AsParameters, anonMethod.AsReturnType, GetLocation($1));
+               var decl = new BlockVariable(type, li);
+               decl.Initializer = anonMethod;
+               current_block.AddLocalName (li);
+               current_block.ParametersBlock.TopBlock.AddScopeStatement (decl);        
+               $$ = new AsLocalFunction(GetLocation($1), lt.Value, anonMethod, decl);
+*/
+         }
+       ;       
+
+//anonymous_method_signature
+//     : OPEN_PARENS
+//       {
+//             valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
+//       }
+//       opt_formal_parameter_list CLOSE_PARENS opt_method_return_type
+//       {
+//             valid_param_mod = 0;
+//             $$ = $3;
+//       }
+//     ;
+
+default_value_expression
+       : DEFAULT open_parens_any type CLOSE_PARENS
+         {
+               CheckIsPlayScript("default values", GetLocation($1));
+         
+               if (lang_version < LanguageVersion.ISO_2)
+                       FeatureIsNotAvailable (GetLocation ($1), "default value expression");
+
+               $$ = new DefaultValueExpression ((Expression) $3, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
+         }
+       ;
+
+unary_expression
+       : primary_expression
+       | BANG prefixed_unary_expression
+         {
+               $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, GetLocation ($1));
+         }
+       | TILDE prefixed_unary_expression
+         {
+               $$ = new Unary (Unary.Operator.OnesComplement, (Expression) $2, GetLocation ($1));
+         }
+//     | OPEN_PARENS_CAST type CLOSE_PARENS prefixed_unary_expression
+//       {
+//             $$ = new Cast ((FullNamedExpression) $2, (Expression) $4, GetLocation ($1));
+//             lbag.AddLocation ($$, GetLocation ($3));
+//       }
+       | AWAIT prefixed_unary_expression
+         {
+               CheckIsPlayScript("await", GetLocation($1));
+               
+               if (!async_block) {
+                        if (current_anonymous_method is LambdaExpression) {
+                               report.Error (4034, GetLocation ($1),
+                                       "The `await' operator can only be used when its containing lambda expression is marked with the `async' modifier");
+                       } else if (current_anonymous_method is AnonymousMethodExpression) {
+                               report.Error (4035, GetLocation ($1),
+                                       "The `await' operator can only be used when its containing anonymous method is marked with the `async' modifier");
+                       } else {
+                               report.Error (4033, GetLocation ($1),
+                                       "The `await' operator can only be used when its containing method is marked with the `async' modifier");
+                       }
+               } else {
+                       current_block.Explicit.RegisterAsyncAwait ();
+               }
+               
+               $$ = new Await ((Expression) $2, GetLocation ($1));
+         }
+       | OP_AT prefixed_unary_expression
+         {
+// TODO:               $$ = new Unary (Unary.Operator.AsE4xAttribute, (Expression) $2, GetLocation ($1));
+         }
+       | TYPEOF prefixed_unary_expression
+         {
+               $$ = new TypeOf ((Expression) $2, GetLocation ($1));
+         }
+       | DELETE prefixed_unary_expression
+         {
+               $$ = new Delete ((Expression) $2, GetLocation ($1));
+         } 
+       | BANG error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Unary (Unary.Operator.LogicalNot, null, GetLocation ($1));
+         }
+       | TILDE error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Unary (Unary.Operator.OnesComplement, null, GetLocation ($1));
+         }
+//     | OPEN_PARENS_CAST type CLOSE_PARENS error
+//       {
+//             Error_SyntaxError (yyToken);
+//
+//             $$ = new Cast ((FullNamedExpression) $2, null, GetLocation ($1));
+//             lbag.AddLocation ($$, GetLocation ($3));
+//       }
+       | AWAIT error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Await (null, GetLocation ($1));
+         }
+//     | OP_AT error
+//       {
+//             Error_SyntaxError (yyToken);
+
+//             $$ = new Unary (Unary.Operator.AsE4xAttribute, null, GetLocation ($1));
+//       }    
+       | DELETE error
+         {
+               Error_SyntaxError (yyToken);
+               
+               $$ = new Delete (null, GetLocation ($1));
+         }       
+       ;
+
+       //
+       // The idea to split this out is from Rhys' grammar
+       // to solve the problem with casts.
+       //
+prefixed_unary_expression
+       : unary_expression
+       | PLUS prefixed_unary_expression
+         { 
+               $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, GetLocation ($1));
+         } 
+       | MINUS prefixed_unary_expression 
+         { 
+               $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1));
+         }
+       | OP_INC prefixed_unary_expression 
+         {
+               $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, (Expression) $2, GetLocation ($1));
+         }
+       | OP_DEC prefixed_unary_expression 
+         {
+               $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, (Expression) $2, GetLocation ($1));
+         }
+//     | STAR prefixed_unary_expression
+//       {
+//             $$ = new Indirection ((Expression) $2, GetLocation ($1));
+//       }
+       | BITWISE_AND prefixed_unary_expression
+         {
+               $$ = new Unary (Unary.Operator.AddressOf, (Expression) $2, GetLocation ($1));
+         }
+       | PLUS error
+         { 
+               Error_SyntaxError (yyToken);
+
+               $$ = new Unary (Unary.Operator.UnaryPlus, null, GetLocation ($1));
+         } 
+       | MINUS error 
+         { 
+               Error_SyntaxError (yyToken);
+
+               $$ = new Unary (Unary.Operator.UnaryNegation, null, GetLocation ($1));
+         }
+       | OP_INC error 
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new UnaryMutator (UnaryMutator.Mode.PreIncrement, null, GetLocation ($1));
+         }
+       | OP_DEC error 
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new UnaryMutator (UnaryMutator.Mode.PreDecrement, null, GetLocation ($1));
+         }
+//     | STAR error
+//       {
+//             Error_SyntaxError (yyToken);
+//
+//             $$ = new Indirection (null, GetLocation ($1));
+//       }
+       | BITWISE_AND error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Unary (Unary.Operator.AddressOf, null, GetLocation ($1));
+         }
+       ;
+
+multiplicative_expression
+       : prefixed_unary_expression
+       | multiplicative_expression STAR prefixed_unary_expression
+         {
+               $$ = new Binary (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | multiplicative_expression DIV prefixed_unary_expression
+         {
+               $$ = new Binary (Binary.Operator.Division, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | multiplicative_expression PERCENT prefixed_unary_expression 
+         {
+               $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | multiplicative_expression STAR error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.Multiply, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | multiplicative_expression DIV error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.Division, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | multiplicative_expression PERCENT error 
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+additive_expression
+       : multiplicative_expression
+       | additive_expression PLUS multiplicative_expression 
+         {
+               $$ = new Binary (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | additive_expression MINUS multiplicative_expression
+         {
+               $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | additive_expression OP_IN multiplicative_expression
+         {
+               $$ = new In ((Expression) $1, (Expression) $3, GetLocation ($2));
+         }       
+       | additive_expression AS type
+         {
+               $$ = new As ((Expression) $1, (Expression) $3, GetLocation ($2));
+         }
+       | additive_expression IS type
+         {
+               $$ = new Is ((Expression) $1, (Expression) $3, GetLocation ($2));
+         }       
+       | additive_expression PLUS error 
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.Addition, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | additive_expression MINUS error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | additive_expression OP_IN error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new In ((Expression) $1, null, GetLocation ($2));
+         }
+       | additive_expression AS error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new As ((Expression) $1, null, GetLocation ($2));
+         }
+       | additive_expression IS error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Is ((Expression) $1, null, GetLocation ($2));
+         }
+       ;
+
+shift_expression
+       : additive_expression
+       | shift_expression OP_SHIFT_LEFT additive_expression
+         {
+               $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | shift_expression OP_SHIFT_RIGHT additive_expression
+         {
+               $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | shift_expression OP_USHIFT_RIGHT additive_expression
+         {
+               $$ = new Binary (Binary.Operator.UnsignedRightShift, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | shift_expression OP_SHIFT_LEFT error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | shift_expression OP_SHIFT_RIGHT error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | shift_expression OP_USHIFT_RIGHT error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.UnsignedRightShift, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }       
+       ; 
+
+relational_expression
+       : shift_expression
+       | relational_expression OP_LT shift_expression
+         {
+               $$ = new Binary (Binary.Operator.LessThan, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | relational_expression OP_GT shift_expression
+         {
+               $$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | relational_expression OP_LE shift_expression
+         {
+               $$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | relational_expression OP_GE shift_expression
+         {
+               $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | relational_expression OP_LT error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.LessThan, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | relational_expression OP_GT error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | relational_expression OP_LE error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | relational_expression OP_GE error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+equality_expression
+       : relational_expression
+       | equality_expression OP_EQ relational_expression
+         {
+               $$ = new Binary (Binary.Operator.Equality, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | equality_expression OP_NE relational_expression
+         {
+               $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | equality_expression OP_REF_EQ relational_expression
+         {
+               $$ = new Binary (Binary.Operator.ReferenceEquality, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | equality_expression OP_REF_NE relational_expression
+         {
+               $$ = new Binary (Binary.Operator.ReferenceInequality, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ; 
+
+and_expression
+       : equality_expression
+       | and_expression BITWISE_AND equality_expression
+         {
+               $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | and_expression BITWISE_AND error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+exclusive_or_expression
+       : and_expression
+       | exclusive_or_expression CARRET and_expression
+         {
+               $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | exclusive_or_expression CARRET error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+inclusive_or_expression
+       : exclusive_or_expression
+       | inclusive_or_expression BITWISE_OR exclusive_or_expression
+         {
+               $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | inclusive_or_expression BITWISE_OR error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+conditional_and_expression
+       : inclusive_or_expression
+       | conditional_and_expression OP_AND inclusive_or_expression
+         {
+               $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | conditional_and_expression OP_AND error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+conditional_or_expression
+       : conditional_and_expression
+       | conditional_or_expression OP_OR conditional_and_expression
+         {
+               $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | conditional_or_expression OP_OR error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, null);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+       
+null_coalescing_expression
+       : conditional_or_expression
+       | conditional_or_expression OP_COALESCING null_coalescing_expression
+         {
+               CheckIsPlayScript("?? operator", GetLocation($2));
+         
+               if (lang_version < LanguageVersion.ISO_2)
+                       FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
+                       
+               $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+conditional_expression
+       : null_coalescing_expression
+       | null_coalescing_expression INTERR expression COLON expression
+         {
+               $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2));
+               lbag.AddLocation ($$, GetLocation ($4));
+         }
+       | null_coalescing_expression INTERR expression error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
+         }
+       | null_coalescing_expression INTERR expression COLON error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
+               lbag.AddLocation ($$, GetLocation ($4));
+         }
+       ;
+
+assignment_expression
+       : prefixed_unary_expression ASSIGN expression
+         {
+               Expression target = (Expression) $1;
+               Expression source = (Expression) $3;
+
+               $$ = new SimpleAssign (target, source);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_MULT_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_DIV_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.Division, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_MOD_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_ADD_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_SUB_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_USHIFT_RIGHT_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.UnsignedRightShift, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_AND_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression LOGICAL_AND_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.LogicalAnd, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_OR_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression LOGICAL_OR_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.LogicalOr, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | prefixed_unary_expression OP_XOR_ASSIGN expression
+         {
+               $$ = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+lambda_parameter_list
+       : lambda_parameter
+         {
+               var pars = new List<Parameter> (4);
+               pars.Add ((Parameter) $1);
+
+               $$ = pars;
+         }
+       | lambda_parameter_list COMMA lambda_parameter
+         {
+               var pars = (List<Parameter>) $1;
+               Parameter p = (Parameter)$3;
+               if (pars[0].GetType () != p.GetType ()) {
+                       report.Error (748, p.Location, "All lambda parameters must be typed either explicitly or implicitly");
+               }
+               
+               pars.Add (p);
+               $$ = pars;
+         }
+       ;
+
+lambda_parameter
+       : parameter_modifier parameter_type identifier_inside_body
+         {
+               var lt = (LocatedToken) $3;
+
+               $$ = new Parameter ((FullNamedExpression) $2, lt.Value, (Parameter.Modifier) $1, null, lt.Location);
+         }
+       | parameter_type identifier_inside_body
+         {
+               var lt = (LocatedToken) $2;
+
+               $$ = new Parameter ((FullNamedExpression) $1, lt.Value, Parameter.Modifier.NONE, null, lt.Location);
+         }
+       | IDENTIFIER
+         {
+               var lt = (LocatedToken) $1;
+               $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
+         }
+       | AWAIT
+         {
+               var lt = (LocatedToken) Error_AwaitAsIdentifier ($1);
+               $$ = new ImplicitLambdaParameter (lt.Value, lt.Location);
+         }
+       ;
+
+opt_lambda_parameter_list
+       : /* empty */                   { $$ = ParametersCompiled.EmptyReadOnlyParameters; }
+       | lambda_parameter_list         { 
+               var pars_list = (List<Parameter>) $1;
+               $$ = new ParametersCompiled (pars_list.ToArray ());
+         }
+       ;
+
+lambda_expression_body
+       : {
+               start_block (Location.Null);
+         }
+         expression    // All expressions must handle error or current block won't be restored and breaking ast completely
+         {
+               Block b = end_block (Location.Null);
+               b.IsCompilerGenerated = true;
+               b.AddStatement (new ContextualReturn ((Expression) $2));
+               $$ = b;
+         } 
+       | block
+       | error
+         {
+               // Handles only cases like foo = x.FirstOrDefault (l => );
+               // where we must restore current_variable
+               Block b = end_block (Location.Null);
+               b.IsCompilerGenerated = true;
+
+               Error_SyntaxError (yyToken);
+               $$ = null;
+         }
+       ;
+
+expression_or_error
+       : expression
+       | error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = null;
+         }
+       ;
+       
+lambda_expression
+       : IDENTIFIER ARROW 
+         {
+               var lt = (LocatedToken) $1;     
+               Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
+               start_anonymous (true, new ParametersCompiled (p), null, false, lt.Location);
+         }
+         lambda_expression_body
+         {
+               CheckIsPlayScript("lambda", GetLocation($1));     
+               $$ = end_anonymous ((ParametersBlock) $4);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | AWAIT ARROW
+         {
+               var lt = (LocatedToken) Error_AwaitAsIdentifier ($1);
+               Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
+               start_anonymous (true, new ParametersCompiled (p), null, false, lt.Location);
+         }
+         lambda_expression_body
+         {
+               CheckIsPlayScript("lambda", GetLocation($1));     
+               $$ = end_anonymous ((ParametersBlock) $4);
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | ASYNC identifier_inside_body ARROW
+         {
+               var lt = (LocatedToken) $2;
+               Parameter p = new ImplicitLambdaParameter (lt.Value, lt.Location);
+               start_anonymous (true, new ParametersCompiled (p), null, true, lt.Location);
+         }
+         lambda_expression_body
+         {
+               CheckIsPlayScript("lambda", GetLocation($1));     
+               $$ = end_anonymous ((ParametersBlock) $5);
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
+         }
+       | OPEN_PARENS_LAMBDA
+         {
+               valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
+         }
+         opt_lambda_parameter_list CLOSE_PARENS ARROW 
+         {
+               valid_param_mod = 0;
+               start_anonymous (true, (ParametersCompiled) $3, null, false, GetLocation ($1));
+         }
+         lambda_expression_body
+         {
+               CheckIsPlayScript("lambda", GetLocation($1));     
+               $$ = end_anonymous ((ParametersBlock) $7);
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($4), GetLocation ($5));
+         }
+       | ASYNC OPEN_PARENS_LAMBDA
+         {
+               valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;          
+         }
+         opt_lambda_parameter_list CLOSE_PARENS ARROW 
+         {
+               valid_param_mod = 0;
+               start_anonymous (true, (ParametersCompiled) $4, null, true, GetLocation ($1));
+         }
+         lambda_expression_body
+         {
+               CheckIsPlayScript("lambda", GetLocation($1));     
+               $$ = end_anonymous ((ParametersBlock) $8);
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($2), GetLocation ($5), GetLocation ($6));
+         }
+       ;
+
+expression
+       : assignment_expression 
+       | non_assignment_expression
+       ;
+       
+non_assignment_expression
+       : conditional_expression
+       | lambda_expression
+       | query_expression
+       ;
+
+constant_expression
+       : expression
+       ;
+
+boolean_expression
+       : expression
+         {
+               $$ = new BooleanExpression ((Expression) $1);
+         }
+       ;
+
+//
+// 10 classes
+//
+class_declaration
+       : opt_attributes
+         opt_modifiers
+         opt_partial
+         CLASS
+         {
+               lexer.ConstraintsParsing = true;
+               lexer.AutoSemiInsertion = false;
+         }
+         type_declaration_name
+         {
+               Class c = new Class (current_container, (MemberName) $6, (Modifiers) $2, (Attributes) $1, true);
+
+               if (((c.ModFlags & Modifiers.STATIC) != 0) && lang_version == LanguageVersion.ISO_1) {
+                       FeatureIsNotAvailable (c.Location, "static classes");
+               }
+                       
+           bool is_partial = IsPartial($1) || $3 != null;
+               push_current_container (c, is_partial);
+         }
+         opt_class_extends
+         opt_class_implements
+         opt_type_parameter_constraints_clauses
+         {
+               lexer.ConstraintsParsing = false;
+
+               if ($10 != null)
+                       current_container.SetConstraints ((List<Constraints>) $10);
+               lbag.AddMember (current_container, mod_locations, GetLocation ($4));
+
+               if (doc_support) {
+                       current_container.PartialContainer.DocComment = Lexer.consume_doc_comment ();
+                       Lexer.doc_state = XmlCommentState.Allowed;
+               }
+               
+               lexer.parsing_modifiers = true;
+               lexer.DynamicParsing = false;
+         }
+         OPEN_BRACE
+         {
+               lexer.AutoSemiInsertion = true;         
+         }
+         opt_class_member_declarations CLOSE_BRACE
+         {
+               lexer.DynamicParsing = true;      
+               --lexer.parsing_declaration;
+               if (doc_support)
+                       Lexer.doc_state = XmlCommentState.Allowed;
+         }
+         opt_semicolon 
+         {
+               lbag.AppendToMember (current_container, GetLocation ($12), GetLocation ($15), GetLocation ($17));
+               $$ = pop_current_class ();
+         }
+       ;       
+
+opt_partial
+       : /* empty */
+         { $$ = null; }
+       | PARTIAL
+         { $$ = $1; } // location
+       ;
+
+opt_modifiers
+       : /* empty */
+         {
+           mod_locations = null;
+               $$ = ModifierNone;
+               lexer.parsing_modifiers = false;
+         }
+       | modifiers
+         {
+               lexer.parsing_modifiers = false;                
+         }
+       ;
+
+modifiers
+       : modifier
+         {
+               $$ = $1 ?? ModifierNone;
+         }
+       | modifiers modifier
+         {
+               if ($2 == null) {
+                       var m1 = (Modifiers) $1;
+
+                       if ((m1 & Modifiers.AccessibilityMask) != 0) {
+                               report.ErrorPlayScript (1003, GetLocation ($2),
+                                       "Access specifiers are not allowed with namespace attributes.");
+                       }
+               } else {
+                       var m1 = (Modifiers) $1;
+                       var m2 = (Modifiers) $2;
+
+                       if ((m1 & m2) != 0) {
+                               report.ErrorPlayScript (1127, lexer.Location - ModifiersExtensions.Name (m2).Length,
+                                       "Attribute `{0}' was specified multiple times.", ModifiersExtensions.Name (m2));
+                       } else if ((m2 & Modifiers.AccessibilityMask) != 0 && (m1 & Modifiers.AccessibilityMask) != 0 &&
+                               ((m2 | m1 & Modifiers.AccessibilityMask) != (Modifiers.PROTECTED | Modifiers.INTERNAL))) {
+                               report.ErrorPlayScript (1154, lexer.Location - ModifiersExtensions.Name (m2).Length,
+                                       "Only one of public, private, protected, or internal can be specified on a definition.");
+                       }
+                       
+                       $$ = m1 | m2;
+               }
+         }
+       ;
+
+modifier
+/*     : NEW
+         {
+               $$ = Modifiers.NEW;
+               StoreModifierLocation ($$, GetLocation ($1));
+               
+               if (current_container.Kind == MemberKind.Namespace)
+                       report.Error (1530, GetLocation ($1), "Keyword `new' is not allowed on namespace elements");
+         }
+*/
+       : PUBLIC
+         {
+               $$ = Modifiers.PUBLIC;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | PROTECTED
+         {
+               $$ = Modifiers.PROTECTED;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | INTERNAL
+         {
+               $$ = Modifiers.INTERNAL;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | PRIVATE
+         {
+               $$ = Modifiers.PRIVATE;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | ABSTRACT
+         {
+               $$ = Modifiers.ABSTRACT;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | FINAL
+         {
+               $$ = (Modifiers)0; // Modifiers.SEALED;  // The semantics for SEALED and FINAL don't quite match.  Ignore FINAL for right now. (BEN)
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | STATIC
+         {
+               $$ = Modifiers.STATIC;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+//     | READONLY
+//       {
+//             $$ = Modifiers.READONLY;
+//             StoreModifierLocation ($$, GetLocation ($1));
+//       }
+       | VIRTUAL
+         {
+               $$ = Modifiers.VIRTUAL;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | OVERRIDE
+         {
+               $$ = Modifiers.OVERRIDE;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | NATIVE
+         {
+               $$ = Modifiers.EXTERN;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | VOLATILE
+         {
+               $$ = Modifiers.VOLATILE;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+//     | UNSAFE
+//       {
+//             $$ = Modifiers.UNSAFE;
+//             StoreModifierLocation ($$, GetLocation ($1));
+//             if (!settings.Unsafe)
+//                     Error_UnsafeCodeNotAllowed (GetLocation ($1));
+//       }
+       | ASYNC
+         {
+               $$ = Modifiers.ASYNC;
+               StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | DYNAMIC
+         {
+           $$ = Modifiers.DYNAMIC;
+           StoreModifierLocation ($$, GetLocation ($1));
+         }
+       | IDENTIFIER
+         {
+               if (namespace_modifier != null)
+                       report.ErrorPlayScript (1162, GetLocation ($1), "Only one namespace attribute can be used per definition");
+               else
+                       namespace_modifier = (LocatedToken) $1;
+
+               $$ = null;
+         }
+       ;
+       
+opt_class_extends
+       : /* empty */
+       | EXTENDS base_type_name
+        {
+               current_type.AddBaseType ((FullNamedExpression) $2);
+        }
+       | EXTENDS base_type_name error
+         {
+               Error_SyntaxError (yyToken);
+
+               current_type.AddBaseType ((FullNamedExpression) $2);
+         }
+       ;
+       
+opt_class_implements
+       : /* empty */
+       | IMPLEMENTS type_list
+        {
+               current_type.AddBaseTypes ((List<FullNamedExpression>) $2);
+        }
+       | IMPLEMENTS type_list error
+         {
+               Error_SyntaxError (yyToken);
+
+               current_type.AddBaseTypes ((List<FullNamedExpression>) $2);
+         }
+       ;       
+
+opt_type_parameter_constraints_clauses
+       : /* empty */
+       | type_parameter_constraints_clauses 
+         {
+               $$ = $1;
+         }
+       ;
+
+type_parameter_constraints_clauses
+       : type_parameter_constraints_clause
+         {
+               var constraints = new List<Constraints> (1);
+               constraints.Add ((Constraints) $1);
+               $$ = constraints;
+         }
+       | type_parameter_constraints_clauses type_parameter_constraints_clause
+         {
+               var constraints = (List<Constraints>) $1;
+               Constraints new_constraint = (Constraints)$2;
+
+               foreach (Constraints c in constraints) {
+                       if (new_constraint.TypeParameter.Value == c.TypeParameter.Value) {
+                               report.Error (409, new_constraint.Location,
+                                       "A constraint clause has already been specified for type parameter `{0}'",
+                                       new_constraint.TypeParameter.Value);
+                       }
+               }
+
+               constraints.Add (new_constraint);
+               $$ = constraints;
+         }
+       ; 
+
+type_parameter_constraints_clause
+       : WHERE IDENTIFIER COLON type_parameter_constraints
+         {
+               var lt = (LocatedToken) $2;
+               $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), (List<FullNamedExpression>) $4, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($3));
+         }
+       | WHERE IDENTIFIER error
+         {
+               Error_SyntaxError (yyToken);
+         
+               var lt = (LocatedToken) $2;
+               $$ = new Constraints (new SimpleMemberName (lt.Value, lt.Location), null, GetLocation ($1));
+         }
+       ; 
+
+type_parameter_constraints
+       : type_parameter_constraint
+         {
+               var constraints = new List<FullNamedExpression> (1);
+               constraints.Add ((FullNamedExpression) $1);
+               $$ = constraints;
+         }
+       | type_parameter_constraints COMMA type_parameter_constraint
+         {
+               var constraints = (List<FullNamedExpression>) $1;
+               var prev = constraints [constraints.Count - 1] as SpecialContraintExpr;
+               if (prev != null && (prev.Constraint & SpecialConstraint.Constructor) != 0) {                   
+                       report.Error (401, GetLocation ($2), "The `new()' constraint must be the last constraint specified");
+               }
+               
+               prev = $3 as SpecialContraintExpr;
+               if (prev != null) {
+                       if ((prev.Constraint & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0) {
+                               report.Error (449, prev.Location, "The `class' or `struct' constraint must be the first constraint specified");                 
+                       } else {
+                               prev = constraints [0] as SpecialContraintExpr;
+                               if (prev != null && (prev.Constraint & SpecialConstraint.Struct) != 0) {                        
+                                       report.Error (451, GetLocation ($3), "The `new()' constraint cannot be used with the `struct' constraint");
+                               }
+                       }
+               }
+
+               constraints.Add ((FullNamedExpression) $3);
+               $$ = constraints;
+         }
+       ;
+
+type_parameter_constraint
+       : type
+         {
+               if ($1 is ComposedCast)
+                       report.Error (706, GetLocation ($1), "Invalid constraint type `{0}'", ((ComposedCast)$1).GetSignatureForError ());
+         
+               $$ = $1;
+         }
+       | NEW OPEN_PARENS CLOSE_PARENS
+         {
+               $$ = new SpecialContraintExpr (SpecialConstraint.Constructor, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($2), GetLocation ($3));
+         }
+       | CLASS
+         {
+               $$ = new SpecialContraintExpr (SpecialConstraint.Class, GetLocation ($1));
+         }
+       | STRUCT
+         {
+               $$ = new SpecialContraintExpr (SpecialConstraint.Struct, GetLocation ($1));
+         }
+       ;
+
+opt_type_parameter_variance
+       : /* empty */
+         {
+               $$ = Variance.None;
+         }
+       | type_parameter_variance
+         {
+               if (lang_version <= LanguageVersion.V_3)
+                       FeatureIsNotAvailable (lexer.Location, "generic type variance");
+               
+               $$ = $1;
+         }
+       ;
+
+type_parameter_variance
+       : OUT
+         {
+               $$ = Variance.Covariant;
+         }
+       | IN
+         {
+               $$ = Variance.Contravariant;
+         }
+       ;
+
+//
+// Statements (8.2)
+//
+
+//
+// A block is "contained" on the following places:
+//     method_body
+//     property_declaration as part of the accessor body (get/set)
+//      operator_declaration
+//     constructor_declaration
+//     destructor_declaration
+//     event_declaration as part of add_accessor_declaration or remove_accessor_declaration
+//      
+block
+       : OPEN_BRACE  
+         {
+               ++lexer.parsing_block;
+               lexer.AutoSemiInsertion = true;
+               start_block (GetLocation ($1));
+         } 
+         opt_statement_list block_end
+         {
+               $$ = $4;
+         }
+       ;
+/*     
+//
+// An optional config block is "contained" on the following places:
+//     method_body
+//      
+config_block
+       : opt_block_config OPEN_BRACE  
+         {
+               ++lexer.parsing_block;
+               start_block (GetLocation ($2));
+         } 
+         opt_statement_list block_end
+         {
+           if (is_config_enabled) {
+             // This block should be included
+                 $$ = $5;
+               } else {
+                 // This block should not be included.. create an empty block
+                 start_block (GetLocation ($2));
+                 $$ = end_block (GetLocation ($5));
+               }
+         }
+       ;
+*/
+//opt_block_config
+//     : /* empty */
+//     | IDENTIFIER DOUBLE_COLON IDENTIFIER
+//       {
+//         var lt1 = (LocatedToken) $1;
+//         var lt2 = (LocatedToken) $3;
+//        is_config_enabled = file.IsConditionalDefined (lt1.Value + "_" + lt2.Value);
+//       }
+//     ;
+
+block_end 
+       : CLOSE_BRACE 
+         {
+               Lexer.AutoSemiInsertion = true;
+               --lexer.parsing_block;
+               $$ = end_block (GetLocation ($1));
+         }
+       | COMPLETE_COMPLETION
+         {
+               Lexer.AutoSemiInsertion = true;
+               --lexer.parsing_block;
+               $$ = end_block (lexer.Location);
+         }
+       ;
+
+
+block_prepared
+       : OPEN_BRACE
+         {
+               ++lexer.parsing_block;
+               current_block.StartLocation = GetLocation ($1);
+         }
+         opt_statement_list CLOSE_BRACE 
+         {
+               Lexer.AutoSemiInsertion = true;
+               --lexer.parsing_block;
+               $$ = end_block (GetLocation ($4));
+         }
+       ;
+
+opt_statement_list
+       : /* empty */
+       | statement_list 
+       ;
+
+statement_list
+       : statement
+       | statement_list statement
+       ;
+
+statement
+       : block_variable_declaration
+         {
+               current_block.AddStatement ((Statement) $1);
+         }
+       | valid_declaration_statement
+         {
+               current_block.AddStatement ((Statement) $1);
+         }
+       | labeled_statement
+       | error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = null;
+         }
+       ;
+
+//
+// The interactive_statement and its derivatives are only 
+// used to provide a special version of `expression_statement'
+// that has a side effect of assigning the expression to
+// $retval
+//
+interactive_statement_list
+       : interactive_statement
+       | interactive_statement_list interactive_statement
+       ;
+
+interactive_statement
+       : block_variable_declaration
+         {
+               current_block.AddStatement ((Statement) $1);
+         }
+       | interactive_valid_declaration_statement
+         {
+               current_block.AddStatement ((Statement) $1);
+         }
+       | labeled_statement
+       ;
+
+valid_declaration_statement
+       : block
+       | empty_statement
+       | expression_statement
+       | selection_statement
+       | iteration_statement
+       | jump_statement                  
+       | try_statement
+       | checked_statement
+       | unchecked_statement
+       | lock_statement
+       | using_statement
+       | unsafe_statement
+       | fixed_statement
+       | local_function_statement
+       ;
+
+interactive_valid_declaration_statement
+       : block
+       | empty_statement
+    | interactive_expression_statement
+       | selection_statement
+       | iteration_statement
+       | jump_statement                  
+       | try_statement
+       | checked_statement
+       | unchecked_statement
+       | lock_statement
+       | using_statement
+       | unsafe_statement
+       | fixed_statement
+       | local_function_statement
+       ;
+
+embedded_statement
+       : valid_declaration_statement
+       | block_variable_declaration
+         {
+                 if (parsing_playscript) {
+                         report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
+                         $$ = null;
+                 } else {
+                         // NOTE: This is actually allowed in PlayScript.  We'll turn it off in ASX though as it's error prone.
+                         $$ = $1;
+                 }
+         }
+       | labeled_statement
+         {
+                 report.Error (1023, GetLocation ($1), "An embedded statement may not be a declaration or labeled statement");
+                 $$ = null;
+         }
+       | error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new EmptyStatement (GetLocation ($1));
+         }
+       ;
+
+empty_statement
+       : SEMICOLON
+         {
+           Lexer.AutoSemiInsertion = true;
+               // Uses lexer.Location because semicolon location is not kept in quick mode
+               $$ = new EmptyStatement (lexer.Location);
+         }
+       ;
+
+labeled_statement
+       : identifier_inside_body COLON 
+         {
+               var lt = (LocatedToken) $1;
+               LabeledStatement labeled = new LabeledStatement (lt.Value, current_block, lt.Location);
+               lbag.AddLocation (labeled, GetLocation ($2));
+               current_block.AddLabel (labeled);
+               current_block.AddStatement (labeled);
+         }
+         statement
+       ;
+
+use_namespace_statement
+       : USE NAMESPACE IDENTIFIER stmnt_end_semicolon
+         {
+               var lt = (LocatedToken) $3;
+               $$ = new UseNamespace (lt.Value, GetLocation ($1));             
+         }
+       ;
+
+variable_type
+       : variable_type_simple
+       | variable_type_simple rank_specifiers
+         {
+               if ($1 is VarExpr)
+                       $1 = new SimpleName ("var", ((VarExpr) $1).Location);
+         
+               $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
+         }
+       ;
+
+/* 
+ * The following is from Rhys' grammar:
+ * > Types in local variable declarations must be recognized as 
+ * > expressions to prevent reduce/reduce errors in the grammar.
+ * > The expressions are converted into types during semantic analysis.
+ */
+variable_type_simple
+       : primary_expression_or_type opt_nullable
+         { 
+               // Ok, the above "primary_expression" is there to get rid of
+               // both reduce/reduce and shift/reduces in the grammar, it should
+               // really just be "type_name".  If you use type_name, a reduce/reduce
+               // creeps up.  If you use namespace_or_type_name (which is all we need
+               // really) two shift/reduces appear.
+               // 
+
+               // So the super-trick is that primary_expression
+               // can only be either a SimpleName or a MemberAccess. 
+               // The MemberAccess case arises when you have a fully qualified type-name like :
+               // Foo.Bar.Blah i;
+               // SimpleName is when you have
+               // Blah i;
+               
+               Expression expr = (Expression) $1;
+               if ($2 == null) {
+//                     SimpleName sn = expr as SimpleName;
+//                     if (sn != null)
+//                             $$ = ConvertAsType(sn, $1);
+//                     else
+                               $$ = $1;
+               } else if (expr is ATypeNameExpression) {
+                       $$ = new ComposedCast ((ATypeNameExpression)expr, (ComposedTypeSpecifier) $2);
+               } else {
+                       Error_ExpectingTypeName (expr);
+                       $$ = null;
+               }
+         }
+//     | primary_expression_or_type pointer_stars
+//       {
+//             ATypeNameExpression expr = $1 as ATypeNameExpression;
+//
+//             if (expr != null) {
+//                     $$ = new ComposedCast (expr, (ComposedTypeSpecifier) $2);
+//             } else {
+//                     Error_ExpectingTypeName ((Expression)$1);
+//                     $$ = expr;
+//             }
+//       }
+       | builtin_types opt_nullable
+         {
+               if ($2 == null)
+                       $$ = $1;
+               else
+                       $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
+         }
+//     | builtin_types pointer_stars
+//       {
+//             $$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
+//       }
+//     | VOID pointer_stars
+//       {
+//             $$ = new ComposedCast (new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1)), (ComposedTypeSpecifier) $2);
+//       }       
+       | VOID
+         {
+               Expression.Error_VoidInvalidInTheContext (GetLocation ($1), report);
+               $$ = new TypeExpression (compiler.BuiltinTypes.Void, GetLocation ($1));
+         }
+       ;
+       
+//pointer_stars
+//     : pointer_star
+//     | pointer_star pointer_stars
+//       {
+//             ((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
+//             $$ = $1;
+//       }       
+//     ;
+
+//pointer_star
+//     : STAR
+//       {
+//             $$ = ComposedTypeSpecifier.CreatePointer (GetLocation ($1));
+//       }
+//     ;
+
+identifier_inside_body
+       : IDENTIFIER
+       | AWAIT
+         {
+               if (async_block) {
+                       report.Error (4003, GetLocation ($1), "`await' cannot be used as an identifier within an async method or lambda expression");
+                       $$ = new LocatedToken ("await", GetLocation ($1));
+               }
+         }
+       ;
+
+stmnt_end_semicolon
+       : SEMICOLON
+         {
+               Lexer.AutoSemiInsertion = true;
+         }
+       ;
+
+block_variable_declaration
+       : VAR identifier_inside_body COLON type 
+         {
+               var lt = (LocatedToken) $2;
+               var li = GetOrCreateLocalVariable (current_block, lt.Value, 0, (FullNamedExpression) $4, lt.Location);
+               current_variable = new BlockVariable ((FullNamedExpression) $4, li);
+         }
+         opt_local_variable_initializer opt_variable_declarators stmnt_end_semicolon
+         {
+               $$ = current_variable;
+               current_variable = null;
+               lbag.AddLocation ($$, GetLocation ($6));
+         }
+       | VAR identifier_inside_body 
+         {
+               var lt = (LocatedToken) $2;
+               var li = GetOrCreateLocalVariable (current_block, lt.Value, 0, null, lt.Location);
+               current_variable = new BlockVariable (new VarExpr (GetLocation($1)), li);
+         }
+         opt_local_variable_initializer opt_variable_declarators stmnt_end_semicolon
+         {
+               $$ = current_variable;
+               current_variable = null;
+               lbag.AddLocation ($$, GetLocation ($4));
+         }
+       | CONST identifier_inside_body COLON type 
+         {
+               var lt = (LocatedToken) $2;
+               var li = GetOrCreateLocalVariable (current_block, lt.Value, LocalVariable.Flags.Constant, null, lt.Location);
+               current_variable = new BlockConstant ((FullNamedExpression) $4, li);
+         }
+         const_variable_initializer opt_const_declarators stmnt_end_semicolon
+         {
+               $$ = current_variable;
+               current_variable = null;
+               lbag.AddLocation ($$, GetLocation ($1), GetLocation ($7));
+         }
+       ;
+
+opt_local_variable_initializer
+       : /* empty */
+       | ASSIGN block_variable_initializer
+         {
+               current_variable.Initializer = (Expression) $2;
+               // TODO: lbag
+         }
+       | error
+         {
+               if (yyToken == Token.OPEN_BRACKET_EXPR) {
+                       report.Error (650, lexer.Location,
+                               "Syntax error, bad array declarator. To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type");
+               } else {
+                       Error_SyntaxError (yyToken);
+               }
+         }
+       ;
+
+opt_variable_declarators
+       : /* empty */
+       | variable_declarators
+       ;
+       
+opt_using_or_fixed_variable_declarators
+       : /* empty */
+       | variable_declarators
+         {
+               foreach (var d in current_variable.Declarators) {
+                       if (d.Initializer == null)
+                               Error_MissingInitializer (d.Variable.Location);
+               }
+         }
+       ;       
+       
+variable_declarators
+       : variable_declarator
+       | variable_declarators variable_declarator
+       ;
+       
+variable_declarator
+       : COMMA identifier_inside_body
+         {
+               var lt = (LocatedToken) $2;       
+               var li = GetOrCreateLocalVariable (current_variable.Variable.Block, lt.Value, 
+                       /*current_variable.Variable.DeclFlags*/ 0, current_variable.TypeExpression, lt.Location);
+               var d = new BlockVariableDeclarator (li, null);
+               current_variable.AddDeclarator (d);
+               lbag.AddLocation (d, GetLocation ($1));
+         }
+       | COMMA identifier_inside_body ASSIGN block_variable_initializer
+         {
+               var lt = (LocatedToken) $2;       
+               var li = GetOrCreateLocalVariable (current_variable.Variable.Block, lt.Value, 
+                       /*current_variable.Variable.DeclFlags*/ 0, current_variable.TypeExpression, lt.Location);
+               var d = new BlockVariableDeclarator (li, (Expression) $4);
+               current_variable.AddDeclarator (d);
+               lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
+         }
+       | COMMA identifier_inside_body COLON type
+         {
+               var lt = (LocatedToken) $2;       
+               var li = GetOrCreateLocalVariable (current_variable.Variable.Block, lt.Value, 
+                       /*current_variable.Variable.DeclFlags*/ 0, (FullNamedExpression) $4, lt.Location);
+               var d = new BlockVariableDeclarator (li, null, (FullNamedExpression) $4);
+//             d.Location = GetLocation($2);
+               current_variable.AddDeclarator (d);
+               lbag.AddLocation (d, GetLocation ($1));
+         }
+       | COMMA identifier_inside_body COLON type ASSIGN block_variable_initializer
+         {
+               var lt = (LocatedToken) $2;       
+               var li = GetOrCreateLocalVariable (current_variable.Variable.Block, lt.Value, 
+                       /*current_variable.Variable.DeclFlags*/ 0, (FullNamedExpression) $4, lt.Location);
+               var d = new BlockVariableDeclarator (li, (Expression) $6, (FullNamedExpression) $4);
+//             d.Location = GetLocation($2);
+               current_variable.AddDeclarator (d);
+               lbag.AddLocation (d, GetLocation ($1), GetLocation ($5));
+         }               
+       ;
+       
+const_variable_initializer
+       : /* empty */
+         {
+               report.Error (145, lexer.Location, "A const field requires a value to be provided");
+         }
+       | ASSIGN constant_initializer_expr 
+         {
+               current_variable.Initializer = (Expression) $2;
+         }
+       ;
+       
+opt_const_declarators
+       : /* empty */
+       | const_declarators
+       ;
+       
+const_declarators
+       : const_declarator
+       | const_declarators const_declarator
+       ;
+       
+const_declarator
+       : COMMA identifier_inside_body ASSIGN constant_initializer_expr
+         {
+               var lt = (LocatedToken) $2;       
+               var li = GetOrCreateLocalVariable (current_block, lt.Value, 
+                       LocalVariable.Flags.Constant, current_variable.TypeExpression, lt.Location);
+               var d = new BlockVariableDeclarator (li, (Expression) $4);
+               current_variable.AddDeclarator (d);
+               lbag.AddLocation (d, GetLocation ($1), GetLocation ($3));
+         }
+       ;
+       
+block_variable_initializer
+       : variable_initializer
+//     | STACKALLOC simple_type OPEN_BRACKET_EXPR expression CLOSE_BRACKET
+//       {
+//             $$ = new StackAlloc ((Expression) $2, (Expression) $4, GetLocation ($1));
+//             lbag.AddLocation ($$, GetLocation ($3), GetLocation ($5));
+//       }
+//     | STACKALLOC simple_type
+//       {
+//             report.Error (1575, GetLocation ($1), "A stackalloc expression requires [] after type");
+//             $$ = new StackAlloc ((Expression) $2, null, GetLocation ($1));          
+//       }
+       ;
+
+expression_statement
+       : statement_expression stmnt_end_semicolon
+         {
+               $$ = $1;
+               lbag.AddStatement ($$, GetLocation ($2));
+         }
+       | statement_expression COMPLETE_COMPLETION { $$ = $1; }
+       | statement_expression CLOSE_BRACE
+         {
+               $$ = $1;
+               report.Error (1002, GetLocation ($2), "; expected");
+               lexer.putback ('}');
+         }
+       ;
+
+interactive_expression_statement
+       : interactive_statement_expression SEMICOLON { $$ = $1; }
+       | interactive_statement_expression COMPLETE_COMPLETION { $$ = $1; }
+       ;
+
+       //
+       // We have to do the wrapping here and not in the case above,
+       // because statement_expression is used for example in for_statement
+       //
+statement_expression
+       : expression
+         {
+               $$ = ConvertExpressionToStatement((Expression)$1);
+         }
+       ;
+
+interactive_statement_expression
+       : expression
+         {
+               Expression expr = (Expression) $1;
+               $$ = new StatementExpression (new OptionalAssign (expr, lexer.Location));
+         }
+       | error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new EmptyStatement (GetLocation ($1));
+         }
+       ;
+       
+selection_statement
+       : if_statement
+       | switch_statement
+       ; 
+
+stmnt_close_parens
+       : CLOSE_PARENS
+         {
+               Lexer.AutoSemiInsertionAfter = 1;
+         }
+       ;
+       
+stmnt_else
+       : ELSE
+         {
+               Lexer.AutoSemiInsertionAfter = 1;
+         }
+       ;       
+
+if_statement
+       : IF open_parens_any boolean_expression stmnt_close_parens 
+         embedded_statement
+         { 
+               if ($5 is EmptyStatement)
+                       Warning_EmptyStatement (GetLocation ($5));
+               
+               $$ = new If ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | IF open_parens_any boolean_expression stmnt_close_parens
+         embedded_statement stmnt_else embedded_statement
+         {
+               $$ = new If ((BooleanExpression) $3, (Statement) $5, (Statement) $7, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4), GetLocation ($6));
+               
+               if ($5 is EmptyStatement)
+                       Warning_EmptyStatement (GetLocation ($5));
+               if ($7 is EmptyStatement)
+                       Warning_EmptyStatement (GetLocation ($7));
+         }
+       | IF open_parens_any boolean_expression error
+         {
+               Error_SyntaxError (yyToken);
+               
+               $$ = new If ((BooleanExpression) $3, null, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2));
+         }
+       ;
+
+switch_statement
+       : SWITCH open_parens_any expression CLOSE_PARENS OPEN_BRACE
+         {
+           Lexer.AutoSemiInsertion = true;
+               start_block (GetLocation ($5));
+         }
+         opt_switch_sections CLOSE_BRACE
+         {
+               $$ = new Switch ((Expression) $3, (ExplicitBlock) current_block.Explicit, GetLocation ($1));    
+               end_block (GetLocation ($8));
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | SWITCH open_parens_any expression error
+         {
+               Error_SyntaxError (yyToken);
+         
+               $$ = new Switch ((Expression) $3, null, GetLocation ($1));      
+               lbag.AddStatement ($$, GetLocation ($2));
+         }
+       ;
+
+opt_switch_sections
+       : /* empty */           
+      {
+               report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); 
+         }
+       | switch_labels
+      {
+               report.Warning (1522, 1, current_block.StartLocation, "Empty switch block"); 
+         }
+       | switch_sections opt_switch_labels
+       ;
+
+switch_sections
+       : switch_section 
+       | switch_sections switch_section
+       | error
+         {
+               Error_SyntaxError (yyToken);
+         } 
+       ;
+
+switch_section
+       : switch_labels statement_list 
+       ;
+
+opt_switch_labels
+       : /* empty */
+       | switch_labels
+       ;
+
+switch_labels
+       : switch_label 
+         {
+               var label = (SwitchLabel) $1;
+               label.SectionStart = true;
+               current_block.AddStatement (label);
+         }
+       | switch_labels switch_label 
+         {
+               current_block.AddStatement ((Statement) $2);
+         }
+       ;
+
+switch_label
+       : CASE constant_expression COLON
+        {
+               $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($3));
+               Lexer.AutoSemiInsertionAfter = 1;               
+        }
+       | CASE constant_expression error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
+         }
+       | DEFAULT_COLON
+         {
+               $$ = new SwitchLabel (null, GetLocation ($1));
+               Lexer.AutoSemiInsertionAfter = 1;               
+         }
+       ;
+
+iteration_statement
+       : while_statement
+       | do_statement
+       | for_statement
+       | foreach_statement
+       ;
+
+while_statement
+       : WHILE open_parens_any boolean_expression stmnt_close_parens embedded_statement
+         {
+               if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
+                       Warning_EmptyStatement (GetLocation ($5));
+         
+               $$ = new While ((BooleanExpression) $3, (Statement) $5, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | WHILE open_parens_any boolean_expression error
+         {
+               Error_SyntaxError (yyToken);
+               
+               $$ = new While ((BooleanExpression) $3, null, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2));
+         }
+       ;
+
+stmnt_do
+       : DO
+         {
+           Lexer.AutoSemiInsertionAfter = 1;
+         }
+       ;
+       
+do_while_stmnt_close_parens
+       : CLOSE_PARENS
+         {
+           Lexer.AutoSemiInsertion = true;
+         }
+       ;
+
+do_statement
+       : stmnt_do embedded_statement WHILE open_parens_any boolean_expression do_while_stmnt_close_parens stmnt_end_semicolon
+         {
+           Lexer.AutoSemiInsertion = true;
+           
+               $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
+               lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7));
+         }
+       | stmnt_do embedded_statement error
+         {
+           Lexer.AutoSemiInsertion = true;
+           
+               Error_SyntaxError (yyToken);
+               $$ = new Do ((Statement) $2, null, GetLocation ($1), Location.Null);
+         }
+       | stmnt_do embedded_statement WHILE open_parens_any boolean_expression error
+         {
+           Lexer.AutoSemiInsertion = true;
+
+               Error_SyntaxError (yyToken);
+         
+               $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
+               lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4));
+         }
+       ;
+
+for_statement
+       : FOR open_parens_any
+         {
+               start_block (GetLocation ($2));
+               current_block.IsCompilerGenerated = true;
+               lexer.ForInParsing = true;
+               $$ = new Tuple<Location,Location>(GetLocation($0), GetLocation($1));
+         }
+         for_statement_cont
+         {
+               lexer.ForInParsing = false;       
+               $$ = $4;
+         }
+       ;
+       
+// Has to use be extra rule to recover started block
+for_statement_cont
+       : for_initializer IN
+         {
+           lexer.ForInParsing = false;
+         } 
+         expression stmnt_close_parens embedded_statement
+         {
+               if ($6 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
+                       Warning_EmptyStatement (GetLocation ($6));
+
+               var blockVar = $1 as BlockVariable;
+               if (blockVar != null) {
+                       if (blockVar == null || blockVar.Initializer != null || blockVar.Declarators != null) {
+                               report.Error (7036, GetLocation ($4), "Invalid for each initializer");  
+                               $$ = end_block (current_block.StartLocation);
+                       } else {
+                               var locations = (Tuple<Location,Location>) $0;
+                               
+                               Foreach f = new Foreach (blockVar.TypeExpression, blockVar.Variable, (Expression) $4, (Statement) $6, current_block, AsForEachType.ForEachKey, locations.Item1);
+                               lbag.AddStatement (f, locations.Item2, GetLocation ($2), GetLocation ($5));
+                               
+                               end_block (GetLocation ($5));
+                               $$ = f;
+                       }
+               } else {
+                       var expList = $1 as List<Expression>;
+                       var varRef = ($1 as FullNamedExpression) ?? ((expList != null && expList.Count == 1) ? (expList[0] as FullNamedExpression) : null);
+                       if (varRef == null) {
+                               report.Error (7041, GetLocation ($1), "Invalid iterator initializer");          
+                               $$ = end_block (current_block.StartLocation);
+                       } else {
+                               var locations = (Tuple<Location,Location>) $0;
+                               
+                               Foreach f = new Foreach (varRef, (Expression) $4, (Statement) $6, current_block, AsForEachType.ForEachKey, locations.Item1);
+                               lbag.AddStatement (f, locations.Item2, GetLocation ($2), GetLocation ($5));
+                               
+                               end_block (GetLocation ($5));
+                               $$ = f;
+                       }
+               }
+         }     
+       | opt_for_initializer SEMICOLON
+         {
+           lexer.ForInParsing = false;
+         
+               var locations = (Tuple<Location,Location>) $0;
+
+               For f = new For (locations.Item1);
+               current_block.AddStatement (f);
+               
+               var expList = $1 as List<Expression>;
+               if (expList != null) 
+                       f.Initializer = ExpressionListToStatementList (expList);
+               else
+                       f.Initializer = (Statement) $1;
+
+               // Pass the "For" object to the iterator_part4
+               oob_stack.Push (f);
+               
+               $$ = f;
+         }
+         for_condition_and_iterator_part
+         embedded_statement
+         {
+               var locations = (Tuple<Location,Location>) $4;
+               oob_stack.Pop ();
+               if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
+                       Warning_EmptyStatement (GetLocation ($5));
+         
+               For f = ((For) $3);
+               f.Statement = (Statement) $5;
+               lbag.AddStatement (f, current_block.StartLocation, GetLocation ($2), GetLocation (locations.Item1), GetLocation (locations.Item2));
+
+               $$ = end_block (GetLocation ($2));
+         }
+       | error
+         {
+               Lexer.AutoSemiInsertion = true;
+               Error_SyntaxError (yyToken);
+               $$ = end_block (current_block.StartLocation);
+         }
+       ;
+
+for_condition_and_iterator_part
+       : opt_for_condition SEMICOLON
+         {
+               For f = (For) oob_stack.Peek ();
+               f.Condition = (BooleanExpression) $1;
+         }
+         for_iterator_part {
+               $$ = new Tuple<Location,Location> (GetLocation ($2), (Location) $4);
+         }
+
+       // Handle errors in the case of opt_for_condition being followed by
+       // a close parenthesis
+       | opt_for_condition close_parens_close_brace {
+               Lexer.AutoSemiInsertion = true;
+               report.Error (1525, GetLocation ($2), "Unexpected symbol `}'");
+               For f = (For) oob_stack.Peek ();
+               f.Condition = (BooleanExpression) $1;
+               $$ = new Tuple<Location,Location> (GetLocation ($2), GetLocation ($2));
+         }
+       ;
+
+for_iterator_part
+       : opt_for_iterator stmnt_close_parens {
+               For f = (For) oob_stack.Peek ();
+               f.Iterator = (Statement) $1;
+               $$ = GetLocation ($2);
+         }
+       | opt_for_iterator CLOSE_BRACE {
+               Lexer.AutoSemiInsertion = true;
+               report.Error (1525, GetLocation ($2), "Unexpected symbol expected ')'");
+               For f = (For) oob_stack.Peek ();
+               f.Iterator = (Statement) $1;
+               $$ = GetLocation ($2);
+         }
+       ; 
+
+close_parens_close_brace 
+       : CLOSE_PARENS
+       | CLOSE_BRACE { lexer.putback ('}'); }
+       ;
+
+opt_for_initializer
+       : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
+       | for_initializer       
+       ;
+
+for_initializer
+       : VAR identifier_inside_body COLON type
+         {
+               var lt = (LocatedToken) $2;
+               var type = (FullNamedExpression) $4;
+               var li = GetOrCreateLocalVariable (current_block, lt.Value, 0, type, lt.Location);
+               current_variable = new BlockVariable (type, li);
+         }
+         opt_local_variable_initializer opt_variable_declarators
+         {
+               $$ = current_variable;
+               current_variable = null;
+         }
+       | expression_list
+         {
+               
+         }
+       ;
+
+opt_for_condition
+       : /* empty */           { $$ = null; }
+       | boolean_expression
+       ;
+
+opt_for_iterator
+       : /* empty */           { $$ = new EmptyStatement (lexer.Location); }
+       | for_iterator
+       ;
+
+for_iterator
+       : statement_expression_list
+       ;
+
+statement_expression_list
+       : statement_expression
+       | statement_expression_list COMMA statement_expression
+         {
+               var sl = $1 as StatementList;
+               if (sl == null) {
+                       sl = new StatementList ((Statement) $1, (Statement) $3);
+                       lbag.AddStatement (sl, GetLocation ($2));
+               } else {
+                       sl.Add ((Statement) $3);
+                       lbag.AppendTo (sl, GetLocation ($2));
+               }
+                       
+               $$ = sl;
+         }
+       ;
+
+foreach_statement
+       : FOR_EACH 
+         {
+               lexer.ForInParsing = true;
+         } 
+         open_parens_any for_initializer IN
+         {
+               lexer.ForInParsing = false;
+         } 
+         expression stmnt_close_parens 
+         {
+               start_block (GetLocation ($3));
+               current_block.IsCompilerGenerated = true;
+         } 
+         embedded_statement
+         {
+               if ($10 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
+                       Warning_EmptyStatement (GetLocation ($10));
+
+               var blockVar = $4 as BlockVariable;
+               if (blockVar != null) {
+                       if (blockVar == null || blockVar.Initializer != null || blockVar.Declarators != null) {
+                               report.Error (7036, GetLocation ($4), "Invalid for each initializer");  
+                               $$ = end_block (current_block.StartLocation);
+                       } else {
+                               Foreach f = new Foreach (blockVar.TypeExpression, blockVar.Variable, (Expression) $7, (Statement) $10, current_block, AsForEachType.ForEachValue, GetLocation ($1));
+                               lbag.AddStatement (f, GetLocation ($3), GetLocation ($5), GetLocation ($8));
+                               
+                               end_block (GetLocation ($5));
+                               $$ = f;
+                       }
+               } else {
+                       var expList = $4 as List<Expression>;
+                       var varRef = ($4 as FullNamedExpression) ?? ((expList != null && expList.Count == 1) ? (expList[0] as FullNamedExpression) : null);
+                       if (varRef == null) {
+                               report.Error (7041, GetLocation ($4), "Invalid iterator initializer");          
+                               $$ = end_block (current_block.StartLocation);
+                       } else {
+                               Foreach f = new Foreach (varRef, (Expression) $7, (Statement) $10, current_block, AsForEachType.ForEachValue, GetLocation ($1));
+                               lbag.AddStatement (f, GetLocation ($3), GetLocation ($5), GetLocation ($8));
+                               
+                               end_block (GetLocation ($5));
+                               $$ = f;
+                       }
+               }
+         }
+       ;
+
+jump_statement
+       : break_statement
+       | continue_statement
+       | goto_statement
+       | return_statement
+       | throw_statement
+       | yield_statement
+       | use_namespace_statement
+       ;
+
+break_statement
+       : BREAK stmnt_end_semicolon
+         {
+               $$ = new Break (GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2));
+         }
+       ;
+
+continue_statement
+       : CONTINUE stmnt_end_semicolon
+         {
+               $$ = new Continue (GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2));
+         }
+       | CONTINUE error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = new Continue (GetLocation ($1));
+         }
+       ;
+
+goto_statement
+       : GOTO identifier_inside_body stmnt_end_semicolon 
+         {
+               var lt = (LocatedToken) $2;
+               $$ = new Goto (lt.Value, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
+         }
+       | GOTO CASE constant_expression stmnt_end_semicolon
+         {
+               $$ = new GotoCase ((Expression) $3, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | GOTO DEFAULT stmnt_end_semicolon 
+         {
+               $$ = new GotoDefault (GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
+         }
+       ; 
+
+return_statement
+       : RETURN opt_expression stmnt_end_semicolon
+         {
+               $$ = new Return ((Expression) $2, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($3));
+         }
+       | RETURN expression error
+         {
+           Lexer.AutoSemiInsertion = true;
+               Error_SyntaxError (yyToken);
+               $$ = new Return ((Expression) $2, GetLocation ($1));
+         }
+       | RETURN error
+         {
+           Lexer.AutoSemiInsertion = true;
+               Error_SyntaxError (yyToken);
+               $$ = new Return (null, GetLocation ($1));
+         }
+       ;
+
+throw_statement
+       : THROW opt_expression stmnt_end_semicolon
+         {
+               $$ = new Throw ((Expression) $2, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($3));
+         }
+       | THROW error
+         {
+           Lexer.AutoSemiInsertion = true;
+               Error_SyntaxError (yyToken);
+               $$ = new Throw (null, GetLocation ($1));
+         }
+       ;
+
+yield_statement 
+       : identifier_inside_body RETURN opt_expression stmnt_end_semicolon
+         {
+               var lt = (LocatedToken) $1;
+               string s = lt.Value;
+               if (s != "yield"){
+                       report.Error (1003, lt.Location, "; expected");
+               } else if ($3 == null) {
+                       report.Error (1627, GetLocation ($4), "Expression expected after yield return");
+               } else if (lang_version == LanguageVersion.ISO_1){
+                       FeatureIsNotAvailable (lt.Location, "iterators");
+               }
+               
+               current_block.Explicit.RegisterIteratorYield ();
+               $$ = new Yield ((Expression) $3, lt.Location);
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | identifier_inside_body RETURN expression error
+         {
+           Lexer.AutoSemiInsertion = true;
+         
+               Error_SyntaxError (yyToken);
+
+               var lt = (LocatedToken) $1;
+               string s = lt.Value;
+               if (s != "yield"){
+                       report.Error (1003, lt.Location, "; expected");
+               } else if ($3 == null) {
+                       report.Error (1627, GetLocation ($4), "Expression expected after yield return");
+               } else if (lang_version == LanguageVersion.ISO_1){
+                       FeatureIsNotAvailable (lt.Location, "iterators");
+               }
+               
+               current_block.Explicit.RegisterIteratorYield ();
+               $$ = new Yield ((Expression) $3, lt.Location);
+               lbag.AddStatement ($$, GetLocation ($2));
+         }
+       | identifier_inside_body BREAK stmnt_end_semicolon
+         {
+               var lt = (LocatedToken) $1;
+               string s = lt.Value;
+               if (s != "yield"){
+                       report.Error (1003, lt.Location, "; expected");
+               } else if (lang_version == LanguageVersion.ISO_1){
+                       FeatureIsNotAvailable (lt.Location, "iterators");
+               }
+               
+               current_block.Explicit.RegisterIteratorYield ();
+               $$ = new YieldBreak (lt.Location);
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($3));
+         }
+       ;
+
+opt_expression
+       : /* empty */
+       | expression
+       ;
+
+try_statement
+       : TRY block catch_clauses
+         {
+               $$ = new TryCatch ((Block) $2, (List<Catch>) $3, GetLocation ($1), false);
+         }
+       | TRY block FINALLY block
+         {
+               $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($3));
+         }
+       | TRY block catch_clauses FINALLY block
+         {
+               $$ = new TryFinally (new TryCatch ((Block) $2, (List<Catch>) $3, Location.Null, true), (Block) $5, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($4));
+         }
+       | TRY block error
+         {
+               Error_SyntaxError (1524, yyToken);
+               $$ = new TryCatch ((Block) $2, null, GetLocation ($1), false);
+         }
+       ;
+
+catch_clauses
+       : catch_clause 
+         {
+               var l = new List<Catch> (2);
+
+               l.Add ((Catch) $1);
+               $$ = l;
+         }
+       | catch_clauses catch_clause
+         {
+               var l = (List<Catch>) $1;
+               
+               Catch c = (Catch) $2;
+               if (l [l.Count - 1].IsGeneral) {
+                       report.Error (1017, c.loc, "Try statement already has an empty catch block");
+               }
+               
+               l.Add (c);
+               $$ = l;
+         }
+       ;
+
+opt_identifier
+       : /* empty */
+       | identifier_inside_body
+       ;
+
+catch_clause 
+       : CATCH block
+         {
+               $$ = new Catch ((Block) $2, GetLocation ($1));
+         }
+       | CATCH open_parens_any IDENTIFIER COLON type CLOSE_PARENS
+         {
+               start_block (GetLocation ($2));
+               var c = new Catch (current_block, GetLocation ($1));
+               c.TypeExpression = (FullNamedExpression) $5;
+
+               var lt = (LocatedToken) $3;
+               c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
+//TODO:                c.Variable.TypeExpr = c.TypeExpression;
+               current_block.AddLocalName (c.Variable);
+               
+               lbag.AddLocation (c, GetLocation ($2), GetLocation ($6));
+               $$ = c;
+         }
+         block_prepared
+         {
+               $$ = $7;
+         }
+       | CATCH open_parens_any error
+         {
+               if (yyToken == Token.CLOSE_PARENS) {
+                       report.Error (1015, lexer.Location,
+                               "A type that derives from `System.Exception', `object', or `string' expected");
+               } else {
+                       Error_SyntaxError (yyToken);
+               }
+               
+               $$ = new Catch (null, GetLocation ($1));
+         }
+       | CATCH open_parens_any type opt_identifier CLOSE_PARENS error
+         {
+               Error_SyntaxError (yyToken);
+
+               // Required otherwise missing block could not be detected because
+               // start_block is run early
+               var c = new Catch (null, GetLocation ($1));
+               c.TypeExpression = (FullNamedExpression) $3;
+
+               if ($4 != null) {
+                       var lt = (LocatedToken) $4;
+                       c.Variable = new LocalVariable (current_block, lt.Value, lt.Location);
+               }
+
+               lbag.AddLocation (c, GetLocation ($2), GetLocation ($5));
+
+               $$ = c;
+         }
+       ;
+
+checked_statement
+       : CHECKED block
+         {
+               $$ = new Checked ((Block) $2, GetLocation ($1));
+         }
+       ;
+
+unchecked_statement
+       : UNCHECKED block
+         {
+               $$ = new Unchecked ((Block) $2, GetLocation ($1));
+         }
+       ;
+
+unsafe_statement
+       : UNSAFE
+         {
+               if (!settings.Unsafe)
+                       Error_UnsafeCodeNotAllowed (GetLocation ($1));
+         } block {
+               $$ = new Unsafe ((Block) $3, GetLocation ($1));
+         }
+       ;
+
+lock_statement
+       : LOCK open_parens_any expression CLOSE_PARENS embedded_statement
+         {
+               if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
+                       Warning_EmptyStatement (GetLocation ($5));
+         
+               $$ = new Lock ((Expression) $3, (Statement) $5, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | LOCK open_parens_any expression error
+         {
+               Error_SyntaxError (yyToken);
+
+               $$ = new Lock ((Expression) $3, null, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2));
+         }
+       ;
+
+fixed_statement
+       : FIXED open_parens_any type identifier_inside_body
+         {
+           start_block (GetLocation ($2));
+           
+               current_block.IsCompilerGenerated = true;
+               var lt = (LocatedToken) $4;
+               var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.FixedVariable | LocalVariable.Flags.Used, lt.Location);
+               current_block.AddLocalName (li);
+               current_variable = new Fixed.VariableDeclaration ((FullNamedExpression) $3, li);
+         }
+         using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators CLOSE_PARENS
+         {
+               $$ = current_variable;
+               current_variable = null;
+         }
+         embedded_statement
+         {
+               if ($10 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
+                       Warning_EmptyStatement (GetLocation ($10));
+         
+               Fixed f = new Fixed ((Fixed.VariableDeclaration) $9, (Statement) $10, GetLocation ($1));
+               current_block.AddStatement (f);
+               $$ = end_block (GetLocation ($8));
+         }
+       ;
+
+using_statement
+       : USING open_parens_any variable_type identifier_inside_body
+         {
+           start_block (GetLocation ($2));
+           
+               current_block.IsCompilerGenerated = true;
+               var lt = (LocatedToken) $4;
+               var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.UsingVariable | LocalVariable.Flags.Used, lt.Location);
+               current_block.AddLocalName (li);
+               current_variable = new Using.VariableDeclaration ((FullNamedExpression) $3, li);
+         }
+         using_initialization CLOSE_PARENS
+         {
+               $$ = current_variable;    
+               current_variable = null;
+         }
+         embedded_statement
+         {
+               CheckIsPlayScript("using", GetLocation($2));
+               
+               if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
+                       Warning_EmptyStatement (GetLocation ($9));
+         
+               Using u = new Using ((Using.VariableDeclaration) $8, (Statement) $9, GetLocation ($1));
+               current_block.AddStatement (u);
+               $$ = end_block (GetLocation ($7));
+         }
+       | USING open_parens_any expression CLOSE_PARENS embedded_statement
+         {
+               CheckIsPlayScript("using", GetLocation($2));
+
+               if ($5 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
+                       Warning_EmptyStatement (GetLocation ($5));
+         
+               $$ = new Using ((Expression) $3, (Statement) $5, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
+         }
+       | USING open_parens_any expression error
+         {
+               CheckIsPlayScript("using", GetLocation($2));
+         
+               Error_SyntaxError (yyToken);
+               
+               $$ = new Using ((Expression) $3, null, GetLocation ($1));
+               lbag.AddStatement ($$, GetLocation ($2));
+         }
+       ;
+       
+using_initialization
+       : using_or_fixed_variable_initializer opt_using_or_fixed_variable_declarators
+       | error
+         {
+               // It has to be here for the parent to safely restore artificial block
+               Error_SyntaxError (yyToken);
+         }
+       ;
+       
+using_or_fixed_variable_initializer
+       : /* empty */
+         {
+               Error_MissingInitializer (lexer.Location);
+         }
+       | ASSIGN variable_initializer
+         {
+               current_variable.Initializer = (Expression) $2;
+               $$ = current_variable;
+         }
+       ;
+
+// LINQ
+
+query_expression
+       : first_from_clause query_body 
+         {
+               lexer.query_parsing = false;
+                       
+               Linq.AQueryClause from = $1 as Linq.AQueryClause;
+                       
+               from.Tail.Next = (Linq.AQueryClause)$2;
+               $$ = from;
+               
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         }
+       | nested_from_clause query_body
+         {
+               Linq.AQueryClause from = $1 as Linq.AQueryClause;
+                       
+               from.Tail.Next = (Linq.AQueryClause)$2;
+               $$ = from;
+               
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         }     
+
+       // Bubble up COMPLETE_COMPLETION productions
+       | first_from_clause COMPLETE_COMPLETION {
+               lexer.query_parsing = false;
+               $$ = $1;
+
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         }
+       | nested_from_clause COMPLETE_COMPLETION {
+               $$ = $1;
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         }
+       ;
+       
+first_from_clause
+       : FROM_FIRST identifier_inside_body IN expression
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         
+               var lt = (LocatedToken) $2;
+               var rv = new Linq.RangeVariable (lt.Value, lt.Location);
+               $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)));
+         }
+       | FROM_FIRST type identifier_inside_body IN expression
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         
+               var lt = (LocatedToken) $3;
+               var rv = new Linq.RangeVariable (lt.Value, lt.Location);
+               $$ = new Linq.QueryExpression (
+                       new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
+                               IdentifierType = (FullNamedExpression)$2
+                       }
+               );
+         }
+       ;
+
+nested_from_clause
+       : FROM identifier_inside_body IN expression
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         
+               var lt = (LocatedToken) $2;
+               var rv = new Linq.RangeVariable (lt.Value, lt.Location);
+               $$ = new Linq.QueryExpression (new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$4, rv, GetLocation ($1)));
+         }
+       | FROM type identifier_inside_body IN expression
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         
+               var lt = (LocatedToken) $3;
+               var rv = new Linq.RangeVariable (lt.Value, lt.Location);
+               $$ = new Linq.QueryExpression (
+                       new Linq.QueryStartClause ((Linq.QueryBlock)current_block, (Expression)$5, rv, GetLocation ($1)) {
+                               IdentifierType = (FullNamedExpression)$2
+                       }
+               );
+         }
+       ;
+       
+from_clause
+       : FROM identifier_inside_body IN
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         expression_or_error
+         {
+               var lt = (LocatedToken) $2;
+               var sn = new Linq.RangeVariable (lt.Value, lt.Location);
+               $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$5, GetLocation ($1));
+               
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+               
+               ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
+         }       
+       | FROM type identifier_inside_body IN
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         expression_or_error
+         {
+               var lt = (LocatedToken) $3;
+               var sn = new Linq.RangeVariable (lt.Value, lt.Location);
+
+               $$ = new Linq.SelectMany ((Linq.QueryBlock)current_block, sn, (Expression)$6, GetLocation ($1)) {
+                       IdentifierType = (FullNamedExpression)$2
+               };
+               
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+               
+               ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
+         }
+       ;       
+
+query_body
+       : query_body_clauses select_or_group_clause opt_query_continuation 
+         {
+               Linq.AQueryClause head = (Linq.AQueryClause)$2;
+               
+               if ($3 != null)
+                       head.Next = (Linq.AQueryClause)$3;
+                               
+               if ($1 != null) {
+                       Linq.AQueryClause clause = (Linq.AQueryClause)$1;
+                       clause.Tail.Next = head;
+                       head = clause;
+               }
+               
+               $$ = head;
+         }
+       | select_or_group_clause opt_query_continuation
+         {
+               Linq.AQueryClause head = (Linq.AQueryClause)$2;
+
+               if ($1 != null) {
+                       Linq.AQueryClause clause = (Linq.AQueryClause)$1;
+                       clause.Tail.Next = head;
+                       head = clause;
+               }
+               
+               $$ = head;
+         }
+       | query_body_clauses COMPLETE_COMPLETION
+       | query_body_clauses error
+         {
+               report.Error (742, GetLocation ($2), "Unexpected symbol `{0}'. A query body must end with select or group clause", GetSymbolName (yyToken));
+               $$ = $1;
+         }
+       | error
+         {
+               Error_SyntaxError (yyToken);
+               $$ = null;
+         }
+       ;
+       
+select_or_group_clause
+       : SELECT
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         expression_or_error
+         {
+               $$ = new Linq.Select ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
+
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         }
+       | GROUP
+         {
+               if (linq_clause_blocks == null)
+                       linq_clause_blocks = new Stack<Linq.QueryBlock> ();
+                       
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+               linq_clause_blocks.Push ((Linq.QueryBlock)current_block);
+         }
+         expression_or_error
+         {
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         BY expression_or_error
+         {
+               $$ = new Linq.GroupBy ((Linq.QueryBlock)current_block, (Expression)$3, linq_clause_blocks.Pop (), (Expression)$6, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($5));
+               
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         }
+       ;
+       
+query_body_clauses
+       : query_body_clause
+       | query_body_clauses query_body_clause
+         {
+               ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$2;
+               $$ = $1;
+         }
+       ;
+       
+query_body_clause
+       : from_clause
+       | let_clause 
+       | where_clause
+       | join_clause
+       | orderby_clause
+       ;
+       
+let_clause
+       : LET identifier_inside_body ASSIGN 
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         expression_or_error
+         {
+               var lt = (LocatedToken) $2;
+               var sn = new Linq.RangeVariable (lt.Value, lt.Location);
+               $$ = new Linq.Let ((Linq.QueryBlock) current_block, sn, (Expression)$5, GetLocation ($1));
+               lbag.AddLocation ($$, GetLocation ($3));
+               
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+               
+               ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
+         }
+       ;
+
+where_clause
+       : WHERE
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         expression_or_error
+         {
+               $$ = new Linq.Where ((Linq.QueryBlock)current_block, (Expression)$3, GetLocation ($1));
+
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         }
+       ;
+       
+join_clause
+       : JOIN identifier_inside_body IN
+         {
+               if (linq_clause_blocks == null)
+                       linq_clause_blocks = new Stack<Linq.QueryBlock> ();
+                       
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+               linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
+         }
+         expression_or_error ON
+         {
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+               linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
+         }
+         expression_or_error EQUALS
+         {
+               current_block.AddStatement (new ContextualReturn ((Expression) $8));
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         expression_or_error opt_join_into
+         {
+               current_block.AddStatement (new ContextualReturn ((Expression) $11));
+               current_block.SetEndLocation (lexer.Location);
+         
+               var outer_selector = linq_clause_blocks.Pop ();
+               var block = linq_clause_blocks.Pop ();
+
+               var lt = (LocatedToken) $2;     
+               var sn = new Linq.RangeVariable (lt.Value, lt.Location);
+               Linq.RangeVariable into;
+               
+               if ($12 == null) {
+                       into = sn;
+                       $$ = new Linq.Join (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1));
+                       lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9));
+               } else {
+                       //
+                       // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
+                       //
+                       var parent = block.Parent;
+                       while (parent is Linq.QueryBlock) {
+                               parent = parent.Parent;
+                       }
+                       current_block.Parent = parent;
+                       
+                       ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
+               
+                       lt = (LocatedToken) $12;
+                       into = new Linq.RangeVariable (lt.Value, lt.Location);
+
+                       $$ = new Linq.GroupJoin (block, sn, (Expression)$5, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1));   
+                       lbag.AddLocation ($$, GetLocation ($3), GetLocation ($6), GetLocation ($9), GetLocation ($12));
+               }
+
+               current_block = block.Parent;
+               ((Linq.QueryBlock)current_block).AddRangeVariable (into);
+         }
+       | JOIN type identifier_inside_body IN
+         {
+               if (linq_clause_blocks == null)
+                       linq_clause_blocks = new Stack<Linq.QueryBlock> ();
+                       
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+               linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
+         }
+         expression_or_error ON
+         {
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+               linq_clause_blocks.Push ((Linq.QueryBlock) current_block);
+         }
+         expression_or_error EQUALS
+         {
+               current_block.AddStatement (new ContextualReturn ((Expression) $9));
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         expression_or_error opt_join_into
+         {
+               current_block.AddStatement (new ContextualReturn ((Expression) $12));
+               current_block.SetEndLocation (lexer.Location);
+         
+               var outer_selector = linq_clause_blocks.Pop ();
+               var block = linq_clause_blocks.Pop ();
+               
+               var lt = (LocatedToken) $3;
+               var sn = new Linq.RangeVariable (lt.Value, lt.Location);
+               Linq.RangeVariable into;
+               
+               if ($13 == null) {
+                       into = sn;              
+                       $$ = new Linq.Join (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, GetLocation ($1)) {
+                               IdentifierType = (FullNamedExpression)$2
+                       };
+               } else {
+                       //
+                       // Set equals right side parent to beginning of linq query, it is not accessible therefore cannot cause name collisions
+                       //
+                       var parent = block.Parent;
+                       while (parent is Linq.QueryBlock) {
+                               parent = parent.Parent;
+                       }
+                       current_block.Parent = parent;
+               
+                       ((Linq.QueryBlock)current_block).AddRangeVariable (sn);
+               
+                       lt = (LocatedToken) $13;
+                       into = new Linq.RangeVariable (lt.Value, lt.Location); // TODO:
+                       
+                       $$ = new Linq.GroupJoin (block, sn, (Expression)$6, outer_selector, (Linq.QueryBlock) current_block, into, GetLocation ($1)) {
+                               IdentifierType = (FullNamedExpression)$2
+                       };                      
+               }
+               
+               current_block = block.Parent;
+               ((Linq.QueryBlock)current_block).AddRangeVariable (into);               
+         }
+       ;
+       
+opt_join_into
+       : /* empty */
+       | INTO identifier_inside_body
+         {
+               $$ = $2;
+         }
+       ;
+       
+orderby_clause
+       : ORDERBY
+         {
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         orderings
+         {
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         
+               $$ = $3;
+         }
+       ;
+       
+orderings
+       : order_by
+       | order_by COMMA
+         {
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+         }
+         orderings_then_by
+         {
+               ((Linq.AQueryClause)$1).Next = (Linq.AQueryClause)$4;
+               $$ = $1;
+         }
+       ;
+       
+orderings_then_by
+       : then_by
+       | orderings_then_by COMMA
+        {
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+         
+               current_block = new Linq.QueryBlock ((Linq.QueryBlock) current_block, lexer.Location);   
+        }
+        then_by
+        {
+               ((Linq.AQueryClause)$1).Tail.Next = (Linq.AQueryClause)$4;
+               $$ = $1;
+        }
+       ;       
+       
+order_by
+       : expression
+         {
+               $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
+         }
+       | expression ASCENDING
+         {
+               $$ = new Linq.OrderByAscending ((Linq.QueryBlock) current_block, (Expression)$1);       
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | expression DESCENDING
+         {
+               $$ = new Linq.OrderByDescending ((Linq.QueryBlock) current_block, (Expression)$1);      
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       ;
+
+then_by
+       : expression
+         {
+               $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
+         }
+       | expression ASCENDING
+         {
+               $$ = new Linq.ThenByAscending ((Linq.QueryBlock) current_block, (Expression)$1);        
+               lbag.AddLocation ($$, GetLocation ($2));
+         }
+       | expression DESCENDING
+         {
+               $$ = new Linq.ThenByDescending ((Linq.QueryBlock) current_block, (Expression)$1);       
+               lbag.AddLocation ($$, GetLocation ($2));
+         }     
+       ;
+
+
+opt_query_continuation
+       : /* empty */
+       | INTO identifier_inside_body
+         {
+               // query continuation block is not linked with query block but with block
+               // before. This means each query can use same range variable names for
+               // different identifiers.
+
+               current_block.SetEndLocation (GetLocation ($1));
+               current_block = current_block.Parent;
+       
+               current_block = new Linq.QueryBlock (current_block, lexer.Location);
+               
+               if (linq_clause_blocks == null)
+                       linq_clause_blocks = new Stack<Linq.QueryBlock> ();
+                       
+               linq_clause_blocks.Push ((Linq.QueryBlock) current_block);              
+         }
+         query_body
+         {
+               var current_block = linq_clause_blocks.Pop ();    
+               var lt = (LocatedToken) $2;
+               var rv = new Linq.RangeVariable (lt.Value, lt.Location);
+               $$ = new Linq.QueryStartClause ((Linq.QueryBlock)current_block, null, rv, GetLocation ($1)) {
+                       next = (Linq.AQueryClause)$4
+               };
+         }
+       ;
+       
+//
+// Support for using the compiler as an interactive parser
+//
+// The INTERACTIVE_PARSER token is first sent to parse our
+// productions;  If the result is a Statement, the parsing
+// is repeated, this time with INTERACTIVE_PARSE_WITH_BLOCK
+// to setup the blocks in advance.
+//
+// This setup is here so that in the future we can add 
+// support for other constructs (type parsing, namespaces, etc)
+// that do not require a block to be setup in advance
+//
+
+interactive_parsing
+       : EVAL_STATEMENT_PARSER EOF 
+       | EVAL_USING_DECLARATIONS_UNIT_PARSER package_directives opt_COMPLETE_COMPLETION
+       | EVAL_STATEMENT_PARSER
+        { 
+               current_container = current_type = new Class (current_container, new MemberName ("<InteractiveExpressionClass>"), Modifiers.PUBLIC, null);
+
+               // (ref object retval)
+               Parameter [] mpar = new Parameter [1];
+               mpar [0] = new Parameter (new TypeExpression (compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null);
+
+               ParametersCompiled pars = new ParametersCompiled (mpar);
+               var mods = Modifiers.PUBLIC | Modifiers.STATIC;
+               if (settings.Unsafe)
+                       mods |= Modifiers.UNSAFE;
+
+               current_local_parameters = pars;
+               Method method = new Method (
+                       current_type,
+                       new TypeExpression (compiler.BuiltinTypes.Void, Location.Null),
+                       mods,
+                       new MemberName ("Host"),
+                       pars,
+                       null /* attributes */);
+                       
+               current_type.AddMember (method);
+
+               // Always set to true when in ineractive mode
+               is_config_enabled = true; 
+               
+               oob_stack.Push (method);
+               ++lexer.parsing_block;
+               start_block (lexer.Location);
+         }             
+         interactive_statement_list opt_COMPLETE_COMPLETION
+         {
+               --lexer.parsing_block;
+               Method method = (Method) oob_stack.Pop ();
+
+               method.Block = (ToplevelBlock) end_block(lexer.Location);
+
+               InteractiveResult = (Class) pop_current_class ();
+               current_local_parameters = null;
+         } 
+       | EVAL_COMPILATION_UNIT_PARSER interactive_compilation_unit
+       ;
+
+interactive_compilation_unit
+       : opt_extern_alias_directives opt_package_directives
+       | opt_extern_alias_directives opt_package_directives package_declaration
+       ;
+
+opt_COMPLETE_COMPLETION
+       : /* nothing */
+       | COMPLETE_COMPLETION
+       ;
+
+//close_brace_or_complete_completion
+//     : CLOSE_BRACE
+//     | COMPLETE_COMPLETION
+//     ;
+       
+//
+// XML documentation code references micro parser
+//
+documentation_parsing
+       : DOC_SEE doc_cref
+         {
+               module.DocumentationBuilder.ParsedName = (MemberName) $2;
+         }
+       ;
+
+doc_cref
+       : doc_type_declaration_name opt_doc_method_sig
+         {
+               module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$2;
+         }
+       | builtin_types opt_doc_method_sig
+         {
+               module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
+               module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$2;
+               $$ = null;
+         }
+       | builtin_types DOT IDENTIFIER opt_doc_method_sig
+         {
+               module.DocumentationBuilder.ParsedBuiltinType = (TypeExpression)$1;
+               module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$4;
+               var lt = (LocatedToken) $3;
+               $$ = new MemberName (lt.Value);
+         }
+       | doc_type_declaration_name DOT THIS
+         {
+               $$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
+         }
+       | doc_type_declaration_name DOT THIS OPEN_BRACKET
+         {
+               valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
+         }
+         opt_doc_parameters CLOSE_BRACKET
+         {
+               module.DocumentationBuilder.ParsedParameters = (List<DocumentationParameter>)$6;
+               $$ = new MemberName ((MemberName) $1, MemberCache.IndexerNameAlias, Location.Null);
+         }
+       | EXPLICIT OPERATOR type opt_doc_method_sig
+         {
+               var p = (List<DocumentationParameter>)$4 ?? new List<DocumentationParameter> (1);
+               p.Add (new DocumentationParameter ((FullNamedExpression) $3));
+               module.DocumentationBuilder.ParsedParameters = p;
+               module.DocumentationBuilder.ParsedOperator = Operator.OpType.Explicit;
+               $$ = null;
+         }
+       | IMPLICIT OPERATOR type opt_doc_method_sig
+         {
+               var p = (List<DocumentationParameter>)$4 ?? new List<DocumentationParameter> (1);
+               p.Add (new DocumentationParameter ((FullNamedExpression) $3));
+               module.DocumentationBuilder.ParsedParameters = p;
+               module.DocumentationBuilder.ParsedOperator = Operator.OpType.Implicit;
+               $$ = null;
+         }       
+       | OPERATOR overloadable_operator opt_doc_method_sig
+         {
+               var p = (List<DocumentationParameter>)$3 ?? new List<DocumentationParameter> (1);
+               module.DocumentationBuilder.ParsedParameters = p;
+               module.DocumentationBuilder.ParsedOperator = (Operator.OpType) $2;
+               $$ = null;
+         }
+       ;
+       
+doc_type_declaration_name
+       : type_declaration_name
+       | doc_type_declaration_name DOT type_declaration_name
+         {
+               $$ = new MemberName (((MemberName) $1), (MemberName) $3);
+         }
+       ;
+       
+opt_doc_method_sig
+       : /* empty */
+       | OPEN_PARENS
+         {
+               valid_param_mod = ParameterModifierType.Ref | ParameterModifierType.Out;
+         }
+         opt_doc_parameters CLOSE_PARENS
+         {
+               $$ = $3;
+         }
+       ;
+       
+opt_doc_parameters
+       : /* empty */
+         {
+               $$ = new List<DocumentationParameter> (0);
+         }
+       | doc_parameters
+       ;
+       
+doc_parameters
+       : doc_parameter
+         {
+               var parameters = new List<DocumentationParameter> ();
+               parameters.Add ((DocumentationParameter) $1);
+               $$ = parameters;
+         }
+       | doc_parameters COMMA doc_parameter
+         {
+               var parameters = $1 as List<DocumentationParameter>;
+               parameters.Add ((DocumentationParameter) $3);
+               $$ = parameters;
+         }
+       ;
+       
+doc_parameter
+       : opt_parameter_modifier parameter_type
+         {
+               if ($1 != null)
+                       $$ = new DocumentationParameter ((Parameter.Modifier) $1, (FullNamedExpression) $2);
+               else
+                       $$ = new DocumentationParameter ((FullNamedExpression) $2);
+         }
+       ;
+       
+%%
+
+// <summary>
+//  A class used to hold info about an operator declarator
+// </summary>
+class OperatorDeclaration {
+       public readonly Operator.OpType optype;
+       public readonly FullNamedExpression ret_type;
+       public readonly Location location;
+
+       public OperatorDeclaration (Operator.OpType op, FullNamedExpression ret_type, Location location)
+       {
+               optype = op;
+               this.ret_type = ret_type;
+               this.location = location;
+       }
+}
+
+void Error_ExpectingTypeName (Expression expr)
+{
+       if (expr is Invocation){
+               report.Error (1002, expr.Location, "Expecting `;'");
+       } else {
+               expr.Error_InvalidExpressionStatement (report);
+       }
+}
+
+void Error_ParameterModifierNotValid (string modifier, Location loc)
+{
+       report.Error (631, loc, "The parameter modifier `{0}' is not valid in this context",
+                                     modifier);
+}
+
+void Error_DuplicateParameterModifier (Location loc, Parameter.Modifier mod)
+{
+       report.Error (1107, loc, "Duplicate parameter modifier `{0}'",
+               Parameter.GetModifierSignature (mod));
+}
+
+void Error_TypeExpected (Location loc)
+{
+       report.Error (1031, loc, "Type expected");
+}
+
+void Error_UnsafeCodeNotAllowed (Location loc)
+{
+       report.Error (227, loc, "Unsafe code requires the `unsafe' command line option to be specified");
+}
+
+void Warning_EmptyStatement (Location loc)
+{
+       report.Warning (642, 3, loc, "Possible mistaken empty statement");
+}
+
+void Error_NamedArgumentExpected (NamedArgument a)
+{
+       report.Error (1738, a.Location, "Named arguments must appear after the positional arguments");
+}
+
+void Error_MissingInitializer (Location loc)
+{
+       report.Error (210, loc, "You must provide an initializer in a fixed or using statement declaration");
+}
+
+object Error_AwaitAsIdentifier (object token)
+{
+       if (async_block) {
+               report.Error (4003, GetLocation (token), "`await' cannot be used as an identifier within an async method or lambda expression");
+               return new LocatedToken ("await", GetLocation (token));
+       }
+
+       return token;
+}
+
+void push_current_container (TypeDefinition tc, object partial_token)
+{
+       if (module.Evaluator != null){
+               tc.Definition.Modifiers = tc.ModFlags = (tc.ModFlags & ~Modifiers.AccessibilityMask) | Modifiers.PUBLIC;
+               if (undo == null)
+                       undo = new Undo ();
+
+               undo.AddTypeContainer (current_container, tc);
+       }
+       
+       if (is_config_enabled) {
+               if (partial_token != null)
+                       current_container.AddPartial (tc);
+               else
+                       current_container.AddTypeContainer (tc);
+       }
+       
+       is_config_enabled = true;
+               
+       ++lexer.parsing_declaration;
+       current_container = tc;
+       current_type = tc;
+}
+
+TypeContainer pop_current_class ()
+{
+       var retval = current_container;
+
+       current_container = current_container.Parent;
+       current_type = current_type.Parent as TypeDefinition;
+
+       return retval;
+}
+
+[System.Diagnostics.Conditional ("FULL_AST")]
+void StoreModifierLocation (object token, Location loc)
+{
+       if (lbag == null)
+               return;
+
+       if (mod_locations == null)
+               mod_locations = new List<Tuple<Modifiers, Location>> ();
+
+       mod_locations.Add (Tuple.Create ((Modifiers) token, loc));
+}
+
+string CheckAttributeTarget (string a, Location l)
+{
+       switch (a) {
+       case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
+                       return a;
+       }
+
+       report.Warning (658, 1, l,
+                "`{0}' is invalid attribute target. All attributes in this attribute section will be ignored", a);
+       return string.Empty;
+}
+
+bool IsPartial (object a)
+{
+       var attrs = a as Attributes;
+       if (attrs == null)
+               return false;
+       foreach (var attr in attrs.Attrs) {
+               if (attr.TypeExpression.Name == "Partial")
+                       return true;
+       }
+       return false;
+}
+
+static bool IsUnaryOperator (Operator.OpType op)
+{
+       switch (op) {
+               
+       case Operator.OpType.LogicalNot: 
+       case Operator.OpType.OnesComplement: 
+       case Operator.OpType.Increment:
+       case Operator.OpType.Decrement:
+       case Operator.OpType.True: 
+       case Operator.OpType.False: 
+       case Operator.OpType.UnaryPlus: 
+       case Operator.OpType.UnaryNegation:
+               return true;
+       }
+       return false;
+}
+
+void syntax_error (Location l, string msg)
+{
+       report.Error (1003, l, "Syntax error, " + msg);
+}
+
+Tokenizer lexer;
+
+public Tokenizer Lexer {
+       get {
+               return lexer;
+       }
+}                 
+
+public PlayScriptParser (SeekableStreamReader reader, CompilationSourceFile file, ParserSession session)
+       : this (reader, file, file.Compiler.Report, session)
+{
+}
+
+public PlayScriptParser (SeekableStreamReader reader, CompilationSourceFile file, Report report, ParserSession session)
+{
+       this.file = file;
+       current_container = current_namespace = file;
+       
+       this.module = file.Module;
+       this.compiler = file.Compiler;
+       this.settings = compiler.Settings;
+       this.report = report;
+       
+       lang_version = settings.Version;
+       yacc_verbose_flag = settings.VerboseParserFlag;
+       doc_support = settings.DocumentationFile != null;
+       lexer = new Tokenizer (reader, file, session);
+       oob_stack = new Stack<object> ();
+       lbag = session.LocationsBag;
+       use_global_stacks = session.UseJayGlobalArrays;
+       parameters_bucket = session.ParametersStack;
+}
+
+public void parse ()
+{
+       eof_token = Token.EOF;
+       
+       try {
+               if (yacc_verbose_flag > 1)
+                       yyparse (lexer, new yydebug.yyDebugSimple ());
+               else
+                       yyparse (lexer);
+                       
+               Tokenizer tokenizer = lexer as Tokenizer;
+               tokenizer.cleanup ();           
+       } catch (Exception e){
+               if (e is yyParser.yyUnexpectedEof) {
+                       Error_SyntaxError (yyToken);
+                       UnexpectedEOF = true;
+                       return;
+               }
+                       
+               if (e is yyParser.yyException) {
+                       if (report.Errors == 0)
+                               report.Error (-25, lexer.Location, "Parsing error");
+               } else {
+                       // Used by compiler-tester to test internal errors
+                       if (yacc_verbose_flag > 0 || e is FatalException)
+                               throw;
+               
+                       report.Error (589, lexer.Location, "Internal compiler error during parsing" + e);
+               }
+       }
+}
+
+void CheckToken (int error, int yyToken, string msg, Location loc)
+{
+       if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD)
+               report.Error (error, loc, "{0}: `{1}' is a keyword", msg, GetTokenName (yyToken));
+       else
+               report.Error (error, loc, msg);
+}
+
+string ConsumeStoredComment ()
+{
+       string s = tmpComment;
+       tmpComment = null;
+       Lexer.doc_state = XmlCommentState.Allowed;
+       return s;
+}
+
+void FeatureIsNotAvailable (Location loc, string feature)
+{
+       report.FeatureIsNotAvailable (compiler, loc, feature);
+}
+
+Location GetLocation (object obj)
+{
+       var lt = obj as LocatedToken;
+       if (lt != null)
+               return lt.Location;
+               
+       var mn = obj as MemberName;
+       if (mn != null)
+               return mn.Location;
+               
+       var expr = obj as Expression;
+       if (expr != null)
+               return expr.Location;
+
+       return lexer.Location;
+}
+
+void start_block (Location loc)
+{
+       if (current_block == null) {
+               current_block = new ToplevelBlock (compiler, current_local_parameters, loc);
+               parsing_anonymous_method = false;
+       } else if (parsing_anonymous_method) {
+               current_block = new ParametersBlock (current_block, current_local_parameters, loc);
+               parsing_anonymous_method = false;
+       } else {
+               current_block = new ExplicitBlock (current_block, loc, Location.Null);
+       }
+}
+
+Block
+end_block (Location loc)
+{
+       Block retval = current_block.Explicit;
+       retval.SetEndLocation (loc);
+       current_block = retval.Parent;
+       return retval;
+}
+
+void start_anonymous (bool isLambda, ParametersCompiled parameters, FullNamedExpression retType, bool isAsync, Location loc)
+{
+       oob_stack.Push (current_anonymous_method);
+       oob_stack.Push (current_local_parameters);
+       oob_stack.Push (current_variable);
+       oob_stack.Push (async_block);
+       oob_stack.Push (Lexer.AutoSemiInsertion);
+
+       current_local_parameters = parameters;
+       if (isLambda) {
+               if (lang_version <= LanguageVersion.ISO_2)
+                       FeatureIsNotAvailable (loc, "lambda expressions");
+
+               current_anonymous_method = new LambdaExpression (loc);
+       } else {
+               if (lang_version == LanguageVersion.ISO_1)
+                       FeatureIsNotAvailable (loc, "anonymous methods");
+                       
+               current_anonymous_method = new AnonymousMethodExpression (loc); // TODO: they are just explicit parameters , parameters, retType);
+       }
+
+       async_block = isAsync;
+       // Force the next block to be created as a ToplevelBlock
+       parsing_anonymous_method = true;
+}
+
+/*
+ * Completes the anonymous method processing, if lambda_expr is null, this
+ * means that we have a Statement instead of an Expression embedded 
+ */
+AnonymousMethodExpression end_anonymous (ParametersBlock anon_block)
+{
+       AnonymousMethodExpression retval;
+
+       if (async_block)
+               anon_block.IsAsync = true;
+
+       current_anonymous_method.Block = anon_block;
+       retval = current_anonymous_method;
+
+       Lexer.AutoSemiInsertion = (bool) oob_stack.Pop ();
+       async_block = (bool) oob_stack.Pop ();
+       current_variable = (BlockVariable) oob_stack.Pop ();
+       current_local_parameters = (ParametersCompiled) oob_stack.Pop ();
+       current_anonymous_method = (AnonymousMethodExpression) oob_stack.Pop ();
+
+       return retval;
+}
+
+static TypeDefinition GetTypeDefinition (TypeContainer container)
+{
+       var td = container as TypeDefinition;
+       if (td != null)
+               return td;
+
+       Package pkg = (Package) container;
+       return pkg.GetGlobalsTypeDefinition ();
+
+}
+
+void Error_SyntaxError (int token)
+{
+       Error_SyntaxError (0, token);
+}
+
+void Error_SyntaxError (int error_code, int token)
+{
+       Error_SyntaxError (error_code, token, "Unexpected symbol");
+}
+
+void Error_SyntaxError (int error_code, int token, string msg)
+{
+       Lexer.CompleteOnEOF = false;
+
+       // An error message has been reported by tokenizer
+       if (token == Token.ERROR)
+               return;
+       
+       // Avoid duplicit error message after unterminated string literals
+       if (token == Token.LITERAL && lexer.Location.Column == 0)
+               return;
+
+       string symbol = GetSymbolName (token);
+       string expecting = GetExpecting ();
+       var loc = lexer.Location - symbol.Length;
+       
+       if (error_code == 0) {
+               if (expecting == "`identifier'") {
+                       if (token > Token.FIRST_KEYWORD && token < Token.LAST_KEYWORD) {
+                               report.Error (1041, loc, "Identifier expected, `{0}' is a keyword", symbol);
+                               return;
+                       }
+                       
+                       error_code = 1001;
+                       expecting = "identifier";
+               } else if (expecting == "`)'") {
+                       error_code = 1026;
+               } else {
+                       error_code = 1525;
+               }
+       }
+       
+       if (string.IsNullOrEmpty (expecting))
+               report.Error (error_code, loc, "{1} `{0}'", symbol, msg);
+       else
+               report.Error (error_code, loc, "{2} `{0}', expecting {1}", symbol, expecting, msg);       
+}
+
+void CheckIsPlayScript(string elem, Location loc) 
+{
+       if (!parsing_playscript) {
+               report.Error (7035, loc, "`{0}' only supported in PlayScript", elem);
+       }
+
+}
+
+MemberName CreateFullMemberName (LocatedToken lt, TypeParameters tparams = null)
+{
+       if (namespace_modifier != null) {
+               var res = new NamespaceMemberName (namespace_modifier.Value, lt.Value, lt.Location);
+               namespace_modifier = null;
+               return res;
+       }
+
+       return new MemberName (lt.Value, tparams, lt.Location);
+}
+
+/*
+object ConvertAsType(SimpleName sn, object e)
+{
+       if (sn.Name == "Object") 
+               return new TypeExpression (compiler.BuiltinTypes.Dynamic, GetLocation (e));
+       else if (sn.Name == "Boolean") 
+               return new TypeExpression (compiler.BuiltinTypes.Bool, GetLocation (e));
+       else if (sn.Name == "Number")
+               return new TypeExpression (compiler.BuiltinTypes.Double, GetLocation (e));
+       else if (sn.Name == "String")
+               return new TypeExpression (compiler.BuiltinTypes.String, GetLocation (e));
+       else if (sn.Name == "void")
+               return new TypeExpression (compiler.BuiltinTypes.Void, GetLocation (e));
+       else if (sn.Name == "Function")
+               return new TypeExpression (compiler.BuiltinTypes.Delegate, GetLocation (e));
+       else if (sn.Name == "Class")
+               return new TypeExpression (compiler.BuiltinTypes.Type, GetLocation (e));
+       else
+               return e;
+}
+*/
+Statement ExpressionListToStatementList(List<Expression> list)
+{
+       if (list.Count == 1) {
+               return ConvertExpressionToStatement(list[0]);
+       } else if (list.Count > 1) {
+               var sl = new StatementList(ConvertExpressionToStatement(list[0]), ConvertExpressionToStatement(list[1]));
+               for (var i = 2; i < list.Count; i++) {
+                       sl.Add(ConvertExpressionToStatement(list[i]));
+               }
+               return sl;
+       }
+       
+       return new StatementErrorExpression (EmptyExpression.MissingValue);
+}
+
+Statement ConvertExpressionToStatement(Expression ex)
+{
+       Statement ret;
+       ExpressionStatement s = ex as ExpressionStatement;
+       if (s == null) {
+               if (Lexer.ParsingPlayScript) {
+                       ex.Error_InvalidExpressionStatement (report);
+                       ret = new StatementErrorExpression (ex);
+               } else {
+                       ret = new AsNonAssignStatementExpression (ex);
+               }
+       } else {
+               ret = new StatementExpression (s);
+       }
+       return ret;
+}
+
+Expression MakeMonoSimdType(string typeName, Location loc)
+{
+       return new MemberAccess(new MemberAccess(new SimpleName("Mono", loc), "Simd", loc), typeName, loc);
+}
+
+LocalVariable GetOrCreateLocalVariable(Block block, string name, LocalVariable.Flags flags, FullNamedExpression typeExpr, Location loc)
+{
+       INamedBlockVariable existing = null;
+       LocalVariable li = null;
+
+/*
+       if (!parsing_playscript) {
+               if (block.ParametersBlock.TopBlock.GetLocalName (name, block, ref existing)) {
+                       if (existing is LocalVariable) {
+                               li = existing as LocalVariable;
+                               if (li.TypeExpr != null && existing.TypeExpr != null && li.TypeExpr.Equals (existing.TypeExpr)) {
+                                       report.Warning (7138, 1, loc, "Variable is declared more than once.");
+                                       li.DeclFlags |= LocalVariable.Flags.AsIgnoreMultiple;
+                                       return li;
+                               }
+                       }
+               }
+       }
+*/     
+       li = new LocalVariable(block, name, flags, loc);
+//     li.TypeExpr = typeExpr;
+
+       block.AddLocalName (li);
+       
+       return li;
+}
+
+string GetExpecting ()
+{
+       int [] tokens = yyExpectingTokens (yyExpectingState);
+       var names = new List<string> (tokens.Length);
+       bool has_type = false;
+       bool has_identifier = false;
+       for (int i = 0; i < tokens.Length; i++){
+               int token = tokens [i];
+               has_identifier |= token == Token.IDENTIFIER;
+               
+               string name = GetTokenName (token);
+               if (name == "<internal>")
+                       continue;
+                       
+               has_type |= name == "type";
+               if (names.Contains (name))
+                       continue;
+               
+               names.Add (name);
+       }
+
+       //
+       // Too many tokens to enumerate
+       //
+       if (names.Count > 8)
+               return null;
+
+       if (has_type && has_identifier)
+               names.Remove ("identifier");
+
+       if (names.Count == 1)
+               return "`" + GetTokenName (tokens [0]) + "'";
+       
+       StringBuilder sb = new StringBuilder ();
+       names.Sort ();
+       int count = names.Count;
+       for (int i = 0; i < count; i++){
+               bool last = i + 1 == count;
+               if (last)
+                       sb.Append ("or ");
+               sb.Append ('`');
+               sb.Append (names [i]);
+               sb.Append (last ? "'" : count < 3 ? "' " : "', ");
+       }
+       return sb.ToString ();
+}
+
+
+string GetSymbolName (int token)
+{
+       switch (token){
+       case Token.LITERAL:
+               return "Literal " + ((Constant)lexer.Value).GetValue ().ToString ();
+       case Token.IDENTIFIER:
+       case Token.IDENTIFIER_CONFIG:
+               return "Identifier " + ((LocatedToken)lexer.Value).Value ?? "";
+       case Token.BOOL:
+               return "bool";
+       case Token.BOOLEAN:
+               return "boolean";
+       case Token.BYTE:
+               return "byte";
+       case Token.CHAR:
+               return "char";
+       case Token.VOID:
+               return "void";
+       case Token.DECIMAL:
+               return "decimal";
+       case Token.DOUBLE:
+               return "double";
+       case Token.DOUBLE2:
+               return "double2";
+       case Token.DOUBLE3:
+               return "double3";
+       case Token.DOUBLE4:
+               return "double4";
+       case Token.DYNAMIC:
+               return "dynamic";
+       case Token.FLOAT:
+               return "float";
+       case Token.FLOAT2:
+               return "float2";
+       case Token.FLOAT3:
+               return "float3";
+       case Token.FLOAT4:
+               return "float4";
+       case Token.INT:
+               return "int";
+       case Token.LONG:
+               return "long";
+       case Token.SBYTE:
+               return "sbyte";
+       case Token.SHORT:
+               return "short";
+       case Token.STRING:
+               return "string";
+       case Token.UINT:
+               return "uint";
+       case Token.ULONG:
+               return "ulong";
+       case Token.USHORT:
+               return "ushort";
+       case Token.OBJECT:
+               return "object";
+               
+       case Token.PLUS:
+               return "+";
+       case Token.UMINUS:
+       case Token.MINUS:
+               return "-";
+       case Token.BANG:
+               return "!";
+       case Token.BITWISE_AND:
+               return "&";
+       case Token.BITWISE_OR:
+               return "|";
+       case Token.LOGICAL_AND_ASSIGN:
+               return "&&=";
+       case Token.LOGICAL_OR_ASSIGN:
+               return "||=";
+       case Token.STAR:
+               return "*";
+       case Token.PERCENT:
+               return "%";
+       case Token.DIV:
+               return "/";
+       case Token.CARRET:
+               return "^";
+       case Token.OP_INC:
+               return "++";
+       case Token.OP_DEC:
+               return "--";
+       case Token.OP_SHIFT_LEFT:
+               return "<<";
+       case Token.OP_SHIFT_RIGHT:
+               return ">>";
+       case Token.OP_USHIFT_RIGHT:
+               return ">>>";
+       case Token.OP_LT:
+               return "<";
+       case Token.OP_GT:
+               return ">";
+       case Token.OP_LE:
+               return "<=";
+       case Token.OP_GE:
+               return ">=";
+       case Token.OP_EQ:
+               return "==";
+       case Token.OP_REF_EQ:
+               return "===";
+       case Token.OP_NE:
+               return "!=";
+       case Token.OP_AND:
+               return "&&";
+       case Token.OP_OR:
+               return "||";
+       case Token.OP_PTR:
+               return "->";
+       case Token.OP_IN:
+               return "in";
+       case Token.OP_COALESCING:       
+               return "??";
+       case Token.OP_MULT_ASSIGN:
+               return "*=";
+       case Token.OP_DIV_ASSIGN:
+               return "/=";
+       case Token.OP_MOD_ASSIGN:
+               return "%=";
+       case Token.OP_ADD_ASSIGN:
+               return "+=";
+       case Token.OP_SUB_ASSIGN:
+               return "-=";
+       case Token.OP_SHIFT_LEFT_ASSIGN:
+               return "<<=";
+       case Token.OP_SHIFT_RIGHT_ASSIGN:
+               return ">>=";
+       case Token.OP_USHIFT_RIGHT_ASSIGN:
+               return ">>>=";
+       case Token.OP_AND_ASSIGN:
+               return "&=";
+       case Token.OP_XOR_ASSIGN:
+               return "^=";
+       case Token.OP_OR_ASSIGN:
+               return "|=";
+       }
+
+       return GetTokenName (token);
+}
+
+static string GetTokenName (int token)
+{
+       switch (token){
+       case Token.ABSTRACT:
+               return "abstract";
+       case Token.AS:
+               return "as";
+       case Token.ADD:
+               return "add";
+       case Token.ASYNC:
+               return "async";
+       case Token.SUPER:
+               return "super";
+       case Token.BREAK:
+               return "break";
+       case Token.CASE:
+               return "case";
+       case Token.CATCH:
+               return "catch";
+       case Token.CHECKED:
+               return "checked";
+       case Token.CLASS:
+               return "class";
+       case Token.CONST:
+               return "const";
+       case Token.CONTINUE:
+               return "continue";
+       case Token.DEFAULT:
+               return "default";
+       case Token.DELEGATE:
+               return "delegate";
+       case Token.DELETE:
+               return "delete";
+       case Token.DO:
+               return "do";
+       case Token.EACH:
+               return "each";
+       case Token.ELSE:
+               return "else";
+       case Token.ENUM:
+               return "enum";
+       case Token.EVENT:
+               return "event";
+       case Token.EXPLICIT:
+               return "explicit";
+       case Token.EXTENDS:
+               return "extends";
+       case Token.EXTERN:
+               return "extern";
+       case Token.FALSE:
+               return "false";
+       case Token.FINAL:
+               return "final";
+       case Token.FINALLY:
+               return "finally";
+       case Token.FIXED:
+               return "fixed";
+       case Token.FOR:
+               return "for";
+       case Token.FOR_EACH:
+               return "for each";
+       case Token.FUNCTION:
+               return "function";
+       case Token.FUNCTION_GET:
+               return "function get";
+       case Token.FUNCTION_SET:
+               return "function set";
+       case Token.GOTO:
+               return "goto";
+       case Token.IF:
+               return "if";
+       case Token.IMPLEMENTS:
+               return "implements";
+       case Token.IMPLICIT:
+               return "implicit";
+       case Token.IMPORT:
+               return "import";
+       case Token.IN:
+               return "in";
+       case Token.INDEXER:
+               return "indexer";
+       case Token.INSTANCEOF:
+               return "instanceof";
+       case Token.INTERFACE:
+               return "interface";
+       case Token.INTERNAL:
+               return "internal";
+       case Token.IS:
+               return "is";
+       case Token.LOCK:
+               return "lock";
+       case Token.NAMESPACE:
+               return "namespace";
+       case Token.NATIVE:
+               return "native";
+       case Token.NEW:
+               return "new";
+       case Token.NULL:
+               return "null";
+       case Token.OPERATOR:
+               return "operator";
+       case Token.OUT:
+               return "out";
+       case Token.OVERRIDE:
+               return "override";
+       case Token.OVERLOAD:
+               return "overload";
+       case Token.PARAMS:
+               return "params";
+       case Token.PRIVATE:
+               return "private";
+       case Token.PROPERTY:
+               return "property";
+       case Token.PROTECTED:
+               return "protected";
+       case Token.PUBLIC:
+               return "public";
+       case Token.READONLY:
+               return "readonly";
+       case Token.REF:
+               return "ref";
+       case Token.RETURN:
+               return "return";
+       case Token.REMOVE:
+               return "remove";
+       case Token.SIZEOF:
+               return "sizeof";
+       case Token.STACKALLOC:
+               return "stackalloc";
+       case Token.STATIC:
+               return "static";
+       case Token.STRUCT:
+               return "struct";
+       case Token.SWITCH:
+               return "switch";
+       case Token.THIS:
+               return "this";
+       case Token.THROW:
+               return "throw";
+       case Token.TRUE:
+               return "true";
+       case Token.TRY:
+               return "try";
+       case Token.TYPEOF:
+               return "typeof";
+       case Token.UNCHECKED:
+               return "unchecked";
+       case Token.UNSAFE:
+               return "unsafe";
+       case Token.USE:
+               return "use";
+       case Token.USING:
+               return "using";
+       case Token.VAR:
+               return "var";
+       case Token.VIRTUAL:
+               return "virtual";
+       case Token.VOLATILE:
+               return "volatile";
+       case Token.WHERE:
+               return "where";
+       case Token.WHILE:
+               return "while";
+//     case Token.ARGLIST:
+//             return "__arglist";
+//     case Token.REFVALUE:
+//             return "__refvalue";
+//     case Token.REFTYPE:
+//             return "__reftype";
+//     case Token.MAKEREF:
+//             return "__makeref";
+       case Token.PARTIAL:
+               return "partial";
+       case Token.ARROW:
+               return "=>";
+       case Token.FROM:
+       case Token.FROM_FIRST:
+               return "from";
+       case Token.JOIN:
+               return "join";
+       case Token.ON:
+               return "on";
+       case Token.EQUALS:
+               return "equals";
+       case Token.SELECT:
+               return "select";
+       case Token.GROUP:
+               return "group";
+       case Token.BY:
+               return "by";
+       case Token.LET:
+               return "let";
+       case Token.ORDERBY:
+               return "orderby";
+       case Token.ASCENDING:
+               return "ascending";
+       case Token.DESCENDING:
+               return "descending";
+       case Token.INTO:
+               return "into";
+       case Token.GET:
+               return "get";
+       case Token.SET:
+               return "set";
+       case Token.OPEN_BRACE:
+       case Token.OPEN_BRACE_INIT:
+               return "{";
+       case Token.CLOSE_BRACE:
+               return "}";
+       case Token.OPEN_BRACKET:
+       case Token.OPEN_BRACKET_EXPR:
+               return "[";
+       case Token.CLOSE_BRACKET:
+               return "]";
+       case Token.OPEN_PARENS_CAST:
+       case Token.OPEN_PARENS_LAMBDA:
+       case Token.OPEN_PARENS:
+               return "(";
+       case Token.CLOSE_PARENS:
+               return ")";
+       case Token.DOT:
+               return ".";
+       case Token.DOT_AT:
+               return ".@";
+       case Token.DOT_STAR:
+               return ".*";
+       case Token.DOTDOT:
+               return "..";
+       case Token.DOTDOT_AT:
+               return "..@";
+       case Token.DOTDOT_STAR:
+               return "..*";
+       case Token.DOTDOTDOT:
+               return "...";
+       case Token.COMMA:
+               return ",";
+       case Token.DEFAULT_COLON:
+               return "default:";
+       case Token.COLON:
+               return ":";
+       case Token.SEMICOLON:
+               return ";";
+       case Token.TILDE:
+               return "~";
+               
+       case Token.PLUS:
+       case Token.UMINUS:
+       case Token.MINUS:
+       case Token.BANG:
+       case Token.OP_LT:
+       case Token.OP_GT:
+       case Token.BITWISE_AND:
+       case Token.BITWISE_OR:
+       case Token.STAR:
+       case Token.PERCENT:
+       case Token.DIV:
+       case Token.CARRET:
+       case Token.OP_INC:
+       case Token.OP_DEC:
+       case Token.OP_SHIFT_LEFT:
+       case Token.OP_SHIFT_RIGHT:
+       case Token.OP_LE:
+       case Token.OP_GE:
+       case Token.OP_EQ:
+       case Token.OP_NE:
+       case Token.OP_AND:
+       case Token.OP_OR:
+       case Token.OP_PTR:
+       case Token.OP_COALESCING:       
+       case Token.OP_MULT_ASSIGN:
+       case Token.OP_DIV_ASSIGN:
+       case Token.OP_MOD_ASSIGN:
+       case Token.OP_ADD_ASSIGN:
+       case Token.OP_SUB_ASSIGN:
+       case Token.OP_SHIFT_LEFT_ASSIGN:
+       case Token.OP_SHIFT_RIGHT_ASSIGN:
+       case Token.OP_AND_ASSIGN:
+       case Token.OP_XOR_ASSIGN:
+       case Token.OP_OR_ASSIGN:
+       case Token.OP_AT:
+               return "<operator>";
+
+       case Token.BOOL:
+       case Token.BYTE:
+       case Token.CHAR:
+       case Token.VOID:
+       case Token.DECIMAL:
+       case Token.DOUBLE:
+       case Token.FLOAT:
+       case Token.INT:
+       case Token.LONG:
+       case Token.SBYTE:
+       case Token.SHORT:
+       case Token.STRING:
+       case Token.UINT:
+       case Token.ULONG:
+       case Token.USHORT:
+       case Token.OBJECT:
+               return "type";
+       
+       case Token.ASSIGN:
+               return "=";
+       case Token.OP_GENERICS_LT:
+       case Token.GENERIC_DIMENSION:
+               return ".<";
+       case Token.OP_GENERICS_GT:
+               return ">";
+       case Token.INTERR:
+       case Token.INTERR_NULLABLE:
+               return "?";
+       case Token.DOUBLE_COLON:
+               return "::";
+       case Token.LITERAL:
+               return "value";
+       case Token.IDENTIFIER:
+       case Token.AWAIT:
+               return "identifier";
+
+       case Token.EOF:
+               return "end-of-file";
+
+               // All of these are internal.
+       case Token.NONE:
+       case Token.ERROR:
+       case Token.FIRST_KEYWORD:
+       case Token.EVAL_COMPILATION_UNIT_PARSER:
+       case Token.EVAL_USING_DECLARATIONS_UNIT_PARSER:
+       case Token.EVAL_STATEMENT_PARSER:
+       case Token.LAST_KEYWORD:
+       case Token.GENERATE_COMPLETION:
+       case Token.COMPLETE_COMPLETION:
+               return "<internal>";
+
+               // A bit more robust.
+       default:
+               return yyNames [token];
+        }
+}
+
+/* end end end */
+}
diff --git a/mcs/mcs/ps-tokenizer.cs b/mcs/mcs/ps-tokenizer.cs
new file mode 100644 (file)
index 0000000..cc0cdb1
--- /dev/null
@@ -0,0 +1,4356 @@
+//
+// ps-tokenizer.cs: The Tokenizer for the PlayScript compiler
+//                  This also implements the preprocessor
+//
+// Authors: Miguel de Icaza (miguel@gnu.org)
+//         Marek Safar (marek.safar@gmail.com)
+//         Ben Cooley (bcooley@zynga.com)
+//
+// Dual licensed under the terms of the MIT X11 or GNU GPL
+//
+// Copyright 2001, 2002 Ximian, Inc (http://www.ximian.com)
+// Copyright 2004-2008 Novell, Inc
+// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+//
+
+using System;
+using System.Text;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Diagnostics;
+using System.Collections;
+using Mono.CSharp;
+
+namespace Mono.PlayScript
+{
+       /// <summary>
+       ///    Tokenizer for C# source code. 
+       /// </summary>
+
+       public class Tokenizer : yyParser.yyInput
+       {
+               class KeywordEntry<T>
+               {
+                       public readonly T Token;
+                       public KeywordEntry<T> Next;
+                       public readonly char[] Value;
+
+                       public KeywordEntry (string value, T token)
+                       {
+                               this.Value = value.ToCharArray ();
+                               this.Token = token;
+                       }
+               }
+
+               sealed class IdentifiersComparer : IEqualityComparer<char[]>
+               {
+                       readonly int length;
+
+                       public IdentifiersComparer (int length)
+                       {
+                               this.length = length;
+                       }
+
+                       public bool Equals (char[] x, char[] y)
+                       {
+                               for (int i = 0; i < length; ++i)
+                                       if (x [i] != y [i])
+                                               return false;
+
+                               return true;
+                       }
+
+                       public int GetHashCode (char[] obj)
+                       {
+                               int h = 0;
+                               for (int i = 0; i < length; ++i)
+                                       h = (h << 5) - h + obj [i];
+
+                               return h;
+                       }
+               }
+/*
+               //
+               // This class has to be used by parser only, it reuses token
+               // details after each file parse completion
+               //
+               public class LocatedToken : CSharp.Tokenizer.LocatedToken
+               {
+                       public LocatedToken ()
+                       {
+                       }
+
+                       public LocatedToken (string value, Location loc)
+                               : base (value, loc)
+                       {
+                       }
+               }
+*/
+               public class LocatedTokenBuffer : CSharp.Tokenizer.LocatedTokenBuffer
+               {
+                       public LocatedTokenBuffer ()
+                       {
+                       }
+
+                       public LocatedTokenBuffer (LocatedToken[] buffer)
+                               : base (buffer)
+                       {
+                       }
+               }
+
+               public enum PreprocessorDirective
+               {
+                       Invalid = 0,
+
+                       Region = 1,
+                       Endregion = 2,
+                       If = 3 | RequiresArgument,
+                       Endif = 4,
+                       Elif = 5 | RequiresArgument,
+                       Else = 6,
+                       Define = 7 | RequiresArgument,
+                       Undef = 8 | RequiresArgument,
+                       Error = 9,
+                       Warning = 10,
+                       Pragma = 11 | CustomArgumentsParsing,
+                       Line = 12 | CustomArgumentsParsing,
+
+                       CustomArgumentsParsing = 1 << 10,
+                       RequiresArgument = 1 << 11
+               }
+
+               readonly SeekableStreamReader reader;
+               readonly CompilationSourceFile source_file;
+               readonly CompilerContext context;
+
+               SourceFile current_source;
+               Location hidden_block_start;
+               int ref_line = 1;
+               int line = 1;
+               int col = 0;
+               int previous_col;
+               int prev_token;
+               int prev_token_line;
+               int current_token;
+               int current_token_line;
+               int putback_token = -1;
+               int parse_regex_xml = 0;
+               int parse_colon = 0;
+               bool allow_auto_semi = true;
+               int allow_auto_semi_after = 0;
+               bool has_temp_auto_semi_after_tokens = false;
+               List<int> temp_auto_semi_after_tokens = new List<int>();
+               readonly int tab_size;
+               bool parsing_playscript = true;
+               bool handle_get_set = false;
+               bool handle_dynamic = true;
+               bool handle_each = false;
+               bool handle_remove_add = false;
+               bool handle_where = false;
+               bool handle_typeof = false;
+               bool handle_for_in = false;
+               bool lambda_arguments_parsing;
+               List<Location> escaped_identifiers;
+               int parsing_generic_less_than;
+               readonly bool doc_processing;
+               readonly LocatedTokenBuffer ltb;
+
+               private static BitArray allowed_auto_semi_tokens = new BitArray(750, false);  
+               private static BitArray disallowed_next_auto_semi_tokens = new BitArray(750, false);  
+
+               //
+               // Used mainly for parser optimizations. Some expressions for instance
+               // can appear only in block (including initializer, base initializer)
+               // scope only
+               //
+               public int parsing_block;
+               internal bool query_parsing;
+               
+               // 
+               // When parsing type only, useful for ambiguous nullable types
+               //
+               public int parsing_type;
+               
+               //
+               // Set when parsing generic declaration (type or method header)
+               //
+               public bool parsing_generic_declaration;
+               public bool parsing_generic_declaration_doc;
+               
+               //
+               // The value indicates that we have not reach any declaration or
+               // namespace yet
+               //
+               public int parsing_declaration;
+
+               public bool parsing_attribute_section;
+
+               public bool parsing_modifiers;
+
+               //
+               // The special characters to inject on streams to run the unit parser
+               // in the special expression mode. Using private characters from
+               // Plane Sixteen (U+100000 to U+10FFFD)
+               //
+               // This character is only tested just before the tokenizer is about to report
+               // an error;   So on the regular operation mode, this addition will have no
+               // impact on the tokenizer's performance.
+               //
+               
+               public const int EvalStatementParserCharacter = 0x100000;
+               public const int EvalCompilationUnitParserCharacter = 0x100001;
+               public const int EvalUsingDeclarationsParserCharacter = 0x100002;
+               public const int DocumentationXref = 0x100003;
+               
+               //
+               // XML documentation buffer. The save point is used to divide
+               // comments on types and comments on members.
+               //
+               StringBuilder xml_comment_buffer;
+
+               //
+               // See comment on XmlCommentState enumeration.
+               //
+               XmlCommentState xml_doc_state = XmlCommentState.Allowed;
+
+               //
+               // Whether tokens have been seen on this line
+               //
+               bool tokens_seen = false;
+
+               //
+               // Set to true once the GENERATE_COMPLETION token has bee
+               // returned.   This helps produce one GENERATE_COMPLETION,
+               // as many COMPLETE_COMPLETION as necessary to complete the
+               // AST tree and one final EOF.
+               //
+               bool generated;
+               
+               //
+               // Whether a token has been seen on the file
+               // This is needed because `define' is not allowed to be used
+               // after a token has been seen.
+               //
+               bool any_token_seen;
+
+               //
+               // Class variables
+               // 
+               static readonly KeywordEntry<int>[][] keywords;
+               static readonly KeywordEntry<PreprocessorDirective>[][] keywords_preprocessor;
+               static readonly HashSet<string> keyword_strings;
+               static readonly NumberStyles styles;
+               static readonly NumberFormatInfo csharp_format_info;
+
+               // Pragma arguments
+               static readonly char[] pragma_warning = "warning".ToCharArray ();
+               static readonly char[] pragma_warning_disable = "disable".ToCharArray ();
+               static readonly char[] pragma_warning_restore = "restore".ToCharArray ();
+               static readonly char[] pragma_checksum = "checksum".ToCharArray ();
+               static readonly char[] line_hidden = "hidden".ToCharArray ();
+               static readonly char[] line_default = "default".ToCharArray ();
+
+               static readonly char[] simple_whitespaces = new char[] { ' ', '\t' };
+
+               public bool ParsingPlayScript {
+                       get { return parsing_playscript; }
+                       set { parsing_playscript = value; }
+               }
+
+               public bool PropertyParsing {
+                       get { return handle_get_set; }
+                       set { handle_get_set = value; }
+               }
+
+               public bool EventParsing {
+                       get { return handle_remove_add; }
+                       set { handle_remove_add = value; }
+               }
+
+               public bool ConstraintsParsing {
+                       get { return handle_where; }
+                       set { handle_where = value; }
+               }
+
+               public bool TypeOfParsing {
+                       get { return handle_typeof; }
+                       set { handle_typeof = value; }
+               }
+
+               public bool ForInParsing {
+                       get { return handle_for_in; }
+                       set { handle_for_in = value; }
+               }
+
+               public bool DynamicParsing {
+                       get { return handle_dynamic; }
+                       set { handle_dynamic = value; }
+               }
+
+               public bool AutoSemiInsertion {
+                       get { return allow_auto_semi; }
+                       set { 
+                               allow_auto_semi = value; 
+                               allow_auto_semi_after = 0; 
+                       }
+               }
+
+               public int AutoSemiInsertionAfter 
+               {
+                       get { return allow_auto_semi_after; }
+                       set { 
+                               allow_auto_semi = true;
+                               allow_auto_semi_after = value + 1;
+                       }
+               }
+
+               public void AllowAutoSemiAfterToken (int token, bool allow)
+               {
+                       allowed_auto_semi_tokens.Set (token, allow);
+                       if (true) {
+                               has_temp_auto_semi_after_tokens = true;
+                               temp_auto_semi_after_tokens.Add (token);
+                       }
+               }
+
+               public bool RegexXmlParsing {
+                       get { return parse_regex_xml > 0; }
+               }
+
+               public XmlCommentState doc_state {
+                       get { return xml_doc_state; }
+                       set {
+                               if (value == XmlCommentState.Allowed) {
+                                       check_incorrect_doc_comment ();
+                                       reset_doc_comment ();
+                               }
+                               xml_doc_state = value;
+                       }
+               }
+
+               //
+               // This is used to trigger completion generation on the parser
+               public bool CompleteOnEOF;
+               
+               void AddEscapedIdentifier (Location loc)
+               {
+                       if (escaped_identifiers == null)
+                               escaped_identifiers = new List<Location> ();
+
+                       escaped_identifiers.Add (loc);
+               }
+
+               public bool IsEscapedIdentifier (ATypeNameExpression name)
+               {
+                       return escaped_identifiers != null && escaped_identifiers.Contains (name.Location);
+               }
+
+               //
+               // Values for the associated token returned
+               //
+               internal int putback_char;      // Used by repl only
+               object val;
+
+               //
+               // Pre-processor
+               //
+               const int TAKING        = 1;
+               const int ELSE_SEEN     = 4;
+               const int PARENT_TAKING = 8;
+               const int REGION        = 16;           
+
+               //
+               // pre-processor if stack state:
+               //
+               Stack<int> ifstack;
+
+               public const int MaxIdentifierLength = 512;
+               public const int MaxNumberLength = 512;
+
+               readonly char[] id_builder;
+               readonly Dictionary<char[], string>[] identifiers;
+               readonly char[] number_builder;
+               int number_pos;
+
+               char[] value_builder = new char[64];
+
+               public int Line {
+                       get {
+                               return ref_line;
+                       }
+               }
+
+               //
+               // This is used when the tokenizer needs to save
+               // the current position as it needs to do some parsing
+               // on its own to deamiguate a token in behalf of the
+               // parser.
+               //
+               Stack<Position> position_stack = new Stack<Position> (2);
+
+               class Position {
+                       public int position;
+                       public int line;
+                       public int ref_line;
+                       public int col;
+                       public Location hidden;
+                       public int putback_char;
+                       public int previous_col;
+                       public Stack<int> ifstack;
+                       public int parsing_generic_less_than;
+                       public int parse_regex_xml;
+                       public int parse_colon;
+                       public bool allow_auto_semi;
+                       public int allow_auto_semi_after;
+                       public object val;
+                       public int prev_token;
+                       public int prev_token_line;
+                       public int current_token;
+                       public int current_token_line;
+                       public int putback_token;
+
+                       public Position (Tokenizer t)
+                       {
+                               position = t.reader.Position;
+                               line = t.line;
+                               ref_line = t.ref_line;
+                               col = t.col;
+                               hidden = t.hidden_block_start;
+                               putback_char = t.putback_char;
+                               previous_col = t.previous_col;
+                               if (t.ifstack != null && t.ifstack.Count != 0) {
+                                       // There is no simple way to clone Stack<T> all
+                                       // methods reverse the order
+                                       var clone = t.ifstack.ToArray ();
+                                       Array.Reverse (clone);
+                                       ifstack = new Stack<int> (clone);
+                               }
+                               parsing_generic_less_than = t.parsing_generic_less_than;
+                               parse_regex_xml = t.parse_regex_xml;
+                               parse_colon = t.parse_colon;
+                               allow_auto_semi = t.allow_auto_semi;
+                               allow_auto_semi_after = t.allow_auto_semi_after;
+                               prev_token = t.prev_token;
+                               prev_token_line = t.prev_token_line;
+                               current_token = t.current_token;
+                               current_token_line = t.current_token_line;
+                               putback_token = t.putback_token;
+                               val = t.val;
+                       }
+               }
+
+               public Tokenizer (SeekableStreamReader input, CompilationSourceFile file, ParserSession session)
+               {
+                       this.source_file = file;
+                       this.parsing_playscript = true; // file.SourceFile.PsExtended;
+                       this.context = file.Compiler;
+                       this.current_source = file.SourceFile;
+                       this.identifiers = session.Identifiers;
+                       this.id_builder = session.IDBuilder;
+                       this.number_builder = session.NumberBuilder;
+                       this.ltb = new LocatedTokenBuffer (session.LocatedTokens);
+
+                       reader = input;
+
+                       putback_char = -1;
+
+                       xml_comment_buffer = new StringBuilder ();
+                       doc_processing = context.Settings.DocumentationFile != null;
+
+                       tab_size = context.Settings.TabSize;
+               }
+               
+               public void PushPosition ()
+               {
+                       position_stack.Push (new Position (this));
+               }
+
+               public void PopPosition ()
+               {
+                       Position p = position_stack.Pop ();
+
+                       reader.Position = p.position;
+                       ref_line = p.ref_line;
+                       line = p.line;
+                       col = p.col;
+                       hidden_block_start = p.hidden;
+                       putback_char = p.putback_char;
+                       previous_col = p.previous_col;
+                       ifstack = p.ifstack;
+                       parsing_generic_less_than = p.parsing_generic_less_than;
+                       parse_regex_xml = p.parse_regex_xml;
+                       parse_colon = p.parse_colon;
+                       prev_token = p.prev_token;
+                       prev_token_line = p.prev_token_line;
+                       allow_auto_semi = p.allow_auto_semi;
+                       allow_auto_semi_after = p.allow_auto_semi_after;
+                       current_token = p.current_token;
+                       current_token_line = p.current_token_line;
+                       putback_token = p.putback_token;
+                       val = p.val;
+               }
+
+               // Do not reset the position, ignore it.
+               public void DiscardPosition ()
+               {
+                       position_stack.Pop ();
+               }
+               
+               static void AddKeyword (string kw, int token)
+               {
+                       keyword_strings.Add (kw);
+
+                       AddKeyword (keywords, kw, token);
+               }
+
+               static void AddPreprocessorKeyword (string kw, PreprocessorDirective directive)
+               {
+                       AddKeyword (keywords_preprocessor, kw, directive);
+               }
+
+               static void AddKeyword<T> (KeywordEntry<T>[][] keywords, string kw, T token)
+               {
+                       int length = kw.Length;
+                       if (keywords[length] == null) {
+                               keywords[length] = new KeywordEntry<T>['z' - '_' + 1];
+                       }
+
+                       int char_index = kw[0] - '_';
+                       var kwe = keywords[length][char_index];
+                       if (kwe == null) {
+                               keywords[length][char_index] = new KeywordEntry<T> (kw, token);
+                               return;
+                       }
+
+                       while (kwe.Next != null) {
+                               kwe = kwe.Next;
+                       }
+
+                       kwe.Next = new KeywordEntry<T> (kw, token);
+               }
+
+               static void AddAllowedAutoSemiTokens(int[] tokens) {
+                       var len = tokens.Length;
+                       for (var i = 0; i < len; i++) {
+                               allowed_auto_semi_tokens.Set (tokens[i], true);
+                       }
+               }
+
+               static void AddDisallowedNextAutoSemiTokens(int[] tokens) {
+                       var len = tokens.Length;
+                       for (var i = 0; i < len; i++) {
+                               disallowed_next_auto_semi_tokens.Set (tokens[i], true);
+                       }
+               }
+
+               //
+               // Class initializer
+               // 
+               static Tokenizer ()
+               {
+                       keyword_strings = new HashSet<string> ();
+
+                       // 13 is the length of the longest keyword for now
+                       keywords = new KeywordEntry<int>[13][];
+
+                       AddKeyword ("abstract", Token.ABSTRACT);
+                       AddKeyword ("as", Token.AS);
+                       AddKeyword ("add", Token.ADD);
+                       AddKeyword ("bool", Token.BOOL);
+                       AddKeyword ("boolean", Token.BOOLEAN);
+                       AddKeyword ("break", Token.BREAK);
+                       AddKeyword ("byte", Token.BYTE);
+                       AddKeyword ("case", Token.CASE);
+                       AddKeyword ("catch", Token.CATCH);
+                       AddKeyword ("char", Token.CHAR);
+                       AddKeyword ("checked", Token.CHECKED);
+                       AddKeyword ("class", Token.CLASS);
+                       AddKeyword ("const", Token.CONST);
+                       AddKeyword ("continue", Token.CONTINUE);
+                       AddKeyword ("decimal", Token.DECIMAL);
+                       AddKeyword ("default", Token.DEFAULT);
+                       AddKeyword ("delegate", Token.DELEGATE);
+                       AddKeyword ("delete", Token.DELETE);
+                       AddKeyword ("do", Token.DO);
+                       AddKeyword ("double", Token.DOUBLE);
+                       AddKeyword ("double2", Token.DOUBLE2);
+                       AddKeyword ("double3", Token.DOUBLE3);
+                       AddKeyword ("double4", Token.DOUBLE4);
+                       AddKeyword ("dynamic", Token.DYNAMIC);
+                       AddKeyword ("each", Token.EACH);
+                       AddKeyword ("else", Token.ELSE);
+                       AddKeyword ("enum", Token.ENUM);
+                       AddKeyword ("event", Token.EVENT);
+                       AddKeyword ("explicit", Token.EXPLICIT);
+                       AddKeyword ("extends", Token.EXTENDS);
+                       AddKeyword ("extern", Token.EXTERN);
+                       AddKeyword ("false", Token.FALSE);
+                       AddKeyword ("final", Token.FINAL);
+                       AddKeyword ("finally", Token.FINALLY);
+                       AddKeyword ("fixed", Token.FIXED);
+                       AddKeyword ("float", Token.FLOAT);
+                       AddKeyword ("float2", Token.FLOAT2);
+                       AddKeyword ("float3", Token.FLOAT3);
+                       AddKeyword ("float4", Token.FLOAT4);
+                       AddKeyword ("for", Token.FOR);
+                       AddKeyword ("function", Token.FUNCTION);
+                       AddKeyword ("goto", Token.GOTO);
+                       AddKeyword ("get", Token.GET);
+                       AddKeyword ("if", Token.IF);
+                       AddKeyword ("implements", Token.IMPLEMENTS);
+                       AddKeyword ("implicit", Token.IMPLICIT);
+                       AddKeyword ("import", Token.IMPORT);
+                       AddKeyword ("in", Token.IN);
+                       AddKeyword ("indexer", Token.INDEXER);
+                       AddKeyword ("instanceof", Token.INSTANCEOF);
+                       AddKeyword ("int", Token.INT);
+                       AddKeyword ("interface", Token.INTERFACE);
+                       AddKeyword ("internal", Token.INTERNAL);
+                       AddKeyword ("is", Token.IS);
+                       AddKeyword ("lock", Token.LOCK);
+                       AddKeyword ("long", Token.LONG);
+                       AddKeyword ("namespace", Token.NAMESPACE);
+                       AddKeyword ("native", Token.NATIVE);
+                       AddKeyword ("new", Token.NEW);
+                       AddKeyword ("null", Token.NULL);
+                       AddKeyword ("object", Token.OBJECT);
+                       AddKeyword ("operator", Token.OPERATOR);
+                       AddKeyword ("out", Token.OUT);
+                       AddKeyword ("override", Token.OVERRIDE);
+                       AddKeyword ("overload", Token.OVERLOAD);
+                       AddKeyword ("package", Token.PACKAGE);
+                       AddKeyword ("params", Token.PARAMS);
+                       AddKeyword ("property", Token.PROPERTY);
+                       AddKeyword ("private", Token.PRIVATE);
+                       AddKeyword ("protected", Token.PROTECTED);
+                       AddKeyword ("public", Token.PUBLIC);
+                       AddKeyword ("readonly", Token.READONLY);
+                       AddKeyword ("ref", Token.REF);
+                       AddKeyword ("remove", Token.REMOVE);
+                       AddKeyword ("return", Token.RETURN);
+                       AddKeyword ("sbyte", Token.SBYTE);
+                       AddKeyword ("set", Token.SET);
+                       AddKeyword ("short", Token.SHORT);
+                       AddKeyword ("sizeof", Token.SIZEOF);
+                       AddKeyword ("stackalloc", Token.STACKALLOC);
+                       AddKeyword ("static", Token.STATIC);
+                       AddKeyword ("string", Token.STRING);
+                       AddKeyword ("struct", Token.STRUCT);
+                       AddKeyword ("super", Token.SUPER);
+                       AddKeyword ("switch", Token.SWITCH);
+                       AddKeyword ("this", Token.THIS);
+                       AddKeyword ("throw", Token.THROW);
+                       AddKeyword ("true", Token.TRUE);
+                       AddKeyword ("try", Token.TRY);
+                       AddKeyword ("typeof", Token.TYPEOF);
+                       AddKeyword ("uint", Token.UINT);
+                       AddKeyword ("ulong", Token.ULONG);
+                       AddKeyword ("unchecked", Token.UNCHECKED);
+                       AddKeyword ("unsafe", Token.UNSAFE);
+                       AddKeyword ("use", Token.USE);
+                       AddKeyword ("ushort", Token.USHORT);
+                       AddKeyword ("using", Token.USING);
+                       AddKeyword ("var", Token.VAR);
+                       AddKeyword ("virtual", Token.VIRTUAL);
+                       AddKeyword ("void", Token.VOID);
+                       AddKeyword ("volatile", Token.VOLATILE);
+                       AddKeyword ("while", Token.WHILE);
+                       AddKeyword ("partial", Token.PARTIAL);
+                       AddKeyword ("where", Token.WHERE);
+
+                       // LINQ keywords
+                       AddKeyword ("from", Token.FROM);
+                       AddKeyword ("join", Token.JOIN);
+                       AddKeyword ("on", Token.ON);
+                       AddKeyword ("equals", Token.EQUALS);
+                       AddKeyword ("select", Token.SELECT);
+                       AddKeyword ("group", Token.GROUP);
+                       AddKeyword ("by", Token.BY);
+                       AddKeyword ("let", Token.LET);
+                       AddKeyword ("orderby", Token.ORDERBY);
+                       AddKeyword ("ascending", Token.ASCENDING);
+                       AddKeyword ("descending", Token.DESCENDING);
+                       AddKeyword ("into", Token.INTO);
+
+                       // Contextual async keywords
+                       AddKeyword ("async", Token.ASYNC);
+                       AddKeyword ("await", Token.AWAIT);
+
+                       keywords_preprocessor = new KeywordEntry<PreprocessorDirective>[10][];
+
+                       AddPreprocessorKeyword ("region", PreprocessorDirective.Region);
+                       AddPreprocessorKeyword ("endregion", PreprocessorDirective.Endregion);
+                       AddPreprocessorKeyword ("if", PreprocessorDirective.If);
+                       AddPreprocessorKeyword ("endif", PreprocessorDirective.Endif);
+                       AddPreprocessorKeyword ("elif", PreprocessorDirective.Elif);
+                       AddPreprocessorKeyword ("else", PreprocessorDirective.Else);
+                       AddPreprocessorKeyword ("define", PreprocessorDirective.Define);
+                       AddPreprocessorKeyword ("undef", PreprocessorDirective.Undef);
+                       AddPreprocessorKeyword ("error", PreprocessorDirective.Error);
+                       AddPreprocessorKeyword ("warning", PreprocessorDirective.Warning);
+                       AddPreprocessorKeyword ("pragma", PreprocessorDirective.Pragma);
+                       AddPreprocessorKeyword ("line", PreprocessorDirective.Line);
+
+                       // Semicolons will be auto-inserted after these tokens by default (unless manually disabled by the parser).
+                       AddAllowedAutoSemiTokens(new int [] {
+                               Token.CLOSE_BRACKET,
+                               Token.CLOSE_PARENS,
+                               Token.IDENTIFIER,
+                               Token.LITERAL,
+                               Token.OP_INC,
+                               Token.OP_DEC,
+                               Token.TRUE,
+                               Token.FALSE,
+                               Token.NULL,
+                               Token.CHAR,
+                               Token.INT,
+                               Token.UINT,
+                               Token.OBJECT,
+                               Token.DECIMAL,
+                               Token.BYTE,
+                               Token.SBYTE,
+                               Token.LONG,
+                               Token.ULONG,
+                               Token.VOID,
+                               Token.DOUBLE,
+                               Token.DOUBLE2,
+                               Token.DOUBLE3,
+                               Token.DOUBLE4,
+                               Token.FLOAT,
+                               Token.FLOAT2,
+                               Token.FLOAT3,
+                               Token.FLOAT4,
+                               Token.STRING,
+                               Token.BOOL,
+                               Token.BOOLEAN,
+                               Token.SHORT,
+                               Token.USHORT,
+                               Token.BREAK,
+                               Token.CONTINUE,
+                               Token.RETURN,
+                               Token.STAR
+                       });
+
+                       AddDisallowedNextAutoSemiTokens(new int [] {
+                               Token.ADD,
+                               Token.MINUS,
+                               Token.DIV,
+                               Token.PERCENT,
+                               Token.STAR,
+                               Token.DOT,
+                               Token.DOT_AT,
+                               Token.DOT_STAR,
+                               Token.DOTDOT,
+                               Token.DOTDOT_AT,
+                               Token.DOTDOT_STAR,
+                               Token.OP_SHIFT_LEFT,
+                               Token.OP_SHIFT_RIGHT,
+                               Token.OP_USHIFT_RIGHT,
+                               Token.LOGICAL_AND_ASSIGN,
+                               Token.LOGICAL_OR_ASSIGN,
+                               Token.CLOSE_BRACKET,
+                               Token.CLOSE_PARENS,
+                               Token.OP_ADD_ASSIGN,
+                               Token.OP_AT,
+                               Token.OP_IN,
+                               Token.AS,
+                               Token.IN,
+                               Token.ARROW,
+                               Token.ASSIGN,
+                               Token.COLON,
+                               Token.COMMA,
+                               Token.OP_ADD_ASSIGN,
+                               Token.OP_SUB_ASSIGN,
+                               Token.OP_MOD_ASSIGN,
+                               Token.OP_MULT_ASSIGN,
+                               Token.OP_DIV_ASSIGN,
+                               Token.OP_COALESCING,
+                               Token.OP_AND_ASSIGN,
+                               Token.OP_OR_ASSIGN,
+                               Token.OP_XOR_ASSIGN,
+                               Token.OP_SHIFT_LEFT_ASSIGN,
+                               Token.OP_SHIFT_RIGHT_ASSIGN,
+                               Token.OP_USHIFT_RIGHT_ASSIGN,
+                               Token.OP_EQ,
+                               Token.OP_NE,
+                               Token.OP_REF_EQ,
+                               Token.OP_REF_NE,
+                               Token.OP_LT,
+                               Token.OP_GT,
+                               Token.OP_GE,
+                               Token.OP_LE,
+                               Token.OP_AND,
+                               Token.OP_OR,
+                               Token.BITWISE_AND,
+                               Token.BITWISE_OR,
+                               Token.CARRET,
+                               Token.INTERR,
+
+                       });
+
+                       csharp_format_info = NumberFormatInfo.InvariantInfo;
+                       styles = NumberStyles.Float;
+               }
+
+               int GetKeyword (char[] id, int id_len)
+               {
+                       //
+                       // Keywords are stored in an array of arrays grouped by their
+                       // length and then by the first character
+                       //
+                       if (id_len >= keywords.Length || keywords [id_len] == null)
+                               return -1;
+
+                       int first_index = id [0] - '_';
+                       if (first_index > 'z' - '_')
+                               return -1;
+
+                       var kwe = keywords [id_len] [first_index];
+                       if (kwe == null)
+                               return -1;
+
+                       int res;
+                       do {
+                               res = kwe.Token;
+                               for (int i = 1; i < id_len; ++i) {
+                                       if (id [i] != kwe.Value [i]) {
+                                               res = 0;
+                                               kwe = kwe.Next;
+                                               break;
+                                       }
+                               }
+                       } while (res == 0 && kwe != null);
+
+                       if (res == 0)
+                               return -1;
+
+                       int next_token;
+                       switch (res) {
+                       case Token.FOR:
+                               this.handle_each = true;
+                               next_token = peek_token ();
+                               if (next_token == Token.EACH) {
+                                       token ();
+                                       res = Token.FOR_EACH;
+                               }
+                               this.handle_each = false;
+                               break;
+                       case Token.FUNCTION:
+                               parsing_modifiers = false;
+                               allow_auto_semi = false;
+                               allow_auto_semi_after = 0;
+                               bool is_get_set = false;
+                               PushPosition();
+                               var fn_token = token ();
+                               if (fn_token == Token.IDENTIFIER)
+                               {
+                                       var get_set = (string)((LocatedToken)val).Value;
+                                       if (get_set == "get" || get_set == "set") {
+                                               fn_token = token ();
+                                               if (fn_token == Token.IDENTIFIER) {
+                                                       res = (get_set == "get") ? Token.FUNCTION_GET : Token.FUNCTION_SET;
+                                               }
+                                       }
+                               }
+                               PopPosition ();
+                               if (res != Token.FUNCTION) 
+                                       token ();
+                               break;
+                       case Token.GET:
+                       case Token.SET:
+                               if (!handle_get_set)
+                                       res = -1;
+                               break;
+                       case Token.IF:
+                       case Token.WHILE:
+                       case Token.DO:
+                       case Token.TRY:
+                       case Token.CATCH:
+                       case Token.SWITCH:
+                       case Token.CASE:
+                               allow_auto_semi = false;
+                               allow_auto_semi_after = 0;
+                               break;
+                       case Token.DYNAMIC:
+                               if (!handle_dynamic)
+                                       res = -1;
+                               break;
+                       case Token.EACH:
+                               if (!handle_each)
+                                       res = -1;
+                               break;
+                       case Token.REMOVE:
+                       case Token.ADD:
+                               if (!handle_remove_add || !parsing_playscript)
+                                       res = -1;
+                               break;
+                       case Token.EXTERN:
+                               if (parsing_declaration != 0 || !parsing_playscript)
+                                       res = -1;
+                               break;
+                       case Token.DEFAULT:
+                               if (peek_token () == Token.COLON) {
+                                       token ();
+                                       res = Token.DEFAULT_COLON;
+                               }
+                               break;
+                       case Token.WHERE:
+                               if (!handle_where && !query_parsing || !parsing_playscript)
+                                       res = -1;
+                               break;
+                       case Token.FROM:
+                               //
+                               // A query expression is any expression that starts with `from identifier'
+                               // followed by any token except ; , =
+                               // 
+                               if (!parsing_playscript) {
+                                       res = -1;
+                               } else if (!query_parsing) {
+                                       if (lambda_arguments_parsing) {
+                                               res = -1;
+                                               break;
+                                       }
+
+                                       PushPosition ();
+                                       // HACK: to disable generics micro-parser, because PushPosition does not
+                                       // store identifiers array
+                                       parsing_generic_less_than = 1;
+                                       switch (xtoken ()) {
+                                       case Token.IDENTIFIER:
+                                       case Token.INT:
+                                       case Token.BOOL:
+                                       case Token.BYTE:
+                                       case Token.CHAR:
+                                       case Token.DECIMAL:
+                                       case Token.FLOAT:
+                                       case Token.LONG:
+                                       case Token.OBJECT:
+                                       case Token.STRING:
+                                       case Token.UINT:
+                                       case Token.ULONG:
+                                               next_token = xtoken ();
+                                               if (next_token == Token.SEMICOLON || next_token == Token.COMMA || next_token == Token.EQUALS)
+                                                       goto default;
+                                               
+                                               res = Token.FROM_FIRST;
+                                               query_parsing = true;
+                                               if (context.Settings.Version <= LanguageVersion.ISO_2)
+                                                       Report.FeatureIsNotAvailable (context, Location, "query expressions");
+                                               break;
+                                       case Token.VOID:
+                                               Expression.Error_VoidInvalidInTheContext (Location, Report);
+                                               break;
+                                       default:
+                                               PopPosition ();
+                                               // HACK: A token is not a keyword so we need to restore identifiers buffer
+                                               // which has been overwritten before we grabbed the identifier
+                                               id_builder [0] = 'f'; id_builder [1] = 'r'; id_builder [2] = 'o'; id_builder [3] = 'm';
+                                               return -1;
+                                       }
+                                       PopPosition ();
+                               }
+                               break;
+                       case Token.JOIN:
+                       case Token.ON:
+                       case Token.EQUALS:
+                       case Token.SELECT:
+                       case Token.GROUP:
+                       case Token.BY:
+                       case Token.LET:
+                       case Token.ORDERBY:
+                       case Token.ASCENDING:
+                       case Token.DESCENDING:
+                       case Token.INTO:
+                               if (!query_parsing || !parsing_playscript)
+                                       res = -1;
+                               break;
+
+                       case Token.IN:
+                               if (!handle_for_in)
+                                       res = Token.OP_IN;
+                               break;
+
+                       case Token.USING:
+                               // TODO: some explanation needed
+                               check_incorrect_doc_comment ();
+                               break;
+                               
+                       case Token.PARTIAL:
+                               if (parsing_block > 0 || !parsing_playscript) {
+                                       res = -1;
+                                       break;
+                               }
+
+                               // Save current position and parse next token.
+                               PushPosition ();
+
+                               next_token = token ();
+                               bool ok = (next_token == Token.CLASS) ||
+                                       (next_token == Token.STRUCT) ||
+                                       (next_token == Token.INTERFACE) ||
+                                       (next_token == Token.VOID);
+
+                               PopPosition ();
+
+                               if (ok) {
+                                       if (next_token == Token.VOID) {
+                                               if (context.Settings.Version <= LanguageVersion.ISO_2)
+                                                       Report.FeatureIsNotAvailable (context, Location, "partial methods");
+                                       } else if (context.Settings.Version == LanguageVersion.ISO_1)
+                                               Report.FeatureIsNotAvailable (context, Location, "partial types");
+
+                                       return res;
+                               }
+
+                               if (next_token < Token.LAST_KEYWORD) {
+                                       Report.Error (267, Location,
+                                               "The `partial' modifier can be used only immediately before `class', `struct', `interface', or `void' keyword");
+                                       return token ();
+                               }                                       
+
+                               res = -1;
+                               break;
+
+                       case Token.ASYNC:
+                               if (!parsing_playscript) {
+                                       return -1;
+                               } else if (parsing_modifiers) {
+                                       //
+                                       // Skip attributes section or constructor called async
+                                       //
+                                       if (parsing_attribute_section || peek_token () == Token.OPEN_PARENS) {
+                                               res = -1;
+                                       } else {
+                                               // async is keyword
+                                       }
+                               } else if (parsing_block > 0) {
+                                       switch (peek_token ()) {
+                                       case Token.DELEGATE:
+                                       case Token.OPEN_PARENS_LAMBDA:
+                                               // async is keyword
+                                               break;
+                                       case Token.IDENTIFIER:
+                                               PushPosition ();
+                                               xtoken ();
+                                               if (xtoken () != Token.ARROW)
+                                                       res = -1;
+
+                                               PopPosition ();
+                                               break;
+                                       default:
+                                               res = -1;
+                                               break;
+                                       }
+                               } else {
+                                       res = -1;
+                               }
+
+                               if (res == Token.ASYNC && context.Settings.Version <= LanguageVersion.V_4) {
+                                       Report.FeatureIsNotAvailable (context, Location, "asynchronous functions");
+                               }
+                               
+                               break;
+
+                       case Token.AWAIT:
+                               if (parsing_block == 0 || !parsing_playscript)
+                                       res = -1;
+
+                               break;
+
+                               // PLAYSCRIPT Extension Type keywords
+                       case Token.BOOL:
+                       case Token.CHAR:
+                       case Token.BYTE:
+                       case Token.SBYTE:
+                       case Token.DECIMAL:
+                       case Token.OBJECT:
+                       case Token.STRING:
+                       case Token.LONG:
+                       case Token.ULONG:
+                       case Token.SHORT:
+                       case Token.USHORT:
+                       case Token.FLOAT:
+                       case Token.FLOAT2:
+                       case Token.FLOAT3:
+                       case Token.FLOAT4:
+                       case Token.DOUBLE:
+                       case Token.DOUBLE2:
+                       case Token.DOUBLE3:
+                       case Token.DOUBLE4:
+                               if (!parsing_playscript)
+                                       res = -1;
+
+                               break;
+
+                               // PLAYSCRIPT Extension keywords
+                       case Token.CHECKED:
+                       case Token.EXPLICIT:
+                       case Token.IMPLICIT:
+                       case Token.OVERLOAD:
+                       case Token.LOCK:
+                       case Token.OUT:
+                       case Token.PARAMS:
+                       case Token.READONLY:
+                       case Token.REF:
+                       case Token.UNCHECKED:
+                       case Token.UNSAFE:
+                       case Token.FIXED:
+                       case Token.GOTO:
+                               if (!parsing_playscript)
+                                       res = -1;
+
+                               break;
+
+                       case Token.EVENT:
+                       case Token.INDEXER:
+                       case Token.OPERATOR:
+                       case Token.PROPERTY:
+                               if (!parsing_playscript)
+                                       res = -1;
+                               else
+                                       parsing_modifiers = false;
+                               
+                               break;
+
+                       case Token.STRUCT:
+                       case Token.DELEGATE:
+                       case Token.ENUM:
+                               if (!parsing_playscript)
+                                       res = -1;
+                               else
+                                       parsing_modifiers = false;
+                               
+                               break;
+
+                       case Token.CLASS:
+                       case Token.INTERFACE:
+                               parsing_modifiers = false;
+                               break;
+
+                       }
+
+
+                       return res;
+               }
+
+               static PreprocessorDirective GetPreprocessorDirective (char[] id, int id_len)
+               {
+                       //
+                       // Keywords are stored in an array of arrays grouped by their
+                       // length and then by the first character
+                       //
+                       if (id_len >= keywords_preprocessor.Length || keywords_preprocessor[id_len] == null)
+                               return PreprocessorDirective.Invalid;
+
+                       int first_index = id[0] - '_';
+                       if (first_index > 'z' - '_')
+                               return PreprocessorDirective.Invalid;
+
+                       var kwe = keywords_preprocessor[id_len][first_index];
+                       if (kwe == null)
+                               return PreprocessorDirective.Invalid;
+
+                       PreprocessorDirective res = PreprocessorDirective.Invalid;
+                       do {
+                               res = kwe.Token;
+                               for (int i = 1; i < id_len; ++i) {
+                                       if (id[i] != kwe.Value[i]) {
+                                               res = 0;
+                                               kwe = kwe.Next;
+                                               break;
+                                       }
+                               }
+                       } while (res == PreprocessorDirective.Invalid && kwe != null);
+
+                       return res;
+               }
+
+               public Location Location {
+                       get {
+                               return new Location (current_source, ref_line, col);
+                       }
+               }
+
+               static bool is_identifier_start_character (int c)
+               {
+                       return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || Char.IsLetter ((char)c);
+               }
+
+               static bool is_identifier_part_character (char c)
+               {
+                       if (c >= 'a' && c <= 'z')
+                               return true;
+
+                       if (c >= 'A' && c <= 'Z')
+                               return true;
+
+                       if (c == '_' || c == '$' || (c >= '0' && c <= '9'))
+                               return true;
+
+                       if (c < 0x80)
+                               return false;
+
+                       return Char.IsLetter (c) || Char.GetUnicodeCategory (c) == UnicodeCategory.ConnectorPunctuation;
+               }
+
+               public static bool IsKeyword (string s)
+               {
+                       return keyword_strings.Contains (s);
+               }
+
+               //
+               // Open parens micro parser. Detects both lambda and cast ambiguity.
+               //      
+               int TokenizeOpenParens ()
+               {
+                       int ptoken;
+                       current_token = -1;
+                       current_token_line = 0;
+
+                       int bracket_level = 0;
+                       bool is_type = false;
+                       bool can_be_type = false;
+                       
+                       while (true) {
+                               ptoken = current_token;
+                               token ();
+
+                               switch (current_token) {
+                               case Token.CLOSE_PARENS:
+                                       token ();
+                                       
+                                       //
+                                       // Expression inside parens is lambda, (int i) => 
+                                       //
+                                       if (current_token == Token.ARROW)
+                                               return Token.OPEN_PARENS_LAMBDA;
+
+//                                     //
+//                                     // Expression inside parens is single type, (int[])
+//                                     //
+//                                     if (is_type)
+//                                             return Token.OPEN_PARENS_CAST;
+//
+//                                     //
+//                                     // Expression is possible cast, look at next token, (T)null
+//                                     //
+//                                     if (can_be_type) {
+//                                             switch (current_token) {
+//                                             case Token.OPEN_PARENS:
+//                                             case Token.BANG:
+//                                             case Token.TILDE:
+//                                             case Token.IDENTIFIER:
+//                                             case Token.LITERAL:
+//                                             case Token.SUPER:
+//                                             case Token.CHECKED:
+//                                             case Token.DELEGATE:
+//                                             case Token.FALSE:
+//                                             case Token.FIXED:
+//                                             case Token.NEW:
+//                                             case Token.NULL:
+//                                             case Token.SIZEOF:
+//                                             case Token.THIS:
+//                                             case Token.THROW:
+//                                             case Token.TRUE:
+//                                             case Token.TYPEOF:
+//                                             case Token.UNCHECKED:
+//                                             case Token.UNSAFE:
+//                                             case Token.DEFAULT:
+//                                             case Token.AWAIT:
+//
+//                                             //
+//                                             // These can be part of a member access
+//                                             //
+//                                             case Token.INT:
+//                                             case Token.UINT:
+//                                             case Token.SHORT:
+//                                             case Token.USHORT:
+//                                             case Token.LONG:
+//                                             case Token.ULONG:
+//                                             case Token.DOUBLE:
+//                                             case Token.FLOAT:
+//                                             case Token.CHAR:
+//                                             case Token.BYTE:
+//                                             case Token.DECIMAL:
+//                                             case Token.BOOL:
+//                                                     return Token.OPEN_PARENS_CAST;
+//                                             }
+//                                     }
+                                       return Token.OPEN_PARENS;
+                                       
+                               case Token.DOT:
+                               case Token.DOUBLE_COLON:
+                                       if (ptoken != Token.IDENTIFIER && ptoken != Token.OP_GENERICS_GT)
+                                               goto default;
+
+                                       continue;
+
+                               case Token.IDENTIFIER:
+                                       switch (ptoken) {
+                                       case Token.DOT:
+                                               if (bracket_level == 0) {
+                                                       is_type = false;
+                                                       can_be_type = true;
+                                               }
+
+                                               continue;
+                                       case Token.OP_GENERICS_LT:
+                                       case Token.COMMA:
+                                       case Token.DOUBLE_COLON:
+                                       case -1:
+                                               if (bracket_level == 0)
+                                                       can_be_type = true;
+                                               continue;
+                                       default:
+                                               can_be_type = is_type = false;
+                                               continue;
+                                       }
+
+                               case Token.OBJECT:
+                               case Token.STRING:
+                               case Token.BOOL:
+                               case Token.DECIMAL:
+                               case Token.FLOAT:
+                               case Token.DOUBLE:
+                               case Token.SBYTE:
+                               case Token.BYTE:
+                               case Token.SHORT:
+                               case Token.USHORT:
+                               case Token.INT:
+                               case Token.UINT:
+                               case Token.LONG:
+                               case Token.ULONG:
+                               case Token.CHAR:
+                               case Token.VOID:
+                                       if (bracket_level == 0)
+                                               is_type = true;
+                                       continue;
+
+                               case Token.COMMA:
+                                       if (bracket_level == 0) {
+                                               bracket_level = 100;
+                                               can_be_type = is_type = false;
+                                       }
+                                       continue;
+
+                               case Token.OP_GENERICS_LT:
+                               case Token.OPEN_BRACKET:
+                                       if (bracket_level++ == 0)
+                                               is_type = true;
+                                       continue;
+
+                               case Token.OP_GENERICS_GT:
+                               case Token.CLOSE_BRACKET:
+                                       --bracket_level;
+                                       continue;
+
+                               case Token.INTERR_NULLABLE:
+                               case Token.STAR:
+                                       if (bracket_level == 0)
+                                               is_type = true;
+                                       continue;
+
+                               case Token.REF:
+                               case Token.OUT:
+                                       can_be_type = is_type = false;
+                                       continue;
+
+                               default:
+                                       return Token.OPEN_PARENS;
+                               }
+                       }
+               }
+
+               public static bool IsValidIdentifier (string s)
+               {
+                       if (s == null || s.Length == 0)
+                               return false;
+
+                       if (!is_identifier_start_character (s [0]))
+                               return false;
+                       
+                       for (int i = 1; i < s.Length; i ++)
+                               if (! is_identifier_part_character (s [i]))
+                                       return false;
+                       
+                       return true;
+               }
+
+               bool parse_less_than ()
+               {
+               start:
+                       int the_token = token ();
+                       if (the_token == Token.OPEN_BRACKET) {
+                               do {
+                                       the_token = token ();
+                               } while (the_token != Token.CLOSE_BRACKET);
+                               the_token = token ();
+                       } else if (the_token == Token.IN || the_token == Token.OUT) {
+                               the_token = token ();
+                       }
+                       switch (the_token) {
+                       case Token.IDENTIFIER:
+                       case Token.OBJECT:
+                       case Token.STRING:
+                       case Token.BOOL:
+                       case Token.DECIMAL:
+                       case Token.FLOAT:
+                       case Token.DOUBLE:
+                       case Token.SBYTE:
+                       case Token.BYTE:
+                       case Token.SHORT:
+                       case Token.USHORT:
+                       case Token.INT:
+                       case Token.UINT:
+                       case Token.LONG:
+                       case Token.ULONG:
+                       case Token.CHAR:
+                       case Token.VOID:
+                               break;
+                       case Token.OP_GENERICS_GT:
+                       case Token.IN:
+                       case Token.OUT:
+                               return true;
+
+                       default:
+                               return false;
+                       }
+               again:
+                       the_token = token ();
+
+                       if (the_token == Token.OP_GENERICS_GT)
+                               return true;
+                       else if (the_token == Token.COMMA || the_token == Token.DOT || the_token == Token.DOUBLE_COLON)
+                               goto start;
+                       else if (the_token == Token.INTERR_NULLABLE || the_token == Token.STAR)
+                               goto again;
+                       else if (the_token == Token.OP_GENERICS_LT) {
+                               if (!parse_less_than ())
+                                       return false;
+                               goto again;
+                       } else if (the_token == Token.OPEN_BRACKET) {
+                       rank_specifiers:
+                               the_token = token ();
+                               if (the_token == Token.CLOSE_BRACKET)
+                                       goto again;
+                               else if (the_token == Token.COMMA)
+                                       goto rank_specifiers;
+                               return false;
+                       }
+
+                       return false;
+               }
+
+               bool parse_generic_dimension (out int dimension)
+               {
+                       dimension = 1;
+
+               again:
+                       int the_token = token ();
+                       if (the_token == Token.OP_GENERICS_GT)
+                               return true;
+                       else if (the_token == Token.COMMA) {
+                               dimension++;
+                               goto again;
+                       }
+
+                       return false;
+               }
+               
+               public int peek_token ()
+               {
+                       int the_token;
+
+                       PushPosition ();
+                       the_token = token ();
+                       PopPosition ();
+                       
+                       return the_token;
+               }
+                                       
+               //
+               // Tonizes `?' using custom disambiguous rules to return one
+               // of following tokens: INTERR_NULLABLE, OP_COALESCING, INTERR
+               //
+               // Tricky expression look like:
+               //
+               // Foo ? a = x ? b : c;
+               //
+               int TokenizePossibleNullableType ()
+               {
+                       if (parsing_block == 0 || parsing_type > 0)
+                               return Token.INTERR_NULLABLE;
+
+                       int d = peek_char ();
+                       if (d == '?') {
+                               get_char ();
+                               return Token.OP_COALESCING;
+                       }
+
+                       switch (current_token) {
+                       case Token.CLOSE_PARENS:
+                       case Token.TRUE:
+                       case Token.FALSE:
+                       case Token.NULL:
+                       case Token.LITERAL:
+                               return Token.INTERR;
+                       }
+
+                       if (d != ' ') {
+                               if (d == ',' || d == ';' || d == '>')
+                                       return Token.INTERR_NULLABLE;
+                               if (d == '*' || (d >= '0' && d <= '9'))
+                                       return Token.INTERR;
+                       }
+
+                       PushPosition ();
+//                     current_token = Token.NONE;  // Doesn't work with auto semi-insertion - needs prev token history always
+                       int next_token;
+                       switch (xtoken ()) {
+                       case Token.LITERAL:
+                       case Token.TRUE:
+                       case Token.FALSE:
+                       case Token.NULL:
+                       case Token.THIS:
+                       case Token.NEW:
+                               next_token = Token.INTERR;
+                               break;
+                               
+                       case Token.SEMICOLON:
+                       case Token.COMMA:
+                       case Token.CLOSE_PARENS:
+                       case Token.OPEN_BRACKET:
+                       case Token.OP_GENERICS_GT:
+                       case Token.INTERR:
+                               next_token = Token.INTERR_NULLABLE;
+                               break;
+                               
+                       default:
+                               next_token = -1;
+                               break;
+                       }
+
+                       if (next_token == -1) {
+                               switch (xtoken ()) {
+                               case Token.COMMA:
+                               case Token.SEMICOLON:
+                               case Token.OPEN_BRACE:
+                               case Token.CLOSE_PARENS:
+                               case Token.IN:
+                                       next_token = Token.INTERR_NULLABLE;
+                                       break;
+                                       
+                               case Token.COLON:
+                                       next_token = Token.INTERR;
+                                       break;                                                  
+                                       
+                               default:
+                                       int ntoken;
+                                       int interrs = 1;
+                                       int colons = 0;
+                                       int braces = 0;
+                                       //
+                                       // All shorcuts failed, do it hard way
+                                       //
+                                       while ((ntoken = xtoken ()) != Token.EOF) {
+                                               if (ntoken == Token.OPEN_BRACE) {
+                                                       ++braces;
+                                                       continue;
+                                               }
+
+                                               if (ntoken == Token.CLOSE_BRACE) {
+                                                       --braces;
+                                                       continue;
+                                               }
+
+                                               if (braces != 0)
+                                                       continue;
+
+                                               if (ntoken == Token.SEMICOLON)
+                                                       break;
+                                               
+                                               if (ntoken == Token.COLON) {
+                                                       if (++colons == interrs)
+                                                               break;
+                                                       continue;
+                                               }
+                                               
+                                               if (ntoken == Token.INTERR) {
+                                                       ++interrs;
+                                                       continue;
+                                               }
+                                       }
+                                       
+                                       next_token = colons != interrs && braces == 0 ? Token.INTERR_NULLABLE : Token.INTERR;
+                                       break;
+                               }
+                       }
+                       
+                       PopPosition ();
+                       return next_token;
+               }
+
+               bool decimal_digits (int c)
+               {
+                       int d;
+                       bool seen_digits = false;
+                       
+                       if (c != -1){
+                               if (number_pos == MaxNumberLength)
+                                       Error_NumericConstantTooLong ();
+                               number_builder [number_pos++] = (char) c;
+                       }
+                       
+                       //
+                       // We use peek_char2, because decimal_digits needs to do a 
+                       // 2-character look-ahead (5.ToString for example).
+                       //
+                       while ((d = peek_char2 ()) != -1){
+                               if (d >= '0' && d <= '9'){
+                                       if (number_pos == MaxNumberLength)
+                                               Error_NumericConstantTooLong ();
+                                       number_builder [number_pos++] = (char) d;
+                                       get_char ();
+                                       seen_digits = true;
+                               } else
+                                       break;
+                       }
+                       
+                       return seen_digits;
+               }
+
+               static bool is_hex (int e)
+               {
+                       return (e >= '0' && e <= '9') || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
+               }
+
+               static TypeCode real_type_suffix (int c)
+               {
+                       switch (c){
+                       case 'F': case 'f':
+                               return TypeCode.Single;
+                       case 'D': case 'd':
+                               return TypeCode.Double;
+                       case 'M': case 'm':
+                               return TypeCode.Decimal;
+                       default:
+                               return TypeCode.Empty;
+                       }
+               }
+
+               ILiteralConstant integer_type_suffix (ulong ul, int c, Location loc)
+               {
+                       bool is_unsigned = false;
+                       bool is_long = false;
+
+                       if (c != -1){
+                               bool scanning = true;
+                               do {
+                                       switch (c){
+                                       case 'U': case 'u':
+                                               if (is_unsigned)
+                                                       scanning = false;
+                                               is_unsigned = true;
+                                               get_char ();
+                                               break;
+
+                                       case 'l':
+                                               if (!is_unsigned){
+                                                       //
+                                                       // if we have not seen anything in between
+                                                       // report this error
+                                                       //
+                                                       Report.Warning (78, 4, Location, "The 'l' suffix is easily confused with the digit '1' (use 'L' for clarity)");
+                                               }
+
+                                               goto case 'L';
+
+                                       case 'L': 
+                                               if (is_long)
+                                                       scanning = false;
+                                               is_long = true;
+                                               get_char ();
+                                               break;
+                                               
+                                       default:
+                                               scanning = false;
+                                               break;
+                                       }
+                                       c = peek_char ();
+                               } while (scanning);
+                       }
+
+                       if (is_long && is_unsigned){
+                               return new ULongLiteral (context.BuiltinTypes, ul, loc);
+                       }
+                       
+                       if (is_unsigned){
+                               // uint if possible, or ulong else.
+
+                               if ((ul & 0xffffffff00000000) == 0)
+                                       return new UIntLiteral (context.BuiltinTypes, (uint) ul, loc);
+                               else
+                                       return new ULongLiteral (context.BuiltinTypes, ul, loc);
+                       } else if (is_long){
+                               // long if possible, ulong otherwise
+                               if ((ul & 0x8000000000000000) != 0)
+                                       return new ULongLiteral (context.BuiltinTypes, ul, loc);
+                               else
+                                       return new LongLiteral (context.BuiltinTypes, (long) ul, loc);
+                       } else {
+                               // int, uint, long or ulong in that order
+                               if ((ul & 0xffffffff00000000) == 0){
+                                       uint ui = (uint) ul;
+                                       
+                                       if ((ui & 0x80000000) != 0)
+                                               return new UIntLiteral (context.BuiltinTypes, ui, loc);
+                                       else
+                                               return new IntLiteral (context.BuiltinTypes, (int) ui, loc);
+                               } else {
+                                       if ((ul & 0x8000000000000000) != 0)
+                                               return new ULongLiteral (context.BuiltinTypes, ul, loc);
+                                       else
+                                               return new LongLiteral (context.BuiltinTypes, (long) ul, loc);
+                               }
+                       }
+               }
+                               
+               //
+               // given `c' as the next char in the input decide whether
+               // we need to convert to a special type, and then choose
+               // the best representation for the integer
+               //
+               ILiteralConstant adjust_int (int c, Location loc)
+               {
+                       try {
+                               if (number_pos > 9){
+                                       ulong ul = (uint) (number_builder [0] - '0');
+
+                                       for (int i = 1; i < number_pos; i++){
+                                               ul = checked ((ul * 10) + ((uint)(number_builder [i] - '0')));
+                                       }
+
+                                       return integer_type_suffix (ul, c, loc);
+                               } else {
+                                       uint ui = (uint) (number_builder [0] - '0');
+
+                                       for (int i = 1; i < number_pos; i++){
+                                               ui = checked ((ui * 10) + ((uint)(number_builder [i] - '0')));
+                                       }
+
+                                       return integer_type_suffix (ui, c, loc);
+                               }
+                       } catch (OverflowException) {
+                               Error_NumericConstantTooLong ();
+                               return new IntLiteral (context.BuiltinTypes, 0, loc);
+                       }
+                       catch (FormatException) {
+                               Report.Error (1013, Location, "Invalid number");
+                               return new IntLiteral (context.BuiltinTypes, 0, loc);
+                       }
+               }
+               
+               ILiteralConstant adjust_real (TypeCode t, Location loc)
+               {
+                       string s = new string (number_builder, 0, number_pos);
+                       const string error_details = "Floating-point constant is outside the range of type `{0}'";
+
+                       switch (t){
+                       case TypeCode.Decimal:
+                               try {
+                                       return new DecimalLiteral (context.BuiltinTypes, decimal.Parse (s, styles, csharp_format_info), loc);
+                               } catch (OverflowException) {
+                                       Report.Error (594, Location, error_details, "decimal");
+                                       return new DecimalLiteral (context.BuiltinTypes, 0, loc);
+                               }
+                       case TypeCode.Single:
+                               try {
+                                       return new FloatLiteral (context.BuiltinTypes, float.Parse (s, styles, csharp_format_info), loc);
+                               } catch (OverflowException) {
+                                       Report.Error (594, Location, error_details, "float");
+                                       return new FloatLiteral (context.BuiltinTypes, 0, loc);
+                               }
+                       default:
+                               try {
+                                       return new DoubleLiteral (context.BuiltinTypes, double.Parse (s, styles, csharp_format_info), loc);
+                               } catch (OverflowException) {
+                                       Report.Error (594, loc, error_details, "double");
+                                       return new DoubleLiteral (context.BuiltinTypes, 0, loc);
+                               }
+                       }
+               }
+
+               ILiteralConstant handle_hex (Location loc)
+               {
+                       int d;
+                       ulong ul;
+                       
+                       get_char ();
+                       while ((d = peek_char ()) != -1){
+                               if (is_hex (d)){
+                                       number_builder [number_pos++] = (char) d;
+                                       get_char ();
+                               } else
+                                       break;
+                       }
+                       
+                       string s = new String (number_builder, 0, number_pos);
+
+                       try {
+                               if (number_pos <= 8)
+                                       ul = System.UInt32.Parse (s, NumberStyles.HexNumber);
+                               else
+                                       ul = System.UInt64.Parse (s, NumberStyles.HexNumber);
+
+                               return integer_type_suffix (ul, peek_char (), loc);
+                       } catch (OverflowException){
+                               Error_NumericConstantTooLong ();
+                               return new IntLiteral (context.BuiltinTypes, 0, loc);
+                       }
+                       catch (FormatException) {
+                               Report.Error (1013, Location, "Invalid number");
+                               return new IntLiteral (context.BuiltinTypes, 0, loc);
+                       }
+               }
+
+               //
+               // Invoked if we know we have .digits or digits
+               //
+               int is_number (int c)
+               {
+                       ILiteralConstant res;
+
+#if FULL_AST
+                       int read_start = reader.Position - 1;
+                       if (c == '.') {
+                               //
+                               // Caller did peek_char
+                               //
+                               --read_start;
+                       }
+#endif
+                       number_pos = 0;
+                       var loc = Location;
+
+                       if (c >= '0' && c <= '9'){
+                               if (c == '0'){
+                                       int peek = peek_char ();
+
+                                       if (peek == 'x' || peek == 'X') {
+                                               val = res = handle_hex (loc);
+#if FULL_AST
+                                               res.ParsedValue = reader.ReadChars (read_start, reader.Position - 1);
+#endif
+
+                                               return Token.LITERAL;
+                                       }
+                               }
+                               decimal_digits (c);
+                               c = get_char ();
+                       }
+
+                       //
+                       // We need to handle the case of
+                       // "1.1" vs "1.string" (LITERAL_FLOAT vs NUMBER DOT IDENTIFIER)
+                       //
+                       bool is_real = false;
+                       if (c == '.'){
+                               if (decimal_digits ('.')){
+                                       is_real = true;
+                                       c = get_char ();
+                               } else {
+                                       putback ('.');
+                                       number_pos--;
+                                       val = res = adjust_int (-1, loc);
+
+#if FULL_AST
+                                       res.ParsedValue = reader.ReadChars (read_start, reader.Position - 1);
+#endif
+                                       return Token.LITERAL;
+                               }
+                       }
+                       
+                       if (c == 'e' || c == 'E'){
+                               is_real = true;
+                               if (number_pos == MaxNumberLength)
+                                       Error_NumericConstantTooLong ();
+                               number_builder [number_pos++] = (char) c;
+                               c = get_char ();
+                               
+                               if (c == '+'){
+                                       if (number_pos == MaxNumberLength)
+                                               Error_NumericConstantTooLong ();
+                                       number_builder [number_pos++] = '+';
+                                       c = -1;
+                               } else if (c == '-') {
+                                       if (number_pos == MaxNumberLength)
+                                               Error_NumericConstantTooLong ();
+                                       number_builder [number_pos++] = '-';
+                                       c = -1;
+                               } else {
+                                       if (number_pos == MaxNumberLength)
+                                               Error_NumericConstantTooLong ();
+                                       number_builder [number_pos++] = '+';
+                               }
+                                       
+                               decimal_digits (c);
+                               c = get_char ();
+                       }
+
+                       var type = real_type_suffix (c);
+                       if (type == TypeCode.Empty && !is_real) {
+                               putback (c);
+                               res = adjust_int (c, loc);
+                       } else {
+                               is_real = true;
+
+                               if (type == TypeCode.Empty) {
+                                       putback (c);
+                               }
+
+                               res = adjust_real (type, loc);
+                       }
+
+                       val = res;
+
+#if FULL_AST
+                       var chars = reader.ReadChars (read_start, reader.Position - (type == TypeCode.Empty && c > 0 ? 1 : 0));
+                       if (chars[chars.Length - 1] == '\r')
+                               Array.Resize (ref chars, chars.Length - 1);
+                       res.ParsedValue = chars;
+#endif
+
+                       return Token.LITERAL;
+               }
+
+               //
+               // Accepts exactly count (4 or 8) hex, no more no less
+               //
+               int getHex (int count, out int surrogate, out bool error)
+               {
+                       int i;
+                       int total = 0;
+                       int c;
+                       int top = count != -1 ? count : 4;
+                       
+                       get_char ();
+                       error = false;
+                       surrogate = 0;
+                       for (i = 0; i < top; i++){
+                               c = get_char ();
+
+                               if (c >= '0' && c <= '9')
+                                       c = (int) c - (int) '0';
+                               else if (c >= 'A' && c <= 'F')
+                                       c = (int) c - (int) 'A' + 10;
+                               else if (c >= 'a' && c <= 'f')
+                                       c = (int) c - (int) 'a' + 10;
+                               else {
+                                       error = true;
+                                       return 0;
+                               }
+                               
+                               total = (total * 16) + c;
+                               if (count == -1){
+                                       int p = peek_char ();
+                                       if (p == -1)
+                                               break;
+                                       if (!is_hex ((char)p))
+                                               break;
+                               }
+                       }
+
+                       if (top == 8) {
+                               if (total > 0x0010FFFF) {
+                                       error = true;
+                                       return 0;
+                               }
+
+                               if (total >= 0x00010000) {
+                                       surrogate = ((total - 0x00010000) % 0x0400 + 0xDC00);                                   
+                                       total = ((total - 0x00010000) / 0x0400 + 0xD800);
+                               }
+                       }
+
+                       return total;
+               }
+
+               int escape (int c, out int surrogate)
+               {
+                       bool error;
+                       int d;
+                       int v;
+
+                       d = peek_char ();
+                       if (c != '\\') {
+                               surrogate = 0;
+                               return c;
+                       }
+                       
+                       switch (d){
+                       case 'a':
+                               v = '\a'; break;
+                       case 'b':
+                               v = '\b'; break;
+                       case 'n':
+                               v = '\n'; break;
+                       case 't':
+                               v = '\t'; break;
+                       case 'v':
+                               v = '\v'; break;
+                       case 'r':
+                               v = '\r'; break;
+                       case '\\':
+                               v = '\\'; break;
+                       case '/':
+                               v = '/'; break;
+                       case 'f':
+                               v = '\f'; break;
+                       case '0':
+                               v = 0; break;
+                       case '"':
+                               v = '"'; break;
+                       case '\'':
+                               v = '\''; break;
+                       case 'x':
+                               v = getHex (-1, out surrogate, out error);
+                               if (error)
+                                       goto default;
+                               return v;
+                       case 'u':
+                       case 'U':
+                               return EscapeUnicode (d, out surrogate);
+                       default:
+                               surrogate = 0;
+                               Report.Error (1009, Location, "Unrecognized escape sequence `\\{0}'", ((char)d).ToString ());
+                               return d;
+                       }
+
+                       get_char ();
+                       surrogate = 0;
+                       return v;
+               }
+
+               int EscapeUnicode (int ch, out int surrogate)
+               {
+                       bool error;
+                       if (ch == 'U') {
+                               ch = getHex (8, out surrogate, out error);
+                       } else {
+                               ch = getHex (4, out surrogate, out error);
+                       }
+
+                       if (error)
+                               Report.Error (1009, Location, "Unrecognized escape sequence");
+
+                       return ch;
+               }
+
+               int get_char ()
+               {
+                       int x;
+                       if (putback_char != -1) {
+                               x = putback_char;
+                               putback_char = -1;
+                       } else {
+                               x = reader.Read ();
+                       }
+                       
+                       if (x == '\r') {
+                               if (peek_char () == '\n') {
+                                       putback_char = -1;
+                               }
+
+                               x = '\n';
+                               advance_line ();
+                       } else if (x == '\n') {
+                               advance_line ();
+                       } else {
+                               col++;
+                       }
+                       return x;
+               }
+
+               void advance_line ()
+               {
+                       line++;
+                       ref_line++;
+                       previous_col = col;
+                       col = 0;
+               }
+
+               int peek_char ()
+               {
+                       if (putback_char == -1)
+                               putback_char = reader.Read ();
+                       return putback_char;
+               }
+
+               int peek_char2 ()
+               {
+                       if (putback_char != -1)
+                               return putback_char;
+                       return reader.Peek ();
+               }
+               
+               public void putback (int c)
+               {
+                       if (putback_char != -1) {
+                               throw new InternalErrorException (string.Format ("Secondary putback [{0}] putting back [{1}] is not allowed", (char)putback_char, (char) c), Location);
+                       }
+
+                       if (c == '\n' || col == 0) {
+                               // It won't happen though.
+                               line--;
+                               ref_line--;
+                               col = previous_col;
+                       }
+                       else
+                               col--;
+                       putback_char = c;
+               }
+
+               public bool advance ()
+               {
+                       return peek_char () != -1 || CompleteOnEOF;
+               }
+
+               public Object Value {
+                       get {
+                               return val;
+                       }
+               }
+
+               public Object value ()
+               {
+                       return val;
+               }
+
+               public int token ()
+               {
+                       prev_token = current_token;
+                       prev_token_line = current_token_line;
+                       
+                       current_token = xtoken (true);
+                       current_token_line = line;
+
+                       return current_token;
+               }
+
+               public void token_putback (int token)
+               {
+                       if (putback_token != -1)
+                               throw new Exception("Can't put back token twice.'");
+                       putback_token = token;
+               }
+
+               int TokenizePreprocessorIdentifier (out int c)
+               {
+                       // skip over white space
+                       do {
+                               c = get_char ();
+                       } while (c == ' ' || c == '\t');
+
+
+                       int pos = 0;
+                       while (c != -1 && c >= 'a' && c <= 'z') {
+                               id_builder[pos++] = (char) c;
+                               c = get_char ();
+                               if (c == '\\') {
+                                       int peek = peek_char ();
+                                       if (peek == 'U' || peek == 'u') {
+                                               int surrogate;
+                                               c = EscapeUnicode (c, out surrogate);
+                                               if (surrogate != 0) {
+                                                       if (is_identifier_part_character ((char) c)) {
+                                                               id_builder[pos++] = (char) c;
+                                                       }
+                                                       c = surrogate;
+                                               }
+                                       }
+                               }
+                       }
+
+                       return pos;
+               }
+
+               PreprocessorDirective get_cmd_arg (out string arg)
+               {
+                       int c;          
+
+                       tokens_seen = false;
+                       arg = "";
+
+                       var cmd = GetPreprocessorDirective (id_builder, TokenizePreprocessorIdentifier (out c));
+
+                       if ((cmd & PreprocessorDirective.CustomArgumentsParsing) != 0)
+                               return cmd;
+
+                       // skip over white space
+                       while (c == ' ' || c == '\t')
+                               c = get_char ();
+
+                       int has_identifier_argument = (int)(cmd & PreprocessorDirective.RequiresArgument);
+                       int pos = 0;
+
+                       while (c != -1 && c != '\n') {
+                               if (c == '\\' && has_identifier_argument >= 0) {
+                                       if (has_identifier_argument != 0) {
+                                               has_identifier_argument = 1;
+
+                                               int peek = peek_char ();
+                                               if (peek == 'U' || peek == 'u') {
+                                                       int surrogate;
+                                                       c = EscapeUnicode (c, out surrogate);
+                                                       if (surrogate != 0) {
+                                                               if (is_identifier_part_character ((char) c)) {
+                                                                       if (pos == value_builder.Length)
+                                                                               Array.Resize (ref value_builder, pos * 2);
+
+                                                                       value_builder[pos++] = (char) c;
+                                                               }
+                                                               c = surrogate;
+                                                       }
+                                               }
+                                       } else {
+                                               has_identifier_argument = -1;
+                                       }
+                               } else if (c == '/' && peek_char () == '/') {
+                                       //
+                                       // Eat single-line comments
+                                       //
+                                       get_char ();
+                                       do {
+                                               c = get_char ();
+                                       } while (c != -1 && c != '\n');
+
+                                       break;
+                               }
+
+                               if (pos == value_builder.Length)
+                                       Array.Resize (ref value_builder, pos * 2);
+
+                               value_builder[pos++] = (char) c;
+                               c = get_char ();
+                       }
+
+                       if (pos != 0) {
+                               if (pos > MaxIdentifierLength)
+                                       arg = new string (value_builder, 0, pos);
+                               else
+                                       arg = InternIdentifier (value_builder, pos);
+
+                               // Eat any trailing whitespaces
+                               arg = arg.Trim (simple_whitespaces);
+                       }
+
+                       return cmd;
+               }
+
+               //
+               // Handles the #line directive
+               //
+               bool PreProcessLine ()
+               {
+                       Location loc = Location;
+
+                       int c;
+
+                       int length = TokenizePreprocessorIdentifier (out c);
+                       if (length == line_default.Length) {
+                               if (!IsTokenIdentifierEqual (line_default))
+                                       return false;
+
+                               current_source = source_file.SourceFile;
+                               if (!hidden_block_start.IsNull) {
+                                       current_source.RegisterHiddenScope (hidden_block_start, loc);
+                                       hidden_block_start = Location.Null;
+                               }
+
+                               ref_line = line;
+                               return true;
+                       }
+
+                       if (length == line_hidden.Length) {
+                               if (!IsTokenIdentifierEqual (line_hidden))
+                                       return false;
+
+                               if (hidden_block_start.IsNull)
+                                       hidden_block_start = loc;
+
+                               return true;
+                       }
+
+                       if (length != 0 || c < '0' || c > '9') {
+                               //
+                               // Eat any remaining characters to continue parsing on next line
+                               //
+                               while (c != -1 && c != '\n') {
+                                       c = get_char ();
+                               }
+
+                               return false;
+                       }
+
+                       int new_line = TokenizeNumber (c);
+                       if (new_line < 1) {
+                               //
+                               // Eat any remaining characters to continue parsing on next line
+                               //
+                               while (c != -1 && c != '\n') {
+                                       c = get_char ();
+                               }
+
+                               return new_line != 0;
+                       }
+
+                       c = get_char ();
+                       if (c == ' ') {
+                               // skip over white space
+                               do {
+                                       c = get_char ();
+                               } while (c == ' ' || c == '\t');
+                       } else if (c == '"') {
+                               c = 0;
+                       }
+
+                       if (c != '\n' && c != '/' && c != '"') {
+                               //
+                               // Eat any remaining characters to continue parsing on next line
+                               //
+                               while (c != -1 && c != '\n') {
+                                       c = get_char ();
+                               }
+
+                               Report.Error (1578, loc, "Filename, single-line comment or end-of-line expected");
+                               return true;
+                       }
+
+                       string new_file_name = null;
+                       if (c == '"') {
+                               new_file_name = TokenizeFileName (ref c);
+
+                               // skip over white space
+                               while (c == ' ' || c == '\t') {
+                                       c = get_char ();
+                               }
+                       }
+
+                       if (c == '\n') {
+                       } else if (c == '/') {
+                               ReadSingleLineComment ();
+                       } else {
+                               //
+                               // Eat any remaining characters to continue parsing on next line
+                               //
+                               while (c != -1 && c != '\n') {
+                                       c = get_char ();
+                               }
+
+                               Error_EndLineExpected ();
+                               return true;
+                       }
+
+                       if (new_file_name != null) {
+                               current_source = context.LookupFile (source_file, new_file_name);
+                               source_file.AddIncludeFile (current_source);
+                       }
+
+                       if (!hidden_block_start.IsNull) {
+                               current_source.RegisterHiddenScope (hidden_block_start, loc);
+                               hidden_block_start = Location.Null;
+                       }
+
+                       ref_line = new_line;
+                       return true;
+               }
+
+               //
+               // Handles #define and #undef
+               //
+               void PreProcessDefinition (bool is_define, string ident, bool caller_is_taking)
+               {
+                       if (ident.Length == 0 || ident == "true" || ident == "false"){
+                               Report.Error (1001, Location, "Missing identifier to pre-processor directive");
+                               return;
+                       }
+
+                       if (ident.IndexOfAny (simple_whitespaces) != -1){
+                               Error_EndLineExpected ();
+                               return;
+                       }
+
+                       if (!is_identifier_start_character (ident [0]))
+                               Report.Error (1001, Location, "Identifier expected: {0}", ident);
+                       
+                       foreach (char c in ident.Substring (1)){
+                               if (!is_identifier_part_character (c)){
+                                       Report.Error (1001, Location, "Identifier expected: {0}",  ident);
+                                       return;
+                               }
+                       }
+
+                       if (!caller_is_taking)
+                               return;
+
+                       if (is_define) {
+                               //
+                               // #define ident
+                               //
+                               if (context.Settings.IsConditionalSymbolDefined (ident))
+                                       return;
+
+                               source_file.AddDefine (ident);
+                       } else {
+                               //
+                               // #undef ident
+                               //
+                               source_file.AddUndefine (ident);
+                       }
+               }
+
+               byte read_hex (out bool error)
+               {
+                       int total;
+                       int c = get_char ();
+
+                       if ((c >= '0') && (c <= '9'))
+                               total = (int) c - (int) '0';
+                       else if ((c >= 'A') && (c <= 'F'))
+                               total = (int) c - (int) 'A' + 10;
+                       else if ((c >= 'a') && (c <= 'f'))
+                               total = (int) c - (int) 'a' + 10;
+                       else {
+                               error = true;
+                               return 0;
+                       }
+
+                       total *= 16;
+                       c = get_char ();
+
+                       if ((c >= '0') && (c <= '9'))
+                               total += (int) c - (int) '0';
+                       else if ((c >= 'A') && (c <= 'F'))
+                               total += (int) c - (int) 'A' + 10;
+                       else if ((c >= 'a') && (c <= 'f'))
+                               total += (int) c - (int) 'a' + 10;
+                       else {
+                               error = true;
+                               return 0;
+                       }
+
+                       error = false;
+                       return (byte) total;
+               }
+
+               //
+               // Parses #pragma checksum
+               //
+               bool ParsePragmaChecksum ()
+               {
+                       //
+                       // The syntax is ` "foo.txt" "{guid}" "hash"'
+                       //
+                       // guid is predefined hash algorithm guid {406ea660-64cf-4c82-b6f0-42d48172a799} for md5
+                       //
+                       int c = get_char ();
+
+                       if (c != '"')
+                               return false;
+
+                       string file_name = TokenizeFileName (ref c);
+
+                       // TODO: Any white-spaces count
+                       if (c != ' ')
+                               return false;
+
+                       SourceFile file = context.LookupFile (source_file, file_name);
+
+                       if (get_char () != '"' || get_char () != '{')
+                               return false;
+
+                       bool error;
+                       byte[] guid_bytes = new byte [16];
+                       int i = 0;
+
+                       for (; i < 4; i++) {
+                               guid_bytes [i] = read_hex (out error);
+                               if (error)
+                                       return false;
+                       }
+
+                       if (get_char () != '-')
+                               return false;
+
+                       for (; i < 10; i++) {
+                               guid_bytes [i] = read_hex (out error);
+                               if (error)
+                                       return false;
+
+                               guid_bytes [i++] = read_hex (out error);
+                               if (error)
+                                       return false;
+
+                               if (get_char () != '-')
+                                       return false;
+                       }
+
+                       for (; i < 16; i++) {
+                               guid_bytes [i] = read_hex (out error);
+                               if (error)
+                                       return false;
+                       }
+
+                       if (get_char () != '}' || get_char () != '"')
+                               return false;
+
+                       // TODO: Any white-spaces count
+                       c = get_char ();
+                       if (c != ' ')
+                               return false;
+
+                       if (get_char () != '"')
+                               return false;
+
+                       // Any length of checksum
+                       List<byte> checksum_bytes = new List<byte> (16);
+
+                       var checksum_location = Location;
+                       c = peek_char ();
+                       while (c != '"' && c != -1) {
+                               checksum_bytes.Add (read_hex (out error));
+                               if (error)
+                                       return false;
+
+                               c = peek_char ();
+                       }
+
+                       if (c == '/') {
+                               ReadSingleLineComment ();
+                       } else if (get_char () != '"') {
+                               return false;
+                       }
+
+                       if (context.Settings.GenerateDebugInfo) {
+                               var chsum = checksum_bytes.ToArray ();
+
+                               if (file.HasChecksum) {
+                                       if (!ArrayComparer.IsEqual (file.Checksum, chsum)) {
+                                               // TODO: Report.SymbolRelatedToPreviousError
+                                               Report.Warning (1697, 1, checksum_location, "Different checksum values specified for file `{0}'", file.Name);
+                                       }
+                               }
+
+                               file.SetChecksum (guid_bytes, chsum);
+                       current_source.AutoGenerated = true;
+                       }
+
+                       return true;
+               }
+
+               bool IsTokenIdentifierEqual (char[] identifier)
+               {
+                       for (int i = 0; i < identifier.Length; ++i) {
+                               if (identifier[i] != id_builder[i])
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               int TokenizeNumber (int value)
+               {
+                       number_pos = 0;
+
+                       decimal_digits (value);
+                       uint ui = (uint) (number_builder[0] - '0');
+
+                       try {
+                               for (int i = 1; i < number_pos; i++) {
+                                       ui = checked ((ui * 10) + ((uint) (number_builder[i] - '0')));
+                               }
+
+                               return (int) ui;
+                       } catch (OverflowException) {
+                               Error_NumericConstantTooLong ();
+                               return -1;
+                       }
+               }
+
+               string TokenizeFileName (ref int c)
+               {
+                       var string_builder = new StringBuilder ();
+                       while (c != -1 && c != '\n') {
+                               c = get_char ();
+                               if (c == '"') {
+                                       c = get_char ();
+                                       break;
+                               }
+
+                               string_builder.Append ((char) c);
+                       }
+
+                       if (string_builder.Length == 0) {
+                               Report.Warning (1709, 1, Location, "Filename specified for preprocessor directive is empty");
+                       }
+
+               
+                       return string_builder.ToString ();
+               }
+
+               int TokenizePragmaNumber (ref int c)
+               {
+                       number_pos = 0;
+
+                       int number;
+
+                       if (c >= '0' && c <= '9') {
+                               number = TokenizeNumber (c);
+
+                               c = get_char ();
+
+                               // skip over white space
+                               while (c == ' ' || c == '\t')
+                                       c = get_char ();
+
+                               if (c == ',') {
+                                       c = get_char ();
+                               }
+
+                               // skip over white space
+                               while (c == ' ' || c == '\t')
+                                       c = get_char ();
+                       } else {
+                               number = -1;
+                               if (c == '/') {
+                                       ReadSingleLineComment ();
+                               } else {
+                                       Report.Warning (1692, 1, Location, "Invalid number");
+
+                                       // Read everything till the end of the line or file
+                                       do {
+                                               c = get_char ();
+                                       } while (c != -1 && c != '\n');
+                               }
+                       }
+
+                       return number;
+               }
+
+               void ReadSingleLineComment ()
+               {
+                       if (peek_char () != '/')
+                               Report.Warning (1696, 1, Location, "Single-line comment or end-of-line expected");
+
+                       // Read everything till the end of the line or file
+                       int c;
+                       do {
+                               c = get_char ();
+                       } while (c != -1 && c != '\n');
+               }
+
+               /// <summary>
+               /// Handles #pragma directive
+               /// </summary>
+               void ParsePragmaDirective (string arg)
+               {
+                       int c;
+                       int length = TokenizePreprocessorIdentifier (out c);
+                       if (length == pragma_warning.Length && IsTokenIdentifierEqual (pragma_warning)) {
+                               length = TokenizePreprocessorIdentifier (out c);
+
+                               //
+                               // #pragma warning disable
+                               // #pragma warning restore
+                               //
+                               if (length == pragma_warning_disable.Length) {
+                                       bool disable = IsTokenIdentifierEqual (pragma_warning_disable);
+                                       if (disable || IsTokenIdentifierEqual (pragma_warning_restore)) {
+                                               // skip over white space
+                                               while (c == ' ' || c == '\t')
+                                                       c = get_char ();
+
+                                               var loc = Location;
+
+                                               if (c == '\n' || c == '/') {
+                                                       if (c == '/')
+                                                               ReadSingleLineComment ();
+
+                                                       //
+                                                       // Disable/Restore all warnings
+                                                       //
+                                                       if (disable) {
+                                                               Report.RegisterWarningRegion (loc).WarningDisable (loc.Row);
+                                                       } else {
+                                                               Report.RegisterWarningRegion (loc).WarningEnable (loc.Row);
+                                                       }
+                                               } else {
+                                                       //
+                                                       // Disable/Restore a warning or group of warnings
+                                                       //
+                                                       int code;
+                                                       do {
+                                                               code = TokenizePragmaNumber (ref c);
+                                                               if (code > 0) {
+                                                                       if (disable) {
+                                                                               Report.RegisterWarningRegion (loc).WarningDisable (loc, code, context.Report);
+                                                                       } else {
+                                                                               Report.RegisterWarningRegion (loc).WarningEnable (loc, code, context);
+                                                                       }
+                                                               }
+                                                       } while (code >= 0 && c != '\n' && c != -1);
+                                               }
+
+                                               return;
+                                       }
+                               }
+
+                               Report.Warning (1634, 1, Location, "Expected disable or restore");
+                               return;
+                       }
+
+                       //
+                       // #pragma checksum
+                       //
+                       if (length == pragma_checksum.Length && IsTokenIdentifierEqual (pragma_checksum)) {
+                               if (c != ' ' || !ParsePragmaChecksum ()) {
+                                       Report.Warning (1695, 1, Location,
+                                               "Invalid #pragma checksum syntax. Expected \"filename\" \"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\" \"XXXX...\"");
+                               }
+
+                               return;
+                       }
+
+                       Report.Warning (1633, 1, Location, "Unrecognized #pragma directive");
+               }
+
+               bool eval_val (string s)
+               {
+                       if (s == "true")
+                               return true;
+                       if (s == "false")
+                               return false;
+
+                       return source_file.IsConditionalDefined (s);
+               }
+
+               bool pp_primary (ref string s)
+               {
+                       s = s.Trim ();
+                       int len = s.Length;
+
+                       if (len > 0){
+                               char c = s [0];
+                               
+                               if (c == '('){
+                                       s = s.Substring (1);
+                                       bool val = pp_expr (ref s, false);
+                                       if (s.Length > 0 && s [0] == ')'){
+                                               s = s.Substring (1);
+                                               return val;
+                                       }
+                                       Error_InvalidDirective ();
+                                       return false;
+                               }
+                               
+                               if (is_identifier_start_character (c)){
+                                       int j = 1;
+
+                                       while (j < len){
+                                               c = s [j];
+                                               
+                                               if (is_identifier_part_character (c)){
+                                                       j++;
+                                                       continue;
+                                               }
+                                               bool v = eval_val (s.Substring (0, j));
+                                               s = s.Substring (j);
+                                               return v;
+                                       }
+                                       bool vv = eval_val (s);
+                                       s = "";
+                                       return vv;
+                               }
+                       }
+                       Error_InvalidDirective ();
+                       return false;
+               }
+               
+               bool pp_unary (ref string s)
+               {
+                       s = s.Trim ();
+                       int len = s.Length;
+
+                       if (len > 0){
+                               if (s [0] == '!'){
+                                       if (len > 1 && s [1] == '='){
+                                               Error_InvalidDirective ();
+                                               return false;
+                                       }
+                                       s = s.Substring (1);
+                                       return ! pp_primary (ref s);
+                               } else
+                                       return pp_primary (ref s);
+                       } else {
+                               Error_InvalidDirective ();
+                               return false;
+                       }
+               }
+               
+               bool pp_eq (ref string s)
+               {
+                       bool va = pp_unary (ref s);
+
+                       s = s.Trim ();
+                       int len = s.Length;
+                       if (len > 0){
+                               if (s [0] == '='){
+                                       if (len > 2 && s [1] == '='){
+                                               s = s.Substring (2);
+                                               return va == pp_unary (ref s);
+                                       } else {
+                                               Error_InvalidDirective ();
+                                               return false;
+                                       }
+                               } else if (s [0] == '!' && len > 1 && s [1] == '='){
+                                       s = s.Substring (2);
+
+                                       return va != pp_unary (ref s);
+
+                               } 
+                       }
+
+                       return va;
+                               
+               }
+               
+               bool pp_and (ref string s)
+               {
+                       bool va = pp_eq (ref s);
+
+                       s = s.Trim ();
+                       int len = s.Length;
+                       if (len > 0){
+                               if (s [0] == '&'){
+                                       if (len > 2 && s [1] == '&'){
+                                               s = s.Substring (2);
+                                               return (va & pp_and (ref s));
+                                       } else {
+                                               Error_InvalidDirective ();
+                                               return false;
+                                       }
+                               } 
+                       }
+                       return va;
+               }
+               
+               //
+               // Evaluates an expression for `#if' or `#elif'
+               //
+               bool pp_expr (ref string s, bool isTerm)
+               {
+                       bool va = pp_and (ref s);
+                       s = s.Trim ();
+                       int len = s.Length;
+                       if (len > 0){
+                               char c = s [0];
+                               
+                               if (c == '|'){
+                                       if (len > 2 && s [1] == '|'){
+                                               s = s.Substring (2);
+                                               return va | pp_expr (ref s, isTerm);
+                                       } else {
+                                               Error_InvalidDirective ();
+                                               return false;
+                                       }
+                               }
+                               if (isTerm) {
+                                       Error_EndLineExpected ();
+                                       return false;
+                               }
+                       }
+                       
+                       return va;
+               }
+
+               bool eval (string s)
+               {
+                       bool v = pp_expr (ref s, true);
+                       s = s.Trim ();
+                       if (s.Length != 0){
+                               return false;
+                       }
+
+                       return v;
+               }
+
+               void Error_NumericConstantTooLong ()
+               {
+                       Report.Error (1021, Location, "Integral constant is too large");                        
+               }
+               
+               void Error_InvalidDirective ()
+               {
+                       Report.Error (1517, Location, "Invalid preprocessor directive");
+               }
+
+               void Error_UnexpectedDirective (string extra)
+               {
+                       Report.Error (
+                               1028, Location,
+                               "Unexpected processor directive ({0})", extra);
+               }
+
+               void Error_TokensSeen ()
+               {
+                       Report.Error (1032, Location,
+                               "Cannot define or undefine preprocessor symbols after first token in file");
+               }
+
+               void Eror_WrongPreprocessorLocation ()
+               {
+                       Report.Error (1040, Location,
+                               "Preprocessor directives must appear as the first non-whitespace character on a line");
+               }
+
+               void Error_EndLineExpected ()
+               {
+                       Report.Error (1025, Location, "Single-line comment or end-of-line expected");
+               }
+
+               //
+               // Raises a warning when tokenizer found documentation comment
+               // on unexpected place
+               //
+               void WarningMisplacedComment (Location loc)
+               {
+                       if (doc_state != XmlCommentState.Error) {
+                               doc_state = XmlCommentState.Error;
+                               Report.Warning (1587, 2, loc, "XML comment is not placed on a valid language element");
+                       }
+               }
+               
+               //
+               // if true, then the code continues processing the code
+               // if false, the code stays in a loop until another directive is
+               // reached.
+               // When caller_is_taking is false we ignore all directives except the ones
+               // which can help us to identify where the #if block ends
+               bool ParsePreprocessingDirective (bool caller_is_taking)
+               {
+                       string arg;
+                       bool region_directive = false;
+
+                       var directive = get_cmd_arg (out arg);
+
+                       //
+                       // The first group of pre-processing instructions is always processed
+                       //
+                       switch (directive) {
+                       case PreprocessorDirective.Region:
+                               region_directive = true;
+                               arg = "true";
+                               goto case PreprocessorDirective.If;
+
+                       case PreprocessorDirective.Endregion:
+                               if (ifstack == null || ifstack.Count == 0){
+                                       Error_UnexpectedDirective ("no #region for this #endregion");
+                                       return true;
+                               }
+                               int pop = ifstack.Pop ();
+                                       
+                               if ((pop & REGION) == 0)
+                                       Report.Error (1027, Location, "Expected `#endif' directive");
+                                       
+                               return caller_is_taking;
+                               
+                       case PreprocessorDirective.If:
+                               if (ifstack == null)
+                                       ifstack = new Stack<int> (2);
+
+                               int flags = region_directive ? REGION : 0;
+                               if (ifstack.Count == 0){
+                                       flags |= PARENT_TAKING;
+                               } else {
+                                       int state = ifstack.Peek ();
+                                       if ((state & TAKING) != 0) {
+                                               flags |= PARENT_TAKING;
+                                       }
+                               }
+
+                               if (eval (arg) && caller_is_taking) {
+                                       ifstack.Push (flags | TAKING);
+                                       return true;
+                               }
+                               ifstack.Push (flags);
+                               return false;
+
+                       case PreprocessorDirective.Endif:
+                               if (ifstack == null || ifstack.Count == 0){
+                                       Error_UnexpectedDirective ("no #if for this #endif");
+                                       return true;
+                               } else {
+                                       pop = ifstack.Pop ();
+                                       
+                                       if ((pop & REGION) != 0)
+                                               Report.Error (1038, Location, "#endregion directive expected");
+                                       
+                                       if (arg.Length != 0) {
+                                               Error_EndLineExpected ();
+                                       }
+                                       
+                                       if (ifstack.Count == 0)
+                                               return true;
+
+                                       int state = ifstack.Peek ();
+                                       return (state & TAKING) != 0;
+                               }
+
+                       case PreprocessorDirective.Elif:
+                               if (ifstack == null || ifstack.Count == 0){
+                                       Error_UnexpectedDirective ("no #if for this #elif");
+                                       return true;
+                               } else {
+                                       int state = ifstack.Pop ();
+
+                                       if ((state & REGION) != 0) {
+                                               Report.Error (1038, Location, "#endregion directive expected");
+                                               return true;
+                                       }
+
+                                       if ((state & ELSE_SEEN) != 0){
+                                               Error_UnexpectedDirective ("#elif not valid after #else");
+                                               return true;
+                                       }
+
+                                       if ((state & TAKING) != 0) {
+                                               ifstack.Push (0);
+                                               return false;
+                                       }
+
+                                       if (eval (arg) && ((state & PARENT_TAKING) != 0)){
+                                               ifstack.Push (state | TAKING);
+                                               return true;
+                                       }
+
+                                       ifstack.Push (state);
+                                       return false;
+                               }
+
+                       case PreprocessorDirective.Else:
+                               if (ifstack == null || ifstack.Count == 0){
+                                       Error_UnexpectedDirective ("no #if for this #else");
+                                       return true;
+                               } else {
+                                       int state = ifstack.Peek ();
+
+                                       if ((state & REGION) != 0) {
+                                               Report.Error (1038, Location, "#endregion directive expected");
+                                               return true;
+                                       }
+
+                                       if ((state & ELSE_SEEN) != 0){
+                                               Error_UnexpectedDirective ("#else within #else");
+                                               return true;
+                                       }
+
+                                       ifstack.Pop ();
+
+                                       if (arg.Length != 0) {
+                                               Error_EndLineExpected ();
+                                               return true;
+                                       }
+
+                                       bool ret = false;
+                                       if ((state & PARENT_TAKING) != 0) {
+                                               ret = (state & TAKING) == 0;
+                                       
+                                               if (ret)
+                                                       state |= TAKING;
+                                               else
+                                                       state &= ~TAKING;
+                                       }
+       
+                                       ifstack.Push (state | ELSE_SEEN);
+                                       
+                                       return ret;
+                               }
+                       case PreprocessorDirective.Define:
+                               if (any_token_seen){
+                                       Error_TokensSeen ();
+                                       return caller_is_taking;
+                               }
+                               PreProcessDefinition (true, arg, caller_is_taking);
+                               return caller_is_taking;
+
+                       case PreprocessorDirective.Undef:
+                               if (any_token_seen){
+                                       Error_TokensSeen ();
+                                       return caller_is_taking;
+                               }
+                               PreProcessDefinition (false, arg, caller_is_taking);
+                               return caller_is_taking;
+
+                       case PreprocessorDirective.Invalid:
+                               Report.Error (1024, Location, "Wrong preprocessor directive");
+                               return true;
+                       }
+
+                       //
+                       // These are only processed if we are in a `taking' block
+                       //
+                       if (!caller_is_taking)
+                               return false;
+                                       
+                       switch (directive){
+                       case PreprocessorDirective.Error:
+                               Report.Error (1029, Location, "#error: '{0}'", arg);
+                               return true;
+
+                       case PreprocessorDirective.Warning:
+                               Report.Warning (1030, 1, Location, "#warning: `{0}'", arg);
+                               return true;
+
+                       case PreprocessorDirective.Pragma:
+                               if (context.Settings.Version == LanguageVersion.ISO_1) {
+                                       Report.FeatureIsNotAvailable (context, Location, "#pragma");
+                               }
+
+                               ParsePragmaDirective (arg);
+                               return true;
+
+                       case PreprocessorDirective.Line:
+                               Location loc = Location;
+                               if (!PreProcessLine ())
+                                       Report.Error (1576, loc, "The line number specified for #line directive is missing or invalid");
+
+                               return caller_is_taking;
+                       }
+
+                       throw new NotImplementedException (directive.ToString ());
+               }
+
+               private int consume_string (bool quoted, char quoteChar = '"')
+               {
+                       int c;
+                       int pos = 0;
+                       Location start_location = Location;
+                       if (quoted)
+                               start_location = start_location - 1;
+
+#if FULL_AST
+                       int reader_pos = reader.Position;
+#endif
+
+                       while (true) {
+                               c = get_char ();
+                               if (c == quoteChar) {
+                                       if (quoted && peek_char () == quoteChar) {
+                                               if (pos == value_builder.Length)
+                                                       Array.Resize (ref value_builder, pos * 2);
+
+                                               value_builder[pos++] = (char) c;
+                                               get_char ();
+                                               continue;
+                                       }
+
+                                       string s;
+                                       if (pos == 0)
+                                               s = string.Empty;
+                                       else if (pos <= 4)
+                                               s = InternIdentifier (value_builder, pos);
+                                       else
+                                               s = new string (value_builder, 0, pos);
+
+                                       ILiteralConstant res = new StringLiteral (context.BuiltinTypes, s, start_location);
+                                       val = res;
+#if FULL_AST
+                                       res.ParsedValue = quoted ?
+                                               reader.ReadChars (reader_pos - 2, reader.Position - 1) :
+                                               reader.ReadChars (reader_pos - 1, reader.Position);
+#endif
+
+                                       return Token.LITERAL;
+                               }
+
+                               if (c == '\n') {
+                                       if (!quoted) {
+                                               Report.Error (1010, Location, "Newline in constant");
+                                               val = new StringLiteral (context.BuiltinTypes, new string (value_builder, 0, pos), start_location);
+                                               return Token.LITERAL;
+                                       }
+                               } else if (c == '\\' && !quoted) {
+                                       int surrogate;
+                                       c = escape (c, out surrogate);
+                                       if (c == -1)
+                                               return Token.ERROR;
+                                       if (surrogate != 0) {
+                                               if (pos == value_builder.Length)
+                                                       Array.Resize (ref value_builder, pos * 2);
+
+                                               value_builder[pos++] = (char) c;
+                                               c = surrogate;
+                                       }
+                               } else if (c == -1) {
+                                       Report.Error (1039, Location, "Unterminated string literal");
+                                       return Token.EOF;
+                               }
+
+                               if (pos == value_builder.Length)
+                                       Array.Resize (ref value_builder, pos * 2);
+
+                               value_builder[pos++] = (char) c;
+                       }
+               }
+
+               private int consume_regex ()
+               {
+                       int c;
+                       int pos = 0;
+                       Location start_location = Location;
+
+#if FULL_AST
+                       int reader_pos = reader.Position;
+#endif
+
+                       StringBuilder opt_builder = null;
+
+                       while (true) {
+                               c = get_char ();
+                               if (c == '\\') {
+                                       if (pos == value_builder.Length)
+                                               Array.Resize (ref value_builder, pos * 2);
+                                       value_builder[pos++] = (char) c;
+                                       c = get_char ();
+                                       // c will be added automatically at the end of this block
+                               } else if (c == '/') {
+
+                                       c = peek_char();
+                                       while (c == 'g' || c == 'i' || c == 'm' || c == 's' || c == 'x') {
+                                               if (opt_builder == null)
+                                                       opt_builder = new StringBuilder();
+                                               opt_builder.Append((char) get_char ());
+                                               c = peek_char ();
+                                       }
+
+                                       string s;
+                                       if (pos == 0)
+                                               s = string.Empty;
+                                       else
+                                               s = new string (value_builder, 0, pos);
+
+                                       ILiteralConstant res = new RegexLiteral (s, 
+                                                                                opt_builder != null ? opt_builder.ToString() : null, 
+                                                                                start_location);
+                                       val = res;
+#if FULL_AST
+                                       res.ParsedValue = quoted ?
+                                               reader.ReadChars (reader_pos - 2, reader.Position - 1) :
+                                               reader.ReadChars (reader_pos - 1, reader.Position);
+#endif
+
+                                       return Token.LITERAL;
+                               }
+
+                               if (c == '\n') {
+                                       Report.Error (7027, Location, "Newline in regex constant");
+                                       val = new StringLiteral (context.BuiltinTypes, new string (value_builder, 0, pos), start_location);
+                                       return Token.LITERAL;
+                               } /* else if (c == '\\') {
+                                       c = get_char();
+                                       if (c != -1) {
+                                               if (pos == value_builder.Length)
+                                                       Array.Resize (ref value_builder, pos * 2);
+                                               value_builder[pos++] = (char) c;
+                                       }
+                               } */
+
+                               if (c == -1) {
+                                       Report.Error (7028, Location, "Unterminated regex literal");
+                                       return Token.EOF;
+                               }
+
+                               if (pos == value_builder.Length)
+                                       Array.Resize (ref value_builder, pos * 2);
+
+                               value_builder[pos++] = (char) c;
+                       }
+               }
+
+               private int consume_xml ()
+               {
+                       int c;
+                       int pos = 0;
+                       Location start_location = Location;
+                       
+#if FULL_AST
+                       int reader_pos = reader.Position;
+#endif
+                       
+                       if (pos == value_builder.Length)
+                               Array.Resize (ref value_builder, pos * 2);
+                       value_builder[pos++] = (char) '<';
+
+                       while (true) {
+
+                               c = get_char ();
+                               if (c == '>') {
+
+                                       if (pos == value_builder.Length)
+                                               Array.Resize (ref value_builder, pos * 2);
+                                       value_builder[pos++] = (char) c;
+
+                                       c = peek_char();
+                                       while (c == ' ' || c == '\t') {
+                                               c = get_char ();
+                                               if (pos == value_builder.Length)
+                                                       Array.Resize (ref value_builder, pos * 2);
+                                               value_builder[pos++] = (char) c;
+                                       }
+
+                                       // TODO: This is a pretty ghetto way to identify the end of the xml literal.  Probably will
+                                       // work most of the time, but is not a general solution.  FIXME
+                                       if (c == ';' || c == '.' || c == ',' || c == ')' || c == '}' || c == ']') {
+
+                                               string s;
+                                               if (pos == 0)
+                                                       s = string.Empty;
+                                               else
+                                                       s = new string (value_builder, 0, pos);
+                                               
+                                               ILiteralConstant res = new XmlLiteral (s, start_location);
+                                               val = res;
+#if FULL_AST
+                                               res.ParsedValue = quoted ?
+                                                       reader.ReadChars (reader_pos - 2, reader.Position - 1) :
+                                                               reader.ReadChars (reader_pos - 1, reader.Position);
+#endif
+                                               
+                                               return Token.LITERAL;
+                                       }
+                               }
+                               
+                               if (c == -1) {
+                                       Report.Error (7029, Location, "Unterminated xml literal");
+                                       return Token.EOF;
+                               }
+                               
+                               if (pos == value_builder.Length)
+                                       Array.Resize (ref value_builder, pos * 2);
+                               value_builder[pos++] = (char) c;
+                       }
+               }
+
+               private int consume_identifier (bool parse_token, int s)
+               {
+                       int res = consume_identifier (parse_token, s, false);
+
+                       if (doc_state == XmlCommentState.Allowed)
+                               doc_state = XmlCommentState.NotAllowed;
+
+                       return res;
+               }
+
+               int consume_identifier (bool parse_token, int c, bool quoted) 
+               {
+                       //
+                       // This method is very performance sensitive. It accounts
+                       // for approximately 25% of all parser time
+                       //
+
+                       int pos = 0;
+                       int column = col;
+                       if (quoted)
+                               --column;
+
+                       if (c == '\\') {
+                               int surrogate;
+                               c = escape (c, out surrogate);
+                               if (surrogate != 0) {
+                                       id_builder [pos++] = (char) c;
+                                       c = surrogate;
+                               }
+                       }
+
+                       id_builder [pos++] = (char) c;
+
+                       bool is_config_ident = false;
+
+                       try {
+                               while (true) {
+                                       c = reader.Read ();
+
+                                       if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9') || c == '$') {
+                                               id_builder [pos++] = (char) c;
+                                               continue;
+                                       }
+
+                                       if (parsing_block == 0 && c == ':' && !is_config_ident) {
+                                               var colonPos = reader.Position;
+                                               c = reader.Read ();
+                                               if (c == ':') { 
+                                                       c = reader.Read ();
+                                                       if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$') {
+                                                               is_config_ident = true;
+                                                               id_builder [pos++] = ':';
+                                                               id_builder [pos++] = ':';
+                                                               id_builder [pos++] = (char) c;
+                                                               continue;
+                                                       } 
+                                               }
+                                               if (!is_config_ident) {
+                                                       reader.Position = colonPos;
+                                                       c = ':';
+                                               }
+                                       }
+
+                                       if (c < 0x80) {
+                                               if (c == '\\') {
+                                                       int surrogate;
+                                                       c = escape (c, out surrogate);
+                                                       if (is_identifier_part_character ((char) c))
+                                                               id_builder[pos++] = (char) c;
+
+                                                       if (surrogate != 0) {
+                                                               c = surrogate;
+                                                       }
+
+                                                       continue;
+                                               }
+                                       } else if (Char.IsLetter ((char) c) || Char.GetUnicodeCategory ((char) c) == UnicodeCategory.ConnectorPunctuation) {
+                                               id_builder [pos++] = (char) c;
+                                               continue;
+                                       }
+
+                                       putback_char = c;
+                                       break;
+                               }
+                       } catch (IndexOutOfRangeException) {
+                               Report.Error (645, Location, "Identifier too long (limit is 512 chars)");
+                               --pos;
+                               col += pos;
+                       }
+
+                       col += pos - 1;
+
+                       //
+                       // Optimization: avoids doing the keyword lookup
+                       // on uppercase letters
+                       //
+                       if (!quoted && !is_config_ident && id_builder [0] >= '_') {
+                               int keyword = GetKeyword (id_builder, pos);
+                               if (keyword != -1) {
+                                       val = ltb.Create (keyword == Token.AWAIT ? "await" : null, current_source, ref_line, column);
+                                       if (keyword == Token.ELSE && do_auto_semi_insertion(parse_token, line, -1, keyword)) 
+                                               return Token.SEMICOLON;
+                                       return keyword;
+                               }
+                       }
+
+                       string s = InternIdentifier (id_builder, pos);
+
+                       val = ltb.Create (s, current_source, ref_line, column);
+                       if (quoted && parsing_attribute_section)
+                               AddEscapedIdentifier (((LocatedToken) val).Location);
+
+                       return is_config_ident ? Token.IDENTIFIER_CONFIG : Token.IDENTIFIER;
+               }
+
+               string InternIdentifier (char[] charBuffer, int length)
+               {
+                       //
+                       // Keep identifiers in an array of hashtables to avoid needless
+                       // allocations
+                       //
+                       var identifiers_group = identifiers[length];
+                       string s;
+                       if (identifiers_group != null) {
+                               if (identifiers_group.TryGetValue (charBuffer, out s)) {
+                                       return s;
+                               }
+                       } else {
+                               // TODO: this should be number of files dependant
+                               // corlib compilation peaks at 1000 and System.Core at 150
+                               int capacity = length > 20 ? 10 : 100;
+                               identifiers_group = new Dictionary<char[], string> (capacity, new IdentifiersComparer (length));
+                               identifiers[length] = identifiers_group;
+                       }
+
+                       char[] chars = new char[length];
+                       Array.Copy (charBuffer, chars, length);
+
+                       s = new string (charBuffer, 0, length);
+                       identifiers_group.Add (chars, s);
+                       return s;
+               }
+               
+               public int xtoken (bool parse_token = false)
+               {
+                       int d, c, next;
+
+                       // Allow next token to be pushed back if we insert semicolons
+                       if (putback_token != -1) {
+                               next = putback_token;
+                               putback_token = -1;
+                               return next;
+                       }
+
+                       // Decrement parse regex counter (allows regex literals to follow 1 token after 
+                       // symbols '=', ':', '(', '[', and ',')
+                       if (parse_regex_xml > 0)
+                               parse_regex_xml--;
+
+                       // Decrement parse colon counter (allows us to disambiguate ident:*=value from *= operator)
+                       if (parse_colon > 0)
+                               parse_colon--;
+
+                       // Decrement allow auto semi counter (allows us to allow semicolon insertion only after next x symbols)
+                       if (allow_auto_semi_after > 0)
+                               allow_auto_semi_after--;
+
+                       // Whether we have seen comments on the current line
+                       bool comments_seen = false;
+                       while ((c = get_char ()) != -1) {
+                               switch (c) {
+                               case '\t':
+                                       col = ((col - 1 + tab_size) / tab_size) * tab_size;
+                                       continue;
+
+                               case ' ':
+                               case '\f':
+                               case '\v':
+                               case 0xa0:
+                               case 0:
+                               case 0xFEFF:    // Ignore BOM anywhere in the file
+                                       continue;
+
+/*                             This is required for compatibility with .NET
+                               case 0xEF:
+                                       if (peek_char () == 0xBB) {
+                                               PushPosition ();
+                                               get_char ();
+                                               if (get_char () == 0xBF)
+                                                       continue;
+                                               PopPosition ();
+                                       }
+                                       break;
+*/
+                               case '\\':
+                                       tokens_seen = true;
+                                       return consume_identifier (parse_token, c);
+
+                               case '{':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       if (current_token == Token.OPEN_PARENS || 
+                                         current_token == Token.ASSIGN ||
+                                         current_token == Token.COMMA ||
+                                         current_token == Token.COLON ||
+                                         current_token == Token.OPEN_BRACKET ||
+                                         current_token == Token.OPEN_BRACKET_EXPR ||
+                                         current_token == Token.RETURN) {
+                                               bool isInit = true;
+                                               PushPosition();
+                                               next = token ();
+                                               if (next != Token.CLOSE_BRACE) {
+                                                       if (next != Token.IDENTIFIER && next != Token.LITERAL) {
+                                                               isInit = false;
+                                                       } else {
+                                                               next = token ();
+                                                               if (next != Token.COLON) {
+                                                                       isInit = false;
+                                                               }
+                                                       }
+                                               }
+                                               PopPosition();
+                                               if (isInit) 
+                                                       return Token.OPEN_BRACE_INIT;
+                                       }
+                                       return Token.OPEN_BRACE;
+                               case '}':
+                                       if (do_auto_semi_insertion (parse_token, line, c, -1))
+                                               return Token.SEMICOLON;
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       return Token.CLOSE_BRACE;
+                               case '[':
+                                       // To block doccomment inside attribute declaration.
+                                       if (doc_state == XmlCommentState.Allowed)
+                                               doc_state = XmlCommentState.NotAllowed;
+
+                                       val = ltb.Create (current_source, ref_line, col);
+
+                                       parse_regex_xml = 2;  // regex literals may be included in array initializers.
+
+                                       if (parsing_block == 0 || lambda_arguments_parsing)
+                                               return Token.OPEN_BRACKET;
+
+                                       next = peek_char ();
+                                       switch (next) {
+                                       case ']':
+                                       case ',':
+                                               return Token.OPEN_BRACKET;
+
+                                       case ' ':
+                                       case '\f':
+                                       case '\v':
+                                       case '\r':
+                                       case '\n':
+                                       case '/':
+                                               next = peek_token ();
+                                               if (next == Token.COMMA || next == Token.CLOSE_BRACKET)
+                                                       return Token.OPEN_BRACKET;
+
+                                               return Token.OPEN_BRACKET_EXPR;
+                                       default:
+                                               return Token.OPEN_BRACKET_EXPR;
+                                       }
+                               case ']':
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
+                                       return Token.CLOSE_BRACKET;
+                               case '(':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       parse_regex_xml = 2; // regex literals may follow open parens (method param, expressions).
+                                       //
+                                       // An expression versions of parens can appear in block context only
+                                       //
+                                       if (parsing_block != 0 && !lambda_arguments_parsing) {
+                                               
+                                               //
+                                               // Optmize most common case where we know that parens
+                                               // is not special
+                                               //
+                                               switch (current_token) {
+                                               case Token.IDENTIFIER:
+                                               case Token.IF:
+                                               case Token.FOR:
+                                               case Token.FOR_EACH:
+                                               case Token.TYPEOF:
+                                               case Token.WHILE:
+                                               case Token.USING:
+                                               case Token.DEFAULT:
+                                               case Token.DELEGATE:
+                                               case Token.OP_GENERICS_GT:
+                                                       return Token.OPEN_PARENS;
+                                               }
+
+                                               // Optimize using peek
+                                               int xx = peek_char ();
+                                               switch (xx) {
+                                               case '(':
+                                               case '\'':
+                                               case '"':
+                                               case '0':
+                                               case '1':
+                                                       return Token.OPEN_PARENS;
+                                               }
+
+                                               lambda_arguments_parsing = true;
+                                               PushPosition ();
+                                               d = TokenizeOpenParens ();
+                                               PopPosition ();
+                                               lambda_arguments_parsing = false;
+                                               return d;
+                                       }
+
+                                       return Token.OPEN_PARENS;
+                               case ')':
+//                                     d = peek_char ();
+//                                     if (d == '.') {
+//                                             get_char ();
+//                                             return Token.CLOSE_PARENS_DOT;
+//                                     }
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
+                                       return Token.CLOSE_PARENS;
+                               case ',':
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
+                                       parse_regex_xml = 2; // Regex literals may follow commas, (method param, initializer element)
+                                       return Token.COMMA;
+                               case ';':
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
+                                       return Token.SEMICOLON;
+                               case '~':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       return Token.TILDE;
+                               case '?':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       return TokenizePossibleNullableType ();
+
+                               case '<':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       d = peek_char ();
+
+                                       if (d == '=') {
+                                               get_char ();
+                                               return Token.OP_LE;
+                                       }
+
+                                       if (d == '<') {
+                                               get_char ();
+                                               d = peek_char ();
+
+                                               if (d == '=') {
+                                                       get_char ();
+                                                       return Token.OP_SHIFT_LEFT_ASSIGN;
+                                               }
+                                               return Token.OP_SHIFT_LEFT;
+                                       }
+
+                                       if (parse_regex_xml > 0 && char.IsLetter ((char)d)) {
+                                               return consume_xml();
+                                       }
+
+                                       return Token.OP_LT;
+
+                               case '>':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       d = peek_char ();
+
+                                       if (parsing_generic_less_than > 1 || (parsing_generic_less_than == 1 && d != '>')) {
+                                               parsing_generic_less_than--;
+                                               return Token.OP_GENERICS_GT;
+                                       }
+
+                                       if (d == '=') {
+                                               get_char ();
+                                               return Token.OP_GE;
+                                       }
+
+                                       if (d == '>') {
+                                               get_char ();
+                                               d = peek_char ();
+
+                                               if (d == '=') {
+                                                       get_char ();
+                                                       return Token.OP_SHIFT_RIGHT_ASSIGN;
+                                               }
+
+                                               if (d == '>') {
+                                                       get_char ();
+                                                       d = peek_char ();
+
+                                                       if (d == '=') {
+                                                               get_char ();
+                                                               return Token.OP_USHIFT_RIGHT_ASSIGN;
+                                                       }
+
+                                                       return Token.OP_USHIFT_RIGHT;
+                                               }
+                                               return Token.OP_SHIFT_RIGHT;
+                                       }
+
+                                       return Token.OP_GT;
+
+                               case '+':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       d = peek_char ();
+                                       if (d == '+') {
+                                               d = Token.OP_INC;
+                                       } else if (d == '=') {
+                                               d = Token.OP_ADD_ASSIGN;
+                                       } else {
+                                               return Token.PLUS;
+                                       }
+                                       get_char ();
+                                       return d;
+
+                               case '-':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       d = peek_char ();
+                                       if (d == '-') {
+                                               d = Token.OP_DEC;
+                                       } else if (d == '=')
+                                               d = Token.OP_SUB_ASSIGN;
+                                       else if (d == '>')
+                                               d = Token.OP_PTR;
+                                       else {
+                                               return Token.MINUS;
+                                       }
+                                       get_char ();
+                                       return d;
+
+                               case '!':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       if (peek_char () == '=') {
+                                               get_char ();
+                                               if (peek_char () == '=') {
+                                                       get_char ();
+                                                       return Token.OP_REF_NE;
+                                               }
+                                               return Token.OP_NE;
+                                       }
+                                       return Token.BANG;
+
+                               case '=':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       d = peek_char ();
+                                       if (d == '=') {
+                                               parse_regex_xml = 2; // Regex literals may follow equality test operators.
+                                               get_char ();
+                                               d = peek_char ();
+                                               if (d == '=') {
+                                                       get_char ();
+                                                       return Token.OP_REF_EQ;
+                                               }
+                                               return Token.OP_EQ;
+                                       }
+                                       if (d == '>' && parsing_playscript) {
+                                               get_char ();
+                                               return Token.ARROW;
+                                       }
+
+                                       parse_regex_xml = 2; // Regex literals may follow assignment op '='
+                                       return Token.ASSIGN;
+
+                               case '&':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       d = peek_char ();
+                                       if (d == '&') {
+                                               get_char ();
+                                               d = peek_char ();
+                                               if (d == '=') {
+                                                       get_char ();
+                                                       return Token.LOGICAL_AND_ASSIGN;
+                                               }
+                                               return Token.OP_AND;
+                                       }
+                                       if (d == '=') {
+                                               get_char ();
+                                               return Token.OP_AND_ASSIGN;
+                                       }
+                                       return Token.BITWISE_AND;
+
+                               case '|':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       d = peek_char ();
+                                       if (d == '|') {
+                                               get_char ();
+                                               d = peek_char ();
+                                               if (d == '=') {
+                                                       get_char ();
+                                                       return Token.LOGICAL_OR_ASSIGN;
+                                               }
+                                               return Token.OP_OR;
+                                       }
+                                       if (d == '=') {
+                                               get_char ();
+                                               return Token.OP_OR_ASSIGN;
+                                       }
+                                       return Token.BITWISE_OR;
+
+                               case '*':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       if (peek_char () == '=' && parse_colon == 0) {
+                                               get_char ();
+                                               return Token.OP_MULT_ASSIGN;
+                                       }
+                                       return Token.STAR;
+
+                               case '/':
+                                       d = peek_char ();
+                                       if (d == '=') {
+                                               val = ltb.Create (current_source, ref_line, col);
+                                               get_char ();
+                                               return Token.OP_DIV_ASSIGN;
+                                       }
+
+                                       // Handle double-slash comments.
+                                       if (d == '/') {
+                                               get_char ();
+                                               if (doc_processing) {
+                                                       if (peek_char () == '/') {
+                                                               get_char ();
+                                                               // Don't allow ////.
+                                                               if ((d = peek_char ()) != '/') {
+                                                                       if (doc_state == XmlCommentState.Allowed)
+                                                                               handle_one_line_xml_comment ();
+                                                                       else if (doc_state == XmlCommentState.NotAllowed)
+                                                                               WarningMisplacedComment (Location - 3);
+                                                               }
+                                                       } else {
+                                                               if (xml_comment_buffer.Length > 0)
+                                                                       doc_state = XmlCommentState.NotAllowed;
+                                                       }
+                                               }
+
+                                               while ((d = get_char ()) != -1 && d != '\n');
+
+                                               if (d == '\n')
+                                                       putback (d);
+
+                                               any_token_seen |= tokens_seen;
+                                               tokens_seen = false;
+                                               comments_seen = false;
+                                               continue;
+                                       } else if (d == '*') {
+                                               get_char ();
+                                               // Handle /*@asx conditional comment
+                                               if (peek_char () == '@') {
+                                                       PushPosition();
+                                                       get_char ();
+                                                       if (peek_char() == 'a') {
+                                                               get_char ();
+                                                               if (peek_char () == 's') {
+                                                                       get_char ();
+                                                                       if (peek_char () == 'x') {
+                                                                               get_char ();
+                                                                               DiscardPosition();
+                                                                               continue;
+                                                                       }
+                                                               }
+                                                       }
+                                                       PopPosition();
+                                               }
+                                               bool docAppend = false;
+                                               if (doc_processing && peek_char () == '*') {
+                                                       get_char ();
+                                                       // But when it is /**/, just do nothing.
+                                                       if (peek_char () == '/') {
+                                                               get_char ();
+                                                               continue;
+                                                       }
+                                                       if (doc_state == XmlCommentState.Allowed)
+                                                               docAppend = true;
+                                                       else if (doc_state == XmlCommentState.NotAllowed) {
+                                                               WarningMisplacedComment (Location - 2);
+                                                       }
+                                               }
+
+                                               int current_comment_start = 0;
+                                               if (docAppend) {
+                                                       current_comment_start = xml_comment_buffer.Length;
+                                                       xml_comment_buffer.Append (Environment.NewLine);
+                                               }
+
+                                               while ((d = get_char ()) != -1) {
+                                                       if (d == '*' && peek_char () == '/') {
+                                                               get_char ();
+                                                               comments_seen = true;
+                                                               break;
+                                                       }
+                                                       if (docAppend)
+                                                               xml_comment_buffer.Append ((char)d);
+                                                       
+                                                       if (d == '\n') {
+                                                               any_token_seen |= tokens_seen;
+                                                               tokens_seen = false;
+                                                               // 
+                                                               // Reset 'comments_seen' just to be consistent.
+                                                               // It doesn't matter either way, here.
+                                                               //
+                                                               comments_seen = false;
+                                                       }
+                                               }
+                                               if (!comments_seen)
+                                                       Report.Error (1035, Location, "End-of-file found, '*/' expected");
+
+                                               if (docAppend)
+                                                       update_formatted_doc_comment (current_comment_start);
+                                               continue;
+                                       } else if (parse_regex_xml > 0) {
+                                               // A regex literal may follow an '=', '==', '===' '(' ',' ':' or '['. 
+                                               return consume_regex();
+                                       }
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       return Token.DIV;
+
+                               case '%':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       if (peek_char () == '=') {
+                                               get_char ();
+                                               return Token.OP_MOD_ASSIGN;
+                                       }
+                                       return Token.PERCENT;
+
+                               case '^':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       if (peek_char () == '=') {
+                                               get_char ();
+                                               return Token.OP_XOR_ASSIGN;
+                                       }
+                                       return Token.CARRET;
+
+                               case ':':
+                                       val = ltb.Create (current_source, ref_line, col);
+                                       if (peek_char () == ':') {
+                                               get_char ();
+                                               return Token.DOUBLE_COLON;
+                                       }
+                                       parse_regex_xml = 2;  // Regex literals may follow colons in object initializers.
+                                       parse_colon = 2;  // Don't parse *= after a colon 
+                                       return Token.COLON;
+
+                               case '0': case '1': case '2': case '3': case '4':
+                               case '5': case '6': case '7': case '8': case '9':
+                                       tokens_seen = true;
+                                       return is_number (c);
+
+                               case '\n': // white space
+                                       if (do_auto_semi_insertion (parse_token, line - 1, c, -1))
+                                               return Token.SEMICOLON;
+                                       any_token_seen |= tokens_seen;
+                                       tokens_seen = false;
+                                       comments_seen = false;
+                                       continue;
+
+                               case '.':
+                                       tokens_seen = true;
+                                       d = peek_char ();
+                                       if (d >= '0' && d <= '9') 
+                                               return is_number (c);
+
+                                       if (d == '@') {
+                                               get_char ();
+                                               return Token.DOT_AT;
+                                       }
+
+                                       if (d == '*') {
+                                               get_char ();
+                                               return Token.DOT_STAR;
+                                       }
+
+//                                     if (d == '(') {
+//                                             get_char ();
+//                                             return Token.DOT_OPEN_PARENS;
+//                                     }
+
+                                       if (d == '.') {
+                                               get_char ();
+                                               d = peek_char ();
+                                               if (d == '.') {
+                                                       get_char ();
+                                                       return Token.DOTDOTDOT;
+                                               }
+                                               if (d == '@') {
+                                                       get_char ();
+                                                       return Token.DOTDOT_AT;
+                                               }
+                                               if (d == '*') {
+                                                       get_char ();
+                                                       return Token.DOTDOT_STAR;
+                                               }
+                                               return Token.DOTDOT;
+                                       }
+
+                                       ltb.CreateOptional (current_source, ref_line, col, ref val);
+                                       if (d != '<') {
+                                               return Token.DOT;
+                                       }
+                                       get_char ();
+                                       parsing_generic_less_than++;
+                                       int dim;
+                                       PushPosition ();
+                                       if (parse_generic_dimension (out dim)) {
+                                               val = dim;
+                                               DiscardPosition ();
+                                               return Token.GENERIC_DIMENSION;
+                                       }
+                                       PopPosition ();
+                                       return Token.OP_GENERICS_LT;
+                               
+                               case '#':
+                                       if (tokens_seen || comments_seen) {
+                                               Eror_WrongPreprocessorLocation ();
+                                               return Token.ERROR;
+                                       }
+                                       
+                                       if (ParsePreprocessingDirective (true))
+                                               continue;
+
+                                       bool directive_expected = false;
+                                       while ((c = get_char ()) != -1) {
+                                               if (col == 1) {
+                                                       directive_expected = true;
+                                               } else if (!directive_expected) {
+                                                       // TODO: Implement comment support for disabled code and uncomment this code
+//                                                     if (c == '#') {
+//                                                             Eror_WrongPreprocessorLocation ();
+//                                                             return Token.ERROR;
+//                                                     }
+                                                       continue;
+                                               }
+
+                                               if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\v')
+                                                       continue;
+
+                                               if (c == '#') {
+                                                       if (ParsePreprocessingDirective (false))
+                                                               break;
+                                               }
+                                               directive_expected = false;
+                                       }
+
+                                       if (c != -1) {
+                                               tokens_seen = false;
+                                               continue;
+                                       }
+
+                                       return Token.EOF;
+                               
+                               case '"':
+                                       return consume_string (false, '"');
+                               case '\'':
+                                       return consume_string (false, '\'');
+
+//                             case '\'':
+//                                     return TokenizeBackslash ();
+                               
+                               case '@':
+                                       if (!parsing_playscript)
+                                               return Token.OP_AT;
+
+                                       c = get_char ();
+                                       if (c == '"') {
+                                               tokens_seen = true;
+                                               return consume_string (true);
+                                       }
+
+                                       // Handle end @asx*/ conditional comment
+                                       PushPosition();
+                                       if (c == 'a') {
+                                               if (peek_char () == 's') {
+                                                       get_char ();
+                                                       if (peek_char () == 'x') {
+                                                               get_char ();
+                                                               if (peek_char () == '*') {
+                                                                       get_char ();
+                                                                       if (peek_char () == '/') {
+                                                                               get_char ();
+                                                                               DiscardPosition();
+                                                                               continue;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       PopPosition();
+
+                                       if (is_identifier_start_character (c)){
+                                               return consume_identifier (parse_token, c, true);
+                                       }
+
+                                       Report.Error (1646, Location, "Keyword, identifier, or string expected after verbatim specifier: @");
+                                       return Token.ERROR;
+
+                               case EvalStatementParserCharacter:
+                                       return Token.EVAL_STATEMENT_PARSER;
+                               case EvalCompilationUnitParserCharacter:
+                                       return Token.EVAL_COMPILATION_UNIT_PARSER;
+                               case EvalUsingDeclarationsParserCharacter:
+                                       return Token.EVAL_USING_DECLARATIONS_UNIT_PARSER;
+                               case DocumentationXref:
+                                       return Token.DOC_SEE;
+                               }
+
+                               if (is_identifier_start_character (c)) {
+                                       tokens_seen = true;
+                                       return consume_identifier (parse_token, c);
+                               }
+
+                               if (char.IsWhiteSpace ((char) c))
+                                       continue;
+
+                               Report.Error (1056, Location, "Unexpected character `{0}'", ((char) c).ToString ());
+                       }
+
+                       if (CompleteOnEOF){
+                               if (generated)
+                                       return Token.COMPLETE_COMPLETION;
+                               
+                               generated = true;
+                               return Token.GENERATE_COMPLETION;
+                       }
+                       
+
+                       return Token.EOF;
+               }
+
+//             int TokenizeBackslash ()
+//             {
+//#if FULL_AST
+//                     int read_start = reader.Position;
+//#endif
+//                     Location start_location = Location;
+//                     int c = get_char ();
+//                     tokens_seen = true;
+//                     if (c == '\'') {
+//                             val = new CharLiteral (context.BuiltinTypes, (char) c, start_location);
+//                             Report.Error (1011, start_location, "Empty character literal");
+//                             return Token.LITERAL;
+//                     }
+//
+//                     if (c == '\n') {
+//                             Report.Error (1010, start_location, "Newline in constant");
+//                             return Token.ERROR;
+//                     }
+//
+//                     int d;
+//                     c = escape (c, out d);
+//                     if (c == -1)
+//                             return Token.ERROR;
+//                     if (d != 0)
+//                             throw new NotImplementedException ();
+//
+//                     ILiteralConstant res = new CharLiteral (context.BuiltinTypes, (char) c, start_location);
+//                     val = res;
+//                     c = get_char ();
+//
+//                     if (c != '\'') {
+//                             Report.Error (1012, start_location, "Too many characters in character literal");
+//
+//                             // Try to recover, read until newline or next "'"
+//                             while ((c = get_char ()) != -1) {
+//                                     if (c == '\n' || c == '\'')
+//                                             break;
+//                             }
+//                     }
+//
+//#if FULL_AST
+//                     res.ParsedValue = reader.ReadChars (read_start - 1, reader.Position);
+//#endif
+//
+//                     return Token.LITERAL;
+//             }
+
+
+               //
+               // Handles one line xml comment
+               //
+               private void handle_one_line_xml_comment ()
+               {
+                       int c;
+                       while ((c = peek_char ()) == ' ')
+                               get_char (); // skip heading whitespaces.
+                       while ((c = peek_char ()) != -1 && c != '\n' && c != '\r') {
+                               xml_comment_buffer.Append ((char) get_char ());
+                       }
+                       if (c == '\r' || c == '\n')
+                               xml_comment_buffer.Append (Environment.NewLine);
+               }
+
+               //
+               // Remove heading "*" in Javadoc-like xml documentation.
+               //
+               private void update_formatted_doc_comment (int current_comment_start)
+               {
+                       int length = xml_comment_buffer.Length - current_comment_start;
+                       string [] lines = xml_comment_buffer.ToString (
+                               current_comment_start,
+                               length).Replace ("\r", "").Split ('\n');
+                       
+                       // The first line starts with /**, thus it is not target
+                       // for the format check.
+                       for (int i = 1; i < lines.Length; i++) {
+                               string s = lines [i];
+                               int idx = s.IndexOf ('*');
+                               string head = null;
+                               if (idx < 0) {
+                                       if (i < lines.Length - 1)
+                                               return;
+                                       head = s;
+                               } else
+                                       head = s.Substring (0, idx);
+                               foreach (char c in head)
+                                       if (c != ' ')
+                                               return;
+                               lines [i] = s.Substring (idx + 1);
+                       }
+                       xml_comment_buffer.Remove (current_comment_start, length);
+                       xml_comment_buffer.Insert (current_comment_start, String.Join (Environment.NewLine, lines));
+               }
+
+               //
+               // Checks if there was incorrect doc comments and raise
+               // warnings.
+               //
+               public void check_incorrect_doc_comment ()
+               {
+                       if (xml_comment_buffer.Length > 0)
+                               WarningMisplacedComment (Location);
+               }
+
+               //
+               // Consumes the saved xml comment lines (if any)
+               // as for current target member or type.
+               //
+               public string consume_doc_comment ()
+               {
+                       if (xml_comment_buffer.Length > 0) {
+                               string ret = xml_comment_buffer.ToString ();
+                               reset_doc_comment ();
+                               return ret;
+                       }
+                       return null;
+               }
+
+               Report Report {
+                       get { return context.Report; }
+               }
+
+               void reset_doc_comment ()
+               {
+                       xml_comment_buffer.Length = 0;
+               }
+
+               bool do_auto_semi_insertion (bool parse_token, int line, int c, int t)
+               {
+                       bool insert_semi = false;
+                       if (parse_token && prev_token_line == line && prev_token != Token.SEMICOLON && !parsing_playscript && allow_auto_semi && 
+                           allow_auto_semi_after == 0 && allowed_auto_semi_tokens[prev_token]) {
+                               PushPosition ();
+                               int next = xtoken ();
+                               PopPosition ();
+                               if (!disallowed_next_auto_semi_tokens[next]) {
+                                       if (c != -1)
+                                               putback (c);
+                                       else
+                                               token_putback (t);
+                                       warn_semi_inserted (Location);
+                                       insert_semi = true;
+                               }
+                       }
+                       if (parse_token && has_temp_auto_semi_after_tokens)
+                               clear_temp_auto_semi_tokens ();
+                       return insert_semi;
+               }
+
+               void warn_semi_inserted (Location loc) 
+               {
+                       Report.Warning (7093, 1, loc, "Semicolon automatically inserted on unterminated line.");
+               }
+
+               void clear_temp_auto_semi_tokens ()
+               {
+                       var len = temp_auto_semi_after_tokens.Count;
+                       for (var i = 0; i < len; i++) {
+                               int token = temp_auto_semi_after_tokens[i];
+                               allowed_auto_semi_tokens.Set (token, false);
+                       }
+                       has_temp_auto_semi_after_tokens = false;
+               }
+
+               public void cleanup ()
+               {
+                       if (ifstack != null && ifstack.Count >= 1) {
+                               int state = ifstack.Pop ();
+                               if ((state & REGION) != 0)
+                                       Report.Error (1038, Location, "#endregion directive expected");
+                               else 
+                                       Report.Error (1027, Location, "Expected `#endif' directive");
+                       }
+               }
+       }
+
+       //
+       // Indicates whether it accepts XML documentation or not.
+       //
+       public enum XmlCommentState {
+               // comment is allowed in this state.
+               Allowed,
+               // comment is not allowed in this state.
+               NotAllowed,
+               // once comments appeared when it is NotAllowed, then the
+               // state is changed to it, until the state is changed to
+               // .Allowed.
+               Error
+       }
+}
+
index f49a2980d7aa08a37ad608d4a1e958b934a35208..655d469ccca673ac9c6355096151a755ff60bd7e 100644 (file)
@@ -231,6 +231,22 @@ namespace Mono.CSharp {
                        printer.Print (msg, settings.ShowFullPaths);
                }
 
+               public void WarningPlayScript (int code, Location loc, string format, string arg)
+               {
+                       WarningPlayScript (code, loc, string.Format (format, arg));
+               }
+
+               public void WarningPlayScript (int code, Location loc, string error)
+               {
+                       if (reporting_disabled > 0)
+                               return;
+
+                       var msg = new PlayScript.WarningMessage (code, loc, error, extra_information);
+                       extra_information.Clear ();
+
+                       printer.Print (msg, settings.ShowFullPaths);
+               }
+
                public void Warning (int code, int level, Location loc, string format, string arg)
                {
                        Warning (code, level, loc, String.Format (format, arg));
@@ -278,9 +294,30 @@ namespace Mono.CSharp {
                        if (reporting_disabled > 0)
                                return;
 
-                       ErrorMessage msg = new ErrorMessage (code, loc, error, extra_information);
+                       var msg = new ErrorMessage (code, loc, error, extra_information);
+                       extra_information.Clear ();
+
+                       ProcessErrorMessage (msg);
+               }
+
+               public void ErrorPlayScript (int code, Location loc, string format, string arg)
+               {
+                       ErrorPlayScript (code, loc, string.Format (format, arg));
+               }
+
+               public void ErrorPlayScript (int code, Location loc, string error)
+               {
+                       if (reporting_disabled > 0)
+                               return;
+
+                       var msg = new PlayScript.ErrorMessage (code, loc, error, extra_information);
                        extra_information.Clear ();
 
+                       ProcessErrorMessage (msg);
+               }
+
+               void ProcessErrorMessage (AbstractMessage msg)
+               {
                        printer.Print (msg, settings.ShowFullPaths);
 
                        if (settings.Stacktrace)
@@ -489,6 +526,12 @@ namespace Mono.CSharp {
 
                public abstract bool IsWarning { get; }
 
+               public virtual string LanguagePrefix {
+                       get {
+                               return "CS";
+                       }
+               }
+
                public Location Location {
                        get { return location; }
                }
@@ -594,7 +637,7 @@ namespace Mono.CSharp {
                                txt.Append (" ");
                        }
 
-                       txt.AppendFormat ("{0} CS{1:0000}: {2}", msg.MessageType, msg.Code, msg.Text);
+                       txt.AppendFormat ("{0} {3}{1:0000}: {2}", msg.MessageType, msg.Code, msg.Text, msg.LanguagePrefix);
 
                        if (!msg.IsWarning)
                                output.WriteLine (FormatText (txt.ToString ()));
index 4bd207aa00f0f72729c019c4458dfeec50794d6a..4e553f70a76c065ecba9941508401f7a362716be 100644 (file)
@@ -969,7 +969,7 @@ namespace Mono.CSharp {
                                return false;
 
                        if (expr.Type != block_return_type && expr.Type != InternalType.ErrorType) {
-                               expr = Convert.ImplicitConversionRequired (ec, expr, block_return_type, loc);
+                               expr = Convert.ImplicitConversionRequiredEnhanced (ec, expr, block_return_type, loc);
 
                                if (expr == null) {
                                        if (am != null && block_return_type == ec.ReturnType) {
index f9e623971a7eae404d3dd59a6bdee4ed2af5d711..362f425dcdbb0d3f179e5f63bf0f0065fcc96958 100644 (file)
@@ -190,6 +190,15 @@ namespace Mono.CSharp
                        }
                }
 
+               //
+               // Only used by PlayScript dynamic classes
+               //
+               public bool IsDynamicClass {
+                       get {
+                               return (Modifiers & Modifiers.DYNAMIC) != 0;
+                       }
+               }
+
                //
                // Returns true for instances of Expression<T>
                //
@@ -647,7 +656,7 @@ namespace Mono.CSharp
                                //
                                // Null is considered to be a reference type
                                //                      
-                               return t == InternalType.NullLiteral || t.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
+                               return t == InternalType.NullLiteral || t.BuiltinType == BuiltinTypeSpec.Type.Dynamic || t.BuiltinType == BuiltinTypeSpec.Type.Object;
                        default:
                                return true;
                        }
@@ -920,7 +929,7 @@ namespace Mono.CSharp
                        case "String": return "string";
                        case "Boolean": return "bool";
                        case "Void": return "void";
-                       case "Object": return "object";
+                       case "Object": return ns.Length == 0 ? name : "object";
                        case "UInt32": return "uint";
                        case "Int16": return "short";
                        case "UInt16": return "ushort";
@@ -1388,6 +1397,7 @@ namespace Mono.CSharp
                bool IsPartial { get; }
                bool IsComImport { get; }
                bool IsTypeForwarder { get; }
+               bool IsPlayScriptType { get; }
                int TypeParametersCount { get; }
                TypeParameterSpec[] TypeParameters { get; }
 
@@ -1453,6 +1463,12 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsPlayScriptType {
+                       get {
+                               return false;
+                       }
+               }
+
                bool ITypeDefinition.IsTypeForwarder {
                        get {
                                return false;
@@ -1589,6 +1605,12 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsPlayScriptType {
+                       get {
+                               return false;
+                       }
+               }
+
                public override string Name {
                        get {
                                throw new NotSupportedException ();
index b0a932eb4f9f77f89dc060317ca77501c0e1133c..a9d9c112017a56a08c160555f3ca81d8d8f297e7 100644 (file)
@@ -68,6 +68,9 @@ qcheck2:
 gen-mt-tests:
        $(TESTER) -mode:nunit -files:'v2' -compiler:$(COMPILER) -issues:known-issues-mt -compiler-options:"-lib:$(topdir)/class/lib/monotouch projects/MonoTouch/ivt.cs"
 
+playscript:
+       $(TESTER) -mode:pos -files:'*-???.play' -compiler:$(COMPILER) -issues:known-issues-$(PROFILE) -log:$(PROFILE).log -il:ver-il-$(PROFILE).xml $(DEFINES) $(TOPTIONS)
+
 test-local:
        @:
 
diff --git a/mcs/tests/test-ps-001.play b/mcs/tests/test-ps-001.play
new file mode 100644 (file)
index 0000000..2a7f2f6
--- /dev/null
@@ -0,0 +1,10 @@
+package\r
+{\r
+       public class HelloWorld \r
+       {\r
+               public static function Main():void\r
+               {\r
+                       trace ("Hello World!");\r
+               }\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-002-2.play b/mcs/tests/test-ps-002-2.play
new file mode 100644 (file)
index 0000000..ffc9296
--- /dev/null
@@ -0,0 +1,6 @@
+package {\r
+       public function testFunction (obj:*, cl:Class):Boolean\r
+       {\r
+               return false;\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-002.play b/mcs/tests/test-ps-002.play
new file mode 100644 (file)
index 0000000..5d36a3e
--- /dev/null
@@ -0,0 +1,13 @@
+// Compiler options: test-ps-002-2.play\r
+\r
+package\r
+{\r
+       public class Test \r
+       {\r
+               public static function Main():int\r
+               {\r
+                       testFunction ("arg", null);\r
+                       return 0;\r
+               }\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-003.play b/mcs/tests/test-ps-003.play
new file mode 100644 (file)
index 0000000..99e5f80
--- /dev/null
@@ -0,0 +1,24 @@
+package\r
+{\r
+       public class BasicTypes \r
+       {\r
+               var f_obj:Object = null;\r
+               var f_str:String = "string";\r
+               var f_n:Number = 9.3;\r
+               var f_i:int = -3;\r
+               var f_ui:uint = 44;\r
+               var f_b:Boolean = true;\r
+               var f_any:* = 9;\r
+\r
+               public static function Main():void\r
+               {\r
+                       var obj:Object = null;\r
+                       var str1:String = "string";\r
+                       var n:Number = 9.3;\r
+                       var i:int = -3;\r
+                       var ui:uint = 44;\r
+                       var b:Boolean = true;\r
+                       var any:* = null;\r
+               }\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-004.play b/mcs/tests/test-ps-004.play
new file mode 100644 (file)
index 0000000..d20d1dd
--- /dev/null
@@ -0,0 +1,33 @@
+package\r
+{\r
+       public static function Main():int\r
+       {\r
+               var a:BaseClass = new TestClass ();\r
+               if (a.p != 15)\r
+                       return 1;\r
+                       \r
+               a = new BaseClass ();\r
+               if (a.p != 3)\r
+                       return 2;\r
+               \r
+               return 0;\r
+       }\r
+}\r
+\r
+class BaseClass\r
+{\r
+       public var p:int;\r
+       \r
+       function BaseClass ()\r
+       {\r
+               p = 3;\r
+       }\r
+}\r
+\r
+class TestClass extends BaseClass\r
+{\r
+       function TestClass ()\r
+       {\r
+               p *= 5;\r
+       }\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-005.play b/mcs/tests/test-ps-005.play
new file mode 100644 (file)
index 0000000..0dd6633
--- /dev/null
@@ -0,0 +1,18 @@
+package\r
+{\r
+       internal class test\r
+       {\r
+               public static function Main():int\r
+               {\r
+                       if (max (4, 30) != 30)\r
+                               return 1;\r
+                               \r
+                       return 0;\r
+               }\r
+\r
+               internal static function max (n1:Number, n2:Number): Number\r
+               {\r
+                       return System.Math.Max (n1, n2);\r
+               }\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-006-2.play b/mcs/tests/test-ps-006-2.play
new file mode 100644 (file)
index 0000000..1e48a75
--- /dev/null
@@ -0,0 +1,20 @@
+package\r
+{\r
+       public dynamic class TestClass \r
+       {\r
+               public function TestClass() \r
+               {\r
+               }\r
+               \r
+               private var ui:uint;\r
+\r
+               internal function get Prop():uint {\r
+                       return ui;\r
+               }\r
+\r
+               internal function set Prop(value:uint):void {\r
+                       ui = value;\r
+               }\r
+               \r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-006.play b/mcs/tests/test-ps-006.play
new file mode 100644 (file)
index 0000000..9e7942e
--- /dev/null
@@ -0,0 +1,39 @@
+// Compiler options: test-ps-006-2.play\r
+\r
+package\r
+{\r
+       public class test\r
+       {\r
+               public static function Main():int\r
+               {\r
+                       //Prop = 3;\r
+                       //if (Prop != 3)\r
+                       //      return 1;\r
+\r
+                       var m:TestClass = new TestClass ();\r
+                       m.Prop = 300;\r
+                       if (m.Prop != 300)\r
+                               return 2;\r
+                               \r
+                       m["Prop"] = 500;\r
+                       if (m.Prop != 500)\r
+                               return 3;\r
+                               \r
+                       if (m["Prop"] != 500)\r
+                               return 4;\r
+                               \r
+                       return 0;\r
+               }\r
+       }\r
+}\r
+/*\r
+var n:Number = 4;\r
+\r
+function get Prop():Number {\r
+       return n;\r
+}\r
+\r
+function set Prop(value:Number):void {\r
+       n = value;\r
+}\r
+*/\r
diff --git a/mcs/tests/test-ps-007.play b/mcs/tests/test-ps-007.play
new file mode 100644 (file)
index 0000000..4b15ff4
--- /dev/null
@@ -0,0 +1,21 @@
+package\r
+{\r
+       public dynamic class test\r
+       {\r
+               public static function Main():int\r
+               {\r
+                       var dynamic:int = 0;\r
+\r
+                       return 0;\r
+               }\r
+\r
+               private function foo():void\r
+               {\r
+                       dynamic (9);    \r
+               }\r
+\r
+               private function dynamic(dynamic:int):void\r
+               {\r
+               }\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-008.play b/mcs/tests/test-ps-008.play
new file mode 100644 (file)
index 0000000..f8ac30c
--- /dev/null
@@ -0,0 +1,59 @@
+package\r
+{\r
+       public dynamic class test\r
+       {\r
+               public static function Main():int\r
+               {\r
+                       var res:int;\r
+                       res = Local ();\r
+                       if (res != 0)\r
+                               return res + 10;\r
+                               \r
+                       res = Imported ();\r
+                       if (res != 0)\r
+                               return res + 20;\r
+                               \r
+                       return 0;\r
+               }\r
+               \r
+               static function Local ():int\r
+               {\r
+                       var m:test = new test ();\r
+                       m["Prop"] = 500;\r
+                       if (m.Prop != 500)\r
+                               return 1;\r
+\r
+                       if (m["Prop"] != 500)\r
+                               return 2;\r
+\r
+                       if (m.Prop != 500)\r
+                               return 3;\r
+\r
+                       m.Prop = 300;\r
+                       if (m.Prop != 300)\r
+                               return 4;\r
+                       \r
+                       return 0;\r
+               }\r
+               \r
+               static function Imported ():int\r
+               {\r
+                       var m:Array = new Array ();\r
+                       m["Prop"] = 500;\r
+                       if (m.Prop != 500)\r
+                               return 1;\r
+                               \r
+                       if (m["Prop"] != 500)\r
+                               return 2;\r
+\r
+                       if (m.Prop != 500)\r
+                               return 3;\r
+\r
+                       m.Prop = 300;\r
+                       if (m.Prop != 300)\r
+                               return 4;\r
+                               \r
+                       return 0;\r
+               }\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-009-2.play b/mcs/tests/test-ps-009-2.play
new file mode 100644 (file)
index 0000000..17125ee
--- /dev/null
@@ -0,0 +1,14 @@
+package\r
+{\r
+       public class base \r
+       {\r
+               protected function base() \r
+               {\r
+               }\r
+               \r
+               public virtual function F1 () : String\r
+               {\r
+                       return "a";\r
+               }\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-009.play b/mcs/tests/test-ps-009.play
new file mode 100644 (file)
index 0000000..e4efcf3
--- /dev/null
@@ -0,0 +1,21 @@
+// Compiler options: test-ps-009-2.play\r
+\r
+package\r
+{\r
+       public class inheritance extends base\r
+       {\r
+               public static function Main():int\r
+               {\r
+                       var b:base = new inheritance ();\r
+                       if (b.F1 () != "b")\r
+                               return 1;\r
+                               \r
+                       return 0;\r
+               }\r
+               \r
+               public override function F1 () : String\r
+               {\r
+                       return "b";\r
+               }\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-010.play b/mcs/tests/test-ps-010.play
new file mode 100644 (file)
index 0000000..a7223a8
--- /dev/null
@@ -0,0 +1,19 @@
+package\r
+{\r
+       public class conversions\r
+       {\r
+               public static function Main():int\r
+               {\r
+                       var i:int = -1;\r
+                       var u:uint = i;\r
+                       if (u != 4294967295)\r
+                               return 1;\r
+                               \r
+                       i = u - 1;\r
+                       if (i != -2)\r
+                               return 2;\r
+                               \r
+                       return 0;\r
+               }\r
+       }\r
+}\r
diff --git a/mcs/tests/test-ps-011.play b/mcs/tests/test-ps-011.play
new file mode 100644 (file)
index 0000000..e2cfa76
--- /dev/null
@@ -0,0 +1,48 @@
+package\r
+{\r
+       public class TestClass extends BaseClass\r
+       {\r
+               internal var local:Number = 4.5;\r
+               \r
+               public function TestClass(a:uint, b:String):*\r
+               {\r
+                       var b_ui:uint = ui;\r
+                       var b_s:* = s;\r
+                       var b_local:Number = local;\r
+                               \r
+                       super (a, b + "X");\r
+                       \r
+                       if (b_ui != 0)\r
+                               throw new ArgumentError ("1");\r
+\r
+                       if (b_local != 4.5)\r
+                               throw new ArgumentError ("2");\r
+                               \r
+                       if (b_s != null)\r
+                               throw new ArgumentError ("3");\r
+                       \r
+                       if (ui != a)\r
+                               throw new ArgumentError ("4");\r
+                               \r
+                       if (s != b + "X")\r
+                               throw new ArgumentError ("5");\r
+               }\r
+               \r
+               public static function Main ():void\r
+               {\r
+                       new TestClass (1, null);\r
+               }\r
+       }\r
+       \r
+       public class BaseClass \r
+       {               \r
+               public var ui:uint = 9;\r
+               public var s:String;\r
+               \r
+               public function BaseClass(a:uint, b:String) \r
+               {\r
+                       ui = a;\r
+                       s = b;\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-012.play b/mcs/tests/test-ps-012.play
new file mode 100644 (file)
index 0000000..cbb0c99
--- /dev/null
@@ -0,0 +1,19 @@
+package\r
+{\r
+       public class ArrayInitialization\r
+       {\r
+               public static function Main ():int\r
+               {\r
+                       var a:Object = [];\r
+                       if (!(a is Array))\r
+                               return 1;\r
+                               \r
+                       var b:* = ["1", "2", "3" ];\r
+                       if (!(b is Array))\r
+                               return 2;\r
+                               \r
+                       return 0;\r
+               }\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-013.play b/mcs/tests/test-ps-013.play
new file mode 100644 (file)
index 0000000..d64c795
--- /dev/null
@@ -0,0 +1,29 @@
+package\r
+{\r
+       public class TestClass\r
+       {\r
+               public static function Main ():int\r
+               {\r
+                       var v1:* = new <int> [9, 0];\r
+                       if (!(v1 is Vector.<int>))\r
+                               return 1;\r
+                       if (v1.length != 2)\r
+                               return 2;\r
+\r
+                       var v2:Vector.<String> = new <String> [];\r
+                       if (!(v2 is Vector.<String>))\r
+                               return 3;\r
+                       if (v2.length != 0)\r
+                               return 4;\r
+\r
+                       var v3:Object = new <Number> [0.0, 0.1,];\r
+                       if (!(v3 is Vector.<Number>))\r
+                               return 5;\r
+                       if (v3.length != 2)\r
+                               return 6;\r
+                               \r
+                       return 0;\r
+               }\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-014.play b/mcs/tests/test-ps-014.play
new file mode 100644 (file)
index 0000000..da9ccd8
--- /dev/null
@@ -0,0 +1,19 @@
+package\r
+{\r
+       public class BinaryOperations\r
+       {\r
+               public static function Main ():int\r
+               {\r
+                       var a:Object = 400;\r
+                       if (a != 400)\r
+                               return 1;\r
+                               \r
+                       if (400 != a)\r
+                               return 2;\r
+                       \r
+                       trace ("ok");\r
+                       return 0;\r
+               }\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-015.play b/mcs/tests/test-ps-015.play
new file mode 100644 (file)
index 0000000..cdeacc5
--- /dev/null
@@ -0,0 +1,38 @@
+package\r
+{\r
+       public class TestClass\r
+       {\r
+               public static function Main ():int\r
+               {\r
+                       if (test1 () != 0)\r
+                               return 1;\r
+                               \r
+                       if (test1 (1, "2", 3.0) != 3)\r
+                               return 2;\r
+                               \r
+                       if (test1(null) != 1)\r
+                               return 3;\r
+                               \r
+                       if (test1(new Array ()) != 1)\r
+                               return 4;\r
+\r
+                       test2();\r
+                               \r
+                       trace ("ok");\r
+                       return 0;\r
+               }\r
+               \r
+               public static function test1 (...rest) : int\r
+               {\r
+                       if (!(rest is Array))\r
+                               throw new ArgumentError ("Argument is not an array");\r
+                               \r
+                       return rest.length;\r
+               }\r
+               \r
+               public static function test2 (...rest:Array) : void\r
+               {\r
+               }       \r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-016.play b/mcs/tests/test-ps-016.play
new file mode 100644 (file)
index 0000000..84081b0
--- /dev/null
@@ -0,0 +1,19 @@
+package\r
+{\r
+       public class ObjectInitializer\r
+       {\r
+               public static function Main ():int\r
+               {\r
+                       var o:Object = { type:"Flat Panel", resolution:"1600x1200", value:3, value:5 };\r
+                       if (o.value != 3)\r
+                               return 1;\r
+\r
+                       if (o.type != "Flat Panel")\r
+                               return 2;\r
+\r
+                       var o2:* = { };\r
+\r
+                       return 0;\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-017.play b/mcs/tests/test-ps-017.play
new file mode 100644 (file)
index 0000000..934165b
--- /dev/null
@@ -0,0 +1,20 @@
+package\r
+{\r
+       public class NewExpression\r
+       {\r
+               public static function Main ():int\r
+               {\r
+                       var o:Object = new Object ();\r
+                       if (o == null)\r
+                               return 1;\r
+\r
+                       o = new NewExpression;\r
+                       o = new Object;\r
+                       o = new int ();\r
+                       o = new int;\r
+                       o = new Array (new Object);\r
+\r
+                       return 0;\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-018.play b/mcs/tests/test-ps-018.play
new file mode 100644 (file)
index 0000000..0233f54
--- /dev/null
@@ -0,0 +1,81 @@
+package\r
+{\r
+       public const cg1:Object = new Object ();\r
+       internal const cg2:int = -9;\r
+\r
+       public class ConstantFields\r
+       {\r
+               public static const cs1:Object = new Object ();\r
+       //      public static const cs2:* = undefined;\r
+               internal static const cs3:Object = 8;\r
+               public static const cs4:Array = [1, 2, 3];\r
+               public static const cs5:int = 2, cs6:uint = 7;\r
+               public static const cs8:int = vs8;\r
+               private static const cs9:String;\r
+               \r
+               static var vs8:int = 8;\r
+\r
+               public const c1:Object = cs1;\r
+       //      public const c2:* = undefined;\r
+               public const c3:Object = null;\r
+               public const c4:Array = [5];\r
+               public const c5:int = 20, c6:uint = 70;\r
+               public const c8:int = v8;\r
+               private const c9:String;\r
+               \r
+               static var v8:int = 8;\r
+               \r
+               public static function Main ():int\r
+               {\r
+                       if (cg1 == null)\r
+                               return 1;\r
+                       if (cg2 != -9)\r
+                               return 2;\r
+                               \r
+                       if (cs1 == null)\r
+                               return 10;\r
+                       if (cs3 != 8)\r
+                               return 11;\r
+                       if (cs4.length != 3)\r
+                               return 12;\r
+                       if (cs5 != 2)\r
+                               return 13;\r
+                       if (cs6 != 7)\r
+                               return 14;\r
+\r
+                       vs8 = 80;\r
+                       if (cs8 != 80)\r
+                               return 15;\r
+                       if (cs9 != null)\r
+                               return 16;\r
+                       \r
+                       var c = new ConstantFields ();\r
+                       if (c.c1 == null)\r
+                               return 20;\r
+                       if (c.c3 != null)\r
+                               return 21;\r
+                       if (c.c4.length != 1)\r
+                               return 22;\r
+                       if (c.c5 != 20)\r
+                               return 23;\r
+                       if (c.c6 != 70)\r
+                               return 24;\r
+                       if (c.c8 != 8)\r
+                               return 25;\r
+                       if (c.c9 != null)\r
+                               return 25;\r
+                               \r
+                       if (c.MM () != 40)\r
+                               return 30;\r
+\r
+                       trace ("ok");\r
+                                                       \r
+                       return 0;\r
+               }\r
+\r
+               function MM (arg1:int = cs5, arg2:int = c5):int\r
+               {\r
+                       return arg1 * arg2;\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-019.play b/mcs/tests/test-ps-019.play
new file mode 100644 (file)
index 0000000..bef3b9f
--- /dev/null
@@ -0,0 +1,54 @@
+package\r
+{\r
+       public class TypeofExpression\r
+       {\r
+               public static function Main ():int\r
+               {\r
+                       if (typeof "s" != "string")\r
+                               return 1;\r
+                               \r
+                       if (typeof 1 != "number")\r
+                               return 2;\r
+                               \r
+                       if (typeof -9.3 != "number")\r
+                               return 3;\r
+\r
+                       var ui:uint = 9;                        \r
+                       if (typeof ui != "number")\r
+                               return 4;\r
+                               \r
+                       if (typeof true != "boolean")\r
+                               return 5;\r
+                               \r
+                       if (typeof XML != "object")\r
+                               return 6;\r
+\r
+                       var x:Object = <a></a>;                         \r
+                       if (typeof x != "xml")\r
+                               return 7;\r
+                               \r
+                       x = <example><two>2</two></example>;\r
+\r
+                       if (typeof x != "xml")\r
+                               return 8;\r
+                               \r
+//                     var u:* = undefined;\r
+                       \r
+//                     if (typeof u != "undefined")\r
+//                             return 9;\r
+\r
+//                     if (typeof undefined != "undefined")\r
+//                             return 10;\r
+                               \r
+//                     var uo:Object = u;\r
+//                     if (typeof uo != "object")\r
+//                             return 11;\r
+                               \r
+                       if (typeof null != "object")\r
+                               return 12;\r
+                               \r
+                       trace ("ok");\r
+                       return 0;\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-020.play b/mcs/tests/test-ps-020.play
new file mode 100644 (file)
index 0000000..aad3173
--- /dev/null
@@ -0,0 +1,60 @@
+package\r
+{\r
+       public class InOperator\r
+       {\r
+               public static function Main ():int\r
+               {\r
+                       if (!("PI" in Math))\r
+                               return 1;\r
+\r
+                       var o:Object = "PI";\r
+                       if (!(o in Math))\r
+                               return 2;\r
+\r
+                       o = Math;\r
+                       if (!("PI" in o))\r
+                               return 21;\r
+\r
+                       if ("test" in Main)\r
+                               return 3;\r
+\r
+                       if ("PropI" in TestClass)\r
+                               return 4;\r
+                               \r
+                       if (!("PropI" in new TestClass ()))\r
+                               return 5;\r
+\r
+                       if ("PropS" in new TestClass ())\r
+                               return 6;\r
+                               \r
+                       if (!("PropS" in TestClass))\r
+                               return 7;\r
+\r
+                       if ("PropS2" in TestClass)\r
+                               return 8;\r
+\r
+                       var a_i:Object = [1, 4];\r
+                       var o_i:Object = -0;\r
+                       if (!(o_i in a_i))\r
+                               return 20;\r
+                               \r
+                       if (3 in a_i)\r
+                               return 21;\r
+                               \r
+                       trace ("ok");\r
+                       return 0;\r
+               }\r
+       }\r
+\r
+       public class TestClass\r
+       {\r
+               public static function set PropS(value:Number):void {\r
+               }               \r
+\r
+               protected static function set PropS2(value:Number):void {\r
+               }               \r
+               \r
+               public function set PropI(value:Number):void {\r
+               }                       \r
+       }       \r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-021.play b/mcs/tests/test-ps-021.play
new file mode 100644 (file)
index 0000000..43bf2c0
--- /dev/null
@@ -0,0 +1,77 @@
+package\r
+{\r
+       public class DeleteOperator\r
+       {\r
+               static var s:int;\r
+\r
+               public static function Main ():int\r
+               {\r
+                       var account:Object = new Object(); \r
+\r
+                       if (!(delete account.name))\r
+                               return 1;\r
+                       \r
+                       account.name = "Jon"; \r
+                       \r
+                       if (!(delete account.name))\r
+                               return 2;\r
+                               \r
+//                     if (account.name != undefined)\r
+//                             return 3;\r
+                               \r
+                       var tc:TestClass = new TestClass ();\r
+                       \r
+                       if (delete tc.PropI)\r
+                               return 10;\r
+\r
+                       if (!delete Foo ())\r
+                               return 11;\r
+\r
+                       if (s != 1)\r
+                               return 12;\r
+\r
+                       delete 5;       \r
+\r
+                       var my_array:Array = new Array(); \r
+                       my_array[0] = "a";\r
+                       my_array["1"] = "b";\r
+                       my_array[2] = "c";\r
+\r
+                       if (!(delete my_array[2]))\r
+                               return 20;\r
+\r
+                       if (my_array.length != 3)\r
+                               return 21;\r
+\r
+                       if (!(delete my_array[2]))\r
+                               return 22;\r
+\r
+                       if (!(delete my_array[-2]))\r
+                               return 23;\r
+\r
+                       if (my_array.length != 3)\r
+                               return 24;\r
+\r
+                       trace ("ok");\r
+                       return 0;\r
+               }\r
+\r
+               private static function Foo ():void\r
+               {\r
+                       s++;\r
+               }\r
+       }\r
+\r
+       public dynamic class TestClass\r
+       {\r
+               public static function set PropS(value:Number):void {\r
+               }               \r
+\r
+               protected static function set PropS2(value:Number):void {\r
+               }               \r
+               \r
+               public function get PropI():Number {\r
+                       return 4;\r
+               }                       \r
+       }       \r
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ps-022.play b/mcs/tests/test-ps-022.play
new file mode 100644 (file)
index 0000000..df03149
--- /dev/null
@@ -0,0 +1,30 @@
+package\r
+{\r
+       public class NamespaceDeclarationTest\r
+       {\r
+               public namespace French = "f";\r
+               internal namespace Hawaiian;\r
+               private namespace Latin = "text/hoo";\r
+               private namespace French2 = French;\r
+               Latin namespace Nested = "";\r
+               \r
+               Hawaiian function hello():String {\r
+                       return "aloha";\r
+           }\r
+\r
+               French var v:Object;\r
+               French const c:Object = null; \r
+               \r
+               public static function Main():int\r
+               {\r
+                       if (Latin.uri != "text/hoo")\r
+                               return 1;\r
+                               \r
+                       if (French2.uri != "f")\r
+                               return 2;\r
+                               \r
+                       return 0;\r
+               }\r
+       }\r
+}\r
+\r
diff --git a/mcs/tests/test-ps-023.play b/mcs/tests/test-ps-023.play
new file mode 100644 (file)
index 0000000..a13645a
--- /dev/null
@@ -0,0 +1,32 @@
+package\r
+{\r
+       public class UseNamespaceTest\r
+       {\r
+               private namespace Test;\r
+               private namespace Test2;\r
+               \r
+               Test static function Foo ():int\r
+               {\r
+                       trace (1);\r
+                       return 1;\r
+               }\r
+\r
+               Test2 static function Foo ():int\r
+               {\r
+                       trace (2);\r
+                       return 2;\r
+               }\r
+               \r
+               public static function Main():int\r
+               {\r
+                       if (Test::Foo () != 1)\r
+                               return 1;\r
+\r
+                       if (Test2::Foo () != 2)\r
+                               return 2;\r
+                               \r
+                       return 0;\r
+               }\r
+       }\r
+}\r
+\r