/parsing/d/destructorunit.d

http://github.com/wilkie/djehuty · D · 191 lines · 137 code · 18 blank · 36 comment · 47 complexity · 614a014882c44f3c9e96d5046ec30b40 MD5 · raw file

  1. /*
  2. * expressionunit.d
  3. *
  4. * This module parses expressions.
  5. *
  6. */
  7. module parsing.d.destructorunit;
  8. import parsing.parseunit;
  9. import parsing.token;
  10. import parsing.d.tokens;
  11. import parsing.d.nodes;
  12. import parsing.d.parameterlistunit;
  13. import parsing.d.functionbodyunit;
  14. import io.console;
  15. import djehuty;
  16. class DestructorUnit : ParseUnit {
  17. override bool tokenFound(Token current) {
  18. switch (current.type) {
  19. // First, we look for the left paren of the parameter list
  20. case DToken.LeftParen:
  21. if (!thisFound) {
  22. // Error: Need this after ~
  23. error(_common_error_msg,
  24. "Did you intend on having a destructor here? You are missing 'this'.",
  25. _common_error_usages);
  26. }
  27. else if (this.state != 0) {
  28. // It should be the first thing!
  29. // Error: Too many left parentheses!
  30. error(_common_error_msg,
  31. "You accidentally placed too many left parentheses here.",
  32. _common_error_usages);
  33. }
  34. this.state = 1;
  35. break;
  36. // After finding a left paren, look for a right one
  37. case DToken.RightParen:
  38. if (!thisFound) {
  39. // Error: Need this after ~
  40. error(_common_error_msg,
  41. null,
  42. _common_error_usages);
  43. }
  44. else if (this.state == 0) {
  45. // Error: No left paren found before this right one!
  46. error(_common_error_msg,
  47. "You are missing a left parenthesis.",
  48. _common_error_usages);
  49. }
  50. else if (this.state != 1) {
  51. // Error: Already parsed a right paren! We have too many right parens!
  52. error(_common_error_msg,
  53. "You have placed too many right parentheses.",
  54. _common_error_usages);
  55. }
  56. this.state = 2;
  57. break;
  58. // Look for the end of a bodyless declaration
  59. case DToken.Semicolon:
  60. if (!thisFound) {
  61. // Error: Need this after ~
  62. error(_common_error_msg,
  63. "A '~' does nothing on its own.",
  64. _common_error_usages);
  65. }
  66. else if (this.state == 0) {
  67. // Error: Have not found a left paren!
  68. error(_common_error_msg,
  69. "You must have a empty parameter list for your destructor.",
  70. _common_error_usages);
  71. }
  72. else if (this.state != 2) {
  73. // Error: Have not found a right paren!
  74. error(_common_error_msg,
  75. "You accidentally left out a right parenthesis.",
  76. _common_error_usages);
  77. }
  78. // Done.
  79. return false;
  80. // Function body
  81. case DToken.In:
  82. case DToken.Out:
  83. case DToken.Body:
  84. case DToken.LeftCurly:
  85. // Have we found a parameter list?
  86. if (!thisFound) {
  87. // Error: Need this after ~
  88. error(_common_error_msg,
  89. null,
  90. _common_error_usages);
  91. }
  92. else if (this.state == 0 ) {
  93. // Error: No parameter list given at all
  94. error(_common_error_msg,
  95. "You must have an empty parameter list for a destructor.",
  96. _common_error_usages);
  97. }
  98. else if (this.state == 1) {
  99. // Error: We have a left parenthesis... but no right one
  100. error(_common_error_msg,
  101. "You have accidentally left out a right parenthesis.",
  102. _common_error_usages);
  103. }
  104. // Function body!
  105. lexer.push(current);
  106. auto tree = expand!(FunctionBodyUnit)();
  107. Console.putln("Destructor");
  108. // Done.
  109. return false;
  110. // We are only given that the first token, ~, is found...
  111. // So, we must ensure that the This keyword is the first item
  112. case DToken.This:
  113. if (this.state == 0 && !thisFound) {
  114. thisFound = true;
  115. }
  116. else if (this.state == 0 && thisFound) {
  117. // Error: this this <- listed twice in a row
  118. error(_common_error_msg,
  119. "You accidentally placed two 'this' in a row.",
  120. _common_error_usages);
  121. }
  122. else if (this.state == 1) {
  123. // Error: Expected right paren, got this.
  124. error(_common_error_msg,
  125. "The parameter list should be empty for a destructor.",
  126. _common_error_usages);
  127. }
  128. else {
  129. // Error: Got this, expected function body or ;
  130. error(_common_error_msg,
  131. "You probably forgot a semicolon.",
  132. _common_error_usages);
  133. }
  134. break;
  135. // All other tokens are errors.
  136. default:
  137. if (!thisFound) {
  138. // Error: Need this after ~
  139. error(_common_error_msg,
  140. "A '~' character is unexpected here.",
  141. _common_error_usages);
  142. }
  143. else if (this.state == 0) {
  144. // Error this BLEH...Need ()
  145. error(_common_error_msg,
  146. "The destructor must have an empty parameter list: ~this ()",
  147. _common_error_usages);
  148. }
  149. else if (this.state == 1) {
  150. // Error: Expected right paren
  151. error(_common_error_msg,
  152. "The destructor must have an empty parameter list: ~this ()",
  153. _common_error_usages);
  154. }
  155. else if (this.state == 2) {
  156. // Error: this(...) BLEH... Need function body or semicolon!
  157. error(_common_error_msg,
  158. "You are probably missing a curly brace or a semicolon.",
  159. _common_error_usages);
  160. }
  161. break;
  162. }
  163. return true;
  164. }
  165. protected:
  166. bool thisFound = false;
  167. string cur_string = "";
  168. static const string _common_error_msg = "Destructor declaration invalid.";
  169. static const string[] _common_error_usages = [
  170. "~this() { }",
  171. "~this();"
  172. ];
  173. }