Entering Lines in Viewer and Editor

1

Entering Lines in Viewer and Editor

2
@Add(global elements)
class Line {
public:
@put(line elements)
private:
@put(line privates)
};
@End(global elements)
3
@def(line elements)
int operator()(int cur, int end) const {
int res {};
@put(get line)
return res;
}
@end(line elements)
4
@def(line privates)
int line_ { -1 };
bool relative_ { false };
@end(line privates)
5
@add(line elements)
operator bool() const {
return line_ >= 0 || relative_;
}
@end(line elements)
6
@def(get line)
if (! *this) {
res = cur;
} else {
res = line_;
if (relative_) { res += cur; }
}
if (res < 0) { res = 0; }
if (res > end) { res = end; }
@end(get line)
7
@add(line privates)
Line(int line, bool relative):
line_ { line }, relative_ { relative }
{}
@end(line privates)
8
@add(line elements)
Line() = default;
@end(line elements)
9
@add(line elements)
static Line relative(int line) {
return Line { line, true };
}
@end(line elements)
10
@add(line elements)
static Line line(int line) {
return Line { line, false };
}
@end(line elements)
11
@add(line elements)
static Line begin() {
return line(0);
}
@end(line elements)
12
@Add(includes)
#include <limits>
@End(includes)
13
@add(line elements)
static const int max { std::numeric_limits<int>::max() };

static Line end() {
return line(max);
}
@end(line elements)
14
@Add(global elements)
@Put(range prereqs)
@Put(range vars)
@End(global elements)
15
@Def(range vars)
Line line;
@End(range vars)
16
@Add(global elements)
int get_number(std::string &s) {
int res = 0;
while (! s.empty() && isdigit(s[0])) {
res = res * 10 + s[0] - '0';
s.erase(0, 1);
}
return res;
}
@End(global elements)
17
@Add(global elements)
Line get_line(std::string &s) {
Line line {};
do {
@put(parse line)
} while (false);
trim(s);
return line;
}
@End(global elements)
18
@def(parse line)
if (s[0] == '.') {
s.erase(0, 1);
line = Line::relative(0);
break;
}
@end(parse line)
19
@add(parse line)
if (s[0] == '+') {
s.erase(0, 1);
int n = get_number(s);
line = Line::relative(n);
break;
}
@end(parse line)
20
@add(parse line)
if (s[0] == '-') {
s.erase(0, 1);
int n = -get_number(s);
line = Line::relative(n);
break;
}
@end(parse line)
21
@add(parse line)
if (s[0] == '$') {
line = Line::end();
s.erase(0, 1);
continue;
}
@end(parse line)
22
@add(parse line)
if (isdigit(s[0])) {
int n = get_number(s);
line = Line::line(n);
continue;
}
@end(parse line);
23
@Def(do range)
line = get_line(cmd);
@End(do range)
24
@Add(perform unit-tests)
@put(unit-tests)
@end(perform unit-tests)
25
@def(unit-tests)
ASSERT(! Line {});
@end(unit-tests)
26
@add(unit-tests)
ASSERT(Line::begin());
ASSERT(Line::end());
@end(unit-tests)
27
@add(unit-tests)
ASSERT(Line::line(0));
@end(unit-tests)
28
@add(unit-tests)
ASSERT(Line::relative(0));
ASSERT(Line::relative(-2));
@end(unit-tests)
29
@add(unit-tests)
ASSERT(Line {}(5, 10) == 5);
@end(unit-tests)
30
@add(unit-tests)
ASSERT(Line::begin()(5, 10) == 0);
ASSERT(Line::end()(5, 10) == 10);
@end(unit-tests)
31
@add(unit-tests)
ASSERT(Line::line(0)(5, 10) == 0);
ASSERT(Line::line(6)(5, 10) == 6);
ASSERT(Line::line(20)(5, 10) == 10);
@end(unit-tests)
32
@add(unit-tests)
ASSERT(
Line::relative(2)(5, 10) == 7
);
@end(unit-tests)
33
@add(unit-tests)
ASSERT(
Line::relative(7)(5, 10) == 10
);
@end(unit-tests)
34
@add(unit-tests)
ASSERT(Line::relative(-2)(5, 10) == 3);
@end(unit-tests)
35
@add(unit-tests)
ASSERT(Line::relative(-7)(5, 10) == 0);
@end(unit-tests)
36
@add(unit-tests) {
std::string f = "+3";
ASSERT(get_line(f)(5, 10) == 8);
} @end(unit-tests)
37
@add(unit-tests) {
std::string f = ".";
ASSERT(get_line(f)(5, 10) == 5);
} @end(unit-tests)
38
@add(unit-tests) {
std::string f = "$";
ASSERT(get_line(f)(5, 10) == 10);
} @end(unit-tests)
39
@Def(do block range)
if (line) {
next = line(
(curBlock - curInput->blocks.begin() ) + 1,
curInput->blocks.size()
) - 1;
if (next < 0) { next = 0; }
}
@End(do block range)
40
@Def(do inputs range)
if (line) {
next = line((curInput - inputs.begin()) + 1, inputs.size()) - 1;
if (next < 0) { next = 0; }
}
@End(do inputs range)
41
@Def(do str range)
if (line) {
next = line(Line::max, c.size() + 1) - 1;
if (next < 0) { next = 0; }
}
@End(do str range)