diff --git a/compiler/.vscode/settings.json b/compiler/.vscode/settings.json index 956857a..0da43e9 100644 --- a/compiler/.vscode/settings.json +++ b/compiler/.vscode/settings.json @@ -1,7 +1,7 @@ { "C_Cpp.default.includePath": [ "${workspaceFolder}/include/", - "/usr/include/antlr4-runtime", + "${workspaceFolder}/build/antlr4_runtime/src/antlr4_runtime/runtime/Cpp/runtime/src", ], "files.associations": { "*.embeddedhtml": "html", @@ -77,6 +77,8 @@ "typeinfo": "cpp", "valarray": "cpp", "variant": "cpp", - "*.inc": "cpp" + "*.inc": "cpp", + "source_location": "cpp", + "text_encoding": "cpp" } } \ No newline at end of file diff --git a/compiler/CMakeLists.txt b/compiler/CMakeLists.txt index f79d0b2..7f5ab21 100644 --- a/compiler/CMakeLists.txt +++ b/compiler/CMakeLists.txt @@ -17,7 +17,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) include(ExternalAntlr4Cpp) find_package( - Boost 1.84 REQUIRED + Boost 1.83 REQUIRED COMPONENTS json ) diff --git a/compiler/cmake/ExternalAntlr4Cpp.cmake b/compiler/cmake/ExternalAntlr4Cpp.cmake index 4da7fbc..95953e1 100644 --- a/compiler/cmake/ExternalAntlr4Cpp.cmake +++ b/compiler/cmake/ExternalAntlr4Cpp.cmake @@ -18,7 +18,7 @@ endif() # Ensure that the include dir already exists at configure time (to avoid cmake erroring # on non-existent include dirs) -file(MAKE_DIRECTORY "${ANTLR4_INCLUDE_DIRS}") +file(MAKE_DIRECTORY ${ANTLR4_INCLUDE_DIRS}) if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*") set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(Configuration)) diff --git a/compiler/include/AST/AST.h b/compiler/include/AST/AST.h new file mode 100644 index 0000000..bc6f373 --- /dev/null +++ b/compiler/include/AST/AST.h @@ -0,0 +1,27 @@ +#pragma once + +#include "Base.h" + +#include "Expr/BinExpr.h" +#include "Expr/CallExpr.h" +#include "Expr/CastExpr.h" +#include "Expr/Identifier.h" +#include "Expr/LambdaExpr.h" +#include "Expr/UnExpr.h" +#include "Expr/Value.h" + +#include "Module/Import.h" +#include "Module/Module.h" + +#include "Stmt/AssignStmt.h" +#include "Stmt/ExprStmt.h" +#include "Stmt/FnDecl.h" +#include "Stmt/IfStmt.h" +#include "Stmt/RetStmt.h" +#include "Stmt/VarDecl.h" +#include "Stmt/WhileStmt.h" + +#include "Type/FunctionType.h" +#include "Type/PrimitiveType.h" + +#include "TypeName/PrimitiveTypeName.h" diff --git a/compiler/include/AST/Base.h b/compiler/include/AST/Base.h index 5943484..209c28c 100644 --- a/compiler/include/AST/Base.h +++ b/compiler/include/AST/Base.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -11,42 +12,75 @@ #include -#define LOC_ARG const Location &location +#define LOC_ARG const SourceRange &sourceRange namespace plsm { namespace ast { -class Location { +class BinExpr; +class CallExpr; +class CastExpr; +class Identifier; +class LambdaExpr; +class UnExpr; +class IntValue; +class FloatValue; + +class Import; +class Module; + +class AssignStmt; +class ExprStmt; +class FnParam; +class FnDecl; +class IfStmt; +class RetStmt; +class VarDecl; +class WhileStmt; + +class PrimitiveTypeName; + +class ASTVisitor { public: - Location(const std::string &file, std::pair start, - std::pair end) - : file(file), start(start), end(end) {} + virtual ~ASTVisitor() = default; - const std::string file; - const std::pair start, end; + virtual std::any visit(BinExpr &binExpr, std::any param) = 0; + virtual std::any visit(CallExpr &callExpr, std::any param) = 0; + virtual std::any visit(CastExpr &castExpr, std::any param) = 0; + virtual std::any visit(Identifier &identifier, std::any param) = 0; + virtual std::any visit(LambdaExpr &lambdaExpr, std::any param) = 0; + virtual std::any visit(UnExpr &unExpr, std::any param) = 0; + virtual std::any visit(IntValue &intValue, std::any param) = 0; + virtual std::any visit(FloatValue &floatValue, std::any param) = 0; - static Location json() { return Location("", {-1, -1}, {-1, -1}); }; + virtual std::any visit(Import &import, std::any param) = 0; + virtual std::any visit(Module &module, std::any param) = 0; + + virtual std::any visit(AssignStmt &assignStmt, std::any param) = 0; + virtual std::any visit(ExprStmt &exprStmt, std::any param) = 0; + virtual std::any visit(FnParam &fnParam, std::any param) = 0; + virtual std::any visit(FnDecl &fnDecl, std::any param) = 0; + virtual std::any visit(IfStmt &ifStmt, std::any param) = 0; + virtual std::any visit(RetStmt &retStmt, std::any param) = 0; + virtual std::any visit(VarDecl &varDecl, std::any param) = 0; + virtual std::any visit(WhileStmt &whileStmt, std::any param) = 0; + + virtual std::any visit(PrimitiveTypeName &primitiveTypeName, + std::any param) = 0; }; -class ASTNode { -public: - ASTNode(LOC_ARG) : location(location) {} - virtual ~ASTNode() = default; +} // namespace ast +} // namespace plsm - const Location location; +namespace plsm { +namespace ast { + +class Jsonable { +public: + virtual ~Jsonable() = default; virtual boost::json::value toJson() = 0; - virtual std::string toJsonString() { - return boost::json::serialize(toJson()); - } - - static std::unique_ptr fromJson(boost::json::value json); - - virtual bool isExpr() { return false; } - virtual bool isStmt() { return false; } - virtual bool isType() { return false; } - protected: template static inline boost::json::value getJsonProperty(boost::json::value json, @@ -88,7 +122,7 @@ protected: std::string property) { auto arr = getJsonProperty(json, property).as_array(); - std::vector> result; + std::vector result; for (auto &el : arr) { result.push_back(SubNode::fromJson(el)); } @@ -97,31 +131,80 @@ protected: } }; +class SourceRange { +public: + SourceRange(const std::string &file, const std::string &text, + std::pair start, std::pair end) + : file(file), text(text), start(start), end(end) {} + + const std::string file, text; + const std::pair start, end; + + static SourceRange unknown() { + return SourceRange("", "", {-1, -1}, {-1, -1}); + }; + + static SourceRange json() { + return SourceRange("", "", {-1, -1}, {-1, -1}); + }; +}; + +class ASTNode : public Jsonable { +public: + ASTNode(LOC_ARG) : Jsonable(), sourceRange(sourceRange) {} + virtual ~ASTNode() = default; + + const SourceRange sourceRange; + + virtual std::string toJsonString() { + return boost::json::serialize(toJson(), {}); + } + + static ASTNode *fromJson(boost::json::value json); + + virtual bool isExpr() { return false; } + virtual bool isStmt() { return false; } + virtual bool isTypeName() { return false; } + + virtual std::any accept(ASTVisitor *visitor, std::any param) = 0; +}; + class Expr : public ASTNode { public: - Expr(LOC_ARG) : ASTNode(location) {} + Expr(LOC_ARG) : ASTNode(sourceRange) {} + virtual ~Expr() = default; - static std::unique_ptr fromJson(boost::json::value json); + static Expr *fromJson(boost::json::value json); virtual bool isExpr() override { return true; } }; class Stmt : public ASTNode { public: - Stmt(LOC_ARG) : ASTNode(location) {} + Stmt(LOC_ARG) : ASTNode(sourceRange) {} + virtual ~Stmt() = default; - static std::unique_ptr fromJson(boost::json::value json); + static Stmt *fromJson(boost::json::value json); virtual bool isStmt() override { return true; } }; -class Type : public ASTNode { +class TypeName : public ASTNode { public: - Type(LOC_ARG) : ASTNode(location) {} + TypeName(LOC_ARG) : ASTNode(sourceRange) {} + virtual ~TypeName() = default; - static std::unique_ptr fromJson(boost::json::value json); + static TypeName *fromJson(boost::json::value json); - virtual bool isType() override { return true; } + virtual bool isTypeName() override { return true; } +}; + +class Type : public Jsonable { +public: + Type() : Jsonable() {} + virtual ~Type() = default; + + static Type *fromJson(boost::json::value json); }; } // namespace ast diff --git a/compiler/include/AST/Def.h b/compiler/include/AST/Def.h deleted file mode 100644 index c0e2da4..0000000 --- a/compiler/include/AST/Def.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "Base.h" - -#include "Expr/BinExpr.h" -#include "Expr/Block.h" -#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/FnDef.h" -#include "Stmt/TraitAlias.h" -#include "Stmt/TraitDef.h" -#include "Stmt/TypeAlias.h" -#include "Stmt/TypeDef.h" -#include "Stmt/ValDecl.h" - -#include "Type/Closure.h" -#include "Type/Generic.h" -#include "Type/Named.h" -#include "Type/Tuple.h" - -#include "Module/Import.h" -#include "Module/Module.h" diff --git a/compiler/include/AST/Expr/BinExpr.h b/compiler/include/AST/Expr/BinExpr.h index bb5fb93..5a36d08 100644 --- a/compiler/include/AST/Expr/BinExpr.h +++ b/compiler/include/AST/Expr/BinExpr.h @@ -1,37 +1,44 @@ #pragma once #include "AST/Base.h" -#include #include -#include #include namespace plsm { namespace ast { -class BinExpr : public Expr { - const std::string op; - const std::unique_ptr left, right; +enum BinOp { + ADD, + SUB, + MUL, + DIV, + MOD, -public: - BinExpr(LOC_ARG, std::unique_ptr &left, const std::string &op, - std::unique_ptr &right) - : Expr(location), left(std::move(left)), op(op), right(std::move(right)) { - } + EQ, + NE, + GT, + GE, + LT, + LE, - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); + AND, + OR, }; -class PrefExpr : public Expr { - const std::unique_ptr expr; +class BinExpr : public Expr { + const BinOp op; + const std::shared_ptr lhs, rhs; public: - PrefExpr(LOC_ARG, std::unique_ptr &expr) - : Expr(location), expr(std::move(expr)) {} + BinExpr(LOC_ARG, const BinOp op, Expr *lhs, Expr *rhs) + : Expr(sourceRange), op(op), lhs(lhs), rhs(rhs) {} virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); + static BinExpr *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } }; } // namespace ast diff --git a/compiler/include/AST/Expr/Block.h b/compiler/include/AST/Expr/Block.h deleted file mode 100644 index 7b7843c..0000000 --- a/compiler/include/AST/Expr/Block.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include - -namespace plsm { -namespace ast { - -class BlockExpr : public Expr { - const std::vector> stmts; - const std::unique_ptr result; - -public: - BlockExpr(LOC_ARG, std::vector> &stmts, - std::unique_ptr &result) - : Expr(location), stmts(std::move(stmts)), result(std::move(result)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; - -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Expr/Call.h b/compiler/include/AST/Expr/Call.h deleted file mode 100644 index e7d8dbe..0000000 --- a/compiler/include/AST/Expr/Call.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include - -namespace plsm { -namespace ast { - -class CallExpr : public Expr { - const std::unique_ptr callee; - const std::vector> args; - -public: - CallExpr(LOC_ARG, std::unique_ptr &callee, - std::vector> &args) - : Expr(location), callee(std::move(callee)), args(std::move(args)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; - -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Expr/CallExpr.h b/compiler/include/AST/Expr/CallExpr.h new file mode 100644 index 0000000..5dbdd5a --- /dev/null +++ b/compiler/include/AST/Expr/CallExpr.h @@ -0,0 +1,31 @@ +#pragma once + +#include "AST/Base.h" +#include +#include + +namespace plsm { +namespace ast { + +class CallExpr : public Expr { + const std::shared_ptr callee; + std::vector> args; + +public: + CallExpr(LOC_ARG, Expr *callee, std::vector args) + : Expr(sourceRange), callee(callee), args() { + for (auto &arg : args) { + this->args.push_back(std::shared_ptr(arg)); + } + } + + virtual boost::json::value toJson() override; + static CallExpr *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; + +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Expr/CastExpr.h b/compiler/include/AST/Expr/CastExpr.h new file mode 100644 index 0000000..d4224ad --- /dev/null +++ b/compiler/include/AST/Expr/CastExpr.h @@ -0,0 +1,26 @@ +#pragma once + +#include "AST/Base.h" +#include + +namespace plsm { +namespace ast { + +class CastExpr : public Expr { + const std::shared_ptr value; + const std::shared_ptr typeName; + +public: + CastExpr(LOC_ARG, Expr *value, TypeName *typeName) + : Expr(sourceRange), value(value), typeName(typeName) {} + + virtual boost::json::value toJson() override; + static CastExpr *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; + +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Expr/Closure.h b/compiler/include/AST/Expr/Closure.h deleted file mode 100644 index a04e720..0000000 --- a/compiler/include/AST/Expr/Closure.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include -#include - -namespace plsm { -namespace ast { -class FnArg; - -class Closure : public Expr { - const std::vector> args; - const std::unique_ptr body; - -public: - Closure(LOC_ARG, std::vector> &args, std::unique_ptr &body) - : Expr(location), args(std::move(args)), body(std::move(body)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Expr/Identifier.h b/compiler/include/AST/Expr/Identifier.h index 384b32e..451c300 100644 --- a/compiler/include/AST/Expr/Identifier.h +++ b/compiler/include/AST/Expr/Identifier.h @@ -9,10 +9,15 @@ class Identifier : public Expr { const std::string name; public: - Identifier(LOC_ARG, const std::string &name) : Expr(location), name(name) {} + Identifier(LOC_ARG, const std::string &name) + : Expr(sourceRange), name(name) {} virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); + static Identifier *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } }; } // namespace ast diff --git a/compiler/include/AST/Expr/LambdaExpr.h b/compiler/include/AST/Expr/LambdaExpr.h new file mode 100644 index 0000000..3d94e95 --- /dev/null +++ b/compiler/include/AST/Expr/LambdaExpr.h @@ -0,0 +1,36 @@ +#pragma once + +#include "AST/Base.h" +#include +#include +#include + +namespace plsm { +namespace ast { +class FnParam; + +class LambdaExpr : public Expr { + std::vector> params; + std::vector> body; + +public: + LambdaExpr(LOC_ARG, std::vector params, std::vector body) + : Expr(sourceRange), params(), body() { + for (auto ¶m : params) { + this->params.push_back(std::shared_ptr(param)); + } + + for (auto &expr : body) { + this->body.push_back(std::shared_ptr(expr)); + } + } + + virtual boost::json::value toJson() override; + static LambdaExpr *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Expr/PropExpr.h b/compiler/include/AST/Expr/PropExpr.h deleted file mode 100644 index 564c826..0000000 --- a/compiler/include/AST/Expr/PropExpr.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include - -namespace plsm { -namespace ast { -class PropExpr : public Expr { - const std::unique_ptr expr; - const std::string property; - -public: - PropExpr(LOC_ARG, std::unique_ptr &expr, const std::string &property) - : Expr(location), expr(std::move(expr)), property(property) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Expr/Tuple.h b/compiler/include/AST/Expr/Tuple.h deleted file mode 100644 index db45bf2..0000000 --- a/compiler/include/AST/Expr/Tuple.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include - -namespace plsm { -namespace ast { - -class Tuple : public Expr { - const std::vector> values; - -public: - Tuple(LOC_ARG, std::vector> &values) - : Expr(location), values(std::move(values)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; - -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Expr/UnExpr.h b/compiler/include/AST/Expr/UnExpr.h new file mode 100644 index 0000000..a415435 --- /dev/null +++ b/compiler/include/AST/Expr/UnExpr.h @@ -0,0 +1,31 @@ +#pragma once + +#include "AST/Base.h" +#include +#include + +namespace plsm { +namespace ast { +enum UnOp { + NOT, + POS, + NEG, +}; + +class UnExpr : public Expr { + const UnOp op; + const std::shared_ptr expr; + +public: + UnExpr(LOC_ARG, const UnOp op, Expr *expr) + : Expr(sourceRange), op(op), expr(expr) {} + + virtual boost::json::value toJson() override; + static UnExpr *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Expr/UnaryExpr.h b/compiler/include/AST/Expr/UnaryExpr.h deleted file mode 100644 index 1809242..0000000 --- a/compiler/include/AST/Expr/UnaryExpr.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include -#include - -namespace plsm { -namespace ast { -class UnaryExpr : public Expr { - const std::string op; - const std::unique_ptr expr; - -public: - UnaryExpr(LOC_ARG, const std::string &op, std::unique_ptr &expr) - : Expr(location), op(op), expr(std::move(expr)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Expr/Value.h b/compiler/include/AST/Expr/Value.h index 32c730c..81f4b8a 100644 --- a/compiler/include/AST/Expr/Value.h +++ b/compiler/include/AST/Expr/Value.h @@ -1,38 +1,47 @@ #pragma once #include "AST/Base.h" -#include -#include #include +#include +#include namespace plsm { namespace ast { -class NullValue : public Expr { -public: - NullValue(LOC_ARG) : Expr(location) {} +// class NullValue : public Expr { +// public: +// NullValue(LOC_ARG) : Expr(sourceRange) {} - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; +// virtual boost::json::value toJson() override; +// static std::unique_ptr fromJson(boost::json::value json); +// }; class IntValue : public Expr { const std::int64_t value; public: - IntValue(LOC_ARG, int64_t value) : Expr(location), value(value) {} + IntValue(LOC_ARG, int64_t value) : Expr(sourceRange), value(value) {} virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); + static IntValue *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } }; class FloatValue : public Expr { const std::double_t value; public: - FloatValue(LOC_ARG, double value) : Expr(location), value(value) {} + FloatValue(LOC_ARG, double value) : Expr(sourceRange), value(value) {} virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); + static FloatValue *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } }; + } // namespace ast } // namespace plsm diff --git a/compiler/include/AST/Module/Import.h b/compiler/include/AST/Module/Import.h index c0b8038..6ba9014 100644 --- a/compiler/include/AST/Module/Import.h +++ b/compiler/include/AST/Module/Import.h @@ -1,8 +1,6 @@ #pragma once #include "AST/Base.h" -#include -#include #include namespace plsm { @@ -12,10 +10,14 @@ class Import : public ASTNode { public: Import(LOC_ARG, const std::string &moduleName) - : ASTNode(location), moduleName(moduleName) {} + : ASTNode(sourceRange), moduleName(moduleName) {} virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); + static Import *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } }; } // namespace ast } // namespace plsm diff --git a/compiler/include/AST/Module/Module.h b/compiler/include/AST/Module/Module.h index 84140c2..c2fd40e 100644 --- a/compiler/include/AST/Module/Module.h +++ b/compiler/include/AST/Module/Module.h @@ -1,11 +1,8 @@ #pragma once #include "AST/Base.h" -#include -#include #include #include -#include namespace plsm { namespace ast { @@ -13,18 +10,28 @@ class Import; class Module : public ASTNode { const std::string name; - const std::vector> imports; - const std::vector> stmts; + std::vector> imports; + std::vector> stmts; public: - Module(LOC_ARG, const std::string &name, - std::vector> &imports, - std::vector> &stmts) - : ASTNode(location), name(name), imports(std::move(imports)), - stmts(std::move(stmts)) {} + Module(LOC_ARG, const std::string &name, const std::vector &imports, + const std::vector &stmts) + : ASTNode(sourceRange), name(name), imports(), stmts() { + for (auto &import : imports) { + this->imports.push_back(std::shared_ptr(import)); + } + + for (auto &stmt : stmts) { + this->stmts.push_back(std::shared_ptr(stmt)); + } + } virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); + static Module *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } }; } // namespace ast } // namespace plsm diff --git a/compiler/include/AST/Stmt/AssignStmt.h b/compiler/include/AST/Stmt/AssignStmt.h new file mode 100644 index 0000000..560145e --- /dev/null +++ b/compiler/include/AST/Stmt/AssignStmt.h @@ -0,0 +1,27 @@ +#pragma once + +#include "AST/Base.h" +#include +#include + +namespace plsm { +namespace ast { + +class AssignStmt : public Stmt { + const std::shared_ptr lval; + const std::shared_ptr rval; + +public: + AssignStmt(LOC_ARG, Expr *lval, Expr *rval) + : Stmt(sourceRange), lval(lval), rval(rval) {} + + virtual boost::json::value toJson() override; + static AssignStmt *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; + +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Stmt/ExprStmt.h b/compiler/include/AST/Stmt/ExprStmt.h index 9ec58d8..6dfeb55 100644 --- a/compiler/include/AST/Stmt/ExprStmt.h +++ b/compiler/include/AST/Stmt/ExprStmt.h @@ -6,14 +6,17 @@ namespace plsm { namespace ast { class ExprStmt : public Stmt { - const std::unique_ptr expr; + const std::shared_ptr expr; public: - ExprStmt(LOC_ARG, std::unique_ptr &expr) - : Stmt(location), expr(std::move(expr)) {} + ExprStmt(LOC_ARG, Expr *expr) : Stmt(sourceRange), expr(expr) {} virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); + static ExprStmt *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } }; } // namespace ast } // namespace plsm diff --git a/compiler/include/AST/Stmt/FnDecl.h b/compiler/include/AST/Stmt/FnDecl.h new file mode 100644 index 0000000..1ab6c43 --- /dev/null +++ b/compiler/include/AST/Stmt/FnDecl.h @@ -0,0 +1,56 @@ +#pragma once + +#include "AST/Base.h" +#include +#include +#include + +namespace plsm { +namespace ast { + +class FnParam : public ASTNode { + const std::string name; + const std::shared_ptr typeName; + +public: + FnParam(LOC_ARG, const std::string &name, TypeName *typeName) + : ASTNode(sourceRange), name(name), typeName(typeName) {} + + virtual boost::json::value toJson() override; + static FnParam *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; + +class FnDecl : public Stmt { + const std::string name; + std::vector> params; + const std::shared_ptr returnTypeName; + std::vector> body; + +public: + FnDecl(LOC_ARG, const std::string &name, const std::vector ¶ms, + TypeName *returnTypeName, const std::vector &body) + : Stmt(sourceRange), name(name), params(), returnTypeName(returnTypeName), + body() { + for (auto ¶m : params) { + this->params.push_back(std::shared_ptr(param)); + } + + for (auto &stmt : body) { + this->body.push_back(std::shared_ptr(stmt)); + } + } + + virtual boost::json::value toJson() override; + static FnDecl *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; + +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Stmt/FnDef.h b/compiler/include/AST/Stmt/FnDef.h deleted file mode 100644 index 7d57ece..0000000 --- a/compiler/include/AST/Stmt/FnDef.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include -#include -#include - -namespace plsm { -namespace ast { -class FnArg : public ASTNode { - const std::string name; - const std::unique_ptr type; - -public: - FnArg(LOC_ARG, const std::string &name, std::unique_ptr &type) - : ASTNode(location), name(name), type(std::move(type)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; - -class FnDef : public Stmt { - const std::string name; - const std::vector> args; - const std::unique_ptr returnType; - const std::unique_ptr body; - -public: - FnDef(LOC_ARG, const std::string &name, - std::vector> &args, - std::unique_ptr &returnType, std::unique_ptr &body) - : Stmt(location), name(name), args(std::move(args)), - returnType(std::move(returnType)), body(std::move(body)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Stmt/IfStmt.h b/compiler/include/AST/Stmt/IfStmt.h new file mode 100644 index 0000000..f32400a --- /dev/null +++ b/compiler/include/AST/Stmt/IfStmt.h @@ -0,0 +1,36 @@ +#pragma once + +#include "AST/Base.h" +#include +#include + +namespace plsm { +namespace ast { + +class IfStmt : public Stmt { + const std::shared_ptr condition; + std::vector> ifBody, elseBody; + +public: + IfStmt(LOC_ARG, Expr *condition, const std::vector &ifBody, + const std::vector &elseBody) + : Stmt(sourceRange), condition(condition) { + for (auto &stmt : ifBody) { + this->ifBody.push_back(std::shared_ptr(stmt)); + } + + for (auto &stmt : elseBody) { + this->elseBody.push_back(std::shared_ptr(stmt)); + } + } + + virtual boost::json::value toJson() override; + static IfStmt *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; + +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Stmt/RetStmt.h b/compiler/include/AST/Stmt/RetStmt.h new file mode 100644 index 0000000..b8514d5 --- /dev/null +++ b/compiler/include/AST/Stmt/RetStmt.h @@ -0,0 +1,22 @@ +#pragma once + +#include "AST/Base.h" +#include + +namespace plsm { +namespace ast { +class RetStmt : public Stmt { + const std::shared_ptr value; + +public: + RetStmt(LOC_ARG, Expr *value) : Stmt(sourceRange), value(value) {} + + virtual boost::json::value toJson() override; + static RetStmt *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Stmt/TraitAlias.h b/compiler/include/AST/Stmt/TraitAlias.h deleted file mode 100644 index 9ad1723..0000000 --- a/compiler/include/AST/Stmt/TraitAlias.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include -#include -#include - -namespace plsm { -namespace ast { -class TraitAlias : public Stmt { - const std::string alias; - const std::string aliased; - -public: - TraitAlias(LOC_ARG, const std::string &alias, const std::string &aliased) - : Stmt(location), alias(alias), aliased(aliased) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Stmt/TraitDef.h b/compiler/include/AST/Stmt/TraitDef.h deleted file mode 100644 index 946a055..0000000 --- a/compiler/include/AST/Stmt/TraitDef.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include -#include -#include - -namespace plsm { -namespace ast { -class FnDef; -class TraitDef : public Stmt { - const std::string name; - const std::vector> traits; - -public: - TraitDef(LOC_ARG, const std::string &name, - std::vector> &traits) - : Stmt(location), name(name), traits(std::move(traits)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Stmt/TypeAlias.h b/compiler/include/AST/Stmt/TypeAlias.h deleted file mode 100644 index 97a3060..0000000 --- a/compiler/include/AST/Stmt/TypeAlias.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include -#include -#include - -namespace plsm { -namespace ast { -class TypeAlias : public Stmt { - const std::string alias; - const std::unique_ptr type; - -public: - TypeAlias(LOC_ARG, const std::string &alias, std::unique_ptr &type) - : Stmt(location), alias(alias), type(std::move(type)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Stmt/TypeDef.h b/compiler/include/AST/Stmt/TypeDef.h deleted file mode 100644 index 883bd1c..0000000 --- a/compiler/include/AST/Stmt/TypeDef.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include - -namespace plsm { -namespace ast { -class FnDef; -class FnArg; - -class TypeDef : public Stmt { - const std::string name; - const std::vector> attrs; - const std::vector> members; - -public: - TypeDef(LOC_ARG, const std::string &name, - std::vector> &attrs, - std::vector> &members) - : Stmt(location), name(name), attrs(std::move(attrs)), - members(std::move(members)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Stmt/ValDecl.h b/compiler/include/AST/Stmt/ValDecl.h deleted file mode 100644 index 3f65947..0000000 --- a/compiler/include/AST/Stmt/ValDecl.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include - -namespace plsm { -namespace ast { -class ValDecl : public Stmt { - const std::string name; - const std::unique_ptr type; - const std::unique_ptr value; - -public: - ValDecl(LOC_ARG, const std::string &name, std::unique_ptr &type, - std::unique_ptr &value) - : Stmt(location), name(name), type(std::move(type)), - value(std::move(value)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Stmt/VarDecl.h b/compiler/include/AST/Stmt/VarDecl.h new file mode 100644 index 0000000..10c01f8 --- /dev/null +++ b/compiler/include/AST/Stmt/VarDecl.h @@ -0,0 +1,26 @@ +#pragma once + +#include "AST/Base.h" +#include +#include + +namespace plsm { +namespace ast { + +class VarDecl : public Stmt { + const std::string name; + const std::shared_ptr typeName; + +public: + VarDecl(LOC_ARG, const std::string &name, TypeName *typeName) + : Stmt(sourceRange), name(name), typeName(typeName) {} + + virtual boost::json::value toJson() override; + static VarDecl *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Stmt/WhileStmt.h b/compiler/include/AST/Stmt/WhileStmt.h new file mode 100644 index 0000000..5b1318d --- /dev/null +++ b/compiler/include/AST/Stmt/WhileStmt.h @@ -0,0 +1,29 @@ +#pragma once + +#include "AST/Base.h" +#include +#include + +namespace plsm { +namespace ast { +class WhileStmt : public Stmt { + const std::shared_ptr condition; + std::vector> body; + +public: + WhileStmt(LOC_ARG, Expr *condition, const std::vector &body) + : Stmt(sourceRange), condition(condition) { + for (auto &stmt : body) { + this->body.push_back(std::shared_ptr(stmt)); + } + } + + virtual boost::json::value toJson() override; + static WhileStmt *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Type/Closure.h b/compiler/include/AST/Type/Closure.h deleted file mode 100644 index 06a432f..0000000 --- a/compiler/include/AST/Type/Closure.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include - -namespace plsm { -namespace ast { -class ClosureType : public Type { - const std::vector> from; - const std::unique_ptr to; - -public: - ClosureType(LOC_ARG, std::vector> &from, - std::unique_ptr &to) - : Type(location), from(std::move(from)), to(std::move(to)) {} - - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Type/FunctionType.h b/compiler/include/AST/Type/FunctionType.h new file mode 100644 index 0000000..d23c2ab --- /dev/null +++ b/compiler/include/AST/Type/FunctionType.h @@ -0,0 +1,25 @@ +#pragma once + +#include "AST/Base.h" +#include +#include + +namespace plsm { +namespace ast { +class FunctionType : public Type { + std::vector> paramTypes; + const std::unique_ptr returnType; + +public: + FunctionType(const std::vector ¶mTypes, Type *returnType) + : Type(), returnType(returnType) { + for (auto ¶mType : paramTypes) { + this->paramTypes.push_back(std::unique_ptr(paramType)); + } + } + + virtual boost::json::value toJson() override; + static FunctionType *fromJson(boost::json::value json); +}; +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Type/Generic.h b/compiler/include/AST/Type/Generic.h deleted file mode 100644 index 33443d0..0000000 --- a/compiler/include/AST/Type/Generic.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include -#include -#include - -namespace plsm { -namespace ast { -class GenericType : public Type { - const std::string name; - const std::vector> types; - -public: - GenericType(LOC_ARG, const std::string &name, - std::vector> &types) - : Type(location), name(name), types(std::move(types)) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Type/Named.h b/compiler/include/AST/Type/Named.h deleted file mode 100644 index bb51a49..0000000 --- a/compiler/include/AST/Type/Named.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "AST/Base.h" -#include - -namespace plsm { -namespace ast { - -class NamedType : public Type { - const std::string name; - -public: - NamedType(LOC_ARG, const std::string &name) : Type(location), name(name) {} - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; - -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/Type/PrimitiveType.h b/compiler/include/AST/Type/PrimitiveType.h new file mode 100644 index 0000000..ecc10a3 --- /dev/null +++ b/compiler/include/AST/Type/PrimitiveType.h @@ -0,0 +1,22 @@ +#pragma once + +#include "AST/Base.h" + +namespace plsm { +namespace ast { + +class PrimitiveType : public Type { + const std::string name; + +public: + PrimitiveType(const std::string &name) : Type(), name(name) {} + + bool operator==(const PrimitiveType &other) { return name == other.name; } + bool operator!=(const PrimitiveType &other) { return !(*this == other); } + + virtual boost::json::value toJson() override; + static PrimitiveType *fromJson(boost::json::value json); +}; + +} // namespace ast +} // namespace plsm diff --git a/compiler/include/AST/Type/Tuple.h b/compiler/include/AST/Type/Tuple.h deleted file mode 100644 index b80f4ec..0000000 --- a/compiler/include/AST/Type/Tuple.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "AST/Def.h" -#include -#include - -namespace plsm { -namespace ast { -class TupleType : public Type { - const std::vector> types; - -public: - TupleType(LOC_ARG, std::vector> &types) - : Type(location), types(std::move(types)) {} - - - virtual boost::json::value toJson() override; - static std::unique_ptr fromJson(boost::json::value json); -}; -} // namespace ast -} // namespace plsm diff --git a/compiler/include/AST/TypeName/PrimitiveTypeName.h b/compiler/include/AST/TypeName/PrimitiveTypeName.h new file mode 100644 index 0000000..282557e --- /dev/null +++ b/compiler/include/AST/TypeName/PrimitiveTypeName.h @@ -0,0 +1,27 @@ +#pragma once + +#include "AST/Base.h" + +namespace plsm { +namespace ast { + +class PrimitiveTypeName : public TypeName { + const std::string name; + +public: + PrimitiveTypeName(LOC_ARG, const std::string &name) + : TypeName(sourceRange), name(name) {} + + bool operator==(const PrimitiveTypeName &other) { return name == other.name; } + bool operator!=(const PrimitiveTypeName &other) { return !(*this == other); } + + virtual boost::json::value toJson() override; + static PrimitiveTypeName *fromJson(boost::json::value json); + + virtual std::any accept(ASTVisitor *visitor, std::any param) override { + return visitor->visit(*this, param); + } +}; + +} // namespace ast +} // namespace plsm \ No newline at end of file diff --git a/compiler/include/Parser.h b/compiler/include/Parser.h index 2904152..1d509d4 100644 --- a/compiler/include/Parser.h +++ b/compiler/include/Parser.h @@ -1,12 +1,11 @@ #pragma once -#include #include +#include -#include "AST/Def.h" +#include "AST/AST.h" -namespace plsm -{ - std::unique_ptr parse(const std::string &file, const std::string &input); +namespace plsm { +std::shared_ptr parse(const std::string &file, + const std::string &input); } - diff --git a/compiler/plsm.g4 b/compiler/plsm.g4 index 56493b4..cfd408a 100644 --- a/compiler/plsm.g4 +++ b/compiler/plsm.g4 @@ -1,84 +1,323 @@ grammar plsm; -module: MODULE identifier ';' moduleImport* moduleStmt*; +@parser::header { +#include "AST/AST.h" -moduleImport: IMPORT importName ';'; -importName: identifier ('/' identifier)*; -moduleStmt: let | fnDecl | fnDef | traitDef | typeDef; +using namespace plsm::ast; +} -traitDef: TRAIT identifier '=' identifier ';' - | TRAIT identifier '=' '{' (fnDecl)* '}' ';'; +@parser::members { -typeDef: TYPE identifier '=' type ';' - | TYPE identifier '=' ('(' fnDefArgs ')')? '{' (fnDecl | fnDef)* '}' ';'; +std::string filename; -fnDef: FN identifier '[' fnDefArgs? ']' type '=' expr ';'; -fnDefArgs: identifier type (',' identifier type)*; +void setFileName(const std::string &filename) { this->filename = filename; } -fnDecl: FN identifier '[' fnDeclArgs? ']' type ';'; -fnDeclArgs: identifier? type (',' identifier? type)*; +inline SourceRange getSourceRange(antlr4::ParserRuleContext *ctx) { + if (!ctx->getStart() || !ctx->getStop()) { + return SourceRange::unknown(); + } -let: LET identifier type? '=' expr ';'; + return SourceRange( + filename, ctx->getText(), + std::pair(ctx->getStart()->getLine(), + ctx->getStart()->getCharPositionInLine()), + std::pair(ctx->getStop()->getLine(), + ctx->getStop()->getCharPositionInLine())); +} -exprStmt: expr ';'; +} -type: type1; // novisit -type1: type0 - | '(' type ')' - | '(' tupleTypeList ')' // tuple - | '[' typeList? ']' '->' type; // closure -type0: identifier - | identifier '{' typeList '}'; // generic +module + returns[Module *ast]: (stmts += topLevelStmt)* { + std::vector stmts; + for (auto &stmt : $ctx->stmts) { + stmts.push_back(stmt->ast); + } -tupleTypeList: type (',' type)+; -typeList: type (',' type)*; + $ast = new Module(getSourceRange($ctx), "default", std::vector(), stmts); + }; + +topLevelStmt + returns[Stmt *ast]: + varDecl { + $ast = $ctx->varDecl()->ast; + } + | fnDecl { + $ast = $ctx->fnDecl()->ast; + }; + +stmt + returns[Stmt *ast]: + exprStmt { + $ast = $ctx->exprStmt()->ast; + } + | varDecl { + $ast = $ctx->varDecl()->ast; + } + | retStmt { + $ast = $ctx->retStmt()->ast; + } + | assignStmt { + $ast = $ctx->assignStmt()->ast; + } + | implDeclAssignStmt { + $ast = $ctx->implDeclAssignStmt()->ast; + } + | ifStmt { + $ast = $ctx->ifStmt()->ast; + } + | whileStmt { + $ast = $ctx->whileStmt()->ast; + }; + +whileStmt + returns[WhileStmt *ast]: + 'while' '(' condition = expr ')' ( + '{' (stmts += stmt)* '}' + | singleStmt = stmt + ) { + auto cond = $ctx->condition->ast; + + std::vector body; + for (auto &stmt : $ctx->stmts) { + body.push_back(stmt->ast); + } + if ($ctx->singleStmt) body.push_back($ctx->singleStmt->ast); + + $ast = new WhileStmt(getSourceRange($ctx), cond, body); + }; + +ifStmt + returns[IfStmt *ast]: + 'if' '(' condition = expr ')' ( + '{' (ifStmts += stmt)* '}' + | ifSingleStmt = stmt + ) ( + 'else' ( + '{' (elseStmts += stmt)* '}' + | elseSingleStmt = stmt + ) + )? { + auto cond = $ctx->condition->ast; + + std::vector ifBody; + for (auto &stmt : $ctx->ifStmts) { + ifBody.push_back(stmt->ast); + } + if ($ctx->ifSingleStmt) ifBody.push_back($ctx->ifSingleStmt->ast); -expr: expr3; // novisit -expr3: expr2 - | '[' fnDefArgs? ']' '->' expr // closure - | '{' blockStmt* (expr ';') '}'; -expr2: expr1 - | expr2 operator expr1; // binary expr -expr1: expr0 - | operator expr0; // unary expr -expr0: literal - | identifier - | expr0 '[' exprList? ']' // fn call - | '(' expr ')' - | '(' tupleExprList ')' // tuple - | expr0 '.' identifier; // property accessor + std::vector elseBody; + for (auto &stmt : $ctx->elseStmts) { + elseBody.push_back(stmt->ast); + } + if ($ctx->elseSingleStmt) elseBody.push_back($ctx->elseSingleStmt->ast); -blockStmt: let | exprStmt | fnDef; -tupleExprList: expr (',' expr)+; -exprList: expr (',' expr)*; + $ast = new IfStmt(getSourceRange($ctx), cond, ifBody, elseBody); + }; -identifierList: identifier (',' identifier)*; +implDeclAssignStmt + returns[Stmt *ast]: + IDENTIFIER ':=' expr { + // TODO + }; -literal: NULL='null' | INT_LIT | FLOAT_LIT; +assignStmt + returns[AssignStmt *ast]: + lval = expr '=' rval = expr { + $ast = new AssignStmt(getSourceRange($ctx), $ctx->lval->ast, $ctx->rval->ast); + }; -operator: '=' | '->' - | OPERATOR; +retStmt + returns[RetStmt *ast]: + 'ret' expr ';' { + $ast = new RetStmt(getSourceRange($ctx), $ctx->expr()->ast); + }; -identifier: keyword | IDENTIFIER; -keyword: BINOP | FN | IMPORT | LET | MODULE | NATIVE | TRAIT | TYPE | UNOP; +fnDecl + returns[FnDecl *ast]: + 'fun' name = IDENTIFIER '(' ( + params += fnParam (',' params += fnParam)* + )? ')' typeName '{' (stmts += stmt)* '}' { + auto name = $ctx->name->getText(); + std::vector params; + for (auto ¶m : $ctx->params) { + params.push_back(param->ast); + } -INT_LIT: [0-9]+ | '0x' [0-9a-fA-F]+ | '0o' [0-7]+ | '0b' [01]+; -FLOAT_LIT: [0-9]+ '.' | [0-9]* '.' [0-9]+; + auto returnTypeName = $ctx->typeName()->ast; -OPERATOR: ('+'|'-'|'*'|'/'|'%'|'!'|'&'|'$'|'ยง'|'|'|'='|'<'|'>'|'?'|'~'|'#'|':'|'^'|'\\'|'.')+; + std::vector body; + for (auto &stmt : $ctx->stmts) { + body.push_back(stmt->ast); + } -BINOP: 'binop'; -FN: 'fn'; -IMPORT: 'import'; -LET: 'let'; -MODULE: 'module'; -NATIVE: 'native'; -TRAIT: 'trait'; -TYPE: 'type'; -UNOP: 'unop'; + $ast = new FnDecl(getSourceRange($ctx), name, params, returnTypeName, body); + }; + +fnParam + returns[FnParam *ast]: + IDENTIFIER typeName { + $ast = new FnParam(getSourceRange($ctx), $ctx->IDENTIFIER()->getText(), $ctx->typeName()->ast); + }; + +varDecl + returns[VarDecl *ast]: + 'var' IDENTIFIER ':' typeName ';' { + auto name = $ctx->IDENTIFIER()->getText(); + $ast = new VarDecl(getSourceRange($ctx), name, $ctx->typeName()->ast); + }; + +exprStmt + returns[ExprStmt *ast]: + expr ';' { + $ast = new ExprStmt(getSourceRange($ctx), $ctx->expr()->ast); + }; + +expr + returns[Expr *ast]: + value = binaryExpr { + $ast = $ctx->value->ast; + }; + +binaryExpr + returns[Expr *ast]: + value = unaryExpr { + $ast = $ctx->value->ast; + } + | lhs = binaryExpr op = ('*' | '/' | '%') rhs = binaryExpr { + auto opText = $ctx->op->getText(); + + BinOp op; + if (opText == "*") op = BinOp::MUL; + if (opText == "/") op = BinOp::DIV; + if (opText == "%") op = BinOp::MOD; + + $ast = new BinExpr(getSourceRange($ctx), op, $ctx->lhs->ast, $ctx->rhs->ast); + } + | lhs = binaryExpr op = ('+' | '-') rhs = binaryExpr { + auto opText = $ctx->op->getText(); + + BinOp op; + if (opText == "+") op = BinOp::ADD; + if (opText == "-") op = BinOp::SUB; + + $ast = new BinExpr(getSourceRange($ctx), op, $ctx->lhs->ast, $ctx->rhs->ast); + } + | operand = binaryExpr 'as' typeName { + $ast = new CastExpr(getSourceRange($ctx), $ctx->operand->ast, $ctx->typeName()->ast); + } + | lhs = binaryExpr op = ( + '==' + | '!=' + | '>=' + | '<=' + | '>' + | '<' + ) rhs = binaryExpr { + auto opText = $ctx->op->getText(); + + BinOp op; + if (opText == "==") op = BinOp::EQ; + if (opText == "!=") op = BinOp::NE; + if (opText == ">=") op = BinOp::GE; + if (opText == "<=") op = BinOp::LE; + if (opText == ">") op = BinOp::GT; + if (opText == "<") op = BinOp::LT; + + $ast = new BinExpr(getSourceRange($ctx), op, $ctx->lhs->ast, $ctx->rhs->ast); + } + | lhs = binaryExpr '&&' rhs = binaryExpr { + $ast = new BinExpr(getSourceRange($ctx), BinOp::AND, $ctx->lhs->ast, $ctx->rhs->ast); + } + | lhs = binaryExpr '||' rhs = binaryExpr { + $ast = new BinExpr(getSourceRange($ctx), BinOp::OR, $ctx->lhs->ast, $ctx->rhs->ast); + }; + +unaryExpr + returns[Expr *ast]: + factorExpr { + $ast = $ctx->factorExpr()->ast; + } + | functionCall { + $ast = $ctx->functionCall()->ast; + } + | '!' unaryExpr { + $ast = new UnExpr(getSourceRange($ctx), UnOp::NOT, $ctx->unaryExpr()->ast); + } + | '+' unaryExpr { + $ast = new UnExpr(getSourceRange($ctx), UnOp::POS, $ctx->unaryExpr()->ast); + } + | '-' unaryExpr { + $ast = new UnExpr(getSourceRange($ctx), UnOp::NEG, $ctx->unaryExpr()->ast); + }; + +factorExpr + returns[Expr *ast]: + IDENTIFIER { + $ast = new Identifier(getSourceRange($ctx), $ctx->IDENTIFIER()->getText()); + } + | INT { + auto text = $ctx->INT()->getText(); + + int64_t value; + + if (!text.rfind("0x", 0)) + value = std::strtol(text.substr(2).data(), NULL, 16); + + else if (!text.rfind("0o", 0)) + value = std::strtol(text.substr(2).data(), NULL, 8); + + else if (!text.rfind("0b", 0)) + value = std::strtol(text.substr(2).data(), NULL, 2); + + else + value = std::strtol(text.data(), NULL, 10); + + $ast = new IntValue(getSourceRange($ctx), value); + } + | FLOAT { + auto text = $ctx->FLOAT()->getText(); + + if (text.at(text.size() - 1) == '.') + text += "0"; + if (text.at(0) == '0') + text = "0" + text; + + double value = std::strtod(text.data(), NULL); + $ast = new FloatValue(getSourceRange($ctx), value); + } + | BOOL { + auto text = $ctx->BOOL()->getText(); + $ast = new IntValue(getSourceRange($ctx), text == "true" ? 1 : 0); + } + | '(' expr ')' { + $ast = $ctx->expr()->ast; + }; + +functionCall + returns[Expr *ast]: + callee = factorExpr '(' (args += expr (',' args += expr)*)? ')' { + std::vector args; + for (auto &arg : $ctx->args) { + args.push_back(arg->ast); + } + + $ast = new CallExpr(getSourceRange($ctx), $ctx->callee->ast, args); + }; + +typeName + returns[TypeName *ast]: + IDENTIFIER { + auto text = $ctx->IDENTIFIER()->getText(); + $ast = new PrimitiveTypeName(getSourceRange($ctx), text); + }; + +INT: [0-9]+ | '0x' [0-9a-fA-F]+ | '0o' [0-7]+ | '0b' [01]+; +FLOAT: [0-9]+ '.' | [0-9]* '.' [0-9]+; +BOOL: 'true' | 'false'; IDENTIFIER: [a-zA-Z_] [a-zA-Z0-9_]*; -WHITESPACE: [ \r\n\t]+ -> skip; +WHITESPACE: [ \r\n\t]+ -> skip; \ No newline at end of file diff --git a/compiler/src/AST/Base.cpp b/compiler/src/AST/Base.cpp index 2ac86ff..fca60f8 100644 --- a/compiler/src/AST/Base.cpp +++ b/compiler/src/AST/Base.cpp @@ -1,23 +1,21 @@ -#include "AST/Def.h" -#include "AST/Expr/BinExpr.h" -#include "AST/Expr/Value.h" +#include "AST/AST.h" #include #include #include namespace plsm { +namespace ast { -std::unique_ptr ast::ASTNode::fromJson(boost::json::value json) { - if (json.is_null()) - return std::make_unique(ast::Location::json()); +ASTNode *ASTNode::fromJson(boost::json::value json) { + // if (json.is_null()) + // return std::make_unique(Location::json()); if (json.is_int64()) - return std::make_unique(ast::Location::json(), json.as_int64()); + return new IntValue(SourceRange::json(), json.as_int64()); if (json.is_double()) - return std::make_unique(ast::Location::json(), - json.as_double()); + return new FloatValue(SourceRange::json(), json.as_double()); std::string type; try { @@ -28,86 +26,93 @@ std::unique_ptr ast::ASTNode::fromJson(boost::json::value json) { } if (type == "BinExpr") - return ast::BinExpr::fromJson(json); - if (type == "BlockExpr") - return ast::BlockExpr::fromJson(json); + return BinExpr::fromJson(json); if (type == "CallExpr") - return ast::CallExpr::fromJson(json); - if (type == "Closure") - return ast::Closure::fromJson(json); + return CallExpr::fromJson(json); + if (type == "CastExpr") + return CastExpr::fromJson(json); if (type == "Identifier") - return ast::Identifier::fromJson(json); - if (type == "PropExpr") - return ast::PropExpr::fromJson(json); - if (type == "Tuple") - return ast::Tuple::fromJson(json); - if (type == "UnaryExpr") - return ast::UnaryExpr::fromJson(json); - - if (type == "Import") - return ast::Import::fromJson(json); - if (type == "Module") - return ast::Module::fromJson(json); + return Identifier::fromJson(json); + if (type == "LambdaExpr") + return LambdaExpr::fromJson(json); + if (type == "LambdaExpr") + return LambdaExpr::fromJson(json); + if (type == "UnExpr") + return UnExpr::fromJson(json); + if (type == "AssignStmt") + return AssignStmt::fromJson(json); if (type == "ExprStmt") - return ast::ExprStmt::fromJson(json); - if (type == "FnDef") - return ast::FnDef::fromJson(json); - if (type == "TraitAlias") - return ast::TraitAlias::fromJson(json); - if (type == "TraitDef") - return ast::TraitDef::fromJson(json); - if (type == "TypeAlias") - return ast::TypeAlias::fromJson(json); - if (type == "TypeDef") - return ast::TypeDef::fromJson(json); - if (type == "ValDecl") - return ast::ValDecl::fromJson(json); + return ExprStmt::fromJson(json); + if (type == "FnParam") + return FnParam::fromJson(json); + if (type == "FnDecl") + return FnDecl::fromJson(json); + if (type == "IfStmt") + return IfStmt::fromJson(json); + if (type == "RetStmt") + return RetStmt::fromJson(json); + if (type == "VarDecl") + return VarDecl::fromJson(json); + if (type == "WhileStmt") + return WhileStmt::fromJson(json); - if (type == "ClosureType") - return ast::ClosureType::fromJson(json); - if (type == "GenericType") - return ast::GenericType::fromJson(json); - if (type == "NamedType") - return ast::NamedType::fromJson(json); - if (type == "TupleType") - return ast::TupleType::fromJson(json); + if (type == "PrimitiveTypeName") + return PrimitiveTypeName::fromJson(json); throw std::runtime_error("json conversion for '" + type + "' not implemented"); } -std::unique_ptr ast::Expr::fromJson(boost::json::value json) { - auto node = ast::ASTNode::fromJson(json); +Expr *Expr::fromJson(boost::json::value json) { + auto node = ASTNode::fromJson(json); - if (dynamic_cast(node.get())) { - return std::unique_ptr((ast::Expr *)node.release()); + if (dynamic_cast(node)) { + return (Expr *)node; } throw std::runtime_error(json.as_object().at("@type").as_string().c_str() + std::string(" is not of type 'Expr'")); } -std::unique_ptr ast::Type::fromJson(boost::json::value json) { - auto node = ast::ASTNode::fromJson(json); +TypeName *TypeName::fromJson(boost::json::value json) { + auto node = ASTNode::fromJson(json); - if (dynamic_cast(node.get())) { - return std::unique_ptr((ast::Type *)node.release()); + if (dynamic_cast(node)) { + return (TypeName *)node; } throw std::runtime_error(json.as_object().at("@type").as_string().c_str() + - std::string(" is not of type 'Type'")); + std::string(" is not of type 'TypeName'")); } -std::unique_ptr ast::Stmt::fromJson(boost::json::value json) { - auto node = ast::ASTNode::fromJson(json); +Stmt *Stmt::fromJson(boost::json::value json) { + auto node = ASTNode::fromJson(json); - if (dynamic_cast(node.get())) { - return std::unique_ptr((ast::Stmt *)node.release()); + if (dynamic_cast(node)) { + return (Stmt *)node; } throw std::runtime_error(json.as_object().at("@type").as_string().c_str() + std::string(" is not of type 'Stmt'")); } -} // namespace plsm +Type *Type::fromJson(boost::json::value json) { + std::string type; + try { + type = json.as_object().at("@type").as_string().c_str(); + } catch (...) { + throw std::runtime_error("called Type::fromJson without @type constraint"); + } + + if (type == "FunctionType") + return FunctionType::fromJson(json); + if (type == "PrimitiveType") + return PrimitiveType::fromJson(json); + + throw std::runtime_error("json conversion for '" + type + + "' not implemented"); +} + +} // namespace ast +} // namespace plsm \ No newline at end of file diff --git a/compiler/src/AST/Expr/BinExpr.cpp b/compiler/src/AST/Expr/BinExpr.cpp index 4a76f25..9bd646b 100644 --- a/compiler/src/AST/Expr/BinExpr.cpp +++ b/compiler/src/AST/Expr/BinExpr.cpp @@ -1,37 +1,41 @@ -#include "AST/Expr/BinExpr.h" -#include "AST/Base.h" -#include "AST/Def.h" +#include "AST/AST.h" #include namespace plsm { +namespace ast { -boost::json::value ast::BinExpr::toJson() { +static const std::unordered_map binOpToString = { + {BinOp::ADD, "+"}, {BinOp::SUB, "-"}, {BinOp::MUL, "*"}, {BinOp::DIV, "/"}, + {BinOp::MOD, "%"}, {BinOp::EQ, "=="}, {BinOp::NE, "!="}, {BinOp::LT, "<"}, + {BinOp::LE, "<="}, {BinOp::GT, ">"}, {BinOp::GE, ">="}, {BinOp::AND, "&&"}, + {BinOp::OR, "||"}, +}; + +static const std::unordered_map stringToBinOp = { + {"+", BinOp::ADD}, {"-", BinOp::SUB}, {"*", BinOp::MUL}, {"/", BinOp::DIV}, + {"%", BinOp::MOD}, {"==", BinOp::EQ}, {"!=", BinOp::NE}, {"<", BinOp::LT}, + {"<=", BinOp::LE}, {">", BinOp::GT}, {">=", BinOp::GE}, {"&&", BinOp::AND}, + {"||", BinOp::OR}, +}; + +boost::json::value BinExpr::toJson() { return { {"@type", "BinExpr"}, - {"op", op}, - {"left", left->toJson()}, - {"right", right->toJson()}, + {"op", binOpToString.at(op)}, + {"lhs", lhs->toJson()}, + {"rhs", rhs->toJson()}, }; } -std::unique_ptr ast::BinExpr::fromJson(boost::json::value json) { - auto op = getJsonValue(json, "op"); - auto left = fromJsonProperty(json, "left"); - auto right = fromJsonProperty(json, "right"); - return std::make_unique(ast::Location::json(), left, op, right); -} - -boost::json::value ast::PrefExpr::toJson() { - return { - {"@type", "PrefExpr"}, - {"expr", expr->toJson()}, - }; -} - -std::unique_ptr -ast::PrefExpr::fromJson(boost::json::value json) { - auto expr = fromJsonProperty(json, "expr"); - return std::make_unique(ast::Location::json(), expr); +BinExpr *BinExpr::fromJson(boost::json::value json) { + auto opString = getJsonValue(json, "op"); + auto op = stringToBinOp.at(opString); + + auto lhs = fromJsonProperty(json, "lhs"); + auto rhs = fromJsonProperty(json, "rhs"); + + return new BinExpr(SourceRange::json(), op, lhs, rhs); } +} // namespace ast } // namespace plsm diff --git a/compiler/src/AST/Expr/Block.cpp b/compiler/src/AST/Expr/Block.cpp deleted file mode 100644 index 0bbe462..0000000 --- a/compiler/src/AST/Expr/Block.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "AST/Expr/Block.h" -#include "AST/Base.h" -#include "AST/Def.h" -#include "Utils.h" -#include -#include - -namespace plsm { - -boost::json::value ast::BlockExpr::toJson() { - return { - {"@type", "BlockExpr"}, - {"stmts", utils::mapToJson(stmts)}, - {"result", result->toJson()}, - }; -} - -std::unique_ptr -ast::BlockExpr::fromJson(boost::json::value json) { - auto stmts = fromJsonVector(json, "stmts"); - auto result = fromJsonProperty(json, "result"); - return std::make_unique(ast::Location::json(), stmts, result); -} - -} // namespace plsm diff --git a/compiler/src/AST/Expr/Call.cpp b/compiler/src/AST/Expr/Call.cpp deleted file mode 100644 index 8661951..0000000 --- a/compiler/src/AST/Expr/Call.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "AST/Expr/Call.h" -#include "AST/Def.h" -#include "Utils.h" - -namespace plsm { - -boost::json::value ast::CallExpr::toJson() { - return { - {"@type", "CallExpr"}, - {"callee", callee->toJson()}, - {"args", utils::mapToJson(args)}, - }; -} - -std::unique_ptr -ast::CallExpr::fromJson(boost::json::value json) { - auto callee = fromJsonProperty(json, "callee"); - auto args = fromJsonVector(json, "args"); - return std::make_unique(ast::Location::json(), callee, args); -} - -} // namespace plsm diff --git a/compiler/src/AST/Expr/CallExpr.cpp b/compiler/src/AST/Expr/CallExpr.cpp new file mode 100644 index 0000000..aa1d1bc --- /dev/null +++ b/compiler/src/AST/Expr/CallExpr.cpp @@ -0,0 +1,22 @@ +#include "AST/AST.h" +#include "Utils.h" + +namespace plsm { +namespace ast { + +boost::json::value CallExpr::toJson() { + return { + {"@type", "CallExpr"}, + {"callee", callee->toJson()}, + {"args", utils::mapToJson(args)}, + }; +} + +CallExpr *CallExpr::fromJson(boost::json::value json) { + auto callee = fromJsonProperty(json, "callee"); + auto args = fromJsonVector(json, "args"); + return new CallExpr(SourceRange::json(), callee, args); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Expr/CastExpr.cpp b/compiler/src/AST/Expr/CastExpr.cpp new file mode 100644 index 0000000..a85d53e --- /dev/null +++ b/compiler/src/AST/Expr/CastExpr.cpp @@ -0,0 +1,22 @@ +#include "AST/AST.h" +#include "Utils.h" + +namespace plsm { +namespace ast { + +boost::json::value CastExpr::toJson() { + return { + {"@type", "CastExpr"}, + {"value", value->toJson()}, + {"typeName", typeName->toJson()}, + }; +} + +CastExpr *CastExpr::fromJson(boost::json::value json) { + auto value = fromJsonProperty(json, "value"); + auto typeName = fromJsonProperty(json, "typeName"); + return new CastExpr(SourceRange::json(), value, typeName); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Expr/Closure.cpp b/compiler/src/AST/Expr/Closure.cpp deleted file mode 100644 index 8d3f26a..0000000 --- a/compiler/src/AST/Expr/Closure.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "AST/Def.h" -#include "Utils.h" - -namespace plsm { - -boost::json::value ast::Closure::toJson() { - return { - {"@type", "Closure"}, - {"args", utils::mapToJson(args)}, - {"body", body->toJson()}, - }; -} - -std::unique_ptr ast::Closure::fromJson(boost::json::value json) { - auto args = fromJsonVector(json, "args"); - auto body = fromJsonProperty(json, "body"); - return std::make_unique(ast::Location::json(), args, body); -} - -} // namespace plsm diff --git a/compiler/src/AST/Expr/Identifier.cpp b/compiler/src/AST/Expr/Identifier.cpp index 8ea1fb8..10aa811 100644 --- a/compiler/src/AST/Expr/Identifier.cpp +++ b/compiler/src/AST/Expr/Identifier.cpp @@ -1,19 +1,19 @@ -#include "AST/Def.h" -#include "AST/Expr/Identifier.h" +#include "AST/AST.h" namespace plsm { +namespace ast { -boost::json::value ast::Identifier::toJson() { +boost::json::value Identifier::toJson() { return { {"@type", "Identifier"}, {"name", name}, }; } -std::unique_ptr -ast::Identifier::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - return std::make_unique(ast::Location::json(), name); +Identifier *Identifier::fromJson(boost::json::value json) { + auto name = getJsonValue(json, "name"); + return new Identifier(SourceRange::json(), name); } +} // namespace ast } // namespace plsm diff --git a/compiler/src/AST/Expr/LambdaExpr.cpp b/compiler/src/AST/Expr/LambdaExpr.cpp new file mode 100644 index 0000000..1894bb8 --- /dev/null +++ b/compiler/src/AST/Expr/LambdaExpr.cpp @@ -0,0 +1,22 @@ +#include "AST/AST.h" +#include "Utils.h" + +namespace plsm { +namespace ast { + +boost::json::value LambdaExpr::toJson() { + return { + {"@type", "LambdaExpr"}, + {"params", utils::mapToJson(params)}, + {"body", utils::mapToJson(body)}, + }; +} + +LambdaExpr *LambdaExpr::fromJson(boost::json::value json) { + auto params = fromJsonVector(json, "params"); + auto body = fromJsonVector(json, "body"); + return new LambdaExpr(SourceRange::json(), params, body); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Expr/PropExpr.cpp b/compiler/src/AST/Expr/PropExpr.cpp deleted file mode 100644 index 2cccd61..0000000 --- a/compiler/src/AST/Expr/PropExpr.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "AST/Def.h" -#include - -namespace plsm { - -boost::json::value ast::PropExpr::toJson() { - return { - {"@type", "PropExpr"}, - {"expr", expr->toJson()}, - {"property", property}, - }; -} - -std::unique_ptr -ast::PropExpr::fromJson(boost::json::value json) { - auto expr = fromJsonProperty(json, "expr"); - auto property = getJsonValue(json, "property"); - return std::make_unique(ast::Location::json(), expr, property); -} - -} // namespace plsm diff --git a/compiler/src/AST/Expr/Tuple.cpp b/compiler/src/AST/Expr/Tuple.cpp deleted file mode 100644 index 04ef18f..0000000 --- a/compiler/src/AST/Expr/Tuple.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "AST/Def.h" -#include "Utils.h" - -namespace plsm { - -boost::json::value ast::Tuple::toJson() { - return { - {"@type", "Tuple"}, - {"values", utils::mapToJson(values)}, - }; -} - -std::unique_ptr ast::Tuple::fromJson(boost::json::value json) { - auto values = fromJsonVector(json, "values"); - return std::make_unique(ast::Location::json(), values); -} - -} // namespace plsm diff --git a/compiler/src/AST/Expr/UnExpr.cpp b/compiler/src/AST/Expr/UnExpr.cpp new file mode 100644 index 0000000..f20d872 --- /dev/null +++ b/compiler/src/AST/Expr/UnExpr.cpp @@ -0,0 +1,36 @@ +#include "AST/AST.h" +#include + +namespace plsm { +namespace ast { + +static const std::unordered_map unOpToString = { + {UnOp::POS, "+"}, + {UnOp::NEG, "-"}, + {UnOp::NOT, "!"}, +}; + +static const std::unordered_map stringToUnOp = { + {"+", UnOp::POS}, + {"-", UnOp::NEG}, + {"!", UnOp::NOT}, +}; + +boost::json::value UnExpr::toJson() { + return { + {"@type", "UnExpr"}, + {"op", unOpToString.at(op)}, + {"expr", expr->toJson()}, + }; +} + +UnExpr *UnExpr::fromJson(boost::json::value json) { + auto opString = getJsonValue(json, "op"); + auto op = stringToUnOp.at(opString); + + auto expr = fromJsonProperty(json, "expr"); + return new UnExpr(SourceRange::json(), op, expr); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Expr/UnaryExpr.cpp b/compiler/src/AST/Expr/UnaryExpr.cpp deleted file mode 100644 index 0242754..0000000 --- a/compiler/src/AST/Expr/UnaryExpr.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "AST/Def.h" -#include "AST/Expr/UnaryExpr.h" -#include - -namespace plsm { - -boost::json::value ast::UnaryExpr::toJson() { - return { - {"@type", "UnaryExpr"}, - {"op", op}, - {"expr", expr->toJson()}, - }; -} - -std::unique_ptr -ast::UnaryExpr::fromJson(boost::json::value json) { - auto op = getJsonValue(json, "op"); - auto expr = fromJsonProperty(json, "expr"); - return std::make_unique(ast::Location::json(), op, expr); -} - -} // namespace plsm diff --git a/compiler/src/AST/Expr/Value.cpp b/compiler/src/AST/Expr/Value.cpp index 849d26c..71bc7b3 100644 --- a/compiler/src/AST/Expr/Value.cpp +++ b/compiler/src/AST/Expr/Value.cpp @@ -1,29 +1,26 @@ -#include "AST/Def.h" +#include "AST/AST.h" #include namespace plsm { +namespace ast { +// boost::json::value NullValue::toJson() { return nullptr; } -boost::json::value ast::NullValue::toJson() { return nullptr; } +// std::unique_ptr +// NullValue::fromJson(boost::json::value json) { +// return std::make_unique(SourceRange::json()); +// } -std::unique_ptr -ast::NullValue::fromJson(boost::json::value json) { - return std::make_unique(ast::Location::json()); +boost::json::value IntValue::toJson() { return value; } + +IntValue *IntValue::fromJson(boost::json::value json) { + return new IntValue(SourceRange::json(), json.as_int64()); } -boost::json::value ast::IntValue::toJson() { return value; } +boost::json::value FloatValue::toJson() { return value; } -std::unique_ptr -ast::IntValue::fromJson(boost::json::value json) { - return std::make_unique(ast::Location::json(), - json.as_int64()); -} - -boost::json::value ast::FloatValue::toJson() { return value; } - -std::unique_ptr -ast::FloatValue::fromJson(boost::json::value json) { - return std::make_unique(ast::Location::json(), - json.as_double()); +FloatValue *FloatValue::fromJson(boost::json::value json) { + return new FloatValue(SourceRange::json(), json.as_double()); } +} // namespace ast } // namespace plsm diff --git a/compiler/src/AST/Module/Import.cpp b/compiler/src/AST/Module/Import.cpp index 0d0f8a6..7dfb761 100644 --- a/compiler/src/AST/Module/Import.cpp +++ b/compiler/src/AST/Module/Import.cpp @@ -1,19 +1,16 @@ -#include "AST/Def.h" +#include "AST/AST.h" #include namespace plsm { +namespace ast { -boost::json::value ast::Import::toJson() { - return { - {"@type", "Import"}, - {"moduleName", moduleName} - }; -} - -std::unique_ptr -ast::Import::fromJson(boost::json::value json) { - auto moduleName = getJsonValue(json, "moduleName"); - return std::make_unique(ast::Location::json(), moduleName); +boost::json::value Import::toJson() { + return {{"@type", "Import"}, {"moduleName", moduleName}}; +} +Import *Import::fromJson(boost::json::value json) { + auto moduleName = getJsonValue(json, "moduleName"); + return new Import(SourceRange::json(), moduleName); } +} // namespace ast } // namespace plsm diff --git a/compiler/src/AST/Module/Module.cpp b/compiler/src/AST/Module/Module.cpp index 590d890..0a2ce23 100644 --- a/compiler/src/AST/Module/Module.cpp +++ b/compiler/src/AST/Module/Module.cpp @@ -1,9 +1,10 @@ -#include "AST/Def.h" +#include "AST/AST.h" #include "Utils.h" namespace plsm { +namespace ast { -boost::json::value ast::Module::toJson() { +boost::json::value Module::toJson() { return { {"@type", "Module"}, {"name", name}, @@ -12,11 +13,13 @@ boost::json::value ast::Module::toJson() { }; } -std::unique_ptr ast::Module::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - auto imports = fromJsonVector(json, "imports"); - auto stmts = fromJsonVector(json, "stmts"); - return std::make_unique(ast::Location::json(), name, imports, stmts); +Module *Module::fromJson(boost::json::value json) { + auto name = getJsonValue(json, "name"); + auto imports = fromJsonVector(json, "imports"); + auto stmts = fromJsonVector(json, "stmts"); + + return new Module(SourceRange::json(), name, imports, stmts); } +} // namespace ast } // namespace plsm diff --git a/compiler/src/AST/Stmt/AssignStmt.cpp b/compiler/src/AST/Stmt/AssignStmt.cpp new file mode 100644 index 0000000..fe3e622 --- /dev/null +++ b/compiler/src/AST/Stmt/AssignStmt.cpp @@ -0,0 +1,21 @@ +#include "AST/AST.h" + +namespace plsm { +namespace ast { + +boost::json::value AssignStmt::toJson() { + return { + {"@type", "AssignStmt"}, + {"lval", lval->toJson()}, + {"rval", rval->toJson()}, + }; +} + +AssignStmt *AssignStmt::fromJson(boost::json::value json) { + auto lval = fromJsonProperty(json, "lval"); + auto rval = fromJsonProperty(json, "rval"); + return new AssignStmt(SourceRange::json(), lval, rval); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Stmt/ExprStmt.cpp b/compiler/src/AST/Stmt/ExprStmt.cpp index 74d183c..344d8b6 100644 --- a/compiler/src/AST/Stmt/ExprStmt.cpp +++ b/compiler/src/AST/Stmt/ExprStmt.cpp @@ -1,16 +1,19 @@ -#include "AST/Stmt/ExprStmt.h" -#include "AST/Def.h" +#include "AST/AST.h" namespace plsm { +namespace ast { -boost::json::value ast::ExprStmt::toJson() { - return {{"@type", "ExprStmt"}, {"expr", expr->toJson()}}; +boost::json::value ExprStmt::toJson() { + return { + {"@type", "ExprStmt"}, + {"expr", expr->toJson()}, + }; } -std::unique_ptr -ast::ExprStmt::fromJson(boost::json::value json) { - auto expr = fromJsonProperty(json, "expr"); - return std::make_unique(ast::Location::json(), expr); +ExprStmt *ExprStmt::fromJson(boost::json::value json) { + auto expr = fromJsonProperty(json, "expr"); + return new ExprStmt(SourceRange::json(), expr); } +} // namespace ast } // namespace plsm diff --git a/compiler/src/AST/Stmt/FnDecl.cpp b/compiler/src/AST/Stmt/FnDecl.cpp new file mode 100644 index 0000000..7bafb0d --- /dev/null +++ b/compiler/src/AST/Stmt/FnDecl.cpp @@ -0,0 +1,41 @@ +#include "AST/AST.h" +#include "Utils.h" + +namespace plsm { +namespace ast { + +boost::json::value FnParam::toJson() { + return { + {"@type", "FnParam"}, + {"name", name}, + {"typeName", typeName->toJson()}, + }; +} + +FnParam *FnParam::fromJson(boost::json::value json) { + auto name = getJsonValue(json, "name"); + auto typeName = fromJsonProperty(json, "typeName"); + return new FnParam(SourceRange::json(), name, typeName); +} + +boost::json::value FnDecl::toJson() { + return { + {"@type", "FnDecl"}, + {"name", name}, + {"params", utils::mapToJson(params)}, + {"returnTypeName", returnTypeName->toJson()}, + {"body", utils::mapToJson(body)}, + }; +} + +FnDecl *FnDecl::fromJson(boost::json::value json) { + auto name = getJsonValue(json, "name"); + auto params = fromJsonVector(json, "params"); + auto returnTypeName = + fromJsonProperty(json, "returnTypeName"); + auto body = fromJsonVector(json, "body"); + return new FnDecl(SourceRange::json(), name, params, returnTypeName, body); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Stmt/FnDef.cpp b/compiler/src/AST/Stmt/FnDef.cpp deleted file mode 100644 index deea330..0000000 --- a/compiler/src/AST/Stmt/FnDef.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "AST/Def.h" -#include "Utils.h" - -namespace plsm { - -boost::json::value ast::FnArg::toJson() { - return { - {"@type", "FnArg"}, - {"name", name}, - {"type", type->toJson()}, - }; -} - -std::unique_ptr ast::FnArg::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - auto type = fromJsonProperty(json, "type"); - return std::make_unique(ast::Location::json(), name, type); -} - -boost::json::value ast::FnDef::toJson() { - return { - {"@type", "FnDef"}, - {"name", name}, - {"args", utils::mapToJson(args)}, - {"returnType", returnType->toJson()}, - {"body", body->toJson()}, - }; -} - -std::unique_ptr ast::FnDef::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - auto args = fromJsonVector(json, "args"); - auto returnType = fromJsonProperty(json, "returnType"); - auto body = fromJsonProperty(json, "body"); - return std::make_unique(ast::Location::json(), name, args, - returnType, body); -} - -} // namespace plsm diff --git a/compiler/src/AST/Stmt/IfStmt.cpp b/compiler/src/AST/Stmt/IfStmt.cpp new file mode 100644 index 0000000..261c378 --- /dev/null +++ b/compiler/src/AST/Stmt/IfStmt.cpp @@ -0,0 +1,24 @@ +#include "AST/AST.h" +#include "Utils.h" + +namespace plsm { +namespace ast { + +boost::json::value IfStmt::toJson() { + return { + {"@type", "IfStmt"}, + {"condition", condition->toJson()}, + {"ifBody", utils::mapToJson(ifBody)}, + {"elseBody", utils::mapToJson(elseBody)}, + }; +} + +IfStmt *IfStmt::fromJson(boost::json::value json) { + auto condition = fromJsonProperty(json, "condition"); + auto ifBody = fromJsonVector(json, "ifBody"); + auto elseBody = fromJsonVector(json, "elseBody"); + return new IfStmt(SourceRange::json(), condition, ifBody, elseBody); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Stmt/RetStmt.cpp b/compiler/src/AST/Stmt/RetStmt.cpp new file mode 100644 index 0000000..b262b6a --- /dev/null +++ b/compiler/src/AST/Stmt/RetStmt.cpp @@ -0,0 +1,19 @@ +#include "AST/AST.h" + +namespace plsm { +namespace ast { + +boost::json::value RetStmt::toJson() { + return { + {"@type", "RetStmt"}, + {"value", value->toJson()}, + }; +} + +RetStmt *RetStmt::fromJson(boost::json::value json) { + auto value = fromJsonProperty(json, "value"); + return new RetStmt(SourceRange::json(), value); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Stmt/TraitAlias.cpp b/compiler/src/AST/Stmt/TraitAlias.cpp deleted file mode 100644 index 25ee489..0000000 --- a/compiler/src/AST/Stmt/TraitAlias.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "AST/Stmt/TraitAlias.h" -#include "AST/Def.h" - -namespace plsm { - -boost::json::value ast::TraitAlias::toJson() { - return { - {"@type", "TraitAlias"}, - {"alias", alias}, - {"aliased", aliased}, - }; -} - -std::unique_ptr -ast::TraitAlias::fromJson(boost::json::value json) { - auto alias = getJsonValue(json, "alias"); - auto aliased = getJsonValue(json, "aliased"); - return std::make_unique(ast::Location::json(), alias, - aliased); -} - -} // namespace plsm diff --git a/compiler/src/AST/Stmt/TraitDef.cpp b/compiler/src/AST/Stmt/TraitDef.cpp deleted file mode 100644 index fecb378..0000000 --- a/compiler/src/AST/Stmt/TraitDef.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "AST/Def.h" -#include "AST/Stmt/FnDef.h" -#include "AST/Stmt/TraitDef.h" -#include "Utils.h" - -namespace plsm { - -boost::json::value ast::TraitDef::toJson() { - return { - {"@type", "TraitDef"}, - {"name", name}, - {"traits", utils::mapToJson(traits)}, - }; -} - -std::unique_ptr -ast::TraitDef::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - auto traits = fromJsonVector(json, "traits"); - return std::make_unique(ast::Location::json(), name, traits); -} - -} // namespace plsm diff --git a/compiler/src/AST/Stmt/TypeAlias.cpp b/compiler/src/AST/Stmt/TypeAlias.cpp deleted file mode 100644 index 45c0a06..0000000 --- a/compiler/src/AST/Stmt/TypeAlias.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "AST/Def.h" - -namespace plsm { - -boost::json::value ast::TypeAlias::toJson() { - return { - {"@type", "TypeAlias"}, - {"alias", alias}, - {"type", type->toJson()}, - }; -} - -std::unique_ptr -ast::TypeAlias::fromJson(boost::json::value json) { - return nullptr; -} - -} // namespace plsm diff --git a/compiler/src/AST/Stmt/TypeDef.cpp b/compiler/src/AST/Stmt/TypeDef.cpp deleted file mode 100644 index 19f76ef..0000000 --- a/compiler/src/AST/Stmt/TypeDef.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "AST/Def.h" -#include "AST/Stmt/FnDef.h" -#include "AST/Stmt/TypeDef.h" -#include "Utils.h" -#include - -namespace plsm { - -boost::json::value ast::TypeDef::toJson() { - return { - {"@type", "TypeDef"}, - {"name", name}, - {"attrs", utils::mapToJson(attrs)}, - {"members", utils::mapToJson(members)}, - }; -} - -std::unique_ptr ast::TypeDef::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - auto attrs = fromJsonVector(json, "attrs"); - auto members = fromJsonVector(json, "members"); - return std::make_unique(ast::Location::json(), name, attrs, members); -} - -} // namespace plsm diff --git a/compiler/src/AST/Stmt/ValDecl.cpp b/compiler/src/AST/Stmt/ValDecl.cpp deleted file mode 100644 index c2b3934..0000000 --- a/compiler/src/AST/Stmt/ValDecl.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "AST/Def.h" - -namespace plsm { - -boost::json::value ast::ValDecl::toJson() { - return { - {"@type", "ValDecl"}, - {"name", name}, - {"type", type->toJson()}, - {"value", value->toJson()}, - }; -} - -std::unique_ptr ast::ValDecl::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - auto type = fromJsonProperty(json, "type"); - auto value = fromJsonProperty(json, "value"); - return std::make_unique(ast::Location::json(), name, type, value); -} - -} // namespace plsm diff --git a/compiler/src/AST/Stmt/VarDecl.cpp b/compiler/src/AST/Stmt/VarDecl.cpp new file mode 100644 index 0000000..22c0d0d --- /dev/null +++ b/compiler/src/AST/Stmt/VarDecl.cpp @@ -0,0 +1,21 @@ +#include "AST/AST.h" + +namespace plsm { +namespace ast { + +boost::json::value VarDecl::toJson() { + return { + {"@type", "VarDecl"}, + {"name", name}, + {"typeName", typeName->toJson()}, + }; +} + +VarDecl *VarDecl::fromJson(boost::json::value json) { + auto name = getJsonValue(json, "name"); + auto typeName = fromJsonProperty(json, "typeName"); + return new VarDecl(SourceRange::json(), name, typeName); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Stmt/WhileStmt.cpp b/compiler/src/AST/Stmt/WhileStmt.cpp new file mode 100644 index 0000000..e25515b --- /dev/null +++ b/compiler/src/AST/Stmt/WhileStmt.cpp @@ -0,0 +1,22 @@ +#include "AST/AST.h" +#include "Utils.h" + +namespace plsm { +namespace ast { + +boost::json::value WhileStmt::toJson() { + return { + {"@type", "WhileStmt"}, + {"condition", condition->toJson()}, + {"body", utils::mapToJson(body)}, + }; +} + +WhileStmt *WhileStmt::fromJson(boost::json::value json) { + auto condition = fromJsonProperty(json, "condition"); + auto body = fromJsonVector(json, "body"); + return new WhileStmt(SourceRange::json(), condition, body); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Type/Closure.cpp b/compiler/src/AST/Type/Closure.cpp deleted file mode 100644 index 53cf414..0000000 --- a/compiler/src/AST/Type/Closure.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "AST/Def.h" -#include "Utils.h" - -namespace plsm { - -boost::json::value ast::ClosureType::toJson() { - return { - {"@type", "ClosureType"}, - {"from", utils::mapToJson(from)}, - {"to", to->toJson()}, - }; -} - -std::unique_ptr -ast::ClosureType::fromJson(boost::json::value json) { - auto from = fromJsonVector(json, "from"); - auto to = fromJsonProperty(json, "to"); - return std::make_unique(ast::Location::json(), from, to); -} - -} // namespace plsm diff --git a/compiler/src/AST/Type/FunctionType.cpp b/compiler/src/AST/Type/FunctionType.cpp new file mode 100644 index 0000000..9c26c39 --- /dev/null +++ b/compiler/src/AST/Type/FunctionType.cpp @@ -0,0 +1,22 @@ +#include "AST/AST.h" +#include "Utils.h" + +namespace plsm { +namespace ast { + +boost::json::value FunctionType::toJson() { + return { + {"@type", "FunctionType"}, + {"paramTypes", utils::mapToJson(paramTypes)}, + {"returnType", returnType->toJson()}, + }; +} + +FunctionType *FunctionType::fromJson(boost::json::value json) { + auto paramTypes = fromJsonVector(json, "paramTypes"); + auto returnType = fromJsonProperty(json, "returnType"); + return new FunctionType(paramTypes, returnType); +} + +} // namespace ast +} // namespace plsm \ No newline at end of file diff --git a/compiler/src/AST/Type/Generic.cpp b/compiler/src/AST/Type/Generic.cpp deleted file mode 100644 index 5b9bd06..0000000 --- a/compiler/src/AST/Type/Generic.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "AST/Def.h" -#include "AST/Type/Generic.h" -#include "Utils.h" - -namespace plsm { - -boost::json::value ast::GenericType::toJson() { - return { - {"@type", "GenericType"}, - {"name", name}, - {"types", utils::mapToJson(types)}, - }; -} - -std::unique_ptr -ast::GenericType::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - auto types = fromJsonVector(json, "types"); - return std::make_unique(ast::Location::json(), name, types); -} - -} // namespace plsm diff --git a/compiler/src/AST/Type/Named.cpp b/compiler/src/AST/Type/Named.cpp deleted file mode 100644 index 04b57d3..0000000 --- a/compiler/src/AST/Type/Named.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "AST/Def.h" -#include "AST/Type/Named.h" - -namespace plsm { - -boost::json::value ast::NamedType::toJson() { - return { - {"@type", "NamedType"}, - {"name", name}, - }; -} - -std::unique_ptr -ast::NamedType::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - return std::make_unique(ast::Location::json(), name); -} - -} // namespace plsm diff --git a/compiler/src/AST/Type/PrimitiveType.cpp b/compiler/src/AST/Type/PrimitiveType.cpp new file mode 100644 index 0000000..9d660bd --- /dev/null +++ b/compiler/src/AST/Type/PrimitiveType.cpp @@ -0,0 +1,19 @@ +#include "AST/AST.h" + +namespace plsm { +namespace ast { + +boost::json::value PrimitiveType::toJson() { + return { + {"@type", "PrimitiveType"}, + {"name", name}, + }; +} + +PrimitiveType *PrimitiveType::fromJson(boost::json::value json) { + auto name = getJsonValue(json, "name"); + return new PrimitiveType(name); +} + +} // namespace ast +} // namespace plsm \ No newline at end of file diff --git a/compiler/src/AST/Type/Tuple.cpp b/compiler/src/AST/Type/Tuple.cpp deleted file mode 100644 index 2d60bb1..0000000 --- a/compiler/src/AST/Type/Tuple.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "AST/Def.h" -#include "AST/Type/Tuple.h" -#include "Utils.h" - -namespace plsm { - -boost::json::value ast::TupleType::toJson() { - return { - {"@type", "TupleType"}, - {"types", utils::mapToJson(types)}, - }; -} - -std::unique_ptr -ast::TupleType::fromJson(boost::json::value json) { - auto types = fromJsonVector(json, "types"); - return std::make_unique(ast::Location::json(), types); -} - -} // namespace plsm diff --git a/compiler/src/AST/TypeName/PrimitiveTypeName.cpp b/compiler/src/AST/TypeName/PrimitiveTypeName.cpp new file mode 100644 index 0000000..da42043 --- /dev/null +++ b/compiler/src/AST/TypeName/PrimitiveTypeName.cpp @@ -0,0 +1,16 @@ +#include "AST/AST.h" + +namespace plsm { +namespace ast { + +boost::json::value PrimitiveTypeName::toJson() { + return {{"@type", "PrimitiveTypeName"}, {"name", name}}; +} + +PrimitiveTypeName *PrimitiveTypeName::fromJson(boost::json::value json) { + auto name = getJsonValue(json, "name"); + return new PrimitiveTypeName(SourceRange::json(), name); +} + +} // namespace ast +} // namespace plsm \ No newline at end of file diff --git a/compiler/src/Parser.cpp b/compiler/src/Parser.cpp index f0bbf6d..7f85184 100644 --- a/compiler/src/Parser.cpp +++ b/compiler/src/Parser.cpp @@ -1,21 +1,16 @@ #include "Parser.h" -#include "AST/Def.h" - -#include -#include - -#include "AST/Module/Module.h" +#include "AST/AST.h" #include "plsmBaseVisitor.h" #include "plsmLexer.h" #include "plsmParser.h" -class ErrorListener : public antlr4::BaseErrorListener { +class MyAntlr4ErrorListener : public antlr4::BaseErrorListener { std::string file; std::string *error; public: - ErrorListener(const std::string &file, std::string *error) + MyAntlr4ErrorListener(const std::string &file, std::string *error) : file(file), error(error) {} virtual void syntaxError(antlr4::Recognizer *recognizer, @@ -30,423 +25,7 @@ public: 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(ctx->getStart()->getLine(), - ctx->getStart()->getCharPositionInLine()), - std::pair(ctx->getStop()->getLine(), - ctx->getStop()->getCharPositionInLine())); - } - - template inline T visitT(antlr4::tree::ParseTree *ctx) { - return std::any_cast(visit(ctx)); - } - - template - inline std::unique_ptr visitU(antlr4::tree::ParseTree *ctx) { - return std::unique_ptr(visitT(ctx)); - } - - template - inline std::vector> visitVU(antlr4::tree::ParseTree *ctx) { - std::vector> res; - for (auto &el : visitT>(ctx)) - res.push_back(std::unique_ptr(el)); - return res; - } - - virtual std::any visitModule(plsmParser::ModuleContext *ctx) override { - auto name = ctx->identifier()->getText(); - - std::vector> imports; - for (auto &import : ctx->moduleImport()) - imports.push_back(visitU(import)); - - std::vector> stmts; - for (auto &stmt : ctx->moduleStmt()) - stmts.push_back(visitU(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(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(ctx->let()); - if (ctx->fnDecl()) - stmt = (ast::Stmt *)visitT(ctx->fnDecl()); - if (ctx->fnDef()) - stmt = (ast::Stmt *)visitT(ctx->fnDef()); - if (ctx->traitDef()) - stmt = (ast::Stmt *)visitT(ctx->traitDef()); - if (ctx->typeDef()) - stmt = (ast::Stmt *)visitT(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> fns; - for (auto &decl : ctx->fnDecl()) - fns.push_back(visitU(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(ctx->type()); - return std::any((ast::Stmt *)new ast::TypeAlias(loc(ctx), name, gen)); - } - - std::vector> attrs; - if (ctx->fnDefArgs()) - attrs = visitVU(ctx->fnDefArgs()); - - std::vector> members; - for (auto &def : ctx->fnDef()) - members.push_back(visitU(def)); - for (auto &decl : ctx->fnDecl()) - members.push_back(visitU(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> args; - if (ctx->fnDefArgs()) - args = std::move(visitVU(ctx->fnDefArgs())); - - auto returnType = visitU(ctx->type()); - auto body = visitU(ctx->expr()); - - return std::any(new ast::FnDef(loc(ctx), name, args, returnType, body)); - } - - virtual std::any visitFnDefArgs(plsmParser::FnDefArgsContext *ctx) override { - std::vector args; - - for (size_t i = 0; i < ctx->children.size(); i += 3) { - auto name = ctx->children[i]->getText(); - auto type = visitU(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> args; - if (ctx->fnDeclArgs()) - args = visitVU(ctx->fnDeclArgs()); - - auto returnType = visitU(ctx->type()); - auto body = std::unique_ptr(nullptr); - - return std::any(new ast::FnDef(loc(ctx), name, args, returnType, body)); - } - - virtual std::any - visitFnDeclArgs(plsmParser::FnDeclArgsContext *ctx) override { - std::vector args; - - for (size_t i = 0; i < ctx->children.size(); i++) { - std::string name; - if (dynamic_cast(ctx->children[i])) - name = ctx->children[i++]->getText(); - - auto type = visitU(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 type(nullptr); - if (ctx->type()) - type = visitU(ctx->type()); - - auto expr = visitU(ctx->expr()); - - return std::any(new ast::ValDecl(loc(ctx), name, type, expr)); - } - - virtual std::any visitExprStmt(plsmParser::ExprStmtContext *ctx) override { - auto expr = visitU(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(ctx->tupleTypeList()); - return std::any((ast::Type *)new ast::TupleType(loc(ctx), types)); - } - } - - if (ctx->children[0]->getText() == "[") { - std::vector> args; - if (ctx->typeList()) - args = visitVU(ctx->typeList()); - - auto returnType = visitU(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(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 types; - for (auto &type : ctx->type()) - types.push_back(visitT(type)); - - return std::any(types); - } - - virtual std::any visitTypeList(plsmParser::TypeListContext *ctx) override { - std::vector types; - for (auto &type : ctx->type()) - types.push_back(visitT(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> args; - if (ctx->fnDefArgs()) - args = visitVU(ctx->fnDefArgs()); - - auto body = visitU(ctx->expr()); - - return std::any((ast::Expr *)new ast::Closure(loc(ctx), args, body)); - } - - // block - if (ctx->children[0]->getText() == "{") { - std::vector> stmts; - for (auto &stmt : ctx->blockStmt()) - stmts.push_back(visitU(stmt)); - - auto result = visitU(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(ctx->expr2()); - auto op = ctx->operator_()->getText(); - auto right = visitU(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(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(ctx->expr()); - return std::any((ast::Expr *)new ast::PrefExpr(loc(ctx), expr)); - } - - if (ctx->expr0()) { - auto expr = visitU(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> args; - if (ctx->exprList()) - args = visitVU(ctx->exprList()); - - return std::any((ast::Expr *)new ast::CallExpr(loc(ctx), expr, args)); - } - - // tuple - if (ctx->tupleExprList()) { - auto values = visitVU(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(ctx->let()); - if (ctx->exprStmt()) - stmt = (ast::Stmt *)visitT(ctx->exprStmt()); - if (ctx->fnDef()) - stmt = (ast::Stmt *)visitT(ctx->fnDef()); - - return std::any(stmt); - } - - virtual std::any - visitTupleExprList(plsmParser::TupleExprListContext *ctx) override { - std::vector exprs; - for (auto &expr : ctx->expr()) - exprs.push_back(visitT(expr)); - - return std::any(exprs); - } - - virtual std::any visitExprList(plsmParser::ExprListContext *ctx) override { - std::vector exprs; - for (auto &expr : ctx->expr()) - exprs.push_back(visitT(expr)); - - return std::any(exprs); - } - - virtual std::any - visitIdentifierList(plsmParser::IdentifierListContext *ctx) override { - std::vector identifiers; - for (auto &identifier : ctx->identifier()) - identifiers.push_back(visitT(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); - - else if (!text.rfind("0o", 0)) - value = std::strtol(text.substr(2).data(), NULL, 8); - - else if (!text.rfind("0b", 0)) - value = std::strtol(text.substr(2).data(), NULL, 2); - - else value = std::strtol(text.data(), NULL, 10); - - 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"; - if (text.at(0) == '0') - text = "0" + text; - - 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 parse(const std::string &file, +std::shared_ptr parse(const std::string &file, const std::string &input) { auto istream = antlr4::ANTLRInputStream(input); auto lexer = plsmLexer(&istream); @@ -454,17 +33,12 @@ std::unique_ptr parse(const std::string &file, auto parser = plsmParser(&tokens); std::string error; - ErrorListener listener(file, &error); + MyAntlr4ErrorListener 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(Visitor(file).visitModule(tree)); - return std::unique_ptr(module); + return std::shared_ptr(tree->ast); } } // namespace plsm diff --git a/compiler/src/main.cpp b/compiler/src/main.cpp index 2fd99da..b2d4f45 100644 --- a/compiler/src/main.cpp +++ b/compiler/src/main.cpp @@ -1,12 +1,11 @@ -#include #include +#include #include #include #include "Parser.h" -static std::string readFile(const std::string &path) -{ +static std::string readFile(const std::string &path) { std::ifstream f(path); auto data = (std::stringstream() << f.rdbuf()).str(); f.close(); @@ -14,10 +13,8 @@ static std::string readFile(const std::string &path) return data; } -int main(int argc, char *argv[]) -{ - if (argc != 2) - { +int main(int argc, char *argv[]) { + if (argc != 2) { std::cout << "Usage:" << std::endl << "\t" << argv[0] << " " << std::endl; exit(EXIT_FAILURE); @@ -25,19 +22,17 @@ int main(int argc, char *argv[]) auto input = readFile(argv[1]); - std::cout << input << std::endl; + // std::cout << input << std::endl; - try - { + try { auto module = plsm::parse(argv[1], input); std::cout << module->toJsonString() << std::endl; - std::cout << "\n\n"; + // std::cout << "\n\n"; - std::cout << plsm::ast::Module::fromJson(module->toJson())->toJson() << std::endl; - } - catch (std::runtime_error &err) - { + // std::cout << plsm::ast::Module::fromJson(module->toJson())->toJson() << + // std::endl; + } catch (std::runtime_error &err) { std::cerr << err.what() << std::endl; exit(EXIT_FAILURE); } diff --git a/compiler/test.json b/compiler/test.json new file mode 100644 index 0000000..afd7649 --- /dev/null +++ b/compiler/test.json @@ -0,0 +1,142 @@ +{ + "@type": "Module", + "name": "default", + "imports": [], + "stmts": [ + { + "@type": "FnDecl", + "name": "main", + "params": [], + "returnTypeName": { + "@type": "PrimitiveTypeName", + "name": "i64" + }, + "body": [ + { + "@type": "VarDecl", + "name": "asdf", + "typeName": { + "@type": "PrimitiveTypeName", + "name": "int" + } + }, + { + "@type": "AssignStmt", + "lval": { + "@type": "Identifier", + "name": "asdf" + }, + "rval": 100 + }, + { + "@type": "IfStmt", + "condition": { + "@type": "BinExpr", + "op": ">", + "lhs": { + "@type": "Identifier", + "name": "asdf" + }, + "rhs": 1000 + }, + "ifBody": [ + { + "@type": "AssignStmt", + "lval": { + "@type": "Identifier", + "name": "a" + }, + "rval": 1 + } + ], + "elseBody": [ + { + "@type": "IfStmt", + "condition": { + "@type": "BinExpr", + "op": ">", + "lhs": { + "@type": "Identifier", + "name": "asdf" + }, + "rhs": 500 + }, + "ifBody": [ + { + "@type": "AssignStmt", + "lval": { + "@type": "Identifier", + "name": "a" + }, + "rval": 2 + } + ], + "elseBody": [ + { + "@type": "AssignStmt", + "lval": { + "@type": "Identifier", + "name": "a" + }, + "rval": 3 + } + ] + } + ] + }, + { + "@type": "WhileStmt", + "condition": { + "@type": "BinExpr", + "op": "<", + "lhs": { + "@type": "Identifier", + "name": "a" + }, + "rhs": 10 + }, + "body": [ + { + "@type": "AssignStmt", + "lval": { + "@type": "Identifier", + "name": "a" + }, + "rval": { + "@type": "Identifier", + "name": "a" + } + }, + { + "@type": "ExprStmt", + "expr": { + "@type": "UnExpr", + "op": "+", + "expr": 1 + } + } + ] + }, + { + "@type": "RetStmt", + "value": { + "@type": "BinExpr", + "op": "+", + "lhs": { + "@type": "BinExpr", + "op": "*", + "lhs": 3, + "rhs": 10 + }, + "rhs": { + "@type": "BinExpr", + "op": "*", + "lhs": 21, + "rhs": 2 + } + } + } + ] + } + ] +} \ No newline at end of file diff --git a/examples/new.plsm b/examples/new.plsm new file mode 100644 index 0000000..dffb258 --- /dev/null +++ b/examples/new.plsm @@ -0,0 +1,18 @@ +fun main() i64 { + var asdf : int; + asdf = 100; + + if (asdf > 1000) { + a = 1; + } else if (asdf > 500) { + a = 2; + } else { + a = 3; + } + + while (a < 10) { + a = a + 1; + } + + ret 3 * 10 + 21.0 * 2; +}