lithe now retains the source range for parsed nodes
2 files changed, 45 insertions(+), 6 deletions(-)

M ast.h
M lithe.cpp
M ast.h +6 -0
@@ 13,6 13,12 @@ namespace lithe {
 		node(const char *strbeg = nullptr, const char *strend = nullptr) :strbeg(strbeg), strend(strend) {}
 		const char *strbeg;
 		const char *strend;
+
+		const char* src_begin{ nullptr };
+		const char* src_end{ nullptr };
+#define LITHE_EXTENT_BEGIN(n, p) (n).src_begin = p;
+#define LITHE_EXTENT_END(n, p) (n).src_end = p;
+
 		std::vector<node> children;
 
 		std::string get_string() const;

          
M lithe.cpp +39 -6
@@ 47,9 47,13 @@ namespace lithe {
 			node operator()(cursor& current, cursor limit)  const override {
 				cursor start = current;
 				node tmp;
+				LITHE_EXTENT_BEGIN(tmp, current)
 				for (auto o : table[(unsigned char)*current]) {
 					tmp = (*o)(current, limit);
-					if (!tmp.is_error() || tmp.is_fatal()) return tmp;
+					if (!tmp.is_error() || tmp.is_fatal()) {
+						LITHE_EXTENT_END(tmp,current);
+						return tmp;
+					}
 					current = start;
 				}
 				return node::error(this, current, tmp);

          
@@ 142,6 146,7 @@ namespace lithe {
 			node complex_seq(cursor& current, cursor limit, node result, size_t i) const {
 				for (;i < sequence.size();++i) {
 					node tmp = (*sequence[i])(current, limit);
+					LITHE_EXTENT_END(result,current);
 					if (tmp.is_error()) {
 						if (tmp.is_fatal()) return tmp;
 						else return node::error(this, current, tmp);

          
@@ 153,19 158,24 @@ namespace lithe {
 
 			node operator()(cursor& current, cursor limit)  const override {
 				assert(!sequence.empty());
+				auto beg = current;
 				size_t i = 0;
 				node str;
 				while (i < sequence.size()) {
 					str = (*sequence[i++])(current, limit);
 					if (str.is_error()) {
-						if (str.is_fatal()) return str;
-						else return node::error(this, current, str);
+						if (str.is_fatal()) {
+							return str;
+						} else {
+							return node::error(this, current, str);
+						}
 					}
 					if (str.strbeg || str.children.size()) break;
 				}
 
 				if (!str.children.empty()) {
 					node result;
+					LITHE_EXTENT_BEGIN(result, beg)
 					flatten_to(result.children, str);
 					return complex_seq(current, limit, std::move(result), i);
 				}

          
@@ 186,6 196,7 @@ namespace lithe {
 					} 
 
 					node result;
+					LITHE_EXTENT_BEGIN(result, beg)
 					flatten_to(result.children, str);
 					flatten_to(result.children, tmp);
 					return complex_seq(current, limit, std::move(result), i);

          
@@ 271,6 282,8 @@ namespace lithe {
 				if (!insert) return c;
 				if (c.strbeg) {
 					node tmp;
+					LITHE_EXTENT_BEGIN(tmp, c.src_begin)
+					LITHE_EXTENT_END(tmp,c.src_end);
 					tmp.strbeg = tag;
 					tmp.children.emplace_back(std::move(c));
 					return tmp;

          
@@ 297,6 310,7 @@ namespace lithe {
 			node operator()(cursor& current, cursor limit)  const override {
 				node tmp;
 				tmp.strbeg = current;
+				LITHE_EXTENT_BEGIN(tmp, current);
 				for (auto p = str; *p; ++current, ++p) {
 					if (current >= limit || *p != *current) {
 						return node::error(this, current);

          
@@ 304,6 318,7 @@ namespace lithe {
 				}
 
 				tmp.strend = current;
+				LITHE_EXTENT_END(tmp, current);
 				return tmp;
 			}
 

          
@@ 391,6 406,7 @@ namespace lithe {
 
 			node operator()(cursor& current, cursor limit)  const override {
 				node result;
+				LITHE_EXTENT_BEGIN(result, current)
 				for (int matches = 0;;++matches) {
 					cursor pos = current;
 					auto tmp = (*r)(current, limit);

          
@@ 402,6 418,7 @@ namespace lithe {
 					}
 					result.children.emplace_back(tmp);
 				}
+				LITHE_EXTENT_END(result,current);
 				return result;
 			}
 

          
@@ 432,6 449,7 @@ namespace lithe {
 
 			node operator()(cursor& current, cursor limit) const override {
 				node result;
+				LITHE_EXTENT_BEGIN(result, current)
 				for (bool first = true;;first = false) {
 					cursor at = current;
 					node tmp = (*end)(current, limit);

          
@@ 440,6 458,7 @@ namespace lithe {
 						current = at;
 					} else {
 						flatten_to(result.children, tmp);
+						LITHE_EXTENT_END(result,current);
 						return result;
 					}
 

          
@@ 502,7 521,12 @@ namespace lithe {
 
 
 			node operator()(cursor& current, cursor limit)  const override {
-				if (!can_work[(unsigned char)current[0]]) return {};
+				if (!can_work[(unsigned char)current[0]]) {
+					node tmp;
+					LITHE_EXTENT_BEGIN(tmp, current)
+					LITHE_EXTENT_END(tmp, current);
+					return tmp;
+				}
 				cursor start = current;
 				node tmp = wrapper::operator()(current, limit);
 				if (tmp.is_error() && !tmp.is_fatal()) {

          
@@ 563,6 587,7 @@ namespace lithe {
 			node operator()(cursor& current, cursor limit)  const override {
 				node tmp;
 				tmp.strbeg = current;
+				LITHE_EXTENT_BEGIN(tmp, current)
 
 				if (maximum != 0) {
 					auto avail = limit - current;

          
@@ 575,6 600,7 @@ namespace lithe {
 				}
 				if (current >= tmp.strbeg + minimum) {
 					tmp.strend = current;
+					LITHE_EXTENT_END(tmp,current);
 					return tmp;
 				} else {
 					return node::error(this, current);

          
@@ 588,9 614,13 @@ namespace lithe {
 			ignore(rule r):wrapper(r) {}
 
 			node operator()(cursor& current, cursor limit)  const override {
+				auto b = current;
 				auto tmp = wrapper::operator()(current, limit);
 				if (tmp.is_error()) return tmp;
-				return {};
+				node i;
+				LITHE_EXTENT_BEGIN(i, b)
+				LITHE_EXTENT_END(i,current);
+				return i;
 			}
 		};
 

          
@@ 659,7 689,10 @@ namespace lithe {
 
 			node operator()(cursor& begin, cursor end) const override {
 				if (begin == end) {
-					return {};
+					node e;
+					LITHE_EXTENT_BEGIN(e, end)
+					LITHE_EXTENT_END(e, end)
+					return e;
 				}
 				return node::error(this, begin);
 			}