Explorar el Código

improving field access

Nicolas Winkler hace 6 años
padre
commit
b17a94139a
Se han modificado 7 ficheros con 34 adiciones y 7 borrados
  1. 6 1
      src/CodeGeneration.cpp
  2. 20 3
      src/CodegenVisitor.cpp
  3. 3 1
      src/CodegenVisitor.h
  4. 1 0
      src/Semantic.cpp
  5. 2 0
      src/Semantic.h
  6. 1 1
      src/parser.y
  7. 1 1
      src/test.qlw

+ 6 - 1
src/CodeGeneration.cpp

@@ -116,13 +116,18 @@ llvm::Function* generateFunction(llvm::Module* module, sem::Method* method)
     using llvm::Type;
     using llvm::FunctionType;
     
-    std::vector<Type*> argumentTypes;
     Type* returnType;
     if (method->returnType)
         returnType = method->returnType->getLlvmType(context);
     else
         returnType = llvm::Type::getVoidTy(context);
     
+    std::vector<Type*> argumentTypes;
+    if (method->containingType != nullptr) {
+        Type* enclosingType = method->containingType->llvmType;
+        argumentTypes.push_back(enclosingType);
+    }
+    
     for (auto& arg : method->arguments) {
         Type* argumentType = arg->type->getLlvmType(context);
         argumentTypes.push_back(argumentType);

+ 20 - 3
src/CodegenVisitor.cpp

@@ -128,10 +128,17 @@ llvm::Value* ExpressionCodegenVisitor::visit(sem::NewArrayExpression& naexpr, ll
 llvm::Value* ExpressionCodegenVisitor::visit(sem::MethodCallExpression& call, llvm::IRBuilder<>& builder)
 {
     using llvm::Value;
-    std::vector<Value*> arguments;
     if (call.arguments.size() != call.callee->arguments.size()) {
         throw "wrong number of arguments";
     }
+    
+    std::vector<Value*> arguments;
+    
+    if (call.target != nullptr) {
+        auto* target = call.target->accept(*this, builder);
+        arguments.push_back(target);
+    }
+    
     for (size_t i = 0; i < call.arguments.size(); i++) {
         // : call.arguments) {
         auto& arg = call.arguments[i];
@@ -165,6 +172,12 @@ llvm::Value* ExpressionCodegenVisitor::visit(sem::IntConst& node, llvm::IRBuilde
 }
 
 
+llvm::Value* ExpressionCodegenVisitor::visit(sem::ThisExpression& thisExpr, llvm::IRBuilder<>& builder)
+{
+    return thisExpr.allocaInst;
+}
+
+
 llvm::Value* StatementVisitor::visit(sem::DoEndBlock& assignment,
         qlow::gen::FunctionGenerator& fg)
 {
@@ -260,9 +273,13 @@ llvm::Value* StatementVisitor::visit(sem::AssignmentStatement& assignment,
         builder.CreateStore(val, targetVar->var->allocaInst);
     }
     else if (auto* targetVar =
-        dynamic_cast<sem::MethodCallExpression*>(assignment.target.get()); targetVar) {
+        dynamic_cast<sem::FieldAccessExpression*>(assignment.target.get()); targetVar) {
         
-        logger.debug() << "assigning to MethodCallExpression" << std::endl;
+        logger.debug() << "assigning to FieldAccessExpression" << std::endl;
+    
+        llvm::Value* target = targetVar->target->accept(fg.expressionVisitor, builder);
+        auto elementPtr = builder.CreateGEP(target, llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0)));
+        builder.CreateStore(val, elementPtr);
     }
     else {
         

+ 3 - 1
src/CodegenVisitor.h

@@ -42,7 +42,8 @@ class qlow::ExpressionCodegenVisitor :
         sem::NewArrayExpression,
         sem::MethodCallExpression,
         sem::FieldAccessExpression,
-        sem::IntConst
+        sem::IntConst,
+        sem::ThisExpression
     >
 {
 public:
@@ -54,6 +55,7 @@ public:
     llvm::Value* visit(sem::MethodCallExpression& node, llvm::IRBuilder<>&) override;
     llvm::Value* visit(sem::FieldAccessExpression& node, llvm::IRBuilder<>&) override;
     llvm::Value* visit(sem::IntConst& node, llvm::IRBuilder<>&) override;
+    llvm::Value* visit(sem::ThisExpression& node, llvm::IRBuilder<>&) override;
 };
 
 

+ 1 - 0
src/Semantic.cpp

@@ -177,6 +177,7 @@ ACCEPT_DEFINITION(UnaryOperation, ExpressionCodegenVisitor, llvm::Value*, llvm::
 ACCEPT_DEFINITION(MethodCallExpression, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
 ACCEPT_DEFINITION(FieldAccessExpression, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
 ACCEPT_DEFINITION(IntConst, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
+ACCEPT_DEFINITION(ThisExpression, ExpressionCodegenVisitor, llvm::Value*, llvm::IRBuilder<>&)
 
 ACCEPT_DEFINITION(AssignmentStatement, StatementVisitor, llvm::Value*, qlow::gen::FunctionGenerator&) 
 ACCEPT_DEFINITION(DoEndBlock, StatementVisitor, llvm::Value*, qlow::gen::FunctionGenerator&) 

+ 2 - 0
src/Semantic.h

@@ -163,6 +163,8 @@ struct qlow::sem::ThisExpression : public Variable
         method{ method}
     {
     }
+    
+    llvm::Value* accept(ExpressionCodegenVisitor& visitor, llvm::IRBuilder<>& arg2);
 };
 
 

+ 1 - 1
src/parser.y

@@ -168,7 +168,7 @@ typedef qlow::CodePosition QLOW_PARSER_LTYPE;
 %destructor { if ($$) delete $$; } <*>
 
 %left DOT
-%nonassoc AS 
+%left AS 
 %left ASTERISK SLASH
 %left PLUS MINUS
 %left EQUALS

+ 1 - 1
src/test.qlw

@@ -25,7 +25,7 @@ bignumbers do
     c: Int64
 
     b := a + c as Int128
-    c := b as Int64
+    //c := b as Int64
 end
 
 main2 do