a lot.
This commit is contained in:
parent
9890630b79
commit
0a68529c3b
1
.gitignore
vendored
1
.gitignore
vendored
@ -23,6 +23,7 @@
|
||||
|
||||
!scripts
|
||||
!scripts/common.mak
|
||||
!scripts/lsproj.mak
|
||||
!scripts/install.bat
|
||||
!scripts/uninstall.bat
|
||||
|
||||
|
4
Makefile
4
Makefile
@ -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))
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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> {
|
||||
|
@ -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 {
|
||||
|
@ -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 $@
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user