From 6efcb23d6b97aa1440dd405e731ccbde4d83f1cc Mon Sep 17 00:00:00 2001 From: Sofia Date: Tue, 14 Apr 2026 18:48:17 +0300 Subject: [PATCH] Add get_codegen_type --- a.out | Bin 0 -> 16040 bytes src/ast.h | 10 ++++++ src/codegen.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ test.c | 7 ++-- 4 files changed, 100 insertions(+), 4 deletions(-) create mode 100755 a.out diff --git a/a.out b/a.out new file mode 100755 index 0000000000000000000000000000000000000000..0abd102242ccff8d29c31e152e897daeb1f786ea GIT binary patch literal 16040 zcmeHOU2GKB6~4P*FbUx0uQAYufkI>|v8;`8fQYijtQn^^IAE$KDxIu%$M!1wW9^Pp zLxbvyCavQl(L6+I)rU%bL47HT^3Y0EyOb1YX(Xq8L9LovZ6g__Nr*x#rzLE^bLX7# zc(BtdQmZ`7k#^5L-}$*`&fJ;3vvcoPQ{A1>NJI%OQlC{M^~PKz$%>|jxdE0`d(=vN zKd3&XmOx&tF;|~-8MH3N7R}}Lj1x?L4(o&blWZqkG9*rZ3(=F55J8}Qm`E4 zJyB9BC0z7ge}+~o72rc;021!^qf{n$XtkQ$KbQA%e_voOek79L6#GrFpU1hsDdtj7 zstJ91xt>A36*?l}WJ^SxK24iRx|bUoojvSee&|?3M?O~^8Qn3ur)@`DYrIm5x9Dq+VoAIY&vsV38cq5H$p&Bq zLC6$;KKoq@;9mo7;1i_t0E{3Ac`H6!=E0R^Rh)F@DJwJdlr@mfQG zKr*9gYamxl=X0lRHC)aWodHEwRHHU^xV!6Mht(2qiSPE>tzK(atFpTKdaSHnwg+<+ z$1eBvbmU7#yD#0Jw-J1>P%3hFmTNk%p;B~;7wI!Pd(Vjg*#}(4$;gJ>GSVJmY;7*L zg1mZJe)-!kV)#YX6Of7IJ|Ndoa+QnU;OkuQTiiio($xzta`k|V)7YkSDRj+;^AOdl zNguB7gY0m_hx@OSDIdO6f)h`=0%3fs(LlWqmut_p48Ow)gcS%Y5LO_pKv;pW0$~L{ zP8E2s;lY2JXa81jPSjo6sg(I_)rr<7&9kr6U)E{XcK;f1ZQF0~-LNT%7Rf`TyE#<@ zZTkhuGzGmm36bJ8ztuJV+Lz4nKbvR&daJiD)m&}U^U~V~%u6$i%*Yk< zwY$z*1o$BC2B@!14K!@R;HyS39fcPNZh8s0vh?y!vr}$*eiCcw3V` zl+?`C)GKJIhFIOcm0+tsM`}@78K%K=(b?p8=osufU*v`4XLt`~Hub zblmh_H#(-Oi_xZMdm?I+o@CM!5k{Yo!U}{H2rCd)Agn-Gfv^H$1;Pr16$mTvzo>w$ zCzSPr@_a&T7KxU-%v->S#fqAeycl#n%d$>!Bg=S{(zJoOtXHJxFCx+Z{cf#9@_Aky zC~FOe`9Vn57+z#Oy^JLKq07|$%o~}nV=heA98UB4L|NmgpAlgs&zZ7j@d0*BaL0lV zb7GQrmF=*YQdwYFX-x$4o76VEy|nOWqv*|ITFnc(CI( ze!lHwE_zvKdbp!wpV5RT+U-X3ZmhU%Hd+!bZHbn|UX{tGi-X3~cDa%(6^)kWcyoM@ zxZlI6K8w}6^vZY+QN1Hri7e~K4c4v!pU-|1@F+&{SRmicj9(1k^dAD*%k=jsC6oMUMID0gOc^}66!D7{sAS|jo|O2G2c4yPoN-%82R`!8gEpwqz^>11$ay~ zdi50TUf`>vE0o+{1V2Ey2tNMA0(e2=%hmUJy)-j*8aVYE%;y`x4PRVoz6g9(v{A|U z7W@Z2iv=?qn(|{Q+-xn`@!xMJc8Q|lCquPKW!YavuP)- z^wA*7++7S_kXGKV-~qHrAv1(Kr47$=#epluaW^19n7bRn%2rAith2OJq3bBDvbmx) zQn9nj`%_k-idlH}S1KHZcTHfQgOr6fK+LP*%a@f6+%c?lGX4vInrO}~uWk|)dr;3Q+a;NNS_(x)nU_n>5^J#M6)^OgT zh&g;a_9(t-B*gB*;s@#y$M$hR& zE`zj6=nP+Roq^jM%B$iS+y#tTxtcyYr+F03J#aZ{T4;Y3tMB>W80*j!E^*I)q5X2= zPquz)gYXZ`MWlb3p9z&2n!Tv8m>GvNpTx;P~SM2HekHXpSFZ0blmw(-PlhvLlE0C3 zH3s_!?Wr$6t>FII+*65v5Ep+xm$C0TqtVNb7dSEc9axQz get_codegen_type(codegen::Scope& scope) = 0; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, @@ -55,6 +56,7 @@ namespace AST { virtual ~IntLiteralExpression() override = default; virtual std::string formatted() override; virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + virtual std::shared_ptr get_codegen_type(codegen::Scope& scope) override; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, @@ -71,6 +73,7 @@ namespace AST { virtual ~StringLiteralExpression() override = default; virtual std::string formatted() override; virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + virtual std::shared_ptr get_codegen_type(codegen::Scope& scope) override; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, @@ -87,6 +90,7 @@ namespace AST { virtual ~ValueReferenceExpression() override = default; virtual std::string formatted() override; virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + virtual std::shared_ptr get_codegen_type(codegen::Scope& scope) override; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, @@ -114,6 +118,7 @@ namespace AST { virtual ~BinaryOperationExpression() override = default; virtual std::string formatted() override; virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + virtual std::shared_ptr get_codegen_type(codegen::Scope& scope) override; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, @@ -138,6 +143,7 @@ namespace AST { virtual ~FunctionCallExpression() override = default; virtual std::string formatted() override; virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + virtual std::shared_ptr get_codegen_type(codegen::Scope& scope) override; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, @@ -162,6 +168,7 @@ namespace AST { virtual ~CastExpression() override = default; virtual std::string formatted() override; virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + virtual std::shared_ptr get_codegen_type(codegen::Scope& scope) override; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, @@ -183,6 +190,7 @@ namespace AST { virtual ~RefExpression() override = default; virtual std::string formatted() override; virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + virtual std::shared_ptr get_codegen_type(codegen::Scope& scope) override; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, @@ -204,6 +212,7 @@ namespace AST { virtual ~DerefExpression() override = default; virtual std::string formatted() override; virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + virtual std::shared_ptr get_codegen_type(codegen::Scope& scope) override; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, @@ -228,6 +237,7 @@ namespace AST { virtual ~IndexAccessExpression() override = default; virtual std::string formatted() override; virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + virtual std::shared_ptr get_codegen_type(codegen::Scope& scope) override; virtual std::shared_ptr typecheck( typecheck::State& state, typecheck::Scope& scope, diff --git a/src/codegen.cpp b/src/codegen.cpp index d19a566..5d11dea 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -16,6 +16,10 @@ namespace codegen { } namespace AST { + std::shared_ptr IntLiteralExpression::get_codegen_type(codegen::Scope&) { + return this->m_ty; + } + codegen::StackValue IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope&) { auto ty = this->m_ty->codegen(builder); @@ -25,6 +29,14 @@ namespace AST { }; } + std::shared_ptr StringLiteralExpression::get_codegen_type(codegen::Scope&) { + auto stack_type = new types::ArrayType{ + std::make_unique(types::FundamentalTypeKind::Char), + static_cast(this->m_value.size()) + 1 + }; + return std::shared_ptr {stack_type}; + } + codegen::StackValue StringLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope&) { auto stack_type = new types::ArrayType{ std::make_unique(types::FundamentalTypeKind::Char), @@ -40,6 +52,16 @@ namespace AST { }; } + std::shared_ptr ValueReferenceExpression::get_codegen_type(codegen::Scope& scope) { + auto value = scope.values.find(this->m_name); + if (value != scope.values.end()) { + return value->second.ty; + } + else { + throw CompileError("Value " + this->m_name + " not found", this->m_meta); + } + } + codegen::StackValue ValueReferenceExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { auto value = scope.values.find(this->m_name); if (value != scope.values.end()) { @@ -59,6 +81,30 @@ namespace AST { } } + std::shared_ptr BinaryOperationExpression::get_codegen_type(codegen::Scope& scope) { + auto lhs = this->m_lhs->get_codegen_type(scope); + auto rhs = this->m_rhs->get_codegen_type(scope); + try { + switch (this->m_binop) { + case types::BinOp::Assignment: + return rhs; + default: + auto binop = types::find_binop( + scope.binops, + lhs, + this->m_binop, + rhs); + if (binop) { + return binop->result(*binop, lhs, rhs); + } + throw CompileError("invalid binop", this->m_meta); + } + } + catch (std::runtime_error& error) { + throw CompileError(error.what(), this->m_meta); + } + } + codegen::StackValue BinaryOperationExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { auto lvalued = scope.with_lvalue(); auto lhs = this->m_lhs->codegen(builder, this->m_binop == types::BinOp::Assignment ? lvalued : scope); @@ -88,6 +134,11 @@ namespace AST { } } + std::shared_ptr FunctionCallExpression::get_codegen_type(codegen::Scope& scope) { + auto fn_ty = this->m_fn_expr->get_codegen_type(scope); + return *fn_ty->return_type(); + } + codegen::StackValue FunctionCallExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { std::vector args{}; for (auto& arg : this->m_args) { @@ -102,6 +153,10 @@ namespace AST { }; } + std::shared_ptr CastExpression::get_codegen_type(codegen::Scope&) { + return this->m_ty; + } + codegen::StackValue CastExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { auto expr = this->m_expr->codegen(builder, scope); auto cast = types::find_cast(scope.casts, expr.ty, this->m_ty); @@ -122,11 +177,28 @@ namespace AST { return expr; } + std::shared_ptr RefExpression::get_codegen_type(codegen::Scope& scope) { + return std::shared_ptr { + new types::PointerType{ this->m_expr->get_codegen_type(scope) } + }; + } + codegen::StackValue RefExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { auto with_lvalue = scope.with_lvalue(); return this->m_expr->codegen(builder, with_lvalue); } + std::shared_ptr DerefExpression::get_codegen_type(codegen::Scope& scope) { + auto ty = this->m_expr->get_codegen_type(scope); + if (ty->m_kind == types::TypeKind::Pointer) { + auto ptr_ty = dynamic_cast(ty.get()); + return ptr_ty->m_inner; + } + else { + throw new CompileError("Tried to deref a non-pointer!", this->m_meta); + } + } + codegen::StackValue DerefExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { auto value = this->m_expr->codegen(builder, scope); if (value.ty->m_kind == types::TypeKind::Pointer) { @@ -141,6 +213,21 @@ namespace AST { } } + std::shared_ptr IndexAccessExpression::get_codegen_type(codegen::Scope& scope) { + auto ty = this->m_expr->get_codegen_type(scope); + if (ty->m_kind == types::TypeKind::Array) { + auto ptr_ty = dynamic_cast(ty.get()); + return ptr_ty->m_inner; + } + else if (ty->m_kind == types::TypeKind::Pointer) { + auto ptr_ty = dynamic_cast(ty.get()); + return ptr_ty->m_inner; + } + else { + throw CompileError("Tried indexing a non-pointer", this->m_meta); + } + } + codegen::StackValue IndexAccessExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { auto lvalue_scope = scope.with_lvalue(); diff --git a/test.c b/test.c index 7708643..96b9cf3 100644 --- a/test.c +++ b/test.c @@ -6,8 +6,8 @@ int fibonacci(int n) { return fibonacci(n - 1) + fibonacci(n - 2); } -void modify_value(char* otus) { - *otus = 20; +void change_first(char otus[5]) { + otus[0] = 115; } int main() { @@ -17,8 +17,7 @@ int main() { char somelist[5]; somelist[0] = 15; - somelist[1] = 20; - somelist[2] = 25; + change_first(somelist); return somelist[0]; } \ No newline at end of file