소스 검색

tests added

Nicolas Winkler 6 년 전
부모
커밋
77dea98f94
13개의 변경된 파일122개의 추가작업 그리고 16개의 파일을 삭제
  1. 0 4
      src/CodegenVisitor.cpp
  2. 2 4
      src/ast/Ast.cpp
  3. 16 1
      src/ast/Ast.h
  4. 7 0
      src/ast/Parser.cpp
  5. 3 0
      src/ast/Parser.h
  6. 1 0
      src/ast/lexer.l
  7. 27 3
      src/ast/syntax.y
  8. 0 1
      src/sem/Type.cpp
  9. 2 2
      src/tests/structs.qlw
  10. 48 0
      tests/runTests.py
  11. 15 0
      tests/syntax/class.qlw
  12. 0 0
      tests/syntax/class.qlw.c.should
  13. 1 1
      vim/syntax/qlow.vim

+ 0 - 4
src/CodegenVisitor.cpp

@@ -213,10 +213,6 @@ llvm::Value* ExpressionCodegenVisitor::visit(sem::FieldAccessExpression& access,
     }
     
     llvm::Value* target = access.target->accept(fg.lvalueVisitor, fg);
-    llvm::raw_os_ostream os(Printer::getInstance());
-    type->print(os);
-    os << "\n";
-    os.flush();
 
     int structIndex = access.accessed->llvmStructIndex;
     llvm::ArrayRef<Value*> indexList = {

+ 2 - 4
src/ast/Ast.cpp

@@ -6,11 +6,9 @@
 
 using namespace qlow::ast;
 
-void Ast::merge(Ast&& other)
+void Ast::merge(Ast other)
 {
-    objects.insert(objects.end(),
-                   std::make_move_iterator(other.objects.begin()),
-                   std::make_move_iterator(other.objects.end()));
+    std::move(other.objects.begin(), other.objects.end(), std::back_inserter(this->objects));
 }
 
 

+ 16 - 1
src/ast/Ast.h

@@ -44,6 +44,8 @@ namespace qlow
         // base class
         struct AstObject;
 
+        struct ImportDeclaration;
+
         struct Class;
 
         struct Type;
@@ -104,7 +106,7 @@ public:
     inline const OwningList<AstObject>& getObjects(void) const  { return objects; }
     inline       OwningList<AstObject>& getObjects(void)        { return objects; }
 
-    void merge(Ast&& other);
+    void merge(Ast other);
 };
 
 
@@ -120,6 +122,19 @@ struct qlow::ast::AstObject :
 };
 
 
+struct qlow::ast::ImportDeclaration
+{
+    CodePosition pos;
+    std::string imported;
+    
+    inline ImportDeclaration(std::string imported, const CodePosition& cp) :
+        pos{ cp },
+        imported{ std::move(imported) }
+    {
+    }
+};
+
+
 struct qlow::ast::Class : public AstObject
 {
     std::string name;

+ 7 - 0
src/ast/Parser.cpp

@@ -25,3 +25,10 @@ qlow::ast::Ast Parser::parse(void)
 
     return result;
 }
+
+
+void Parser::addImports(std::vector<std::unique_ptr<ImportDeclaration>> toAdd)
+{
+    std::move(toAdd.begin(), toAdd.end(), std::back_inserter(this->imports));
+
+}

+ 3 - 0
src/ast/Parser.h

@@ -17,12 +17,15 @@ class qlow::ast::Parser
 {
     FILE* stream;
     std::string filename;
+    std::vector<std::unique_ptr<ImportDeclaration>> imports;
 public:
     inline Parser(FILE* stream, std::string filename) :
         stream{ stream }, filename{ std::move(filename) } {}
     
     Ast parse(void);
 
+    void addImports(std::vector<std::unique_ptr<ImportDeclaration>> toAdd);
+
     inline const std::string& getFilename(void) const { return filename; }
 };
 

+ 1 - 0
src/ast/lexer.l

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

+ 27 - 3
src/ast/syntax.y

@@ -91,7 +91,7 @@ while (0)
 %lex-param   { yyscan_t scanner }
 %parse-param { yyscan_t scanner }
 %parse-param { qlow::ast::Ast& ast }
-%parse-param { const qlow::ast::Parser& parser }
+%parse-param { qlow::ast::Parser& parser }
 
 
 %define api.prefix {qlow_parser_}
@@ -149,6 +149,9 @@ while (0)
     qlow::ast::NewArrayExpression* newArrayExpression;
     qlow::ast::CastExpression* castExpression;
 
