Selaa lähdekoodia

improving language

Nicolas Winkler 7 vuotta sitten
vanhempi
commit
07dc421fd2
9 muutettua tiedostoa jossa 114 lisäystä ja 47 poistoa
  1. 1 1
      src/Ast.cpp
  2. 16 16
      src/Ast.h
  3. 31 17
      src/AstVisitor.cpp
  4. 4 2
      src/AstVisitor.h
  5. 12 1
      src/Semantic.cpp
  6. 32 1
      src/Semantic.h
  7. 5 4
      src/lexer.l
  8. 9 1
      src/main.cpp
  9. 4 4
      src/parser.y

+ 1 - 1
src/Ast.cpp

@@ -11,7 +11,7 @@ AstObject::~AstObject(void)
 
 
 #define ACCEPT_DEFINITION(ClassName) \
-std::unique_ptr<qlow::sem::SemanticObject> ClassName::accept(AstVisitor& v, const sem::SymbolTable<sem::Class>& c) \
+std::unique_ptr<qlow::sem::SemanticObject> ClassName::accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>& c) \
 { \
     v.visit(*this, c); \
 }

+ 16 - 16
src/Ast.h

@@ -32,7 +32,7 @@
 
 namespace qlow
 {
-    class AstVisitor;
+    class StructureVisitor;
     namespace ast
     {
         template<typename T>
@@ -77,7 +77,7 @@ namespace qlow
 
 
 struct qlow::ast::AstObject :
-    public Visitable<std::unique_ptr<sem::SemanticObject>, const sem::SymbolTable<sem::Class>, AstVisitor>
+    public Visitable<std::unique_ptr<sem::SemanticObject>, const sem::SymbolTable<sem::Class>, StructureVisitor>
 {
     virtual ~AstObject(void);
 };
@@ -93,7 +93,7 @@ struct qlow::ast::Class : public AstObject
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&) override;
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&) override;
 };
 
 
