diff --git a/compiler/CMakeLists.txt b/compiler/CMakeLists.txt index 7f5ab21..4ee8249 100644 --- a/compiler/CMakeLists.txt +++ b/compiler/CMakeLists.txt @@ -30,7 +30,7 @@ add_custom_command(PRE_BUILD OUTPUT ${ANTLR_INC} COMMENT "Generating plsm_parser" COMMAND java -jar - ${CMAKE_SOURCE_DIR}/thirdparty/antlr-4.13.1-complete.jar + ${CMAKE_SOURCE_DIR}/thirdparty/antlr4-4.13.2-complete.jar ${CMAKE_SOURCE_DIR}/plsm.g4 -o ${GEN_DIR} -Dlanguage=Cpp -no-listener -visitor COMMAND ${CMAKE_COMMAND} -E copy ${GEN_DIR}/*.h ${INC_DIR} diff --git a/compiler/cmake/ExternalAntlr4Cpp.cmake b/compiler/cmake/ExternalAntlr4Cpp.cmake index 95953e1..4266203 100644 --- a/compiler/cmake/ExternalAntlr4Cpp.cmake +++ b/compiler/cmake/ExternalAntlr4Cpp.cmake @@ -9,7 +9,7 @@ include(ExternalProject) set(ANTLR4_ROOT ${CMAKE_CURRENT_BINARY_DIR}/antlr4_runtime/src/antlr4_runtime) set(ANTLR4_INCLUDE_DIRS ${ANTLR4_ROOT}/runtime/Cpp/runtime/src) # set(ANTLR4_GIT_REPOSITORY https://github.com/antlr/antlr4.git) -set(ANTLR4_ZIP_REPOSITORY ${PROJECT_SOURCE_DIR}/thirdparty/antlr-4.13.1.zip) +set(ANTLR4_ZIP_REPOSITORY ${PROJECT_SOURCE_DIR}/thirdparty/antlr4-4.13.2.zip) if(NOT DEFINED ANTLR4_TAG) # Set to branch name to keep library updated at the cost of needing to rebuild after 'clean' # Set to commit hash to keep the build stable and does not need to rebuild after 'clean' @@ -47,7 +47,7 @@ else() set(ANTLR4_SHARED_LIBRARIES ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a) set(ANTLR4_RUNTIME_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/cygantlr4-runtime-4.13.1.dll) + ${ANTLR4_OUTPUT_DIR}/cygantlr4-runtime-4.13.2.dll) elseif(APPLE) set(ANTLR4_RUNTIME_LIBRARIES ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dylib) diff --git a/compiler/include/AST/AST.h b/compiler/include/AST/AST.h index bc6f373..5136e82 100644 --- a/compiler/include/AST/AST.h +++ b/compiler/include/AST/AST.h @@ -14,6 +14,7 @@ #include "Module/Module.h" #include "Stmt/AssignStmt.h" +#include "Stmt/Block.h" #include "Stmt/ExprStmt.h" #include "Stmt/FnDecl.h" #include "Stmt/IfStmt.h" @@ -24,4 +25,4 @@ #include "Type/FunctionType.h" #include "Type/PrimitiveType.h" -#include "TypeName/PrimitiveTypeName.h" +#include "TypeName/NamedTypeName.h" diff --git a/compiler/include/AST/Base.h b/compiler/include/AST/Base.h index cbd28a2..ec403d8 100644 --- a/compiler/include/AST/Base.h +++ b/compiler/include/AST/Base.h @@ -3,15 +3,17 @@ #include #include #include -#include #include #include +#include #include #include #include #include +#include "Terminal.h" + #define LOC_ARG const SourceRange &sourceRange namespace plsm { @@ -30,6 +32,7 @@ class Import; class Module; class AssignStmt; +class Block; class ExprStmt; class FnParam; class FnDecl; @@ -38,7 +41,7 @@ class RetStmt; class VarDecl; class WhileStmt; -class PrimitiveTypeName; +class NamedTypeName; class ASTVisitor { public: @@ -57,6 +60,7 @@ public: virtual std::any visit(Module &module, std::any param) = 0; virtual std::any visit(AssignStmt &assignStmt, std::any param) = 0; + virtual std::any visit(Block &block, 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; @@ -65,8 +69,7 @@ public: 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; + virtual std::any visit(NamedTypeName &namedTypeName, std::any param) = 0; }; } // namespace ast @@ -79,7 +82,7 @@ class Jsonable { public: virtual ~Jsonable() = default; - virtual boost::json::value toJson() = 0; + virtual boost::json::value toJson() const = 0; protected: template @@ -114,7 +117,8 @@ protected: template static inline auto fromJsonProperty(boost::json::value json, std::string property) { - return SubNode::fromJson(getJsonProperty(json, property)); + return std::unique_ptr( + SubNode::fromJson(getJsonProperty(json, property))); } template @@ -122,9 +126,9 @@ 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)); + result.push_back(std::unique_ptr(SubNode::fromJson(el))); } return result; @@ -133,7 +137,7 @@ protected: class SourceRange { public: - SourceRange(const std::string &file, const std::string &text, + SourceRange(const std::string &file, std::string text, std::pair start, std::pair end) : file(file), text(text), start(start), end(end) {} @@ -141,27 +145,34 @@ public: const std::pair start, end; static SourceRange unknown() { - return SourceRange("", "", {-1, -1}, {-1, -1}); + return SourceRange("", "", {0, 0}, {0, 0}); }; static SourceRange json() { - return SourceRange("", "", {-1, -1}, {-1, -1}); + return SourceRange("", "", {0, 0}, {0, 0}); }; }; +class TypeName; + class Type : public Jsonable { public: Type() : Jsonable() {} virtual ~Type() = default; + virtual TypeName *toTypeName() = 0; + + virtual bool operator==(const Type &other) = 0; + virtual bool operator!=(const Type &other) { return !(*this == other); } + static Type *fromJson(boost::json::value json); }; class Symbol { +public: const std::string name; std::shared_ptr type; -public: Symbol(const std::string &name) : name(name) {} Symbol(const std::string &name, Type *type) : name(name), type(type) {} }; @@ -173,29 +184,40 @@ public: const SourceRange sourceRange; - virtual std::string toJsonString() { + virtual std::string toJsonString() const { 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 bool isExpr() const { return false; } + virtual bool isStmt() const { return false; } + virtual bool isTypeName() const { return false; } + + virtual std::string error(const std::string &message) const { + std::stringstream ss; + + ss << "In file " << sourceRange.file << ":" << sourceRange.start.first + << ":" << sourceRange.start.second + 1 << "\n" + << terminal::cyan << sourceRange.text << terminal::reset << "\n" + << terminal::red << message << terminal::reset; + + return ss.str(); + } virtual std::any accept(ASTVisitor *visitor, std::any param) = 0; }; class Expr : public ASTNode { +public: std::shared_ptr type; -public: Expr(LOC_ARG) : ASTNode(sourceRange) {} virtual ~Expr() = default; static Expr *fromJson(boost::json::value json); - virtual bool isExpr() override { return true; } + virtual bool isExpr() const override { return true; } }; class Stmt : public ASTNode { @@ -205,17 +227,19 @@ public: static Stmt *fromJson(boost::json::value json); - virtual bool isStmt() override { return true; } + virtual bool isStmt() const override { return true; } }; class TypeName : public ASTNode { public: + std::shared_ptr type; + TypeName(LOC_ARG) : ASTNode(sourceRange) {} virtual ~TypeName() = default; static TypeName *fromJson(boost::json::value json); - virtual bool isTypeName() override { return true; } + virtual bool isTypeName() const override { return true; } }; } // namespace ast diff --git a/compiler/include/AST/BaseASTVisitor.h b/compiler/include/AST/BaseASTVisitor.h index f5b5b28..e3f41e1 100644 --- a/compiler/include/AST/BaseASTVisitor.h +++ b/compiler/include/AST/BaseASTVisitor.h @@ -10,24 +10,30 @@ public: BaseASTVisitor() : ASTVisitor() {}; virtual std::any visit(BinExpr &binExpr, std::any param) override { - binExpr.lhs->accept(this, param); - binExpr.rhs->accept(this, param); + if (binExpr.lhs.get()) + binExpr.lhs->accept(this, param); + if (binExpr.rhs.get()) + binExpr.rhs->accept(this, param); return std::any(); } virtual std::any visit(CallExpr &callExpr, std::any param) override { - callExpr.callee->accept(this, param); + if (callExpr.callee.get()) + callExpr.callee->accept(this, param); for (auto &arg : callExpr.args) { - arg->accept(this, param); + if (arg.get()) + arg->accept(this, param); } return std::any(); } virtual std::any visit(CastExpr &castExpr, std::any param) override { - castExpr.value->accept(this, param); - castExpr.typeName->accept(this, param); + if (castExpr.value.get()) + castExpr.value->accept(this, param); + if (castExpr.typeName.get()) + castExpr.typeName->accept(this, param); return std::any(); } @@ -36,19 +42,23 @@ public: } virtual std::any visit(LambdaExpr &lambdaExpr, std::any param) override { - for (auto ¶m : lambdaExpr.params) { - param->accept(this, param); + if (lambdaExpr.returnTypeName.get()) + lambdaExpr.returnTypeName->accept(this, param); + + for (auto &p : lambdaExpr.params) { + if (p.get()) + p->accept(this, param); } - for (auto &body : lambdaExpr.body) { - body->accept(this, param); - } + if (lambdaExpr.body.get()) + lambdaExpr.body->accept(this, param); return std::any(); } virtual std::any visit(UnExpr &unExpr, std::any param) override { - unExpr.expr->accept(this, param); + if (unExpr.expr.get()) + unExpr.expr->accept(this, param); return std::any(); } @@ -70,75 +80,90 @@ public: } for (auto &stmt : module.stmts) { - stmt->accept(this, param); + if (stmt.get()) + stmt->accept(this, param); } return std::any(); } virtual std::any visit(AssignStmt &assignStmt, std::any param) override { - assignStmt.lval->accept(this, param); - assignStmt.rval->accept(this, param); + if (assignStmt.lval.get()) + assignStmt.lval->accept(this, param); + if (assignStmt.rval.get()) + assignStmt.rval->accept(this, param); + return std::any(); + } + + virtual std::any visit(Block &block, std::any param) override { + for (auto &stmt : block.stmts) { + if (stmt.get()) + stmt->accept(this, param); + } + return std::any(); } virtual std::any visit(ExprStmt &exprStmt, std::any param) override { - exprStmt.expr->accept(this, param); + if (exprStmt.expr.get()) + exprStmt.expr->accept(this, param); return std::any(); } virtual std::any visit(FnParam &fnParam, std::any param) override { - fnParam.typeName->accept(this, param); + if (fnParam.typeName.get()) + fnParam.typeName->accept(this, param); return std::any(); } virtual std::any visit(FnDecl &fnDecl, std::any param) override { - for (auto ¶m : fnDecl.params) { - param->accept(this, param); + if (fnDecl.returnTypeName.get()) + fnDecl.returnTypeName->accept(this, param); + + for (auto &p : fnDecl.params) { + if (p.get()) + p->accept(this, param); } - for (auto &body : fnDecl.body) { - body->accept(this, param); - } + if (fnDecl.body.get()) + fnDecl.body->accept(this, param); return std::any(); } virtual std::any visit(IfStmt &ifStmt, std::any param) override { - ifStmt.condition->accept(this, param); - - for (auto &ifBody : ifStmt.ifBody) { - ifBody->accept(this, param); - } - - for (auto &elseBody : ifStmt.elseBody) { - elseBody->accept(this, param); - } + if (ifStmt.condition.get()) + ifStmt.condition->accept(this, param); + if (ifStmt.ifBody.get()) + ifStmt.ifBody->accept(this, param); + if (ifStmt.elseBody.get()) + ifStmt.elseBody->accept(this, param); return std::any(); } virtual std::any visit(RetStmt &retStmt, std::any param) override { - retStmt.value->accept(this, param); + if (retStmt.value.get()) + retStmt.value->accept(this, param); return std::any(); } virtual std::any visit(VarDecl &varDecl, std::any param) override { - varDecl.typeName->accept(this, param); + if (varDecl.typeName.get()) + varDecl.typeName->accept(this, param); return std::any(); } virtual std::any visit(WhileStmt &whileStmt, std::any param) override { - whileStmt.condition->accept(this, param); - - for (auto &body : whileStmt.body) { - body->accept(this, param); - } + if (whileStmt.condition.get()) + whileStmt.condition->accept(this, param); + if (whileStmt.body.get()) + whileStmt.body->accept(this, param); return std::any(); } - virtual std::any visit(PrimitiveTypeName &primitiveTypeName, + virtual std::any visit(NamedTypeName &namedTypeName, std::any param) override { return std::any(); } diff --git a/compiler/include/AST/Expr/BinExpr.h b/compiler/include/AST/Expr/BinExpr.h index f7e2932..b5d6a0b 100644 --- a/compiler/include/AST/Expr/BinExpr.h +++ b/compiler/include/AST/Expr/BinExpr.h @@ -2,7 +2,6 @@ #include "AST/Base.h" #include -#include namespace plsm { namespace ast { @@ -28,12 +27,17 @@ enum BinOp { class BinExpr : public Expr { public: const BinOp op; - const std::shared_ptr lhs, rhs; + std::unique_ptr lhs, rhs; - BinExpr(LOC_ARG, const BinOp op, Expr *lhs, Expr *rhs) - : Expr(sourceRange), op(op), lhs(lhs), rhs(rhs) {} + BinExpr(LOC_ARG, const BinOp op, std::unique_ptr lhs, + std::unique_ptr rhs) + : Expr(sourceRange), op(op), lhs(std::move(lhs)), rhs(std::move(rhs)) {} - virtual boost::json::value toJson() override; + BinExpr(LOC_ARG, const BinOp op, std::unique_ptr &lhs, + std::unique_ptr &rhs) + : Expr(sourceRange), op(op), lhs(std::move(lhs)), rhs(std::move(rhs)) {} + + virtual boost::json::value toJson() const override; static BinExpr *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Expr/CallExpr.h b/compiler/include/AST/Expr/CallExpr.h index 0043a97..7d54535 100644 --- a/compiler/include/AST/Expr/CallExpr.h +++ b/compiler/include/AST/Expr/CallExpr.h @@ -9,17 +9,14 @@ namespace ast { class CallExpr : public Expr { public: - const std::shared_ptr callee; - std::vector> args; + std::unique_ptr callee; + std::vector> args; - 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)); - } - } + CallExpr(LOC_ARG, std::unique_ptr callee, + std::vector> args) + : Expr(sourceRange), callee(std::move(callee)), args(std::move(args)) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static CallExpr *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Expr/CastExpr.h b/compiler/include/AST/Expr/CastExpr.h index 65db20d..e5e77ab 100644 --- a/compiler/include/AST/Expr/CastExpr.h +++ b/compiler/include/AST/Expr/CastExpr.h @@ -1,20 +1,21 @@ #pragma once #include "AST/Base.h" -#include namespace plsm { namespace ast { class CastExpr : public Expr { public: - const std::shared_ptr value; - const std::shared_ptr typeName; + std::unique_ptr value; + std::unique_ptr typeName; - CastExpr(LOC_ARG, Expr *value, TypeName *typeName) - : Expr(sourceRange), value(value), typeName(typeName) {} + CastExpr(LOC_ARG, std::unique_ptr value, + std::unique_ptr typeName) + : Expr(sourceRange), value(std::move(value)), + typeName(std::move(typeName)) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static CastExpr *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Expr/Identifier.h b/compiler/include/AST/Expr/Identifier.h index 55be875..1c3fbda 100644 --- a/compiler/include/AST/Expr/Identifier.h +++ b/compiler/include/AST/Expr/Identifier.h @@ -14,7 +14,7 @@ public: Identifier(LOC_ARG, const std::string &name) : Expr(sourceRange), name(name) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static Identifier *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Expr/LambdaExpr.h b/compiler/include/AST/Expr/LambdaExpr.h index c09cd3a..4a4c7ed 100644 --- a/compiler/include/AST/Expr/LambdaExpr.h +++ b/compiler/include/AST/Expr/LambdaExpr.h @@ -2,7 +2,6 @@ #include "AST/Base.h" #include -#include #include namespace plsm { @@ -11,21 +10,17 @@ class FnParam; class LambdaExpr : public Expr { public: - std::vector> params; - std::vector> body; + std::vector> params; + std::unique_ptr returnTypeName; + std::unique_ptr body; - 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)); - } + LambdaExpr(LOC_ARG, std::vector> params, + std::unique_ptr returnTypeName, + std::unique_ptr body) + : Expr(sourceRange), params(std::move(params)), + returnTypeName(std::move(returnTypeName)), body(std::move(body)) {} - for (auto &expr : body) { - this->body.push_back(std::shared_ptr(expr)); - } - } - - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static LambdaExpr *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Expr/UnExpr.h b/compiler/include/AST/Expr/UnExpr.h index ebbe43f..169cb35 100644 --- a/compiler/include/AST/Expr/UnExpr.h +++ b/compiler/include/AST/Expr/UnExpr.h @@ -2,7 +2,6 @@ #include "AST/Base.h" #include -#include namespace plsm { namespace ast { @@ -15,12 +14,12 @@ enum UnOp { class UnExpr : public Expr { public: const UnOp op; - const std::shared_ptr expr; + std::unique_ptr expr; - UnExpr(LOC_ARG, const UnOp op, Expr *expr) - : Expr(sourceRange), op(op), expr(expr) {} + UnExpr(LOC_ARG, const UnOp op, std::unique_ptr expr) + : Expr(sourceRange), op(op), expr(std::move(expr)) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static UnExpr *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Expr/Value.h b/compiler/include/AST/Expr/Value.h index 4974264..e516baa 100644 --- a/compiler/include/AST/Expr/Value.h +++ b/compiler/include/AST/Expr/Value.h @@ -3,7 +3,6 @@ #include "AST/Base.h" #include #include -#include namespace plsm { namespace ast { @@ -11,7 +10,7 @@ namespace ast { // public: // NullValue(LOC_ARG) : Expr(sourceRange) {} -// virtual boost::json::value toJson() override; +// virtual boost::json::value toJson() const override; // static std::unique_ptr fromJson(boost::json::value json); // }; @@ -21,7 +20,7 @@ public: IntValue(LOC_ARG, int64_t value) : Expr(sourceRange), value(value) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static IntValue *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { @@ -35,7 +34,7 @@ public: FloatValue(LOC_ARG, double value) : Expr(sourceRange), value(value) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static FloatValue *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Module/Import.h b/compiler/include/AST/Module/Import.h index 4499248..3210dfa 100644 --- a/compiler/include/AST/Module/Import.h +++ b/compiler/include/AST/Module/Import.h @@ -12,7 +12,7 @@ public: Import(LOC_ARG, const std::string &moduleName) : ASTNode(sourceRange), moduleName(moduleName) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static Import *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Module/Module.h b/compiler/include/AST/Module/Module.h index 4fadc44..51085c2 100644 --- a/compiler/include/AST/Module/Module.h +++ b/compiler/include/AST/Module/Module.h @@ -11,22 +11,16 @@ class Import; class Module : public ASTNode { public: const std::string name; - std::vector> imports; - std::vector> stmts; + std::vector> imports; + std::vector> 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)); - } + Module(LOC_ARG, const std::string &name, + std::vector> imports, + std::vector> stmts) + : ASTNode(sourceRange), name(name), imports(std::move(imports)), + stmts(std::move(stmts)) {} - for (auto &stmt : stmts) { - this->stmts.push_back(std::shared_ptr(stmt)); - } - } - - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static Module *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Stmt/AssignStmt.h b/compiler/include/AST/Stmt/AssignStmt.h index 73accb1..937dc5e 100644 --- a/compiler/include/AST/Stmt/AssignStmt.h +++ b/compiler/include/AST/Stmt/AssignStmt.h @@ -2,20 +2,19 @@ #include "AST/Base.h" #include -#include namespace plsm { namespace ast { class AssignStmt : public Stmt { public: - const std::shared_ptr lval; - const std::shared_ptr rval; + std::unique_ptr lval; + std::unique_ptr rval; - AssignStmt(LOC_ARG, Expr *lval, Expr *rval) - : Stmt(sourceRange), lval(lval), rval(rval) {} + AssignStmt(LOC_ARG, std::unique_ptr lval, std::unique_ptr rval) + : Stmt(sourceRange), lval(std::move(lval)), rval(std::move(rval)) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static AssignStmt *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Stmt/Block.h b/compiler/include/AST/Stmt/Block.h new file mode 100644 index 0000000..7f96236 --- /dev/null +++ b/compiler/include/AST/Stmt/Block.h @@ -0,0 +1,24 @@ +#pragma once + +#include "AST/Base.h" + +namespace plsm { +namespace ast { + +class Block : public ASTNode { +public: + std::vector> stmts; + + Block(LOC_ARG, std::vector> stmts) + : ASTNode(sourceRange), stmts(std::move(stmts)) {} + + virtual boost::json::value toJson() const override; + static Block *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 8864eec..c562f63 100644 --- a/compiler/include/AST/Stmt/ExprStmt.h +++ b/compiler/include/AST/Stmt/ExprStmt.h @@ -7,11 +7,12 @@ namespace plsm { namespace ast { class ExprStmt : public Stmt { public: - const std::shared_ptr expr; + std::unique_ptr expr; - ExprStmt(LOC_ARG, Expr *expr) : Stmt(sourceRange), expr(expr) {} + ExprStmt(LOC_ARG, std::unique_ptr expr) + : Stmt(sourceRange), expr(std::move(expr)) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static ExprStmt *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Stmt/FnDecl.h b/compiler/include/AST/Stmt/FnDecl.h index 52f4399..d187f5b 100644 --- a/compiler/include/AST/Stmt/FnDecl.h +++ b/compiler/include/AST/Stmt/FnDecl.h @@ -11,14 +11,14 @@ namespace ast { class FnParam : public ASTNode { public: const std::string name; - const std::shared_ptr typeName; + std::unique_ptr typeName; std::shared_ptr symbol; - FnParam(LOC_ARG, const std::string &name, TypeName *typeName) - : ASTNode(sourceRange), name(name), typeName(typeName) {} + FnParam(LOC_ARG, const std::string &name, std::unique_ptr typeName) + : ASTNode(sourceRange), name(name), typeName(std::move(typeName)) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static FnParam *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { @@ -29,26 +29,19 @@ public: class FnDecl : public Stmt { public: const std::string name; - std::vector> params; - const std::shared_ptr returnTypeName; - std::vector> body; + std::vector> params; + std::unique_ptr returnTypeName; + std::unique_ptr body; std::shared_ptr symbol; - 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)); - } + FnDecl(LOC_ARG, const std::string &name, + std::vector> params, + std::unique_ptr returnTypeName, std::unique_ptr body) + : Stmt(sourceRange), name(name), params(std::move(params)), + returnTypeName(std::move(returnTypeName)), body(std::move(body)) {} - for (auto &stmt : body) { - this->body.push_back(std::shared_ptr(stmt)); - } - } - - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static FnDecl *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Stmt/IfStmt.h b/compiler/include/AST/Stmt/IfStmt.h index 262d988..a5b62ea 100644 --- a/compiler/include/AST/Stmt/IfStmt.h +++ b/compiler/include/AST/Stmt/IfStmt.h @@ -2,29 +2,21 @@ #include "AST/Base.h" #include -#include namespace plsm { namespace ast { class IfStmt : public Stmt { public: - const std::shared_ptr condition; - std::vector> ifBody, elseBody; + std::unique_ptr condition; + std::unique_ptr ifBody, elseBody; - 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)); - } + IfStmt(LOC_ARG, std::unique_ptr condition, + std::unique_ptr ifBody, std::unique_ptr elseBody) + : Stmt(sourceRange), condition(std::move(condition)), + ifBody(std::move(ifBody)), elseBody(std::move(elseBody)) {} - for (auto &stmt : elseBody) { - this->elseBody.push_back(std::shared_ptr(stmt)); - } - } - - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static IfStmt *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Stmt/RetStmt.h b/compiler/include/AST/Stmt/RetStmt.h index 1f5becc..4ef2ef1 100644 --- a/compiler/include/AST/Stmt/RetStmt.h +++ b/compiler/include/AST/Stmt/RetStmt.h @@ -7,11 +7,12 @@ namespace plsm { namespace ast { class RetStmt : public Stmt { public: - const std::shared_ptr value; + std::unique_ptr value; - RetStmt(LOC_ARG, Expr *value) : Stmt(sourceRange), value(value) {} + RetStmt(LOC_ARG, std::unique_ptr value) + : Stmt(sourceRange), value(std::move(value)) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static RetStmt *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Stmt/VarDecl.h b/compiler/include/AST/Stmt/VarDecl.h index c0d66d7..808edcb 100644 --- a/compiler/include/AST/Stmt/VarDecl.h +++ b/compiler/include/AST/Stmt/VarDecl.h @@ -10,14 +10,14 @@ namespace ast { class VarDecl : public Stmt { public: const std::string name; - const std::shared_ptr typeName; + std::unique_ptr typeName; std::shared_ptr symbol; - VarDecl(LOC_ARG, const std::string &name, TypeName *typeName) - : Stmt(sourceRange), name(name), typeName(typeName) {} + VarDecl(LOC_ARG, const std::string &name, std::unique_ptr typeName) + : Stmt(sourceRange), name(name), typeName(std::move(typeName)) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static VarDecl *fromJson(boost::json::value json); virtual std::any accept(ASTVisitor *visitor, std::any param) override { diff --git a/compiler/include/AST/Stmt/WhileStmt.h b/compiler/include/AST/Stmt/WhileStmt.h index 9c48b7b..ba7d1d1 100644 --- a/compiler/include/AST/Stmt/WhileStmt.h +++ b/compiler/include/AST/Stmt/WhileStmt.h @@ -2,28 +2,26 @@ #include "AST/Base.h" #include -#include namespace plsm { namespace ast { class WhileStmt : public Stmt { public: - const std::shared_ptr condition; - std::vector> body; + std::unique_ptr condition; + std::unique_ptr body; - 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)); - } - } + WhileStmt(LOC_ARG, std::unique_ptr condition, + std::unique_ptr body) + : Stmt(sourceRange), condition(std::move(condition)), + body(std::move(body)) {} - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const 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/FunctionType.h b/compiler/include/AST/Type/FunctionType.h index 1cfb077..51b08c3 100644 --- a/compiler/include/AST/Type/FunctionType.h +++ b/compiler/include/AST/Type/FunctionType.h @@ -11,14 +11,36 @@ public: std::vector> paramTypes; const std::shared_ptr returnType; - FunctionType(const std::vector ¶mTypes, Type *returnType) - : Type(), returnType(returnType) { - for (auto ¶mType : paramTypes) { - this->paramTypes.push_back(std::shared_ptr(paramType)); + FunctionType(std::vector> paramTypes, + std::shared_ptr returnType) + : Type(), paramTypes(paramTypes), returnType(returnType) {} + + virtual TypeName *toTypeName() override; + + virtual bool operator==(const Type &other) override { + if (const FunctionType *ft = dynamic_cast(&other)) { + Type &lhsType = *returnType; + Type &rhsType = *ft->returnType; + if (lhsType != rhsType) + return false; + + if (paramTypes.size() != ft->paramTypes.size()) + return false; + + for (ssize_t i = 0; i < paramTypes.size(); i++) { + Type &lhsType = *paramTypes[i]; + Type &rhsType = *ft->paramTypes[i]; + if (lhsType != rhsType) + return false; + } + + return true; } + + return false; } - virtual boost::json::value toJson() override; + virtual boost::json::value toJson() const override; static FunctionType *fromJson(boost::json::value json); }; } // namespace ast diff --git a/compiler/include/AST/Type/PrimitiveType.h b/compiler/include/AST/Type/PrimitiveType.h index 5d40ee5..8c37362 100644 --- a/compiler/include/AST/Type/PrimitiveType.h +++ b/compiler/include/AST/Type/PrimitiveType.h @@ -11,10 +11,17 @@ 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 TypeName *toTypeName() override; - virtual boost::json::value toJson() override; + virtual bool operator==(const Type &other) override { + if (const PrimitiveType *pt = dynamic_cast(&other)) { + return name == pt->name; + } + + return false; + } + + virtual boost::json::value toJson() const override; static PrimitiveType *fromJson(boost::json::value json); }; diff --git a/compiler/include/AST/TypeName/NamedTypeName.h b/compiler/include/AST/TypeName/NamedTypeName.h new file mode 100644 index 0000000..5118966 --- /dev/null +++ b/compiler/include/AST/TypeName/NamedTypeName.h @@ -0,0 +1,27 @@ +#pragma once + +#include "AST/Base.h" + +namespace plsm { +namespace ast { + +class NamedTypeName : public TypeName { +public: + const std::string name; + + NamedTypeName(LOC_ARG, const std::string &name) + : TypeName(sourceRange), name(name) {} + + bool operator==(const NamedTypeName &other) { return name == other.name; } + bool operator!=(const NamedTypeName &other) { return !(*this == other); } + + virtual boost::json::value toJson() const override; + static NamedTypeName *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/AST/TypeName/PrimitiveTypeName.h b/compiler/include/AST/TypeName/PrimitiveTypeName.h deleted file mode 100644 index aef83dd..0000000 --- a/compiler/include/AST/TypeName/PrimitiveTypeName.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "AST/Base.h" - -namespace plsm { -namespace ast { - -class PrimitiveTypeName : public TypeName { -public: - const std::string name; - - 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/Analysis.h b/compiler/include/Analysis.h index 0f3333f..432ac9b 100644 --- a/compiler/include/Analysis.h +++ b/compiler/include/Analysis.h @@ -4,6 +4,7 @@ namespace plsm { -void performNameAnalysis(std::shared_ptr module); +void performNameAnalysis(std::unique_ptr &module); +void performTypeAnalysis(std::unique_ptr &module); -} \ No newline at end of file +} // namespace plsm diff --git a/compiler/include/Errors.h b/compiler/include/Errors.h new file mode 100644 index 0000000..b5d565f --- /dev/null +++ b/compiler/include/Errors.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +namespace plsm { +namespace errors { + +void put(const std::string &msg); +std::vector get(); + +} // namespace errors +} // namespace plsm diff --git a/compiler/include/Parser.h b/compiler/include/Parser.h index 1d509d4..4599028 100644 --- a/compiler/include/Parser.h +++ b/compiler/include/Parser.h @@ -6,6 +6,6 @@ #include "AST/AST.h" namespace plsm { -std::shared_ptr parse(const std::string &file, +std::unique_ptr parse(const std::string &file, const std::string &input); } diff --git a/compiler/include/Terminal.h b/compiler/include/Terminal.h new file mode 100644 index 0000000..8b65b2a --- /dev/null +++ b/compiler/include/Terminal.h @@ -0,0 +1,10 @@ +#pragma once + +namespace terminal { + +const auto reset = "\x1B[0m"; +const auto cyan = "\x1B[36m"; +const auto red = "\x1B[31m"; +const auto yellow = "\x1B[33m"; + +} // namespace terminal \ No newline at end of file diff --git a/compiler/include/Utils.h b/compiler/include/Utils.h index 79bc489..c0003b4 100644 --- a/compiler/include/Utils.h +++ b/compiler/include/Utils.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -5,7 +7,7 @@ namespace plsm { namespace utils { -template auto mapToJson(const std::vector &vector) { +template inline auto mapToJson(const std::vector &vector) { boost::json::array result(vector.size()); for (size_t i = 0; i < vector.size(); i++) result[i] = vector[i]->toJson(); @@ -13,12 +15,30 @@ template auto mapToJson(const std::vector &vector) { } template -auto mapToJson(const std::vector &vector, const Mapper &mapper) { +inline auto mapToJson(const std::vector &vector, const Mapper &mapper) { boost::json::array result(vector.size()); for (size_t i = 0; i < vector.size(); i++) result[i] = mapper(vector[i]); return result; } +template inline bool is(const A *value) { + return value && dynamic_cast(value); +} + +template +inline std::unique_ptr ptrcast(std::unique_ptr &ptr) { + return std::unique_ptr(static_cast(ptr.release())); +} + +template +inline std::shared_ptr ptrcast(std::shared_ptr &ptr) { + return std::static_pointer_cast(ptr); +} + +// template inline bool is(const A &value) { +// return dynamic_cast(&value) != nullptr; +// } + } // namespace utils } // namespace plsm diff --git a/compiler/plsm.g4 b/compiler/plsm.g4 index cfd408a..4506511 100644 --- a/compiler/plsm.g4 +++ b/compiler/plsm.g4 @@ -2,189 +2,199 @@ grammar plsm; @parser::header { #include "AST/AST.h" +#include "Utils.h" +#include +#include +using namespace plsm::utils; using namespace plsm::ast; } @parser::members { + std::string filename, sourceText; -std::string filename; + void setFileName(const std::string &filename) { this->filename = filename; } + void setSourceText(const std::string &sourceText) { this->sourceText = sourceText; } -void setFileName(const std::string &filename) { this->filename = filename; } + inline SourceRange getSourceRange(antlr4::ParserRuleContext *ctx) { + auto start = ctx->start; + auto stop = getCurrentToken(); -inline SourceRange getSourceRange(antlr4::ParserRuleContext *ctx) { - if (!ctx->getStart() || !ctx->getStop()) { - return SourceRange::unknown(); - } + auto startPos = std::pair(start->getLine(), + start->getCharPositionInLine()); + auto stopPos = std::pair(stop->getLine(), + stop->getCharPositionInLine()); - return SourceRange( - filename, ctx->getText(), - std::pair(ctx->getStart()->getLine(), - ctx->getStart()->getCharPositionInLine()), - std::pair(ctx->getStop()->getLine(), - ctx->getStop()->getCharPositionInLine())); -} + auto text = sourceText.substr( + start->getStartIndex(), stop->getStartIndex() - start->getStartIndex()); + text = boost::trim_copy(text); +// std::cout << "text: `" << text << "`" << std::endl; + + return SourceRange(filename, text, startPos, stopPos); + } } module - returns[Module *ast]: (stmts += topLevelStmt)* { - std::vector stmts; + returns[std::unique_ptr ast]: (stmts += topLevelStmt)* EOF { + std::vector> stmts; for (auto &stmt : $ctx->stmts) { - stmts.push_back(stmt->ast); + stmts.push_back(std::move(stmt->ast)); } - $ast = new Module(getSourceRange($ctx), "default", std::vector(), stmts); + $ast = std::make_unique(getSourceRange($ctx), "default", std::vector>(), std::move(stmts)); }; topLevelStmt - returns[Stmt *ast]: + returns[std::unique_ptr ast]: varDecl { - $ast = $ctx->varDecl()->ast; + $ast = ptrcast($ctx->varDecl()->ast); } | fnDecl { - $ast = $ctx->fnDecl()->ast; + $ast = ptrcast($ctx->fnDecl()->ast); + }; + +block + returns[std::unique_ptr ast]: + (stmts += stmt)* { + std::vector> stmts; + for (auto &stmt : $ctx->stmts) { + stmts.push_back(std::move(stmt->ast)); + } + + $ast = std::make_unique(getSourceRange($ctx), std::move(stmts)); + }; + +singleStmtBlock + returns[std::unique_ptr ast]: + stmt { + std::vector> stmts; + stmts.push_back(std::move($ctx->stmt()->ast)); + $ast = std::make_unique(getSourceRange($ctx), std::move(stmts)); }; stmt - returns[Stmt *ast]: + returns[std::unique_ptr ast]: exprStmt { - $ast = $ctx->exprStmt()->ast; + $ast = ptrcast($ctx->exprStmt()->ast); } | varDecl { - $ast = $ctx->varDecl()->ast; + $ast = ptrcast($ctx->varDecl()->ast); } | retStmt { - $ast = $ctx->retStmt()->ast; + $ast = ptrcast($ctx->retStmt()->ast); } | assignStmt { - $ast = $ctx->assignStmt()->ast; + $ast = ptrcast($ctx->assignStmt()->ast); } | implDeclAssignStmt { - $ast = $ctx->implDeclAssignStmt()->ast; + $ast = ptrcast($ctx->implDeclAssignStmt()->ast); } | ifStmt { - $ast = $ctx->ifStmt()->ast; + $ast = ptrcast($ctx->ifStmt()->ast); } | whileStmt { - $ast = $ctx->whileStmt()->ast; + $ast = ptrcast($ctx->whileStmt()->ast); }; whileStmt - returns[WhileStmt *ast]: + returns[std::unique_ptr ast]: 'while' '(' condition = expr ')' ( - '{' (stmts += stmt)* '}' - | singleStmt = stmt + '{' block '}' + | singleStmtBlock ) { - auto cond = $ctx->condition->ast; + std::unique_ptr body; + if ($ctx->block()) body = std::move($ctx->block()->ast); + else body = std::move($ctx->singleStmtBlock()->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); + $ast = std::make_unique(getSourceRange($ctx), std::move($ctx->condition->ast), std::move(body)); }; ifStmt - returns[IfStmt *ast]: + returns[std::unique_ptr ast]: 'if' '(' condition = expr ')' ( - '{' (ifStmts += stmt)* '}' - | ifSingleStmt = stmt + '{' ifBlock = block '}' + | ifSingleBlock = singleStmtBlock ) ( 'else' ( - '{' (elseStmts += stmt)* '}' - | elseSingleStmt = stmt + '{' elseBlock = block '}' + | elseSingleBlock = singleStmtBlock ) )? { - auto cond = $ctx->condition->ast; + std::unique_ptr ifBody; + if ($ctx->ifBlock) ifBody = std::move($ctx->ifBlock->ast); + else ifBody = std::move($ctx->ifSingleBlock->ast); - std::vector ifBody; - for (auto &stmt : $ctx->ifStmts) { - ifBody.push_back(stmt->ast); - } - if ($ctx->ifSingleStmt) ifBody.push_back($ctx->ifSingleStmt->ast); + std::unique_ptr elseBody; + if ($ctx->elseBlock) elseBody = std::move($ctx->elseBlock->ast); + else if ($ctx->elseSingleBlock) elseBody = std::move($ctx->elseSingleBlock->ast); + else elseBody = std::make_unique(SourceRange::unknown(), std::vector>()); - - std::vector elseBody; - for (auto &stmt : $ctx->elseStmts) { - elseBody.push_back(stmt->ast); - } - if ($ctx->elseSingleStmt) elseBody.push_back($ctx->elseSingleStmt->ast); - - $ast = new IfStmt(getSourceRange($ctx), cond, ifBody, elseBody); + $ast = std::make_unique(getSourceRange($ctx), std::move($ctx->condition->ast), std::move(ifBody), std::move(elseBody)); }; implDeclAssignStmt - returns[Stmt *ast]: + returns[std::unique_ptr ast]: IDENTIFIER ':=' expr { // TODO }; assignStmt - returns[AssignStmt *ast]: - lval = expr '=' rval = expr { - $ast = new AssignStmt(getSourceRange($ctx), $ctx->lval->ast, $ctx->rval->ast); + returns[std::unique_ptr ast]: + lval = expr '=' rval = expr ';' { + $ast = std::make_unique(getSourceRange($ctx), std::move($ctx->lval->ast), std::move($ctx->rval->ast)); }; retStmt - returns[RetStmt *ast]: + returns[std::unique_ptr ast]: 'ret' expr ';' { - $ast = new RetStmt(getSourceRange($ctx), $ctx->expr()->ast); + $ast = std::make_unique(getSourceRange($ctx), std::move($ctx->expr()->ast)); }; fnDecl - returns[FnDecl *ast]: + returns[std::unique_ptr ast]: 'fun' name = IDENTIFIER '(' ( params += fnParam (',' params += fnParam)* - )? ')' typeName '{' (stmts += stmt)* '}' { + )? ')' typeName '{' block '}' { auto name = $ctx->name->getText(); - std::vector params; + std::vector> params; for (auto ¶m : $ctx->params) { - params.push_back(param->ast); + params.push_back(std::move(param->ast)); } - auto returnTypeName = $ctx->typeName()->ast; - - std::vector body; - for (auto &stmt : $ctx->stmts) { - body.push_back(stmt->ast); - } - - $ast = new FnDecl(getSourceRange($ctx), name, params, returnTypeName, body); + $ast = std::make_unique(getSourceRange($ctx), name, std::move(params), std::move($ctx->typeName()->ast), std::move($ctx->block()->ast)); }; fnParam - returns[FnParam *ast]: + returns[std::unique_ptr ast]: IDENTIFIER typeName { - $ast = new FnParam(getSourceRange($ctx), $ctx->IDENTIFIER()->getText(), $ctx->typeName()->ast); + $ast = std::make_unique(getSourceRange($ctx), $ctx->IDENTIFIER()->getText(), std::move($ctx->typeName()->ast)); }; varDecl - returns[VarDecl *ast]: + returns[std::unique_ptr ast]: 'var' IDENTIFIER ':' typeName ';' { auto name = $ctx->IDENTIFIER()->getText(); - $ast = new VarDecl(getSourceRange($ctx), name, $ctx->typeName()->ast); + $ast = std::make_unique(getSourceRange($ctx), name, std::move($ctx->typeName()->ast)); }; exprStmt - returns[ExprStmt *ast]: + returns[std::unique_ptr ast]: expr ';' { - $ast = new ExprStmt(getSourceRange($ctx), $ctx->expr()->ast); + $ast = std::make_unique(getSourceRange($ctx), std::move($ctx->expr()->ast)); }; expr - returns[Expr *ast]: + returns[std::unique_ptr ast]: value = binaryExpr { - $ast = $ctx->value->ast; + $ast = std::move($ctx->value->ast); }; binaryExpr - returns[Expr *ast]: + returns[std::unique_ptr ast]: value = unaryExpr { - $ast = $ctx->value->ast; + $ast = std::move($ctx->value->ast); } | lhs = binaryExpr op = ('*' | '/' | '%') rhs = binaryExpr { auto opText = $ctx->op->getText(); @@ -194,7 +204,8 @@ binaryExpr if (opText == "/") op = BinOp::DIV; if (opText == "%") op = BinOp::MOD; - $ast = new BinExpr(getSourceRange($ctx), op, $ctx->lhs->ast, $ctx->rhs->ast); + auto binExpr = std::make_unique(getSourceRange($ctx), op, std::move($ctx->lhs->ast), std::move($ctx->rhs->ast)); + $ast = ptrcast(binExpr); } | lhs = binaryExpr op = ('+' | '-') rhs = binaryExpr { auto opText = $ctx->op->getText(); @@ -203,10 +214,12 @@ binaryExpr if (opText == "+") op = BinOp::ADD; if (opText == "-") op = BinOp::SUB; - $ast = new BinExpr(getSourceRange($ctx), op, $ctx->lhs->ast, $ctx->rhs->ast); + auto binExpr = std::make_unique(getSourceRange($ctx), op, std::move($ctx->lhs->ast), std::move($ctx->rhs->ast)); + $ast = ptrcast(binExpr); } | operand = binaryExpr 'as' typeName { - $ast = new CastExpr(getSourceRange($ctx), $ctx->operand->ast, $ctx->typeName()->ast); + auto castExpr = std::make_unique(getSourceRange($ctx), std::move($ctx->operand->ast), std::move($ctx->typeName()->ast)); + $ast = ptrcast(castExpr); } | lhs = binaryExpr op = ( '==' @@ -226,37 +239,44 @@ binaryExpr if (opText == ">") op = BinOp::GT; if (opText == "<") op = BinOp::LT; - $ast = new BinExpr(getSourceRange($ctx), op, $ctx->lhs->ast, $ctx->rhs->ast); + auto binExpr = std::make_unique(getSourceRange($ctx), op, std::move($ctx->lhs->ast), std::move($ctx->rhs->ast)); + $ast = ptrcast(binExpr); } | lhs = binaryExpr '&&' rhs = binaryExpr { - $ast = new BinExpr(getSourceRange($ctx), BinOp::AND, $ctx->lhs->ast, $ctx->rhs->ast); + auto binExpr = std::make_unique(getSourceRange($ctx), BinOp::AND, std::move($ctx->lhs->ast), std::move($ctx->rhs->ast)); + $ast = ptrcast(binExpr); } | lhs = binaryExpr '||' rhs = binaryExpr { - $ast = new BinExpr(getSourceRange($ctx), BinOp::OR, $ctx->lhs->ast, $ctx->rhs->ast); + auto binExpr = std::make_unique(getSourceRange($ctx), BinOp::OR, std::move($ctx->lhs->ast), std::move($ctx->rhs->ast)); + $ast = ptrcast(binExpr); }; unaryExpr - returns[Expr *ast]: + returns[std::unique_ptr ast]: factorExpr { - $ast = $ctx->factorExpr()->ast; + $ast = ptrcast($ctx->factorExpr()->ast); } | functionCall { - $ast = $ctx->functionCall()->ast; + $ast = ptrcast($ctx->functionCall()->ast); } | '!' unaryExpr { - $ast = new UnExpr(getSourceRange($ctx), UnOp::NOT, $ctx->unaryExpr()->ast); + auto unExpr = std::make_unique(getSourceRange($ctx), UnOp::NOT, std::move($ctx->unaryExpr()->ast)); + $ast = ptrcast(unExpr); } | '+' unaryExpr { - $ast = new UnExpr(getSourceRange($ctx), UnOp::POS, $ctx->unaryExpr()->ast); + auto unExpr = std::make_unique(getSourceRange($ctx), UnOp::POS, std::move($ctx->unaryExpr()->ast)); + $ast = ptrcast(unExpr); } | '-' unaryExpr { - $ast = new UnExpr(getSourceRange($ctx), UnOp::NEG, $ctx->unaryExpr()->ast); + auto unExpr = std::make_unique(getSourceRange($ctx), UnOp::NEG, std::move($ctx->unaryExpr()->ast)); + $ast = ptrcast(unExpr); }; factorExpr - returns[Expr *ast]: + returns[std::unique_ptr ast]: IDENTIFIER { - $ast = new Identifier(getSourceRange($ctx), $ctx->IDENTIFIER()->getText()); + auto id = std::make_unique(getSourceRange($ctx), $ctx->IDENTIFIER()->getText()); + $ast = ptrcast(id); } | INT { auto text = $ctx->INT()->getText(); @@ -275,7 +295,8 @@ factorExpr else value = std::strtol(text.data(), NULL, 10); - $ast = new IntValue(getSourceRange($ctx), value); + auto val = std::make_unique(getSourceRange($ctx), value); + $ast = ptrcast(val); } | FLOAT { auto text = $ctx->FLOAT()->getText(); @@ -286,32 +307,35 @@ factorExpr text = "0" + text; double value = std::strtod(text.data(), NULL); - $ast = new FloatValue(getSourceRange($ctx), value); + auto val = std::make_unique(getSourceRange($ctx), value); + $ast = ptrcast(val); } | BOOL { auto text = $ctx->BOOL()->getText(); - $ast = new IntValue(getSourceRange($ctx), text == "true" ? 1 : 0); + auto val = std::make_unique(getSourceRange($ctx), text == "true" ? 1 : 0); + $ast = ptrcast(val); } | '(' expr ')' { - $ast = $ctx->expr()->ast; + $ast = std::move($ctx->expr()->ast); }; functionCall - returns[Expr *ast]: + returns[std::unique_ptr ast]: callee = factorExpr '(' (args += expr (',' args += expr)*)? ')' { - std::vector args; + std::vector> args; for (auto &arg : $ctx->args) { - args.push_back(arg->ast); + args.push_back(std::move(arg->ast)); } - $ast = new CallExpr(getSourceRange($ctx), $ctx->callee->ast, args); + $ast = std::make_unique(getSourceRange($ctx), std::move($ctx->callee->ast), std::move(args)); }; typeName - returns[TypeName *ast]: + returns[std::unique_ptr ast]: IDENTIFIER { auto text = $ctx->IDENTIFIER()->getText(); - $ast = new PrimitiveTypeName(getSourceRange($ctx), text); + auto named = std::make_unique(getSourceRange($ctx), text); + $ast = ptrcast(named); }; INT: [0-9]+ | '0x' [0-9a-fA-F]+ | '0o' [0-7]+ | '0b' [01]+; diff --git a/compiler/src/AST/Base.cpp b/compiler/src/AST/Base.cpp index fca60f8..0f19b38 100644 --- a/compiler/src/AST/Base.cpp +++ b/compiler/src/AST/Base.cpp @@ -57,8 +57,8 @@ ASTNode *ASTNode::fromJson(boost::json::value json) { if (type == "WhileStmt") return WhileStmt::fromJson(json); - if (type == "PrimitiveTypeName") - return PrimitiveTypeName::fromJson(json); + if (type == "NamedTypeName") + return NamedTypeName::fromJson(json); throw std::runtime_error("json conversion for '" + type + "' not implemented"); diff --git a/compiler/src/AST/Expr/BinExpr.cpp b/compiler/src/AST/Expr/BinExpr.cpp index 9bd646b..ea5b56f 100644 --- a/compiler/src/AST/Expr/BinExpr.cpp +++ b/compiler/src/AST/Expr/BinExpr.cpp @@ -18,7 +18,7 @@ static const std::unordered_map stringToBinOp = { {"||", BinOp::OR}, }; -boost::json::value BinExpr::toJson() { +boost::json::value BinExpr::toJson() const { return { {"@type", "BinExpr"}, {"op", binOpToString.at(op)}, @@ -34,7 +34,7 @@ BinExpr *BinExpr::fromJson(boost::json::value json) { auto lhs = fromJsonProperty(json, "lhs"); auto rhs = fromJsonProperty(json, "rhs"); - return new BinExpr(SourceRange::json(), op, lhs, rhs); + return new BinExpr(SourceRange::json(), op, std::move(lhs), std::move(rhs)); } } // namespace ast diff --git a/compiler/src/AST/Expr/CallExpr.cpp b/compiler/src/AST/Expr/CallExpr.cpp index aa1d1bc..15ce659 100644 --- a/compiler/src/AST/Expr/CallExpr.cpp +++ b/compiler/src/AST/Expr/CallExpr.cpp @@ -4,7 +4,7 @@ namespace plsm { namespace ast { -boost::json::value CallExpr::toJson() { +boost::json::value CallExpr::toJson() const { return { {"@type", "CallExpr"}, {"callee", callee->toJson()}, @@ -15,7 +15,7 @@ boost::json::value CallExpr::toJson() { CallExpr *CallExpr::fromJson(boost::json::value json) { auto callee = fromJsonProperty(json, "callee"); auto args = fromJsonVector(json, "args"); - return new CallExpr(SourceRange::json(), callee, args); + return new CallExpr(SourceRange::json(), std::move(callee), std::move(args)); } } // namespace ast diff --git a/compiler/src/AST/Expr/CastExpr.cpp b/compiler/src/AST/Expr/CastExpr.cpp index a85d53e..a1780b3 100644 --- a/compiler/src/AST/Expr/CastExpr.cpp +++ b/compiler/src/AST/Expr/CastExpr.cpp @@ -4,7 +4,7 @@ namespace plsm { namespace ast { -boost::json::value CastExpr::toJson() { +boost::json::value CastExpr::toJson() const { return { {"@type", "CastExpr"}, {"value", value->toJson()}, @@ -15,7 +15,8 @@ boost::json::value CastExpr::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); + return new CastExpr(SourceRange::json(), std::move(value), + std::move(typeName)); } } // namespace ast diff --git a/compiler/src/AST/Expr/Identifier.cpp b/compiler/src/AST/Expr/Identifier.cpp index 10aa811..564c9e5 100644 --- a/compiler/src/AST/Expr/Identifier.cpp +++ b/compiler/src/AST/Expr/Identifier.cpp @@ -3,7 +3,7 @@ namespace plsm { namespace ast { -boost::json::value Identifier::toJson() { +boost::json::value Identifier::toJson() const { return { {"@type", "Identifier"}, {"name", name}, diff --git a/compiler/src/AST/Expr/LambdaExpr.cpp b/compiler/src/AST/Expr/LambdaExpr.cpp index 1894bb8..23f9488 100644 --- a/compiler/src/AST/Expr/LambdaExpr.cpp +++ b/compiler/src/AST/Expr/LambdaExpr.cpp @@ -4,18 +4,22 @@ namespace plsm { namespace ast { -boost::json::value LambdaExpr::toJson() { +boost::json::value LambdaExpr::toJson() const { return { {"@type", "LambdaExpr"}, {"params", utils::mapToJson(params)}, - {"body", utils::mapToJson(body)}, + {"returnTypeName", returnTypeName->toJson()}, + {"body", body->toJson()}, }; } LambdaExpr *LambdaExpr::fromJson(boost::json::value json) { auto params = fromJsonVector(json, "params"); - auto body = fromJsonVector(json, "body"); - return new LambdaExpr(SourceRange::json(), params, body); + auto returnTypeName = + fromJsonProperty(json, "returnTypeName"); + auto body = fromJsonProperty(json, "body"); + return new LambdaExpr(SourceRange::json(), std::move(params), + std::move(returnTypeName), std::move(body)); } } // namespace ast diff --git a/compiler/src/AST/Expr/UnExpr.cpp b/compiler/src/AST/Expr/UnExpr.cpp index f20d872..763acec 100644 --- a/compiler/src/AST/Expr/UnExpr.cpp +++ b/compiler/src/AST/Expr/UnExpr.cpp @@ -16,7 +16,7 @@ static const std::unordered_map stringToUnOp = { {"!", UnOp::NOT}, }; -boost::json::value UnExpr::toJson() { +boost::json::value UnExpr::toJson() const { return { {"@type", "UnExpr"}, {"op", unOpToString.at(op)}, @@ -29,7 +29,7 @@ UnExpr *UnExpr::fromJson(boost::json::value json) { auto op = stringToUnOp.at(opString); auto expr = fromJsonProperty(json, "expr"); - return new UnExpr(SourceRange::json(), op, expr); + return new UnExpr(SourceRange::json(), op, std::move(expr)); } } // namespace ast diff --git a/compiler/src/AST/Expr/Value.cpp b/compiler/src/AST/Expr/Value.cpp index 71bc7b3..a3ce274 100644 --- a/compiler/src/AST/Expr/Value.cpp +++ b/compiler/src/AST/Expr/Value.cpp @@ -3,20 +3,20 @@ namespace plsm { namespace ast { -// boost::json::value NullValue::toJson() { return nullptr; } +// boost::json::value NullValue::toJson() const { return nullptr; } // std::unique_ptr // NullValue::fromJson(boost::json::value json) { // return std::make_unique(SourceRange::json()); // } -boost::json::value IntValue::toJson() { return value; } +boost::json::value IntValue::toJson() const { return value; } IntValue *IntValue::fromJson(boost::json::value json) { return new IntValue(SourceRange::json(), json.as_int64()); } -boost::json::value FloatValue::toJson() { return value; } +boost::json::value FloatValue::toJson() const { return value; } FloatValue *FloatValue::fromJson(boost::json::value json) { return new FloatValue(SourceRange::json(), json.as_double()); diff --git a/compiler/src/AST/Module/Import.cpp b/compiler/src/AST/Module/Import.cpp index 7dfb761..443e624 100644 --- a/compiler/src/AST/Module/Import.cpp +++ b/compiler/src/AST/Module/Import.cpp @@ -4,7 +4,7 @@ namespace plsm { namespace ast { -boost::json::value Import::toJson() { +boost::json::value Import::toJson() const { return {{"@type", "Import"}, {"moduleName", moduleName}}; } Import *Import::fromJson(boost::json::value json) { diff --git a/compiler/src/AST/Module/Module.cpp b/compiler/src/AST/Module/Module.cpp index 0a2ce23..33c4776 100644 --- a/compiler/src/AST/Module/Module.cpp +++ b/compiler/src/AST/Module/Module.cpp @@ -4,7 +4,7 @@ namespace plsm { namespace ast { -boost::json::value Module::toJson() { +boost::json::value Module::toJson() const { return { {"@type", "Module"}, {"name", name}, @@ -18,7 +18,8 @@ Module *Module::fromJson(boost::json::value json) { auto imports = fromJsonVector(json, "imports"); auto stmts = fromJsonVector(json, "stmts"); - return new Module(SourceRange::json(), name, imports, stmts); + return new Module(SourceRange::json(), name, std::move(imports), + std::move(stmts)); } } // namespace ast diff --git a/compiler/src/AST/Stmt/AssignStmt.cpp b/compiler/src/AST/Stmt/AssignStmt.cpp index fe3e622..f483ce6 100644 --- a/compiler/src/AST/Stmt/AssignStmt.cpp +++ b/compiler/src/AST/Stmt/AssignStmt.cpp @@ -3,7 +3,7 @@ namespace plsm { namespace ast { -boost::json::value AssignStmt::toJson() { +boost::json::value AssignStmt::toJson() const { return { {"@type", "AssignStmt"}, {"lval", lval->toJson()}, @@ -14,7 +14,7 @@ boost::json::value AssignStmt::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); + return new AssignStmt(SourceRange::json(), std::move(lval), std::move(rval)); } } // namespace ast diff --git a/compiler/src/AST/Stmt/Block.cpp b/compiler/src/AST/Stmt/Block.cpp new file mode 100644 index 0000000..1246dfb --- /dev/null +++ b/compiler/src/AST/Stmt/Block.cpp @@ -0,0 +1,20 @@ +#include "AST/AST.h" +#include "Utils.h" + +namespace plsm { +namespace ast { + +boost::json::value Block::toJson() const { + return { + {"@type", "Block"}, + {"stmts", utils::mapToJson(stmts)}, + }; +} + +Block *Block::fromJson(boost::json::value json) { + auto stmts = fromJsonVector(json, "stmts"); + return new Block(SourceRange::json(), std::move(stmts)); +} + +} // namespace ast +} // namespace plsm diff --git a/compiler/src/AST/Stmt/ExprStmt.cpp b/compiler/src/AST/Stmt/ExprStmt.cpp index 344d8b6..c9d35f9 100644 --- a/compiler/src/AST/Stmt/ExprStmt.cpp +++ b/compiler/src/AST/Stmt/ExprStmt.cpp @@ -3,7 +3,7 @@ namespace plsm { namespace ast { -boost::json::value ExprStmt::toJson() { +boost::json::value ExprStmt::toJson() const { return { {"@type", "ExprStmt"}, {"expr", expr->toJson()}, @@ -12,7 +12,7 @@ boost::json::value ExprStmt::toJson() { ExprStmt *ExprStmt::fromJson(boost::json::value json) { auto expr = fromJsonProperty(json, "expr"); - return new ExprStmt(SourceRange::json(), expr); + return new ExprStmt(SourceRange::json(), std::move(expr)); } } // namespace ast diff --git a/compiler/src/AST/Stmt/FnDecl.cpp b/compiler/src/AST/Stmt/FnDecl.cpp index 7bafb0d..c09ef64 100644 --- a/compiler/src/AST/Stmt/FnDecl.cpp +++ b/compiler/src/AST/Stmt/FnDecl.cpp @@ -4,7 +4,7 @@ namespace plsm { namespace ast { -boost::json::value FnParam::toJson() { +boost::json::value FnParam::toJson() const { return { {"@type", "FnParam"}, {"name", name}, @@ -15,16 +15,16 @@ boost::json::value FnParam::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); + return new FnParam(SourceRange::json(), name, std::move(typeName)); } -boost::json::value FnDecl::toJson() { +boost::json::value FnDecl::toJson() const { return { {"@type", "FnDecl"}, {"name", name}, {"params", utils::mapToJson(params)}, {"returnTypeName", returnTypeName->toJson()}, - {"body", utils::mapToJson(body)}, + {"body", body->toJson()}, }; } @@ -33,8 +33,9 @@ FnDecl *FnDecl::fromJson(boost::json::value json) { auto params = fromJsonVector(json, "params"); auto returnTypeName = fromJsonProperty(json, "returnTypeName"); - auto body = fromJsonVector(json, "body"); - return new FnDecl(SourceRange::json(), name, params, returnTypeName, body); + auto body = fromJsonProperty(json, "body"); + return new FnDecl(SourceRange::json(), name, std::move(params), + std::move(returnTypeName), std::move(body)); } } // namespace ast diff --git a/compiler/src/AST/Stmt/IfStmt.cpp b/compiler/src/AST/Stmt/IfStmt.cpp index 261c378..b9b0dde 100644 --- a/compiler/src/AST/Stmt/IfStmt.cpp +++ b/compiler/src/AST/Stmt/IfStmt.cpp @@ -4,20 +4,21 @@ namespace plsm { namespace ast { -boost::json::value IfStmt::toJson() { +boost::json::value IfStmt::toJson() const { return { {"@type", "IfStmt"}, {"condition", condition->toJson()}, - {"ifBody", utils::mapToJson(ifBody)}, - {"elseBody", utils::mapToJson(elseBody)}, + {"ifBody", ifBody->toJson()}, + {"elseBody", elseBody->toJson()}, }; } 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); + auto ifBody = fromJsonProperty(json, "ifBody"); + auto elseBody = fromJsonProperty(json, "elseBody"); + return new IfStmt(SourceRange::json(), std::move(condition), + std::move(ifBody), std::move(elseBody)); } } // namespace ast diff --git a/compiler/src/AST/Stmt/RetStmt.cpp b/compiler/src/AST/Stmt/RetStmt.cpp index b262b6a..e26dd60 100644 --- a/compiler/src/AST/Stmt/RetStmt.cpp +++ b/compiler/src/AST/Stmt/RetStmt.cpp @@ -3,7 +3,7 @@ namespace plsm { namespace ast { -boost::json::value RetStmt::toJson() { +boost::json::value RetStmt::toJson() const { return { {"@type", "RetStmt"}, {"value", value->toJson()}, @@ -12,7 +12,7 @@ boost::json::value RetStmt::toJson() { RetStmt *RetStmt::fromJson(boost::json::value json) { auto value = fromJsonProperty(json, "value"); - return new RetStmt(SourceRange::json(), value); + return new RetStmt(SourceRange::json(), std::move(value)); } } // namespace ast diff --git a/compiler/src/AST/Stmt/VarDecl.cpp b/compiler/src/AST/Stmt/VarDecl.cpp index 22c0d0d..86d9e6c 100644 --- a/compiler/src/AST/Stmt/VarDecl.cpp +++ b/compiler/src/AST/Stmt/VarDecl.cpp @@ -3,7 +3,7 @@ namespace plsm { namespace ast { -boost::json::value VarDecl::toJson() { +boost::json::value VarDecl::toJson() const { return { {"@type", "VarDecl"}, {"name", name}, @@ -14,7 +14,7 @@ boost::json::value VarDecl::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); + return new VarDecl(SourceRange::json(), name, std::move(typeName)); } } // namespace ast diff --git a/compiler/src/AST/Stmt/WhileStmt.cpp b/compiler/src/AST/Stmt/WhileStmt.cpp index e25515b..3b13ae7 100644 --- a/compiler/src/AST/Stmt/WhileStmt.cpp +++ b/compiler/src/AST/Stmt/WhileStmt.cpp @@ -4,18 +4,19 @@ namespace plsm { namespace ast { -boost::json::value WhileStmt::toJson() { +boost::json::value WhileStmt::toJson() const { return { {"@type", "WhileStmt"}, {"condition", condition->toJson()}, - {"body", utils::mapToJson(body)}, + {"body", body->toJson()}, }; } WhileStmt *WhileStmt::fromJson(boost::json::value json) { auto condition = fromJsonProperty(json, "condition"); - auto body = fromJsonVector(json, "body"); - return new WhileStmt(SourceRange::json(), condition, body); + auto body = fromJsonProperty(json, "body"); + return new WhileStmt(SourceRange::json(), std::move(condition), + std::move(body)); } } // namespace ast diff --git a/compiler/src/AST/Type/FunctionType.cpp b/compiler/src/AST/Type/FunctionType.cpp index 9c26c39..3aaf145 100644 --- a/compiler/src/AST/Type/FunctionType.cpp +++ b/compiler/src/AST/Type/FunctionType.cpp @@ -1,10 +1,13 @@ +#include "AST/Type/FunctionType.h" #include "AST/AST.h" +#include "AST/Base.h" #include "Utils.h" +#include namespace plsm { namespace ast { -boost::json::value FunctionType::toJson() { +boost::json::value FunctionType::toJson() const { return { {"@type", "FunctionType"}, {"paramTypes", utils::mapToJson(paramTypes)}, @@ -13,10 +16,19 @@ boost::json::value FunctionType::toJson() { } FunctionType *FunctionType::fromJson(boost::json::value json) { - auto paramTypes = fromJsonVector(json, "paramTypes"); - auto returnType = fromJsonProperty(json, "returnType"); + auto paramTypesU = fromJsonVector(json, "paramTypes"); + auto returnTypeU = fromJsonProperty(json, "returnType"); + + std::vector> paramTypes; + for (auto ¶mType : paramTypesU) + paramTypes.push_back(std::shared_ptr(paramType.release())); + + auto returnType = std::shared_ptr(returnTypeU.release()); + return new FunctionType(paramTypes, returnType); } +TypeName *FunctionType::toTypeName() { return nullptr; } + } // namespace ast } // namespace plsm \ No newline at end of file diff --git a/compiler/src/AST/Type/PrimitiveType.cpp b/compiler/src/AST/Type/PrimitiveType.cpp index 9d660bd..3aa4532 100644 --- a/compiler/src/AST/Type/PrimitiveType.cpp +++ b/compiler/src/AST/Type/PrimitiveType.cpp @@ -1,9 +1,12 @@ #include "AST/AST.h" +#include "AST/Base.h" +#include "AST/TypeName/NamedTypeName.h" +#include namespace plsm { namespace ast { -boost::json::value PrimitiveType::toJson() { +boost::json::value PrimitiveType::toJson() const { return { {"@type", "PrimitiveType"}, {"name", name}, @@ -15,5 +18,9 @@ PrimitiveType *PrimitiveType::fromJson(boost::json::value json) { return new PrimitiveType(name); } +TypeName *PrimitiveType::toTypeName() { + return new NamedTypeName(SourceRange::unknown(), name); +} + } // namespace ast } // namespace plsm \ No newline at end of file diff --git a/compiler/src/AST/TypeName/PrimitiveTypeName.cpp b/compiler/src/AST/TypeName/PrimitiveTypeName.cpp index da42043..2934030 100644 --- a/compiler/src/AST/TypeName/PrimitiveTypeName.cpp +++ b/compiler/src/AST/TypeName/PrimitiveTypeName.cpp @@ -3,13 +3,13 @@ namespace plsm { namespace ast { -boost::json::value PrimitiveTypeName::toJson() { - return {{"@type", "PrimitiveTypeName"}, {"name", name}}; +boost::json::value NamedTypeName::toJson() const { + return {{"@type", "NamedTypeName"}, {"name", name}}; } -PrimitiveTypeName *PrimitiveTypeName::fromJson(boost::json::value json) { - auto name = getJsonValue(json, "name"); - return new PrimitiveTypeName(SourceRange::json(), name); +NamedTypeName *NamedTypeName::fromJson(boost::json::value json) { + auto name = getJsonValue(json, "name"); + return new NamedTypeName(SourceRange::json(), name); } } // namespace ast diff --git a/compiler/src/Anlaysis/NameAnalysis.cpp b/compiler/src/Anlaysis/NameAnalysis.cpp index 34d3784..d2257b3 100644 --- a/compiler/src/Anlaysis/NameAnalysis.cpp +++ b/compiler/src/Anlaysis/NameAnalysis.cpp @@ -1,58 +1,138 @@ #include "AST/BaseASTVisitor.h" #include "Analysis.h" +#include "Errors.h" +#include "Utils.h" #include -#include +#include namespace plsm { - namespace { class NameAnalysisVisitor1 : public ast::BaseASTVisitor { - std::stack>> *scopes; + std::vector>> *scopes; public: NameAnalysisVisitor1( - std::stack>> *scopes) + std::vector>> *scopes) : scopes(scopes) {} virtual std::any visit(ast::FnDecl &fnDecl, std::any param) override { + if (!fnDecl.name.size()) + return std::any(); + auto symbol = std::make_shared(fnDecl.name); fnDecl.symbol = symbol; - scopes->top()[fnDecl.name] = symbol; + scopes->back()[fnDecl.name] = symbol; return std::any(); } virtual std::any visit(ast::VarDecl &varDecl, std::any param) override { + if (!varDecl.name.size()) + return std::any(); + auto symbol = std::make_shared(varDecl.name); varDecl.symbol = symbol; - scopes->top()[varDecl.name] = symbol; + scopes->back()[varDecl.name] = symbol; return std::any(); } }; class NameAnalysisVisitor2 : public ast::BaseASTVisitor { - std::stack>> *scopes; + std::vector>> *scopes; void push() { - scopes->push(std::map>()); + scopes->push_back(std::map>()); } - void pop() { scopes->pop(); } + void pop() { scopes->pop_back(); } + + std::shared_ptr findSymbol(std::string name) { + for (long i = scopes->size() - 1; i >= 0; i--) { + auto scope = scopes->at(i); + if (scope.count(name)) + return scope[name]; + } + + return std::shared_ptr(); + } public: NameAnalysisVisitor2( - std::stack>> *scopes) + std::vector>> *scopes) : scopes(scopes) {} + + virtual std::any visit(ast::FnParam &fnParam, std::any param) override { + if (!fnParam.name.size()) + return std::any(); + + auto symbol = std::make_shared(fnParam.name); + fnParam.symbol = symbol; + scopes->back()[fnParam.name] = symbol; + + return std::any(); + } + + virtual std::any visit(ast::FnDecl &fnDecl, std::any param) override { + push(); + BaseASTVisitor::visit(fnDecl, param); + pop(); + + return std::any(); + } + + virtual std::any visit(ast::Block &block, std::any param) override { + push(); + BaseASTVisitor::visit(block, param); + pop(); + + return std::any(); + } + + virtual std::any visit(ast::LambdaExpr &lambdaExpr, std::any param) override { + push(); + BaseASTVisitor::visit(lambdaExpr, param); + pop(); + + return std::any(); + } + + virtual std::any visit(ast::Identifier &identifier, std::any param) override { + if (!identifier.name.size()) + return std::any(); + + auto symbol = findSymbol(identifier.name); + + if (!symbol.get()) { + errors::put(identifier.error("unable to resolve identifier '" + + identifier.name + "'")); + return std::any(); + } + + identifier.symbol = symbol; + + return std::any(); + } + + virtual std::any visit(ast::VarDecl &varDecl, std::any param) override { + if (!varDecl.name.size()) + return std::any(); + + auto symbol = std::make_shared(varDecl.name); + varDecl.symbol = symbol; + scopes->back()[varDecl.name] = symbol; + + return std::any(); + } }; } // namespace -void performNameAnalysis(std::shared_ptr module) { - std::stack>> scopes; - scopes.push(std::map>()); +void performNameAnalysis(std::unique_ptr &module) { + std::vector>> scopes; + scopes.push_back(std::map>()); NameAnalysisVisitor1 visitor1(&scopes); NameAnalysisVisitor2 visitor2(&scopes); @@ -62,7 +142,8 @@ void performNameAnalysis(std::shared_ptr module) { } for (auto &stmt : module->stmts) { - stmt->accept(&visitor2, nullptr); + if (utils::is(stmt.get())) + stmt->accept(&visitor2, nullptr); } } diff --git a/compiler/src/Anlaysis/TypeAnalysis.cpp b/compiler/src/Anlaysis/TypeAnalysis.cpp new file mode 100644 index 0000000..d4b36ba --- /dev/null +++ b/compiler/src/Anlaysis/TypeAnalysis.cpp @@ -0,0 +1,407 @@ +#include "AST/Base.h" +#include "AST/Type/PrimitiveType.h" +#include "Analysis.h" + +#include "AST/BaseASTVisitor.h" +#include "Errors.h" +#include "Utils.h" + +#include +#include +#include + +namespace plsm { + +using namespace ast; + +namespace { + +static std::map> primitiveTypes = { + {"i8", std::make_shared("i8")}, + {"i16", std::make_shared("i16")}, + {"i32", std::make_shared("i32")}, + {"i64", std::make_shared("i64")}, + {"u8", std::make_shared("u8")}, + {"u16", std::make_shared("u16")}, + {"u32", std::make_shared("u32")}, + {"u64", std::make_shared("u64")}, + {"float", std::make_shared("float")}, + {"double", std::make_shared("double")}, +}; + +static std::shared_ptr resolveTypeName(const TypeName *typeName) { + if (utils::is(typeName)) { + auto named = (NamedTypeName *)typeName; + if (primitiveTypes.count(named->name)) + return primitiveTypes[named->name]; + + errors::put( + typeName->error("unable to resolve named type '" + named->name + "'")); + return std::shared_ptr(nullptr); + } + + // TODO: function type + + errors::put(typeName->error("unable to resolve type")); + return std::shared_ptr(nullptr); +} + +static void castTo(std::unique_ptr &expr, + const std::shared_ptr &type) { + auto cast = new CastExpr(expr->sourceRange, std::move(expr), + std::unique_ptr(type->toTypeName())); + cast->type = type; + cast->typeName->type = type; + + auto newExpr = std::unique_ptr(cast); + expr.swap(newExpr); +} + +static bool tryAssignTo(std::unique_ptr &from, + const std::shared_ptr &toType) { + if (*from->type == *toType) + return true; + + if (utils::is(from->type.get()) && + utils::is(toType.get())) { + PrimitiveType *fromT = (PrimitiveType *)from->type.get(); + const PrimitiveType *toT = (PrimitiveType *)toType.get(); + + std::map> castMatrix = { + {"i8", {"i16", "i32", "i64", "u8", "u16", "u32", "u64"}}, + {"i16", {"i32", "i64", "u16", "u32", "u64"}}, + {"i32", {"i64", "u32", "u64"}}, + {"i64", {"u64"}}, + {"u8", {"i16", "i32", "i64", "u16", "u32", "u64"}}, + {"u16", {"i32", "i64", "u32", "u64"}}, + {"u32", {"i64", "u64"}}, + {"u64", {}}, + {"float", {"double"}}, + {"double", {}}, + }; + + if (!castMatrix.count(fromT->name)) + return false; + + auto castableTo = castMatrix[fromT->name]; + + for (auto &toName : castableTo) { + if (toT->name == toName) { + castTo(from, toType); + return true; + } + } + + return false; + } + + return false; +} + +static bool canBeCastedTo(std::unique_ptr &from, + const std::shared_ptr &toType) { + if (*from->type == *toType) + return true; + + if (utils::is(from->type.get()) && + utils::is(toType.get())) { + PrimitiveType *fromT = (PrimitiveType *)from->type.get(); + const PrimitiveType *toT = (PrimitiveType *)toType.get(); + + std::vector allNumberTypes = {"i8", "i16", "i32", "i64", + "u8", "u16", "u32", "u64", + "float", "double"}; + std::map> castMatrix = { + {"i8", allNumberTypes}, {"i16", allNumberTypes}, + {"i32", allNumberTypes}, {"i64", allNumberTypes}, + {"u8", allNumberTypes}, {"u16", allNumberTypes}, + {"u32", allNumberTypes}, {"u64", allNumberTypes}, + {"float", allNumberTypes}, {"double", allNumberTypes}, + }; + + if (!castMatrix.count(fromT->name)) + return false; + + auto castableTo = castMatrix[fromT->name]; + + for (auto &toName : castableTo) { + if (toT->name == toName) { + castTo(from, toType); + return true; + } + } + + return false; + } + + return false; +} + +class TypeAnalysisVisitor1 : public BaseASTVisitor { +public: + virtual std::any visit(NamedTypeName &namedTypeName, + std::any param) override { + namedTypeName.type = resolveTypeName(&namedTypeName); + return std::any(); + } + + virtual std::any visit(VarDecl &varDecl, std::any param) override { + if (!varDecl.typeName.get() || !varDecl.symbol.get()) + return std::any(); + + varDecl.typeName->accept(this, param); + if (varDecl.typeName->type.get()) + varDecl.symbol->type = varDecl.typeName->type; + + return std::any(); + } + + virtual std::any visit(FnParam &fnParam, std::any param) override { + if (!fnParam.typeName.get() || !fnParam.symbol.get()) + return std::any(); + + fnParam.typeName->accept(this, param); + if (fnParam.typeName->type.get()) + fnParam.symbol->type = fnParam.typeName->type; + + return std::any(); + } + + virtual std::any visit(FnDecl &fnDecl, std::any param) override { + if (!fnDecl.symbol.get()) + return std::any(); + + std::shared_ptr returnType(nullptr); + if (fnDecl.returnTypeName.get()) { + fnDecl.returnTypeName->accept(this, param); + returnType = fnDecl.returnTypeName->type; + } + + std::vector> paramTypes; + for (auto &p : fnDecl.params) { + if (p.get()) + p->accept(this, param); + + if (p->symbol.get()) { + paramTypes.push_back(p->symbol->type); + } else { + paramTypes.push_back(std::shared_ptr(nullptr)); + } + } + + fnDecl.symbol->type = + std::make_shared(paramTypes, returnType); + + return std::any(); + } +}; + +class TypeAnalysisVisitor2 : public BaseASTVisitor { + std::shared_ptr currentReturnType = nullptr; + +public: + virtual std::any visit(NamedTypeName &namedTypeName, + std::any param) override { + namedTypeName.type = resolveTypeName(&namedTypeName); + return std::any(); + } + + virtual std::any visit(VarDecl &varDecl, std::any param) override { + if (!varDecl.typeName.get() || !varDecl.symbol.get()) + return std::any(); + + varDecl.typeName->accept(this, param); + if (varDecl.typeName->type.get()) + varDecl.symbol->type = varDecl.typeName->type; + + return std::any(); + } + + virtual std::any visit(FnParam &fnParam, std::any param) override { + if (!fnParam.typeName.get() || !fnParam.symbol.get()) + return std::any(); + + fnParam.typeName->accept(this, param); + fnParam.symbol->type = resolveTypeName(fnParam.typeName.get()); + return std::any(); + } + + virtual std::any visit(FnDecl &fnDecl, std::any param) override { + if (fnDecl.symbol.get() && fnDecl.symbol->type.get()) { + auto functionType = (FunctionType *)fnDecl.symbol->type.get(); + currentReturnType = functionType->returnType; + } else { + currentReturnType = std::shared_ptr(nullptr); + } + + if (fnDecl.body.get()) + fnDecl.body->accept(this, param); + + return std::any(); + } + + virtual std::any visit(Identifier &identifier, std::any param) override { + if (!identifier.symbol.get()) + return std::any(); + + identifier.type = identifier.symbol->type; + return std::any(); + } + + virtual std::any visit(IntValue &intValue, std::any param) override { + if ((int8_t)intValue.value == intValue.value) { + intValue.type = std::make_shared("i8"); + } else if ((uint8_t)intValue.value == intValue.value) { + intValue.type = std::make_shared("u8"); + } else if ((int16_t)intValue.value == intValue.value) { + intValue.type = std::make_shared("i16"); + } else if ((uint16_t)intValue.value == intValue.value) { + intValue.type = std::make_shared("u16"); + } else if ((int32_t)intValue.value == intValue.value) { + intValue.type = std::make_shared("i32"); + } else if ((uint32_t)intValue.value == intValue.value) { + intValue.type = std::make_shared("u32"); + } else { + intValue.type = std::make_shared("i64"); + } + + return std::any(); + } + + virtual std::any visit(FloatValue &floatValue, std::any param) override { + if ((float_t)floatValue.value == floatValue.value) { + floatValue.type = std::make_shared("float"); + } else { + floatValue.type = std::make_shared("double"); + } + + return std::any(); + } + + virtual std::any visit(CastExpr &castExpr, std::any param) override { + BaseASTVisitor::visit(castExpr, param); + + // do not multiplicate errors + if (!castExpr.value.get() || !castExpr.value->type.get()) + return std::any(); + if (!castExpr.typeName.get() || !castExpr.typeName->type.get()) + return std::any(); + + if (!canBeCastedTo(castExpr.value, castExpr.typeName->type)) { + errors::put(castExpr.error("cast type mismatch")); + return std::any(); + } + + castExpr.type = castExpr.typeName->type; + + return std::any(); + } + + virtual std::any visit(AssignStmt &assignStmt, std::any param) override { + BaseASTVisitor::visit(assignStmt, param); + + // do not multiplicate errors + if (!assignStmt.lval.get() || !assignStmt.lval->type.get()) + return std::any(); + if (!assignStmt.lval.get() || !assignStmt.rval->type.get()) + return std::any(); + + if (!tryAssignTo(assignStmt.rval, assignStmt.lval->type)) { + errors::put(assignStmt.error("assignment type mismatch")); + return std::any(); + } + + return std::any(); + } + + virtual std::any visit(RetStmt &retStmt, std::any param) override { + BaseASTVisitor::visit(retStmt, param); + + // do not multiplicate errors + if (!retStmt.value.get() || !retStmt.value->type.get()) + return std::any(); + if (!currentReturnType.get()) + return std::any(); + + if (!tryAssignTo(retStmt.value, currentReturnType)) { + errors::put(retStmt.error("return type mismatch")); + return std::any(); + } + + return std::any(); + } + + virtual std::any visit(IfStmt &ifStmt, std::any param) override { + BaseASTVisitor::visit(ifStmt, param); + + // do not multiplicate errors + if (ifStmt.condition.get() && ifStmt.condition->type.get()) { + if (!utils::is(ifStmt.condition->type.get())) { + errors::put(ifStmt.error("condition must be of primitive type")); + } else { + // cast condition to int (to make sure jnz succeeds) + castTo(ifStmt.condition, std::make_shared("i32")); + } + } + + return std::any(); + } + + virtual std::any visit(WhileStmt &whileStmt, std::any param) override { + BaseASTVisitor::visit(whileStmt, param); + + // do not multiplicate errors + if (whileStmt.condition.get() && whileStmt.condition->type.get()) { + if (!utils::is(whileStmt.condition->type.get())) { + errors::put(whileStmt.error("condition must be of primitive type")); + return std::any(); + } else { + // cast condition to int (to make sure jnz succeeds) + castTo(whileStmt.condition, std::make_shared("i32")); + } + } + + return std::any(); + } + + virtual std::any visit(CallExpr &callExpr, std::any param) override { + BaseASTVisitor::visit(callExpr, param); + + // do not multiplicate errors + if (!callExpr.callee.get() || !callExpr.callee->type.get()) + return std::any(); + + if (!utils::is(callExpr.callee->type.get())) { + errors::put(callExpr.error("callee must be a function")); + return std::any(); + } + + callExpr.type = callExpr.callee->type; + + auto functionType = (FunctionType *)(callExpr.callee->type.get()); + if (functionType->paramTypes.size() != callExpr.args.size()) { + errors::put(callExpr.error("wrong number of arguments")); + return std::any(); + } + + return std::any(); + } +}; + +} // namespace + +void performTypeAnalysis(std::unique_ptr &module) { + TypeAnalysisVisitor1 visitor1; + TypeAnalysisVisitor2 visitor2; + + for (auto &stmt : module->stmts) { + stmt->accept(&visitor1, std::any()); + } + + for (auto &stmt : module->stmts) { + if (utils::is(stmt.get())) + stmt->accept(&visitor2, std::any()); + } +} + +} // namespace plsm \ No newline at end of file diff --git a/compiler/src/Errors.cpp b/compiler/src/Errors.cpp new file mode 100644 index 0000000..c04c660 --- /dev/null +++ b/compiler/src/Errors.cpp @@ -0,0 +1,7 @@ +#include "Errors.h" + +static std::vector _errors; + +void plsm::errors::put(const std::string &error) { _errors.push_back(error); } + +std::vector plsm::errors::get() { return std::vector(_errors); } diff --git a/compiler/src/Parser.cpp b/compiler/src/Parser.cpp index e0e4c81..2868085 100644 --- a/compiler/src/Parser.cpp +++ b/compiler/src/Parser.cpp @@ -1,46 +1,49 @@ #include "Parser.h" #include "AST/AST.h" +#include "Errors.h" #include "plsmBaseVisitor.h" #include "plsmLexer.h" #include "plsmParser.h" +namespace plsm { + namespace { class MyAntlr4ErrorListener : public antlr4::BaseErrorListener { std::string file; - std::string *error; public: - MyAntlr4ErrorListener(const std::string &file, std::string *error) - : file(file), error(error) {} + MyAntlr4ErrorListener(const std::string &file) : file(file) {} virtual void syntaxError(antlr4::Recognizer *recognizer, antlr4::Token *offendingSymbol, size_t line, size_t charPositionInLine, const std::string &msg, std::exception_ptr e) override { + std::stringstream ss; - ss << file << ": line " << line << ":" << charPositionInLine << ": " << msg; - *error = ss.str(); + ss << "In file " << file << ":" << line << ":" << charPositionInLine << "\n" + << terminal::red << msg << terminal::reset; + + errors::put(ss.str()); } }; } // namespace -namespace plsm { - -std::shared_ptr parse(const std::string &file, +std::unique_ptr parse(const std::string &file, const std::string &input) { auto istream = antlr4::ANTLRInputStream(input); auto lexer = plsmLexer(&istream); auto tokens = antlr4::CommonTokenStream(&lexer); auto parser = plsmParser(&tokens); + parser.setFileName(file); + parser.setSourceText(input); - std::string error; - MyAntlr4ErrorListener listener(file, &error); + MyAntlr4ErrorListener listener(file); parser.removeErrorListeners(); parser.addErrorListener(&listener); auto tree = parser.module(); - return std::shared_ptr(tree->ast); + return std::move(tree->ast); } } // namespace plsm diff --git a/compiler/src/main.cpp b/compiler/src/main.cpp index ed0d693..d40249f 100644 --- a/compiler/src/main.cpp +++ b/compiler/src/main.cpp @@ -4,6 +4,7 @@ #include #include "Analysis.h" +#include "Errors.h" #include "Parser.h" static std::string readFile(const std::string &path) { @@ -25,21 +26,36 @@ int main(int argc, char *argv[]) { // std::cout << input << std::endl; + int exitStatus = EXIT_SUCCESS; + try { auto module = plsm::parse(argv[1], input); - std::cout << module->toJsonString() << std::endl; + // std::cout << module->toJsonString() << std::endl; plsm::performNameAnalysis(module); + plsm::performTypeAnalysis(module); // std::cout << "\n\n"; // 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); + if (strlen(err.what()) > 0) + std::cerr << err.what() << std::endl; + exitStatus = EXIT_FAILURE; } + auto errors = plsm::errors::get(); + for (size_t i = 0; i < errors.size(); i++) { + exitStatus = EXIT_FAILURE; + + std::cerr << errors[i] << std::endl; + if (i != errors.size() - 1) + std::cerr << std::endl; + } + + exit(exitStatus); + // auto module = Parser().parse(argv[1], readFile(argv[1])); // auto fn = (ast::FnDef *)module->stmts.at(0); diff --git a/compiler/test.json b/compiler/test.json deleted file mode 100644 index afd7649..0000000 --- a/compiler/test.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "@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/compiler/thirdparty/antlr-4.13.1-complete.jar b/compiler/thirdparty/antlr4-4.13.2-complete.jar similarity index 90% rename from compiler/thirdparty/antlr-4.13.1-complete.jar rename to compiler/thirdparty/antlr4-4.13.2-complete.jar index f539ab0..75bfcc3 100644 Binary files a/compiler/thirdparty/antlr-4.13.1-complete.jar and b/compiler/thirdparty/antlr4-4.13.2-complete.jar differ diff --git a/compiler/thirdparty/antlr-4.13.1.zip b/compiler/thirdparty/antlr4-4.13.2.zip similarity index 86% rename from compiler/thirdparty/antlr-4.13.1.zip rename to compiler/thirdparty/antlr4-4.13.2.zip index a14091b..fb5b940 100644 Binary files a/compiler/thirdparty/antlr-4.13.1.zip and b/compiler/thirdparty/antlr4-4.13.2.zip differ diff --git a/examples/new.plsm b/examples/new.plsm index dffb258..d2b03cb 100644 --- a/examples/new.plsm +++ b/examples/new.plsm @@ -1,6 +1,8 @@ -fun main() i64 { - var asdf : int; - asdf = 100; +var asdf : i64; + +fun main(arg0 i64) i8 { + var a : i64; + a = 10 + 2; if (asdf > 1000) { a = 1; @@ -10,9 +12,5 @@ fun main() i64 { a = 3; } - while (a < 10) { - a = a + 1; - } - - ret 3 * 10 + 21.0 * 2; + ret 100; } diff --git a/examples/new1.plsm b/examples/new1.plsm new file mode 100644 index 0000000..8867d52 --- /dev/null +++ b/examples/new1.plsm @@ -0,0 +1,4 @@ +fun main() i64 { + var a : int; + ret a; +}