Christopher
8 years ago
577 changed files with 40593 additions and 8143 deletions
@ -0,0 +1,36 @@
|
||||
{ |
||||
"version": "0.2.0", |
||||
"configurations": [ |
||||
{ |
||||
"name": "Unity Editor", |
||||
"type": "unity", |
||||
"request": "launch" |
||||
}, |
||||
{ |
||||
"name": "Windows Player", |
||||
"type": "unity", |
||||
"request": "launch" |
||||
}, |
||||
{ |
||||
"name": "OSX Player", |
||||
"type": "unity", |
||||
"request": "launch" |
||||
}, |
||||
{ |
||||
"name": "Linux Player", |
||||
"type": "unity", |
||||
"request": "launch" |
||||
}, |
||||
{ |
||||
"name": "iOS Player", |
||||
"type": "unity", |
||||
"request": "launch" |
||||
}, |
||||
{ |
||||
"name": "Android Player", |
||||
"type": "unity", |
||||
"request": "launch" |
||||
|
||||
} |
||||
] |
||||
} |
@ -0,0 +1,57 @@
|
||||
{ |
||||
"files.exclude": |
||||
{ |
||||
"**/.DS_Store":true, |
||||
"**/.git":true, |
||||
"**/.gitignore":true, |
||||
"**/.gitattributes":true, |
||||
"**/.gitmodules":true, |
||||
"**/.svn":true, |
||||
"**/*.booproj":true, |
||||
"**/*.pidb":true, |
||||
"**/*.suo":true, |
||||
"**/*.user":true, |
||||
"**/*.userprefs":true, |
||||
"**/*.unityproj":true, |
||||
"**/*.dll":true, |
||||
"**/*.exe":true, |
||||
"**/*.pdf":true, |
||||
"**/*.mid":true, |
||||
"**/*.midi":true, |
||||
"**/*.wav":true, |
||||
"**/*.gif":true, |
||||
"**/*.ico":true, |
||||
"**/*.jpg":true, |
||||
"**/*.jpeg":true, |
||||
"**/*.png":true, |
||||
"**/*.psd":true, |
||||
"**/*.tga":true, |
||||
"**/*.tif":true, |
||||
"**/*.tiff":true, |
||||
"**/*.3ds":true, |
||||
"**/*.3DS":true, |
||||
"**/*.fbx":true, |
||||
"**/*.FBX":true, |
||||
"**/*.lxo":true, |
||||
"**/*.LXO":true, |
||||
"**/*.ma":true, |
||||
"**/*.MA":true, |
||||
"**/*.obj":true, |
||||
"**/*.OBJ":true, |
||||
"**/*.asset":true, |
||||
"**/*.cubemap":true, |
||||
"**/*.flare":true, |
||||
"**/*.mat":true, |
||||
"**/*.meta":true, |
||||
"**/*.prefab":true, |
||||
"**/*.unity":true, |
||||
"build/":true, |
||||
"Build/":true, |
||||
"Library/":true, |
||||
"library/":true, |
||||
"obj/":true, |
||||
"Obj/":true, |
||||
"ProjectSettings/":true,
"temp/":true, |
||||
"Temp/":true |
||||
} |
||||
} |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: fe983e267963641219d60f73a36907ce |
||||
folderAsset: yes |
||||
timeCreated: 1475786652 |
||||
licenseType: Pro |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 71b4d33685e4746ca9cfe341d75910d9 |
||||
folderAsset: yes |
||||
timeCreated: 1476112669 |
||||
licenseType: Pro |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,316 @@
|
||||
#if (!PCL) && ((!UNITY_5) || UNITY_STANDALONE) |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Text.RegularExpressions; |
||||
using System.Threading; |
||||
using MoonSharp.Interpreter; |
||||
using MoonSharp.Interpreter.Debugging; |
||||
using MoonSharp.VsCodeDebugger; |
||||
using MoonSharp.VsCodeDebugger.SDK; |
||||
|
||||
namespace MoonSharp.VsCodeDebugger.DebuggerLogic |
||||
{ |
||||
internal class AsyncDebugger : IDebugger |
||||
{ |
||||
private static object s_AsyncDebuggerIdLock = new object(); |
||||
private static int s_AsyncDebuggerIdCounter = 0; |
||||
|
||||
object m_Lock = new object(); |
||||
private IAsyncDebuggerClient m_Client__; |
||||
DebuggerAction m_PendingAction = null; |
||||
|
||||
List<WatchItem>[] m_WatchItems; |
||||
Dictionary<int, SourceCode> m_SourcesMap = new Dictionary<int, SourceCode>(); |
||||
Dictionary<int, string> m_SourcesOverride = new Dictionary<int, string>(); |
||||
Func<SourceCode, string> m_SourceFinder; |
||||
|
||||
|
||||
public DebugService DebugService { get; private set; } |
||||
|
||||
public Regex ErrorRegex { get; set; } |
||||
|
||||
public Script Script { get; private set; } |
||||
|
||||
public bool PauseRequested { get; set; } |
||||
|
||||
public string Name { get; set; } |
||||
|
||||
public int Id { get; private set; } |
||||
|
||||
|
||||
public AsyncDebugger(Script script, Func<SourceCode, string> sourceFinder, string name) |
||||
{ |
||||
lock (s_AsyncDebuggerIdLock) |
||||
Id = s_AsyncDebuggerIdCounter++; |
||||
|
||||
m_SourceFinder = sourceFinder; |
||||
ErrorRegex = new Regex(@"\A.*\Z"); |
||||
Script = script; |
||||
m_WatchItems = new List<WatchItem>[(int)WatchType.MaxValue]; |
||||
Name = name; |
||||
|
||||
for (int i = 0; i < m_WatchItems.Length; i++) |
||||
m_WatchItems[i] = new List<WatchItem>(64); |
||||
} |
||||
|
||||
|
||||
public IAsyncDebuggerClient Client |
||||
{ |
||||
get { return m_Client__; } |
||||
set |
||||
{ |
||||
lock (m_Lock) |
||||
{ |
||||
if (m_Client__ != null && m_Client__ != value) |
||||
{ |
||||
m_Client__.Unbind(); |
||||
} |
||||
|
||||
if (value != null) |
||||
{ |
||||
for (int i = 0; i < Script.SourceCodeCount; i++) |
||||
if (m_SourcesMap.ContainsKey(i)) |
||||
value.OnSourceCodeChanged(i); |
||||
} |
||||
|
||||
m_Client__ = value; |
||||
} |
||||
} |
||||
} |
||||
|
||||
DebuggerAction IDebugger.GetAction(int ip, SourceRef sourceref) |
||||
{ |
||||
PauseRequested = false; |
||||
|
||||
lock (m_Lock) |
||||
if (Client != null) |
||||
{ |
||||
Client.SendStopEvent(); |
||||
} |
||||
|
||||
while (true) |
||||
{ |
||||
lock (m_Lock) |
||||
{ |
||||
if (Client == null) |
||||
{ |
||||
return new DebuggerAction() { Action = DebuggerAction.ActionType.Run }; |
||||
} |
||||
|
||||
if (m_PendingAction != null) |
||||
{ |
||||
var action = m_PendingAction; |
||||
m_PendingAction = null; |
||||
return action; |
||||
} |
||||
} |
||||
|
||||
Sleep(10); |
||||
} |
||||
} |
||||
|
||||
|
||||
public void QueueAction(DebuggerAction action) |
||||
{ |
||||
while (true) |
||||
{ |
||||
lock (m_Lock) |
||||
if (m_PendingAction == null) |
||||
{ |
||||
m_PendingAction = action; |
||||
break; |
||||
} |
||||
|
||||
Sleep(10); |
||||
} |
||||
} |
||||
|
||||
private void Sleep(int v) |
||||
{ |
||||
#if DOTNET_CORE |
||||
System.Threading.Tasks.Task.Delay(10).Wait(); |
||||
#else |
||||
System.Threading.Thread.Sleep(10); |
||||
#endif |
||||
} |
||||
|
||||
private DynamicExpression CreateDynExpr(string code) |
||||
{ |
||||
try |
||||
{ |
||||
return Script.CreateDynamicExpression(code); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
return Script.CreateConstantDynamicExpression(code, DynValue.NewString(ex.Message)); |
||||
} |
||||
} |
||||
|
||||
List<DynamicExpression> IDebugger.GetWatchItems() |
||||
{ |
||||
return new List<DynamicExpression>(); |
||||
} |
||||
|
||||
bool IDebugger.IsPauseRequested() |
||||
{ |
||||
return PauseRequested; |
||||
} |
||||
|
||||
void IDebugger.RefreshBreakpoints(IEnumerable<SourceRef> refs) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void IDebugger.SetByteCode(string[] byteCode) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void IDebugger.SetSourceCode(SourceCode sourceCode) |
||||
{ |
||||
m_SourcesMap[sourceCode.SourceID] = sourceCode; |
||||
|
||||
bool invalidFile = false; |
||||
|
||||
string file = m_SourceFinder(sourceCode); |
||||
|
||||
if (!string.IsNullOrEmpty(file)) |
||||
{ |
||||
try |
||||
{ |
||||
if (!File.Exists(file)) |
||||
invalidFile = true; |
||||
} |
||||
catch |
||||
{ |
||||
invalidFile = true; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
invalidFile = true; |
||||
} |
||||
|
||||
if (invalidFile) |
||||
{ |
||||
file = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".lua"); |
||||
File.WriteAllText(file, sourceCode.Code + GetFooterForTempFile()); |
||||
m_SourcesOverride[sourceCode.SourceID] = file; |
||||
} |
||||
else if (file != sourceCode.Name) |
||||
{ |
||||
m_SourcesOverride[sourceCode.SourceID] = file; |
||||
} |
||||
|
||||
|
||||
lock (m_Lock) |
||||
if (Client != null) |
||||
Client.OnSourceCodeChanged(sourceCode.SourceID); |
||||
} |
||||
|
||||
private string GetFooterForTempFile() |
||||
{ |
||||
return "\n\n" + |
||||
"----------------------------------------------------------------------------------------------------------\n" + |
||||
"-- This file has been generated by the debugger as a placeholder for a script snippet stored in memory. --\n" + |
||||
"-- If you restart the host process, the contents of this file are not valid anymore. --\n" + |
||||
"----------------------------------------------------------------------------------------------------------\n"; |
||||
} |
||||
|
||||
public string GetSourceFile(int sourceId) |
||||
{ |
||||
if (m_SourcesOverride.ContainsKey(sourceId)) |
||||
return m_SourcesOverride[sourceId]; |
||||
else if (m_SourcesMap.ContainsKey(sourceId)) |
||||
return m_SourcesMap[sourceId].Name; |
||||
return null; |
||||
} |
||||
|
||||
public bool IsSourceOverride(int sourceId) |
||||
{ |
||||
return (m_SourcesOverride.ContainsKey(sourceId)); |
||||
} |
||||
|
||||
|
||||
void IDebugger.SignalExecutionEnded() |
||||
{ |
||||
lock (m_Lock) |
||||
if (Client != null) |
||||
Client.OnExecutionEnded(); |
||||
} |
||||
|
||||
bool IDebugger.SignalRuntimeException(ScriptRuntimeException ex) |
||||
{ |
||||
lock (m_Lock) |
||||
if (Client == null) |
||||
return false; |
||||
|
||||
Client.OnException(ex); |
||||
PauseRequested = ErrorRegex.IsMatch(ex.Message); |
||||
return PauseRequested; |
||||
} |
||||
|
||||
void IDebugger.Update(WatchType watchType, IEnumerable<WatchItem> items) |
||||
{ |
||||
var list = m_WatchItems[(int)watchType]; |
||||
|
||||
list.Clear(); |
||||
list.AddRange(items); |
||||
|
||||
lock (m_Lock) |
||||
if (Client != null) |
||||
Client.OnWatchesUpdated(watchType); |
||||
} |
||||
|
||||
|
||||
public List<WatchItem> GetWatches(WatchType watchType) |
||||
{ |
||||
return m_WatchItems[(int)watchType]; |
||||
} |
||||
|
||||
public SourceCode GetSource(int id) |
||||
{ |
||||
if (m_SourcesMap.ContainsKey(id)) |
||||
return m_SourcesMap[id]; |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public SourceCode FindSourceByName(string path) |
||||
{ |
||||
// we use case insensitive match - be damned if you have files which differ only by |
||||
// case in the same directory on Unix. |
||||
path = path.Replace('\\', '/').ToUpperInvariant(); |
||||
|
||||
foreach (var kvp in m_SourcesOverride) |
||||
{ |
||||
if (kvp.Value.Replace('\\', '/').ToUpperInvariant() == path) |
||||
return m_SourcesMap[kvp.Key]; |
||||
} |
||||
|
||||
return m_SourcesMap.Values.FirstOrDefault(s => s.Name.Replace('\\', '/').ToUpperInvariant() == path); |
||||
} |
||||
|
||||
void IDebugger.SetDebugService(DebugService debugService) |
||||
{ |
||||
DebugService = debugService; |
||||
} |
||||
|
||||
public DynValue Evaluate(string expression) |
||||
{ |
||||
DynamicExpression expr = CreateDynExpr(expression); |
||||
return expr.Evaluate(); |
||||
} |
||||
|
||||
DebuggerCaps IDebugger.GetDebuggerCaps() |
||||
{ |
||||
return DebuggerCaps.CanDebugSourceCode | DebuggerCaps.HasLineBasedBreakpoints; |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9984211c3fbdf48d2bab7bc81675b60f |
||||
timeCreated: 1476432885 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,209 @@
|
||||
#if (!PCL) && ((!UNITY_5) || UNITY_STANDALONE) |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using MoonSharp.Interpreter; |
||||
using MoonSharp.VsCodeDebugger.SDK; |
||||
|
||||
namespace MoonSharp.VsCodeDebugger.DebuggerLogic |
||||
{ |
||||
internal class EmptyDebugSession : DebugSession |
||||
{ |
||||
MoonSharpVsCodeDebugServer m_Server; |
||||
|
||||
internal EmptyDebugSession(MoonSharpVsCodeDebugServer server) |
||||
: base(true, false) |
||||
{ |
||||
m_Server = server; |
||||
} |
||||
|
||||
public override void Initialize(Response response, Table args) |
||||
{ |
||||
#if DOTNET_CORE |
||||
SendText("Connected to MoonSharp {0} [{1}]", |
||||
Script.VERSION, |
||||
Script.GlobalOptions.Platform.GetPlatformName()); |
||||
#else |
||||
SendText("Connected to MoonSharp {0} [{1}] on process {2} (PID {3})", |
||||
Script.VERSION, |
||||
Script.GlobalOptions.Platform.GetPlatformName(), |
||||
System.Diagnostics.Process.GetCurrentProcess().ProcessName, |
||||
System.Diagnostics.Process.GetCurrentProcess().Id); |
||||
#endif |
||||
|
||||
SendText("No script is set as default for debugging; use the debug console to select the script to debug.\n"); |
||||
|
||||
SendList(); |
||||
|
||||
SendResponse(response, new Capabilities() |
||||
{ |
||||
// This debug adapter does not need the configurationDoneRequest. |
||||
supportsConfigurationDoneRequest = false, |
||||
|
||||
// This debug adapter does not support function breakpoints. |
||||
supportsFunctionBreakpoints = false, |
||||
|
||||
// This debug adapter doesn't support conditional breakpoints. |
||||
supportsConditionalBreakpoints = false, |
||||
|
||||
// This debug adapter does not support a side effect free evaluate request for data hovers. |
||||
supportsEvaluateForHovers = false, |
||||
|
||||
// This debug adapter does not support exception breakpoint filters |
||||
exceptionBreakpointFilters = new object[0] |
||||
}); |
||||
|
||||
// Debugger is ready to accept breakpoints immediately |
||||
SendEvent(new InitializedEvent()); |
||||
} |
||||
|
||||
private void SendList() |
||||
{ |
||||
int currId = m_Server.CurrentId ?? -1000; |
||||
|
||||
SendText("=========================================================="); |
||||
|
||||
foreach (var pair in m_Server.GetAttachedDebuggersByIdAndName()) |
||||
{ |
||||
string isdef = (pair.Key == currId) ? " (default)" : ""; |
||||
SendText("{0} : {1}{2}", pair.Key.ToString().PadLeft(9), pair.Value, isdef); |
||||
} |
||||
SendText(""); |
||||
SendText("Type the number of the script to debug, or '!' to refresh"); |
||||
} |
||||
|
||||
public override void Attach(Response response, Table arguments) |
||||
{ |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Continue(Response response, Table arguments) |
||||
{ |
||||
SendList(); |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Disconnect(Response response, Table arguments) |
||||
{ |
||||
SendResponse(response); |
||||
} |
||||
|
||||
private static string getString(Table args, string property, string dflt = null) |
||||
{ |
||||
var s = (string)args[property]; |
||||
if (s == null) |
||||
{ |
||||
return dflt; |
||||
} |
||||
s = s.Trim(); |
||||
if (s.Length == 0) |
||||
{ |
||||
return dflt; |
||||
} |
||||
return s; |
||||
} |
||||
|
||||
public override void Evaluate(Response response, Table args) |
||||
{ |
||||
var expression = getString(args, "expression"); |
||||
var context = getString(args, "context") ?? "hover"; |
||||
|
||||
if (context == "repl") |
||||
ExecuteRepl(expression); |
||||
|
||||
SendResponse(response); |
||||
} |
||||
|
||||
private void ExecuteRepl(string cmd) |
||||
{ |
||||
int id = 0; |
||||
if (int.TryParse(cmd, out id)) |
||||
{ |
||||
m_Server.CurrentId = id; |
||||
|
||||
SendText("Re-attach the debugger to debug the selected script."); |
||||
|
||||
Unbind(); |
||||
} |
||||
else |
||||
{ |
||||
SendList(); |
||||
} |
||||
} |
||||
|
||||
|
||||
public override void Launch(Response response, Table arguments) |
||||
{ |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Next(Response response, Table arguments) |
||||
{ |
||||
SendList(); |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Pause(Response response, Table arguments) |
||||
{ |
||||
SendList(); |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Scopes(Response response, Table arguments) |
||||
{ |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void SetBreakpoints(Response response, Table args) |
||||
{ |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void StackTrace(Response response, Table args) |
||||
{ |
||||
SendResponse(response); |
||||
} |
||||
|
||||
|
||||
public override void StepIn(Response response, Table arguments) |
||||
{ |
||||
SendList(); |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void StepOut(Response response, Table arguments) |
||||
{ |
||||
SendList(); |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Threads(Response response, Table arguments) |
||||
{ |
||||
var threads = new List<Thread>() { new Thread(0, "Main Thread") }; |
||||
SendResponse(response, new ThreadsResponseBody(threads)); |
||||
} |
||||
|
||||
|
||||
public override void Variables(Response response, Table arguments) |
||||
{ |
||||
SendResponse(response); |
||||
} |
||||
|
||||
|
||||
private void SendText(string msg, params object[] args) |
||||
{ |
||||
msg = string.Format(msg, args); |
||||
SendEvent(new OutputEvent("console", msg + "\n")); |
||||
} |
||||
|
||||
|
||||
public void Unbind() |
||||
{ |
||||
SendText("Bye."); |
||||
SendEvent(new TerminatedEvent()); |
||||
} |
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e92a4cfb128864cc1a914e4f59b2c73e |
||||
timeCreated: 1476432887 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,23 @@
|
||||
#if (!PCL) && ((!UNITY_5) || UNITY_STANDALONE) |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using MoonSharp.Interpreter; |
||||
using MoonSharp.Interpreter.Debugging; |
||||
|
||||
namespace MoonSharp.VsCodeDebugger.DebuggerLogic |
||||
{ |
||||
internal interface IAsyncDebuggerClient |
||||
{ |
||||
void SendStopEvent(); |
||||
void OnWatchesUpdated(WatchType watchType); |
||||
void OnSourceCodeChanged(int sourceID); |
||||
void OnExecutionEnded(); |
||||
void OnException(ScriptRuntimeException ex); |
||||
void Unbind(); |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 439fb2da136aa426ab021def5caf0f6e |
||||
timeCreated: 1476265156 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,460 @@
|
||||
#if (!PCL) && ((!UNITY_5) || UNITY_STANDALONE) |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Text.RegularExpressions; |
||||
using MoonSharp.Interpreter; |
||||
using MoonSharp.Interpreter.Debugging; |
||||
using MoonSharp.VsCodeDebugger.SDK; |
||||
|
||||
|
||||
namespace MoonSharp.VsCodeDebugger.DebuggerLogic |
||||
{ |
||||
internal class MoonSharpDebugSession : DebugSession, IAsyncDebuggerClient |
||||
{ |
||||
AsyncDebugger m_Debug; |
||||
MoonSharpVsCodeDebugServer m_Server; |
||||
List<DynValue> m_Variables = new List<DynValue>(); |
||||
bool m_NotifyExecutionEnd = false; |
||||
|
||||
const int SCOPE_LOCALS = 65536; |
||||
const int SCOPE_SELF = 65537; |
||||
|
||||
|
||||
internal MoonSharpDebugSession(MoonSharpVsCodeDebugServer server, AsyncDebugger debugger) |
||||
: base(true, false) |
||||
{ |
||||
m_Server = server; |
||||
m_Debug = debugger; |
||||
} |
||||
|
||||
public override void Initialize(Response response, Table args) |
||||
{ |
||||
#if DOTNET_CORE |
||||
SendText("Connected to MoonSharp {0} [{1}]", |
||||
Script.VERSION, |
||||
Script.GlobalOptions.Platform.GetPlatformName()); |
||||
#else |
||||
SendText("Connected to MoonSharp {0} [{1}] on process {2} (PID {3})", |
||||
Script.VERSION, |
||||
Script.GlobalOptions.Platform.GetPlatformName(), |
||||
System.Diagnostics.Process.GetCurrentProcess().ProcessName, |
||||
System.Diagnostics.Process.GetCurrentProcess().Id); |
||||
#endif |
||||
|
||||
SendText("Debugging script '{0}'; use the debug console to debug another script.", m_Debug.Name); |
||||
|
||||
SendText("Type '!help' in the Debug Console for available commands."); |
||||
|
||||
SendResponse(response, new Capabilities() |
||||
{ |
||||
// This debug adapter does not need the configurationDoneRequest. |
||||
supportsConfigurationDoneRequest = false, |
||||
|
||||
// This debug adapter does not support function breakpoints. |
||||
supportsFunctionBreakpoints = false, |
||||
|
||||
// This debug adapter doesn't support conditional breakpoints. |
||||
supportsConditionalBreakpoints = false, |
||||
|
||||
// This debug adapter does not support a side effect free evaluate request for data hovers. |
||||
supportsEvaluateForHovers = false, |
||||
|
||||
// This debug adapter does not support exception breakpoint filters |
||||
exceptionBreakpointFilters = new object[0] |
||||
}); |
||||
|
||||
// Debugger is ready to accept breakpoints immediately |
||||
SendEvent(new InitializedEvent()); |
||||
|
||||
m_Debug.Client = this; |
||||
} |
||||
|
||||
public override void Attach(Response response, Table arguments) |
||||
{ |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Continue(Response response, Table arguments) |
||||
{ |
||||
m_Debug.QueueAction(new DebuggerAction() { Action = DebuggerAction.ActionType.Run }); |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Disconnect(Response response, Table arguments) |
||||
{ |
||||
m_Debug.Client = null; |
||||
SendResponse(response); |
||||
} |
||||
|
||||
private static string getString(Table args, string property, string dflt = null) |
||||
{ |
||||
var s = (string)args[property]; |
||||
if (s == null) |
||||
{ |
||||
return dflt; |
||||
} |
||||
s = s.Trim(); |
||||
if (s.Length == 0) |
||||
{ |
||||
return dflt; |
||||
} |
||||
return s; |
||||
} |
||||
|
||||
public override void Evaluate(Response response, Table args) |
||||
{ |
||||
var expression = getString(args, "expression"); |
||||
var frameId = getInt(args, "frameId", 0); |
||||
var context = getString(args, "context") ?? "hover"; |
||||
|
||||
if (frameId != 0 && context != "repl") |
||||
SendText("Warning : Evaluation of variables/watches is always done with the top-level scope."); |
||||
|
||||
if (context == "repl" && expression.StartsWith("!")) |
||||
{ |
||||
ExecuteRepl(expression.Substring(1)); |
||||
SendResponse(response); |
||||
return; |
||||
} |
||||
|
||||
DynValue v = m_Debug.Evaluate(expression) ?? DynValue.Nil; |
||||
m_Variables.Add(v); |
||||
|
||||
SendResponse(response, new EvaluateResponseBody(v.ToDebugPrintString(), m_Variables.Count - 1) |
||||
{ |
||||
type = v.Type.ToLuaDebuggerString() |
||||
}); |
||||
} |
||||
|
||||
private void ExecuteRepl(string cmd) |
||||
{ |
||||
bool showHelp = false; |
||||
cmd = cmd.Trim(); |
||||
if (cmd == "help") |
||||
{ |
||||
showHelp = true; |
||||
} |
||||
else if (cmd.StartsWith("geterror")) |
||||
{ |
||||
SendText("Current error regex : {0}", m_Debug.ErrorRegex.ToString()); |
||||
} |
||||
else if (cmd.StartsWith("seterror")) |
||||
{ |
||||
string regex = cmd.Substring("seterror".Length).Trim(); |
||||
|
||||
try |
||||
{ |
||||
Regex rx = new Regex(regex); |
||||
m_Debug.ErrorRegex = rx; |
||||
SendText("Current error regex : {0}", m_Debug.ErrorRegex.ToString()); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
SendText("Error setting regex: {0}", ex.Message); |
||||
} |
||||
} |
||||
else if (cmd.StartsWith("execendnotify")) |
||||
{ |
||||
string val = cmd.Substring("execendnotify".Length).Trim(); |
||||
|
||||
if (val == "off") |
||||
{ |
||||
m_NotifyExecutionEnd = false; |
||||
} |
||||
else if (val == "on") |
||||
{ |
||||
m_NotifyExecutionEnd = true; |
||||
} |
||||
else if (val.Length > 0) |
||||
SendText("Error : expected 'on' or 'off'"); |
||||
|
||||
SendText("Notifications of execution end are : {0}", m_NotifyExecutionEnd ? "enabled" : "disabled"); |
||||
} |
||||
else if (cmd == "list") |
||||
{ |
||||
int currId = m_Server.CurrentId ?? -1000; |
||||
|
||||
foreach (var pair in m_Server.GetAttachedDebuggersByIdAndName()) |
||||
{ |
||||
string isthis = (pair.Key == m_Debug.Id) ? " (this)" : ""; |
||||
string isdef = (pair.Key == currId) ? " (default)" : ""; |
||||
|
||||
SendText("{0} : {1}{2}{3}", pair.Key.ToString().PadLeft(9), pair.Value, isdef, isthis); |
||||
} |
||||
} |
||||
else if (cmd.StartsWith("select") || cmd.StartsWith("switch")) |
||||
{ |
||||
string arg = cmd.Substring("switch".Length).Trim(); |
||||
|
||||
try |
||||
{ |
||||
int id = int.Parse(arg); |
||||
m_Server.CurrentId = id; |
||||
|
||||
if (cmd.StartsWith("switch")) |
||||
Unbind(); |
||||
else |
||||
SendText("Next time you'll attach the debugger, it will be atteched to script #{0}", id); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
SendText("Error setting regex: {0}", ex.Message); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
SendText("Syntax error : {0}\n", cmd); |
||||
showHelp = true; |
||||
} |
||||
|
||||
if (showHelp) |
||||
{ |
||||
SendText("Available commands : "); |
||||
SendText(" !help - gets this help"); |
||||
SendText(" !list - lists the other scripts which can be debugged"); |
||||
SendText(" !select <id> - select another script for future sessions"); |
||||
SendText(" !switch <id> - switch to another script (same as select + disconnect)"); |
||||
SendText(" !seterror <regex> - sets the regex which tells which errors to trap"); |
||||
SendText(" !geterror - gets the current value of the regex which tells which errors to trap"); |
||||
SendText(" !execendnotify [on|off] - sets the notification of end of execution on or off (default = off)"); |
||||
SendText(" ... or type an expression to evaluate it on the fly."); |
||||
} |
||||
} |
||||
|
||||
|
||||
public override void Launch(Response response, Table arguments) |
||||
{ |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Next(Response response, Table arguments) |
||||
{ |
||||
m_Debug.QueueAction(new DebuggerAction() { Action = DebuggerAction.ActionType.StepOver }); |
||||
SendResponse(response); |
||||
} |
||||
|
||||
private StoppedEvent CreateStoppedEvent(string reason, string text = null) |
||||
{ |
||||
return new StoppedEvent(0, reason, text); |
||||
} |
||||
|
||||
public override void Pause(Response response, Table arguments) |
||||
{ |
||||
m_Debug.PauseRequested = true; |
||||
SendResponse(response); |
||||
SendText("Pause pending -- will pause at first script statement."); |
||||
} |
||||
|
||||
public override void Scopes(Response response, Table arguments) |
||||
{ |
||||
var scopes = new List<Scope>(); |
||||
|
||||
scopes.Add(new Scope("Locals", SCOPE_LOCALS)); |
||||
scopes.Add(new Scope("Self", SCOPE_SELF)); |
||||
|
||||
SendResponse(response, new ScopesResponseBody(scopes)); |
||||
} |
||||
|
||||
public override void SetBreakpoints(Response response, Table args) |
||||
{ |
||||
string path = null; |
||||
|
||||
Table args_source = args["source"] as Table; |
||||
|
||||
if (args_source != null) |
||||
{ |
||||
string p = args_source["path"].ToString(); |
||||
if (p != null && p.Trim().Length > 0) |
||||
path = p; |
||||
} |
||||
|
||||
if (path == null) |
||||
{ |
||||
SendErrorResponse(response, 3010, "setBreakpoints: property 'source' is empty or misformed", null, false, true); |
||||
return; |
||||
} |
||||
|
||||
path = ConvertClientPathToDebugger(path); |
||||
|
||||
SourceCode src = m_Debug.FindSourceByName(path); |
||||
|
||||
if (src == null) |
||||
{ |
||||
// we only support breakpoints in files mono can handle |
||||
SendResponse(response, new SetBreakpointsResponseBody()); |
||||
return; |
||||
} |
||||
|
||||
Table clientLines = args.Get("lines").Table; |
||||
|
||||
var lin = new HashSet<int>(clientLines.Values.Select(jt => ConvertClientLineToDebugger(jt.ToObject<int>())).ToArray()); |
||||
|
||||
var lin2 = m_Debug.DebugService.ResetBreakPoints(src, lin); |
||||
|
||||
var breakpoints = new List<Breakpoint>(); |
||||
foreach (var l in lin) |
||||
{ |
||||
breakpoints.Add(new Breakpoint(lin2.Contains(l), l)); |
||||
} |
||||
|
||||
response.SetBody(new SetBreakpointsResponseBody(breakpoints)); SendResponse(response); |
||||
} |
||||
|
||||
public override void StackTrace(Response response, Table args) |
||||
{ |
||||
int maxLevels = getInt(args, "levels", 10); |
||||
//int threadReference = getInt(args, "threadId", 0); |
||||
|
||||
var stackFrames = new List<StackFrame>(); |
||||
|
||||
var stack = m_Debug.GetWatches(WatchType.CallStack); |
||||
|
||||
var coroutine = m_Debug.GetWatches(WatchType.Threads).LastOrDefault(); |
||||
|
||||
int level = 0; |
||||
int max = Math.Min(maxLevels - 3, stack.Count); |
||||
|
||||
while (level < max) |
||||
{ |
||||
WatchItem frame = stack[level]; |
||||
|
||||
string name = frame.Name; |
||||
SourceRef sourceRef = frame.Location ?? DefaultSourceRef; |
||||
int sourceIdx = sourceRef.SourceIdx; |
||||
string path = sourceRef.IsClrLocation ? "(native)" : (m_Debug.GetSourceFile(sourceIdx) ?? "???"); |
||||
string sourceName = Path.GetFileName(path); |
||||
|
||||
var source = new Source(sourceName, path); // ConvertDebuggerPathToClient(path)); |
||||
|
||||
stackFrames.Add(new StackFrame(level, name, source, |
||||
ConvertDebuggerLineToClient(sourceRef.FromLine), sourceRef.FromChar, |
||||
ConvertDebuggerLineToClient(sourceRef.ToLine), sourceRef.ToChar)); |
||||
|
||||
level++; |
||||
} |
||||
|
||||
if (stack.Count > maxLevels - 3) |
||||
stackFrames.Add(new StackFrame(level++, "(...)", null, 0)); |
||||
|
||||
if (coroutine != null) |
||||
stackFrames.Add(new StackFrame(level++, "(" + coroutine.Name + ")", null, 0)); |
||||
else |
||||
stackFrames.Add(new StackFrame(level++, "(main coroutine)", null, 0)); |
||||
|
||||
stackFrames.Add(new StackFrame(level++, "(native)", null, 0)); |
||||
|
||||
SendResponse(response, new StackTraceResponseBody(stackFrames)); |
||||
} |
||||
|
||||
readonly SourceRef DefaultSourceRef = new SourceRef(-1, 0, 0, 0, 0, false); |
||||
|
||||
|
||||
private int getInt(Table args, string propName, int defaultValue) |
||||
{ |
||||
var jo = args.Get(propName); |
||||
|
||||
if (jo.Type != DataType.Number) |
||||
return defaultValue; |
||||
else |
||||
return jo.ToObject<int>(); |
||||
} |
||||
|
||||
|
||||
public override void StepIn(Response response, Table arguments) |
||||
{ |
||||
m_Debug.QueueAction(new DebuggerAction() { Action = DebuggerAction.ActionType.StepIn }); |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void StepOut(Response response, Table arguments) |
||||
{ |
||||
m_Debug.QueueAction(new DebuggerAction() { Action = DebuggerAction.ActionType.StepOut }); |
||||
SendResponse(response); |
||||
} |
||||
|
||||
public override void Threads(Response response, Table arguments) |
||||
{ |
||||
var threads = new List<Thread>() { new Thread(0, "Main Thread") }; |
||||
SendResponse(response, new ThreadsResponseBody(threads)); |
||||
} |
||||
|
||||
|
||||
public override void Variables(Response response, Table arguments) |
||||
{ |
||||
int index = getInt(arguments, "variablesReference", -1); |
||||
|
||||
var variables = new List<Variable>(); |
||||
|
||||
if (index == SCOPE_SELF) |
||||
{ |
||||
DynValue v = m_Debug.Evaluate("self"); |
||||
VariableInspector.InspectVariable(v, variables); |
||||
} |
||||
else if (index == SCOPE_LOCALS) |
||||
{ |
||||
foreach (var w in m_Debug.GetWatches(WatchType.Locals)) |
||||
variables.Add(new Variable(w.Name, (w.Value ?? DynValue.Void).ToDebugPrintString())); |
||||
} |
||||
else if (index < 0 || index >= m_Variables.Count) |
||||
{ |
||||
variables.Add(new Variable("<error>", null)); |
||||
} |
||||
else |
||||
{ |
||||
VariableInspector.InspectVariable(m_Variables[index], variables); |
||||
} |
||||
|
||||
SendResponse(response, new VariablesResponseBody(variables)); |
||||
} |
||||
|
||||
void IAsyncDebuggerClient.SendStopEvent() |
||||
{ |
||||
SendEvent(CreateStoppedEvent("step")); |
||||
} |
||||
|
||||
|
||||
void IAsyncDebuggerClient.OnWatchesUpdated(WatchType watchType) |
||||
{ |
||||
if (watchType == WatchType.CallStack) |
||||
m_Variables.Clear(); |
||||
} |
||||
|
||||
void IAsyncDebuggerClient.OnSourceCodeChanged(int sourceID) |
||||
{ |
||||
if (m_Debug.IsSourceOverride(sourceID)) |
||||
SendText("Loaded source '{0}' -> '{1}'", m_Debug.GetSource(sourceID).Name, m_Debug.GetSourceFile(sourceID)); |
||||
else |
||||
SendText("Loaded source '{0}'", m_Debug.GetSource(sourceID).Name); |
||||
} |
||||
|
||||
public void OnExecutionEnded() |
||||
{ |
||||
if (m_NotifyExecutionEnd) |
||||
SendText("Execution ended."); |
||||
} |
||||
|
||||
private void SendText(string msg, params object[] args) |
||||
{ |
||||
msg = string.Format(msg, args); |
||||
// SendEvent(new OutputEvent("console", DateTime.Now.ToString("u") + ": " + msg + "\n")); |
||||
SendEvent(new OutputEvent("console", msg + "\n")); |
||||
} |
||||
|
||||
public void OnException(ScriptRuntimeException ex) |
||||
{ |
||||
SendText("runtime error : {0}", ex.DecoratedMessage); |
||||
} |
||||
|
||||
public void Unbind() |
||||
{ |
||||
SendText("Debug session has been closed by the hosting process."); |
||||
SendText("Bye."); |
||||
SendEvent(new TerminatedEvent()); |
||||
} |
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8e5d177091ab64f8fbd15ad5f48d06ae |
||||
timeCreated: 1476432884 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,88 @@
|
||||
#if (!PCL) && ((!UNITY_5) || UNITY_STANDALONE) |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using MoonSharp.Interpreter; |
||||
using MoonSharp.VsCodeDebugger.SDK; |
||||
|
||||
namespace MoonSharp.VsCodeDebugger.DebuggerLogic |
||||
{ |
||||
internal static class VariableInspector |
||||
{ |
||||
internal static void InspectVariable(DynValue v, List<Variable> variables) |
||||
{ |
||||
variables.Add(new Variable("(value)", v.ToPrintString())); |
||||
variables.Add(new Variable("(type)", v.Type.ToLuaDebuggerString())); |
||||
variables.Add(new Variable("(val #id)", v.ReferenceID.ToString())); |
||||
|
||||
switch (v.Type) |
||||
{ |
||||
case DataType.Tuple: |
||||
for (int i = 0; i < v.Tuple.Length; i++) |
||||
variables.Add(new Variable("[i]", (v.Tuple[i] ?? DynValue.Void).ToDebugPrintString())); |
||||
break; |
||||
case DataType.Function: |
||||
variables.Add(new Variable("(address)", v.Function.EntryPointByteCodeLocation.ToString("X8"))); |
||||
variables.Add(new Variable("(upvalues)", v.Function.GetUpvaluesCount().ToString())); |
||||
variables.Add(new Variable("(upvalues type)", v.Function.GetUpvaluesType().ToString())); |
||||
break; |
||||
case DataType.Table: |
||||
|
||||
if (v.Table.MetaTable != null && (v.Table.OwnerScript == null)) |
||||
variables.Add(new Variable("(table type)", "prime table with metatable")); |
||||
else if (v.Table.MetaTable != null) |
||||
variables.Add(new Variable("(table type)", "has metatable")); |
||||
else if (v.Table.OwnerScript == null) |
||||
variables.Add(new Variable("(table type)", "prime table")); |
||||
else |
||||
variables.Add(new Variable("(table type)", "standard")); |
||||
|
||||
variables.Add(new Variable("(table #id)", v.Table.ReferenceID.ToString())); |
||||
|
||||
if (v.Table.MetaTable != null) |
||||
variables.Add(new Variable("(metatable #id)", v.Table.MetaTable.ReferenceID.ToString())); |
||||
|
||||
variables.Add(new Variable("(length)", v.Table.Length.ToString())); |
||||
|
||||
foreach (TablePair p in v.Table.Pairs) |
||||
variables.Add(new Variable("[" + p.Key.ToDebugPrintString() + "]", p.Value.ToDebugPrintString())); |
||||
|
||||
break; |
||||
case DataType.UserData: |
||||
if (v.UserData.Descriptor != null) |
||||
{ |
||||
variables.Add(new Variable("(descriptor)", v.UserData.Descriptor.Name)); |
||||
variables.Add(new Variable("(native type)", v.UserData.Descriptor.Type.ToString())); |
||||
} |
||||
else |
||||
{ |
||||
variables.Add(new Variable("(descriptor)", "null!")); |
||||
} |
||||
|
||||
variables.Add(new Variable("(native object)", v.UserData.Object != null ? v.UserData.Object.ToString() : "(null)")); |
||||
break; |
||||
case DataType.Thread: |
||||
variables.Add(new Variable("(coroutine state)", v.Coroutine.State.ToString())); |
||||
variables.Add(new Variable("(coroutine type)", v.Coroutine.Type.ToString())); |
||||
variables.Add(new Variable("(auto-yield counter)", v.Coroutine.AutoYieldCounter.ToString())); |
||||
break; |
||||
case DataType.ClrFunction: |
||||
variables.Add(new Variable("(name)", v.Callback.Name ?? "(unnamed)")); |
||||
break; |
||||
case DataType.TailCallRequest: |
||||
case DataType.YieldRequest: |
||||
case DataType.Nil: |
||||
case DataType.Void: |
||||
case DataType.Boolean: |
||||
case DataType.Number: |
||||
case DataType.String: |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9b828a4315be6894f9ae25f9d3cacd0e |
||||
timeCreated: 1476265158 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,399 @@
|
||||
#if (!PCL) && ((!UNITY_5) || UNITY_STANDALONE) |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Net; |
||||
using System.Net.Sockets; |
||||
using System.Text; |
||||
using System.Threading; |
||||
using MoonSharp.VsCodeDebugger.DebuggerLogic; |
||||
using MoonSharp.Interpreter; |
||||
using MoonSharp.Interpreter.Debugging; |
||||
using MoonSharp.VsCodeDebugger.SDK; |
||||
|
||||
namespace MoonSharp.VsCodeDebugger |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing a debugger allowing attaching from a Visual Studio Code debugging session. |
||||
/// </summary> |
||||
public class MoonSharpVsCodeDebugServer : IDisposable |
||||
{ |
||||
object m_Lock = new object(); |
||||
List<AsyncDebugger> m_DebuggerList = new List<AsyncDebugger>(); |
||||
AsyncDebugger m_Current = null; |
||||
ManualResetEvent m_StopEvent = new ManualResetEvent(false); |
||||
bool m_Started = false; |
||||
int m_Port; |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of the <see cref="MoonSharpVsCodeDebugServer" /> class. |
||||
/// </summary> |
||||
/// <param name="port">The port on which the debugger listens. It's recommended to use 41912.</param> |
||||
public MoonSharpVsCodeDebugServer(int port = 41912) |
||||
{ |
||||
m_Port = port; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Initializes a new instance of the <see cref="MoonSharpVsCodeDebugServer" /> class with a default script. |
||||
/// Note that for this specific script, it will NOT attach the debugger to the script. |
||||
/// </summary> |
||||
/// <param name="script">The script object to debug.</param> |
||||
/// <param name="port">The port on which the debugger listens. It's recommended to use 41912 unless you are going to keep more than one script object around.</param> |
||||
/// <param name="sourceFinder">A function which gets in input a source code and returns the path to |
||||
/// source file to use. It can return null and in that case (or if the file cannot be found) |
||||
/// a temporary file will be generated on the fly.</param> |
||||
[Obsolete("Use the constructor taking only a port, and the 'Attach' method instead.")] |
||||
public MoonSharpVsCodeDebugServer(Script script, int port, Func<SourceCode, string> sourceFinder = null) |
||||
{ |
||||
m_Port = port; |
||||
m_Current = new AsyncDebugger(script, sourceFinder ?? (s => s.Name), "Default script"); |
||||
m_DebuggerList.Add(m_Current); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Attaches the specified script to the debugger |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="name">The name of the script.</param> |
||||
/// <param name="sourceFinder">A function which gets in input a source code and returns the path to |
||||
/// source file to use. It can return null and in that case (or if the file cannot be found) |
||||
/// a temporary file will be generated on the fly.</param> |
||||
/// <exception cref="ArgumentException">If the script has already been attached to this debugger.</exception> |
||||
public void AttachToScript(Script script, string name, Func<SourceCode, string> sourceFinder = null) |
||||
{ |
||||
lock (m_Lock) |
||||
{ |
||||
if (m_DebuggerList.Any(d => d.Script == script)) |
||||
throw new ArgumentException("Script already attached to this debugger."); |
||||
|
||||
var debugger = new AsyncDebugger(script, sourceFinder ?? (s => s.Name), name); |
||||
script.AttachDebugger(debugger); |
||||
m_DebuggerList.Add(debugger); |
||||
|
||||
if (m_Current == null) |
||||
m_Current = debugger; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets a list of the attached debuggers by id and name |
||||
/// </summary> |
||||
public IEnumerable<KeyValuePair<int, string>> GetAttachedDebuggersByIdAndName() |
||||
{ |
||||
lock (m_Lock) |
||||
return m_DebuggerList |
||||
.OrderBy(d => d.Id) |
||||
.Select(d => new KeyValuePair<int, string>(d.Id, d.Name)) |
||||
.ToArray(); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Gets or sets the current script by ID (see GetAttachedDebuggersByIdAndName). |
||||
/// New vscode connections will attach to this debugger ID. Changing the current ID does NOT disconnect |
||||
/// connected clients. |
||||
/// </summary> |
||||
public int? CurrentId |
||||
{ |
||||
get { lock (m_Lock) return m_Current != null ? m_Current.Id : (int?)null; } |
||||
set |
||||
{ |
||||
lock (m_Lock) |
||||
{ |
||||
if (value == null) |
||||
{ |
||||
m_Current = null; |
||||
return; |
||||
} |
||||
|
||||
var current = (m_DebuggerList.FirstOrDefault(d => d.Id == value)); |
||||
|
||||
if (current == null) |
||||
throw new ArgumentException("Cannot find debugger with given Id."); |
||||
|
||||
m_Current = current; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Gets or sets the current script. New vscode connections will attach to this script. Changing the current script does NOT disconnect |
||||
/// connected clients. |
||||
/// </summary> |
||||
public Script Current |
||||
{ |
||||
get { lock(m_Lock) return m_Current != null ? m_Current.Script : null; } |
||||
set |
||||
{ |
||||
lock (m_Lock) |
||||
{ |
||||
if (value == null) |
||||
{ |
||||
m_Current = null; |
||||
return; |
||||
} |
||||
|
||||
var current = (m_DebuggerList.FirstOrDefault(d => d.Script == value)); |
||||
|
||||
if (current == null) |
||||
throw new ArgumentException("Cannot find debugger with given script associated."); |
||||
|
||||
m_Current = current; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Detaches the specified script. The debugger attached to that script will get disconnected. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <exception cref="ArgumentException">Thrown if the script cannot be found.</exception> |
||||
public void Detach(Script script) |
||||
{ |
||||
lock (m_Lock) |
||||
{ |
||||
var removed = m_DebuggerList.FirstOrDefault(d => d.Script == script); |
||||
|
||||
if (removed == null) |
||||
throw new ArgumentException("Cannot detach script - not found."); |
||||
|
||||
removed.Client = null; |
||||
|
||||
m_DebuggerList.Remove(removed); |
||||
|
||||
if (m_Current == removed) |
||||
{ |
||||
if (m_DebuggerList.Count > 0) |
||||
m_Current = m_DebuggerList[m_DebuggerList.Count - 1]; |
||||
else |
||||
m_Current = null; |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets or sets a delegate which will be called when logging messages are generated |
||||
/// </summary> |
||||
public Action<string> Logger { get; set; } |
||||
|
||||
|
||||
/// <summary> |
||||
/// Gets the debugger object. Obsolete, use the new interface using the Attach method instead. |
||||
/// </summary> |
||||
[Obsolete("Use the Attach method instead.")] |
||||
public IDebugger GetDebugger() |
||||
{ |
||||
lock(m_Lock) |
||||
return m_Current; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Stops listening |
||||
/// </summary> |
||||
/// <exception cref="InvalidOperationException">Cannot stop; server was not started.</exception> |
||||
public void Dispose() |
||||
{ |
||||
m_StopEvent.Set(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Starts listening on the localhost for incoming connections. |
||||
/// </summary> |
||||
public MoonSharpVsCodeDebugServer Start() |
||||
{ |
||||
lock (m_Lock) |
||||
{ |
||||
if (m_Started) |
||||
throw new InvalidOperationException("Cannot start; server has already been started."); |
||||
|
||||
m_StopEvent.Reset(); |
||||
|
||||
TcpListener serverSocket = null; |
||||
serverSocket = new TcpListener(IPAddress.Parse("127.0.0.1"), m_Port); |
||||
serverSocket.Start(); |
||||
|
||||
SpawnThread("VsCodeDebugServer_" + m_Port.ToString(), () => ListenThread(serverSocket)); |
||||
|
||||
m_Started = true; |
||||
|
||||
return this; |
||||
} |
||||
} |
||||
|
||||
|
||||
private void ListenThread(TcpListener serverSocket) |
||||
{ |
||||
try |
||||
{ |
||||
while (!m_StopEvent.WaitOne(0)) |
||||
{ |
||||
#if DOTNET_CORE |
||||
var task = serverSocket.AcceptSocketAsync(); |
||||
task.Wait(); |
||||
var clientSocket = task.Result; |
||||
#else |
||||
var clientSocket = serverSocket.AcceptSocket(); |
||||
#endif |
||||
|
||||
if (clientSocket != null) |
||||
{ |
||||
string sessionId = Guid.NewGuid().ToString("N"); |
||||
Log("[{0}] : Accepted connection from client {1}", sessionId, clientSocket.RemoteEndPoint); |
||||
|
||||
SpawnThread("VsCodeDebugSession_" + sessionId, () => |
||||
{ |
||||
using (var networkStream = new NetworkStream(clientSocket)) |
||||
{ |
||||
try |
||||
{ |
||||
RunSession(sessionId, networkStream); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
Log("[{0}] : Error : {1}", ex.Message); |
||||
} |
||||
} |
||||
|
||||
#if DOTNET_CORE |
||||
clientSocket.Dispose(); |
||||
#else |
||||
clientSocket.Close(); |
||||
#endif |
||||
Log("[{0}] : Client connection closed", sessionId); |
||||
}); |
||||
} |
||||
} |
||||
} |
||||
catch (Exception e) |
||||
{ |
||||
Log("Fatal error in listening thread : {0}", e.Message); |
||||
} |
||||
finally |
||||
{ |
||||
if (serverSocket != null) |
||||
serverSocket.Stop(); |
||||
} |
||||
} |
||||
|
||||
|
||||
private void RunSession(string sessionId, NetworkStream stream) |
||||
{ |
||||
DebugSession debugSession = null; |
||||
|
||||
lock (m_Lock) |
||||
{ |
||||
if (m_Current != null) |
||||
debugSession = new MoonSharpDebugSession(this, m_Current); |
||||
else |
||||
debugSession = new EmptyDebugSession(this); |
||||
} |
||||
|
||||
debugSession.ProcessLoop(stream, stream); |
||||
} |
||||
|
||||
private void Log(string format, params object[] args) |
||||
{ |
||||
Action<string> logger = Logger; |
||||
|
||||
if (logger != null) |
||||
{ |
||||
string msg = string.Format(format, args); |
||||
logger(msg); |
||||
} |
||||
} |
||||
|
||||
|
||||
private static void SpawnThread(string name, Action threadProc) |
||||
{ |
||||
#if DOTNET_CORE |
||||
System.Threading.Tasks.Task.Run(() => threadProc()); |
||||
#else |
||||
new System.Threading.Thread(() => threadProc()) |
||||
{ |
||||
IsBackground = true, |
||||
Name = name |
||||
} |
||||
.Start(); |
||||
#endif |
||||
} |
||||
} |
||||
} |
||||
|
||||
#else |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using MoonSharp.Interpreter; |
||||
using MoonSharp.Interpreter.Debugging; |
||||
|
||||
namespace MoonSharp.VsCodeDebugger |
||||
{ |
||||
public class MoonSharpVsCodeDebugServer : IDisposable |
||||
{ |
||||
public MoonSharpVsCodeDebugServer(int port = 41912) |
||||
{ |
||||
} |
||||
|
||||
[Obsolete("Use the constructor taking only a port, and the 'Attach' method instead.")] |
||||
public MoonSharpVsCodeDebugServer(Script script, int port, Func<SourceCode, string> sourceFinder = null) |
||||
{ |
||||
} |
||||
|
||||
public void AttachToScript(Script script, string name, Func<SourceCode, string> sourceFinder = null) |
||||
{ |
||||
} |
||||
|
||||
public IEnumerable<KeyValuePair<int, string>> GetAttachedDebuggersByIdAndName() |
||||
{ |
||||
yield break; |
||||
} |
||||
|
||||
|
||||
public int? CurrentId |
||||
{ |
||||
get { return null; } |
||||
set { } |
||||
} |
||||
|
||||
|
||||
public Script Current |
||||
{ |
||||
get { return null; } |
||||
set { } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Detaches the specified script. The debugger attached to that script will get disconnected. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <exception cref="ArgumentException">Thrown if the script cannot be found.</exception> |
||||
public void Detach(Script script) |
||||
{ |
||||
|
||||
} |
||||
|
||||
public Action<string> Logger { get; set; } |
||||
|
||||
|
||||
[Obsolete("Use the Attach method instead.")] |
||||
public IDebugger GetDebugger() |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
} |
||||
|
||||
public MoonSharpVsCodeDebugServer Start() |
||||
{ |
||||
return this; |
||||
} |
||||
|
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1f49800a7463743149b597062d1b42a2 |
||||
timeCreated: 1476432878 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: b0c4fed5fd89f42c5ba1250cd726961b |
||||
folderAsset: yes |
||||
timeCreated: 1475786652 |
||||
licenseType: Pro |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,610 @@
|
||||
#if (!PCL) && ((!UNITY_5) || UNITY_STANDALONE) |
||||
|
||||
/*--------------------------------------------------------------------------------------------- |
||||
Copyright (c) Microsoft Corporation |
||||
|
||||
All rights reserved. |
||||
|
||||
MIT License |
||||
|
||||
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 System.Linq; |
||||
using System.IO; |
||||
using MoonSharp.Interpreter; |
||||
|
||||
namespace MoonSharp.VsCodeDebugger.SDK |
||||
{ |
||||
// ---- Types ------------------------------------------------------------------------- |
||||
|
||||
public class Message |
||||
{ |
||||
public int id { get; private set; } |
||||
public string format { get; private set; } |
||||
public object variables { get; private set; } |
||||
public object showUser { get; private set; } |
||||
public object sendTelemetry { get; private set; } |
||||
|
||||
public Message(int id, string format, object variables = null, bool user = true, bool telemetry = false) |
||||
{ |
||||
this.id = id; |
||||
this.format = format; |
||||
this.variables = variables; |
||||
this.showUser = user; |
||||
this.sendTelemetry = telemetry; |
||||
} |
||||
} |
||||
|
||||
public class StackFrame |
||||
{ |
||||
public int id { get; private set; } |
||||
public Source source { get; private set; } |
||||
public int line { get; private set; } |
||||
public int column { get; private set; } |
||||
public string name { get; private set; } |
||||
|
||||
public int? endLine { get; private set; } |
||||
public int? endColumn { get; private set; } |
||||
|
||||
public StackFrame(int id, string name, Source source, int line, int column = 0, int? endLine = null, int? endColumn = null) |
||||
{ |
||||
this.id = id; |
||||
this.name = name; |
||||
this.source = source; |
||||
this.line = line; |
||||
this.column = column; |
||||
this.endLine = endLine; |
||||
this.endColumn = endColumn; |
||||
} |
||||
} |
||||
|
||||
public class Scope |
||||
{ |
||||
public string name { get; private set; } |
||||
public int variablesReference { get; private set; } |
||||
public bool expensive { get; private set; } |
||||
|
||||
public Scope(string name, int variablesReference, bool expensive = false) |
||||
{ |
||||
this.name = name; |
||||
this.variablesReference = variablesReference; |
||||
this.expensive = expensive; |
||||
} |
||||
} |
||||
|
||||
public class Variable |
||||
{ |
||||
public string name { get; private set; } |
||||
public string value { get; private set; } |
||||
public int variablesReference { get; private set; } |
||||
|
||||
public Variable(string name, string value, int variablesReference = 0) |
||||
{ |
||||
this.name = name; |
||||
this.value = value; |
||||
this.variablesReference = variablesReference; |
||||
} |
||||
} |
||||
|
||||
public class Thread |
||||
{ |
||||
public int id { get; private set; } |
||||
public string name { get; private set; } |
||||
|
||||
public Thread(int id, string name) |
||||
{ |
||||
this.id = id; |
||||
if (name == null || name.Length == 0) |
||||
{ |
||||
this.name = string.Format("Thread #{0}", id); |
||||
} |
||||
else |
||||
{ |
||||
this.name = name; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class Source |
||||
{ |
||||
public string name { get; private set; } |
||||
public string path { get; private set; } |
||||
public int sourceReference { get; private set; } |
||||
|
||||
public Source(string name, string path, int sourceReference = 0) |
||||
{ |
||||
this.name = name; |
||||
this.path = path; |
||||
this.sourceReference = sourceReference; |
||||
} |
||||
|
||||
public Source(string path, int sourceReference = 0) |
||||
{ |
||||
this.name = Path.GetFileName(path); |
||||
this.path = path; |
||||
this.sourceReference = sourceReference; |
||||
} |
||||
} |
||||
|
||||
public class Breakpoint |
||||
{ |
||||
public bool verified { get; private set; } |
||||
public int line { get; private set; } |
||||
|
||||
public Breakpoint(bool verified, int line) |
||||
{ |
||||
this.verified = verified; |
||||
this.line = line; |
||||
} |
||||
} |
||||
|
||||
// ---- Events ------------------------------------------------------------------------- |
||||
|
||||
public class InitializedEvent : Event |
||||
{ |
||||
public InitializedEvent() |
||||
: base("initialized") { } |
||||
} |
||||
|
||||
public class StoppedEvent : Event |
||||
{ |
||||
public StoppedEvent(int tid, string reasn, string txt = null) |
||||
: base("stopped", new |
||||
{ |
||||
threadId = tid, |
||||
reason = reasn, |
||||
text = txt |
||||
}) |
||||
{ } |
||||
} |
||||
|
||||
public class ExitedEvent : Event |
||||
{ |
||||
public ExitedEvent(int exCode) |
||||
: base("exited", new { exitCode = exCode }) { } |
||||
} |
||||
|
||||
public class TerminatedEvent : Event |
||||
{ |
||||
public TerminatedEvent() |
||||
: base("terminated") { } |
||||
} |
||||
|
||||
public class ThreadEvent : Event |
||||
{ |
||||
public ThreadEvent(string reasn, int tid) |
||||
: base("thread", new |
||||
{ |
||||
reason = reasn, |
||||
threadId = tid |
||||
}) |
||||
{ } |
||||
} |
||||
|
||||
public class OutputEvent : Event |
||||
{ |
||||
public OutputEvent(string cat, string outpt) |
||||
: base("output", new |
||||
{ |
||||
category = cat, |
||||
output = outpt |
||||
}) |
||||
{ } |
||||
} |
||||
|
||||
// ---- Response ------------------------------------------------------------------------- |
||||
|
||||
public class Capabilities : ResponseBody |
||||
{ |
||||
|
||||
public bool supportsConfigurationDoneRequest; |
||||
public bool supportsFunctionBreakpoints; |
||||
public bool supportsConditionalBreakpoints; |
||||
public bool supportsEvaluateForHovers; |
||||
public object[] exceptionBreakpointFilters; |
||||
} |
||||
|
||||
public class ErrorResponseBody : ResponseBody |
||||
{ |
||||
|
||||
public Message error { get; private set; } |
||||
|
||||
public ErrorResponseBody(Message error) |
||||
{ |
||||
this.error = error; |
||||
} |
||||
} |
||||
|
||||
public class StackTraceResponseBody : ResponseBody |
||||
{ |
||||
public StackFrame[] stackFrames { get; private set; } |
||||
|
||||
public StackTraceResponseBody(List<StackFrame> frames = null) |
||||
{ |
||||
if (frames == null) |
||||
stackFrames = new StackFrame[0]; |
||||
else |
||||
stackFrames = frames.ToArray<StackFrame>(); |
||||
} |
||||
} |
||||
|
||||
public class ScopesResponseBody : ResponseBody |
||||
{ |
||||
public Scope[] scopes { get; private set; } |
||||
|
||||
public ScopesResponseBody(List<Scope> scps = null) |
||||
{ |
||||
if (scps == null) |
||||
scopes = new Scope[0]; |
||||
else |
||||
scopes = scps.ToArray<Scope>(); |
||||
} |
||||
} |
||||
|
||||
public class VariablesResponseBody : ResponseBody |
||||
{ |
||||
public Variable[] variables { get; private set; } |
||||
|
||||
public VariablesResponseBody(List<Variable> vars = null) |
||||
{ |
||||
if (vars == null) |
||||
variables = new Variable[0]; |
||||
else |
||||
variables = vars.ToArray<Variable>(); |
||||
} |
||||
} |
||||
|
||||
public class ThreadsResponseBody : ResponseBody |
||||
{ |
||||
public Thread[] threads { get; private set; } |
||||
|
||||
public ThreadsResponseBody(List<Thread> vars = null) |
||||
{ |
||||
if (vars == null) |
||||
threads = new Thread[0]; |
||||
else |
||||
threads = vars.ToArray<Thread>(); |
||||
} |
||||
} |
||||
|
||||
public class EvaluateResponseBody : ResponseBody |
||||
{ |
||||
public string result { get; private set; } |
||||
public string type { get; set; } |
||||
public int variablesReference { get; private set; } |
||||
|
||||
public EvaluateResponseBody(string value, int reff = 0) |
||||
{ |
||||
result = value; |
||||
variablesReference = reff; |
||||
} |
||||
} |
||||
|
||||
public class SetBreakpointsResponseBody : ResponseBody |
||||
{ |
||||
public Breakpoint[] breakpoints { get; private set; } |
||||
|
||||
public SetBreakpointsResponseBody(List<Breakpoint> bpts = null) |
||||
{ |
||||
if (bpts == null) |
||||
breakpoints = new Breakpoint[0]; |
||||
else |
||||
breakpoints = bpts.ToArray<Breakpoint>(); |
||||
} |
||||
} |
||||
|
||||
// ---- The Session -------------------------------------------------------- |
||||
|
||||
public abstract class DebugSession : ProtocolServer |
||||
{ |
||||
private bool _debuggerLinesStartAt1; |
||||
private bool _debuggerPathsAreURI; |
||||
private bool _clientLinesStartAt1 = true; |
||||
private bool _clientPathsAreURI = true; |
||||
|
||||
|
||||
public DebugSession(bool debuggerLinesStartAt1, bool debuggerPathsAreURI = false) |
||||
{ |
||||
_debuggerLinesStartAt1 = debuggerLinesStartAt1; |
||||
_debuggerPathsAreURI = debuggerPathsAreURI; |
||||
} |
||||
|
||||
public void SendResponse(Response response, ResponseBody body = null) |
||||
{ |
||||
if (body != null) |
||||
{ |
||||
response.SetBody(body); |
||||
} |
||||
SendMessage(response); |
||||
} |
||||
|
||||
public void SendErrorResponse(Response response, int id, string format, object arguments = null, bool user = true, bool telemetry = false) |
||||
{ |
||||
var msg = new Message(id, format, arguments, user, telemetry); |
||||
var message = Utilities.ExpandVariables(msg.format, msg.variables); |
||||
response.SetErrorBody(message, new ErrorResponseBody(msg)); |
||||
SendMessage(response); |
||||
} |
||||
|
||||
protected override void DispatchRequest(string command, Table args, Response response) |
||||
{ |
||||
if (args == null) |
||||
{ |
||||
args = new Table(null); |
||||
} |
||||
|
||||
try |
||||
{ |
||||
switch (command) |
||||
{ |
||||
|
||||
case "initialize": |
||||
|
||||
if (args["linesStartAt1"] != null) |
||||
_clientLinesStartAt1 = args.Get("linesStartAt1").ToObject<bool>(); |
||||
|
||||
var pathFormat = args.Get("pathFormat").ToObject<string>(); |
||||
if (pathFormat != null) |
||||
{ |
||||
switch (pathFormat) |
||||
{ |
||||
case "uri": |
||||
_clientPathsAreURI = true; |
||||
break; |
||||
case "path": |
||||
_clientPathsAreURI = false; |
||||
break; |
||||
default: |
||||
SendErrorResponse(response, 1015, "initialize: bad value '{_format}' for pathFormat", new { _format = pathFormat }); |
||||
return; |
||||
} |
||||
} |
||||
Initialize(response, args); |
||||
break; |
||||
|
||||
case "launch": |
||||
Launch(response, args); |
||||
break; |
||||
|
||||
case "attach": |
||||
Attach(response, args); |
||||
break; |
||||
|
||||
case "disconnect": |
||||
Disconnect(response, args); |
||||
break; |
||||
|
||||
case "next": |
||||
Next(response, args); |
||||
break; |
||||
|
||||
case "continue": |
||||
Continue(response, args); |
||||
break; |
||||
|
||||
case "stepIn": |
||||
StepIn(response, args); |
||||
break; |
||||
|
||||
case "stepOut": |
||||
StepOut(response, args); |
||||
break; |
||||
|
||||
case "pause": |
||||
Pause(response, args); |
||||
break; |
||||
|
||||
case "stackTrace": |
||||
StackTrace(response, args); |
||||
break; |
||||
|
||||
case "scopes": |
||||
Scopes(response, args); |
||||
break; |
||||
|
||||
case "variables": |
||||
Variables(response, args); |
||||
break; |
||||
|
||||
case "source": |
||||
Source(response, args); |
||||
break; |
||||
|
||||
case "threads": |
||||
Threads(response, args); |
||||
break; |
||||
|
||||
case "setBreakpoints": |
||||
SetBreakpoints(response, args); |
||||
break; |
||||
|
||||
case "setFunctionBreakpoints": |
||||
SetFunctionBreakpoints(response, args); |
||||
break; |
||||
|
||||
case "setExceptionBreakpoints": |
||||
SetExceptionBreakpoints(response, args); |
||||
break; |
||||
|
||||
case "evaluate": |
||||
Evaluate(response, args); |
||||
break; |
||||
|
||||
default: |
||||
SendErrorResponse(response, 1014, "unrecognized request: {_request}", new { _request = command }); |
||||
break; |
||||
} |
||||
} |
||||
catch (Exception e) |
||||
{ |
||||
SendErrorResponse(response, 1104, "error while processing request '{_request}' (exception: {_exception})", new { _request = command, _exception = e.Message }); |
||||
} |
||||
|
||||
if (command == "disconnect") |
||||
{ |
||||
Stop(); |
||||
} |
||||
} |
||||
|
||||
public abstract void Initialize(Response response, Table args); |
||||
|
||||
public abstract void Launch(Response response, Table arguments); |
||||
|
||||
public abstract void Attach(Response response, Table arguments); |
||||
|
||||
public abstract void Disconnect(Response response, Table arguments); |
||||
|
||||
public virtual void SetFunctionBreakpoints(Response response, Table arguments) |
||||
{ |
||||
} |
||||
|
||||
public virtual void SetExceptionBreakpoints(Response response, Table arguments) |
||||
{ |
||||
} |
||||
|
||||
public abstract void SetBreakpoints(Response response, Table arguments); |
||||
|
||||
public abstract void Continue(Response response, Table arguments); |
||||
|
||||
public abstract void Next(Response response, Table arguments); |
||||
|
||||
public abstract void StepIn(Response response, Table arguments); |
||||
|
||||
public abstract void StepOut(Response response, Table arguments); |
||||
|
||||
public abstract void Pause(Response response, Table arguments); |
||||
|
||||
public abstract void StackTrace(Response response, Table arguments); |
||||
|
||||
public abstract void Scopes(Response response, Table arguments); |
||||
|
||||
public abstract void Variables(Response response, Table arguments); |
||||
|
||||
public virtual void Source(Response response, Table arguments) |
||||
{ |
||||
SendErrorResponse(response, 1020, "Source not supported"); |
||||
} |
||||
|
||||
public abstract void Threads(Response response, Table arguments); |
||||
|
||||
public abstract void Evaluate(Response response, Table arguments); |
||||
|
||||
// protected |
||||
|
||||
protected int ConvertDebuggerLineToClient(int line) |
||||
{ |
||||
if (_debuggerLinesStartAt1) |
||||
{ |
||||
return _clientLinesStartAt1 ? line : line - 1; |
||||
} |
||||
else |
||||
{ |
||||
return _clientLinesStartAt1 ? line + 1 : line; |
||||
} |
||||
} |
||||
|
||||
protected int ConvertClientLineToDebugger(int line) |
||||
{ |
||||
if (_debuggerLinesStartAt1) |
||||
{ |
||||
return _clientLinesStartAt1 ? line : line + 1; |
||||
} |
||||
else |
||||
{ |
||||
return _clientLinesStartAt1 ? line - 1 : line; |
||||
} |
||||
} |
||||
|
||||
protected string ConvertDebuggerPathToClient(string path) |
||||
{ |
||||
if (_debuggerPathsAreURI) |
||||
{ |
||||
if (_clientPathsAreURI) |
||||
{ |
||||
return path; |
||||
} |
||||
else |
||||
{ |
||||
Uri uri = new Uri(path); |
||||
return uri.LocalPath; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if (_clientPathsAreURI) |
||||
{ |
||||
try |
||||
{ |
||||
var uri = new System.Uri(path); |
||||
return uri.AbsoluteUri; |
||||
} |
||||
catch |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
return path; |
||||
} |
||||
} |
||||
} |
||||
|
||||
protected string ConvertClientPathToDebugger(string clientPath) |
||||
{ |
||||
if (clientPath == null) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
if (_debuggerPathsAreURI) |
||||
{ |
||||
if (_clientPathsAreURI) |
||||
{ |
||||
return clientPath; |
||||
} |
||||
else |
||||
{ |
||||
var uri = new System.Uri(clientPath); |
||||
return uri.AbsoluteUri; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if (_clientPathsAreURI) |
||||
{ |
||||
if (Uri.IsWellFormedUriString(clientPath, UriKind.Absolute)) |
||||
{ |
||||
Uri uri = new Uri(clientPath); |
||||
return uri.LocalPath; |
||||
} |
||||
Console.Error.WriteLine("path not well formed: '{0}'", clientPath); |
||||
return null; |
||||
} |
||||
else |
||||
{ |
||||
return clientPath; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 41359a96dff8e497abb39aab280e3dcf |
||||
timeCreated: 1476265156 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,342 @@
|
||||
#if (!PCL) && ((!UNITY_5) || UNITY_STANDALONE) |
||||
|
||||
/*--------------------------------------------------------------------------------------------- |
||||
Copyright (c) Microsoft Corporation |
||||
|
||||
All rights reserved. |
||||
|
||||
MIT License |
||||
|
||||
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.Text; |
||||
using System.IO; |
||||
using System.Text.RegularExpressions; |
||||
using MoonSharp.Interpreter; |
||||
using MoonSharp.Interpreter.Serialization.Json; |
||||
using MoonSharp.Interpreter.Serialization; |
||||
|
||||
namespace MoonSharp.VsCodeDebugger.SDK |
||||
{ |
||||
public class ProtocolMessage |
||||
{ |
||||
public int seq; |
||||
public string type { get; private set; } |
||||
|
||||
public ProtocolMessage(string typ) |
||||
{ |
||||
type = typ; |
||||
} |
||||
|
||||
public ProtocolMessage(string typ, int sq) |
||||
{ |
||||
type = typ; |
||||
seq = sq; |
||||
} |
||||
} |
||||
|
||||
public class Request : ProtocolMessage |
||||
{ |
||||
public string command; |
||||
public Table arguments; |
||||
|
||||
public Request(int id, string cmd, Table arg) : base("request", id) |
||||
{ |
||||
command = cmd; |
||||
arguments = arg; |
||||
} |
||||
} |
||||
|
||||
/* |
||||
* subclasses of ResponseBody are serialized as the body of a response. |
||||
* Don't change their instance variables since that will break the debug protocol. |
||||
*/ |
||||
public class ResponseBody |
||||
{ |
||||
// empty |
||||
} |
||||
|
||||
public class Response : ProtocolMessage |
||||
{ |
||||
public bool success { get; private set; } |
||||
public string message { get; private set; } |
||||
public int request_seq { get; private set; } |
||||
public string command { get; private set; } |
||||
public ResponseBody body { get; private set; } |
||||
|
||||
public Response(Table req) : base("response") |
||||
{ |
||||
success = true; |
||||
request_seq = req.Get("seq").ToObject<int>(); |
||||
command = req.Get("command").ToObject<string>(); |
||||
} |
||||
|
||||
public void SetBody(ResponseBody bdy) |
||||
{ |
||||
success = true; |
||||
body = bdy; |
||||
} |
||||
|
||||
public void SetErrorBody(string msg, ResponseBody bdy = null) |
||||
{ |
||||
success = false; |
||||
message = msg; |
||||
body = bdy; |
||||
} |
||||
} |
||||
|
||||
public class Event : ProtocolMessage |
||||
{ |
||||
public string @event { get; private set; } |
||||
public object body { get; private set; } |
||||
|
||||
public Event(string type, object bdy = null) : base("event") |
||||
{ |
||||
@event = type; |
||||
body = bdy; |
||||
} |
||||
} |
||||
|
||||
/* |
||||
* The ProtocolServer can be used to implement a server that uses the VSCode debug protocol. |
||||
*/ |
||||
public abstract class ProtocolServer |
||||
{ |
||||
public bool TRACE; |
||||
public bool TRACE_RESPONSE; |
||||
|
||||
protected const int BUFFER_SIZE = 4096; |
||||
protected const string TWO_CRLF = "\r\n\r\n"; |
||||
protected static readonly Regex CONTENT_LENGTH_MATCHER = new Regex(@"Content-Length: (\d+)"); |
||||
|
||||
protected static readonly Encoding Encoding = System.Text.Encoding.UTF8; |
||||
|
||||
private int _sequenceNumber; |
||||
|
||||
private Stream _outputStream; |
||||
|
||||
private ByteBuffer _rawData; |
||||
private int _bodyLength; |
||||
|
||||
private bool _stopRequested; |
||||
|
||||
|
||||
public ProtocolServer() |
||||
{ |
||||
_sequenceNumber = 1; |
||||
_bodyLength = -1; |
||||
_rawData = new ByteBuffer(); |
||||
} |
||||
|
||||
public void ProcessLoop(Stream inputStream, Stream outputStream) |
||||
{ |
||||
_outputStream = outputStream; |
||||
|
||||
byte[] buffer = new byte[BUFFER_SIZE]; |
||||
|
||||
_stopRequested = false; |
||||
while (!_stopRequested) |
||||
{ |
||||
var read = inputStream.Read(buffer, 0, buffer.Length); |
||||
|
||||
if (read == 0) |
||||
{ |
||||
// end of stream |
||||
break; |
||||
} |
||||
|
||||
if (read > 0) |
||||
{ |
||||
_rawData.Append(buffer, read); |
||||
ProcessData(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void Stop() |
||||
{ |
||||
_stopRequested = true; |
||||
} |
||||
|
||||
public void SendEvent(Event e) |
||||
{ |
||||
SendMessage(e); |
||||
} |
||||
|
||||
protected abstract void DispatchRequest(string command, Table args, Response response); |
||||
|
||||
// ---- private ------------------------------------------------------------------------ |
||||
|
||||
private void ProcessData() |
||||
{ |
||||
while (true) |
||||
{ |
||||
if (_bodyLength >= 0) |
||||
{ |
||||
if (_rawData.Length >= _bodyLength) |
||||
{ |
||||
var buf = _rawData.RemoveFirst(_bodyLength); |
||||
|
||||
_bodyLength = -1; |
||||
|
||||
Dispatch(Encoding.GetString(buf)); |
||||
|
||||
continue; // there may be more complete messages to process |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
string s = _rawData.GetString(Encoding); |
||||
var idx = s.IndexOf(TWO_CRLF); |
||||
if (idx != -1) |
||||
{ |
||||
Match m = CONTENT_LENGTH_MATCHER.Match(s); |
||||
if (m.Success && m.Groups.Count == 2) |
||||
{ |
||||
_bodyLength = Convert.ToInt32(m.Groups[1].ToString()); |
||||
|
||||
_rawData.RemoveFirst(idx + TWO_CRLF.Length); |
||||
|
||||
continue; // try to handle a complete message |
||||
} |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
|
||||
private void Dispatch(string req) |
||||
{ |
||||
try |
||||
{ |
||||
Table request = JsonTableConverter.JsonToTable(req); |
||||
if (request != null && request["type"].ToString() == "request") |
||||
{ |
||||
if (TRACE) |
||||
Console.Error.WriteLine(string.Format("C {0}: {1}", request["command"], req)); |
||||
|
||||
var response = new Response(request); |
||||
|
||||
DispatchRequest(request.Get("command").String, request.Get("arguments").Table, response); |
||||
|
||||
SendMessage(response); |
||||
} |
||||
} |
||||
catch |
||||
{ |
||||
} |
||||
} |
||||
|
||||
protected void SendMessage(ProtocolMessage message) |
||||
{ |
||||
message.seq = _sequenceNumber++; |
||||
|
||||
if (TRACE_RESPONSE && message.type == "response") |
||||
{ |
||||
Console.Error.WriteLine(string.Format(" R: {0}", JsonTableConverter.ObjectToJson(message))); |
||||
} |
||||
if (TRACE && message.type == "event") |
||||
{ |
||||
Event e = (Event)message; |
||||
Console.Error.WriteLine(string.Format("E {0}: {1}", e.@event, JsonTableConverter.ObjectToJson(e.body))); |
||||
} |
||||
|
||||
var data = ConvertToBytes(message); |
||||
try |
||||
{ |
||||
_outputStream.Write(data, 0, data.Length); |
||||
_outputStream.Flush(); |
||||
} |
||||
catch (Exception) |
||||
{ |
||||
// ignore |
||||
} |
||||
} |
||||
|
||||
|
||||
private static byte[] ConvertToBytes(ProtocolMessage request) |
||||
{ |
||||
var asJson = JsonTableConverter.ObjectToJson(request); |
||||
byte[] jsonBytes = Encoding.GetBytes(asJson); |
||||
|
||||
string header = string.Format("Content-Length: {0}{1}", jsonBytes.Length, TWO_CRLF); |
||||
byte[] headerBytes = Encoding.GetBytes(header); |
||||
|
||||
byte[] data = new byte[headerBytes.Length + jsonBytes.Length]; |
||||
System.Buffer.BlockCopy(headerBytes, 0, data, 0, headerBytes.Length); |
||||
System.Buffer.BlockCopy(jsonBytes, 0, data, headerBytes.Length, jsonBytes.Length); |
||||
|
||||
return data; |
||||
} |
||||
} |
||||
|
||||
//-------------------------------------------------------------------------------------- |
||||
|
||||
class ByteBuffer |
||||
{ |
||||
private byte[] _buffer; |
||||
|
||||
public ByteBuffer() |
||||
{ |
||||
_buffer = new byte[0]; |
||||
} |
||||
|
||||
public int Length |
||||
{ |
||||
get { return _buffer.Length; } |
||||
} |
||||
|
||||
public string GetString(Encoding enc) |
||||
{ |
||||
return enc.GetString(_buffer); |
||||
} |
||||
|
||||
public void Append(byte[] b, int length) |
||||
{ |
||||
byte[] newBuffer = new byte[_buffer.Length + length]; |
||||
System.Buffer.BlockCopy(_buffer, 0, newBuffer, 0, _buffer.Length); |
||||
System.Buffer.BlockCopy(b, 0, newBuffer, _buffer.Length, length); |
||||
_buffer = newBuffer; |
||||
} |
||||
|
||||
public byte[] RemoveFirst(int n) |
||||
{ |
||||
byte[] b = new byte[n]; |
||||
System.Buffer.BlockCopy(_buffer, 0, b, 0, n); |
||||
byte[] newBuffer = new byte[_buffer.Length - n]; |
||||
System.Buffer.BlockCopy(_buffer, n, newBuffer, 0, _buffer.Length - n); |
||||
_buffer = newBuffer; |
||||
return b; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 62430b596d436444d80bee2512f25a29 |
||||
timeCreated: 1476265157 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,95 @@
|
||||
#if (!PCL) && ((!UNITY_5) || UNITY_STANDALONE) |
||||
|
||||
/*--------------------------------------------------------------------------------------------- |
||||
Copyright (c) Microsoft Corporation |
||||
|
||||
All rights reserved. |
||||
|
||||
MIT License |
||||
|
||||
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.Net; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Text.RegularExpressions; |
||||
using System.Reflection; |
||||
using MoonSharp.Interpreter.Compatibility; |
||||
|
||||
namespace MoonSharp.VsCodeDebugger.SDK |
||||
{ |
||||
internal class Utilities |
||||
{ |
||||
private static readonly Regex VARIABLE = new Regex(@"\{(\w+)\}"); |
||||
|
||||
|
||||
/* |
||||
* Resolve hostname, dotted-quad notation for IPv4, or colon-hexadecimal notation for IPv6 to IPAddress. |
||||
* Returns null on failure. |
||||
*/ |
||||
|
||||
public static string ExpandVariables(string format, object variables, bool underscoredOnly = true) |
||||
{ |
||||
if (variables == null) |
||||
{ |
||||
variables = new { }; |
||||
} |
||||
Type type = variables.GetType(); |
||||
return VARIABLE.Replace(format, match => { |
||||
string name = match.Groups[1].Value; |
||||
if (!underscoredOnly || name.StartsWith("_")) |
||||
{ |
||||
|
||||
PropertyInfo property = Framework.Do.GetProperty(type, name); |
||||
if (property != null) |
||||
{ |
||||
object value = property.GetValue(variables, null); |
||||
return value.ToString(); |
||||
} |
||||
return '{' + name + ": not found}"; |
||||
} |
||||
return match.Groups[0].Value; |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* converts the given absPath into a path that is relative to the given dirPath. |
||||
*/ |
||||
public static string MakeRelativePath(string dirPath, string absPath) |
||||
{ |
||||
if (!dirPath.EndsWith("/")) |
||||
{ |
||||
dirPath += "/"; |
||||
} |
||||
if (absPath.StartsWith(dirPath)) |
||||
{ |
||||
return absPath.Replace(dirPath, ""); |
||||
} |
||||
return absPath; |
||||
/* |
||||
Uri uri1 = new Uri(path); |
||||
Uri uri2 = new Uri(dir_path); |
||||
return uri2.MakeRelativeUri(uri1).ToString(); |
||||
*/ |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 91853d42160014ebd843ee4e1a4f676e |
||||
timeCreated: 1476432884 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1d2c5df22fca24da0aab88203047712f |
||||
folderAsset: yes |
||||
timeCreated: 1475786652 |
||||
licenseType: Pro |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,421 @@
|
||||
#if HASDYNAMIC |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using MoonSharp.Interpreter.REPL; |
||||
|
||||
namespace MoonSharp.Interpreter |
||||
{ |
||||
/// <summary> |
||||
/// This class contains extension methods providing async wrappers of many methods. |
||||
/// Asynchronous execution is performed by scheduling the method on the thread pool (through a Task.Factory.StartNew). |
||||
/// |
||||
/// This type is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
public static class AsyncExtensions |
||||
{ |
||||
private static Task<T> ExecAsync<T>(Func<T> func) |
||||
{ |
||||
return Task.Factory.StartNew<T>(func); |
||||
} |
||||
|
||||
private static Task ExecAsyncVoid(Action func) |
||||
{ |
||||
return Task.Factory.StartNew(func); |
||||
} |
||||
|
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously calls this function with the specified args |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="function">The function.</param> |
||||
/// <returns></returns> |
||||
/// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> |
||||
public static Task<DynValue> CallAsync(this Closure function) |
||||
{ |
||||
return ExecAsync(() => function.Call()); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Asynchronously calls this function with the specified args |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="function">The function.</param> |
||||
/// <param name="args">The arguments to pass to the function.</param> |
||||
/// <returns></returns> |
||||
/// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> |
||||
public static Task<DynValue> CallAsync(this Closure function, params object[] args) |
||||
{ |
||||
return ExecAsync(() => function.Call(args)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Asynchronously calls this function with the specified args |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="function">The function.</param> |
||||
/// <param name="args">The arguments to pass to the function.</param> |
||||
/// <returns></returns> |
||||
/// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> |
||||
public static Task<DynValue> CallAsync(this Closure function, params DynValue[] args) |
||||
{ |
||||
return ExecAsync(() => function.Call(args)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Asynchronously loads and executes a string containing a Lua/MoonSharp script. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="code">The code.</param> |
||||
/// <param name="globalContext">The global context.</param> |
||||
/// <param name="codeFriendlyName">Name of the code - used to report errors, etc. Also used by debuggers to locate the original source file.</param> |
||||
/// <returns> |
||||
/// A DynValue containing the result of the processing of the loaded chunk. |
||||
/// </returns> |
||||
public static Task<DynValue> DoStringAsync(this Script script, string code, Table globalContext = null, string codeFriendlyName = null) |
||||
{ |
||||
return ExecAsync(() => script.DoString(code, globalContext, codeFriendlyName)); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously loads and executes a stream containing a Lua/MoonSharp script. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="stream">The stream.</param> |
||||
/// <param name="globalContext">The global context.</param> |
||||
/// <param name="codeFriendlyName">Name of the code - used to report errors, etc. Also used by debuggers to locate the original source file.</param> |
||||
/// <returns> |
||||
/// A DynValue containing the result of the processing of the loaded chunk. |
||||
/// </returns> |
||||
public static Task<DynValue> DoStreamAsync(this Script script, Stream stream, Table globalContext = null, string codeFriendlyName = null) |
||||
{ |
||||
return ExecAsync(() => script.DoStream(stream, globalContext, codeFriendlyName)); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously loads and executes a file containing a Lua/MoonSharp script. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="filename">The filename.</param> |
||||
/// <param name="globalContext">The global context.</param> |
||||
/// <param name="codeFriendlyName">Name of the code - used to report errors, etc. Also used by debuggers to locate the original source file.</param> |
||||
/// <returns> |
||||
/// A DynValue containing the result of the processing of the loaded chunk. |
||||
/// </returns> |
||||
public static Task<DynValue> DoFileAsync(this Script script, string filename, Table globalContext = null, string codeFriendlyName = null) |
||||
{ |
||||
return ExecAsync(() => script.DoFile(filename, globalContext, codeFriendlyName)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Asynchronously loads a string containing a Lua/MoonSharp function. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="code">The code.</param> |
||||
/// <param name="globalTable">The global table to bind to this chunk.</param> |
||||
/// <param name="funcFriendlyName">Name of the function used to report errors, etc.</param> |
||||
/// <returns> |
||||
/// A DynValue containing a function which will execute the loaded code. |
||||
/// </returns> |
||||
public static Task<DynValue> LoadFunctionAsync(this Script script, string code, Table globalTable = null, string funcFriendlyName = null) |
||||
{ |
||||
return ExecAsync(() => script.LoadFunction(code, globalTable, funcFriendlyName)); |
||||
} |
||||
|
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously loads a string containing a Lua/MoonSharp script. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="code">The code.</param> |
||||
/// <param name="globalTable">The global table to bind to this chunk.</param> |
||||
/// <param name="codeFriendlyName">Name of the code - used to report errors, etc.</param> |
||||
/// <returns> |
||||
/// A DynValue containing a function which will execute the loaded code. |
||||
/// </returns> |
||||
public static Task<DynValue> LoadStringAsync(this Script script, string code, Table globalTable = null, string codeFriendlyName = null) |
||||
{ |
||||
return ExecAsync(() => script.LoadString(code, globalTable, codeFriendlyName)); |
||||
} |
||||
|
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously loads a Lua/MoonSharp script from a System.IO.Stream. NOTE: This will *NOT* close the stream! |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="stream">The stream containing code.</param> |
||||
/// <param name="globalTable">The global table to bind to this chunk.</param> |
||||
/// <param name="codeFriendlyName">Name of the code - used to report errors, etc.</param> |
||||
/// <returns> |
||||
/// A DynValue containing a function which will execute the loaded code. |
||||
/// </returns> |
||||
public static Task<DynValue> LoadStreamAsync(this Script script, Stream stream, Table globalTable = null, string codeFriendlyName = null) |
||||
{ |
||||
return ExecAsync(() => script.LoadStream(stream, globalTable, codeFriendlyName)); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously dumps a function on the specified stream. |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="function">The function.</param> |
||||
/// <param name="stream">The stream.</param> |
||||
/// <returns></returns> |
||||
/// <exception cref="System.ArgumentException">function arg is not a function! |
||||
/// or |
||||
/// stream is readonly! |
||||
/// or |
||||
/// function arg has upvalues other than _ENV</exception> |
||||
public static Task DumpAsync(this Script script, DynValue function, Stream stream) |
||||
{ |
||||
return ExecAsyncVoid(() => script.Dump(function, stream)); |
||||
} |
||||
|
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously loads a string containing a Lua/MoonSharp script. |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="filename">The code.</param> |
||||
/// <param name="globalContext">The global table to bind to this chunk.</param> |
||||
/// <param name="friendlyFilename">The filename to be used in error messages.</param> |
||||
/// <returns> |
||||
/// A DynValue containing a function which will execute the loaded code. |
||||
/// </returns> |
||||
public static Task<DynValue> LoadFileAsync(this Script script, string filename, Table globalContext = null, string friendlyFilename = null) |
||||
{ |
||||
return ExecAsync(() => script.LoadFile(filename, globalContext, friendlyFilename)); |
||||
} |
||||
|
||||
|
||||
|
||||
/// <summary> |
||||
/// Calls the specified function. |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="function">The Lua/MoonSharp function to be called</param> |
||||
/// <returns> |
||||
/// The return value(s) of the function call. |
||||
/// </returns> |
||||
/// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> |
||||
public static Task<DynValue> CallAsync(this Script script, DynValue function) |
||||
{ |
||||
return ExecAsync(() => script.Call(function)); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously calls the specified function. |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="function">The Lua/MoonSharp function to be called</param> |
||||
/// <param name="args">The arguments to pass to the function.</param> |
||||
/// <returns> |
||||
/// The return value(s) of the function call. |
||||
/// </returns> |
||||
/// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> |
||||
public static Task<DynValue> CallAsync(this Script script, DynValue function, params DynValue[] args) |
||||
{ |
||||
return ExecAsync(() => script.Call(function, args)); |
||||
} |
||||
|
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously calls the specified function. |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="function">The Lua/MoonSharp function to be called</param> |
||||
/// <param name="args">The arguments to pass to the function.</param> |
||||
/// <returns> |
||||
/// The return value(s) of the function call. |
||||
/// </returns> |
||||
/// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> |
||||
public static Task<DynValue> CallAsync(this Script script, DynValue function, params object[] args) |
||||
{ |
||||
return ExecAsync(() => script.Call(function, args)); |
||||
} |
||||
|
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously calls the specified function. |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="function">The Lua/MoonSharp function to be called</param> |
||||
/// <returns></returns> |
||||
/// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> |
||||
public static Task<DynValue> CallAsync(this Script script, object function) |
||||
{ |
||||
return ExecAsync(() => script.Call(function)); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Asynchronously calls the specified function. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="function">The Lua/MoonSharp function to be called</param> |
||||
/// <param name="args">The arguments to pass to the function.</param> |
||||
/// <returns></returns> |
||||
/// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> |
||||
public static Task<DynValue> CallAsync(this Script script, object function, params object[] args) |
||||
{ |
||||
return ExecAsync(() => script.Call(function, args)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Asynchronously creates a new dynamic expression. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="script">The script.</param> |
||||
/// <param name="code">The code of the expression.</param> |
||||
/// <returns></returns> |
||||
public static Task<DynamicExpression> CreateDynamicExpressionAsync(this Script script, string code) |
||||
{ |
||||
return ExecAsync(() => script.CreateDynamicExpression(code)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Asynchronously evaluates a REPL command. |
||||
/// This method returns the result of the computation, or null if more input is needed for having valid code. |
||||
/// In case of errors, exceptions are propagated to the caller. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="interpreter">The interpreter.</param> |
||||
/// <param name="input">The input.</param> |
||||
/// <returns> |
||||
/// This method returns the result of the computation, or null if more input is needed for a computation. |
||||
/// </returns> |
||||
public static Task<DynValue> EvaluateAsync(this ReplInterpreter interpreter, string input) |
||||
{ |
||||
return ExecAsync(() => interpreter.Evaluate(input)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Resumes the coroutine. |
||||
/// Only non-CLR coroutines can be resumed with this overload of the Resume method. Use the overload accepting a ScriptExecutionContext instead. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="cor">The coroutine</param> |
||||
/// <param name="args">The arguments.</param> |
||||
/// <returns></returns> |
||||
/// <exception cref="System.InvalidOperationException">Only non-CLR coroutines can be resumed with this overload of the Resume method. Use the overload accepting a ScriptExecutionContext instead</exception> |
||||
public static Task<DynValue> ResumeAsync(this Coroutine cor, params DynValue[] args) |
||||
{ |
||||
return ExecAsync(() => cor.Resume(args)); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Resumes the coroutine. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="cor">The coroutine</param> |
||||
/// <param name="context">The ScriptExecutionContext.</param> |
||||
/// <param name="args">The arguments.</param> |
||||
/// <returns></returns> |
||||
public static Task<DynValue> ResumeAsync(this Coroutine cor, ScriptExecutionContext context, params DynValue[] args) |
||||
{ |
||||
return ExecAsync(() => cor.Resume(context, args)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Resumes the coroutine. |
||||
/// Only non-CLR coroutines can be resumed with this overload of the Resume method. Use the overload accepting a ScriptExecutionContext instead. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="cor">The coroutine</param> |
||||
/// <returns></returns> |
||||
/// <exception cref="System.InvalidOperationException">Only non-CLR coroutines can be resumed with this overload of the Resume method. Use the overload accepting a ScriptExecutionContext instead</exception> |
||||
public static Task<DynValue> ResumeAsync(this Coroutine cor) |
||||
{ |
||||
return ExecAsync(() => cor.Resume()); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Resumes the coroutine. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="cor">The coroutine</param> |
||||
/// <param name="context">The ScriptExecutionContext.</param> |
||||
/// <returns></returns> |
||||
public static Task<DynValue> ResumeAsync(this Coroutine cor, ScriptExecutionContext context) |
||||
{ |
||||
return ExecAsync(() => cor.Resume(context)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Resumes the coroutine. |
||||
/// Only non-CLR coroutines can be resumed with this overload of the Resume method. Use the overload accepting a ScriptExecutionContext instead. |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="cor">The coroutine</param> |
||||
/// <param name="args">The arguments.</param> |
||||
/// <returns></returns> |
||||
/// <exception cref="System.InvalidOperationException">Only non-CLR coroutines can be resumed with this overload of the Resume method. Use the overload accepting a ScriptExecutionContext instead.</exception> |
||||
public static Task<DynValue> ResumeAsync(this Coroutine cor, params object[] args) |
||||
{ |
||||
return ExecAsync(() => cor.Resume(args)); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// Resumes the coroutine |
||||
/// |
||||
/// This method is supported only on .NET 4.x and .NET 4.x PCL targets. |
||||
/// </summary> |
||||
/// <param name="cor">The coroutine</param> |
||||
/// <param name="context">The ScriptExecutionContext.</param> |
||||
/// <param name="args">The arguments.</param> |
||||
/// <returns></returns> |
||||
public static Task<DynValue> ResumeAsync(this Coroutine cor, ScriptExecutionContext context, params object[] args) |
||||
{ |
||||
return ExecAsync(() => cor.Resume(context, args)); |
||||
} |
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 66aa67af332e348cbb7dd54b3d5d6433 |
||||
timeCreated: 1475786654 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 5eef0a4b7d8c7458b9f013fcbe0202b3 |
||||
folderAsset: yes |
||||
timeCreated: 1475786652 |
||||
licenseType: Pro |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,7 @@
|
||||
|
||||
namespace MoonSharp.Interpreter.CodeAnalysis |
||||
{ |
||||
class AstNode |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: db3e424c3ff444bb5b4872a8ecb430dd |
||||
timeCreated: 1475786656 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 45b1b1eac93b04a4a8d6ec29d4803aa9 |
||||
timeCreated: 1454345352 |
||||
guid: 6d150008f68617545b69adb7e7fe0f28 |
||||
folderAsset: yes |
||||
timeCreated: 1476432865 |
||||
licenseType: Free |
||||
DefaultImporter: |
||||
userData: |
@ -0,0 +1,21 @@
|
||||
#if PCL || ((!UNITY_EDITOR) && (ENABLE_DOTNET)) |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace System.Reflection |
||||
{ |
||||
internal class ComVisibleAttribute : Attribute |
||||
{ |
||||
public ComVisibleAttribute(bool dummy) |
||||
{ } |
||||
} |
||||
internal class GuidAttribute : Attribute |
||||
{ |
||||
public GuidAttribute(string dummy) |
||||
{ } |
||||
} |
||||
} |
||||
#endif |
||||
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 24be313cbb7a91d42bb1de866ca88289 |
||||
timeCreated: 1476432878 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,16 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
using MoonSharp.Interpreter.Compatibility.Frameworks; |
||||
|
||||
namespace MoonSharp.Interpreter.Compatibility |
||||
{ |
||||
public static class Framework |
||||
{ |
||||
static FrameworkCurrent s_FrameworkCurrent = new FrameworkCurrent(); |
||||
|
||||
public static FrameworkBase Do { get { return s_FrameworkCurrent; } } |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 96e3b35563b935d4c8baa02b06f40965 |
||||
timeCreated: 1476432884 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 77bed9ffa87904128bf91eb0d73bd35e |
||||
timeCreated: 1455193522 |
||||
guid: 0d5353a4a6a04164095893dcf6dcd6cb |
||||
folderAsset: yes |
||||
timeCreated: 1476432866 |
||||
licenseType: Free |
||||
DefaultImporter: |
||||
userData: |
@ -1,6 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: f5996939cde6945dbaa205884e73d770 |
||||
timeCreated: 1455193522 |
||||
guid: 0acf142145bc05446acafd786f0bac46 |
||||
folderAsset: yes |
||||
timeCreated: 1476432866 |
||||
licenseType: Free |
||||
DefaultImporter: |
||||
userData: |
@ -0,0 +1,75 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.Compatibility.Frameworks |
||||
{ |
||||
public abstract class FrameworkBase |
||||
{ |
||||
public abstract bool StringContainsChar(string str, char chr); |
||||
|
||||
public abstract bool IsValueType(Type t); |
||||
|
||||
public abstract Assembly GetAssembly(Type t); |
||||
|
||||
public abstract Type GetBaseType(Type t); |
||||
|
||||
public abstract bool IsGenericType(Type t); |
||||
|
||||
public abstract bool IsGenericTypeDefinition(Type t); |
||||
|
||||
public abstract bool IsEnum(Type t); |
||||
|
||||
public abstract bool IsNestedPublic(Type t); |
||||
|
||||
public abstract bool IsAbstract(Type t); |
||||
|
||||
public abstract bool IsInterface(Type t); |
||||
|
||||
public abstract Attribute[] GetCustomAttributes(Type t, bool inherit); |
||||
|
||||
public abstract Attribute[] GetCustomAttributes(Type t, Type at, bool inherit); |
||||
|
||||
public abstract Type[] GetInterfaces(Type t); |
||||
|
||||
public abstract bool IsInstanceOfType(Type t, object o); |
||||
|
||||
public abstract MethodInfo GetAddMethod(EventInfo ei); |
||||
|
||||
public abstract MethodInfo GetRemoveMethod(EventInfo ei); |
||||
|
||||
public abstract MethodInfo GetGetMethod(PropertyInfo pi); |
||||
|
||||
public abstract MethodInfo GetSetMethod(PropertyInfo pi); |
||||
|
||||
public abstract Type GetInterface(Type type, string name); |
||||
|
||||
public abstract PropertyInfo[] GetProperties(Type type); |
||||
|
||||
public abstract PropertyInfo GetProperty(Type type, string name); |
||||
|
||||
public abstract Type[] GetNestedTypes(Type type); |
||||
|
||||
public abstract EventInfo[] GetEvents(Type type); |
||||
|
||||
public abstract ConstructorInfo[] GetConstructors(Type type); |
||||
|
||||
public abstract Type[] GetAssemblyTypes(Assembly asm); |
||||
|
||||
public abstract MethodInfo[] GetMethods(Type type); |
||||
|
||||
public abstract FieldInfo[] GetFields(Type t); |
||||
|
||||
public abstract MethodInfo GetMethod(Type type, string name); |
||||
|
||||
public abstract Type[] GetGenericArguments(Type t); |
||||
|
||||
public abstract bool IsAssignableFrom(Type current, Type toCompare); |
||||
|
||||
public abstract bool IsDbNull(object o); |
||||
|
||||
public abstract MethodInfo GetMethod(Type resourcesType, string v, Type[] type); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: dbb9f51b6e0b0684ca09c843924edd61 |
||||
timeCreated: 1476432886 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,116 @@
|
||||
#if !(DOTNET_CORE || NETFX_CORE) |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.Compatibility.Frameworks |
||||
{ |
||||
abstract class FrameworkClrBase : FrameworkReflectionBase |
||||
{ |
||||
BindingFlags BINDINGFLAGS_MEMBER = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; |
||||
BindingFlags BINDINGFLAGS_INNERCLASS = BindingFlags.Public | BindingFlags.NonPublic; |
||||
|
||||
public override Type GetTypeInfoFromType(Type t) |
||||
{ |
||||
return t; |
||||
} |
||||
|
||||
public override MethodInfo GetAddMethod(EventInfo ei) |
||||
{ |
||||
return ei.GetAddMethod(true); |
||||
} |
||||
|
||||
public override ConstructorInfo[] GetConstructors(Type type) |
||||
{ |
||||
return type.GetConstructors(BINDINGFLAGS_MEMBER); |
||||
} |
||||
|
||||
public override EventInfo[] GetEvents(Type type) |
||||
{ |
||||
return type.GetEvents(BINDINGFLAGS_MEMBER); |
||||
} |
||||
|
||||
public override FieldInfo[] GetFields(Type type) |
||||
{ |
||||
return type.GetFields(BINDINGFLAGS_MEMBER); |
||||
} |
||||
|
||||
public override Type[] GetGenericArguments(Type type) |
||||
{ |
||||
return type.GetGenericArguments(); |
||||
} |
||||
|
||||
public override MethodInfo GetGetMethod(PropertyInfo pi) |
||||
{ |
||||
return pi.GetGetMethod(true); |
||||
} |
||||
|
||||
public override Type[] GetInterfaces(Type t) |
||||
{ |
||||
return t.GetInterfaces(); |
||||
} |
||||
|
||||
public override MethodInfo GetMethod(Type type, string name) |
||||
{ |
||||
return type.GetMethod(name); |
||||
} |
||||
|
||||
public override MethodInfo[] GetMethods(Type type) |
||||
{ |
||||
return type.GetMethods(BINDINGFLAGS_MEMBER); |
||||
} |
||||
|
||||
public override Type[] GetNestedTypes(Type type) |
||||
{ |
||||
return type.GetNestedTypes(BINDINGFLAGS_INNERCLASS); |
||||
} |
||||
|
||||
public override PropertyInfo[] GetProperties(Type type) |
||||
{ |
||||
return type.GetProperties(BINDINGFLAGS_MEMBER); |
||||
} |
||||
|
||||
public override PropertyInfo GetProperty(Type type, string name) |
||||
{ |
||||
return type.GetProperty(name); |
||||
} |
||||
|
||||
public override MethodInfo GetRemoveMethod(EventInfo ei) |
||||
{ |
||||
return ei.GetRemoveMethod(true); |
||||
} |
||||
|
||||
public override MethodInfo GetSetMethod(PropertyInfo pi) |
||||
{ |
||||
return pi.GetSetMethod(true); |
||||
} |
||||
|
||||
|
||||
public override bool IsAssignableFrom(Type current, Type toCompare) |
||||
{ |
||||
return current.IsAssignableFrom(toCompare); |
||||
} |
||||
|
||||
public override bool IsInstanceOfType(Type t, object o) |
||||
{ |
||||
return t.IsInstanceOfType(o); |
||||
} |
||||
|
||||
|
||||
public override MethodInfo GetMethod(Type resourcesType, string name, Type[] types) |
||||
{ |
||||
return resourcesType.GetMethod(name, types); |
||||
} |
||||
|
||||
public override Type[] GetAssemblyTypes(Assembly asm) |
||||
{ |
||||
return asm.GetTypes(); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 0bbb9dec367acb94dbebde49d3745c4d |
||||
timeCreated: 1476432876 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,76 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
|
||||
#if DOTNET_CORE || NETFX_CORE |
||||
using TTypeInfo = System.Reflection.TypeInfo; |
||||
#else |
||||
using TTypeInfo = System.Type; |
||||
#endif |
||||
|
||||
namespace MoonSharp.Interpreter.Compatibility.Frameworks |
||||
{ |
||||
abstract class FrameworkReflectionBase : FrameworkBase |
||||
{ |
||||
public abstract TTypeInfo GetTypeInfoFromType(Type t); |
||||
|
||||
public override Assembly GetAssembly(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).Assembly; |
||||
} |
||||
|
||||
public override Type GetBaseType(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).BaseType; |
||||
} |
||||
|
||||
|
||||
public override bool IsValueType(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).IsValueType; |
||||
} |
||||
|
||||
public override bool IsInterface(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).IsInterface; |
||||
} |
||||
|
||||
public override bool IsNestedPublic(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).IsNestedPublic; |
||||
} |
||||
public override bool IsAbstract(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).IsAbstract; |
||||
} |
||||
|
||||
public override bool IsEnum(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).IsEnum; |
||||
} |
||||
|
||||
public override bool IsGenericTypeDefinition(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).IsGenericTypeDefinition; |
||||
} |
||||
|
||||
public override bool IsGenericType(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).IsGenericType; |
||||
} |
||||
|
||||
public override Attribute[] GetCustomAttributes(Type t, bool inherit) |
||||
{ |
||||
return GetTypeInfoFromType(t).GetCustomAttributes(inherit).OfType<Attribute>().ToArray(); |
||||
} |
||||
|
||||
public override Attribute[] GetCustomAttributes(Type t, Type at, bool inherit) |
||||
{ |
||||
return GetTypeInfoFromType(t).GetCustomAttributes(at, inherit).OfType<Attribute>().ToArray(); |
||||
} |
||||
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: f03cffebd263dcb4ab8680ce8d152968 |
||||
timeCreated: 1476432887 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,31 @@
|
||||
#if !(DOTNET_CORE || NETFX_CORE) && !PCL |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.Compatibility.Frameworks |
||||
{ |
||||
class FrameworkCurrent : FrameworkClrBase |
||||
{ |
||||
public override bool IsDbNull(object o) |
||||
{ |
||||
return o != null && Convert.IsDBNull(o); |
||||
} |
||||
|
||||
|
||||
public override bool StringContainsChar(string str, char chr) |
||||
{ |
||||
return str.Contains(chr); |
||||
} |
||||
|
||||
public override Type GetInterface(Type type, string name) |
||||
{ |
||||
return type.GetInterface(name); |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 25aeabf9258b9944ab81620030353790 |
||||
timeCreated: 1476432878 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,132 @@
|
||||
#if DOTNET_CORE |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.Compatibility.Frameworks |
||||
{ |
||||
class FrameworkCurrent : FrameworkReflectionBase |
||||
{ |
||||
public override TypeInfo GetTypeInfoFromType(Type t) |
||||
{ |
||||
return t.GetTypeInfo(); |
||||
} |
||||
|
||||
private T[] SafeArray<T>(IEnumerable<T> prop) |
||||
{ |
||||
return prop != null ? prop.ToArray() : new T[0]; |
||||
} |
||||
|
||||
public override MethodInfo GetAddMethod(EventInfo ei) |
||||
{ |
||||
return ei.GetAddMethod(true); |
||||
} |
||||
|
||||
public override ConstructorInfo[] GetConstructors(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredConstructors); |
||||
} |
||||
|
||||
public override EventInfo[] GetEvents(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredEvents); |
||||
} |
||||
|
||||
public override FieldInfo[] GetFields(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredFields); |
||||
} |
||||
|
||||
public override Type[] GetGenericArguments(Type type) |
||||
{ |
||||
return type.GetTypeInfo().GetGenericArguments(); |
||||
} |
||||
|
||||
public override MethodInfo GetGetMethod(PropertyInfo pi) |
||||
{ |
||||
return pi.GetGetMethod(true); |
||||
} |
||||
|
||||
public override Type GetInterface(Type type, string name) |
||||
{ |
||||
return GetTypeInfoFromType(type).GetInterface(name); |
||||
} |
||||
|
||||
public override Type[] GetInterfaces(Type t) |
||||
{ |
||||
return GetTypeInfoFromType(t).GetInterfaces(); |
||||
} |
||||
|
||||
|
||||
public override MethodInfo GetMethod(Type type, string name) |
||||
{ |
||||
return GetTypeInfoFromType(type).GetMethod(name); |
||||
} |
||||
|
||||
public override MethodInfo[] GetMethods(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredMethods); |
||||
} |
||||
|
||||
public override Type[] GetNestedTypes(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredNestedTypes.Select(ti => ti.AsType())); |
||||
} |
||||
|
||||
public override PropertyInfo[] GetProperties(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredProperties); |
||||
} |
||||
|
||||
public override PropertyInfo GetProperty(Type type, string name) |
||||
{ |
||||
return GetTypeInfoFromType(type).GetProperty(name); |
||||
} |
||||
|
||||
public override MethodInfo GetRemoveMethod(EventInfo ei) |
||||
{ |
||||
return ei.GetRemoveMethod(true); |
||||
} |
||||
|
||||
public override MethodInfo GetSetMethod(PropertyInfo pi) |
||||
{ |
||||
return pi.GetSetMethod(true); |
||||
} |
||||
|
||||
|
||||
public override bool IsAssignableFrom(Type current, Type toCompare) |
||||
{ |
||||
return current.GetTypeInfo().IsAssignableFrom(toCompare.GetTypeInfo()); |
||||
} |
||||
|
||||
public override bool IsDbNull(object o) |
||||
{ |
||||
return o != null && o.GetType().FullName.StartsWith("System.DBNull"); |
||||
} |
||||
|
||||
public override bool IsInstanceOfType(Type t, object o) |
||||
{ |
||||
return t.GetTypeInfo().IsInstanceOfType(o); |
||||
} |
||||
|
||||
public override bool StringContainsChar(string str, char chr) |
||||
{ |
||||
return str.Contains(chr); |
||||
} |
||||
|
||||
public override MethodInfo GetMethod(Type resourcesType, string name, Type[] types) |
||||
{ |
||||
return resourcesType.GetTypeInfo().GetMethod(name, types); |
||||
} |
||||
|
||||
public override Type[] GetAssemblyTypes(Assembly asm) |
||||
{ |
||||
return asm.GetExportedTypes(); |
||||
} |
||||
|
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e6df3d0c4b051a347a75d7268c2f6d2a |
||||
timeCreated: 1476432886 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,30 @@
|
||||
#if !(DOTNET_CORE || NETFX_CORE) && PCL |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.Compatibility.Frameworks |
||||
{ |
||||
class FrameworkCurrent : FrameworkClrBase |
||||
{ |
||||
public override bool IsDbNull(object o) |
||||
{ |
||||
return o != null && o.GetType().FullName.StartsWith("System.DBNull"); |
||||
} |
||||
|
||||
public override bool StringContainsChar(string str, char chr) |
||||
{ |
||||
return str.Contains(chr.ToString()); |
||||
} |
||||
|
||||
public override Type GetInterface(Type type, string name) |
||||
{ |
||||
return type.GetInterfaces(). |
||||
FirstOrDefault(t => t.Name == name); |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: bac0f6f9dc5d85f41af33f3b83dbee01 |
||||
timeCreated: 1476432885 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,160 @@
|
||||
#if NETFX_CORE && !DOTNET_CORE |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.Compatibility.Frameworks |
||||
{ |
||||
class FrameworkCurrent : FrameworkReflectionBase |
||||
{ |
||||
public override TypeInfo GetTypeInfoFromType(Type t) |
||||
{ |
||||
return t.GetTypeInfo(); |
||||
} |
||||
|
||||
private T[] SafeArray<T>(IEnumerable<T> prop) |
||||
{ |
||||
return prop != null ? prop.ToArray() : new T[0]; |
||||
} |
||||
|
||||
public override MethodInfo GetAddMethod(EventInfo ei) |
||||
{ |
||||
return ei.AddMethod; |
||||
} |
||||
|
||||
public override ConstructorInfo[] GetConstructors(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredConstructors); |
||||
} |
||||
|
||||
public override EventInfo[] GetEvents(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredEvents); |
||||
} |
||||
|
||||
public override FieldInfo[] GetFields(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredFields); |
||||
} |
||||
|
||||
public override Type[] GetGenericArguments(Type type) |
||||
{ |
||||
return type.GetTypeInfo().GenericTypeArguments; |
||||
} |
||||
|
||||
public override MethodInfo GetGetMethod(PropertyInfo pi) |
||||
{ |
||||
return pi.GetMethod; |
||||
} |
||||
|
||||
public override Type GetInterface(Type type, string name) |
||||
{ |
||||
return type.GetTypeInfo().ImplementedInterfaces.FirstOrDefault(t => t.Name == name); |
||||
} |
||||
|
||||
public override Type[] GetInterfaces(Type t) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(t).ImplementedInterfaces); |
||||
} |
||||
|
||||
|
||||
public override MethodInfo GetMethod(Type type, string name) |
||||
{ |
||||
return GetTypeInfoFromType(type).GetDeclaredMethod(name); |
||||
} |
||||
|
||||
public override MethodInfo[] GetMethods(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredMethods); |
||||
} |
||||
|
||||
public override Type[] GetNestedTypes(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredNestedTypes.Select(ti => ti.AsType())); |
||||
} |
||||
|
||||
public override PropertyInfo[] GetProperties(Type type) |
||||
{ |
||||
return SafeArray(GetTypeInfoFromType(type).DeclaredProperties); |
||||
} |
||||
|
||||
public override PropertyInfo GetProperty(Type type, string name) |
||||
{ |
||||
return GetTypeInfoFromType(type).GetDeclaredProperty(name); |
||||
} |
||||
|
||||
public override MethodInfo GetRemoveMethod(EventInfo ei) |
||||
{ |
||||
return ei.RemoveMethod; |
||||
} |
||||
|
||||
public override MethodInfo GetSetMethod(PropertyInfo pi) |
||||
{ |
||||
return pi.SetMethod; |
||||
} |
||||
|
||||
|
||||
public override bool IsAssignableFrom(Type current, Type toCompare) |
||||
{ |
||||
return current.GetTypeInfo().IsAssignableFrom(toCompare.GetTypeInfo()); |
||||
} |
||||
|
||||
public override bool IsDbNull(object o) |
||||
{ |
||||
return o != null && o.GetType().FullName.StartsWith("System.DBNull"); |
||||
} |
||||
|
||||
public override bool IsInstanceOfType(Type t, object o) |
||||
{ |
||||
if (o == null) |
||||
return false; |
||||
|
||||
return t.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()); |
||||
} |
||||
|
||||
public override bool StringContainsChar(string str, char chr) |
||||
{ |
||||
return str.Contains(chr); |
||||
} |
||||
|
||||
private static MethodInfo GetMethodEx(Type t, string name, Type[] parameters) |
||||
{ |
||||
var ti = t.GetTypeInfo(); |
||||
var methods = ti.GetDeclaredMethods(name); |
||||
foreach (var m in methods) |
||||
{ |
||||
var plist = m.GetParameters(); |
||||
bool match = true; |
||||
foreach (var param in plist) |
||||
{ |
||||
bool valid = true; |
||||
if (parameters != null) |
||||
{ |
||||
foreach (var ptype in parameters) |
||||
valid &= ptype == param.ParameterType; |
||||
} |
||||
match &= valid; |
||||
} |
||||
if (match) |
||||
return m; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
|
||||
public override MethodInfo GetMethod(Type resourcesType, string name, Type[] types) |
||||
{ |
||||
return GetMethodEx(resourcesType, name, types); |
||||
} |
||||
|
||||
public override Type[] GetAssemblyTypes(Assembly asm) |
||||
{ |
||||
return SafeArray(asm.ExportedTypes); |
||||
} |
||||
|
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 11ab1e37f96fc08418f4794c17e8be0c |
||||
timeCreated: 1476435850 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,41 @@
|
||||
#if PCL || ((!UNITY_EDITOR) && (ENABLE_DOTNET)) |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
namespace System.Diagnostics |
||||
{ |
||||
internal class Stopwatch |
||||
{ |
||||
DateTime startTime, stopTime; |
||||
|
||||
public void Start() |
||||
{ |
||||
startTime = DateTime.UtcNow; |
||||
} |
||||
|
||||
public void Stop() |
||||
{ |
||||
stopTime = DateTime.UtcNow; |
||||
} |
||||
|
||||
public static Stopwatch StartNew() |
||||
{ |
||||
Stopwatch sw = new Stopwatch(); |
||||
sw.Start(); |
||||
return sw; |
||||
} |
||||
|
||||
public long ElapsedMilliseconds |
||||
{ |
||||
get |
||||
{ |
||||
return (long)((stopTime - startTime).TotalMilliseconds); |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 23ea8da0a506c1444af1949fa30dd149 |
||||
timeCreated: 1476432878 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 960b24834b8044fc6acf64f473b5ca61 |
||||
folderAsset: yes |
||||
timeCreated: 1475786652 |
||||
licenseType: Pro |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,273 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Globalization; |
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing basic Lua functions (print, type, tostring, etc) as a MoonSharp module. |
||||
/// </summary> |
||||
[MoonSharpModule] |
||||
public class BasicModule |
||||
{ |
||||
//type (v) |
||||
//---------------------------------------------------------------------------------------------------------------- |
||||
//Returns the type of its only argument, coded as a string. The possible results of this function are "nil" |
||||
//(a string, not the value nil), "number", "string", "boolean", "table", "function", "thread", and "userdata". |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue type(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
if (args.Count < 1) throw ScriptRuntimeException.BadArgumentValueExpected(0, "type"); |
||||
|
||||
DynValue v = args[0]; |
||||
return DynValue.NewString(v.Type.ToLuaTypeString()); |
||||
} |
||||
|
||||
|
||||
|
||||
//assert (v [, message]) |
||||
//---------------------------------------------------------------------------------------------------------------- |
||||
//Issues an error when the value of its argument v is false (i.e., nil or false); |
||||
//otherwise, returns all its arguments. message is an error message; when absent, it defaults to "assertion failed!" |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue assert(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v = args[0]; |
||||
DynValue message = args[1]; |
||||
|
||||
if (!v.CastToBool()) |
||||
{ |
||||
if (message.IsNil()) |
||||
throw new ScriptRuntimeException("assertion failed!"); // { DoNotDecorateMessage = true }; |
||||
else |
||||
throw new ScriptRuntimeException(message.ToPrintString()); // { DoNotDecorateMessage = true }; |
||||
} |
||||
|
||||
return DynValue.NewTupleNested(args.GetArray()); |
||||
} |
||||
|
||||
// collectgarbage ([opt [, arg]]) |
||||
// ---------------------------------------------------------------------------------------------------------------- |
||||
// This function is mostly a stub towards the CLR GC. If mode is nil, "collect" or "restart", a GC is forced. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue collectgarbage(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue opt = args[0]; |
||||
|
||||
string mode = opt.CastToString(); |
||||
|
||||
if (mode == null || mode == "collect" || mode == "restart") |
||||
{ |
||||
#if PCL || ENABLE_DOTNET |
||||
GC.Collect(); |
||||
#else |
||||
GC.Collect(2, GCCollectionMode.Forced); |
||||
#endif |
||||
} |
||||
|
||||
return DynValue.Nil; |
||||
} |
||||
|
||||
// error (message [, level]) |
||||
// ---------------------------------------------------------------------------------------------------------------- |
||||
// Terminates the last protected function called and returns message as the error message. Function error never returns. |
||||
// Usually, error adds some information about the error position at the beginning of the message. |
||||
// The level argument specifies how to get the error position. |
||||
// With level 1 (the default), the error position is where the error function was called. |
||||
// Level 2 points the error to where the function that called error was called; and so on. |
||||
// Passing a level 0 avoids the addition of error position information to the message. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue error(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue message = args.AsType(0, "error", DataType.String, false); |
||||
throw new ScriptRuntimeException(message.String); // { DoNotDecorateMessage = true }; |
||||
} |
||||
|
||||
|
||||
// tostring (v) |
||||
// ---------------------------------------------------------------------------------------------------------------- |
||||
// Receives a value of any type and converts it to a string in a reasonable format. (For complete control of how |
||||
// numbers are converted, use string.format.) |
||||
// |
||||
// If the metatable of v has a "__tostring" field, then tostring calls the corresponding value with v as argument, |
||||
// and uses the result of the call as its result. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue tostring(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
if (args.Count < 1) throw ScriptRuntimeException.BadArgumentValueExpected(0, "tostring"); |
||||
|
||||
DynValue v = args[0]; |
||||
DynValue tail = executionContext.GetMetamethodTailCall(v, "__tostring", v); |
||||
|
||||
if (tail == null || tail.IsNil()) |
||||
return DynValue.NewString(v.ToPrintString()); |
||||
|
||||
tail.TailCallData.Continuation = new CallbackFunction(__tostring_continuation, "__tostring"); |
||||
|
||||
return tail; |
||||
} |
||||
|
||||
private static DynValue __tostring_continuation(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue b = args[0].ToScalar(); |
||||
|
||||
if (b.IsNil()) |
||||
return b; |
||||
|
||||
if (b.Type != DataType.String) |
||||
throw new ScriptRuntimeException("'tostring' must return a string"); |
||||
|
||||
|
||||
return b; |
||||
} |
||||
|
||||
// select (index, ...) |
||||
// ----------------------------------------------------------------------------- |
||||
// If index is a number, returns all arguments after argument number index; a negative number indexes from |
||||
// the end (-1 is the last argument). Otherwise, index must be the string "#", and select returns the total |
||||
// number of extra arguments it received. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue select(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
if (args[0].Type == DataType.String && args[0].String == "#") |
||||
{ |
||||
if (args[args.Count - 1].Type == DataType.Tuple) |
||||
{ |
||||
return DynValue.NewNumber(args.Count - 1 + args[args.Count - 1].Tuple.Length); |
||||
} |
||||
else |
||||
{ |
||||
return DynValue.NewNumber(args.Count - 1); |
||||
} |
||||
} |
||||
|
||||
DynValue v_num = args.AsType(0, "select", DataType.Number, false); |
||||
int num = (int)v_num.Number; |
||||
|
||||
List<DynValue> values = new List<DynValue>(); |
||||
|
||||
if (num > 0) |
||||
{ |
||||
for (int i = num; i < args.Count; i++) |
||||
values.Add(args[i]); |
||||
} |
||||
else if (num < 0) |
||||
{ |
||||
num = args.Count + num; |
||||
|
||||
if (num < 1) |
||||
throw ScriptRuntimeException.BadArgumentIndexOutOfRange("select", 0); |
||||
|
||||
for (int i = num; i < args.Count; i++) |
||||
values.Add(args[i]); |
||||
} |
||||
else |
||||
{ |
||||
throw ScriptRuntimeException.BadArgumentIndexOutOfRange("select", 0); |
||||
} |
||||
|
||||
return DynValue.NewTupleNested(values.ToArray()); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
// tonumber (e [, base]) |
||||
// ---------------------------------------------------------------------------------------------------------------- |
||||
// When called with no base, tonumber tries to convert its argument to a number. If the argument is already |
||||
// a number or a string convertible to a number (see §3.4.2), then tonumber returns this number; otherwise, |
||||
// it returns nil. |
||||
// |
||||
// When called with base, then e should be a string to be interpreted as an integer numeral in that base. |
||||
// The base may be any integer between 2 and 36, inclusive. In bases above 10, the letter 'A' (in either |
||||
// upper or lower case) represents 10, 'B' represents 11, and so forth, with 'Z' representing 35. If the |
||||
// string e is not a valid numeral in the given base, the function returns nil. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue tonumber(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
if (args.Count < 1) throw ScriptRuntimeException.BadArgumentValueExpected(0, "tonumber"); |
||||
|
||||
DynValue e = args[0]; |
||||
DynValue b = args.AsType(1, "tonumber", DataType.Number, true); |
||||
|
||||
if (b.IsNil()) |
||||
{ |
||||
if (e.Type == DataType.Number) |
||||
return e; |
||||
|
||||
if (e.Type != DataType.String) |
||||
return DynValue.Nil; |
||||
|
||||
double d; |
||||
if (double.TryParse(e.String, NumberStyles.Any, CultureInfo.InvariantCulture, out d)) |
||||
{ |
||||
return DynValue.NewNumber(d); |
||||
} |
||||
return DynValue.Nil; |
||||
} |
||||
else |
||||
{ |
||||
//!COMPAT: tonumber supports only 2,8,10 or 16 as base |
||||
//UPDATE: added support for 3-9 base numbers |
||||
DynValue ee; |
||||
|
||||
if (args[0].Type != DataType.Number) |
||||
ee = args.AsType(0, "tonumber", DataType.String, false); |
||||
else |
||||
ee = DynValue.NewString(args[0].Number.ToString(CultureInfo.InvariantCulture)); ; |
||||
|
||||
int bb = (int)b.Number; |
||||
|
||||
uint uiv = 0; |
||||
if (bb == 2 || bb == 8 || bb == 10 || bb == 16) |
||||
{ |
||||
uiv = Convert.ToUInt32(ee.String.Trim(), bb); |
||||
} |
||||
else if (bb < 10 && bb > 2) // Support for 3, 4, 5, 6, 7 and 9 based numbers |
||||
{ |
||||
foreach (char digit in ee.String.Trim()) |
||||
{ |
||||
int value = digit - 48; |
||||
if (value < 0 || value >= bb) |
||||
{ |
||||
throw new ScriptRuntimeException("bad argument #1 to 'tonumber' (invalid character)"); |
||||
} |
||||
|
||||
uiv = (uint)(uiv * bb) + (uint)value; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
throw new ScriptRuntimeException("bad argument #2 to 'tonumber' (base out of range)"); |
||||
} |
||||
|
||||
return DynValue.NewNumber(uiv); |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue print(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(); |
||||
|
||||
for (int i = 0; i < args.Count; i++) |
||||
{ |
||||
if (args[i].IsVoid()) |
||||
break; |
||||
|
||||
if (i != 0) |
||||
sb.Append('\t'); |
||||
|
||||
sb.Append(args.AsStringUsingMeta(executionContext, i, "print")); |
||||
} |
||||
|
||||
executionContext.GetScript().Options.DebugPrint(sb.ToString()); |
||||
|
||||
return DynValue.Nil; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: eed70b0c3561d4512b8cf9426b5814cd |
||||
timeCreated: 1476205335 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,245 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing bit32 Lua functions |
||||
/// </summary> |
||||
[MoonSharpModule(Namespace = "bit32")] |
||||
public class Bit32Module |
||||
{ |
||||
static readonly uint[] MASKS = new uint[] { |
||||
0x1, 0x3, 0x7, 0xF, |
||||
0x1F, 0x3F, 0x7F, 0xFF, |
||||
0x1FF, 0x3FF, 0x7FF, 0xFFF, |
||||
0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, |
||||
0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, |
||||
0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, |
||||
0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, |
||||
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, }; |
||||
|
||||
static uint ToUInt32(DynValue v) |
||||
{ |
||||
double d = v.Number; |
||||
d = Math.IEEERemainder(d, Math.Pow(2.0, 32.0)); |
||||
return (uint)d; |
||||
} |
||||
|
||||
static int ToInt32(DynValue v) |
||||
{ |
||||
double d = v.Number; |
||||
d = Math.IEEERemainder(d, Math.Pow(2.0, 32.0)); |
||||
return (int)d; |
||||
} |
||||
|
||||
static uint NBitMask(int bits) |
||||
{ |
||||
|
||||
if (bits <= 0) |
||||
return 0; |
||||
if (bits >= 32) |
||||
return MASKS[31]; |
||||
|
||||
return MASKS[bits - 1]; |
||||
} |
||||
|
||||
public static uint Bitwise(string funcName, CallbackArguments args, Func<uint, uint, uint> accumFunc) |
||||
{ |
||||
uint accum = ToUInt32(args.AsType(0, funcName, DataType.Number, false)); |
||||
|
||||
for (int i = 1; i < args.Count; i++) |
||||
{ |
||||
uint vv = ToUInt32(args.AsType(i, funcName, DataType.Number, false)); |
||||
accum = accumFunc(accum, vv); |
||||
} |
||||
|
||||
return accum; |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue extract(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v_v = args.AsType(0, "extract", DataType.Number); |
||||
uint v = ToUInt32(v_v); |
||||
|
||||
DynValue v_pos = args.AsType(1, "extract", DataType.Number); |
||||
DynValue v_width = args.AsType(2, "extract", DataType.Number, true); |
||||
|
||||
int pos = (int)v_pos.Number; |
||||
int width = (v_width).IsNilOrNan() ? 1 : (int)v_width.Number; |
||||
|
||||
ValidatePosWidth("extract", 2, pos, width); |
||||
|
||||
uint res = (v >> pos) & NBitMask(width); |
||||
return DynValue.NewNumber(res); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue replace(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v_v = args.AsType(0, "replace", DataType.Number); |
||||
uint v = ToUInt32(v_v); |
||||
|
||||
DynValue v_u = args.AsType(1, "replace", DataType.Number); |
||||
uint u = ToUInt32(v_u); |
||||
DynValue v_pos = args.AsType(2, "replace", DataType.Number); |
||||
DynValue v_width = args.AsType(3, "replace", DataType.Number, true); |
||||
|
||||
int pos = (int)v_pos.Number; |
||||
int width = (v_width).IsNilOrNan() ? 1 : (int)v_width.Number; |
||||
|
||||
ValidatePosWidth("replace", 3, pos, width); |
||||
|
||||
uint mask = NBitMask(width) << pos; |
||||
v = v & (~mask); |
||||
u = u & (mask); |
||||
v = v | u; |
||||
|
||||
return DynValue.NewNumber(v); |
||||
} |
||||
|
||||
|
||||
private static void ValidatePosWidth(string func, int argPos, int pos, int width) |
||||
{ |
||||
if (pos > 31 || (pos + width) > 31) |
||||
throw new ScriptRuntimeException("trying to access non-existent bits"); |
||||
|
||||
if (pos < 0) |
||||
throw new ScriptRuntimeException("bad argument #{1} to '{0}' (field cannot be negative)", func, argPos); |
||||
|
||||
if (width <= 0) |
||||
throw new ScriptRuntimeException("bad argument #{1} to '{0}' (width must be positive)", func, argPos+1); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue arshift(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v_v = args.AsType(0, "arshift", DataType.Number); |
||||
int v = ToInt32(v_v); |
||||
|
||||
DynValue v_a = args.AsType(1, "arshift", DataType.Number); |
||||
|
||||
int a = (int)v_a.Number; |
||||
|
||||
if (a < 0) |
||||
v = v << -a; |
||||
else |
||||
v = v >> a; |
||||
|
||||
return DynValue.NewNumber(v); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue rshift(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v_v = args.AsType(0, "rshift", DataType.Number); |
||||
uint v = ToUInt32(v_v); |
||||
|
||||
DynValue v_a = args.AsType(1, "rshift", DataType.Number); |
||||
|
||||
int a = (int)v_a.Number; |
||||
|
||||
if (a < 0) |
||||
v = v << -a; |
||||
else |
||||
v = v >> a; |
||||
|
||||
return DynValue.NewNumber(v); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue lshift(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v_v = args.AsType(0, "lshift", DataType.Number); |
||||
uint v = ToUInt32(v_v); |
||||
|
||||
DynValue v_a = args.AsType(1, "lshift", DataType.Number); |
||||
|
||||
int a = (int)v_a.Number; |
||||
|
||||
if (a < 0) |
||||
v = v >> -a; |
||||
else |
||||
v = v << a; |
||||
|
||||
return DynValue.NewNumber(v); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue band(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return DynValue.NewNumber(Bitwise("band", args, (x, y) => x & y)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue btest(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return DynValue.NewBoolean(0 != Bitwise("btest", args, (x, y) => x & y)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue bor(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return DynValue.NewNumber(Bitwise("bor", args, (x, y) => x | y)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue bnot(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v_v = args.AsType(0, "bnot", DataType.Number); |
||||
uint v = ToUInt32(v_v); |
||||
return DynValue.NewNumber(~v); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue bxor(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return DynValue.NewNumber(Bitwise("bxor", args, (x, y) => x ^ y)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue lrotate(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v_v = args.AsType(0, "lrotate", DataType.Number); |
||||
uint v = ToUInt32(v_v); |
||||
|
||||
DynValue v_a = args.AsType(1, "lrotate", DataType.Number); |
||||
|
||||
int a = ((int)v_a.Number) % 32; |
||||
|
||||
if (a < 0) |
||||
v = (v >> (-a)) | (v << (32 + a)); |
||||
else |
||||
v = (v << a) | (v >> (32 - a)); |
||||
|
||||
return DynValue.NewNumber(v); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue rrotate(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v_v = args.AsType(0, "rrotate", DataType.Number); |
||||
uint v = ToUInt32(v_v); |
||||
|
||||
DynValue v_a = args.AsType(1, "rrotate", DataType.Number); |
||||
|
||||
int a = ((int)v_a.Number) % 32; |
||||
|
||||
if (a < 0) |
||||
v = (v << (-a)) | (v >> (32 + a)); |
||||
else |
||||
v = (v >> a) | (v << (32 - a)); |
||||
|
||||
return DynValue.NewNumber(v); |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: c71b14e2cd41a4f70a45ea70cab3e2c7 |
||||
timeCreated: 1475786655 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,127 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System.Collections.Generic; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing coroutine Lua functions |
||||
/// </summary> |
||||
[MoonSharpModule(Namespace = "coroutine")] |
||||
public class CoroutineModule |
||||
{ |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue create(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
if (args[0].Type != DataType.Function && args[0].Type != DataType.ClrFunction) |
||||
args.AsType(0, "create", DataType.Function); // this throws |
||||
|
||||
return executionContext.GetScript().CreateCoroutine(args[0]); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue wrap(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
if (args[0].Type != DataType.Function && args[0].Type != DataType.ClrFunction) |
||||
args.AsType(0, "wrap", DataType.Function); // this throws |
||||
|
||||
DynValue v = create(executionContext, args); |
||||
DynValue c = DynValue.NewCallback(__wrap_wrapper); |
||||
c.Callback.AdditionalData = v; |
||||
return c; |
||||
} |
||||
|
||||
public static DynValue __wrap_wrapper(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue handle = (DynValue)executionContext.AdditionalData; |
||||
return handle.Coroutine.Resume(args.GetArray()); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue resume(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue handle = args.AsType(0, "resume", DataType.Thread); |
||||
|
||||
try |
||||
{ |
||||
DynValue ret = handle.Coroutine.Resume(args.GetArray(1)); |
||||
|
||||
List<DynValue> retval = new List<DynValue>(); |
||||
retval.Add(DynValue.True); |
||||
|
||||
if (ret.Type == DataType.Tuple) |
||||
{ |
||||
for (int i = 0; i < ret.Tuple.Length; i++) |
||||
{ |
||||
var v = ret.Tuple[i]; |
||||
|
||||
if ((i == ret.Tuple.Length - 1) && (v.Type == DataType.Tuple)) |
||||
{ |
||||
retval.AddRange(v.Tuple); |
||||
} |
||||
else |
||||
{ |
||||
retval.Add(v); |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
retval.Add(ret); |
||||
} |
||||
|
||||
return DynValue.NewTuple(retval.ToArray()); |
||||
} |
||||
catch (ScriptRuntimeException ex) |
||||
{ |
||||
return DynValue.NewTuple( |
||||
DynValue.False, |
||||
DynValue.NewString(ex.Message)); |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue yield(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return DynValue.NewYieldReq(args.GetArray()); |
||||
} |
||||
|
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue running(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
Coroutine C = executionContext.GetCallingCoroutine(); |
||||
return DynValue.NewTuple(DynValue.NewCoroutine(C), DynValue.NewBoolean(C.State == CoroutineState.Main)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue status(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue handle = args.AsType(0, "status", DataType.Thread); |
||||
Coroutine running = executionContext.GetCallingCoroutine(); |
||||
CoroutineState cs = handle.Coroutine.State; |
||||
|
||||
switch (cs) |
||||
{ |
||||
case CoroutineState.Main: |
||||
case CoroutineState.Running: |
||||
return (handle.Coroutine == running) ? |
||||
DynValue.NewString("running") : |
||||
DynValue.NewString("normal"); |
||||
case CoroutineState.NotStarted: |
||||
case CoroutineState.Suspended: |
||||
case CoroutineState.ForceSuspended: |
||||
return DynValue.NewString("suspended"); |
||||
case CoroutineState.Dead: |
||||
return DynValue.NewString("dead"); |
||||
default: |
||||
throw new InternalErrorException("Unexpected coroutine state {0}", cs); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: c160220c9253a4031baa523b549ea9e4 |
||||
timeCreated: 1475786655 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,343 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System; |
||||
using System.Text; |
||||
using MoonSharp.Interpreter.Debugging; |
||||
using MoonSharp.Interpreter.REPL; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing debug Lua functions. Support for the debug module is partial. |
||||
/// </summary> |
||||
[MoonSharpModule(Namespace = "debug")] |
||||
public class DebugModule |
||||
{ |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue debug(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
Script script = executionContext.GetScript(); |
||||
|
||||
if (script.Options.DebugInput == null) |
||||
throw new ScriptRuntimeException("debug.debug not supported on this platform/configuration"); |
||||
|
||||
ReplInterpreter interpreter = new ReplInterpreter(script) |
||||
{ |
||||
HandleDynamicExprs = false, |
||||
HandleClassicExprsSyntax = true |
||||
}; |
||||
|
||||
while (true) |
||||
{ |
||||
string s = script.Options.DebugInput(interpreter.ClassicPrompt + " "); |
||||
|
||||
try |
||||
{ |
||||
DynValue result = interpreter.Evaluate(s); |
||||
|
||||
if (result != null && result.Type != DataType.Void) |
||||
script.Options.DebugPrint(string.Format("{0}", result)); |
||||
} |
||||
catch (InterpreterException ex) |
||||
{ |
||||
script.Options.DebugPrint(string.Format("{0}", ex.DecoratedMessage ?? ex.Message)); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
script.Options.DebugPrint(string.Format("{0}", ex.Message)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue getuservalue(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v = args[0]; |
||||
|
||||
if (v.Type != DataType.UserData) |
||||
return DynValue.Nil; |
||||
|
||||
return v.UserData.UserValue ?? DynValue.Nil; |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue setuservalue(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v = args.AsType(0, "setuservalue", DataType.UserData, false); |
||||
DynValue t = args.AsType(0, "setuservalue", DataType.Table, true); |
||||
|
||||
return v.UserData.UserValue = t; |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue getregistry(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return DynValue.NewTable(executionContext.GetScript().Registry); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue getmetatable(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v = args[0]; |
||||
Script S = executionContext.GetScript(); |
||||
|
||||
if (v.Type.CanHaveTypeMetatables()) |
||||
return DynValue.NewTable(S.GetTypeMetatable(v.Type)); |
||||
else if (v.Type == DataType.Table) |
||||
return DynValue.NewTable(v.Table.MetaTable); |
||||
else |
||||
return DynValue.Nil; |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue setmetatable(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v = args[0]; |
||||
DynValue t = args.AsType(1, "setmetatable", DataType.Table, true); |
||||
Table m = (t.IsNil()) ? null : t.Table; |
||||
Script S = executionContext.GetScript(); |
||||
|
||||
if (v.Type.CanHaveTypeMetatables()) |
||||
S.SetTypeMetatable(v.Type, m); |
||||
else if (v.Type == DataType.Table) |
||||
v.Table.MetaTable = m; |
||||
else |
||||
throw new ScriptRuntimeException("cannot debug.setmetatable on type {0}", v.Type.ToErrorTypeString()); |
||||
|
||||
return v; |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue getupvalue(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
var index = (int)args.AsType(1, "getupvalue", DataType.Number, false).Number - 1; |
||||
|
||||
if (args[0].Type == DataType.ClrFunction) |
||||
return DynValue.Nil; |
||||
|
||||
var fn = args.AsType(0, "getupvalue", DataType.Function, false).Function; |
||||
|
||||
var closure = fn.ClosureContext; |
||||
|
||||
if (index < 0 || index >= closure.Count) |
||||
return DynValue.Nil; |
||||
|
||||
return DynValue.NewTuple( |
||||
DynValue.NewString(closure.Symbols[index]), |
||||
closure[index]); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue upvalueid(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
var index = (int)args.AsType(1, "getupvalue", DataType.Number, false).Number - 1; |
||||
|
||||
if (args[0].Type == DataType.ClrFunction) |
||||
return DynValue.Nil; |
||||
|
||||
var fn = args.AsType(0, "getupvalue", DataType.Function, false).Function; |
||||
|
||||
var closure = fn.ClosureContext; |
||||
|
||||
if (index < 0 || index >= closure.Count) |
||||
return DynValue.Nil; |
||||
|
||||
return DynValue.NewNumber(closure[index].ReferenceID); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue setupvalue(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
var index = (int)args.AsType(1, "setupvalue", DataType.Number, false).Number - 1; |
||||
|
||||
if (args[0].Type == DataType.ClrFunction) |
||||
return DynValue.Nil; |
||||
|
||||
var fn = args.AsType(0, "setupvalue", DataType.Function, false).Function; |
||||
|
||||
var closure = fn.ClosureContext; |
||||
|
||||
if (index < 0 || index >= closure.Count) |
||||
return DynValue.Nil; |
||||
|
||||
closure[index].Assign(args[2]); |
||||
|
||||
return DynValue.NewString(closure.Symbols[index]); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue upvaluejoin(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue f1 = args.AsType(0, "upvaluejoin", DataType.Function, false); |
||||
DynValue f2 = args.AsType(2, "upvaluejoin", DataType.Function, false); |
||||
int n1 = args.AsInt(1, "upvaluejoin") - 1; |
||||
int n2 = args.AsInt(3, "upvaluejoin") - 1; |
||||
|
||||
Closure c1 = f1.Function; |
||||
Closure c2 = f2.Function; |
||||
|
||||
if (n1 < 0 || n1 >= c1.ClosureContext.Count) |
||||
throw ScriptRuntimeException.BadArgument(1, "upvaluejoin", "invalid upvalue index"); |
||||
|
||||
if (n2 < 0 || n2 >= c2.ClosureContext.Count) |
||||
throw ScriptRuntimeException.BadArgument(3, "upvaluejoin", "invalid upvalue index"); |
||||
|
||||
c2.ClosureContext[n2] = c1.ClosureContext[n1]; |
||||
|
||||
return DynValue.Void; |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue traceback(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(); |
||||
|
||||
DynValue vmessage = args[0]; |
||||
DynValue vlevel = args[1]; |
||||
|
||||
double defaultSkip = 1.0; |
||||
|
||||
Coroutine cor = executionContext.GetCallingCoroutine(); |
||||
|
||||
if (vmessage.Type == DataType.Thread) |
||||
{ |
||||
cor = vmessage.Coroutine; |
||||
vmessage = args[1]; |
||||
vlevel = args[2]; |
||||
defaultSkip = 0.0; |
||||
} |
||||
|
||||
if (vmessage.IsNotNil() && vmessage.Type != DataType.String && vmessage.Type != DataType.Number) |
||||
{ |
||||
return vmessage; |
||||
} |
||||
|
||||
string message = vmessage.CastToString(); |
||||
|
||||
int skip = (int)((vlevel.CastToNumber()) ?? defaultSkip); |
||||
|
||||
WatchItem[] stacktrace = cor.GetStackTrace(Math.Max(0, skip)); |
||||
|
||||
if (message != null) |
||||
sb.AppendLine(message); |
||||
|
||||
sb.AppendLine("stack traceback:"); |
||||
|
||||
foreach (WatchItem wi in stacktrace) |
||||
{ |
||||
string name; |
||||
|
||||
if (wi.Name == null) |
||||
if (wi.RetAddress < 0) |
||||
name = "main chunk"; |
||||
else |
||||
name = "?"; |
||||
else |
||||
name = "function '" + wi.Name + "'"; |
||||
|
||||
string loc = wi.Location != null ? wi.Location.FormatLocation(executionContext.GetScript()) : "[clr]"; |
||||
sb.AppendFormat("\t{0}: in {1}\n", loc, name); |
||||
} |
||||
|
||||
return DynValue.NewString(sb); |
||||
} |
||||
|
||||
//[MoonSharpModuleMethod] |
||||
//public static DynValue getlocal(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
//{ |
||||
// Coroutine c; |
||||
// int funcIdx; |
||||
// Closure f; |
||||
// int nextArg = ParseComplexArgs("getlocal", executionContext, args, out c, out f, out funcIdx); |
||||
|
||||
// int localIdx = args.AsInt(nextArg, "getlocal"); |
||||
|
||||
// if (f != null) |
||||
// { |
||||
|
||||
// } |
||||
// else |
||||
// { |
||||
|
||||
// } |
||||
|
||||
|
||||
|
||||
//} |
||||
|
||||
//private static int ParseComplexArgs(string funcname, ScriptExecutionContext executionContext, CallbackArguments args, out Coroutine c, out Closure f, out int funcIdx) |
||||
//{ |
||||
// DynValue arg1 = args[0]; |
||||
// int argbase = 0; |
||||
// c = null; |
||||
|
||||
// if (arg1.Type == DataType.Thread) |
||||
// { |
||||
// c = arg1.Coroutine; |
||||
// argbase = 1; |
||||
// } |
||||
|
||||
// if (args[argbase].Type == DataType.Number) |
||||
// { |
||||
// funcIdx = (int)args[argbase].Number; |
||||
// f = null; |
||||
// } |
||||
// else |
||||
// { |
||||
// funcIdx = -1; |
||||
// f = args.AsType(argbase, funcname, DataType.Function, false).Function; |
||||
// } |
||||
|
||||
// return argbase + 1; |
||||
//} |
||||
|
||||
|
||||
//[MoonSharpMethod] |
||||
//public static DynValue getinfo(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
//{ |
||||
// Coroutine cor = executionContext.GetCallingCoroutine(); |
||||
// int vfArgIdx = 0; |
||||
|
||||
// if (args[0].Type == DataType.Thread) |
||||
// cor = args[0].Coroutine; |
||||
|
||||
// DynValue vf = args[vfArgIdx+0]; |
||||
// DynValue vwhat = args[vfArgIdx+1]; |
||||
|
||||
// args.AsType(vfArgIdx + 1, "getinfo", DataType.String, true); |
||||
|
||||
// string what = vwhat.CastToString() ?? "nfSlu"; |
||||
|
||||
// DynValue vt = DynValue.NewTable(executionContext.GetScript()); |
||||
// Table t = vt.Table; |
||||
|
||||
// if (vf.Type == DataType.Function) |
||||
// { |
||||
// Closure f = vf.Function; |
||||
// executionContext.GetInfoForFunction |
||||
// } |
||||
// else if (vf.Type == DataType.ClrFunction) |
||||
// { |
||||
|
||||
// } |
||||
// else if (vf.Type == DataType.Number || vf.Type == DataType.String) |
||||
// { |
||||
|
||||
// } |
||||
// else |
||||
// { |
||||
// args.AsType(vfArgIdx + 0, "getinfo", DataType.Number, true); |
||||
// } |
||||
|
||||
// return vt; |
||||
|
||||
|
||||
//} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9b3743855cdb543c88b2320c61f28424 |
||||
timeCreated: 1475786655 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,71 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing dynamic expression evaluations at runtime (a MoonSharp addition). |
||||
/// </summary> |
||||
[MoonSharpModule(Namespace = "dynamic")] |
||||
public class DynamicModule |
||||
{ |
||||
private class DynamicExprWrapper |
||||
{ |
||||
public DynamicExpression Expr; |
||||
} |
||||
|
||||
public static void MoonSharpInit(Table globalTable, Table stringTable) |
||||
{ |
||||
UserData.RegisterType<DynamicExprWrapper>(InteropAccessMode.HideMembers); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue eval(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
try |
||||
{ |
||||
if (args[0].Type == DataType.UserData) |
||||
{ |
||||
UserData ud = args[0].UserData; |
||||
if (ud.Object is DynamicExprWrapper) |
||||
{ |
||||
return ((DynamicExprWrapper)ud.Object).Expr.Evaluate(executionContext); |
||||
} |
||||
else |
||||
{ |
||||
throw ScriptRuntimeException.BadArgument(0, "dynamic.eval", "A userdata was passed, but was not a previously prepared expression."); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
DynValue vs = args.AsType(0, "dynamic.eval", DataType.String, false); |
||||
DynamicExpression expr = executionContext.GetScript().CreateDynamicExpression(vs.String); |
||||
return expr.Evaluate(executionContext); |
||||
} |
||||
} |
||||
catch (SyntaxErrorException ex) |
||||
{ |
||||
throw new ScriptRuntimeException(ex); |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue prepare(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
try |
||||
{ |
||||
DynValue vs = args.AsType(0, "dynamic.prepare", DataType.String, false); |
||||
DynamicExpression expr = executionContext.GetScript().CreateDynamicExpression(vs.String); |
||||
return UserData.Create(new DynamicExprWrapper() { Expr = expr }); |
||||
} |
||||
catch (SyntaxErrorException ex) |
||||
{ |
||||
throw new ScriptRuntimeException(ex); |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a82c0d3fa46554bd5857d852f9bd2812 |
||||
timeCreated: 1475786655 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,132 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System.Collections.Generic; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing error handling Lua functions (pcall and xpcall) |
||||
/// </summary> |
||||
[MoonSharpModule] |
||||
public class ErrorHandlingModule |
||||
{ |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue pcall(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return SetErrorHandlerStrategy("pcall", executionContext, args, null); |
||||
} |
||||
|
||||
|
||||
private static DynValue SetErrorHandlerStrategy(string funcName, |
||||
ScriptExecutionContext executionContext, |
||||
CallbackArguments args, |
||||
DynValue handlerBeforeUnwind) |
||||
{ |
||||
DynValue v = args[0]; |
||||
DynValue[] a = new DynValue[args.Count - 1]; |
||||
|
||||
for (int i = 1; i < args.Count; i++) |
||||
a[i - 1] = args[i]; |
||||
|
||||
if (args[0].Type == DataType.ClrFunction) |
||||
{ |
||||
try |
||||
{ |
||||
DynValue ret = args[0].Callback.Invoke(executionContext, a); |
||||
if (ret.Type == DataType.TailCallRequest) |
||||
{ |
||||
if (ret.TailCallData.Continuation != null || ret.TailCallData.ErrorHandler != null) |
||||
throw new ScriptRuntimeException("the function passed to {0} cannot be called directly by {0}. wrap in a script function instead.", funcName); |
||||
|
||||
return DynValue.NewTailCallReq(new TailCallData() |
||||
{ |
||||
Args = ret.TailCallData.Args, |
||||
Function = ret.TailCallData.Function, |
||||
Continuation = new CallbackFunction(pcall_continuation, funcName), |
||||
ErrorHandler = new CallbackFunction(pcall_onerror, funcName), |
||||
ErrorHandlerBeforeUnwind = handlerBeforeUnwind |
||||
}); |
||||
} |
||||
else if (ret.Type == DataType.YieldRequest) |
||||
{ |
||||
throw new ScriptRuntimeException("the function passed to {0} cannot be called directly by {0}. wrap in a script function instead.", funcName); |
||||
} |
||||
else |
||||
{ |
||||
return DynValue.NewTupleNested(DynValue.True, ret); |
||||
} |
||||
} |
||||
catch (ScriptRuntimeException ex) |
||||
{ |
||||
executionContext.PerformMessageDecorationBeforeUnwind(handlerBeforeUnwind, ex); |
||||
return DynValue.NewTupleNested(DynValue.False, DynValue.NewString(ex.DecoratedMessage)); |
||||
} |
||||
} |
||||
else if (args[0].Type != DataType.Function) |
||||
{ |
||||
return DynValue.NewTupleNested(DynValue.False, DynValue.NewString("attempt to " + funcName + " a non-function")); |
||||
} |
||||
else |
||||
{ |
||||
return DynValue.NewTailCallReq(new TailCallData() |
||||
{ |
||||
Args = a, |
||||
Function = v, |
||||
Continuation = new CallbackFunction(pcall_continuation, funcName), |
||||
ErrorHandler = new CallbackFunction(pcall_onerror, funcName), |
||||
ErrorHandlerBeforeUnwind = handlerBeforeUnwind |
||||
}); |
||||
} |
||||
} |
||||
|
||||
private static DynValue MakeReturnTuple(bool retstatus, CallbackArguments args) |
||||
{ |
||||
DynValue[] rets = new DynValue[args.Count + 1]; |
||||
|
||||
for (int i = 0; i < args.Count; i++) |
||||
rets[i + 1] = args[i]; |
||||
|
||||
rets[0] = DynValue.NewBoolean(retstatus); |
||||
|
||||
return DynValue.NewTuple(rets); |
||||
} |
||||
|
||||
|
||||
public static DynValue pcall_continuation(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return MakeReturnTuple(true, args); |
||||
} |
||||
|
||||
public static DynValue pcall_onerror(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return MakeReturnTuple(false, args); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue xpcall(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
List<DynValue> a = new List<DynValue>(); |
||||
|
||||
for (int i = 0; i < args.Count; i++) |
||||
{ |
||||
if (i != 1) |
||||
a.Add(args[i]); |
||||
} |
||||
|
||||
DynValue handler = null; |
||||
if (args[1].Type == DataType.Function || args[1].Type == DataType.ClrFunction) |
||||
{ |
||||
handler = args[1]; |
||||
} |
||||
else if (args[1].Type != DataType.Nil) |
||||
{ |
||||
args.AsType(1, "xpcall", DataType.Function, false); |
||||
} |
||||
|
||||
return SetErrorHandlerStrategy("xpcall", executionContext, new CallbackArguments(a, false), handler); |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 25a48a75173cc44959f158f5aed1fc00 |
||||
timeCreated: 1475786653 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d1f6f1bb70deb40239486ed094a36ea2 |
||||
folderAsset: yes |
||||
timeCreated: 1475786652 |
||||
licenseType: Pro |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,53 @@
|
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib.IO |
||||
{ |
||||
class BinaryEncoding : Encoding |
||||
{ |
||||
public BinaryEncoding() |
||||
: base() |
||||
{ |
||||
|
||||
} |
||||
|
||||
public override int GetByteCount(char[] chars, int index, int count) |
||||
{ |
||||
return count; |
||||
} |
||||
|
||||
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) |
||||
{ |
||||
for (int i = 0; i < charCount; i++) |
||||
{ |
||||
bytes[byteIndex + i] = (byte)((int)chars[charIndex + i]); |
||||
} |
||||
|
||||
return charCount; |
||||
} |
||||
|
||||
public override int GetCharCount(byte[] bytes, int index, int count) |
||||
{ |
||||
return count; |
||||
} |
||||
|
||||
public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) |
||||
{ |
||||
for (int i = 0; i < byteCount; i++) |
||||
{ |
||||
chars[charIndex + i] = (char)((int)bytes[byteIndex + i]); |
||||
} |
||||
|
||||
return byteCount; |
||||
} |
||||
|
||||
public override int GetMaxByteCount(int charCount) |
||||
{ |
||||
return charCount; |
||||
} |
||||
|
||||
public override int GetMaxCharCount(int byteCount) |
||||
{ |
||||
return byteCount; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 675a461a252db43b0a24db05a6dbeabc |
||||
timeCreated: 1475786654 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,21 @@
|
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib.IO |
||||
{ |
||||
/// <summary> |
||||
/// Abstract class implementing a file Lua userdata. Methods are meant to be called by Lua code. |
||||
/// </summary> |
||||
internal class FileUserData : StreamFileUserDataBase |
||||
{ |
||||
public FileUserData(Script script, string filename, Encoding encoding, string mode) |
||||
{ |
||||
Stream stream = Script.GlobalOptions.Platform.IO_OpenFile(script, filename, encoding, mode); |
||||
|
||||
StreamReader reader = (stream.CanRead) ? new StreamReader(stream, encoding) : null; |
||||
StreamWriter writer = (stream.CanWrite) ? new StreamWriter(stream, encoding) : null; |
||||
|
||||
base.Initialize(stream, reader, writer); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: af797d1c8ef1a415ca0a84f11c04a6f5 |
||||
timeCreated: 1475786655 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,225 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using MoonSharp.Interpreter.Compatibility; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib.IO |
||||
{ |
||||
/// <summary> |
||||
/// Abstract class implementing a file Lua userdata. Methods are meant to be called by Lua code. |
||||
/// </summary> |
||||
internal abstract class FileUserDataBase : RefIdObject |
||||
{ |
||||
public DynValue lines(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
List<DynValue> readLines = new List<DynValue>(); |
||||
|
||||
DynValue readValue = null; |
||||
|
||||
do |
||||
{ |
||||
readValue = read(executionContext, args); |
||||
readLines.Add(readValue); |
||||
|
||||
} while (readValue.IsNotNil()); |
||||
|
||||
return DynValue.FromObject(executionContext.GetScript(), readLines.Select(s => s)); |
||||
} |
||||
|
||||
public DynValue read(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
if (args.Count == 0) |
||||
{ |
||||
string str = ReadLine(); |
||||
|
||||
if (str == null) |
||||
return DynValue.Nil; |
||||
|
||||
str = str.TrimEnd('\n', '\r'); |
||||
return DynValue.NewString(str); |
||||
} |
||||
else |
||||
{ |
||||
List<DynValue> rets = new List<DynValue>(); |
||||
|
||||
for (int i = 0; i < args.Count; i++) |
||||
{ |
||||
DynValue v; |
||||
|
||||
if (args[i].Type == DataType.Number) |
||||
{ |
||||
if (Eof()) |
||||
return DynValue.Nil; |
||||
|
||||
int howmany = (int)args[i].Number; |
||||
|
||||
string str = ReadBuffer(howmany); |
||||
v = DynValue.NewString(str); |
||||
} |
||||
else |
||||
{ |
||||
string opt = args.AsType(i, "read", DataType.String, false).String; |
||||
|
||||
if (Eof()) |
||||
{ |
||||
v = opt.StartsWith("*a") ? DynValue.NewString("") : DynValue.Nil; |
||||
} |
||||
else if (opt.StartsWith("*n")) |
||||
{ |
||||
double? d = ReadNumber(); |
||||
|
||||
if (d.HasValue) |
||||
v = DynValue.NewNumber(d.Value); |
||||
else |
||||
v = DynValue.Nil; |
||||
} |
||||
else if (opt.StartsWith("*a")) |
||||
{ |
||||
string str = ReadToEnd(); |
||||
v = DynValue.NewString(str); |
||||
} |
||||
else if (opt.StartsWith("*l")) |
||||
{ |
||||
string str = ReadLine(); |
||||
str = str.TrimEnd('\n', '\r'); |
||||
v = DynValue.NewString(str); |
||||
} |
||||
else if (opt.StartsWith("*L")) |
||||
{ |
||||
string str = ReadLine(); |
||||
|
||||
str = str.TrimEnd('\n', '\r'); |
||||
str += "\n"; |
||||
|
||||
v = DynValue.NewString(str); |
||||
} |
||||
else |
||||
{ |
||||
throw ScriptRuntimeException.BadArgument(i, "read", "invalid option"); |
||||
} |
||||
} |
||||
|
||||
rets.Add(v); |
||||
} |
||||
|
||||
return DynValue.NewTuple(rets.ToArray()); |
||||
} |
||||
} |
||||
|
||||
|
||||
public DynValue write(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
try |
||||
{ |
||||
for (int i = 0; i < args.Count; i++) |
||||
{ |
||||
//string str = args.AsStringUsingMeta(executionContext, i, "file:write"); |
||||
string str = args.AsType(i, "write", DataType.String, false).String; |
||||
Write(str); |
||||
} |
||||
|
||||
return UserData.Create(this); |
||||
} |
||||
catch (ScriptRuntimeException) |
||||
{ |
||||
throw; |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.Message)); |
||||
} |
||||
} |
||||
|
||||
public DynValue close(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
try |
||||
{ |
||||
string msg = Close(); |
||||
if (msg == null) |
||||
return DynValue.True; |
||||
else |
||||
return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(msg)); |
||||
} |
||||
catch (ScriptRuntimeException) |
||||
{ |
||||
throw; |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.Message)); |
||||
} |
||||
} |
||||
|
||||
|
||||
double? ReadNumber() |
||||
{ |
||||
string chr = ""; |
||||
|
||||
while (!Eof()) |
||||
{ |
||||
char c = Peek(); |
||||
if (char.IsWhiteSpace(c)) |
||||
{ |
||||
ReadBuffer(1); |
||||
} |
||||
else if (IsNumericChar(c, chr)) |
||||
{ |
||||
ReadBuffer(1); |
||||
chr += c; |
||||
} |
||||
else break; |
||||
} |
||||
|
||||
double d; |
||||
|
||||
if (double.TryParse(chr, out d)) |
||||
{ |
||||
return d; |
||||
} |
||||
else |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
private bool IsNumericChar(char c, string numAsFar) |
||||
{ |
||||
if (char.IsDigit(c)) |
||||
return true; |
||||
|
||||
if (c == '-') |
||||
return numAsFar.Length == 0; |
||||
|
||||
if (c == '.') |
||||
return !Framework.Do.StringContainsChar(numAsFar, '.'); |
||||
|
||||
if (c == 'E' || c == 'e') |
||||
return !(Framework.Do.StringContainsChar(numAsFar, 'E') || Framework.Do.StringContainsChar(numAsFar, 'e')); |
||||
|
||||
return false; |
||||
} |
||||
|
||||
protected abstract bool Eof(); |
||||
protected abstract string ReadLine(); |
||||
protected abstract string ReadBuffer(int p); |
||||
protected abstract string ReadToEnd(); |
||||
protected abstract char Peek(); |
||||
protected abstract void Write(string value); |
||||
|
||||
|
||||
protected internal abstract bool isopen(); |
||||
protected abstract string Close(); |
||||
|
||||
public abstract bool flush(); |
||||
public abstract long seek(string whence, long offset); |
||||
public abstract bool setvbuf(string mode); |
||||
|
||||
public override string ToString() |
||||
{ |
||||
if (isopen()) |
||||
return string.Format("file ({0:X8})", base.ReferenceID); |
||||
else |
||||
return "file (closed)"; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1e0c682730fd243eca755897f724ff91 |
||||
timeCreated: 1476432878 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,31 @@
|
||||
using System.IO; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib.IO |
||||
{ |
||||
/// <summary> |
||||
/// Abstract class implementing an unclosable file Lua userdata. Methods are meant to be called by Lua code. |
||||
/// </summary> |
||||
internal class StandardIOFileUserDataBase : StreamFileUserDataBase |
||||
{ |
||||
protected override string Close() |
||||
{ |
||||
return ("cannot close standard file"); |
||||
} |
||||
|
||||
public static StandardIOFileUserDataBase CreateInputStream(Stream stream) |
||||
{ |
||||
var f = new StandardIOFileUserDataBase(); |
||||
f.Initialize(stream, new StreamReader(stream), null); |
||||
return f; |
||||
} |
||||
|
||||
public static StandardIOFileUserDataBase CreateOutputStream(Stream stream) |
||||
{ |
||||
var f = new StandardIOFileUserDataBase(); |
||||
f.Initialize(stream, null, new StreamWriter(stream)); |
||||
return f; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: c1fccf4c28e9a4667a0a6984cb2c736d |
||||
timeCreated: 1475786655 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,140 @@
|
||||
using System.IO; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib.IO |
||||
{ |
||||
/// <summary> |
||||
/// Abstract class implementing a file Lua userdata. Methods are meant to be called by Lua code. |
||||
/// </summary> |
||||
internal abstract class StreamFileUserDataBase : FileUserDataBase |
||||
{ |
||||
protected Stream m_Stream; |
||||
protected StreamReader m_Reader; |
||||
protected StreamWriter m_Writer; |
||||
protected bool m_Closed = false; |
||||
|
||||
|
||||
protected void Initialize(Stream stream, StreamReader reader, StreamWriter writer) |
||||
{ |
||||
m_Stream = stream; |
||||
m_Reader = reader; |
||||
m_Writer = writer; |
||||
} |
||||
|
||||
|
||||
private void CheckFileIsNotClosed() |
||||
{ |
||||
if (m_Closed) |
||||
throw new ScriptRuntimeException("attempt to use a closed file"); |
||||
} |
||||
|
||||
|
||||
protected override bool Eof() |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
|
||||
if (m_Reader != null) |
||||
return m_Reader.EndOfStream; |
||||
else |
||||
return false; |
||||
} |
||||
|
||||
protected override string ReadLine() |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
return m_Reader.ReadLine(); |
||||
} |
||||
|
||||
protected override string ReadToEnd() |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
return m_Reader.ReadToEnd(); |
||||
} |
||||
|
||||
protected override string ReadBuffer(int p) |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
char[] buffer = new char[p]; |
||||
int length = m_Reader.ReadBlock(buffer, 0, p); |
||||
return new string(buffer, 0, length); |
||||
} |
||||
|
||||
protected override char Peek() |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
return (char)m_Reader.Peek(); |
||||
} |
||||
|
||||
protected override void Write(string value) |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
m_Writer.Write(value); |
||||
} |
||||
|
||||
protected override string Close() |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
|
||||
if (m_Writer != null) |
||||
m_Writer.Dispose(); |
||||
|
||||
if (m_Reader != null) |
||||
m_Reader.Dispose(); |
||||
|
||||
m_Stream.Dispose(); |
||||
|
||||
m_Closed = true; |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public override bool flush() |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
|
||||
if (m_Writer != null) |
||||
m_Writer.Flush(); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
public override long seek(string whence, long offset) |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
if (whence != null) |
||||
{ |
||||
if (whence == "set") |
||||
{ |
||||
m_Stream.Seek(offset, SeekOrigin.Begin); |
||||
} |
||||
else if (whence == "cur") |
||||
{ |
||||
m_Stream.Seek(offset, SeekOrigin.Current); |
||||
} |
||||
else if (whence == "end") |
||||
{ |
||||
m_Stream.Seek(offset, SeekOrigin.End); |
||||
} |
||||
else |
||||
{ |
||||
throw ScriptRuntimeException.BadArgument(0, "seek", "invalid option '" + whence + "'"); |
||||
} |
||||
} |
||||
|
||||
return m_Stream.Position; |
||||
} |
||||
|
||||
public override bool setvbuf(string mode) |
||||
{ |
||||
CheckFileIsNotClosed(); |
||||
if (m_Writer != null) |
||||
m_Writer.AutoFlush = (mode == "no" || mode == "line"); |
||||
return true; |
||||
} |
||||
|
||||
protected internal override bool isopen() |
||||
{ |
||||
return !m_Closed; |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 07ffca2aa60ad4febb46043b8eb2b531 |
||||
timeCreated: 1475786653 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,309 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using MoonSharp.Interpreter.Compatibility; |
||||
using MoonSharp.Interpreter.CoreLib.IO; |
||||
using MoonSharp.Interpreter.Platforms; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing io Lua functions. Proper support requires a compatible IPlatformAccessor |
||||
/// </summary> |
||||
[MoonSharpModule(Namespace = "io")] |
||||
public class IoModule |
||||
{ |
||||
public static void MoonSharpInit(Table globalTable, Table ioTable) |
||||
{ |
||||
UserData.RegisterType<FileUserDataBase>(InteropAccessMode.Default, "file"); |
||||
|
||||
Table meta = new Table(ioTable.OwnerScript); |
||||
DynValue __index = DynValue.NewCallback(new CallbackFunction(__index_callback, "__index_callback")); |
||||
meta.Set("__index", __index); |
||||
ioTable.MetaTable = meta; |
||||
|
||||
SetStandardFile(globalTable.OwnerScript, StandardFileType.StdIn, globalTable.OwnerScript.Options.Stdin); |
||||
SetStandardFile(globalTable.OwnerScript, StandardFileType.StdOut, globalTable.OwnerScript.Options.Stdout); |
||||
SetStandardFile(globalTable.OwnerScript, StandardFileType.StdErr, globalTable.OwnerScript.Options.Stderr); |
||||
} |
||||
|
||||
private static DynValue __index_callback(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
string name = args[1].CastToString(); |
||||
|
||||
if (name == "stdin") |
||||
return GetStandardFile(executionContext.GetScript(), StandardFileType.StdIn); |
||||
else if (name == "stdout") |
||||
return GetStandardFile(executionContext.GetScript(), StandardFileType.StdOut); |
||||
else if (name == "stderr") |
||||
return GetStandardFile(executionContext.GetScript(), StandardFileType.StdErr); |
||||
else |
||||
return DynValue.Nil; |
||||
} |
||||
|
||||
private static DynValue GetStandardFile(Script S, StandardFileType file) |
||||
{ |
||||
Table R = S.Registry; |
||||
|
||||
DynValue ff = R.Get("853BEAAF298648839E2C99D005E1DF94_STD_" + file.ToString()); |
||||
return ff; |
||||
} |
||||
|
||||
private static void SetStandardFile(Script S, StandardFileType file, Stream optionsStream) |
||||
{ |
||||
Table R = S.Registry; |
||||
|
||||
optionsStream = optionsStream ?? Script.GlobalOptions.Platform.IO_GetStandardStream(file); |
||||
|
||||
FileUserDataBase udb = null; |
||||
|
||||
if (file == StandardFileType.StdIn) |
||||
udb = StandardIOFileUserDataBase.CreateInputStream(optionsStream); |
||||
else |
||||
udb = StandardIOFileUserDataBase.CreateOutputStream(optionsStream); |
||||
|
||||
R.Set("853BEAAF298648839E2C99D005E1DF94_STD_" + file.ToString(), UserData.Create(udb)); |
||||
} |
||||
|
||||
|
||||
static FileUserDataBase GetDefaultFile(ScriptExecutionContext executionContext, StandardFileType file) |
||||
{ |
||||
Table R = executionContext.GetScript().Registry; |
||||
|
||||
DynValue ff = R.Get("853BEAAF298648839E2C99D005E1DF94_" + file.ToString()); |
||||
|
||||
if (ff.IsNil()) |
||||
{ |
||||
ff = GetStandardFile(executionContext.GetScript(), file); |
||||
} |
||||
|
||||
return ff.CheckUserDataType<FileUserDataBase>("getdefaultfile(" + file.ToString() + ")"); |
||||
} |
||||
|
||||
|
||||
static void SetDefaultFile(ScriptExecutionContext executionContext, StandardFileType file, FileUserDataBase fileHandle) |
||||
{ |
||||
SetDefaultFile(executionContext.GetScript(), file, fileHandle); |
||||
} |
||||
|
||||
internal static void SetDefaultFile(Script script, StandardFileType file, FileUserDataBase fileHandle) |
||||
{ |
||||
Table R = script.Registry; |
||||
R.Set("853BEAAF298648839E2C99D005E1DF94_" + file.ToString(), UserData.Create(fileHandle)); |
||||
} |
||||
|
||||
public static void SetDefaultFile(Script script, StandardFileType file, Stream stream) |
||||
{ |
||||
if (file == StandardFileType.StdIn) |
||||
SetDefaultFile(script, file, StandardIOFileUserDataBase.CreateInputStream(stream)); |
||||
else |
||||
SetDefaultFile(script, file, StandardIOFileUserDataBase.CreateOutputStream(stream)); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue close(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
FileUserDataBase outp = args.AsUserData<FileUserDataBase>(0, "close", true) ?? GetDefaultFile(executionContext, StandardFileType.StdOut); |
||||
return outp.close(executionContext, args); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue flush(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
FileUserDataBase outp = args.AsUserData<FileUserDataBase>(0, "close", true) ?? GetDefaultFile(executionContext, StandardFileType.StdOut); |
||||
outp.flush(); |
||||
return DynValue.True; |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue input(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return HandleDefaultStreamSetter(executionContext, args, StandardFileType.StdIn); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue output(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return HandleDefaultStreamSetter(executionContext, args, StandardFileType.StdOut); |
||||
} |
||||
|
||||
private static DynValue HandleDefaultStreamSetter(ScriptExecutionContext executionContext, CallbackArguments args, StandardFileType defaultFiles) |
||||
{ |
||||
if (args.Count == 0 || args[0].IsNil()) |
||||
{ |
||||
var file = GetDefaultFile(executionContext, defaultFiles); |
||||
return UserData.Create(file); |
||||
} |
||||
|
||||
FileUserDataBase inp = null; |
||||
|
||||
if (args[0].Type == DataType.String || args[0].Type == DataType.Number) |
||||
{ |
||||
string fileName = args[0].CastToString(); |
||||
inp = Open(executionContext, fileName, GetUTF8Encoding(), defaultFiles == StandardFileType.StdIn ? "r" : "w"); |
||||
} |
||||
else |
||||
{ |
||||
inp = args.AsUserData<FileUserDataBase>(0, defaultFiles == StandardFileType.StdIn ? "input" : "output", false); |
||||
} |
||||
|
||||
SetDefaultFile(executionContext, defaultFiles, inp); |
||||
|
||||
return UserData.Create(inp); |
||||
} |
||||
|
||||
private static Encoding GetUTF8Encoding() |
||||
{ |
||||
return new System.Text.UTF8Encoding(false); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue lines(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
string filename = args.AsType(0, "lines", DataType.String, false).String; |
||||
|
||||
try |
||||
{ |
||||
List<DynValue> readLines = new List<DynValue>(); |
||||
|
||||
using (var stream = Script.GlobalOptions.Platform.IO_OpenFile(executionContext.GetScript(), filename, null, "r")) |
||||
{ |
||||
using (var reader = new System.IO.StreamReader(stream)) |
||||
{ |
||||
while (!reader.EndOfStream) |
||||
{ |
||||
string line = reader.ReadLine(); |
||||
readLines.Add(DynValue.NewString(line)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
readLines.Add(DynValue.Nil); |
||||
|
||||
return DynValue.FromObject(executionContext.GetScript(), readLines.Select(s => s)); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
throw new ScriptRuntimeException(IoExceptionToLuaMessage(ex, filename)); |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue open(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
string filename = args.AsType(0, "open", DataType.String, false).String; |
||||
DynValue vmode = args.AsType(1, "open", DataType.String, true); |
||||
DynValue vencoding = args.AsType(2, "open", DataType.String, true); |
||||
|
||||
string mode = vmode.IsNil() ? "r" : vmode.String; |
||||
|
||||
string invalidChars = mode.Replace("+", "") |
||||
.Replace("r", "") |
||||
.Replace("a", "") |
||||
.Replace("w", "") |
||||
.Replace("b", "") |
||||
.Replace("t", ""); |
||||
|
||||
if (invalidChars.Length > 0) |
||||
throw ScriptRuntimeException.BadArgument(1, "open", "invalid mode"); |
||||
|
||||
|
||||
try |
||||
{ |
||||
string encoding = vencoding.IsNil() ? null : vencoding.String; |
||||
|
||||
// list of codes: http://msdn.microsoft.com/en-us/library/vstudio/system.text.encoding%28v=vs.90%29.aspx. |
||||
// In addition, "binary" is available. |
||||
Encoding e = null; |
||||
bool isBinary = Framework.Do.StringContainsChar(mode, 'b'); |
||||
|
||||
if (encoding == "binary") |
||||
{ |
||||
isBinary = true; |
||||
e = new BinaryEncoding(); |
||||
} |
||||
else if (encoding == null) |
||||
{ |
||||
if (!isBinary) e = GetUTF8Encoding(); |
||||
else e = new BinaryEncoding(); |
||||
} |
||||
else |
||||
{ |
||||
if (isBinary) |
||||
throw new ScriptRuntimeException("Can't specify encodings other than nil or 'binary' for binary streams."); |
||||
|
||||
e = Encoding.GetEncoding(encoding); |
||||
} |
||||
|
||||
return UserData.Create(Open(executionContext, filename, e, mode)); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.Nil, |
||||
DynValue.NewString(IoExceptionToLuaMessage(ex, filename))); |
||||
} |
||||
|
||||
} |
||||
|
||||
public static string IoExceptionToLuaMessage(Exception ex, string filename) |
||||
{ |
||||
if (ex is System.IO.FileNotFoundException) |
||||
return string.Format("{0}: No such file or directory", filename); |
||||
else |
||||
return ex.Message; |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue type(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
if (args[0].Type != DataType.UserData) |
||||
return DynValue.Nil; |
||||
|
||||
FileUserDataBase file = args[0].UserData.Object as FileUserDataBase; |
||||
|
||||
if (file == null) |
||||
return DynValue.Nil; |
||||
else if (file.isopen()) |
||||
return DynValue.NewString("file"); |
||||
else |
||||
return DynValue.NewString("closed file"); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue read(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
FileUserDataBase file = GetDefaultFile(executionContext, StandardFileType.StdIn); |
||||
return file.read(executionContext, args); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue write(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
FileUserDataBase file = GetDefaultFile(executionContext, StandardFileType.StdOut); |
||||
return file.write(executionContext, args); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue tmpfile(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
string tmpfilename = Script.GlobalOptions.Platform.IO_OS_GetTempFilename(); |
||||
FileUserDataBase file = Open(executionContext, tmpfilename, GetUTF8Encoding(), "w"); |
||||
return UserData.Create(file); |
||||
} |
||||
|
||||
private static FileUserDataBase Open(ScriptExecutionContext executionContext, string filename, Encoding encoding, string mode) |
||||
{ |
||||
return new FileUserData(executionContext.GetScript(), filename, encoding, mode); |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 5209e5cca6a8f4dbc888ed4b7e061d55 |
||||
timeCreated: 1476432882 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,55 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using MoonSharp.Interpreter.Serialization.Json; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
[MoonSharpModule(Namespace = "json")] |
||||
public class JsonModule |
||||
{ |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue parse(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
try |
||||
{ |
||||
DynValue vs = args.AsType(0, "parse", DataType.String, false); |
||||
Table t = JsonTableConverter.JsonToTable(vs.String, executionContext.GetScript()); |
||||
return DynValue.NewTable(t); |
||||
} |
||||
catch (SyntaxErrorException ex) |
||||
{ |
||||
throw new ScriptRuntimeException(ex); |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue serialize(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
try |
||||
{ |
||||
DynValue vt = args.AsType(0, "serialize", DataType.Table, false); |
||||
string s = JsonTableConverter.TableToJson(vt.Table); |
||||
return DynValue.NewString(s); |
||||
} |
||||
catch (SyntaxErrorException ex) |
||||
{ |
||||
throw new ScriptRuntimeException(ex); |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue isnull(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue vs = args[0]; |
||||
return DynValue.NewBoolean((JsonNull.IsJsonNull(vs)) || (vs.IsNil())); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue @null(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return JsonNull.Create(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: df9d3ec3d79f5431c88af4ab97b6f18a |
||||
timeCreated: 1475786656 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,248 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing loading Lua functions like 'require', 'load', etc. |
||||
/// </summary> |
||||
[MoonSharpModule] |
||||
public class LoadModule |
||||
{ |
||||
public static void MoonSharpInit(Table globalTable, Table ioTable) |
||||
{ |
||||
DynValue package = globalTable.Get("package"); |
||||
|
||||
if (package.IsNil()) |
||||
{ |
||||
package = DynValue.NewTable(globalTable.OwnerScript); |
||||
globalTable["package"] = package; |
||||
} |
||||
else if (package.Type != DataType.Table) |
||||
{ |
||||
throw new InternalErrorException("'package' global variable was found and it is not a table"); |
||||
} |
||||
|
||||
#if PCL || ENABLE_DOTNET || NETFX_CORE |
||||
string cfg = "\\\n;\n?\n!\n-\n"; |
||||
#else |
||||
string cfg = System.IO.Path.DirectorySeparatorChar + "\n;\n?\n!\n-\n"; |
||||
#endif |
||||
|
||||
package.Table.Set("config", DynValue.NewString(cfg)); |
||||
} |
||||
|
||||
|
||||
|
||||
// load (ld [, source [, mode [, env]]]) |
||||
// ---------------------------------------------------------------- |
||||
// Loads a chunk. |
||||
// |
||||
// If ld is a string, the chunk is this string. |
||||
// |
||||
// If there are no syntactic errors, returns the compiled chunk as a function; |
||||
// otherwise, returns nil plus the error message. |
||||
// |
||||
// source is used as the source of the chunk for error messages and debug |
||||
// information (see §4.9). When absent, it defaults to ld, if ld is a string, |
||||
// or to "=(load)" otherwise. |
||||
// |
||||
// The string mode is ignored, and assumed to be "t"; |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue load(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return load_impl(executionContext, args, null); |
||||
} |
||||
|
||||
// loadsafe (ld [, source [, mode [, env]]]) |
||||
// ---------------------------------------------------------------- |
||||
// Same as load, except that "env" defaults to the current environment of the function |
||||
// calling load, instead of the actual global environment. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue loadsafe(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return load_impl(executionContext, args, GetSafeDefaultEnv(executionContext)); |
||||
} |
||||
|
||||
public static DynValue load_impl(ScriptExecutionContext executionContext, CallbackArguments args, Table defaultEnv) |
||||
{ |
||||
try |
||||
{ |
||||
Script S = executionContext.GetScript(); |
||||
DynValue ld = args[0]; |
||||
string script = ""; |
||||
|
||||
if (ld.Type == DataType.Function) |
||||
{ |
||||
while (true) |
||||
{ |
||||
DynValue ret = executionContext.GetScript().Call(ld); |
||||
if (ret.Type == DataType.String && ret.String.Length > 0) |
||||
script += ret.String; |
||||
else if (ret.IsNil()) |
||||
break; |
||||
else |
||||
return DynValue.NewTuple(DynValue.Nil, DynValue.NewString("reader function must return a string")); |
||||
} |
||||
} |
||||
else if (ld.Type == DataType.String) |
||||
{ |
||||
script = ld.String; |
||||
} |
||||
else |
||||
{ |
||||
args.AsType(0, "load", DataType.Function, false); |
||||
} |
||||
|
||||
DynValue source = args.AsType(1, "load", DataType.String, true); |
||||
DynValue env = args.AsType(3, "load", DataType.Table, true); |
||||
|
||||
DynValue fn = S.LoadString(script, |
||||
!env.IsNil() ? env.Table : defaultEnv, |
||||
!source.IsNil() ? source.String : "=(load)"); |
||||
|
||||
return fn; |
||||
} |
||||
catch (SyntaxErrorException ex) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.DecoratedMessage ?? ex.Message)); |
||||
} |
||||
} |
||||
|
||||
// loadfile ([filename [, mode [, env]]]) |
||||
// ---------------------------------------------------------------- |
||||
// Similar to load, but gets the chunk from file filename or from the standard input, |
||||
// if no file name is given. INCOMPAT: stdin not supported, mode ignored |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue loadfile(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return loadfile_impl(executionContext, args, null); |
||||
} |
||||
|
||||
// loadfile ([filename [, mode [, env]]]) |
||||
// ---------------------------------------------------------------- |
||||
// Same as loadfile, except that "env" defaults to the current environment of the function |
||||
// calling load, instead of the actual global environment. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue loadfilesafe(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return loadfile_impl(executionContext, args, GetSafeDefaultEnv(executionContext)); |
||||
} |
||||
|
||||
|
||||
|
||||
private static DynValue loadfile_impl(ScriptExecutionContext executionContext, CallbackArguments args, Table defaultEnv) |
||||
{ |
||||
try |
||||
{ |
||||
Script S = executionContext.GetScript(); |
||||
DynValue filename = args.AsType(0, "loadfile", DataType.String, false); |
||||
DynValue env = args.AsType(2, "loadfile", DataType.Table, true); |
||||
|
||||
DynValue fn = S.LoadFile(filename.String, env.IsNil() ? defaultEnv : env.Table); |
||||
|
||||
return fn; |
||||
} |
||||
catch (SyntaxErrorException ex) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.DecoratedMessage ?? ex.Message)); |
||||
} |
||||
} |
||||
|
||||
|
||||
private static Table GetSafeDefaultEnv(ScriptExecutionContext executionContext) |
||||
{ |
||||
Table env = executionContext.CurrentGlobalEnv; |
||||
|
||||
if (env == null) |
||||
throw new ScriptRuntimeException("current environment cannot be backtracked."); |
||||
|
||||
return env; |
||||
} |
||||
|
||||
//dofile ([filename]) |
||||
//-------------------------------------------------------------------------------------------------------------- |
||||
//Opens the named file and executes its contents as a Lua chunk. When called without arguments, |
||||
//dofile executes the contents of the standard input (stdin). Returns all values returned by the chunk. |
||||
//In case of errors, dofile propagates the error to its caller (that is, dofile does not run in protected mode). |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue dofile(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
try |
||||
{ |
||||
Script S = executionContext.GetScript(); |
||||
DynValue v = args.AsType(0, "dofile", DataType.String, false); |
||||
|
||||
DynValue fn = S.LoadFile(v.String); |
||||
|
||||
return DynValue.NewTailCallReq(fn); // tail call to dofile |
||||
} |
||||
catch (SyntaxErrorException ex) |
||||
{ |
||||
throw new ScriptRuntimeException(ex); |
||||
} |
||||
} |
||||
|
||||
//require (modname) |
||||
//---------------------------------------------------------------------------------------------------------------- |
||||
//Loads the given module. The function starts by looking into the package.loaded table to determine whether |
||||
//modname is already loaded. If it is, then require returns the value stored at package.loaded[modname]. |
||||
//Otherwise, it tries to find a loader for the module. |
||||
// |
||||
//To find a loader, require is guided by the package.loaders array. By changing this array, we can change |
||||
//how require looks for a module. The following explanation is based on the default configuration for package.loaders. |
||||
// |
||||
//First require queries package.preload[modname]. If it has a value, this value (which should be a function) |
||||
//is the loader. Otherwise require searches for a Lua loader using the path stored in package.path. |
||||
//If that also fails, it searches for a C loader using the path stored in package.cpath. If that also fails, |
||||
//it tries an all-in-one loader (see package.loaders). |
||||
// |
||||
//Once a loader is found, require calls the loader with a single argument, modname. If the loader returns any value, |
||||
//require assigns the returned value to package.loaded[modname]. If the loader returns no value and has not assigned |
||||
//any value to package.loaded[modname], then require assigns true to this entry. In any case, require returns the |
||||
//final value of package.loaded[modname]. |
||||
// |
||||
//If there is any error loading or running the module, or if it cannot find any loader for the module, then require |
||||
//signals an error. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue __require_clr_impl(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
Script S = executionContext.GetScript(); |
||||
DynValue v = args.AsType(0, "__require_clr_impl", DataType.String, false); |
||||
|
||||
DynValue fn = S.RequireModule(v.String); |
||||
|
||||
return fn; // tail call to dofile |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public const string require = @"
|
||||
function(modulename) |
||||
if (package == nil) then package = { }; end |
||||
if (package.loaded == nil) then package.loaded = { }; end |
||||
|
||||
local m = package.loaded[modulename]; |
||||
|
||||
if (m ~= nil) then |
||||
return m; |
||||
end |
||||
|
||||
local func = __require_clr_impl(modulename); |
||||
|
||||
local res = func(modulename); |
||||
|
||||
if (res == nil) then |
||||
res = true; |
||||
end |
||||
|
||||
package.loaded[modulename] = res; |
||||
|
||||
return res; |
||||
end";
|
||||
|
||||
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 90b319234a9a342b6a8649eef72352fd |
||||
timeCreated: 1476432884 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,324 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System; |
||||
using MoonSharp.Interpreter.Interop; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing math Lua functions |
||||
/// </summary> |
||||
[MoonSharpModule(Namespace = "math")] |
||||
public class MathModule |
||||
{ |
||||
[MoonSharpModuleConstant] |
||||
public const double pi = Math.PI; |
||||
[MoonSharpModuleConstant] |
||||
public const double huge = double.MaxValue; |
||||
|
||||
private static Random GetRandom(Script s) |
||||
{ |
||||
DynValue rr = s.Registry.Get("F61E3AA7247D4D1EB7A45430B0C8C9BB_MATH_RANDOM"); |
||||
return (rr.UserData.Object as AnonWrapper<Random>).Value; |
||||
} |
||||
|
||||
private static void SetRandom(Script s, Random random) |
||||
{ |
||||
DynValue rr = UserData.Create(new AnonWrapper<Random>(random)); |
||||
s.Registry.Set("F61E3AA7247D4D1EB7A45430B0C8C9BB_MATH_RANDOM", rr); |
||||
} |
||||
|
||||
|
||||
public static void MoonSharpInit(Table globalTable, Table ioTable) |
||||
{ |
||||
SetRandom(globalTable.OwnerScript, new Random()); |
||||
} |
||||
|
||||
|
||||
|
||||
private static DynValue exec1(CallbackArguments args, string funcName, Func<double, double> func) |
||||
{ |
||||
DynValue arg = args.AsType(0, funcName, DataType.Number, false); |
||||
return DynValue.NewNumber(func(arg.Number)); |
||||
} |
||||
|
||||
private static DynValue exec2(CallbackArguments args, string funcName, Func<double, double, double> func) |
||||
{ |
||||
DynValue arg = args.AsType(0, funcName, DataType.Number, false); |
||||
DynValue arg2 = args.AsType(1, funcName, DataType.Number, false); |
||||
return DynValue.NewNumber(func(arg.Number, arg2.Number)); |
||||
} |
||||
private static DynValue exec2n(CallbackArguments args, string funcName, double defVal, Func<double, double, double> func) |
||||
{ |
||||
DynValue arg = args.AsType(0, funcName, DataType.Number, false); |
||||
DynValue arg2 = args.AsType(1, funcName, DataType.Number, true); |
||||
|
||||
return DynValue.NewNumber(func(arg.Number, arg2.IsNil() ? defVal : arg2.Number)); |
||||
} |
||||
private static DynValue execaccum(CallbackArguments args, string funcName, Func<double, double, double> func) |
||||
{ |
||||
double accum = double.NaN; |
||||
|
||||
if (args.Count == 0) |
||||
{ |
||||
throw new ScriptRuntimeException("bad argument #1 to '{0}' (number expected, got no value)", funcName); |
||||
} |
||||
|
||||
for (int i = 0; i < args.Count; i++) |
||||
{ |
||||
DynValue arg = args.AsType(i, funcName, DataType.Number, false); |
||||
|
||||
if (i == 0) |
||||
accum = arg.Number; |
||||
else |
||||
accum = func(accum, arg.Number); |
||||
} |
||||
|
||||
return DynValue.NewNumber(accum); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue abs(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "abs", d => Math.Abs(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue acos(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "acos", d => Math.Acos(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue asin(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "asin", d => Math.Asin(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue atan(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "atan", d => Math.Atan(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue atan2(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec2(args, "atan2", (d1, d2) => Math.Atan2(d1, d2)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue ceil(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "ceil", d => Math.Ceiling(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue cos(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "cos", d => Math.Cos(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue cosh(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "cosh", d => Math.Cosh(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue deg(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "deg", d => d * 180.0 / Math.PI); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue exp(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "exp", d => Math.Exp(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue floor(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "floor", d => Math.Floor(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue fmod(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec2(args, "fmod", (d1, d2) => Math.IEEERemainder(d1, d2)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue frexp(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
// http://stackoverflow.com/questions/389993/extracting-mantissa-and-exponent-from-double-in-c-sharp |
||||
|
||||
DynValue arg = args.AsType(0, "frexp", DataType.Number, false); |
||||
|
||||
double d = arg.Number; |
||||
|
||||
// Translate the double into sign, exponent and mantissa. |
||||
long bits = BitConverter.DoubleToInt64Bits(d); |
||||
// Note that the shift is sign-extended, hence the test against -1 not 1 |
||||
bool negative = (bits < 0); |
||||
int exponent = (int) ((bits >> 52) & 0x7ffL); |
||||
long mantissa = bits & 0xfffffffffffffL; |
||||
|
||||
// Subnormal numbers; exponent is effectively one higher, |
||||
// but there's no extra normalisation bit in the mantissa |
||||
if (exponent==0) |
||||
{ |
||||
exponent++; |
||||
} |
||||
// Normal numbers; leave exponent as it is but add extra |
||||
// bit to the front of the mantissa |
||||
else |
||||
{ |
||||
mantissa = mantissa | (1L<<52); |
||||
} |
||||
|
||||
// Bias the exponent. It's actually biased by 1023, but we're |
||||
// treating the mantissa as m.0 rather than 0.m, so we need |
||||
// to subtract another 52 from it. |
||||
exponent -= 1075; |
||||
|
||||
if (mantissa == 0) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.NewNumber(0), DynValue.NewNumber(0)); |
||||
} |
||||
|
||||
/* Normalize */ |
||||
while((mantissa & 1) == 0) |
||||
{ /* i.e., Mantissa is even */ |
||||
mantissa >>= 1; |
||||
exponent++; |
||||
} |
||||
|
||||
double m = (double)mantissa; |
||||
double e = (double)exponent; |
||||
while( m >= 1 ) |
||||
{ |
||||
m /= 2.0; |
||||
e += 1.0; |
||||
} |
||||
|
||||
if( negative ) m = -m; |
||||
|
||||
return DynValue.NewTuple(DynValue.NewNumber(m), DynValue.NewNumber(e)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue ldexp(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec2(args, "ldexp", (d1, d2) => d1 * Math.Pow(2, d2)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue log(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec2n(args, "log", Math.E, (d1, d2) => Math.Log(d1, d2)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue max(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return execaccum(args, "max", (d1, d2) => Math.Max(d1, d2)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue min(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return execaccum(args, "min", (d1, d2) => Math.Min(d1, d2)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue modf(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg = args.AsType(0, "modf", DataType.Number, false); |
||||
return DynValue.NewTuple(DynValue.NewNumber(Math.Floor(arg.Number)), DynValue.NewNumber(arg.Number - Math.Floor(arg.Number))); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue pow(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec2(args, "pow", (d1, d2) => Math.Pow(d1, d2)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue rad(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "rad", d => d * Math.PI / 180.0); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue random(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue m = args.AsType(0, "random", DataType.Number, true); |
||||
DynValue n = args.AsType(1, "random", DataType.Number, true); |
||||
Random R = GetRandom(executionContext.GetScript()); |
||||
double d; |
||||
|
||||
if (m.IsNil() && n.IsNil()) |
||||
{ |
||||
d = R.NextDouble(); |
||||
} |
||||
else |
||||
{ |
||||
int a = n.IsNil() ? 1 : (int)n.Number; |
||||
int b = (int)m.Number; |
||||
|
||||
if (a < b) |
||||
d = R.Next(a, b + 1); |
||||
else |
||||
d = R.Next(b, a + 1); |
||||
} |
||||
|
||||
return DynValue.NewNumber(d); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue randomseed(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg = args.AsType(0, "randomseed", DataType.Number, false); |
||||
var script = executionContext.GetScript(); |
||||
SetRandom(script, new Random((int)arg.Number)); |
||||
return DynValue.Nil; |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue sin(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "sin", d => Math.Sin(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue sinh(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "sinh", d => Math.Sinh(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue sqrt(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "sqrt", d => Math.Sqrt(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue tan(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "tan", d => Math.Tan(d)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue tanh(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return exec1(args, "tanh", d => Math.Tanh(d)); |
||||
} |
||||
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 38103786f8d984326b5123cab6ca4b47 |
||||
timeCreated: 1475786653 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,122 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing metatable related Lua functions (xxxmetatable and rawxxx). |
||||
/// </summary> |
||||
[MoonSharpModule] |
||||
public class MetaTableModule |
||||
{ |
||||
// setmetatable (table, metatable) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
// Sets the metatable for the given table. (You cannot change the metatable of other |
||||
// types from Lua, only from C.) If metatable is nil, removes the metatable of the given table. |
||||
// If the original metatable has a "__metatable" field, raises an error ("cannot change a protected metatable"). |
||||
// This function returns table. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue setmetatable(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue table = args.AsType(0, "setmetatable", DataType.Table); |
||||
DynValue metatable = args.AsType(1, "setmetatable", DataType.Table, true); |
||||
|
||||
DynValue curmeta = executionContext.GetMetamethod(table, "__metatable"); |
||||
|
||||
if (curmeta != null) |
||||
{ |
||||
throw new ScriptRuntimeException("cannot change a protected metatable"); |
||||
} |
||||
|
||||
table.Table.MetaTable = metatable.Table; |
||||
return table; |
||||
} |
||||
|
||||
// getmetatable (object) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
// If object does not have a metatable, returns nil. Otherwise, if the object's metatable |
||||
// has a "__metatable" field, returns the associated value. Otherwise, returns the metatable of the given object. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue getmetatable(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue obj = args[0]; |
||||
Table meta = null; |
||||
|
||||
if (obj.Type.CanHaveTypeMetatables()) |
||||
{ |
||||
meta = executionContext.GetScript().GetTypeMetatable(obj.Type); |
||||
} |
||||
|
||||
|
||||
if (obj.Type == DataType.Table) |
||||
{ |
||||
meta = obj.Table.MetaTable; |
||||
} |
||||
|
||||
if (meta == null) |
||||
return DynValue.Nil; |
||||
else if (meta.RawGet("__metatable") != null) |
||||
return meta.Get("__metatable"); |
||||
else |
||||
return DynValue.NewTable(meta); |
||||
} |
||||
|
||||
// rawget (table, index) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
// Gets the real value of table[index], without invoking any metamethod. table must be a table; index may be any value. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue rawget(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue table = args.AsType(0, "rawget", DataType.Table); |
||||
DynValue index = args[1]; |
||||
|
||||
return table.Table.Get(index); |
||||
} |
||||
|
||||
// rawset (table, index, value) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
// Sets the real value of table[index] to value, without invoking any metamethod. table must be a table, |
||||
// index any value different from nil and NaN, and value any Lua value. |
||||
// This function returns table. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue rawset(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue table = args.AsType(0, "rawset", DataType.Table); |
||||
DynValue index = args[1]; |
||||
|
||||
table.Table.Set(index, args[2]); |
||||
|
||||
return table; |
||||
} |
||||
|
||||
// rawequal (v1, v2) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
// Checks whether v1 is equal to v2, without invoking any metamethod. Returns a boolean. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue rawequal(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v1 = args[0]; |
||||
DynValue v2 = args[1]; |
||||
|
||||
return DynValue.NewBoolean(v1.Equals(v2)); |
||||
} |
||||
|
||||
//rawlen (v) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
//Returns the length of the object v, which must be a table or a string, without invoking any metamethod. Returns an integer number. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue rawlen(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
if (args[0].Type != DataType.String && args[0].Type != DataType.Table) |
||||
{ |
||||
throw ScriptRuntimeException.BadArgument(0, "rawlen", "table or string", args[0].Type.ToErrorTypeString(), false); |
||||
} |
||||
|
||||
return args[0].GetLength(); |
||||
} |
||||
|
||||
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: b3b971ba440d24e91a6ff0bc9e306d59 |
||||
timeCreated: 1475786655 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,132 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing system related Lua functions from the 'os' module. |
||||
/// Proper support requires a compatible IPlatformAccessor |
||||
/// </summary> |
||||
[MoonSharpModule(Namespace = "os")] |
||||
public class OsSystemModule |
||||
{ |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue execute(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v = args.AsType(0, "execute", DataType.String, true); |
||||
|
||||
if (v.IsNil()) |
||||
{ |
||||
return DynValue.NewBoolean(true); |
||||
} |
||||
else |
||||
{ |
||||
try |
||||
{ |
||||
int exitCode = Script.GlobalOptions.Platform.OS_Execute(v.String); |
||||
|
||||
return DynValue.NewTuple( |
||||
DynValue.Nil, |
||||
DynValue.NewString("exit"), |
||||
DynValue.NewNumber(exitCode)); |
||||
} |
||||
catch (Exception) |
||||
{ |
||||
// +++ bad to swallow.. |
||||
return DynValue.Nil; |
||||
} |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue exit(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue v_exitCode = args.AsType(0, "exit", DataType.Number, true); |
||||
int exitCode = 0; |
||||
|
||||
if (v_exitCode.IsNotNil()) |
||||
exitCode = (int)v_exitCode.Number; |
||||
|
||||
Script.GlobalOptions.Platform.OS_ExitFast(exitCode); |
||||
|
||||
throw new InvalidOperationException("Unreachable code.. reached."); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue getenv(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue varName = args.AsType(0, "getenv", DataType.String, false); |
||||
|
||||
string val = Script.GlobalOptions.Platform.GetEnvironmentVariable(varName.String); |
||||
|
||||
if (val == null) |
||||
return DynValue.Nil; |
||||
else |
||||
return DynValue.NewString(val); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue remove(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
string fileName = args.AsType(0, "remove", DataType.String, false).String; |
||||
|
||||
try |
||||
{ |
||||
if (Script.GlobalOptions.Platform.OS_FileExists(fileName)) |
||||
{ |
||||
Script.GlobalOptions.Platform.OS_FileDelete(fileName); |
||||
return DynValue.True; |
||||
} |
||||
else |
||||
{ |
||||
return DynValue.NewTuple( |
||||
DynValue.Nil, |
||||
DynValue.NewString("{0}: No such file or directory.", fileName), |
||||
DynValue.NewNumber(-1)); |
||||
} |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.Message), DynValue.NewNumber(-1)); |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue rename(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
string fileNameOld = args.AsType(0, "rename", DataType.String, false).String; |
||||
string fileNameNew = args.AsType(1, "rename", DataType.String, false).String; |
||||
|
||||
try |
||||
{ |
||||
if (!Script.GlobalOptions.Platform.OS_FileExists(fileNameOld)) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.Nil, |
||||
DynValue.NewString("{0}: No such file or directory.", fileNameOld), |
||||
DynValue.NewNumber(-1)); |
||||
} |
||||
|
||||
Script.GlobalOptions.Platform.OS_FileMove(fileNameOld, fileNameNew); |
||||
return DynValue.True; |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.Message), DynValue.NewNumber(-1)); |
||||
} |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue setlocale(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return DynValue.NewString("n/a"); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue tmpname(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return DynValue.NewString(Script.GlobalOptions.Platform.IO_OS_GetTempFilename()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1bb7798955cba48c6b0e19cf3daa219f |
||||
timeCreated: 1475786653 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,287 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing time related Lua functions from the 'os' module. |
||||
/// </summary> |
||||
[MoonSharpModule(Namespace = "os")] |
||||
public class OsTimeModule |
||||
{ |
||||
static DateTime Time0 = DateTime.UtcNow; |
||||
static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); |
||||
|
||||
private static DynValue GetUnixTime(DateTime dateTime, DateTime? epoch = null) |
||||
{ |
||||
double time = (dateTime - (epoch ?? Epoch)).TotalSeconds; |
||||
|
||||
if (time < 0.0) |
||||
return DynValue.Nil; |
||||
|
||||
return DynValue.NewNumber(time); |
||||
} |
||||
|
||||
private static DateTime FromUnixTime(double unixtime) |
||||
{ |
||||
TimeSpan ts = TimeSpan.FromSeconds(unixtime); |
||||
return Epoch + ts; |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue clock(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return GetUnixTime(DateTime.UtcNow, Time0); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue difftime(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue t2 = args.AsType(0, "difftime", DataType.Number, false); |
||||
DynValue t1 = args.AsType(1, "difftime", DataType.Number, true); |
||||
|
||||
if (t1.IsNil()) |
||||
return DynValue.NewNumber(t2.Number); |
||||
|
||||
return DynValue.NewNumber(t2.Number - t1.Number); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue time(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DateTime date = DateTime.UtcNow; |
||||
|
||||
if (args.Count > 0) |
||||
{ |
||||
DynValue vt = args.AsType(0, "time", DataType.Table, true); |
||||
if (vt.Type == DataType.Table) |
||||
date = ParseTimeTable(vt.Table); |
||||
} |
||||
|
||||
return GetUnixTime(date); |
||||
} |
||||
|
||||
static DateTime ParseTimeTable(Table t) |
||||
{ |
||||
int sec = GetTimeTableField(t, "sec") ?? 0; |
||||
int min = GetTimeTableField(t, "min") ?? 0; |
||||
int hour = GetTimeTableField(t, "hour") ?? 12; |
||||
int? day = GetTimeTableField(t, "day"); |
||||
int? month = GetTimeTableField(t, "month"); |
||||
int? year = GetTimeTableField(t, "year"); |
||||
|
||||
if (day == null) |
||||
throw new ScriptRuntimeException("field 'day' missing in date table"); |
||||
|
||||
if (month == null) |
||||
throw new ScriptRuntimeException("field 'month' missing in date table"); |
||||
|
||||
if (year == null) |
||||
throw new ScriptRuntimeException("field 'year' missing in date table"); |
||||
|
||||
return new DateTime(year.Value, month.Value, day.Value, hour, min, sec); |
||||
} |
||||
|
||||
|
||||
private static int? GetTimeTableField(Table t, string key) |
||||
{ |
||||
DynValue v = t.Get(key); |
||||
double? d = v.CastToNumber(); |
||||
|
||||
if (d.HasValue) |
||||
return (int)d.Value; |
||||
|
||||
return null; |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue date(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DateTime reference = DateTime.UtcNow; |
||||
|
||||
DynValue vformat = args.AsType(0, "date", DataType.String, true); |
||||
DynValue vtime = args.AsType(1, "date", DataType.Number, true); |
||||
|
||||
string format = (vformat.IsNil()) ? "%c" : vformat.String; |
||||
|
||||
if (vtime.IsNotNil()) |
||||
reference = FromUnixTime(vtime.Number); |
||||
|
||||
bool isDst = false; |
||||
|
||||
if (format.StartsWith("!")) |
||||
{ |
||||
format = format.Substring(1); |
||||
} |
||||
else |
||||
{ |
||||
#if !(PCL || ENABLE_DOTNET || NETFX_CORE) |
||||
|
||||
try |
||||
{ |
||||
reference = TimeZoneInfo.ConvertTimeFromUtc(reference, TimeZoneInfo.Local); |
||||
isDst = reference.IsDaylightSavingTime(); |
||||
} |
||||
catch (TimeZoneNotFoundException) |
||||
{ |
||||
// this catches a weird mono bug: https://bugzilla.xamarin.com/show_bug.cgi?id=11817 |
||||
// however the behavior is definitely not correct. damn. |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
|
||||
if (format == "*t") |
||||
{ |
||||
Table t = new Table(executionContext.GetScript()); |
||||
|
||||
t.Set("year", DynValue.NewNumber(reference.Year)); |
||||
t.Set("month", DynValue.NewNumber(reference.Month)); |
||||
t.Set("day", DynValue.NewNumber(reference.Day)); |
||||
t.Set("hour", DynValue.NewNumber(reference.Hour)); |
||||
t.Set("min", DynValue.NewNumber(reference.Minute)); |
||||
t.Set("sec", DynValue.NewNumber(reference.Second)); |
||||
t.Set("wday", DynValue.NewNumber(((int)reference.DayOfWeek) + 1)); |
||||
t.Set("yday", DynValue.NewNumber(reference.DayOfYear)); |
||||
t.Set("isdst", DynValue.NewBoolean(isDst)); |
||||
|
||||
return DynValue.NewTable(t); |
||||
} |
||||
|
||||
else return DynValue.NewString(StrFTime(format, reference)); |
||||
} |
||||
|
||||
private static string StrFTime(string format, DateTime d) |
||||
{ |
||||
// ref: http://www.cplusplus.com/reference/ctime/strftime/ |
||||
|
||||
Dictionary<char, string> STANDARD_PATTERNS = new Dictionary<char, string>() |
||||
{ |
||||
{ 'a', "ddd" }, |
||||
{ 'A', "dddd" }, |
||||
{ 'b', "MMM" }, |
||||
{ 'B', "MMMM" }, |
||||
{ 'c', "f" }, |
||||
{ 'd', "dd" }, |
||||
{ 'D', "MM/dd/yy" }, |
||||
{ 'F', "yyyy-MM-dd" }, |
||||
{ 'g', "yy" }, |
||||
{ 'G', "yyyy" }, |
||||
{ 'h', "MMM" }, |
||||
{ 'H', "HH" }, |
||||
{ 'I', "hh" }, |
||||
{ 'm', "MM" }, |
||||
{ 'M', "mm" }, |
||||
{ 'p', "tt" }, |
||||
{ 'r', "h:mm:ss tt" }, |
||||
{ 'R', "HH:mm" }, |
||||
{ 'S', "ss" }, |
||||
{ 'T', "HH:mm:ss" }, |
||||
{ 'y', "yy" }, |
||||
{ 'Y', "yyyy" }, |
||||
{ 'x', "d" }, |
||||
{ 'X', "T" }, |
||||
{ 'z', "zzz" }, |
||||
{ 'Z', "zzz" }, |
||||
}; |
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder(); |
||||
|
||||
bool isEscapeSequence = false; |
||||
|
||||
for (int i = 0; i < format.Length; i++) |
||||
{ |
||||
char c = format[i]; |
||||
|
||||
if (c == '%') |
||||
{ |
||||
if (isEscapeSequence) |
||||
{ |
||||
sb.Append('%'); |
||||
isEscapeSequence = false; |
||||
} |
||||
else |
||||
isEscapeSequence = true; |
||||
|
||||
continue; |
||||
} |
||||
|
||||
if (!isEscapeSequence) |
||||
{ |
||||
sb.Append(c); |
||||
continue; |
||||
} |
||||
|
||||
if (c == 'O' || c == 'E') continue; // no modifiers |
||||
|
||||
isEscapeSequence = false; |
||||
|
||||
if (STANDARD_PATTERNS.ContainsKey(c)) |
||||
{ |
||||
sb.Append(d.ToString(STANDARD_PATTERNS[c])); |
||||
} |
||||
else if (c == 'e') |
||||
{ |
||||
string s = d.ToString("%d"); |
||||
if (s.Length < 2) s = " " + s; |
||||
sb.Append(s); |
||||
} |
||||
else if (c == 'n') |
||||
{ |
||||
sb.Append('\n'); |
||||
} |
||||
else if (c == 't') |
||||
{ |
||||
sb.Append('\t'); |
||||
} |
||||
else if (c == 'C') |
||||
{ |
||||
sb.Append((int)(d.Year / 100)); |
||||
} |
||||
else if (c == 'j') |
||||
{ |
||||
sb.Append(d.DayOfYear.ToString("000")); |
||||
} |
||||
else if (c == 'u') |
||||
{ |
||||
int weekDay = (int)d.DayOfWeek; |
||||
if (weekDay == 0) |
||||
weekDay = 7; |
||||
|
||||
sb.Append(weekDay); |
||||
} |
||||
else if (c == 'w') |
||||
{ |
||||
int weekDay = (int)d.DayOfWeek; |
||||
sb.Append(weekDay); |
||||
} |
||||
else if (c == 'U') |
||||
{ |
||||
// Week number with the first Sunday as the first day of week one (00-53) |
||||
sb.Append("??"); |
||||
} |
||||
else if (c == 'V') |
||||
{ |
||||
// ISO 8601 week number (00-53) |
||||
sb.Append("??"); |
||||
} |
||||
else if (c == 'W') |
||||
{ |
||||
// Week number with the first Monday as the first day of week one (00-53) |
||||
sb.Append("??"); |
||||
} |
||||
else |
||||
{ |
||||
throw new ScriptRuntimeException("bad argument #1 to 'date' (invalid conversion specifier '{0}')", format); |
||||
} |
||||
} |
||||
|
||||
return sb.ToString(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 29679b67516094990a23d5066e7af0ea |
||||
timeCreated: 1476432879 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a18a955a013284f08b443c601f5b9612 |
||||
folderAsset: yes |
||||
timeCreated: 1475786652 |
||||
licenseType: Pro |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,998 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
// |
||||
// This part taken from KopiLua - https://github.com/NLua/KopiLua |
||||
// |
||||
// ========================================================================================================= |
||||
// |
||||
// Kopi Lua License |
||||
// ---------------- |
||||
// MIT License for KopiLua |
||||
// Copyright (c) 2012 LoDC |
||||
// 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. |
||||
// =============================================================================== |
||||
// Lua License |
||||
// ----------- |
||||
// Lua is licensed under the terms of the MIT license reproduced below. |
||||
// This means that Lua is free software and can be used for both academic |
||||
// and commercial purposes at absolutely no cost. |
||||
// For details and rationale, see http://www.lua.org/license.html . |
||||
// =============================================================================== |
||||
// Copyright (C) 1994-2008 Lua.org, PUC-Rio. |
||||
// 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 MoonSharp.Interpreter.Interop.LuaStateInterop; |
||||
using lua_Integer = System.Int32; |
||||
using LUA_INTFRM_T = System.Int64; |
||||
using ptrdiff_t = System.Int32; |
||||
using UNSIGNED_LUA_INTFRM_T = System.UInt64; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib.StringLib |
||||
{ |
||||
internal class KopiLua_StringLib : LuaBase |
||||
{ |
||||
public const int LUA_MAXCAPTURES = 32; |
||||
|
||||
private static ptrdiff_t posrelat(ptrdiff_t pos, uint len) |
||||
{ |
||||
/* relative string position: negative means back from end */ |
||||
if (pos < 0) pos += (ptrdiff_t)len + 1; |
||||
return (pos >= 0) ? pos : 0; |
||||
} |
||||
|
||||
/* |
||||
** {====================================================== |
||||
** PATTERN MATCHING |
||||
** ======================================================= |
||||
*/ |
||||
|
||||
|
||||
public const int CAP_UNFINISHED = (-1); |
||||
public const int CAP_POSITION = (-2); |
||||
|
||||
public class MatchState |
||||
{ |
||||
|
||||
public MatchState() |
||||
{ |
||||
for (int i = 0; i < LUA_MAXCAPTURES; i++) |
||||
capture[i] = new capture_(); |
||||
} |
||||
|
||||
public int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ |
||||
public CharPtr src_init; /* init of source string */ |
||||
public CharPtr src_end; /* end (`\0') of source string */ |
||||
public LuaState L; |
||||
public int level; /* total number of captures (finished or unfinished) */ |
||||
|
||||
public class capture_ |
||||
{ |
||||
public CharPtr init; |
||||
public ptrdiff_t len; |
||||
}; |
||||
public capture_[] capture = new capture_[LUA_MAXCAPTURES]; |
||||
}; |
||||
|
||||
|
||||
public const int MAXCCALLS = 200; |
||||
public const char L_ESC = '%'; |
||||
public const string SPECIALS = "^$*+?.([%-"; |
||||
|
||||
|
||||
private static int check_capture(MatchState ms, int l) |
||||
{ |
||||
l -= '1'; |
||||
if (l < 0 || l >= ms.level || ms.capture[l].len == CAP_UNFINISHED) |
||||
return LuaLError(ms.L, "invalid capture index {0}", l + 1); |
||||
return l; |
||||
} |
||||
|
||||
|
||||
|
||||
private static int capture_to_close(MatchState ms) |
||||
{ |
||||
int level = ms.level; |
||||
for (level--; level >= 0; level--) |
||||
if (ms.capture[level].len == CAP_UNFINISHED) return level; |
||||
return LuaLError(ms.L, "invalid pattern capture"); |
||||
} |
||||
|
||||
|
||||
private static CharPtr classend(MatchState ms, CharPtr p) |
||||
{ |
||||
p = new CharPtr(p); |
||||
char c = p[0]; |
||||
p = p.next(); |
||||
switch (c) |
||||
{ |
||||
case L_ESC: |
||||
{ |
||||
if (p[0] == '\0') |
||||
LuaLError(ms.L, "malformed pattern (ends with " + LUA_QL("%") + ")"); |
||||
return p + 1; |
||||
} |
||||
case '[': |
||||
{ |
||||
if (p[0] == '^') p = p.next(); |
||||
do |
||||
{ /* look for a `]' */ |
||||
if (p[0] == '\0') |
||||
LuaLError(ms.L, "malformed pattern (missing " + LUA_QL("]") + ")"); |
||||
c = p[0]; |
||||
p = p.next(); |
||||
if (c == L_ESC && p[0] != '\0') |
||||
p = p.next(); /* skip escapes (e.g. `%]') */ |
||||
} while (p[0] != ']'); |
||||
return p + 1; |
||||
} |
||||
default: |
||||
{ |
||||
return p; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
private static int match_class(char c, char cl) |
||||
{ |
||||
bool res; |
||||
switch (tolower(cl)) |
||||
{ |
||||
case 'a': res = isalpha(c); break; |
||||
case 'c': res = iscntrl(c); break; |
||||
case 'd': res = isdigit(c); break; |
||||
case 'l': res = islower(c); break; |
||||
case 'p': res = ispunct(c); break; |
||||
case 's': res = isspace(c); break; |
||||
case 'g': res = isgraph(c); break; |
||||
case 'u': res = isupper(c); break; |
||||
case 'w': res = isalnum(c); break; |
||||
case 'x': res = isxdigit((char)c); break; |
||||
case 'z': res = (c == 0); break; |
||||
default: return (cl == c) ? 1 : 0; |
||||
} |
||||
return (islower(cl) ? (res ? 1 : 0) : ((!res) ? 1 : 0)); |
||||
} |
||||
|
||||
|
||||
|
||||
private static int matchbracketclass(int c, CharPtr p, CharPtr ec) |
||||
{ |
||||
int sig = 1; |
||||
if (p[1] == '^') |
||||
{ |
||||
sig = 0; |
||||
p = p.next(); /* skip the `^' */ |
||||
} |
||||
while ((p = p.next()) < ec) |
||||
{ |
||||
if (p == L_ESC) |
||||
{ |
||||
p = p.next(); |
||||
if (match_class((char)c, (char)(p[0])) != 0) |
||||
return sig; |
||||
} |
||||
else if ((p[1] == '-') && (p + 2 < ec)) |
||||
{ |
||||
p += 2; |
||||
if ((byte)((p[-2])) <= c && (c <= (byte)p[0])) |
||||
return sig; |
||||
} |
||||
else if ((byte)(p[0]) == c) return sig; |
||||
} |
||||
return (sig == 0) ? 1 : 0; |
||||
} |
||||
|
||||
|
||||
private static int singlematch(int c, CharPtr p, CharPtr ep) |
||||
{ |
||||
switch (p[0]) |
||||
{ |
||||
case '.': return 1; /* matches any char */ |
||||
case L_ESC: return match_class((char)c, (char)(p[1])); |
||||
case '[': return matchbracketclass(c, p, ep - 1); |
||||
default: return ((byte)(p[0]) == c) ? 1 : 0; |
||||
} |
||||
} |
||||
|
||||
|
||||
private static CharPtr matchbalance(MatchState ms, CharPtr s, |
||||
CharPtr p) |
||||
{ |
||||
if ((p[0] == 0) || (p[1] == 0)) |
||||
LuaLError(ms.L, "unbalanced pattern"); |
||||
if (s[0] != p[0]) return null; |
||||
else |
||||
{ |
||||
int b = p[0]; |
||||
int e = p[1]; |
||||
int cont = 1; |
||||
while ((s = s.next()) < ms.src_end) |
||||
{ |
||||
if (s[0] == e) |
||||
{ |
||||
if (--cont == 0) return s + 1; |
||||
} |
||||
else if (s[0] == b) cont++; |
||||
} |
||||
} |
||||
return null; /* string ends out of balance */ |
||||
} |
||||
|
||||
|
||||
private static CharPtr max_expand(MatchState ms, CharPtr s, |
||||
CharPtr p, CharPtr ep) |
||||
{ |
||||
ptrdiff_t i = 0; /* counts maximum expand for item */ |
||||
while ((s + i < ms.src_end) && (singlematch((byte)(s[i]), p, ep) != 0)) |
||||
i++; |
||||
/* keeps trying to match with the maximum repetitions */ |
||||
while (i >= 0) |
||||
{ |
||||
CharPtr res = match(ms, (s + i), ep + 1); |
||||
if (res != null) return res; |
||||
i--; /* else didn't match; reduce 1 repetition to try again */ |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
|
||||
private static CharPtr min_expand(MatchState ms, CharPtr s, |
||||
CharPtr p, CharPtr ep) |
||||
{ |
||||
for (; ; ) |
||||
{ |
||||
CharPtr res = match(ms, s, ep + 1); |
||||
if (res != null) |
||||
return res; |
||||
else if ((s < ms.src_end) && (singlematch((byte)(s[0]), p, ep) != 0)) |
||||
s = s.next(); /* try with one more repetition */ |
||||
else return null; |
||||
} |
||||
} |
||||
|
||||
|
||||
private static CharPtr start_capture(MatchState ms, CharPtr s, |
||||
CharPtr p, int what) |
||||
{ |
||||
CharPtr res; |
||||
int level = ms.level; |
||||
if (level >= LUA_MAXCAPTURES) LuaLError(ms.L, "too many captures"); |
||||
ms.capture[level].init = s; |
||||
ms.capture[level].len = what; |
||||
ms.level = level + 1; |
||||
if ((res = match(ms, s, p)) == null) /* match failed? */ |
||||
ms.level--; /* undo capture */ |
||||
return res; |
||||
} |
||||
|
||||
|
||||
private static CharPtr end_capture(MatchState ms, CharPtr s, |
||||
CharPtr p) |
||||
{ |
||||
int l = capture_to_close(ms); |
||||
CharPtr res; |
||||
ms.capture[l].len = s - ms.capture[l].init; /* close capture */ |
||||
if ((res = match(ms, s, p)) == null) /* match failed? */ |
||||
ms.capture[l].len = CAP_UNFINISHED; /* undo capture */ |
||||
return res; |
||||
} |
||||
|
||||
|
||||
private static CharPtr match_capture(MatchState ms, CharPtr s, int l) |
||||
{ |
||||
uint len; |
||||
l = check_capture(ms, l); |
||||
len = (uint)ms.capture[l].len; |
||||
if ((uint)(ms.src_end - s) >= len && |
||||
memcmp(ms.capture[l].init, s, len) == 0) |
||||
return s + len; |
||||
else return null; |
||||
} |
||||
|
||||
|
||||
|
||||
private static CharPtr match(MatchState ms, CharPtr s, CharPtr p) |
||||
{ |
||||
s = new CharPtr(s); |
||||
p = new CharPtr(p); |
||||
if (ms.matchdepth-- == 0) |
||||
LuaLError(ms.L, "pattern too complex"); |
||||
init: /* using goto's to optimize tail recursion */ |
||||
switch (p[0]) |
||||
{ |
||||
case '(': |
||||
{ /* start capture */ |
||||
if (p[1] == ')') /* position capture? */ |
||||
return start_capture(ms, s, p + 2, CAP_POSITION); |
||||
else |
||||
return start_capture(ms, s, p + 1, CAP_UNFINISHED); |
||||
} |
||||
case ')': |
||||
{ /* end capture */ |
||||
return end_capture(ms, s, p + 1); |
||||
} |
||||
case L_ESC: |
||||
{ |
||||
switch (p[1]) |
||||
{ |
||||
case 'b': |
||||
{ /* balanced string? */ |
||||
s = matchbalance(ms, s, p + 2); |
||||
if (s == null) return null; |
||||
p += 4; goto init; /* else return match(ms, s, p+4); */ |
||||
} |
||||
case 'f': |
||||
{ /* frontier? */ |
||||
CharPtr ep; char previous; |
||||
p += 2; |
||||
if (p[0] != '[') |
||||
LuaLError(ms.L, "missing " + LUA_QL("[") + " after " + |
||||
LUA_QL("%f") + " in pattern"); |
||||
ep = classend(ms, p); /* points to what is next */ |
||||
previous = (s == ms.src_init) ? '\0' : s[-1]; |
||||
if ((matchbracketclass((byte)(previous), p, ep - 1) != 0) || |
||||
(matchbracketclass((byte)(s[0]), p, ep - 1) == 0)) return null; |
||||
p = ep; goto init; /* else return match(ms, s, ep); */ |
||||
} |
||||
default: |
||||
{ |
||||
if (isdigit((char)(p[1]))) |
||||
{ /* capture results (%0-%9)? */ |
||||
s = match_capture(ms, s, (byte)(p[1])); |
||||
if (s == null) return null; |
||||
p += 2; goto init; /* else return match(ms, s, p+2) */ |
||||
} |
||||
//ismeretlen hiba miatt lett ide átmásolva |
||||
{ /* it is a pattern item */ |
||||
CharPtr ep = classend(ms, p); /* points to what is next */ |
||||
int m = (s < ms.src_end) && (singlematch((byte)(s[0]), p, ep) != 0) ? 1 : 0; |
||||
switch (ep[0]) |
||||
{ |
||||
case '?': |
||||
{ /* optional */ |
||||
CharPtr res; |
||||
if ((m != 0) && ((res = match(ms, s + 1, ep + 1)) != null)) |
||||
return res; |
||||
p = ep + 1; goto init; /* else return match(ms, s, ep+1); */ |
||||
} |
||||
case '*': |
||||
{ /* 0 or more repetitions */ |
||||
return max_expand(ms, s, p, ep); |
||||
} |
||||
case '+': |
||||
{ /* 1 or more repetitions */ |
||||
return ((m != 0) ? max_expand(ms, s + 1, p, ep) : null); |
||||
} |
||||
case '-': |
||||
{ /* 0 or more repetitions (minimum) */ |
||||
return min_expand(ms, s, p, ep); |
||||
} |
||||
default: |
||||
{ |
||||
if (m == 0) return null; |
||||
s = s.next(); p = ep; goto init; /* else return match(ms, s+1, ep); */ |
||||
} |
||||
} |
||||
} |
||||
//goto dflt; /* case default */ |
||||
} |
||||
} |
||||
} |
||||
case '\0': |
||||
{ /* end of pattern */ |
||||
return s; /* match succeeded */ |
||||
} |
||||
case '$': |
||||
{ |
||||
if (p[1] == '\0') /* is the `$' the last char in pattern? */ |
||||
return (s == ms.src_end) ? s : null; /* check end of string */ |
||||
else goto dflt; |
||||
} |
||||
default: |
||||
dflt: |
||||
{ /* it is a pattern item */ |
||||
CharPtr ep = classend(ms, p); /* points to what is next */ |
||||
int m = (s < ms.src_end) && (singlematch((byte)(s[0]), p, ep) != 0) ? 1 : 0; |
||||
switch (ep[0]) |
||||
{ |
||||
case '?': |
||||
{ /* optional */ |
||||
CharPtr res; |
||||
if ((m != 0) && ((res = match(ms, s + 1, ep + 1)) != null)) |
||||
return res; |
||||
p = ep + 1; goto init; /* else return match(ms, s, ep+1); */ |
||||
} |
||||
case '*': |
||||
{ /* 0 or more repetitions */ |
||||
return max_expand(ms, s, p, ep); |
||||
} |
||||
case '+': |
||||
{ /* 1 or more repetitions */ |
||||
return ((m != 0) ? max_expand(ms, s + 1, p, ep) : null); |
||||
} |
||||
case '-': |
||||
{ /* 0 or more repetitions (minimum) */ |
||||
return min_expand(ms, s, p, ep); |
||||
} |
||||
default: |
||||
{ |
||||
if (m == 0) return null; |
||||
s = s.next(); p = ep; goto init; /* else return match(ms, s+1, ep); */ |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
private static CharPtr lmemfind(CharPtr s1, uint l1, |
||||
CharPtr s2, uint l2) |
||||
{ |
||||
if (l2 == 0) return s1; /* empty strings are everywhere */ |
||||
else if (l2 > l1) return null; /* avoids a negative `l1' */ |
||||
else |
||||
{ |
||||
CharPtr init; /* to search for a `*s2' inside `s1' */ |
||||
l2--; /* 1st char will be checked by `memchr' */ |
||||
l1 = l1 - l2; /* `s2' cannot be found after that */ |
||||
while (l1 > 0 && (init = memchr(s1, s2[0], l1)) != null) |
||||
{ |
||||
init = init.next(); /* 1st char is already checked */ |
||||
if (memcmp(init, s2 + 1, l2) == 0) |
||||
return init - 1; |
||||
else |
||||
{ /* correct `l1' and `s1' to try again */ |
||||
l1 -= (uint)(init - s1); |
||||
s1 = init; |
||||
} |
||||
} |
||||
return null; /* not found */ |
||||
} |
||||
} |
||||
|
||||
|
||||
private static void push_onecapture(MatchState ms, int i, CharPtr s, |
||||
CharPtr e) |
||||
{ |
||||
if (i >= ms.level) |
||||
{ |
||||
if (i == 0) /* ms.level == 0, too */ |
||||
LuaPushLString(ms.L, s, (uint)(e - s)); /* add whole match */ |
||||
else |
||||
LuaLError(ms.L, "invalid capture index"); |
||||
} |
||||
else |
||||
{ |
||||
ptrdiff_t l = ms.capture[i].len; |
||||
if (l == CAP_UNFINISHED) LuaLError(ms.L, "unfinished capture"); |
||||
if (l == CAP_POSITION) |
||||
LuaPushInteger(ms.L, ms.capture[i].init - ms.src_init + 1); |
||||
else |
||||
LuaPushLString(ms.L, ms.capture[i].init, (uint)l); |
||||
} |
||||
} |
||||
|
||||
|
||||
private static int push_captures(MatchState ms, CharPtr s, CharPtr e) |
||||
{ |
||||
int i; |
||||
int nlevels = ((ms.level == 0) && (s != null)) ? 1 : ms.level; |
||||
LuaLCheckStack(ms.L, nlevels, "too many captures"); |
||||
for (i = 0; i < nlevels; i++) |
||||
push_onecapture(ms, i, s, e); |
||||
return nlevels; /* number of strings pushed */ |
||||
} |
||||
|
||||
|
||||
private static int str_find_aux(LuaState L, int find) |
||||
{ |
||||
uint l1, l2; |
||||
CharPtr s = LuaLCheckLString(L, 1, out l1); |
||||
CharPtr p = PatchPattern(LuaLCheckLString(L, 2, out l2)); |
||||
|
||||
ptrdiff_t init = posrelat(LuaLOptInteger(L, 3, 1), l1) - 1; |
||||
if (init < 0) init = 0; |
||||
else if ((uint)(init) > l1) init = (ptrdiff_t)l1; |
||||
if ((find != 0) && ((LuaToBoolean(L, 4) != 0) || /* explicit request? */ |
||||
strpbrk(p, SPECIALS) == null)) |
||||
{ /* or no special characters? */ |
||||
/* do a plain search */ |
||||
CharPtr s2 = lmemfind(s + init, (uint)(l1 - init), p, (uint)(l2)); |
||||
if (s2 != null) |
||||
{ |
||||
LuaPushInteger(L, s2 - s + 1); |
||||
LuaPushInteger(L, (int)(s2 - s + l2)); |
||||
return 2; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
MatchState ms = new MatchState(); |
||||
int anchor = 0; |
||||
if (p[0] == '^') |
||||
{ |
||||
p = p.next(); |
||||
anchor = 1; |
||||
} |
||||
CharPtr s1 = s + init; |
||||
ms.L = L; |
||||
ms.matchdepth = MAXCCALLS; |
||||
ms.src_init = s; |
||||
ms.src_end = s + l1; |
||||
do |
||||
{ |
||||
CharPtr res; |
||||
ms.level = 0; |
||||
// LuaAssert(ms.matchdepth == MAXCCALLS); |
||||
ms.matchdepth = MAXCCALLS; |
||||
if ((res = match(ms, s1, p)) != null) |
||||
{ |
||||
if (find != 0) |
||||
{ |
||||
LuaPushInteger(L, s1 - s + 1); /* start */ |
||||
LuaPushInteger(L, res - s); /* end */ |
||||
return push_captures(ms, null, null) + 2; |
||||
} |
||||
else |
||||
return push_captures(ms, s1, res); |
||||
} |
||||
} while (((s1 = s1.next()) <= ms.src_end) && (anchor == 0)); |
||||
} |
||||
LuaPushNil(L); /* not found */ |
||||
return 1; |
||||
} |
||||
|
||||
|
||||
public static int str_find(LuaState L) |
||||
{ |
||||
return str_find_aux(L, 1); |
||||
} |
||||
|
||||
|
||||
public static int str_match(LuaState L) |
||||
{ |
||||
return str_find_aux(L, 0); |
||||
} |
||||
|
||||
private class GMatchAuxData |
||||
{ |
||||
public CharPtr S; |
||||
public CharPtr P; |
||||
public uint LS; |
||||
public uint POS; |
||||
} |
||||
|
||||
|
||||
private static int gmatch_aux(LuaState L, GMatchAuxData auxdata) |
||||
{ |
||||
MatchState ms = new MatchState(); |
||||
uint ls = auxdata.LS; |
||||
CharPtr s = auxdata.S; |
||||
CharPtr p = auxdata.P; |
||||
CharPtr src; |
||||
ms.L = L; |
||||
ms.matchdepth = MAXCCALLS; |
||||
ms.src_init = s; |
||||
ms.src_end = s + ls; |
||||
for (src = s + auxdata.POS; |
||||
src <= ms.src_end; |
||||
src = src.next()) |
||||
{ |
||||
CharPtr e; |
||||
ms.level = 0; |
||||
//LuaAssert(ms.matchdepth == MAXCCALLS); |
||||
ms.matchdepth = MAXCCALLS; |
||||
|
||||
if ((e = match(ms, src, p)) != null) |
||||
{ |
||||
lua_Integer newstart = e - s; |
||||
if (e == src) newstart++; /* empty match? go at least one position */ |
||||
auxdata.POS = (uint)newstart; |
||||
return push_captures(ms, src, e); |
||||
} |
||||
} |
||||
return 0; /* not found */ |
||||
} |
||||
|
||||
|
||||
private static DynValue gmatch_aux_2(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return executionContext.EmulateClassicCall(args, "gmatch", |
||||
L => gmatch_aux(L, (GMatchAuxData)executionContext.AdditionalData)); |
||||
} |
||||
|
||||
|
||||
public static int str_gmatch(LuaState L) |
||||
{ |
||||
CallbackFunction C = new CallbackFunction(gmatch_aux_2, "gmatch"); |
||||
string s = ArgAsType(L, 1, DataType.String, false).String; |
||||
string p = PatchPattern(ArgAsType(L, 2, DataType.String, false).String); |
||||
|
||||
|
||||
C.AdditionalData = new GMatchAuxData() |
||||
{ |
||||
S = new CharPtr(s), |
||||
P = new CharPtr(p), |
||||
LS = (uint)s.Length, |
||||
POS = 0 |
||||
}; |
||||
|
||||
L.Push(DynValue.NewCallback(C)); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
|
||||
private static int gfind_nodef(LuaState L) |
||||
{ |
||||
return LuaLError(L, LUA_QL("string.gfind") + " was renamed to " + |
||||
LUA_QL("string.gmatch")); |
||||
} |
||||
|
||||
|
||||
private static void add_s(MatchState ms, LuaLBuffer b, CharPtr s, CharPtr e) |
||||
{ |
||||
uint l, i; |
||||
CharPtr news = LuaToLString(ms.L, 3, out l); |
||||
for (i = 0; i < l; i++) |
||||
{ |
||||
if (news[i] != L_ESC) |
||||
LuaLAddChar(b, news[i]); |
||||
else |
||||
{ |
||||
i++; /* skip ESC */ |
||||
if (!isdigit((char)(news[i]))) |
||||
{ |
||||
if (news[i] != L_ESC) |
||||
{ |
||||
LuaLError(ms.L, "invalid use of '%' in replacement string"); |
||||
} |
||||
LuaLAddChar(b, news[i]); |
||||
} |
||||
else if (news[i] == '0') |
||||
LuaLAddLString(b, s, (uint)(e - s)); |
||||
else |
||||
{ |
||||
push_onecapture(ms, news[i] - '1', s, e); |
||||
LuaLAddValue(b); /* add capture to accumulated result */ |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
private static void add_value(MatchState ms, LuaLBuffer b, CharPtr s, |
||||
CharPtr e) |
||||
{ |
||||
LuaState L = ms.L; |
||||
switch (LuaType(L, 3)) |
||||
{ |
||||
case LUA_TNUMBER: |
||||
case LUA_TSTRING: |
||||
{ |
||||
add_s(ms, b, s, e); |
||||
return; |
||||
} |
||||
// case LUA_TUSERDATA: /// +++ does this make sense ?? |
||||
case LUA_TFUNCTION: |
||||
{ |
||||
int n; |
||||
LuaPushValue(L, 3); |
||||
n = push_captures(ms, s, e); |
||||
LuaCall(L, n, 1); |
||||
break; |
||||
} |
||||
case LUA_TTABLE: |
||||
{ |
||||
push_onecapture(ms, 0, s, e); |
||||
LuaGetTable(L, 3); |
||||
break; |
||||
} |
||||
} |
||||
if (LuaToBoolean(L, -1) == 0) |
||||
{ /* nil or false? */ |
||||
LuaPop(L, 1); |
||||
LuaPushLString(L, s, (uint)(e - s)); /* keep original text */ |
||||
} |
||||
else if (LuaIsString(L, -1) == 0) |
||||
LuaLError(L, "invalid replacement value (a {0})", LuaLTypeName(L, -1)); |
||||
|
||||
LuaLAddValue(b); /* add result to accumulator */ |
||||
} |
||||
|
||||
|
||||
public static int str_gsub(LuaState L) |
||||
{ |
||||
uint srcl; |
||||
CharPtr src = LuaLCheckLString(L, 1, out srcl); |
||||
CharPtr p = PatchPattern(LuaLCheckStringStr(L, 2)); |
||||
int tr = LuaType(L, 3); |
||||
int max_s = LuaLOptInt(L, 4, (int)(srcl + 1)); |
||||
int anchor = 0; |
||||
if (p[0] == '^') |
||||
{ |
||||
p = p.next(); |
||||
anchor = 1; |
||||
} |
||||
int n = 0; |
||||
MatchState ms = new MatchState(); |
||||
LuaLBuffer b = new LuaLBuffer(L); |
||||
LuaLArgCheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || |
||||
tr == LUA_TFUNCTION || tr == LUA_TTABLE || |
||||
tr == LUA_TUSERDATA, 3, |
||||
"string/function/table expected"); |
||||
LuaLBuffInit(L, b); |
||||
ms.L = L; |
||||
ms.matchdepth = MAXCCALLS; |
||||
ms.src_init = src; |
||||
ms.src_end = src + srcl; |
||||
while (n < max_s) |
||||
{ |
||||
CharPtr e; |
||||
ms.level = 0; |
||||
//LuaAssert(ms.matchdepth == MAXCCALLS); |
||||
ms.matchdepth = MAXCCALLS; |
||||
e = match(ms, src, p); |
||||
if (e != null) |
||||
{ |
||||
n++; |
||||
add_value(ms, b, src, e); |
||||
} |
||||
if ((e != null) && e > src) /* non empty match? */ |
||||
src = e; /* skip it */ |
||||
else if (src < ms.src_end) |
||||
{ |
||||
char c = src[0]; |
||||
src = src.next(); |
||||
LuaLAddChar(b, c); |
||||
} |
||||
else break; |
||||
if (anchor != 0) break; |
||||
} |
||||
LuaLAddLString(b, src, (uint)(ms.src_end - src)); |
||||
LuaLPushResult(b); |
||||
LuaPushInteger(L, n); /* number of substitutions */ |
||||
return 2; |
||||
} |
||||
|
||||
|
||||
/* }====================================================== */ |
||||
|
||||
|
||||
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ |
||||
public const int MAX_ITEM = 512; |
||||
/* valid flags in a format specification */ |
||||
public const string FLAGS = "-+ #0"; |
||||
/* |
||||
** maximum size of each format specification (such as '%-099.99d') |
||||
** (+10 accounts for %99.99x plus margin of error) |
||||
*/ |
||||
public static readonly int MAX_FORMAT = (FLAGS.Length + 1) + (LUA_INTFRMLEN.Length + 1) + 10; |
||||
|
||||
|
||||
private static void addquoted(LuaState L, LuaLBuffer b, int arg) |
||||
{ |
||||
uint l; |
||||
CharPtr s = LuaLCheckLString(L, arg, out l); |
||||
LuaLAddChar(b, '"'); |
||||
while ((l--) != 0) |
||||
{ |
||||
switch (s[0]) |
||||
{ |
||||
case '"': |
||||
case '\\': |
||||
case '\n': |
||||
{ |
||||
LuaLAddChar(b, '\\'); |
||||
LuaLAddChar(b, s[0]); |
||||
break; |
||||
} |
||||
case '\r': |
||||
{ |
||||
LuaLAddLString(b, "\\r", 2); |
||||
break; |
||||
} |
||||
default: |
||||
{ |
||||
if (s[0] < (char)16) |
||||
{ |
||||
bool isfollowedbynum = false; |
||||
|
||||
if (l >= 1) |
||||
{ |
||||
if (char.IsNumber(s[1])) |
||||
isfollowedbynum = true; |
||||
} |
||||
|
||||
if (isfollowedbynum) |
||||
LuaLAddString(b, string.Format("\\{0:000}", (int)s[0])); |
||||
else |
||||
LuaLAddString(b, string.Format("\\{0}", (int)s[0])); |
||||
} |
||||
else |
||||
{ |
||||
LuaLAddChar(b, s[0]); |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
s = s.next(); |
||||
} |
||||
LuaLAddChar(b, '"'); |
||||
} |
||||
|
||||
private static CharPtr scanformat(LuaState L, CharPtr strfrmt, CharPtr form) |
||||
{ |
||||
CharPtr p = strfrmt; |
||||
while (p[0] != '\0' && strchr(FLAGS, p[0]) != null) p = p.next(); /* skip flags */ |
||||
if ((uint)(p - strfrmt) >= (FLAGS.Length + 1)) |
||||
LuaLError(L, "invalid format (repeated flags)"); |
||||
if (isdigit((byte)(p[0]))) p = p.next(); /* skip width */ |
||||
if (isdigit((byte)(p[0]))) p = p.next(); /* (2 digits at most) */ |
||||
if (p[0] == '.') |
||||
{ |
||||
p = p.next(); |
||||
if (isdigit((byte)(p[0]))) p = p.next(); /* skip precision */ |
||||
if (isdigit((byte)(p[0]))) p = p.next(); /* (2 digits at most) */ |
||||
} |
||||
if (isdigit((byte)(p[0]))) |
||||
LuaLError(L, "invalid format (width or precision too long)"); |
||||
form[0] = '%'; |
||||
form = form.next(); |
||||
strncpy(form, strfrmt, p - strfrmt + 1); |
||||
form += p - strfrmt + 1; |
||||
form[0] = '\0'; |
||||
return p; |
||||
} |
||||
|
||||
|
||||
private static void addintlen(CharPtr form) |
||||
{ |
||||
uint l = (uint)strlen(form); |
||||
char spec = form[l - 1]; |
||||
strcpy(form + l - 1, LUA_INTFRMLEN); |
||||
form[l + (LUA_INTFRMLEN.Length + 1) - 2] = spec; |
||||
form[l + (LUA_INTFRMLEN.Length + 1) - 1] = '\0'; |
||||
} |
||||
|
||||
|
||||
public static int str_format(LuaState L) |
||||
{ |
||||
int top = LuaGetTop(L); |
||||
int arg = 1; |
||||
uint sfl; |
||||
CharPtr strfrmt = LuaLCheckLString(L, arg, out sfl); |
||||
CharPtr strfrmt_end = strfrmt + sfl; |
||||
LuaLBuffer b = new LuaLBuffer(L); |
||||
LuaLBuffInit(L, b); |
||||
while (strfrmt < strfrmt_end) |
||||
{ |
||||
if (strfrmt[0] != L_ESC) |
||||
{ |
||||
LuaLAddChar(b, strfrmt[0]); |
||||
strfrmt = strfrmt.next(); |
||||
} |
||||
else if (strfrmt[1] == L_ESC) |
||||
{ |
||||
LuaLAddChar(b, strfrmt[0]); /* %% */ |
||||
strfrmt = strfrmt + 2; |
||||
} |
||||
else |
||||
{ /* format item */ |
||||
strfrmt = strfrmt.next(); |
||||
CharPtr form = new char[MAX_FORMAT]; /* to store the format (`%...') */ |
||||
CharPtr buff = new char[MAX_ITEM]; /* to store the formatted item */ |
||||
if (++arg > top) |
||||
LuaLArgError(L, arg, "no value"); |
||||
strfrmt = scanformat(L, strfrmt, form); |
||||
char ch = strfrmt[0]; |
||||
strfrmt = strfrmt.next(); |
||||
switch (ch) |
||||
{ |
||||
case 'c': |
||||
{ |
||||
sprintf(buff, form, (int)LuaLCheckNumber(L, arg)); |
||||
break; |
||||
} |
||||
case 'd': |
||||
case 'i': |
||||
{ |
||||
addintlen(form); |
||||
sprintf(buff, form, (LUA_INTFRM_T)LuaLCheckNumber(L, arg)); |
||||
break; |
||||
} |
||||
case 'o': |
||||
case 'u': |
||||
case 'x': |
||||
case 'X': |
||||
{ |
||||
addintlen(form); |
||||
sprintf(buff, form, (UNSIGNED_LUA_INTFRM_T)LuaLCheckNumber(L, arg)); |
||||
break; |
||||
} |
||||
case 'e': |
||||
case 'E': |
||||
case 'f': |
||||
case 'g': |
||||
case 'G': |
||||
{ |
||||
sprintf(buff, form, (double)LuaLCheckNumber(L, arg)); |
||||
break; |
||||
} |
||||
case 'q': |
||||
{ |
||||
addquoted(L, b, arg); |
||||
continue; /* skip the 'addsize' at the end */ |
||||
} |
||||
case 's': |
||||
{ |
||||
uint l; |
||||
CharPtr s = LuaLCheckLString(L, arg, out l); |
||||
if ((strchr(form, '.') == null) && l >= 100) |
||||
{ |
||||
/* no precision and string is too long to be formatted; |
||||
keep original string */ |
||||
LuaPushValue(L, arg); |
||||
LuaLAddValue(b); |
||||
continue; /* skip the `addsize' at the end */ |
||||
} |
||||
else |
||||
{ |
||||
sprintf(buff, form, s); |
||||
break; |
||||
} |
||||
} |
||||
default: |
||||
{ /* also treat cases `pnLlh' */ |
||||
return LuaLError(L, "invalid option " + LUA_QL("%" + ch) + " to " + |
||||
LUA_QL("format"), strfrmt[-1]); |
||||
} |
||||
} |
||||
LuaLAddLString(b, buff, (uint)strlen(buff)); |
||||
} |
||||
} |
||||
LuaLPushResult(b); |
||||
return 1; |
||||
} |
||||
|
||||
|
||||
private static string PatchPattern(string charPtr) |
||||
{ |
||||
return charPtr.Replace("\0", "%z"); |
||||
} |
||||
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d921f217918ee4c0e97d5ad218c273ab |
||||
timeCreated: 1475786656 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,56 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib.StringLib |
||||
{ |
||||
internal class StringRange |
||||
{ |
||||
public int Start { get; set; } |
||||
public int End { get; set; } |
||||
|
||||
public StringRange() |
||||
{ |
||||
Start = 0; |
||||
End = 0; |
||||
} |
||||
|
||||
public StringRange(int start, int end) |
||||
{ |
||||
Start = start; |
||||
End = end; |
||||
} |
||||
|
||||
public static StringRange FromLuaRange(DynValue start, DynValue end, int? defaultEnd = null) |
||||
{ |
||||
int i = start.IsNil() ? 1 : (int)start.Number; |
||||
int j = end.IsNil() ? (defaultEnd ?? i) : (int)end.Number; |
||||
|
||||
return new StringRange(i, j); |
||||
} |
||||
|
||||
|
||||
// Returns the substring of s that starts at i and continues until j; i and j can be negative. |
||||
// If, after the translation of negative indices, i is less than 1, it is corrected to 1. |
||||
// If j is greater than the string length, it is corrected to that length. |
||||
// If, after these corrections, i is greater than j, the function returns the empty string. |
||||
public string ApplyToString(string value) |
||||
{ |
||||
int i = Start < 0 ? Start + value.Length + 1 : Start; |
||||
int j = End < 0 ? End + value.Length + 1 : End; |
||||
|
||||
if (i < 1) i = 1; |
||||
if (j > value.Length) j = value.Length; |
||||
|
||||
if (i > j) |
||||
return string.Empty; |
||||
|
||||
return value.Substring(i - 1, j - i + 1); |
||||
} |
||||
|
||||
public int Length() |
||||
{ |
||||
return (End - Start) + 1; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 155a3aa6f6abc4dd5b920c33c2151dab |
||||
timeCreated: 1475786653 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,298 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Text; |
||||
using MoonSharp.Interpreter.CoreLib.StringLib; |
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing string Lua functions |
||||
/// </summary> |
||||
[MoonSharpModule(Namespace = "string")] |
||||
public class StringModule |
||||
{ |
||||
public const string BASE64_DUMP_HEADER = "MoonSharp_dump_b64::"; |
||||
|
||||
public static void MoonSharpInit(Table globalTable, Table stringTable) |
||||
{ |
||||
Table stringMetatable = new Table(globalTable.OwnerScript); |
||||
stringMetatable.Set("__index", DynValue.NewTable(stringTable)); |
||||
globalTable.OwnerScript.SetTypeMetatable(DataType.String, stringMetatable); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue dump(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue fn = args.AsType(0, "dump", DataType.Function, false); |
||||
|
||||
try |
||||
{ |
||||
byte[] bytes; |
||||
using (MemoryStream ms = new MemoryStream()) |
||||
{ |
||||
executionContext.GetScript().Dump(fn, ms); |
||||
ms.Seek(0, SeekOrigin.Begin); |
||||
bytes = ms.ToArray(); |
||||
} |
||||
string base64 = Convert.ToBase64String(bytes); |
||||
return DynValue.NewString(BASE64_DUMP_HEADER + base64); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
throw new ScriptRuntimeException(ex.Message); |
||||
} |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue @char(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(args.Count); |
||||
|
||||
for (int i = 0; i < args.Count; i++) |
||||
{ |
||||
DynValue v = args[i]; |
||||
double d = 0d; |
||||
|
||||
if (v.Type == DataType.String) |
||||
{ |
||||
double? nd = v.CastToNumber(); |
||||
if (nd == null) |
||||
args.AsType(i, "char", DataType.Number, false); |
||||
else |
||||
d = nd.Value; |
||||
} |
||||
else |
||||
{ |
||||
args.AsType(i, "char", DataType.Number, false); |
||||
d = v.Number; |
||||
} |
||||
|
||||
sb.Append((char)(d)); |
||||
} |
||||
|
||||
return DynValue.NewString(sb.ToString()); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue @byte(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue vs = args.AsType(0, "byte", DataType.String, false); |
||||
DynValue vi = args.AsType(1, "byte", DataType.Number, true); |
||||
DynValue vj = args.AsType(2, "byte", DataType.Number, true); |
||||
|
||||
return PerformByteLike(vs, vi, vj, |
||||
i => Unicode2Ascii(i)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue unicode(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue vs = args.AsType(0, "unicode", DataType.String, false); |
||||
DynValue vi = args.AsType(1, "unicode", DataType.Number, true); |
||||
DynValue vj = args.AsType(2, "unicode", DataType.Number, true); |
||||
|
||||
return PerformByteLike(vs, vi, vj, i => i); |
||||
} |
||||
|
||||
private static int Unicode2Ascii(int i) |
||||
{ |
||||
if (i >= 0 && i < 255) |
||||
return i; |
||||
|
||||
return (int)'?'; |
||||
} |
||||
|
||||
private static DynValue PerformByteLike(DynValue vs, DynValue vi, DynValue vj, Func<int, int> filter) |
||||
{ |
||||
StringRange range = StringRange.FromLuaRange(vi, vj, null); |
||||
string s = range.ApplyToString(vs.String); |
||||
|
||||
int length = s.Length; |
||||
DynValue[] rets = new DynValue[length]; |
||||
|
||||
for (int i = 0; i < length; ++i) |
||||
{ |
||||
rets[i] = DynValue.NewNumber(filter((int)s[i])); |
||||
} |
||||
|
||||
return DynValue.NewTuple(rets); |
||||
} |
||||
|
||||
|
||||
private static int? AdjustIndex(string s, DynValue vi, int defval) |
||||
{ |
||||
if (vi.IsNil()) |
||||
return defval; |
||||
|
||||
int i = (int)Math.Round(vi.Number, 0); |
||||
|
||||
if (i == 0) |
||||
return null; |
||||
|
||||
if (i > 0) |
||||
return i - 1; |
||||
|
||||
return s.Length - i; |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue len(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue vs = args.AsType(0, "len", DataType.String, false); |
||||
return DynValue.NewNumber(vs.String.Length); |
||||
} |
||||
|
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue match(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return executionContext.EmulateClassicCall(args, "match", KopiLua_StringLib.str_match); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue gmatch(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return executionContext.EmulateClassicCall(args, "gmatch", KopiLua_StringLib.str_gmatch); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue gsub(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return executionContext.EmulateClassicCall(args, "gsub", KopiLua_StringLib.str_gsub); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue find(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return executionContext.EmulateClassicCall(args, "find", |
||||
KopiLua_StringLib.str_find); |
||||
} |
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue lower(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg_s = args.AsType(0, "lower", DataType.String, false); |
||||
return DynValue.NewString(arg_s.String.ToLower()); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue upper(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg_s = args.AsType(0, "upper", DataType.String, false); |
||||
return DynValue.NewString(arg_s.String.ToUpper()); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue rep(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg_s = args.AsType(0, "rep", DataType.String, false); |
||||
DynValue arg_n = args.AsType(1, "rep", DataType.Number, false); |
||||
DynValue arg_sep = args.AsType(2, "rep", DataType.String, true); |
||||
|
||||
if (String.IsNullOrEmpty(arg_s.String) || (arg_n.Number < 1)) |
||||
{ |
||||
return DynValue.NewString(""); |
||||
} |
||||
|
||||
string sep = (arg_sep.IsNotNil()) ? arg_sep.String : null; |
||||
|
||||
int count = (int)arg_n.Number; |
||||
StringBuilder result = new StringBuilder(arg_s.String.Length * count); |
||||
|
||||
for (int i = 0; i < count; ++i) |
||||
{ |
||||
if (i != 0 && sep != null) |
||||
result.Append(sep); |
||||
|
||||
result.Append(arg_s.String); |
||||
} |
||||
|
||||
return DynValue.NewString(result.ToString()); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue format(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
return executionContext.EmulateClassicCall(args, "format", KopiLua_StringLib.str_format); |
||||
} |
||||
|
||||
|
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue reverse(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg_s = args.AsType(0, "reverse", DataType.String, false); |
||||
|
||||
if (String.IsNullOrEmpty(arg_s.String)) |
||||
{ |
||||
return DynValue.NewString(""); |
||||
} |
||||
|
||||
char[] elements = arg_s.String.ToCharArray(); |
||||
Array.Reverse(elements); |
||||
|
||||
return DynValue.NewString(new String(elements)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue sub(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg_s = args.AsType(0, "sub", DataType.String, false); |
||||
DynValue arg_i = args.AsType(1, "sub", DataType.Number, true); |
||||
DynValue arg_j = args.AsType(2, "sub", DataType.Number, true); |
||||
|
||||
StringRange range = StringRange.FromLuaRange(arg_i, arg_j, -1); |
||||
string s = range.ApplyToString(arg_s.String); |
||||
|
||||
return DynValue.NewString(s); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue startsWith(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg_s1 = args.AsType(0, "startsWith", DataType.String, true); |
||||
DynValue arg_s2 = args.AsType(1, "startsWith", DataType.String, true); |
||||
|
||||
if (arg_s1.IsNil() || arg_s2.IsNil()) |
||||
return DynValue.False; |
||||
|
||||
return DynValue.NewBoolean(arg_s1.String.StartsWith(arg_s2.String)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue endsWith(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg_s1 = args.AsType(0, "endsWith", DataType.String, true); |
||||
DynValue arg_s2 = args.AsType(1, "endsWith", DataType.String, true); |
||||
|
||||
if (arg_s1.IsNil() || arg_s2.IsNil()) |
||||
return DynValue.False; |
||||
|
||||
return DynValue.NewBoolean(arg_s1.String.EndsWith(arg_s2.String)); |
||||
} |
||||
|
||||
[MoonSharpModuleMethod] |
||||
public static DynValue contains(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue arg_s1 = args.AsType(0, "contains", DataType.String, true); |
||||
DynValue arg_s2 = args.AsType(1, "contains", DataType.String, true); |
||||
|
||||
if (arg_s1.IsNil() || arg_s2.IsNil()) |
||||
return DynValue.False; |
||||
|
||||
return DynValue.NewBoolean(arg_s1.String.Contains(arg_s2.String)); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: b3eb3848b53e142a483d14eb6b5b0484 |
||||
timeCreated: 1475786655 |
||||
licenseType: Pro |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,92 @@
|
||||
// Disable warnings about XML documentation |
||||
#pragma warning disable 1591 |
||||
|
||||
|
||||
namespace MoonSharp.Interpreter.CoreLib |
||||
{ |
||||
/// <summary> |
||||
/// Class implementing table Lua iterators (pairs, ipairs, next) |
||||
/// </summary> |
||||
[MoonSharpModule] |
||||
public class TableIteratorsModule |
||||
{ |
||||
// ipairs (t) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
// If t has a metamethod __ipairs, calls it with t as argument and returns the first three results from the call. |
||||
// Otherwise, returns three values: an iterator function, the table t, and 0, so that the construction |
||||
// for i,v in ipairs(t) do body end |
||||
// will iterate over the pairs (1,t[1]), (2,t[2]), ..., up to the first integer key absent from the table. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue ipairs(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue table = args[0]; |
||||
|
||||
DynValue meta = executionContext.GetMetamethodTailCall(table, "__ipairs", args.GetArray()); |
||||
|
||||
return meta ?? DynValue.NewTuple(DynValue.NewCallback(__next_i), table, DynValue.NewNumber(0)); |
||||
} |
||||
|
||||
// pairs (t) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
// If t has a metamethod __pairs, calls it with t as argument and returns the first three results from the call. |
||||
// Otherwise, returns three values: the next function, the table t, and nil, so that the construction |
||||
// for k,v in pairs(t) do body end |
||||
// will iterate over all key–value pairs of table t. |
||||
// See function next for the caveats of modifying the table during its traversal. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue pairs(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue table = args[0]; |
||||
|
||||
DynValue meta = executionContext.GetMetamethodTailCall(table, "__pairs", args.GetArray()); |
||||
|
||||
return meta ?? DynValue.NewTuple(DynValue.NewCallback(next), table); |
||||
} |
||||
|
||||
// next (table [, index]) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
// Allows a program to traverse all fields of a table. Its first argument is a table and its second argument is an |
||||
// index in this table. next returns the next index of the table and its associated value. |
||||
// When called with nil as its second argument, next returns an initial index and its associated value. |
||||
// When called with the last index, or with nil in an empty table, next returns nil. If the second argument is absent, |
||||
// then it is interpreted as nil. In particular, you can use next(t) to check whether a table is empty. |
||||
// The order in which the indices are enumerated is not specified, even for numeric indices. |
||||
// (To traverse a table in numeric order, use a numerical for.) |
||||
// The behavior of next is undefined if, during the traversal, you assign any value to a non-existent field in the table. |
||||
// You may however modify existing fields. In particular, you may clear existing fields. |
||||
[MoonSharpModuleMethod] |
||||
public static DynValue next(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue table = args.AsType(0, "next", DataType.Table); |
||||
DynValue index = args[1]; |
||||
|
||||
TablePair? pair = table.Table.NextKey(index); |
||||
|
||||
if (pair.HasValue) |
||||
return DynValue.NewTuple(pair.Value.Key, pair.Value.Value); |
||||
else |
||||
throw new ScriptRuntimeException("invalid key to 'next'"); |
||||
} |
||||
|
||||
// __next_i (table [, index]) |
||||
// ------------------------------------------------------------------------------------------------------------------- |
||||
// Allows a program to traverse all fields of an array. index is an integer number |
||||
public static DynValue __next_i(ScriptExecutionContext executionContext, CallbackArguments args) |
||||
{ |
||||
DynValue table = args.AsType(0, "!!next_i!!", DataType.Table); |
||||
DynValue index = args.AsType(1, "!!next_i!!", DataType.Number); |
||||
|
||||
int idx = ((int)index.Number) + 1; |
||||
DynValue val = table.Table.Get(idx); |
||||
|
||||
if (val.Type != DataType.Nil) |
||||
{ |
||||
return DynValue.NewTuple(DynValue.NewNumber(idx), val); |
||||
} |
||||
else |
||||
{ |
||||
return DynValue.Nil; |
||||
} |
||||
} |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue