From 129e7c0d3e91ee3fdf6835464bf8ec97f2ffc9a5 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 23 Mar 2019 16:07:27 +0800 Subject: Tools - add a hacky crate metadata dump tool (macros only currently) --- tools/dump_hirfile/Makefile | 56 +++++++++++++++++++ tools/dump_hirfile/main.cpp | 128 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 tools/dump_hirfile/Makefile create mode 100644 tools/dump_hirfile/main.cpp diff --git a/tools/dump_hirfile/Makefile b/tools/dump_hirfile/Makefile new file mode 100644 index 00000000..10fb8e81 --- /dev/null +++ b/tools/dump_hirfile/Makefile @@ -0,0 +1,56 @@ +# +ifeq ($(OS),Windows_NT) + EXESUF ?= .exe +endif +EXESUF ?= + +V ?= @ + +OBJDIR := .obj/ + +BIN := ../bin/dump_hirfile$(EXESUF) +OBJS := main.o +OBJS += debug.o rc_string.o span.o ident.o +OBJS += parse/parseerror.o # Why is this needed? ast/path.cpp uses it in binding +OBJS += hir/hir.o hir/type.o hir/deserialise.o hir/serialise_lowlevel.o +OBJS += hir/crate_ptr.o hir/generic_params.o hir/path.o hir/pattern.o hir/expr_ptr.o +OBJS += hir/expr.o # Why is this needed? +OBJS += parse/token.o parse/tokentree.o parse/tokenstream.o +OBJS += ast/ast.o ast/expr.o ast/path.o ast/types.o ast/pattern.o +OBJS += mir/mir.o mir/mir_ptr.o +OBJS += macro_rules/mod.o + +LINKFLAGS := -g -lpthread -lz +CXXFLAGS := -Wall -std=c++14 -g -O2 +CXXFLAGS += -I ../common -I ../../src -I ../../src/include + +OBJS := $(OBJS:%=$(OBJDIR)%) + +.PHONY: all clean + +all: $(BIN) + +clean: + rm $(BIN) $(OBJS) + +$(BIN): $(OBJS) ../bin/common_lib.a + @mkdir -p $(dir $@) + @echo [CXX] -o $@ + $V$(CXX) -o $@ $(OBJS) ../bin/common_lib.a $(LINKFLAGS) + +$(OBJDIR)%.o: %.cpp + @mkdir -p $(dir $@) + @echo [CXX] $< + $V$(CXX) -o $@ -c $< $(CXXFLAGS) -MMD -MP -MF $@.dep + +$(OBJDIR)%.o: ../../src/%.cpp + @mkdir -p $(dir $@) + @echo [CXX] $< + $V$(CXX) -o $@ -c $< $(CXXFLAGS) -MMD -MP -MF $@.dep + +../bin/common_lib.a: $(wildcard ../common/*.* ../common/Makefile) + make -C ../common + +-include $(OBJS:%.o=%.o.dep) + + diff --git a/tools/dump_hirfile/main.cpp b/tools/dump_hirfile/main.cpp new file mode 100644 index 00000000..df3e48df --- /dev/null +++ b/tools/dump_hirfile/main.cpp @@ -0,0 +1,128 @@ +#include +#include +#include + +int g_debug_indent_level = 0; + +struct Args +{ + Args(int argc, const char* const argv[]); + + ::std::string infile; +}; + +int main(int argc, const char* argv[]) +{ + Args args(argc, argv); + + auto hir = HIR_Deserialise(args.infile, ""); + + // Dump macros + for(const auto& mac : hir->m_exported_macros) + { + ::std::cout << "macro_rules! " << mac.first << "{" << std::endl; + for(const auto& arm : mac.second->m_rules) + { + ::std::cout << " ("; + for(const auto& pat : arm.m_pattern) + { + TU_MATCH_HDRA( (pat), {) + TU_ARMA(End, e) + ::std::cout << " EOS"; + TU_ARMA(LoopStart, e) + ::std::cout << " ("; + TU_ARMA(LoopNext, e) + ::std::cout << " ^"; + TU_ARMA(LoopEnd, e) + ::std::cout << " )"; + TU_ARMA(Jump, e) + ::std::cout << " <" << e.jump_target; + TU_ARMA(ExpectTok, e) + ::std::cout << " =" << e; + TU_ARMA(ExpectPat, e) + ::std::cout << " " << e.idx << "=" << e.type; + TU_ARMA(If, e) { + ::std::cout << " ?" << (e.is_equal ? "" : "!") << "{"; + for(const auto& ent : e.ents) { + if(ent.ty == MacroPatEnt::PAT_TOKEN) + ::std::cout << " =" << ent.tok; + else + ::std::cout << " " << ent.ty; + } + ::std::cout << "}->" << e.jump_target; + } + } + } + ::std::cout << " ) => {" << ::std::endl; + // TODO... + ::std::cout << " }" << ::std::endl; + } + ::std::cout << "}" << ::std::endl; + ::std::cout << ::std::endl; + } +} + +bool debug_enabled() +{ + return false; +} +::std::ostream& debug_output(int indent, const char* function) +{ + return ::std::cout << "- " << RepeatLitStr { " ", indent } << function << ": "; +} + +Args::Args(int argc, const char* const argv[]) +{ + this->infile = argv[1]; +} + +// TODO: This is copy-pasted from src/main.cpp, should live somewhere better +::std::ostream& operator<<(::std::ostream& os, const FmtEscaped& x) +{ + os << ::std::hex; + for(auto s = x.s; *s != '\0'; s ++) + { + switch(*s) + { + case '\0': os << "\\0"; break; + case '\n': os << "\\n"; break; + case '\\': os << "\\\\"; break; + case '"': os << "\\\""; break; + default: + uint8_t v = *s; + if( v < 0x80 ) + { + if( v < ' ' || v > 0x7F ) + os << "\\u{" << ::std::hex << (unsigned int)v << "}"; + else + os << v; + } + else if( v < 0xC0 ) + ; + else if( v < 0xE0 ) + { + uint32_t val = (uint32_t)(v & 0x1F) << 6; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 6; + os << "\\u{" << ::std::hex << val << "}"; + } + else if( v < 0xF0 ) + { + uint32_t val = (uint32_t)(v & 0x0F) << 12; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 12; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 6; + os << "\\u{" << ::std::hex << val << "}"; + } + else if( v < 0xF8 ) + { + uint32_t val = (uint32_t)(v & 0x07) << 18; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 18; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 12; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 6; + os << "\\u{" << ::std::hex << val << "}"; + } + break; + } + } + os << ::std::dec; + return os; +} -- cgit v1.2.3