aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCori Barker <coribarker2@gmail.com>2026-02-22 22:24:27 +0000
committerCori Barker <coribarker2@gmail.com>2026-02-22 22:24:27 +0000
commit5c1f937a7eb7a9cc9cd86cb69b3263f41f24408f (patch)
tree46154166a56f9a074c5b75dbb1a1b9560908b8f1
parent2cfc45ff22cd9b6166de3cf963aceede21b358aa (diff)
Partially completed lots of changes, refactoring most of the files
-rw-r--r--include/ast_node.hpp36
-rw-r--r--include/lexer.hpp (renamed from include/lexer/lexer.hpp)5
-rw-r--r--include/parser.hpp (renamed from include/parser/parser.hpp)5
-rw-r--r--include/parser/ast_node.hpp70
-rw-r--r--include/parser/node_type.hpp10
-rw-r--r--include/scope.hpp (renamed from include/semantic/scope.hpp)0
-rw-r--r--include/semantic_analyzer.hpp (renamed from include/semantic/semantic_analyzer.hpp)0
-rw-r--r--include/symbol.hpp (renamed from include/semantic/symbol.hpp)0
-rw-r--r--include/symbol_table.hpp (renamed from include/semantic/symbol_table.hpp)0
-rw-r--r--include/symbol_type.hpp (renamed from include/semantic/symbol_type.hpp)0
-rw-r--r--include/token.hpp (renamed from include/lexer/token.hpp)5
-rw-r--r--include/token_type.hpp (renamed from include/lexer/token_type.hpp)5
-rw-r--r--include/type.hpp11
-rw-r--r--src/lexer.cpp (renamed from src/lexer/lexer.cpp)2
-rw-r--r--src/main.cpp4
-rw-r--r--src/parser.cpp (renamed from src/parser/parser.cpp)2
-rw-r--r--src/scope.cpp (renamed from src/semantic/scope.cpp)2
-rw-r--r--src/semantic/semantic_analyzer.cpp33
-rw-r--r--src/semantic_analyzer.cpp235
-rw-r--r--src/symbol.cpp (renamed from src/semantic/symbol.cpp)2
-rw-r--r--src/symbol_table.cpp (renamed from src/semantic/symbol_table.cpp)2
21 files changed, 293 insertions, 136 deletions
diff --git a/include/ast_node.hpp b/include/ast_node.hpp
new file mode 100644
index 0000000..caffb35
--- /dev/null
+++ b/include/ast_node.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "node_type.hpp"
+#include "type.hpp"
+
+#include <string>
+#include <vector>
+#include <memory>
+
+class ASTNode {
+public:
+ int line;
+ int column;
+
+ virtual ~ASTNode() = default;
+};
+
+class ProgramNode : ASTNode {
+public:
+ std::vector<ASTNode> function_declarations;
+
+ explicit ProgramNode(std::vector<ASTNode> f) : function_declarations(f) { }
+};
+
+class FunctionDeclNode : ASTNode {
+ Type type;
+ std::vector<ParameterNode> parameters;
+ std::vector<ASTNode> body;
+
+ FunctionDeclNode(std::string t,std::vector<ASTNode> p, std::vector<ASTNode> b) : type(t), parameters(p), body(b) { }
+};
+
+class ParameterNode : ASTNode {
+ std::string name;
+ std::string type;
+};
diff --git a/include/lexer/lexer.hpp b/include/lexer.hpp
index 2c165b6..2ef9700 100644
--- a/include/lexer/lexer.hpp
+++ b/include/lexer.hpp
@@ -1,5 +1,4 @@
-#ifndef LEXER_H
-#define LEXER_H
+#pragma once
#include "token.hpp"
@@ -23,5 +22,3 @@ private:
void skipWhitespace();
void skipComment();
};
-
-#endif
diff --git a/include/parser/parser.hpp b/include/parser.hpp
index 438b8fe..f986ce2 100644
--- a/include/parser/parser.hpp
+++ b/include/parser.hpp
@@ -1,5 +1,4 @@
-#ifndef PARSER_H
-#define PARSER_H
+#pragma once
#include "lexer/token.hpp"
#include "parser/ast_node.hpp"
@@ -27,5 +26,3 @@ private:
bool isAtEnd();
void error(std::string s);
};
-
-#endif
diff --git a/include/parser/ast_node.hpp b/include/parser/ast_node.hpp
deleted file mode 100644
index 6539cf6..0000000
--- a/include/parser/ast_node.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef AST_NODE_H
-#define AST_NODE_H
-
-#include "node_type.hpp"
-
-#include <string>
-#include <vector>
-#include <memory>
-
-class ASTNode {
-public:
- int line;
- int column;
-
- virtual ~ASTNode() = default;
-};
-
-class Program : public ASTNode {
-public:
- std::vector<std::unique_ptr<ASTNode>> declarations;
-};
-
-class Declaration : public ASTNode {
-public:
- std::string type;
- std::string var_name;
- std::unique_ptr<ASTNode> value;
-
- Declaration(std::string type, std::string var_name, std::unique_ptr<ASTNode> value = nullptr) : type(type), var_name(var_name), value(std::move(value)) {}
-};
-
-class Assignment : public ASTNode {
-public:
- std::string variable_name;
- std::unique_ptr<ASTNode> value;
-
- Assignment(std::string var, std::unique_ptr<ASTNode> val) : variable_name(var), value(std::move(val)) {}
-};
-
-class NumberLiteral : public ASTNode {
-public:
- double value;
-
- NumberLiteral(double val) : value(val) {}
-};
-
-class StringLiteral : public ASTNode {
-public:
- std::string value;
-
- StringLiteral(std::string val) : value(val) {}
-};
-
-class Identifier : public ASTNode {
-public:
- std::string name;
-
- Identifier(std::string name) : name(name) {}
-};
-
-class BinaryOp : public ASTNode {
-public:
- std::unique_ptr<ASTNode> left;
- std::string value;
- std::unique_ptr<ASTNode> right;
-
- BinaryOp(std::unique_ptr<ASTNode> left, std::string value, std::unique_ptr<ASTNode> right) : left(std::move(left)), value(std::move(value)), right(std::move(right)) {}
-};
-
-#endif
diff --git a/include/parser/node_type.hpp b/include/parser/node_type.hpp
deleted file mode 100644
index 1766b19..0000000
--- a/include/parser/node_type.hpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef NODE_TYPE_H
-#define NODE_TYPE_H
-
-enum class NodeType {
- PROGRAM,
- VARIABLE_DECLARATION,
- ASSIGNMENT,
-};
-
-#endif
diff --git a/include/semantic/scope.hpp b/include/scope.hpp
index ff20542..ff20542 100644
--- a/include/semantic/scope.hpp
+++ b/include/scope.hpp
diff --git a/include/semantic/semantic_analyzer.hpp b/include/semantic_analyzer.hpp
index 0d56599..0d56599 100644
--- a/include/semantic/semantic_analyzer.hpp
+++ b/include/semantic_analyzer.hpp
diff --git a/include/semantic/symbol.hpp b/include/symbol.hpp
index 4bee45d..4bee45d 100644
--- a/include/semantic/symbol.hpp
+++ b/include/symbol.hpp
diff --git a/include/semantic/symbol_table.hpp b/include/symbol_table.hpp
index b2b8270..b2b8270 100644
--- a/include/semantic/symbol_table.hpp
+++ b/include/symbol_table.hpp
diff --git a/include/semantic/symbol_type.hpp b/include/symbol_type.hpp
index a792c09..a792c09 100644
--- a/include/semantic/symbol_type.hpp
+++ b/include/symbol_type.hpp
diff --git a/include/lexer/token.hpp b/include/token.hpp
index 86a41f6..d85ba94 100644
--- a/include/lexer/token.hpp
+++ b/include/token.hpp
@@ -1,5 +1,4 @@
-#ifndef TOKEN_H
-#define TOKEN_H
+#pragma once
#include "token_type.hpp"
@@ -13,5 +12,3 @@ struct Token {
Token(TokenType t, const std::string& val, int line, int col) : type{t}, value{val}, line{line}, column{col} {};
};
-
-#endif
diff --git a/include/lexer/token_type.hpp b/include/token_type.hpp
index f83c6d6..d123aaa 100644
--- a/include/lexer/token_type.hpp
+++ b/include/token_type.hpp
@@ -1,5 +1,4 @@
-#ifndef TOKEN_TYPE_H
-#define TOKEN_TYPE_H
+#pragma once
enum class TokenType {
INT,
@@ -21,5 +20,3 @@ enum class TokenType {
INVALID
};
-
-#endif
diff --git a/include/type.hpp b/include/type.hpp
new file mode 100644
index 0000000..c46ff34
--- /dev/null
+++ b/include/type.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+enum struct Type {
+ INT,
+ CHAR,
+ BOOL,
+ STRING,
+ FLOAT,
+ DOUBLE,
+ VOID,
+};
diff --git a/src/lexer/lexer.cpp b/src/lexer.cpp
index 70af4b5..3b134eb 100644
--- a/src/lexer/lexer.cpp
+++ b/src/lexer.cpp
@@ -1,4 +1,4 @@
-#include "lexer/lexer.hpp"
+#include "lexer.hpp"
Lexer::Lexer(const std::string& src) : src(src), position(0), line(1), column(1) {}
diff --git a/src/main.cpp b/src/main.cpp
index 9a11516..24a748d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2,8 +2,8 @@
#include <sstream>
#include <fstream>
-#include "lexer/lexer.hpp"
-#include "parser/parser.hpp"
+#include "lexer.hpp"
+#include "parser.hpp"
std::string tokenTypeToString(TokenType type) {
switch (type) {
diff --git a/src/parser/parser.cpp b/src/parser.cpp
index 97a1f27..6f47890 100644
--- a/src/parser/parser.cpp
+++ b/src/parser.cpp
@@ -1,6 +1,6 @@
#include <iostream>
-#include "parser/parser.hpp"
+#include "parser.hpp"
Parser::Parser(const std::vector<Token>& tokens) : tokens_(tokens), position_(0) {}
diff --git a/src/semantic/scope.cpp b/src/scope.cpp
index ba5aa41..86e2668 100644
--- a/src/semantic/scope.cpp
+++ b/src/scope.cpp
@@ -1,4 +1,4 @@
-#include "semantic/scope.hpp"
+#include "scope.hpp"
Scope::Scope(std::string name, int level, std::unique_ptr<Scope> parent) : scope_name(name), scope_level(level), parent_scope(parent) {}
diff --git a/src/semantic/semantic_analyzer.cpp b/src/semantic/semantic_analyzer.cpp
deleted file mode 100644
index 57f217e..0000000
--- a/src/semantic/semantic_analyzer.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "semantic/semantic_analyzer.hpp"
-
-SemanticAnalyzer::SemanticAnalyzer() : symobl_table(new SemanticTable), errors(std::vector<Error>), warnings(std::vector<Error>), current_function(nullptr), current_function_return_type(""), has_main_function(false) {}
-
-bool SemanticAnalyzer::analyze(ASTNode* ast) {
- this->symbol_table.enterScope("global")
- this->visit(ast);
- this->validateMainFunction();
-
- if (has_main_function == false) {
- //error
- return false;
- }
-
- this->symbol_table.exitScope();
- return true;
-}
-
-std::vector<Error> SemanticAnalyzer::getErrors() {
- return this->errors;
-}
-
-std::vector<Error> SemanticAnalyzer::getWarnings() {
- return this->warnings;
-}
-
-bool SemanticAnalyzer::hasErrors() {
- return !this->errors.empty();
-}
-
-std::string SemanticAnalyzer::visit(ASTNode* ast) {
-
-}
diff --git a/src/semantic_analyzer.cpp b/src/semantic_analyzer.cpp
new file mode 100644
index 0000000..e097e4f
--- /dev/null
+++ b/src/semantic_analyzer.cpp
@@ -0,0 +1,235 @@
+#include "semantic_analyzer.hpp"
+
+SemanticAnalyzer::SemanticAnalyzer() : symobl_table(new SemanticTable), errors(std::vector<Error>), warnings(std::vector<Error>), current_function(nullptr), current_function_return_type(""), has_main_function(false) {}
+
+bool SemanticAnalyzer::analyze(ASTNode* ast) {
+ symbol_table.enterScope("global")
+ visit(ast);
+ validateMainFunction();
+
+ if (has_main_function == false) {
+ //error
+ return false;
+ }
+
+ symbol_table.exitScope();
+ return true;
+}
+
+std::vector<Error> SemanticAnalyzer::getErrors() {
+ return errors;
+}
+
+std::vector<Error> SemanticAnalyzer::getWarnings() {
+ return warnings;
+}
+
+bool SemanticAnalyzer::hasErrors() {
+ return !errors.empty();
+}
+
+std::string SemanticAnalyzer::visit(ASTNode* node) {
+ if (ProgramNode* prog = dynamic_cast<ProgramNode*>(node)) {
+ return visitProgram(prog);
+ }
+
+ else if (FunctionDeclNode* func = dynamic_cast<FunctionDeclNode*>(node)) {
+ return visitFunctionDecl(func);
+ }
+
+ else if (ParameterNode* param = dynamic_cast<ParameterNode*>(node)) {
+ return visitParameter(param);
+ }
+
+ else if (VarDeclNode* var = dynamic_cast<VarDeclNode*>(node)) {
+ return visitVarDeclaration(var);
+ }
+
+ else if (AssignmentNode as = dynamic_cast<AssignmentNode>(node)) {
+ return visitAssignment(as);
+ }
+
+ else if (IfStatementNode is = dynamic_cast<IfStatementNode>(node)) {
+ return visitIfStatement(is);
+ }
+
+ else if (WhileStatementNode ws = dynamic_cast<WhileStatementNode>(node)) {
+ return visitWhileStatement(ws);
+ }
+
+ else if (ForStatementNode fs = dynamic_cast<ForStatementNode>(node)) {
+ return visitForStatement(fs);
+ }
+
+ else if (ReturnStatementNode rs = dynamic_cast<ReturnStatementNode>(node)) {
+ return visitReturnStatement(rs);
+ }
+
+ else if (ExpressionStatementNode es = dynamic_cast<ExpressionStatementNode>(node)) {
+ return visitExpressionStatement(es);
+ }
+
+ else if (BinaryExprNode bin = dynamic_cast<BinaryExprNode>(node)) {
+ return visitBinaryExpression(bin);
+ }
+
+ else if (UnaryExprNode un = dynamic_cast<UnaryExprNode>(node)) {
+ return visitUnaryExpression(un);
+ }
+
+ else if (FunctionCallNode func_call = dynamic_cast<FunctionCallNode>(node)) {
+ return visitFunctionCall(func_call);
+ }
+
+ else if (IdentifierNode ident = dynamic_cast<IdentifierNode>(node)) {
+ return visitIdentifier(ident);
+ }
+
+ else if (LiteralNode lit = dynamic_cast<LiteralNode>(node)) {
+ return visitLiteral(lit);
+ }
+}
+
+std::string visitProgram(ProgramNode* node){
+ // get list of functions
+ // visit each function
+ // return
+
+}
+
+std::string visitFunctionDecl(FunctionDeclNode* node){
+ // check for dupe name
+ // create function symbol and insert into global scope
+ // check if main function
+ // enter function scope
+ // process parameters
+ // process function body
+ // verify non-void functions have return statements
+ // exit function scope and clear context
+ // return
+
+}
+
+std::string visitParameter(ParameterNode*){
+ // get parameter info from node
+ // check for dupes
+ // create parameter symbol
+ // insert into current scope
+ // return parameter type
+
+}
+
+std::string visitVarDeclaration(VarDeclNode* node){
+ // get variable information
+ // check for dupes
+ // if initializer exists, check type
+ // create variable symbol
+ // insert into current scope
+ // return
+
+}
+
+std::string visitAssignment(AssignmentNode* node){
+ // get left side info
+ // look up target variable
+ // verify variable
+ // analyze right side info
+ // check type compatability
+ // make var as initialized
+ // return
+
+}
+
+std::string visitIfStatement(IfStatementNode* node){
+ // analyze condition
+ // verify condition is bool
+ // analyze then branch
+ // analyze else branch
+ // return
+
+}
+
+std::string visitWhileStatement(WhileStatementNode* node){
+ // analyze condition
+ // verify condition is bool
+ // analyze loop body
+ // return
+
+}
+
+std::string visitForStatement(ForStatementNode* node){
+ // enter new scope for loop
+ // analyze initialization
+ // analyze condition
+ // analyze update statement
+ // analyze loop body
+ // exit for loop scope
+ // return
+
+}
+
+std::string visitReturnStatement(ReturnStatementNode* node){
+ // check if inside function
+ // get return expression
+ // analyze return expression
+ // validate return type matches function
+ // return
+
+}
+
+std::String visitExpressionStatement(ExpressionStatementNode* node){
+ // get the expression
+ // analyze expression
+ // return
+
+}
+
+std::string visitBinaryExpression(BinaryExprNode* node){
+ // get operator and operands
+ // analyze operands
+ // infer result type based on operator
+ // return result type
+
+}
+
+std::string visitUnaryExpression(UnaryExprNode* node){
+ // get operator and operand
+ // analyze operand
+ // infer result type
+ // return result type
+
+}
+
+std::string visitFunctionCall(FunctionCallNode* node){
+ // get function name and args
+ // look up function
+ // verify its a function
+ // get expected parameter information
+ // check argument count
+ // check each argument type
+ // return functions return type
+
+}
+
+std::string visitIdentifier(IdentifierNode* node){
+ // get identifier name
+ // look up in symbol table
+ // check if initialized
+ // return symbol type
+
+}
+
+std::string visitLiteral(LiteralNode* node){
+ // determine literal type
+ // return appropriate type
+
+}
+
+bool checkTypeCompatibility(std::string target, std::string source){
+ // determines if a value of source type can be used where target type is expected
+
+}
+
+std::string inferBinaryOpType(std::string op, std::string left, std::string right){
+
+}
diff --git a/src/semantic/symbol.cpp b/src/symbol.cpp
index 5142ea8..ad2041d 100644
--- a/src/semantic/symbol.cpp
+++ b/src/symbol.cpp
@@ -1,4 +1,4 @@
-#include "semantic/symbol.hpp"
+#include "symbol.hpp"
Symbol::Symbol(std::string name, SymbolType type, std::string data_type, int scope) : symbol_name(name), symbol_type(type), data_type(data_type), scope_level(scope_level) {}
diff --git a/src/semantic/symbol_table.cpp b/src/symbol_table.cpp
index 548d6ee..81ff474 100644
--- a/src/semantic/symbol_table.cpp
+++ b/src/symbol_table.cpp
@@ -1,4 +1,4 @@
-#include "semantic/symbol_table.hpp"
+#include "symbol_table.hpp"
#include <iostream>