Check-in [38fcc662be]
Not logged in
Overview
SHA1 Hash:38fcc662be6dccf9e0ca16f65c63a59fa6d35055
Date: 2010-11-10 21:38:54
User: kinaba
Comment:cleaned up documentation comments
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified .poseidon from [374d8a7e60e3002a] to [706faeb501e0d2d1].

42 42 </source> 43 43 <interface /> 44 44 <resource /> 45 45 <othersDMD /> 46 46 <others> 47 47 <name>build.bat</name> 48 48 <name>build.sh</name> 49 + <name>builddoc.bat</name> 49 50 <name>readme.txt</name> 50 51 </others> 51 52 </projectFiles> 52 53 <includePaths /> 53 54 <linkLibrarys /> 54 55 <importExpressions /> 55 56 </buildSpec> 56 57 </projectDescription>

Added builddoc.bat version [7f7c5c8755679d44]

1 +@setlocal ENABLEDELAYEDEXPANSION 2 +@set ARGS= 3 +@for %%I in (main.d polemy\*.d tricks\*.d) do @set ARGS=!ARGS! %%I 4 +@if not exist bin mkdir bin 5 +@echo dmd -o- -Dddoc doc\candydoc\candy.ddoc doc\candydoc\modules.ddoc %ARGS% 6 +@dmd -o- -Dddoc doc\candydoc\candy.ddoc doc\candydoc\modules.ddoc %ARGS%

Added doc/candydoc/CANDYDOC.txt version [1ca7967fbd360bdd]

1 + 2 +CanDyDOC is fileset for creating advanced documentation of programs written 3 +in D programming language. CanDyDOC adds some eye-candy and advanced navigation 4 +features to .html documents that are generated by D compiler and known as DDOC. 5 +Produced result is AJAX web-application that is compatible with all mainstream 6 +web browsers. 7 + 8 +This is a version 0.80. For latest release see 9 +http://trac.dsource.org/projects/helix/ 10 + 11 +CanDyDOC includes following files: 12 + - candy.ddoc 13 + File with DDOC macro definitions. You haven't to touch it. 14 + 15 + - modules.ddoc 16 + You should enumerate all modules that would be avaible for navigation 17 + here. 18 + 19 + - style.css 20 + Cascading style sheet file that defines look of produced documentation. 21 + You can leave this file without changes or adjust fonts, colors, etc 22 + here. See it for documentation. 23 + 24 + - ie56hack.css 25 + CSS file to force Internet Explorer 5/6 browser show documentation 26 + as it looks like in standard-compliant browsers. 27 + 28 + - tree.js 29 + JavaScript implementing tree control that looks like native one. 30 + 31 + - util.js 32 + Common cross-browser routines. 33 + 34 + - explorer.js 35 + Heart of every documentation's page. Controls generation, behaviour and 36 + navigation of a page. 37 + 38 + - numerous of image files in 'img' folder. 39 + 40 +How to use: 41 + 1) Put 'candydoc' directory in place where documentation will be. 42 + 2) Modify modules.ddoc file: enumerate all modules that should be avaible 43 + for navigation. 44 + 3) Modify style.css file if you want to change style of documentation. Or 45 + leave it unmodified to apply defaul theme. 46 + 4) Run documentation compilation with candy.ddoc and modules.ddoc specified 47 + on command line. 48 + 5) Enjoy a result :) 49 + 50 +Known bugs: 51 + - Explorer window doesn't work on Safari browser. 52 + - Scroll bar positions are not adjusted after explorer's tab change in Opera 53 + browser. So it is posible to see nothing on some tab: solution is to 54 + return to a previous tab, scroll it to top and then return back. 55 + - Overlapping of some elements when too few horizontal place avaible.

Added doc/candydoc/candy.ddoc version [ed60e1fc46edfd39]

1 +DDOC = 2 +<html><head> 3 +<meta http-equiv="content-type" content="text/html; charset=utf-8"> 4 +<meta content="text/javascript" http-equiv="content-script-type"> 5 +<title>$(TITLE)</title> 6 +<link rel="stylesheet" type="text/css" href="candydoc/style.css"> 7 +<!--[if lt IE 7]><link rel="stylesheet" type="text/css" href="candydoc/ie56hack.css"><![endif]--> 8 +<script language="JavaScript" src="candydoc/util.js" type="text/javascript"></script> 9 +<script language="JavaScript" src="candydoc/tree.js" type="text/javascript"></script> 10 +<script language="JavaScript" src="candydoc/explorer.js" type="text/javascript"></script> 11 +</head><body> 12 +<div id="tabarea"></div><div id="explorerclient"></div> 13 +<div id="content"><script>explorer.initialize("$(TITLE)");</script> 14 + <table class="content"> 15 + <tr><td id="docbody"><h1>$(TITLE)</h1>$(BODY)</td></tr> 16 + <tr><td id="docfooter"> 17 + Page was generated with 18 + <img src="candydoc/img/candydoc.gif" style="vertical-align:middle; position:relative; top:-1px"> 19 + on $(DATETIME) 20 + </td></tr> 21 + </table> 22 +</div> 23 +$(ADD_MODULES) 24 +</body></html> 25 + 26 + 27 +DDOC_DECL = 28 +<script>explorer.outline.writeEnabled = true;</script> 29 +$(DT <span class="decl">$0</span>) 30 +<script>explorer.outline.writeEnabled = false;</script> 31 + 32 + 33 +DDOC_PSYMBOL = 34 +<span class="currsymbol">$0</span> 35 +<script>explorer.outline.addDecl('$0');</script> 36 + 37 + 38 +DDOC_MEMBERS = 39 +<script>explorer.outline.incSymbolLevel();</script> 40 +$(DL $0) 41 +<script>explorer.outline.decSymbolLevel();</script> 42 + 43 + 44 +DDOC_PARAM_ID = 45 +<td nowrap valign="top" style="padding-right: 8px">$0</td> 46 + 47 + 48 +DDOC_PARAM =<span class="funcparam">$0</span> 49 +ADD_MODULES =<script>$(MODULES)</script> 50 +MODULE =explorer.packageExplorer.addModule("$0");

Added doc/candydoc/explorer.js version [9da5605d97dbb635]

