Browse Source

extern calling now works

Nicolas Winkler 6 years ago
parent
commit
954c7d4895
7 changed files with 49 additions and 18 deletions
  1. 13 2
      src/Ast.h
  2. 6 0
      src/CodeGeneration.cpp
  3. 4 2
      src/Semantic.cpp
  4. 4 2
      src/Semantic.h
  5. 1 0
      src/lexer.l
  6. 17 9
      src/parser.y
  7. 4 3
      src/test.qlw

+ 13 - 2
src/Ast.h

@@ -196,6 +196,9 @@ struct qlow::ast::FieldDeclaration : public FeatureDeclaration
 struct qlow::ast::MethodDefinition : public FeatureDeclaration
 struct qlow::ast::MethodDefinition : public FeatureDeclaration
 {
 {
     OwningList<ArgumentDeclaration> arguments;
     OwningList<ArgumentDeclaration> arguments;
+    
+    /// pointer to method body. If this is a null pointer, the method has only
+    /// been declared and not defined (with extern)
     std::unique_ptr<DoEndBlock> body;
     std::unique_ptr<DoEndBlock> body;
 
 
     inline MethodDefinition(std::unique_ptr<ast::Type> type, const std::string& name,
     inline MethodDefinition(std::unique_ptr<ast::Type> type, const std::string& name,
@@ -213,13 +216,21 @@ struct qlow::ast::MethodDefinition : public FeatureDeclaration
         body{ std::move(body) }
         body{ std::move(body) }
     {
     {
     }
     }
+
     
     
+    inline MethodDefinition(std::unique_ptr<ast::Type> type, const std::string& name,
+            const CodePosition& cp) :
+        FeatureDeclaration{ std::move(type), name, cp },
+        body{ nullptr }
+    {
+    }
     
     
+
     inline MethodDefinition(std::unique_ptr<ast::Type> type, const std::string& name,
     inline MethodDefinition(std::unique_ptr<ast::Type> type, const std::string& name,
-            OwningList<ArgumentDeclaration>&& arguments, std::unique_ptr<DoEndBlock> body, const CodePosition& cp) :
+            OwningList<ArgumentDeclaration>&& arguments, const CodePosition& cp) :
         FeatureDeclaration{ std::move(type), name, cp },
         FeatureDeclaration{ std::move(type), name, cp },
         arguments(std::move(arguments)),
         arguments(std::move(arguments)),
-        body{ std::move(body) }
+        body{ nullptr }
     {
     {
     }
     }
 
 

+ 6 - 0
src/CodeGeneration.cpp

@@ -77,6 +77,9 @@ std::unique_ptr<llvm::Module> generateModule(const sem::GlobalScope& objects)
 
 
     for (auto& [name, cl] : objects.classes){
     for (auto& [name, cl] : objects.classes){
         for (auto& [name, method] : cl->methods) {
         for (auto& [name, method] : cl->methods) {
+            if (!method->body)
+                continue;
+            
             FunctionGenerator fg(*method, module.get());
             FunctionGenerator fg(*method, module.get());
             Function* f = fg.generate();
             Function* f = fg.generate();
             logger.debug() << "verifying function: " << method->name << std::endl;
             logger.debug() << "verifying function: " << method->name << std::endl;
@@ -89,6 +92,9 @@ std::unique_ptr<llvm::Module> generateModule(const sem::GlobalScope& objects)
         }
         }
     }
     }
     for (auto& [name, method] : objects.functions) {
     for (auto& [name, method] : objects.functions) {
+        if (!method->body)
+            continue;
+        
         FunctionGenerator fg(*method, module.get());
         FunctionGenerator fg(*method, module.get());
         Function* f = fg.generate();
         Function* f = fg.generate();
         logger.debug() << "verifying function: " << method->name << std::endl;
         logger.debug() << "verifying function: " << method->name << std::endl;

+ 4 - 2
src/Semantic.cpp

@@ -87,11 +87,13 @@ std::unique_ptr<GlobalScope>
     
     
     for (auto& [name, semClass] : globalScope->classes) {
     for (auto& [name, semClass] : globalScope->classes) {
         for (auto& [name, method] : semClass->methods) {
         for (auto& [name, method] : semClass->methods) {
-            method->body = unique_dynamic_cast<sem::DoEndBlock>(av.visit(*method->astNode->body, method->scope));
+            if (method->astNode->body) // if not declaration
+                method->body = unique_dynamic_cast<sem::DoEndBlock>(av.visit(*method->astNode->body, method->scope));
         }
         }
     }
     }
     for (auto& [name, method] : globalScope->functions) {
     for (auto& [name, method] : globalScope->functions) {
-        method->body = unique_dynamic_cast<sem::DoEndBlock>(av.visit(*method->astNode->body, method->scope));
+        if (method->astNode->body) // if not declaration
+            method->body = unique_dynamic_cast<sem::DoEndBlock>(av.visit(*method->astNode->body, method->scope));
     }
     }
     
     
 #ifdef DEBUGGING
 #ifdef DEBUGGING

+ 4 - 2
src/Semantic.h

@@ -142,14 +142,16 @@ struct qlow::sem::Method : public SemanticObject
 
 
     inline Method(Scope& parentScope, Type* returnType) :
     inline Method(Scope& parentScope, Type* returnType) :
         returnType{ returnType },
         returnType{ returnType },
-        scope{ parentScope }
+        scope{ parentScope },
+        body{ nullptr }
     {
     {
     }
     }
     
     
     inline Method(ast::MethodDefinition* astNode, Scope& parentScope) :
     inline Method(ast::MethodDefinition* astNode, Scope& parentScope) :
         astNode{ astNode },
         astNode{ astNode },
         name{ astNode->name },
         name{ astNode->name },
-        scope{ parentScope }
+        scope{ parentScope },
+        body{ nullptr }
     {
     {
     }
     }
     
     

+ 1 - 0
src/lexer.l

@@ -98,6 +98,7 @@ UTF8CHAR [\x00-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xe
 "else"                  return SET_TOKEN(ELSE);
 "else"                  return SET_TOKEN(ELSE);
 "return"                return SET_TOKEN(RETURN);
 "return"                return SET_TOKEN(RETURN);
 "new"                   return SET_TOKEN(NEW);
 "new"                   return SET_TOKEN(NEW);
+"extern"                return SET_TOKEN(EXTERN);
 
 
 ":"                     return SET_TOKEN(COLON);
 ":"                     return SET_TOKEN(COLON);
 ";"                     return SET_TOKEN(SEMICOLON);
 ";"                     return SET_TOKEN(SEMICOLON);

+ 17 - 9
src/parser.y

@@ -80,7 +80,7 @@ typedef qlow::CodePosition QLOW_PARSER_LTYPE;
 
 
 %initial-action
 %initial-action
 {
 {
-  @$.filename = qlow_parser_filename;
+    @$.filename = qlow_parser_filename;
 };
 };
 
 
 //%define api.location.type {qlow::CodePosition}
 //%define api.location.type {qlow::CodePosition}
@@ -128,7 +128,7 @@ typedef qlow::CodePosition QLOW_PARSER_LTYPE;
 %token <string> IDENTIFIER
 %token <string> IDENTIFIER
 %token <string> INT_LITERAL
 %token <string> INT_LITERAL
 %token <token> TRUE FALSE
 %token <token> TRUE FALSE
-%token <token> CLASS DO END IF ELSE WHILE RETURN NEW
+%token <token> CLASS DO END IF ELSE WHILE RETURN NEW EXTERN
 %token <token> NEW_LINE
 %token <token> NEW_LINE
 %token <token> SEMICOLON COLON COMMA DOT ASSIGN EQUALS NOT_EQUALS
 %token <token> SEMICOLON COLON COMMA DOT ASSIGN EQUALS NOT_EQUALS
 %token <token> ROUND_LEFT ROUND_RIGHT SQUARE_LEFT SQUARE_RIGHT
 %token <token> ROUND_LEFT ROUND_RIGHT SQUARE_LEFT SQUARE_RIGHT
@@ -140,6 +140,7 @@ typedef qlow::CodePosition QLOW_PARSER_LTYPE;
 %type <featureDeclaration> featureDeclaration
 %type <featureDeclaration> featureDeclaration
 %type <fieldDeclaration> fieldDeclaration
 %type <fieldDeclaration> fieldDeclaration
 %type <methodDefinition> methodDefinition
 %type <methodDefinition> methodDefinition
+%type <methodDefinition> externMethodDeclaration
 %type <featureList> featureList
 %type <featureList> featureList
 %type <argumentList> argumentList
 %type <argumentList> argumentList
 %type <statements> statements
 %type <statements> statements
@@ -191,7 +192,9 @@ topLevel:
         $2 = nullptr;
         $2 = nullptr;
     }
     }
     |
     |
-    topLevel externMethodDefinition {
+    topLevel externMethodDeclaration {
+        parsedClasses->push_back(std::move(std::unique_ptr<qlow::ast::MethodDefinition>($2)));
+        $2 = nullptr;
     }
     }
     |
     |
     topLevel error methodDefinition {
     topLevel error methodDefinition {
@@ -276,19 +279,24 @@ fieldDeclaration:
 
 
 externMethodDeclaration:
 externMethodDeclaration:
     EXTERN IDENTIFIER COLON type {
     EXTERN IDENTIFIER COLON type {
-    
+        $$ = new MethodDefinition(std::unique_ptr<qlow::ast::Type>($4), *$2, @$);
+        delete $2; $2 = nullptr;
     }
     }
     |
     |
     EXTERN IDENTIFIER {
     EXTERN IDENTIFIER {
-    
+        $$ = new MethodDefinition(nullptr, *$2, @$);
+        delete $2; $2 = nullptr;
     }
     }
     |
     |
     EXTERN IDENTIFIER ROUND_LEFT argumentList ROUND_RIGHT {
     EXTERN IDENTIFIER ROUND_LEFT argumentList ROUND_RIGHT {
-    
+        $$ = new MethodDefinition(nullptr, *$2, std::move(*$4), @$);
+        delete $2; delete $4; $2 = nullptr; $4 = nullptr;
     }
     }
     |
     |
     EXTERN IDENTIFIER ROUND_LEFT argumentList ROUND_RIGHT COLON type {
     EXTERN IDENTIFIER ROUND_LEFT argumentList ROUND_RIGHT COLON type {
-    
+        $$ = new MethodDefinition(std::unique_ptr<qlow::ast::Type>($7),
+                                 *$2, std::move(*$4), @$);
+        delete $2; delete $4; $2 = nullptr; $4 = nullptr;
     };
     };
     
     
 
 
@@ -342,8 +350,8 @@ doEndBlock:
         $$ = new DoEndBlock(std::move(*$2), @$);
         $$ = new DoEndBlock(std::move(*$2), @$);
         delete $2; $2 = nullptr;
         delete $2; $2 = nullptr;
     };
     };
-    
-    
+
+
 ifElseBlock:
 ifElseBlock:
     IF expression doEndBlock {
     IF expression doEndBlock {
         $$ = new IfElseBlock(std::unique_ptr<Expression>($2),
         $$ = new IfElseBlock(std::unique_ptr<Expression>($2),

+ 4 - 3
src/test.qlw

@@ -16,12 +16,13 @@ fast_fibonacci(i: Integer): Integer do
     return a
     return a
 end
 end
 
 
-/*
+extern do_shit
+
 main do
 main do
     value: Integer
     value: Integer
-    value := fast_fibonacci(5)
+    do_shit
 end
 end
-*/
+