switching to ANTLR

This commit is contained in:
Ludwig Lehnert 2024-02-28 21:16:05 +01:00
parent 99ac38be63
commit f45adb1810
38 changed files with 489 additions and 646 deletions

9
compiler/.gitignore vendored
View File

@ -1 +1,8 @@
*.gen.* # antlr
.antlr/
*.interp
*.tokens
# antlr-generated files
plsm*.h
plsm*.cpp

View File

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

View File

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

@ -0,0 +1,8 @@
grammar adscript;
module:;
// TODO ;)
FN: 'fn';
TYPE: 'type';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

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

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

View File

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

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
View 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_]*;

View File

@ -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)
{
return std::any_cast<T>(visit(ctx));
}
yy_scan_string(input.str().data()); template <typename T>
inline std::unique_ptr<T> visitU(antlr4::tree::ParseTree *ctx)
{
return std::unique_ptr<T>(visitT<T *>(ctx));
}
int res = yy::parser(*this)(); virtual std::any visitModule(plsmParser::ModuleContext *ctx) override
{
std::vector<std::unique_ptr<ast::Import>> imports;
std::vector<std::unique_ptr<ast::Stmt>> stmts;
return module; 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");
} }

View File

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

Binary file not shown.

View File

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