switching to ANTLR
This commit is contained in:
		
							parent
							
								
									99ac38be63
								
							
						
					
					
						commit
						f45adb1810
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1 +1 @@ | ||||
| build/ | ||||
| build/ | ||||
|  | ||||
							
								
								
									
										9
									
								
								compiler/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								compiler/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1 +1,8 @@ | ||||
| *.gen.* | ||||
| # antlr | ||||
| .antlr/ | ||||
| *.interp | ||||
| *.tokens | ||||
| 
 | ||||
| # antlr-generated files | ||||
| plsm*.h | ||||
| plsm*.cpp | ||||
|  | ||||
| @ -1,15 +1,17 @@ | ||||
| 
 | ||||
| { | ||||
|   "[yacc]": { | ||||
|     "problems.decorations.enabled": false, | ||||
|   }, | ||||
|   "C_Cpp.default.includePath": [ | ||||
|     "${workspaceFolder}/include/", | ||||
|     "/usr/include/antlr4-runtime", | ||||
|   ], | ||||
|   "files.associations": { | ||||
|     "*.embeddedhtml": "html", | ||||
|     "iosfwd": "cpp", | ||||
|     "any": "cpp", | ||||
|     "array": "cpp", | ||||
|     "atomic": "cpp", | ||||
|     "bit": "cpp", | ||||
|     "*.tcc": "cpp", | ||||
|     "bitset": "cpp", | ||||
|     "cctype": "cpp", | ||||
|     "charconv": "cpp", | ||||
|     "chrono": "cpp", | ||||
| @ -28,10 +30,13 @@ | ||||
|     "cwchar": "cpp", | ||||
|     "cwctype": "cpp", | ||||
|     "deque": "cpp", | ||||
|     "forward_list": "cpp", | ||||
|     "list": "cpp", | ||||
|     "map": "cpp", | ||||
|     "set": "cpp", | ||||
|     "string": "cpp", | ||||
|     "unordered_map": "cpp", | ||||
|     "unordered_set": "cpp", | ||||
|     "vector": "cpp", | ||||
|     "exception": "cpp", | ||||
|     "algorithm": "cpp", | ||||
| @ -52,7 +57,6 @@ | ||||
|     "fstream": "cpp", | ||||
|     "initializer_list": "cpp", | ||||
|     "iomanip": "cpp", | ||||
|     "iosfwd": "cpp", | ||||
|     "iostream": "cpp", | ||||
|     "istream": "cpp", | ||||
|     "limits": "cpp", | ||||
| @ -61,6 +65,7 @@ | ||||
|     "numbers": "cpp", | ||||
|     "ostream": "cpp", | ||||
|     "semaphore": "cpp", | ||||
|     "shared_mutex": "cpp", | ||||
|     "span": "cpp", | ||||
|     "sstream": "cpp", | ||||
|     "stdexcept": "cpp", | ||||
| @ -72,18 +77,6 @@ | ||||
|     "typeinfo": "cpp", | ||||
|     "valarray": "cpp", | ||||
|     "variant": "cpp", | ||||
|     "int.h": "c", | ||||
|     "macros.h": "c", | ||||
|     "stdint.h": "c", | ||||
|     "type.h": "c", | ||||
|     "stdlib.h": "c", | ||||
|     "bitset": "cpp", | ||||
|     "codecvt": "cpp", | ||||
|     "forward_list": "cpp", | ||||
|     "set": "cpp", | ||||
|     "unordered_set": "cpp", | ||||
|     "source_location": "cpp", | ||||
|     "shared_mutex": "cpp", | ||||
|     "strstream": "cpp" | ||||
|   }, | ||||
|     "*.inc": "cpp" | ||||
|   } | ||||
| } | ||||
| @ -3,26 +3,37 @@ cmake_minimum_required(VERSION 3.25) | ||||
| project(plasmatum) | ||||
| 
 | ||||
| set(CMAKE_CXX_STANDARD 23) | ||||
| set(SOURCE_DIR ${CMAKE_SOURCE_DIR}/src) | ||||
| set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include) | ||||
| set(SRC_DIR ${CMAKE_SOURCE_DIR}/src) | ||||
| set(INC_DIR ${CMAKE_SOURCE_DIR}/include) | ||||
| 
 | ||||
| find_package(FLEX REQUIRED) | ||||
| find_package(BISON REQUIRED) | ||||
| set(GEN_DIR ${CMAKE_SOURCE_DIR}/generated) | ||||
| 
 | ||||
| BISON_TARGET(parser | ||||
|   ${CMAKE_SOURCE_DIR}/parser.yy | ||||
|   ${SOURCE_DIR}/parser.gen.cpp | ||||
|   DEFINES_FILE ${INCLUDE_DIR}/parser.gen.h) | ||||
| set(ANTLR_INC ${INC_DIR}/plsmLexer.h ${INC_DIR}/plsmParser.h ${INC_DIR}/plsmVisitor.h ${INC_DIR}/plsmBaseVisitor.h) | ||||
| set(ANTLR_SRC ${SRC_DIR}/plsmLexer.cpp ${SRC_DIR}/plsmParser.cpp ${SRC_DIR}/plsmVisitor.cpp ${SRC_DIR}/plsmBaseVisitor.cpp) | ||||
| 
 | ||||