1 +/* This file is a part of CanDyDOC fileset. 2 + File is written by Victor Nakoryakov and placed into the public domain. 3 + 4 + This file is javascript with classes that represents explorer window. 5 + And things related to navigation. */ 6 + 7 +var explorer = new Explorer(); 8 + 9 +/////////////////////////////////////////////////////////////////////////////// 10 +// Current symbol marker class constructor 11 +/////////////////////////////////////////////////////////////////////////////// 12 +function Marker() 13 +{ 14 + this.top = document.createElement("div"); 15 + this.middle = document.createElement("div"); 16 + this.bottom = document.createElement("div"); 17 + this.container = document.createElement("div"); 18 + 19 + this.setTo = function(term) 20 + { 21 + // find definition related to `term` 22 + var def = term.nextSibling; 23 + while (def && def.nodeName != "DD") 24 + def = def.nextSibling; 25 + 26 + var defHeight = 0; 27 + var childrenHeight = 0; // children of current declaration 28 + if (def) 29 + { 30 + defHeight = def.offsetHeight; 31 + var child = def.firstChild; 32 + 33 + // traverse until DL tag, until children definition 34 + while (child && child.nodeName != "DL") 35 + child = child.nextSibling; 36 + 37 + if (child) 38 + childrenHeight = child.offsetHeight; 39 + } 40 + 41 + this.top.style.height = term.offsetHeight; 42 + this.middle.style.height = defHeight - childrenHeight; 43 + this.bottom.style.height = childrenHeight; 44 + 45 + if (childrenHeight == 0) 46 + this.bottom.style.display = "none"; 47 + else 48 + this.bottom.style.display = ""; 49 + 50 + this.container.style.left = getLeft(term) - 8; 51 + this.container.style.top = getTop(term); 52 + this.container.style.display = ""; 53 + } 54 + 55 + /////////////////////////////////////////////////////////////////////////// 56 + this.container.style.position = "absolute"; 57 + this.container.style.display = "none"; 58 + 59 + this.top.className = "markertop"; 60 + this.middle.className = "markermiddle"; 61 + this.bottom.className = "markerbottom"; 62 + 63 + this.container.appendChild(this.top); 64 + this.container.appendChild(this.middle); 65 + this.container.appendChild(this.bottom); 66 + 67 + //document.body.appendChild( this.container ); 68 + 69 + // Workaround bug in IE 5/6. We can not append anything to document body until 70 + // full page load. 71 + window.marker = this; 72 + if (window.addEventListener) 73 + window.addEventListener("load", new Function("document.body.appendChild( window.marker.container );"), false); 74 + else if (window.attachEvent) 75 + window.attachEvent("onload", new Function("document.body.appendChild( window.marker.container );")); 76 +} 77 + 78 +/////////////////////////////////////////////////////////////////////////////// 79 +// Outline class constructor 80 +/////////////////////////////////////////////////////////////////////////////// 81 +function Outline() 82 +{ 83 + this.tree = new TreeView(); 84 + this.mountPoint = null; 85 + this.writeEnabled = false; 86 + this.marker = new Marker(); 87 + this.classRegExp = new RegExp; 88 + this.structRegExp = new RegExp; 89 + this.enumRegExp = new RegExp; 90 + this.templateRegExp = new RegExp; 91 + this.aliasRegExp = new RegExp; 92 + this.funcRegExp = new RegExp; 93 + 94 + this.incSymbolLevel = function() 95 + { 96 + if (this.mountPoint == null) 97 + this.mountPoint = this.tree.children[ 0 ]; 98 + else 99 + this.mountPoint = this.mountPoint.lastChild(); 100 + } 101 + 102 + this.decSymbolLevel = function() 103 + { 104 + // place icons near items according to extracted below type 105 + for (var i = 0; i < this.mountPoint.children.length; ++i) 106 + { 107 + child = this.mountPoint.children[i]; 108 + var term = child.termRef; 109 + 110 + // find first span node 111 + var n = term.firstChild; 112 + while (n && n.nodeName != "SPAN") 113 + n = n.nextSibling; 114 + 115 + if (!n) // shouldn't happen 116 + continue; 117 + 118 + var iconSrc; 119 + if (n.firstChild.nodeName == "#text") 120 + { 121 + var text = n.firstChild.data; // text before declaration 122 + 123 + if ( this.classRegExp.test(text) ) 124 + iconSrc = "candydoc/img/outline/class.gif"; 125 + else if ( this.structRegExp.test(text) ) 126 + iconSrc = "candydoc/img/outline/struct.gif"; 127 + else if ( this.enumRegExp.test(text) ) 128 + iconSrc = "candydoc/img/outline/enum.gif"; 129 + else if ( this.templateRegExp.test(text) ) 130 + iconSrc = "candydoc/img/outline/template.gif"; 131 + else if ( this.aliasRegExp.test(text) ) 132 + iconSrc = "candydoc/img/outline/alias.gif"; 133 + else // function or variable? check whether '(' ')' exists on the right 134 + { 135 + var np = n.firstChild; 136 + while (np && np.nodeName != "SCRIPT") // find our script "onDecl" 137 + np = np.nextSibling; 138 + 139 + if (np && np.nextSibling && np.nextSibling.nodeName == "#text" && 140 + this.funcRegExp.test(np.nextSibling.data)) 141 + { 142 + iconSrc = "candydoc/img/outline/func.gif"; 143 + } 144 + else 145 + iconSrc = "candydoc/img/outline/var.gif"; 146 + } 147 + } 148 + else // enum member ? 149 + iconSrc = "candydoc/img/outline/var.gif"; 150 + 151 + child.icon.src = iconSrc; 152 + child.icon.width = 16; 153 + child.icon.height = 16; 154 + } 155 + 156 + this.mountPoint = this.mountPoint.parentNode; 157 + } 158 + 159 + this.addDecl = function(decl) 160 + { 161 + function getLastLeaf(elem) 162 + { 163 + if (elem.childNodes.length > 0) 164 + return getLastLeaf(elem.lastChild); 165 + else 166 + return elem; 167 + } 168 + 169 + function getCurrentTerm() 170 + { 171 + var ret = getLastLeaf( document.getElementById("content") ); 172 + while (ret && ret.nodeName != "DT") 173 + ret = ret.parentNode; 174 + 175 + return ret; 176 + } 177 + 178 + if (this.writeEnabled) 179 + { 180 + var node = this.mountPoint.createChild(decl); 181 + node.termRef = getCurrentTerm(); 182 + node.setOnclick( new Function("explorer.outline.mark(this.termRef);") ); 183 + } 184 + } 185 + 186 + this.mark = function(term) 187 + { 188 + this.marker.setTo(term); 189 + window.scrollTo(0, getTop(term) - getWindowHeight() / 6); 190 + } 191 + 192 + 193 + this.classRegExp.compile("(.*\b)?class(\b.*)?"); 194 + this.structRegExp.compile("(.*\b)?struct(\b.*)?"); 195 + this.enumRegExp.compile("(.*\b)?enum(\b.*)?"); 196 + this.templateRegExp.compile("(.*\b)?template(\b.*)?"); 197 + this.aliasRegExp.compile("(.*\b)?alias(\b.*)?"); 198 + this.funcRegExp.compile(/.*\(.*/); 199 +} 200 + 201 + 202 + 203 + 204 +/////////////////////////////////////////////////////////////////////////////// 205 +// Package explorer class constructor 206 +/////////////////////////////////////////////////////////////////////////////// 207 +function PackageExplorer() 208 +{ 209 + this.tree = new TreeView(true); 210 + 211 + this.addModule = function(mod) 212 + { 213 + var moduleIco = "candydoc/img/outline/module.gif"; 214 + var packageIco = "candydoc/img/outline/package.gif"; 215 + 216 + var path = mod.split("\."); 217 + var node = this.tree.branch(path[0]); 218 + if ( !node ) 219 + { 220 + node = this.tree.createBranch(path[0], (path.length == 1) ? moduleIco : packageIco); 221 + // modified by k.inaba : link for toplevel module 222 + if (path.length == 1) 223 + node.setRef(path[0] + ".html"); 224 + } 225 + 226 + for (var i = 1; i < path.length; ++i) 227 + { 228 + var prev = node; 229 + node = node.child(path[i]); 230 + if (!node) 231 + node = prev.createChild(path[i], (path.length == i + 1) ? moduleIco : packageIco); 232 + 233 + if (path.length == i + 1) 234 + node.setRef(path[i] + ".html"); 235 + } 236 + } 237 +} 238 + 239 + 240 + 241 +/////////////////////////////////////////////////////////////////////////////// 242 +// Explorer class constructor 243 +/////////////////////////////////////////////////////////////////////////////// 244 +function Explorer() 245 +{ 246 + this.outline = new Outline(); 247 + this.packageExplorer = new PackageExplorer(); 248 + this.tabs = new Array(); 249 + this.tabCount = 0; 250 + 251 + this.initialize = function(moduleName) 252 + { 253 + this.tabArea = document.getElementById("tabarea"); 254 + this.clientArea = document.getElementById("explorerclient"); 255 + 256 + // prevent text selection 257 + this.tabArea.onmousedown = new Function("return false;"); 258 + this.tabArea.onclick = new Function("return true;"); 259 + this.tabArea.onselectstart = new Function("return false;"); 260 + this.clientArea.onmousedown = new Function("return false;"); 261 + this.clientArea.onclick = new Function("return true;"); 262 + this.clientArea.onselectstart = new Function("return false;"); 263 + 264 + this.outline.tree.createBranch( moduleName, "candydoc/img/outline/module.gif" ); 265 + 266 + // create tabs 267 + this.createTab("Outline", this.outline.tree.domEntry); 268 + this.createTab("Package", this.packageExplorer.tree.domEntry); 269 + } 270 + 271 + this.createTab = function(name, domEntry) 272 + { 273 + var tab = new Object(); 274 + this.tabs[name] = tab; 275 + this.tabCount++; 276 + 277 + tab.domEntry = domEntry; 278 + tab.labelSpan = document.createElement("span"); 279 + 280 + if (this.tabCount > 1) 281 + { 282 + tab.labelSpan.className = "inactivetab"; 283 + tab.domEntry.style.display = "none"; 284 + } 285 + else 286 + { 287 + tab.labelSpan.className = "activetab"; 288 + tab.domEntry.style.display = ""; 289 + } 290 + 291 + tab.labelSpan.appendChild( document.createTextNode(name) ); 292 + tab.labelSpan.owner = this; 293 + tab.labelSpan.onclick = new Function("this.owner.setSelection('" + name + "');"); 294 + 295 + this.tabArea.appendChild( tab.labelSpan ); 296 + this.clientArea.appendChild( domEntry ); 297 + } 298 + 299 + this.setSelection = function(tabName) 300 + { 301 + for (name in this.tabs) 302 + { 303 + this.tabs[name].labelSpan.className = "inactivetab"; 304 + this.tabs[name].domEntry.style.display = "none"; 305 + } 306 + 307 + this.tabs[tabName].labelSpan.className = "activetab"; 308 + this.tabs[tabName].domEntry.style.display = ""; 309 + } 310 +}

