revamping...

This commit is contained in:
Ludwig Lehnert 2024-12-22 00:04:01 +01:00
parent 385f2dd53e
commit f8c17803c3
83 changed files with 1559 additions and 1522 deletions

View File

@ -1,7 +1,7 @@
{ {
"C_Cpp.default.includePath": [ "C_Cpp.default.includePath": [
"${workspaceFolder}/include/", "${workspaceFolder}/include/",
"/usr/include/antlr4-runtime", "${workspaceFolder}/build/antlr4_runtime/src/antlr4_runtime/runtime/Cpp/runtime/src",
], ],
"files.associations": { "files.associations": {
"*.embeddedhtml": "html", "*.embeddedhtml": "html",
@ -77,6 +77,8 @@
"typeinfo": "cpp", "typeinfo": "cpp",
"valarray": "cpp", "valarray": "cpp",
"variant": "cpp", "variant": "cpp",
"*.inc": "cpp" "*.inc": "cpp",
"source_location": "cpp",
"text_encoding": "cpp"
} }
} }

View File

@ -17,7 +17,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
include(ExternalAntlr4Cpp) include(ExternalAntlr4Cpp)
find_package( find_package(
Boost 1.84 REQUIRED Boost 1.83 REQUIRED
COMPONENTS json COMPONENTS json
) )

View File

@ -18,7 +18,7 @@ endif()
# Ensure that the include dir already exists at configure time (to avoid cmake erroring # Ensure that the include dir already exists at configure time (to avoid cmake erroring
# on non-existent include dirs) # on non-existent include dirs)
file(MAKE_DIRECTORY "${ANTLR4_INCLUDE_DIRS}") file(MAKE_DIRECTORY ${ANTLR4_INCLUDE_DIRS})
if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*") if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*")
set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(Configuration)) set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(Configuration))

View File