| FLEX_TARGET(lexer | ||||
|   ${CMAKE_SOURCE_DIR}/lexer.ll | ||||
|   ${SOURCE_DIR}/lexer.gen.cpp) | ||||
| add_custom_command(PRE_BUILD | ||||
|   DEPENDS ${CMAKE_SOURCE_DIR}/plsm.g4 | ||||
|   OUTPUT ${ANTLR_SRC} | ||||
|   OUTPUT ${ANTLR_INC} | ||||
|   COMMENT "Generating plsm_parser" | ||||
|   COMMAND java -jar | ||||
|     ${CMAKE_SOURCE_DIR}/thirdparty/antlr-4.13.1-complete.jar | ||||
|     ${CMAKE_SOURCE_DIR}/plsm.g4 | ||||
|     -o ${GEN_DIR} -Dlanguage=Cpp -no-listener -visitor | ||||
|   COMMAND ${CMAKE_COMMAND} -E copy ${GEN_DIR}/*.h ${INC_DIR} | ||||
|   COMMAND ${CMAKE_COMMAND} -E copy ${GEN_DIR}/*.cpp ${SRC_DIR}) | ||||
| 
 | ||||
| ADD_FLEX_BISON_DEPENDENCY(lexer parser) | ||||
| file(GLOB_RECURSE sources ${SRC_DIR}/*.cpp) | ||||
| set(sources ${sources} ${ANTLR_SRC}) | ||||
| 
 | ||||
| file(GLOB_RECURSE sources ${SOURCE_DIR}/*.cpp) | ||||
| set(sources ${sources} ${FLEX_lexer_OUTPUTS}) | ||||
| set(sources ${sources} ${BISON_parser_OUTPUT_SOURCE}) | ||||
| 
 | ||||
| include_directories(${CMAKE_SOURCE_DIR}/include) | ||||
| add_executable(plsm ${sources}) | ||||
| 
 | ||||
| target_include_directories(plsm PRIVATE ${CMAKE_SOURCE_DIR}/include) | ||||
| target_include_directories(plsm PRIVATE /usr/include/antlr4-runtime) | ||||
| target_link_libraries(plsm antlr4-runtime) | ||||
| 
 | ||||
| add_custom_target(clean-all | ||||
|   COMMAND ${CMAKE_COMMAND} -E rm -rf | ||||
|     ${GEN_DIR} ${CMAKE_SOURCE_DIR}/build | ||||
| ) | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										8
									
								
								compiler/adscript.g4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								compiler/adscript.g4
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| grammar adscript; | ||||
| 
 | ||||
| module:; | ||||
| 
 | ||||
| // TODO ;) | ||||
| 
 | ||||
| FN: 'fn'; | ||||
| TYPE: 'type'; | ||||
| @ -6,17 +6,27 @@ namespace ast | ||||
|   { | ||||
|   public: | ||||
|     virtual ~ASTNode() = default; | ||||
| 
 | ||||
|     virtual bool isExpr() { return false; } | ||||
|     virtual bool isStmt() { return false; } | ||||
|     virtual bool isType() { return false; } | ||||
|   }; | ||||
| 
 | ||||
|   class Expr : public ASTNode | ||||
|   { | ||||
|   public: | ||||
|     virtual bool isExpr() override { return true; } | ||||
|   }; | ||||
| 
 | ||||
|   class Stmt : public ASTNode | ||||
|   { | ||||
|   public: | ||||
|     virtual bool isStmt() override { return true; } | ||||
|   }; | ||||
| 
 | ||||
|   class Type : public ASTNode | ||||
|   { | ||||
|   public: | ||||
|     virtual bool isType() override { return true; } | ||||
|   }; | ||||
| } | ||||
| @ -5,17 +5,20 @@ | ||||
| #include "Expr/BinExpr.h" | ||||
| #include "Expr/Block.h" | ||||
| #include "Expr/Call.h" | ||||
| #include "Expr/Closure.h" | ||||
| #include "Expr/Identifier.h" | ||||
| #include "Expr/UnaryExpr.h" | ||||
| #include "Expr/Value.h" | ||||
| 
 | ||||
| #include "Stmt/ExprStmt.h" | ||||
| #include "Stmt/FnDecl.h" | ||||
| #include "Stmt/TraitDecl.h" | ||||
| #include "Stmt/TypeDecl.h" | ||||
| #include "Stmt/TraitAlias.h" | ||||
| #include "Stmt/TraitDef.h" | ||||
| #include "Stmt/TypeAlias.h" | ||||
| #include "Stmt/TypeDef.h" | ||||
| #include "Stmt/ValDecl.h" | ||||
| 
 | ||||
| #include "Type/Function.h" | ||||
| #include "Type/Closure.h" | ||||
| #include "Type/Generic.h" | ||||
| #include "Type/Named.h" | ||||
| #include "Type/Tuple.h" | ||||
|  | ||||
| @ -2,33 +2,25 @@ | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <string> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class BinExpr : public Expr | ||||
|   { | ||||
|   public: | ||||
|     BinExpr(const Expr *left, const std::string &op, const Expr *right) | ||||
|         : left(left), op(op), right(right) {} | ||||
| 
 | ||||
|     ~BinExpr() | ||||
|     { | ||||
|       delete left; | ||||
|       delete right; | ||||
|     } | ||||
| 
 | ||||
|     const Expr *left; | ||||
|     const std::string op; | ||||
|     const Expr *right; | ||||
|     const std::unique_ptr<Expr> left, right; | ||||
| 
 | ||||
|   public: | ||||
|     BinExpr(std::unique_ptr<Expr> &left, const std::string &op, std::unique_ptr<Expr> &right) | ||||
|         : left(std::move(left)), op(op), right(std::move(right)) {} | ||||
|   }; | ||||
| 
 | ||||
|   class PrefExpr : public Expr | ||||
|   { | ||||
|     const std::unique_ptr<Expr> expr; | ||||
| 
 | ||||
|   public: | ||||
|     PrefExpr(const Expr *expr) : expr(expr) {} | ||||
| 
 | ||||
|     ~PrefExpr() { delete expr; } | ||||
| 
 | ||||
|     const Expr *expr; | ||||
|     PrefExpr(std::unique_ptr<Expr> &expr) : expr(std::move(expr)) {} | ||||
|   }; | ||||
| } | ||||
| @ -2,19 +2,15 @@ | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class BlockExpr : public Expr | ||||
|   { | ||||
|   public: | ||||
|     BlockExpr(const std::vector<Stmt *> &stmts) : stmts(std::move(stmts)) {} | ||||
|     ~BlockExpr() | ||||
|     { | ||||
|       for (auto &stmt : stmts) | ||||
|         delete stmt; | ||||
|     } | ||||
|     const std::vector<std::unique_ptr<Stmt>> stmts; | ||||
| 
 | ||||
|     const std::vector<Stmt *> stmts; | ||||
|   public: | ||||
|     BlockExpr(std::vector<std::unique_ptr<Stmt>> &stmts) : stmts(std::move(stmts)) {} | ||||
|   }; | ||||
| } | ||||
| @ -2,23 +2,17 @@ | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class CallExpr : public Expr | ||||
|   { | ||||
|     const std::unique_ptr<Expr> callee; | ||||
|     const std::vector<std::unique_ptr<Expr>> args; | ||||
| 
 | ||||
|   public: | ||||
|     CallExpr(const Expr *callee, const std::vector<Expr *> &args) | ||||
|         : callee(callee), args(std::move(args)) {} | ||||
| 
 | ||||
|     ~CallExpr() | ||||
|     { | ||||
|       delete callee; | ||||
|       for (auto &arg : args) | ||||
|         delete arg; | ||||
|     } | ||||
| 
 | ||||
|     const Expr *callee; | ||||
|     const std::vector<Expr *> args; | ||||
|     CallExpr(std::unique_ptr<Expr> &callee, std::vector<std::unique_ptr<Expr>> &args) | ||||
|         : callee(std::move(callee)), args(std::move(args)) {} | ||||
|   }; | ||||
| } | ||||
| @ -3,17 +3,17 @@ | ||||
| #include "AST/Base.h" | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class Closure : public Expr | ||||
|   { | ||||
|   public: | ||||
|     Closure(const std::vector<std::string> &args, const Expr *body) | ||||
|         : args(std::move(args)), body(body) {} | ||||
|     ~Closure() { delete body; } | ||||
| 
 | ||||
|     const std::vector<std::string> args; | ||||
|     const Expr *body; | ||||
|     const std::unique_ptr<Expr> body; | ||||
| 
 | ||||
|   public: | ||||
|     Closure(std::vector<std::string> &args, std::unique_ptr<Expr> &body) | ||||
|         : args(std::move(args)), body(std::move(body)) {} | ||||
|   }; | ||||
| } | ||||
| @ -7,9 +7,9 @@ namespace ast | ||||
| { | ||||
|   class Identifier : public Expr | ||||
|   { | ||||
|     const std::string name; | ||||
| 
 | ||||
|   public: | ||||
|     Identifier(const std::string &name) : name(name) {} | ||||
| 
 | ||||
|     const std::string name; | ||||
|   }; | ||||
| } | ||||
| @ -2,18 +2,17 @@ | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <string> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class UnaryExpr : public Expr | ||||
|   { | ||||
|   public: | ||||
|     UnaryExpr(const std::string &op, const Expr *expr) | ||||
|         : op(op), expr(expr) {} | ||||
| 
 | ||||
|     ~UnaryExpr() { delete expr; } | ||||
| 
 | ||||
|     const std::string op; | ||||
|     const Expr *expr; | ||||
|     const std::unique_ptr<Expr> expr; | ||||
| 
 | ||||
|   public: | ||||
|     UnaryExpr(const std::string &op, std::unique_ptr<Expr> &expr) | ||||
|         : op(op), expr(std::move(expr)) {} | ||||
|   }; | ||||
| } | ||||
| @ -7,15 +7,17 @@ namespace ast | ||||
| { | ||||
|   class IntValue : public Expr | ||||
|   { | ||||
|     const int64_t value; | ||||
| 
 | ||||
|   public: | ||||
|     IntValue(int64_t value) : value(value) {} | ||||
|     const int64_t value; | ||||
|   }; | ||||
| 
 | ||||
|   class FloatValue : public Expr | ||||
|   { | ||||
|     const double value; | ||||
| 
 | ||||
|   public: | ||||
|     FloatValue(double value) : value(value) {} | ||||
|     const double value; | ||||
|   }; | ||||
| } | ||||
|  | ||||
| @ -7,8 +7,9 @@ namespace ast | ||||
| { | ||||
|   class Import : public ASTNode | ||||
|   { | ||||
|     const std::string moduleName; | ||||
| 
 | ||||
|   public: | ||||
|     Import(const std::string &moduleName) : moduleName(moduleName) {} | ||||
|     const std::string moduleName; | ||||
|   }; | ||||
| } | ||||
| @ -2,6 +2,7 @@ | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
| @ -9,20 +10,11 @@ namespace ast | ||||
| 
 | ||||
|   class Module : public ASTNode | ||||
|   { | ||||
|     const std::vector<std::unique_ptr<Import>> imports; | ||||
|     const std::vector<std::unique_ptr<Stmt>> stmts; | ||||
| 
 | ||||
|   public: | ||||
|     Module(const std::vector<Import *> &imports, const std::vector<Stmt *> &stmts) | ||||
|     Module(std::vector<std::unique_ptr<Import>> &imports, std::vector<std::unique_ptr<Stmt>> &stmts) | ||||
|         : imports(std::move(imports)), stmts(std::move(stmts)) {} | ||||
| 
 | ||||
|     ~Module() | ||||
|     { | ||||
|       for (auto &import : imports) | ||||
|         delete import; | ||||
| 
 | ||||
|       for (auto &stmt : stmts) | ||||
|         delete stmt; | ||||
|     } | ||||
| 
 | ||||
|     const std::vector<Import *> &imports; | ||||
|     const std::vector<Stmt *> stmts; | ||||
|   }; | ||||
| } | ||||
| @ -1,15 +1,15 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class ExprStmt : public Stmt | ||||
|   { | ||||
|   public: | ||||
|     ExprStmt(const Expr *expr) : expr(expr) {} | ||||
|     ~ExprStmt() { delete expr; } | ||||
|     const std::unique_ptr<Expr> expr; | ||||
| 
 | ||||
|     const Expr *expr; | ||||
|   public: | ||||
|     ExprStmt(std::unique_ptr<Expr> &expr) : expr(std::move(expr)) {} | ||||
|   }; | ||||
| } | ||||
| @ -3,29 +3,21 @@ | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   typedef std::pair<std::string, Type *> FnArg; | ||||
|   typedef std::pair<std::string, std::unique_ptr<Type>> FnArg; | ||||
| 
 | ||||
|   class FnDecl : public Stmt | ||||
|   { | ||||
|   public: | ||||
|     FnDecl(const std::string &name, const std::vector<FnArg> &args, const Type *returnType, const Expr *body) | ||||
|         : name(name), args(std::move(args)), returnType(returnType), body(body) {} | ||||
| 
 | ||||
|     ~FnDecl() | ||||
|     { | ||||
|       for (auto &arg : args) | ||||
|         delete arg.second; | ||||
| 
 | ||||
|       delete returnType; | ||||
|       delete body; | ||||
|     } | ||||
| 
 | ||||
|     const std::string name; | ||||
|     const std::vector<FnArg> args; | ||||
|     const Type *returnType; | ||||
|     const Expr *body; | ||||
|     const std::unique_ptr<Type> returnType; | ||||
|     const std::unique_ptr<Expr> body; | ||||
| 
 | ||||
|   public: | ||||
|     FnDecl(const std::string &name, std::vector<FnArg> &args, std::unique_ptr<Type> &returnType, std::unique_ptr<Expr> &body) | ||||
|         : name(name), args(std::move(args)), returnType(std::move(returnType)), body(std::move(body)) {} | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										19
									
								
								compiler/include/AST/Stmt/TraitAlias.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								compiler/include/AST/Stmt/TraitAlias.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class TraitAlias : public Stmt | ||||
|   { | ||||
|     const std::string alias; | ||||
|     const std::string aliased; | ||||
| 
 | ||||
|   public: | ||||
|     TraitAlias(const std::string &alias, const std::string &aliased) | ||||
|         : alias(alias), aliased(aliased) {} | ||||
|   }; | ||||
| } | ||||
| @ -1,25 +0,0 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <string> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class FnDecl; | ||||
| 
 | ||||
|   class TraitDecl : public Stmt | ||||
|   { | ||||
|   public: | ||||
|     TraitDecl(const std::string &name, const std::vector<FnDecl *> &traits) | ||||
|         : name(name), traits(std::move(traits)) {} | ||||
|     ~TraitDecl() | ||||
|     { | ||||
|       for (auto &trait : traits) | ||||
|         delete trait; | ||||
|     } | ||||
| 
 | ||||
|     const std::string name; | ||||
|     const std::vector<FnDecl *> traits; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										21
									
								
								compiler/include/AST/Stmt/TraitDef.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								compiler/include/AST/Stmt/TraitDef.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class FnDecl; | ||||
| 
 | ||||
|   class TraitDef : public Stmt | ||||
|   { | ||||
|     const std::string name; | ||||
|     const std::vector<std::unique_ptr<FnDecl>> traits; | ||||
| 
 | ||||
|   public: | ||||
|     TraitDef(const std::string &name, std::vector<std::unique_ptr<FnDecl>> &traits) | ||||
|         : name(name), traits(std::move(traits)) {} | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										19
									
								
								compiler/include/AST/Stmt/TypeAlias.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								compiler/include/AST/Stmt/TypeAlias.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class TypeAlias : public Stmt | ||||
|   { | ||||
|     const std::string alias; | ||||
|     const std::unique_ptr<Type> type; | ||||
| 
 | ||||
|   public: | ||||
|     TypeAlias(const std::string &alias, std::unique_ptr<Type> &type) | ||||
|         : alias(alias), type(std::move(type)) {} | ||||
|   }; | ||||
| } | ||||
| @ -1,31 +0,0 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <string> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class FnDecl; | ||||
| 
 | ||||
|   typedef std::pair<std::string, Type *> TypeAttr; | ||||
| 
 | ||||
|   class TypeDecl : public Stmt | ||||
|   { | ||||
|   public: | ||||
|     TypeDecl(const std::string &name, const std::vector<TypeAttr> &attrs, const std::vector<FnDecl *> &members) | ||||
|         : name(name), attrs(std::move(attrs)), members(std::move(members)) {} | ||||
|     ~TypeDecl() | ||||
|     { | ||||
|       for (auto &attr : attrs) | ||||
|         delete attr.second; | ||||
| 
 | ||||
|       for (auto &member : members) | ||||
|         delete member; | ||||
|     } | ||||
| 
 | ||||
|     const std::string name; | ||||
|     const std::vector<TypeAttr> attrs; | ||||
|     const std::vector<FnDecl *> members; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										24
									
								
								compiler/include/AST/Stmt/TypeDef.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								compiler/include/AST/Stmt/TypeDef.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class FnDecl; | ||||
| 
 | ||||
|   typedef std::pair<std::string, std::unique_ptr<Type>> TypeAttr; | ||||
| 
 | ||||
|   class TypeDef : public Stmt | ||||
|   { | ||||
|     const std::string name; | ||||
|     const std::vector<TypeAttr> attrs; | ||||
|     const std::vector<std::unique_ptr<FnDecl>> members; | ||||
| 
 | ||||
|   public: | ||||
|     TypeDef(const std::string &name, std::vector<TypeAttr> &attrs, std::vector<std::unique_ptr<FnDecl>> &members) | ||||
|         : name(name), attrs(std::move(attrs)), members(std::move(members)) {} | ||||
|   }; | ||||
| } | ||||
| @ -2,23 +2,18 @@ | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <string> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class ValDecl : public Stmt | ||||
|   { | ||||
|   public: | ||||
|     ValDecl(const std::string &name, const Type *type, const Expr *value) | ||||
|         : name(name), type(type), value(value) {} | ||||
| 
 | ||||
|     ~ValDecl() | ||||
|     { | ||||
|       delete type; | ||||
|       delete value; | ||||
|     } | ||||
| 
 | ||||
|     const std::string name; | ||||
|     const Type *type; | ||||
|     const Expr *value; | ||||
|     const std::unique_ptr<Type> type; | ||||
|     const std::unique_ptr<Expr> value; | ||||
| 
 | ||||
|   public: | ||||
|     ValDecl(const std::string &name, std::unique_ptr<Type> &type, std::unique_ptr<Expr> &value) | ||||
|         : name(name), type(std::move(type)), value(std::move(value)) {} | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										18
									
								
								compiler/include/AST/Type/Closure.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								compiler/include/AST/Type/Closure.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class ClosureType : public Type | ||||
|   { | ||||
|     const std::vector<std::unique_ptr<Type>> from; | ||||
|     const std::unique_ptr<Type> to; | ||||
| 
 | ||||
|   public: | ||||
|     ClosureType(std::vector<std::unique_ptr<Type>> &from, std::unique_ptr<Type> &to) | ||||
|         : from(std::move(from)), to(std::move(to)) {} | ||||
|   }; | ||||
| } | ||||
| @ -1,25 +0,0 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "AST/Base.h" | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class FunctionType : public Type | ||||
|   { | ||||
|   public: | ||||
|     FunctionType(const std::vector<Type *> &from, const Type *to) | ||||
|         : from(std::move(from)), to(to) {} | ||||
| 
 | ||||
|     ~FunctionType() | ||||
|     { | ||||
|       for (auto &arg : from) | ||||
|         delete arg; | ||||
| 
 | ||||
|       delete to; | ||||
|     } | ||||
| 
 | ||||
|     const std::vector<Type *> from; | ||||
|     const Type *to; | ||||
|   }; | ||||
| } | ||||
| @ -3,22 +3,17 @@ | ||||
| #include "AST/Base.h" | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class GenericType : public Type | ||||
|   { | ||||
|   public: | ||||
|     GenericType(const std::string &name, const std::vector<Type *> &types) | ||||
|         : name(name), types(std::move(types)) {} | ||||
| 
 | ||||
|     ~GenericType() | ||||
|     { | ||||
|       for (auto &type : types) | ||||
|         delete type; | ||||
|     } | ||||
| 
 | ||||
|     const std::string name; | ||||
|     const std::vector<Type *> types; | ||||
|     const std::vector<std::unique_ptr<Type>> types; | ||||
| 
 | ||||
|   public: | ||||
|     GenericType(const std::string &name, std::vector<std::unique_ptr<Type>> &types) | ||||
|         : name(name), types(std::move(types)) {} | ||||
|   }; | ||||
| } | ||||
|  | ||||
| @ -7,8 +7,9 @@ namespace ast | ||||
| { | ||||
|   class NamedType : public Type | ||||
|   { | ||||
|     const std::string name; | ||||
| 
 | ||||
|   public: | ||||
|     NamedType(const std::string &name) : name(name) {} | ||||
|     const std::string name; | ||||
|   }; | ||||
| } | ||||
| @ -2,20 +2,16 @@ | ||||
| 
 | ||||
| #include "AST/Def.h" | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class TupleType : public Type | ||||
|   { | ||||
|     const std::vector<std::unique_ptr<Type>> types; | ||||
| 
 | ||||
|   public: | ||||
|     TupleType(const std::vector<Type *> &types) : types(std::move(types)) {} | ||||
| 
 | ||||
|     ~TupleType() | ||||
|     { | ||||
|       for (auto &type : types) | ||||
|         delete type; | ||||
|     } | ||||
| 
 | ||||
|     const std::vector<Type *> types; | ||||
|     TupleType(std::vector<std::unique_ptr<Type>> &types) | ||||
|         : types(std::move(types)) {} | ||||
|   }; | ||||
| } | ||||
| @ -1,18 +1,18 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <string> | ||||
| #include <stdexcept> | ||||
| 
 | ||||
| #include "AST/Def.h" | ||||
| #include "parser.gen.h" | ||||
| #include "plsmLexer.h" | ||||
| #include "plsmParser.h" | ||||
| 
 | ||||
| class Parser | ||||
| namespace plsm | ||||
| { | ||||
| public: | ||||
|   Parser() {} | ||||
|   std::unique_ptr<ast::Module> parse(const std::string &input); | ||||
| } | ||||
| 
 | ||||
|   ast::Module *parse(const std::string &file, const std::stringstream &input); | ||||
| 
 | ||||
|   std::string file; | ||||
|   yy::location location; | ||||
|   ast::Module *module; | ||||
| }; | ||||
| namespace adscript | ||||
| { | ||||
|   std::unique_ptr<ast::Module> parse(const std::string &input); | ||||
| } | ||||
|  | ||||
| @ -1,67 +0,0 @@ | ||||
| %{ | ||||
| #include "parser.gen.h" | ||||
| #include "Parser.h" | ||||
| 
 | ||||
| #undef YY_DECL | ||||
| #define YY_DECL yy::parser::symbol_type yylex(Parser &driver) | ||||
| 
 | ||||
| #define yyterminate() yy::parser::make_END(yy::location()) | ||||
| 
 | ||||
| #define _token(token) yy::parser::make_##token(yytext, driver.location) | ||||
| %} | ||||
| 
 | ||||
| %option noyywrap nounput noinput batch | ||||
| 
 | ||||
| digit       [0-9] | ||||
| bindigit    [0-1] | ||||
| octdigit    [0-7] | ||||
| hexdigit    [0-9a-fA-F] | ||||
| 
 | ||||
| letter      [a-zA-Z] | ||||
| 
 | ||||
| opchar      ("+"|"-"|"*"|"/"|"%"|"!"|"&"|"$"|"§"|"|"|"="|"<"|">"|"?"|"~"|"#"|":"|"^"|"\\"|".") | ||||
| 
 | ||||
| whitespace  [ \n\t\r\v]+ | ||||
| 
 | ||||
| %% | ||||
| 
 | ||||
| "0b"{bindigit}+       { return yy::parser::make_INT(std::strtol(yytext, NULL, 2), driver.location); } | ||||
| "0o"{octdigit}+       { return yy::parser::make_INT(std::strtol(yytext, NULL, 8), driver.location); } | ||||
| "0x"{hexdigit}+       { return yy::parser::make_INT(std::strtol(yytext, NULL, 16), driver.location); } | ||||
| {digit}+              { return yy::parser::make_INT(std::strtol(yytext, NULL, 10), driver.location); } | ||||
| 
 | ||||
| {digit}*"."{digit}+   { return yy::parser::make_FLOAT(std::strtod(yytext, NULL), driver.location); } | ||||
| 
 | ||||
| 
 | ||||
| {opchar}+     { std::string text = yytext; | ||||
|                 if (text == "=") return _token(EQUALS); | ||||
|                 if (text == "->") return _token(RARR); | ||||
|                 if (text == ".") return _token(DOT); | ||||
|                 return _token(OPERATOR); } | ||||
| 
 | ||||
| ","           { return _token(COMMA); } | ||||
| ";"           { return _token(SEMI); } | ||||
| "("           { return _token(LPAREN); } | ||||
| ")"           { return _token(RPAREN); } | ||||
| "["           { return _token(LBRACKET); } | ||||
| "]"           { return _token(RBRACKET); } | ||||
| "{"           { return _token(LBRACE); } | ||||
| "}"           { return _token(RBRACE); } | ||||
| 
 | ||||
| "binop"       { return _token(BINOP); } | ||||
| "declare"     { return _token(DECLARE); } | ||||
| "fn"          { return _token(FN); } | ||||
| "import"      { return _token(IMPORT); } | ||||
| "trait"       { return _token(TRAIT); } | ||||
| "type"        { return _token(TYPE); } | ||||
| "unop"        { return _token(UNOP); } | ||||
| "val"         { return _token(VAL); } | ||||
| 
 | ||||
| 
 | ||||
| {letter}({digit}|{letter})*   { return _token(IDENTIFIER); } | ||||
| 
 | ||||
| <<EOF>>   { return yy::parser::make_END(driver.location); } | ||||
| 
 | ||||
| {whitespace}                  { ; } | ||||
| 
 | ||||
| %% | ||||
| @ -1,289 +0,0 @@ | ||||
| %require "3.8" | ||||
| %language "c++" | ||||
| 
 | ||||
| %header | ||||
| 
 | ||||
| %define api.token.raw | ||||
| %define api.value.type variant | ||||
| %define api.token.constructor | ||||
| %define api.token.prefix {TOK_} | ||||
| 
 | ||||
| %define parse.assert | ||||
| %define parse.trace | ||||
| %define parse.error detailed | ||||
| %define parse.lac full | ||||
| 
 | ||||
| %locations | ||||
| %define api.location.file "../include/location.gen.h" | ||||
| %define api.location.include {"location.gen.h"} | ||||
| 
 | ||||
| %code requires { | ||||
| #include "AST/Def.h" | ||||
| class Parser; | ||||
| } | ||||
| 
 | ||||
| %lex-param { Parser &driver } | ||||
| %parse-param { Parser &driver } | ||||
| 
 | ||||
| %code { | ||||
| #include "Parser.h" | ||||
| yy::parser::symbol_type yylex(Parser &driver); | ||||
| } | ||||
| 
 | ||||
| %token <long> INT "integer literal" | ||||
| %token <double> FLOAT "float literal" | ||||
| 
 | ||||
| %token <std::string> | ||||
|   OPERATOR "operator" | ||||
|   IDENTIFIER "identifier" | ||||
| 
 | ||||
|   RARR "->" | ||||
|   EQUALS "=" | ||||
|   DOT "." | ||||
|   COMMA "," | ||||
|   SEMI ";" | ||||
|   LPAREN "(" | ||||
|   RPAREN ")" | ||||
|   LBRACKET "[" | ||||
|   RBRACKET "]" | ||||
|   LBRACE "{" | ||||
|   RBRACE "}" | ||||
| 
 | ||||
|   BINOP "binop" | ||||
|   DECLARE "declare" | ||||
|   FN "fn" | ||||
|   IMPORT "import" | ||||
|   TRAIT "trait" | ||||
|   TYPE "type" | ||||
|   UNOP "unop" | ||||
|   VAL "val" | ||||
| ; | ||||
| 
 | ||||
| %token END 0 "end of file" | ||||
| 
 | ||||
| %type <std::vector<ast::Stmt *>> | ||||
|   topLevelStmts | ||||
|   blockStmts | ||||
| ; | ||||
| 
 | ||||
| %type <ast::Stmt *> | ||||
|   topLevelStmt | ||||
|   blockStmt | ||||
| ; | ||||
| 
 | ||||
| %type <std::vector<ast::FnDecl *>> fnDecls fnDecls0; | ||||
| %type <ast::FnDecl *> fnDecl fnDef; | ||||
| %type <ast::ValDecl *> valDecl; | ||||
| 
 | ||||
| %type <std::vector<ast::Type *>> | ||||
|   types | ||||
|   tupleTypes | ||||
|   fnTypeArgs | ||||
| ; | ||||
| 
 | ||||
| %type <ast::Type *> type type1; | ||||
| 
 | ||||
| %type <std::vector<ast::Expr *>> exprs args; | ||||
| 
 | ||||
| %type <ast::Expr *> | ||||
|   expr | ||||
|   expr3 | ||||
|   expr2 | ||||
|   expr1 | ||||
|   expr0 | ||||
|   literal | ||||
| ; | ||||
| 
 | ||||
| %type <ast::FnArg> fnArg; | ||||
| %type <std::vector<ast::FnArg>> fnArgs fnArgs0; | ||||
| 
 | ||||
| %type <std::vector<std::string>> | ||||
|   lambdaArgs | ||||
|   identifiers | ||||
| ; | ||||
| 
 | ||||
| %type <std::string> | ||||
|   moduleName | ||||
|   type0 | ||||
|   operator | ||||
|   identifier | ||||
|   keyword | ||||
| ; | ||||
| 
 | ||||
| %type <ast::Import *> import; | ||||
| %type <std::vector<ast::Import *>> | ||||
|   imports0 | ||||
|   imports | ||||
| ; | ||||
| 
 | ||||
| %type <ast::TraitDecl *> traitDecl; | ||||
| %type <ast::TypeDecl *> typeDecl; | ||||
| 
 | ||||
| %start module | ||||
| 
 | ||||
| %% | ||||
| 
 | ||||
| module: imports topLevelStmts { driver.module = new ast::Module($1, $2); } | ||||
|       ; | ||||
| 
 | ||||
| 
 | ||||
| imports: %empty     { ; } | ||||
|        | imports0   { $$ = std::move($1); } | ||||
|        ; | ||||
| 
 | ||||
| imports0: import            { $$.push_back($1); } | ||||
|         | imports0 import   { $1.push_back($2); $$ = std::move($1); } | ||||
|         ; | ||||
| 
 | ||||
| import: IMPORT moduleName ";" { $$ = new ast::Import($2); } | ||||
|       ; | ||||
| 
 | ||||
| moduleName: identifier                  { $$ = $1; } | ||||
|           | moduleName "." identifier   { $$ = $1 + $2 + $3; } | ||||
|           ; | ||||
| 
 | ||||
| topLevelStmts: topLevelStmt                 { $$.push_back($1); } | ||||
|              | topLevelStmts topLevelStmt   { $1.push_back($2); $$ = std::move($1); } | ||||
|              ; | ||||
| 
 | ||||
| topLevelStmt: fnDef       { $$ = $1; } | ||||
|             | fnDecl      { $$ = $1; } | ||||
|             | valDecl     { $$ = $1; } | ||||
|             | typeDecl    { $$ = $1; } | ||||
|             | traitDecl   { $$ = $1; } | ||||
|             ; | ||||
| 
 | ||||
| blockStmts: blockStmt              { $$.push_back($1); } | ||||
|           | blockStmts blockStmt   { $1.push_back($2); $$ = std::move($1); } | ||||
|           ; | ||||
| 
 | ||||
| blockStmt: valDecl    { $$ = $1; } | ||||
|          | fnDef      { $$ = $1; } | ||||
|          | expr ";"   { $$ = new ast::ExprStmt($1); } | ||||
|          ; | ||||
| 
 | ||||
| traitDecl: TRAIT identifier "=" "{" fnDecls "}"   { $$ = new ast::TraitDecl($2, $5); } | ||||
|          ; | ||||
| 
 | ||||
| typeDecl: TYPE identifier "=" "(" fnArgs ")" "{" fnDecls "}"   { $$ = new ast::TypeDecl($2, $5, $8); } | ||||
|         ; | ||||
| 
 | ||||
| fnDecls: %empty   { ; } | ||||
|        | fnDecls0 { $$ = std::move($1); } | ||||
|        ; | ||||
| 
 | ||||
| fnDecls0: fnDecl            { $$.push_back($1); } | ||||
|         | fnDecls0 fnDecl   { $1.push_back($2); $$ = std::move($1); } | ||||
|         ; | ||||
| 
 | ||||
| valDecl: VAL identifier "=" expr ";"        { $$ = new ast::ValDecl($2, nullptr, $4); } | ||||
|        | VAL identifier type "=" expr ";"   { $$ = new ast::ValDecl($2, $3, $5); } | ||||
|        ; | ||||
| 
 | ||||
| fnDef : FN identifier "[" fnArgs "]" type "=" expr ";"  { $$ = new ast::FnDecl($2, $4, $6, $8); } | ||||
|       ; | ||||
| 
 | ||||
| fnDecl: FN identifier "[" fnArgs "]" type ";"  { $$ = new ast::FnDecl($2, $4, $6, nullptr); } | ||||
|       ; | ||||
| 
 | ||||
| fnArgs: %empty    { ; } | ||||
|       | fnArgs0   { $$ = std::move($1); } | ||||
|       ; | ||||
| 
 | ||||
| fnArgs0: fnArg              { $$.push_back($1); } | ||||
|        | fnArgs0 "," fnArg  { $$.push_back($3); $$ = std::move($1); } | ||||
|        ; | ||||
| 
 | ||||
| fnArg: identifier type  { $$ = ast::FnArg($1, $2); } | ||||
|      ; | ||||
| 
 | ||||
| types: type             { $$.push_back($1); } | ||||
|      | types "," type   { $1.push_back($3); $$ = std::move($1); } | ||||
|      ; | ||||
| 
 | ||||
| type: type1 | ||||
|     | "(" type ")"                   { $$ = $2; }    | ||||
|     | "(" tupleTypes ")"             { $$ = new ast::TupleType($2); } | ||||
|     | "[" fnTypeArgs "]" "->" type   { $$ = new ast::FunctionType($2, $5); } | ||||
|     ; | ||||
| 
 | ||||
| type1: type0                { $$ = new ast::NamedType($1); } | ||||
|      | type0 "{" types "}"  { $$ = new ast::GenericType($1, $3); } | ||||
|      ; | ||||
| 
 | ||||
| type0: identifier; | ||||
| 
 | ||||
| tupleTypes: type "," type             { $$.push_back($1); $$.push_back($3); } | ||||
|           | tupleTypes "," type       { $1.push_back($3); $$ = std::move($1); } | ||||
|           ; | ||||
| 
 | ||||
| fnTypeArgs: %empty { ; } | ||||
|           | types  { $$ = std::move($1); } | ||||
|           ; | ||||
| 
 | ||||
| exprs: expr             { $$.push_back($1); } | ||||
|      | exprs "," expr   { $1.push_back($3); $$ = std::move($1); } | ||||
|      ; | ||||
| 
 | ||||
| expr: expr3 { $$ = $1; } | ||||
|     ; | ||||
| 
 | ||||
| expr3: expr2                          { $$ = $1; } | ||||
|      | "[" lambdaArgs "]" "->" expr   { $$ = nullptr; } | ||||
|      | "{" blockStmts "}"             { $$ = new ast::BlockExpr($2); } | ||||
|      ; | ||||
| 
 | ||||
| expr2: expr1                  { $$ = $1; } | ||||
|      | expr2 operator expr1   { $$ = new ast::BinExpr($1, $2, $3); } | ||||
|      ; | ||||
| 
 | ||||
| expr1: expr0            { $$ = $1; } | ||||
|      | operator expr1   { $$ = new ast::UnaryExpr($1, $2); } | ||||
|      ; | ||||
| 
 | ||||
| expr0: literal              { $$ = $1; } | ||||
|      | identifier           { $$ = new ast::Identifier($1); } | ||||
|      | expr0 "[" args "]"   { $$ = new ast::CallExpr($1, $3); } | ||||
|      | "(" expr ")"         { $$ = new ast::PrefExpr($2); } | ||||
|      | expr0 "." identifier { $$ = $1; } | ||||
|      ; | ||||
| 
 | ||||
| lambdaArgs: %empty        { ; } | ||||
|           | identifiers   { $$ = std::move($1); } | ||||
|           ; | ||||
| 
 | ||||
| args: %empty  { ; } | ||||
|     | exprs   { $$ = std::move($1); } | ||||
|     ; | ||||
| 
 | ||||
| 
 | ||||
| literal: INT        { $$ = new ast::IntValue($1); } | ||||
|        | FLOAT      { $$ = new ast::FloatValue($1); } | ||||
|        ; | ||||
| 
 | ||||
| operator: "->" | ||||
|         | "=" | ||||
|         | OPERATOR | ||||
|         ; | ||||
| 
 | ||||
| identifiers: identifier                   { $$.push_back($1); } | ||||
|            | identifiers "," identifier   { $1.push_back($3); $$ = std::move($1); } | ||||
|            ; | ||||
| 
 | ||||
| identifier: keyword | ||||
|           | IDENTIFIER | ||||
|           ; | ||||
| 
 | ||||
| keyword: FN | ||||
|        | VAL | ||||
|        | UNOP | ||||
|        | BINOP | ||||
|        | IMPORT | ||||
|        | DECLARE | ||||
|        ; | ||||
| 
 | ||||
| %% | ||||
| 
 | ||||
| void yy::parser::error(const location_type& l, const std::string& m) { | ||||
|   std::cerr << l << ": " << m << '\n'; | ||||
| } | ||||
							
								
								
									
										78
									
								
								compiler/plsm.g4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								compiler/plsm.g4
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,78 @@ | ||||
| grammar plsm; | ||||
| 
 | ||||
| module: moduleImport* (let | fnDecl | fnDef | traitDef | typeDef)*; | ||||
| 
 | ||||
| moduleImport: IMPORT moduleName ';'; | ||||
| moduleName: identifier ('.' identifier)*; | ||||
| 
 | ||||
| traitDef: TRAIT identifier '=' identifier ';' | ||||
|         | TRAIT identifier '=' '{' (fnDecl)* '}' ';'; | ||||
| 
 | ||||
| typeDef: TYPE identifier '=' type ';' | ||||
|        | TYPE identifier '=' ('(' fnDefArgs ')')? '{' (fnDecl | fnDef)* '}' ';'; | ||||
| 
 | ||||
| fnDef: FN identifier '[' fnDefArgs? ']' type '=' expr ';'; | ||||
| fnDefArgs: identifier type (',' identifier type)*; | ||||
| 
 | ||||
| fnDecl: FN identifier '[' fnDeclArgs? ']' type ';'; | ||||
| fnDeclArgs: identifier? type (',' identifier? type)*; | ||||
| 
 | ||||
| let: LET identifier type? '=' expr ';'; | ||||
| 
 | ||||
| exprStmt: expr ';'; | ||||
| 
 | ||||
| type: type2; | ||||
| type2: type1 | ||||
|      | '(' type ')' | ||||
|      | '(' tupleTypeList ')'          // tuple | ||||
|      | '[' typeList? ']' '->' type;   // closure | ||||
| type1: type0 | ||||
|      | type0 '{' typeList '}';        // generic | ||||
| type0: identifier; | ||||
| 
 | ||||
| tupleTypeList: type ',' type (',' type)*; | ||||
| typeList: type (',' type)*; | ||||
| 
 | ||||
| 
 | ||||
| expr: expr3; | ||||
| expr3: expr2 | ||||
|      | '[' identifierList? ']' '->' expr     // closure | ||||
|      | '{' (let | exprStmt | fnDef)* (expr ';') '}'; | ||||
| expr2: expr1 | ||||
|      | expr2 operator expr1;                 // binary expr | ||||
| expr1: expr0 | ||||
|      | operator expr0;                       // unary expr | ||||
| expr0: literal | ||||
|      | identifier | ||||
|      | expr0 '[' exprList? ']'               // fn call | ||||
|      | '(' expr ')' | ||||
|      | expr0 '.' identifier;                 // property accessor | ||||
| 
 | ||||
| exprList: expr (',' expr)*; | ||||
| 
 | ||||
| identifierList: identifier (',' identifier)*; | ||||
| 
 | ||||
| literal: 'null' | INT_LIT | FLOAT_LIT; | ||||
| 
 | ||||
| operator: '=' | '->' | ||||
|         | OPERATOR; | ||||
| 
 | ||||
| identifier: keyword | IDENTIFIER; | ||||
| keyword: BINOP | FN | IMPORT | LET | NATIVE | TRAIT | TYPE | UNOP; | ||||
| 
 | ||||
| 
 | ||||
| INT_LIT: [0-9]+ | '0x' [0-9a-fA-F]+ | '0o' [0-7]+ | '0b' [01]+; | ||||
| FLOAT_LIT: [0-9]+ '.' | [0-9]* '.' [0-9]+; | ||||
| 
 | ||||
| OPERATOR: ('+'|'-'|'*'|'/'|'%'|'!'|'&'|'$'|'§'|'|'|'='|'<'|'>'|'?'|'~'|'#'|':'|'^'|'\\'|'.')+; | ||||
| 
 | ||||
| BINOP: 'binop'; | ||||
| FN: 'fn'; | ||||
| IMPORT: 'import'; | ||||
| LET: 'let'; | ||||
| NATIVE: 'native'; | ||||
| TRAIT: 'trait'; | ||||
| TYPE: 'type'; | ||||
| UNOP: 'unop'; | ||||
| 
 | ||||
| IDENTIFIER: [a-zA-Z_] [a-zA-Z0-9_]*; | ||||
| @ -1,20 +1,131 @@ | ||||
| #include "Parser.h" | ||||
| 
 | ||||
| #include "plsmBaseVisitor.h" | ||||
| 
 | ||||
| #include <sstream> | ||||
| #include <fstream> | ||||
| 
 | ||||
| void yy_scan_string(const char *); | ||||
| 
 | ||||
| ast::Module *Parser::parse(const std::string &file, const std::stringstream &input) | ||||
| class Visitor : public plsmBaseVisitor | ||||
| { | ||||
|   module = nullptr; | ||||
| public: | ||||
|   Visitor() {} | ||||
| 
 | ||||
|   this->file = file; | ||||
|   location.initialize(&file); | ||||
|   template <typename T> | ||||
|   inline T visitT(antlr4::tree::ParseTree *ctx) | ||||
|   { | ||||
|     return std::any_cast<T>(visit(ctx)); | ||||
|   } | ||||
| 
 | ||||
|   yy_scan_string(input.str().data()); | ||||
|   template <typename T> | ||||
|   inline std::unique_ptr<T> visitU(antlr4::tree::ParseTree *ctx) | ||||
|   { | ||||
|     return std::unique_ptr<T>(visitT<T *>(ctx)); | ||||
|   } | ||||
| 
 | ||||
|   int res = yy::parser(*this)(); | ||||
|   virtual std::any visitModule(plsmParser::ModuleContext *ctx) override | ||||
|   { | ||||
|     std::vector<std::unique_ptr<ast::Import>> imports; | ||||
|     std::vector<std::unique_ptr<ast::Stmt>> stmts; | ||||
| 
 | ||||
|   return module; | ||||
|     for (auto &child : ctx->children) | ||||
|     { | ||||
|       if (plsmParser::ModuleImportContext *c = dynamic_cast<plsmParser::ModuleImportContext *>(child)) | ||||
|         imports.push_back(visitU<ast::Import>(child)); | ||||
|       else | ||||
|         stmts.push_back(visitU<ast::Stmt>(child)); | ||||
|     } | ||||
| 
 | ||||
|     return std::any(new ast::Module(imports, stmts)); | ||||
|   } | ||||
| 
 | ||||
|   virtual std::any visitModuleImport(plsmParser::ModuleImportContext *ctx) override | ||||
|   { | ||||
|     return std::any(new ast::Import(visitT<std::string>(ctx->moduleName()))); | ||||
|   } | ||||
| 
 | ||||
|   virtual std::any visitModuleName(plsmParser::ModuleNameContext *ctx) override | ||||
|   { | ||||
|     auto name = visitT<std::string>(ctx->identifier(0)); | ||||
| 
 | ||||
|     for (size_t i = 1; ctx->identifier(i); i++) | ||||
|     { | ||||
|       name = name + "." + visitT<std::string>(ctx->identifier(i)); | ||||
|     } | ||||
| 
 | ||||
|     return std::any(name); | ||||
|   } | ||||
| 
 | ||||
|   virtual std::any visitTraitDef(plsmParser::TraitDefContext *ctx) override | ||||
|   { | ||||
|     auto name = visitT<std::string>(ctx->identifier(0)); | ||||
| 
 | ||||
|     if (ctx->identifier(1)) | ||||
|     { | ||||
|       auto aliased = visitT<std::string>(ctx->identifier(1)); | ||||
|       return std::any(new ast::TraitAlias(name, aliased)); | ||||
|     } | ||||
| 
 | ||||
|     std::vector<std::unique_ptr<ast::FnDecl>> fns; | ||||
| 
 | ||||
|     for (size_t i = 0; ctx->fnDecl(i); i++) | ||||
|       fns.push_back(visitU<ast::FnDecl>(ctx->fnDecl(i))); | ||||
| 
 | ||||
|     return std::any(new ast::TraitDef(name, fns)); | ||||
|   } | ||||
| 
 | ||||
|   virtual std::any visitTypeDef(plsmParser::TypeDefContext *ctx) override | ||||
|   { | ||||
|     auto name = visitT<std::string>(ctx->identifier()); | ||||
| 
 | ||||
|     if (ctx->type()) | ||||
|     { | ||||
|       auto gen = visitU<ast::Type>(ctx->type()); | ||||
|       return std::any(new ast::TypeAlias(name, gen)); | ||||
|     } | ||||
| 
 | ||||
|     std::vector<int> args; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| class ErrorListener : public antlr4::BaseErrorListener | ||||
| { | ||||
|   std::string *error; | ||||
| 
 | ||||
| public: | ||||
|   ErrorListener(std::string *error) : error(error) {} | ||||
| 
 | ||||
|   virtual void syntaxError(antlr4::Recognizer *recognizer, antlr4::Token *offendingSymbol, size_t line, size_t charPositionInLine, | ||||
|                            const std::string &msg, std::exception_ptr e) override | ||||
|   { | ||||
|     std::stringstream ss; | ||||
|     ss << "line " << line << ":" << charPositionInLine << ": " << msg; | ||||
|     *error = ss.str(); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| std::unique_ptr<ast::Module> | ||||
| plsm::parse(const std::string &input) | ||||
| { | ||||
|   auto istream = antlr4::ANTLRInputStream(input); | ||||
|   auto lexer = plsmLexer(&istream); | ||||
|   auto tokens = antlr4::CommonTokenStream(&lexer); | ||||
|   auto parser = plsmParser(&tokens); | ||||
| 
 | ||||
|   std::string error; | ||||
|   ErrorListener listener(&error); | ||||
|   parser.removeErrorListeners(); | ||||
|   parser.addErrorListener(&listener); | ||||
| 
 | ||||
|   auto tree = parser.module(); | ||||
| 
 | ||||
|   if (error.size()) | ||||
|     throw std::runtime_error(error); | ||||
| 
 | ||||
|   auto module = std::any_cast<ast::Module *>(Visitor().visitModule(tree)); | ||||
|   return std::unique_ptr<ast::Module>(module); | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<ast::Module> | ||||
| adscript::parse(const std::string &input) | ||||
| { | ||||
|   throw std::logic_error("adscript::parse not implemented"); | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,3 @@ | ||||
| #include "Parser.h" | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
| #include <sstream> | ||||
| @ -21,10 +19,10 @@ int main(int argc, char *argv[]) | ||||
|     exit(EXIT_FAILURE); | ||||
|   } | ||||
| 
 | ||||
|   auto module = Parser().parse(argv[1], readFile(argv[1])); | ||||
|   // auto module = Parser().parse(argv[1], readFile(argv[1]));
 | ||||
| 
 | ||||
|   auto fn = (ast::FnDecl *)module->stmts.at(0); | ||||
|   std::cout << fn->name << std::endl; | ||||
|   // auto fn = (ast::FnDecl *)module->stmts.at(0);
 | ||||
|   // std::cout << fn->name << std::endl;
 | ||||
| 
 | ||||
|   delete module; | ||||
|   // delete module;
 | ||||
| } | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								compiler/thirdparty/antlr-4.13.1-complete.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								compiler/thirdparty/antlr-4.13.1-complete.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -1,33 +1,38 @@ | ||||
| type Bool = { | ||||
|   declare unop ! Bool; | ||||
|   native unop ! Bool; | ||||
| 
 | ||||
|   declare binop &&[b Bool] Bool; | ||||
|   declare binop ||[b Bool] Bool; | ||||
|   native binop ||[Bool] Bool; | ||||
|   native binop &&[Bool] Bool; | ||||
| }; | ||||
| 
 | ||||
| type Byte = {}; | ||||
| 
 | ||||
| type Int = { | ||||
|   declare unop + Int; | ||||
|   declare unop - Int; | ||||
|   native unop + Int; | ||||
|   native unop - Int; | ||||
|   native unop ~ Int; | ||||
| 
 | ||||
|   declare binop ==[Int] Bool; | ||||
|   declare binop !=[Int] Bool; | ||||
|   declare binop >[Int] Bool; | ||||
|   declare binop <[Int] Bool; | ||||
|   declare binop >=[Int] Bool; | ||||
|   declare binop <=[Int] Bool; | ||||
|   native binop ==[Int] Bool; | ||||
|   native binop !=[Int] Bool; | ||||
|   native binop >[Int] Bool; | ||||
|   native binop <[Int] Bool; | ||||
|   native binop >=[Int] Bool; | ||||
|   native binop <=[Int] Bool; | ||||
| 
 | ||||
|   declare binop +[Int] Int; | ||||
|   declare binop -[Int] Int; | ||||
|   declare binop *[Int] Int; | ||||
|   declare binop /[Int] Int; | ||||
|   declare binop %[Int] Int; | ||||
|   native binop <<[Int] Int; | ||||
|   native binop >>[Int] Int; | ||||
|   native binop |[Int] Int; | ||||
|   native binop &[Int] Int; | ||||
| 
 | ||||
|   declare factory [f Float]; | ||||
|   declare factory []; | ||||
|   native binop +[Int] Int; | ||||
|   native binop -[Int] Int; | ||||
|   native binop *[Int] Int; | ||||
|   native binop /[Int] Int; | ||||
|   native binop %[Int] Int; | ||||
| 
 | ||||
|   declare fn str[] String;  | ||||
|   fn str[] String;  | ||||
| }; | ||||
| 
 | ||||
| trait List{T} = { | ||||
|   fn | ||||
| type Float = { | ||||
| 
 | ||||
| }; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ludwig Lehnert
						Ludwig Lehnert