~emersion/mrsh-dev

parser: implement octal and hex literals v1 PROPOSED

Cormac Stephenson: 1
 parser: implement octal and hex literals

 2 files changed, 54 insertions(+), 7 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~emersion/mrsh-dev/patches/29876/mbox | git am -3
Learn more about email & git

[RFC PATCH] parser: implement octal and hex literals Export this patch

---

I'm not sure whether returning 0 in the case that none of the base
prefixes match is appropriate. If it's not, what's the better way to
handle that error?

 parser/arithm.c | 58 +++++++++++++++++++++++++++++++++++++++++++------
 test/arithm.sh  |  3 +++
 2 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/parser/arithm.c b/parser/arithm.c
index cfd49e2..85c0602 100644
--- a/parser/arithm.c
+++ b/parser/arithm.c
@@ -53,18 +53,62 @@ static bool parse_str(struct mrsh_parser *parser, const char *str) {
	return true;
}

static bool isoctal(char c)
{
	return (unsigned)c - '0' < 8;
}

static size_t peek_literal(struct mrsh_parser *parser) {
	enum { DEC, OCT, HEX } base = DEC;
	size_t i = 0;
	while (true) {
		parser_peek(parser, NULL, i + 1);

		char c = parser->buf.data[i];
		// TODO: 0x, 0b prefixes
		if (!isdigit(c)) {
			break;
	parser_peek(parser, NULL, i + 1);
	char c = parser->buf.data[i];
	if (c == '0') {
		parser_peek(parser, NULL, i + 2);
		c = parser->buf.data[i + 1];
		if (isoctal(c)) {
			base = OCT;
			i += 1;
		} else if (c == 'x' || c == 'X') {
			base = HEX;
			i += 2;
		} else {
			return 0;
		}
	}

		++i;
	switch (base) {
	case DEC:
		while (true) {
			parser_peek(parser, NULL, i + 1);
			char c = parser->buf.data[i];
			if (!isdigit(c)) {
				break;
			}
			++i;
		}
		break;
	case OCT:
		while (true) {
			parser_peek(parser, NULL, i + 1);
			c = parser->buf.data[i];
			if (!isoctal(c)) {
				break;
			}
			++i;
		}
		break;
	case HEX:
		while (true) {
			parser_peek(parser, NULL, i + 1);
			c = parser->buf.data[i];
			if (!isxdigit(c)) {
				break;
			}
			++i;
		}
		break;
	}

	return i;
diff --git a/test/arithm.sh b/test/arithm.sh
index 7cc9df5..1a0abb0 100644
--- a/test/arithm.sh
+++ b/test/arithm.sh
@@ -44,6 +44,9 @@ echo "\$a+2 =" $(($a+2))

# Assignments
a=0
echo "(a=042) =" $((a=042)) "->" $a
echo "(a=0x42af) =" $((a=0x42af)) "->" $a
echo "(a=0X42AF) =" $((a=0X42AF)) "->" $a
echo "(a=42) =" $((a=42)) "->" $a
echo "(a+=1) =" $((a+=1)) "->" $a
echo "(a-=4) =" $((a-=4)) "->" $a
-- 
2.35.1