QlowB il y a 7 ans
Parent
commit
c088319167
6 fichiers modifiés avec 111 ajouts et 29 suppressions
  1. 19 9
      src/Ast.cpp
  2. 17 3
      src/Ast.h
  3. 37 1
      src/AstVisitor.cpp
  4. 29 14
      src/Semantic.h
  5. 2 0
      src/lexer.l
  6. 7 2
      src/parser.y

+ 19 - 9
src/Ast.cpp

@@ -2,6 +2,8 @@
 #include "AstVisitor.h"
 #include "Semantic.h"
 
+#include <cstdlib>
+
 using namespace qlow::ast;
 
 
@@ -23,15 +25,14 @@ ACCEPT_DEFINITION(MethodDefinition, StructureVisitor)
 ACCEPT_DEFINITION(VariableDeclaration, StructureVisitor)
 ACCEPT_DEFINITION(ArgumentDeclaration, StructureVisitor)
 
-
-ACCEPT_DEFINITION(DoEndBlock, BodyVisitor)
-ACCEPT_DEFINITION(Statement, BodyVisitor)
-ACCEPT_DEFINITION(Expression, BodyVisitor)
-ACCEPT_DEFINITION(FeatureCall, BodyVisitor)
-ACCEPT_DEFINITION(AssignmentStatement, BodyVisitor)
-ACCEPT_DEFINITION(NewVariableStatement, BodyVisitor)
-ACCEPT_DEFINITION(UnaryOperation, BodyVisitor)
-ACCEPT_DEFINITION(BinaryOperation, BodyVisitor)
+ACCEPT_DEFINITION(DoEndBlock, StructureVisitor)
+ACCEPT_DEFINITION(Statement, StructureVisitor)
+ACCEPT_DEFINITION(Expression, StructureVisitor)
+ACCEPT_DEFINITION(FeatureCall, StructureVisitor)
+ACCEPT_DEFINITION(AssignmentStatement, StructureVisitor)
+ACCEPT_DEFINITION(NewVariableStatement, StructureVisitor)
+ACCEPT_DEFINITION(UnaryOperation, StructureVisitor)
+ACCEPT_DEFINITION(BinaryOperation, StructureVisitor)
 
 
 
@@ -40,6 +41,15 @@ Statement::~Statement(void)
 }
 
 
+qlow::ast::IntConst::IntConst(const std::string& val, const qlow::CodePosition& p) :
+    AstObject{ p },
+    Expression{ p },
+    value{ strtoull(val.c_str(), nullptr, 0) }
+{
+}
+
+
+
 
 
 

+ 17 - 3
src/Ast.h

@@ -60,6 +60,7 @@ namespace qlow
         struct FeatureCall;
         struct AssignmentStatement;
         struct NewVariableStatement;
+        struct IntConst;
 
         struct Operation;
         struct UnaryOperation;
@@ -256,13 +257,13 @@ struct qlow::ast::FeatureCall : public Expression, public Statement
 
 struct qlow::ast::AssignmentStatement : public Statement
 {
-    std::string target;
+    std::unique_ptr<Expression> target;
     std::unique_ptr<Expression> expr;
 
-    inline AssignmentStatement(const std::string& target, std::unique_ptr<Expression> expr, const CodePosition& cp) :
+    inline AssignmentStatement(std::unique_ptr<Expression> target, std::unique_ptr<Expression> expr, const CodePosition& cp) :
         AstObject{ cp },
         Statement{ cp },
-        target(target), expr(std::move(expr))
+        target{ std::move(target) }, expr{ std::move(expr) }
     {
     }
 
@@ -285,6 +286,19 @@ struct qlow::ast::NewVariableStatement : public Statement
 };
 
 
+struct qlow::ast::IntConst : public Expression
+{
+    unsigned long long value;
+    
+    IntConst(unsigned long long v, const CodePosition& p) :
+        AstObject(p),
+        Expression(p),
+        value{ v } {}
+        
+    IntConst(const std::string& val, const CodePosition& p);
+};
+
+
 struct qlow::ast::Operation : public Expression
 {
     enum Operator {

+ 37 - 1
src/AstVisitor.cpp

@@ -1,6 +1,8 @@
 #include "AstVisitor.h"
 #include "Ast.h"
 
+#include "Util.h"
+
 using namespace qlow;
 
 
@@ -82,7 +84,23 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::DoEndBlock& as
 {
     auto body = std::make_unique<sem::DoEndBlock>();
     for (auto& statement : ast.statements) {
-        body->statements.push_back(unique_dynamic_cast<sem::Statement>(visit(*statement, classes)));
+        
+        if (ast::NewVariableStatement* nvs = dynamic_cast<ast::NewVariableStatement*>(statement.get()); nvs) {
+            auto var = std::make_unique<sem::Variable>(getType(nvs->type, classes), nvs->name);
+            if (var->type == nullptr)
+                throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE, nvs->type, nvs->pos);
+            
+            body->variables.push_back(std::move(var));
+            continue;
+        }
+        
+        auto v = visit(*statement, classes);
+        if (dynamic_cast<sem::FeatureCallExpression*>(v.get()) != nullptr) {
+            body->statements.push_back(std::make_unique<sem::FeatureCallStatement>(unique_dynamic_cast<sem::FeatureCallExpression>(std::move(v))));
+        }
+        else {
+            body->statements.push_back(unique_dynamic_cast<sem::Statement>(std::move(v)));
+        }
     }
     return body;
 }
@@ -100,11 +118,19 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Expression& as
 
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FeatureCall& ast, const sem::SymbolTable<sem::Class>& classes)
 {
+    auto fce = std::make_unique<sem::FeatureCallExpression>();
+    //fce->callee = unique_dynamic_cast<sem::Expression>(visit(*ast.target, classes));
+    return fce;
 }
 
 
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::AssignmentStatement& ast, const sem::SymbolTable<sem::Class>& classes)
 {
+    auto as = std::make_unique<sem::AssignmentStatement>();
+    
+    as->value = unique_dynamic_cast<sem::Expression>(visit(*ast.expr, classes));
+    as->target = unique_dynamic_cast<sem::Expression>(visit(*ast.target, classes));
+    return as;
 }
 
 
