Add compiling of lvalues differently

This commit is contained in:
Sofia 2026-04-09 17:25:41 +03:00
parent a6939784f8
commit 16833ad1a0
2 changed files with 23 additions and 3 deletions

View File

@ -6,6 +6,12 @@
#include <memory> #include <memory>
#include <iostream> #include <iostream>
namespace codegen {
Scope Scope::with_lvalue() {
return Scope{ this->values, true };
}
}
namespace AST { namespace AST {
llvm::Value* IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { llvm::Value* IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto ty = builder.builder->getInt32Ty(); auto ty = builder.builder->getInt32Ty();
@ -15,20 +21,31 @@ namespace AST {
llvm::Value* ValueReferenceExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { llvm::Value* ValueReferenceExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto value = scope.values.find(this->m_name); auto value = scope.values.find(this->m_name);
if (value != scope.values.end()) { if (value != scope.values.end()) {
if (scope.is_lvalue) {
return value->second.value;
}
else {
return builder.builder->CreateLoad(value->second.ty, value->second.value); return builder.builder->CreateLoad(value->second.ty, value->second.value);
} }
}
else { else {
throw new std::runtime_error("Value " + this->m_name + " not found"); throw new std::runtime_error("Value " + this->m_name + " not found");
} }
} }
llvm::Value* BinaryOperationExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { llvm::Value* BinaryOperationExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto lhs = this->m_lhs->codegen(builder, scope); auto lvalued = scope.with_lvalue();
auto lhs = this->m_lhs->codegen(builder, lvalued);
auto rhs = this->m_rhs->codegen(builder, scope); auto rhs = this->m_rhs->codegen(builder, scope);
switch (this->m_binop) { switch (this->m_binop) {
case BinOp::Assignment: case BinOp::Assignment:
builder.builder->CreateStore(rhs, lhs, false); builder.builder->CreateStore(rhs, lhs, false);
if (scope.is_lvalue) {
return lhs; return lhs;
}
else {
return rhs;
}
default: default:
throw std::runtime_error("invalid binop"); throw std::runtime_error("invalid binop");
} }

View File

@ -21,6 +21,9 @@ namespace codegen {
struct Scope { struct Scope {
std::map<std::string, StackValue> values; std::map<std::string, StackValue> values;
bool is_lvalue;
Scope with_lvalue();
}; };
} }