PageRenderTime 68ms CodeModel.GetById 1ms app.highlight 62ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/dspec/output.d

http://github.com/wilkie/djehuty
D | 596 lines | 462 code | 110 blank | 24 comment | 78 complexity | 55c02f08110cf873e6c049de18b09932 MD5 | raw file
  1module output;
  2
  3import djehuty;
  4
  5import io.file;
  6import io.console;
  7
  8import ast;
  9import parser;
 10
 11class Output {
 12	this(string path) {
 13		if (!readyOutput(path)) {
 14			// Error: cannot write file
 15			Console.putln("Error: Cannot write to ", path);
 16		}
 17		printHeader();
 18	}
 19
 20	~this() {
 21	}
 22
 23	void work(AST result, string path) {
 24		specName = path.dup;
 25
 26		//Console.putln("Outputting ... ");
 27		AST working = result;
 28		AST node;
 29
 30		moduleName = "";
 31		packageName = "";
 32
 33		while(working !is null) {
 34			node = working.right;
 35			if (node !is null) {
 36				if (node.valueType == AST.ValueType.Name) {
 37					string name;
 38					node.getValue(name);
 39
 40					//Console.putln("Tree: ", name.array);
 41					//writefln(name);
 42
 43					switch(name) {
 44						case "ParseDescribe":
 45
 46							tests = null;
 47							lines = null;
 48							className = null;
 49
 50							printDescribe(node);
 51							break;
 52						case "ParseImport":
 53							printImport(node);
 54							break;
 55						case "ParseModule":
 56							AST work = node;
 57							while (work !is null) {
 58								node = work.right;
 59								if (node !is null) {
 60									if (node.valueType == AST.ValueType.Name) {
 61									}
 62									else {
 63										string content;
 64										node.getValue(content);
 65										moduleName = content.trim();
 66										packageName = moduleName.substring(0, moduleName.findReverse("."));
 67										moduleName = moduleName.substring(packageName.length+1);
 68									}
 69								}
 70
 71								work = work.left;
 72							}
 73
 74							break;
 75						default:
 76						// error
 77							break;
 78					}
 79				}
 80			}
 81			working = working.left;
 82		}
 83	}
 84
 85	bool finalizeOutput() {
 86		if (outfp is null) {
 87			return false;
 88		}
 89
 90		outfp.close();
 91		//fclose(outfp);
 92		return true;
 93	}
 94
 95protected:
 96
 97	string specName;
 98
 99	File outfp;
100	//_iobuf* outfp;
101	string className;
102	string moduleName;
103	string packageName;
104	string[] tests;
105	ulong[] lines;
106
107	string[] classes;
108
109	string exception;
110
111	bool shouldThrow = false;
112
113	bool readyOutput(string path) {
114		//Console.putln("opening file");
115		//outfp = fopen(std.string.toStringz(path), "w+");
116		outfp = new File(path);
117
118		if (outfp is null) {
119			return false;
120		}
121
122		return true;
123	}
124
125	bool printHeader() {
126		//fwritef(outfp, "%s", header);
127		//Console.putln("output header");
128		print("/*\n *\n */\n\n");
129		print("import spec.specification;\n");
130		print("import spec.itemspecification;\n");
131		print("import spec.modulespecification;\n");
132		print("import spec.packagespecification;\n");
133		print("\nimport spec.logic;\n");
134		print("\nimport djehuty;\n");
135
136		return true;
137
138	}
139
140	bool printDone(AST tree, string describing) {
141		AST working = tree;
142		AST node;
143
144		if (describing !is null) {
145			print("done before_" ~ describing);
146		}
147		else {
148			print("done before");
149		}
150
151		print("()\n\t{");
152
153		while (working !is null) {
154			node = working.right;
155			if (node !is null) {
156				if (node.valueType == AST.ValueType.Name) {
157				}
158				else {
159					string content;
160					node.getValue(content);
161					printContent(content, 3);
162				}
163			}
164
165			working = working.left;
166		}
167
168		print("}");
169
170		return true;
171	}
172
173	bool printImport(AST tree) {
174		AST working = tree;
175		AST node;
176
177		while (working !is null) {
178			node = working.right;
179			if (node !is null) {
180				if (node.valueType == AST.ValueType.Name) {
181				}
182				else {
183					string content;
184					node.getValue(content);
185					if (!(content == " testing.support")) {
186						print("import");
187						print(content);
188						print(";\n\n");
189					}
190				}
191			}
192
193			working = working.left;
194		}
195
196		return true;
197	}
198
199	bool printIt(AST tree, string describing) {
200		AST working = tree;
201		AST node;
202
203		while (working !is null) {
204			node = working.right;
205			if (node !is null) {
206				if (node.valueType == AST.ValueType.Name) {
207					string name;
208					node.getValue(name);
209
210					switch(name) {
211						case "Identifier":
212							string val;
213							node.right.getValue(val);
214
215							print("\n\tit ");
216							if (describing !is null) {
217								val = describing ~ "!" ~ val;
218							}
219
220							print(val.replace('!','_') ~ "() {\n");
221
222							print("\t\tbefore();\n");
223							print("\t\tbefore");
224							if (describing !is null) {
225								print("_" ~ describing);
226							}
227							print("();\n");
228							
229
230
231							if (describing is null) {
232								val = "_" ~ val;
233							}
234
235							tests ~= val;
236
237							print("\t\tit _ret = it.does;\n");
238
239							print("\t\ttry {\n");
240							break;
241						case "LineNumber":
242							ulong val;
243							node.right.getValue(val);
244							//Console.putln("LineNumber ", val);
245
246							lines ~= [val];
247							//Console.putln(lines);
248							break;
249						case "ParseDone":
250							printDone(node,describing);
251							break;
252						case "ParseShould":
253							printShould(node);
254							break;
255						case "ParseShouldNot":
256							printShouldNot(node);
257							break;
258						case "ParseShouldThrow":
259							printShouldThrow(node);
260							break;
261						default:
262							break;
263					}
264				}
265				else {
266					string content;
267					node.getValue(content);
268					printContent(content, 3);
269				}
270			}
271
272			working = working.left;
273		}
274
275		print("\t\t}\n\t\tcatch(Exception _exception_) {\n");
276		if (shouldThrow) {
277			//Console.putln("!!", exception.array);
278			if (exception == "") {
279				print("\t\t\t_ret = it.does");
280			}
281			else {
282				print("\t\t\tif (_exception_.msg != ");
283				print(exception);
284				print(") { _ret = it.doesnt; }\n\t\t\t_ret = it.does");
285			}
286		}
287		else {
288			print("\t\t\t_ret = it.doesnt");
289		}
290		
291		
292		print(";\n\t\t}\n\t\treturn _ret;\n\t}\n");
293
294
295		return true;
296	}
297
298	bool printShould(AST tree) {
299		AST working = tree;
300		AST node;
301
302		print("\t\t\tif(!(");
303
304		while (working !is null) {
305			node = working.right;
306			if (node !is null) {
307				if (node.valueType == AST.ValueType.Name) {
308				}
309				else {
310					string content;
311					node.getValue(content);
312					printContent(content, 0);
313				}
314			}
315
316			working = working.left;
317		}
318		
319		print(")) {\n\t\t\t\t_ret = it.doesnt;\n\t\t\t}\n");
320
321		return true;
322	}
323
324	bool printShouldNot(AST tree) {
325		AST working = tree;
326		AST node;
327
328		print("\t\t\tif(");
329
330		while (working !is null) {
331			node = working.right;
332			if (node !is null) {
333				if (node.valueType == AST.ValueType.Name) {
334				}
335				else {
336					string content;
337					node.getValue(content);
338					printContent(content, 0);
339				}
340			}
341
342			working = working.left;
343		}
344		
345		print(") {\n\t\t\t\t_ret = it.doesnt;\n\t\t\t}\n");
346
347		return true;
348	}
349
350	bool printShouldThrow(AST tree) {
351		AST working = tree;
352		AST node;
353
354		exception = "";
355
356		while (working !is null) {
357			node = working.right;
358			if (node !is null) {
359				if (node.valueType == AST.ValueType.Name) {
360				}
361				else {
362					string content;
363					node.getValue(content);
364					exception = content;
365				}
366			}
367
368			working = working.left;
369		}
370
371		shouldThrow = true;
372
373		return true;
374	}
375
376	bool printDescribeSection(AST tree) {
377		AST working = tree;
378		AST node;
379
380		string describing;
381
382		bool hasDone = false;
383
384		while (working !is null) {
385			node = working.right;
386			if (node !is null) {
387				if (node.valueType == AST.ValueType.Name) {
388					string name;
389					node.getValue(name);
390
391					switch(name) {
392						case "Identifier":
393							node.right.getValue(describing);
394							break;
395						case "ParseDone":
396							hasDone = true;
397							printDone(node,describing);
398							break;
399						case "ParseIt":
400							printIt(node,describing);
401							break;
402						default:
403							break;
404					}
405				}
406				else {
407					string content;
408					node.getValue(content);
409					printContent(content, 3);
410				}
411			}
412
413			working = working.left;
414		}
415
416		if (!hasDone) {
417			print("\n\tdone before_" ~ describing ~ "() {\n\t}\n");
418		}
419
420		return true;
421	}
422
423	bool printDescribe(AST tree) {
424		AST working = tree;
425		AST node;
426
427		bool hasDone = false;
428
429		string val;
430
431		while (working !is null) {
432			node = working.right;
433			if (node !is null) {
434				if (node.valueType == AST.ValueType.Name) {
435					string name;
436					node.getValue(name);
437
438					switch(name) {
439						case "Identifier":
440							node.right.getValue(val);
441							//Console.putln("ID: ", val.array);
442
443							if (val[0] >= 'a' && val[0] <= 'z') {
444								val[0] = val[0] - 32;
445							}
446							//Console.putln("ID: ", val.array, " len ", val.length);
447
448							val ~= "Tests";
449							//Console.putln("ID: ", val.array, " len ", val.length);
450
451							print("private struct " ~ val ~ " {\nstatic:\n");
452							Console.putln("Creating ", val);
453							className = val;
454							break;
455						case "ParseDone":
456							hasDone = true;
457							printDone(node,null);
458							break;
459						case "ParseIt":
460							printIt(node,null);
461							break;
462						case "ParseDescribeSection":
463							printDescribeSection(node);
464							break;
465						default:
466							break;
467					}
468				}
469				else {
470					string content;
471					node.getValue(content);
472					if (content.trim() != "") {
473						print("\n");
474						printContent(content, 1);
475					}
476				}
477			}
478
479			working = working.left;
480		}
481
482		if (!hasDone) {
483			print("\n\tdone before() {\n\t}\n\n");
484		}
485
486		// do tests
487
488		//Console.putln("className: ", className.array, " len " , className.length);
489		string classNameFixed = className.substring(0,className.length-6);
490		//Console.putln("className::", classNameFixed.array);
491		//Console.putln("className::", className[0..className.length-6]);
492
493		print("\n}\n\n");
494
495		print ("\nstatic this() {\n");
496
497		print ("\t// Add to specification\n");
498		// Split packageName into separate things
499		string[] packages = packageName.split('.');
500		print ("\tPackageSpecification ps;\n");
501		print ("\tPackageSpecification tmpps;\n");
502
503		print ("\tps = Specification.traverse(\"" ~ packages[0] ~ "\");\n");
504		print ("\tif(ps is null) {\n");
505		print ("\t\tps = new PackageSpecification(\"" ~ packages[0] ~ "\");\n");
506		print ("\t\tSpecification.add(ps);\n");
507		print ("\t}\n\n");
508
509		foreach(pack; packages[1..$]) {
510			print ("\ttmpps = ps;\n");
511			print ("\tps = tmpps.traverse(\"" ~ pack ~ "\");\n");
512			print ("\tif(ps is null) {\n");
513			print ("\t\tps = new PackageSpecification(\"" ~ pack ~ "\");\n");
514			print ("\t\ttmpps.add(ps);\n");
515			print ("\t}\n\n");
516		}
517
518		print ("\t// Add to this module\n");
519		print ("\tModuleSpecification ms = ps.retrieve(\"" ~ moduleName ~ "\");\n");
520		print ("\tif(ms is null) {\n");
521		print ("\t\tms = new ModuleSpecification(\"" ~ moduleName ~ "\");\n");
522		print ("\t\tps.add(ms);\n");
523		print ("\t}\n\n");
524
525		print ("\tItemSpecification item;\n\n");
526
527		string currentSection = "";
528		foreach(i, test; tests) {
529			int pos = test.find("!");
530			string section = test[0..pos].dup;
531			Console.putln("cs:", currentSection, " t:", test);
532			if (currentSection != section) {
533				currentSection = section;
534				print ("\titem = new ItemSpecification(\"" ~ section ~ "\");\n");
535				print ("\tms.add(item);\n");
536			}
537			print("\titem.add(\"" ~ test[pos+1..$].replace('_', ' ') ~ "\", &" ~ className ~ "." ~ test.replace('!','_') ~ ");\n");
538		}
539
540		print("}\n\n");
541
542		classes ~= classNameFixed;
543
544		return true;
545	}
546
547	bool print(string stuff) {
548		return outfp.write(Unicode.toUtf8(stuff));
549		//fwritef(outfp, "%s", stuff);
550		//return true;
551	}
552
553	void printContent(string content, int tabs) {
554		content = content.trim();
555		if (content == "") { return; }
556		int pos = content.find("\n");
557		while(pos != -1) {
558			if (tabs > 0) {
559				switch(tabs) {
560					case 3:
561						print("\t");
562					case 2:
563						print("\t");
564					case 1:
565						print("\t");
566					default:
567						break;
568				}
569				print(content.substring(0, pos));
570				print("\n");
571			}
572			else {
573				print(content.substring(0, pos));
574			}
575			content = content.substring(pos+1).trim();
576			pos = content.find("\n");
577		}
578		if (tabs > 0) {
579			switch(tabs) {
580				case 3:
581					print("\t");
582				case 2:
583					print("\t");
584				case 1:
585					print("\t");
586				default:
587					break;
588			}
589			print(content);
590			print("\n");
591		}
592		else {
593			print(content);
594		}
595	}
596}