Added doc/candydoc/ie56hack.css version [177859c3a34718bb]

1 +/* This file is a part of CanDyDOC fileset. 2 + File is written by Victor Nakoryakov and placed into the public domain. 3 + 4 + This file is CSS to work around IE6 and earlier bugs. It's included just 5 + in these browsers. */ 6 + 7 + 8 +/* Some magic to emulate unsupported "position: fixed" style. */ 9 +#tabarea 10 +{ 11 + _position: absolute; 12 + _top: expression(eval(document.body.scrollTop+8)); 13 +} 14 + 15 +/* ditto */ 16 +#explorerclient 17 +{ 18 + _position: absolute; 19 + _top: expression(eval(document.body.scrollTop+24)); 20 + _height: expression(eval(document.body.clientHeight-48)); 21 +}

Added doc/candydoc/img/bg.gif version [8b43eecd7f0cf023]

cannot compute difference between binary files

Added doc/candydoc/img/candydoc.gif version [d9604d4fff4a9b9f]

cannot compute difference between binary files

Added doc/candydoc/img/outline/alias.gif version [4013130069c797c0]

cannot compute difference between binary files

Added doc/candydoc/img/outline/bg.gif version [8064c26d23284159]

cannot compute difference between binary files

Added doc/candydoc/img/outline/class.gif version [02a1203268a966bf]

cannot compute difference between binary files

Added doc/candydoc/img/outline/enum.gif version [3b88f3b3c70424df]

cannot compute difference between binary files

Added doc/candydoc/img/outline/func.gif version [619abf5327b13347]

cannot compute difference between binary files

Added doc/candydoc/img/outline/module.gif version [e6d45a489ef7379f]

cannot compute difference between binary files

Added doc/candydoc/img/outline/package.gif version [c3b57c22493b9f7c]

cannot compute difference between binary files

Added doc/candydoc/img/outline/struct.gif version [7596246f3412f81e]

cannot compute difference between binary files

Added doc/candydoc/img/outline/template.gif version [e390946b34a75c96]

cannot compute difference between binary files

Added doc/candydoc/img/outline/var.gif version [c07b8395e3b2d664]

cannot compute difference between binary files

Added doc/candydoc/img/package/bg.gif version [6e80eac03ee6940c]

cannot compute difference between binary files

Added doc/candydoc/img/tree/shim.gif version [bb926bd9423a14af]

cannot compute difference between binary files

Added doc/candydoc/img/tree/tb.gif version [4fd910f003176986]

cannot compute difference between binary files

Added doc/candydoc/img/tree/tbr.gif version [c80b19ec4a47a45c]

cannot compute difference between binary files

Added doc/candydoc/img/tree/tbrm.gif version [22fbc976c0a6e479]

cannot compute difference between binary files

Added doc/candydoc/img/tree/tbrp.gif version [68befbbc4ac30202]

cannot compute difference between binary files

Added doc/candydoc/img/tree/tr.gif version [d6fceae266cb21e5]

cannot compute difference between binary files

Added doc/candydoc/img/tree/trm.gif version [d01cfe110b86b024]

cannot compute difference between binary files

Added doc/candydoc/img/tree/trp.gif version [dc0fd6c5cc15b562]

cannot compute difference between binary files

Added doc/candydoc/modules.ddoc version [d7e1d5353bbe670c]

1 +MODULES = 2 + $(MODULE main) 3 + $(MODULE tricks.tricks) 4 + $(MODULE tricks.test) 5 + $(MODULE polemy._common) 6 + $(MODULE polemy.lex) 7 + $(MODULE polemy.parse) 8 + $(MODULE polemy.ast) 9 + $(MODULE polemy.eval) 10 + $(MODULE polemy.value)

Added doc/candydoc/style.css version [8f458aa995dfd14e]

