commit 4e72e5c

uint  ·  2026-10-23 20:55:20 +0000 UTC
parent 03db476
Parse strings
2 files changed,  +66, -21
M expl.c
M expl.h
M expl.c
+65, -21
  1@@ -5,7 +5,8 @@
  2 
  3 #include "expl.h"
  4 
  5-#define parser_current_char(p, c) ((p)->src[(p)->pos] == (c))
  6+#define current_char(p, c) ((p)->src[(p)->pos] == (c))
  7+#define advance(p) ((p)->pos++) /* XXX */
  8 
  9 typedef struct {
 10 	const char* src;
 11@@ -14,10 +15,11 @@ typedef struct {
 12 } parser;
 13 
 14 static expl_node* atom(parser* p);
 15-static char* _strndup(const char* src, size_t len);
 16 static expl_node* node_new(expl_type type);
 17 static void node_free(expl_node* node);
 18 static void skip_whitespace(parser* p);
 19+static expl_node* string(parser* p);
 20+static char* _strndup(const char* src, size_t len);
 21 
 22 static expl_node*
 23 atom(parser* p)
 24@@ -25,11 +27,11 @@ atom(parser* p)
 25 	size_t start = p->pos;
 26 	expl_node* node = NULL;
 27 	
 28-	while (!parser_current_char(p, '(') &&
 29-	       !parser_current_char(p, ')') &&
 30-	       !parser_current_char(p, '"') &&
 31-	       !parser_current_char(p, ';') &&
 32-	       !parser_current_char(p, '\0') &&
 33+	while (!current_char(p, '(') &&
 34+	       !current_char(p, ')') &&
 35+	       !current_char(p, '"') &&
 36+	       !current_char(p, ';') &&
 37+	       !current_char(p, '\0') &&
 38 	       !isspace((unsigned char)p->src[p->pos]))
 39 		p->pos++;
 40 	
 41@@ -54,19 +56,6 @@ atom(parser* p)
 42 	return node;
 43 }
 44 
 45-static char*
 46-_strndup(const char* src, size_t len)
 47-{
 48-	char* str = malloc(len + 1);
 49-	if (!str)
 50-		return NULL;
 51-
 52-	memcpy(str, src, len);
 53-	str[len] = '\0';
 54-
 55-	return str;
 56-}
 57-
 58 static expl_node*
 59 node_new(expl_type type)
 60 {
 61@@ -100,7 +89,7 @@ node_free(expl_node* node)
 62 static void
 63 skip_whitespace(parser* p)
 64 {
 65-	while (isspace((unsigned char)p->src[p->pos]) || parser_current_char(p, ';')) {
 66+	while (isspace((unsigned char)p->src[p->pos]) || current_char(p, ';')) {
 67 		/* comment */
 68 		if (parser_current_char(p, ';')) {
 69 			while (!parser_current_char(p, '\n') && !parser_current_char(p, '\0'))
 70@@ -113,6 +102,61 @@ skip_whitespace(parser* p)
 71 	}
 72 }
 73 
 74+static expl_node*
 75+string(parser* p)
 76+{
 77+	expl_node* node = NULL;
 78+	size_t start = 0;
 79+
 80+	if (!current_char(p, '"')) {
 81+		p->err = EXPL_ERR_EXPECTED_STRING;
 82+		return NULL;
 83+	}
 84+
 85+	start = p->pos;
 86+	advance(p); /* skip opening " */
 87+
 88+	while (!current_char(p, '"') && !current_char(p, '\0')) {
 89+		if (current_char(p, '\\') && p->src[p->pos + 1])
 90+			p->pos++;
 91+		p->pos++;
 92+	}
 93+
 94+	if (current_char(p, '\0')) {
 95+		p->err = EXPL_ERR_EXPECTED_STRING;
 96+		return NULL;
 97+	}
 98+
 99+	node = node_new(EXPL_STRING);
100+	if (!node) {
101+		p->err = EXPL_ERR_OUT_OF_MEMORY;
102+		return NULL;
103+	}
104+
105+	node->value = _strndup(p->src + start, p->pos - start);
106+	advance(p); /* skip closing " */
107+	if (!node->value) {
108+		node_free(node);
109+		p->err = EXPL_ERR_OUT_OF_MEMORY;
110+		return NULL;
111+	}
112+
113+	return node;
114+}
115+
116+static char*
117+_strndup(const char* src, size_t len)
118+{
119+	char* str = malloc(len + 1);
120+	if (!str)
121+		return NULL;
122+
123+	memcpy(str, src, len);
124+	str[len] = '\0';
125+
126+	return str;
127+}
128+
129 int
130 main(void)
131 {
M expl.h
+1, -0
1@@ -12,6 +12,7 @@ typedef enum {
2 typedef enum {
3 	EXPL_ERR_NONE,
4 	EXPL_ERR_EXPECTED_ATOM,
5+	EXPL_ERR_EXPECTED_STRING,
6 	EXPL_ERR_OUT_OF_MEMORY,
7 
8 	EXPL_ERR_COUNT