diff --git a/lexer.c b/lexer.c index 458764b..cdf809d 100644 --- a/lexer.c +++ b/lexer.c @@ -128,8 +128,6 @@ NextToken(Lexer* l) { tok = newToken(l, TT_ILLEGAL); } - //printf("Invalid token: %X\n", l->ch); - //return NULL; } readChar(l); @@ -146,8 +144,11 @@ newWhitespaceToken(Lexer* l) tok->type = TT_WHITESPACE; int position = l->position; - // grab the char so we can use this funciton for both - // spaces and tabs. + + /* + * Grab the char so we can use this funciton for both + * spaces and tabs. + */ char ch = l->ch; while (peekChar(l) == ch){ readChar(l); @@ -277,7 +278,7 @@ newToken(Lexer* l, { Token* tok = malloc(sizeof(Token)); char* nc = malloc(sizeof(char)+1); - *nc = l->ch; + nc[0] = l->ch; nc[1] = '\0'; tok->type = tt; tok->literal = nc; diff --git a/lexer.h b/lexer.h index a0f9f79..3d0705b 100644 --- a/lexer.h +++ b/lexer.h @@ -4,21 +4,6 @@ #ifndef LEXER_H #define LEXER_H -//typedef enum NodeType { -// NT_Root, -// NT_Header1, -// NT_Header2, -// NT_Header3, -// NT_ListItem, -// NT_OrderedListItem, -// NT_Paragraph, -// NT_PlainText, -// NT_BoldText, -// NT_UnderlineText, -// NT_InlineCode, -// NT_BlockCode, -//} NodeType; - typedef struct Lexer { char* rawFile; int rawLen; @@ -32,19 +17,10 @@ typedef struct Lexer { } Lexer; -//typedef struct Node { -// NodeType type; -// char RawText; -// int LineNumber; -// -// //struct Node **ChildNodes; -// void** ChildNodes; -// int ChildCount; -//} Node; - Lexer* NewLexer(const char* filename); Token* NextToken(Lexer* l); void ReadChar(Lexer* l); void Parse(Lexer* l); +void FreeLexer(Lexer* l); #endif diff --git a/main.c b/main.c index fc71174..a2c937c 100644 --- a/main.c +++ b/main.c @@ -52,15 +52,17 @@ main(int argc, const char** argv) } while(tt != TT_EOF); + FreeLexer(l); + writeTokenFile(firstToken); - Node* node = ParseNodes(firstToken); + Node* firstNode = ParseNodes(firstToken); + Node* node = firstNode; printf("nodes:\n"); while(node != NULL) { - /*PrintNodeType(node->type);*/ - - switch (node->type) { + switch (node->type) + { case NT_Header1: case NT_Header2: case NT_Header3: @@ -115,14 +117,20 @@ main(int argc, const char** argv) node = node->next; } - //printf("rawLen: %d position: %d readPosition: %d ch: %c line: %d column: %d\n", - // l->rawLen, - // l->position, - // l->readPosition, - // l->ch, - // l->line, - // l->column - //); + node = firstNode; + firstNode = NULL; + + while ((node = FreeNode(node)) != NULL); + + if (node != NULL) + printf("last node != NULL\n"); + + if (firstNode != NULL) + { + printf("firstNode != NULL\n"); + printf("%s\n", NodeTypeString(firstNode->type)); + } + return 0; } diff --git a/node.c b/node.c index d627c36..e3bf36d 100644 --- a/node.c +++ b/node.c @@ -1,5 +1,6 @@ #include #include +#include #include "node.h" @@ -19,10 +20,12 @@ ParseNodes(Token* firstToken) Token* currentToken = firstToken; Node* prevNode = NULL; - while (1) { + while (currentToken != NULL) + { Node* currentNode = NULL; - switch (currentToken->type) { + switch (currentToken->type) + { case TT_NEWLINE: case TT_WHITESPACE: break; @@ -44,21 +47,17 @@ ParseNodes(Token* firstToken) break; } - if (currentToken->next == NULL) { - break; - } + if (currentToken->type == TT_NEWLINE || currentToken->type == TT_WHITESPACE) + currentToken = FreeToken(currentToken); - currentToken = currentToken->next; if (currentNode == NULL) continue; - if (prevNode != NULL) { + if (prevNode != NULL) prevNode->next = currentNode; - } - if (firstNode == NULL) { + if (firstNode == NULL) firstNode = currentNode; - } prevNode = currentNode; } @@ -70,12 +69,13 @@ Node* parseHeader(Token** startToken) { Token* t = *startToken; + // Count the number of TT_HASH tokens int count = 1; while (t->next != NULL && t->next->type == TT_HASH) { count++; - t = t->next; + t = FreeToken(t); } if (t->next == NULL) @@ -83,12 +83,11 @@ parseHeader(Token** startToken) printf("Header missing text"); return NULL; } - t = t->next; // Trim leading whitespace while (t->next != NULL && t->type == TT_WHITESPACE) { - t = t->next; + t = FreeToken(t); } if (t->next == NULL) @@ -99,6 +98,7 @@ parseHeader(Token** startToken) Token* end = t; int len = 0; + // find header text size while (end->type != TT_NEWLINE && end->type != TT_EOF) { len += end->length; @@ -110,10 +110,9 @@ parseHeader(Token** startToken) while(t != end) { strncat(strbuff, t->literal, t->length); - t = t->next; + t = FreeToken(t); } - *startToken = t; HeaderNode* retval = malloc(sizeof(HeaderNode)); @@ -144,14 +143,19 @@ parseCodeBlock(Token** startToken) // find closing ticks int tlen = 0; // number of tokens int clen = 0; // number of characters - Token* t = *startToken; - t = t->next; // skip past the opening triple backtick + + // skip past the opening triple backtick + *startToken = FreeToken(*startToken); // skip the first newline - if (t->type == TT_NEWLINE) { - t = t->next; + while ((*startToken)->type == TT_NEWLINE) { + *startToken = FreeToken(*startToken); } + // assign this after we skip tokens so we don't have to + // re-skip them later. + Token* t = *startToken; + while (t->next != NULL && t->type != TT_TRIPLEBACKTICK) { if (t->next->type == TT_EOF) { printf("premature EOF"); @@ -174,20 +178,22 @@ parseCodeBlock(Token** startToken) char* strbuff = malloc(sizeof(char)*clen+1); strbuff[0] = '\0'; int i; - t = t->next; // skip past the opening triple backtick - - // skip the first newline - if (t->type == TT_NEWLINE) { - t = t->next; - } for(i = 0; i < tlen; i++) { strncat(strbuff, t->literal, t->length); - t = t->next; + t = FreeToken(t); } - // skip past closing triple backtick - *startToken = t->next; + /* + * Skip past closing triple backtick + * This is modifying the *parameter* that was passed in, + * so we can return the node and advance the token tree. + */ + *startToken = FreeToken(t); + + while ((*startToken)->type == TT_NEWLINE || (*startToken)->type == TT_WHITESPACE) { + *startToken = FreeToken(*startToken); + } CodeBlockNode* ret = malloc(sizeof(CodeBlockNode)); ret->type = NT_BlockCode; @@ -208,14 +214,11 @@ parseParagraph(Token** startToken) if (t->type == TT_GT) { pnode->ptype = PT_Quote; // consume TT_GT - Token* consumed = t; - t = t->next; - FreeToken(consumed); + t = FreeToken(t); } pnode->content = t; Token* prevToken = NULL; - Token* consumed = NULL; while(t != NULL) { @@ -226,10 +229,8 @@ parseParagraph(Token** startToken) if (t->next->type == TT_WHITESPACE) { // Consume the newline if the next one is a space. - consumed = t; - t = t->next; + t = FreeToken(t); prevToken->next = t; - FreeToken(consumed); } else { @@ -245,18 +246,14 @@ parseParagraph(Token** startToken) if (pnode->ptype == PT_Quote) { if (t->type == TT_GT) { // removes TT_GT - consumed = t; - t = t->next; + t = FreeToken(t); prevToken->next = t; - FreeToken(consumed); if (t->next != NULL && t->next->type == TT_WHITESPACE) { // removes TT_WHITESPACE - consumed = t; - t = t->next; + t = FreeToken(t); prevToken->next = t; - FreeToken(consumed); } continue; } @@ -276,7 +273,6 @@ parseParagraph(Token** startToken) } } // TT_NEWLINE check - //printf("t->literal: %s\n", t->literal); if (prevToken != NULL) prevToken->next = t; prevToken = t; @@ -296,22 +292,22 @@ paragraphEnd: { if(t->next == NULL) { + FreeToken(t); prevToken->next = NULL; break; } else if (t->next->type == TT_WHITESPACE) { - // concatinate the two. + /* concatinate the two. */ int len = t->length + t->next->length; char* newws = malloc(sizeof(char)*len+1); newws[0] = '\0'; strncat(newws, t->literal, t->length); strncat(newws, t->next->literal, t->next->length); - consumed = t; - t = t->next; + t = FreeToken(t); prevToken->next = t; - FreeToken(consumed); + t->length = len; free(t->literal); t->literal = newws; @@ -346,8 +342,6 @@ NodeTypeString(NodeType t) return "NT_InlineCode"; case NT_BlockCode: return "NT_BlockCode"; - case NT_BlockQuote: - return "NT_BlockQuote"; case NT_Bold: return "NT_Bold"; case NT_Underline: @@ -375,3 +369,40 @@ ParagraphTypeString(ParagraphType t) } return "UNKNOWN"; } + +Node* +FreeNode(Node* node) +{ + Node* next = node->next; + switch (node->type) + { + case NT_Header1: + case NT_Header2: + case NT_Header3: + case NT_Header4: + free(((HeaderNode*)node)->rawText); + break; + case NT_BlockCode: + free(((CodeBlockNode*)node)->rawText); + break; + case NT_Error: + free(((ErrorNode*)node)->error); + break; + case NT_Paragraph: + { + ParagraphNode* pnode = (ParagraphNode*)node; + Token* t = pnode->content; + while ((t = FreeToken(t)) != NULL); + } + break; + case NT_UnorderedList: + case NT_OrderedList: + case NT_InlineCode: + case NT_Bold: + case NT_Underline: + assert(0 && "//TODO"); + break; + } + free(node); + return next; +} diff --git a/node.h b/node.h index ec62cab..f79ba5a 100644 --- a/node.h +++ b/node.h @@ -19,7 +19,6 @@ typedef enum { NT_Paragraph, NT_UnorderedList, NT_OrderedList, - NT_BlockQuote, // Contained elements (cannot be bare) // text modifiers @@ -71,5 +70,6 @@ typedef struct { Node* ParseNodes(Token* firstToken); char* NodeTypeString(NodeType t); char* ParagraphTypeString(ParagraphType t); +Node* FreeNode(Node* node); #endif diff --git a/sample.md b/sample.md index 032e62b..92d8211 100644 --- a/sample.md +++ b/sample.md @@ -12,7 +12,6 @@ pellentesque. *Sit fusce.* At ligula dolor parturient sodales auctor. Egestas. this has some `inline code` in it. - > Block Quote thing. > Dictum pharetra nulla _aliquet tincidunt_ parturient netus gravida rutrum > diff --git a/token.c b/token.c index 014c3bf..c569954 100644 --- a/token.c +++ b/token.c @@ -13,23 +13,26 @@ char* printableOnly(char* input); char* TokenString(Token* t) { - //char* str = malloc(sizeof(char) * 1000); - snprintf(stringBuff, 1000, "[%d:%d] Type: %s Literal: '%s'", + char* printable = printableOnly(t->literal); + snprintf(stringBuff, STRING_BUFF_SIZE, "[%d:%d] Type: %s Literal: '%s'", t->line, t->column, TokenTypeString(t->type), - printableOnly(t->literal) + printable ); + free(printable); return stringBuff; } -void +Token* FreeToken(Token* t) { + Token* next = t->next; if (t->type != TT_TRIPLEBACKTICK) free(t->literal); free(t); + return next; } char* diff --git a/token.h b/token.h index cee0e44..a98d70e 100644 --- a/token.h +++ b/token.h @@ -30,6 +30,6 @@ typedef struct Token { char* TokenString(Token* t); char* TokenTypeString(TokenType tt); -void FreeToken(Token* t); +Token* FreeToken(Token* t); #endif