1 +/* This file is a part of CanDyDOC fileset. 2 + File is written by Victor Nakoryakov and placed into the public domain. 3 + 4 + This file is main CSS file of CanDyDOC. You may adjust some part of 5 + parameters to control how result documentation would looks like. See 6 + further documentation for details. */ 7 + 8 + 9 + 10 +/* This controls how background would looks like and 11 + sets some document-scope defaults. */ 12 +body 13 +{ 14 + /* These parameters control default font. */ 15 + font-family: Verdana, Arial, Helvetica, sans-serif; 16 + font-size: 10pt; 17 + color: #666666; 18 + 19 + /* These control look of background. Note that you have to use 20 + fixed background to keep documentation good-looking in 21 + IE6 and earlier. Otherwise whole *explorer* will jerk while 22 + scrolling. If you do not want to use background at all use 23 + some invalid url, e.g. url(foo). */ 24 + background-color: #e6fcea; 25 + background: url(img/bg.gif) fixed; 26 + 27 + /* Don't touch. Necessary for IE6 and earlier. */ 28 + height: 100%; 29 +} 30 + 31 + 32 + 33 +/* Style applied to all tables. Actualy there are two: one table is 34 + that contains contant and footer with CanDyDOC logo, and others 35 + are that contains functions' parameters description. */ 36 +table 37 +{ 38 + font-family: Verdana, Arial, Helvetica, sans-serif; 39 + font-size: 10pt; 40 + color: #666666; 41 + text-align: justify; 42 +} 43 + 44 + 45 +/* Style used for all hyperlinks. */ 46 +a:link { color: #009900; text-decoration: none } 47 +a:visited { color: #009999; text-decoration: none } 48 +a:hover { color: #0033cc; text-decoration: none } 49 +a:active { color: #0033cc; text-decoration: none } 50 + 51 +/* 52 +table.matrix 53 +{ 54 + border-left: double 3px #666666; 55 + border-right: double 3px #666666; 56 + margin-left: 3em; 57 +} 58 +*/ 59 + 60 +/* Style appled to declarations. E.g. 'void foo(int a, float b);' */ 61 +span.decl { font-size: 10pt; font-weight: bold; color: #000000; text-align: left } 62 +/* Style appled to current declaration's symbol. E.g. 'foo' in 'void foo(int a, float b);' */ 63 +span.currsymbol { font-size: 12pt; color: #009900 } 64 +/* Style appled to function's parameters. E.g. 'a' and 'b' in 'void foo(int a, float b);' */ 65 +span.funcparam { font-style: italic; font-weight: normal; color: #331200 } 66 + 67 +/* Style for div that actualy contains documenation. */ 68 +#content 69 +{ 70 + padding-right: 8px; 71 + position: absolute; 72 + left: 245px; 73 + top: 8px; 74 + text-align: justify; 75 +} 76 + 77 +/* Style for table that is inside div considered above. Contains documentaton 78 + itself and footer with CanDyDOC logo. */ 79 +table.content 80 +{ 81 + margin-bottom: 8px; 82 + border-spacing: 0px; 83 + border-collapse: collapse; 84 + background-color: #ffffff; 85 +} 86 + 87 +/* Style for cell of above considered table that contains documentation itself. */ 88 +#docbody 89 +{ 90 + padding: 8px 20px 8px 20px; 91 + border: solid 1px #009900; 92 +} 93 + 94 +/* Style for cell that contains CanDyDOC logo. */ 95 +#docfooter 96 +{ 97 + height: 16px; 98 + background-color: #ddeedd; 99 + padding: 0px 8px 0px 8px; 100 + border: solid 1px #009900; 101 +} 102 + 103 +/* Style applied to currently active tab of explorer window. */ 104 +span.activetab 105 +{ 106 + background-color: #0033cc; 107 + border-top: solid 2px #009900; 108 + color: #ffffff; 109 + font-weight: bold; 110 + padding-left: 4px; 111 + padding-right: 4px; 112 + padding-top: 1px; 113 + margin-right: 1px; 114 +} 115 + 116 +/* Style applied to currently inactive tab of explorer window. */ 117 +span.inactivetab 118 +{ 119 + background-color: #000066; 120 + color: #cccccc; 121 + font-weight: normal; 122 + padding-left: 4px; 123 + padding-right: 4px; 124 + padding-top: 0px; 125 + margin-right: 1px; 126 +} 127 + 128 +/* Style applied to div that contains tabs of explorer. Note that if 129 + you want to change it's position you have to change position of 130 + #explorerclient, #content and corresponding values in ie56hack.css */ 131 +#tabarea 132 +{ 133 + position: fixed; 134 + top: 8px; 135 + width: 205px; 136 + height: 16px; 137 + cursor: default; 138 +} 139 + 140 + 141 +/* Style applied to div that contains tree in explorer. Note that if 142 + you want to change it's position you have to change position of 143 + #tabarea, #content and corresponding values in ie56hack.css */ 144 +#explorerclient 145 +{ 146 + position: fixed; 147 + top: 24px; 148 + bottom: 8px; 149 + width: 205px; 150 + overflow: auto; 151 + background-color: #fcfffc; 152 + border: solid 2px #0033cc; 153 + padding: 4px; 154 + cursor: default; 155 + color: Black; 156 +} 157 + 158 +/* Following 3 styles control appearance of marker that appears 159 + if you click some entity in outline window. */ 160 +div.markertop { border-left: solid 2px #0033cc;} 161 +div.markermiddle{ border-left: dotted 2px #0033cc;} 162 +div.markerbottom{ border-left: dotted 2px #66cc66;} 163 + 164 +/* Style applied to preformated text used to show examples. */ 165 +pre.d_code 166 +{ 167 + border: dotted 1px #9c9; 168 + background-color: #eeffee; 169 +}

Added doc/candydoc/tree.js version [d0527f77fa102d00]

1 +/* This file is a part of CanDyDOC fileset. 2 + File is written by Victor Nakoryakov and placed into the public domain. 3 + 4 + This file is javascript with classes that represents native style tree control. */ 5 + 6 +var pmNone = 0; 7 +var pmPlus = 1; 8 +var pmMinus = 2; 9 + 10 +var hlNone = 0; 11 +var hlGrey = 1; 12 +var hlSelected = 2; 13 + 14 +function TreeView(hrefMode) 15 +{ 16 + this.domEntry = document.createElement("div"); 17 + this.children = new Array(); 18 + this.selection = null; 19 + this.hrefMode = hrefMode; 20 + 21 + this.createBranch = function(text, iconSrc) 22 + { 23 + var root = new TreeNode(text, iconSrc, this.hrefMode); 24 + root.owner = this; 25 + this.children[ this.children.length ] = root; 26 + this.domEntry.appendChild( root.domEntry ); 27 + return root; 28 + } 29 + 30 + this.branch = function(text) 31 + { 32 + var ret = null; 33 + for (var i = 0; i < this.children.length; ++i) 34 + if (this.children[i].textElement.data == text) 35 + { 36 + ret = this.children[i]; 37 + break; 38 + } 39 + 40 + return ret; 41 + } 42 + 43 + this.domEntry.style.fontSize = "10px"; 44 + this.domEntry.style.cursor = "default"; 45 + this.domEntry.style.whiteSpace = "nowrap"; 46 +} 47 + 48 +var idCounter = 0; 49 +function TreeNode(text, iconSrc, hrefMode) 50 +{ 51 + this.id = idCounter++; 52 + this.parentNode = null; 53 + this.children = new Array(); 54 + this.domEntry = document.createElement("div"); 55 + this.icon = document.createElement("img"); 56 + this.textElement = document.createTextNode(text); 57 + this.textSpan = document.createElement("span"); 58 + this.lineDiv = document.createElement("div"); 59 + this.hierarchyImgs = new Array(); 60 + this.onclick = null; 61 + 62 + function createIcon() 63 + { 64 + var img = document.createElement("img"); 65 + img.style.verticalAlign = "middle"; 66 + img.style.position = "relative"; 67 + img.style.top = "-1px"; 68 + img.width = 16; 69 + img.height = 16; 70 + return img; 71 + } 72 + 73 + function createHierarchyImage() 74 + { 75 + var img = createIcon(); 76 + img.pointsTop = false; 77 + img.pointsBottom = false; 78 + img.pointsRight = false; 79 + img.pmState = pmNone; 80 + return img; 81 + } 82 + 83 + function genHierarchyImageSrc(hierarchyImg) 84 + { 85 + var name = ""; 86 + if (hierarchyImg.pointsTop) 87 + name += "t"; 88 + 89 + if (hierarchyImg.pointsBottom) 90 + name += "b"; 91 + 92 + if (hierarchyImg.pointsRight) 93 + name += "r"; 94 + 95 + if (hierarchyImg.pmState == pmPlus) 96 + name += "p"; 97 + else if (hierarchyImg.pmState == pmMinus) 98 + name += "m"; 99 + 100 + if (name == "") 101 + name = "shim"; 102 + 103 + return "candydoc/img/tree/" + name + ".gif"; 104 + } 105 + 106 + function setSrc(icon, src) 107 + { 108 + icon.src = src; 109 + // After src change width and height are reseted in IE. 110 + // Bug workaround: 111 + icon.width = 16; 112 + icon.height = 16; 113 + } 114 + 115 + this.createChild = function(text, iconSrc) 116 + { 117 + var child = new TreeNode(text, iconSrc, this.owner.hrefMode); 118 + this.children[ this.children.length ] = child; 119 + this.domEntry.appendChild( child.domEntry ); 120 + child.parentNode = this; 121 + child.owner = this.owner; 122 + 123 + // insert hierarchy images according to deepness level 124 + // of created child. 125 + 126 + if (this.children.length > 1) 127 + { 128 + // there were already added child before. So copy `level-1` 129 + // hierarchy images from it. 130 + 131 + var prevAddedChild = this.children[ this.children.length - 2 ]; 132 + 133 + for (var i = 0; i < prevAddedChild.hierarchyImgs.length - 1; ++i) 134 + { 135 + var prevAddedChildImg = prevAddedChild.hierarchyImgs[i]; 136 + var img = createHierarchyImage(); 137 + setSrc(img, prevAddedChildImg.src); 138 + img.pointsTop = prevAddedChildImg.pointsTop; 139 + img.pointsBottom = prevAddedChildImg.pointsBottom; 140 + img.pointsRight = prevAddedChildImg.pointsRight; 141 + img.pmState = prevAddedChildImg.pmState; 142 + 143 + child.hierarchyImgs[ child.hierarchyImgs.length ] = img; 144 + child.lineDiv.insertBefore(img, child.icon); 145 + } 146 + 147 + // change last hierarchy image of prevAddedChild from |_ to |- 148 + var lastHierarchyImg = prevAddedChild.hierarchyImgs[ prevAddedChild.hierarchyImgs.length - 1 ]; 149 + lastHierarchyImg.pointsBottom = true; 150 + setSrc(lastHierarchyImg, genHierarchyImageSrc(lastHierarchyImg)); 151 + 152 + // change hierarchy images of prevAddedChild's children on it's last 153 + // level to | 154 + prevAddedChild.addHierarchyTBLine(prevAddedChild.hierarchyImgs.length - 1); 155 + } 156 + else 157 + { 158 + // this is a first child. So copy `level-2` 159 + // hierarchy images from parent, i.e. this. 160 + 161 + for (var i = 0; i < this.hierarchyImgs.length - 1; ++i) 162 + { 163 + var parentImg = this.hierarchyImgs[i]; 164 + var img = createHierarchyImage(); 165 + setSrc(img, parentImg.src); 166 + img.pointsTop = parentImg.pointsTop; 167 + img.pointsBottom = parentImg.pointsBottom; 168 + img.pointsRight = parentImg.pointsRight; 169 + img.pmState = parentImg.pmState; 170 + 171 + child.hierarchyImgs[ child.hierarchyImgs.length ] = img; 172 + child.lineDiv.insertBefore(img, child.icon); 173 + } 174 + 175 + if (this.hierarchyImgs.length > 0) // we are not root 176 + { 177 + // change last hierarchy image of parent (i.e. this): add minus to it 178 + var lastHierarchyImg = this.hierarchyImgs[ this.hierarchyImgs.length - 1]; 179 + lastHierarchyImg.pmState = pmMinus; 180 + setSrc(lastHierarchyImg, genHierarchyImageSrc(lastHierarchyImg)); 181 + lastHierarchyImg.owner = this; 182 + lastHierarchyImg.onclick = new Function("e", "this.owner.processPMClick(e);"); 183 + 184 + // make decision on image on `level-1`. It depends on parent's (ie this) 185 + // image on same level. 186 + var parentL1HierarchyImg = lastHierarchyImg; 187 + var l1HierarchyImg = createHierarchyImage(); 188 + if (parentL1HierarchyImg.pointsBottom) 189 + { 190 + l1HierarchyImg.pointsTop = true; 191 + l1HierarchyImg.pointsBottom = true; 192 + } 193 + setSrc(l1HierarchyImg, genHierarchyImageSrc(l1HierarchyImg)); 194 + child.hierarchyImgs[ child.hierarchyImgs.length ] = l1HierarchyImg; 195 + child.lineDiv.insertBefore(l1HierarchyImg, child.icon); 196 + } 197 + } 198 + 199 + // in any case on last level our child will have icon |_ 200 + var img = createHierarchyImage(); 201 + img.pointsTop = true; 202 + img.pointsRight = true; 203 + setSrc(img, genHierarchyImageSrc(img)); 204 + 205 + child.hierarchyImgs[ child.hierarchyImgs.length ] = img; 206 + child.lineDiv.insertBefore(img, child.icon); 207 + 208 + return child; 209 + } 210 + 211 + this.lastChild = function() 212 + { 213 + return this.children[ this.children.length - 1 ]; 214 + } 215 + 216 + this.child = function(text) 217 + { 218 + var ret = null; 219 + for (var i = 0; i < this.children.length; ++i) 220 + if (this.children[i].textElement.data == text) 221 + { 222 + ret = this.children[i]; 223 + break; 224 + } 225 + 226 + return ret; 227 + } 228 + 229 + this.addHierarchyTBLine = function(level) 230 + { 231 + for (var i = 0; i < this.children.length; ++i) 232 + { 233 + var img = this.children[i].hierarchyImgs[level]; 234 + img.pointsTop = true; 235 + img.pointsBottom = true; 236 + setSrc(img, genHierarchyImageSrc(img)); 237 + this.children[i].addHierarchyTBLine(level); 238 + } 239 + } 240 + 241 + this.expand = function() 242 + { 243 + var img = this.hierarchyImgs[ this.hierarchyImgs.length - 1 ]; 244 + 245 + if (img.pmState == pmPlus) 246 + { 247 + img.pmState = pmMinus; 248 + setSrc(img, genHierarchyImageSrc(img)); 249 + 250 + for (var i = 0; i < this.children.length; ++i) 251 + this.children[i].domEntry.style.display = ""; 252 + } 253 + } 254 + 255 + this.collapse = function() 256 + { 257 + var img = this.hierarchyImgs[ this.hierarchyImgs.length - 1 ]; 258 + 259 + if (img.pmState == pmMinus) 260 + { 261 + img.pmState = pmPlus; 262 + setSrc(img, genHierarchyImageSrc(img)); 263 + 264 + for (var i = 0; i < this.children.length; ++i) 265 + this.children[i].domEntry.style.display = "none"; 266 + } 267 + } 268 + 269 + this.toggle = function() 270 + { 271 + var img = this.hierarchyImgs[ this.hierarchyImgs.length - 1 ]; 272 + if (img.pmState == pmMinus) 273 + this.collapse(); 274 + else 275 + this.expand(); 276 + } 277 + 278 + this.select = function() 279 + { 280 + if (this.owner.selection != this) 281 + { 282 + if (this.owner.selection) 283 + this.owner.selection.setHighlight(hlNone); 284 + 285 + this.owner.selection = this; 286 + this.setHighlight(hlSelected); 287 + } 288 + } 289 + 290 + this.setHighlight = function(mode) 291 + { 292 + if (mode == hlNone) 293 + { 294 + this.textSpan.style.backgroundColor = ""; 295 + this.textSpan.style.color = ""; 296 + this.textSpan.style.border = ""; 297 + } 298 + else if (mode == hlGrey) 299 + { 300 + this.textSpan.style.backgroundColor = "#aaaaaa"; 301 + this.textSpan.style.color = ""; 302 + this.textSpan.style.border = ""; 303 + } 304 + else if (mode == hlSelected) 305 + { 306 + this.textSpan.style.backgroundColor = "3399cc"; 307 + this.textSpan.style.color = "white"; 308 + this.textSpan.style.border = "dotted 1px red"; 309 + } 310 + } 311 + 312 + this.setOnclick = function(proc) 313 + { 314 + this.onclick = proc; 315 + } 316 + 317 + this.setRef = function(url) 318 + { 319 + if (this.anchor) 320 + this.anchor.href = url; 321 + } 322 + 323 + this.processPMClick = function(e) 324 + { 325 + this.toggle(); 326 + 327 + // prevent this line selection, stop bubbling 328 + if (e) 329 + e.stopPropagation(); // Mozilla way 330 + if (window.event) 331 + window.event.cancelBubble = true; // IE way 332 + } 333 + 334 + this.processOnclick = function() 335 + { 336 + this.select(); 337 + if (this.onclick instanceof Function) 338 + this.onclick(); 339 + } 340 + 341 + /////////////////////////////////////////////////////////////////////////// 342 + if (iconSrc) 343 + this.icon.src = iconSrc; 344 + else 345 + { 346 + this.icon.width = 0; 347 + this.icon.height = 0; 348 + } 349 + 350 + this.icon.style.verticalAlign = "middle"; 351 + this.icon.style.position = "relative"; 352 + this.icon.style.top = "-1px"; 353 + this.icon.style.paddingRight = "2px"; 354 + 355 + if (!hrefMode) 356 + { 357 + this.textSpan.appendChild( this.textElement ); 358 + } 359 + else 360 + { 361 + this.anchor = document.createElement("a"); 362 + this.anchor.appendChild( this.textElement ); 363 + this.textSpan.appendChild( this.anchor ); 364 + } 365 + 366 + this.lineDiv.appendChild( this.icon ); 367 + this.lineDiv.appendChild( this.textSpan ); 368 + this.domEntry.appendChild( this.lineDiv ); 369 + 370 + this.lineDiv.owner = this; 371 + 372 + if (!hrefMode) 373 + this.lineDiv.onclick = new Function("this.owner.processOnclick();"); 374 +}

Added doc/candydoc/util.js version [38c5184f5c221c40]

1 +/* This file is a part of CanDyDOC fileset. 2 + File is written by Victor Nakoryakov and placed into the public domain. 3 + 4 + This file is javascript with cross-browser utility functions. */ 5 + 6 +function getLeft(elem) 7 +{ 8 + var ret = 0; 9 + while (elem.offsetParent) 10 + { 11 + ret += elem.offsetLeft; 12 + elem = elem.offsetParent; 13 + } 14 + 15 + return ret; 16 +} 17 + 18 +function getTop(elem) 19 +{ 20 + var ret = 0; 21 + while (elem.offsetParent) 22 + { 23 + ret += elem.offsetTop; 24 + elem = elem.offsetParent; 25 + } 26 + 27 + return ret; 28 +} 29 + 30 +function getWindowHeight() 31 +{ 32 + var ret = 0; 33 + if (typeof(window.innerHeight) == "number") 34 + ret = window.innerHeight; 35 + else if (document.documentElement && document.documentElement.clientHeight) 36 + ret = document.documentElement.clientHeight; 37 + else if (document.body && document.body.clientHeight) 38 + ret = document.body.clientHeight; 39 + 40 + return ret; 41 +}

Modified main.d from [667427a12e5e3b09] to [abae545f4409680b].

9 9 import std.algorithm; 10 10 import polemy.value; 11 11 import polemy.lex; 12 12 import polemy.parse; 13 13 import polemy.ast; 14 14 import polemy.eval; 15 15 16 +/// Tenuki Read-Eval-Print-Loop 16 17 class REPL 17 18 { 18 19 Table ctx; 19 20 string buf; 20 21 Value lastVal; 21 22 int lineno = 1; 22 23 int nextlineno = 1; ................................................................................ 55 56 } 56 57 57 58 version(unittest) { 58 59 bool success = false; 59 60 static ~this(){ if(!success){writeln("(press enter to exit)"); readln();} } 60 61 } 61 62 63 +/// Entry point. If args.length==1, invoke REPL. 64 +/// Otherwise interpret the argument as a filename. 62 65 void main( string[] args ) 63 66 { 64 67 version(unittest) success=true; 65 68 66 69 if( args.length <= 1 ) 67 70 { 68 71 writeln("Welcome to Polemy 0.1.0");

Modified polemy/ast.d from [dd714695d64176f9] to [b8324439b8512940].

4 4 * 5 5 * Syntax tree for Polemy programming language. 6 6 */ 7 7 module polemy.ast; 8 8 import polemy._common; 9 9 import polemy.lex; 10 10 11 +/// 11 12 abstract class AST 12 13 { 13 14 immutable LexPosition pos; 14 15 mixin SimpleConstructor; 15 16 } 16 17 18 +/// 17 19 class StrLiteral : AST 18 20 { 19 21 string data; 20 22 mixin SimpleClass; 21 23 } 22 24 25 +/// 23 26 class IntLiteral : AST 24 27 { 25 28 BigInt data; 26 29 mixin SimpleClass; 27 30 this(immutable LexPosition pos, long n) {super(pos); data = n;} 28 31 this(immutable LexPosition pos, BigInt n) {super(pos); data = n;} 29 32 this(immutable LexPosition pos, string n) {super(pos); data = BigInt(n);} 30 33 } 31 34 35 +/// 32 36 class VarExpression : AST 33 37 { 34 38 string var; 35 39 mixin SimpleClass; 36 40 } 37 41 42 +/// 38 43 class LayeredExpression : AST 39 44 { 40 45 string lay; 41 46 AST expr; 42 47 mixin SimpleClass; 43 48 } 44 49 50 +/// 45 51 class LetExpression : AST 46 52 { 47 53 string var; 48 54 string layer; 49 55 AST init; 50 56 AST expr; 51 57 mixin SimpleClass; 52 58 } 53 59 60 +/// 54 61 class FuncallExpression : AST 55 62 { 56 63 AST fun; 57 64 AST[] args; 58 65 this(immutable LexPosition pos, AST fun, AST[] args...) 59 66 { super(pos); this.fun=fun; this.args=args.dup; } 60 67 mixin SimpleClass; 61 68 } 62 69 70 +/// 63 71 class FunLiteral : AST 64 72 { 65 73 string[] params; 66 74 AST funbody; 67 75 mixin SimpleClass; 68 76 } 69 77 70 78 /// Handy Generator for AST nodes. To use this, mixin EasyAst; 71 79 72 80 /*mixin*/ 73 81 template EasyAST() 74 82 { 83 + /// 75 84 template genEast(T) 76 85 { T genEast(P...)(P ps) { return new T(LexPosition.dummy, ps); } } 77 86 78 - alias genEast!StrLiteral strl; 79 - alias genEast!IntLiteral intl; 80 - auto fun(string[] xs, AST ps) { return genEast!FunLiteral(xs,ps); } // to help type inference of D 81 - alias genEast!VarExpression var; 82 - alias genEast!LayeredExpression lay; 83 - alias genEast!LetExpression let; 84 - alias genEast!FuncallExpression call; 87 + alias genEast!StrLiteral strl; /// 88 + alias genEast!IntLiteral intl; /// 89 + auto fun(string[] xs, AST ps) { return genEast!FunLiteral(xs,ps); } /// 90 + alias genEast!VarExpression var; /// 91 + alias genEast!LayeredExpression lay; /// 92 + alias genEast!LetExpression let; /// 93 + alias genEast!FuncallExpression call; /// 85 94 }

Modified polemy/eval.d from [050eab1743a45f8b] to [ab3a0c217b77981b].

9 9 import polemy.lex : LexPosition; 10 10 import polemy.ast; 11 11 import polemy.parse; 12 12 import polemy.value; 13 13 import std.typecons; 14 14 import std.stdio; 15 15 16 +/// 16 17 Table createGlobalContext() 17 18 { 18 19 auto ctx = new Table; 19 20 // [TODO] autogenerate these typechecks 20 21 ctx.set("+", "@v", new FunValue(delegate Value(immutable LexPosition pos, Layer lay, Value[] args){ 21 22 if( args.length != 2 ) 22 23 throw genex!RuntimeException(pos, "+ takes two arguments!!"); ................................................................................ 85 86 86 87 /// Entry point of this module 87 88 88 89 Tuple!(Value,"val",Table,"ctx") evalString(S,T...)(S str, T fn_ln_cn) 89 90 { 90 91 return eval( polemy.parse.parseString(str, fn_ln_cn) ); 91 92 } 93 + 94 +/// Entry point of this module 92 95 93 96 Tuple!(Value,"val",Table,"ctx") evalFile(S, T...)(S filename, T ln_cn) 94 97 { 95 98 return eval( polemy.parse.parseFile(filename, ln_cn) ); 96 99 } 100 + 101 +/// Entry point of this module 97 102 98 103 Tuple!(Value,"val",Table,"ctx") eval(AST e) 99 104 { 100 105 Table ctx = createGlobalContext(); 101 106 return typeof(return)(eval(e, ctx, false, "@v"), ctx); 102 107 } 103 108 109 +/// Entry point of this module 110 +/// If splitCtx = true, then inner variable declaration do not overwrite ctx. 111 +/// lay is the layer ID for evaluation (standard value semantics uses "@v"). 112 + 104 113 Value eval(AST _e, Table ctx, bool splitCtx, Layer lay) 105 114 { 106 115 if( auto e = cast(StrLiteral)_e ) 107 116 { 108 117 return new StrValue(e.data); 109 118 } 110 119 else

Modified polemy/lex.d from [caf474d107a1f8cb] to [4e484112cd314d8d].

5 5 * Lexer for Polemy programming language. 6 6 */ 7 7 module polemy.lex; 8 8 import polemy._common; 9 9 import std.file : readText; 10 10 import std.ctype : isspace, isalnum; 11 11 12 -/// Exception from this module 13 - 14 12 /*mixin*/ 15 13 template ExceptionWithPosition() 16 14 { 17 15 const LexPosition pos; 18 16 this( const LexPosition pos, string msg, string file=null, size_t line=0, Throwable next=null ) 19 17 { super(sprintf!"[%s] %s"(pos, msg), file, line, next); this.pos = pos; } 20 18 } 21 19 20 +/// 22 21 class UnexpectedEOF : Exception 23 22 { 24 23 mixin ExceptionWithPosition; 25 24 } 26 25 26 +/// 27 27 class LexException : Exception 28 28 { 29 29 mixin ExceptionWithPosition; 30 30 }; 31 31 32 32 /// Represents a position in a source code 33 33 ................................................................................ 93 93 assert( !__traits(compiles, t.pos=p) ); 94 94 assert( !__traits(compiles, t.str=789) ); 95 95 assert( !__traits(compiles, t.quoted=true) ); 96 96 } 97 97 98 98 /// Named Construtors for Lexer 99 99 100 -auto lexerFromFile(T...)( string filename, T rest ) 100 +Lexer lexerFromFile(T...)( string filename, T rest ) 101 101 { 102 102 return lexerFromString( std.file.readText(filename), filename, rest ); 103 103 } 104 104 105 -auto lexerFromString(CharSeq)( CharSeq str, string filename="<unnamed>", int lineno=1, int column=1 ) 105 +/// Named Construtors for Lexer 106 + 107 +LexerT!(PositionedReader!CharSeq) /* ddoc doesn't recognize auto return... bugzilla:2581 */ 108 +lexerFromString(CharSeq)( CharSeq str, string filename="<unnamed>", int lineno=1, int column=1 ) 106 109 { 107 110 return new LexerT!(PositionedReader!CharSeq)( 108 111 PositionedReader!CharSeq(str, filename, lineno, column) 109 112 ); 110 113 } 111 114 112 115 /// Standard Lexer Type (all you have to know is that this is a forward range of Tokens)

Modified polemy/parse.d from [42c980cf31500e88] to [2739b95337ae2aab].

5 5 * Parser for Polemy programming language 6 6 */ 7 7 module polemy.parse; 8 8 import polemy._common; 9 9 import polemy.lex; 10 10 import polemy.ast; 11 11 12 -/// Exception from this module 13 - 12 +/// 14 13 class ParseException : Exception 15 14 { 16 15 mixin ExceptionWithPosition; 17 16 } 18 17 19 18 /// Entry points of this module 20 19 21 -auto parseString(S, T...)(S str, T fn_ln_cn) 20 +AST parseString(S, T...)(S str, T fn_ln_cn) 22 21 { return parserFromString(str, fn_ln_cn).parse(); } 23 22 24 -auto parseFile(S, T...)(S filename, T ln_cn) 23 +/// Entry points of this module 24 + 25 +AST parseFile(S, T...)(S filename, T ln_cn) 25 26 { return parserFromFile(filename, ln_cn).parse(); } 26 27 27 -/// Named Constructor of Parser 28 +// Named Constructors of Parser 28 29 29 30 private auto parserFromLexer(Lexer)(Lexer lex) 30 31 { return new Parser!Lexer(lex); } 31 32 32 33 private auto parserFromString(T...)(T params) 33 34 { return parserFromLexer(polemy.lex.lexerFromString(params)); } 34 35 35 36 private auto parserFromFile(T...)(T params) 36 37 { return parserFromLexer(polemy.lex.lexerFromFile(params)); } 37 38 38 -/// Parser 39 +// Parser 39 40 40 41 private class Parser(Lexer) 41 42 if( isForwardRange!(Lexer) && is(ElementType!(Lexer) == Token) ) 42 43 { 43 44 AST parse() 44 45 { 45 46 auto e = Body();

Modified tricks/test.d from [7c50b0e91b8919b8] to [1483c10390a22fc3].

26 26 catch(Throwable e) 27 27 { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad exception\n >> "~e.toString()); } 28 28 onAssertErrorMsg(fn, ln, msg.length ? msg : "not thrown"); 29 29 } 30 30 31 31 /// Unittest helper that asserts an expression must not throw anything 32 32 33 -auto assert_nothrow(T, string fn=__FILE__, size_t ln=__LINE__)(lazy T t, string msg="") 33 +T assert_nothrow(T, string fn=__FILE__, size_t ln=__LINE__)(lazy T t, string msg="") 34 34 { 35 35 try 36 36 { return t(); } 37 37 catch(Throwable e) 38 38 { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad exception\n >> "~e.toString()); } 39 39 assert(false); 40 40 } ................................................................................ 51 51 52 52 assert_nothrow ( assert_throw!Error(error()) ); 53 53 assert_throw!AssertError( assert_throw!Error(nothing()) ); 54 54 assert_nothrow ( assert_throw!Error(assertError()) ); 55 55 assert_throw!AssertError( assert_throw!AssertError(error()) ); 56 56 } 57 57 58 -/// Unittest helpers asserting two values are in some relation ==, !=, <, <=, >, >= 59 - 60 58 template assertOp(string op) 61 59 { 62 60 void assertOp(A, B, string fn=__FILE__, size_t ln=__LINE__)(A a, B b, string msg="") 63 61 { 64 62 try 65 63 { if( mixin("a"~op~"b") ) return; } 66 64 catch(Throwable e) 67 65 { onAssertErrorMsg(fn, ln, msg.length ? msg : "exception ["~e.toString()~"]"); } 68 66 onAssertErrorMsg(fn, ln, msg.length ? msg : to!string(a)~" !"~op~" "~to!string(b)); 69 67 } 70 68 } 71 69 72 -alias assertOp!(`==`) assert_eq; 73 -alias assertOp!(`!=`) assert_ne; 74 -alias assertOp!(`<`) assert_lt; 75 -alias assertOp!(`<=`) assert_le; 76 -alias assertOp!(`>`) assert_gt; 77 -alias assertOp!(`>=`) assert_ge; 70 +alias assertOp!(`==`) assert_eq; /// asserts two operands are == 71 +alias assertOp!(`!=`) assert_ne; /// asserts two operands are != 72 +alias assertOp!(`<`) assert_lt; /// asserts two operands are < 73 +alias assertOp!(`<=`) assert_le; /// asserts two operands are <= 74 +alias assertOp!(`>`) assert_gt; /// asserts two operands are > 75 +alias assertOp!(`>=`) assert_ge; /// asserts two operands are >= 78 76 79 77 unittest 80 78 { 81 79 assert_nothrow( assert_eq(1, 1) ); 82 80 assert_nothrow( assert_ne(1, 0) ); 83 81 assert_nothrow( assert_lt(0, 1) ); 84 82 assert_nothrow( assert_le(0, 1) );

