Compare commits

...

13 Commits

Author SHA1 Message Date
Tristan B. V. Kildaire 4b62f759c7 Parser
- Cleaned up
1 month ago
Tristan B. V. Kildaire fd46446c5a Parser
- Removed old comment code
1 month ago
Tristan B. V. Kildaire b0441db3de Parser
- Disabled old-unused comment methods
1 month ago
Tristan B. V. Kildaire fd95edb4e9 Test cases
- Updated `simple_comments.t`
1 month ago
Tristan B. V. Kildaire e205dc2930 Parser
- Added debug print
1 month ago
Tristan B. V. Kildaire 84526582f0 Comments
- Added single-line comment support
1 month ago
Tristan B. V. Kildaire b3ea687d8c Test cases
- Updated `simple_comments.t`
1 month ago
Tristan B. V. Kildaire efd3f420b5 Parser
- Now uses new comment method
1 month ago
Tristan B. V. Kildaire e09f6ad59d Parser
- Switched all calls directly to `lexer.nextToken()` to `nextToken()`
1 month ago
Tristan B. V. Kildaire 57cb727103 Parser
- Added `getAssociatedComment(ref Comment comment)`
- Added `getCurrentToken()`
- Added `nextToken()` with `prevToken` support
1 month ago
Tristan B. V. Kildaire fa8204067b Comments (unittests)
- Fixed unittest to conform to new thing
1 month ago
Tristan B. V. Kildaire ea09f1fb56 Test cases
- Updated `simple_comments.t`
1 month ago
Tristan B. V. Kildaire 10cde13079 Comments
- Fixed formatting of the extracted non-param doc lines
1 month ago

