From 54b6e6868be1cedc2e481240564087492884dbeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Sat, 7 Jun 2025 19:30:03 +0900 Subject: [PATCH] Better debug printing --- src/Expression.cpp | 104 +++++++++++++++++++++++++++++++----------- src/Expression.h | 14 +++--- src/ModuleBuilder.cpp | 31 +++++++++---- src/ModuleBuilder.h | 12 +++-- src/Parser.cpp | 8 +++- src/Statement.cpp | 72 ++++++++++++++++++++++------- src/Statement.h | 26 ++++++++--- src/main.cpp | 10 ++-- 8 files changed, 201 insertions(+), 76 deletions(-) diff --git a/src/Expression.cpp b/src/Expression.cpp index cfc8886..43ce172 100644 --- a/src/Expression.cpp +++ b/src/Expression.cpp @@ -16,7 +16,7 @@ bool Expression::isValid() { return kind != Expression::Kind::INVALID; } -string Expression::toString() { +string Expression::toString(int indent) { return "EXPRESSION"; } @@ -24,39 +24,58 @@ string Expression::toString() { // ExpressionBinary ExpressionBinary::ExpressionBinary(shared_ptr token, shared_ptr left, shared_ptr right): Expression(Expression::Kind::BINARY, Expression::ValueType::VOID), left(left), right(right) { + // Types must match + if (left->getValueType() != right->getValueType()) + exit(1); + + // Booleans can only do = or != + if (valueType == Expression::ValueType::BOOL && (token->getKind() != Token::Kind::EQUAL || token->getKind() != Token::Kind::NOT_EQUAL)) + exit(1); + switch (token->getKind()) { case Token::Kind::EQUAL: operation = EQUAL; + valueType = Expression::ValueType::BOOL; break; case Token::Kind::NOT_EQUAL: operation = NOT_EQUAL; + valueType = Expression::ValueType::BOOL; break; case Token::Kind::LESS: operation = LESS; + valueType = Expression::ValueType::BOOL; break; case Token::Kind::LESS_EQUAL: operation = LESS_EQUAL; + valueType = Expression::ValueType::BOOL; break; case Token::Kind::GREATER: operation = GREATER; + valueType = Expression::ValueType::BOOL; break; case Token::Kind::GREATER_EQUAL: operation = GREATER_EQUAL; + valueType = Expression::ValueType::BOOL; break; case Token::Kind::PLUS: operation = ADD; + valueType = left->getValueType(); break; case Token::Kind::MINUS: operation = SUB; + valueType = left->getValueType(); break; case Token::Kind::STAR: operation = MUL; + valueType = left->getValueType(); break; case Token::Kind::SLASH: operation = DIV; + valueType = left->getValueType(); break; case Token::Kind::PERCENT: operation = MOD; + valueType = left->getValueType(); break; default: exit(1); @@ -75,30 +94,30 @@ shared_ptr ExpressionBinary::getRight() { return right; } -string ExpressionBinary::toString() { +string ExpressionBinary::toString(int indent) { switch (operation) { case EQUAL: - return "{= " + left->toString() + " " + right->toString() + "}"; + return "{= " + left->toString(0) + " " + right->toString(0) + "}"; case NOT_EQUAL: - return "{!= " + left->toString() + " " + right->toString() + "}"; + return "{!= " + left->toString(0) + " " + right->toString(0) + "}"; case LESS: - return "{< " + left->toString() + " " + right->toString() + "}"; + return "{< " + left->toString(0) + " " + right->toString(0) + "}"; case LESS_EQUAL: - return "{<= " + left->toString() + " " + right->toString() + "}"; + return "{<= " + left->toString(0) + " " + right->toString(0) + "}"; case GREATER: - return "{> " + left->toString() + " " + right->toString() + "}"; + return "{> " + left->toString(0) + " " + right->toString(0) + "}"; case GREATER_EQUAL: - return "{<= " + left->toString() + " " + right->toString() + "}"; + return "{<= " + left->toString(0) + " " + right->toString(0) + "}"; case ADD: - return "{+ " + left->toString() + " " + right->toString() + "}"; + return "{+ " + left->toString(0) + " " + right->toString(0) + "}"; case SUB: - return "{- " + left->toString() + " " + right->toString() + "}"; + return "{- " + left->toString(0) + " " + right->toString(0) + "}"; case MUL: - return "{* " + left->toString() + " " + right->toString() + "}"; + return "{* " + left->toString(0) + " " + right->toString(0) + "}"; case DIV: - return "{/ " + left->toString() + " " + right->toString() + "}"; + return "{/ " + left->toString(0) + " " + right->toString(0) + "}"; case MOD: - return "{% " + left->toString() + " " + right->toString() + "}"; + return "{% " + left->toString(0) + " " + right->toString(0) + "}"; } } @@ -106,8 +125,22 @@ string ExpressionBinary::toString() { // ExpressionLiteral ExpressionLiteral::ExpressionLiteral(shared_ptr token): Expression(Expression::Kind::LITERAL, Expression::ValueType::VOID) { - valueType = Expression::ValueType::SINT32; - sint32Value = stoi(token->getLexme()); + switch (token->getKind()) { + case Token::Kind::BOOL: + boolValue = token->getLexme().compare("true") == 0; + valueType = Expression::ValueType::BOOL; + break; + case Token::Kind::INTEGER: + sint32Value = stoi(token->getLexme()); + valueType = Expression::ValueType::SINT32; + break; + case Token::Kind::REAL: + real32Value = stof(token->getLexme()); + valueType = Expression::ValueType::REAL32; + break; + default: + exit(1); + } } bool ExpressionLiteral::getBoolValue() { @@ -122,8 +155,7 @@ float ExpressionLiteral::getReal32Value() { return real32Value; } -string ExpressionLiteral::toString() { - //return to_string(integer); +string ExpressionLiteral::toString(int indent) { switch (valueType) { case Expression::ValueType::VOID: return "VOID"; @@ -139,21 +171,35 @@ string ExpressionLiteral::toString() { // // ExpressionGrouping ExpressionGrouping::ExpressionGrouping(shared_ptr expression): - Expression(Expression::Kind::GROUPING, Expression::ValueType::VOID), expression(expression) { + Expression(Expression::Kind::GROUPING, expression->getValueType()), expression(expression) { } shared_ptr ExpressionGrouping::getExpression() { return expression; } -string ExpressionGrouping::toString() { - return "( " + expression->toString() + " )"; +string ExpressionGrouping::toString(int indent) { + return "( " + expression->toString(0) + " )"; } // // ExpressionIfElse ExpressionIfElse::ExpressionIfElse(shared_ptr condition, shared_ptr thenBlock, shared_ptr elseBlock): Expression(Expression::Kind::IF_ELSE, Expression::ValueType::VOID), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) { + // Condition must evaluate to bool + if (condition->getValueType() != Expression::ValueType::BOOL) + exit(1); + + // Return types must match + shared_ptr thenStatementExpression = thenBlock->getStatementExpression(); + shared_ptr thenExpression = thenStatementExpression != nullptr ? thenStatementExpression->getExpression() : nullptr; + shared_ptr elseStatementExpression = elseBlock != nullptr ? elseBlock->getStatementExpression() : nullptr; + shared_ptr elseExpression = elseStatementExpression != nullptr ? elseStatementExpression->getExpression() : nullptr; + if (thenExpression != nullptr && elseExpression != nullptr && thenExpression->getValueType() != elseExpression->getValueType()) + exit(1); + + // get type or default to void + valueType = thenExpression ? thenExpression->getValueType() : Expression::ValueType::VOID; } shared_ptr ExpressionIfElse::getCondition() { @@ -168,15 +214,19 @@ shared_ptr ExpressionIfElse::getElseBlock() { return elseBlock; } -string ExpressionIfElse::toString() { - string value = ""; +string ExpressionIfElse::toString(int indent) { + string value; + value += "IF(" + condition->toString(0) + "):\n"; - value += "IF(" + condition->toString() + ")\n"; - value += thenBlock->toString(); + value += thenBlock->toString(indent+1); if (elseBlock != nullptr) { - value += "ELSE\n"; - value += elseBlock->toString(); + for (int ind=0; indtoString(indent+1); } + for (int ind=0; ind ExpressionInvalid::getToken() { return token; } -string ExpressionInvalid::toString() { +string ExpressionInvalid::toString(int indent) { return "Invalid token " + token->toString() + " at " + to_string(token->getLine()) + ":" + to_string(token->getColumn()) + "\n"; } \ No newline at end of file diff --git a/src/Expression.h b/src/Expression.h index 2ebf8b2..f8f3c7b 100644 --- a/src/Expression.h +++ b/src/Expression.h @@ -5,6 +5,7 @@ #include "Statement.h" class StatementBlock; +class StatementExpression; using namespace std; @@ -36,7 +37,7 @@ public: Kind getKind(); ValueType getValueType(); bool isValid(); - virtual string toString(); + virtual string toString(int indent); }; class ExpressionLiteral: public Expression { @@ -47,11 +48,10 @@ private: public: ExpressionLiteral(shared_ptr token); - //int64_t getInteger(); bool getBoolValue(); int32_t getSint32Value(); float getReal32Value(); - string toString() override; + string toString(int indent) override; }; class ExpressionGrouping: public Expression { @@ -61,7 +61,7 @@ private: public: ExpressionGrouping(shared_ptr expression); shared_ptr getExpression(); - string toString() override; + string toString(int indent) override; }; class ExpressionBinary: public Expression { @@ -90,7 +90,7 @@ public: Operation getOperation(); shared_ptr getLeft(); shared_ptr getRight(); - string toString() override; + string toString(int indent) override; }; class ExpressionIfElse: public Expression { @@ -104,7 +104,7 @@ public: shared_ptr getCondition(); shared_ptr getThenBlock(); shared_ptr getElseBlock(); - string toString() override; + string toString(int indent) override; }; class ExpressionInvalid: public Expression { @@ -114,7 +114,7 @@ private: public: ExpressionInvalid(shared_ptr token); shared_ptr getToken(); - string toString() override; + string toString(int indent) override; }; #endif \ No newline at end of file diff --git a/src/ModuleBuilder.cpp b/src/ModuleBuilder.cpp index aaebecc..11a904a 100644 --- a/src/ModuleBuilder.cpp +++ b/src/ModuleBuilder.cpp @@ -1,12 +1,14 @@ #include "ModuleBuilder.h" -ModuleBuilder::ModuleBuilder(vector> statements): statements(statements) { +/*ModuleBuilder::ModuleBuilder(vector> statements): statements(statements) { context = make_shared(); module = make_shared("dummy", *context); builder = make_shared>(*context); - voidType = llvm::Type::getVoidTy(*context); - int32Type = llvm::Type::getInt32Ty(*context); + typeVoid = llvm::Type::getVoidTy(*context); + typeBool = llvm::Type::getInt1Ty(*context); + typeSInt32 = llvm::Type::getInt32Ty(*context); + typeReal32 = llvm::Type::getFloatTy(*context); } shared_ptr ModuleBuilder::getModule() { @@ -36,7 +38,7 @@ void ModuleBuilder::buildStatement(shared_ptr statement) { } void ModuleBuilder::buildFunctionDeclaration(shared_ptr statement) { - llvm::FunctionType *funType = llvm::FunctionType::get(int32Type, false); + llvm::FunctionType *funType = llvm::FunctionType::get(typeSInt32, false); llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::InternalLinkage, statement->getName(), module.get()); llvm::BasicBlock *block = llvm::BasicBlock::Create(*context, statement->getName(), fun); builder->SetInsertPoint(block); @@ -79,7 +81,7 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr expression llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr expression) { //return llvm::ConstantInt::get(int32Type, expression->getInteger(), true); - return llvm::ConstantInt::get(int32Type, expression->getSint32Value(), true); + return llvm::ConstantInt::get(typeSInt32, expression->getSint32Value(), true); } llvm::Value *ModuleBuilder::valueForGrouping(shared_ptr expression) { @@ -130,14 +132,14 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi // Then builder->SetInsertPoint(thenBlock); - llvm::Value *thenValue = llvm::ConstantInt::get(int32Type, 11, true); + llvm::Value *thenValue = llvm::ConstantInt::get(typeSInt32, 11, true); buildStatement(expression->getThenBlock()); builder->CreateBr(mergeBlock); thenBlock = builder->GetInsertBlock(); // Else fun->insert(fun->end(), elseBlock); - llvm::Value *elseValue = llvm::ConstantInt::get(int32Type, 22, true); + llvm::Value *elseValue = llvm::ConstantInt::get(typeSInt32, 22, true); builder->SetInsertPoint(elseBlock); if (expression->getElseBlock() != nullptr) buildStatement(expression->getElseBlock()); @@ -147,10 +149,23 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi // Merge fun->insert(fun->end(), mergeBlock); builder->SetInsertPoint(mergeBlock); - llvm::PHINode *phi = builder->CreatePHI(int32Type, 2, "phii"); + llvm::PHINode *phi = builder->CreatePHI(typeSInt32, 2, "phii"); phi->addIncoming(thenValue, thenBlock); phi->addIncoming(elseValue, elseBlock); //return llvm::ConstantInt::get(int32Type, 42, true); return phi; } + +llvm::Type *ModuleBuilder::typeForExpression(shared_ptr expression) { + switch (expression->getValueType()) { + case Expression::ValueType::VOID: + return typeVoid; + case Expression::ValueType::BOOL: + return typeBool; + case Expression::ValueType::SINT32: + return typeSInt32; + case Expression::ValueType::REAL32: + return typeReal32; + } +}*/ diff --git a/src/ModuleBuilder.h b/src/ModuleBuilder.h index ac8c507..de31300 100644 --- a/src/ModuleBuilder.h +++ b/src/ModuleBuilder.h @@ -13,13 +13,15 @@ using namespace std; class ModuleBuilder { -private: +/*private: shared_ptr context; shared_ptr module; shared_ptr> builder; - llvm::Type *voidType; - llvm::IntegerType *int32Type; + llvm::Type *typeVoid; + llvm::Type *typeBool; + llvm::IntegerType *typeSInt32; + llvm::Type *typeReal32; vector> statements; @@ -35,9 +37,11 @@ private: llvm::Value *valueForBinary(shared_ptr expression); llvm::Value *valueForIfElse(shared_ptr expression); + llvm::Type *typeForExpression(shared_ptr expression); + public: ModuleBuilder(vector> statements); - shared_ptr getModule(); + shared_ptr getModule();*/ }; #endif \ No newline at end of file diff --git a/src/Parser.cpp b/src/Parser.cpp index b61dc79..c1323f7 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -10,7 +10,7 @@ vector> Parser::getStatements() { shared_ptr statement = nextStatement(); // Abort parsing if we got an error if (!statement->isValid()) { - cerr << statement->toString(); + cerr << statement->toString(0); exit(1); } statements.push_back(statement); @@ -111,6 +111,10 @@ shared_ptr Parser::matchStatementExpression() { else if (!expression->isValid()) return make_shared(tokens.at(currentIndex)); + // Consume new line + if (tokens.at(currentIndex)->getKind() == Token::Kind::NEW_LINE) + currentIndex++; + return make_shared(expression); } @@ -195,7 +199,7 @@ shared_ptr Parser::matchPrimary() { shared_ptr Parser::matchExpressionLiteral() { shared_ptr token = tokens.at(currentIndex); - if (token->isOfKind({Token::Kind::INTEGER})) { + if (token->isOfKind({Token::Kind::BOOL, Token::Kind::INTEGER, Token::Kind::REAL})) { currentIndex++; return make_shared(token); } diff --git a/src/Statement.cpp b/src/Statement.cpp index 9d87903..14e2f32 100644 --- a/src/Statement.cpp +++ b/src/Statement.cpp @@ -1,5 +1,7 @@ #include "Statement.h" +// +// Statement Statement::Statement(Kind kind): kind(kind) { } @@ -11,22 +13,30 @@ bool Statement::isValid() { return kind != Statement::Kind::INVALID; } -string Statement::toString() { +string Statement::toString(int indent) { return "STATEMENT"; } // // StatementFunctionDeclaration StatementFunctionDeclaration::StatementFunctionDeclaration(string name, shared_ptr statementBlock): - Statement(Statement::Kind::FUNCTION_DECLARATION), name(name), statementBlock(statementBlock) { +Statement(Statement::Kind::FUNCTION_DECLARATION), name(name), statementBlock(statementBlock) { } string StatementFunctionDeclaration::getName() { return name; } -string StatementFunctionDeclaration::toString() { - return "FUNCTION(" + name + ")\n" + statementBlock->toString() + "\n;"; +string StatementFunctionDeclaration::toString(int indent) { + string value = ""; + for (int ind=0; indtoString(indent+1); + for (int ind=0; ind StatementFunctionDeclaration::getStatementBlock() { @@ -36,24 +46,44 @@ shared_ptr StatementFunctionDeclaration::getStatementBlock() { // // StatementBlock StatementBlock::StatementBlock(vector> statements): - Statement(Statement::Kind::BLOCK), statements(statements) { +Statement(Statement::Kind::BLOCK), statements(statements) { + if (statements.back()->getKind() == Statement::Kind::EXPRESSION) { + statementExpression = dynamic_pointer_cast(statements.back()); + this->statements.pop_back(); + } } vector> StatementBlock::getStatements() { return statements; } -string StatementBlock::toString() { +shared_ptr StatementBlock::getStatementExpression() { + return statementExpression; +} + +string StatementBlock::toString(int indent) { string value; - for (int i=0; itoString(); + for (int i=0; itoString(indent); + } + if (statementExpression != nullptr) { + for (int ind=0; indtoString(indent); + } + for (int ind=0; ind expression): - Statement(Statement::Kind::RETURN), expression(expression) { +Statement(Statement::Kind::RETURN), expression(expression) { } @@ -61,10 +91,13 @@ shared_ptr StatementReturn::getExpression() { return expression; } -string StatementReturn::toString() { - string value = "RETURN"; +string StatementReturn::toString(int indent) { + string value; + for (int ind=0; indtoString() + ")"; + value += "(" + expression->toString(0) + ")"; value += "\n"; return value; } @@ -72,23 +105,28 @@ string StatementReturn::toString() { // // StatementExpression StatementExpression::StatementExpression(shared_ptr expression): - Statement(Statement::Kind::EXPRESSION), expression(expression) { +Statement(Statement::Kind::EXPRESSION), expression(expression) { } shared_ptr StatementExpression::getExpression() { return expression; } -string StatementExpression::toString() { - return "EXPRESSION(" + expression->toString() + ")"; +string StatementExpression::toString(int indent) { + string value; + for (int ind=0; indtoString(indent); + value += "\n"; + return value; } // // StatementInvalid StatementInvalid::StatementInvalid(shared_ptr token): - Statement(Statement::Kind::INVALID), token(token) { +Statement(Statement::Kind::INVALID), token(token) { } -string StatementInvalid::toString() { +string StatementInvalid::toString(int indent) { return "Invalid token " + token->toString() + " at " + to_string(token->getLine()) + ":" + to_string(token->getColumn()) + "\n"; } diff --git a/src/Statement.h b/src/Statement.h index 1604854..ecc5491 100644 --- a/src/Statement.h +++ b/src/Statement.h @@ -16,6 +16,8 @@ class StatementReturn; class StatementExpression; class StatementInvalid; +// +// Statement class Statement { public: enum Kind { @@ -33,9 +35,11 @@ public: Statement(Kind kind); Kind getKind(); bool isValid(); - virtual string toString(); + virtual string toString(int indent); }; +// +// StatementFunctionDeclaration class StatementFunctionDeclaration: public Statement { private: string name; @@ -45,19 +49,25 @@ public: StatementFunctionDeclaration(string name, shared_ptr statementBlock); string getName(); shared_ptr getStatementBlock(); - string toString() override; + string toString(int indent) override; }; +// +// StatementBlock class StatementBlock: public Statement { private: vector> statements; + shared_ptr statementExpression; public: StatementBlock(vector> statements); vector> getStatements(); - string toString() override; + shared_ptr getStatementExpression(); + string toString(int indent) override; }; +// +// StatementReturn class StatementReturn: public Statement { private: shared_ptr expression; @@ -65,9 +75,11 @@ private: public: StatementReturn(shared_ptr expression); shared_ptr getExpression(); - string toString() override; + string toString(int indent) override; }; +// +// StatementExpression class StatementExpression: public Statement { private: shared_ptr expression; @@ -75,16 +87,18 @@ private: public: StatementExpression(shared_ptr expression); shared_ptr getExpression(); - string toString() override; + string toString(int indent) override; }; +// +// StatementInvalid class StatementInvalid: public Statement { private: shared_ptr token; public: StatementInvalid(shared_ptr token); - string toString() override; + string toString(int indent) override; }; #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f2583bc..a6ab12d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,18 +41,18 @@ int main(int argc, char **argv) { if (i < tokens.size() - 1) std::cout << " "; } - std::cout << std::endl; + cout << endl << endl; Parser parser(tokens); vector> statements = parser.getStatements(); for (shared_ptr &statement : statements) { - cout << statement->toString(); + cout << statement->toString(0); cout << endl; } - ModuleBuilder moduleBuilder(statements); - shared_ptr module = moduleBuilder.getModule(); - module->print(llvm::outs(), nullptr); + //ModuleBuilder moduleBuilder(statements); + //shared_ptr module = moduleBuilder.getModule(); + //module->print(llvm::outs(), nullptr); //CodeGenerator codeGenerator(module); //codeGenerator.generateObjectFile("dummy.s");