Modified tricks/tricks.d from [4c996bb5859ed5ea] to [d70e48b147acc242].

24 24 assert_eq( sprintf!"%s == %04d"("1+2", 3), "1+2 == 0003" ); 25 25 assert_eq( sprintf!"%2$s == %1$s"("1+2", 5, 8), "5 == 1+2" ); 26 26 assert_throw!Error( sprintf!"%s%s"(1) ); 27 27 } 28 28 29 29 /// Create an exception with automatically completed filename and lineno information 30 30 31 -auto genex(ExceptionType, string fn=__FILE__, int ln=__LINE__, T...)(T params) 31 +ExceptionType genex(ExceptionType, string fn=__FILE__, int ln=__LINE__, T...)(T params) 32 32 { 33 33 static if( T.length > 0 && is(T[$-1] : Throwable) ) 34 34 return new ExceptionType(params[0..$-1], fn, ln, params[$-1]); 35 35 else 36 36 return new ExceptionType(params, fn, ln); 37 37 } 38 38 ................................................................................ 44 44 } 45 45 46 46 /// Mixing-in the bean constructor for a class 47 47 48 48 /*mixin*/ 49 49 template SimpleConstructor() 50 50 { 51 + /// member-by-member constructor 51 52 static if( is(typeof(super) == Object) || super.tupleof.length==0 ) 52 53 this( typeof(this.tupleof) params ) 53 54 { 54 55 static if(this.tupleof.length>0) 55 56 this.tupleof = params; 56 57 } 57 58 else ................................................................................ 89 90 assert_eq( (new Tomp(1,"foo",2.5)).z, 2.5 ); 90 91 assert( !__traits(compiles, new Tomp(3.14)) ); 91 92 92 93 // shiyo- desu. Don't use in this way. 93 94 // Tamp tries to call new Tomp(real) (because it only sees Tomp's members), 94 95 // but it fails because Tomp takes (int,string,real). 95 96 assert( !__traits(compiles, { 96 - class Tamp : Tomp 97 - { 98 - mixin SimpleConstructor; 99 - } 97 + class Tamp : Tomp { mixin SimpleConstructor; } 100 98 }) ); 101 99 } 102 100 103 101 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class 104 102 105 103 /*mixin*/ 106 104 template SimpleCompare() 107 105 { 108 - override bool opEquals(Object rhs_) const 106 + override bool opEquals(Object rhs_) const /// member-by-member equality 109 107 { 110 108 if( auto rhs = cast(typeof(this))rhs_ ) 111 109 { 112 110 foreach(i,_; this.tupleof) 113 111 if( this.tupleof[i] != rhs.tupleof[i] ) 114 112 return false; 115 113 return true; 116 114 } 117 115 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_))); 118 116 } 119 117 120 - override hash_t toHash() const 118 + override hash_t toHash() const /// member-by-member hash 121 119 { 122 120 hash_t h = 0; 123 121 foreach(mem; this.tupleof) 124 122 h += typeid(mem).getHash(&mem); 125 123 return h; 126 124 } 127 125 128 - override int opCmp(Object rhs_) const 126 + override int opCmp(Object rhs_) const /// member-by-member compare 129 127 { 130 128 if( auto rhs = cast(typeof(this))rhs_ ) 131 129 { 132 130 foreach(i,_; this.tupleof) 133 131 if(auto c = typeid(_).compare(&this.tupleof[i],&rhs.tupleof[i])) 134 132 return c; 135 133 return 0; ................................................................................ 167 165 } 168 166 169 167 /// Mixing-in a simple toString method 170 168 171 169 /*mixin*/ 172 170 template SimpleToString() 173 171 { 172 + /// member-by-member toString 174 173 override string toString() 175 174 { 176 175 string str = sprintf!"%s("(typeof(this).stringof); 177 176 foreach(i,mem; this.tupleof) 178 177 { 179 178 if(i) str ~= ","; 180 179 static if( is(typeof(mem) == std.bigint.BigInt) )