@ -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"

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <any>
#include <boost/json/serialize.hpp> #include <boost/json/serialize.hpp>
#include <exception> #include <exception>
#include <functional> #include <functional>
@ -11,42 +12,75 @@
#include <boost/json.hpp> #include <boost/json.hpp>
#define LOC_ARG const Location &location #define LOC_ARG const SourceRange &sourceRange
namespace plsm { namespace plsm {
namespace ast { 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: public:
Location(const std::string &file, std::pair<size_t, size_t> start, virtual ~ASTVisitor() = default;
std::pair<size_t, size_t> end)
: file(file), start(start), end(end) {}
const std::string file; virtual std::any visit(BinExpr &binExpr, std::any param) = 0;
const std::pair<size_t, size_t> start, end; 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("<json>", {-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 { } // namespace ast
public: } // namespace plsm
ASTNode(LOC_ARG) : location(location) {}
virtual ~ASTNode() = default;
const Location location; namespace plsm {
namespace ast {
class Jsonable {
public:
virtual ~Jsonable() = default;
virtual boost::json::value toJson() = 0; virtual boost::json::value toJson() = 0;
virtual std::string toJsonString() {
return boost::json::serialize(toJson());
}
static std::unique_ptr<ASTNode> fromJson(boost::json::value json);
virtual bool isExpr() { return false; }
virtual bool isStmt() { return false; }
virtual bool isType() { return false; }
protected: protected:
template <class CurrNode> template <class CurrNode>
static inline boost::json::value getJsonProperty(boost::json::value json, static inline boost::json::value getJsonProperty(boost::json::value json,
@ -88,7 +122,7 @@ protected:
std::string property) { std::string property) {
auto arr = getJsonProperty<CurrNode>(json, property).as_array(); auto arr = getJsonProperty<CurrNode>(json, property).as_array();
std::vector<std::unique_ptr<SubNode>> result; std::vector<SubNode *> result;
for (auto &el : arr) { for (auto &el : arr) {
result.push_back(SubNode::fromJson(el)); 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<size_t, size_t> start, std::pair<size_t, size_t> end)
: file(file), text(text), start(start), end(end) {}
const std::string file, text;
const std::pair<size_t, size_t> start, end;
static SourceRange unknown() {
return SourceRange("<?>", "<?>", {-1, -1}, {-1, -1});
};
static SourceRange json() {
return SourceRange("<json>", "<?>", {-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 { class Expr : public ASTNode {
public: public:
Expr(LOC_ARG) : ASTNode(location) {} Expr(LOC_ARG) : ASTNode(sourceRange) {}
virtual ~Expr() = default;
static std::unique_ptr<Expr> fromJson(boost::json::value json); static Expr *fromJson(boost::json::value json);
virtual bool isExpr() override { return true; } virtual bool isExpr() override { return true; }
}; };
class Stmt : public ASTNode { class Stmt : public ASTNode {
public: public:
Stmt(LOC_ARG) : ASTNode(location) {} Stmt(LOC_ARG) : ASTNode(sourceRange) {}
virtual ~Stmt() = default;
static std::unique_ptr<Stmt> fromJson(boost::json::value json); static Stmt *fromJson(boost::json::value json);
virtual bool isStmt() override { return true; } virtual bool isStmt() override { return true; }
}; };
class Type : public ASTNode { class TypeName : public ASTNode {
public: public:
Type(LOC_ARG) : ASTNode(location) {} TypeName(LOC_ARG) : ASTNode(sourceRange) {}
virtual ~TypeName() = default;
static std::unique_ptr<Type> 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 } // namespace ast

View File

@ -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"

View File

@ -1,37 +1,44 @@
#pragma once #pragma once
#include "AST/Base.h" #include "AST/Base.h"
#include <iomanip>
#include <memory> #include <memory>
#include <sstream>
#include <string> #include <string>
namespace plsm { namespace plsm {
namespace ast { namespace ast {
class BinExpr : public Expr { enum BinOp {
const std::string op; ADD,
const std::unique_ptr<Expr> left, right; SUB,
MUL,
DIV,
MOD,
public: EQ,
BinExpr(LOC_ARG, std::unique_ptr<Expr> &left, const std::string &op, NE,
std::unique_ptr<Expr> &right) GT,
: Expr(location), left(std::move(left)), op(op), right(std::move(right)) { GE,
} LT,
LE,
virtual boost::json::value toJson() override; AND,
static std::unique_ptr<BinExpr> fromJson(boost::json::value json); OR,
}; };
class PrefExpr : public Expr { class BinExpr : public Expr {
const std::unique_ptr<Expr> expr; const BinOp op;
const std::shared_ptr<Expr> lhs, rhs;
public: public:
PrefExpr(LOC_ARG, std::unique_ptr<Expr> &expr) BinExpr(LOC_ARG, const BinOp op, Expr *lhs, Expr *rhs)
: Expr(location), expr(std::move(expr)) {} : Expr(sourceRange), op(op), lhs(lhs), rhs(rhs) {}
virtual boost::json::value toJson() override; virtual boost::json::value toJson() override;
static std::unique_ptr<PrefExpr> 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 } // namespace ast

View File

@ -1,25 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <sstream>
#include <vector>
namespace plsm {
namespace ast {
class BlockExpr : public Expr {
const std::vector<std::unique_ptr<Stmt>> stmts;
const std::unique_ptr<Expr> result;
public:
BlockExpr(LOC_ARG, std::vector<std::unique_ptr<Stmt>> &stmts,
std::unique_ptr<Expr> &result)
: Expr(location), stmts(std::move(stmts)), result(std::move(result)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<BlockExpr> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -1,25 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <sstream>
#include <vector>
namespace plsm {
namespace ast {
class CallExpr : public Expr {
const std::unique_ptr<Expr> callee;
const std::vector<std::unique_ptr<Expr>> args;
public:
CallExpr(LOC_ARG, std::unique_ptr<Expr> &callee,
std::vector<std::unique_ptr<Expr>> &args)
: Expr(location), callee(std::move(callee)), args(std::move(args)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<CallExpr> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -0,0 +1,31 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <vector>
namespace plsm {
namespace ast {
class CallExpr : public Expr {
const std::shared_ptr<Expr> callee;
std::vector<std::shared_ptr<Expr>> args;
public:
CallExpr(LOC_ARG, Expr *callee, std::vector<Expr *> args)
: Expr(sourceRange), callee(callee), args() {
for (auto &arg : args) {
this->args.push_back(std::shared_ptr<Expr>(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

View File

@ -0,0 +1,26 @@
#pragma once
#include "AST/Base.h"
#include <string>
namespace plsm {
namespace ast {
class CastExpr : public Expr {
const std::shared_ptr<Expr> value;
const std::shared_ptr<TypeName> 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

View File

@ -1,25 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <sstream>
#include <string>
#include <vector>
namespace plsm {
namespace ast {
class FnArg;
class Closure : public Expr {
const std::vector<std::unique_ptr<FnArg>> args;
const std::unique_ptr<Expr> body;
public:
Closure(LOC_ARG, std::vector<std::unique_ptr<FnArg>> &args, std::unique_ptr<Expr> &body)
: Expr(location), args(std::move(args)), body(std::move(body)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<Closure> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -9,10 +9,15 @@ class Identifier : public Expr {
const std::string name; const std::string name;
public: 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; virtual boost::json::value toJson() override;
static std::unique_ptr<Identifier> 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 } // namespace ast

View File

@ -0,0 +1,36 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <string>
#include <vector>
namespace plsm {
namespace ast {
class FnParam;
class LambdaExpr : public Expr {
std::vector<std::shared_ptr<FnParam>> params;
std::vector<std::shared_ptr<Expr>> body;
public:
LambdaExpr(LOC_ARG, std::vector<FnParam *> params, std::vector<Expr *> body)
: Expr(sourceRange), params(), body() {
for (auto &param : params) {
this->params.push_back(std::shared_ptr<FnParam>(param));
}
for (auto &expr : body) {
this->body.push_back(std::shared_ptr<Expr>(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

View File

@ -1,22 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <sstream>
#include <string>
namespace plsm {
namespace ast {
class PropExpr : public Expr {
const std::unique_ptr<Expr> expr;
const std::string property;
public:
PropExpr(LOC_ARG, std::unique_ptr<Expr> &expr, const std::string &property)
: Expr(location), expr(std::move(expr)), property(property) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<PropExpr> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -1,23 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <sstream>
#include <vector>
namespace plsm {
namespace ast {
class Tuple : public Expr {
const std::vector<std::unique_ptr<Expr>> values;
public:
Tuple(LOC_ARG, std::vector<std::unique_ptr<Expr>> &values)
: Expr(location), values(std::move(values)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<Tuple> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -0,0 +1,31 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <string>
namespace plsm {
namespace ast {
enum UnOp {
NOT,
POS,
NEG,
};
class UnExpr : public Expr {
const UnOp op;
const std::shared_ptr<Expr> 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

View File

@ -1,23 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <iomanip>
#include <memory>
#include <sstream>
#include <string>
namespace plsm {
namespace ast {
class UnaryExpr : public Expr {
const std::string op;
const std::unique_ptr<Expr> expr;
public:
UnaryExpr(LOC_ARG, const std::string &op, std::unique_ptr<Expr> &expr)
: Expr(location), op(op), expr(std::move(expr)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<UnaryExpr> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -1,38 +1,47 @@
#pragma once #pragma once
#include "AST/Base.h" #include "AST/Base.h"
#include <string>
#include <cstdint>
#include <cfloat> #include <cfloat>
#include <cstdint>
#include <string>
namespace plsm { namespace plsm {
namespace ast { namespace ast {
class NullValue : public Expr { // class NullValue : public Expr {
public: // public:
NullValue(LOC_ARG) : Expr(location) {} // NullValue(LOC_ARG) : Expr(sourceRange) {}
virtual boost::json::value toJson() override; // virtual boost::json::value toJson() override;
static std::unique_ptr<NullValue> fromJson(boost::json::value json); // static std::unique_ptr<NullValue> fromJson(boost::json::value json);
}; // };
class IntValue : public Expr { class IntValue : public Expr {
const std::int64_t value; const std::int64_t value;
public: 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; virtual boost::json::value toJson() override;
static std::unique_ptr<IntValue> 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 { class FloatValue : public Expr {
const std::double_t value; const std::double_t value;
public: 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; virtual boost::json::value toJson() override;
static std::unique_ptr<FloatValue> 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 ast
} // namespace plsm } // namespace plsm

View File

@ -1,8 +1,6 @@
#pragma once #pragma once
#include "AST/Base.h" #include "AST/Base.h"
#include <iomanip>
#include <sstream>
#include <string> #include <string>
namespace plsm { namespace plsm {
@ -12,10 +10,14 @@ class Import : public ASTNode {
public: public:
Import(LOC_ARG, const std::string &moduleName) Import(LOC_ARG, const std::string &moduleName)
: ASTNode(location), moduleName(moduleName) {} : ASTNode(sourceRange), moduleName(moduleName) {}
virtual boost::json::value toJson() override; virtual boost::json::value toJson() override;
static std::unique_ptr<Import> 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 ast
} // namespace plsm } // namespace plsm

View File

@ -1,11 +1,8 @@
#pragma once #pragma once
#include "AST/Base.h" #include "AST/Base.h"
#include <cstddef>
#include <iomanip>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <sstream>
namespace plsm { namespace plsm {
namespace ast { namespace ast {
@ -13,18 +10,28 @@ class Import;
class Module : public ASTNode { class Module : public ASTNode {
const std::string name; const std::string name;
const std::vector<std::unique_ptr<Import>> imports; std::vector<std::shared_ptr<Import>> imports;
const std::vector<std::unique_ptr<Stmt>> stmts; std::vector<std::shared_ptr<Stmt>> stmts;
public: public:
Module(LOC_ARG, const std::string &name, Module(LOC_ARG, const std::string &name, const std::vector<Import *> &imports,
std::vector<std::unique_ptr<Import>> &imports, const std::vector<Stmt *> &stmts)
std::vector<std::unique_ptr<Stmt>> &stmts) : ASTNode(sourceRange), name(name), imports(), stmts() {
: ASTNode(location), name(name), imports(std::move(imports)), for (auto &import : imports) {
stmts(std::move(stmts)) {} this->imports.push_back(std::shared_ptr<Import>(import));
}
for (auto &stmt : stmts) {
this->stmts.push_back(std::shared_ptr<Stmt>(stmt));
}
}
virtual boost::json::value toJson() override; virtual boost::json::value toJson() override;
static std::unique_ptr<Module> 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 ast
} // namespace plsm } // namespace plsm

View File

@ -0,0 +1,27 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <string>
namespace plsm {
namespace ast {
class AssignStmt : public Stmt {
const std::shared_ptr<Expr> lval;
const std::shared_ptr<Expr> 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

View File

@ -6,14 +6,17 @@
namespace plsm { namespace plsm {
namespace ast { namespace ast {
class ExprStmt : public Stmt { class ExprStmt : public Stmt {
const std::unique_ptr<Expr> expr; const std::shared_ptr<Expr> expr;
public: public:
ExprStmt(LOC_ARG, std::unique_ptr<Expr> &expr) ExprStmt(LOC_ARG, Expr *expr) : Stmt(sourceRange), expr(expr) {}
: Stmt(location), expr(std::move(expr)) {}
virtual boost::json::value toJson() override; virtual boost::json::value toJson() override;
static std::unique_ptr<ExprStmt> 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 ast
} // namespace plsm } // namespace plsm

View File

@ -0,0 +1,56 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <string>
#include <vector>
namespace plsm {
namespace ast {
class FnParam : public ASTNode {
const std::string name;
const std::shared_ptr<TypeName> 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<std::shared_ptr<FnParam>> params;
const std::shared_ptr<TypeName> returnTypeName;
std::vector<std::shared_ptr<Stmt>> body;
public:
FnDecl(LOC_ARG, const std::string &name, const std::vector<FnParam *> &params,
TypeName *returnTypeName, const std::vector<Stmt *> &body)
: Stmt(sourceRange), name(name), params(), returnTypeName(returnTypeName),
body() {
for (auto &param : params) {
this->params.push_back(std::shared_ptr<FnParam>(param));
}
for (auto &stmt : body) {
this->body.push_back(std::shared_ptr<Stmt>(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

View File

@ -1,41 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <iomanip>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
namespace plsm {
namespace ast {
class FnArg : public ASTNode {
const std::string name;
const std::unique_ptr<Type> type;
public:
FnArg(LOC_ARG, const std::string &name, std::unique_ptr<Type> &type)
: ASTNode(location), name(name), type(std::move(type)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<FnArg> fromJson(boost::json::value json);
};
class FnDef : public Stmt {
const std::string name;
const std::vector<std::unique_ptr<FnArg>> args;
const std::unique_ptr<Type> returnType;
const std::unique_ptr<Expr> body;
public:
FnDef(LOC_ARG, const std::string &name,
std::vector<std::unique_ptr<FnArg>> &args,
std::unique_ptr<Type> &returnType, std::unique_ptr<Expr> &body)
: Stmt(location), name(name), args(std::move(args)),
returnType(std::move(returnType)), body(std::move(body)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<FnDef> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -0,0 +1,36 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <vector>
namespace plsm {
namespace ast {
class IfStmt : public Stmt {
const std::shared_ptr<Expr> condition;
std::vector<std::shared_ptr<Stmt>> ifBody, elseBody;
public:
IfStmt(LOC_ARG, Expr *condition, const std::vector<Stmt *> &ifBody,
const std::vector<Stmt *> &elseBody)
: Stmt(sourceRange), condition(condition) {
for (auto &stmt : ifBody) {
this->ifBody.push_back(std::shared_ptr<Stmt>(stmt));
}
for (auto &stmt : elseBody) {
this->elseBody.push_back(std::shared_ptr<Stmt>(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

View File

@ -0,0 +1,22 @@
#pragma once
#include "AST/Base.h"
#include <memory>
namespace plsm {
namespace ast {
class RetStmt : public Stmt {
const std::shared_ptr<Expr> 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

View File

@ -1,24 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <iomanip>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
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<TraitAlias> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -1,26 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <iomanip>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
namespace plsm {
namespace ast {
class FnDef;
class TraitDef : public Stmt {
const std::string name;
const std::vector<std::unique_ptr<FnDef>> traits;
public:
TraitDef(LOC_ARG, const std::string &name,
std::vector<std::unique_ptr<FnDef>> &traits)
: Stmt(location), name(name), traits(std::move(traits)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<TraitDef> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -1,24 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <iomanip>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
namespace plsm {
namespace ast {
class TypeAlias : public Stmt {
const std::string alias;
const std::unique_ptr<Type> type;
public:
TypeAlias(LOC_ARG, const std::string &alias, std::unique_ptr<Type> &type)
: Stmt(location), alias(alias), type(std::move(type)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<TypeAlias> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -1,29 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <string>
#include <vector>
namespace plsm {
namespace ast {
class FnDef;
class FnArg;
class TypeDef : public Stmt {
const std::string name;
const std::vector<std::unique_ptr<FnArg>> attrs;
const std::vector<std::unique_ptr<FnDef>> members;
public:
TypeDef(LOC_ARG, const std::string &name,
std::vector<std::unique_ptr<FnArg>> &attrs,
std::vector<std::unique_ptr<FnDef>> &members)
: Stmt(location), name(name), attrs(std::move(attrs)),
members(std::move(members)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<TypeDef> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -1,24 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <string>
namespace plsm {
namespace ast {
class ValDecl : public Stmt {
const std::string name;
const std::unique_ptr<Type> type;
const std::unique_ptr<Expr> value;
public:
ValDecl(LOC_ARG, const std::string &name, std::unique_ptr<Type> &type,
std::unique_ptr<Expr> &value)
: Stmt(location), name(name), type(std::move(type)),
value(std::move(value)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<ValDecl> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -0,0 +1,26 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <string>
namespace plsm {
namespace ast {
class VarDecl : public Stmt {
const std::string name;
const std::shared_ptr<TypeName> 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

View File

@ -0,0 +1,29 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <vector>
namespace plsm {
namespace ast {
class WhileStmt : public Stmt {
const std::shared_ptr<Expr> condition;
std::vector<std::shared_ptr<Stmt>> body;
public:
WhileStmt(LOC_ARG, Expr *condition, const std::vector<Stmt *> &body)
: Stmt(sourceRange), condition(condition) {
for (auto &stmt : body) {
this->body.push_back(std::shared_ptr<Stmt>(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

View File

@ -1,23 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <vector>
namespace plsm {
namespace ast {
class ClosureType : public Type {
const std::vector<std::unique_ptr<Type>> from;
const std::unique_ptr<Type> to;
public:
ClosureType(LOC_ARG, std::vector<std::unique_ptr<Type>> &from,
std::unique_ptr<Type> &to)
: Type(location), from(std::move(from)), to(std::move(to)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<ClosureType> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -0,0 +1,25 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <vector>
namespace plsm {
namespace ast {
class FunctionType : public Type {
std::vector<std::unique_ptr<Type>> paramTypes;
const std::unique_ptr<Type> returnType;
public:
FunctionType(const std::vector<Type *> &paramTypes, Type *returnType)
: Type(), returnType(returnType) {
for (auto &paramType : paramTypes) {
this->paramTypes.push_back(std::unique_ptr<Type>(paramType));
}
}
virtual boost::json::value toJson() override;
static FunctionType *fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -1,23 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <memory>
#include <string>
#include <vector>
namespace plsm {
namespace ast {
class GenericType : public Type {
const std::string name;
const std::vector<std::unique_ptr<Type>> types;
public:
GenericType(LOC_ARG, const std::string &name,
std::vector<std::unique_ptr<Type>> &types)
: Type(location), name(name), types(std::move(types)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<GenericType> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -1,20 +0,0 @@
#pragma once
#include "AST/Base.h"
#include <string>
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<NamedType> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -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

View File

@ -1,21 +0,0 @@
#pragma once
#include "AST/Def.h"
#include <memory>
#include <vector>
namespace plsm {
namespace ast {
class TupleType : public Type {
const std::vector<std::unique_ptr<Type>> types;
public:
TupleType(LOC_ARG, std::vector<std::unique_ptr<Type>> &types)
: Type(location), types(std::move(types)) {}
virtual boost::json::value toJson() override;
static std::unique_ptr<TupleType> fromJson(boost::json::value json);
};
} // namespace ast
} // namespace plsm

View File

@ -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

View File

@ -1,12 +1,11 @@
#pragma once #pragma once
#include <string>
#include <stdexcept> #include <stdexcept>
#include <string>
#include "AST/Def.h" #include "AST/AST.h"
namespace plsm namespace plsm {
{ std::shared_ptr<ast::Module> parse(const std::string &file,
std::unique_ptr<ast::Module> parse(const std::string &file, const std::string &input); const std::string &input);
} }

View File

@ -1,83 +1,322 @@
grammar plsm; grammar plsm;
module: MODULE identifier ';' moduleImport* moduleStmt*; @parser::header {
#include "AST/AST.h"
moduleImport: IMPORT importName ';'; using namespace plsm::ast;
importName: identifier ('/' identifier)*; }
moduleStmt: let | fnDecl | fnDef | traitDef | typeDef;
traitDef: TRAIT identifier '=' identifier ';' @parser::members {
| TRAIT identifier '=' '{' (fnDecl)* '}' ';';
typeDef: TYPE identifier '=' type ';' std::string filename;
| TYPE identifier '=' ('(' fnDefArgs ')')? '{' (fnDecl | fnDef)* '}' ';';
fnDef: FN identifier '[' fnDefArgs? ']' type '=' expr ';'; void setFileName(const std::string &filename) { this->filename = filename; }
fnDefArgs: identifier type (',' identifier type)*;
fnDecl: FN identifier '[' fnDeclArgs? ']' type ';'; inline SourceRange getSourceRange(antlr4::ParserRuleContext *ctx) {
fnDeclArgs: identifier? type (',' identifier? type)*; if (!ctx->getStart() || !ctx->getStop()) {
return SourceRange::unknown();
}
let: LET identifier type? '=' expr ';'; return SourceRange(
filename, ctx->getText(),
std::pair<size_t, size_t>(ctx->getStart()->getLine(),
ctx->getStart()->getCharPositionInLine()),
std::pair<size_t, size_t>(ctx->getStop()->getLine(),
ctx->getStop()->getCharPositionInLine()));
}
exprStmt: expr ';'; }
type: type1; // novisit module
type1: type0 returns[Module *ast]: (stmts += topLevelStmt)* {
| '(' type ')' std::vector<Stmt *> stmts;
| '(' tupleTypeList ')' // tuple for (auto &stmt : $ctx->stmts) {
| '[' typeList? ']' '->' type; // closure stmts.push_back(stmt->ast);
type0: identifier }
| identifier '{' typeList '}'; // generic
tupleTypeList: type (',' type)+; $ast = new Module(getSourceRange($ctx), "default", std::vector<Import *>(), stmts);
typeList: type (',' type)*; };
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<Stmt *> 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<Stmt *> ifBody;
for (auto &stmt : $ctx->ifStmts) {
ifBody.push_back(stmt->ast);
}
if ($ctx->ifSingleStmt) ifBody.push_back($ctx->ifSingleStmt->ast);
expr: expr3; // novisit std::vector<Stmt *> elseBody;
expr3: expr2 for (auto &stmt : $ctx->elseStmts) {
| '[' fnDefArgs? ']' '->' expr // closure elseBody.push_back(stmt->ast);
| '{' blockStmt* (expr ';') '}'; }
expr2: expr1 if ($ctx->elseSingleStmt) elseBody.push_back($ctx->elseSingleStmt->ast);
| 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
blockStmt: let | exprStmt | fnDef; $ast = new IfStmt(getSourceRange($ctx), cond, ifBody, elseBody);
tupleExprList: expr (',' expr)+; };
exprList: expr (',' expr)*;
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: '=' | '->' retStmt
| OPERATOR; returns[RetStmt *ast]:
'ret' expr ';' {
$ast = new RetStmt(getSourceRange($ctx), $ctx->expr()->ast);
};
identifier: keyword | IDENTIFIER; fnDecl
keyword: BINOP | FN | IMPORT | LET | MODULE | NATIVE | TRAIT | TYPE | UNOP; returns[FnDecl *ast]:
'fun' name = IDENTIFIER '(' (
params += fnParam (',' params += fnParam)*
)? ')' typeName '{' (stmts += stmt)* '}' {
auto name = $ctx->name->getText();
std::vector<FnParam *> params;
for (auto &param : $ctx->params) {
params.push_back(param->ast);
}
INT_LIT: [0-9]+ | '0x' [0-9a-fA-F]+ | '0o' [0-7]+ | '0b' [01]+; auto returnTypeName = $ctx->typeName()->ast;
FLOAT_LIT: [0-9]+ '.' | [0-9]* '.' [0-9]+;
OPERATOR: ('+'|'-'|'*'|'/'|'%'|'!'|'&'|'$'|'§'|'|'|'='|'<'|'>'|'?'|'~'|'#'|':'|'^'|'\\'|'.')+; std::vector<Stmt *> body;
for (auto &stmt : $ctx->stmts) {
body.push_back(stmt->ast);
}
BINOP: 'binop'; $ast = new FnDecl(getSourceRange($ctx), name, params, returnTypeName, body);
FN: 'fn'; };
IMPORT: 'import';
LET: 'let'; fnParam
MODULE: 'module'; returns[FnParam *ast]:
NATIVE: 'native'; IDENTIFIER typeName {
TRAIT: 'trait'; $ast = new FnParam(getSourceRange($ctx), $ctx->IDENTIFIER()->getText(), $ctx->typeName()->ast);
TYPE: 'type'; };
UNOP: 'unop';
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<Expr *> 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_]*; IDENTIFIER: [a-zA-Z_] [a-zA-Z0-9_]*;

View File

@ -1,23 +1,21 @@
#include "AST/Def.h" #include "AST/AST.h"
#include "AST/Expr/BinExpr.h"
#include "AST/Expr/Value.h"
#include <map> #include <map>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
namespace plsm { namespace plsm {
namespace ast {
std::unique_ptr<ast::ASTNode> ast::ASTNode::fromJson(boost::json::value json) { ASTNode *ASTNode::fromJson(boost::json::value json) {
if (json.is_null()) // if (json.is_null())
return std::make_unique<NullValue>(ast::Location::json()); // return std::make_unique<NullValue>(Location::json());
if (json.is_int64()) if (json.is_int64())
return std::make_unique<IntValue>(ast::Location::json(), json.as_int64()); return new IntValue(SourceRange::json(), json.as_int64());
if (json.is_double()) if (json.is_double())
return std::make_unique<FloatValue>(ast::Location::json(), return new FloatValue(SourceRange::json(), json.as_double());
json.as_double());
std::string type; std::string type;
try { try {
@ -28,86 +26,93 @@ std::unique_ptr<ast::ASTNode> ast::ASTNode::fromJson(boost::json::value json) {
} }
if (type == "BinExpr") if (type == "BinExpr")
return ast::BinExpr::fromJson(json); return BinExpr::fromJson(json);
if (type == "BlockExpr")
return ast::BlockExpr::fromJson(json);
if (type == "CallExpr") if (type == "CallExpr")
return ast::CallExpr::fromJson(json); return CallExpr::fromJson(json);
if (type == "Closure") if (type == "CastExpr")
return ast::Closure::fromJson(json); return CastExpr::fromJson(json);
if (type == "Identifier") if (type == "Identifier")
return ast::Identifier::fromJson(json); return Identifier::fromJson(json);
if (type == "PropExpr") if (type == "LambdaExpr")
return ast::PropExpr::fromJson(json); return LambdaExpr::fromJson(json);
if (type == "Tuple") if (type == "LambdaExpr")
return ast::Tuple::fromJson(json); return LambdaExpr::fromJson(json);
if (type == "UnaryExpr") if (type == "UnExpr")
return ast::UnaryExpr::fromJson(json); return UnExpr::fromJson(json);
if (type == "Import")
return ast::Import::fromJson(json);
if (type == "Module")
return ast::Module::fromJson(json);
if (type == "AssignStmt")
return AssignStmt::fromJson(json);
if (type == "ExprStmt") if (type == "ExprStmt")
return ast::ExprStmt::fromJson(json); return ExprStmt::fromJson(json);
if (type == "FnDef") if (type == "FnParam")
return ast::FnDef::fromJson(json); return FnParam::fromJson(json);
if (type == "TraitAlias") if (type == "FnDecl")
return ast::TraitAlias::fromJson(json); return FnDecl::fromJson(json);
if (type == "TraitDef") if (type == "IfStmt")
return ast::TraitDef::fromJson(json); return IfStmt::fromJson(json);
if (type == "TypeAlias") if (type == "RetStmt")
return ast::TypeAlias::fromJson(json); return RetStmt::fromJson(json);
if (type == "TypeDef") if (type == "VarDecl")
return ast::TypeDef::fromJson(json); return VarDecl::fromJson(json);
if (type == "ValDecl") if (type == "WhileStmt")
return ast::ValDecl::fromJson(json); return WhileStmt::fromJson(json);
if (type == "ClosureType") if (type == "PrimitiveTypeName")
return ast::ClosureType::fromJson(json); return PrimitiveTypeName::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);
throw std::runtime_error("json conversion for '" + type + throw std::runtime_error("json conversion for '" + type +
"' not implemented"); "' not implemented");
} }
std::unique_ptr<ast::Expr> ast::Expr::fromJson(boost::json::value json) { Expr *Expr::fromJson(boost::json::value json) {
auto node = ast::ASTNode::fromJson(json); auto node = ASTNode::fromJson(json);
if (dynamic_cast<ast::Expr *>(node.get())) { if (dynamic_cast<Expr *>(node)) {
return std::unique_ptr<ast::Expr>((ast::Expr *)node.release()); return (Expr *)node;
} }
throw std::runtime_error(json.as_object().at("@type").as_string().c_str() + throw std::runtime_error(json.as_object().at("@type").as_string().c_str() +
std::string(" is not of type 'Expr'")); std::string(" is not of type 'Expr'"));
} }
std::unique_ptr<ast::Type> ast::Type::fromJson(boost::json::value json) { TypeName *TypeName::fromJson(boost::json::value json) {
auto node = ast::ASTNode::fromJson(json); auto node = ASTNode::fromJson(json);
if (dynamic_cast<ast::Type *>(node.get())) { if (dynamic_cast<TypeName *>(node)) {
return std::unique_ptr<ast::Type>((ast::Type *)node.release()); return (TypeName *)node;
} }
throw std::runtime_error(json.as_object().at("@type").as_string().c_str() + 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> ast::Stmt::fromJson(boost::json::value json) { Stmt *Stmt::fromJson(boost::json::value json) {
auto node = ast::ASTNode::fromJson(json); auto node = ASTNode::fromJson(json);
if (dynamic_cast<ast::Stmt *>(node.get())) { if (dynamic_cast<Stmt *>(node)) {
return std::unique_ptr<ast::Stmt>((ast::Stmt *)node.release()); return (Stmt *)node;
} }
throw std::runtime_error(json.as_object().at("@type").as_string().c_str() + throw std::runtime_error(json.as_object().at("@type").as_string().c_str() +
std::string(" is not of type 'Stmt'")); std::string(" is not of type 'Stmt'"));
} }
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 } // namespace plsm

View File

@ -1,37 +1,41 @@
#include "AST/Expr/BinExpr.h" #include "AST/AST.h"
#include "AST/Base.h"
#include "AST/Def.h"
#include <memory> #include <memory>
namespace plsm { namespace plsm {
namespace ast {
boost::json::value ast::BinExpr::toJson() { static const std::unordered_map<BinOp, std::string> 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<std::string, BinOp> 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 { return {
{"@type", "BinExpr"}, {"@type", "BinExpr"},
{"op", op}, {"op", binOpToString.at(op)},
{"left", left->toJson()}, {"lhs", lhs->toJson()},
{"right", right->toJson()}, {"rhs", rhs->toJson()},
}; };
} }
std::unique_ptr<ast::BinExpr> ast::BinExpr::fromJson(boost::json::value json) { BinExpr *BinExpr::fromJson(boost::json::value json) {
auto op = getJsonValue<ast::BinExpr, std::string>(json, "op"); auto opString = getJsonValue<BinExpr, std::string>(json, "op");
auto left = fromJsonProperty<ast::BinExpr, ast::Expr>(json, "left"); auto op = stringToBinOp.at(opString);
auto right = fromJsonProperty<ast::BinExpr, ast::Expr>(json, "right");
return std::make_unique<ast::BinExpr>(ast::Location::json(), left, op, right); auto lhs = fromJsonProperty<BinExpr, Expr>(json, "lhs");
} auto rhs = fromJsonProperty<BinExpr, Expr>(json, "rhs");
boost::json::value ast::PrefExpr::toJson() { return new BinExpr(SourceRange::json(), op, lhs, rhs);
return {
{"@type", "PrefExpr"},
{"expr", expr->toJson()},
};
}
std::unique_ptr<ast::PrefExpr>
ast::PrefExpr::fromJson(boost::json::value json) {
auto expr = fromJsonProperty<ast::PrefExpr, ast::Expr>(json, "expr");
return std::make_unique<ast::PrefExpr>(ast::Location::json(), expr);
} }
} // namespace ast
} // namespace plsm } // namespace plsm

View File

@ -1,25 +0,0 @@
#include "AST/Expr/Block.h"
#include "AST/Base.h"
#include "AST/Def.h"
#include "Utils.h"
#include <algorithm>
#include <memory>
namespace plsm {
boost::json::value ast::BlockExpr::toJson() {
return {
{"@type", "BlockExpr"},
{"stmts", utils::mapToJson(stmts)},
{"result", result->toJson()},
};
}
std::unique_ptr<ast::BlockExpr>
ast::BlockExpr::fromJson(boost::json::value json) {
auto stmts = fromJsonVector<ast::BlockExpr, ast::Stmt>(json, "stmts");
auto result = fromJsonProperty<ast::BlockExpr, ast::Expr>(json, "result");
return std::make_unique<ast::BlockExpr>(ast::Location::json(), stmts, result);
}
} // namespace plsm

View File

@ -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>
ast::CallExpr::fromJson(boost::json::value json) {
auto callee = fromJsonProperty<ast::CallExpr, ast::Expr>(json, "callee");
auto args = fromJsonVector<ast::CallExpr, ast::Expr>(json, "args");
return std::make_unique<ast::CallExpr>(ast::Location::json(), callee, args);
}
} // namespace plsm

View File

@ -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<CallExpr, Expr>(json, "callee");
auto args = fromJsonVector<CallExpr, Expr>(json, "args");
return new CallExpr(SourceRange::json(), callee, args);
}
} // namespace ast
} // namespace plsm

View File

@ -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<CastExpr, Expr>(json, "value");
auto typeName = fromJsonProperty<CastExpr, TypeName>(json, "typeName");
return new CastExpr(SourceRange::json(), value, typeName);
}
} // namespace ast
} // namespace plsm

View File

@ -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> ast::Closure::fromJson(boost::json::value json) {
auto args = fromJsonVector<ast::Closure, ast::FnArg>(json, "args");
auto body = fromJsonProperty<ast::Closure, ast::Expr>(json, "body");
return std::make_unique<ast::Closure>(ast::Location::json(), args, body);
}
} // namespace plsm

View File

@ -1,19 +1,19 @@
#include "AST/Def.h" #include "AST/AST.h"
#include "AST/Expr/Identifier.h"
namespace plsm { namespace plsm {
namespace ast {
boost::json::value ast::Identifier::toJson() { boost::json::value Identifier::toJson() {
return { return {
{"@type", "Identifier"}, {"@type", "Identifier"},
{"name", name}, {"name", name},
}; };
} }
std::unique_ptr<ast::Identifier> Identifier *Identifier::fromJson(boost::json::value json) {
ast::Identifier::fromJson(boost::json::value json) { auto name = getJsonValue<Identifier, std::string>(json, "name");
auto name = getJsonValue<ast::Identifier, std::string>(json, "name"); return new Identifier(SourceRange::json(), name);
return std::make_unique<ast::Identifier>(ast::Location::json(), name);
} }
} // namespace ast
} // namespace plsm } // namespace plsm

View File

@ -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<LambdaExpr, FnParam>(json, "params");
auto body = fromJsonVector<LambdaExpr, Expr>(json, "body");
return new LambdaExpr(SourceRange::json(), params, body);
}
} // namespace ast
} // namespace plsm

View File

@ -1,21 +0,0 @@
#include "AST/Def.h"
#include <memory>
namespace plsm {
boost::json::value ast::PropExpr::toJson() {
return {
{"@type", "PropExpr"},
{"expr", expr->toJson()},
{"property", property},
};
}
std::unique_ptr<ast::PropExpr>
ast::PropExpr::fromJson(boost::json::value json) {
auto expr = fromJsonProperty<ast::PropExpr, ast::Expr>(json, "expr");
auto property = getJsonValue<ast::PropExpr, std::string>(json, "property");
return std::make_unique<ast::PropExpr>(ast::Location::json(), expr, property);
}
} // namespace plsm

View File

@ -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> ast::Tuple::fromJson(boost::json::value json) {
auto values = fromJsonVector<ast::Tuple, ast::Expr>(json, "values");
return std::make_unique<ast::Tuple>(ast::Location::json(), values);
}
} // namespace plsm

View File

@ -0,0 +1,36 @@
#include "AST/AST.h"
#include <memory>
namespace plsm {
namespace ast {
static const std::unordered_map<UnOp, std::string> unOpToString = {
{UnOp::POS, "+"},
{UnOp::NEG, "-"},
{UnOp::NOT, "!"},
};
static const std::unordered_map<std::string, UnOp> 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<UnExpr, std::string>(json, "op");
auto op = stringToUnOp.at(opString);
auto expr = fromJsonProperty<UnExpr, Expr>(json, "expr");
return new UnExpr(SourceRange::json(), op, expr);
}
} // namespace ast
} // namespace plsm

View File

@ -1,22 +0,0 @@
#include "AST/Def.h"
#include "AST/Expr/UnaryExpr.h"
#include <memory>
namespace plsm {
boost::json::value ast::UnaryExpr::toJson() {
return {
{"@type", "UnaryExpr"},
{"op", op},
{"expr", expr->toJson()},
};
}
std::unique_ptr<ast::UnaryExpr>
ast::UnaryExpr::fromJson(boost::json::value json) {
auto op = getJsonValue<ast::UnaryExpr, std::string>(json, "op");
auto expr = fromJsonProperty<ast::UnaryExpr, ast::Expr>(json, "expr");
return std::make_unique<ast::UnaryExpr>(ast::Location::json(), op, expr);
}
} // namespace plsm

View File

@ -1,29 +1,26 @@
#include "AST/Def.h" #include "AST/AST.h"
#include <memory> #include <memory>
namespace plsm { namespace plsm {
namespace ast {
// boost::json::value NullValue::toJson() { return nullptr; }
boost::json::value ast::NullValue::toJson() { return nullptr; } // std::unique_ptr<NullValue>
// NullValue::fromJson(boost::json::value json) {
// return std::make_unique<NullValue>(SourceRange::json());
// }
std::unique_ptr<ast::NullValue> boost::json::value IntValue::toJson() { return value; }
ast::NullValue::fromJson(boost::json::value json) {
return std::make_unique<ast::NullValue>(ast::Location::json()); 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> FloatValue *FloatValue::fromJson(boost::json::value json) {
ast::IntValue::fromJson(boost::json::value json) { return new FloatValue(SourceRange::json(), json.as_double());
return std::make_unique<ast::IntValue>(ast::Location::json(),
json.as_int64());
}
boost::json::value ast::FloatValue::toJson() { return value; }
std::unique_ptr<ast::FloatValue>
ast::FloatValue::fromJson(boost::json::value json) {
return std::make_unique<ast::FloatValue>(ast::Location::json(),
json.as_double());
} }
} // namespace ast
} // namespace plsm } // namespace plsm

View File

@ -1,19 +1,16 @@
#include "AST/Def.h" #include "AST/AST.h"
#include <memory> #include <memory>
namespace plsm { namespace plsm {
namespace ast {
boost::json::value ast::Import::toJson() { boost::json::value Import::toJson() {
return { return {{"@type", "Import"}, {"moduleName", moduleName}};
{"@type", "Import"}, }
{"moduleName", moduleName} Import *Import::fromJson(boost::json::value json) {
}; auto moduleName = getJsonValue<Import, std::string>(json, "moduleName");
} return new Import(SourceRange::json(), moduleName);
std::unique_ptr<ast::Import>
ast::Import::fromJson(boost::json::value json) {
auto moduleName = getJsonValue<ast::Import, std::string>(json, "moduleName");
return std::make_unique<ast::Import>(ast::Location::json(), moduleName);
} }
} // namespace ast
} // namespace plsm } // namespace plsm

View File

@ -1,9 +1,10 @@
#include "AST/Def.h" #include "AST/AST.h"
#include "Utils.h" #include "Utils.h"
namespace plsm { namespace plsm {
namespace ast {
boost::json::value ast::Module::toJson() { boost::json::value Module::toJson() {
return { return {
{"@type", "Module"}, {"@type", "Module"},
{"name", name}, {"name", name},
@ -12,11 +13,13 @@ boost::json::value ast::Module::toJson() {
}; };
} }
std::unique_ptr<ast::Module> ast::Module::fromJson(boost::json::value json) { Module *Module::fromJson(boost::json::value json) {
auto name = getJsonValue<ast::Module, std::string>(json, "name"); auto name = getJsonValue<Module, std::string>(json, "name");
auto imports = fromJsonVector<ast::Module, ast::Import>(json, "imports"); auto imports = fromJsonVector<Module, Import>(json, "imports");
auto stmts = fromJsonVector<ast::Module, ast::Stmt>(json, "stmts"); auto stmts = fromJsonVector<Module, Stmt>(json, "stmts");
return std::make_unique<ast::Module>(ast::Location::json(), name, imports, stmts);
return new Module(SourceRange::json(), name, imports, stmts);
} }
} // namespace ast
} // namespace plsm } // namespace plsm

View File

@ -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<AssignStmt, Expr>(json, "lval");
auto rval = fromJsonProperty<AssignStmt, Expr>(json, "rval");
return new AssignStmt(SourceRange::json(), lval, rval);
}
} // namespace ast
} // namespace plsm

View File

@ -1,16 +1,19 @@
#include "AST/Stmt/ExprStmt.h" #include "AST/AST.h"
#include "AST/Def.h"
namespace plsm { namespace plsm {
namespace ast {
boost::json::value ast::ExprStmt::toJson() { boost::json::value ExprStmt::toJson() {
return {{"@type", "ExprStmt"}, {"expr", expr->toJson()}}; return {
{"@type", "ExprStmt"},
{"expr", expr->toJson()},
};
} }
std::unique_ptr<ast::ExprStmt> ExprStmt *ExprStmt::fromJson(boost::json::value json) {
ast::ExprStmt::fromJson(boost::json::value json) { auto expr = fromJsonProperty<ExprStmt, Expr>(json, "expr");
auto expr = fromJsonProperty<ast::ExprStmt, ast::Expr>(json, "expr"); return new ExprStmt(SourceRange::json(), expr);
return std::make_unique<ast::ExprStmt>(ast::Location::json(), expr);
} }
} // namespace ast
} // namespace plsm } // namespace plsm

View File

@ -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<FnParam, std::string>(json, "name");
auto typeName = fromJsonProperty<FnParam, TypeName>(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<FnDecl, std::string>(json, "name");
auto params = fromJsonVector<FnDecl, FnParam>(json, "params");
auto returnTypeName =
fromJsonProperty<FnDecl, TypeName>(json, "returnTypeName");
auto body = fromJsonVector<FnDecl, Stmt>(json, "body");
return new FnDecl(SourceRange::json(), name, params, returnTypeName, body);
}
} // namespace ast
} // namespace plsm

View File

@ -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> ast::FnArg::fromJson(boost::json::value json) {
auto name = getJsonValue<ast::FnArg, std::string>(json, "name");
auto type = fromJsonProperty<ast::FnArg, ast::Type>(json, "type");
return std::make_unique<ast::FnArg>(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> ast::FnDef::fromJson(boost::json::value json) {
auto name = getJsonValue<ast::FnDef, std::string>(json, "name");
auto args = fromJsonVector<ast::FnDef, ast::FnArg>(json, "args");
auto returnType = fromJsonProperty<ast::FnDef, ast::Type>(json, "returnType");
auto body = fromJsonProperty<ast::FnDef, ast::Expr>(json, "body");
return std::make_unique<ast::FnDef>(ast::Location::json(), name, args,
returnType, body);
}
} // namespace plsm

View File

@ -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<IfStmt, Expr>(json, "condition");
auto ifBody = fromJsonVector<IfStmt, Stmt>(json, "ifBody");
auto elseBody = fromJsonVector<IfStmt, Stmt>(json, "elseBody");
return new IfStmt(SourceRange::json(), condition, ifBody, elseBody);
}
} // namespace ast
} // namespace plsm

View File

@ -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<RetStmt, Expr>(json, "value");
return new RetStmt(SourceRange::json(), value);
}
} // namespace ast
} // namespace plsm

View File

@ -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>
ast::TraitAlias::fromJson(boost::json::value json) {
auto alias = getJsonValue<ast::TraitAlias, std::string>(json, "alias");
auto aliased = getJsonValue<ast::TraitAlias, std::string>(json, "aliased");
return std::make_unique<ast::TraitAlias>(ast::Location::json(), alias,
aliased);
}
} // namespace plsm

View File

@ -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>
ast::TraitDef::fromJson(boost::json::value json) {
auto name = getJsonValue<ast::TraitDef, std::string>(json, "name");
auto traits = fromJsonVector<ast::TraitDef, ast::FnDef>(json, "traits");
return std::make_unique<ast::TraitDef>(ast::Location::json(), name, traits);
}
} // namespace plsm

View File

@ -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>
ast::TypeAlias::fromJson(boost::json::value json) {
return nullptr;
}
} // namespace plsm

View File

@ -1,25 +0,0 @@
#include "AST/Def.h"
#include "AST/Stmt/FnDef.h"
#include "AST/Stmt/TypeDef.h"
#include "Utils.h"
#include <memory>
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> ast::TypeDef::fromJson(boost::json::value json) {
auto name = getJsonValue<ast::TypeDef, std::string>(json, "name");
auto attrs = fromJsonVector<ast::TypeDef, ast::FnArg>(json, "attrs");
auto members = fromJsonVector<ast::TypeDef, ast::FnDef>(json, "members");
return std::make_unique<ast::TypeDef>(ast::Location::json(), name, attrs, members);
}
} // namespace plsm

View File

@ -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> ast::ValDecl::fromJson(boost::json::value json) {
auto name = getJsonValue<ast::ValDecl, std::string>(json, "name");
auto type = fromJsonProperty<ast::ValDecl, ast::Type>(json, "type");
auto value = fromJsonProperty<ast::ValDecl, ast::Expr>(json, "value");
return std::make_unique<ast::ValDecl>(ast::Location::json(), name, type, value);
}
} // namespace plsm

View File

@ -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<VarDecl, std::string>(json, "name");
auto typeName = fromJsonProperty<VarDecl, TypeName>(json, "typeName");
return new VarDecl(SourceRange::json(), name, typeName);
}
} // namespace ast
} // namespace plsm

View File

@ -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<WhileStmt, Expr>(json, "condition");
auto body = fromJsonVector<WhileStmt, Stmt>(json, "body");
return new WhileStmt(SourceRange::json(), condition, body);
}
} // namespace ast
} // namespace plsm

View File

@ -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>
ast::ClosureType::fromJson(boost::json::value json) {
auto from = fromJsonVector<ast::ClosureType, ast::Type>(json, "from");
auto to = fromJsonProperty<ast::ClosureType, ast::Type>(json, "to");
return std::make_unique<ast::ClosureType>(ast::Location::json(), from, to);
}
} // namespace plsm

View File

@ -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<FunctionType, Type>(json, "paramTypes");
auto returnType = fromJsonProperty<FunctionType, Type>(json, "returnType");
return new FunctionType(paramTypes, returnType);
}
} // namespace ast
} // namespace plsm

View File

@ -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>
ast::GenericType::fromJson(boost::json::value json) {
auto name = getJsonValue<ast::GenericType, std::string>(json, "name");
auto types = fromJsonVector<ast::GenericType, ast::Type>(json, "types");
return std::make_unique<ast::GenericType>(ast::Location::json(), name, types);
}
} // namespace plsm

View File

@ -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>
ast::NamedType::fromJson(boost::json::value json) {
auto name = getJsonValue<ast::NamedType, std::string>(json, "name");
return std::make_unique<ast::NamedType>(ast::Location::json(), name);
}
} // namespace plsm

View File

@ -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<PrimitiveType, std::string>(json, "name");
return new PrimitiveType(name);
}
} // namespace ast
} // namespace plsm

View File

@ -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>
ast::TupleType::fromJson(boost::json::value json) {
auto types = fromJsonVector<ast::TupleType, ast::Type>(json, "types");
return std::make_unique<ast::TupleType>(ast::Location::json(), types);
}
} // namespace plsm

View File

@ -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<PrimitiveTypeName, std::string>(json, "name");
return new PrimitiveTypeName(SourceRange::json(), name);
}
} // namespace ast
} // namespace plsm

View File

@ -1,21 +1,16 @@
#include "Parser.h" #include "Parser.h"
#include "AST/Def.h" #include "AST/AST.h"
#include <any>
#include <sstream>
#include "AST/Module/Module.h"
#include "plsmBaseVisitor.h" #include "plsmBaseVisitor.h"
#include "plsmLexer.h" #include "plsmLexer.h"
#include "plsmParser.h" #include "plsmParser.h"
class ErrorListener : public antlr4::BaseErrorListener { class MyAntlr4ErrorListener : public antlr4::BaseErrorListener {
std::string file; std::string file;
std::string *error; std::string *error;
public: public:
ErrorListener(const std::string &file, std::string *error) MyAntlr4ErrorListener(const std::string &file, std::string *error)
: file(file), error(error) {} : file(file), error(error) {}
virtual void syntaxError(antlr4::Recognizer *recognizer, virtual void syntaxError(antlr4::Recognizer *recognizer,
@ -30,423 +25,7 @@ public:
namespace plsm { namespace plsm {
class Visitor : public plsmBaseVisitor { std::shared_ptr<ast::Module> parse(const std::string &file,
private:
const std::string file;
public:
Visitor(const std::string &file) : file(file) {}
inline ast::Location loc(antlr4::ParserRuleContext *ctx) {
return ast::Location(
file,
std::pair<size_t, size_t>(ctx->getStart()->getLine(),
ctx->getStart()->getCharPositionInLine()),
std::pair<size_t, size_t>(ctx->getStop()->getLine(),
ctx->getStop()->getCharPositionInLine()));
}
template <typename T> inline T visitT(antlr4::tree::ParseTree *ctx) {
return std::any_cast<T>(visit(ctx));
}
template <typename T>
inline std::unique_ptr<T> visitU(antlr4::tree::ParseTree *ctx) {
return std::unique_ptr<T>(visitT<T *>(ctx));
}
template <typename T>
inline std::vector<std::unique_ptr<T>> visitVU(antlr4::tree::ParseTree *ctx) {
std::vector<std::unique_ptr<T>> res;
for (auto &el : visitT<std::vector<T *>>(ctx))
res.push_back(std::unique_ptr<T>(el));
return res;
}
virtual std::any visitModule(plsmParser::ModuleContext *ctx) override {
auto name = ctx->identifier()->getText();
std::vector<std::unique_ptr<ast::Import>> imports;
for (auto &import : ctx->moduleImport())
imports.push_back(visitU<ast::Import>(import));
std::vector<std::unique_ptr<ast::Stmt>> stmts;
for (auto &stmt : ctx->moduleStmt())
stmts.push_back(visitU<ast::Stmt>(stmt));
return std::any(new ast::Module(loc(ctx), name, imports, stmts));
}
virtual std::any
visitModuleImport(plsmParser::ModuleImportContext *ctx) override {
return std::any(
new ast::Import(loc(ctx), visitT<std::string>(ctx->importName())));
}
virtual std::any
visitImportName(plsmParser::ImportNameContext *ctx) override {
auto name = ctx->identifier(0)->getText();
for (size_t i = 1; i < ctx->identifier().size(); i++)
name = name + "/" + ctx->identifier(i)->getText();
return std::any(name);
}
virtual std::any
visitModuleStmt(plsmParser::ModuleStmtContext *ctx) override {
ast::Stmt *stmt;
if (ctx->let())
stmt = (ast::Stmt *)visitT<ast::ValDecl *>(ctx->let());
if (ctx->fnDecl())
stmt = (ast::Stmt *)visitT<ast::FnDef *>(ctx->fnDecl());
if (ctx->fnDef())
stmt = (ast::Stmt *)visitT<ast::FnDef *>(ctx->fnDef());
if (ctx->traitDef())
stmt = (ast::Stmt *)visitT<ast::Stmt *>(ctx->traitDef());
if (ctx->typeDef())
stmt = (ast::Stmt *)visitT<ast::Stmt *>(ctx->typeDef());
return std::any(stmt);
}
virtual std::any visitTraitDef(plsmParser::TraitDefContext *ctx) override {
auto name = ctx->identifier(0)->getText();
if (ctx->identifier(1)) {
auto aliased = ctx->identifier(1)->getText();
return std::any(
(ast::Stmt *)new ast::TraitAlias(loc(ctx), name, aliased));
}
std::vector<std::unique_ptr<ast::FnDef>> fns;
for (auto &decl : ctx->fnDecl())
fns.push_back(visitU<ast::FnDef>(decl));
return std::any((ast::Stmt *)new ast::TraitDef(loc(ctx), name, fns));
}
virtual std::any visitTypeDef(plsmParser::TypeDefContext *ctx) override {
auto name = ctx->identifier()->getText();
if (ctx->type()) {
auto gen = visitU<ast::Type>(ctx->type());
return std::any((ast::Stmt *)new ast::TypeAlias(loc(ctx), name, gen));
}
std::vector<std::unique_ptr<ast::FnArg>> attrs;
if (ctx->fnDefArgs())
attrs = visitVU<ast::FnArg>(ctx->fnDefArgs());
std::vector<std::unique_ptr<ast::FnDef>> members;
for (auto &def : ctx->fnDef())
members.push_back(visitU<ast::FnDef>(def));
for (auto &decl : ctx->fnDecl())
members.push_back(visitU<ast::FnDef>(decl));
return std::any(
(ast::Stmt *)new ast::TypeDef(loc(ctx), name, attrs, members));
}
virtual std::any visitFnDef(plsmParser::FnDefContext *ctx) override {
auto name = ctx->identifier()->getText();
std::vector<std::unique_ptr<ast::FnArg>> args;
if (ctx->fnDefArgs())
args = std::move(visitVU<ast::FnArg>(ctx->fnDefArgs()));
auto returnType = visitU<ast::Type>(ctx->type());
auto body = visitU<ast::Expr>(ctx->expr());
return std::any(new ast::FnDef(loc(ctx), name, args, returnType, body));
}
virtual std::any visitFnDefArgs(plsmParser::FnDefArgsContext *ctx) override {
std::vector<ast::FnArg *> args;
for (size_t i = 0; i < ctx->children.size(); i += 3) {
auto name = ctx->children[i]->getText();
auto type = visitU<ast::Type>(ctx->children[i + 1]);
args.push_back(new ast::FnArg(loc(ctx), name, type));
}
return std::any(args);
}
virtual std::any visitFnDecl(plsmParser::FnDeclContext *ctx) override {
auto name = ctx->identifier()->getText();
std::vector<std::unique_ptr<ast::FnArg>> args;
if (ctx->fnDeclArgs())
args = visitVU<ast::FnArg>(ctx->fnDeclArgs());
auto returnType = visitU<ast::Type>(ctx->type());
auto body = std::unique_ptr<ast::Expr>(nullptr);
return std::any(new ast::FnDef(loc(ctx), name, args, returnType, body));
}
virtual std::any
visitFnDeclArgs(plsmParser::FnDeclArgsContext *ctx) override {
std::vector<ast::FnArg *> args;
for (size_t i = 0; i < ctx->children.size(); i++) {
std::string name;
if (dynamic_cast<plsmParser::IdentifierContext *>(ctx->children[i]))
name = ctx->children[i++]->getText();
auto type = visitU<ast::Type>(ctx->children[i++]);
args.push_back(new ast::FnArg(loc(ctx), name, type));
}
return std::any(args);
}
virtual std::any visitLet(plsmParser::LetContext *ctx) override {
auto name = ctx->identifier()->getText();
std::unique_ptr<ast::Type> type(nullptr);
if (ctx->type())
type = visitU<ast::Type>(ctx->type());
auto expr = visitU<ast::Expr>(ctx->expr());
return std::any(new ast::ValDecl(loc(ctx), name, type, expr));
}
virtual std::any visitExprStmt(plsmParser::ExprStmtContext *ctx) override {
auto expr = visitU<ast::Expr>(ctx->expr());
return std::any(new ast::ExprStmt(loc(ctx), expr));
}
virtual std::any visitType1(plsmParser::Type1Context *ctx) override {
if (ctx->type0())
return visit(ctx->type0());
if (ctx->children[0]->getText() == "(") {
if (ctx->type())
return visit(ctx->type());
if (ctx->tupleTypeList()) {
auto types = visitVU<ast::Type>(ctx->tupleTypeList());
return std::any((ast::Type *)new ast::TupleType(loc(ctx), types));
}
}
if (ctx->children[0]->getText() == "[") {
std::vector<std::unique_ptr<ast::Type>> args;
if (ctx->typeList())
args = visitVU<ast::Type>(ctx->typeList());
auto returnType = visitU<ast::Type>(ctx->type());
return std::any(
(ast::Type *)new ast::ClosureType(loc(ctx), args, returnType));
}
throw std::logic_error("type2 not implemented");
}
virtual std::any visitType0(plsmParser::Type0Context *ctx) override {
auto name = ctx->identifier()->getText();
if (ctx->typeList()) {
auto types = visitVU<ast::Type>(ctx->typeList());
return std::any((ast::Type *)new ast::GenericType(loc(ctx), name, types));
}
return std::any((ast::Type *)new ast::NamedType(loc(ctx), name));
}
virtual std::any
visitTupleTypeList(plsmParser::TupleTypeListContext *ctx) override {
std::vector<ast::Type *> types;
for (auto &type : ctx->type())
types.push_back(visitT<ast::Type *>(type));
return std::any(types);
}
virtual std::any visitTypeList(plsmParser::TypeListContext *ctx) override {
std::vector<ast::Type *> types;
for (auto &type : ctx->type())
types.push_back(visitT<ast::Type *>(type));
return std::any(types);
}
virtual std::any visitExpr3(plsmParser::Expr3Context *ctx) override {
if (ctx->expr2())
return visit(ctx->expr2());
// closure
if (ctx->children[0]->getText() == "[") {
std::vector<std::unique_ptr<ast::FnArg>> args;
if (ctx->fnDefArgs())
args = visitVU<ast::FnArg>(ctx->fnDefArgs());
auto body = visitU<ast::Expr>(ctx->expr());
return std::any((ast::Expr *)new ast::Closure(loc(ctx), args, body));
}
// block
if (ctx->children[0]->getText() == "{") {
std::vector<std::unique_ptr<ast::Stmt>> stmts;
for (auto &stmt : ctx->blockStmt())
stmts.push_back(visitU<ast::Stmt>(stmt));
auto result = visitU<ast::Expr>(ctx->expr());
return std::any((ast::Expr *)new ast::BlockExpr(loc(ctx), stmts, result));
}
throw std::logic_error("expr3 not implemented");
}
virtual std::any visitExpr2(plsmParser::Expr2Context *ctx) override {
if (ctx->expr2()) {
auto left = visitU<ast::Expr>(ctx->expr2());
auto op = ctx->operator_()->getText();
auto right = visitU<ast::Expr>(ctx->expr1());
return std::any((ast::Expr *)new ast::BinExpr(loc(ctx), left, op, right));
}
return visit(ctx->expr1());
}
virtual std::any visitExpr1(plsmParser::Expr1Context *ctx) override {
if (ctx->operator_()) {
auto op = ctx->operator_()->getText();
auto expr = visitU<ast::Expr>(ctx->expr0());
return std::any((ast::Expr *)new ast::UnaryExpr(loc(ctx), op, expr));
}
return visit(ctx->expr0());
}
virtual std::any visitExpr0(plsmParser::Expr0Context *ctx) override {
if (ctx->literal())
return visit(ctx->literal());
if (ctx->expr()) {
auto expr = visitU<ast::Expr>(ctx->expr());
return std::any((ast::Expr *)new ast::PrefExpr(loc(ctx), expr));
}
if (ctx->expr0()) {
auto expr = visitU<ast::Expr>(ctx->expr0());
// property accessor
if (ctx->identifier()) {
auto name = ctx->identifier()->getText();
return std::any((ast::Expr *)new ast::PropExpr(loc(ctx), expr, name));
}
// function/closure call
std::vector<std::unique_ptr<ast::Expr>> args;
if (ctx->exprList())
args = visitVU<ast::Expr>(ctx->exprList());
return std::any((ast::Expr *)new ast::CallExpr(loc(ctx), expr, args));
}
// tuple
if (ctx->tupleExprList()) {
auto values = visitVU<ast::Expr>(ctx->tupleExprList());
return std::any((ast::Expr *)new ast::Tuple(loc(ctx), values));
}
// identifier
if (ctx->identifier()) {
auto name = ctx->identifier()->getText();
return std::any((ast::Expr *)new ast::Identifier(loc(ctx), name));
}
throw std::logic_error("expr0 not implemented");
}
virtual std::any visitBlockStmt(plsmParser::BlockStmtContext *ctx) override {
ast::Stmt *stmt;
if (ctx->let())
stmt = (ast::Stmt *)visitT<ast::ValDecl *>(ctx->let());
if (ctx->exprStmt())
stmt = (ast::Stmt *)visitT<ast::ExprStmt *>(ctx->exprStmt());
if (ctx->fnDef())
stmt = (ast::Stmt *)visitT<ast::FnDef *>(ctx->fnDef());
return std::any(stmt);
}
virtual std::any
visitTupleExprList(plsmParser::TupleExprListContext *ctx) override {
std::vector<ast::Expr *> exprs;
for (auto &expr : ctx->expr())
exprs.push_back(visitT<ast::Expr *>(expr));
return std::any(exprs);
}
virtual std::any visitExprList(plsmParser::ExprListContext *ctx) override {
std::vector<ast::Expr *> exprs;
for (auto &expr : ctx->expr())
exprs.push_back(visitT<ast::Expr *>(expr));
return std::any(exprs);
}
virtual std::any
visitIdentifierList(plsmParser::IdentifierListContext *ctx) override {
std::vector<std::string> identifiers;
for (auto &identifier : ctx->identifier())
identifiers.push_back(visitT<std::string>(identifier));
return std::any(identifiers);
}
virtual std::any visitLiteral(plsmParser::LiteralContext *ctx) override {
if (ctx->NULL_)
return std::any((ast::Expr *)new ast::NullValue(loc(ctx)));
if (ctx->INT_LIT()) {
auto text = ctx->INT_LIT()->getText();
int64_t value;
if (!text.rfind("0x", 0))
value = std::strtol(text.substr(2).data(), NULL, 16);
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<ast::Module> parse(const std::string &file,
const std::string &input) { const std::string &input) {
auto istream = antlr4::ANTLRInputStream(input); auto istream = antlr4::ANTLRInputStream(input);
auto lexer = plsmLexer(&istream); auto lexer = plsmLexer(&istream);
@ -454,17 +33,12 @@ std::unique_ptr<ast::Module> parse(const std::string &file,
auto parser = plsmParser(&tokens); auto parser = plsmParser(&tokens);
std::string error; std::string error;
ErrorListener listener(file, &error); MyAntlr4ErrorListener listener(file, &error);
parser.removeErrorListeners(); parser.removeErrorListeners();
parser.addErrorListener(&listener); parser.addErrorListener(&listener);
auto tree = parser.module(); auto tree = parser.module();
return std::shared_ptr<Module>(tree->ast);
if (error.size())
throw std::runtime_error(error);
auto module = std::any_cast<ast::Module *>(Visitor(file).visitModule(tree));
return std::unique_ptr<ast::Module>(module);
} }
} // namespace plsm } // namespace plsm

View File

@ -1,12 +1,11 @@
#include <iostream>
#include <fstream> #include <fstream>
#include <iostream>
#include <istream> #include <istream>
#include <sstream> #include <sstream>
#include "Parser.h" #include "Parser.h"
static std::string readFile(const std::string &path) static std::string readFile(const std::string &path) {
{
std::ifstream f(path); std::ifstream f(path);
auto data = (std::stringstream() << f.rdbuf()).str(); auto data = (std::stringstream() << f.rdbuf()).str();
f.close(); f.close();
@ -14,10 +13,8 @@ static std::string readFile(const std::string &path)
return data; return data;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[]) {
{ if (argc != 2) {
if (argc != 2)
{
std::cout << "Usage:" << std::endl std::cout << "Usage:" << std::endl
<< "\t" << argv[0] << " <path/to/file>" << std::endl; << "\t" << argv[0] << " <path/to/file>" << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -25,19 +22,17 @@ int main(int argc, char *argv[])
auto input = readFile(argv[1]); auto input = readFile(argv[1]);
std::cout << input << std::endl; // std::cout << input << std::endl;
try try {
{
auto module = plsm::parse(argv[1], input); auto module = plsm::parse(argv[1], input);
std::cout << module->toJsonString() << std::endl; 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; // std::cout << plsm::ast::Module::fromJson(module->toJson())->toJson() <<
} // std::endl;
catch (std::runtime_error &err) } catch (std::runtime_error &err) {
{
std::cerr << err.what() << std::endl; std::cerr << err.what() << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

142
compiler/test.json Normal file
View File

@ -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
}
}
}
]
}
]
}

18
examples/new.plsm Normal file
View File

@ -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;
}