extended ANTLR visitor; added llvm-project
This commit is contained in:
		
							parent
							
								
									f45adb1810
								
							
						
					
					
						commit
						34160a03af
					
				
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | [submodule "compiler/thirdparty/llvm-project"] | ||||||
|  | 	path = compiler/thirdparty/llvm-project | ||||||
|  | 	url = https://github.com/llvm/llvm-project.git | ||||||
							
								
								
									
										3
									
								
								compiler/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								compiler/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -6,3 +6,6 @@ | |||||||
| # antlr-generated files | # antlr-generated files | ||||||
| plsm*.h | plsm*.h | ||||||
| plsm*.cpp | plsm*.cpp | ||||||
|  | 
 | ||||||
|  | # coredumps | ||||||
|  | vgcore.* | ||||||
|  | |||||||
| @ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.25) | |||||||
| 
 | 
 | ||||||
| project(plasmatum) | project(plasmatum) | ||||||
| 
 | 
 | ||||||
|  | set(CMAKE_BUILD_TYPE Debug) | ||||||
|  | 
 | ||||||
| set(CMAKE_CXX_STANDARD 23) | set(CMAKE_CXX_STANDARD 23) | ||||||
| set(SRC_DIR ${CMAKE_SOURCE_DIR}/src) | set(SRC_DIR ${CMAKE_SOURCE_DIR}/src) | ||||||
| set(INC_DIR ${CMAKE_SOURCE_DIR}/include) | set(INC_DIR ${CMAKE_SOURCE_DIR}/include) | ||||||
|  | |||||||
| @ -1,12 +1,33 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <utility> | ||||||
|  | #include <string> | ||||||
|  | #include <functional> | ||||||
|  | 
 | ||||||
|  | #define LOC_ARG const Location &location | ||||||
|  | 
 | ||||||
