some progress. test printing of errors later
This commit is contained in:
@@ -337,7 +337,8 @@ scan_result_t scan_f32(scanner_t *s);
|
|||||||
// valid characters after the identifier is scanned.
|
// valid characters after the identifier is scanned.
|
||||||
scan_result_t scan_identifier(scanner_t *s);
|
scan_result_t scan_identifier(scanner_t *s);
|
||||||
scan_result_t scan_string_literal(scanner_t *s);
|
scan_result_t scan_string_literal(scanner_t *s);
|
||||||
void scanner_print_errors(scan_error_t error, FILE *fp);
|
bool scanner_print_errors_func(FILE *fp, scan_result_t const *results, int results_len);
|
||||||
|
#define scanner_print_errors(FP, ...) scanner_print_errors_func(FP, &(scan_result_t[]){__VA_ARGS__}, sizeof((scan_result_t[]){__VA_ARGS__}))
|
||||||
bool looks_like_float(scanner_t *s);
|
bool looks_like_float(scanner_t *s);
|
||||||
bool looks_like_int(scanner_t *s);
|
bool looks_like_int(scanner_t *s);
|
||||||
|
|
||||||
|
|||||||
@@ -251,9 +251,9 @@ scan_result_t scan_f32(scanner_t *s) {
|
|||||||
return scan_value(.f32=val);
|
return scan_value(.f32=val);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool scan_identifier(scanner_t *s) {
|
scan_result_t scan_identifier(scanner_t *s) {
|
||||||
if (!isalpha((unsigned char)*s->cur) && *s->cur != '_') {
|
if (!isalpha((unsigned char)*s->cur) && *s->cur != '_') {
|
||||||
return false;
|
return scan_error(s, "not an identifier");
|
||||||
}
|
}
|
||||||
char const *start = s->cur++;
|
char const *start = s->cur++;
|
||||||
while (isalnum((unsigned char)*s->cur) || *s->cur == '_') {
|
while (isalnum((unsigned char)*s->cur) || *s->cur == '_') {
|
||||||
@@ -263,21 +263,21 @@ bool scan_identifier(scanner_t *s) {
|
|||||||
char *buf = allocator_alloc(s->allocator, len + 1);
|
char *buf = allocator_alloc(s->allocator, len + 1);
|
||||||
memcpy(buf, start, len);
|
memcpy(buf, start, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
s->value.identifier = buf;
|
return scan_value(.identifier=buf);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool scan_string_literal(scanner_t *s) {
|
scan_result_t scan_string_literal(scanner_t *s) {
|
||||||
char const *save = s->cur;
|
char const *save = s->cur;
|
||||||
if (*s->cur != '"')
|
if (*s->cur != '"')
|
||||||
return false;
|
return scan_error(s, "not a string");
|
||||||
s->cur++; // skip opening quote
|
s->cur++; // skip opening quote
|
||||||
char *buf = allocator_alloc(s->allocator, 256);
|
char *buf = allocator_alloc(s->allocator, 256);
|
||||||
size_t cap = 256;
|
size_t cap = 256;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
while (*s->cur && *s->cur != '"') {
|
while (*s->cur && *s->cur != '"') {
|
||||||
char c = *s->cur++;
|
char c = *s->cur++;
|
||||||
|
scan_result_t ret;
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
char esc = *s->cur++;
|
char esc = *s->cur++;
|
||||||
switch (esc) {
|
switch (esc) {
|
||||||
@@ -288,9 +288,9 @@ bool scan_string_literal(scanner_t *s) {
|
|||||||
case '"': c = '"'; break;
|
case '"': c = '"'; break;
|
||||||
case '0': c = '\0'; break;
|
case '0': c = '\0'; break;
|
||||||
default:
|
default:
|
||||||
scanner_error(s, "invalid escape sequence");
|
ret = scan_error(s, "invalid escape sequence");
|
||||||
s->cur = save;
|
s->cur = save;
|
||||||
return false;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len + 2 >= cap) {
|
if (len + 2 >= cap) {
|
||||||
@@ -300,21 +300,26 @@ bool scan_string_literal(scanner_t *s) {
|
|||||||
buf[len++] = c;
|
buf[len++] = c;
|
||||||
}
|
}
|
||||||
if (*s->cur != '"') {
|
if (*s->cur != '"') {
|
||||||
scanner_error(s, "unterminated string literal");
|
scan_result_t ret = scan_error(s, "unterminated string literal");
|
||||||
s->cur = save;
|
s->cur = save;
|
||||||
return false;
|
return ret;
|
||||||
}
|
}
|
||||||
s->cur++; // skip closing quote
|
s->cur++; // skip closing quote
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
s->value.string_literal = buf;
|
return scan_value(.string_literal=buf);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool scanner_print_errors(scanner_t *s, FILE *fp) {
|
bool scanner_print_errors_func(FILE *fp, scan_result_t const *results, int results_len) {
|
||||||
for (error_node_t *node = s->errors; node != NULL; node = node->next) {
|
bool did_print_errors = false;
|
||||||
fprintf(fp, "%s\n", node->msg);
|
for (int i = 0; i < results_len; i++) {
|
||||||
|
scan_result_t res = results[i];
|
||||||
|
if (!res.ok) {
|
||||||
|
scan_error_t err = res.error;
|
||||||
|
fprintf(fp, "%s:%d:%d: %s", err.buffer_name, err.line, err.column, err.message);
|
||||||
|
did_print_errors = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return s->errors != NULL;
|
return did_print_errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool looks_like_float(scanner_t *s) {
|
bool looks_like_float(scanner_t *s) {
|
||||||
|
|||||||
+27
-1
@@ -22,7 +22,7 @@ Test(scanner, looks_like_float) {
|
|||||||
scanner_t scanner = make_scanner("test", buffer, allocator);
|
scanner_t scanner = make_scanner("test", buffer, allocator);
|
||||||
while (!scan_eof(&scanner)) {
|
while (!scan_eof(&scanner)) {
|
||||||
bool does_look_like_float = looks_like_float(&scanner);
|
bool does_look_like_float = looks_like_float(&scanner);
|
||||||
bool does_look_like_int = looks_like_float(&scanner);
|
bool does_look_like_int = looks_like_int(&scanner);
|
||||||
while (*scanner.cur++ != ' ');
|
while (*scanner.cur++ != ' ');
|
||||||
bool expect;
|
bool expect;
|
||||||
if (scan_literal(&scanner, "true")) {
|
if (scan_literal(&scanner, "true")) {
|
||||||
@@ -41,3 +41,29 @@ Test(scanner, looks_like_float) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Test(scanner, print_errors) {
|
||||||
|
char const *buffer =
|
||||||
|
"1.0 true\n"
|
||||||
|
"12.34 true\n"
|
||||||
|
"0.5 true\n"
|
||||||
|
"9.99 true\n"
|
||||||
|
"+1.2 true\n"
|
||||||
|
"-3.14 true\n"
|
||||||
|
"1 false\n"
|
||||||
|
"42 false\n"
|
||||||
|
"+7 false\n"
|
||||||
|
"1. false\n"
|
||||||
|
".5 false\n"
|
||||||
|
"+. false\n"
|
||||||
|
"abc false\n"
|
||||||
|
"+x false\n";
|
||||||
|
with_borrow(allocator) {
|
||||||
|
scanner_t scanner = make_scanner("test", buffer, allocator);
|
||||||
|
while (!scan_eof(&scanner)) {
|
||||||
|
// TODO
|
||||||
|
cr_assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user