Library.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Yarn
  4. {
  5. public delegate Object ReturningFunction (params Value[] parameters);
  6. public delegate void Function (params Value[] parameters);
  7. public class FunctionInfo {
  8. // The name of the function, as it exists in the script.
  9. public string name { get; private set;}
  10. // The number of parameters this function requires.
  11. // -1 = the function will accept any number of params
  12. public int paramCount {get; private set;}
  13. // The actual implementation of the function.
  14. // Comes in two flavours: a returning one, and a non-returning one.
  15. // Doing this means that you don't have to add "return null"
  16. // to the end of a function if it doesn't return values.
  17. public Function function { get; private set; }
  18. public ReturningFunction returningFunction { get; private set; }
  19. // Does this function return a value?
  20. public bool returnsValue {
  21. get {
  22. return returningFunction != null;
  23. }
  24. }
  25. public Value Invoke(params Value[] parameters) {
  26. return InvokeWithArray(parameters);
  27. }
  28. public Value InvokeWithArray(Value[] parameters) {
  29. int length;
  30. if (parameters != null)
  31. length = parameters.Length;
  32. else
  33. length = 0;
  34. if (IsParameterCountCorrect (length)) {
  35. if (returnsValue) {
  36. return new Value(returningFunction (parameters));
  37. } else {
  38. function (parameters);
  39. return Value.NULL; // a null Value
  40. }
  41. } else {
  42. string error = string.Format (
  43. "Incorrect number of parameters for function {0} (expected {1}, got {2}",
  44. this.name,
  45. this.paramCount,
  46. parameters.Length);
  47. throw new InvalidOperationException (error);
  48. }
  49. }
  50. // TODO: support for typed parameters
  51. // TODO: support for return type
  52. internal FunctionInfo(string name, int paramCount, Function implementation) {
  53. this.name = name;
  54. this.paramCount = paramCount;
  55. this.function = implementation;
  56. this.returningFunction = null;
  57. }
  58. internal FunctionInfo(string name, int paramCount, ReturningFunction implementation) {
  59. this.name = name;
  60. this.paramCount = paramCount;
  61. this.returningFunction = implementation;
  62. this.function = null;
  63. }
  64. internal bool IsParameterCountCorrect (int parameterCount)
  65. {
  66. return paramCount == parameterCount || paramCount == -1;
  67. }
  68. }
  69. // A Library is a collection of callable functions.
  70. public class Library
  71. {
  72. private Dictionary<string, FunctionInfo> functions = new Dictionary<string, FunctionInfo>();
  73. // Returns a function; throws an exception if it doesn't exist.
  74. // Use FunctionExists to check for a function's existence.
  75. public FunctionInfo GetFunction(string name) {
  76. try {
  77. return functions [name];
  78. } catch (KeyNotFoundException) {
  79. throw new InvalidOperationException (name + " is not a valid function");
  80. }
  81. }
  82. // Loads functions from another library. If the other library
  83. // contains a function with the same name as ours, ours will be
  84. // replaced.
  85. public void ImportLibrary(Library otherLibrary) {
  86. foreach (var entry in otherLibrary.functions) {
  87. functions [entry.Key] = entry.Value;
  88. }
  89. }
  90. public void RegisterFunction(FunctionInfo function) {
  91. functions [function.name] = function;
  92. }
  93. public void RegisterFunction(string name, int parameterCount, ReturningFunction implementation) {
  94. var info = new FunctionInfo (name, parameterCount, implementation);
  95. RegisterFunction (info);
  96. }
  97. public void RegisterFunction(string name, int parameterCount, Function implementation) {
  98. var info = new FunctionInfo (name, parameterCount, implementation);
  99. RegisterFunction (info);
  100. }
  101. public bool FunctionExists(string name) {
  102. return functions.ContainsKey (name);
  103. }
  104. public void DeregisterFunction(string name) {
  105. if (functions.ContainsKey(name))
  106. functions.Remove (name);
  107. }
  108. }
  109. }