QlowB 6 年之前
父節點
當前提交
25ba64031a
共有 12 個文件被更改,包括 97 次插入25 次删除
  1. 9 1
      src/Ast.h
  2. 15 0
      src/AstVisitor.cpp
  3. 5 1
      src/Builtin.cpp
  4. 1 0
      src/Builtin.h
  5. 2 0
      src/CodeGeneration.cpp
  6. 19 10
      src/CodegenVisitor.cpp
  7. 3 0
      src/Type.cpp
  8. 2 0
      src/Type.h
  9. 3 3
      src/Util.h
  10. 11 2
      src/lexer.l
  11. 16 3
      src/parser.y
  12. 11 5
      src/test.qlw

+ 9 - 1
src/Ast.h

@@ -345,7 +345,15 @@ struct qlow::ast::IntConst : public Expression
 struct qlow::ast::Operation : public Expression
 struct qlow::ast::Operation : public Expression
 {
 {
     enum Operator {
     enum Operator {
-        PLUS, MINUS, ASTERISK, SLASH
+        PLUS,
+        MINUS,
+        ASTERISK,
+        SLASH,
+        EQUALS,
+        AND,
+        OR,
+        XOR,
+        NOT
     };
     };
     Operator op;
     Operator op;
 
 

+ 15 - 0
src/AstVisitor.cpp

@@ -132,7 +132,22 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::DoEndBlock& as
 
 
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::IfElseBlock& ast, sem::Scope& scope)
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::IfElseBlock& ast, sem::Scope& scope)
 {
 {
+    auto condition = ast.condition->accept(*this, scope);
+    auto ifB = ast.ifBlock->accept(*this, scope);
+    auto eB= ast.elseBlock->accept(*this, scope);
     
     
+    if (!dynamic_cast<sem::DoEndBlock*>(ifB.get())
+        || !dynamic_cast<sem::DoEndBlock*>(eB.get())
+        || !dynamic_cast<sem::Expression*>(condition.get()))
+        throw "internal error";
+    
+    auto condExpr = unique_dynamic_cast<sem::Expression>(std::move(condition));
+    auto ifBBlock = unique_dynamic_cast<sem::DoEndBlock>(std::move(ifB));
+    auto eBBlock= unique_dynamic_cast<sem::DoEndBlock>(std::move(eB));
+    
+    auto ieb = std::make_unique<sem::IfElseBlock>(std::move(condExpr), std::move(ifBBlock), std::move(eBBlock));
+    
+    return ieb;
 }
 }
 
 
 
 

+ 5 - 1
src/Builtin.cpp

@@ -4,6 +4,7 @@
 using namespace qlow;
 using namespace qlow;
 
 
 sem::Class sem::int32 = sem::Class{ "Integer", sem::NativeScope::getInstance() };
 sem::Class sem::int32 = sem::Class{ "Integer", sem::NativeScope::getInstance() };
+sem::Class sem::boolean = sem::Class{ "Boolean", sem::NativeScope::getInstance() };
 
 
 sem::NativeScope qlow::sem::generateNativeScope(void)
 sem::NativeScope qlow::sem::generateNativeScope(void)
 {
 {
@@ -13,8 +14,11 @@ sem::NativeScope qlow::sem::generateNativeScope(void)
     
     
     std::unique_ptr<sem::Type> int32 =
     std::unique_ptr<sem::Type> int32 =
         std::make_unique<sem::Type>(sem::Type::Kind::INTEGER, &sem::int32);
         std::make_unique<sem::Type>(sem::Type::Kind::INTEGER, &sem::int32);
-    
+    std::unique_ptr<sem::Type> boolean =
+        std::make_unique<sem::Type>(sem::Type::Kind::BOOLEAN, &sem::int32);
+        
     scope.types.insert({"Integer", std::move(int32)});
     scope.types.insert({"Integer", std::move(int32)});
+    scope.types.insert({"Boolean", std::move(boolean)});
     return scope;
     return scope;
 }
 }
 
 

+ 1 - 0
src/Builtin.h

@@ -11,6 +11,7 @@ namespace qlow
     namespace sem
     namespace sem
     {
     {
         extern Class int32;
         extern Class int32;
+        extern Class boolean;
         NativeScope generateNativeScope(void);
         NativeScope generateNativeScope(void);
     }
     }
 }
 }

+ 2 - 0
src/CodeGeneration.cpp

