aboutsummaryrefslogtreecommitdiff
path: root/src/semantic_analyzer.cpp
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 /src/semantic_analyzer.cpp
parent2cfc45ff22cd9b6166de3cf963aceede21b358aa (diff)
Partially completed lots of changes, refactoring most of the files
Diffstat (limited to 'src/semantic_analyzer.cpp')
-rw-r--r--src/semantic_analyzer.cpp235
1 files changed, 235 insertions, 0 deletions
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){
+
+}