@@ -115,11 +141,21 @@ std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::NewVariableSta
 
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::UnaryOperation& ast, const sem::SymbolTable<sem::Class>& classes)
 {
+    auto ret = std::make_unique<sem::UnaryOperation>();
+    ret->op = ast.op;
+    ret->side = ast.side;
+    ret->arg = unique_dynamic_cast<sem::Expression>(visit(*ast.expr, classes));
+    return ret;
 }
 
 
 std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::BinaryOperation& ast, const sem::SymbolTable<sem::Class>& classes)
 {
+    auto ret = std::make_unique<sem::BinaryOperation>();
+    ret->op = ast.op;
+    ret->left = unique_dynamic_cast<sem::Expression>(visit(*ast.left, classes));
+    ret->right = unique_dynamic_cast<sem::Expression>(visit(*ast.right, classes));
+    return ret;
 }
 
 

+ 29 - 14
src/Semantic.h

@@ -10,6 +10,9 @@ namespace qlow
 {
     namespace sem
     {
+        
+        SymbolTable<qlow::sem::Class> createFromAst(std::vector<std::unique_ptr<qlow::ast::Class>>& classes);
+        
         /*!
          * \note contains owning pointers to elements
          */
@@ -21,24 +24,24 @@ namespace qlow
 
         struct Field;
         struct Method;
-        
+
         struct Variable;
-        
+
         struct DoEndBlock;
         struct Statement;
         struct Expression;
-        
+
         struct FeatureCallStatement;
         struct AssignmentStatement;
 
         struct Operation;
         struct UnaryOperation;
         struct BinaryOperation;
-        
-        struct FeatureCallExpression;
 
-        SymbolTable<qlow::sem::Class> createFromAst(std::vector<std::unique_ptr<qlow::ast::Class>>& classes);
+        struct FeatureCallExpression;
         
+        struct Type;
+
         class SemanticException;
     }
 }
@@ -96,6 +99,10 @@ struct qlow::sem::Variable : public SemanticObject
 {
     Class* type;
     std::string name;
+    
+    Variable(void) = default;
+    inline Variable(Class* type, std::string& name) :
+        type{ type }, name{ name } {}
 };
 
 
@@ -111,16 +118,9 @@ struct qlow::sem::Statement : public SemanticObject
 };
 
 
-struct qlow::sem::FeatureCallStatement : public Statement 
-{
-    Method* callee;
-    OwningList<Expression> arguments;
-};
-
-
 struct qlow::sem::AssignmentStatement : public Statement 
 {
-    Variable* target;
+    std::unique_ptr<Expression> target;
     std::unique_ptr<Expression> value;
 };
 
@@ -145,6 +145,7 @@ struct qlow::sem::BinaryOperation : public Operation
 
 struct qlow::sem::UnaryOperation : public Operation
 {
+    qlow::ast::UnaryOperation::Side side;
     std::unique_ptr<Expression> arg;
 };
 
@@ -155,6 +156,20 @@ struct qlow::sem::FeatureCallExpression : public Expression
 };
 
 
+struct qlow::sem::FeatureCallStatement : public Statement 
+{
+    std::unique_ptr<FeatureCallExpression> expr;
+    inline FeatureCallStatement(std::unique_ptr<FeatureCallExpression> expr) :
+        expr{ std::move(expr) } {}
+};
+
+
+struct qlow::sem::Type
+{
+    Class* typeClass;
+};
+
+
 class qlow::sem::SemanticException
 {
     std::string message;

+ 2 - 0
src/lexer.l

@@ -102,6 +102,8 @@ extern QLOW_PARSER_LTYPE qlow_parser_lloc;
 "/"                     return SET_TOKEN(SLASH);
 
 
+[0-9_]+                 SET_STRING; return INT_LITERAL;
+0x[0-9A-Fa-f]+          SET_STRING; return INT_LITERAL;
 [a-zA-Z_][a-zA-Z0-9_]*  SET_STRING; return IDENTIFIER;
 .                       printf("Unexpected symbol %s.\n", std::string(yytext, yyleng).c_str()); yyterminate();
 

+ 7 - 2
src/parser.y

@@ -86,6 +86,7 @@ std::unique_ptr<ClassList> parsedClasses;
 
 
 %token <string> IDENTIFIER
+%token <string> INT_LITERAL
 %token <token> CLASS DO END IF
 %token <token> NEW_LINE
 %token <token> SEMICOLON COLON COMMA DOT ASSIGN OPERATOR
@@ -300,6 +301,10 @@ expression:
     |
     paranthesesExpression {
         $$ = $1;
+    }
+    |
+    INT_LITERAL {
+        $$ = new IntConst($1);
     };
 
 
@@ -349,8 +354,8 @@ paranthesesExpression:
 
 
 assignmentStatement:
-    IDENTIFIER ASSIGN expression {
-        $$ = new AssignmentStatement(std::move(*$1), std::unique_ptr<Expression>($3), @$);
+    expression ASSIGN expression {
+        $$ = new AssignmentStatement(std::unique_ptr<Expression>($1), std::unique_ptr<Expression>($3), @$);
         delete $1; $1 = 0;
     };