@@ -202,6 +202,8 @@ llvm::Function* qlow::gen::FunctionGenerator::generate(void)
 #endif
 #endif
     
     
     //Value* val = llvm::ConstantFP::get(context, llvm::APFloat(5.0));
     //Value* val = llvm::ConstantFP::get(context, llvm::APFloat(5.0));
+    
+    builder.SetInsertPoint(getCurrentBlock());
     builder.CreateRetVoid();
     builder.CreateRetVoid();
 
 
     return func;
     return func;

+ 19 - 10
src/CodegenVisitor.cpp

@@ -37,6 +37,7 @@ std::pair<llvm::Value*, sem::Type> ExpressionVisitor::visit(sem::BinaryOperation
     }
     }
     
     
     
     
+    // TODO insert type checks
     switch (binop.op) {
     switch (binop.op) {
         case ast::Operation::Operator::PLUS:
         case ast::Operation::Operator::PLUS:
             return { builder.CreateAdd(left, right, "add"), Type::INTEGER };
             return { builder.CreateAdd(left, right, "add"), Type::INTEGER };
@@ -46,6 +47,14 @@ std::pair<llvm::Value*, sem::Type> ExpressionVisitor::visit(sem::BinaryOperation
             return { builder.CreateMul(left, right, "mul"), Type::INTEGER };
             return { builder.CreateMul(left, right, "mul"), Type::INTEGER };
         case ast::Operation::Operator::SLASH:
         case ast::Operation::Operator::SLASH:
             return { builder.CreateSDiv(left, right, "add"), Type::INTEGER };
             return { builder.CreateSDiv(left, right, "add"), Type::INTEGER };
+        case ast::Operation::Operator::EQUALS:
+            return { builder.CreateICmpEQ(left, right, "equals"), Type::BOOLEAN };
+        case ast::Operation::Operator::AND:
+            return { builder.CreateAnd(left, right, "and"), Type::BOOLEAN };
+        case ast::Operation::Operator::OR:
+            return { builder.CreateOr(left, right, "or"), Type::BOOLEAN };
+        case ast::Operation::Operator::XOR:
+            return { builder.CreateXor(left, right, "xor"), Type::BOOLEAN };
     }
     }
 }
 }
 
 
@@ -61,12 +70,9 @@ std::pair<llvm::Value*, sem::Type> ExpressionVisitor::visit(sem::UnaryOperation&
     switch (unop.op) {
     switch (unop.op) {
         case ast::Operation::Operator::MINUS:
         case ast::Operation::Operator::MINUS:
             return { builder.CreateNeg(value, "negate"), sem::Type::INTEGER };
             return { builder.CreateNeg(value, "negate"), sem::Type::INTEGER };
-
-        case ast::Operation::Operator::PLUS:
-        [[fallthrough]];
-        case ast::Operation::Operator::ASTERISK:
-        [[fallthrough]];
-        case ast::Operation::Operator::SLASH:
+        case ast::Operation::Operator::NOT:
+            return { builder.CreateNot(value, "not"), sem::Type::BOOLEAN };
+        default:
             throw "operator not supported";
             throw "operator not supported";
     }
     }
 }
 }
@@ -128,8 +134,12 @@ llvm::Value* StatementVisitor::visit(sem::IfElseBlock& ifElseBlock,
     llvm::Function* function = fg.getCurrentBlock()->getParent();
     llvm::Function* function = fg.getCurrentBlock()->getParent();
     
     
     BasicBlock* thenB = BasicBlock::Create(fg.getContext(), "then", function);
     BasicBlock* thenB = BasicBlock::Create(fg.getContext(), "then", function);
-    BasicBlock* elseB = BasicBlock::Create(fg.getContext(), "else");
-    BasicBlock* merge = BasicBlock::Create(fg.getContext(), "merge");
+    BasicBlock* elseB = BasicBlock::Create(fg.getContext(), "else", function);
+    BasicBlock* merge = BasicBlock::Create(fg.getContext(), "merge", function);
+    
+    Value* boolCond = builder.CreateIntCast(condition, llvm::Type::getInt1Ty(fg.getContext()), false);
+    
+    builder.CreateCondBr(boolCond, thenB, elseB);  
     
     
     fg.pushBlock(thenB);
     fg.pushBlock(thenB);
     ifElseBlock.ifBlock->accept(*this, fg);
     ifElseBlock.ifBlock->accept(*this, fg);
@@ -141,8 +151,7 @@ llvm::Value* StatementVisitor::visit(sem::IfElseBlock& ifElseBlock,
     builder.SetInsertPoint(elseB);
     builder.SetInsertPoint(elseB);
     builder.CreateBr(merge);
     builder.CreateBr(merge);
     fg.popBlock();
     fg.popBlock();
-    
-    builder.CreateCondBr(condition, thenB, elseB); 
+    fg.popBlock();
     fg.pushBlock(merge);
     fg.pushBlock(merge);
 }
 }
 
 

