Mercurial > projects > dil
diff trunk/src/main.d @ 363:2b387a3c6b58
- Added package cmd.
- Moved code from main.d to cmd.Generate.
- Added command stats/statistics (implemented in cmd.Statistics.)
author | aziz |
---|---|
date | Thu, 30 Aug 2007 12:02:04 +0000 |
parents | 0faf57d99c1c |
children | 1059295c2727 |
line wrap: on
line diff
--- a/trunk/src/main.d Thu Aug 30 10:47:03 2007 +0000 +++ b/trunk/src/main.d Thu Aug 30 12:02:04 2007 +0000 @@ -11,6 +11,8 @@ import dil.Settings; import dil.Declarations, dil.Expressions, dil.SyntaxTree; import dil.File; +import cmd.Generate; +import cmd.Statistics; void main(char[][] args) { @@ -46,6 +48,9 @@ else tokensToDoc(fileName, options); break; + case "stats", "statistics": + statistics(args[2]); + break; case "parse": if (args.length == 3) parse(args[2]); @@ -62,7 +67,8 @@ const char[] COMMANDS = " generate (gen)\n" - " help (?)\n"; + " help (?)\n" + " statistics (stats)\n"; char[] helpMain() { @@ -83,14 +89,6 @@ writefln(msg); } -enum DocOption -{ - Tokens, - Syntax = 1<<1, - HTML = 1<<2, - XML = 1<<3 -} - void parse(string fileName) { auto sourceText = loadFile(fileName); @@ -113,482 +111,3 @@ writefln(`%s(%d)P: %s`, parser.lx.fileName, error.loc, error.getMsg); } } - -char[] xml_escape(char[] text) -{ - char[] result; - foreach(c; text) - switch(c) - { - case '<': result ~= "<"; break; - case '>': result ~= ">"; break; - case '&': result ~= "&"; break; - default: result ~= c; - } - return result; -} - -char[] getShortClassName(Node n) -{ - static char[][] name_table; - if (name_table is null) - name_table = new char[][NodeKind.max+1]; - char[] name = name_table[n.kind]; - if (name !is null) - return name; - - alias std.string.find find; - name = n.classinfo.name; - name = name[find(name, ".")+1 .. $]; // Remove package name - name = name[find(name, ".")+1 .. $]; // Remove module name - char[] remove; - switch (n.category) - { - alias NodeCategory NC; - case NC.Declaration: remove = "Declaration"; break; - case NC.Statement: - if (n.kind == NodeKind.Statements) - return name; - remove = "Statement"; - break; - case NC.Expression: remove = "Expression"; break; - case NC.Type: remove = "Type"; break; - case NC.Other: return name; - default: - } - // Remove common suffix. - auto idx = find(name, remove); - if (idx != -1) - name = name[0 .. idx]; - // Store the name. - name_table[n.kind] = name; - return name; -} - -enum DocPart -{ - Head, - CompBegin, - CompEnd, - Error, - SyntaxBegin, - SyntaxEnd, - SrcBegin, - SrcEnd, - Tail, - // Tokens: - Identifier, - Comment, - StringLiteral, - CharLiteral, - Operator, - LorG, - LessEqual, - GreaterEqual, - AndLogical, - OrLogical, - NotEqual, - Not, - Number, - Bracket, - SpecialToken, - Shebang, - Keyword, - HLineBegin, - HLineEnd, - Filespec, -} - -auto html_tags = [ - // Head - `<html>`\n - `<head>`\n - `<meta http-equiv="Content-Type" content="text/html; charset=utf-8">`\n - `<link href="dil_html.css" rel="stylesheet" type="text/css">`\n - `</head>`\n - `<body>`[], - // CompBegin - `<div class="compilerinfo">`, - // CompEnd - `</div>`, - // Error - `<p class="error %s">%s(%d)%s: %s</p>`, - // SyntaxBegin - `<span class="%s %s">`, - // SyntaxEnd - `</span>`, - // SrcBegin - `<pre class="sourcecode">`, - // SrcEnd - `</pre>`, - // Tail - `</html>`, - // Identifier - `<span class="i">%s</span>`, - // Comment - `<span class="c%s">%s</span>`, - // StringLiteral - `<span class="sl">%s</span>`, - // CharLiteral - `<span class="cl">%s</span>`, - // Operator - `<span class="op">%s</span>`, - // LorG - `<span class="oplg"><></span>`, - // LessEqual - `<span class="ople"><=</span>`, - // GreaterEqual - `<span class="opge">>=</span>`, - // AndLogical - `<span class="opaa">&&</span>`, - // OrLogical - `<span class="opoo">||</span>`, - // NotEqual - `<span class="opne">!=</span>`, - // Not - `<span class="opn">!</span>`, - // Number - `<span class="n">%s</span>`, - // Bracket - `<span class="br">%s</span>`, - // SpecialToken - `<span class="st">%s</span>`, - // Shebang - `<span class="shebang">%s</span>`, - // Keyword - `<span class="k">%s</span>`, - // HLineBegin - `<span class="hl">#line`, - // HLineEnd - "</span>", - // Filespec - `<span class="fs">%s</span>`, -]; - -auto xml_tags = [ - // Head - `<?xml version="1.0"?>`\n - `<?xml-stylesheet href="dil_xml.css" type="text/css"?>`\n - `<root>`[], - // CompBegin - `<compilerinfo>`, - // CompEnd - `</compilerinfo>`, - // Error - `<error t="%s">%s(%d)%s: %s</error>`, - // SyntaxBegin - `<%s t="%s">`, - // SyntaxEnd - `</%s>`, - // SrcBegin - `<sourcecode>`, - // SrcEnd - `</sourcecode>`, - // Tail - `</root>`, - // Identifier - "<i>%s</i>", - // Comment - `<c t="%s">%s</c>`, - // StringLiteral - "<sl>%s</sl>", - // CharLiteral - "<cl>%s</cl>", - // Operator - "<op>%s</op>", - // LorG - `<op t="lg"><></op>`, - // LessEqual - `<op t="le"><=</op>`, - // GreaterEqual - `<op t="ge">>=</op>`, - // AndLogical - `<op t="aa">&&</op>`, - // OrLogical - `<op t="oo">||</op>`, - // NotEqual - `<op t="ne">!=</op>`, - // Not - `<op t="n">!</op>`, - // Number - "<n>%s</n>", - // Bracket - "<br>%s</br>", - // SpecialToken - "<st>%s</st>", - // Shebang - "<shebang>%s</shebang>", - // Keyword - "<k>%s</k>", - // HLineBegin - "<hl>#line", - // HLineEnd - "</hl>", - // Filespec - "<fs>%s</fs>", -]; - -static assert(html_tags.length == DocPart.max+1); -static assert(xml_tags.length == DocPart.max+1); - -void syntaxToDoc(string fileName, DocOption options) -{ - auto tags = options & DocOption.HTML ? html_tags : xml_tags; - auto sourceText = loadFile(fileName); - auto parser = new Parser(sourceText, fileName); - parser.start(); - auto root = parser.parseModule(); - auto lx = parser.lx; - - auto token = lx.head; - char* end = lx.text.ptr; - - writefln(tags[DocPart.Head]); - // Output error messages. - if (lx.errors.length || parser.errors.length) - { - writefln(tags[DocPart.CompBegin]); - foreach (error; lx.errors) - { - writefln(tags[DocPart.Error], "L", lx.fileName, error.loc, "L", xml_escape(error.getMsg)); - } - foreach (error; parser.errors) - { - writefln(tags[DocPart.Error], "P", lx.fileName, error.loc, "P", xml_escape(error.getMsg)); - } - writefln(tags[DocPart.CompEnd]); - } - writef(tags[DocPart.SrcBegin]); - - Node[][Token*] beginNodes, endNodes; - - void populateAAs(Node[] nodes) - { - foreach (node; nodes) - { - auto begin = node.begin; - if (begin) - { - auto end = node.end; - assert(end); - beginNodes[begin] ~= node; - endNodes[end] ~= node; - } - if (node.children.length) - populateAAs(node.children); - } - } - populateAAs(root.children); - - char[] getTag(NodeCategory nc) - { - char[] tag; - switch (nc) - { - alias NodeCategory NC; - case NC.Declaration: tag = "d"; break; - case NC.Statement: tag = "s"; break; - case NC.Expression: tag = "e"; break; - case NC.Type: tag = "t"; break; - case NC.Other: tag = "o"; break; - default: - } - return tag; - } - - // Traverse linked list and print tokens. - while (token.type != TOK.EOF) - { - token = token.next; - - // Print whitespace between previous and current token. - if (end != token.start) - writef("%s", end[0 .. token.start - end]); - - Node[]* nodes = token in beginNodes; - - if (nodes) - { - foreach (node; *nodes) - writef(tags[DocPart.SyntaxBegin], getTag(node.category), getShortClassName(node)); - } - - printToken(token, tags); - - nodes = token in endNodes; - - if (nodes) - { - foreach_reverse (node; *nodes) - if (options & DocOption.HTML) - writef(tags[DocPart.SyntaxEnd]); - else - writef(tags[DocPart.SyntaxEnd], getTag(node.category)); - } - - end = token.end; - } - writef(tags[DocPart.SrcEnd], tags[DocPart.Tail]); -} - -void tokensToDoc(string fileName, DocOption options) -{ - auto tags = options & DocOption.HTML ? html_tags : xml_tags; - auto sourceText = loadFile(fileName); - auto lx = new Lexer(sourceText, fileName); - - auto token = lx.getTokens(); - char* end = lx.text.ptr; - - writefln(tags[DocPart.Head]); - - if (lx.errors.length) - { - writefln(tags[DocPart.CompBegin]); - foreach (error; lx.errors) - { - writefln(tags[DocPart.Error], "L", lx.fileName, error.loc, "L", xml_escape(error.getMsg)); - } - writefln(tags[DocPart.CompEnd]); - } - writef(tags[DocPart.SrcBegin]); - - // Traverse linked list and print tokens. - while (token.type != TOK.EOF) - { - token = token.next; - - // Print whitespace between previous and current token. - if (end != token.start) - writef("%s", end[0 .. token.start - end]); - printToken(token, tags); - end = token.end; - } - writef(\n, tags[DocPart.SrcEnd], \n, tags[DocPart.Tail]); -} - -void printToken(Token* token, string[] tags) -{ - alias DocPart DP; - string srcText = xml_escape(token.srcText); - - switch(token.type) - { - case TOK.Identifier: - writef(tags[DP.Identifier], srcText); - break; - case TOK.Comment: - string t; - switch (token.start[1]) - { - case '/': t = "l"; break; - case '*': t = "b"; break; - case '+': t = "n"; break; - default: - assert(0); - } - writef(tags[DP.Comment], t, srcText); - break; - case TOK.String: - writef(tags[DP.StringLiteral], srcText); - break; - case TOK.CharLiteral, TOK.WCharLiteral, TOK.DCharLiteral: - writef(tags[DP.CharLiteral], srcText); - break; - case TOK.Assign, TOK.Equal, - TOK.Less, TOK.Greater, - TOK.LShiftAssign, TOK.LShift, - TOK.RShiftAssign, TOK.RShift, - TOK.URShiftAssign, TOK.URShift, - TOK.OrAssign, TOK.OrBinary, - TOK.AndAssign, TOK.AndBinary, - TOK.PlusAssign, TOK.PlusPlus, TOK.Plus, - TOK.MinusAssign, TOK.MinusMinus, TOK.Minus, - TOK.DivAssign, TOK.Div, - TOK.MulAssign, TOK.Mul, - TOK.ModAssign, TOK.Mod, - TOK.XorAssign, TOK.Xor, - TOK.CatAssign, - TOK.Tilde, - TOK.Unordered, - TOK.UorE, - TOK.UorG, - TOK.UorGorE, - TOK.UorL, - TOK.UorLorE, - TOK.LorEorG: - writef(tags[DP.Operator], srcText); - break; - case TOK.LorG: - writef(tags[DP.LorG]); - break; - case TOK.LessEqual: - writef(tags[DP.LessEqual]); - break; - case TOK.GreaterEqual: - writef(tags[DP.GreaterEqual]); - break; - case TOK.AndLogical: - writef(tags[DP.AndLogical]); - break; - case TOK.OrLogical: - writef(tags[DP.OrLogical]); - break; - case TOK.NotEqual: - writef(tags[DP.NotEqual]); - break; - case TOK.Not: - // Check if this is part of a template instantiation. - // TODO: comments aren't skipped. - if (token.prev.type == TOK.Identifier && token.next.type == TOK.LParen) - goto default; - writef(tags[DP.Not]); - break; - case TOK.Int32, TOK.Int64, TOK.Uint32, TOK.Uint64, - TOK.Float32, TOK.Float64, TOK.Float80, - TOK.Imaginary32, TOK.Imaginary64, TOK.Imaginary80: - writef(tags[DP.Number], srcText); - break; - case TOK.LParen, TOK.RParen, TOK.LBracket, - TOK.RBracket, TOK.LBrace, TOK.RBrace: - writef(tags[DP.Bracket], srcText); - break; - case TOK.Shebang: - writef(tags[DP.Shebang], srcText); - break; - case TOK.HashLine: - void printWS(char* start, char* end) - { - if (start != end) - writef(start[0 .. end - start]); - } - writef(tags[DP.HLineBegin]); - auto num = token.line_num; - // Print whitespace between #line and number - auto ptr = token.start + "#line".length; - printWS(ptr, num.start); - printToken(num, tags); - if (token.line_filespec) - { - auto filespec = token.line_filespec; - // Print whitespace between number and filespec - printWS(num.end, filespec.start); - writef(tags[DP.Filespec], xml_escape(filespec.srcText)); - - ptr = filespec.end; - } - else - ptr = num.end; - // Print remaining whitespace - printWS(ptr, token.end); - writef(tags[DP.HLineEnd]); - break; - default: - if (token.isKeyword()) - writef(tags[DP.Keyword], srcText); - else if (token.isSpecialToken) - writef(tags[DP.SpecialToken], srcText); - else - writef("%s", srcText); - } -}