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 | ||||
| plsm*.h | ||||
| plsm*.cpp | ||||
| 
 | ||||
| # coredumps | ||||
| vgcore.* | ||||
|  | ||||
| @ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.25) | ||||
| 
 | ||||
| project(plasmatum) | ||||
| 
 | ||||
| set(CMAKE_BUILD_TYPE Debug) | ||||
| 
 | ||||
| set(CMAKE_CXX_STANDARD 23) | ||||
| set(SRC_DIR ${CMAKE_SOURCE_DIR}/src) | ||||
| set(INC_DIR ${CMAKE_SOURCE_DIR}/include) | ||||
|  | ||||
| @ -1,12 +1,33 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <utility> | ||||
| #include <string> | ||||
| #include <functional> | ||||
| 
 | ||||
| #define LOC_ARG const Location &location | ||||
| 
 | ||||
| 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 | ||||
|   { | ||||
|   public: | ||||
|     ASTNode(LOC_ARG) : location(location) {} | ||||
|     virtual ~ASTNode() = default; | ||||
| 
 | ||||
|     const Location location; | ||||
| 
 | ||||
|     virtual std::string str() = 0; | ||||
| 
 | ||||
|     virtual bool isExpr() { return false; } | ||||
|     virtual bool isStmt() { return false; } | ||||
|     virtual bool isType() { return false; } | ||||
| @ -15,18 +36,21 @@ namespace ast | ||||
|   class Expr : public ASTNode | ||||
|   { | ||||
|   public: | ||||
|     Expr(LOC_ARG) : ASTNode(location) {} | ||||
|     virtual bool isExpr() override { return true; } | ||||
|   }; | ||||
| 
 | ||||
|   class Stmt : public ASTNode | ||||
|   { | ||||
|   public: | ||||
|     Stmt(LOC_ARG) : ASTNode(location) {} | ||||
|     virtual bool isStmt() override { return true; } | ||||
|   }; | ||||
| 
 | ||||
|   class Type : public ASTNode | ||||
|   { | ||||
|   public: | ||||
|     Type(LOC_ARG) : ASTNode(location) {} | ||||
|     virtual bool isType() override { return true; } | ||||
|   }; | ||||
| } | ||||
| @ -7,11 +7,13 @@ | ||||
| #include "Expr/Call.h" | ||||
| #include "Expr/Closure.h" | ||||
| #include "Expr/Identifier.h" | ||||
| #include "Expr/PropExpr.h" | ||||
| #include "Expr/Tuple.h" | ||||
| #include "Expr/UnaryExpr.h" | ||||
| #include "Expr/Value.h" | ||||
| 
 | ||||
| #include "Stmt/ExprStmt.h" | ||||
| #include "Stmt/FnDecl.h" | ||||
| #include "Stmt/FnDef.h" | ||||
| #include "Stmt/TraitAlias.h" | ||||
| #include "Stmt/TraitDef.h" | ||||
| #include "Stmt/TypeAlias.h" | ||||
|  | ||||
| @ -12,8 +12,18 @@ namespace ast | ||||
|     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)) {} | ||||
|     BinExpr(LOC_ARG, std::unique_ptr<Expr> &left, const std::string &op, std::unique_ptr<Expr> &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 | ||||
| @ -21,6 +31,15 @@ namespace ast | ||||
|     const std::unique_ptr<Expr> expr; | ||||
| 
 | ||||
|   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 | ||||
|   { | ||||
|     const std::vector<std::unique_ptr<Stmt>> stmts; | ||||
|     const std::unique_ptr<Expr> result; | ||||
| 
 | ||||
|   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; | ||||
| 
 | ||||
|   public: | ||||
|     CallExpr(std::unique_ptr<Expr> &callee, std::vector<std::unique_ptr<Expr>> &args) | ||||
|         : callee(std::move(callee)), args(std::move(args)) {} | ||||
|     CallExpr(LOC_ARG, std::unique_ptr<Expr> &callee, std::vector<std::unique_ptr<Expr>> &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; | ||||
| 
 | ||||
|   public: | ||||
|     Closure(std::vector<std::string> &args, std::unique_ptr<Expr> &body) | ||||
|         : args(std::move(args)), body(std::move(body)) {} | ||||
|     Closure(LOC_ARG, std::vector<std::string> &args, std::unique_ptr<Expr> &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; | ||||
| 
 | ||||
|   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; | ||||
| 
 | ||||
|   public: | ||||
|     UnaryExpr(const std::string &op, std::unique_ptr<Expr> &expr) | ||||
|         : op(op), expr(std::move(expr)) {} | ||||
|     UnaryExpr(LOC_ARG, const std::string &op, std::unique_ptr<Expr> &expr) | ||||
|         : Expr(location), op(op), expr(std::move(expr)) {} | ||||
|   }; | ||||
| } | ||||
| @ -5,12 +5,19 @@ | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class NullValue : public Expr | ||||
|   { | ||||
|   public: | ||||
|     NullValue(LOC_ARG) : Expr(location) {} | ||||
|   }; | ||||
| 
 | ||||
|   class IntValue : public Expr | ||||
|   { | ||||
|     const int64_t value; | ||||
| 
 | ||||
|   public: | ||||
|     IntValue(int64_t value) : value(value) {} | ||||
|     IntValue(LOC_ARG, int64_t value) | ||||
|         : Expr(location), value(value) {} | ||||
|   }; | ||||
| 
 | ||||
|   class FloatValue : public Expr | ||||
| @ -18,6 +25,7 @@ namespace ast | ||||
|     const double value; | ||||
| 
 | ||||
|   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; | ||||
| 
 | ||||
|   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 | ||||
|   { | ||||
|     const std::string name; | ||||
|     const std::vector<std::unique_ptr<Import>> imports; | ||||
|     const std::vector<std::unique_ptr<Stmt>> stmts; | ||||
| 
 | ||||
|   public: | ||||
|     Module(std::vector<std::unique_ptr<Import>> &imports, std::vector<std::unique_ptr<Stmt>> &stmts) | ||||
|         : imports(std::move(imports)), stmts(std::move(stmts)) {} | ||||
|     Module(LOC_ARG, const std::string &name, std::vector<std::unique_ptr<Import>> &imports, std::vector<std::unique_ptr<Stmt>> &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; | ||||
| 
 | ||||
|   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; | ||||
| 
 | ||||
|   public: | ||||
|     TraitAlias(const std::string &alias, const std::string &aliased) | ||||
|         : alias(alias), aliased(aliased) {} | ||||
|     TraitAlias(LOC_ARG, const std::string &alias, const std::string &aliased) | ||||
|         : Stmt(location), alias(alias), aliased(aliased) {} | ||||
|   }; | ||||
| } | ||||
| @ -7,15 +7,15 @@ | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class FnDecl; | ||||
|   class FnDef; | ||||
| 
 | ||||
|   class TraitDef : public Stmt | ||||
|   { | ||||
|     const std::string name; | ||||
|     const std::vector<std::unique_ptr<FnDecl>> traits; | ||||
|     const std::vector<std::unique_ptr<FnDef>> traits; | ||||
| 
 | ||||
|   public: | ||||
|     TraitDef(const std::string &name, std::vector<std::unique_ptr<FnDecl>> &traits) | ||||
|         : name(name), traits(std::move(traits)) {} | ||||
|     TraitDef(LOC_ARG, const std::string &name, std::vector<std::unique_ptr<FnDef>> &traits) | ||||
|         : Stmt(location), name(name), traits(std::move(traits)) {} | ||||
|   }; | ||||
| } | ||||
| @ -13,7 +13,7 @@ namespace ast | ||||
|     const std::unique_ptr<Type> type; | ||||
| 
 | ||||
|   public: | ||||
|     TypeAlias(const std::string &alias, std::unique_ptr<Type> &type) | ||||
|         : alias(alias), type(std::move(type)) {} | ||||
|     TypeAlias(LOC_ARG, const std::string &alias, std::unique_ptr<Type> &type) | ||||
|         : Stmt(location), alias(alias), type(std::move(type)) {} | ||||
|   }; | ||||
| } | ||||
| @ -7,18 +7,17 @@ | ||||
| 
 | ||||