@@ -107,7 +107,7 @@ struct qlow::ast::FeatureDeclaration : public AstObject
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -118,7 +118,7 @@ struct qlow::ast::FieldDeclaration : public FeatureDeclaration
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -143,7 +143,7 @@ struct qlow::ast::MethodDefinition : public FeatureDeclaration
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -156,7 +156,7 @@ struct qlow::ast::VariableDeclaration  : public AstObject
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -168,7 +168,7 @@ struct qlow::ast::ArgumentDeclaration :
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -181,7 +181,7 @@ struct qlow::ast::DoEndBlock : public AstObject
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -189,13 +189,13 @@ struct qlow::ast::Statement : public virtual AstObject
 {
     virtual ~Statement(void);
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
 struct qlow::ast::Expression : public virtual AstObject
 {
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -217,7 +217,7 @@ struct qlow::ast::FeatureCall : public Expression, public Statement
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -231,7 +231,7 @@ struct qlow::ast::AssignmentStatement : public Statement
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -244,7 +244,7 @@ struct qlow::ast::NewVariableStatement : public Statement
     {
     } 
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -280,7 +280,7 @@ struct qlow::ast::UnaryOperation : public Operation
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 
@@ -295,7 +295,7 @@ struct qlow::ast::BinaryOperation : public Operation
     {
     }
 
-    std::unique_ptr<sem::SemanticObject> accept(AstVisitor& v, const sem::SymbolTable<sem::Class>&);
+    std::unique_ptr<sem::SemanticObject> accept(StructureVisitor& v, const sem::SymbolTable<sem::Class>&);
 };
 
 

+ 31 - 17
src/AstVisitor.cpp

@@ -3,84 +3,98 @@
 
 using namespace qlow;
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::Class& ast, const sem::SymbolTable<sem::Class>& classes)
+
+sem::Class* StructureVisitor::getType(const std::string& type, const sem::SymbolTable<sem::Class>& classes)
 {
-    auto c = std::make_unique<sem::Class> ();
-    c->name = ast.name;
+    auto t = classes.find(type);
+    if (t != classes.end())
+        return t->second.get();
+    else
+        throw sem::SemanticException(sem::SemanticException::UNKNOWN_TYPE, type);
+}
 
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Class& ast, const sem::SymbolTable<sem::Class>& classes)
+{
+    auto c = std::make_unique<sem::Class>();
+    c->name = ast.name;
     return c;
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::FeatureDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FeatureDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
 {
     // not needed, because 
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::FieldDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FieldDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
 {
     auto f = std::make_unique<sem::Field>();
     f->name = ast.name;
+    f->type = getType(ast.type, classes);
     return f;
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::MethodDefinition& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::MethodDefinition& ast, const sem::SymbolTable<sem::Class>& classes)
 {
     auto m = std::make_unique<sem::Method>();
     m->name = ast.name;
+    m->returnType = getType(ast.type, classes);
     return m;
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::VariableDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::VariableDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
 {
-    
+    auto v = std::make_unique<sem::Variable>();
+    v->name = ast.name;
+    v->type = getType(ast.type, classes);
+    return v;
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::ArgumentDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::ArgumentDeclaration& ast, const sem::SymbolTable<sem::Class>& classes)
 {
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::DoEndBlock& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::DoEndBlock& ast, const sem::SymbolTable<sem::Class>& classes)
 {
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::Statement& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Statement& ast, const sem::SymbolTable<sem::Class>& classes)
 {
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::Expression& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::Expression& ast, const sem::SymbolTable<sem::Class>& classes)
 {
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::FeatureCall& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::FeatureCall& ast, const sem::SymbolTable<sem::Class>& classes)
 {
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::AssignmentStatement& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::AssignmentStatement& ast, const sem::SymbolTable<sem::Class>& classes)
 {
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::NewVariableStatement& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::NewVariableStatement& ast, const sem::SymbolTable<sem::Class>& classes)
 {
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::UnaryOperation& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::UnaryOperation& ast, const sem::SymbolTable<sem::Class>& classes)
 {
 }
 
 
-std::unique_ptr<sem::SemanticObject> AstVisitor::visit(ast::BinaryOperation& ast, const sem::SymbolTable<sem::Class>& classes)
+std::unique_ptr<sem::SemanticObject> StructureVisitor::visit(ast::BinaryOperation& ast, const sem::SymbolTable<sem::Class>& classes)
 {
 }
 

+ 4 - 2
src/AstVisitor.h

@@ -46,11 +46,11 @@ namespace qlow
 
 namespace qlow
 {
-    class AstVisitor;
+    class StructureVisitor;
 }
 
 
-class qlow::AstVisitor :
+class qlow::StructureVisitor :
     public Visitor<
         std::unique_ptr<sem::SemanticObject>,
         const sem::SymbolTable<sem::Class>&,
@@ -73,6 +73,8 @@ class qlow::AstVisitor :
 {
 public:
     using ReturnType = std::unique_ptr<sem::SemanticObject>;
+    
+    sem::Class* getType(const std::string& type, const sem::SymbolTable<sem::Class>& classes);
 
     ReturnType visit(ast::Class& ast, const sem::SymbolTable<sem::Class>& classes) override;
     ReturnType visit(ast::FeatureDeclaration& ast, const sem::SymbolTable<sem::Class>& classes) override;

+ 12 - 1
src/Semantic.cpp

@@ -44,7 +44,7 @@ SymbolTable<qlow::sem::Class>
         );
     }
 
-    AstVisitor av;
+    StructureVisitor av;
     
     // create all methods and fields
     for (auto& [name, semClass] : semClasses) {
@@ -103,3 +103,14 @@ std::string Method::toString(void) const
     return "Method[" + this->name + "]";
 }
 
+
+std::string SemanticException::getMessage(void) const
+{
+    std::map<ErrorCode, std::string> error = {
+        {UNKNOWN_TYPE, "unknown type"},
+    };
+    
+    return error[errorCode] + ": " + message;
+}
+
+

+ 32 - 1
src/Semantic.h

@@ -11,7 +11,7 @@ namespace qlow
     namespace sem
     {
         /*!
-         * \brief contains owning pointers to elements
+         * \note contains owning pointers to elements
          */
         template<typename T>
         using SymbolTable = std::map<std::string, std::unique_ptr<T>>;
@@ -21,8 +21,13 @@ namespace qlow
 
         struct Field;
         struct Method;
+        
+        struct Variable;
+        struct Variable;
 
         SymbolTable<qlow::sem::Class> createFromAst(std::vector<std::unique_ptr<qlow::ast::Class>>& classes);
+        
+        class SemanticException;
     }
 }
 
@@ -73,6 +78,32 @@ struct qlow::sem::Method : public SemanticObject
 };
 
 
