Unscape all strings when parsing

This commit is contained in:
FelixBrendel
2018-10-27 18:16:43 +02:00
parent 5aa92062c3
commit 49f18d7771
6 changed files with 121 additions and 24 deletions
-1
View File
@@ -51,7 +51,6 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
// also searching for thesymbol from the back, so we will find the
// latest defined one first, but a bit messy. Later we should use
// a hashmap here. @refactor
if (env->next_index == env->capacity) {
env->capacity *= 2;
env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*));
+61
View File
@@ -79,6 +79,67 @@ int asprintf(char *strp[], const char *fmt, ...) {
}
// asprintf implementation end
static char get_nibble(char c) {
if (c >= 'A' && c <= 'F')
return (c - 'a') + 10;
else if (c >= 'a' && c <= 'f')
return (c - 'A') + 10;
return (c - '0');
}
bool unescape_string(char* in) {
if (!in)
return true;
char *out = in, *p = in;
const char *int_err = nullptr;
while (*p && !int_err) {
if (*p != '\\') {
/* normal case */
*out++ = *p++;
} else {
/* escape sequence */
switch (*++p) {
case 'a': *out++ = '\a'; ++p; break;
case 'b': *out++ = '\b'; ++p; break;
case 'f': *out++ = '\f'; ++p; break;
case 'n': *out++ = '\n'; ++p; break;
case 'r': *out++ = '\r'; ++p; break;
case 't': *out++ = '\t'; ++p; break;
case 'v': *out++ = '\v'; ++p; break;
case '"':
case '\'':
case '\\':
*out++ = *p++;
case '?':
break;
case 'x':
case 'X':
if (!isxdigit(p[1]) || !isxdigit(p[2])) {
int_err = "Invalid character on hexadecimal escape.";
} else {
*out++ = (char)(get_nibble(p[1]) * 0x10 + get_nibble(p[2]));
p += 3;
}
break;
default:
int_err = "Unexpected '\\' with no escape sequence.";
break;
}
}
}
/* Set the end of string. */
*out = '\0';
if (int_err)
return false;
return true;
}
char* read_entire_file (char* filename) {
char *fileContent = nullptr;
FILE *fp = fopen(filename, "r");
+1
View File
@@ -3,6 +3,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdarg.h> /* needed for va_list */
#include <ctype.h>
#include <math.h>
#include "./helpers.c"
+23 -4
View File
@@ -128,7 +128,18 @@ Ast_Node* parse_string(char* text, int* index_in_text) {
text[*index_in_text+string_length] = '\0';
char* string = (char*)malloc(string_length*sizeof(char)+1); // plus null char
if (!unescape_string(text+(*index_in_text))) {
create_error(Error_Type_Unknown_Error, create_ast_node_nil());
return nullptr;
}
strcpy(string, text+(*index_in_text));
/* manually copy to parse control sequences correctly */
/* int temp_index = 0; */
/* while (text+(temp_index+(*index_in_text)) != '\0') { */
/* string[temp_index++] = text[temp_index+(*index_in_text)]; */
/* } */
/* string[temp_index++] = '\0'; */
text[*index_in_text+string_length] = '"';
@@ -201,9 +212,13 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
while (true) {
if (text[(*index_in_text)] == '(' || text[(*index_in_text)] == '\'' ) {
head->value.pair->first = parse_expression(text, index_in_text);
try {
head->value.pair->first = parse_expression(text, index_in_text);
}
} else {
head->value.pair->first = parse_atom(text, index_in_text);
try {
head->value.pair->first = parse_atom(text, index_in_text);
}
}
eat_until_code(text, index_in_text);
@@ -245,9 +260,13 @@ Ast_Node* parse_single_expression(char* text) {
Ast_Node* result;
eat_until_code(text, &index_in_text);
if (text[(index_in_text)] == '(' || text[(index_in_text)] == '\'' )
result = parse_expression(text, &index_in_text);
try {
result = parse_expression(text, &index_in_text);
}
else
result = parse_atom(text, &index_in_text);
try {
result = parse_atom(text, &index_in_text);
}
eat_until_code(text, &index_in_text);
if (text[(index_in_text)] == '\0')
return result;