AST building #2

Merged
TopchetoEU merged 74 commits from TopchetoEU/ast-building into master 2022-10-28 11:58:03 +00:00
12 changed files with 103 additions and 38 deletions
Showing only changes of commit 0a68529c3b - Show all commits

1
.gitignore vendored
View File

@ -23,6 +23,7 @@
!scripts
!scripts/common.mak
!scripts/lsproj.mak
!scripts/install.bat
!scripts/uninstall.bat

View File

@ -1,4 +1,4 @@
export MAKEFLAGS += --silent -r
export MAKEFLAGS += --silent -r -j
export flags=-std=c++17 -Wall -Wno-main -Wno-trigraphs -Wno-missing-braces -Wno-stringop-overflow
export ldflags=-L$(bin)/$(profile)
export lib=ppc$(version-major)-
@ -51,7 +51,7 @@ build: version
make -f scripts/common.mak
if exist "$(subst /,\,$(bin)\$(output).exe)" del "$(subst /,\,$(bin)\$(output).exe)"
mklink /H "$(subst /,\,$(bin)\$(output).exe)" "$(subst /,\,$(binary))" > NUL
echo Done!
clear:
if exist $(subst /,\,$(oldbin)) rmdir /s /q $(subst /,\,$(oldbin))

View File

@ -10,6 +10,7 @@
using namespace std::string_literals;
using namespace ppc;
using namespace ppc::lang;
using namespace ppc::messages;
namespace ppc::comp::tree::ast {
@ -42,6 +43,8 @@ namespace ppc::comp::tree::ast {
public:
msg_stack_t &messages;
std::vector<token_t> &tokens;
std::set<lang::namespace_name_t> imports;
located_t<namespace_name_t> nmsp;
void add_parser(std::string name, parser_t &parser);
void add_parser(std::string name, group_parser_t &parser);
@ -57,10 +60,7 @@ namespace ppc::comp::tree::ast {
};
class parser_t {
private:
std::string _name;
public:
const std::string &name() { return _name; }
virtual bool parse(ast_ctx_t &ctx, size_t &res_i, data::map_t &out) const = 0;
bool operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const {
return parse(ctx, i, out);

View File

@ -5,14 +5,19 @@ namespace ppc::comp::tree::ast {
private:
ast_ctx_t &ctx;
size_t &res_i;
size_t i;
void throw_ended() {
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end.", loc());
}
void throw_ended(const std::string &reason) {
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end: " + reason, loc());
}
public:
void submit() {
size_t i;
bool submit() {
res_i = i;
return true;
}
bool ended() {
@ -83,6 +88,11 @@ namespace ppc::comp::tree::ast {
i++;
throw_ended();
}
void advance(const std::string &reason) {
throw_ended(reason);
i++;
throw_ended(reason);
}
tree_helper_t(ast_ctx_t &ctx, size_t &i): ctx(ctx), res_i(i) {
this->i = i;

View File

@ -8,10 +8,9 @@ namespace ppc::lang {
struct located_t : T {
location_t location;
template <class ...Args>
located_t(location_t loc, Args ...args): T(args...), location(loc) { }
template <class ...Args>
located_t(Args ...args): T(args...), location(location_t::NONE) { }
located_t(location_t loc, const T &val): T(val), location(loc) { }
located_t(const T &val): T(val), location(location_t::NONE) { }
located_t() { }
};
struct namespace_name_t : public std::vector<std::string> {

View File

@ -17,7 +17,7 @@ namespace ppc::messages {
std::string content;
location_t location;
message_t(level_t level, std::string content, location_t loc = location_t::NONE) :
message_t(level_t level, const std::string &content, location_t loc = location_t::NONE) :
level(level),
content(content),
location(loc) { }
@ -25,6 +25,8 @@ namespace ppc::messages {
std::string to_string() const;
bool is_severe() const;
static message_t error(const std::string &message, location_t loc = location_t::NONE) { return message_t(ERROR, message, loc); }
};
struct msg_stack_t {

View File

@ -1,14 +1,16 @@
export lsproj = $(bin)/lsproj$(exe)
export flags += "-I$(inc)" -D$(OS) -DPPC_VERSION_MAJOR=$(version-major) -DPPC_VERSION_MINOR=$(version-minor) -DPPC_VERSION_BUILD=$(version-build)
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
rwildcard=$(foreach d, $(wildcard $(1:=/*)),\
$(call rwildcard,$d,$2)\
$(filter $(subst *,%,$2),$d)\
)
uniq=$(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
modoutput=$(shell ./$(lsproj) $(src) $1 output)
deps=$(strip \
$(foreach dep, $(shell ./$(lsproj) $(src) $1 deps),\
$(if $(wildcard src/$(dep)),\
$(dep),\
$(if $(wildcard src/$(dep)), $(dep),\
$(error The module '$(dep)' (dependency of '$1') doesn't exist)\
)\
)\
@ -29,15 +31,14 @@ lrdeps=$(foreach dep,$(call rdeps,$1),-l$(lib)$(call modoutput,$(dep)))
modules = $(patsubst $(src)/%/,$(bin)/lib$(lib)%$(so),$(filter-out $(src)/$(mainmodule)/,$(wildcard $(src)/*/)))
sources = $(call rwildcard,$(src)/$1,*.cc)
headers = $(call rwildcard,$(inc),*.h)
binaries = $(patsubst $(src)/%.cc,$(bin)/%.o,$(call sources,$1))
binaries = $(patsubst $(src)/%.cc,$(bin)/tmp/%.o,$(call sources,$1))
ifneq ($(nolsproj),yes)
$(shell make -f scripts/lsproj.mak $(lsproj))
$(shell make -f scripts/lsproj.mak lsproj=$(lsproj) src=$(src) $(lsproj))
endif
.PHONY: build
.PRECIOUS: $(bin)/%.o
.PRECIOUS: $(bin)/tmp/%.o
build: $(binary)
@ -53,7 +54,7 @@ $(bin)/lib$(lib)%$(so): $$(call frdeps,$$*) $$(call binaries,$$*)
echo Compiling library '$(notdir $@)'...
$(CXX) -shared -fPIC $(flags) $(call binaries,$*) -o $@ $(ldflags) $(call ldeps,$*) -L$(bin) "-I$(inc)"
$(bin)/%.o: $(src)/%.cc $(headers)
$(bin)/tmp/%.o: $(src)/%.cc $(headers)
echo - Compiling '$*.cc'...
$(call mkdir,$(dir $@))
$(CXX) -fPIC -c $(flags) $< -o $@

View File

@ -1,9 +1,59 @@
#include "compiler/treeifier/ast.hh"
#include "compiler/treeifier/ast/helper.hh"
namespace ppc::comp::tree::ast {
class glob_parser_t : public parser_t {
bool parse_nmsp(ast_ctx_t &ctx, size_t &res_i, located_t<namespace_name_t> &out) const {
tree_helper_t h(ctx, res_i);
located_t<namespace_name_t> res;
while (true) {
auto &curr = h.curr();
if (h.ended() || !curr.is_identifier()) return false;
else res.push_back(curr.identifier());
if (!h.try_advance() || !h.curr().is_operator(operator_t::DOUBLE_COLON)) {
out = res;
return h.submit();
}
}
}
bool parse_nmsp_def(ast_ctx_t &ctx, size_t &res_i) const {
tree_helper_t h(ctx, res_i);
if (h.ended()) return true;
if (h.curr().is_identifier("namespace")) {
h.advance("Expected a namespace name.");
if (!parse_nmsp(ctx, h.i, ctx.nmsp)) throw message_t::error("Expected a namespace name.", h.loc());
return h.submit();
}
else return false;
}
bool parse_import(ast_ctx_t &ctx, size_t &res_i) const {
tree_helper_t h(ctx, res_i);
if (h.ended()) return true;
if (h.curr().is_identifier("import")) {
h.advance("Expected a namespace name.");
located_t<namespace_name_t> name;
if (!parse_nmsp(ctx, h.i, name)) throw message_t::error("Expected a namespace name.", h.loc());
if (!ctx.imports.emplace(name).second) {
throw message_t::error("The namespace '" + name.to_string() + "' is already imported.", h.loc());
}
return h.submit();
}
else return false;
}
bool parse(ast_ctx_t &ctx, size_t &res_i, data::map_t &out) const {
return false;
tree_helper_t h(ctx, res_i);
if (h.ended()) return true;
parse_nmsp_def(ctx, h.i);
while (parse_import(ctx, h.i));
return true;
}
};

View File

@ -41,12 +41,14 @@ bool group_parser_t::parse(ast_ctx_t &ctx, size_t &i, data::map_t &out) const {
try {
return h.parse(*parser, out);
}
catch (std::string) {
catch (const message_t &err) {
ctx.messages.push(err);
return false;
}
}
}
return false;
}
group_parser_t &group_parser_t::add(parser_t &parser) {
parsers.push_back(&parser);

View File

@ -52,7 +52,7 @@ static std::vector<char> parse_string(msg_stack_t &msg_stack, bool is_char, lex:
if (is_char) throw message_t(message_t::ERROR, "Unterminated char literal.", token.location);
else throw message_t(message_t::ERROR, "Unterminated string literal.", token.location);
}
static tok::token_t parse_int(msg_stack_t &msg_stack, lex::token_t token) {
static token_t parse_int(msg_stack_t &msg_stack, lex::token_t token) {
enum radix_t {
BINARY,
OCTAL,
@ -119,9 +119,9 @@ static tok::token_t parse_int(msg_stack_t &msg_stack, lex::token_t token) {
}
}
return tok::token_t(res, token.location);
return token_t(res, token.location);
}
static tok::token_t parse_float(msg_stack_t &msg_stack, lex::token_t token) {
static token_t parse_float(msg_stack_t &msg_stack, lex::token_t token) {
double whole = 0, fract = 0;
char c;
@ -143,16 +143,16 @@ static tok::token_t parse_float(msg_stack_t &msg_stack, lex::token_t token) {
}
}
return tok::token_t(whole + fract, token.location);
return token_t(whole + fract, token.location);
}
tok::token_t tok::token_t::parse(messages::msg_stack_t &msg_stack, lex::token_t in) {
token_t token_t::parse(messages::msg_stack_t &msg_stack, lex::token_t in) {
switch (in.type) {
case lex::token_t::IDENTIFIER:
return tok::token_t(in.data, in.location);
return token_t(in.data, in.location);
case lex::token_t::OPERATOR:
try {
auto op = tok::operator_find(in.data);
auto op = operator_find(in.data);
return token_t(op, in.location);
}
catch (std::string &err) {
@ -176,11 +176,11 @@ tok::token_t tok::token_t::parse(messages::msg_stack_t &msg_stack, lex::token_t
throw message_t(message_t::ERROR, "Token type not recognised.", in.location);
}
}
std::vector<tok::token_t> tok::token_t::parse_many(messages::msg_stack_t &msg_stack, std::vector<lex::token_t> tokens) {
std::vector<tok::token_t> res;
std::vector<token_t> token_t::parse_many(messages::msg_stack_t &msg_stack, std::vector<lex::token_t> tokens) {
std::vector<token_t> res;
for (auto &tok : tokens) {
res.push_back(tok::token_t::parse(msg_stack, tok));
res.push_back(token_t::parse(msg_stack, tok));
}
return res;

View File

@ -4,14 +4,14 @@ using namespace ppc;
bool version_t::operator==(version_t other) const {
bool major_same = major == other.major;
bool minor_same = minor == -1 || other.minor == -1 || minor == other.minor;
bool revision_same = revision == -1 || other.revision == -1 || revision == other.revision;
bool minor_same = minor == -1u || other.minor == -1 || minor == other.minor;
bool revision_same = revision == -1u || other.revision == -1u || revision == other.revision;
return major_same && minor_same && revision_same;
}
bool version_t::is_compliant(version_t other) const {
bool major_compliant = major == other.major;
bool minor_compliant = minor == -1 || other.minor == -1 || minor <= other.minor;
bool minor_compliant = minor == -1u || other.minor == -1u || minor <= other.minor;
return major_compliant && minor_compliant;
}

View File

@ -152,11 +152,11 @@ int main(int argc, const char *argv[]) {
for (const auto &file : files) {
std::ifstream f { file, std::ios_base::in };
try {
auto res = tok::token_t::parse_many(msg_stack, lex::token_t::parse_file(msg_stack, file, f));
auto res = token_t::parse_many(msg_stack, lex::token_t::parse_file(msg_stack, file, f));
for (auto tok : res) {
if (tok.is_identifier()) std::cout << "Identifier: \t" << tok.identifier();
if (tok.is_operator()) std::cout << "Operator: \t" << tok::operator_stringify(tok._operator());
if (tok.is_operator()) std::cout << "Operator: \t" << operator_stringify(tok._operator());
if (tok.is_float_lit()) std::cout << "Float: \t" << tok.float_lit();
if (tok.is_int_lit()) std::cout << "Int: \t" << tok.int_lit();
if (tok.is_char_lit()) std::cout << "Char: \t" << tok.char_lit();