| namespace ast | ||||
| { | ||||
|   class FnDecl; | ||||
| 
 | ||||
|   typedef std::pair<std::string, std::unique_ptr<Type>> TypeAttr; | ||||
|   class FnDef; | ||||
|   class FnArg; | ||||
| 
 | ||||
|   class TypeDef : public Stmt | ||||
|   { | ||||
|     const std::string name; | ||||
|     const std::vector<TypeAttr> attrs; | ||||
|     const std::vector<std::unique_ptr<FnDecl>> members; | ||||
|     const std::vector<std::unique_ptr<FnArg>> attrs; | ||||
|     const std::vector<std::unique_ptr<FnDef>> 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)) {} | ||||
|     TypeDef(LOC_ARG, const std::string &name, std::vector<std::unique_ptr<FnArg>> &attrs, std::vector<std::unique_ptr<FnDef>> &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; | ||||
| 
 | ||||
|   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)) {} | ||||
|     ValDecl(LOC_ARG, const std::string &name, std::unique_ptr<Type> &type, std::unique_ptr<Expr> &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; | ||||
| 
 | ||||
|   public: | ||||
|     ClosureType(std::vector<std::unique_ptr<Type>> &from, std::unique_ptr<Type> &to) | ||||
|         : from(std::move(from)), to(std::move(to)) {} | ||||
|     ClosureType(LOC_ARG, std::vector<std::unique_ptr<Type>> &from, std::unique_ptr<Type> &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; | ||||
| 
 | ||||
|   public: | ||||
|     GenericType(const std::string &name, std::vector<std::unique_ptr<Type>> &types) | ||||
|         : name(name), types(std::move(types)) {} | ||||
|     GenericType(LOC_ARG, const std::string &name, std::vector<std::unique_ptr<Type>> &types) | ||||
|         : Type(location), name(name), types(std::move(types)) {} | ||||
|   }; | ||||
| } | ||||
|  | ||||
| @ -10,6 +10,7 @@ namespace ast | ||||
|     const std::string name; | ||||
| 
 | ||||
|   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; | ||||
| 
 | ||||
|   public: | ||||
|     TupleType(std::vector<std::unique_ptr<Type>> &types) | ||||
|         : types(std::move(types)) {} | ||||
|     TupleType(LOC_ARG, std::vector<std::unique_ptr<Type>> &types) | ||||
|         : Type(location), types(std::move(types)) {} | ||||
|   }; | ||||
| } | ||||
| @ -9,10 +9,10 @@ | ||||
| 
 | ||||
| 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 | ||||
| { | ||||
|   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; | ||||
| 
 | ||||
| module: moduleImport* (let | fnDecl | fnDef | traitDef | typeDef)*; | ||||
| module: MODULE identifier ';' moduleImport* moduleStmt*; | ||||
| 
 | ||||
| moduleImport: IMPORT moduleName ';'; | ||||
| moduleName: identifier ('.' identifier)*; | ||||
| moduleImport: IMPORT importName ';'; | ||||
| importName: identifier ('/' identifier)*; | ||||
| moduleStmt: let | fnDecl | fnDef | traitDef | typeDef; | ||||
| 
 | ||||
| traitDef: TRAIT identifier '=' identifier ';' | ||||
|         | TRAIT identifier '=' '{' (fnDecl)* '}' ';'; | ||||
| @ -21,44 +22,46 @@ let: LET identifier type? '=' expr ';'; | ||||
| 
 | ||||
| exprStmt: expr ';'; | ||||
| 
 | ||||
| type: type2; | ||||
| type2: type1 | ||||
| type: type1; // novisit | ||||
| type1: type0 | ||||
|      | '(' type ')' | ||||
|      | '(' tupleTypeList ')'          // tuple | ||||
|      | '[' typeList? ']' '->' type;   // closure | ||||
| type1: type0 | ||||
|      | type0 '{' typeList '}';        // generic | ||||
| type0: identifier; | ||||
| type0: identifier | ||||
|      | identifier '{' typeList '}';   // generic | ||||
| 
 | ||||
| tupleTypeList: type ',' type (',' type)*; | ||||
| tupleTypeList: type (',' type)+; | ||||
| typeList: type (',' type)*; | ||||
| 
 | ||||
| 
 | ||||
| expr: expr3; | ||||
| expr: expr3; // novisit | ||||
| expr3: expr2 | ||||
|      | '[' identifierList? ']' '->' expr     // closure | ||||
|      | '{' (let | exprStmt | fnDef)* (expr ';') '}'; | ||||
|      | '{' blockStmt* (expr ';') '}'; | ||||
| expr2: expr1 | ||||
|      | expr2 operator expr1;                 // binary expr | ||||
|      | expr2 operator expr1;        // binary expr | ||||
| expr1: expr0 | ||||
|      | operator expr0;                       // unary expr | ||||
|      | operator expr0;              // unary expr | ||||
| expr0: literal | ||||
|      | identifier | ||||
|      | expr0 '[' exprList? ']'               // fn call | ||||
|      | expr0 '[' exprList? ']'      // fn call | ||||
|      | '(' expr ')' | ||||
|      | expr0 '.' identifier;                 // property accessor | ||||
|      | '(' tupleExprList ')'        // tuple | ||||
|      | expr0 '.' identifier;        // property accessor | ||||
| 
 | ||||
| blockStmt: let | exprStmt | fnDef; | ||||
| tupleExprList: expr (',' expr)+; | ||||
| exprList: expr (',' expr)*; | ||||
| 
 | ||||
| identifierList: identifier (',' identifier)*; | ||||
| 
 | ||||
| literal: 'null' | INT_LIT | FLOAT_LIT; | ||||
| literal: NULL='null' | INT_LIT | FLOAT_LIT; | ||||
| 
 | ||||
| operator: '=' | '->' | ||||
|         | OPERATOR; | ||||
| 
 | ||||
| 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]+; | ||||
| @ -70,9 +73,12 @@ BINOP: 'binop'; | ||||
| FN: 'fn'; | ||||
| IMPORT: 'import'; | ||||
| LET: 'let'; | ||||
| MODULE: 'module'; | ||||
| NATIVE: 'native'; | ||||
| TRAIT: 'trait'; | ||||
| TYPE: 'type'; | ||||
| UNOP: 'unop'; | ||||
| 
 | ||||
