diff --git a/build-aux/bootstrap/prebirth.js b/build-aux/bootstrap/prebirth.js index b648cb6..b1cb739 100644 --- a/build-aux/bootstrap/prebirth.js +++ b/build-aux/bootstrap/prebirth.js @@ -321,15 +321,45 @@ class Compiler { this.assertApply( t, 'define-block' ); - // e.g. (define-block ((input ...)) body) - const [ , { value: name }, desc, ...body ] = t; + // e.g. (define-block doc ((input ...)) body) + const [ , { value: name }, doc, desc, ...body ] = t; const id = this._idFromName( name ); + const docstr = this._docstring( doc ); const bodyjs = this._bodyToEs( body ); // this is the final format---each block becomes its own function // definition - return `function ${id}()\n{\n${bodyjs}\n};`; + return `${docstr}\nfunction ${id}()\n{\n${bodyjs}\n};`; + } + + + /** + * Compile docblock string + * + * This converts to the docstring T into a docblock. No annotations are + * generated---it is output verbatim. If the docstring is the empty + * string, then the empty string is returned. + * + * @param {string} t docstring token + * + * @return {string} generated docblock or the empty string + */ + _docstring( t ) + { + if ( t.type !== 'string' ) { + throw TypeError( `Expected string docblock, but found ${t.type}` ); + } + + const doc = t.value; + + // don't bother with the docblock generation if we have nothing useful + if ( !doc ) { + return ""; + } + + // enclose in multi-line comment delimiters and prefix each line + return "/**\n" + doc.replace( /^/g, " * " ) + "\n */"; } @@ -525,6 +555,7 @@ class Compiler * Here is an example Hello, World!: * * (define-block + * "A simple 'Hello, World!' program." * () * ( ((message "Hello, world!")))) *