Jelajahi Sumber

initial commit

Nicolas Winkler 7 tahun lalu
melakukan
3eb26fe2aa

+ 126 - 0
src/Ast.h

@@ -0,0 +1,126 @@
+// =============================================================================
+//
+// This file is part of the qlow compiler.
+//
+// Copyright (C) 2014-2015 Nicolas Winkler
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+// =============================================================================
+
+#include <string>
+#include <vector>
+#include <memory>
+
+
+namespace qlow
+{
+    namespace ast
+    {
+        template<typename T>
+        using List = std::vector<std::unique_ptr<T>>;
+
+
+        struct Class;
+
+        struct FeatureDeclaration;
+
+        struct FieldDeclaration;
+        struct MethodDefinition;
+
+        struct VariableDeclaration;
+
+        struct Statement;
+
+        struct Expression;
+        struct Identifier;
+        struct BinaryOperation;
+        struct FunctionCall;
+    }
+}
+
+
+
+struct qlow::ast::Class
+{
+    std::string name;
+};
+
+
+struct qlow::ast::FeatureDeclaration
+{
+    std::string name;
+    std::string type;
+};
+
+
+struct qlow::ast::FieldDeclaration
+{
+    inline MethodDefinition(const std::string& type, const std::string& name) :
+        FeatureDeclaration(type, name)
+    {
+    }
+};
+
+
+struct qlow::ast::MethodDefinition
+{
+    List<ArgumentDeclaration> arguments;
+    std::unique_ptr<DoEndBlock> body;
+
+    inline MethodDefinition(const std::string& type, const std::string& name,
+            std::unique_ptr<DoEndBlock>&& body) :
+        FeatureDeclaration(type, name),
+        body(body)
+    {
+    }
+};
+
+
+struct qlow::ast::VariableDeclaration
+{
+    std::string name;
+    std::string type;
+};
+
+
+struct qlow::ast::Statement
+{
+};
+
+
+struct qlow::ast::Expression
+{
+};
+
+
+struct qlow::ast::BinaryOperation : public Expression
+{
+    std::unique_ptr<Expression> left;
+    std::string operator_str;
+    std::unique_ptr<Expression> right;
+};
+
+
+struct qlow::ast::FunctionCall : public Expression
+{
+    std::string name;
+    std::vector<std::unique_ptr<Expression>> arguments;
+};
+
+
+
+
+
+

+ 72 - 0
src/lexer.l

@@ -0,0 +1,72 @@
+/* =============================================================================
+//
+// This file is part of the qlow compiler.
+//
+// Copyright (C) 2014-2015 Nicolas Winkler
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+// ===========================================================================*/
+
+%{
+#include "Ast.h"
+
+//#define yylval qlow_parser_lval
+#define SET_TOKEN(t) (yylval.token = t)
+#define SET_STRING (yylval.string = new std::string(yytext, yyleng))
+
+extern "C" int yywrap()
+{
+    
+    return 1; /* do not continue on EOF */
+}
+
+%}
+
+
+%option prefix="qlow_parser_"
+
+%%
+
+
+[a-zA-Z_][a-zA-Z0-9_]*  SET_STRING; return IDENTIFIER;
+.                       printf("Unknown token!\n"); yyterminate();
+
+%%
+
+
+/*
+
+[\t ]                   ; // Space or tab ignored
+\/\*[.\n]*\*\/          ; // comment
+\n                      return SET_TOKEN(NEW_LINE);
+
+":"                     return SET_TOKEN(COLON);
+","                     return SET_TOKEN(COMMA);
+":="                    return SET_TOKEN(ASSIGN);
+"."                     return SET_TOKEN(DOT);
+
+"+"		        return SET_TOKEN(PLUS);
+"-"		        return SET_TOKEN(MINUS);
+"*"		        return SET_TOKEN(ASTERISK);
+"/"		        return SET_TOKEN(SLASH);
+
+"("                     return SET_TOKEN(ROUND_LEFT);
+")"                     return SET_TOKEN(ROUND_RIGHT);
+
+"class"                 return SET_TOKEN(CLASS);
+"do"                    return SET_TOKEN(DO);
+"end"                   return SET_TOKEN(END);
+"if"                    return SET_TOKEN(IF);
+*/

+ 9 - 0
src/main.cpp

@@ -0,0 +1,9 @@
+#include "Ast.h"
+
+
+int main()
+{
+
+}
+
+

TEMPAT SAMPAH
src/main.o


+ 37 - 0
src/makefile

