diff --git a/IR-Generator/inc/Lexer.h b/IR-Generator/inc/Lexer.h index 57104c6..c452108 100644 --- a/IR-Generator/inc/Lexer.h +++ b/IR-Generator/inc/Lexer.h @@ -81,6 +81,8 @@ namespace LX OPEN_BRACE, CLOSE_BRACE, OPEN_PAREN, CLOSE_PAREN, + COMMA, + // Operators // ADD, SUB, MUL, DIV, diff --git a/IR-Generator/inc/Parser.h b/IR-Generator/inc/Parser.h index d9d98d8..7a8ebfa 100644 --- a/IR-Generator/inc/Parser.h +++ b/IR-Generator/inc/Parser.h @@ -27,7 +27,6 @@ namespace LX::AST { // General Nodes // - IDENTIFIER, NUMBER_LITERAL, OPERATION, @@ -48,6 +47,9 @@ namespace LX::AST // Function for generating LLVN IR (Intermediate representation) // virtual llvm::Value* GenIR(InfoLLVM& LLVM) = 0; + // Function to log the node to a file // + virtual void Log(std::ofstream* log, unsigned depth) = 0; + // Function for generating C/C++ code (Currently not implemented) // //virtual void GenC() = 0; diff --git a/IR-Generator/src/main.cpp b/IR-Generator/src/main.cpp index 3091ba2..0d86555 100644 --- a/IR-Generator/src/main.cpp +++ b/IR-Generator/src/main.cpp @@ -178,9 +178,11 @@ int main(int argc, char** argv) LX::PrintStringAsColor("Error: ", LX::Color::LIGHT_RED); std::cout << "Invalid character found in "; LX::PrintStringAsColor(inpPath.filename().string(), LX::Color::WHITE); - std::cout << ":\n"; + std::cout << " {"; + LX::PrintStringAsColor(std::string(1, e.invalid), LX::Color::LIGHT_RED); + std::cout << "}:\n"; std::cout << "Line: " << std::setw(lineNumberWidthInConsole) << e.line << " | " << line << "\n"; - std::cout << " " << std::setw(lineNumberWidthInConsole) << "" << " | " << std::setw(e.col); + std::cout << " " << std::setw(lineNumberWidthInConsole) << "" << " | " << std::setw(e.col + 1); LX::PrintStringAsColor("^", LX::Color::LIGHT_RED); std::cout << "\n"; @@ -215,7 +217,7 @@ int main(int argc, char** argv) // Prints the code with the error to the console // std::string errorSquiggle(e.got.length, '~'); std::cout << "Line: " << std::setw(lineNumberWidthInConsole) << e.got.line << " | " << line << "\n"; - std::cout << " " << std::setw(lineNumberWidthInConsole) << "" << " | " << std::setw(e.got.column) << ""; + std::cout << " " << std::setw(lineNumberWidthInConsole) << "" << " | " << std::setw(e.got.column + 1) << ""; LX::PrintStringAsColor(errorSquiggle, LX::Color::LIGHT_RED); std::cout << "\n"; diff --git a/Lexer/src/Lexer.cpp b/Lexer/src/Lexer.cpp index 6f43842..a64a203 100644 --- a/Lexer/src/Lexer.cpp +++ b/Lexer/src/Lexer.cpp @@ -113,7 +113,8 @@ namespace LX { '[', Token::OPEN_BRACE }, { ']', Token::CLOSE_BRACE }, { '(', Token::OPEN_PAREN }, - { ')', Token::CLOSE_PAREN } + { ')', Token::CLOSE_PAREN }, + { ',', Token::COMMA } }; // All the single-char operators currently supported by the lexer with their token-enum equivalents // diff --git a/Parser/inc/AST.h b/Parser/inc/AST.h index 57359ca..c1d4c22 100644 --- a/Parser/inc/AST.h +++ b/Parser/inc/AST.h @@ -16,9 +16,6 @@ namespace LX llvm::Module module; llvm::IRBuilder<> builder; }; - - // Function to turn a AST node into string // - std::string ToString(std::unique_ptr& node); } namespace LX::AST @@ -33,6 +30,9 @@ namespace LX::AST // Function for generating LLVN IR (Intermediate representation) // llvm::Value* GenIR(InfoLLVM& LLVM) override; + // Function to log the node to a file // + void Log(std::ofstream* log, unsigned depth) override; + private: // The number it stores // // Yes the number is stored as a string, It's horrible I know // @@ -49,6 +49,9 @@ namespace LX::AST // Function for generating LLVN IR (Intermediate representation) // llvm::Value* GenIR(InfoLLVM& LLVM) override; + // Function to log the node to a file // + void Log(std::ofstream* log, unsigned depth) override; + private: // The sides of the operation // // Unary operations are handled by a different class // @@ -68,6 +71,9 @@ namespace LX::AST // Function for generating LLVN IR (Intermediate representation) // llvm::Value* GenIR(InfoLLVM& LLVM) override; + // Function to log the node to a file // + void Log(std::ofstream* log, unsigned depth) override; + private: // What it is returning (can be null) // std::unique_ptr m_Val; diff --git a/Parser/src/AST-Loggers.cpp b/Parser/src/AST-Loggers.cpp index 6852f5c..20b3512 100644 --- a/Parser/src/AST-Loggers.cpp +++ b/Parser/src/AST-Loggers.cpp @@ -1,17 +1,43 @@ #include -namespace LX -{ - std::string ToString(std::unique_ptr& node) - { - if (node == nullptr) { return "NULL Node"; } +#include - switch (node->m_Type) +namespace LX::AST +{ + void Node::Log(std::ofstream* log, unsigned depth) + { + (*log) << std::string(depth, '\t') << "NULL node"; + } + + void NumberLiteral::Log(std::ofstream* log, unsigned depth) + { + (*log) << std::string(depth, '\t'); + (*log) << "Number: " << m_Number << "\n"; + } + + void Operation::Log(std::ofstream* log, unsigned depth) + { + (*log) << std::string(depth, '\t'); + (*log) << "Operation {" << ToString(m_Operand) << "}:\n"; + (*log) << std::string(depth + 1, '\t') << "LHS:\n"; + m_Lhs.get()->Log(log, depth + 2); + (*log) << std::string(depth + 1, '\t') << "RHS:\n"; + m_Rhs.get()->Log(log, depth + 2); + } + + void ReturnStatement::Log(std::ofstream* log, unsigned depth) + { + (*log) << std::string(depth, '\t'); + + if (m_Val == nullptr) { - case AST::Node::IDENTIFIER: return "IDENTIFIER"; - case AST::Node::OPERATION: return "OPERATION"; - case AST::Node::RETURN_STATEMENT: return "return"; - case AST::Node::NUMBER_LITERAL: return "number"; + (*log) << "Return\n"; + } + + else + { + (*log) << "Return:\n"; + m_Val->Log(log, depth + 1); } } } diff --git a/Parser/src/Parser.cpp b/Parser/src/Parser.cpp index 28b673d..75a448c 100644 --- a/Parser/src/Parser.cpp +++ b/Parser/src/Parser.cpp @@ -42,12 +42,13 @@ namespace LX case Token::NUMBER_LITERAL: return std::make_unique(p.tokens[p.index++].GetContents()); - // + // TODO: Fix this // case Token::OPEN_BRACKET: p.scopeDepth++; p.index++; return nullptr; + // TODO: Fix this // case Token::CLOSE_BRACE: ThrowIf(p.scopeDepth == 0, Token::UNDEFINED, "need a different error", p.tokens[p.index]); p.scopeDepth--; @@ -148,19 +149,31 @@ namespace LX ThrowIf(p.tokens[p.index].type != Token::IDENTIFIER, Token::IDENTIFIER, "", p.tokens[p.index]); func.name = p.tokens[p.index++].GetContents(); + // Checks for opening paren '(' // + ThrowIf(p.tokens[p.index].type != Token::OPEN_PAREN, Token::OPEN_PAREN, "", p.tokens[p.index]); + p.index++; + + // Loops over all the arguments of the function // + while (p.index < p.len && (p.tokens[p.index].type == Token::CLOSE_PAREN) == false) + { + p.index++; + } + + // Skips over close bracket // + p.index++; + // Checks for opening bracket '{' // ThrowIf(p.tokens[p.index].type != Token::OPEN_BRACKET, Token::OPEN_BRACKET, "", p.tokens[p.index]); p.index++; // Loops over the body until it reaches the end // - // TODO: Detect the end instead of looping over the entire token vector while (p.index < p.len && (p.tokens[p.index].type == Token::CLOSE_BRACKET && p.scopeDepth == 0) == false) { // Actually parses the function std::unique_ptr node = Parse(p); // Logs the node to the log // - SafeLog(log, ToString(node)); + if (log != nullptr) { node->Log(log, 0); } // Adds it to the vector func.body.push_back(std::move(node)); diff --git a/example/main.lx b/example/main.lx index 140ec80..487384e 100644 --- a/example/main.lx +++ b/example/main.lx @@ -1,9 +1,4 @@ -func add +func main() { return 1 + 2 } - -func main -{ - return 375 + 32 -}