+struct qlow::sem::Variable : public SemanticObject
+{
+    Class* type;
+    std::string name;
+};
+
+
+
+class qlow::sem::SemanticException
+{
+    std::string message;
+public:
+    enum ErrorCode
+    {
+        UNKNOWN_TYPE,
+    };
+    
+    
+    ErrorCode errorCode;
+public:
+    inline SemanticException(ErrorCode ec, const std::string& arg) :
+        message{ arg }, errorCode{ ec }
+    {}
+
+    std::string getMessage(void) const;
+};
 
 
 

+ 5 - 4
src/lexer.l

@@ -51,16 +51,17 @@ extern "C" int yywrap()
 
 ":"                     return SET_TOKEN(COLON);
 ","                     return SET_TOKEN(COMMA);
+";"                     return SET_TOKEN(SEMICOLON);
 ":="                    return SET_TOKEN(ASSIGN);
 "."                     return SET_TOKEN(DOT);
 
 "("                     return SET_TOKEN(ROUND_LEFT);
 ")"                     return SET_TOKEN(ROUND_RIGHT);
 
-"+"		        return SET_TOKEN(PLUS);
-"-"		        return SET_TOKEN(MINUS);
-"*"		        return SET_TOKEN(ASTERISK);
-"/"		        return SET_TOKEN(SLASH);
+"+"                     return SET_TOKEN(PLUS);
+"-"                     return SET_TOKEN(MINUS);
+"*"                     return SET_TOKEN(ASTERISK);
+"/"                     return SET_TOKEN(SLASH);
 
 
 [a-zA-Z_][a-zA-Z0-9_]*  SET_STRING; return IDENTIFIER;

+ 9 - 1
src/main.cpp

@@ -6,10 +6,14 @@ extern std::unique_ptr<std::vector<std::unique_ptr<qlow::ast::Class>>> parsedCla
 extern FILE* qlow_parser_in;
 extern int qlow_parser_parse(void);
 
-int main()
+int main(int argc, char** argv)
 {
     try {
         qlow_parser_in = stdin;
+        
+        if (argc > 1)
+            qlow_parser_in = ::fopen(argv[1], "r");
+        
         ::qlow_parser_parse();
         std::cout << parsedClasses->size() << std::endl;
 
@@ -21,6 +25,10 @@ int main()
             std::cout << a << ": " << b->toString() << std::endl;
         }
     }
+    catch (qlow::sem::SemanticException& se)
+    {
+        std::cerr << se.getMessage() << std::endl;
+    }
     catch (const char* err)
     {
         std::cerr << err << std::endl;

+ 4 - 4
src/parser.y

@@ -85,7 +85,7 @@ std::unique_ptr<ClassList> parsedClasses;
 %token <string> IDENTIFIER
 %token <token> CLASS DO END IF
 %token <token> NEW_LINE
-%token <token> COLON COMMA DOT ASSIGN OPERATOR
+%token <token> SEMICOLON COLON COMMA DOT ASSIGN OPERATOR
 %token <token> ROUND_LEFT ROUND_RIGHT
 
 %type <classes> classes
@@ -229,15 +229,15 @@ statements:
 
 
 statement:
-    featureCall {
+    featureCall SEMICOLON {
         $$ = $1;
     }
     |
-    assignmentStatement {
+    assignmentStatement SEMICOLON {
         $$ = $1;
     }
     |
-    newVariableStatement {
+    newVariableStatement SEMICOLON {
         $$ = $1;
     };