Compare commits
6 Commits
30293f7dd7
...
13334f22e3
Author | SHA1 | Date |
---|---|---|
Tristan B. Velloza Kildaire | 13334f22e3 | |
Tristan B. Velloza Kildaire | cc87c8048c | |
Tristan B. Velloza Kildaire | 0b927e93e4 | |
Tristan B. Velloza Kildaire | 87ddafe304 | |
Tristan B. Velloza Kildaire | ad67ce6309 | |
Tristan B. Velloza Kildaire | 0f5ba970af |
|
@ -445,6 +445,23 @@ public final class Parser
|
|||
{
|
||||
Statement ret;
|
||||
|
||||
/* If there are any comments available then pop them off now */
|
||||
// TODO: Check if we should pop anything off of the comment
|
||||
// stack here
|
||||
Comment potComment;
|
||||
if(hasCommentsOnStack())
|
||||
{
|
||||
potComment = popComment();
|
||||
}
|
||||
|
||||
scope(exit)
|
||||
{
|
||||
if(potComment)
|
||||
{
|
||||
ret.setComment(potComment);
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the name or type */
|
||||
string nameTYpe = lexer.getCurrentToken().getToken();
|
||||
DEBUG("parseName(): Current token: "~lexer.getCurrentToken().toString());
|
||||
|
@ -2181,7 +2198,8 @@ public final class Parser
|
|||
}
|
||||
|
||||
import std.container.slist : SList;
|
||||
private SList!(Token) commentStack;
|
||||
import tlang.compiler.symbols.comments;
|
||||
private SList!(Comment) commentStack;
|
||||
private void pushComment(Token commentToken)
|
||||
{
|
||||
// Sanity check
|
||||
|
@ -2190,7 +2208,7 @@ public final class Parser
|
|||
);
|
||||
|
||||
// Push it onto top of stack
|
||||
commentStack.insertFront(commentToken);
|
||||
commentStack.insertFront(Comment.fromToken(commentToken));
|
||||
}
|
||||
//TODO: Add a popToken() (also think if we want a stack-based mechanism)
|
||||
private bool hasCommentsOnStack()
|
||||
|
@ -2204,6 +2222,13 @@ public final class Parser
|
|||
return walkLength(commentStack[]);
|
||||
}
|
||||
|
||||
private Comment popComment()
|
||||
{
|
||||
Comment popped = commentStack.front();
|
||||
commentStack.removeFront();
|
||||
return popped;
|
||||
}
|
||||
|
||||
private void parseComment()
|
||||
{
|
||||
WARN("parseComment(): Enter");
|
||||
|
@ -2396,6 +2421,14 @@ public final class Parser
|
|||
expect("parseStatement(): Unknown symbol: " ~ lexer.getCurrentToken().getToken());
|
||||
}
|
||||
|
||||
// // TODO: Check if we should pop anything off of the comment
|
||||
// // stack here
|
||||
// if(hasCommentsOnStack())
|
||||
// {
|
||||
// statement.setComment(popComment());
|
||||
// }
|
||||
|
||||
|
||||
WARN("parseStatement(): Leave");
|
||||
|
||||
return statement;
|
||||
|
|
|
@ -5,6 +5,78 @@ module tlang.compiler.symbols.comments;
|
|||
import std.string : startsWith, split, strip, stripLeft;
|
||||
import std.array : join;
|
||||
|
||||
import tlang.misc.logging;
|
||||
import std.string : format;
|
||||
|
||||
public enum DocType
|
||||
{
|
||||
PARAM,
|
||||
THROWS,
|
||||
RETURNS
|
||||
}
|
||||
|
||||
public struct ParamDoc
|
||||
{
|
||||
string param;
|
||||
string description;
|
||||
}
|
||||
|
||||
public struct ReturnsDoc
|
||||
{
|
||||
string description;
|
||||
|
||||
public string getDescription()
|
||||
{
|
||||
return this.description;
|
||||
}
|
||||
}
|
||||
|
||||
public struct ExceptionDoc
|
||||
{
|
||||
string description;
|
||||
}
|
||||
|
||||
|
||||
private union DocContent
|
||||
{
|
||||
ParamDoc param;
|
||||
ReturnsDoc returns;
|
||||
ExceptionDoc exception;
|
||||
}
|
||||
|
||||
public struct DocStr
|
||||
{
|
||||
private DocType type;
|
||||
private DocContent content;
|
||||
|
||||
public enum DocType getType()
|
||||
{
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public static DocStr param(string name, string description)
|
||||
{
|
||||
DocStr dstr;
|
||||
dstr.type = DocType.PARAM;
|
||||
dstr.content.param = ParamDoc(name, description);
|
||||
return dstr;
|
||||
}
|
||||
|
||||
public ExceptionDoc getExceptionDoc()
|
||||
{
|
||||
assert(this.type == DocType.THROWS);
|
||||
return content.exception;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private struct CommentParts
|
||||
{
|
||||
string bdy;
|
||||
DocStr[] strs;
|
||||
}
|
||||
|
||||
private class CommentParser
|
||||
{
|
||||
private string source;
|
||||
|
@ -15,8 +87,10 @@ private class CommentParser
|
|||
|
||||
private string commentPart;
|
||||
|
||||
private string extract()
|
||||
private CommentParts extract()
|
||||
{
|
||||
CommentParts parts;
|
||||
|
||||
string buildUp;
|
||||
|
||||
if(this.source.startsWith("/**"))
|
||||
|
@ -65,9 +139,231 @@ private class CommentParser
|
|||
|
||||
// Now put it all together in a new-line seperate string
|
||||
buildUp = join(lines, "\n");
|
||||
|
||||
// Set the body parts
|
||||
parts.bdy = join(stripOutDocLines(lines));
|
||||
|
||||
// TODO: DO @param stuff here
|
||||
|
||||
DocStr[] docStrs;
|
||||
foreach(string line; onlyParams(lines))
|
||||
{
|
||||
DocStr ds;
|
||||
|
||||
if(extractDocLine(line, ds))
|
||||
{
|
||||
docStrs ~= ds;
|
||||
DEBUG(format("Converted docline '%s' to: %s", line, ds));
|
||||
}
|
||||
}
|
||||
|
||||
parts.strs = docStrs;
|
||||
|
||||
}
|
||||
|
||||
return buildUp;
|
||||
return parts;
|
||||
}
|
||||
|
||||
private bool extractDocLine(string line, ref DocStr ds)
|
||||
{
|
||||
string buildUp;
|
||||
bool foundType = false;
|
||||
|
||||
ulong i = 0;
|
||||
bool getch(ref char c)
|
||||
{
|
||||
if(i < line.length)
|
||||
{
|
||||
c = line[i];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void prog()
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
char c;
|
||||
|
||||
|
||||
bool parseParam(ref string paramName, ref string paramDescription)
|
||||
{
|
||||
bool gotParamName = false;
|
||||
string foundParamName;
|
||||
bool gotParamDescription = false;
|
||||
string foundParamDescription;
|
||||
|
||||
while(getch(c))
|
||||
{
|
||||
if(c == ' ')
|
||||
{
|
||||
prog;
|
||||
continue;
|
||||
}
|
||||
else if(!gotParamName)
|
||||
{
|
||||
while(getch(c) && c != ' ')
|
||||
{
|
||||
foundParamName ~= c;
|
||||
prog;
|
||||
}
|
||||
|
||||
// TODO: Validate name?
|
||||
gotParamName = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(getch(c))
|
||||
{
|
||||
foundParamDescription ~= c;
|
||||
prog;
|
||||
}
|
||||
|
||||
gotParamDescription = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(gotParamName && gotParamDescription)
|
||||
{
|
||||
paramName = foundParamName;
|
||||
paramDescription = foundParamDescription;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool parseReturn(ref string returnDescription)
|
||||
{
|
||||
string gotDescription;
|
||||
bool foundDescription;
|
||||
while(getch(c))
|
||||
{
|
||||
if(c == ' ' && !foundDescription)
|
||||
{
|
||||
prog;
|
||||
continue;
|
||||
}
|
||||
|
||||
gotDescription ~= c;
|
||||
prog;
|
||||
foundDescription = true;
|
||||
}
|
||||
|
||||
if(foundDescription)
|
||||
{
|
||||
returnDescription = gotDescription;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while(getch(c))
|
||||
{
|
||||
if(c == ' ')
|
||||
{
|
||||
prog();
|
||||
continue;
|
||||
}
|
||||
else if(c == '@' && !foundType)
|
||||
{
|
||||
string paramType;
|
||||
prog();
|
||||
while(getch(c) && c != ' ')
|
||||
{
|
||||
paramType ~= c;
|
||||
prog();
|
||||
}
|
||||
|
||||
// @param
|
||||
if(paramType == "param")
|
||||
{
|
||||
string paramName, paramDescr;
|
||||
if(parseParam(paramName, paramDescr))
|
||||
{
|
||||
DocStr tmp;
|
||||
tmp.type = DocType.PARAM;
|
||||
tmp.content.param = ParamDoc(paramName, paramDescr);
|
||||
ds = tmp;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// @return
|
||||
else if (paramType == "return")
|
||||
{
|
||||
string returnDescr;
|
||||
if(parseReturn(returnDescr))
|
||||
{
|
||||
DEBUG("hool");
|
||||
DocStr tmp;
|
||||
tmp.type = DocType.RETURNS;
|
||||
tmp.content.returns = ReturnsDoc(returnDescr);
|
||||
ds = tmp;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Unknown @<thing>
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Use niknaks filter
|
||||
private string[] onlyParams(string[] input)
|
||||
{
|
||||
string[] withDoc;
|
||||
|
||||
foreach(string i; input)
|
||||
{
|
||||
if(stripLeft(i).startsWith("@"))
|
||||
{
|
||||
withDoc ~= i;
|
||||
}
|
||||
}
|
||||
|
||||
return withDoc;
|
||||
}
|
||||
|
||||
// TODO: Use niknaks filter
|
||||
private string[] stripOutDocLines(string[] input)
|
||||
{
|
||||
string[] withoutDoc;
|
||||
|
||||
foreach(string i; input)
|
||||
{
|
||||
if(!stripLeft(i).startsWith("@"))
|
||||
{
|
||||
withoutDoc ~= i;
|
||||
}
|
||||
}
|
||||
|
||||
return withoutDoc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,14 +382,16 @@ unittest
|
|||
* there
|
||||
*/`;
|
||||
CommentParser parser = new CommentParser(source);
|
||||
string comment = parser.extract();
|
||||
CommentParts comment = parser.extract();
|
||||
|
||||
writeln(format("Comment: '%s'", comment));
|
||||
|
||||
// *cast(int*)0 = 1;
|
||||
assert(" Hello\n there" == comment);
|
||||
assert(" Hello\n there" == comment.bdy);
|
||||
}
|
||||
|
||||
import tlang.compiler.lexer.core.tokens : Token;
|
||||
|
||||
/**
|
||||
* Represents a comment
|
||||
* which can be attached
|
||||
|
@ -101,16 +399,65 @@ unittest
|
|||
*/
|
||||
public final class Comment
|
||||
{
|
||||
private string content;
|
||||
private CommentParts content;
|
||||
|
||||
this(string content)
|
||||
private this(CommentParts content)
|
||||
{
|
||||
// TODO: Parse the comment into text but annotated section
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public static Comment fromToken(Token commentToken)
|
||||
{
|
||||
return fromText(commentToken.getToken());
|
||||
}
|
||||
|
||||
private static Comment fromText(string text)
|
||||
{
|
||||
// TODO: Inline this behavior here
|
||||
CommentParser parser = new CommentParser(text);
|
||||
|
||||
return new Comment(parser.extract());
|
||||
}
|
||||
|
||||
public string getContent()
|
||||
{
|
||||
return this.content;
|
||||
return this.content.bdy;
|
||||
}
|
||||
|
||||
public DocStr[] getDocStrings()
|
||||
{
|
||||
return this.content.strs;
|
||||
}
|
||||
|
||||
public ParamDoc[string] getAllParamDocs()
|
||||
{
|
||||
// TODO: Use niknaks
|
||||
ParamDoc[string] d;
|
||||
foreach(DocStr i; getDocStrings())
|
||||
{
|
||||
if(i.type == DocType.PARAM)
|
||||
{
|
||||
ParamDoc pDoc = i.content.param;
|
||||
d[pDoc.param] = pDoc;
|
||||
}
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public bool getReturnDoc(ref ReturnsDoc retDoc)
|
||||
{
|
||||
// TODO: Use niknaks flter
|
||||
foreach(DocStr d; getDocStrings())
|
||||
{
|
||||
if(d.type == DocType.RETURNS)
|
||||
{
|
||||
retDoc = d.content.returns;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,13 +1,24 @@
|
|||
module simple_comments;
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
int p;
|
||||
|
||||
/**
|
||||
* Other comment
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns 0
|
||||
* Takes two inputs, does nothing with
|
||||
them and then returns 0 nonetheless
|
||||
*
|
||||
* @param x This is the first input
|
||||
*@param y This is the second input
|
||||
* @param niks this r e a l l y doesn't do anything
|
||||
* @return Just the value 0
|
||||
*/
|
||||
int zero()
|
||||
int zero(int x, int y)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,6 +30,6 @@ int zero()
|
|||
int main()
|
||||
{
|
||||
int k = zero();
|
||||
*(cast(int*)0) = zero();
|
||||
*(cast(int*)0) = zero(0);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue