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