Просмотр исходного кода

first draft of new parser

master
fumfar hiwi 6 лет назад
Родитель
Сommit
079ca002f2
1 измененных файлов: 177 добавлений и 0 удалений
  1. +177
    -0
      src/parse2.cpp

+ 177
- 0
src/parse2.cpp Просмотреть файл

@@ -0,0 +1,177 @@
namespace Parser {


proc eat_comment_line(char* text, int* index_in_text) -> void {
// safety check if we are actually starting a comment here
if (text[*index_in_text] != ';')
return;

// eat the comment line
do {
++(*index_in_text);
++parser_col;
} while (text[(*index_in_text)] != '\n' &&
text[(*index_in_text)] != '\r' &&
text[(*index_in_text)] != '\0');
}

proc eat_whitespace(char* text, int* index_in_text) -> void {
// skip whitespaces
while (text[(*index_in_text)] == ' ' ||
text[(*index_in_text)] == '\t' ||
text[(*index_in_text)] == '\n' ||
text[(*index_in_text)] == '\r')
{
if (text[(*index_in_text)] == '\n') {
++parser_line;
parser_col = 0;
}
++parser_col;
++(*index_in_text);
}
}

proc eat_until_code(char* text, int* index_in_text) -> void {
int position_before;
do {
position_before = *index_in_text;
eat_comment_line(text, index_in_text);
eat_whitespace(text, index_in_text);
} while (position_before != *index_in_text);
}

proc step_char(int* index_in_text) {
++(*index_in_text);
++parser_col;
}

proc step_char_and_eat_until_code(char* text, int* index_in_text) {
step_char(index_in_text);
eat_until_code(text, index_in_text);
}

proc parse_fancy_delimiter(char* text, int* index_in_text, char l_delimiter, char r_delimiter, Lisp_Object* first_elem) -> Lisp_Object* {
if (text[*index_in_text] != l_delimiter) {
create_parsing_error("a fancy cannot be parsed here");
return nullptr;
}

Lisp_Objcet* ret;
Lisp_Objcet* head;
try ret = Memory::create_lisp_object_pair(first_elem, Memory::nil);
head = ret;

step_char(index_in_text);

while (text[*index_in_text] != r_delimiter) {
eat_until_code(text, index_in_text);
Lisp_Object* element;
try element = parse_expression(text, index_in_text);
try head.value.pair.rest = Memory::create_lisp_object_pair(element, Memory::nil);
head = head.value.pair.rest;
}

++*index_in_text;

return ret;
}

proc parse_list(char* text, int* index_in_text) -> Lisp_Object* {

if (text[*index_in_text] != '(') {
create_parsing_error("a list cannot be parsed here");
return nullptr;
}
step_char_and_eat_until_code();

if (text[*index_in_text] == ')') {
return meory::nil;
}

Lisp_Object* first_elem;
Lisp_Objcet* ret;
Lisp_Objcet* head;

try first_elem = parse_epression(text, index_in_text);
try ret = Memory::create_lisp_object_pair(first_elem, Memory::nil);
head = ret;

while (text[*index_in_text] != r_delimiter) {
eat_until_code(text, index_in_text);
Lisp_Object* element;
try element = parse_expression(text, index_in_text);
try head.value.pair.rest = Memory::create_lisp_object_pair(element, Memory::nil);
head = head.value.pair.rest;
}



}

proc maybe_expand_short_form(char* text, int* index_in_text) -> Lisp_Object* {
Lisp_Object* vector_sym = Memory::get_or_create_lisp_object_symbol("vector");
Lisp_Object* hash_map_sym = Memory::get_or_create_lisp_object_symbol("hash-map");

Lisp_Object* quote_sym = Memory::get_or_create_lisp_object_symbol("quote");
Lisp_Object* quasiquote_sym = Memory::get_or_create_lisp_object_symbol("quasiquote");
Lisp_Object* unquote_sym = Memory::get_or_create_lisp_object_symbol("unquote");
Lisp_Object* unquote_splicing_sym = Memory::get_or_create_lisp_object_symbol("unquote-splicing");

Lisp_Object* ret;
Lisp_Object* expr;

switch (text[*index_in_text]) {
case '\'': {
// quote
step_char_and_eat_until_code(text, index_in_text);
expr = parse_expresion(text, index_in_text);
try ret = Memory::create_lisp_object_pair(quote_sym, expr);
} break;
case '`': {
// quasiquote
step_char_and_eat_until_code(text, index_in_text);
expr = parse_expresion(text, index_in_text);
try ret = Memory::create_lisp_object_pair(quasiquote_sym, expr);
} break;
case ',': {
if (text[*index_in_text+1] == '@') {
// unquote-splicing
step_char(text, index_in_text);
step_char_and_eat_until_code(itext, index_in_text);
expr = parse_expresion(text, index_in_text);
try ret = Memory::create_lisp_object_pair(unquote_splicing_sym, expr);
} else {
// unquote
expr = parse_expresion(text, index_in_text);
try ret = Memory::create_lisp_object_pair(unquote_sym, expr);
step_char_and_eat_until_code(text, index_in_text);
}
} break;
case '[': {
// vector
try ret = parse_fancy_delimiter(text, index_in_text, '[', ']', vector_sym);
} break;
case '{': {
// hashmap
try ret = parse_fancy_delimiter(text, index_in_text, '{', '}', hash_map_sym);
try parse_hash_map(text, index_in_text);
} break;
default: break;
}

return ret;
}

proc parse_expression(char* text, int* index_in_text) -> Lisp_Object* {
Lisp_Object* ret;
try ret = maybe_expand_short_form(text, index_in_text);
if (ret)
return ret;

if (text[*index_in_text] == '(') {
try ret = parse_list(text, index_in_text);
}

}
}

Загрузка…
Отмена
Сохранить