| 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,128 +4,502 @@ | ||||
| 
 | ||||
| #include <sstream> | ||||
| 
 | ||||
| class Visitor : public plsmBaseVisitor | ||||
| { | ||||
| public: | ||||
|   Visitor() {} | ||||
| 
 | ||||
|   template <typename T> | ||||
|   inline T visitT(antlr4::tree::ParseTree *ctx) | ||||
|   { | ||||
|     return std::any_cast<T>(visit(ctx)); | ||||
|   } | ||||
| 
 | ||||
|   template <typename T> | ||||
|   inline std::unique_ptr<T> visitU(antlr4::tree::ParseTree *ctx) | ||||
|   { | ||||
|     return std::unique_ptr<T>(visitT<T *>(ctx)); | ||||
|   } | ||||
| 
 | ||||
|   virtual std::any visitModule(plsmParser::ModuleContext *ctx) override | ||||
|   { | ||||
|     std::vector<std::unique_ptr<ast::Import>> imports; | ||||
|     std::vector<std::unique_ptr<ast::Stmt>> stmts; | ||||
| 
 | ||||
|     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 file; | ||||
|   std::string *error; | ||||
| 
 | ||||
| public: | ||||
|   ErrorListener(std::string *error) : error(error) {} | ||||
|   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 << "line " << line << ":" << charPositionInLine << ": " << msg; | ||||
|     ss << file << ": line " << line << ":" << charPositionInLine << ": " << msg; | ||||
|     *error = ss.str(); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| std::unique_ptr<ast::Module> | ||||
| plsm::parse(const std::string &input) | ||||
| namespace plsm | ||||
| { | ||||
|   auto istream = antlr4::ANTLRInputStream(input); | ||||
|   auto lexer = plsmLexer(&istream); | ||||
|   auto tokens = antlr4::CommonTokenStream(&lexer); | ||||
|   auto parser = plsmParser(&tokens); | ||||
|   class Visitor : public plsmBaseVisitor | ||||
|   { | ||||
|   private: | ||||
|     const std::string file; | ||||
| 
 | ||||
|   std::string error; | ||||
|   ErrorListener listener(&error); | ||||
|   parser.removeErrorListeners(); | ||||
|   parser.addErrorListener(&listener); | ||||
|   public: | ||||
|     Visitor(const std::string &file) : file(file) {} | ||||
| 
 | ||||
|   auto tree = parser.module(); | ||||
|     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())); | ||||
|     } | ||||
| 
 | ||||
|   if (error.size()) | ||||
|     throw std::runtime_error(error); | ||||
|     template <typename T> | ||||
|     inline T visitT(antlr4::tree::ParseTree *ctx) | ||||
|     { | ||||
|       return std::any_cast<T>(visit(ctx)); | ||||
|     } | ||||
| 
 | ||||
|   auto module = std::any_cast<ast::Module *>(Visitor().visitModule(tree)); | ||||
|   return std::unique_ptr<ast::Module>(module); | ||||
|     template <typename T> | ||||
|     inline std::unique_ptr<T> visitU(antlr4::tree::ParseTree *ctx) | ||||
|     { | ||||
|       return std::unique_ptr<T>(visitT<T *>(ctx)); | ||||
|     } | ||||
| 
 | ||||
|     template <typename T> | ||||
|     inline std::vector<std::unique_ptr<T>> visitVU(antlr4::tree::ParseTree *ctx) | ||||
|     { | ||||
|       std::vector<std::unique_ptr<T>> res; | ||||
|       for (auto &el : visitT<std::vector<T *>>(ctx)) | ||||
|         res.push_back(std::unique_ptr<T>(el)); | ||||
|       return res; | ||||
|     } | ||||
| 
 | ||||
|     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 | ||||
|     { | ||||
|       return std::any(new ast::Import(loc(ctx), visitT<std::string>(ctx->importName()))); | ||||
|     } | ||||
| 
 | ||||
|     virtual std::any visitImportName(plsmParser::ImportNameContext *ctx) override | ||||
|     { | ||||
|       auto name = ctx->identifier(0)->getText(); | ||||
| 
 | ||||
|       for (size_t i = 1; i < ctx->identifier().size(); i++) | ||||
|         name = name + "/" + ctx->identifier(i)->getText(); | ||||
| 
 | ||||
|       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 | ||||
|     { | ||||
|       auto name = ctx->identifier(0)->getText(); | ||||
| 
 | ||||
|       if (ctx->identifier(1)) | ||||
|       { | ||||
|         auto aliased = ctx->identifier(1)->getText(); | ||||
|         return std::any((ast::Stmt *)new ast::TraitAlias(loc(ctx), name, aliased)); | ||||
|       } | ||||
| 
 | ||||
|       std::vector<std::unique_ptr<ast::FnDef>> fns; | ||||
|       for (auto &decl : ctx->fnDecl()) | ||||
|         fns.push_back(visitU<ast::FnDef>(decl)); | ||||
| 
 | ||||
|       return std::any((ast::Stmt *)new ast::TraitDef(loc(ctx), name, fns)); | ||||
|     } | ||||
| 
 | ||||
|     virtual std::any visitTypeDef(plsmParser::TypeDefContext *ctx) override | ||||
|     { | ||||
|       auto name = ctx->identifier()->getText(); | ||||
| 
 | ||||
|       if (ctx->type()) | ||||
|       { | ||||
|         auto gen = visitU<ast::Type>(ctx->type()); | ||||
|         return std::any((ast::Stmt *)new ast::TypeAlias(loc(ctx), name, gen)); | ||||
|       } | ||||
| 
 | ||||
|       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)); | ||||
|     } | ||||
| 
 | ||||
