From f23d3c1465147842566312fa0a706cd0ed953b3c Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 08:23:04 +0100 Subject: [PATCH 01/12] Create subtraction token --- src/lexer/tokens/operators/subtraction/subtraction.cpp | 4 ++++ src/lexer/tokens/operators/subtraction/subtraction.hpp | 8 ++++++++ 2 files changed, 12 insertions(+) create mode 100644 src/lexer/tokens/operators/subtraction/subtraction.cpp create mode 100644 src/lexer/tokens/operators/subtraction/subtraction.hpp diff --git a/src/lexer/tokens/operators/subtraction/subtraction.cpp b/src/lexer/tokens/operators/subtraction/subtraction.cpp new file mode 100644 index 0000000..8f33a72 --- /dev/null +++ b/src/lexer/tokens/operators/subtraction/subtraction.cpp @@ -0,0 +1,4 @@ +#include "./subtraction.hpp" + +SubtractionToken::SubtractionToken() + : OperatorToken(OperatorType::SUBTRACTION) {} \ No newline at end of file diff --git a/src/lexer/tokens/operators/subtraction/subtraction.hpp b/src/lexer/tokens/operators/subtraction/subtraction.hpp new file mode 100644 index 0000000..d58df88 --- /dev/null +++ b/src/lexer/tokens/operators/subtraction/subtraction.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "../operator.hpp" + +class SubtractionToken : public OperatorToken { +public: + SubtractionToken(); +}; \ No newline at end of file From 4dec6358c3764cbde0c4563244e6b46e9a38e725 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 08:23:18 +0100 Subject: [PATCH 02/12] Create add subtraction token method --- src/lexer/token_container/token_container.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lexer/token_container/token_container.hpp b/src/lexer/token_container/token_container.hpp index 974d400..a0755b1 100644 --- a/src/lexer/token_container/token_container.hpp +++ b/src/lexer/token_container/token_container.hpp @@ -8,6 +8,7 @@ #include "lexer/tokens/number/number.hpp" #include "lexer/tokens/operators/addition/addition.hpp" #include "lexer/tokens/operators/assignment/assignment.hpp" +#include "lexer/tokens/operators/subtraction/subtraction.hpp" #include "lexer/tokens/primitives/uint16/uint16.hpp" #include "lexer/tokens/primitives/uint32/uint32.hpp" #include "lexer/tokens/primitives/uint64/uint64.hpp" @@ -39,6 +40,10 @@ class TokenContainer { tokens.push_back(std::make_unique(token)); } + void addSubtraction(const SubtractionToken& token) { + tokens.push_back(std::make_unique(token)); + } + void addAssignment(const AssignmentToken& token) { tokens.push_back(std::make_unique(token)); } From 768aa9502d73af10e49038c504f5cd64f226d99c Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 08:23:39 +0100 Subject: [PATCH 03/12] Parse subtraction string --- src/lexer/lexer.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lexer/lexer.hpp b/src/lexer/lexer.hpp index 20c99fb..7912986 100644 --- a/src/lexer/lexer.hpp +++ b/src/lexer/lexer.hpp @@ -11,6 +11,7 @@ #include "./tokens/primitives/uint64/uint64.hpp" #include "./tokens/operators/addition/addition.hpp" +#include "lexer/tokens/operators/subtraction/subtraction.hpp" #include "lexer/tokens/primitives/uint16/uint16.hpp" #include "lexer/tokens/primitives/uint32/uint32.hpp" #include "lexer/tokens/print/print.hpp" @@ -54,6 +55,8 @@ class Lexer { tokens.addNumber(StringConverter::toUnsignedLongLong(buffer)); } else if (buffer == "+") { tokens.addAddition(AdditionToken()); + } else if (buffer == "-") { + tokens.addSubtraction(SubtractionToken()); } else if (buffer == "return") { tokens.addReturn(ReturnToken()); } else if (buffer == "print") { From c81b4dfc7f89f82c18a152db17695b5dd9b4189e Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 08:23:48 +0100 Subject: [PATCH 04/12] Add subtraction operator type --- src/lexer/tokens/operators/operator_type.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lexer/tokens/operators/operator_type.hpp b/src/lexer/tokens/operators/operator_type.hpp index 7e32b0c..1b2df38 100644 --- a/src/lexer/tokens/operators/operator_type.hpp +++ b/src/lexer/tokens/operators/operator_type.hpp @@ -1,3 +1,3 @@ #pragma once -enum OperatorType { ASSIGNMENT = 1, ADDITION = 2 }; \ No newline at end of file +enum OperatorType { ASSIGNMENT = 1, ADDITION = 2, SUBTRACTION = 3 }; \ No newline at end of file From b6f7cfb9e122de573d495772d8b98ec898879081 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 08:26:16 +0100 Subject: [PATCH 05/12] Print subtract token --- src/lexer/token_container/token_container.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/lexer/token_container/token_container.cpp b/src/lexer/token_container/token_container.cpp index a6b73b9..c2aaeb5 100644 --- a/src/lexer/token_container/token_container.cpp +++ b/src/lexer/token_container/token_container.cpp @@ -7,6 +7,7 @@ #include "../tokens/number/number.hpp" #include "../tokens/operators/operator.hpp" #include "../tokens/primitives/primitive.hpp" +#include "lexer/tokens/operators/operator_type.hpp" TokenContainer::TokenContainer() {}; @@ -59,18 +60,27 @@ void TokenContainer::print() const { case OPERATOR: { const OperatorToken& op = static_cast(token); + std::string out = "OPERATOR("; switch (op.operatorType) { case ASSIGNMENT: { - std::cout << "OPERATOR(=)\n"; + out += "="; break; } case ADDITION: { - std::cout << "OPERATOR(+)\n"; + out += "+"; + break; + } + + case SUBTRACTION: { + out += "-"; break; } } + out += ")"; + + std::cout << out << "\n"; break; } From e5e33c50c2fc64b89b0e0679cb3eea98d9849a26 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 08:27:19 +0100 Subject: [PATCH 06/12] Create subtraction example --- examples/subtraction.lang | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 examples/subtraction.lang diff --git a/examples/subtraction.lang b/examples/subtraction.lang new file mode 100644 index 0000000..727bbd6 --- /dev/null +++ b/examples/subtraction.lang @@ -0,0 +1,6 @@ +uint8 a = 6 - 1; +uint8 b = a - 1; + +uint8 c = a - b; + +return c; \ No newline at end of file From 1354e5f8c5b5e1a3b1c2e006ad0fc073e9fa1f26 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:41:28 +0100 Subject: [PATCH 07/12] Handle subtraction --- src/generation/generator.hpp | 100 +++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/src/generation/generator.hpp b/src/generation/generator.hpp index db95b86..242f10a 100644 --- a/src/generation/generator.hpp +++ b/src/generation/generator.hpp @@ -15,6 +15,7 @@ #include "syntax_analyser/statement/print/print.hpp" #include "syntax_analyser/statement/return/return.hpp" #include "syntax_analyser/statement/statement.hpp" +#include "syntax_analyser/statement/subtraction/subtraction.hpp" #include "syntax_analyser/statement/value/identifier/identifier.hpp" #include "syntax_analyser/statement/value/number/number.hpp" #include "syntax_analyser/statement/value/value.hpp" @@ -361,6 +362,105 @@ class Generator { builder.store(builder.add(lhs, rhs, outName), outUint.getAlloc()); } + + case StatementType::SUBTRACTION: { + const SubtractionStatement& subtractionStatement = + static_cast(statement); + + std::unique_ptr& out = + symbols.at(subtractionStatement.identifier.name); + + if (out->getType() != BuilderPrimitiveType::UINT) { + throw std::runtime_error( + "Cannot assign subtraction to non-uint type"); + } + + BuilderUintPrimitive& outUint = + static_cast(*out); + + llvm::Value* lhs; + llvm::Value* rhs; + + std::string outName = "subtract_"; + + switch (subtractionStatement.lhs->statementValueType) { + case StatementValueType::IDENTIFIER: { + const IdentifierValue& lhsIdentifierValue = + static_cast( + *subtractionStatement.lhs.get()); + + std::unique_ptr& lhsValue = + symbols.at(lhsIdentifierValue.name); + + if (lhsValue->getType() != BuilderPrimitiveType::UINT) { + throw std::runtime_error("Cannot subtract non-uint types"); + } + + BuilderUintPrimitive& lhsUintValue = + static_cast(*lhsValue); + + lhs = builder.load(lhsUintValue.getLlvmIntegerType(), + lhsUintValue.getAlloc(), + lhsIdentifierValue.name + "_load"); + + outName += lhsIdentifierValue.name; + break; + } + + case StatementValueType::NUMBER: { + const NumberValue& lhsNumberValue = + static_cast( + *subtractionStatement.lhs.get()); + + lhs = builder.createConst8(lhsNumberValue.value); + outName += "const"; + break; + } + } + + outName += "_and_"; + + switch (subtractionStatement.rhs->statementValueType) { + case StatementValueType::IDENTIFIER: { + const IdentifierValue& rhsIdentifierValue = + static_cast( + *subtractionStatement.rhs.get()); + + std::unique_ptr& rhsValue = + symbols.at(rhsIdentifierValue.name); + + if (rhsValue->getType() != BuilderPrimitiveType::UINT) { + throw std::runtime_error("Cannot subtract non-uint types"); + } + + BuilderUintPrimitive& rhsValueUint = + static_cast(*rhsValue); + + rhs = builder.load(rhsValueUint.getLlvmIntegerType(), + rhsValueUint.getAlloc(), + rhsIdentifierValue.name + "_load"); + + outName += rhsIdentifierValue.name; + break; + } + + case StatementValueType::NUMBER: { + const NumberValue& rhsNumberValue = + static_cast( + *subtractionStatement.rhs.get()); + + rhs = builder.createConst8(rhsNumberValue.value); + outName += "const"; + + break; + } + } + + builder.store(builder.subtract(lhs, rhs, outName), + outUint.getAlloc()); + break; + } + case StatementType::PRINT: { const PrintStatement& printStatement = static_cast(statement); From c05838d891b7bd0ad28d87d6520c279ee02c822d Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:41:43 +0100 Subject: [PATCH 08/12] Create subtract LLVM IR wrapper --- src/generation/builder/builder.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/generation/builder/builder.hpp b/src/generation/builder/builder.hpp index 0e78906..fb80590 100644 --- a/src/generation/builder/builder.hpp +++ b/src/generation/builder/builder.hpp @@ -77,6 +77,10 @@ class Builder { return this->irBuilder.CreateAdd(lhs, rhs, name); }; + llvm::Value* subtract(llvm::Value* lhs, llvm::Value* rhs, std::string name) { + return this->irBuilder.CreateSub(lhs, rhs, name); + }; + llvm::Value* zext(llvm::Value* in, llvm::Type* outType) { return this->irBuilder.CreateZExt(in, outType); }; From 9d6ae22e8cbee5f41e3c1f726a8577ddd7bc8466 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:42:04 +0100 Subject: [PATCH 09/12] Handle subtraction statement creation --- src/syntax_analyser/abstract_syntax_tree.cpp | 67 +++++++++++++------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/src/syntax_analyser/abstract_syntax_tree.cpp b/src/syntax_analyser/abstract_syntax_tree.cpp index afcce01..6e6d8c9 100644 --- a/src/syntax_analyser/abstract_syntax_tree.cpp +++ b/src/syntax_analyser/abstract_syntax_tree.cpp @@ -111,38 +111,64 @@ std::vector> AbstractSyntaxTree::evaluateOperations( const OperatorToken& firstTokenOperator = static_cast(firstToken); - if (firstTokenOperator.operatorType != OperatorType::ADDITION) { - throw std::format_error("Only `+` operator is implemented"); + if (firstTokenOperator.operatorType != OperatorType::ADDITION && + firstTokenOperator.operatorType != OperatorType::SUBTRACTION) { + throw std::format_error("Only `+` and `-` operators are implemented"); } const Token& secondToken = static_cast(tokens[tokensIndex + 1].get()); - std::cout << secondToken.tokenType << "\n"; - if (secondToken.tokenType != TokenType::NUMBER && secondToken.tokenType != TokenType::IDENTIFIER) { throw std::runtime_error( "Token adjacent to operator must be an identifier or a value"); } - if (secondToken.tokenType == TokenType::NUMBER) { - statements.push_back(std::make_unique( - IdentifierValue(outputIdentifier), - std::make_unique(outputIdentifier), - std::make_unique( - (static_cast(secondToken)).value))); + switch (firstTokenOperator.operatorType) { + case OperatorType::ADDITION: { + if (secondToken.tokenType == TokenType::NUMBER) { + statements.push_back(std::make_unique( + IdentifierValue(outputIdentifier), + std::make_unique(outputIdentifier), + std::make_unique( + (static_cast(secondToken)).value))); + + std::cout << outputIdentifier << " + " + << (static_cast(secondToken)).value + << "\n"; + } - std::cout << outputIdentifier << " + " - << (static_cast(secondToken)).value << "\n"; - } + if (secondToken.tokenType == TokenType::IDENTIFIER) { + statements.push_back(std::make_unique( + IdentifierValue(outputIdentifier), + std::make_unique(outputIdentifier), + std::make_unique( + static_cast(secondToken).name))); + } + + break; + } - if (secondToken.tokenType == TokenType::IDENTIFIER) { - statements.push_back(std::make_unique( - IdentifierValue(outputIdentifier), - std::make_unique(outputIdentifier), - std::make_unique( - static_cast(secondToken).name))); + case OperatorType::SUBTRACTION: { + if (secondToken.tokenType == TokenType::NUMBER) { + statements.push_back(std::make_unique( + IdentifierValue(outputIdentifier), + std::make_unique(outputIdentifier), + std::make_unique( + (static_cast(secondToken)).value))); + } + + if (secondToken.tokenType == TokenType::IDENTIFIER) { + statements.push_back(std::make_unique( + IdentifierValue(outputIdentifier), + std::make_unique(outputIdentifier), + std::make_unique( + static_cast(secondToken).name))); + } + + break; + } } tokensIndex += 2; @@ -160,10 +186,8 @@ Program AbstractSyntaxTree::parse() { const Token& token = this->tokenContainer.view(i); buffer.push_back(token); - std::cout << "Reading " << token.tokenType << std::endl; if (token.tokenType == TokenType::END_OF_LINE) { - std::cout << "Reading end of line\n"; if (buffer[0].get().tokenType == TokenType::PRIMITIVE && buffer[1].get().tokenType == TokenType::IDENTIFIER && buffer[2].get().tokenType == TokenType::OPERATOR) { @@ -246,6 +270,5 @@ Program AbstractSyntaxTree::parse() { buffer.clear(); } } - std::cout << "program size: " << program.size() << "\n"; return program; } \ No newline at end of file From f1b77c9ab0958958d34777a7ca99c7087bb78f89 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:42:15 +0100 Subject: [PATCH 10/12] Create print subtraction method --- src/syntax_analyser/program/program.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/syntax_analyser/program/program.hpp b/src/syntax_analyser/program/program.hpp index 6291983..14edef0 100644 --- a/src/syntax_analyser/program/program.hpp +++ b/src/syntax_analyser/program/program.hpp @@ -9,6 +9,7 @@ #include "syntax_analyser/statement/print/print.hpp" #include "syntax_analyser/statement/return/return.hpp" #include "syntax_analyser/statement/statement.hpp" +#include "syntax_analyser/statement/subtraction/subtraction.hpp" #include "syntax_analyser/statement/value/identifier/identifier.hpp" #include "syntax_analyser/statement/value/number/number.hpp" #include "syntax_analyser/statement/value/value.hpp" @@ -109,6 +110,15 @@ class Program { << rhs << ";\n"; } + void printSubtractionStatement( + const SubtractionStatement& subtractionStatement) const { + std::string lhs = this->getStatementValueString(*subtractionStatement.lhs); + std::string rhs = this->getStatementValueString(*subtractionStatement.rhs); + + std::cout << subtractionStatement.identifier.name << " = " << lhs << " - " + << rhs << ";\n"; + } + void printPrintStatement(const PrintStatement& printStatement) const { std::string value = this->getStatementValueString(*printStatement.value); @@ -166,6 +176,16 @@ class Program { break; } + case StatementType::SUBTRACTION: { + + const SubtractionStatement& subtractionStatement = + static_cast(statement); + + this->printSubtractionStatement(subtractionStatement); + + break; + } + case StatementType::INITIALISATION: { const InitialisationStatement& initialisationStatement = static_cast(statement); From 32e8a51b60607c6c684c05abc26e9022e561047e Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:42:24 +0100 Subject: [PATCH 11/12] Create subtraction statement --- .../statement/subtraction/subtraction.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/syntax_analyser/statement/subtraction/subtraction.hpp diff --git a/src/syntax_analyser/statement/subtraction/subtraction.hpp b/src/syntax_analyser/statement/subtraction/subtraction.hpp new file mode 100644 index 0000000..b1a2341 --- /dev/null +++ b/src/syntax_analyser/statement/subtraction/subtraction.hpp @@ -0,0 +1,18 @@ +#pragma once +#include + +#include "syntax_analyser/statement/statement.hpp" +#include "syntax_analyser/statement/value/identifier/identifier.hpp" + +class SubtractionStatement : public Statement { +public: + const IdentifierValue identifier; + const std::unique_ptr lhs; + const std::unique_ptr rhs; + + SubtractionStatement(const IdentifierValue identifier, + std::unique_ptr lhs, + std::unique_ptr rhs) + : Statement(StatementType::SUBTRACTION), identifier(identifier), + lhs(std::move(lhs)), rhs(std::move(rhs)) {}; +}; \ No newline at end of file From 187e86356db4befc874fbbaa1ae3a9311626bbb7 Mon Sep 17 00:00:00 2001 From: Thomas <31802793+ThomasNotTom@users.noreply.github.com> Date: Tue, 4 Aug 2026 10:42:31 +0100 Subject: [PATCH 12/12] Create subtraction type --- src/syntax_analyser/statement/statement_type.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/syntax_analyser/statement/statement_type.hpp b/src/syntax_analyser/statement/statement_type.hpp index 3f8fce2..ec221fd 100644 --- a/src/syntax_analyser/statement/statement_type.hpp +++ b/src/syntax_analyser/statement/statement_type.hpp @@ -3,5 +3,6 @@ enum class StatementType { ASSIGNMENT = 2, RETURN = 3, ADDITION = 4, - PRINT = 5 + SUBTRACTION = 5, + PRINT = 6 }; \ No newline at end of file