+    qlow::ast::ImportDeclaration* importDeclaration;
+    std::vector<std::unique_ptr<qlow::ast::ImportDeclaration>>* importList;
+
     const char* cString;
     std::string* string;
     int token;
@@ -159,12 +162,15 @@ while (0)
 %token <string> INT_LITERAL
 %token <string> ASTERISK SLASH PLUS MINUS EQUALS NOT_EQUALS AND OR XOR CUSTOM_OPERATOR
 %token <token> TRUE FALSE
-%token <token> CLASS STRUCT DO END IF ELSE WHILE RETURN NEW EXTERN AS
+%token <token> CLASS STRUCT DO END IF ELSE WHILE RETURN NEW AS
+%token <token> EXTERN IMPORT
 %token <token> NEW_LINE
 %token <token> SEMICOLON COLON COMMA DOT ASSIGN AMPERSAND
 %token <token> ROUND_LEFT ROUND_RIGHT SQUARE_LEFT SQUARE_RIGHT
 %token <string> UNEXPECTED_SYMBOL
 
+%type <importDeclaration> importDeclaration
+%type <importList> importList
 %type <topLevel> topLevel
 %type <classDefinition> classDefinition
 %type <type> type
@@ -216,7 +222,9 @@ while (0)
 
 /* list of class definitions */
 topLevel:
-    /* empty */ {
+    importList {
+       parser.addImports(std::move(*$1));
+       delete $1; $1 = nullptr;
        $$ = &ast;
     }
     |
@@ -254,6 +262,22 @@ topLevel:
         $3 = nullptr;
     };
 
+importList:
+    /* empty */ {
+        $$ = new std::vector<std::unique_ptr<qlow::ast::ImportDeclaration>>();
+    }
+    |
+    importList importDeclaration {
+        $$ = $1;
+        $$->emplace_back($2);
+        $2 = nullptr;
+    };
+
+importDeclaration:
+    IMPORT IDENTIFIER {
+        $$ = new qlow::ast::ImportDeclaration(std::move(*$2), @2);
+        delete $2; $2 = nullptr;
+    };
 
 classDefinition:
     CLASS IDENTIFIER featureList END {

+ 0 - 1
src/sem/Type.cpp

@@ -129,7 +129,6 @@ size_t Type::hash(void) const
         type
     );
     auto h = type.index() * 2542345234523 + value1;
-    Printer::getInstance() << h << std::endl;
     return h;
 }
 

+ 2 - 2
src/tests/structs.qlw

@@ -1,6 +1,6 @@
+import std
 
-
-struct Vec
+class Vec
     x: Integer
     y: Integer
 

+ 48 - 0
tests/runTests.py

@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+import sys
+import os
+import subprocess
+import difflib
+
+
+if len(sys.argv) <= 1:
+    print("please specify the qlow executable as a command line argument")
+    exit()
+
+qlow_executable = sys.argv[1]
+
+succeeded = 0
+failed = 0
+
+def test_file(path):
+    test = [qlow_executable, path, "-o", path + ".o"]
+    print("running test " + " ".join(test))
+    output = subprocess.run(test, stdout=subprocess.PIPE)
+    with open(path + ".c.did", "w") as out:
+        out.write(output.stdout.decode("utf-8"))
+    
+    with open(path + ".c.did", "r") as did, open(path + ".c.should", "r") as should:
+        if did.readlines() == should.readlines():
+            global succeeded
+            succeeded += 1
+        else:
+            global failed
+            failed += 1
+
+
+
+def run_directory(dir):
+    for root, dirs, files in os.walk(dir):
+        for filename in files:
+            if filename.endswith(".qlw"):
+                test_file(os.path.join(root, filename))
+
+def print_results():
+    print("%d out of %d tests succeeded: %d%%" % (succeeded, succeeded + failed, 100 * succeeded / (succeeded + failed)))
+
+run_directory(".")
+
+print_results()
+
+

+ 15 - 0
tests/syntax/class.qlw

@@ -0,0 +1,15 @@
+class A
+    field: Integer
+    field2: B
+end
+
+class B
+    field: A
+end
+
+
+main do
+    a: A
+    a := new A
+end
+

+ 0 - 0
tests/syntax/class.qlw.c.should


+ 1 - 1
vim/syntax/qlow.vim

@@ -12,7 +12,7 @@ endif
 syntax match commenty "//.*"
 syntax region multicommenty start="/\*"  end="\*/" contains=multicommenty
 
-syn keyword keywordy class struct do end if while return extern as new
+syn keyword keywordy class struct do end if while return extern as new import
 syn keyword typey Integer Boolean Abool
 syn keyword typey String Char 
 syn keyword typey Float32 Float64