bl-compiler

compiler for the bl programming language.
Log | Files | Refs | README

semantic_analyzer.cpp (5878B)


      1 #include "semantic_analyzer.hpp"
      2 
      3 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) {}
      4 
      5 bool SemanticAnalyzer::analyze(ASTNode* ast) {
      6     symbol_table.enterScope("global")
      7     visit(ast);
      8     validateMainFunction();
      9 
     10     if (has_main_function == false) {
     11         //error
     12         return false;
     13     }
     14 
     15     symbol_table.exitScope();
     16     return true;
     17 }
     18 
     19 std::vector<Error> SemanticAnalyzer::getErrors() {
     20     return errors;
     21 }
     22 
     23 std::vector<Error> SemanticAnalyzer::getWarnings() {
     24     return warnings;
     25 }
     26 
     27 bool SemanticAnalyzer::hasErrors() {
     28     return !errors.empty();
     29 }
     30 
     31 std::string SemanticAnalyzer::visit(ASTNode* node) {
     32     if (ProgramNode* prog = dynamic_cast<ProgramNode*>(node)) {
     33         return visitProgram(prog);
     34     }
     35 
     36     else if (FunctionDeclNode* func = dynamic_cast<FunctionDeclNode*>(node)) {
     37         return visitFunctionDecl(func);
     38     }
     39 
     40     else if (ParameterNode* param = dynamic_cast<ParameterNode*>(node)) {
     41         return visitParameter(param);
     42     }
     43 
     44     else if (VarDeclNode* var = dynamic_cast<VarDeclNode*>(node)) {
     45         return visitVarDeclaration(var);
     46     }
     47 
     48     else if (AssignmentNode as = dynamic_cast<AssignmentNode>(node)) {
     49         return visitAssignment(as);
     50     }
     51 
     52     else if (IfStatementNode is = dynamic_cast<IfStatementNode>(node)) {
     53         return visitIfStatement(is);
     54     }
     55 
     56     else if (WhileStatementNode ws = dynamic_cast<WhileStatementNode>(node)) {
     57         return visitWhileStatement(ws);
     58     }
     59 
     60     else if (ForStatementNode fs = dynamic_cast<ForStatementNode>(node)) {
     61         return visitForStatement(fs);
     62     }
     63 
     64     else if (ReturnStatementNode rs = dynamic_cast<ReturnStatementNode>(node)) {
     65         return visitReturnStatement(rs);
     66     }
     67 
     68     else if (ExpressionStatementNode es = dynamic_cast<ExpressionStatementNode>(node)) {
     69         return visitExpressionStatement(es);
     70     }
     71 
     72     else if (BinaryExprNode bin = dynamic_cast<BinaryExprNode>(node)) {
     73         return visitBinaryExpression(bin);
     74     }
     75 
     76     else if (UnaryExprNode un = dynamic_cast<UnaryExprNode>(node)) {
     77         return visitUnaryExpression(un);
     78     }
     79 
     80     else if (FunctionCallNode func_call = dynamic_cast<FunctionCallNode>(node)) {
     81         return visitFunctionCall(func_call);
     82     }
     83 
     84     else if (IdentifierNode ident = dynamic_cast<IdentifierNode>(node)) {
     85         return visitIdentifier(ident);
     86     }
     87 
     88     else if (LiteralNode lit = dynamic_cast<LiteralNode>(node)) {
     89         return visitLiteral(lit);
     90     }
     91 }
     92 
     93 std::string visitProgram(ProgramNode* node){
     94     // get list of functions
     95     // visit each function
     96     // return
     97 
     98 }
     99 
    100 std::string visitFunctionDecl(FunctionDeclNode* node){
    101     // check for dupe name
    102     // create function symbol and insert into global scope
    103     // check if main function
    104     // enter function scope
    105     // process parameters
    106     // process function body
    107     // verify non-void functions have return statements
    108     // exit function scope and clear context
    109     // return
    110 
    111 }
    112 
    113 std::string visitParameter(ParameterNode*){
    114     // get parameter info from node
    115     // check for dupes
    116     // create parameter symbol
    117     // insert into current scope
    118     // return parameter type
    119 
    120 }
    121 
    122 std::string visitVarDeclaration(VarDeclNode* node){
    123     // get variable information
    124     // check for dupes
    125     // if initializer exists, check type
    126     // create variable symbol
    127     // insert into current scope
    128     // return
    129 
    130 }
    131 
    132 std::string visitAssignment(AssignmentNode* node){
    133     // get left side info
    134     // look up target variable
    135     // verify variable
    136     // analyze right side info
    137     // check type compatability
    138     // make var as initialized
    139     // return
    140 
    141 }
    142 
    143 std::string visitIfStatement(IfStatementNode* node){
    144     // analyze condition
    145     // verify condition is bool
    146     // analyze then branch
    147     // analyze else branch
    148     // return
    149 
    150 }
    151 
    152 std::string visitWhileStatement(WhileStatementNode* node){
    153     // analyze condition
    154     // verify condition is bool
    155     // analyze loop body
    156     // return
    157 
    158 }
    159 
    160 std::string visitForStatement(ForStatementNode* node){
    161     // enter new scope for loop
    162     // analyze initialization
    163     // analyze condition
    164     // analyze update statement
    165     // analyze loop body
    166     // exit for loop scope
    167     // return 
    168 
    169 }
    170 
    171 std::string visitReturnStatement(ReturnStatementNode* node){
    172     // check if inside function
    173     // get return expression
    174     // analyze return expression
    175     // validate return type matches function
    176     // return
    177     
    178 }
    179 
    180 std::String visitExpressionStatement(ExpressionStatementNode* node){
    181     // get the expression
    182     // analyze expression
    183     // return
    184 
    185 }
    186 
    187 std::string visitBinaryExpression(BinaryExprNode* node){
    188     // get operator and operands
    189     // analyze operands
    190     // infer result type based on operator
    191     // return result type
    192 
    193 }
    194 
    195 std::string visitUnaryExpression(UnaryExprNode* node){
    196     // get operator and operand
    197     // analyze operand
    198     // infer result type
    199     // return result type
    200 
    201 }
    202 
    203 std::string visitFunctionCall(FunctionCallNode* node){
    204     // get function name and args
    205     // look up function
    206     // verify its a function
    207     // get expected parameter information
    208     // check argument count
    209     // check each argument type
    210     // return functions return type
    211 
    212 }
    213 
    214 std::string visitIdentifier(IdentifierNode* node){
    215     // get identifier name
    216     // look up in symbol table
    217     // check if initialized
    218     // return symbol type
    219     
    220 }
    221 
    222 std::string visitLiteral(LiteralNode* node){
    223     // determine literal type
    224     // return appropriate type
    225 
    226 }
    227 
    228 bool checkTypeCompatibility(std::string target, std::string source){
    229     // determines if a value of source type can be used where target type is expected
    230 
    231 }
    232 
    233 std::string inferBinaryOpType(std::string op, std::string left, std::string right){
    234 
    235 }