[assembly: ComVisible (false)]
+[assembly: InternalsVisibleTo ("PlayScript.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010079159977d2d03a8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fddafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef0065d016df")]
../../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
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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)]
+
--- /dev/null
+// 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;
+ }
+ }
+}
+
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
+
--- /dev/null
+// 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;}
+ }
+}
+
--- /dev/null
+// 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;
+ }
+ }
+}
+
--- /dev/null
+// 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();
+ }
+ }
+}
+
--- /dev/null
+// 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 ()
+ {
+ }
+ }
+}
+
--- /dev/null
+// 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;
+// }
+
+ }
+}
+
--- /dev/null
+// 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;
+ }
+
+ }
+
+
+}
--- /dev/null
+// 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();
+ }
+
+ }
+
+}
--- /dev/null
+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
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
--- /dev/null
+//
+// 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();
+ }
+ }
+}
--- /dev/null
+// 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;
+
+ }
+
+}
--- /dev/null
+../../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
--- /dev/null
+//
+// 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; }
+ }
+}
--- /dev/null
+//
+// 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
+ {
+ }
+}
--- /dev/null
+//
+// 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; }
+ }
+}
--- /dev/null
+//
+// 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
+ {
+ }
+}
--- /dev/null
+//
+// 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
+ {
+ }
+}
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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);
+ }
+ }
+}
--- /dev/null
+//
+// 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);
+ }
+ }
+ }
+}
--- /dev/null
+//
+// 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";
+ }
+ }
+}
--- /dev/null
+//
+// 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
--- /dev/null
+// 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;
+
+ }
+
+}
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
+
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
--- /dev/null
+// 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;
+
+ }
+
+}
--- /dev/null
+// 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 ()
+ {
+ }
+ }
+}
+
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
+
--- /dev/null
+// 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;
+ }
+
+ }
+}
+
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
+
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
+
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
+
--- /dev/null
+//
+// 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);
+ }
+ }
+}
+
--- /dev/null
+// 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);
+ }
+
+ }
+
+}
+
+
--- /dev/null
+// 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();
+ }
+ }
+
+}
--- /dev/null
+// 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();
+ }
+ }
+*/
+}
--- /dev/null
+// 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();
+ }
+
+ }
+}
+
--- /dev/null
+// 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;
+ }
+}
+
--- /dev/null
+//
+// 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);
+ }
+*/
+}
y.output
-cs-parser.cs
+*-parser.cs
?mcs.user
?mcs.csproj.user
mcs.csproj.user
PROGRAM_COMPILE = $(BOOT_COMPILE)
-BUILT_SOURCES = cs-parser.cs
+BUILT_SOURCES = cs-parser.cs ps-parser.cs
CLEAN_FILES += y.output
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;
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)
using System.Security.Permissions;
using System.Text;
using System.Diagnostics;
+using System.Linq;
using Mono.CompilerServices.SymbolWriter;
#if NET_2_1
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 ();
}
}
}
+ public bool IsPlayScriptType { get; set; }
+
bool ITypeDefinition.IsTypeForwarder {
get {
return false;
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.
//
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 ();
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);
}
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);
}
}
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);
//
// 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)
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;
// Copyright 2003-2008 Novell, Inc.
//
+using System;
+
#if STATIC
using IKVM.Reflection;
#else
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;
}
// 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
}
// 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))
}
}
+ public bool IsPlayScriptType {
+ get {
+ return CurrentType.MemberDefinition.IsPlayScriptType;
+ }
+ }
+
public bool IsStatic {
get {
return MemberContext.IsStatic;
// 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);
}
return false;
}
+ if (expr_type.BuiltinType == BuiltinTypeSpec.Type.Object)
+ return target_type.BuiltinType == BuiltinTypeSpec.Type.Object || target_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
+
break;
}
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
///
}
}
+ public virtual string LookupName {
+ get {
+ return Name;
+ }
+ }
+
public void CreateMetadataName (StringBuilder sb)
{
if (Left != null)
return Left.GetSignatureForDocumentation () + "." + s;
}
- public string GetSignatureForError ()
+ public virtual string GetSignatureForError ()
{
string s = TypeParameters == null ? null : "<" + TypeParameters.GetSignatureForError () + ">";
s = Name + s;
{
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 ();
+ }
+ }
}
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)
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);
None = 0,
InvocableOnly = 1,
ExactArity = 1 << 2,
- ReadAccess = 1 << 3
+ ReadAccess = 1 << 3,
+ PlayScriptConversion = 1 << 4
}
//
}
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);
}
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;
}
//
// 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)
//
// 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
//
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;
}
}
}
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);
}
// 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++;
}
Error_TypeArgumentsCannotBeUsed (ec, "field", GetSignatureForError (), loc);
}
}
-
//
// Expression that evaluates to a Property.
// 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;
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;
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
case Operator.RightShift:
s = ">>";
break;
+ case Operator.UnsignedRightShift:
+ s = ">>>";
+ break;
case Operator.LessThan:
s = "<";
break;
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;
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");
if (TypeSpec.IsReferenceType (r))
return this;
- if (r.Kind == MemberKind.InternalCompilerType)
+ if (r.Kind == MemberKind.InternalCompilerType && r.BuiltinType != BuiltinTypeSpec.Type.Object)
return null;
}
if (TypeSpec.IsReferenceType (l))
return this;
- if (l.Kind == MemberKind.InternalCompilerType)
+ if (l.Kind == MemberKind.InternalCompilerType && l.BuiltinType != BuiltinTypeSpec.Type.Object)
return null;
}
}
if (type is TypeParameterSpec)
- return DoEmitTypeParameter (ec);
+ return DoEmitTypeParameter (ec);
ec.MarkCallEntry (loc);
ec.Emit (OpCodes.Newobj, method);
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)
//
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
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;
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 ());
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) {
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);
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 ();
}
//
public class FieldSpec : MemberSpec, IInterfaceMemberSpec
{
- FieldInfo metaInfo;
+ protected FieldInfo metaInfo;
TypeSpec memberType;
public FieldSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, FieldInfo info, Modifiers modifiers)
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);
}
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);
}
}
+ bool ITypeDefinition.IsPlayScriptType {
+ get {
+ return false;
+ }
+ }
+
public bool IsMethodTypeParameter {
get {
return spec.IsMethodOwned;
// 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");
if (corlib != null && corlib.GetName ().Version.Major >= 4) {
default_references.Add ("Microsoft.CSharp.dll");
+
+ default_references.Add ("PlayScript.Core");
}
return default_references.ToArray ();
// 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;
protected readonly ModuleContainer module;
public static readonly string CompilerServicesNamespace = "System.Runtime.CompilerServices";
+ public static readonly string PlayScriptCompilerNamespace = "PlayScript.Runtime.CompilerServices";
protected MetadataImporter (ModuleContainer module)
{
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 ();
} 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;
}
}
}
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) {
}
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;
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);
// 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)
else
base_type = CreateType (type.BaseType);
+ if (base_type == null && spec.MemberDefinition.IsPlayScriptType)
+ base_type = module.PlayscriptTypes.Object;
+
spec.BaseType = base_type;
}
}
}
+ public bool IsPlayScriptType { get; set; }
+
public override string Name {
get {
if (name == null) {
}
}
+ bool ITypeDefinition.IsPlayScriptType {
+ get {
+ return false;
+ }
+ }
+
public string Namespace {
get {
return null;
namespace Mono.CSharp
{
+ public enum SourceFileType
+ {
+ CSharp = 0,
+ PlayScript
+ }
+
//
// This is one single source file.
//
public readonly string FullPathName;
public readonly int Index;
public bool AutoGenerated;
+ readonly SourceFileType FileType;
SourceFileEntry file;
byte[] algGuid, checksum;
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 {
}
}
+ public bool IsPlayScript {
+ get {
+ return FileType == SourceFileType.PlayScript;
+ }
+ }
+
public SourceFileEntry SourceFileEntry {
get {
return 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
async.cs
attribute.cs
cs-tokenizer.cs
+ps-tokenizer.cs
cfold.cs
class.cs
codegen.cs
nullable.cs
parameter.cs
pending.cs
+playscript.cs
property.cs
reflection.cs
report.cs
{
// 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);
if (mc is Constructor)
return mc.IsStatic ? Constructor.TypeConstructorName : Constructor.ConstructorName;
- return mc.MemberName.Name;
+ return mc.MemberName.LookupName;
}
//
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;
}
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)
{
}
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;
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)
{
}
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)
VOLATILE = 0x1000,
UNSAFE = 0x2000,
ASYNC = 0x4000,
- TOP = 0x8000,
+ DYNAMIC = 0x8000, // Playscript only
+ TOP = 0x10000,
//
// Compiler specific flags
s = "unsafe"; break;
case Modifiers.ASYNC:
s = "async"; break;
+ case Modifiers.DYNAMIC:
+ s = "dynamic"; break;
}
return s;
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;
}
}
+ 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;
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 ()
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'
//
get {
return clauses;
}
+ protected set {
+ clauses = value;
+ }
}
public override string[] ValidAttributeTargets {
#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");
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) {
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" };
get {
return texpr;
}
+ protected set {
+ texpr = value;
+ }
}
public override string[] ValidAttributeTargets {
return "ref";
case Modifier.This:
return "this";
+ case Modifier.RestArray:
+ return "...";
default:
return "";
}
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;
}
}
//
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) {
--- /dev/null
+//
+// 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";
+ }
+ }
+ }
+}
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)
{
}
}
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)
--- /dev/null
+%{
+//
+// 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 */
+}
--- /dev/null
+//
+// 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
+ }
+}
+
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));
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)
public abstract bool IsWarning { get; }
+ public virtual string LanguagePrefix {
+ get {
+ return "CS";
+ }
+ }
+
public Location Location {
get { return location; }
}
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 ()));
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) {
}
}
+ //
+ // Only used by PlayScript dynamic classes
+ //
+ public bool IsDynamicClass {
+ get {
+ return (Modifiers & Modifiers.DYNAMIC) != 0;
+ }
+ }
+
//
// Returns true for instances of Expression<T>
//
//
// 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;
}
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";
bool IsPartial { get; }
bool IsComImport { get; }
bool IsTypeForwarder { get; }
+ bool IsPlayScriptType { get; }
int TypeParametersCount { get; }
TypeParameterSpec[] TypeParameters { get; }
}
}
+ bool ITypeDefinition.IsPlayScriptType {
+ get {
+ return false;
+ }
+ }
+
bool ITypeDefinition.IsTypeForwarder {
get {
return false;
}
}
+ bool ITypeDefinition.IsPlayScriptType {
+ get {
+ return false;
+ }
+ }
+
public override string Name {
get {
throw new NotSupportedException ();
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:
@:
--- /dev/null
+package\r
+{\r
+ public class HelloWorld \r
+ {\r
+ public static function Main():void\r
+ {\r
+ trace ("Hello World!");\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package {\r
+ public function testFunction (obj:*, cl:Class):Boolean\r
+ {\r
+ return false;\r
+ }\r
+}\r
--- /dev/null
+// 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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+// 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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+// 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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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