/// __ ___ __ ___ ___ ___ ___ ___ ___ _ __ /// \ \/ / '__/ _ \ / __/ _ \/ __/ __|/ _ \| '__| /// > <| | | (_) | (_| __/\__ \__ \ (_) | | /// /_/\_\_| \___/ \___\___||___/___/\___/|_| /// /// 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]); } }