/* baslib (agora-basic) - Agora Basic runtime library Written by Antti-Juhani Kaijanaho You may treat this file as if it were in the public domain. The author can be contacted using the email address antti-juhani@kaijanaho.fi or by snail mail to (as of June 2006) Antti-Juhani Kaijanaho Sienitie 2 B 27 40640 JYVÄSKYLÄ FINLAND (Note that the email address is more likely to stay current.) */ #include #include #include #include #if defined(__GNUC__) # define ATTRIBUTE(x) __attribute__(x) #else # define ATTRIBUTE(x) /**/ #endif extern const char *bas_argv0; extern uintmax_t bas_lineno; extern int error_code; extern int agora_compiler; static inline _Bool bas_throw(int code ATTRIBUTE((unused))) { error_code = code; return !agora_compiler; } typedef struct bas_dim { intmax_t lo; intmax_t hi; } bas_dim_t; #define BAS_PRECISION 7 struct bas_number { _Bool negative : 1; int exponent : 7; unsigned mantissa : 24; }; size_t bas_index_dn(struct bas_number, bas_dim_t); size_t bas_index_nn(double, bas_dim_t); struct bas_number bas_normalize_dn(intmax_t f, intmax_t e); struct bas_number bas_add_dn(const struct bas_number u, const struct bas_number v); struct bas_number bas_mul_dn(const struct bas_number u, const struct bas_number v); struct bas_number bas_div_dn(const struct bas_number u, const struct bas_number v); void bas_print_dn(struct bas_number a); #define BAS_STR_CHARDATA 0 #define BAS_STR_CONCAT 1 #define BAS_STR_SUBSTR 2 struct bas_string { unsigned short refcount; unsigned short mode; // BAS_STR_* size_t length; union { struct { _Bool malloced; char *cs; } chardata; struct { size_t n, maxn; struct bas_string **vec; } concat; struct { struct bas_string *base; size_t start; } substr; } u; }; typedef struct bas_string *bas_string_t; void bas_kill_str(bas_string_t); bas_string_t bas_concat_str(bas_string_t a, bas_string_t b); bas_string_t bas_null_str(void); void bas_assign_substr(bas_string_t *tgt, bas_string_t src, size_t start, size_t end); void bas_take_substring(bas_string_t *tgt, size_t start, size_t end); static inline void bas_unref(bas_string_t s) { if (s == NULL) return; assert(s->refcount > 0); if (--s->refcount == 0) bas_kill_str(s); } extern unsigned bas_print_currcol; extern unsigned bas_print_margin; extern unsigned bas_print_zone; static inline void bas_print_eol(void) { putchar('\n'); bas_print_currcol = 1; } static inline void bas_print_comma(void) { unsigned tab = bas_print_zone - bas_print_currcol % bas_print_zone; if (bas_print_currcol + tab >= bas_print_margin) { putchar('\n'); bas_print_currcol = 1; } else { for (size_t i = 0; i < tab; i++) { putchar(' '); } bas_print_currcol += tab; } } void bas_print_str(bas_string_t); /********************************************************************* INTRINSICS *********************************************************************/