5 #include "script/parser.h"
7 static void skip_whitespaces(const char *str, size_t *cursor, size_t n)
12 while (*cursor < n && isspace(str[*cursor])) {
17 struct ParseResult create_expr_from_str(const char *str,
24 /* TODO: create_expr_from_str doesn't no support comments */
26 skip_whitespaces(str, cursor, n);
28 return parse_failure("EOF", *cursor);
31 switch (str[*cursor]) {
34 struct ParseResult car = create_expr_from_str(str, cursor, n);
39 skip_whitespaces(str, cursor, n);
41 return parse_failure("EOF", *cursor);
44 if (str[*cursor] != '.') {
45 return parse_failure("Expected .", *cursor);
49 skip_whitespaces(str, cursor, n);
51 return parse_failure("EOF", *cursor);
54 struct ParseResult cdr = create_expr_from_str(str, cursor, n);
59 skip_whitespaces(str, cursor, n);
61 return parse_failure("EOF", *cursor);
64 if (str[*cursor] != ')') {
65 return parse_failure("Expected )", *cursor);
70 return parse_success(cons_as_expr(create_cons(car.expr, cdr.expr)));
74 /* TODO: parser does not support escaped string characters */
75 const size_t str_begin = *cursor + 1;
76 size_t str_end = str_begin;
78 while(str_end < n && str[str_end] != '"') {
83 return parse_failure("Unclosed string", str_begin);
86 *cursor = str_end + 1;
90 create_string_atom(str + str_begin, str + str_end)));
94 if (isdigit(str[*cursor])) {
95 const char *nptr = str + *cursor;
97 const float x = strtof(nptr, &endptr);
100 return parse_failure("Number expected", *cursor);
103 *cursor += (size_t) (endptr - nptr);
105 return parse_success(atom_as_expr(create_number_atom(x)));
106 } else if (isalpha(str[*cursor])) {
107 /* TODO(#289): create_expr_from_str does not support symbols */
108 return parse_failure("Symbols are not supported", *cursor);
113 return parse_failure("Unexpected sequence of characters", *cursor);
116 struct ParseResult parse_success(struct Expr expr)
118 struct ParseResult result = {
126 struct ParseResult parse_failure(const char *error,
129 struct ParseResult result = {
132 .error_cursor = error_cursor
138 void print_parse_error(FILE *stream,
140 struct ParseResult result)
142 if (!result.is_error) {
146 /* TODO: print_parse_error doesn't support colors */
147 /* TODO: print_parse_error doesn't support multiple lines */
149 fprintf(stream, "%s\n", str);
150 for (size_t i = 0; i < result.error_cursor; ++i) {
151 fprintf(stream, " ");
153 fprintf(stream, "^\n");
154 fprintf(stream, "%s\n", result.error);