+ 3 - 0
src/Type.cpp

@@ -49,6 +49,8 @@ llvm::Type* sem::Type::getLlvmType(llvm::LLVMContext& context) const
             return llvm::Type::getVoidTy(context);
             return llvm::Type::getVoidTy(context);
         case Kind::INTEGER:
         case Kind::INTEGER:
             return llvm::Type::getInt32Ty(context);
             return llvm::Type::getInt32Ty(context);
+        case Kind::BOOLEAN:
+            return llvm::Type::getInt1Ty(context);
         case Kind::CLASS:
         case Kind::CLASS:
             return data.classType->llvmType;
             return data.classType->llvmType;
     }
     }
@@ -77,5 +79,6 @@ bool sem::Type::operator != (const Type& other) const
 
 
 const sem::Type sem::Type::NULL_TYPE = sem::Type{ sem::Type::Kind::NULL_TYPE };
 const sem::Type sem::Type::NULL_TYPE = sem::Type{ sem::Type::Kind::NULL_TYPE };
 const sem::Type sem::Type::INTEGER = sem::Type{ sem::Type::Kind::INTEGER, &sem::int32 };
 const sem::Type sem::Type::INTEGER = sem::Type{ sem::Type::Kind::INTEGER, &sem::int32 };
+const sem::Type sem::Type::BOOLEAN = sem::Type{ sem::Type::Kind::BOOLEAN, &sem::boolean };
 
 
 
 

+ 2 - 0
src/Type.h

@@ -30,6 +30,7 @@ public:
     {
     {
         NULL_TYPE,
         NULL_TYPE,
         INTEGER,
         INTEGER,
+        BOOLEAN,
         CLASS,
         CLASS,
     };
     };
 
 
@@ -64,6 +65,7 @@ public:
 
 
     static const Type NULL_TYPE;
     static const Type NULL_TYPE;
     static const Type INTEGER;
     static const Type INTEGER;
+    static const Type BOOLEAN;
 };
 };
 
 
 
 

+ 3 - 3
src/Util.h

@@ -4,7 +4,7 @@
 #include <vector>
 #include <vector>
 #include <memory>
 #include <memory>
 #include <sstream>
 #include <sstream>
-//#include <typeinfo>
+#include <typeinfo>
 
 
 
 
 namespace qlow
 namespace qlow
@@ -28,8 +28,8 @@ namespace qlow
             return std::unique_ptr<T> (casted);
             return std::unique_ptr<T> (casted);
         else {
         else {
             delete released;
             delete released;
-            throw "failed unique dynamic cast";
-            //throw std::string("invalid unique_dynamic_cast to ") + typeid(T).name();
+            //throw "failed unique dynamic cast";
+            throw std::string("invalid unique_dynamic_cast from ") + typeid(p.get()).name() + " to " + typeid(T).name();
         }
         }
     }
     }
 
 

+ 11 - 2
src/lexer.l

@@ -86,6 +86,7 @@ extern QLOW_PARSER_LTYPE qlow_parser_lloc;
 <METHOD>"end"           yy_pop_state(); return SET_TOKEN(END);
 <METHOD>"end"           yy_pop_state(); return SET_TOKEN(END);
 <INITIAL>"end"          return SET_TOKEN(END);
 <INITIAL>"end"          return SET_TOKEN(END);
 "if"                    return SET_TOKEN(IF);
 "if"                    return SET_TOKEN(IF);
+"while"                 return SET_TOKEN(WHILE);
 "else"                  return SET_TOKEN(ELSE);
 "else"                  return SET_TOKEN(ELSE);
 "return"                return SET_TOKEN(RETURN);
 "return"                return SET_TOKEN(RETURN);
 
 
@@ -95,14 +96,22 @@ extern QLOW_PARSER_LTYPE qlow_parser_lloc;
 ":="                    return SET_TOKEN(ASSIGN);
 ":="                    return SET_TOKEN(ASSIGN);
 "."                     return SET_TOKEN(DOT);
 "."                     return SET_TOKEN(DOT);
 
 