@ -12,6 +12,7 @@ import tlang.compiler.parsing.exceptions;
import tlang.compiler.core : Compiler;
import std.string : format;
import tlang.compiler.modman;
import tlang.compiler.symbols.comments;
// TODO: Technically we could make a core parser etc
public final class Parser
@ -21,6 +22,14 @@ public final class Parser
*/
private LexerInterface lexer;
/**
* Stores the previous token
*
* This is updated everytime
* `nextToken()` is called
*/
private Token prevToken;
/**
* The associated compiler
*/
@ -130,6 +139,65 @@ public final class Parser
return findOfType(statementType, from).length != 0;
}
/**
* Returns the current token
*
* This is a simple proxy method
*
* Returns: the `Token`
*/
private Token getCurrentToken()
{
return this.lexer.getCurrentToken();
}
/**
* Moves the token pointer back
*
* This is a simple proxy method
*/
private void previousToken()
{
this.lexer.previousToken();
}
/**
* Moves the token pointer forwards
*
* This is a proxy method BUT prior
* to doing the proxy call it first
* saves the current token into `prevToken`
*/
private void nextToken()
{
// Save current token as previous token
this.prevToken = this.getCurrentToken();
// Move onto next token
this.lexer.nextToken();
}
private bool getAssociatedComment(ref Comment comment)
{
// TODO: null check? on this.prevToken
// If the previous token was a comment
if
(
getSymbolType(this.prevToken) == SymbolType.SINGLE_LINE_COMMENT ||
getSymbolType(this.prevToken) == SymbolType.MULTI_LINE_COMMENT
)
{
DEBUG(format("Parsing a comment from token: '%s'", this.prevToken));
comment = Comment.fromToken(this.prevToken);
return true;
}
return false;
}
/**
* Parses if statements
*
@ -152,24 +220,24 @@ public final class Parser
if (getSymbolType(lexer.getCurrentToken()) == SymbolType.IF)
{
/* Pop off the `if` */
lexer.nextToken();
nextToken();
/* Expect an opening brace `(` */
expect(SymbolType.LBRACE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Parse an expression (for the condition) */
currentBranchCondition = parseExpression();
expect(SymbolType.RBRACE, lexer.getCurrentToken());
/* Opening { */
lexer.nextToken();
nextToken();
expect(SymbolType.OCURLY, lexer.getCurrentToken());
/* Parse the if' statement's body AND expect a closing curly */
currentBranchBody = parseBody();
expect(SymbolType.CCURLY, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Create a branch node */
Branch branch = new Branch(currentBranchCondition, currentBranchBody);
@ -180,30 +248,30 @@ public final class Parser
else if (getSymbolType(lexer.getCurrentToken()) == SymbolType.ELSE)
{
/* Pop off the `else` */
lexer.nextToken();
nextToken();
/* Check if we have an `if` after the `{` (so an "else if" statement) */
if (getSymbolType(lexer.getCurrentToken()) == SymbolType.IF)
{
/* Pop off the `if` */
lexer.nextToken();
nextToken();
/* Expect an opening brace `(` */
expect(SymbolType.LBRACE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Parse an expression (for the condition) */
currentBranchCondition = parseExpression();
expect(SymbolType.RBRACE, lexer.getCurrentToken());
/* Opening { */
lexer.nextToken();
nextToken();
expect(SymbolType.OCURLY, lexer.getCurrentToken());
/* Parse the if' statement's body AND expect a closing curly */
currentBranchBody = parseBody();
expect(SymbolType.CCURLY, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Create a branch node */
Branch branch = new Branch(currentBranchCondition, currentBranchBody);
@ -216,7 +284,7 @@ public final class Parser
/* Parse the if' statement's body (starting with `{` AND expect a closing curly */
currentBranchBody = parseBody();
expect(SymbolType.CCURLY, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Create a branch node */
Branch branch = new Branch(null, currentBranchBody);
@ -258,24 +326,24 @@ public final class Parser
Statement[] branchBody;
/* Pop off the `while` */
lexer.nextToken();
nextToken();
/* Expect an opening brace `(` */
expect(SymbolType.LBRACE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Parse an expression (for the condition) */
branchCondition = parseExpression();
expect(SymbolType.RBRACE, lexer.getCurrentToken());
/* Opening { */
lexer.nextToken();
nextToken();
expect(SymbolType.OCURLY, lexer.getCurrentToken());
/* Parse the while' statement's body AND expect a closing curly */
branchBody = parseBody();
expect(SymbolType.CCURLY, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Create a Branch node coupling the condition and body statements */
@ -303,7 +371,7 @@ public final class Parser
Statement[] branchBody;
/* Pop off the `do` */
lexer.nextToken();
nextToken();
/* Expect an opening curly `{` */
expect(SymbolType.OCURLY, lexer.getCurrentToken());
@ -311,24 +379,24 @@ public final class Parser
/* Parse the do-while statement's body AND expect a closing curly */
branchBody = parseBody();
expect(SymbolType.CCURLY, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Expect a `while` */
expect(SymbolType.WHILE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Expect an opening brace `(` */
expect(SymbolType.LBRACE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Parse the condition */
branchCondition = parseExpression();
expect(SymbolType.RBRACE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Expect a semicolon */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Create a Branch node coupling the condition and body statements */
Branch branch = new Branch(branchCondition, branchBody);
@ -358,11 +426,11 @@ public final class Parser
Statement[] branchBody;
/* Pop of the token `for` */
lexer.nextToken();
nextToken();
/* Expect an opening smooth brace `(` */
expect(SymbolType.LBRACE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Expect a single Statement */
// TODO: Make optional, add parser lookahead check
@ -374,7 +442,7 @@ public final class Parser
/* Expect a semi-colon, then move on */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Expect a post-iteration statement with `)` as terminator */
// TODO: Make optional, add parser lookahead check
@ -386,7 +454,7 @@ public final class Parser
/* Expect a closing curly and move on */
expect(SymbolType.CCURLY, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
DEBUG("Yo: "~lexer.getCurrentToken().toString());
@ -419,8 +487,8 @@ public final class Parser
/* The identifier being assigned to */
string identifier = lexer.getCurrentToken().getToken();
lexer.nextToken();
lexer.nextToken();
nextToken();
nextToken();
DEBUG(lexer.getCurrentToken());
/* Expression */
@ -435,7 +503,7 @@ public final class Parser
expect(terminatingSymbol, lexer.getCurrentToken());
/* Move off terminating symbol */
lexer.nextToken();
nextToken();
return assignment;
@ -449,9 +517,9 @@ public final class Parser
// TODO: Check if we should pop anything off of the comment
// stack here
Comment potComment;
if(hasCommentsOnStack())
if(getAssociatedComment(potComment))
{
potComment = popComment();
DEBUG(format("Found associated comment: %s", potComment));
}
scope(exit)
@ -469,7 +537,7 @@ public final class Parser
/* TODO: The problem here is I don't want to progress the token */
/* Get next token */
lexer.nextToken();
nextToken();
SymbolType type = getSymbolType(lexer.getCurrentToken());
/* If we have `(` then function call */
@ -484,7 +552,7 @@ public final class Parser
/* Expect a semi-colon */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
}
/**
* Either we have:
@ -509,14 +577,14 @@ public final class Parser
{
/* Expect a semicolon and consume it */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
}
/* If it is an arrau assignment */
else if(cast(ArrayAssignment)ret)
{
/* Expect a semicolon and consume it */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
}
/* This should never happen */
else
@ -552,7 +620,7 @@ public final class Parser
Statement[] statements;
/* Consume the `struct` that caused `parseStruct` to be called */
lexer.nextToken();
nextToken();
/* Expect an identifier here (no dot) */
string structName = lexer.getCurrentToken().getToken();
@ -563,11 +631,11 @@ public final class Parser
}
/* Consume the name */
lexer.nextToken();
nextToken();
/* TODO: Here we will do a while loop */
expect(SymbolType.OCURLY, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
while(true)
{
@ -596,7 +664,7 @@ public final class Parser
/* Should have a semi-colon and consume it */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
}
/* If it is an accessor */
else if (isAccessor(lexer.getCurrentToken()))
@ -664,7 +732,7 @@ public final class Parser
expect(SymbolType.CCURLY, lexer.getCurrentToken());
/* Consume the closing curly brace */
lexer.nextToken();
nextToken();
WARN("parseStruct(): Leave");
@ -677,7 +745,7 @@ public final class Parser
ReturnStmt returnStatement;
/* Move from `return` onto start of expression */
lexer.nextToken();
nextToken();
// TODO: Check if semicolon here (no expression) else expect expression
@ -702,7 +770,7 @@ public final class Parser
}
/* Move off of the terminator */
lexer.nextToken();
nextToken();
return returnStatement;
}
@ -715,7 +783,7 @@ public final class Parser
Statement[] statements;
/* Consume the `{` symbol */
lexer.nextToken();
nextToken();
/**
* If we were able to get a closing token, `}`, then
@ -815,7 +883,7 @@ public final class Parser
/* Save and consume the init-scope */
InitScope initScope = getInitScope(lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Get the current token's symbol type */
SymbolType symbolType = getSymbolType(lexer.getCurrentToken());
@ -881,7 +949,7 @@ public final class Parser
/* Save and consume the accessor */
AccessorType accessorType = getAccessorType(lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* TODO: Only allow, private, public, protected */
/* TODO: Pass this to call for class prsewr or whatever comes after the accessor */
@ -951,7 +1019,7 @@ public final class Parser
/* Consume the `(` token */
lexer.nextToken();
nextToken();
/* Count for number of parameters processed */
ulong parameterCount;
@ -976,7 +1044,7 @@ public final class Parser
expect("Identifier can not be path");
}
string identifier = lexer.getCurrentToken().getToken();
lexer.nextToken();
nextToken();
/* Add the local variable (parameter variable) */
@ -990,7 +1058,7 @@ public final class Parser
else if(getSymbolType(lexer.getCurrentToken()) == SymbolType.COMMA)
{
/* Consume the `,` */
lexer.nextToken();
nextToken();
moreArgs = true;
}
@ -1001,7 +1069,7 @@ public final class Parser
if(!moreArgs)
{
/* Consume the `)` */
lexer.nextToken();
nextToken();
break;
}
/* Error out if we were and we prematurely ended */
@ -1041,7 +1109,7 @@ public final class Parser
}
}
lexer.nextToken();
nextToken();
}
/* If no body is requested */
else
@ -1071,14 +1139,14 @@ public final class Parser
private DiscardStatement parseDiscard()
{
/* Consume the `discard` */
lexer.nextToken();
nextToken();
/* Parse the following expression */
Expression expression = parseExpression();
/* Expect a semi-colon */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Create a `discard` statement */
DiscardStatement discardStatement = new DiscardStatement(expression);
@ -1096,11 +1164,11 @@ public final class Parser
CastedExpression castedExpression;
/* Consume the `cast` */
lexer.nextToken();
nextToken();
/* Expect an `(` open brace */
expect(SymbolType.LBRACE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/**
* Expect a type
@ -1122,7 +1190,7 @@ public final class Parser
/* Expect a `)` closing brace */
expect(SymbolType.RBRACE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Get the expression to cast */
Expression uncastedExpression = parseExpression();
@ -1310,7 +1378,7 @@ public final class Parser
addRetExp(numberLiteral);
/* Get the next token */
lexer.nextToken();
nextToken();
}
/* If it is a cast operator */
else if(symbol == SymbolType.CAST)
@ -1326,7 +1394,7 @@ public final class Parser
/* TODO: Save operator, also pass to constructor */
/* TODO: Parse expression or pass arithemetic (I think latter) */
lexer.nextToken();
nextToken();
OperatorExpression opExp;
@ -1388,7 +1456,7 @@ public final class Parser
addRetExp(new StringExpression(lexer.getCurrentToken().getToken()));
/* Get the next token */
lexer.nextToken();
nextToken();
}
/* If we have a `[` (array index/access) */
else if(symbol == SymbolType.OBRACKET)
@ -1398,9 +1466,9 @@ public final class Parser
DEBUG("indexTo: "~indexTo.toString());
/* Get the index expression */
lexer.nextToken();
nextToken();
Expression index = parseExpression();
lexer.nextToken();
nextToken();
DEBUG("IndexExpr: "~index.toString());
// gprintln(lexer.getCurrentToken());
@ -1412,7 +1480,7 @@ public final class Parser
{
string identifier = lexer.getCurrentToken().getToken();
lexer.nextToken();
nextToken();
Expression toAdd;
@ -1452,13 +1520,13 @@ public final class Parser
else if (symbol == SymbolType.LBRACE)
{
/* Consume the `(` */
lexer.nextToken();
nextToken();
/* Parse the inner expression till terminator */
addRetExp(parseExpression());
/* Consume the terminator */
lexer.nextToken();
nextToken();
}
/**
* `new` operator
@ -1466,11 +1534,11 @@ public final class Parser
else if(symbol == SymbolType.NEW)
{
/* Cosume the `new` */
lexer.nextToken();
nextToken();
/* Get the identifier */
string identifier = lexer.getCurrentToken().getToken();
lexer.nextToken();
nextToken();
NewExpression toAdd;
@ -1503,7 +1571,7 @@ public final class Parser
Expression previousExpression = removeExp();
/* TODO: Get next expression */
lexer.nextToken();
nextToken();
Expression item = parseExpression();
/* TODO: Construct accessor expression from both and addRetExp */
@ -1545,7 +1613,7 @@ public final class Parser
/* TODO: Save type */
string type = lexer.getCurrentToken().getToken();
string identifier;
lexer.nextToken();
nextToken();
@ -1565,7 +1633,7 @@ public final class Parser
/* If we have `[` then expect a number and/or a `]` */
if(getSymbolType(lexer.getCurrentToken()) == SymbolType.OBRACKET)
{
lexer.nextToken();
nextToken();
SymbolType nextType = getSymbolType(lexer.getCurrentToken());
@ -1617,7 +1685,7 @@ public final class Parser
type=type~"*";
}
lexer.nextToken();
nextToken();
}
/* If were requested to only find a type, then stop here and return it */
@ -1650,7 +1718,7 @@ public final class Parser
}
identifier = lexer.getCurrentToken().getToken();
lexer.nextToken();
nextToken();
DEBUG("ParseTypedDec: DecisionBtwn FuncDef/VarDef: " ~ lexer.getCurrentToken().getToken());
}
/* Anything else is an error */
@ -1735,7 +1803,7 @@ public final class Parser
if(wantsBody)
{
/* Consume the `=` token */
lexer.nextToken();
nextToken();
/* Now parse an expression */
Expression expression = parseExpression();
@ -1790,7 +1858,7 @@ public final class Parser
/* Expect a `=` and consume it */
DEBUG(lexer.getCurrentToken());
expect(SymbolType.ASSIGN, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Parse the expression being assigned followed by a semi-colon `;` */
Expression expressionBeingAssigned = parseExpression();
@ -1826,7 +1894,7 @@ public final class Parser
Clazz generated;
/* Pop off the `class` */
lexer.nextToken();
nextToken();
/* Get the class's name (CAN NOT be dotted) */
expect(SymbolType.IDENT_TYPE, lexer.getCurrentToken());
@ -1836,7 +1904,7 @@ public final class Parser
}
string className = lexer.getCurrentToken().getToken();
DEBUG("parseClass(): Class name found '" ~ className ~ "'");
lexer.nextToken();
nextToken();
generated = new Clazz(className);
@ -1848,14 +1916,14 @@ public final class Parser
/* TODO: Loop until `}` */
/* Consume the inheritance operator `:` */
lexer.nextToken();
nextToken();
while(true)
{
/* Check if it is an identifier (may be dotted) */
expect(SymbolType.IDENT_TYPE, lexer.getCurrentToken());
inheritList ~= lexer.getCurrentToken().getToken();
lexer.nextToken();
nextToken();
/* Check if we have ended with a `{` */
if(getSymbolType(lexer.getCurrentToken()) == SymbolType.OCURLY)
@ -1867,7 +1935,7 @@ public final class Parser
else if(getSymbolType(lexer.getCurrentToken()) == SymbolType.COMMA)
{
/* Consume */
lexer.nextToken();
nextToken();
}
/* Error out if we get anything else */
else
@ -1886,7 +1954,7 @@ public final class Parser
/* TODO: Here we will do a while loop */
expect(SymbolType.OCURLY, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
Statement[] statements;
@ -1917,7 +1985,7 @@ public final class Parser
/* Should have a semi-colon and consume it */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
}
/* If it is a class */
else if(symbolType == SymbolType.CLASS)
@ -1987,7 +2055,7 @@ public final class Parser
parentToContainer(generated, statements);
/* Pop off the ending `}` */
lexer.nextToken();
nextToken();
WARN("parseClass(): Leave");
@ -2165,14 +2233,14 @@ public final class Parser
Statement statement;
/* Consume the star `*` */
lexer.nextToken();
nextToken();
ulong derefCnt = 1;
/* Check if there is another star */
while(getSymbolType(lexer.getCurrentToken()) == SymbolType.STAR)
{
derefCnt+=1;
lexer.nextToken();
nextToken();
}
/* Expect an expression */
@ -2180,14 +2248,14 @@ public final class Parser
/* Expect an assignment operator */
expect(SymbolType.ASSIGN, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Expect an expression */
Expression assigmentExpression = parseExpression();
/* Expect a semicolon */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
// FIXME: We should make a LHSPiinterAssignmentThing
statement = new PointerDereferenceAssignment(pointerExpression, assigmentExpression, derefCnt);
@ -2196,50 +2264,18 @@ public final class Parser
return statement;
}
import std.container.slist : SList;
import tlang.compiler.symbols.comments;
private SList!(Comment) commentStack;
private void pushComment(Token commentToken)
{
// Sanity check
assert(getSymbolType(commentToken) == SymbolType.SINGLE_LINE_COMMENT ||
getSymbolType(commentToken) == SymbolType.MULTI_LINE_COMMENT
);
// Push it onto top of stack
commentStack.insertFront(Comment.fromToken(commentToken));
}
//TODO: Add a popToken() (also think if we want a stack-based mechanism)
private bool hasCommentsOnStack()
{
return getCommentCount() != 0;
}
private ulong getCommentCount()
{
import std.range : walkLength;
return walkLength(commentStack[]);
}
private Comment popComment()
{
Comment popped = commentStack.front();
commentStack.removeFront();
return popped;
}
private void parseComment()
{
WARN("parseComment(): Enter");
Token curCommentToken = lexer.getCurrentToken();
pushComment(curCommentToken);
// pushComment(curCommentToken);
// TODO: Do something here like placing it on some kind of stack
DEBUG("Comment is: '"~curCommentToken.getToken()~"'");
lexer.nextToken(); // Move off comment
nextToken(); // Move off comment
WARN("parseComment(): Leave");
}
@ -2443,11 +2479,11 @@ public final class Parser
Expression[] arguments;
lexer.nextToken();
nextToken();
/* Expect an opening brace `(` */
expect(SymbolType.LBRACE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* If next token is RBRACE we don't expect arguments */
if(getSymbolType(lexer.getCurrentToken()) == SymbolType.RBRACE)
@ -2473,7 +2509,7 @@ public final class Parser
/* If comma expect more */
else if(getSymbolType(lexer.getCurrentToken()) == SymbolType.COMMA)
{
lexer.nextToken();
nextToken();
/* TODO: If rbrace after then error, so save boolean */
}
/* TODO: Add else, could have exited on `;` which is invalid closing */
@ -2485,7 +2521,7 @@ public final class Parser
}
lexer.nextToken();
nextToken();
WARN("parseFuncCall(): Leave");
@ -2497,11 +2533,11 @@ public final class Parser
ExternStmt externStmt;
/* Consume the `extern` token */
lexer.nextToken();
nextToken();
/* Expect the next token to be either `efunc` or `evariable` */
SymbolType externType = getSymbolType(lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Pseudo-entity */
Entity pseudoEntity;
@ -2536,7 +2572,7 @@ public final class Parser
/* Expect a semicolon to end it all and then consume it */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
externStmt = new ExternStmt(pseudoEntity, externType);
@ -2617,14 +2653,14 @@ public final class Parser
WARN("parseImport(): Enter");
/* Consume the `import` keyword */
lexer.nextToken();
nextToken();
/* Get the module's name */
expect(SymbolType.IDENT_TYPE, lexer.getCurrentToken());
string moduleName = lexer.getCurrentToken().getToken();
/* Consume the token */
lexer.nextToken();
nextToken();
/* All modules to be imported */
string[] collectedModuleNames = [moduleName];
@ -2633,7 +2669,7 @@ public final class Parser
while(getSymbolType(lexer.getCurrentToken()) == SymbolType.COMMA)
{
/* Consume the comma `,` */
lexer.nextToken();
nextToken();
/* Get the module's name */
expect(SymbolType.IDENT_TYPE, lexer.getCurrentToken());
@ -2641,12 +2677,12 @@ public final class Parser
collectedModuleNames ~= curModuleName;
/* Consume the name */
lexer.nextToken();
nextToken();
}
/* Expect a semi-colon and consume it */
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Perform the actual import */
doImport(collectedModuleNames);
@ -2669,15 +2705,15 @@ public final class Parser
/* Expect `module` and module name and consume them (and `;`) */
expect(SymbolType.MODULE, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Module name may NOT be dotted (TODO: Maybe it should be yeah) */
expect(SymbolType.IDENT_TYPE, lexer.getCurrentToken());
string moduleName = lexer.getCurrentToken().getToken();
lexer.nextToken();
nextToken();
expect(SymbolType.SEMICOLON, lexer.getCurrentToken());
lexer.nextToken();
nextToken();
/* Initialize Module */
modulle = new Module(moduleName);
@ -2731,7 +2767,7 @@ public final class Parser
prog.setEntryModule(curModEnt, modulle);
}
/* TODO: We should add `lexer.hasTokens()` to the `lexer.nextToken()` */
/* TODO: We should add `lexer.hasTokens()` to the `nextToken()` */
/* TODO: And too the `getCurrentTokem()` and throw an error when we have ran out rather */
/* We can have an import or vardef or funcdef */

@ -2,7 +2,7 @@ module tlang.compiler.symbols.comments;
// TODO: Add comment parsing
import std.string : startsWith, split, strip, stripLeft;
import std.string : startsWith, split, strip, stripLeft, stripRight;
import std.array : join;
import tlang.misc.logging;
@ -33,7 +33,13 @@ public struct ReturnsDoc
public struct ExceptionDoc
{
string exception;
string description;
public string getDescription()
{
return this.description;
}
}
@ -91,8 +97,7 @@ private class CommentParser
{
CommentParts parts;
string buildUp;
// Handle multi-line comments
if(this.source.startsWith("/**"))
{
string[] lines = split(this.source, "\n");
@ -137,14 +142,10 @@ private class CommentParser
lines = lines[0..$-1];
}
// 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
// Set doc strings
DocStr[] docStrs;
foreach(string line; onlyParams(lines))
{
@ -156,9 +157,13 @@ private class CommentParser
DEBUG(format("Converted docline '%s' to: %s", line, ds));
}
}
parts.strs = docStrs;
}
// Handle single-line comments
else
{
// Set body parts
parts.bdy = strip(stripLeft(this.source, ("//")));
}
return parts;
@ -249,7 +254,7 @@ private class CommentParser
prog;
continue;
}
gotDescription ~= c;
prog;
foundDescription = true;
@ -319,6 +324,23 @@ private class CommentParser
return false;
}
}
// @throws
else if(paramType == "throws")
{
string exceptionName, exceptionDescr;
if(parseParam(exceptionName, exceptionDescr)) // Has same structure as a `@param <1> <...>`
{
DocStr tmp;
tmp.type = DocType.THROWS;
tmp.content.exception = ExceptionDoc(exceptionName, exceptionDescr);
ds = tmp;
return true;
}
else
{
return false;
}
}
// Unknown @<thing>
else
{
@ -357,12 +379,21 @@ private class CommentParser
foreach(string i; input)
{
DEBUG(format("'%s'", i));
if(!stripLeft(i).startsWith("@"))
{
withoutDoc ~= i;
// Strip left-hand side of any spaces
// and add trailing space
withoutDoc ~= stripLeft(i)~' ';
}
}
// Remove trailing whitespace on last item
if(withoutDoc.length)
{
withoutDoc[$-1] = stripRight(withoutDoc[$-1]);
}
return withoutDoc;
}
}
@ -387,7 +418,7 @@ unittest
writeln(format("Comment: '%s'", comment));
// *cast(int*)0 = 1;
assert(" Hello\n there" == comment.bdy);
assert("Hello there" == comment.bdy);
}
import tlang.compiler.lexer.core.tokens : Token;

@ -1,8 +1,10 @@
module simple_comments;
// Lol
int i;
int p;
/**
@ -10,12 +12,13 @@ int p;
*/
/**
* Takes two inputs, does nothing with
* 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
* @throws ZeroException if the values passed in are not zero
* @return Just the value 0
*/
int zero(int x, int y)
@ -24,9 +27,7 @@ int zero(int x, int y)
}
/**
* Yo fr
*/
int main()
{
int k = zero();

Loading…
Cancel
Save