| namespace ast | namespace ast | ||||||
| { | { | ||||||
|  |   class Location | ||||||
|  |   { | ||||||
|  |   public: | ||||||
|  |     Location(const std::string &file, std::pair<size_t, size_t> start, std::pair<size_t, size_t> end) | ||||||
|  |         : file(file), start(start), end(end) {} | ||||||
|  | 
 | ||||||
|  |     const std::string file; | ||||||
|  |     const std::pair<size_t, size_t> start, end; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   class ASTNode |   class ASTNode | ||||||
|   { |   { | ||||||
|   public: |   public: | ||||||
|  |     ASTNode(LOC_ARG) : location(location) {} | ||||||
|     virtual ~ASTNode() = default; |     virtual ~ASTNode() = default; | ||||||
| 
 | 
 | ||||||
|  |     const Location location; | ||||||
|  | 
 | ||||||
|  |     virtual std::string str() = 0; | ||||||
|  | 
 | ||||||
|     virtual bool isExpr() { return false; } |     virtual bool isExpr() { return false; } | ||||||
|     virtual bool isStmt() { return false; } |     virtual bool isStmt() { return false; } | ||||||
|     virtual bool isType() { return false; } |     virtual bool isType() { return false; } | ||||||
| @ -15,18 +36,21 @@ namespace ast | |||||||
|   class Expr : public ASTNode |   class Expr : public ASTNode | ||||||
|   { |   { | ||||||
|   public: |   public: | ||||||
|  |     Expr(LOC_ARG) : ASTNode(location) {} | ||||||
|     virtual bool isExpr() override { return true; } |     virtual bool isExpr() override { return true; } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   class Stmt : public ASTNode |   class Stmt : public ASTNode | ||||||
|   { |   { | ||||||
|   public: |   public: | ||||||
|  |     Stmt(LOC_ARG) : ASTNode(location) {} | ||||||
|     virtual bool isStmt() override { return true; } |     virtual bool isStmt() override { return true; } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   class Type : public ASTNode |   class Type : public ASTNode | ||||||
|   { |   { | ||||||
|   public: |   public: | ||||||
|  |     Type(LOC_ARG) : ASTNode(location) {} | ||||||
|     virtual bool isType() override { return true; } |     virtual bool isType() override { return true; } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -7,11 +7,13 @@ | |||||||
| #include "Expr/Call.h" | #include "Expr/Call.h" | ||||||
| #include "Expr/Closure.h" | #include "Expr/Closure.h" | ||||||
| #include "Expr/Identifier.h" | #include "Expr/Identifier.h" | ||||||
|  | #include "Expr/PropExpr.h" | ||||||
|  | #include "Expr/Tuple.h" | ||||||
| #include "Expr/UnaryExpr.h" | #include "Expr/UnaryExpr.h" | ||||||
| #include "Expr/Value.h" | #include "Expr/Value.h" | ||||||
| 
 | 
 | ||||||
| #include "Stmt/ExprStmt.h" | #include "Stmt/ExprStmt.h" | ||||||
| #include "Stmt/FnDecl.h" | #include "Stmt/FnDef.h" | ||||||
| #include "Stmt/TraitAlias.h" | #include "Stmt/TraitAlias.h" | ||||||
| #include "Stmt/TraitDef.h" | #include "Stmt/TraitDef.h" | ||||||
| #include "Stmt/TypeAlias.h" | #include "Stmt/TypeAlias.h" | ||||||
|  | |||||||
| @ -12,8 +12,18 @@ namespace ast | |||||||
|     const std::unique_ptr<Expr> left, right; |     const std::unique_ptr<Expr> left, right; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     BinExpr(std::unique_ptr<Expr> &left, const std::string &op, std::unique_ptr<Expr> &right) |     BinExpr(LOC_ARG, std::unique_ptr<Expr> &left, const std::string &op, std::unique_ptr<Expr> &right) | ||||||
|         : left(std::move(left)), op(op), right(std::move(right)) {} |         : Expr(location), left(std::move(left)), op(op), right(std::move(right)) {} | ||||||
|  | 
 | ||||||
|  |     virtual std::string str(size_t indent, size_t tabstop) | ||||||
|  |     { | ||||||
|  |       return (std::stringstream() << "BinExpr(" | ||||||
|  |                                   << "op=\"" << op << "\", " | ||||||
|  |                                   << "left=" << left->str() << ", " | ||||||
|  |                                   << "right=" << right->str() | ||||||
|  |                                   << ")") | ||||||
|  |           .str(); | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   class PrefExpr : public Expr |   class PrefExpr : public Expr | ||||||
| @ -21,6 +31,15 @@ namespace ast | |||||||
|     const std::unique_ptr<Expr> expr; |     const std::unique_ptr<Expr> expr; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     PrefExpr(std::unique_ptr<Expr> &expr) : expr(std::move(expr)) {} |     PrefExpr(LOC_ARG, std::unique_ptr<Expr> &expr) | ||||||
|  |         : Expr(location), expr(std::move(expr)) {} | ||||||
|  | 
 | ||||||
|  |     virtual std::string str() | ||||||
|  |     { | ||||||
|  |       return (std::stringstream() << "PrefExpr(" | ||||||
|  |                                   << "expr=" << expr->str() | ||||||
|  |                                   << ")") | ||||||
|  |           .str(); | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -9,8 +9,30 @@ namespace ast | |||||||
|   class BlockExpr : public Expr |   class BlockExpr : public Expr | ||||||
|   { |   { | ||||||
|     const std::vector<std::unique_ptr<Stmt>> stmts; |     const std::vector<std::unique_ptr<Stmt>> stmts; | ||||||
|  |     const std::unique_ptr<Expr> result; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     BlockExpr(std::vector<std::unique_ptr<Stmt>> &stmts) : stmts(std::move(stmts)) {} |     BlockExpr(LOC_ARG, std::vector<std::unique_ptr<Stmt>> &stmts, std::unique_ptr<Expr> &result) | ||||||
|  |         : Expr(location), stmts(std::move(stmts)), result(std::move(result)) {} | ||||||
|  | 
 | ||||||
|  |     virtual std::string str() | ||||||
|  |     { | ||||||
|  |       std::stringstream ss; | ||||||
|  |       ss << "BlockExpr("; | ||||||
|  | 
 | ||||||
|  |       ss << "stmts=["; | ||||||
|  |       for (size_t i = 0; i < stmts.size(); i++) | ||||||
|  |       { | ||||||
|  |         ss << stmts[i]->str(); | ||||||
|  |         if (i != stmts.size() - 1) | ||||||
|  |           ss << ", "; | ||||||
|  |       } | ||||||
|  |       ss << "], "; | ||||||
|  | 
 | ||||||
|  |       ss << "result=" << result->str(); | ||||||
|  |       ss << ")"; | ||||||
|  | 
 | ||||||
|  |       return ss.str(); | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -12,7 +12,28 @@ namespace ast | |||||||
|     const std::vector<std::unique_ptr<Expr>> args; |     const std::vector<std::unique_ptr<Expr>> args; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     CallExpr(std::unique_ptr<Expr> &callee, std::vector<std::unique_ptr<Expr>> &args) |     CallExpr(LOC_ARG, std::unique_ptr<Expr> &callee, std::vector<std::unique_ptr<Expr>> &args) | ||||||
|         : callee(std::move(callee)), args(std::move(args)) {} |         : Expr(location), callee(std::move(callee)), args(std::move(args)) {} | ||||||
|  | 
 | ||||||
|  |     virtual std::string str() | ||||||
|  |     { | ||||||
|  |       std::stringstream ss; | ||||||
|  | 
 | ||||||
|  |       ss << "CallExpr("; | ||||||
|  |       ss << "callee=" << callee->str(); | ||||||
|  | 
 | ||||||
|  |       ss << "args=["; | ||||||
|  |       for (size_t i = 0; i < args.size(); i++) | ||||||
|  |       { | ||||||
|  |         ss << args[i]->str(); | ||||||
|  |         if (i != args.size() - 1) | ||||||
|  |           ss << ", "; | ||||||
|  |       } | ||||||
|  |       ss << "]"; | ||||||
|  | 
 | ||||||
|  |       ss << ")"; | ||||||
|  | 
 | ||||||
|  |       return ss.str(); | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -13,7 +13,26 @@ namespace ast | |||||||
|     const std::unique_ptr<Expr> body; |     const std::unique_ptr<Expr> body; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     Closure(std::vector<std::string> &args, std::unique_ptr<Expr> &body) |     Closure(LOC_ARG, std::vector<std::string> &args, std::unique_ptr<Expr> &body) | ||||||
|         : args(std::move(args)), body(std::move(body)) {} |         : Expr(location), args(std::move(args)), body(std::move(body)) {} | ||||||
|  | 
 | ||||||
|  |     virtual std::string str() | ||||||
|  |     { | ||||||
|  |       std::stringstream ss; | ||||||
|  | 
 | ||||||
|  |       ss << "CallExpr("; | ||||||
|  |       ss << "args=["; | ||||||
|  |       for (size_t i = 0; i < args.size(); i++) | ||||||
|  |       { | ||||||
|  |         ss << args[i]; | ||||||
|  |         if (i != args.size() - 1) | ||||||
|  |           ss << ", "; | ||||||
|  |       } | ||||||
|  |       ss << "], "; | ||||||
|  |       ss << "body=" << body->str(); | ||||||
|  |       ss << ")"; | ||||||
|  | 
 | ||||||
|  |       return ss.str(); | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -10,6 +10,12 @@ namespace ast | |||||||
|     const std::string name; |     const std::string name; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     Identifier(const std::string &name) : name(name) {} |     Identifier(LOC_ARG, const std::string &name) | ||||||
|  |         : Expr(location), name(name) {} | ||||||
|  | 
 | ||||||
|  |     virtual std::string str() | ||||||
|  |     { | ||||||
|  |       return "Identifier(" + name + ")"; | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
							
								
								
									
										27
									
								
								compiler/include/AST/Expr/PropExpr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								compiler/include/AST/Expr/PropExpr.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "AST/Base.h" | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | namespace ast | ||||||
|  | { | ||||||
|  |   class PropExpr : public Expr | ||||||
|  |   { | ||||||
|  |     const std::unique_ptr<Expr> expr; | ||||||
|  |     const std::string property; | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  |     PropExpr(LOC_ARG, std::unique_ptr<Expr> &expr, const std::string &property) | ||||||
|  |         : Expr(location), expr(std::move(expr)), property(property) {} | ||||||
|  | 
 | ||||||
|  |     virtual std::string str() | ||||||
|  |     { | ||||||
|  |       return (std::stringstream() << "PropExpr(" | ||||||
|  |                                   << "expr=" << expr->str() << ", " | ||||||
|  |                                   << "property=" << property | ||||||
|  |                                   << ")") | ||||||
|  |           .str(); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								compiler/include/AST/Expr/Tuple.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								compiler/include/AST/Expr/Tuple.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "AST/Base.h" | ||||||
|  | #include <vector> | ||||||
|  | #include <memory> | ||||||
|  | 
 | ||||||
|  | namespace ast | ||||||
|  | { | ||||||
|  |   class Tuple : public Expr | ||||||
|  |   { | ||||||
|  |     const std::vector<std::unique_ptr<Expr>> values; | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  |     Tuple(LOC_ARG, std::vector<std::unique_ptr<Expr>> &values) | ||||||
|  |         : Expr(location), values(std::move(values)) {} | ||||||
|  |   }; | ||||||
|  | } | ||||||
| @ -12,7 +12,7 @@ namespace ast | |||||||
|     const std::unique_ptr<Expr> expr; |     const std::unique_ptr<Expr> expr; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     UnaryExpr(const std::string &op, std::unique_ptr<Expr> &expr) |     UnaryExpr(LOC_ARG, const std::string &op, std::unique_ptr<Expr> &expr) | ||||||
|         : op(op), expr(std::move(expr)) {} |         : Expr(location), op(op), expr(std::move(expr)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -5,12 +5,19 @@ | |||||||
| 
 | 
 | ||||||
| namespace ast | namespace ast | ||||||
| { | { | ||||||
|  |   class NullValue : public Expr | ||||||
|  |   { | ||||||
|  |   public: | ||||||
|  |     NullValue(LOC_ARG) : Expr(location) {} | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   class IntValue : public Expr |   class IntValue : public Expr | ||||||
|   { |   { | ||||||
|     const int64_t value; |     const int64_t value; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     IntValue(int64_t value) : value(value) {} |     IntValue(LOC_ARG, int64_t value) | ||||||
|  |         : Expr(location), value(value) {} | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   class FloatValue : public Expr |   class FloatValue : public Expr | ||||||
| @ -18,6 +25,7 @@ namespace ast | |||||||
|     const double value; |     const double value; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     FloatValue(double value) : value(value) {} |     FloatValue(LOC_ARG, double value) | ||||||
|  |         : Expr(location), value(value) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ namespace ast | |||||||
|     const std::string moduleName; |     const std::string moduleName; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     Import(const std::string &moduleName) : moduleName(moduleName) {} |     Import(LOC_ARG, const std::string &moduleName) | ||||||
|  |         : ASTNode(location), moduleName(moduleName) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -10,11 +10,12 @@ namespace ast | |||||||
| 
 | 
 | ||||||
|   class Module : public ASTNode |   class Module : public ASTNode | ||||||
|   { |   { | ||||||
|  |     const std::string name; | ||||||
|     const std::vector<std::unique_ptr<Import>> imports; |     const std::vector<std::unique_ptr<Import>> imports; | ||||||
|     const std::vector<std::unique_ptr<Stmt>> stmts; |     const std::vector<std::unique_ptr<Stmt>> stmts; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     Module(std::vector<std::unique_ptr<Import>> &imports, std::vector<std::unique_ptr<Stmt>> &stmts) |     Module(LOC_ARG, const std::string &name, std::vector<std::unique_ptr<Import>> &imports, std::vector<std::unique_ptr<Stmt>> &stmts) | ||||||
|         : imports(std::move(imports)), stmts(std::move(stmts)) {} |         : ASTNode(location), name(name), imports(std::move(imports)), stmts(std::move(stmts)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -10,6 +10,7 @@ namespace ast | |||||||
|     const std::unique_ptr<Expr> expr; |     const std::unique_ptr<Expr> expr; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     ExprStmt(std::unique_ptr<Expr> &expr) : expr(std::move(expr)) {} |     ExprStmt(LOC_ARG, std::unique_ptr<Expr> &expr) | ||||||
|  |         : Stmt(location), expr(std::move(expr)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -1,23 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| 
 |  | ||||||
| #include "AST/Base.h" |  | ||||||
| #include <vector> |  | ||||||
| #include <string> |  | ||||||
| #include <memory> |  | ||||||
| 
 |  | ||||||
| namespace ast |  | ||||||
| { |  | ||||||
|   typedef std::pair<std::string, std::unique_ptr<Type>> FnArg; |  | ||||||
| 
 |  | ||||||
|   class FnDecl : public Stmt |  | ||||||
|   { |  | ||||||
|     const std::string name; |  | ||||||
|     const std::vector<FnArg> args; |  | ||||||
|     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)) {} |  | ||||||
|   }; |  | ||||||
| } |  | ||||||
							
								
								
									
										31
									
								
								compiler/include/AST/Stmt/FnDef.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								compiler/include/AST/Stmt/FnDef.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "AST/Base.h" | ||||||
|  | #include <vector> | ||||||
|  | #include <string> | ||||||
|  | #include <memory> | ||||||
|  | 
 | ||||||
|  | namespace ast | ||||||
|  | { | ||||||
|  |   class FnArg : public ASTNode | ||||||
|  |   { | ||||||
|  |     const std::string name; | ||||||
|  |     const std::unique_ptr<Type> type; | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  |     FnArg(LOC_ARG, const std::string &name, std::unique_ptr<Type> &type) | ||||||
|  |         : ASTNode(location), name(name), type(std::move(type)) {} | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   class FnDef : public Stmt | ||||||
|  |   { | ||||||
|  |     const std::string name; | ||||||
|  |     const std::vector<std::unique_ptr<FnArg>> args; | ||||||
|  |     const std::unique_ptr<Type> returnType; | ||||||
|  |     const std::unique_ptr<Expr> body; | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  |     FnDef(LOC_ARG, const std::string &name, std::vector<std::unique_ptr<FnArg>> &args, std::unique_ptr<Type> &returnType, std::unique_ptr<Expr> &body) | ||||||
|  |         : Stmt(location), name(name), args(std::move(args)), returnType(std::move(returnType)), body(std::move(body)) {} | ||||||
|  |   }; | ||||||
|  | } | ||||||
| @ -13,7 +13,7 @@ namespace ast | |||||||
|     const std::string aliased; |     const std::string aliased; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     TraitAlias(const std::string &alias, const std::string &aliased) |     TraitAlias(LOC_ARG, const std::string &alias, const std::string &aliased) | ||||||
|         : alias(alias), aliased(aliased) {} |         : Stmt(location), alias(alias), aliased(aliased) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -7,15 +7,15 @@ | |||||||
| 
 | 
 | ||||||
| namespace ast | namespace ast | ||||||
| { | { | ||||||
|   class FnDecl; |   class FnDef; | ||||||
| 
 | 
 | ||||||
|   class TraitDef : public Stmt |   class TraitDef : public Stmt | ||||||
|   { |   { | ||||||
|     const std::string name; |     const std::string name; | ||||||
|     const std::vector<std::unique_ptr<FnDecl>> traits; |     const std::vector<std::unique_ptr<FnDef>> traits; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     TraitDef(const std::string &name, std::vector<std::unique_ptr<FnDecl>> &traits) |     TraitDef(LOC_ARG, const std::string &name, std::vector<std::unique_ptr<FnDef>> &traits) | ||||||
|         : name(name), traits(std::move(traits)) {} |         : Stmt(location), name(name), traits(std::move(traits)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -13,7 +13,7 @@ namespace ast | |||||||
|     const std::unique_ptr<Type> type; |     const std::unique_ptr<Type> type; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     TypeAlias(const std::string &alias, std::unique_ptr<Type> &type) |     TypeAlias(LOC_ARG, const std::string &alias, std::unique_ptr<Type> &type) | ||||||
|         : alias(alias), type(std::move(type)) {} |         : Stmt(location), alias(alias), type(std::move(type)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -7,18 +7,17 @@ | |||||||
| 
 | 
 | ||||||
| namespace ast | namespace ast | ||||||
| { | { | ||||||
|   class FnDecl; |   class FnDef; | ||||||
| 
 |   class FnArg; | ||||||
|   typedef std::pair<std::string, std::unique_ptr<Type>> TypeAttr; |  | ||||||
| 
 | 
 | ||||||
|   class TypeDef : public Stmt |   class TypeDef : public Stmt | ||||||
|   { |   { | ||||||
|     const std::string name; |     const std::string name; | ||||||
|     const std::vector<TypeAttr> attrs; |     const std::vector<std::unique_ptr<FnArg>> attrs; | ||||||
|     const std::vector<std::unique_ptr<FnDecl>> members; |     const std::vector<std::unique_ptr<FnDef>> members; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     TypeDef(const std::string &name, std::vector<TypeAttr> &attrs, std::vector<std::unique_ptr<FnDecl>> &members) |     TypeDef(LOC_ARG, const std::string &name, std::vector<std::unique_ptr<FnArg>> &attrs, std::vector<std::unique_ptr<FnDef>> &members) | ||||||
|         : name(name), attrs(std::move(attrs)), members(std::move(members)) {} |         : Stmt(location), name(name), attrs(std::move(attrs)), members(std::move(members)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -13,7 +13,7 @@ namespace ast | |||||||
|     const std::unique_ptr<Expr> value; |     const std::unique_ptr<Expr> value; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     ValDecl(const std::string &name, std::unique_ptr<Type> &type, std::unique_ptr<Expr> &value) |     ValDecl(LOC_ARG, const std::string &name, std::unique_ptr<Type> &type, std::unique_ptr<Expr> &value) | ||||||
|         : name(name), type(std::move(type)), value(std::move(value)) {} |         : Stmt(location), name(name), type(std::move(type)), value(std::move(value)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -12,7 +12,7 @@ namespace ast | |||||||
|     const std::unique_ptr<Type> to; |     const std::unique_ptr<Type> to; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     ClosureType(std::vector<std::unique_ptr<Type>> &from, std::unique_ptr<Type> &to) |     ClosureType(LOC_ARG, std::vector<std::unique_ptr<Type>> &from, std::unique_ptr<Type> &to) | ||||||
|         : from(std::move(from)), to(std::move(to)) {} |         : Type(location), from(std::move(from)), to(std::move(to)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -13,7 +13,7 @@ namespace ast | |||||||
|     const std::vector<std::unique_ptr<Type>> types; |     const std::vector<std::unique_ptr<Type>> types; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     GenericType(const std::string &name, std::vector<std::unique_ptr<Type>> &types) |     GenericType(LOC_ARG, const std::string &name, std::vector<std::unique_ptr<Type>> &types) | ||||||
|         : name(name), types(std::move(types)) {} |         : Type(location), name(name), types(std::move(types)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ namespace ast | |||||||
|     const std::string name; |     const std::string name; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     NamedType(const std::string &name) : name(name) {} |     NamedType(LOC_ARG, const std::string &name) | ||||||
|  |         : Type(location), name(name) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -11,7 +11,7 @@ namespace ast | |||||||
|     const std::vector<std::unique_ptr<Type>> types; |     const std::vector<std::unique_ptr<Type>> types; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|     TupleType(std::vector<std::unique_ptr<Type>> &types) |     TupleType(LOC_ARG, std::vector<std::unique_ptr<Type>> &types) | ||||||
|         : types(std::move(types)) {} |         : Type(location), types(std::move(types)) {} | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| @ -9,10 +9,10 @@ | |||||||
| 
 | 
 | ||||||
| namespace plsm | namespace plsm | ||||||
| { | { | ||||||
|   std::unique_ptr<ast::Module> parse(const std::string &input); |   std::unique_ptr<ast::Module> parse(const std::string &file, const std::string &input); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| namespace adscript | namespace adscript | ||||||
| { | { | ||||||
|   std::unique_ptr<ast::Module> parse(const std::string &input); |   std::unique_ptr<ast::Module> parse(const std::string &file, const std::string &input); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,9 +1,10 @@ | |||||||
| grammar plsm; | grammar plsm; | ||||||
| 
 | 
 | ||||||
| module: moduleImport* (let | fnDecl | fnDef | traitDef | typeDef)*; | module: MODULE identifier ';' moduleImport* moduleStmt*; | ||||||
| 
 | 
 | ||||||
| moduleImport: IMPORT moduleName ';'; | moduleImport: IMPORT importName ';'; | ||||||
| moduleName: identifier ('.' identifier)*; | importName: identifier ('/' identifier)*; | ||||||
|  | moduleStmt: let | fnDecl | fnDef | traitDef | typeDef; | ||||||
| 
 | 
 | ||||||
| traitDef: TRAIT identifier '=' identifier ';' | traitDef: TRAIT identifier '=' identifier ';' | ||||||
|         | TRAIT identifier '=' '{' (fnDecl)* '}' ';'; |         | TRAIT identifier '=' '{' (fnDecl)* '}' ';'; | ||||||
| @ -21,23 +22,22 @@ let: LET identifier type? '=' expr ';'; | |||||||
| 
 | 
 | ||||||
| exprStmt: expr ';'; | exprStmt: expr ';'; | ||||||
| 
 | 
 | ||||||
| type: type2; | type: type1; // novisit | ||||||
| type2: type1 | type1: type0 | ||||||
|      | '(' type ')' |      | '(' type ')' | ||||||
|      | '(' tupleTypeList ')'          // tuple |      | '(' tupleTypeList ')'          // tuple | ||||||
|      | '[' typeList? ']' '->' type;   // closure |      | '[' typeList? ']' '->' type;   // closure | ||||||
| type1: type0 | type0: identifier | ||||||
|      | type0 '{' typeList '}';        // generic |      | identifier '{' typeList '}';   // generic | ||||||
| type0: identifier; |  | ||||||
| 
 | 
 | ||||||
| tupleTypeList: type ',' type (',' type)*; | tupleTypeList: type (',' type)+; | ||||||
| typeList: type (',' type)*; | typeList: type (',' type)*; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| expr: expr3; | expr: expr3; // novisit | ||||||
| expr3: expr2 | expr3: expr2 | ||||||
|      | '[' identifierList? ']' '->' expr     // closure |      | '[' identifierList? ']' '->' expr     // closure | ||||||
|      | '{' (let | exprStmt | fnDef)* (expr ';') '}'; |      | '{' blockStmt* (expr ';') '}'; | ||||||
| expr2: expr1 | expr2: expr1 | ||||||
|      | expr2 operator expr1;        // binary expr |      | expr2 operator expr1;        // binary expr | ||||||
| expr1: expr0 | expr1: expr0 | ||||||
| @ -46,19 +46,22 @@ expr0: literal | |||||||
|      | identifier |      | identifier | ||||||
|      | expr0 '[' exprList? ']'      // fn call |      | expr0 '[' exprList? ']'      // fn call | ||||||
|      | '(' expr ')' |      | '(' expr ')' | ||||||
|  |      | '(' tupleExprList ')'        // tuple | ||||||
|      | expr0 '.' identifier;        // property accessor |      | expr0 '.' identifier;        // property accessor | ||||||
| 
 | 
 | ||||||
|  | blockStmt: let | exprStmt | fnDef; | ||||||
|  | tupleExprList: expr (',' expr)+; | ||||||
| exprList: expr (',' expr)*; | exprList: expr (',' expr)*; | ||||||
| 
 | 
 | ||||||
| identifierList: identifier (',' identifier)*; | identifierList: identifier (',' identifier)*; | ||||||
| 
 | 
 | ||||||
| literal: 'null' | INT_LIT | FLOAT_LIT; | literal: NULL='null' | INT_LIT | FLOAT_LIT; | ||||||
| 
 | 
 | ||||||
| operator: '=' | '->' | operator: '=' | '->' | ||||||
|         | OPERATOR; |         | OPERATOR; | ||||||
| 
 | 
 | ||||||
| identifier: keyword | IDENTIFIER; | identifier: keyword | IDENTIFIER; | ||||||
| keyword: BINOP | FN | IMPORT | LET | NATIVE | TRAIT | TYPE | UNOP; | keyword: BINOP | FN | IMPORT | LET | MODULE | NATIVE | TRAIT | TYPE | UNOP; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| INT_LIT: [0-9]+ | '0x' [0-9a-fA-F]+ | '0o' [0-7]+ | '0b' [01]+; | INT_LIT: [0-9]+ | '0x' [0-9a-fA-F]+ | '0o' [0-7]+ | '0b' [01]+; | ||||||
| @ -70,9 +73,12 @@ BINOP: 'binop'; | |||||||
| FN: 'fn'; | FN: 'fn'; | ||||||
| IMPORT: 'import'; | IMPORT: 'import'; | ||||||
| LET: 'let'; | LET: 'let'; | ||||||
|  | MODULE: 'module'; | ||||||
| NATIVE: 'native'; | NATIVE: 'native'; | ||||||
| TRAIT: 'trait'; | TRAIT: 'trait'; | ||||||
| TYPE: 'type'; | TYPE: 'type'; | ||||||
| UNOP: 'unop'; | UNOP: 'unop'; | ||||||
| 
 | 
 | ||||||
| IDENTIFIER: [a-zA-Z_] [a-zA-Z0-9_]*; | IDENTIFIER: [a-zA-Z_] [a-zA-Z0-9_]*; | ||||||
|  | 
 | ||||||
|  | WHITESPACE: [ \r\n\t]+ -> skip; | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								compiler/setup/llvm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								compiler/setup/llvm
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  | 
 | ||||||
|  | BASEDIR=$(dirname $(realpath "$0")) | ||||||
|  | 
 | ||||||
|  | cd "$BASEDIR/../compiler/thirdparty/llvm-project" | ||||||
|  | 
 | ||||||
|  | mkdir -p build | ||||||
|  | cd build | ||||||
|  | 
 | ||||||
|  | cmake -G Ninja ../llvm \ | ||||||
|  |       -DLLVM_ENABLE_PROJECTS="mlir;llvm;lld" \ | ||||||
|  |       -DLLVM_BUILD_EXAMPLES=ON \ | ||||||
|  |       -DLLVM_TARGETS_TO_BUILD="Native;NVPTX;AMDGPU" \ | ||||||
|  |       -DCMAKE_BUILD_TYPE=Release \ | ||||||
|  |       -DLLVM_ENABLE_ASSERTIONS=ON | ||||||
|  | 
 | ||||||
|  | cmake --build . | ||||||
| @ -4,10 +4,45 @@ | |||||||
| 
 | 
 | ||||||
| #include <sstream> | #include <sstream> | ||||||
| 
 | 
 | ||||||
| class Visitor : public plsmBaseVisitor | class ErrorListener : public antlr4::BaseErrorListener | ||||||
| { | { | ||||||
|  |   std::string file; | ||||||
|  |   std::string *error; | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
|   Visitor() {} |   ErrorListener(const std::string &file, std::string *error) | ||||||
|  |       : file(file), 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 << file << ": line " << line << ":" << charPositionInLine << ": " << msg; | ||||||
|  |     *error = ss.str(); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | namespace plsm | ||||||
|  | { | ||||||
|  |   class Visitor : public plsmBaseVisitor | ||||||
|  |   { | ||||||
|  |   private: | ||||||
|  |     const std::string file; | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  |     Visitor(const std::string &file) : file(file) {} | ||||||
|  | 
 | ||||||
|  |     inline ast::Location loc(antlr4::ParserRuleContext *ctx) | ||||||
|  |     { | ||||||
|  |       return ast::Location( | ||||||
|  |           file, | ||||||
|  |           std::pair<size_t, size_t>( | ||||||
|  |               ctx->getStart()->getLine(), | ||||||
|  |               ctx->getStart()->getCharPositionInLine()), | ||||||
|  |           std::pair<size_t, size_t>( | ||||||
|  |               ctx->getStop()->getLine(), | ||||||
|  |               ctx->getStop()->getCharPositionInLine())); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     template <typename T> |     template <typename T> | ||||||
|     inline T visitT(antlr4::tree::ParseTree *ctx) |     inline T visitT(antlr4::tree::ParseTree *ctx) | ||||||
| @ -21,97 +56,435 @@ public: | |||||||
|       return std::unique_ptr<T>(visitT<T *>(ctx)); |       return std::unique_ptr<T>(visitT<T *>(ctx)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|   virtual std::any visitModule(plsmParser::ModuleContext *ctx) override |     template <typename T> | ||||||
|  |     inline std::vector<std::unique_ptr<T>> visitVU(antlr4::tree::ParseTree *ctx) | ||||||
|     { |     { | ||||||
|     std::vector<std::unique_ptr<ast::Import>> imports; |       std::vector<std::unique_ptr<T>> res; | ||||||
|     std::vector<std::unique_ptr<ast::Stmt>> stmts; |       for (auto &el : visitT<std::vector<T *>>(ctx)) | ||||||
| 
 |         res.push_back(std::unique_ptr<T>(el)); | ||||||
|     for (auto &child : ctx->children) |       return res; | ||||||
|     { |  | ||||||
|       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 visitModule(plsmParser::ModuleContext *ctx) override | ||||||
|  |     { | ||||||
|  |       auto name = ctx->identifier()->getText(); | ||||||
|  | 
 | ||||||
|  |       std::vector<std::unique_ptr<ast::Import>> imports; | ||||||
|  |       for (auto &import : ctx->moduleImport()) | ||||||
|  |         imports.push_back(visitU<ast::Import>(import)); | ||||||
|  | 
 | ||||||
|  |       std::vector<std::unique_ptr<ast::Stmt>> stmts; | ||||||
|  |       for (auto &stmt : ctx->moduleStmt()) | ||||||
|  |         stmts.push_back(visitU<ast::Stmt>(stmt)); | ||||||
|  | 
 | ||||||
|  |       return std::any(new ast::Module(loc(ctx), name, imports, stmts)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     virtual std::any visitModuleImport(plsmParser::ModuleImportContext *ctx) override |     virtual std::any visitModuleImport(plsmParser::ModuleImportContext *ctx) override | ||||||
|     { |     { | ||||||
|     return std::any(new ast::Import(visitT<std::string>(ctx->moduleName()))); |       return std::any(new ast::Import(loc(ctx), visitT<std::string>(ctx->importName()))); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|   virtual std::any visitModuleName(plsmParser::ModuleNameContext *ctx) override |     virtual std::any visitImportName(plsmParser::ImportNameContext *ctx) override | ||||||
|     { |     { | ||||||
|     auto name = visitT<std::string>(ctx->identifier(0)); |       auto name = ctx->identifier(0)->getText(); | ||||||
| 
 | 
 | ||||||
|     for (size_t i = 1; ctx->identifier(i); i++) |       for (size_t i = 1; i < ctx->identifier().size(); i++) | ||||||
|     { |         name = name + "/" + ctx->identifier(i)->getText(); | ||||||
|       name = name + "." + visitT<std::string>(ctx->identifier(i)); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|       return std::any(name); |       return std::any(name); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     virtual std::any visitModuleStmt(plsmParser::ModuleStmtContext *ctx) override | ||||||
|  |     { | ||||||
|  |       ast::Stmt *stmt; | ||||||
|  | 
 | ||||||
|  |       if (ctx->let()) | ||||||
|  |         stmt = (ast::Stmt *)visitT<ast::ValDecl *>(ctx->let()); | ||||||
|  |       if (ctx->fnDecl()) | ||||||
|  |         stmt = (ast::Stmt *)visitT<ast::FnDef *>(ctx->fnDecl()); | ||||||
|  |       if (ctx->fnDef()) | ||||||
|  |         stmt = (ast::Stmt *)visitT<ast::FnDef *>(ctx->fnDef()); | ||||||
|  |       if (ctx->traitDef()) | ||||||
|  |         stmt = (ast::Stmt *)visitT<ast::Stmt *>(ctx->traitDef()); | ||||||
|  |       if (ctx->typeDef()) | ||||||
|  |         stmt = (ast::Stmt *)visitT<ast::Stmt *>(ctx->typeDef()); | ||||||
|  | 
 | ||||||
|  |       return std::any(stmt); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     virtual std::any visitTraitDef(plsmParser::TraitDefContext *ctx) override |     virtual std::any visitTraitDef(plsmParser::TraitDefContext *ctx) override | ||||||
|     { |     { | ||||||
|     auto name = visitT<std::string>(ctx->identifier(0)); |       auto name = ctx->identifier(0)->getText(); | ||||||
| 
 | 
 | ||||||
|       if (ctx->identifier(1)) |       if (ctx->identifier(1)) | ||||||
|       { |       { | ||||||
|       auto aliased = visitT<std::string>(ctx->identifier(1)); |         auto aliased = ctx->identifier(1)->getText(); | ||||||
|       return std::any(new ast::TraitAlias(name, aliased)); |         return std::any((ast::Stmt *)new ast::TraitAlias(loc(ctx), name, aliased)); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|     std::vector<std::unique_ptr<ast::FnDecl>> fns; |       std::vector<std::unique_ptr<ast::FnDef>> fns; | ||||||
|  |       for (auto &decl : ctx->fnDecl()) | ||||||
|  |         fns.push_back(visitU<ast::FnDef>(decl)); | ||||||
| 
 | 
 | ||||||
|     for (size_t i = 0; ctx->fnDecl(i); i++) |       return std::any((ast::Stmt *)new ast::TraitDef(loc(ctx), name, fns)); | ||||||
|       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 |     virtual std::any visitTypeDef(plsmParser::TypeDefContext *ctx) override | ||||||
|     { |     { | ||||||
|     auto name = visitT<std::string>(ctx->identifier()); |       auto name = ctx->identifier()->getText(); | ||||||
| 
 | 
 | ||||||
|       if (ctx->type()) |       if (ctx->type()) | ||||||
|       { |       { | ||||||
|         auto gen = visitU<ast::Type>(ctx->type()); |         auto gen = visitU<ast::Type>(ctx->type()); | ||||||
|       return std::any(new ast::TypeAlias(name, gen)); |         return std::any((ast::Stmt *)new ast::TypeAlias(loc(ctx), name, gen)); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|     std::vector<int> args; |       std::vector<std::unique_ptr<ast::FnArg>> attrs; | ||||||
|  |       if (ctx->fnDefArgs()) | ||||||
|  |         attrs = visitVU<ast::FnArg>(ctx->fnDefArgs()); | ||||||
|  | 
 | ||||||
|  |       std::vector<std::unique_ptr<ast::FnDef>> members; | ||||||
|  |       for (auto &def : ctx->fnDef()) | ||||||
|  |         members.push_back(visitU<ast::FnDef>(def)); | ||||||
|  |       for (auto &decl : ctx->fnDecl()) | ||||||
|  |         members.push_back(visitU<ast::FnDef>(decl)); | ||||||
|  | 
 | ||||||
|  |       return std::any((ast::Stmt *)new ast::TypeDef(loc(ctx), name, attrs, members)); | ||||||
|     } |     } | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| class ErrorListener : public antlr4::BaseErrorListener |     virtual std::any visitFnDef(plsmParser::FnDefContext *ctx) override | ||||||
| { |  | ||||||
|   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; |       auto name = ctx->identifier()->getText(); | ||||||
|     ss << "line " << line << ":" << charPositionInLine << ": " << msg; |  | ||||||
|     *error = ss.str(); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| std::unique_ptr<ast::Module> |       std::vector<std::unique_ptr<ast::FnArg>> args; | ||||||
| plsm::parse(const std::string &input) |       if (ctx->fnDefArgs()) | ||||||
| { |         args = std::move(visitVU<ast::FnArg>(ctx->fnDefArgs())); | ||||||
|  | 
 | ||||||
|  |       auto returnType = visitU<ast::Type>(ctx->type()); | ||||||
|  |       auto body = visitU<ast::Expr>(ctx->expr()); | ||||||
|  | 
 | ||||||
|  |       return std::any(new ast::FnDef(loc(ctx), name, args, returnType, body)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitFnDefArgs(plsmParser::FnDefArgsContext *ctx) override | ||||||
|  |     { | ||||||
|  |       std::vector<ast::FnArg *> args; | ||||||
|  | 
 | ||||||
|  |       for (size_t i = 0; i < ctx->children.size(); i += 3) | ||||||
|  |       { | ||||||
|  |         auto name = ctx->children[i]->getText(); | ||||||
|  |         auto type = visitU<ast::Type>(ctx->children[i + 1]); | ||||||
|  |         args.push_back(new ast::FnArg(loc(ctx), name, type)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return std::any(args); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitFnDecl(plsmParser::FnDeclContext *ctx) override | ||||||
|  |     { | ||||||
|  |       auto name = ctx->identifier()->getText(); | ||||||
|  | 
 | ||||||
|  |       std::vector<std::unique_ptr<ast::FnArg>> args; | ||||||
|  |       if (ctx->fnDeclArgs()) | ||||||
|  |         args = visitVU<ast::FnArg>(ctx->fnDeclArgs()); | ||||||
|  | 
 | ||||||
|  |       auto returnType = visitU<ast::Type>(ctx->type()); | ||||||
|  |       auto body = std::unique_ptr<ast::Expr>(nullptr); | ||||||
|  | 
 | ||||||
|  |       return std::any(new ast::FnDef(loc(ctx), name, args, returnType, body)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitFnDeclArgs(plsmParser::FnDeclArgsContext *ctx) override | ||||||
|  |     { | ||||||
|  |       std::vector<ast::FnArg *> args; | ||||||
|  | 
 | ||||||
|  |       for (size_t i = 0; i < ctx->children.size(); i++) | ||||||
|  |       { | ||||||
|  |         std::string name; | ||||||
|  |         if (dynamic_cast<plsmParser::IdentifierContext *>(ctx->children[i])) | ||||||
|  |           name = ctx->children[i++]->getText(); | ||||||
|  | 
 | ||||||
|  |         auto type = visitU<ast::Type>(ctx->children[i++]); | ||||||
|  | 
 | ||||||
|  |         args.push_back(new ast::FnArg(loc(ctx), name, type)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return std::any(args); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitLet(plsmParser::LetContext *ctx) override | ||||||
|  |     { | ||||||
|  |       auto name = ctx->identifier()->getText(); | ||||||
|  | 
 | ||||||
|  |       std::unique_ptr<ast::Type> type(nullptr); | ||||||
|  |       if (ctx->type()) | ||||||
|  |         type = visitU<ast::Type>(ctx->type()); | ||||||
|  | 
 | ||||||
|  |       auto expr = visitU<ast::Expr>(ctx->expr()); | ||||||
|  | 
 | ||||||
|  |       return std::any(new ast::ValDecl(loc(ctx), name, type, expr)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitExprStmt(plsmParser::ExprStmtContext *ctx) override | ||||||
|  |     { | ||||||
|  |       auto expr = visitU<ast::Expr>(ctx->expr()); | ||||||
|  |       return std::any(new ast::ExprStmt(loc(ctx), expr)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitType1(plsmParser::Type1Context *ctx) override | ||||||
|  |     { | ||||||
|  |       if (ctx->type0()) | ||||||
|  |         return visit(ctx->type0()); | ||||||
|  | 
 | ||||||
|  |       if (ctx->children[0]->getText() == "(") | ||||||
|  |       { | ||||||
|  |         if (ctx->type()) | ||||||
|  |           return visit(ctx->type()); | ||||||
|  | 
 | ||||||
|  |         if (ctx->tupleTypeList()) | ||||||
|  |         { | ||||||
|  |           auto types = visitVU<ast::Type>(ctx->tupleTypeList()); | ||||||
|  |           return std::any((ast::Type *)new ast::TupleType(loc(ctx), types)); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (ctx->children[0]->getText() == "[") | ||||||
|  |       { | ||||||
|  |         std::vector<std::unique_ptr<ast::Type>> args; | ||||||
|  |         if (ctx->typeList()) | ||||||
|  |           args = visitVU<ast::Type>(ctx->typeList()); | ||||||
|  | 
 | ||||||
|  |         auto returnType = visitU<ast::Type>(ctx->type()); | ||||||
|  | 
 | ||||||
|  |         return std::any((ast::Type *)new ast::ClosureType(loc(ctx), args, returnType)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       throw std::logic_error("type2 not implemented"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitType0(plsmParser::Type0Context *ctx) override | ||||||
|  |     { | ||||||
|  |       auto name = ctx->identifier()->getText(); | ||||||
|  | 
 | ||||||
|  |       if (ctx->typeList()) | ||||||
|  |       { | ||||||
|  |         auto types = visitVU<ast::Type>(ctx->typeList()); | ||||||
|  |         return std::any((ast::Type *)new ast::GenericType(loc(ctx), name, types)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return std::any((ast::Type *)new ast::NamedType(loc(ctx), name)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitTupleTypeList(plsmParser::TupleTypeListContext *ctx) override | ||||||
|  |     { | ||||||
|  |       std::vector<ast::Type *> types; | ||||||
|  |       for (auto &type : ctx->type()) | ||||||
|  |         types.push_back(visitT<ast::Type *>(type)); | ||||||
|  | 
 | ||||||
|  |       return std::any(types); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitTypeList(plsmParser::TypeListContext *ctx) override | ||||||
|  |     { | ||||||
|  |       std::vector<ast::Type *> types; | ||||||
|  |       for (auto &type : ctx->type()) | ||||||
|  |         types.push_back(visitT<ast::Type *>(type)); | ||||||
|  | 
 | ||||||
|  |       return std::any(types); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitExpr3(plsmParser::Expr3Context *ctx) override | ||||||
|  |     { | ||||||
|  |       if (ctx->expr2()) | ||||||
|  |         return visit(ctx->expr2()); | ||||||
|  | 
 | ||||||
|  |       // closure
 | ||||||
|  |       if (ctx->children[0]->getText() == "[") | ||||||
|  |       { | ||||||
|  |         std::vector<std::string> args; | ||||||
|  |         if (ctx->identifierList()) | ||||||
|  |           args = visitT<std::vector<std::string>>(ctx->identifierList()); | ||||||
|  | 
 | ||||||
|  |         auto body = visitU<ast::Expr>(ctx->expr()); | ||||||
|  | 
 | ||||||
|  |         return std::any((ast::Expr *)new ast::Closure(loc(ctx), args, body)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // block
 | ||||||
|  |       if (ctx->children[0]->getText() == "{") | ||||||
|  |       { | ||||||
|  |         std::vector<std::unique_ptr<ast::Stmt>> stmts; | ||||||
|  |         for (auto &stmt : ctx->blockStmt()) | ||||||
|  |           stmts.push_back(visitU<ast::Stmt>(stmt)); | ||||||
|  | 
 | ||||||
|  |         auto result = visitU<ast::Expr>(ctx->expr()); | ||||||
|  | 
 | ||||||
|  |         return std::any((ast::Expr *)new ast::BlockExpr(loc(ctx), stmts, result)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       throw std::logic_error("expr3 not implemented"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitExpr2(plsmParser::Expr2Context *ctx) override | ||||||
|  |     { | ||||||
|  |       if (ctx->expr2()) | ||||||
|  |       { | ||||||
|  |         auto left = visitU<ast::Expr>(ctx->expr2()); | ||||||
|  |         auto op = ctx->operator_()->getText(); | ||||||
|  |         auto right = visitU<ast::Expr>(ctx->expr1()); | ||||||
|  |         return std::any((ast::Expr *)new ast::BinExpr(loc(ctx), left, op, right)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return visit(ctx->expr1()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitExpr1(plsmParser::Expr1Context *ctx) override | ||||||
|  |     { | ||||||
|  |       if (ctx->operator_()) | ||||||
|  |       { | ||||||
|  |         auto op = ctx->operator_()->getText(); | ||||||
|  |         auto expr = visitU<ast::Expr>(ctx->expr0()); | ||||||
|  |         return std::any((ast::Expr *)new ast::UnaryExpr(loc(ctx), op, expr)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return visit(ctx->expr0()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitExpr0(plsmParser::Expr0Context *ctx) override | ||||||
|  |     { | ||||||
|  |       if (ctx->literal()) | ||||||
|  |         return visit(ctx->literal()); | ||||||
|  | 
 | ||||||
|  |       if (ctx->expr()) | ||||||
|  |       { | ||||||
|  |         auto expr = visitU<ast::Expr>(ctx->expr()); | ||||||
|  |         return std::any((ast::Expr *)new ast::PrefExpr(loc(ctx), expr)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (ctx->expr0()) | ||||||
|  |       { | ||||||
|  |         auto expr = visitU<ast::Expr>(ctx->expr0()); | ||||||
|  | 
 | ||||||
|  |         // property accessor
 | ||||||
|  |         if (ctx->identifier()) | ||||||
|  |         { | ||||||
|  |           auto name = ctx->identifier()->getText(); | ||||||
|  |           return std::any((ast::Expr *)new ast::PropExpr(loc(ctx), expr, name)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // function/closure call
 | ||||||
|  |         std::vector<std::unique_ptr<ast::Expr>> args; | ||||||
|  |         if (ctx->exprList()) | ||||||
|  |           args = visitVU<ast::Expr>(ctx->exprList()); | ||||||
|  | 
 | ||||||
|  |         return std::any((ast::Expr *)new ast::CallExpr(loc(ctx), expr, args)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // tuple
 | ||||||
|  |       if (ctx->tupleExprList()) | ||||||
|  |       { | ||||||
|  |         auto values = visitVU<ast::Expr>(ctx->tupleExprList()); | ||||||
|  |         return std::any((ast::Expr *)new ast::Tuple(loc(ctx), values)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // identifier
 | ||||||
|  |       if (ctx->identifier()) | ||||||
|  |       { | ||||||
|  |         auto name = ctx->identifier()->getText(); | ||||||
|  |         return std::any((ast::Expr *)new ast::Identifier(loc(ctx), name)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       throw std::logic_error("expr0 not implemented"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitBlockStmt(plsmParser::BlockStmtContext *ctx) override | ||||||
|  |     { | ||||||
|  |       ast::Stmt *stmt; | ||||||
|  | 
 | ||||||
|  |       if (ctx->let()) | ||||||
|  |         stmt = (ast::Stmt *)visitT<ast::ValDecl *>(ctx->let()); | ||||||
|  |       if (ctx->exprStmt()) | ||||||
|  |         stmt = (ast::Stmt *)visitT<ast::ExprStmt *>(ctx->exprStmt()); | ||||||
|  |       if (ctx->fnDef()) | ||||||
|  |         stmt = (ast::Stmt *)visitT<ast::FnDef *>(ctx->fnDef()); | ||||||
|  | 
 | ||||||
|  |       return std::any(stmt); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitTupleExprList(plsmParser::TupleExprListContext *ctx) override | ||||||
|  |     { | ||||||
|  |       std::vector<ast::Expr *> exprs; | ||||||
|  |       for (auto &expr : ctx->expr()) | ||||||
|  |         exprs.push_back(visitT<ast::Expr *>(expr)); | ||||||
|  | 
 | ||||||
|  |       return std::any(exprs); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitExprList(plsmParser::ExprListContext *ctx) override | ||||||
|  |     { | ||||||
|  |       std::vector<ast::Expr *> exprs; | ||||||
|  |       for (auto &expr : ctx->expr()) | ||||||
|  |         exprs.push_back(visitT<ast::Expr *>(expr)); | ||||||
|  | 
 | ||||||
|  |       return std::any(exprs); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitIdentifierList(plsmParser::IdentifierListContext *ctx) override | ||||||
|  |     { | ||||||
|  |       std::vector<std::string> identifiers; | ||||||
|  |       for (auto &identifier : ctx->identifier()) | ||||||
|  |         identifiers.push_back(visitT<std::string>(identifier)); | ||||||
|  | 
 | ||||||
|  |       return std::any(identifiers); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     virtual std::any visitLiteral(plsmParser::LiteralContext *ctx) override | ||||||
|  |     { | ||||||
|  |       if (ctx->NULL_) | ||||||
|  |         return std::any((ast::Expr *)new ast::NullValue(loc(ctx))); | ||||||
|  | 
 | ||||||
|  |       if (ctx->INT_LIT()) | ||||||
|  |       { | ||||||
|  |         auto text = ctx->INT_LIT()->getText(); | ||||||
|  | 
 | ||||||
|  |         int64_t value; | ||||||
|  | 
 | ||||||
|  |         if (!text.rfind("0x", 0)) | ||||||
|  |           value = std::strtol(text.substr(2).data(), NULL, 16); | ||||||
|  | 
 | ||||||
|  |         if (!text.rfind("0o", 0)) | ||||||
|  |           value = std::strtol(text.substr(2).data(), NULL, 8); | ||||||
|  | 
 | ||||||
|  |         if (!text.rfind("0b", 0)) | ||||||
|  |           value = std::strtol(text.substr(2).data(), NULL, 2); | ||||||
|  | 
 | ||||||
|  |         return std::any((ast::Expr *)new ast::IntValue(loc(ctx), value)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (ctx->FLOAT_LIT()) | ||||||
|  |       { | ||||||
|  |         auto text = ctx->FLOAT_LIT()->getText(); | ||||||
|  |         if (text.at(text.size() - 1) == '.') | ||||||
|  |           text += "0"; | ||||||
|  | 
 | ||||||
|  |         double value = std::strtod(text.data(), NULL); | ||||||
|  |         return std::any((ast::Expr *)new ast::FloatValue(loc(ctx), value)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       throw std::logic_error("literal not implemented"); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   std::unique_ptr<ast::Module> parse(const std::string &file, const std::string &input) | ||||||
|  |   { | ||||||
|     auto istream = antlr4::ANTLRInputStream(input); |     auto istream = antlr4::ANTLRInputStream(input); | ||||||
|     auto lexer = plsmLexer(&istream); |     auto lexer = plsmLexer(&istream); | ||||||
|     auto tokens = antlr4::CommonTokenStream(&lexer); |     auto tokens = antlr4::CommonTokenStream(&lexer); | ||||||
|     auto parser = plsmParser(&tokens); |     auto parser = plsmParser(&tokens); | ||||||
| 
 | 
 | ||||||
|     std::string error; |     std::string error; | ||||||
|   ErrorListener listener(&error); |     ErrorListener listener(file, &error); | ||||||
|     parser.removeErrorListeners(); |     parser.removeErrorListeners(); | ||||||
|     parser.addErrorListener(&listener); |     parser.addErrorListener(&listener); | ||||||
| 
 | 
 | ||||||
| @ -120,12 +493,13 @@ plsm::parse(const std::string &input) | |||||||
|     if (error.size()) |     if (error.size()) | ||||||
|       throw std::runtime_error(error); |       throw std::runtime_error(error); | ||||||
| 
 | 
 | ||||||
|   auto module = std::any_cast<ast::Module *>(Visitor().visitModule(tree)); |     auto module = std::any_cast<ast::Module *>(Visitor(file).visitModule(tree)); | ||||||
|     return std::unique_ptr<ast::Module>(module); |     return std::unique_ptr<ast::Module>(module); | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::unique_ptr<ast::Module> | std::unique_ptr<ast::Module> | ||||||
| adscript::parse(const std::string &input) | adscript::parse(const std::string &file, const std::string &input) | ||||||
| { | { | ||||||
|   throw std::logic_error("adscript::parse not implemented"); |   throw std::logic_error("adscript::parse not implemented"); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,13 +1,17 @@ | |||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <fstream> | #include <fstream> | ||||||
|  | #include <istream> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| 
 | 
 | ||||||
| static std::stringstream readFile(const std::string &path) | #include "Parser.h" | ||||||
|  | 
 | ||||||
|  | static std::string readFile(const std::string &path) | ||||||
| { | { | ||||||
|   std::ifstream t(path); |   std::ifstream f(path); | ||||||
|   std::stringstream buffer; |   auto data = (std::stringstream() << f.rdbuf()).str(); | ||||||
|   buffer << t.rdbuf(); |   f.close(); | ||||||
|   return buffer; | 
 | ||||||
|  |   return data; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int main(int argc, char *argv[]) | int main(int argc, char *argv[]) | ||||||
| @ -19,9 +23,23 @@ int main(int argc, char *argv[]) | |||||||
|     exit(EXIT_FAILURE); |     exit(EXIT_FAILURE); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   auto input = readFile(argv[1]); | ||||||
|  | 
 | ||||||
|  |   std::cout << input << std::endl; | ||||||
|  | 
 | ||||||
|  |   try | ||||||
|  |   { | ||||||
|  |     auto module = plsm::parse(argv[1], input); | ||||||
|  |   } | ||||||
|  |   catch (std::runtime_error &err) | ||||||
|  |   { | ||||||
|  |     std::cerr << err.what() << std::endl; | ||||||
|  |     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);
 |   // auto fn = (ast::FnDef *)module->stmts.at(0);
 | ||||||
|   // std::cout << fn->name << std::endl;
 |   // std::cout << fn->name << std::endl;
 | ||||||
| 
 | 
 | ||||||
|   // delete module;
 |   // delete module;
 | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								compiler/thirdparty/llvm-project
									
									
									
									
										vendored
									
									
										Submodule
									
								
							
							
								
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								compiler/thirdparty/llvm-project
									
									
									
									
										vendored
									
									
										Submodule
									
								
							| @ -0,0 +1 @@ | |||||||
|  | Subproject commit 525fe4492bbecf357d3580d879f2092bf99c12a2 | ||||||
| @ -1,6 +1,8 @@ | |||||||
| import test.test; | module test; | ||||||
| 
 | 
 | ||||||
| fn main[] Int = 42; | import lib/test; | ||||||
|  | 
 | ||||||
|  | fn main[test (Int, Int)] Int = 42; | ||||||
| 
 | 
 | ||||||
| fn test[b Int] Int = { | fn test[b Int] Int = { | ||||||
|   fn helper[] Int = b; |   fn helper[] Int = b; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ludwig Lehnert
						Ludwig Lehnert