extended ANTLR visitor; added llvm-project

This commit is contained in:
Ludwig Lehnert 2024-03-01 07:06:51 +01:00
parent f45adb1810
commit 34160a03af
35 changed files with 794 additions and 192 deletions

3
.gitmodules vendored Normal file
View 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
View File

@ -6,3 +6,6 @@
# antlr-generated files # antlr-generated files
plsm*.h plsm*.h
plsm*.cpp plsm*.cpp
# coredumps
vgcore.*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 + ")";
}
}; };
} }

View 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();
}
};
}

View 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)) {}
};
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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)) {}
};
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,23 +22,22 @@ 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
@ -46,19 +46,22 @@ expr0: literal
| identifier | identifier
| expr0 '[' exprList? ']' // fn call | expr0 '[' exprList? ']' // fn call
| '(' expr ')' | '(' expr ')'
| '(' tupleExprList ')' // tuple
| expr0 '.' identifier; // property accessor | 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
View 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 .

View File

@ -4,10 +4,45 @@
#include <sstream> #include <sstream>
class Visitor : public plsmBaseVisitor class ErrorListener : public antlr4::BaseErrorListener
{ {
std::string file;
std::string *error;
public: public:
Visitor() {} ErrorListener(const std::string &file, std::string *error)
: file(file), error(error) {}
virtual void syntaxError(antlr4::Recognizer *recognizer, antlr4::Token *offendingSymbol, size_t line, size_t charPositionInLine,
const std::string &msg, std::exception_ptr e) override
{
std::stringstream ss;
ss << file << ": line " << line << ":" << charPositionInLine << ": " << msg;
*error = ss.str();
}
};
namespace plsm
{
class Visitor : public plsmBaseVisitor
{
private:
const std::string file;
public:
Visitor(const std::string &file) : file(file) {}
inline ast::Location loc(antlr4::ParserRuleContext *ctx)
{
return ast::Location(
file,
std::pair<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> template <typename T>
inline T visitT(antlr4::tree::ParseTree *ctx) inline T visitT(antlr4::tree::ParseTree *ctx)
@ -21,97 +56,435 @@ public:
return std::unique_ptr<T>(visitT<T *>(ctx)); return std::unique_ptr<T>(visitT<T *>(ctx));
} }
virtual std::any visitModule(plsmParser::ModuleContext *ctx) override template <typename T>
inline std::vector<std::unique_ptr<T>> visitVU(antlr4::tree::ParseTree *ctx)
{ {
std::vector<std::unique_ptr<ast::Import>> imports; std::vector<std::unique_ptr<T>> res;
std::vector<std::unique_ptr<ast::Stmt>> stmts; for (auto &el : visitT<std::vector<T *>>(ctx))
res.push_back(std::unique_ptr<T>(el));
for (auto &child : ctx->children) return res;
{
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 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 virtual std::any visitModuleImport(plsmParser::ModuleImportContext *ctx) override
{ {
return std::any(new ast::Import(visitT<std::string>(ctx->moduleName()))); return std::any(new ast::Import(loc(ctx), visitT<std::string>(ctx->importName())));
} }
virtual std::any visitModuleName(plsmParser::ModuleNameContext *ctx) override virtual std::any visitImportName(plsmParser::ImportNameContext *ctx) override
{ {
auto name = visitT<std::string>(ctx->identifier(0)); auto name = ctx->identifier(0)->getText();
for (size_t i = 1; ctx->identifier(i); i++) for (size_t i = 1; i < ctx->identifier().size(); i++)
{ name = name + "/" + ctx->identifier(i)->getText();
name = name + "." + visitT<std::string>(ctx->identifier(i));
}
return std::any(name); 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 virtual std::any visitTraitDef(plsmParser::TraitDefContext *ctx) override
{ {
auto name = visitT<std::string>(ctx->identifier(0)); auto name = ctx->identifier(0)->getText();
if (ctx->identifier(1)) if (ctx->identifier(1))
{ {
auto aliased = visitT<std::string>(ctx->identifier(1)); auto aliased = ctx->identifier(1)->getText();
return std::any(new ast::TraitAlias(name, aliased)); return std::any((ast::Stmt *)new ast::TraitAlias(loc(ctx), name, aliased));
} }
std::vector<std::unique_ptr<ast::FnDecl>> fns; std::vector<std::unique_ptr<ast::FnDef>> fns;
for (auto &decl : ctx->fnDecl())
fns.push_back(visitU<ast::FnDef>(decl));
for (size_t i = 0; ctx->fnDecl(i); i++) return std::any((ast::Stmt *)new ast::TraitDef(loc(ctx), name, fns));
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 virtual std::any visitTypeDef(plsmParser::TypeDefContext *ctx) override
{ {
auto name = visitT<std::string>(ctx->identifier()); auto name = ctx->identifier()->getText();
if (ctx->type()) if (ctx->type())
{ {
auto gen = visitU<ast::Type>(ctx->type()); auto gen = visitU<ast::Type>(ctx->type());
return std::any(new ast::TypeAlias(name, gen)); return std::any((ast::Stmt *)new ast::TypeAlias(loc(ctx), name, gen));
} }
std::vector<int> args; 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));
} }
};
class ErrorListener : public antlr4::BaseErrorListener virtual std::any visitFnDef(plsmParser::FnDefContext *ctx) override
{
std::string *error;
public:
ErrorListener(std::string *error) : error(error) {}
virtual void syntaxError(antlr4::Recognizer *recognizer, antlr4::Token *offendingSymbol, size_t line, size_t charPositionInLine,
const std::string &msg, std::exception_ptr e) override
{ {
std::stringstream ss; auto name = ctx->identifier()->getText();
ss << "line " << line << ":" << charPositionInLine << ": " << msg;
*error = ss.str();
}
};
std::unique_ptr<ast::Module> std::vector<std::unique_ptr<ast::FnArg>> args;
plsm::parse(const std::string &input) 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 istream = antlr4::ANTLRInputStream(input);
auto lexer = plsmLexer(&istream); auto lexer = plsmLexer(&istream);
auto tokens = antlr4::CommonTokenStream(&lexer); auto tokens = antlr4::CommonTokenStream(&lexer);
auto parser = plsmParser(&tokens); auto parser = plsmParser(&tokens);
std::string error; std::string error;
ErrorListener listener(&error); ErrorListener listener(file, &error);
parser.removeErrorListeners(); parser.removeErrorListeners();
parser.addErrorListener(&listener); parser.addErrorListener(&listener);
@ -120,12 +493,13 @@ plsm::parse(const std::string &input)
if (error.size()) if (error.size())
throw std::runtime_error(error); throw std::runtime_error(error);
auto module = std::any_cast<ast::Module *>(Visitor().visitModule(tree)); auto module = std::any_cast<ast::Module *>(Visitor(file).visitModule(tree));
return std::unique_ptr<ast::Module>(module); 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");
} }

View File

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

@ -0,0 +1 @@
Subproject commit 525fe4492bbecf357d3580d879f2092bf99c12a2

View File

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