Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved compile time #10

Merged
merged 16 commits into from
Aug 19, 2016
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "include/ict"]
path = include/ict
url = https://github.com/intrig/ict
url = https://github.com/xenon/ict
2 changes: 1 addition & 1 deletion include/ict
Submodule ict updated from 3e2ffc to 662dce
118 changes: 8 additions & 110 deletions include/xenon/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,10 @@ inline int64_t bit_size(message::cursor parent) {

// Create a global prop and set it equal to the given bitstring, or the default given by the spec.
// Precondition: The global does not yet exist.
inline message::cursor create_global(spec::cursor xddl_root, message::cursor globs, const std::string & name,
bitstring bits = bitstring()) {
static auto prop_path = path("export/prop");
auto root = xddl_root;
auto c = find(root, prop_path, tag_of, cmp_name(name));

if (c == root.end()) { // must be an extern
c = find(root, "extern", tag_of, cmp_name(name));
if (c == root.end()) IT_PANIC("internal panic looking for " << name << " in " << xddl_root->parser->file);
}

if (bits.empty()) {
if (auto prop_elem = get_ptr<prop>(c->v)) {
if (!prop_elem) IT_PANIC("internal panic");
auto v = prop_elem->value.value(leaf(globs));
bits = ict::from_integer(v);
}
}
message::cursor create_global(spec::cursor xddl_root, message::cursor globs, const std::string & name,
bitstring bits = bitstring());

return globs.emplace(node::prop_node, c, bits);
}

inline message::cursor set_global(spec::cursor self, message::cursor value) {
auto globs = ict::get_root(value).begin();
auto g = find(globs, value->name());
if (g == globs.end()) g = create_global(get_root(self).begin(), globs, value->name(), value->bits);
else g->bits = value->bits;
return g;
}
message::cursor set_global(spec::cursor self, message::cursor value);

inline message::cursor set_global(spec::cursor self, message::cursor value, spec::cursor elem) {
auto g = set_global(self, value);
Expand All @@ -64,48 +39,10 @@ inline message::cursor set_global(spec::cursor self, message::cursor value, spec
}

// load time
inline spec::cursor get_variable(const std::string & name, spec::cursor context) {
static auto prop_path = path("xddl/export/prop");
static auto extern_path = path("xddl/extern");
spec::ascending_cursor first(context);
while (!first.is_root()) {
if (name == first->name()) return first;
++first;
}
auto root = spec::cursor(first);
auto x = find(root, prop_path, tag_of, cmp_name(name));
if (x != root.end()) return x;

// not found, search for <extern>
// TODO: remove <extern> and just use global, if 2 globals have different defaults, then undefined
// or get rid of global and just use props
auto c = find(root, extern_path, tag_of, cmp_name(name));
if (c != root.end()) return c;

// verify(root);
IT_PANIC("cannot find " << name << " starting at " << context->name());
}
spec::cursor get_variable(const std::string & name, spec::cursor context);

// parse time
inline message::cursor get_variable(const std::string & name, message::cursor context) {
auto first = rfind(context, name);
if (!first.is_root()) return first;

// first is now pointing at message root
auto globs = first.begin();
auto g = find(globs, name);
if (g == globs.end()) {
auto xddl_root = ict::get_root(context->elem).begin();
try {
g = create_global(xddl_root, globs, name);
} catch (std::exception & e) {
ict::osstream os;
os << e.what() << " [" << context->file() << ":" << context->line() << "]";
IT_FATAL(os.str());
}
}
return g;
}
message::cursor get_variable(const std::string & name, message::cursor context);

// load time validation
inline int64_t eval_variable(const std::string &name, spec::cursor context) {
Expand All @@ -117,28 +54,7 @@ inline int64_t eval_variable(const std::string &name, spec::cursor context) {
return 1;
}

inline int64_t eval_variable_list(const std::string &first, const std::string &second, spec::cursor context) {
auto f = get_variable(first, context);
auto s = find(f, second);
if (s == f.end()) { // second not found, it may be in another spec though (f may be a reclink)
// f is a reclink, so get the record it is pointing to.
if (auto r = get_ptr<reclink>(f->v)) {
auto xddl = rfind(context, "xddl", tag_of);
auto c = find(xddl, "record", tag_of, [&](const element &e) {
if (auto rec = get_ptr<recdef>(e.v)) {
if (rec->id == r->href) return 1;
}
return 0;
});
if (c == xddl.end()) IT_PANIC("cannot find record: " << r->href);
s = find(c, second);
if (s == c.end()) IT_PANIC("cannot find " << second << " in " << r->href);
}
}
s->flags.set(element::dependent_flag);
return 1;
}

int64_t eval_variable_list(const std::string &first, const std::string &second, spec::cursor context);

// TODO: move this one to spec.h, otherwise loading a doc is dependent on message.h
inline int64_t eval_function(const std::string &name, spec::cursor,
Expand All @@ -161,26 +77,8 @@ inline int64_t eval_variable_list(const std::string &first, const std::string &s
return ict::to_integer<int64_t>(s->bits);
}

inline int64_t eval_function(const std::string &name, message::cursor context,
const std::vector<ict::expression::param_type> &params) {
if (name == "sizeof") {
auto c = get_variable(params[0].name, context);
return bit_size(c);
}
else if ((name == "defined")) {
if (rfind(context, params[0].name).is_root()) return 0;
return 1;
}

else if ((name == "value")) {
auto c = rfind(context, params[0].name);
if (!c.is_root()) return c->value();
IT_WARN("cannot find " << params[0].name);
return 0;
}

IT_PANIC("runtime eval_function not implemented for " << name);
}
int64_t eval_function(const std::string &name, message::cursor context,
const std::vector<ict::expression::param_type> &params);

template <typename S, typename C>
inline void description_xml(S & os, C c) {
Expand Down
39 changes: 33 additions & 6 deletions include/xenon/xddl_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//-- Copyright 2016 Intrig
//-- See https://github.com/intrig/xenon for license.
#include <xenon/xml_parser_base.h>
#include <ict/osstream.h>

#include <stack>
#include <map>
Expand All @@ -12,11 +13,12 @@ namespace xenon {
class XmlText
{
public:
XmlText(std::string const & s) : content(s) { }
explicit XmlText(std::string const & s) : content(s) { }
std::string content;
};

inline std::ostream & operator<<(std::ostream & os, XmlText const & cd)
template <typename S>
inline S & to_stream(S & os, XmlText const & cd)
{
std::string::const_iterator it;
for (it=cd.content.begin(); it!= cd.content.end(); ++it)
Expand All @@ -35,6 +37,16 @@ namespace xenon {
return os;
}

template <typename S>
inline S & operator<<(S & os, XmlText const & cd) {
return to_stream(os, cd);
}

inline ict::osstream & operator<<(ict::osstream & os, XmlText const & cd) {
return to_stream(os, cd);
}


typedef std::pair<std::string, std::string> attpair;

class XmlAttribute
Expand All @@ -45,7 +57,7 @@ namespace xenon {
};

template <typename S>
inline S & operator<<(S & os, XmlAttribute const & cd) {
inline S & to_stream(S & os, XmlAttribute const & cd) {
for (auto it=cd.content.begin(); it!= cd.content.end(); ++it)
{
switch (*it)
Expand All @@ -61,6 +73,14 @@ namespace xenon {
}
return os;
}
template <typename S>
inline S & operator<<(S & os, XmlAttribute const & cd) {
return to_stream(os, cd);
}

inline ict::osstream & operator<<(ict::osstream & os, XmlAttribute const & cd) {
return to_stream(os, cd);
}

template <typename Stream>
class Xml : public xml_parser_base {
Expand Down Expand Up @@ -151,7 +171,7 @@ namespace xenon {
//std::sort(attvec.begin(), attvec.end(), AttCompare());
my_sort(attvec);

std::ostringstream os;
ict::osstream os;

std::vector<attpair>::iterator it;
for (it=attvec.begin(); it!=attvec.end(); ++it)
Expand Down Expand Up @@ -215,11 +235,18 @@ namespace xenon {

std::string str()
{
std::ostringstream ss;
ict::osstream ss;
str(ss);
return ss.str();
}

template <typename S>
void to_stream(S & os) {
str(os);
}



std::string raw()
{
return _code;
Expand Down Expand Up @@ -363,5 +390,5 @@ namespace xenon {
std::stack<std::shared_ptr<XmlElement>> elements;
};

using xml_type = Xml<std::ostream>;
using xml_type = Xml<ict::osstream>;
}
11 changes: 2 additions & 9 deletions include/xenon/xenon.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <xenon/recref.h>
#include <xenon/message.h>
#include <xenon/spec_server.h>
#include <ict/bitstring.h>
namespace xenon {
inline ict::bitstring serialize(const message & m) {
ict::obitstream bs;
Expand All @@ -15,18 +16,10 @@ inline ict::bitstring serialize(const message & m) {
return bs.bits();
}

inline ict::bitstring random_bitstring(size_t bit_len) {
std::random_device engine;
auto bytes = bit_len / 8 + 1;
auto v = std::vector<unsigned char>(bytes);
for (auto & b : v) b = engine();
return ict::bitstring(v.begin(), bit_len);
}

template <typename Message>
inline void recombobulate(Message & a) {
ict::recurse(a.root(), [&](message::cursor c, message::cursor) {
if (c->is_pof()) c->bits = random_bitstring(c->bits.bit_size());
if (c->is_pof()) c->bits = ict::random_bitstring(c->bits.bit_size());
});
}

Expand Down
2 changes: 1 addition & 1 deletion include/xenon/ximsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace util {

auto nvar = ict::netvar<uint16_t>(D);

auto bs = bitstring((const char *) nvar.data.data(), 16);
auto bs = bitstring(bit_iterator(nvar.data.data()), 16);
bs.remove(0, 6);

return bs;
Expand Down
7 changes: 4 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ include_directories(lua-5.1.4/src)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/o)

add_custom_command(
OUTPUT ${CMAKE_SOURCE_DIR}/include/xenon/xddl.h
COMMAND xspx ${CMAKE_CURRENT_SOURCE_DIR}/xddl.xspx > t
OUTPUT ${CMAKE_SOURCE_DIR}/include/xenon/xddl.h ${CMAKE_SOURCE_DIR}/src/xddl_impl.cpp
COMMAND xspx -H t -S xddl_impl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xddl.xspx
COMMAND ${CMAKE_COMMAND} -E copy_if_different t ${CMAKE_SOURCE_DIR}/include/xenon/xddl.h
COMMAND ${CMAKE_COMMAND} -E copy_if_different xddl_impl.cpp ${CMAKE_SOURCE_DIR}/src/xddl_impl.cpp
DEPENDS xspx
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/xddl.xspx
VERBATIM)

add_library(xenon ${CMAKE_SOURCE_DIR}/include/xenon/xddl.h lua-5.1.4/src/lua_all.cpp xml_parser_base.cpp message.cpp xddl.cpp)
add_library(xenon ${CMAKE_SOURCE_DIR}/include/xenon/xddl.h lua-5.1.4/src/lua_all.cpp xml_parser_base.cpp message.cpp xddl.cpp xddl_impl.cpp)

set_target_properties(xenon PROPERTIES POSITION_INDEPENDENT_CODE ON)
Loading