Skip to content

Commit

Permalink
Start work on SourceLocation for ASTNodes
Browse files Browse the repository at this point in the history
  • Loading branch information
wpmed92 committed Aug 7, 2024
1 parent 722fe13 commit e9f1245
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 47 deletions.
19 changes: 17 additions & 2 deletions include/AST/AST.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ namespace shaderpulse {

namespace ast {

struct SourceLocation {
SourceLocation() = default;
SourceLocation(int startLine, int startCol, int endLine, int endCol) : startLine(startLine), startCol(startCol),
endLine(endLine), endCol(endCol) { }
int startLine;
int startCol;
int endLine;
int endCol;
};

enum UnaryOperator { Inc, Dec, Plus, Dash, Bang, Tilde };

enum BinaryOperator {
Expand Down Expand Up @@ -51,8 +61,13 @@ enum AssignmentOperator {

class ASTNode {
public:
ASTNode(SourceLocation loc = SourceLocation()) : loc(loc) { }
virtual ~ASTNode() = default;
virtual void accept(ASTVisitor *visitor) = 0;
SourceLocation getSourceLocation() { return loc; }

protected:
SourceLocation loc;
};

class Expression : public ASTNode {
Expand Down Expand Up @@ -608,10 +623,10 @@ class AssignmentExpression : public Statement {
class FunctionDeclaration : public ExternalDeclaration {

public:
FunctionDeclaration(std::unique_ptr<Type> returnType, const std::string &name,
FunctionDeclaration(SourceLocation location, std::unique_ptr<Type> returnType, const std::string &name,
std::vector<std::unique_ptr<ParameterDeclaration>> params,
std::unique_ptr<Statement> body)
: returnType(std::move(returnType)), name(name),
: ASTNode(location), returnType(std::move(returnType)), name(name),
params(std::move(params)), body(std::move(body)) {}

void accept(ASTVisitor *visitor) override { visitor->visit(this); }
Expand Down
1 change: 1 addition & 0 deletions include/AST/PrinterASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class PrinterASTVisitor : public ASTVisitor {
void print(const std::string &text);
int indentationLevel = 0;
std::set<int> levels;
std::string loc(const SourceLocation &sourceLoc);
};

}; // namespace ast
Expand Down
14 changes: 4 additions & 10 deletions include/Lexer/Token.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
#pragma once
#include "AST/AST.h"
#include <memory>
#include <string>

namespace shaderpulse {

namespace lexer {

struct SourceLocation {
SourceLocation() = default;
SourceLocation(int line, int col) : line(line), col(col) { }
int line;
int col;
};

class NumericLiteral {
public:
virtual ~NumericLiteral() = 0;
Expand Down Expand Up @@ -83,14 +77,14 @@ class Token {
bool isDoubleConstant() const;
NumericLiteral *getLiteralData() const;
void setLiteralData(std::unique_ptr<NumericLiteral>);
void setSourceLocation(SourceLocation loc);
SourceLocation getSourceLocation() const;
void setSourceLocation(ast::SourceLocation loc);
ast::SourceLocation getSourceLocation() const;
void setRawData(const std::string&);
std::string getRawData() const;

private:
TokenKind tokenKind;
SourceLocation sourceLoc;
ast::SourceLocation sourceLoc;
std::string identifierName;
std::string rawData;
std::unique_ptr<NumericLiteral> literalData;
Expand Down
9 changes: 8 additions & 1 deletion lib/AST/PrinterASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "AST/Util.h"
#include "AST/PrinterASTVisitor.h"
#include <iostream>
#include <sstream>

namespace shaderpulse {

Expand Down Expand Up @@ -268,7 +269,7 @@ void PrinterASTVisitor::visit(DiscardStatement *discardStmt) {
}

void PrinterASTVisitor::visit(FunctionDeclaration *funcDecl) {
print("|-FunctionDeclaration: name=" + funcDecl->getName() + ", return type=" + funcDecl->getReturnType()->toString());
print("|-FunctionDeclaration: name=" + funcDecl->getName() + " " + loc(funcDecl->getSourceLocation()) + ", return type=" + funcDecl->getReturnType()->toString());
indent();

print("|-Args:");
Expand Down Expand Up @@ -296,5 +297,11 @@ void PrinterASTVisitor::visit(CaseLabel *caseLabel) {
resetIndent();
}

std::string PrinterASTVisitor::loc(const SourceLocation &sourceLoc) {
std::stringstream ssLoc;
ssLoc << "[line: " << sourceLoc.startLine << ", col:" << sourceLoc.startCol << "]->" << "[line: " << sourceLoc.endLine << ", col:" << sourceLoc.endCol << "]";
return ssLoc.str();
}

} // namespace ast
} // namespace shaderpulse
28 changes: 20 additions & 8 deletions lib/Lexer/Lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ Lexer::lexCharacterStream() {
}
}

auto tok = std::make_unique<Token>();
tok->setTokenKind(TokenKind::Eof);
tok->setSourceLocation(ast::SourceLocation(lineNum, col, lineNum, col));
tokenStream.push_back(std::move(tok));

return tokenStream;
}

Expand Down Expand Up @@ -109,7 +114,8 @@ bool Lexer::handleIdentifier(Error &error) {
tok->setTokenKind(TokenKind::Identifier);
}

tok->setSourceLocation(SourceLocation(lineNum, startCol));
int endCol = col;
tok->setSourceLocation(ast::SourceLocation(lineNum, startCol, lineNum, endCol));
tok->setRawData(token);
tokenStream.push_back(std::move(tok));

Expand Down Expand Up @@ -156,7 +162,8 @@ bool Lexer::handleHexLiteral(Error &error) {

tok->setTokenKind(isUnsigned ? TokenKind::UnsignedIntegerConstant
: TokenKind::IntegerConstant);
tok->setSourceLocation(SourceLocation(lineNum, startCol));
int endCol = col;
tok->setSourceLocation(ast::SourceLocation(lineNum, startCol, lineNum, endCol));
tok->setRawData(literalConstant);
tokenStream.push_back(std::move(tok));

Expand Down Expand Up @@ -206,7 +213,8 @@ bool Lexer::handleOctalLiteral(Error &error) {
tok->setTokenKind(isUnsigned ? TokenKind::UnsignedIntegerConstant
: TokenKind::IntegerConstant);

tok->setSourceLocation(SourceLocation(lineNum, startCol));
int endCol = col;
tok->setSourceLocation(ast::SourceLocation(lineNum, startCol, lineNum, endCol));
tok->setRawData(literalConstant);
tokenStream.push_back(std::move(tok));

Expand Down Expand Up @@ -268,7 +276,8 @@ bool Lexer::handleDecimalOrFloatLiteral(Error &error) {
std::make_unique<FloatLiteral>(std::stof(literalConstant)));
}

tok->setSourceLocation(SourceLocation(lineNum, startCol));
int endCol = col;
tok->setSourceLocation(ast::SourceLocation(lineNum, startCol, lineNum, endCol));
tok->setRawData(literalConstant);
tokenStream.push_back(std::move(tok));
return true;
Expand All @@ -287,7 +296,8 @@ bool Lexer::handleDecimalOrFloatLiteral(Error &error) {
tok->setTokenKind(TokenKind::IntegerConstant);
}

tok->setSourceLocation(SourceLocation(lineNum, startCol));
int endCol = col;
tok->setSourceLocation(ast::SourceLocation(lineNum, startCol, lineNum, endCol));
tok->setRawData(literalConstant);
tokenStream.push_back(std::move(tok));
return true;
Expand Down Expand Up @@ -343,7 +353,8 @@ bool Lexer::handleExponentialForm(std::string &literalConstant, Error &error) {
tok->setTokenKind(TokenKind::FloatConstant);
}

tok->setSourceLocation(SourceLocation(lineNum, startCol));
int endCol = col;
tok->setSourceLocation(ast::SourceLocation(lineNum, startCol, lineNum, endCol));
tok->setRawData(literalConstant);
tokenStream.push_back(std::move(tok));

Expand Down Expand Up @@ -586,8 +597,9 @@ bool Lexer::peekExponentialPart() {
void Lexer::addToken(TokenKind kind) {
auto tok = std::make_unique<Token>();
tok->setTokenKind(kind);
tok->setSourceLocation(SourceLocation(lineNum, col));
std::string rawData = characters.substr(savedCharPos, curCharPos - savedCharPos + 1);
int tokenLength = curCharPos - savedCharPos + 1;
tok->setSourceLocation(ast::SourceLocation(lineNum, col - tokenLength, lineNum, col));
std::string rawData = characters.substr(savedCharPos, tokenLength);
tok->setRawData(rawData);
tokenStream.push_back(std::move(tok));
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Lexer/Token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ void Token::setLiteralData(std::unique_ptr<NumericLiteral> literalData) {
this->literalData = std::move(literalData);
}

void Token::setSourceLocation(SourceLocation loc) {
void Token::setSourceLocation(ast::SourceLocation loc) {
sourceLoc = loc;
}

SourceLocation Token::getSourceLocation() const {
ast::SourceLocation Token::getSourceLocation() const {
return sourceLoc;
}

Expand Down
19 changes: 7 additions & 12 deletions lib/Parser/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ std::unique_ptr<FunctionDeclaration> Parser::parseFunctionDeclaration() {
return nullptr;
}

auto startLoc = curToken->getSourceLocation();
advanceToken();

auto returnType = std::move(type);
Expand All @@ -78,9 +79,9 @@ std::unique_ptr<FunctionDeclaration> Parser::parseFunctionDeclaration() {
advanceToken();

if (auto body = parseStatement()) {
return std::make_unique<FunctionDeclaration>(
std::move(returnType), functionName, std::move(params),
std::move(body));
auto endLoc = curToken->getSourceLocation();
auto spanLoc = SourceLocation(startLoc.startLine, startLoc.startCol, endLoc.endLine, endLoc.endCol);
return std::make_unique<FunctionDeclaration>(spanLoc, std::move(returnType), functionName, std::move(params), std::move(body));
} else {
return nullptr;
}
Expand Down Expand Up @@ -1466,10 +1467,7 @@ std::unique_ptr<Expression> Parser::parseConditionalExpression() {
}

void Parser::advanceToken() {
if ((cursor > -1) && ((size_t)cursor >= (tokenStream.size() - 1))) {
auto tok = std::make_unique<Token>();
tok->setTokenKind(TokenKind::Eof);
tokenStream.push_back(std::move(tok));
if ((cursor > -1) && (size_t)cursor >= (tokenStream.size())) {
curToken = tokenStream.back().get();
} else {
curToken = tokenStream[++cursor].get();
Expand All @@ -1478,17 +1476,14 @@ void Parser::advanceToken() {

const Token *Parser::peek(int k) {
if ((size_t)(cursor + k) >= tokenStream.size()) {
auto tok = std::make_unique<Token>();
tok->setTokenKind(TokenKind::Eof);
tokenStream.push_back(std::move(tok));
return tokenStream[tokenStream.size() - 1].get();
return tokenStream.back().get();
} else {
return tokenStream[cursor + k].get();
}
}

void Parser::reportError(ParserErrorKind kind, const std::string &msg) {
std::cout << msg << ", at line: " << curToken->getSourceLocation().line << ", col: " << curToken->getSourceLocation().col << std::endl;
std::cout << msg << ", at line: " << curToken->getSourceLocation().startLine << ", col: " << curToken->getSourceLocation().startCol << std::endl;
error = ParserError(kind, msg);
}

Expand Down
24 changes: 12 additions & 12 deletions test/Lexer/LexerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ TEST(LexerTest, IntegerLiterals) {

auto& tokens = (*resp).get();

EXPECT_EQ(tokens.size(), expectedValues.size());
EXPECT_EQ(tokens.size()-1, expectedValues.size());

for (size_t i = 0; i < tokens.size(); i++) {
for (size_t i = 0; i < tokens.size()-1; i++) {
if (i > 2) {
EXPECT_EQ(tokens[i].get()->getTokenKind(), TokenKind::UnsignedIntegerConstant);
EXPECT_EQ(dynamic_cast<UnsignedIntegerLiteral*>(tokens.at(i)->getLiteralData())->getVal(), expectedValues[i]);
Expand All @@ -81,9 +81,9 @@ TEST(LexerTest, FloatLiterals) {

auto& tokens = (*resp).get();

EXPECT_EQ(tokens.size(), expectedValues.size());
EXPECT_EQ(tokens.size()-1, expectedValues.size());

for (size_t i = 0; i < tokens.size(); i++) {
for (size_t i = 0; i < tokens.size()-1; i++) {
EXPECT_EQ(tokens[i].get()->getTokenKind(), TokenKind::FloatConstant);
EXPECT_EQ(dynamic_cast<FloatLiteral*>(tokens.at(i)->getLiteralData())->getVal(), expectedValues[i]);
}
Expand All @@ -105,9 +105,9 @@ TEST(LexerTest, DoubleLiterals) {

auto& tokens = (*resp).get();

EXPECT_EQ(tokens.size(), expectedValues.size());
EXPECT_EQ(tokens.size()-1, expectedValues.size());

for (size_t i = 0; i < tokens.size(); i++) {
for (size_t i = 0; i < tokens.size()-1; i++) {
EXPECT_EQ(tokens[i].get()->getTokenKind(), TokenKind::DoubleConstant);
EXPECT_EQ(dynamic_cast<DoubleLiteral*>(tokens.at(i)->getLiteralData())->getVal(), expectedValues[i]);
}
Expand All @@ -129,9 +129,9 @@ TEST(LexerText, Identifiers) {

auto& tokens = (*resp).get();

EXPECT_EQ(tokens.size(), identifiersList.size());
EXPECT_EQ(tokens.size()-1, identifiersList.size());

for (size_t i = 0; i < tokens.size(); i++) {
for (size_t i = 0; i < tokens.size()-1; i++) {
EXPECT_EQ(tokens[i].get()->getIdentifierName(), identifiersList[i]);
EXPECT_EQ(tokens[i].get()->getTokenKind(), TokenKind::Identifier);
}
Expand All @@ -147,9 +147,9 @@ TEST(LexerTest, Keywords) {

auto& tokens = (*resp).get();

EXPECT_EQ(tokens.size(), expectedTokenKinds.size());
EXPECT_EQ(tokens.size()-1, expectedTokenKinds.size());

for (size_t i = 0; i < tokens.size(); ++i) {
for (size_t i = 0; i < tokens.size()-1; ++i) {
EXPECT_EQ(tokens[i]->getTokenKind(), expectedTokenKinds[i]);
}
}
Expand All @@ -164,9 +164,9 @@ TEST(LexerTest, Punctuators) {

auto& tokens = (*resp).get();

EXPECT_EQ(tokens.size(), expectedTokenKinds.size());
EXPECT_EQ(tokens.size()-1, expectedTokenKinds.size());

for (size_t i = 0; i < tokens.size(); ++i) {
for (size_t i = 0; i < tokens.size()-1; ++i) {
EXPECT_EQ(tokens[i]->getTokenKind(), expectedTokenKinds[i]);
}
}
Expand Down

0 comments on commit e9f1245

Please sign in to comment.