Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,14 @@ struct ReturnStmt : Stmt {
Expr* value;
explicit ReturnStmt(Expr* v) : value(v) {}
~ReturnStmt() { delete value; }
void print(std::ostream& os, int indent) const override { doIndent(os, indent); os << "return\n"; value->print(os, indent + 1); }
void print(std::ostream& os, int indent) const override {
doIndent(os, indent);
os << "return\n";
if (value) value->print(os, indent + 1);
}
};


struct IfStmt : Stmt {
Expr* cond; Stmt* thenS; Stmt* elseS;
IfStmt(Expr* c, Stmt* t, Stmt* e) : cond(c), thenS(t), elseS(e) {}
Expand Down
7 changes: 5 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ int main(int argc, char** argv) {
return 2;
}

std::cout << "\n=== Semantic Analysis ===\n";
std::cout << "\n=== ORIGINAL AST ===\n";
g_program->print(std::cout);

std::cout << "\n=== SEMANTIC ANALYSIS ===\n";
SemanticAnalyzer analyzer;
SemanticResult res = analyzer.analyze(g_program);

Expand Down Expand Up @@ -82,7 +85,7 @@ int main(int argc, char** argv) {
std::cout << "\n=== Final AST (After Semantic Analysis) ===\n";
g_program->print(std::cout);

std::cout << "\n=== Interpretation ===\n";
std::cout << "\n=== INTERPRETATION ===\n";
Interpreter interp(g_program);
interp.run();

Expand Down
Binary file modified mycompiler
Binary file not shown.
308 changes: 157 additions & 151 deletions parser.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ stmt

simple_stmt
: RETURN expr { $$ = new AST::ReturnStmt($2); }
| RETURN { $$ = new AST::ReturnStmt(nullptr); }
| VAR IDENTIFIER COLON type_spec { $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, nullptr)); free($2); free($4); }
| VAR IDENTIFIER COLON type_spec EQUAL expr { $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, $6)); free($2); free($4); }
| VAR IDENTIFIER COLON type_spec ASSIGN expr { $$ = new AST::VarDeclStmt(new AST::VarDecl($2, $4, $6)); free($2); free($4); }
Expand Down
20 changes: 15 additions & 5 deletions semantic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,16 +217,26 @@ void SemanticAnalyzer::analyzeStmt(AST::Stmt*& s) {
if (!curMethod) {
result.addError("Return used outside of method");
} else {
analyzeExpr(ret->value);
auto rv = typeOfExpr(ret->value);
if (!curMethod->returnType.empty()) {
if (rv != "" && curMethod->returnType != rv) {
result.addError("Return type mismatch in method '" + curMethod->name + "': expected " + curMethod->returnType + ", got " + rv);
if (curMethod->returnType == "Void") {
if (ret->value) {
analyzeExpr(ret->value);
result.addError("Void method '" + curMethod->name + "' must not return a value");
}
} else {
if (!ret->value) {
result.addError("Non-void method '" + curMethod->name + "' must return a value of type '" + curMethod->returnType + "'");
} else {
analyzeExpr(ret->value);
auto rv = typeOfExpr(ret->value);
if (rv != "" && curMethod->returnType != rv) {
result.addError("Return type mismatch in method '" + curMethod->name + "': expected " + curMethod->returnType + ", got " + rv);
}
}
}
}
return;
}

if (auto* es = dynamic_cast<AST::ExprStmt*>(s)) {
analyzeExpr(es->expr);
return;
Expand Down
7 changes: 7 additions & 0 deletions tests/test6.o
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Main is
method main() : Void =>
output("before");
return;
output("after");
output("after2")
end
Loading