Ver código fonte

renamed files readded to prj

Xanathar 11 anos atrás
pai
commit
b4f1e97c7c

+ 28 - 0
src/MoonSharp.Debugger/Ext_Methods.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+namespace MoonSharp.Debugger
+{
+	static class Ext_Methods
+	{
+		public static ListViewItem Add(this ListView lv, params object[] texts)
+		{
+			ListViewItem lvi = new ListViewItem();
+			lvi.Text = texts[0].ToString();
+
+			for (int i = 1; i < texts.Length; i++)
+			{
+				ListViewItem.ListViewSubItem lvsi = new ListViewItem.ListViewSubItem();
+				lvsi.Text = texts[i].ToString();
+				lvi.SubItems.Add(lvsi);
+			}
+
+			lv.Items.Add(lvi);
+
+			return lvi;
+		}
+	}
+}

+ 609 - 0
src/MoonSharp.Interpreter/Execution/DataTypes/DynValue.cs

@@ -0,0 +1,609 @@
+using System;
+using System.Collections.Generic;
+using MoonSharp.Interpreter.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace MoonSharp.Interpreter.Execution
+{
+	/// <summary>
+	/// A class representing a value in a Lua/Moon# script.
+	/// </summary>
+	public sealed class DynValue
+	{
+		static int s_RefIDCounter = 0;
+		private int m_RefID = ++s_RefIDCounter;
+		private int m_HashCode = -1;
+
+
+		/// <summary>
+		/// Gets a unique reference identifier. This is guaranteed to be unique only in a single Script object as it's not thread-safe.
+		/// </summary>
+		public int ReferenceID { get { return m_RefID; } }
+
+		/// <summary>
+		/// Gets the type of the value.
+		/// </summary>
+		public DataType Type { get; private set; }
+		/// <summary>
+		/// Gets the function (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Function"/>)
+		/// </summary>
+		public Closure Function { get; private set; }
+		/// <summary>
+		/// Gets the numeric value (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Number"/>)
+		/// </summary>
+		public double Number { get; private set; }
+		/// <summary>
+		/// Gets the values in the tuple (valid only if the <seealso cref="Type"/> is Tuple).
+		/// This field is currently also used to hold arguments in values whose <seealso cref="Type"/> is <seealso cref="DataType.TailCallRequest"/>.
+		/// </summary>
+		public DynValue[] Tuple { get; private set; }
+		/// <summary>
+		/// Gets the table (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Table"/>)
+		/// </summary>
+		public Table Table { get; private set; }
+		/// <summary>
+		/// Gets the boolean value (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Boolean"/>)
+		/// </summary>
+		public bool Boolean { get; private set; }
+		/// <summary>
+		/// Gets the string value (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.String"/>)
+		/// </summary>
+		public string String { get; private set; }
+		/// <summary>
+		/// Gets the symbol reference contained in this value (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Symbol"/>)
+		/// </summary>
+		public SymbolRef Symbol { get; private set; }
+		/// <summary>
+		/// Gets the CLR callback (valid only if the <seealso cref="Type"/> is <seealso cref="DataType.Callback"/>)
+		/// </summary>
+		public CallbackFunction Callback { get; set; }
+		/// <summary>
+		/// Gets the meta-table associated with this instance.
+		/// </summary>
+		public DynValue Meta { get; set; }
+
+		/// <summary>
+		/// Returns true if this instance is write protected.
+		/// </summary>
+		public bool ReadOnly { get; internal set; }
+
+
+		/// <summary>
+		/// Creates a new writable value initialized to Nil.
+		/// </summary>
+		public static DynValue NewNil()
+		{
+			return new DynValue();
+		}
+
+		/// <summary>
+		/// Creates a new writable value initialized to the specified boolean.
+		/// </summary>
+		public static DynValue NewBoolean(bool v)
+		{
+			return new DynValue()
+			{
+				Boolean = v,
+				Type = DataType.Boolean,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new writable value initialized to the specified number.
+		/// </summary>
+		public static DynValue NewNumber(double num)
+		{
+			return new DynValue()
+			{
+				Number = num,
+				Type = DataType.Number,
+				m_HashCode = -1,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new writable value initialized to the specified symbol reference.
+		/// </summary>
+		public static DynValue NewReference(SymbolRef symbol)
+		{
+			return new DynValue()
+			{
+				Symbol = symbol,
+				Type = DataType.Symbol,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new writable value initialized to the specified string.
+		/// </summary>
+		public static DynValue NewString(string str)
+		{
+			return new DynValue()
+			{
+				String = str,
+				Type = DataType.String,
+			};
+		}
+
+
+		/// <summary>
+		/// Creates a new writable value initialized to the specified closure (function).
+		/// </summary>
+		public static DynValue NewClosure(Closure function)
+		{
+			return new DynValue()
+			{
+				Function = function,
+				Type = DataType.Function,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new writable value initialized to the specified CLR callback.
+		/// </summary>
+		public static DynValue NewCallback(Func<IExecutionContext, CallbackArguments, DynValue> callBack)
+		{
+			return new DynValue()
+			{
+				Callback = new CallbackFunction(callBack),
+				Type = DataType.ClrFunction,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new writable value initialized to the specified CLR callback.
+		/// </summary>
+		public static DynValue NewCallback(CallbackFunction function)
+		{
+			return new DynValue()
+			{
+				Callback = function,
+				Type = DataType.ClrFunction,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new writable value initialized to the specified table.
+		/// </summary>
+		public static DynValue NewTable(Table table = null)
+		{
+			return new DynValue()
+			{
+				Table = table ?? new Table(),
+				Type = DataType.Table,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new request for a tail call. This is the preferred way to execute Lua/Moon# code from a callback,
+		/// although it's not always possible to use it. When a function (callback or script closure) returns a
+		/// TailCallRequest, the bytecode processor immediately executes the function contained in the request.
+		/// By executing script in this way, a callback function ensures it's not on the stack anymore and thus state
+		/// can be saved.
+		/// </summary>
+		/// <param name="tailFn">The function to be called.</param>
+		/// <param name="args">The arguments.</param>
+		/// <returns></returns>
+		public static DynValue NewTailCallReq(DynValue tailFn, params DynValue[] args)
+		{
+			return new DynValue()
+			{
+				Meta = tailFn,
+				Tuple = args,
+				Type = DataType.TailCallRequest,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new value initialized to the specified tuple.
+		/// </summary>
+		public static DynValue NewTuple(params DynValue[] tuple)
+		{
+			return new DynValue()
+			{
+				Tuple = tuple,
+				Type = DataType.Tuple,
+			};
+		}
+
+		/// <summary>
+		/// Creates a new value initialized to the specified coroutine index.
+		/// </summary>
+		internal static DynValue NewCoroutine(int coroutineIdx)
+		{
+			return new DynValue()
+			{
+				Number = coroutineIdx,
+				Type = DataType.Thread
+			};
+		}
+
+
+
+		/// <summary>
+		/// Returns this value as readonly - eventually cloning it in the process if it isn't readonly to start with.
+		/// </summary>
+		public DynValue AsReadOnly()
+		{
+			if (ReadOnly)
+				return this;
+			else
+			{
+				DynValue v = Clone();
+				v.ReadOnly = true;
+				return v;
+			}
+		}
+
+		/// <summary>
+		/// Clones this instance.
+		/// </summary>
+		/// <exception cref="System.ArgumentException">Can't clone Symbol values</exception>
+		public DynValue Clone()
+		{
+			if (this.Type == DataType.Symbol)
+				throw new ArgumentException("Can't clone Symbol values");
+
+			DynValue v = new DynValue();
+			v.Boolean = this.Boolean;
+			v.Callback = this.Callback;
+			v.Function = this.Function;
+			v.Number = this.Number;
+			v.ReadOnly = this.ReadOnly;
+			v.String = this.String;
+			v.Table = this.Table;
+			v.Tuple = this.Tuple;
+			v.Type = this.Type;
+			v.Meta = this.Meta;
+			v.m_HashCode = this.m_HashCode;
+			return v;
+		}
+
+		/// <summary>
+		/// Clones this instance, returning a writable copy.
+		/// </summary>
+		/// <exception cref="System.ArgumentException">Can't clone Symbol values</exception>
+		public DynValue CloneAsWritable()
+		{
+			if (this.Type == DataType.Symbol)
+				throw new ArgumentException("Can't clone Symbol values");
+
+			DynValue v = new DynValue();
+			v.Boolean = this.Boolean;
+			v.Function = this.Function;
+			v.Callback = this.Callback;
+			v.Number = this.Number;
+			v.ReadOnly = false;
+			v.String = this.String;
+			v.Table = this.Table;
+			v.Tuple = this.Tuple;
+			v.Type = this.Type;
+			v.Meta = this.Meta;
+			v.m_HashCode = this.m_HashCode;
+			return v;
+		}
+
+
+		/// <summary>
+		/// A preinitialized, readonly instance, equaling Nil
+		/// </summary>
+		public static DynValue Nil { get; private set; }
+		/// <summary>
+		/// A preinitialized, readonly instance, equaling True
+		/// </summary>
+		public static DynValue True { get; private set; }
+		/// <summary>
+		/// A preinitialized, readonly instance, equaling False
+		/// </summary>
+		public static DynValue False { get; private set; }
+
+
+		static DynValue()
+		{
+			Nil = new DynValue().AsReadOnly();
+			True = DynValue.NewBoolean(true).AsReadOnly();
+			False = DynValue.NewBoolean(false).AsReadOnly();
+		}
+
+
+		/// <summary>
+		/// Returns a string which is what it's expected to be output by the print function applied to this value.
+		/// </summary>
+		public string ToPrintString()
+		{
+			switch (Type)
+			{
+				case DataType.String:
+					return String;
+				case DataType.Table:
+					return "(Table)";
+				case DataType.Tuple:
+					return string.Join("\t", Tuple.Select(t => t.ToPrintString()).ToArray());
+				case DataType.Symbol:
+					return "(Symbol -- INTERNAL!)";
+				case DataType.TailCallRequest:
+					return "(TailCallRequest -- INTERNAL!)";
+				case DataType.UserData:
+					return "(UserData)";
+				case DataType.Thread:
+					return "(Thread)";
+				default:
+					return ToString();
+			}
+		}
+
+		/// <summary>
+		/// Returns a <see cref="System.String" /> that represents this instance.
+		/// </summary>
+		/// <returns>
+		/// A <see cref="System.String" /> that represents this instance.
+		/// </returns>
+		public override string ToString()
+		{
+			switch (Type)
+			{
+				case DataType.Nil:
+					return "nil";
+				case DataType.Boolean:
+					return Boolean.ToString().ToLower();
+				case DataType.Number:
+					return Number.ToString();
+				case DataType.String:
+					return "\"" + String + "\"";
+				case DataType.Function:
+					return string.Format("(Function {0:X8})", Function.ByteCodeLocation);
+				case DataType.ClrFunction:
+					return string.Format("(Function CLR)", Function);
+				case DataType.Table:
+					return "(Table)";
+				case DataType.Tuple:
+					return string.Join(", ", Tuple.Select(t => t.ToString()).ToArray());
+				case DataType.TailCallRequest:
+					return "Tail:(" + string.Join(", ", Tuple.Select(t => t.ToString()).ToArray()) + ")";
+				case DataType.Symbol:
+					return Symbol.ToString();
+				case DataType.UserData:
+					return "(UserData)";
+				case DataType.Thread:
+					return "(Thread)";
+				default:
+					return "(???)";
+			}
+		}
+
+		/// <summary>
+		/// Returns a hash code for this instance.
+		/// </summary>
+		/// <returns>
+		/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
+		/// </returns>
+		public override int GetHashCode()
+		{
+			if (m_HashCode != -1)
+				return m_HashCode;
+
+			int baseValue = ((int)(Type)) << 27;
+
+			switch (Type)
+			{
+				case DataType.Nil:
+					m_HashCode = 0;
+					break;
+				case DataType.Boolean:
+					m_HashCode = Boolean ? 1 : 2;
+					break;
+				case DataType.Number:
+					m_HashCode = baseValue ^ Number.GetHashCode();
+					break;
+				case DataType.String:
+					m_HashCode = baseValue ^ String.GetHashCode();
+					break;
+				case DataType.Function:
+					m_HashCode = baseValue ^ Function.GetHashCode();
+					break;
+				case DataType.ClrFunction:
+					m_HashCode = baseValue ^ Callback.GetHashCode();
+					break;
+				case DataType.Table:
+					m_HashCode = baseValue ^ Table.GetHashCode();
+					break;
+				case DataType.Tuple:
+				case DataType.TailCallRequest:
+					m_HashCode = baseValue ^ Tuple.GetHashCode();
+					break;
+				case DataType.UserData:
+				case DataType.Thread:
+				default:
+					m_HashCode = 999;
+					break;
+			}
+
+			return m_HashCode;
+		}
+
+		/// <summary>
+		/// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
+		/// </summary>
+		/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
+		/// <returns>
+		///   <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
+		/// </returns>
+		public override bool Equals(object obj)
+		{
+			DynValue other = obj as DynValue;
+
+			if (other == null) return false;
+			if (other.Type != this.Type) return false;
+
+			if (other.Meta != this.Meta) return false;
+
+			switch (Type)
+			{
+				case DataType.Nil:
+					return true;
+				case DataType.Boolean:
+					return Boolean == other.Boolean;
+				case DataType.Number:
+					return Number == other.Number;
+				case DataType.String:
+					return String == other.String;
+				case DataType.Function:
+					return Function == other.Function;
+				case DataType.ClrFunction:
+					return Callback == other.Callback;
+				case DataType.Table:
+					return Table == other.Table;
+				case DataType.Tuple:
+				case DataType.TailCallRequest:
+					return Tuple == other.Tuple;
+				case DataType.UserData:
+				case DataType.Thread:
+				default:
+					return object.ReferenceEquals(this, other);
+			}
+		}
+
+
+		/// <summary>
+		/// Casts this DynValue to string, using coercion if the type is number.
+		/// </summary>
+		/// <returns>The string representation, or null if not number, not string.</returns>
+		public string CastToString()
+		{
+			DynValue rv = ToScalar();
+			if (rv.Type == DataType.Number)
+			{
+				return rv.Number.ToString();
+			}
+			else if (rv.Type == DataType.String)
+			{
+				return rv.String;
+			}
+			return null;
+		}
+
+		/// <summary>
+		/// Casts this DynValue to a double, using coercion if the type is string.
+		/// </summary>
+		/// <returns>The string representation, or null if not number, not string or non-convertible-string.</returns>
+		public double? CastToNumber()
+		{
+			DynValue rv = ToScalar();
+			if (rv.Type == DataType.Number)
+			{
+				return rv.Number;
+			}
+			else if (rv.Type == DataType.String)
+			{
+				double num;
+				if (double.TryParse(rv.String, NumberStyles.Any, CultureInfo.InvariantCulture, out num))
+					return num;
+			}
+			return null;
+		}
+
+
+		/// <summary>
+		/// Casts this DynValue to a bool
+		/// </summary>
+		/// <returns>False if value is false or nil, true otherwise.</returns>
+		public bool CastToBool()
+		{
+			DynValue rv = ToScalar();
+			if (rv.Type == DataType.Boolean)
+				return rv.Boolean;
+			else return (rv.Type != DataType.Nil);
+		}
+
+		/// <summary>
+		/// Converts a tuple to a scalar value. If it's already a scalar value, this function returns "this".
+		/// </summary>
+		public DynValue ToScalar()
+		{
+			if (Type != DataType.Tuple)
+				return this;
+
+			if (Tuple.Length == 0)
+				return DynValue.Nil;
+
+			return Tuple[0].ToScalar();
+		}
+
+		/// <summary>
+		/// Performs an assignment, overwriting the value with the specified one.
+		/// </summary>
+		/// <param name="value">The value.</param>
+		/// <exception cref="ScriptRuntimeException">If the value is readonly.</exception>
+		public void Assign(DynValue value)
+		{
+			if (this.ReadOnly)
+				throw new ScriptRuntimeException(null, "Assigning on r-value");
+
+			this.Boolean = value.Boolean;
+			this.Callback = value.Callback;
+			this.Function = value.Function;
+			this.Number = value.Number;
+			this.ReadOnly = false;
+			this.String = value.String;
+			this.Table = value.Table;
+			this.Tuple = value.Tuple;
+			this.Type = value.Type;
+			this.Meta = value.Meta;
+			this.m_HashCode = -1;
+		}
+
+
+
+		/// <summary>
+		/// Gets the length of a string or table value.
+		/// </summary>
+		/// <returns></returns>
+		/// <exception cref="ScriptRuntimeException">Value is not a table or string.</exception>
+		public DynValue GetLength()
+		{
+			if (this.Type == DataType.Table)
+				return DynValue.NewNumber(this.Table.Length);
+			if (this.Type == DataType.String)
+				return DynValue.NewNumber(this.String.Length);
+
+			throw new ScriptRuntimeException(null, "Can't get length of type {0}", this.Type);
+		}
+
+		/// <summary>
+		/// Determines whether this instance is nil.
+		/// </summary>
+		public bool IsNil()
+		{
+			return this.Type == DataType.Nil;
+		}
+
+		/// <summary>
+		/// Determines whether is nil or NaN (and thus unsuitable for using as a table key).
+		/// </summary>
+		public bool IsNilOrNan()
+		{
+			return (this.Type == DataType.Nil) || (this.Type == DataType.Number && double.IsNaN(this.Number));
+		}
+
+		/// <summary>
+		/// Changes the numeric value of a number DynValue.
+		/// </summary>
+		internal void AssignNumber(double num)
+		{
+			if (this.ReadOnly)
+				throw new InternalErrorException(null, "Writing on r-value");
+
+			if (this.Type != DataType.Number)
+				throw new InternalErrorException("Can't assign number to type {0}", this.Type);
+
+			this.Number = num;
+		}
+	}
+
+
+
+
+}

+ 0 - 13
src/MoonSharp.Interpreter/Execution/ScopeRef.cs

@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MoonSharp.Interpreter.Execution
-{
-	public class ScopeRef
-	{
-		public string Name { get; set; }
-		public int Index { get; set; }
-	}
-}

+ 3 - 1
src/MoonSharp.Interpreter/MoonSharp.Interpreter.csproj

@@ -97,6 +97,9 @@
     <Compile Include="Execution\DataTypes\CallbackArguments.cs" />
     <Compile Include="Execution\DataTypes\Closure.cs" />
     <Compile Include="Execution\DataTypes\CallbackFunction.cs" />
+    <Compile Include="Execution\DataTypes\DynValue.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="Execution\DataTypes\TablePair.cs" />
     <Compile Include="Execution\FileLoadRequestedEventArgs.cs" />
     <Compile Include="Execution\IExecutionContext.cs">
@@ -114,7 +117,6 @@
     <Compile Include="Execution\Scopes\RuntimeScopeFrame.cs" />
     <Compile Include="Execution\ScriptLoadingContext.cs" />
     <Compile Include="Execution\DataTypes\DataType.cs" />
-    <Compile Include="Execution\DataTypes\DynValue.cs" />
     <Compile Include="Execution\Script.cs" />
     <Compile Include="Execution\DataTypes\Table.cs" />
     <Compile Include="Execution\VM\ByteCode.cs" />