switching to ANTLR
This commit is contained in:
parent
99ac38be63
commit
f45adb1810
9
compiler/.gitignore
vendored
9
compiler/.gitignore
vendored
@ -1 +1,8 @@
|
|||||||
*.gen.*
|
# antlr
|
||||||
|
.antlr/
|
||||||
|
*.interp
|
||||||
|
*.tokens
|
||||||
|
|
||||||
|
# antlr-generated files
|
||||||
|
plsm*.h
|
||||||
|
plsm*.cpp
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
"[yacc]": {
|
"C_Cpp.default.includePath": [
|
||||||
"problems.decorations.enabled": false,
|
"${workspaceFolder}/include/",
|
||||||
},
|
"/usr/include/antlr4-runtime",
|
||||||
|
],
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.embeddedhtml": "html",
|
"*.embeddedhtml": "html",
|
||||||
|
"iosfwd": "cpp",
|
||||||
"any": "cpp",
|
"any": "cpp",
|
||||||
"array": "cpp",
|
"array": "cpp",
|
||||||
"atomic": "cpp",
|
"atomic": "cpp",
|
||||||
"bit": "cpp",
|
"bit": "cpp",
|
||||||
"*.tcc": "cpp",
|
"*.tcc": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
"cctype": "cpp",
|
"cctype": "cpp",
|
||||||
"charconv": "cpp",
|
"charconv": "cpp",
|
||||||
"chrono": "cpp",
|
"chrono": "cpp",
|
||||||
@ -28,10 +30,13 @@
|
|||||||
"cwchar": "cpp",
|
"cwchar": "cpp",
|
||||||
"cwctype": "cpp",
|
"cwctype": "cpp",
|
||||||
"deque": "cpp",
|
"deque": "cpp",
|
||||||
|
"forward_list": "cpp",
|
||||||
"list": "cpp",
|
"list": "cpp",
|
||||||
"map": "cpp",
|
"map": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
"string": "cpp",
|
"string": "cpp",
|
||||||
"unordered_map": "cpp",
|
"unordered_map": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
"vector": "cpp",
|
"vector": "cpp",
|
||||||
"exception": "cpp",
|
"exception": "cpp",
|
||||||
"algorithm": "cpp",
|
"algorithm": "cpp",
|
||||||
@ -52,7 +57,6 @@
|
|||||||
"fstream": "cpp",
|
"fstream": "cpp",
|
||||||
"initializer_list": "cpp",
|
"initializer_list": "cpp",
|
||||||
"iomanip": "cpp",
|
"iomanip": "cpp",
|
||||||
"iosfwd": "cpp",
|
|
||||||
"iostream": "cpp",
|
"iostream": "cpp",
|
||||||
"istream": "cpp",
|
"istream": "cpp",
|
||||||
"limits": "cpp",
|
"limits": "cpp",
|
||||||
@ -61,6 +65,7 @@
|
|||||||
"numbers": "cpp",
|
"numbers": "cpp",
|
||||||
"ostream": "cpp",
|
"ostream": "cpp",
|
||||||
"semaphore": "cpp",
|
"semaphore": "cpp",
|
||||||
|
"shared_mutex": "cpp",
|
||||||
"span": "cpp",
|
"span": "cpp",
|
||||||
"sstream": "cpp",
|
"sstream": "cpp",
|
||||||
"stdexcept": "cpp",
|
"stdexcept": "cpp",
|
||||||
@ -72,18 +77,6 @@
|
|||||||
"typeinfo": "cpp",
|
"typeinfo": "cpp",
|
||||||
"valarray": "cpp",
|
"valarray": "cpp",
|
||||||
"variant": "cpp",
|
"variant": "cpp",
|
||||||
"int.h": "c",
|
"*.inc": "cpp"
|
||||||
"macros.h": "c",
|
}
|
||||||
"stdint.h": "c",
|
|
||||||
"type.h": "c",
|
|
||||||
"stdlib.h": "c",
|
|
||||||
"bitset": "cpp",
|
|
||||||
"codecvt": "cpp",
|
|
||||||
"forward_list": "cpp",
|
|
||||||
"set": "cpp",
|
|
||||||
"unordered_set": "cpp",
|
|
||||||
"source_location": "cpp",
|
|
||||||
"shared_mutex": "cpp",
|
|
||||||
"strstream": "cpp"
|
|
||||||
},
|
|
||||||
}
|
}
|
@ -3,26 +3,37 @@ cmake_minimum_required(VERSION 3.25)
|
|||||||
project(plasmatum)
|
project(plasmatum)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
set(SOURCE_DIR ${CMAKE_SOURCE_DIR}/src)
|
set(SRC_DIR ${CMAKE_SOURCE_DIR}/src)
|
||||||
set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
|
set(INC_DIR ${CMAKE_SOURCE_DIR}/include)
|
||||||
|
|
||||||
find_package(FLEX REQUIRED)
|
set(GEN_DIR ${CMAKE_SOURCE_DIR}/generated)
|
||||||
find_package(BISON REQUIRED)
|
|
||||||
|
|
||||||
BISON_TARGET(parser
|
set(ANTLR_INC ${INC_DIR}/plsmLexer.h ${INC_DIR}/plsmParser.h ${INC_DIR}/plsmVisitor.h ${INC_DIR}/plsmBaseVisitor.h)
|
||||||
${CMAKE_SOURCE_DIR}/parser.yy
|
set(ANTLR_SRC ${SRC_DIR}/plsmLexer.cpp ${SRC_DIR}/plsmParser.cpp ${SRC_DIR}/plsmVisitor.cpp ${SRC_DIR}/plsmBaseVisitor.cpp)
|
||||||
${SOURCE_DIR}/parser.gen.cpp
|
|
||||||
DEFINES_FILE ${INCLUDE_DIR}/parser.gen.h)
|
|
||||||
|
|
||||||
FLEX_TARGET(lexer
|
add_custom_command(PRE_BUILD
|
||||||
${CMAKE_SOURCE_DIR}/lexer.ll
|
DEPENDS ${CMAKE_SOURCE_DIR}/plsm.g4
|
||||||
${SOURCE_DIR}/lexer.gen.cpp)
|
OUTPUT ${ANTLR_SRC}
|
||||||
|
OUTPUT ${ANTLR_INC}
|
||||||
|
COMMENT "Generating plsm_parser"
|
||||||
|
COMMAND java -jar
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty/antlr-4.13.1-complete.jar
|
||||||
|
${CMAKE_SOURCE_DIR}/plsm.g4
|
||||||
|
-o ${GEN_DIR} -Dlanguage=Cpp -no-listener -visitor
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${GEN_DIR}/*.h ${INC_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${GEN_DIR}/*.cpp ${SRC_DIR})
|
||||||
|
|
||||||
ADD_FLEX_BISON_DEPENDENCY(lexer parser)
|
file(GLOB_RECURSE sources ${SRC_DIR}/*.cpp)
|
||||||
|
set(sources ${sources} ${ANTLR_SRC})
|
||||||
|
|
||||||
file(GLOB_RECURSE sources ${SOURCE_DIR}/*.cpp)
|
|
||||||
set(sources ${sources} ${FLEX_lexer_OUTPUTS})
|
|
||||||
set(sources ${sources} ${BISON_parser_OUTPUT_SOURCE})
|
|
||||||
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
|
||||||
add_executable(plsm ${sources})
|
add_executable(plsm ${sources})
|
||||||
|
|
||||||
|
target_include_directories(plsm PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||||
|
target_include_directories(plsm PRIVATE /usr/include/antlr4-runtime)
|
||||||
|
target_link_libraries(plsm antlr4-runtime)
|
||||||
|
|
||||||
|
add_custom_target(clean-all
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E rm -rf
|
||||||
|
${GEN_DIR} ${CMAKE_SOURCE_DIR}/build
|
||||||
|
)
|
||||||
|
|
||||||
|
8
compiler/adscript.g4
Normal file
8
compiler/adscript.g4
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
grammar adscript;
|
||||||
|
|
||||||
|
module:;
|
||||||
|
|
||||||
|
// TODO ;)
|
||||||
|
|
||||||
|
FN: 'fn';
|
||||||
|
TYPE: 'type';
|
@ -6,17 +6,27 @@ namespace ast
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~ASTNode() = default;
|
virtual ~ASTNode() = default;
|
||||||
|
|
||||||
|
virtual bool isExpr() { return false; }
|
||||||
|
virtual bool isStmt() { return false; }
|
||||||
|
virtual bool isType() { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Expr : public ASTNode
|
class Expr : public ASTNode
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual bool isExpr() override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Stmt : public ASTNode
|
class Stmt : public ASTNode
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual bool isStmt() override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Type : public ASTNode
|
class Type : public ASTNode
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual bool isType() override { return true; }
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -5,17 +5,20 @@
|
|||||||
#include "Expr/BinExpr.h"
|
#include "Expr/BinExpr.h"
|
||||||
#include "Expr/Block.h"
|
#include "Expr/Block.h"
|
||||||
#include "Expr/Call.h"
|
#include "Expr/Call.h"
|
||||||
|
#include "Expr/Closure.h"
|
||||||
#include "Expr/Identifier.h"
|
#include "Expr/Identifier.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/FnDecl.h"
|
||||||
#include "Stmt/TraitDecl.h"
|
#include "Stmt/TraitAlias.h"
|
||||||
#include "Stmt/TypeDecl.h"
|
#include "Stmt/TraitDef.h"
|
||||||
|
#include "Stmt/TypeAlias.h"
|
||||||
|
#include "Stmt/TypeDef.h"
|
||||||
#include "Stmt/ValDecl.h"
|
#include "Stmt/ValDecl.h"
|
||||||
|
|
||||||
#include "Type/Function.h"
|
#include "Type/Closure.h"
|
||||||
#include "Type/Generic.h"
|
#include "Type/Generic.h"
|
||||||
#include "Type/Named.h"
|
#include "Type/Named.h"
|
||||||
#include "Type/Tuple.h"
|
#include "Type/Tuple.h"
|
||||||
|
@ -2,33 +2,25 @@
|
|||||||
|
|
||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
class BinExpr : public Expr
|
class BinExpr : public Expr
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
BinExpr(const Expr *left, const std::string &op, const Expr *right)
|
|
||||||
: left(left), op(op), right(right) {}
|
|
||||||
|
|
||||||
~BinExpr()
|
|
||||||
{
|
|
||||||
delete left;
|
|
||||||
delete right;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Expr *left;
|
|
||||||
const std::string op;
|
const std::string op;
|
||||||
const Expr *right;
|
const std::unique_ptr<Expr> left, right;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BinExpr(std::unique_ptr<Expr> &left, const std::string &op, std::unique_ptr<Expr> &right)
|
||||||
|
: left(std::move(left)), op(op), right(std::move(right)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PrefExpr : public Expr
|
class PrefExpr : public Expr
|
||||||
{
|
{
|
||||||
|
const std::unique_ptr<Expr> expr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PrefExpr(const Expr *expr) : expr(expr) {}
|
PrefExpr(std::unique_ptr<Expr> &expr) : expr(std::move(expr)) {}
|
||||||
|
|
||||||
~PrefExpr() { delete expr; }
|
|
||||||
|
|
||||||
const Expr *expr;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -2,19 +2,15 @@
|
|||||||
|
|
||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
class BlockExpr : public Expr
|
class BlockExpr : public Expr
|
||||||
{
|
{
|
||||||
public:
|
const std::vector<std::unique_ptr<Stmt>> stmts;
|
||||||
BlockExpr(const std::vector<Stmt *> &stmts) : stmts(std::move(stmts)) {}
|
|
||||||
~BlockExpr()
|
|
||||||
{
|
|
||||||
for (auto &stmt : stmts)
|
|
||||||
delete stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<Stmt *> stmts;
|
public:
|
||||||
|
BlockExpr(std::vector<std::unique_ptr<Stmt>> &stmts) : stmts(std::move(stmts)) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -2,23 +2,17 @@
|
|||||||
|
|
||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
class CallExpr : public Expr
|
class CallExpr : public Expr
|
||||||
{
|
{
|
||||||
|
const std::unique_ptr<Expr> callee;
|
||||||
|
const std::vector<std::unique_ptr<Expr>> args;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CallExpr(const Expr *callee, const std::vector<Expr *> &args)
|
CallExpr(std::unique_ptr<Expr> &callee, std::vector<std::unique_ptr<Expr>> &args)
|
||||||
: callee(callee), args(std::move(args)) {}
|
: callee(std::move(callee)), args(std::move(args)) {}
|
||||||
|
|
||||||
~CallExpr()
|
|
||||||
{
|
|
||||||
delete callee;
|
|
||||||
for (auto &arg : args)
|
|
||||||
delete arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Expr *callee;
|
|
||||||
const std::vector<Expr *> args;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -3,17 +3,17 @@
|
|||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
class Closure : public Expr
|
class Closure : public Expr
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
Closure(const std::vector<std::string> &args, const Expr *body)
|
|
||||||
: args(std::move(args)), body(body) {}
|
|
||||||
~Closure() { delete body; }
|
|
||||||
|
|
||||||
const std::vector<std::string> args;
|
const std::vector<std::string> args;
|
||||||
const Expr *body;
|
const std::unique_ptr<Expr> body;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Closure(std::vector<std::string> &args, std::unique_ptr<Expr> &body)
|
||||||
|
: args(std::move(args)), body(std::move(body)) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -7,9 +7,9 @@ namespace ast
|
|||||||
{
|
{
|
||||||
class Identifier : public Expr
|
class Identifier : public Expr
|
||||||
{
|
{
|
||||||
|
const std::string name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Identifier(const std::string &name) : name(name) {}
|
Identifier(const std::string &name) : name(name) {}
|
||||||
|
|
||||||
const std::string name;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -2,18 +2,17 @@
|
|||||||
|
|
||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
class UnaryExpr : public Expr
|
class UnaryExpr : public Expr
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
UnaryExpr(const std::string &op, const Expr *expr)
|
|
||||||
: op(op), expr(expr) {}
|
|
||||||
|
|
||||||
~UnaryExpr() { delete expr; }
|
|
||||||
|
|
||||||
const std::string op;
|
const std::string op;
|
||||||
const Expr *expr;
|
const std::unique_ptr<Expr> expr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UnaryExpr(const std::string &op, std::unique_ptr<Expr> &expr)
|
||||||
|
: op(op), expr(std::move(expr)) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -7,15 +7,17 @@ namespace ast
|
|||||||
{
|
{
|
||||||
class IntValue : public Expr
|
class IntValue : public Expr
|
||||||
{
|
{
|
||||||
|
const int64_t value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IntValue(int64_t value) : value(value) {}
|
IntValue(int64_t value) : value(value) {}
|
||||||
const int64_t value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloatValue : public Expr
|
class FloatValue : public Expr
|
||||||
{
|
{
|
||||||
|
const double value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FloatValue(double value) : value(value) {}
|
FloatValue(double value) : value(value) {}
|
||||||
const double value;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,9 @@ namespace ast
|
|||||||
{
|
{
|
||||||
class Import : public ASTNode
|
class Import : public ASTNode
|
||||||
{
|
{
|
||||||
|
const std::string moduleName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Import(const std::string &moduleName) : moduleName(moduleName) {}
|
Import(const std::string &moduleName) : moduleName(moduleName) {}
|
||||||
const std::string moduleName;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
@ -9,20 +10,11 @@ namespace ast
|
|||||||
|
|
||||||
class Module : public ASTNode
|
class Module : public ASTNode
|
||||||
{
|
{
|
||||||
|
const std::vector<std::unique_ptr<Import>> imports;
|
||||||
|
const std::vector<std::unique_ptr<Stmt>> stmts;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Module(const std::vector<Import *> &imports, const std::vector<Stmt *> &stmts)
|
Module(std::vector<std::unique_ptr<Import>> &imports, std::vector<std::unique_ptr<Stmt>> &stmts)
|
||||||
: imports(std::move(imports)), stmts(std::move(stmts)) {}
|
: imports(std::move(imports)), stmts(std::move(stmts)) {}
|
||||||
|
|
||||||
~Module()
|
|
||||||
{
|
|
||||||
for (auto &import : imports)
|
|
||||||
delete import;
|
|
||||||
|
|
||||||
for (auto &stmt : stmts)
|
|
||||||
delete stmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<Import *> &imports;
|
|
||||||
const std::vector<Stmt *> stmts;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,15 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
class ExprStmt : public Stmt
|
class ExprStmt : public Stmt
|
||||||
{
|
{
|
||||||
public:
|
const std::unique_ptr<Expr> expr;
|
||||||
ExprStmt(const Expr *expr) : expr(expr) {}
|
|
||||||
~ExprStmt() { delete expr; }
|
|
||||||
|
|
||||||
const Expr *expr;
|
public:
|
||||||
|
ExprStmt(std::unique_ptr<Expr> &expr) : expr(std::move(expr)) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -3,29 +3,21 @@
|
|||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
typedef std::pair<std::string, Type *> FnArg;
|
typedef std::pair<std::string, std::unique_ptr<Type>> FnArg;
|
||||||
|
|
||||||
class FnDecl : public Stmt
|
class FnDecl : public Stmt
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
FnDecl(const std::string &name, const std::vector<FnArg> &args, const Type *returnType, const Expr *body)
|
|
||||||
: name(name), args(std::move(args)), returnType(returnType), body(body) {}
|
|
||||||
|
|
||||||
~FnDecl()
|
|
||||||
{
|
|
||||||
for (auto &arg : args)
|
|
||||||
delete arg.second;
|
|
||||||
|
|
||||||
delete returnType;
|
|
||||||
delete body;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string name;
|
const std::string name;
|
||||||
const std::vector<FnArg> args;
|
const std::vector<FnArg> args;
|
||||||
const Type *returnType;
|
const std::unique_ptr<Type> returnType;
|
||||||
const Expr *body;
|
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)) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
19
compiler/include/AST/Stmt/TraitAlias.h
Normal file
19
compiler/include/AST/Stmt/TraitAlias.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AST/Base.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ast
|
||||||
|
{
|
||||||
|
class TraitAlias : public Stmt
|
||||||
|
{
|
||||||
|
const std::string alias;
|
||||||
|
const std::string aliased;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TraitAlias(const std::string &alias, const std::string &aliased)
|
||||||
|
: alias(alias), aliased(aliased) {}
|
||||||
|
};
|
||||||
|
}
|
@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "AST/Base.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace ast
|
|
||||||
{
|
|
||||||
class FnDecl;
|
|
||||||
|
|
||||||
class TraitDecl : public Stmt
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TraitDecl(const std::string &name, const std::vector<FnDecl *> &traits)
|
|
||||||
: name(name), traits(std::move(traits)) {}
|
|
||||||
~TraitDecl()
|
|
||||||
{
|
|
||||||
for (auto &trait : traits)
|
|
||||||
delete trait;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string name;
|
|
||||||
const std::vector<FnDecl *> traits;
|
|
||||||
};
|
|
||||||
}
|
|
21
compiler/include/AST/Stmt/TraitDef.h
Normal file
21
compiler/include/AST/Stmt/TraitDef.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AST/Base.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ast
|
||||||
|
{
|
||||||
|
class FnDecl;
|
||||||
|
|
||||||
|
class TraitDef : public Stmt
|
||||||
|
{
|
||||||
|
const std::string name;
|
||||||
|
const std::vector<std::unique_ptr<FnDecl>> traits;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TraitDef(const std::string &name, std::vector<std::unique_ptr<FnDecl>> &traits)
|
||||||
|
: name(name), traits(std::move(traits)) {}
|
||||||
|
};
|
||||||
|
}
|
19
compiler/include/AST/Stmt/TypeAlias.h
Normal file
19
compiler/include/AST/Stmt/TypeAlias.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AST/Base.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ast
|
||||||
|
{
|
||||||
|
class TypeAlias : public Stmt
|
||||||
|
{
|
||||||
|
const std::string alias;
|
||||||
|
const std::unique_ptr<Type> type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TypeAlias(const std::string &alias, std::unique_ptr<Type> &type)
|
||||||
|
: alias(alias), type(std::move(type)) {}
|
||||||
|
};
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "AST/Base.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace ast
|
|
||||||
{
|
|
||||||
class FnDecl;
|
|
||||||
|
|
||||||
typedef std::pair<std::string, Type *> TypeAttr;
|
|
||||||
|
|
||||||
class TypeDecl : public Stmt
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TypeDecl(const std::string &name, const std::vector<TypeAttr> &attrs, const std::vector<FnDecl *> &members)
|
|
||||||
: name(name), attrs(std::move(attrs)), members(std::move(members)) {}
|
|
||||||
~TypeDecl()
|
|
||||||
{
|
|
||||||
for (auto &attr : attrs)
|
|
||||||
delete attr.second;
|
|
||||||
|
|
||||||
for (auto &member : members)
|
|
||||||
delete member;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string name;
|
|
||||||
const std::vector<TypeAttr> attrs;
|
|
||||||
const std::vector<FnDecl *> members;
|
|
||||||
};
|
|
||||||
}
|
|
24
compiler/include/AST/Stmt/TypeDef.h
Normal file
24
compiler/include/AST/Stmt/TypeDef.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AST/Base.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ast
|
||||||
|
{
|
||||||
|
class FnDecl;
|
||||||
|
|
||||||
|
typedef std::pair<std::string, std::unique_ptr<Type>> TypeAttr;
|
||||||
|
|
||||||
|
class TypeDef : public Stmt
|
||||||
|
{
|
||||||
|
const std::string name;
|
||||||
|
const std::vector<TypeAttr> attrs;
|
||||||
|
const std::vector<std::unique_ptr<FnDecl>> members;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TypeDef(const std::string &name, std::vector<TypeAttr> &attrs, std::vector<std::unique_ptr<FnDecl>> &members)
|
||||||
|
: name(name), attrs(std::move(attrs)), members(std::move(members)) {}
|
||||||
|
};
|
||||||
|
}
|
@ -2,23 +2,18 @@
|
|||||||
|
|
||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
class ValDecl : public Stmt
|
class ValDecl : public Stmt
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
ValDecl(const std::string &name, const Type *type, const Expr *value)
|
|
||||||
: name(name), type(type), value(value) {}
|
|
||||||
|
|
||||||
~ValDecl()
|
|
||||||
{
|
|
||||||
delete type;
|
|
||||||
delete value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string name;
|
const std::string name;
|
||||||
const Type *type;
|
const std::unique_ptr<Type> type;
|
||||||
const Expr *value;
|
const std::unique_ptr<Expr> value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ValDecl(const std::string &name, std::unique_ptr<Type> &type, std::unique_ptr<Expr> &value)
|
||||||
|
: name(name), type(std::move(type)), value(std::move(value)) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
18
compiler/include/AST/Type/Closure.h
Normal file
18
compiler/include/AST/Type/Closure.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AST/Base.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ast
|
||||||
|
{
|
||||||
|
class ClosureType : public Type
|
||||||
|
{
|
||||||
|
const std::vector<std::unique_ptr<Type>> from;
|
||||||
|
const std::unique_ptr<Type> to;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ClosureType(std::vector<std::unique_ptr<Type>> &from, std::unique_ptr<Type> &to)
|
||||||
|
: from(std::move(from)), to(std::move(to)) {}
|
||||||
|
};
|
||||||
|
}
|
@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "AST/Base.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace ast
|
|
||||||
{
|
|
||||||
class FunctionType : public Type
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FunctionType(const std::vector<Type *> &from, const Type *to)
|
|
||||||
: from(std::move(from)), to(to) {}
|
|
||||||
|
|
||||||
~FunctionType()
|
|
||||||
{
|
|
||||||
for (auto &arg : from)
|
|
||||||
delete arg;
|
|
||||||
|
|
||||||
delete to;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<Type *> from;
|
|
||||||
const Type *to;
|
|
||||||
};
|
|
||||||
}
|
|
@ -3,22 +3,17 @@
|
|||||||
#include "AST/Base.h"
|
#include "AST/Base.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
class GenericType : public Type
|
class GenericType : public Type
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
GenericType(const std::string &name, const std::vector<Type *> &types)
|
|
||||||
: name(name), types(std::move(types)) {}
|
|
||||||
|
|
||||||
~GenericType()
|
|
||||||
{
|
|
||||||
for (auto &type : types)
|
|
||||||
delete type;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string name;
|
const std::string name;
|
||||||
const std::vector<Type *> types;
|
const std::vector<std::unique_ptr<Type>> types;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GenericType(const std::string &name, std::vector<std::unique_ptr<Type>> &types)
|
||||||
|
: name(name), types(std::move(types)) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,9 @@ namespace ast
|
|||||||
{
|
{
|
||||||
class NamedType : public Type
|
class NamedType : public Type
|
||||||
{
|
{
|
||||||
|
const std::string name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NamedType(const std::string &name) : name(name) {}
|
NamedType(const std::string &name) : name(name) {}
|
||||||
const std::string name;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -2,20 +2,16 @@
|
|||||||
|
|
||||||
#include "AST/Def.h"
|
#include "AST/Def.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ast
|
namespace ast
|
||||||
{
|
{
|
||||||
class TupleType : public Type
|
class TupleType : public Type
|
||||||
{
|
{
|
||||||
|
const std::vector<std::unique_ptr<Type>> types;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TupleType(const std::vector<Type *> &types) : types(std::move(types)) {}
|
TupleType(std::vector<std::unique_ptr<Type>> &types)
|
||||||
|
: types(std::move(types)) {}
|
||||||
~TupleType()
|
|
||||||
{
|
|
||||||
for (auto &type : types)
|
|
||||||
delete type;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<Type *> types;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,18 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "AST/Def.h"
|
#include "AST/Def.h"
|
||||||
#include "parser.gen.h"
|
#include "plsmLexer.h"
|
||||||
|
#include "plsmParser.h"
|
||||||
|
|
||||||
class Parser
|
namespace plsm
|
||||||
{
|
{
|
||||||
public:
|
std::unique_ptr<ast::Module> parse(const std::string &input);
|
||||||
Parser() {}
|
}
|
||||||
|
|
||||||
ast::Module *parse(const std::string &file, const std::stringstream &input);
|
namespace adscript
|
||||||
|
{
|
||||||
std::string file;
|
std::unique_ptr<ast::Module> parse(const std::string &input);
|
||||||
yy::location location;
|
}
|
||||||
ast::Module *module;
|
|
||||||
};
|
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
%{
|
|
||||||
#include "parser.gen.h"
|
|
||||||
#include "Parser.h"
|
|
||||||
|
|
||||||
#undef YY_DECL
|
|
||||||
#define YY_DECL yy::parser::symbol_type yylex(Parser &driver)
|
|
||||||
|
|
||||||
#define yyterminate() yy::parser::make_END(yy::location())
|
|
||||||
|
|
||||||
#define _token(token) yy::parser::make_##token(yytext, driver.location)
|
|
||||||
%}
|
|
||||||
|
|
||||||
%option noyywrap nounput noinput batch
|
|
||||||
|
|
||||||
digit [0-9]
|
|
||||||
bindigit [0-1]
|
|
||||||
octdigit [0-7]
|
|
||||||
hexdigit [0-9a-fA-F]
|
|
||||||
|
|
||||||
letter [a-zA-Z]
|
|
||||||
|
|
||||||
opchar ("+"|"-"|"*"|"/"|"%"|"!"|"&"|"$"|"§"|"|"|"="|"<"|">"|"?"|"~"|"#"|":"|"^"|"\\"|".")
|
|
||||||
|
|
||||||
whitespace [ \n\t\r\v]+
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
"0b"{bindigit}+ { return yy::parser::make_INT(std::strtol(yytext, NULL, 2), driver.location); }
|
|
||||||
"0o"{octdigit}+ { return yy::parser::make_INT(std::strtol(yytext, NULL, 8), driver.location); }
|
|
||||||
"0x"{hexdigit}+ { return yy::parser::make_INT(std::strtol(yytext, NULL, 16), driver.location); }
|
|
||||||
{digit}+ { return yy::parser::make_INT(std::strtol(yytext, NULL, 10), driver.location); }
|
|
||||||
|
|
||||||
{digit}*"."{digit}+ { return yy::parser::make_FLOAT(std::strtod(yytext, NULL), driver.location); }
|
|
||||||
|
|
||||||
|
|
||||||
{opchar}+ { std::string text = yytext;
|
|
||||||
if (text == "=") return _token(EQUALS);
|
|
||||||
if (text == "->") return _token(RARR);
|
|
||||||
if (text == ".") return _token(DOT);
|
|
||||||
return _token(OPERATOR); }
|
|
||||||
|
|
||||||
"," { return _token(COMMA); }
|
|
||||||
";" { return _token(SEMI); }
|
|
||||||
"(" { return _token(LPAREN); }
|
|
||||||
")" { return _token(RPAREN); }
|
|
||||||
"[" { return _token(LBRACKET); }
|
|
||||||
"]" { return _token(RBRACKET); }
|
|
||||||
"{" { return _token(LBRACE); }
|
|
||||||
"}" { return _token(RBRACE); }
|
|
||||||
|
|
||||||
"binop" { return _token(BINOP); }
|
|
||||||
"declare" { return _token(DECLARE); }
|
|
||||||
"fn" { return _token(FN); }
|
|
||||||
"import" { return _token(IMPORT); }
|
|
||||||
"trait" { return _token(TRAIT); }
|
|
||||||
"type" { return _token(TYPE); }
|
|
||||||
"unop" { return _token(UNOP); }
|
|
||||||
"val" { return _token(VAL); }
|
|
||||||
|
|
||||||
|
|
||||||
{letter}({digit}|{letter})* { return _token(IDENTIFIER); }
|
|
||||||
|
|
||||||
<<EOF>> { return yy::parser::make_END(driver.location); }
|
|
||||||
|
|
||||||
{whitespace} { ; }
|
|
||||||
|
|
||||||
%%
|
|
@ -1,289 +0,0 @@
|
|||||||
%require "3.8"
|
|
||||||
%language "c++"
|
|
||||||
|
|
||||||
%header
|
|
||||||
|
|
||||||
%define api.token.raw
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.prefix {TOK_}
|
|
||||||
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
|
|
||||||
%locations
|
|
||||||
%define api.location.file "../include/location.gen.h"
|
|
||||||
%define api.location.include {"location.gen.h"}
|
|
||||||
|
|
||||||
%code requires {
|
|
||||||
#include "AST/Def.h"
|
|
||||||
class Parser;
|
|
||||||
}
|
|
||||||
|
|
||||||
%lex-param { Parser &driver }
|
|
||||||
%parse-param { Parser &driver }
|
|
||||||
|
|
||||||
%code {
|
|
||||||
#include "Parser.h"
|
|
||||||
yy::parser::symbol_type yylex(Parser &driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token <long> INT "integer literal"
|
|
||||||
%token <double> FLOAT "float literal"
|
|
||||||
|
|
||||||
%token <std::string>
|
|
||||||
OPERATOR "operator"
|
|
||||||
IDENTIFIER "identifier"
|
|
||||||
|
|
||||||
RARR "->"
|
|
||||||
EQUALS "="
|
|
||||||
DOT "."
|
|
||||||
COMMA ","
|
|
||||||
SEMI ";"
|
|
||||||
LPAREN "("
|
|
||||||
RPAREN ")"
|
|
||||||
LBRACKET "["
|
|
||||||
RBRACKET "]"
|
|
||||||
LBRACE "{"
|
|
||||||
RBRACE "}"
|
|
||||||
|
|
||||||
BINOP "binop"
|
|
||||||
DECLARE "declare"
|
|
||||||
FN "fn"
|
|
||||||
IMPORT "import"
|
|
||||||
TRAIT "trait"
|
|
||||||
TYPE "type"
|
|
||||||
UNOP "unop"
|
|
||||||
VAL "val"
|
|
||||||
;
|
|
||||||
|
|
||||||
%token END 0 "end of file"
|
|
||||||
|
|
||||||
%type <std::vector<ast::Stmt *>>
|
|
||||||
topLevelStmts
|
|
||||||
blockStmts
|
|
||||||
;
|
|
||||||
|
|
||||||
%type <ast::Stmt *>
|
|
||||||
topLevelStmt
|
|
||||||
blockStmt
|
|
||||||
;
|
|
||||||
|
|
||||||
%type <std::vector<ast::FnDecl *>> fnDecls fnDecls0;
|
|
||||||
%type <ast::FnDecl *> fnDecl fnDef;
|
|
||||||
%type <ast::ValDecl *> valDecl;
|
|
||||||
|
|
||||||
%type <std::vector<ast::Type *>>
|
|
||||||
types
|
|
||||||
tupleTypes
|
|
||||||
fnTypeArgs
|
|
||||||
;
|
|
||||||
|
|
||||||
%type <ast::Type *> type type1;
|
|
||||||
|
|
||||||
%type <std::vector<ast::Expr *>> exprs args;
|
|
||||||
|
|
||||||
%type <ast::Expr *>
|
|
||||||
expr
|
|
||||||
expr3
|
|
||||||
expr2
|
|
||||||
expr1
|
|
||||||
expr0
|
|
||||||
literal
|
|
||||||
;
|
|
||||||
|
|
||||||
%type <ast::FnArg> fnArg;
|
|
||||||
%type <std::vector<ast::FnArg>> fnArgs fnArgs0;
|
|
||||||
|
|
||||||
%type <std::vector<std::string>>
|
|
||||||
lambdaArgs
|
|
||||||
identifiers
|
|
||||||
;
|
|
||||||
|
|
||||||
%type <std::string>
|
|
||||||
moduleName
|
|
||||||
type0
|
|
||||||
operator
|
|
||||||
identifier
|
|
||||||
keyword
|
|
||||||
;
|
|
||||||
|
|
||||||
%type <ast::Import *> import;
|
|
||||||
%type <std::vector<ast::Import *>>
|
|
||||||
imports0
|
|
||||||
imports
|
|
||||||
;
|
|
||||||
|
|
||||||
%type <ast::TraitDecl *> traitDecl;
|
|
||||||
%type <ast::TypeDecl *> typeDecl;
|
|
||||||
|
|
||||||
%start module
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
module: imports topLevelStmts { driver.module = new ast::Module($1, $2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
imports: %empty { ; }
|
|
||||||
| imports0 { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
imports0: import { $$.push_back($1); }
|
|
||||||
| imports0 import { $1.push_back($2); $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
import: IMPORT moduleName ";" { $$ = new ast::Import($2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
moduleName: identifier { $$ = $1; }
|
|
||||||
| moduleName "." identifier { $$ = $1 + $2 + $3; }
|
|
||||||
;
|
|
||||||
|
|
||||||
topLevelStmts: topLevelStmt { $$.push_back($1); }
|
|
||||||
| topLevelStmts topLevelStmt { $1.push_back($2); $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
topLevelStmt: fnDef { $$ = $1; }
|
|
||||||
| fnDecl { $$ = $1; }
|
|
||||||
| valDecl { $$ = $1; }
|
|
||||||
| typeDecl { $$ = $1; }
|
|
||||||
| traitDecl { $$ = $1; }
|
|
||||||
;
|
|
||||||
|
|
||||||
blockStmts: blockStmt { $$.push_back($1); }
|
|
||||||
| blockStmts blockStmt { $1.push_back($2); $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
blockStmt: valDecl { $$ = $1; }
|
|
||||||
| fnDef { $$ = $1; }
|
|
||||||
| expr ";" { $$ = new ast::ExprStmt($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
traitDecl: TRAIT identifier "=" "{" fnDecls "}" { $$ = new ast::TraitDecl($2, $5); }
|
|
||||||
;
|
|
||||||
|
|
||||||
typeDecl: TYPE identifier "=" "(" fnArgs ")" "{" fnDecls "}" { $$ = new ast::TypeDecl($2, $5, $8); }
|
|
||||||
;
|
|
||||||
|
|
||||||
fnDecls: %empty { ; }
|
|
||||||
| fnDecls0 { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
fnDecls0: fnDecl { $$.push_back($1); }
|
|
||||||
| fnDecls0 fnDecl { $1.push_back($2); $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
valDecl: VAL identifier "=" expr ";" { $$ = new ast::ValDecl($2, nullptr, $4); }
|
|
||||||
| VAL identifier type "=" expr ";" { $$ = new ast::ValDecl($2, $3, $5); }
|
|
||||||
;
|
|
||||||
|
|
||||||
fnDef : FN identifier "[" fnArgs "]" type "=" expr ";" { $$ = new ast::FnDecl($2, $4, $6, $8); }
|
|
||||||
;
|
|
||||||
|
|
||||||
fnDecl: FN identifier "[" fnArgs "]" type ";" { $$ = new ast::FnDecl($2, $4, $6, nullptr); }
|
|
||||||
;
|
|
||||||
|
|
||||||
fnArgs: %empty { ; }
|
|
||||||
| fnArgs0 { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
fnArgs0: fnArg { $$.push_back($1); }
|
|
||||||
| fnArgs0 "," fnArg { $$.push_back($3); $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
fnArg: identifier type { $$ = ast::FnArg($1, $2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
types: type { $$.push_back($1); }
|
|
||||||
| types "," type { $1.push_back($3); $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
type: type1
|
|
||||||
| "(" type ")" { $$ = $2; }
|
|
||||||
| "(" tupleTypes ")" { $$ = new ast::TupleType($2); }
|
|
||||||
| "[" fnTypeArgs "]" "->" type { $$ = new ast::FunctionType($2, $5); }
|
|
||||||
;
|
|
||||||
|
|
||||||
type1: type0 { $$ = new ast::NamedType($1); }
|
|
||||||
| type0 "{" types "}" { $$ = new ast::GenericType($1, $3); }
|
|
||||||
;
|
|
||||||
|
|
||||||
type0: identifier;
|
|
||||||
|
|
||||||
tupleTypes: type "," type { $$.push_back($1); $$.push_back($3); }
|
|
||||||
| tupleTypes "," type { $1.push_back($3); $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
fnTypeArgs: %empty { ; }
|
|
||||||
| types { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
exprs: expr { $$.push_back($1); }
|
|
||||||
| exprs "," expr { $1.push_back($3); $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr: expr3 { $$ = $1; }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr3: expr2 { $$ = $1; }
|
|
||||||
| "[" lambdaArgs "]" "->" expr { $$ = nullptr; }
|
|
||||||
| "{" blockStmts "}" { $$ = new ast::BlockExpr($2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr2: expr1 { $$ = $1; }
|
|
||||||
| expr2 operator expr1 { $$ = new ast::BinExpr($1, $2, $3); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr1: expr0 { $$ = $1; }
|
|
||||||
| operator expr1 { $$ = new ast::UnaryExpr($1, $2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr0: literal { $$ = $1; }
|
|
||||||
| identifier { $$ = new ast::Identifier($1); }
|
|
||||||
| expr0 "[" args "]" { $$ = new ast::CallExpr($1, $3); }
|
|
||||||
| "(" expr ")" { $$ = new ast::PrefExpr($2); }
|
|
||||||
| expr0 "." identifier { $$ = $1; }
|
|
||||||
;
|
|
||||||
|
|
||||||
lambdaArgs: %empty { ; }
|
|
||||||
| identifiers { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
args: %empty { ; }
|
|
||||||
| exprs { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
literal: INT { $$ = new ast::IntValue($1); }
|
|
||||||
| FLOAT { $$ = new ast::FloatValue($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
operator: "->"
|
|
||||||
| "="
|
|
||||||
| OPERATOR
|
|
||||||
;
|
|
||||||
|
|
||||||
identifiers: identifier { $$.push_back($1); }
|
|
||||||
| identifiers "," identifier { $1.push_back($3); $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
identifier: keyword
|
|
||||||
| IDENTIFIER
|
|
||||||
;
|
|
||||||
|
|
||||||
keyword: FN
|
|
||||||
| VAL
|
|
||||||
| UNOP
|
|
||||||
| BINOP
|
|
||||||
| IMPORT
|
|
||||||
| DECLARE
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void yy::parser::error(const location_type& l, const std::string& m) {
|
|
||||||
std::cerr << l << ": " << m << '\n';
|
|
||||||
}
|
|
78
compiler/plsm.g4
Normal file
78
compiler/plsm.g4
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
grammar plsm;
|
||||||
|
|
||||||
|
module: moduleImport* (let | fnDecl | fnDef | traitDef | typeDef)*;
|
||||||
|
|
||||||
|
moduleImport: IMPORT moduleName ';';
|
||||||
|
moduleName: identifier ('.' identifier)*;
|
||||||
|
|
||||||
|
traitDef: TRAIT identifier '=' identifier ';'
|
||||||
|
| TRAIT identifier '=' '{' (fnDecl)* '}' ';';
|
||||||
|
|
||||||
|
typeDef: TYPE identifier '=' type ';'
|
||||||
|
| TYPE identifier '=' ('(' fnDefArgs ')')? '{' (fnDecl | fnDef)* '}' ';';
|
||||||
|
|
||||||
|
fnDef: FN identifier '[' fnDefArgs? ']' type '=' expr ';';
|
||||||
|
fnDefArgs: identifier type (',' identifier type)*;
|
||||||
|
|
||||||
|
fnDecl: FN identifier '[' fnDeclArgs? ']' type ';';
|
||||||
|
fnDeclArgs: identifier? type (',' identifier? type)*;
|
||||||
|
|
||||||
|
let: LET identifier type? '=' expr ';';
|
||||||
|
|
||||||
|
exprStmt: expr ';';
|
||||||
|
|
||||||
|
type: type2;
|
||||||
|
type2: type1
|
||||||
|
| '(' type ')'
|
||||||
|
| '(' tupleTypeList ')' // tuple
|
||||||
|
| '[' typeList? ']' '->' type; // closure
|
||||||
|
type1: type0
|
||||||
|
| type0 '{' typeList '}'; // generic
|
||||||
|
type0: identifier;
|
||||||
|
|
||||||
|
tupleTypeList: type ',' type (',' type)*;
|
||||||
|
typeList: type (',' type)*;
|
||||||
|
|
||||||
|
|
||||||
|
expr: expr3;
|
||||||
|
expr3: expr2
|
||||||
|
| '[' identifierList? ']' '->' expr // closure
|
||||||
|
| '{' (let | exprStmt | fnDef)* (expr ';') '}';
|
||||||
|
expr2: expr1
|
||||||
|
| expr2 operator expr1; // binary expr
|
||||||
|
expr1: expr0
|
||||||
|
| operator expr0; // unary expr
|
||||||
|
expr0: literal
|
||||||
|
| identifier
|
||||||
|
| expr0 '[' exprList? ']' // fn call
|
||||||
|
| '(' expr ')'
|
||||||
|
| expr0 '.' identifier; // property accessor
|
||||||
|
|
||||||
|
exprList: expr (',' expr)*;
|
||||||
|
|
||||||
|
identifierList: identifier (',' identifier)*;
|
||||||
|
|
||||||
|
literal: 'null' | INT_LIT | FLOAT_LIT;
|
||||||
|
|
||||||
|
operator: '=' | '->'
|
||||||
|
| OPERATOR;
|
||||||
|
|
||||||
|
identifier: keyword | IDENTIFIER;
|
||||||
|
keyword: BINOP | FN | IMPORT | LET | NATIVE | TRAIT | TYPE | UNOP;
|
||||||
|
|
||||||
|
|
||||||
|
INT_LIT: [0-9]+ | '0x' [0-9a-fA-F]+ | '0o' [0-7]+ | '0b' [01]+;
|
||||||
|
FLOAT_LIT: [0-9]+ '.' | [0-9]* '.' [0-9]+;
|
||||||
|
|
||||||
|
OPERATOR: ('+'|'-'|'*'|'/'|'%'|'!'|'&'|'$'|'§'|'|'|'='|'<'|'>'|'?'|'~'|'#'|':'|'^'|'\\'|'.')+;
|
||||||
|
|
||||||
|
BINOP: 'binop';
|
||||||
|
FN: 'fn';
|
||||||
|
IMPORT: 'import';
|
||||||
|
LET: 'let';
|
||||||
|
NATIVE: 'native';
|
||||||
|
TRAIT: 'trait';
|
||||||
|
TYPE: 'type';
|
||||||
|
UNOP: 'unop';
|
||||||
|
|
||||||
|
IDENTIFIER: [a-zA-Z_] [a-zA-Z0-9_]*;
|
@ -1,20 +1,131 @@
|
|||||||
#include "Parser.h"
|
#include "Parser.h"
|
||||||
|
|
||||||
|
#include "plsmBaseVisitor.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
void yy_scan_string(const char *);
|
class Visitor : public plsmBaseVisitor
|
||||||
|
|
||||||
ast::Module *Parser::parse(const std::string &file, const std::stringstream &input)
|
|
||||||
{
|
{
|
||||||
module = nullptr;
|
public:
|
||||||
|
Visitor() {}
|
||||||
|
|
||||||
this->file = file;
|
template <typename T>
|
||||||
location.initialize(&file);
|
inline T visitT(antlr4::tree::ParseTree *ctx)
|
||||||
|
{
|
||||||
yy_scan_string(input.str().data());
|
return std::any_cast<T>(visit(ctx));
|
||||||
|
}
|
||||||
int res = yy::parser(*this)();
|
|
||||||
|
template <typename T>
|
||||||
return module;
|
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
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
ss << "line " << line << ":" << charPositionInLine << ": " << msg;
|
||||||
|
*error = ss.str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<ast::Module>
|
||||||
|
plsm::parse(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(&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().visitModule(tree));
|
||||||
|
return std::unique_ptr<ast::Module>(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ast::Module>
|
||||||
|
adscript::parse(const std::string &input)
|
||||||
|
{
|
||||||
|
throw std::logic_error("adscript::parse not implemented");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#include "Parser.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -21,10 +19,10 @@ int main(int argc, char *argv[])
|
|||||||
exit(EXIT_FAILURE);
|
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::FnDecl *)module->stmts.at(0);
|
||||||
std::cout << fn->name << std::endl;
|
// std::cout << fn->name << std::endl;
|
||||||
|
|
||||||
delete module;
|
// delete module;
|
||||||
}
|
}
|
||||||
|
BIN
compiler/thirdparty/antlr-4.13.1-complete.jar
vendored
Normal file
BIN
compiler/thirdparty/antlr-4.13.1-complete.jar
vendored
Normal file
Binary file not shown.
@ -1,33 +1,38 @@
|
|||||||
type Bool = {
|
type Bool = {
|
||||||
declare unop ! Bool;
|
native unop ! Bool;
|
||||||
|
|
||||||
declare binop &&[b Bool] Bool;
|
native binop ||[Bool] Bool;
|
||||||
declare binop ||[b Bool] Bool;
|
native binop &&[Bool] Bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type Byte = {};
|
||||||
|
|
||||||
type Int = {
|
type Int = {
|
||||||
declare unop + Int;
|
native unop + Int;
|
||||||
declare unop - Int;
|
native unop - Int;
|
||||||
|
native unop ~ Int;
|
||||||
|
|
||||||
declare binop ==[Int] Bool;
|
native binop ==[Int] Bool;
|
||||||
declare binop !=[Int] Bool;
|
native binop !=[Int] Bool;
|
||||||
declare binop >[Int] Bool;
|
native binop >[Int] Bool;
|
||||||
declare binop <[Int] Bool;
|
native binop <[Int] Bool;
|
||||||
declare binop >=[Int] Bool;
|
native binop >=[Int] Bool;
|
||||||
declare binop <=[Int] Bool;
|
native binop <=[Int] Bool;
|
||||||
|
|
||||||
declare binop +[Int] Int;
|
native binop <<[Int] Int;
|
||||||
declare binop -[Int] Int;
|
native binop >>[Int] Int;
|
||||||
declare binop *[Int] Int;
|
native binop |[Int] Int;
|
||||||
declare binop /[Int] Int;
|
native binop &[Int] Int;
|
||||||
declare binop %[Int] Int;
|
|
||||||
|
|
||||||
declare factory [f Float];
|
native binop +[Int] Int;
|
||||||
declare factory [];
|
native binop -[Int] Int;
|
||||||
|
native binop *[Int] Int;
|
||||||
|
native binop /[Int] Int;
|
||||||
|
native binop %[Int] Int;
|
||||||
|
|
||||||
declare fn str[] String;
|
fn str[] String;
|
||||||
};
|
};
|
||||||
|
|
||||||
trait List{T} = {
|
type Float = {
|
||||||
fn
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user