xolatilization/xrocessor.h

272 lines
9.7 KiB
C
Executable File

/// __ ___ __ ___ ___ ___ ___ ___ ___ _ __
/// \ \/ / '__/ _ \ / __/ _ \/ __/ __|/ _ \| '__|
/// > <| | | (_) | (_| __/\__ \__ \ (_) | |
/// /_/\_\_| \___/ \___\___||___/___/\___/|_|
///
/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
///
/// xolatile@chud.cyou - xrocessor - Probably the most minimalistic general preprocessor aimed at EAXHLA language syntax.
///
/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
///
/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
/// for more details, if you dare, it is a lot of text that nobody wants to read...
static natural processor_parse_comment (character * buffer);
static natural processor_parse_include (character * buffer);
static natural processor_parse_use (character * buffer);
static natural processor_parse_alias (character * buffer);
static natural processor_parse_macro (character * buffer);
static natural processor_parse_scope (character * buffer);
static natural processor_parse_unscope (character * buffer);
static natural processor_parse_default (character * buffer);
static procedure processor_parse_buffer (character * buffer, natural limit);
typedef enum {
processor_token_comment, processor_token_include, processor_token_use, processor_token_alias,
processor_token_macro, processor_token_scope, processor_token_unscope, processor_token_default,
processor_token_count
} processor_token_enumeration;
static character * processor_token_key [processor_token_count - 1] = {
"---", "include ", "use ", "alias ", "macro ", "scope ", "unscope "
};
static natural (* processor_parse_key [processor_token_count]) (character * buffer) = {
processor_parse_comment, processor_parse_include, processor_parse_use, processor_parse_alias,
processor_parse_macro, processor_parse_scope, processor_parse_unscope, processor_parse_default
};
typedef struct {
natural count;
natural limit;
character * * token_array_data;
natural * token_array_size;
natural * token_array_type;
} processor_structure;
static natural processor_parse_default (character * buffer) {
for (natural select = 0; select < token_count; ++select) {
if (string_compare_limit (buffer, token_array [select]->data, token_array [select]->size) == true) {
if (token_array [select]->type == token_alias) {
if (character_is_separator (buffer [-1]) == false) continue;
if (character_is_separator (buffer [token_array [select]->size]) == false) continue;
output (token_value [select]->data, token_value [select]->size);
return (token_array [select]->size);
}
if (token_array [select]->type == token_macro) {
if (character_is_separator (buffer [-1]) == false) continue;
if (character_is_separator (buffer [token_array [select]->size]) == false) continue;
processor_parse_buffer (token_value [select]->data, token_value [select]->size);
return (token_array [select]->size);
}
}
}
output (buffer, 1);
return (1);
}
static natural processor_parse_comment (character * buffer) {
for (natural offset = 3; buffer [offset] != '\0'; ++offset) {
if (buffer [offset] == '\n') break;
}
return (offset + 1);
}
static natural processor_parse_use (character * buffer) {
natural length = 0;
for (natural offset = 4; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
++token_count;
token_array [token_count - 1] = arena_add (sizeof (* * token_array));
token_array [token_count - 1]->data = & buffer [offset];
token_array [token_count - 1]->type = token_use;
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
token_array [token_count - 1]->size = length;
return (offset + length + 1);
}
static natural processor_parse_include (character * buffer) {
natural length = 0;
natural offset = 0;
character * data = null;
for (offset = 8; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
fatal_failure (buffer [offset] != '"', "processor_parse_include: Not a string.");
++token_count;
token_array [token_count - 1] = arena_add (sizeof (* * token_array));
token_array [token_count - 1]->data = & buffer [offset + 1];
token_array [token_count - 1]->type = token_include;
for (length = 1; (buffer [offset + length] != '\0') && (buffer [offset + length] != '"'); ++length);
token_array [token_count - 1]->size = length - 1;
data = arena_add_file (token_array [token_count - 1]->data, token_array [token_count - 1]->size);
processor_parse_buffer (data, -1);
return (offset + length + 1);
}
static natural processor_parse_alias (character * buffer) {
natural offset = 0;
natural length = 0;
for (offset = 6; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
++token_count;
token_array [token_count - 1] = arena_add (sizeof (* * token_array));
token_value [token_count - 1] = arena_add (sizeof (* * token_value));
token_array [token_count - 1]->data = & buffer [offset];
token_array [token_count - 1]->type = token_alias;
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
token_array [token_count - 1]->size = length;
for (offset += length; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
token_value [token_count - 1]->data = & buffer [offset];
token_value [token_count - 1]->type = token_alias;
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
token_value [token_count - 1]->size = length;
return (offset + length + 1);
}
static natural processor_parse_macro (character * buffer) {
natural offset = 0;
natural length = 0;
for (offset = 6; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
++token_count;
token_array [token_count - 1] = arena_add (sizeof (* * token_array));
token_value [token_count - 1] = arena_add (sizeof (* * token_value));
token_array [token_count - 1]->data = & buffer [offset];
token_array [token_count - 1]->type = token_macro;
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
token_array [token_count - 1]->size = length;
for (offset += length; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
token_value [token_count - 1]->data = & buffer [offset];
token_value [token_count - 1]->type = token_macro;
for (length = 0; buffer [offset + length] != '\0'; ++length) {
if (string_compare_limit (& buffer [offset + length], "end macro", 9) == true) {
break;
}
}
token_value [token_count - 1]->size = length;
return (offset + length + 9 + 1);
}
static natural processor_parse_scope (character * buffer) {
natural offset = 0;
natural length = 0;
natural select = 0;
for (offset = 6; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
for (select = 0; select < token_count; ++select) {
if ((string_compare_limit (token_array [select]->data, & buffer [offset], length) == true) && (token_array [select]->type == token_use)) {
for (; buffer [offset + length] != '\0'; ++length) {
if (string_compare_limit (& buffer [offset + length], "end scope", 9) == true) {
return (offset + length + 9 + 1);
}
}
}
}
return (offset + length + 1);
}
static natural processor_parse_unscope (character * buffer) {
natural offset = 0;
natural length = 0;
natural select = 0;
for (offset = 8; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
for (select = 0; select < token_count; ++select) {
if ((string_compare_limit (token_array [select]->data, & buffer [offset], length) == true) && (token_array [select]->type == token_use)) {
return (offset + length + 1);
}
}
for (; buffer [offset + length] != '\0'; ++length) {
if (string_compare_limit (& buffer [offset + length], "end unscope", 11) == true) {
return (offset + length + 11 + 1);
}
}
return (offset + length + 1);
}
static procedure processor_parse_buffer (character * buffer, natural limit) {
for (natural length = 0, offset = 0; (buffer [offset] != '\0') && (offset != limit); offset += length) {
natural select = 0;
for (select = 0; select < token_default; ++select) {
length = string_length (token_key [select]);
if (string_compare_limit (& buffer [offset], token_key [select], length) == true) {
break;
}
}
if (string_compare_limit (& buffer [offset], "end macro", 9) == true) {
length = 9;
continue;
}
if (string_compare_limit (& buffer [offset], "end scope", 9) == true) {
length = 9;
continue;
}
if (string_compare_limit (& buffer [offset], "end unscope", 11) == true) {
length = 11;
continue;
}
length = processor_parse_key [select] (& buffer [offset]);
}
}