|     virtual std::any visitFnDef(plsmParser::FnDefContext *ctx) override | ||||
|     { | ||||
|       auto name = ctx->identifier()->getText(); | ||||
| 
 | ||||
|       std::vector<std::unique_ptr<ast::FnArg>> args; | ||||
|       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 lexer = plsmLexer(&istream); | ||||
|     auto tokens = antlr4::CommonTokenStream(&lexer); | ||||
|     auto parser = plsmParser(&tokens); | ||||
| 
 | ||||
|     std::string error; | ||||
|     ErrorListener listener(file, &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(file).visitModule(tree)); | ||||
|     return std::unique_ptr<ast::Module>(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"); | ||||
| } | ||||
|  | ||||
| @ -1,13 +1,17 @@ | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
| #include <istream> | ||||
| #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::stringstream buffer; | ||||
|   buffer << t.rdbuf(); | ||||
|   return buffer; | ||||
|   std::ifstream f(path); | ||||
|   auto data = (std::stringstream() << f.rdbuf()).str(); | ||||
|   f.close(); | ||||
| 
 | ||||
|   return data; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| @ -19,9 +23,23 @@ int main(int argc, char *argv[]) | ||||
|     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 fn = (ast::FnDecl *)module->stmts.at(0);
 | ||||
|   // auto fn = (ast::FnDef *)module->stmts.at(0);
 | ||||
|   // std::cout << fn->name << std::endl;
 | ||||
| 
 | ||||
|   // 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 helper[] Int = b; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ludwig Lehnert
						Ludwig Lehnert