PageRenderTime 18ms CodeModel.GetById 1ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

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