-"("                     return SET_TOKEN(ROUND_LEFT);
-")"                     return SET_TOKEN(ROUND_RIGHT);
+"=="                    return SET_TOKEN(EQUALS);
+"and"                   return SET_TOKEN(AND);
+"or"                    return SET_TOKEN(OR);
+"xor"                   return SET_TOKEN(XOR);
+"not"                   return SET_TOKEN(NOT);
 
 
 "+"                     return SET_TOKEN(PLUS);
 "+"                     return SET_TOKEN(PLUS);
 "-"                     return SET_TOKEN(MINUS);
 "-"                     return SET_TOKEN(MINUS);
 "*"                     return SET_TOKEN(ASTERISK);
 "*"                     return SET_TOKEN(ASTERISK);
 "/"                     return SET_TOKEN(SLASH);
 "/"                     return SET_TOKEN(SLASH);
 
 
+"("                     return SET_TOKEN(ROUND_LEFT);
+")"                     return SET_TOKEN(ROUND_RIGHT);
+
+"false"                 return SET_TOKEN(FALSE);
+"true"                  return SET_TOKEN(TRUE);
 
 
 [0-9_]+                 SET_STRING; return INT_LITERAL;
 [0-9_]+                 SET_STRING; return INT_LITERAL;
 0x[0-9A-Fa-f]+          SET_STRING; return INT_LITERAL;
 0x[0-9A-Fa-f]+          SET_STRING; return INT_LITERAL;

+ 16 - 3
src/parser.y

@@ -89,9 +89,10 @@ std::unique_ptr<ClassList> parsedClasses;
 
 
 %token <string> IDENTIFIER
 %token <string> IDENTIFIER
 %token <string> INT_LITERAL
 %token <string> INT_LITERAL
-%token <token> CLASS DO END IF ELSE RETURN
+%token <token> TRUE FALSE
+%token <token> CLASS DO END IF ELSE WHILE RETURN
 %token <token> NEW_LINE
 %token <token> NEW_LINE
-%token <token> SEMICOLON COLON COMMA DOT ASSIGN OPERATOR
+%token <token> SEMICOLON COLON COMMA DOT ASSIGN
 %token <token> ROUND_LEFT ROUND_RIGHT
 %token <token> ROUND_LEFT ROUND_RIGHT
 
 
 %type <classes> classes
 %type <classes> classes
@@ -116,6 +117,10 @@ std::unique_ptr<ClassList> parsedClasses;
 
 
 %left ASTERISK SLASH
 %left ASTERISK SLASH
 %left PLUS MINUS
 %left PLUS MINUS
+%left EQUALS
+%left NOT
+%left AND
+%left OR XOR
 
 
 %start classes
 %start classes
 
 
@@ -376,7 +381,15 @@ operator:
     |
     |
     ASTERISK { $$ = qlow::ast::Operation::Operator::ASTERISK; }
     ASTERISK { $$ = qlow::ast::Operation::Operator::ASTERISK; }
     |
     |
-    SLASH { $$ = qlow::ast::Operation::Operator::SLASH; };
+    SLASH { $$ = qlow::ast::Operation::Operator::SLASH; }
+    |
+    EQUALS { $$ = qlow::ast::Operation::Operator::EQUALS; }
+    |
+    AND { $$ = qlow::ast::Operation::Operator::AND; }
+    |
+    OR { $$ = qlow::ast::Operation::Operator::OR; }
+    |
+    XOR { $$ = qlow::ast::Operation::Operator::XOR; };
 
 
 
 
 paranthesesExpression:
 paranthesesExpression:

+ 11 - 5
src/test.qlw

@@ -41,14 +41,20 @@ class FF
         return x + x
         return x + x
     end
     end
 
 
+    istfumf(x: Integer): Integer do
+        if x == 5 do
+            return 1
+        else
+            return 0
+        end
+        return 100;
+    end
+
     sum_func: Integer do
     sum_func: Integer do
         variable: Integer
         variable: Integer
         variable := verdoppel(51)
         variable := verdoppel(51)
-        if variable do
-            variable := 1
-        else
-            variable := 2
-        end
+        variable := istfumf(variable)
+        variable := 3 == 3
         return variable + 2
         return variable + 2
     end
     end
 end
 end