LoadMethods.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using MoonSharp.Interpreter.Execution;
  6. namespace MoonSharp.Interpreter.CoreLib
  7. {
  8. [MoonSharpModule]
  9. public class LoadMethods
  10. {
  11. // load (ld [, source [, mode [, env]]])
  12. // ----------------------------------------------------------------
  13. // Loads a chunk.
  14. //
  15. // If ld is a string, the chunk is this string.
  16. //
  17. // If there are no syntactic errors, returns the compiled chunk as a function;
  18. // otherwise, returns nil plus the error message.
  19. //
  20. // source is used as the source of the chunk for error messages and debug
  21. // information (see §4.9). When absent, it defaults to ld, if ld is a string,
  22. // or to "=(load)" otherwise.
  23. //
  24. // The string mode is ignored, and assumed to be "t";
  25. [MoonSharpMethod]
  26. public static DynValue load(ScriptExecutionContext executionContext, CallbackArguments args)
  27. {
  28. try
  29. {
  30. Script S = executionContext.GetScript();
  31. DynValue ld = args[0];
  32. string script = "";
  33. if (ld.Type == DataType.Function)
  34. {
  35. while (true)
  36. {
  37. DynValue ret = executionContext.GetScript().Call(ld);
  38. if (ret.Type == DataType.String && ret.String.Length > 0)
  39. script += ret.String;
  40. else
  41. break;
  42. }
  43. }
  44. else if (ld.Type == DataType.String)
  45. {
  46. script = ld.String;
  47. }
  48. else
  49. {
  50. args.AsType(0, "load", DataType.Function, false);
  51. }
  52. DynValue source = args.AsType(1, "load", DataType.String, true);
  53. DynValue env = args.AsType(3, "load", DataType.Table, true);
  54. DynValue fn = S.LoadString(script,
  55. !env.IsNil() ? env.Table : null,
  56. !source.IsNil() ? source.String : "=(load)");
  57. return fn;
  58. }
  59. catch (SyntaxErrorException ex)
  60. {
  61. return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.Message));
  62. }
  63. }
  64. // loadfile ([filename [, mode [, env]]])
  65. // ----------------------------------------------------------------
  66. // Similar to load, but gets the chunk from file filename or from the standard input,
  67. // if no file name is given. INCOMPAT: stdin not supported, mode ignored
  68. [MoonSharpMethod]
  69. public static DynValue loadfile(ScriptExecutionContext executionContext, CallbackArguments args)
  70. {
  71. try
  72. {
  73. Script S = executionContext.GetScript();
  74. DynValue filename = args.AsType(0, "loadfile", DataType.String, false);
  75. DynValue env = args.AsType(2, "loadfile", DataType.Table, true);
  76. DynValue fn = S.LoadFile(filename.String, env.IsNil() ? null : env.Table);
  77. return fn;
  78. }
  79. catch (SyntaxErrorException ex)
  80. {
  81. return DynValue.NewTuple(DynValue.Nil, DynValue.NewString(ex.Message));
  82. }
  83. }
  84. //dofile ([filename])
  85. //--------------------------------------------------------------------------------------------------------------
  86. //Opens the named file and executes its contents as a Lua chunk. When called without arguments,
  87. //dofile executes the contents of the standard input (stdin). Returns all values returned by the chunk.
  88. //In case of errors, dofile propagates the error to its caller (that is, dofile does not run in protected mode).
  89. [MoonSharpMethod]
  90. public static DynValue dofile(ScriptExecutionContext executionContext, CallbackArguments args)
  91. {
  92. try
  93. {
  94. Script S = executionContext.GetScript();
  95. DynValue v = args.AsType(0, "dofile", DataType.String, false);
  96. DynValue fn = S.LoadFile(v.String);
  97. return DynValue.NewTailCallReq(fn); // tail call to dofile
  98. }
  99. catch (SyntaxErrorException ex)
  100. {
  101. throw new ScriptRuntimeException(ex);
  102. }
  103. }
  104. //require (modname)
  105. //----------------------------------------------------------------------------------------------------------------
  106. //Loads the given module. The function starts by looking into the package.loaded table to determine whether
  107. //modname is already loaded. If it is, then require returns the value stored at package.loaded[modname].
  108. //Otherwise, it tries to find a loader for the module.
  109. //
  110. //To find a loader, require is guided by the package.loaders array. By changing this array, we can change
  111. //how require looks for a module. The following explanation is based on the default configuration for package.loaders.
  112. //
  113. //First require queries package.preload[modname]. If it has a value, this value (which should be a function)
  114. //is the loader. Otherwise require searches for a Lua loader using the path stored in package.path.
  115. //If that also fails, it searches for a C loader using the path stored in package.cpath. If that also fails,
  116. //it tries an all-in-one loader (see package.loaders).
  117. //
  118. //Once a loader is found, require calls the loader with a single argument, modname. If the loader returns any value,
  119. //require assigns the returned value to package.loaded[modname]. If the loader returns no value and has not assigned
  120. //any value to package.loaded[modname], then require assigns true to this entry. In any case, require returns the
  121. //final value of package.loaded[modname].
  122. //
  123. //If there is any error loading or running the module, or if it cannot find any loader for the module, then require
  124. //signals an error.
  125. [MoonSharpMethod]
  126. public static DynValue __require_clr_impl(ScriptExecutionContext executionContext, CallbackArguments args)
  127. {
  128. Script S = executionContext.GetScript();
  129. DynValue v = args.AsType(0, "__require_clr_impl", DataType.String, false);
  130. DynValue fn = S.RequireModule(v.String);
  131. return fn; // tail call to dofile
  132. }
  133. [MoonSharpMethod]
  134. public const string require = @"
  135. function(modulename)
  136. if (package == nil) then package = { }; end
  137. if (package.loaded == nil) then package.loaded = { }; end
  138. local m = package.loaded[modulename];
  139. if (m ~= nil) then
  140. return m;
  141. end
  142. local func = __require_clr_impl(modulename);
  143. local res = func();
  144. package.loaded[modulename] = res;
  145. return res;
  146. end
  147. ";
  148. }
  149. }