diff --git a/xanguage.h b/xanguage.h new file mode 100644 index 0000000..4323066 --- /dev/null +++ b/xanguage.h @@ -0,0 +1,188 @@ +/// __ ____ _ _ __ __ _ _ _ __ _ __ _ ___ +/// \ \/ / _` | '_ \ / _` | | | |/ _` |/ _` |/ _ \ +/// > < (_| | | | | (_| | |_| | (_| | (_| | __/ +/// /_/\_\__,_|_| |_|\__, |\__,_|\__,_|\__, |\___| +/// |___/ |___/ +/// +/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic +/// +/// xolatile@chud.cyou - xanguage - Syntax definitions of programming languages that I care about (and some that I don't care about). +/// +/// 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... + +typedef enum { + language_common, language_ada, language_c, language_cpp, + language_d, language_eaxhla, language_flat, language_fortran, + language_pascal, language_python, language_go, language_lua, + language_bash, language_haskell, language_valgrind, language_holy_c, + language_count +} language_enumeration; + +typedef struct { + natural comment_colour; + natural processor_colour; + natural character_colour; + natural string_colour; + natural keyword_colour; + natural type_colour; + natural bracket_colour; + natural operator_colour; + natural number_colour; + natural lowercase_colour; + natural uppercase_colour; + natural underscore_colour; + natural register_colour; + natural extension_colour; + natural fatal_colour; + natural comment_effect; + natural processor_effect; + natural character_effect; + natural string_effect; + natural keyword_effect; + natural type_effect; + natural bracket_effect; + natural operator_effect; + natural number_effect; + natural lowercase_effect; + natural uppercase_effect; + natural underscore_effect; + natural register_effect; + natural extension_effect; + natural fatal_effect; +} language_structure; + +#define language_lowercase "abcdefghijklmnopqrstuvwxyz" +#define language_uppercase "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define language_letters "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define language_digits "0123456789" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef language_lowercase +#undef language_uppercase +#undef language_letters +#undef language_digits + +static procedure (* language_highlighter [language_count]) (language_structure * language, syntax_structure * syntax) = { + language_highlight_common, language_highlight_ada, language_highlight_c, language_highlight_cpp, + language_highlight_d, language_highlight_eaxhla, language_highlight_flat, language_highlight_fortran, + language_highlight_pascal, language_highlight_python, language_highlight_go, language_highlight_lua, + language_highlight_bash, language_highlight_haskell, language_highlight_valgrind, language_highlight_holy_c +}; + +static character * language_short_option [language_count] = { + "-X", "-A", "-C", "-S", "-D", "-E", "-T", "-F", "-P", "-Y", "-G", "-L", "-B", "-H", "-V", "-O" +}; + +static character * language_long_option [language_count] = { + "--common", "--ada", "--c", "--cpp", "--d", "--eaxhla", "--flat", "--fortran", + "--pascal", "--python", "--go", "--lua", "--bash", "--haskell", "--valgrind", "--holyc" +}; + +static character * language_identifier [language_count] = { + "Common", "Ada", "C", "C++", "D", "EAXHLA", "Flat", "Fortran", + "Pascal", "Python", "Go", "Lua", "Bash", "Haskell", "Valgrind", "Holy C" +}; + +static language_structure * language_initialize (boolean true_colour) { + language_structure * language = allocate (sizeof (* language)); + + if (true_colour == true) { + language->comment_colour = 0xff777777u; + language->processor_colour = 0xff3377aau; + language->character_colour = 0xff7733ccu; + language->string_colour = 0xffcc3377u; + language->keyword_colour = 0xff33cceeu; + language->type_colour = 0xff55cceeu; + language->bracket_colour = 0xffee5533u; + language->operator_colour = 0xffeeaa33u; + language->number_colour = 0xffee33aau; + language->lowercase_colour = 0xffccccccu; + language->uppercase_colour = 0xffeeeeeeu; + language->underscore_colour = 0xffaaaaaau; + language->register_colour = 0xff5577aau; + language->extension_colour = 0xff55aaccu; + language->fatal_colour = 0xffcc7755u; + } else { + language->comment_colour = colour_grey; + language->processor_colour = colour_cyan; + language->character_colour = colour_pink; + language->string_colour = colour_pink; + language->keyword_colour = colour_yellow; + language->type_colour = colour_yellow; + language->bracket_colour = colour_blue; + language->operator_colour = colour_cyan; + language->number_colour = colour_pink; + language->lowercase_colour = colour_white; + language->uppercase_colour = colour_white; + language->underscore_colour = colour_white; + language->register_colour = colour_cyan; + language->extension_colour = colour_yellow; + language->fatal_colour = colour_red; + language->comment_effect = effect_bold; + language->processor_effect = effect_italic; + language->character_effect = effect_bold; + language->string_effect = effect_normal; + language->keyword_effect = effect_bold; + language->type_effect = effect_normal; + language->bracket_effect = effect_bold; + language->operator_effect = effect_normal; + language->number_effect = effect_bold; + language->lowercase_effect = effect_normal; + language->uppercase_effect = effect_bold; + language->underscore_effect = effect_italic; + language->register_effect = effect_italic; + language->extension_effect = effect_italic; + language->fatal_effect = effect_bold; + } + + return (language); +} + +static language_structure * language_deinitialize (language_structure * language) { + return (deallocate (language)); +} + +static procedure language_conditionally_select (language_structure * language, syntax_structure * syntax, language_enumeration select) { + if (syntax->count == 0) { + if ((select == file_type_c_source) || (select == file_type_c_header)) { + language_highlight_c (language, syntax); + } else if ((select == file_type_ada_sexy_body) || (select == file_type_ada_specification)) { + language_highlight_ada (language, syntax); + } else if ((select == file_type_cpp_source) || (select == file_type_cpp_header)) { + language_highlight_cpp (language, syntax); + } else if (select == file_type_flat_assembly) { + language_highlight_flat (language, syntax); + } else if (select == file_type_fortran_90_source) { + language_highlight_fortran (language, syntax); + } else if (select == file_type_pascal_source) { + language_highlight_pascal (language, syntax); + } else if (select == file_type_eax_assembly) { + language_highlight_eaxhla (language, syntax); + } else if (select == file_type_python_script) { + language_highlight_python (language, syntax); + } else { + language_highlight_common (language, syntax); + } + } +} diff --git a/xatrix.h b/xatrix.h new file mode 100644 index 0000000..aa8cc58 --- /dev/null +++ b/xatrix.h @@ -0,0 +1,510 @@ +/// _ _ +/// __ ____ _| |_ _ __(_)_ __ +/// \ \/ / _` | __| '__| \ \/ / +/// > < (_| | |_| | | |> < +/// /_/\_\__,_|\__|_| |_/_/\_\ +/// +/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic +/// +/// xolatile@chud.cyou - xatrix - Very dumb and slow matrix library, mathematical matrix, because I don't like other people ideas... +/// +/// 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... + +typedef real matrix_2 [2] [2]; +typedef real matrix_3 [3] [3]; +typedef real matrix_4 [4] [4]; + +static matrix_2 * matrix_2_assign (matrix_2 * destination, + real m00, real m01, + real m10, real m11) { + destination [0] [0] = m00; + destination [0] [1] = m01; + destination [1] [0] = m10; + destination [1] [1] = m11; + + return (destination); +} + +static matrix_3 * matrix_3_assign (matrix_3 * destination, + real m00, real m01, real m02, + real m10, real m11, real m12, + real m20, real m21, real m22) { + destination [0] [0] = m00; + destination [0] [1] = m01; + destination [0] [2] = m02; + destination [1] [0] = m10; + destination [1] [1] = m11; + destination [1] [2] = m12; + destination [2] [0] = m20; + destination [2] [1] = m21; + destination [2] [2] = m22; + + return (destination); +} + +static matrix_4 * matrix_4_assign (matrix_4 * destination, + real m00, real m01, real m02, real m03, + real m10, real m11, real m12, real m13, + real m20, real m21, real m22, real m23, + real m30, real m31, real m32, real m33) { + destination [0] [0] = m00; + destination [0] [1] = m01; + destination [0] [2] = m02; + destination [0] [3] = m03; + destination [1] [0] = m10; + destination [1] [1] = m11; + destination [1] [2] = m12; + destination [1] [3] = m13; + destination [2] [0] = m20; + destination [2] [1] = m21; + destination [2] [2] = m22; + destination [2] [3] = m23; + destination [3] [0] = m30; + destination [3] [1] = m31; + destination [3] [2] = m32; + destination [3] [3] = m33; + + return (destination); +} + +static matrix_2 * matrix_2_nullify (matrix_2 * destination) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + destination [row] [column] = 0.0f; + } + } + + return (destination); +} + +static matrix_3 * matrix_3_nullify (matrix_3 * destination) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + destination [row] [column] = 0.0f; + } + } + + return (destination); +} + +static matrix_4 * matrix_4_nullify (matrix_4 * destination) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + destination [row] [column] = 0.0f; + } + } + + return (destination); +} + +static matrix_2 * matrix_2_identity (matrix_2 * destination) { + destination = matrix_2_nullify (destination); + + for (natural index = 0; index < 2; ++index) { + destination [index] [index] = 1.0f; + } + + return (destination); +} + +static matrix_3 * matrix_3_identity (matrix_3 * destination) { + destination = matrix_3_nullify (destination); + + for (natural index = 0; index < 3; ++index) { + destination [index] [index] = 1.0f; + } + + return (destination); +} + +static matrix_4 * matrix_4_identity (matrix_4 * destination) { + destination = matrix_4_nullify (destination); + + for (natural index = 0; index < 4; ++index) { + destination [index] [index] = 1.0f; + } + + return (destination); +} + +static real matrix_2_determinant (matrix_2 * matrix) { + real a = matrix [0] [0] * matrix [1] [1]; + real b = matrix [0] [1] * matrix [1] [0]; + + return (a - b); +} + +static real matrix_3_determinant (matrix_3 * matrix) { + matrix_2 matrix_a = { { matrix [1] [1], matrix [1] [2] }, + { matrix [2] [1], matrix [2] [2] } }; + matrix_2 matrix_b = { { matrix [1] [0], matrix [1] [2] }, + { matrix [2] [0], matrix [2] [2] } }; + matrix_2 matrix_c = { { matrix [1] [0], matrix [1] [1] }, + { matrix [2] [0], matrix [2] [1] } }; + + real a = matrix [0] [0] * matrix_2_determinant (& matrix_a); + real b = matrix [0] [1] * matrix_2_determinant (& matrix_b); + real c = matrix [0] [2] * matrix_2_determinant (& matrix_c); + + return (a - b + c); +} + +static real matrix_4_determinant (matrix_4 * matrix) { + matrix_3 matrix_a = { { matrix [1] [1], matrix [1] [2], matrix [1] [3] }, + { matrix [2] [1], matrix [2] [2], matrix [2] [3] }, + { matrix [3] [1], matrix [3] [2], matrix [3] [3] } }; + matrix_3 matrix_b = { { matrix [1] [0], matrix [1] [2], matrix [1] [3] }, + { matrix [2] [0], matrix [2] [2], matrix [2] [3] }, + { matrix [3] [0], matrix [3] [2], matrix [3] [3] } }; + matrix_3 matrix_c = { { matrix [1] [0], matrix [1] [1], matrix [1] [3] }, + { matrix [2] [0], matrix [2] [1], matrix [2] [3] }, + { matrix [3] [0], matrix [3] [1], matrix [3] [3] } }; + matrix_3 matrix_d = { { matrix [1] [0], matrix [1] [1], matrix [1] [2] }, + { matrix [2] [0], matrix [2] [1], matrix [2] [2] }, + { matrix [3] [0], matrix [3] [1], matrix [3] [2] } }; + + real a = matrix [0] [0] * matrix_3_determinant (& matrix_a); + real b = matrix [0] [1] * matrix_3_determinant (& matrix_b); + real c = matrix [0] [2] * matrix_3_determinant (& matrix_c); + real d = matrix [0] [3] * matrix_3_determinant (& matrix_d); + + return (a - b + c - d); +} + +static matrix_2 * matrix_2_copy (matrix_2 * destination, matrix_2 * source) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + destination [row] [column] = source [row] [column]; + } + } + + return (destination); +} + +static matrix_3 * matrix_3_copy (matrix_3 * destination, matrix_3 * source) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + destination [row] [column] = source [row] [column]; + } + } + + return (destination); +} + +static matrix_4 * matrix_4_copy (matrix_4 * destination, matrix_4 * source) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + destination [row] [column] = source [row] [column]; + } + } + + return (destination); +} + +static matrix_2 * matrix_2_scale (matrix_2 * destination, real scale) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + destination [row] [column] *= scale; + } + } + + return (destination); +} + +static matrix_3 * matrix_3_scale (matrix_3 * destination, real scale) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + destination [row] [column] *= scale; + } + } + + return (destination); +} + +static matrix_4 * matrix_4_scale (matrix_4 * destination, real scale) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + destination [row] [column] *= scale; + } + } + + return (destination); +} + +static matrix_2 * matrix_2_scale_to (matrix_2 * destination, matrix_2 * source, real scale) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + destination [row] [column] = source [row] [column] * scale; + } + } + + return (destination); +} + +static matrix_3 * matrix_3_scale_to (matrix_3 * destination, matrix_3 * source, real scale) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + destination [row] [column] = source [row] [column] * scale; + } + } + + return (destination); +} + +static matrix_4 * matrix_4_scale_to (matrix_4 * destination, matrix_4 * source, real scale) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + destination [row] [column] = source [row] [column] * scale; + } + } + + return (destination); +} + +static matrix_2 * matrix_2_add (matrix_2 * destination, matrix_2 * source) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + destination [row] [column] += source [row] [column]; + } + } + + return (destination); +} + +static matrix_3 * matrix_3_add (matrix_3 * destination, matrix_3 * source) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + destination [row] [column] += source [row] [column]; + } + } + + return (destination); +} + +static matrix_4 * matrix_4_add (matrix_4 * destination, matrix_4 * source) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + destination [row] [column] += source [row] [column]; + } + } + + return (destination); +} + +static matrix_2 * matrix_2_add_to (matrix_2 * destination, matrix_2 * matrix_a, matrix_2 * matrix_b) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + destination [row] [column] = matrix_a [row] [column] + matrix_b [row] [column]; + } + } + + return (destination); +} + +static matrix_3 * matrix_3_add_to (matrix_3 * destination, matrix_3 * matrix_a, matrix_3 * matrix_b) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + destination [row] [column] = matrix_a [row] [column] + matrix_b [row] [column]; + } + } + + return (destination); +} + +static matrix_4 * matrix_4_add_to (matrix_4 * destination, matrix_4 * matrix_a, matrix_4 * matrix_b) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + destination [row] [column] = matrix_a [row] [column] + matrix_b [row] [column]; + } + } + + return (destination); +} + +static matrix_2 * matrix_2_subtract (matrix_2 * destination, matrix_2 * source) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + destination [row] [column] -= source [row] [column]; + } + } + + return (destination); +} + +static matrix_3 * matrix_3_subtract (matrix_3 * destination, matrix_3 * source) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + destination [row] [column] -= source [row] [column]; + } + } + + return (destination); +} + +static matrix_4 * matrix_4_subtract (matrix_4 * destination, matrix_4 * source) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + destination [row] [column] -= source [row] [column]; + } + } + + return (destination); +} + +static matrix_2 * matrix_2_subtract_to (matrix_2 * destination, matrix_2 * matrix_a, matrix_2 * matrix_b) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + destination [row] [column] = matrix_a [row] [column] - matrix_b [row] [column]; + } + } + + return (destination); +} + +static matrix_3 * matrix_3_subtract_to (matrix_3 * destination, matrix_3 * matrix_a, matrix_3 * matrix_b) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + destination [row] [column] = matrix_a [row] [column] - matrix_b [row] [column]; + } + } + + return (destination); +} + +static matrix_4 * matrix_4_subtract_to (matrix_4 * destination, matrix_4 * matrix_a, matrix_4 * matrix_b) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + destination [row] [column] = matrix_a [row] [column] - matrix_b [row] [column]; + } + } + + return (destination); +} + +static matrix_2 * matrix_2_multiply (matrix_2 * result, matrix_2 * matrix_a, matrix_2 * matrix_b) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + result [row] [column] = 0.0f; + + for (natural index = 0; index < 2; ++index) { + result [row] [column] += matrix_a [row] [index] * matrix_b [index] [column]; + } + } + } + + return (result); +} + +static matrix_3 * matrix_3_multiply (matrix_3 * result, matrix_3 * matrix_a, matrix_3 * matrix_b) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + result [row] [column] = 0.0f; + + for (natural index = 0; index < 3; ++index) { + result [row] [column] += matrix_a [row] [index] * matrix_b [index] [column]; + } + } + } + + return (result); +} + +static matrix_4 * matrix_4_multiply (matrix_4 * result, matrix_4 * matrix_a, matrix_4 * matrix_b) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + result [row] [column] = 0.0f; + + for (natural index = 0; index < 4; ++index) { + result [row] [column] += matrix_a [row] [index] * matrix_b [index] [column]; + } + } + } + + return (result); +} + +static real matrix_2_trace (matrix_2 * matrix) { + return (matrix [0] [0] + matrix [1] [1]); +} + +static real matrix_3_trace (matrix_3 * matrix) { + return (matrix [0] [0] + matrix [1] [1] + matrix [2] [2]); +} + +static real matrix_4_trace (matrix_4 * matrix) { + return (matrix [0] [0] + matrix [1] [1] + matrix [2] [2] + matrix [3] [3]); +} + +static boolean matrix_2_compare (matrix_2 * matrix_a, matrix_2 * matrix_b) { + for (natural row = 0; row < 2; ++row) { + for (natural column = 0; column < 2; ++column) { + if (matrix_a [row] [column] != matrix_b [row] [column]) { + return (false); + } + } + } + + return (true); +} + +static boolean matrix_3_compare (matrix_3 * matrix_a, matrix_3 * matrix_b) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + if (matrix_a [row] [column] != matrix_b [row] [column]) { + return (false); + } + } + } + + return (true); +} + +static boolean matrix_4_compare (matrix_4 * matrix_a, matrix_4 * matrix_b) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + if (matrix_a [row] [column] != matrix_b [row] [column]) { + return (false); + } + } + } + + return (true); +} + +static procedure matrix_2_transpose (matrix_2 * matrix_a, matrix_2 * matrix_b) { + for (natural row = 0; row < 2; ++row) { + for (natural column = row + 1; column < 2; ++column) { + real temporary = matrix_a [row] [column]; + + matrix_a [row] [column] = matrix_b [column] [row]; + matrix_b [column] [row] = temporary; + } + } +} + +static procedure matrix_3_transpose (matrix_3 * matrix_a, matrix_3 * matrix_b) { + for (natural row = 0; row < 3; ++row) { + for (natural column = 0; column < 3; ++column) { + real temporary = matrix_a [row] [column]; + + matrix_a [row] [column] = matrix_b [column] [row]; + matrix_b [column] [row] = temporary; + } + } +} + +static procedure matrix_4_transpose (matrix_4 * matrix_a, matrix_4 * matrix_b) { + for (natural row = 0; row < 4; ++row) { + for (natural column = 0; column < 4; ++column) { + real temporary = matrix_a [row] [column]; + + matrix_a [row] [column] = matrix_b [column] [row]; + matrix_b [column] [row] = temporary; + } + } +} diff --git a/xcript.h b/xcript.h new file mode 100644 index 0000000..cf5183f --- /dev/null +++ b/xcript.h @@ -0,0 +1,383 @@ +/// _ _ +/// __ _____ _ __(_)_ __ | |_ +/// \ \/ / __| '__| | '_ \| __| +/// > < (__| | | | |_) | |_ +/// /_/\_\___|_| |_| .__/ \__| +/// |_| +/// +/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic +/// +/// xolatile@chud.cyou - xcript - Whitespace insignificant INI/CFG-like script parser. +/// +/// 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... + +typedef enum { + script_unknown, script_comment, script_string, script_number, script_marker, script_header, script_assign, script_end, + script_from, script_to, script_next +} script_word_type; + +typedef struct { + character * path; + character * source; + natural prefix; + natural length; + natural suffix; + natural offset; + natural line; + natural last_length; + character * last_string; + boolean force; + boolean range; +} script_data_structure; + +typedef struct { + natural counter; + character * * identifier; + natural * index; +} script_structure; + +static procedure script_warning (script_data_structure * script, boolean condition, character * message) { + if (condition == true) { + print ("/w %s: %i: %s\n", script->path, script->line, message); + } +} + +static procedure script_failure (script_data_structure * script, boolean condition, character * message) { + if (condition == true) { + print ("/f %s: %i: %s\n", script->path, script->line, message); + + print ("/1%s/-", & script->source [script->offset]); + + exit (log_failure); + } +} + +static script_data_structure * script_open (character * path) { + script_data_structure * script = allocate (sizeof (* script)); + + script->path = string_duplicate (path); + script->source = file_import (path); + + script->prefix = 0; + script->length = 0; + script->suffix = 0; + script->offset = 0; + script->line = 1; + script->last_length = 0; + script->last_string = & script->source [0]; + + return (script); +} + +static script_data_structure * script_close (script_data_structure * script) { + script->path = deallocate (script->path); + script->source = deallocate (script->source); + + return (deallocate (script)); +} + +static boolean script_compare (script_data_structure * script, character * string) { + return (string_compare_limit (string, script->last_string, script->last_length)); +} + +static boolean script_check (script_structure * information, natural index, character * identifier) { + return (string_compare (identifier, information->identifier [index])); +} + +static character * script_export_string (script_data_structure * script) { + return (string_duplicate_limit (script->last_string, script->last_length)); +} + +static natural script_export_number (script_data_structure * script) { + return (string_limit_to_number (script->last_string, script->last_length)); +} + +static natural script_export_marker (script_structure * information, script_data_structure * script) { + for (natural counter = 0; counter < information->counter; ++counter) { + if (script_compare (script, information->identifier [counter]) == true) { + return (information->index [counter]); + } + } + + script_failure (script, true, "No such identifier defined so far in any of the headers!"); + + return (~ 0u); +} + +static script_word_type script_parser (script_data_structure * script) { + script_word_type word = script_unknown; + + script->prefix = 0; + script->length = 0; + script->suffix = 0; + + for (; character_is_blank (script->source [script->offset + script->prefix]) == true; ++script->prefix) { + if (script->source [script->offset + script->prefix] == '\n') { + ++script->line; + } + } + + if (script->source [script->offset + script->prefix] == '\0') { + word = script_end; + } else if (script->source [script->offset + script->prefix] == '(') { + script_failure (script, script->range == true, "You are already defining a range, only one pair of () is allowed."); + script->range = true; + ++script->length; + word = script_from; + } else if (script->source [script->offset + script->prefix] == ',') { + script_failure (script, script->range == false, "You can't use ',' outside of a range."); + ++script->length; + word = script_next; + } else if (script->source [script->offset + script->prefix] == ')') { + script_failure (script, script->range == false, "You already defined a range, only one pair of () is allowed."); + script->range = false; + ++script->length; + word = script_to; + } else if (script->source [script->offset + script->prefix] == ';') { + for (; script->source [script->offset + script->prefix + script->length] != '\n'; ++script->length) { + script_warning (script, script->source [script->offset + script->prefix + script->length] == '\0', + "Expected at least a trailing new line or some blank character after a comment!"); + } + word = script_comment; + } else if (script->source [script->offset + script->prefix] == '#') { + for (; script->source [script->offset + script->prefix + script->length] != '\n'; ++script->length) { + script_warning (script, script->source [script->offset + script->prefix + script->length] == '\0', + "Expected at least a trailing new line or some blank character after a comment!"); + } + word = script_comment; + } else if (script->source [script->offset + script->prefix] == '=') { + ++script->length; + word = script_assign; + } else if (script->source [script->offset + script->prefix] == '"') { + script_failure (script, script->range == true, "You can't use string inside of a range."); + for (script->length = 1; script->source [script->offset + script->prefix + script->length] != '"'; ++script->length) { + script_failure (script, script->source [script->offset + script->prefix + script->length] == '\0', + "Unterminated string literal, missing '\"' character."); + } + ++script->prefix; + --script->length; + ++script->suffix; + word = script_string; + } else if (script->source [script->offset + script->prefix] == '\'') { + script_failure (script, script->range == true, "You can't use string inside of a range."); + for (script->length = 1; script->source [script->offset + script->prefix + script->length] != '\''; ++script->length) { + script_failure (script, script->source [script->offset + script->prefix + script->length] == '\0', + "Unterminated string literal, missing ''' character."); + } + ++script->prefix; + --script->length; + ++script->suffix; + word = script_string; + } else if (script->source [script->offset + script->prefix] == '[') { + script_failure (script, script->range == true, "You can't use header inside of a range."); + for (; script->source [script->offset + script->prefix + script->length] != ']'; ++script->length) { + script_failure (script, script->source [script->offset + script->prefix + script->length] == '\0', + "Unterminated header element, missing ']' character."); + } + ++script->prefix; + --script->length; + ++script->suffix; + word = script_header; + } else if (character_is_digit (script->source [script->offset + script->prefix]) == true) { + for (; character_is_digit (script->source [script->offset + script->prefix + script->length]) == true; ++script->length) { + script_warning (script, script->source [script->offset + script->prefix + script->length] == '\0', + "Expected at least a trailing new line or some blank character after a number!"); + } + word = script_number; + } else if (character_is_identifier (script->source [script->offset + script->prefix]) == true) { + for (; character_is_identifier (script->source [script->offset + script->prefix + script->length]) == true; ++script->length) { + script_warning (script, script->source [script->offset + script->prefix + script->length] == '\0', + "Expected at least a trailing new line or some blank character after a marker!"); + } + word = script_marker; + } else { + script_failure (script, true, format ("Illegal character '%c' in script.", script->source [script->offset + script->prefix])); + } + + script->last_string = & script->source [script->offset + script->prefix]; + script->last_length = script->length; + + script->offset += script->prefix + script->length + script->suffix; + + return (word); +} + +static character * script_expect_header (script_structure * information, script_data_structure * script, natural index, boolean accept) { + if (accept == true) { + ++information->counter; + + information->identifier = reallocate (information->identifier, information->counter * sizeof (* information->identifier)); + information->index = reallocate (information->index, information->counter * sizeof (* information->index)); + + information->identifier [information->counter - 1] = string_duplicate_limit (script->last_string, script->last_length); + information->index [information->counter - 1] = index; + } + + return (script_export_string (script)); +} + +static character * script_expect_string (script_data_structure * script) { + script_word_type word = script_unknown; + + script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator."); + script_failure (script, (word = script_parser (script)) != script_string, "Expected string literal."); + + return (script_export_string (script)); +} + +static natural script_expect_number (script_data_structure * script) { + script_word_type word = script_unknown; + + script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator."); + script_failure (script, (word = script_parser (script)) != script_number, "Expected number literal."); + + return (script_export_number (script)); +} + +static natural script_expect_marker (script_structure * information, script_data_structure * script) { + script_word_type word = script_unknown; + + script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator."); + script_failure (script, (word = script_parser (script)) != script_marker, "Expected marker literal."); + + return (script_export_marker (information, script)); +} + +static natural script_expect_number_or_marker (script_structure * information, script_data_structure * script) { + script_word_type word = script_unknown; + + script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator."); + + word = script_parser (script); + + if (word == script_number) { + return (script_export_number (script)); + } else if (word == script_marker) { + return (script_export_marker (information, script)); + } else { + script_failure (script, true, "Expected number or marker literal."); + } + + return (~ 0u); +} + +static natural * script_expect_ordered_array (script_structure * information, script_data_structure * script, natural * count) { + script_word_type word = script_unknown; + + natural found = 0; + natural * array = null; + + script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator."); + script_failure (script, (word = script_parser (script)) != script_from, "Expected '(', begin range operator."); + + for (word = script_parser (script); word != script_to; word = script_parser (script)) { + ++found; + + array = reallocate (array, found * sizeof (* array)); + + if (word == script_number) { + array [found - 1] = script_export_number (script); + } else if (word == script_marker) { + array [found - 1] = script_export_marker (information, script); + } else { + script_failure (script, true, "Expected number or marker!"); + } + + if ((word = script_parser (script)) == script_to) break; + + script_failure (script, word != script_next, "Expected ranged next ','."); + script_failure (script, word == script_end, "Expected ranged to ')'."); + } + + (* count) = found; + + return (array); +} + +static natural * script_expect_unordered_array (script_structure * information, script_data_structure * script, natural count) { + script_word_type word = script_unknown; + + natural * array = allocate (count * sizeof (* array)); + + script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator."); + script_failure (script, (word = script_parser (script)) != script_from, "Expected '(', begin range operator."); + + for (word = script_parser (script); word != script_to; word = script_parser (script)) { + natural index = script_export_marker (information, script); + + script_failure (script, word != script_marker, "Expected ranged marker."); + + script_failure (script, (word = script_parser (script)) != script_assign, "Expected '=', assignment operator."); + + word = script_parser (script); + + if (word == script_number) { + array [index] = script_export_number (script); + } else if (word == script_marker) { + array [index] = script_export_marker (information, script); + } else { + script_failure (script, true, "Expected number or marker!"); + } + + if ((word = script_parser (script)) == script_to) break; + + script_failure (script, word != script_next, "Expected ranged next ','."); + script_failure (script, word == script_end, "Expected ranged to ')'."); + } + + return (array); +} + +static script_structure * script_initialize (character * general_script_file_path) { + script_structure * script = allocate (sizeof (* script)); + + script_word_type word = script_unknown; + + script_data_structure * general = script_open (general_script_file_path); + + for (word = script_parser (general); word != script_end; word = script_parser (general)) { + if (word == script_header) { + ++script->counter; + script->identifier = reallocate (script->identifier, script->counter * sizeof (* script->identifier)); + script->index = reallocate (script->index, script->counter * sizeof (* script->index)); + script->identifier [script->counter - 1] = string_duplicate_limit (general->last_string, general->last_length); + script->index [script->counter - 1] = script->counter - 1; + } else if ((word == script_end) || (word == script_comment)) { + continue; + } else { + script_failure (general, true, "Expected header in general script."); + } + } + + general = script_close (general); + + return (script); +} + +static script_structure * script_deinitialize (script_structure * script) { + for (natural index = 0; index < script->counter; ++index) { + script->identifier [index] = deallocate (script->identifier [index]); + } + + script->identifier = deallocate (script->identifier); + script->index = deallocate (script->index); + + return (deallocate (script)); +} + +static natural script_indexer (script_structure * information, character * identifier) { + for (natural counter = 0; counter < information->counter; ++counter) { + if (string_compare (identifier, information->identifier [counter]) == true) { + return (information->index [counter]); + } + } + + fatal_failure (true, "script_indexer: No such identifier defined so far in any of the headers!"); + + return (~ 0u); +} diff --git a/xector.h b/xector.h new file mode 100644 index 0000000..e85ba7a --- /dev/null +++ b/xector.h @@ -0,0 +1,388 @@ +/// _ +/// __ _____ ___| |_ ___ _ __ +/// \ \/ / _ \/ __| __/ _ \| '__| +/// > < __/ (__| || (_) | | +/// /_/\_\___|\___|\__\___/|_| +/// +/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic +/// +/// xolatile@chud.cyou - xector - Very slow and dumb vector library, mathematical vector, not that C++ cancer by the way... +/// +/// 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... + +typedef struct { + real x, y; +} vector_2; + +typedef struct { + real x, y, z; +} vector_3; + +typedef struct { + real x, y, z, w; +} vector_4; + +static vector_2 * vector_2_assign (vector_2 * destination, real x, real y) { + destination->x = x; + destination->y = y; + + return (destination); +} + +static vector_3 * vector_3_assign (vector_3 * destination, real x, real y, real z) { + destination->x = x; + destination->y = y; + destination->z = z; + + return (destination); +} + +static vector_4 * vector_4_assign (vector_4 * destination, real x, real y, real z, real w) { + destination->x = x; + destination->y = y; + destination->z = z; + destination->w = w; + + return (destination); +} + +static vector_2 * vector_2_nullify (vector_2 * destination) { + destination->x = destination->y = 0.0f; + + return (destination); +} + +static vector_3 * vector_3_nullify (vector_3 * destination) { + destination->x = destination->y = destination->z = 0.0f; + + return (destination); +} + +static vector_4 * vector_4_nullify (vector_4 * destination) { + destination->x = destination->y = destination->z = destination->w = 0.0f; + + return (destination); +} + +static real vector_2_length (vector_2 * vector) { + real x = vector->x; + real y = vector->y; + + return (square_root (x * x + y * y)); +} + +static real vector_3_length (vector_3 * vector) { + real x = vector->x; + real y = vector->y; + real z = vector->z; + + return (square_root (x * x + y * y + z * z)); +} + +static real vector_4_length (vector_4 * vector) { + real x = vector->x; + real y = vector->y; + real z = vector->z; + real w = vector->w; + + return (square_root (x * x + y * y + z * z + w * w)); +} + +static vector_2 * vector_2_normalize (vector_2 * destination) { + real length = vector_2_length (destination); + + destination->x /= length; + destination->y /= length; + + return (destination); +} + +static vector_3 * vector_3_normalize (vector_3 * destination) { + real length = vector_3_length (destination); + + destination->x /= length; + destination->y /= length; + destination->z /= length; + + return (destination); +} + +static vector_4 * vector_4_normalize (vector_4 * destination) { + real length = vector_4_length (destination); + + destination->x /= length; + destination->y /= length; + destination->z /= length; + destination->w /= length; + + return (destination); +} + +static vector_2 * vector_2_normalize_to (vector_2 * destination, vector_2 * source) { + real length = vector_2_length (source); + + destination->x = source->x / length; + destination->y = source->y / length; + + return (destination); +} + +static vector_3 * vector_3_normalize_to (vector_3 * destination, vector_3 * source) { + real length = vector_3_length (source); + + destination->x = source->x / length; + destination->y = source->y / length; + destination->z = source->z / length; + + return (destination); +} + +static vector_4 * vector_4_normalize_to (vector_4 * destination, vector_4 * source) { + real length = vector_4_length (source); + + destination->x = source->x / length; + destination->y = source->y / length; + destination->z = source->z / length; + destination->w = source->w / length; + + return (destination); +} + +static vector_2 * vector_2_copy (vector_2 * destination, vector_2 * source) { + destination->x = source->x; + destination->y = source->y; + + return (destination); +} + +static vector_3 * vector_3_copy (vector_3 * destination, vector_3 * source) { + destination->x = source->x; + destination->y = source->y; + destination->z = source->z; + + return (destination); +} + +static vector_4 * vector_4_copy (vector_4 * destination, vector_4 * source) { + destination->x = source->x; + destination->y = source->y; + destination->z = source->z; + destination->w = source->w; + + return (destination); +} + +static procedure vector_2_exchange (vector_2 * vector_a, vector_2 * vector_b) { + exchange_real (& vector_a->x, & vector_b->x); + exchange_real (& vector_a->y, & vector_b->y); +} + +static procedure vector_3_exchange (vector_3 * vector_a, vector_3 * vector_b) { + exchange_real (& vector_a->x, & vector_b->x); + exchange_real (& vector_a->y, & vector_b->y); + exchange_real (& vector_a->z, & vector_b->z); +} + +static procedure vector_4_exchange (vector_4 * vector_a, vector_4 * vector_b) { + exchange_real (& vector_a->x, & vector_b->x); + exchange_real (& vector_a->y, & vector_b->y); + exchange_real (& vector_a->z, & vector_b->z); + exchange_real (& vector_a->w, & vector_b->w); +} + +static vector_2 * vector_2_scale (vector_2 * destination, real scale) { + destination->x *= scale; + destination->y *= scale; + + return (destination); +} + +static vector_3 * vector_3_scale (vector_3 * destination, real scale) { + destination->x *= scale; + destination->y *= scale; + destination->z *= scale; + + return (destination); +} + +static vector_4 * vector_4_scale (vector_4 * destination, real scale) { + destination->x *= scale; + destination->y *= scale; + destination->z *= scale; + destination->w *= scale; + + return (destination); +} + +static vector_2 * vector_2_scale_to (vector_2 * destination, vector_2 * source, real scale) { + destination->x = source->x * scale; + destination->y = source->y * scale; + + return (destination); +} + +static vector_3 * vector_3_scale_to (vector_3 * destination, vector_3 * source, real scale) { + destination->x = source->x * scale; + destination->y = source->y * scale; + destination->z = source->z * scale; + + return (destination); +} + +static vector_4 * vector_4_scale_to (vector_4 * destination, vector_4 * source, real scale) { + destination->x = source->x * scale; + destination->y = source->y * scale; + destination->z = source->z * scale; + destination->w = source->w * scale; + + return (destination); +} + +static vector_2 * vector_2_add (vector_2 * destination, vector_2 * source) { + destination->x += source->x; + destination->y += source->y; + + return (destination); +} + +static vector_3 * vector_3_add (vector_3 * destination, vector_3 * source) { + destination->x += source->x; + destination->y += source->y; + destination->z += source->z; + + return (destination); +} + +static vector_4 * vector_4_add (vector_4 * destination, vector_4 * source) { + destination->x += source->x; + destination->y += source->y; + destination->z += source->z; + destination->w += source->w; + + return (destination); +} + +static vector_2 * vector_2_add_to (vector_2 * destination, vector_2 * vector_a, vector_2 * vector_b) { + destination->x = vector_a->x + vector_b->x; + destination->y = vector_a->y + vector_b->y; + + return (destination); +} + +static vector_3 * vector_3_add_to (vector_3 * destination, vector_3 * vector_a, vector_3 * vector_b) { + destination->x = vector_a->x + vector_b->x; + destination->y = vector_a->y + vector_b->y; + destination->z = vector_a->z + vector_b->z; + + return (destination); +} + +static vector_4 * vector_4_add_to (vector_4 * destination, vector_4 * vector_a, vector_4 * vector_b) { + destination->x = vector_a->x + vector_b->x; + destination->y = vector_a->y + vector_b->y; + destination->z = vector_a->z + vector_b->z; + destination->w = vector_a->w + vector_b->w; + + return (destination); +} + +static vector_2 * vector_2_subtract (vector_2 * destination, vector_2 * source) { + destination->x -= source->x; + destination->y -= source->y; + + return (destination); +} + +static vector_3 * vector_3_subtract (vector_3 * destination, vector_3 * source) { + destination->x -= source->x; + destination->y -= source->y; + destination->z -= source->z; + + return (destination); +} + +static vector_4 * vector_4_subtract (vector_4 * destination, vector_4 * source) { + destination->x -= source->x; + destination->y -= source->y; + destination->z -= source->z; + destination->w -= source->w; + + return (destination); +} + +static vector_2 * vector_2_subtract_to (vector_2 * destination, vector_2 * vector_a, vector_2 * vector_b) { + destination->x = vector_a->x - vector_b->x; + destination->y = vector_a->y - vector_b->y; + + return (destination); +} + +static vector_3 * vector_3_subtract_to (vector_3 * destination, vector_3 * vector_a, vector_3 * vector_b) { + destination->x = vector_a->x - vector_b->x; + destination->y = vector_a->y - vector_b->y; + destination->z = vector_a->z - vector_b->z; + + return (destination); +} + +static vector_4 * vector_4_subtract_to (vector_4 * destination, vector_4 * vector_a, vector_4 * vector_b) { + destination->x = vector_a->x - vector_b->x; + destination->y = vector_a->y - vector_b->y; + destination->z = vector_a->z - vector_b->z; + destination->w = vector_a->w - vector_b->w; + + return (destination); +} + +static boolean vector_2_compare (vector_2 * vector_a, vector_2 * vector_b) { + if ((vector_a->x == vector_b->x) && (vector_a->y == vector_b->y)) { + return (true); + } else { + return (false); + } +} + +static boolean vector_3_compare (vector_3 * vector_a, vector_3 * vector_b) { + if ((vector_a->x == vector_b->x) && (vector_a->y == vector_b->y) && (vector_a->z == vector_b->z)) { + return (true); + } else { + return (false); + } +} + +static boolean vector_4_compare (vector_4 * vector_a, vector_4 * vector_b) { + if ((vector_a->x == vector_b->x) && (vector_a->y == vector_b->y) && (vector_a->z == vector_b->z) && (vector_a->w == vector_b->w)) { + return (true); + } else { + return (false); + } +} + +static real vector_2_dot_product (vector_2 * vector_a, vector_2 * vector_b) { + return (vector_a->x * vector_b->x + vector_a->y * vector_b->y); +} + +static real vector_3_dot_product (vector_3 * vector_a, vector_3 * vector_b) { + return (vector_a->x * vector_b->x + vector_a->y * vector_b->y + vector_a->z * vector_b->z); +} + +static real vector_4_dot_product (vector_4 * vector_a, vector_4 * vector_b) { + return (vector_a->x * vector_b->x + vector_a->y * vector_b->y + vector_a->z * vector_b->z + vector_a->w * vector_b->w); +} + +static real vector_2_cross_product (vector_2 * vector_a, vector_2 * vector_b) { + return (vector_a->x * vector_b->y - vector_a->y * vector_b->x); +} + +static vector_3 * vector_3_cross_product (vector_3 * destination, vector_3 * source) { + destination->x = destination->y * source->z - destination->z * source->y; + destination->y = destination->z * source->x - destination->x * source->z; + destination->z = destination->x * source->y - destination->y * source->x; + + return (destination); +} diff --git a/xrena.h b/xrena.h new file mode 100644 index 0000000..7789e82 --- /dev/null +++ b/xrena.h @@ -0,0 +1,110 @@ +/// __ ___ __ ___ _ __ __ _ +/// \ \/ / '__/ _ \ '_ \ / _` | +/// > <| | | __/ | | | (_| | +/// /_/\_\_| \___|_| |_|\__,_| +/// +/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic +/// +/// xolatile@chud.cyou - xrena - Probably the most minimalistic arena allocator possible, and undoubtedly evil in implementation details. +/// +/// 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... + +#ifndef arena_block_limit +#define arena_block_limit (1024 * 1024) +#endif + +static struct { + natural_64 block_count; + natural_64 block_limit; + struct { + natural_64 count; + natural_64 capacity; + character * buffer; + } * * block_array; +} * arena = null; + +static procedure arena_initialize (none) { + natural_64 current = ++arena->block_count - 1; + + arena->block_limit = arena_block_limit; + + arena->block_array = reallocate (arena->block_array, arena->block_count * sizeof (* arena->block_array)); + + arena->block_array [current] = allocate (sizeof (* arena)); + + arena->block_array [current]->buffer = allocate (arena_block_limit); + arena->block_array [current]->count = 0; + arena->block_array [current]->capacity = arena_block_limit; +} + +static procedure arena_deinitialize (none) { + for (natural_64 index = 0; index < arena->block_count; ++index) { + arena->block_array [index]->buffer = deallocate (arena->block_array [index]->buffer); + arena->block_array [index] = deallocate (arena->block_array [index]); + } + + arena->block_array = deallocate (arena->block_array); + arena = deallocate (arena); +} + +static generic * arena_add (natural_64 size) { + natural_64 current = arena->block_count - 1; + + if (arena == null) { + clean_up (arena_deinitialize); + + arena = allocate (sizeof (* arena)); + + arena_initialize (); + } + + fatal_failure (size > arena->block_limit, "arena_add: Block limit reached."); + + if (arena->block_array [current]->count + size > arena->block_array [current]->capacity) { + arena_initialize (); + } + + arena->block_array [current]->count += size; + + return ((v0*) & arena->block_array [current]->buffer [arena->block_array [current]->count - size]); +} + +static character * arena_add_data (generic * data, natural_64 size) { + generic * pointer = arena_add (size); + + memory_copy (pointer, data, size); + + return (pointer); +} + +static character * arena_add_file (character * path, natural flag, boolean null_terminate) { + integer file = -1; + natural_64 size = 0; + character * data = null; + + file = file_open (path, flag); + size = file_size (path) + (natural_64) null_terminate; + data = arena_add (size); + + file_read (file, data, size - (natural_64) null_terminate); + + file = file_close (file); + + return (data); +} + +static natural_64 arena_usage (none) { + natural_64 usage = 0; + + for (natural_64 block = 0; block < arena->block_count; ++block) { + usage += arena->block_array [block]->count; + } + + return (usage); +} +