@@ -0,0 +1,37 @@
+CXX := g++
+CXXFLAGS := -g -Wall
+LINKFLAGS :=
+
+YACC := bison
+YACCFLAGS := -d
+LEX := flex
+LEXFLAGS :=
+
+OBJECTS := $(patsubst %.cpp, %.o, $(wildcard *.cpp */*.cpp)) \
+    parser.o lexer.o
+LIBRARIES := 
+EXECUTABLE := glow
+
+
+all: $(EXECUTABLE)
+
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) $^ $(LINKFLAGS) -o $@
+
+
+%.o: %.cpp
+	$(CXX) -c -o $@ $< $(CXXFLAGS)
+
+%.cpp: %.y
+	$(YACC) -o $@ $< $(YACCFLAGS)
+
+%.cpp: %.l parser.cpp
+	$(LEX) -o $@ $< $(LEXFLAGS)
+
+
+
+clear:
+	rm -f *.o  */*.o parser/Parser.cpp parser/Lexer.cpp
+
+

+ 332 - 0
src/parser.y

@@ -0,0 +1,332 @@
+/* =============================================================================
+//
+// This file is part of the qlow compiler.
+//
+// Copyright (C) 2014-2015 Nicolas Winkler
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+// ===========================================================================*/
+
+
+%{
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <cstdio>
+#include "Ast.h"
+using namespace qlow::parser;
+
+extern int qlow_parser_lex();
+
+int qlow_parser_error(const char*)
+{
+    throw "syntax error";
+}
+
+using ClassList = std::vector<std::unique_ptr<qlow::ast::Class>>;
+std::unique_ptr<ClassList> parsedClasses;
+
+%}
+
+%define api.prefix {uetli_parser_}
+
+/*
+%skeleton "lalr1.cc" // generate C++ parser
+//%define api.namespace {uetli::parser}
+//%define api.value.type {struct semantic_type}
+//%define parser_class_name {Parser}
+
+//%name-prefix "uetli_parser_"
+*/
+%union {
+    std::vector<std::unique_ptr<uetli::parser::Class>>* classes;
+    ClassDefinition* classDefinition;
+    FeatureDeclaration* featureDeclaration;
+    std::vector<std::unique_ptr<uetli::parser::FeatureDeclaration>>* featureList;
+
+    const char* cString;
+    int token;
+};
+
+
+%token <string> IDENTIFIER
+%token <token> CLASS DO END IF
+%token <token> NEW_LINE
+%token <token> COLON COMMA DOT ASSIGN OPERATOR
+%token <token> ROUND_LEFT ROUND_RIGHT
+
+%type <classes> classes
+%type <classDefinition> classDefinition
+%type <featureDeclaration> featureDeclaration fieldDeclaration methodDeclaration
+%type <featureList> featureList
+
+%left ASTERISK SLASH
+%left PLUS MINUS
+
+%start compilationUnit
+
+%%
+
+
+compilationUnit:
+    /* empty */ {
+        parsedClasses = std::make_unique<ClassList>();
+    }
+    |
+    compilationUnit classes {
+        parsedClasses = $2;
+    };
+
+
+/* possible newline characters
+pnl:
+    {
+    }
+    |
+    pnl NEW_LINE {
+    };
+*/
+
+/* list of class definitions */
+classes:
+    classDefinition {
+        $$ = new std::vector<std::unique_ptr<ClassDefinition>>();
+        $$->push_back($1);
+    }
+    |
+    classes classDefinition {
+        $$->push_back($3);
+    };
+
+
+classDefinition:
+    CLASS IDENTIFIER featureList END {
+        $$ = new ClassDefinition(*$2, *$3);
+        delete $2; $2 = 0; $3 = 0;
+    };
+
+
+featureList:
+    /* empty */ {
+        $$ = new std::vector<std::unique_ptr<FeatureDeclaration>>();
+    }
+    |
+    featureList featureDeclaration {
+        $$ = $1;
+        $$->push_back($2);
+    };
+
+
+featureDeclaration:
+    fieldDeclaration {
+        $$ = $1;
+    }
+    |
+    methodDeclaration {
+        $$ = $1;
+    };
+
+
+fieldDeclaration:
+    IDENTIFIER COLON IDENTIFIER {
+        $$ = new FieldDeclaration(*$3, *$1);
+        delete $3; delete $1; $1 = $3 = 0;
+    };
+
+
+methodDefinition:
+    IDENTIFIER COLON IDENTIFIER doEndBlock {
+        $$ = new MethodDefinition(*$3, *$1, $4);
+        delete $3; delete $1; $1 = $3 = 0;
+    }
+    |
+    IDENTIFIER doEndBlock {
+        $$ = new MethodDefinition("", *$1, $2);
+        delete $1; $1 = 0;
+    }
+    |
+    IDENTIFIER
+        ROUND_LEFT argumentList ROUND_RIGHT COLON IDENTIFIER doEndBlock {
+        $$ = new MethodDefinition(*$6, *$1, $7);
+        delete $6; delete $1; $1 = $6 = 0;
+    }
+    |
+    IDENTIFIER ROUND_LEFT argumentList ROUND_RIGHT doEndBlock {
+        $$ = new MethodDefinition("", *$1, $5);
+        delete $1; $1 = 0;
+    };
+
+
+argumentList:
+    argumentDeclaration {
+        $$ = new std::vector<std::unique_ptr<ArgumentDeclaration>>();
+        $$->push_back($1);
+    }
+    |
+    argumentList COMMA argumentDeclaration {
+        $$ = $1;
+        $$->push_back($3);
+    };
+
+
+argumentDeclaration:
+    IDENTIFIER COLON IDENTIFIER {
+        $$ = new ArgumentDeclaration(*$3, *$1);
+        delete $3; delete $1; $1 = $3 = 0;
+    };
+
+
+doEndBlock:
+    DO statements END {
+        $$ = new DoEndBlock(*$2);
+        delete $2; $2 = 0;
+    };
+
+
+statements:
+    /* empty */ {
+        $$ = new std::vector<std::unique_ptr<Statement>>();
+    }
+    |
+    statements statement {
+        $$ = $1;
+        $$->push_back($2);
+    };
+
+
+statement:
+    callOrVariableStatement {
+        $$ = $1;
+    }
+    |
+    assignmentStatement {
+        $$ = $1;
+    }
+    |
+    newVariableStatement {
+        $$ = $1;
+    };
+
+
+callOrVariableStatement:
+    IDENTIFIER {
+        $$ = new CallOrVariableStatement(0, *$1);
+        delete $1; $1 = 0;
+    }
+    |
+    IDENTIFIER ROUND_LEFT expressionList ROUND_RIGHT {
+        $$ = new CallOrVariableStatement(0, *$1, *$3);
+        delete $1; delete $3; $1 = 0; $3 = 0;
+    }
+    |
+    expression DOT IDENTIFIER {
+        $$ = new CallOrVariableStatement($1, *$3);
+        delete $3; $3 = 0;
+    }
+    |
+    expression DOT IDENTIFIER ROUND_LEFT expressionList ROUND_RIGHT {
+        $$ = new CallOrVariableStatement($1, *$3, *$5);
+        delete $3; $3 = 0; delete $5; $5 = 0;
+    };
+
+
+/* list of effective arguments */
+expressionList:
+    expression {
+        $$ = new std::vector<std::unique_ptr<Expression>>();
+        $$->push_back($1);
+    }
+    |
+    expressionList COMMA expression {
+        $$ = $1;
+        $$->push_back($3);
+    };
+
+
+expression:
+    callOrVariableStatement {
+        $$ = $1;
+    }
+    |
+    operationExpression {
+        $$ = $1;
+    }
+    |
+    paranthesesExpression {
+        $$ = $1;
+    };
+
+
+operationExpression:
+    binaryOperationExpression {
+        $$ = $1;
+    }
+    |
+    unaryOperationExpression {
+        $$ = $1;
+    };
+
+
+binaryOperationExpression:
+    expression operator expression {
+        $$ = new BinaryOperationExpression($1, $3, $2);
+    };
+
+
+unaryOperationExpression:
+    expression operator {
+        $$ = new UnaryOperationExpression($1,
+            UnaryOperationExpression::SUFFIX, $2);
+    }
+    |
+    operator expression {
+        $$ = new UnaryOperationExpression($2,
+            UnaryOperationExpression::PREFIX, $1);
+    };
+
+
+operator:
+    PLUS { $$ = "+"; }
+    |
+    MINUS { $$ = "-"; }
+    |
+    ASTERISK { $$ = "*"; }
+    |
+    SLASH { $$ = "/"; };
+
+
+paranthesesExpression:
+    ROUND_LEFT expression ROUND_RIGHT {
+        $$ = $2;
+    };
+
+
+assignmentStatement:
+    callOrVariableStatement ASSIGN expression {
+        $$ = new AssignmentStatement($1, $3);
+    };
+
+
+newVariableStatement:
+    IDENTIFIER COLON IDENTIFIER {
+        $$ = new NewVariableStatement(*$3, *$1);
+        delete $3; delete $1; $3 = 0; $1 = 0;
+    };
+
+
+%%
+
+

+ 18 - 0
src/tests/full_tests/simple_arithmetic.qlw

@@ -0,0 +1,18 @@
+
+// define our variables
+var a : int
+var b : int
+var c : int
+
+// initialize values
+a = 3
+b = 10
+
+// calculate
+c = a + b
+
+print(c)
+
+add(a, b, c)
+
+

+ 1 - 0
src/tests/full_tests/simple_arithmetic.qlw.out

@@ -0,0 +1 @@
+13

+ 14 - 0
src/tests/lexer/lex.cpp

@@ -0,0 +1,14 @@
+#include <iostream>
+
+union valtype {
+    int token;
+    const char* string;
+};
+
+valtype yylval;
+
+int main()
+{
+
+}
+

+ 18 - 0
src/tests/simple_arithmetic.qlw

@@ -0,0 +1,18 @@
+
+// define our variables
+var a : int
+var b : int
+var c : int
+
+// initialize values
+a = 3
+b = 10
+
+// calculate
+c = a + b
+
+print(c)
+
+add(a, b, c)
+
+