diff options
58 files changed, 2622 insertions, 2589 deletions
@@ -20,7 +20,7 @@ include config.mk CC=cc CCONFIG=-std=c2x -fPIC \ -fno-signed-zeros -fno-finite-math-only -fno-trapping-math \ - -fvisibility=hidden -fdollars-in-identifiers \ + -fvisibility=hidden \ -DGC_THREADS LTO= LDFLAGS= diff --git a/lib/commands/commands.c b/lib/commands/commands.c index 1e9afe8e..b8d08d4b 100644 --- a/lib/commands/commands.c +++ b/lib/commands/commands.c @@ -62,13 +62,13 @@ int run_command(Text_t exe, List_t arg_list, Table_t env_table, posix_spawn_file_actions_addclose(&actions, child_errpipe[READ_END]); } - const char *exe_str = Text$as_c_string(exe); + const char *exe_str = Textヽas_c_string(exe); List_t arg_strs = {}; - List$insert_value(&arg_strs, exe_str, I(0), sizeof(char*)); + Listヽinsert_value(&arg_strs, exe_str, I(0), sizeof(char*)); for (int64_t i = 0; i < arg_list.length; i++) - List$insert_value(&arg_strs, Text$as_c_string(*(Text_t*)(arg_list.data + i*arg_list.stride)), I(0), sizeof(char*)); - List$insert_value(&arg_strs, NULL, I(0), sizeof(char*)); + Listヽinsert_value(&arg_strs, Textヽas_c_string(*(Text_t*)(arg_list.data + i*arg_list.stride)), I(0), sizeof(char*)); + Listヽinsert_value(&arg_strs, NULL, I(0), sizeof(char*)); char **args = arg_strs.data; extern char **environ; @@ -76,14 +76,14 @@ int run_command(Text_t exe, List_t arg_list, Table_t env_table, if (env_table.entries.length > 0) { List_t env_list = {}; // List of const char* for (char **e = environ; *e; e++) - List$insert(&env_list, e, I(0), sizeof(char*)); + Listヽinsert(&env_list, e, I(0), sizeof(char*)); for (int64_t i = 0; i < env_table.entries.length; i++) { struct { Text_t key, value; } *entry = env_table.entries.data + env_table.entries.stride*i; const char *env_entry = String(entry->key, "=", entry->value); - List$insert(&env_list, &env_entry, I(0), sizeof(char*)); + Listヽinsert(&env_list, &env_entry, I(0), sizeof(char*)); } - List$insert_value(&env_list, NULL, I(0), sizeof(char*)); + Listヽinsert_value(&env_list, NULL, I(0), sizeof(char*)); assert(env_list.stride == sizeof(char*)); env = env_list.data; } @@ -108,7 +108,7 @@ int run_command(Text_t exe, List_t arg_list, Table_t env_table, if (error_bytes) pollfds[2] = (struct pollfd){.fd=child_errpipe[WRITE_END], .events=POLLIN}; if (input_bytes.length > 0 && input_bytes.stride != 1) - List$compact(&input_bytes, sizeof(char)); + Listヽcompact(&input_bytes, sizeof(char)); if (output_bytes) *output_bytes = (List_t){.atomic=1, .stride=1, .length=0}; if (error_bytes) @@ -225,7 +225,7 @@ static Text_t _next_line(child_info_t *child) if (u8_check((uint8_t*)line, (size_t)len) != NULL) fail("Invalid UTF8!"); - Text_t line_text = Text$from_strn(line, len); + Text_t line_text = Textヽfrom_strn(line, len); free(line); return line_text; } @@ -243,13 +243,13 @@ OptionalClosure_t command_by_line(Text_t exe, List_t arg_list, Table_t env_table posix_spawn_file_actions_adddup2(&actions, child_outpipe[WRITE_END], STDOUT_FILENO); posix_spawn_file_actions_addclose(&actions, child_outpipe[READ_END]); - const char *exe_str = Text$as_c_string(exe); + const char *exe_str = Textヽas_c_string(exe); List_t arg_strs = {}; - List$insert_value(&arg_strs, exe_str, I(0), sizeof(char*)); + Listヽinsert_value(&arg_strs, exe_str, I(0), sizeof(char*)); for (int64_t i = 0; i < arg_list.length; i++) - List$insert_value(&arg_strs, Text$as_c_string(*(Text_t*)(arg_list.data + i*arg_list.stride)), I(0), sizeof(char*)); - List$insert_value(&arg_strs, NULL, I(0), sizeof(char*)); + Listヽinsert_value(&arg_strs, Textヽas_c_string(*(Text_t*)(arg_list.data + i*arg_list.stride)), I(0), sizeof(char*)); + Listヽinsert_value(&arg_strs, NULL, I(0), sizeof(char*)); char **args = arg_strs.data; extern char **environ; @@ -257,14 +257,14 @@ OptionalClosure_t command_by_line(Text_t exe, List_t arg_list, Table_t env_table if (env_table.entries.length > 0) { List_t env_list = {}; // List of const char* for (char **e = environ; *e; e++) - List$insert(&env_list, e, I(0), sizeof(char*)); + Listヽinsert(&env_list, e, I(0), sizeof(char*)); for (int64_t i = 0; i < env_table.entries.length; i++) { struct { Text_t key, value; } *entry = env_table.entries.data + env_table.entries.stride*i; const char *env_entry = String(entry->key, "=", entry->value); - List$insert(&env_list, &env_entry, I(0), sizeof(char*)); + Listヽinsert(&env_list, &env_entry, I(0), sizeof(char*)); } - List$insert_value(&env_list, NULL, I(0), sizeof(char*)); + Listヽinsert_value(&env_list, NULL, I(0), sizeof(char*)); assert(env_list.stride == sizeof(char*)); env = env_list.data; } diff --git a/lib/core/core.tm b/lib/core/core.tm index 0b8aba53..5ed77756 100644 --- a/lib/core/core.tm +++ b/lib/core/core.tm @@ -1,7 +1,7 @@ # This file just uses all the most commonly used standard # library modules so you don't have to import them one-by-one -use patterns_v1.0 +use patterns_v1.1 use commands_v1.0 use shell_v1.0 use pthreads_v1.0 diff --git a/lib/patterns/patterns.c b/lib/patterns/patterns.c index 224a00a0..5df1047c 100644 --- a/lib/patterns/patterns.c +++ b/lib/patterns/patterns.c @@ -48,7 +48,7 @@ static Text_t replace_list(Text_t text, List_t replacements, Text_t backref_pat, static INLINE void skip_whitespace(TextIter_t *state, int64_t *i) { while (*i < state->stack[0].text.length) { - int32_t grapheme = Text$get_grapheme_fast(state, *i); + int32_t grapheme = Textヽget_grapheme_fast(state, *i); if (grapheme > 0 && !uc_is_property_white_space((ucs4_t)grapheme)) return; *i += 1; @@ -57,7 +57,7 @@ static INLINE void skip_whitespace(TextIter_t *state, int64_t *i) static INLINE bool match_grapheme(TextIter_t *state, int64_t *i, int32_t grapheme) { - if (*i < state->stack[0].text.length && Text$get_grapheme_fast(state, *i) == grapheme) { + if (*i < state->stack[0].text.length && Textヽget_grapheme_fast(state, *i) == grapheme) { *i += 1; return true; } @@ -68,7 +68,7 @@ static INLINE bool match_str(TextIter_t *state, int64_t *i, const char *str) { int64_t matched = 0; while (matched[str]) { - if (*i + matched >= state->stack[0].text.length || Text$get_grapheme_fast(state, *i + matched) != str[matched]) + if (*i + matched >= state->stack[0].text.length || Textヽget_grapheme_fast(state, *i + matched) != str[matched]) return false; matched += 1; } @@ -80,7 +80,7 @@ static int64_t parse_int(TextIter_t *state, int64_t *i) { int64_t value = 0; for (;; *i += 1) { - uint32_t grapheme = Text$get_main_grapheme_fast(state, *i); + uint32_t grapheme = Textヽget_main_grapheme_fast(state, *i); int digit = uc_digit_value(grapheme); if (digit < 0) break; if (value >= INT64_MAX/10) break; @@ -95,7 +95,7 @@ static const char *get_property_name(TextIter_t *state, int64_t *i) char *name = GC_MALLOC_ATOMIC(UNINAME_MAX); char *dest = name; while (*i < state->stack[0].text.length) { - int32_t grapheme = Text$get_grapheme_fast(state, *i); + int32_t grapheme = Textヽget_grapheme_fast(state, *i); if (!(grapheme & ~0xFF) && (isalnum(grapheme) || grapheme == ' ' || grapheme == '_' || grapheme == '-')) { *dest = (char)grapheme; ++dest; @@ -116,16 +116,16 @@ static const char *get_property_name(TextIter_t *state, int64_t *i) } #define EAT1(state, index, cond) ({\ - int32_t grapheme = Text$get_grapheme_fast(state, index); \ + int32_t grapheme = Textヽget_grapheme_fast(state, index); \ bool success = (cond); \ if (success) index += 1; \ success; }) #define EAT2(state, index, cond1, cond2) ({\ - int32_t grapheme = Text$get_grapheme_fast(state, index); \ + int32_t grapheme = Textヽget_grapheme_fast(state, index); \ bool success = (cond1); \ if (success) { \ - grapheme = Text$get_grapheme_fast(state, index + 1); \ + grapheme = Textヽget_grapheme_fast(state, index + 1); \ success = (cond2); \ if (success) \ index += 2; \ @@ -138,12 +138,12 @@ static const char *get_property_name(TextIter_t *state, int64_t *i) static int64_t match_email(TextIter_t *state, int64_t index) { // email = local "@" domain - // local = 1-64 ([a-zA-Z0-9!#$%&‘*+–/=?^_`.{|}~] | non-ascii) + // local = 1-64 ([a-zA-Z0-9!#ヽ%&‘*+–/=?^_`.{|}~] | non-ascii) // domain = dns-label ("." dns-label)* // dns-label = 1-63 ([a-zA-Z0-9-] | non-ascii) if (index > 0) { - uint32_t prev_codepoint = Text$get_main_grapheme_fast(state, index - 1); + uint32_t prev_codepoint = Textヽget_main_grapheme_fast(state, index - 1); if (uc_is_property_alphabetic(prev_codepoint)) return -1; } @@ -187,7 +187,7 @@ static int64_t match_email(TextIter_t *state, int64_t index) static int64_t match_ipv6(TextIter_t *state, int64_t index) { if (index > 0) { - int32_t prev_codepoint = Text$get_grapheme_fast(state, index - 1); + int32_t prev_codepoint = Textヽget_grapheme_fast(state, index - 1); if ((prev_codepoint & ~0x7F) && (isxdigit(prev_codepoint) || prev_codepoint == ':')) return -1; } @@ -222,7 +222,7 @@ static int64_t match_ipv6(TextIter_t *state, int64_t index) static int64_t match_ipv4(TextIter_t *state, int64_t index) { if (index > 0) { - int32_t prev_codepoint = Text$get_grapheme_fast(state, index - 1); + int32_t prev_codepoint = Textヽget_grapheme_fast(state, index - 1); if ((prev_codepoint & ~0x7F) && (isdigit(prev_codepoint) || prev_codepoint == '.')) return -1; } @@ -310,7 +310,7 @@ static int64_t match_uri(TextIter_t *state, int64_t index) if (index > 0) { // Don't match if we're not at a word edge: - uint32_t prev_codepoint = Text$get_main_grapheme_fast(state, index - 1); + uint32_t prev_codepoint = Textヽget_main_grapheme_fast(state, index - 1); if (uc_is_property_alphabetic(prev_codepoint)) return -1; } @@ -408,10 +408,10 @@ static int64_t match_newline(TextIter_t *state, int64_t index) if (index >= state->stack[0].text.length) return -1; - uint32_t grapheme = index >= state->stack[0].text.length ? 0 : Text$get_main_grapheme_fast(state, index); + uint32_t grapheme = index >= state->stack[0].text.length ? 0 : Textヽget_main_grapheme_fast(state, index); if (grapheme == '\n') return 1; - if (grapheme == '\r' && Text$get_grapheme_fast(state, index + 1) == '\n') + if (grapheme == '\r' && Textヽget_grapheme_fast(state, index + 1) == '\n') return 2; return -1; } @@ -419,7 +419,7 @@ static int64_t match_newline(TextIter_t *state, int64_t index) static int64_t match_pat(TextIter_t *state, int64_t index, pat_t pat) { Text_t text = state->stack[0].text; - int32_t grapheme = index >= text.length ? 0 : Text$get_grapheme_fast(state, index); + int32_t grapheme = index >= text.length ? 0 : Textヽget_grapheme_fast(state, index); switch (pat.tag) { case PAT_START: { @@ -466,7 +466,7 @@ static int64_t match_pat(TextIter_t *state, int64_t index, pat_t pat) if (index + match_len >= text.length) return pat.negated ? 1 : -1; - int32_t c = Text$get_grapheme_fast(state, index + match_len); + int32_t c = Textヽget_grapheme_fast(state, index + match_len); if (c == open) depth += 1; else if (c == close) @@ -485,7 +485,7 @@ static int64_t match_pat(TextIter_t *state, int64_t index, pat_t pat) int32_t close = pat.quote_graphemes[1]; for (int64_t i = index + 1; i < text.length; i++) { - int32_t c = Text$get_grapheme_fast(state, i); + int32_t c = Textヽget_grapheme_fast(state, i); if (c == close) { return pat.negated ? -1 : (i - index) + 1; } else if (c == '\\' && index + 1 < text.length) { @@ -512,7 +512,7 @@ static pat_t parse_next_pat(TextIter_t *state, int64_t *index) uc_is_property((ucs4_t)grapheme, UC_PROPERTY_QUOTATION_MARK), grapheme == '?')) { // Quotations: "?", '?', etc - int32_t open = Text$get_grapheme_fast(state, *index-2); + int32_t open = Textヽget_grapheme_fast(state, *index-2); int32_t close = open; uc_mirror_char((ucs4_t)open, (ucs4_t*)&close); if (!match_grapheme(state, index, close)) @@ -527,7 +527,7 @@ static pat_t parse_next_pat(TextIter_t *state, int64_t *index) uc_is_property((ucs4_t)grapheme, UC_PROPERTY_PAIRED_PUNCTUATION), grapheme == '?')) { // Nested punctuation: (?), [?], etc - int32_t open = Text$get_grapheme_fast(state, *index-2); + int32_t open = Textヽget_grapheme_fast(state, *index-2); int32_t close = open; uc_mirror_char((ucs4_t)open, (ucs4_t*)&close); if (!match_grapheme(state, index, close)) @@ -541,7 +541,7 @@ static pat_t parse_next_pat(TextIter_t *state, int64_t *index) } else if (EAT1(state, *index, grapheme == '{')) { // named patterns {id}, {2-3 hex}, etc. skip_whitespace(state, index); int64_t min, max; - if (uc_is_digit((ucs4_t)Text$get_grapheme_fast(state, *index))) { + if (uc_is_digit((ucs4_t)Textヽget_grapheme_fast(state, *index))) { min = parse_int(state, index); skip_whitespace(state, index); if (match_grapheme(state, index, '+')) { @@ -569,7 +569,7 @@ static pat_t parse_next_pat(TextIter_t *state, int64_t *index) if (!prop_name) { // Literal character, e.g. {1?} skip_whitespace(state, index); - int32_t grapheme = Text$get_grapheme_fast(state, (*index)++); + int32_t grapheme = Textヽget_grapheme_fast(state, (*index)++); if (!match_grapheme(state, index, '}')) fail("Missing closing '}' in pattern: ", state->stack[0].text); return PAT(PAT_GRAPHEME, .grapheme=grapheme); @@ -680,7 +680,7 @@ static pat_t parse_next_pat(TextIter_t *state, int64_t *index) return PAT(PAT_GRAPHEME, .grapheme=(int32_t)grapheme); #undef PAT } else { - return (pat_t){.tag=PAT_GRAPHEME, .non_capturing=true, .min=1, .max=1, .grapheme=Text$get_grapheme_fast(state, (*index)++)}; + return (pat_t){.tag=PAT_GRAPHEME, .non_capturing=true, .min=1, .max=1, .grapheme=Textヽget_grapheme_fast(state, (*index)++)}; } } @@ -786,7 +786,7 @@ static int64_t match(Text_t text, int64_t text_index, Text_t pattern, int64_t pa static int64_t _find(Text_t text, Text_t pattern, int64_t first, int64_t last, int64_t *match_length, capture_t *captures) { - int32_t first_grapheme = Text$get_grapheme(pattern, 0); + int32_t first_grapheme = Textヽget_grapheme(pattern, 0); bool find_first = (first_grapheme != '{' && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_QUOTATION_MARK) && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_PAIRED_PUNCTUATION)); @@ -795,7 +795,7 @@ static int64_t _find(Text_t text, Text_t pattern, int64_t first, int64_t last, i for (int64_t i = first; i <= last; i++) { // Optimization: quickly skip ahead to first char in pattern: if (find_first) { - while (i < text.length && Text$get_grapheme_fast(&text_state, i) != first_grapheme) + while (i < text.length && Textヽget_grapheme_fast(&text_state, i) != first_grapheme) ++i; } @@ -813,7 +813,7 @@ static int64_t _find(Text_t text, Text_t pattern, int64_t first, int64_t last, i static OptionalPatternMatch find(Text_t text, Text_t pattern, Int_t from_index) { - int64_t first = Int64$from_int(from_index, false); + int64_t first = Int64ヽfrom_int(from_index, false); if (first == 0) fail("Invalid index: 0"); if (first < 0) first = text.length + first + 1; if (first > text.length || first < 1) @@ -827,22 +827,22 @@ static OptionalPatternMatch find(Text_t text, Text_t pattern, Int_t from_index) List_t capture_list = {}; for (int i = 0; captures[i].occupied; i++) { - Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); - List$insert(&capture_list, &capture, I(0), sizeof(Text_t)); + Text_t capture = Textヽslice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); + Listヽinsert(&capture_list, &capture, I(0), sizeof(Text_t)); } return (OptionalPatternMatch){ - .text=Text$slice(text, I(found+1), I(found+len)), + .text=Textヽslice(text, I(found+1), I(found+len)), .index=I(found+1), .captures=capture_list, }; } -PUREFUNC static bool Pattern$has(Text_t text, Text_t pattern) +PUREFUNC static bool Patternヽhas(Text_t text, Text_t pattern) { - if (Text$starts_with(pattern, Text("{start}"), &pattern)) { + if (Textヽstarts_with(pattern, Text("{start}"), &pattern)) { int64_t m = match(text, 0, pattern, 0, NULL, 0); return m >= 0; - } else if (Text$ends_with(text, Text("{end}"), NULL)) { + } else if (Textヽends_with(text, Text("{end}"), NULL)) { for (int64_t i = text.length-1; i >= 0; i--) { int64_t match_len = match(text, i, pattern, 0, NULL, 0); if (match_len >= 0 && i + match_len == text.length) @@ -855,16 +855,16 @@ PUREFUNC static bool Pattern$has(Text_t text, Text_t pattern) } } -static bool Pattern$matches(Text_t text, Text_t pattern) +static bool Patternヽmatches(Text_t text, Text_t pattern) { capture_t captures[MAX_BACKREFS] = {}; int64_t match_len = match(text, 0, pattern, 0, NULL, 0); return (match_len == text.length); } -static bool Pattern$match_at(Text_t text, Text_t pattern, Int_t pos, PatternMatch *dest) +static bool Patternヽmatch_at(Text_t text, Text_t pattern, Int_t pos, PatternMatch *dest) { - int64_t start = Int64$from_int(pos, false) - 1; + int64_t start = Int64ヽfrom_int(pos, false) - 1; capture_t captures[MAX_BACKREFS] = {}; int64_t match_len = match(text, start, pattern, 0, captures, 0); if (match_len < 0) @@ -872,16 +872,16 @@ static bool Pattern$match_at(Text_t text, Text_t pattern, Int_t pos, PatternMatc List_t capture_list = {}; for (int i = 0; captures[i].occupied; i++) { - Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); - List$insert(&capture_list, &capture, I(0), sizeof(Text_t)); + Text_t capture = Textヽslice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); + Listヽinsert(&capture_list, &capture, I(0), sizeof(Text_t)); } - dest->text = Text$slice(text, I(start+1), I(start+match_len)); + dest->text = Textヽslice(text, I(start+1), I(start+match_len)); dest->index = I(start+1); dest->captures = capture_list; return true; } -static OptionalList_t Pattern$captures(Text_t text, Text_t pattern) +static OptionalList_t Patternヽcaptures(Text_t text, Text_t pattern) { capture_t captures[MAX_BACKREFS] = {}; int64_t match_len = match(text, 0, pattern, 0, captures, 0); @@ -890,13 +890,13 @@ static OptionalList_t Pattern$captures(Text_t text, Text_t pattern) List_t capture_list = {}; for (int i = 0; captures[i].occupied; i++) { - Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); - List$insert(&capture_list, &capture, I(0), sizeof(Text_t)); + Text_t capture = Textヽslice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); + Listヽinsert(&capture_list, &capture, I(0), sizeof(Text_t)); } return capture_list; } -static List_t Pattern$find_all(Text_t text, Text_t pattern) +static List_t Patternヽfind_all(Text_t text, Text_t pattern) { if (pattern.length == 0) // special case return (List_t){.length=0}; @@ -906,8 +906,8 @@ static List_t Pattern$find_all(Text_t text, Text_t pattern) OptionalPatternMatch m = find(text, pattern, I(i)); if (m.is_none) break; - i = Int64$from_int(m.index, false) + m.text.length; - List$insert(&matches, &m, I_small(0), sizeof(PatternMatch)); + i = Int64ヽfrom_int(m.index, false) + m.text.length; + Listヽinsert(&matches, &m, I_small(0), sizeof(PatternMatch)); } return matches; } @@ -920,18 +920,18 @@ typedef struct { static OptionalPatternMatch next_match(match_iter_state_t *state) { - if (Int64$from_int(state->i, false) > state->state.stack[0].text.length) + if (Int64ヽfrom_int(state->i, false) > state->state.stack[0].text.length) return NONE_MATCH; OptionalPatternMatch m = find(state->state.stack[0].text, state->pattern, state->i); if (m.is_none) // No match state->i = I(state->state.stack[0].text.length + 1); else - state->i = Int$plus(m.index, I(MAX(1, m.text.length))); + state->i = Intヽplus(m.index, I(MAX(1, m.text.length))); return m; } -static Closure_t Pattern$by_match(Text_t text, Text_t pattern) +static Closure_t Patternヽby_match(Text_t text, Text_t pattern) { return (Closure_t){ .fn=(void*)next_match, @@ -944,7 +944,7 @@ static Text_t apply_backrefs(Text_t text, List_t recursive_replacements, Text_t if (backref_pat.length == 0) return replacement; - int32_t first_grapheme = Text$get_grapheme(backref_pat, 0); + int32_t first_grapheme = Textヽget_grapheme(backref_pat, 0); bool find_first = (first_grapheme != '{' && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_QUOTATION_MARK) && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_PAIRED_PUNCTUATION)); @@ -955,7 +955,7 @@ static Text_t apply_backrefs(Text_t text, List_t recursive_replacements, Text_t for (int64_t pos = 0; pos < replacement.length; ) { // Optimization: quickly skip ahead to first char in the backref pattern: if (find_first) { - while (pos < replacement.length && Text$get_grapheme_fast(&replacement_state, pos) != first_grapheme) + while (pos < replacement.length && Textヽget_grapheme_fast(&replacement_state, pos) != first_grapheme) ++pos; } @@ -974,39 +974,39 @@ static Text_t apply_backrefs(Text_t text, List_t recursive_replacements, Text_t if (backref < 0 || backref > 9) fail("Invalid backref index: ", backref, " (only 0-", MAX_BACKREFS-1, " are allowed)"); backref_len = (after_backref - pos); - if (Text$get_grapheme_fast(&replacement_state, pos + backref_len) == ';') + if (Textヽget_grapheme_fast(&replacement_state, pos + backref_len) == ';') backref_len += 1; // skip optional semicolon if (!captures[backref].occupied) fail("There is no capture number ", backref, "!"); - Text_t backref_text = Text$slice(text, I(captures[backref].index+1), I(captures[backref].index + captures[backref].length)); + Text_t backref_text = Textヽslice(text, I(captures[backref].index+1), I(captures[backref].index + captures[backref].length)); if (captures[backref].recursive && recursive_replacements.length > 0) backref_text = replace_list(backref_text, recursive_replacements, backref_pat, true); if (pos > nonmatching_pos) { - Text_t before_slice = Text$slice(replacement, I(nonmatching_pos+1), I(pos)); - ret = Text$concat(ret, before_slice, backref_text); + Text_t before_slice = Textヽslice(replacement, I(nonmatching_pos+1), I(pos)); + ret = Textヽconcat(ret, before_slice, backref_text); } else { - ret = Text$concat(ret, backref_text); + ret = Textヽconcat(ret, backref_text); } pos += backref_len; nonmatching_pos = pos; } if (nonmatching_pos < replacement.length) { - Text_t last_slice = Text$slice(replacement, I(nonmatching_pos+1), I(replacement.length)); - ret = Text$concat(ret, last_slice); + Text_t last_slice = Textヽslice(replacement, I(nonmatching_pos+1), I(replacement.length)); + ret = Textヽconcat(ret, last_slice); } return ret; } -static Text_t Pattern$replace(Text_t text, Text_t pattern, Text_t replacement, Text_t backref_pat, bool recursive) +static Text_t Patternヽreplace(Text_t text, Text_t pattern, Text_t replacement, Text_t backref_pat, bool recursive) { Text_t ret = EMPTY_TEXT; - int32_t first_grapheme = Text$get_grapheme(pattern, 0); + int32_t first_grapheme = Textヽget_grapheme(pattern, 0); bool find_first = (first_grapheme != '{' && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_QUOTATION_MARK) && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_PAIRED_PUNCTUATION)); @@ -1023,7 +1023,7 @@ static Text_t Pattern$replace(Text_t text, Text_t pattern, Text_t replacement, T for (int64_t pos = 0; pos < text.length; ) { // Optimization: quickly skip ahead to first char in pattern: if (find_first) { - while (pos < text.length && Text$get_grapheme_fast(&text_state, pos) != first_grapheme) + while (pos < text.length && Textヽget_grapheme_fast(&text_state, pos) != first_grapheme) ++pos; } @@ -1040,22 +1040,22 @@ static Text_t Pattern$replace(Text_t text, Text_t pattern, Text_t replacement, T Text_t replacement_text = apply_backrefs(text, recursive ? replacements : (List_t){}, replacement, backref_pat, captures); if (pos > nonmatching_pos) { - Text_t before_slice = Text$slice(text, I(nonmatching_pos+1), I(pos)); - ret = Text$concat(ret, before_slice, replacement_text); + Text_t before_slice = Textヽslice(text, I(nonmatching_pos+1), I(pos)); + ret = Textヽconcat(ret, before_slice, replacement_text); } else { - ret = Text$concat(ret, replacement_text); + ret = Textヽconcat(ret, replacement_text); } nonmatching_pos = pos + match_len; pos += MAX(match_len, 1); } if (nonmatching_pos < text.length) { - Text_t last_slice = Text$slice(text, I(nonmatching_pos+1), I(text.length)); - ret = Text$concat(ret, last_slice); + Text_t last_slice = Textヽslice(text, I(nonmatching_pos+1), I(text.length)); + ret = Textヽconcat(ret, last_slice); } return ret; } -static Text_t Pattern$trim(Text_t text, Text_t pattern, bool trim_left, bool trim_right) +static Text_t Patternヽtrim(Text_t text, Text_t pattern, bool trim_left, bool trim_right) { int64_t first = 0, last = text.length-1; if (trim_left) { @@ -1071,14 +1071,14 @@ static Text_t Pattern$trim(Text_t text, Text_t pattern, bool trim_left, bool tri last = i-1; } } - return Text$slice(text, I(first+1), I(last+1)); + return Textヽslice(text, I(first+1), I(last+1)); } -static Text_t Pattern$map(Text_t text, Text_t pattern, Closure_t fn, bool recursive) +static Text_t Patternヽmap(Text_t text, Text_t pattern, Closure_t fn, bool recursive) { Text_t ret = EMPTY_TEXT; - int32_t first_grapheme = Text$get_grapheme(pattern, 0); + int32_t first_grapheme = Textヽget_grapheme(pattern, 0); bool find_first = (first_grapheme != '{' && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_QUOTATION_MARK) && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_PAIRED_PUNCTUATION)); @@ -1090,7 +1090,7 @@ static Text_t Pattern$map(Text_t text, Text_t pattern, Closure_t fn, bool recurs for (int64_t pos = 0; pos < text.length; pos++) { // Optimization: quickly skip ahead to first char in pattern: if (find_first) { - while (pos < text.length && Text$get_grapheme_fast(&text_state, pos) != first_grapheme) + while (pos < text.length && Textヽget_grapheme_fast(&text_state, pos) != first_grapheme) ++pos; } @@ -1099,37 +1099,37 @@ static Text_t Pattern$map(Text_t text, Text_t pattern, Closure_t fn, bool recurs if (match_len < 0) continue; PatternMatch m = { - .text=Text$slice(text, I(pos+1), I(pos+match_len)), + .text=Textヽslice(text, I(pos+1), I(pos+match_len)), .index=I(pos+1), .captures={}, }; for (int i = 0; captures[i].occupied; i++) { - Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); + Text_t capture = Textヽslice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); if (recursive) - capture = Pattern$map(capture, pattern, fn, recursive); - List$insert(&m.captures, &capture, I(0), sizeof(Text_t)); + capture = Patternヽmap(capture, pattern, fn, recursive); + Listヽinsert(&m.captures, &capture, I(0), sizeof(Text_t)); } Text_t replacement = text_mapper(m, fn.userdata); if (pos > nonmatching_pos) { - Text_t before_slice = Text$slice(text, I(nonmatching_pos+1), I(pos)); - ret = Text$concat(ret, before_slice, replacement); + Text_t before_slice = Textヽslice(text, I(nonmatching_pos+1), I(pos)); + ret = Textヽconcat(ret, before_slice, replacement); } else { - ret = Text$concat(ret, replacement); + ret = Textヽconcat(ret, replacement); } nonmatching_pos = pos + match_len; pos += (match_len - 1); } if (nonmatching_pos < text.length) { - Text_t last_slice = Text$slice(text, I(nonmatching_pos+1), I(text.length)); - ret = Text$concat(ret, last_slice); + Text_t last_slice = Textヽslice(text, I(nonmatching_pos+1), I(text.length)); + ret = Textヽconcat(ret, last_slice); } return ret; } -static void Pattern$each(Text_t text, Text_t pattern, Closure_t fn, bool recursive) +static void Patternヽeach(Text_t text, Text_t pattern, Closure_t fn, bool recursive) { - int32_t first_grapheme = Text$get_grapheme(pattern, 0); + int32_t first_grapheme = Textヽget_grapheme(pattern, 0); bool find_first = (first_grapheme != '{' && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_QUOTATION_MARK) && !uc_is_property((ucs4_t)first_grapheme, UC_PROPERTY_PAIRED_PUNCTUATION)); @@ -1139,7 +1139,7 @@ static void Pattern$each(Text_t text, Text_t pattern, Closure_t fn, bool recursi for (int64_t pos = 0; pos < text.length; pos++) { // Optimization: quickly skip ahead to first char in pattern: if (find_first) { - while (pos < text.length && Text$get_grapheme_fast(&text_state, pos) != first_grapheme) + while (pos < text.length && Textヽget_grapheme_fast(&text_state, pos) != first_grapheme) ++pos; } @@ -1148,15 +1148,15 @@ static void Pattern$each(Text_t text, Text_t pattern, Closure_t fn, bool recursi if (match_len < 0) continue; PatternMatch m = { - .text=Text$slice(text, I(pos+1), I(pos+match_len)), + .text=Textヽslice(text, I(pos+1), I(pos+match_len)), .index=I(pos+1), .captures={}, }; for (int i = 0; captures[i].occupied; i++) { - Text_t capture = Text$slice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); + Text_t capture = Textヽslice(text, I(captures[i].index+1), I(captures[i].index+captures[i].length)); if (recursive) - Pattern$each(capture, pattern, fn, recursive); - List$insert(&m.captures, &capture, I(0), sizeof(Text_t)); + Patternヽeach(capture, pattern, fn, recursive); + Listヽinsert(&m.captures, &capture, I(0), sizeof(Text_t)); } action(m, fn.userdata); @@ -1183,14 +1183,14 @@ Text_t replace_list(Text_t text, List_t replacements, Text_t backref_pat, bool r // If we skipped over some non-matching text before finding a match, insert it here: if (pos > nonmatch_pos) { - Text_t before_slice = Text$slice(text, I(nonmatch_pos+1), I(pos)); - ret = Text$concat(ret, before_slice); + Text_t before_slice = Textヽslice(text, I(nonmatch_pos+1), I(pos)); + ret = Textヽconcat(ret, before_slice); } // Concatenate the replacement: Text_t replacement = *(Text_t*)(replacements.data + i*replacements.stride + sizeof(Text_t)); Text_t replacement_text = apply_backrefs(text, recursive ? replacements : (List_t){}, replacement, backref_pat, captures); - ret = Text$concat(ret, replacement_text); + ret = Textヽconcat(ret, replacement_text); pos += MAX(len, 1); nonmatch_pos = pos; goto next_pos; @@ -1202,24 +1202,24 @@ Text_t replace_list(Text_t text, List_t replacements, Text_t backref_pat, bool r } if (nonmatch_pos <= text.length) { - Text_t last_slice = Text$slice(text, I(nonmatch_pos+1), I(text.length)); - ret = Text$concat(ret, last_slice); + Text_t last_slice = Textヽslice(text, I(nonmatch_pos+1), I(text.length)); + ret = Textヽconcat(ret, last_slice); } return ret; } -static Text_t Pattern$replace_all(Text_t text, Table_t replacements, Text_t backref_pat, bool recursive) +static Text_t Patternヽreplace_all(Text_t text, Table_t replacements, Text_t backref_pat, bool recursive) { return replace_list(text, replacements.entries, backref_pat, recursive); } -static List_t Pattern$split(Text_t text, Text_t pattern) +static List_t Patternヽsplit(Text_t text, Text_t pattern) { if (text.length == 0) // special case return (List_t){.length=0}; if (pattern.length == 0) // special case - return Text$clusters(text); + return Textヽclusters(text); List_t chunks = {}; @@ -1230,13 +1230,13 @@ static List_t Pattern$split(Text_t text, Text_t pattern) if (found == i && len == 0) found = _find(text, pattern, i + 1, text.length-1, &len, NULL); if (found < 0) break; - Text_t chunk = Text$slice(text, I(i+1), I(found)); - List$insert(&chunks, &chunk, I_small(0), sizeof(Text_t)); + Text_t chunk = Textヽslice(text, I(i+1), I(found)); + Listヽinsert(&chunks, &chunk, I_small(0), sizeof(Text_t)); i = MAX(found + len, i + 1); } - Text_t last_chunk = Text$slice(text, I(i+1), I(text.length)); - List$insert(&chunks, &last_chunk, I_small(0), sizeof(Text_t)); + Text_t last_chunk = Textヽslice(text, I(i+1), I(text.length)); + Listヽinsert(&chunks, &last_chunk, I_small(0), sizeof(Text_t)); return chunks; } @@ -1259,7 +1259,7 @@ static OptionalText_t next_split(split_iter_state_t *state) } if (state->pattern.length == 0) { // special case - Text_t ret = Text$cluster(text, I(state->i+1)); + Text_t ret = Textヽcluster(text, I(state->i+1)); state->i += 1; return ret; } @@ -1273,14 +1273,14 @@ static OptionalText_t next_split(split_iter_state_t *state) if (found >= 0) { state->i = MAX(found + len, state->i + 1); - return Text$slice(text, I(start+1), I(found)); + return Textヽslice(text, I(start+1), I(found)); } else { state->i = state->state.stack[0].text.length + 1; - return Text$slice(text, I(start+1), I(text.length)); + return Textヽslice(text, I(start+1), I(text.length)); } } -static Closure_t Pattern$by_split(Text_t text, Text_t pattern) +static Closure_t Patternヽby_split(Text_t text, Text_t pattern) { return (Closure_t){ .fn=(void*)next_split, @@ -1288,34 +1288,34 @@ static Closure_t Pattern$by_split(Text_t text, Text_t pattern) }; } -static Text_t Pattern$escape_text(Text_t text) +static Text_t Patternヽescape_text(Text_t text) { // TODO: optimize for spans of non-escaped text Text_t ret = EMPTY_TEXT; TextIter_t state = NEW_TEXT_ITER_STATE(text); for (int64_t i = 0; i < text.length; i++) { - uint32_t g = Text$get_main_grapheme_fast(&state, i); + uint32_t g = Textヽget_main_grapheme_fast(&state, i); if (g == '{') { - ret = Text$concat(ret, Text("{1{}")); + ret = Textヽconcat(ret, Text("{1{}")); } else if (g == '?' || uc_is_property_quotation_mark(g) || (uc_is_property_paired_punctuation(g) && uc_is_property_left_of_pair(g))) { - ret = Text$concat(ret, Text("{1"), Text$slice(text, I(i+1), I(i+1)), Text("}")); + ret = Textヽconcat(ret, Text("{1"), Textヽslice(text, I(i+1), I(i+1)), Text("}")); } else { - ret = Text$concat(ret, Text$slice(text, I(i+1), I(i+1))); + ret = Textヽconcat(ret, Textヽslice(text, I(i+1), I(i+1))); } } return ret; } -static Text_t Pattern$as_text(const void *obj, bool colorize, const TypeInfo_t *info) +static Text_t Patternヽas_text(const void *obj, bool colorize, const TypeInfo_t *info) { (void)info; if (!obj) return Text("Pattern"); Text_t pat = *(Text_t*)obj; - Text_t quote = Pattern$has(pat, Text("/")) && !Pattern$has(pat, Text("|")) ? Text("|") : Text("/"); - return Text$concat(colorize ? Text("\x1b[1m$\033[m") : Text("$"), Text$quoted(pat, colorize, quote)); + Text_t quote = Patternヽhas(pat, Text("/")) && !Patternヽhas(pat, Text("|")) ? Text("|") : Text("/"); + return Textヽconcat(colorize ? Text("\x1b[1mヽ\033[m") : Text("ヽ"), Textヽquoted(pat, colorize, quote)); } // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/lib/patterns/patterns.tm b/lib/patterns/patterns.tm index c5444b86..bcc54460 100644 --- a/lib/patterns/patterns.tm +++ b/lib/patterns/patterns.tm @@ -4,7 +4,7 @@ struct PatternMatch(text:Text, index:Int, captures:[Text]) lang Pat convert(text:Text -> Pat) - return C_code:Pat(Pattern$escape_text(@text)) + return C_code:Pat(Patternヽescape_text(@text)) convert(n:Int -> Pat) return Pat.from_text("$n") @@ -12,45 +12,45 @@ lang Pat extend Text func matching_pattern(text:Text, pattern:Pat, pos:Int = 1 -> PatternMatch?) result : PatternMatch - if C_code:Bool(Pattern$match_at(@text, @pattern, @pos, (void*)&@result)) + if C_code:Bool(Patternヽmatch_at(@text, @pattern, @pos, (void*)&@result)) return result return none func matches_pattern(text:Text, pattern:Pat -> Bool) - return C_code:Bool(Pattern$matches(@text, @pattern)) + return C_code:Bool(Patternヽmatches(@text, @pattern)) func pattern_captures(text:Text, pattern:Pat -> [Text]?) - return C_code:[Text]?(Pattern$captures(@text, @pattern)) + return C_code:[Text]?(Patternヽcaptures(@text, @pattern)) func replace_pattern(text:Text, pattern:Pat, replacement:Text, backref="@", recursive=yes -> Text) - return C_code:Text(Pattern$replace(@text, @pattern, @replacement, @backref, @recursive)) + return C_code:Text(Patternヽreplace(@text, @pattern, @replacement, @backref, @recursive)) func translate_patterns(text:Text, replacements:{Pat=Text}, backref="@", recursive=yes -> Text) - return C_code:Text(Pattern$replace_all(@text, @replacements, @backref, @recursive)) + return C_code:Text(Patternヽreplace_all(@text, @replacements, @backref, @recursive)) func has_pattern(text:Text, pattern:Pat -> Bool) - return C_code:Bool(Pattern$has(@text, @pattern)) + return C_code:Bool(Patternヽhas(@text, @pattern)) func find_patterns(text:Text, pattern:Pat -> [PatternMatch]) - return C_code:[PatternMatch](Pattern$find_all(@text, @pattern)) + return C_code:[PatternMatch](Patternヽfind_all(@text, @pattern)) func by_pattern(text:Text, pattern:Pat -> func(->PatternMatch?)) - return C_code:func(->PatternMatch?)(Pattern$by_match(@text, @pattern)) + return C_code:func(->PatternMatch?)(Patternヽby_match(@text, @pattern)) func each_pattern(text:Text, pattern:Pat, fn:func(m:PatternMatch), recursive=yes) - C_code { Pattern$each(@text, @pattern, @fn, @recursive); } + C_code { Patternヽeach(@text, @pattern, @fn, @recursive); } func map_pattern(text:Text, pattern:Pat, fn:func(m:PatternMatch -> Text), recursive=yes -> Text) - return C_code:Text(Pattern$map(@text, @pattern, @fn, @recursive)) + return C_code:Text(Patternヽmap(@text, @pattern, @fn, @recursive)) func split_pattern(text:Text, pattern:Pat -> [Text]) - return C_code:[Text](Pattern$split(@text, @pattern)) + return C_code:[Text](Patternヽsplit(@text, @pattern)) func by_pattern_split(text:Text, pattern:Pat -> func(->Text?)) - return C_code:func(->Text?)(Pattern$by_split(@text, @pattern)) + return C_code:func(->Text?)(Patternヽby_split(@text, @pattern)) func trim_pattern(text:Text, pattern=$Pat"{space}", left=yes, right=yes -> Text) - return C_code:Text(Pattern$trim(@text, @pattern, @left, @right)) + return C_code:Text(Patternヽtrim(@text, @pattern, @left, @right)) func main() >> "Hello world".matching_pattern($Pat'{id}') diff --git a/lib/random/random.tm b/lib/random/random.tm index 107fad66..6e7240e7 100644 --- a/lib/random/random.tm +++ b/lib/random/random.tm @@ -216,7 +216,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret mpz_urandomm(r, gmp_rng, range_size); gmp_randclear(gmp_rng); - Int$plus(@min, Int$from_mpz(r)) + Intヽplus(@min, Intヽfrom_mpz(r)) ) diff --git a/lib/time/time.tm b/lib/time/time.tm index 456b5f08..82d7d9eb 100644 --- a/lib/time/time.tm +++ b/lib/time/time.tm @@ -24,7 +24,7 @@ struct Time(tv_sec:Int64, tv_usec:Int64; extern) char *zoneinfo = strstr(buf, "/zoneinfo/"); if (zoneinfo) - _local_timezone = Text$from_str(zoneinfo + strlen("/zoneinfo/")); + _local_timezone = Textヽfrom_str(zoneinfo + strlen("/zoneinfo/")); else fail("Could not resolve local tz!"); } @@ -46,17 +46,17 @@ struct Time(tv_sec:Int64, tv_usec:Int64; extern) WITH_TIMEZONE(@timezone, final_info = localtime_r(&time, &result)); static char buf[256]; size_t len = strftime(buf, sizeof(buf), String(@format), final_info); - Text$from_strn(buf, len) + Textヽfrom_strn(buf, len) ) func new(year,month,day:Int, hour=0, minute=0, second=0.0, timezone=Time.local_timezone() -> Time) return C_code : Time( struct tm info = { - .tm_min=Int32$from_int(@minute, false), - .tm_hour=Int32$from_int(@hour, false), - .tm_mday=Int32$from_int(@day, false), - .tm_mon=Int32$from_int(@month, false) - 1, - .tm_year=Int32$from_int(@year, false) - 1900, + .tm_min=Int32ヽfrom_int(@minute, false), + .tm_hour=Int32ヽfrom_int(@hour, false), + .tm_mday=Int32ヽfrom_int(@day, false), + .tm_mon=Int32ヽfrom_int(@month, false) - 1, + .tm_year=Int32ヽfrom_int(@year, false) - 1900, .tm_isdst=-1, }; @@ -154,9 +154,9 @@ struct Time(tv_sec:Int64, tv_usec:Int64; extern) struct tm info = {}; WITH_TIMEZONE(@timezone, localtime_r(&@t.tv_sec, &info)); - info.tm_mday += Int32$from_int(@days, false) + 7*Int32$from_int(@weeks, false); - info.tm_mon += Int32$from_int(@months, false); - info.tm_year += Int32$from_int(@years, false); + info.tm_mday += Int32ヽfrom_int(@days, false) + 7*Int32ヽfrom_int(@weeks, false); + info.tm_mon += Int32ヽfrom_int(@months, false); + info.tm_year += Int32ヽfrom_int(@years, false); time_t t = mktime(&info); (Time){ @@ -169,8 +169,8 @@ struct Time(tv_sec:Int64, tv_usec:Int64; extern) ret : Time? C_code { struct tm info = {.tm_isdst=-1}; - const char *str = Text$as_c_string(@text); - const char *fmt = Text$as_c_string(@format); + const char *str = Textヽas_c_string(@text); + const char *fmt = Textヽas_c_string(@format); if (strstr(fmt, "%Z")) fail("The %Z specifier is not supported for time parsing!"); diff --git a/lib/time/time_defs.h b/lib/time/time_defs.h index 30000983..ae2d009a 100644 --- a/lib/time/time_defs.h +++ b/lib/time/time_defs.h @@ -10,12 +10,12 @@ static INLINE Text_t num_format(long n, const char *unit) { if (n == 0) return Text("now"); - return Text$from_str(String((int64_t)labs(n), " ", unit, (n == -1 || n == 1) ? "" : "s", n <= 0 ? " ago" : " later")); + return Textヽfrom_str(String((int64_t)labs(n), " ", unit, (n == -1 || n == 1) ? "" : "s", n <= 0 ? " ago" : " later")); } static void set_local_timezone(Text_t tz) { - setenv("TZ", Text$as_c_string(tz), 1); + setenv("TZ", Textヽas_c_string(tz), 1); _local_timezone = tz; tzset(); } @@ -10,7 +10,7 @@ #include "stdlib/text.h" static Text_t quoted_text(const char *text) { - return Text$quoted(Text$from_str(text), false, Text("\"")); + return Textヽquoted(Textヽfrom_str(text), false, Text("\"")); } CONSTFUNC const char *binop_method_name(ast_e tag) { @@ -150,7 +150,7 @@ Text_t ast_to_sexp(ast_t *ast) T(Var, "(Var ", quoted_text(data.name), ")") T(Int, "(Int ", quoted_text(ast_source(ast)), ")") T(Num, "(Num ", quoted_text(ast_source(ast)), ")") - T(TextLiteral, Text$quoted(data.text, false, Text("\""))) + T(TextLiteral, Textヽquoted(data.text, false, Text("\""))) T(TextJoin, "(Text", data.lang ? Texts(" :lang ", quoted_text(data.lang)) : EMPTY_TEXT, ast_list_to_sexp(data.children), ")") T(Path, "(Path ", quoted_text(data.path), ")") T(Declare, "(Declare ", ast_to_sexp(data.var), " ", type_ast_to_sexp(data.type), " ", ast_to_sexp(data.value), ")") @@ -216,7 +216,7 @@ Text_t ast_to_sexp(ast_t *ast) const char *ast_to_sexp_str(ast_t *ast) { - return Text$as_c_string(ast_to_sexp(ast)); + return Textヽas_c_string(ast_to_sexp(ast)); } const char *ast_source(ast_t *ast) @@ -250,14 +250,14 @@ void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Clo void (*visit)(void*, ast_t*) = (void*)fn.fn; if (ast->tag == StructDef) { DeclareMatch(def, ast, StructDef); - if (Table$str_get(*visited, def->name)) + if (Tableヽstr_get(*visited, def->name)) return; - Table$str_set(visited, def->name, (void*)_visit_topologically); + Tableヽstr_set(visited, def->name, (void*)_visit_topologically); for (arg_ast_t *field = def->fields; field; field = field->next) { if (field->type && field->type->tag == VarTypeAST) { const char *field_type_name = Match(field->type, VarTypeAST)->name; - ast_t *dependency = Table$str_get(definitions, field_type_name); + ast_t *dependency = Tableヽstr_get(definitions, field_type_name); if (dependency) { _visit_topologically(dependency, definitions, visited, fn); } @@ -267,15 +267,15 @@ void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Clo visit(fn.userdata, ast); } else if (ast->tag == EnumDef) { DeclareMatch(def, ast, EnumDef); - if (Table$str_get(*visited, def->name)) + if (Tableヽstr_get(*visited, def->name)) return; - Table$str_set(visited, def->name, (void*)_visit_topologically); + Tableヽstr_set(visited, def->name, (void*)_visit_topologically); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { for (arg_ast_t *field = tag->fields; field; field = field->next) { if (field->type && field->type->tag == VarTypeAST) { const char *field_type_name = Match(field->type, VarTypeAST)->name; - ast_t *dependency = Table$str_get(definitions, field_type_name); + ast_t *dependency = Tableヽstr_get(definitions, field_type_name); if (dependency) { _visit_topologically(dependency, definitions, visited, fn); } @@ -285,7 +285,7 @@ void _visit_topologically(ast_t *ast, Table_t definitions, Table_t *visited, Clo visit(fn.userdata, ast); } else if (ast->tag == LangDef) { DeclareMatch(def, ast, LangDef); - if (Table$str_get(*visited, def->name)) + if (Tableヽstr_get(*visited, def->name)) return; visit(fn.userdata, ast); } else { @@ -305,13 +305,13 @@ void visit_topologically(ast_list_t *asts, Closure_t fn) for (ast_list_t *stmt = asts; stmt; stmt = stmt->next) { if (stmt->ast->tag == StructDef) { DeclareMatch(def, stmt->ast, StructDef); - Table$str_set(&definitions, def->name, stmt->ast); + Tableヽstr_set(&definitions, def->name, stmt->ast); } else if (stmt->ast->tag == EnumDef) { DeclareMatch(def, stmt->ast, EnumDef); - Table$str_set(&definitions, def->name, stmt->ast); + Tableヽstr_set(&definitions, def->name, stmt->ast); } else if (stmt->ast->tag == LangDef) { DeclareMatch(def, stmt->ast, LangDef); - Table$str_set(&definitions, def->name, stmt->ast); + Tableヽstr_set(&definitions, def->name, stmt->ast); } } diff --git a/src/compile.c b/src/compile.c index cc9a7bd6..44316713 100644 --- a/src/compile.c +++ b/src/compile.c @@ -47,11 +47,11 @@ static ast_t *add_to_set_comprehension(ast_t *item, ast_t *subject); static Text_t compile_lvalue(env_t *env, ast_t *ast); static Text_t quoted_str(const char *str) { - return Text$quoted(Text$from_str(str), false, Text("\"")); + return Textヽquoted(Textヽfrom_str(str), false, Text("\"")); } static inline Text_t quoted_text(Text_t text) { - return Text$quoted(text, false, Text("\"")); + return Textヽquoted(text, false, Text("\"")); } Text_t promote_to_optional(type_t *t, Text_t code) @@ -159,7 +159,7 @@ static bool promote(env_t *env, ast_t *ast, Text_t *code, type_t *actual, type_t // Text_t to C String if (actual->tag == TextType && type_eq(actual, TEXT_TYPE) && needed->tag == CStringType) { - *code = Texts("Text$as_c_string(", *code, ")"); + *code = Texts("Text", SEP, "as_c_string(", *code, ")"); return true; } @@ -218,7 +218,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t if (b) { binding_t *shadow = get_binding(env, Match(ast, Var)->name); if (!shadow || shadow == b) - Table$str_set(closed_vars, Match(ast, Var)->name, b); + Tableヽstr_set(closed_vars, Match(ast, Var)->name, b); } break; } @@ -307,7 +307,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t DeclareMatch(lambda, ast, Lambda); env_t *lambda_scope = fresh_scope(env); for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) - set_binding(lambda_scope, arg->name, get_arg_ast_type(env, arg), Texts("_$", arg->name)); + set_binding(lambda_scope, arg->name, get_arg_ast_type(env, arg), USER_ID(arg->name)); add_closed_vars(closed_vars, enclosing_scope, lambda_scope, lambda->body); break; } @@ -422,7 +422,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t case Reduction: { DeclareMatch(reduction, ast, Reduction); static int64_t next_id = 1; - ast_t *item = FakeAST(Var, String("$it", next_id++)); + ast_t *item = FakeAST(Var, String(INTERNAL_ID("it"), next_id++)); ast_t *loop = FakeAST(For, .vars=new(ast_list_t, .ast=item), .iter=reduction->iter, .body=FakeAST(Pass)); env_t *scope = for_scope(env, loop); add_closed_vars(closed_vars, enclosing_scope, scope, reduction->key ? reduction->key : item); @@ -484,7 +484,7 @@ static Table_t get_closed_vars(env_t *env, arg_ast_t *args, ast_t *block) env_t *body_scope = fresh_scope(env); for (arg_ast_t *arg = args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); - set_binding(body_scope, arg->name, arg_type, Texts("_$", arg->name)); + set_binding(body_scope, arg->name, arg_type, USER_ID(arg->name)); } Table_t closed_vars = {}; @@ -707,7 +707,7 @@ static Text_t compile_binary_op(env_t *env, ast_t *ast) } case Minus: { if (overall_t->tag == SetType) - return Texts("Table$without(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")"); + return Texts("Table", SEP, "without(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")"); if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) code_err(ast, "Math operations are only supported for values of the same numeric type, not ", type_to_str(lhs_t), " and ", type_to_str(rhs_t)); return Texts("(", lhs, " - ", rhs, ")"); @@ -738,7 +738,7 @@ static Text_t compile_binary_op(env_t *env, ast_t *ast) else if (overall_t->tag == IntType || overall_t->tag == ByteType) return Texts("(", lhs, " & ", rhs, ")"); else if (overall_t->tag == SetType) - return Texts("Table$overlap(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")"); + return Texts("Table", SEP, "overlap(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")"); else code_err(ast, "The 'and' operator isn't supported between ", type_to_str(lhs_t), " and ", type_to_str(rhs_t), " values"); } @@ -751,7 +751,7 @@ static Text_t compile_binary_op(env_t *env, ast_t *ast) } else if (overall_t->tag == IntType || overall_t->tag == ByteType) { return Texts("(", lhs, " | ", rhs, ")"); } else if (overall_t->tag == SetType) { - return Texts("Table$with(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")"); + return Texts("Table", SEP, "with(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")"); } else { code_err(ast, "The 'or' operator isn't supported between ", type_to_str(lhs_t), " and ", type_to_str(rhs_t), " values"); } @@ -761,19 +761,19 @@ static Text_t compile_binary_op(env_t *env, ast_t *ast) if (overall_t->tag == BoolType || overall_t->tag == IntType || overall_t->tag == ByteType) return Texts("(", lhs, " ^ ", rhs, ")"); else if (overall_t->tag == SetType) - return Texts("Table$xor(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")"); + return Texts("Table", SEP, "xor(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")"); else code_err(ast, "The 'xor' operator isn't supported between ", type_to_str(lhs_t), " and ", type_to_str(rhs_t), " values"); } case Concat: { if (overall_t == PATH_TYPE) - return Texts("Path$concat(", lhs, ", ", rhs, ")"); + return Texts("Path", SEP, "concat(", lhs, ", ", rhs, ")"); switch (overall_t->tag) { case TextType: { - return Texts("Text$concat(", lhs, ", ", rhs, ")"); + return Texts("Text", SEP, "concat(", lhs, ", ", rhs, ")"); } case ListType: { - return Texts("List$concat(", lhs, ", ", rhs, ", sizeof(", compile_type(Match(overall_t, ListType)->item_type), "))"); + return Texts("List", SEP, "concat(", lhs, ", ", rhs, ", sizeof(", compile_type(Match(overall_t, ListType)->item_type), "))"); } default: code_err(ast, "Concatenation isn't supported between ", type_to_str(lhs_t), " and ", type_to_str(rhs_t), " values"); @@ -819,7 +819,7 @@ Text_t compile_type(type_t *t) if (!text->lang || streq(text->lang, "Text")) return Text("Text_t"); else - return namespace_name(text->env, text->env->namespace, Text("$type")); + return namespace_name(text->env, text->env->namespace, Texts(INTERNAL_ID("type"))); } case ListType: return Text("List_t"); case SetType: return Text("Table_t"); @@ -839,12 +839,12 @@ Text_t compile_type(type_t *t) case PointerType: return Texts(compile_type(Match(t, PointerType)->pointed), "*"); case StructType: { DeclareMatch(s, t, StructType); - if (s->external) return Text$from_str(s->name); - return Texts("struct ", namespace_name(s->env, s->env->namespace, Text("$struct"))); + if (s->external) return Textヽfrom_str(s->name); + return Texts("struct ", namespace_name(s->env, s->env->namespace, Texts(INTERNAL_ID("struct")))); } case EnumType: { DeclareMatch(e, t, EnumType); - return namespace_name(e->env, e->env->namespace, Text("$type")); + return namespace_name(e->env, e->env->namespace, Texts(INTERNAL_ID("type"))); } case OptionalType: { type_t *nonnull = Match(t, OptionalType)->type; @@ -863,7 +863,7 @@ Text_t compile_type(type_t *t) if (nonnull == PATH_TYPE_TYPE) return Text("OptionalPathType_t"); DeclareMatch(s, nonnull, StructType); - return namespace_name(s->env, s->env->namespace->parent, Texts("$Optional", s->name, "$$type")); + return namespace_name(s->env, s->env->namespace->parent, Texts(INTERNAL_ID("Optional"), s->name, SEP, INTERNAL_ID("type"))); } default: compiler_err(NULL, NULL, NULL, "Optional types are not supported for: ", type_to_str(t)); @@ -906,7 +906,7 @@ Text_t compile_lvalue(env_t *env, ast_t *ast) type_t *item_type = Match(container_t, ListType)->item_type; Text_t index_code = index->index->tag == Int ? compile_int_to_type(env, index->index, Type(IntType, .bits=TYPE_IBITS64)) - : (index_t->tag == BigIntType ? Texts("Int64$from_int(", compile(env, index->index), ", no)") + : (index_t->tag == BigIntType ? Texts("Int64", SEP, "from_int(", compile(env, index->index), ", no)") : Texts("(Int64_t)(", compile(env, index->index), ")")); if (index->unchecked) { return Texts("List_lvalue_unchecked(", compile_type(item_type), ", ", target_code, ", ", @@ -921,7 +921,7 @@ Text_t compile_lvalue(env_t *env, ast_t *ast) DeclareMatch(table_type, container_t, TableType); if (table_type->default_value) { type_t *value_type = get_type(env, table_type->default_value); - return Texts("*Table$get_or_setdefault(", + return Texts("*Table", SEP, "get_or_setdefault(", compile_to_pointer_depth(env, index->indexed, 1, false), ", ", compile_type(table_type->key_type), ", ", compile_type(value_type), ", ", @@ -931,7 +931,7 @@ Text_t compile_lvalue(env_t *env, ast_t *ast) } if (index->unchecked) code_err(ast, "Table indexes cannot be unchecked"); - return Texts("*(", compile_type(Type(PointerType, table_type->value_type)), ")Table$reserve(", + return Texts("*(", compile_type(Type(PointerType, table_type->value_type)), ")Table", SEP, "reserve(", compile_to_pointer_depth(env, index->indexed, 1, false), ", ", compile_to_type(env, index->index, Type(PointerType, table_type->key_type, .is_stack=true)), ", NULL,", compile_type_info(container_t), ")"); @@ -995,9 +995,9 @@ Text_t check_none(type_t *t, Text_t value) if (t->tag == PointerType || t->tag == FunctionType || t->tag == CStringType) return Texts("({", value, " == NULL;})"); else if (t == PATH_TYPE) - return Texts("({(", value, ").type.$tag == PATH_NONE;})"); + return Texts("({(", value, ").type.", INTERNAL_ID("tag"), " == PATH_NONE;})"); else if (t == PATH_TYPE_TYPE) - return Texts("({(", value, ").$tag == PATH_NONE;})"); + return Texts("({(", value, ").", INTERNAL_ID("tag"), " == PATH_NONE;})"); else if (t->tag == BigIntType) return Texts("({(", value, ").small == 0;})"); else if (t->tag == ClosureType) @@ -1016,7 +1016,7 @@ Text_t check_none(type_t *t, Text_t value) return Texts("(", value, ").is_none"); else if (t->tag == EnumType) { if (enum_has_fields(t)) - return Texts("({(", value, ").$tag == 0;})"); + return Texts("({(", value, ").", INTERNAL_ID("tag"), " == 0;})"); else return Texts("((", value, ") == 0)"); } @@ -1091,7 +1091,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) if (clause->pattern->tag == Var) { const char *clause_tag_name = Match(clause->pattern, Var)->name; type_t *clause_type = clause->body ? get_type(env, clause->body) : Type(VoidType); - code = Texts(code, "case ", namespace_name(enum_t->env, enum_t->env->namespace, Texts("tag$", clause_tag_name)), ": {\n", + code = Texts(code, "case ", namespace_name(enum_t->env, enum_t->env->namespace, Texts(INTERNAL_ID("tag"), SEP, clause_tag_name)), ": {\n", compile_inline_block(env, clause->body), (clause_type->tag == ReturnType || clause_type->tag == AbortType) ? EMPTY_TEXT : Text("break;\n"), "}\n"); @@ -1102,7 +1102,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) code_err(clause->pattern, "This is not a valid pattern for a ", type_to_str(subject_t), " enum type"); const char *clause_tag_name = Match(Match(clause->pattern, FunctionCall)->fn, Var)->name; - code = Texts(code, "case ", namespace_name(enum_t->env, enum_t->env->namespace, Texts("tag$", clause_tag_name)), ": {\n"); + code = Texts(code, "case ", namespace_name(enum_t->env, enum_t->env->namespace, Texts(INTERNAL_ID("tag"), SEP, clause_tag_name)), ": {\n"); type_t *tag_type = NULL; for (tag_t *tag = enum_t->tags; tag; tag = tag->next) { if (streq(tag->name, clause_tag_name)) { @@ -1120,7 +1120,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) code_err(args->value, "This is not a valid variable to bind to"); const char *var_name = Match(args->value, Var)->name; if (!streq(var_name, "_")) { - Text_t var = Texts("_$", var_name); + Text_t var = USER_ID(var_name); code = Texts(code, compile_declaration(tag_type, var), " = _when_subject.", valid_c_name(clause_tag_name), ";\n"); scope = fresh_scope(scope); set_binding(scope, Match(args->value, Var)->name, tag_type, EMPTY_TEXT); @@ -1138,7 +1138,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) const char *var_name = Match(arg->value, Var)->name; if (!streq(var_name, "_")) { - Text_t var = Texts("_$", var_name); + Text_t var = USER_ID(var_name); code = Texts(code, compile_declaration(field->type, var), " = _when_subject.", valid_c_name(clause_tag_name), ".", valid_c_name(field->name), ";\n"); set_binding(scope, Match(arg->value, Var)->name, field->type, var); @@ -1184,7 +1184,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) DeclareMatch(decl, test->expr, Declare); type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value); if (t->tag == FunctionType) t = Type(ClosureType, t); - Text_t var = Texts("_$", Match(decl->var, Var)->name); + Text_t var = USER_ID(Match(decl->var, Var)->name); Text_t val_code = compile_declared_value(env, test->expr); setup = Texts(compile_declaration(t, var), ";\n"); test_code = Texts("(", var, " = ", val_code, ")"); @@ -1222,16 +1222,16 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) expr_t = lhs_t; env_t *val_scope = with_enum_scope(env, lhs_t); Text_t val_code = compile_to_type(val_scope, value->ast, lhs_t); - test_code = Texts(test_code, compile_type(lhs_t), " $", String(i), " = ", val_code, ";\n"); + test_code = Texts(test_code, compile_type(lhs_t), " ", INTERNAL_ID(String(i)), " = ", val_code, ";\n"); i += 1; } i = 1; for (ast_list_t *target = assign->targets; target; target = target->next) { - test_code = Texts(test_code, compile_assignment(env, target->ast, Texts("$", String(i))), ";\n"); + test_code = Texts(test_code, compile_assignment(env, target->ast, INTERNAL_ID(String(i))), ";\n"); i += 1; } - test_code = Texts(test_code, "$1; })"); + test_code = Texts(test_code, INTERNAL_ID("1"), "; })"); } } else if (is_update_assignment(test->expr)) { binary_operands_t update = UPDATE_OPERANDS(test->expr); @@ -1328,7 +1328,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) "fail_source(", quoted_str(ast->file->filename), ", ", String((int64_t)(expr->start - expr->file->text)), ", ", String((int64_t)(expr->end - expr->file->text)), ", ", - message ? Texts("Text$as_c_string(", compile_to_type(env, message, Type(TextType)), ")") + message ? Texts("Text", SEP, "as_c_string(", compile_to_type(env, message, Type(TextType)), ")") : Text("\"This assertion failed!\""), ", ", "\" (\", ", expr_as_text(Text("_lhs"), operand_t, Text("no")), ", " "\" ", failure, " \", ", expr_as_text(Text("_rhs"), operand_t, Text("no")), ", \")\");\n"), @@ -1343,7 +1343,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) "fail_source(", quoted_str(ast->file->filename), ", ", String((int64_t)(expr->start - expr->file->text)), ", ", String((int64_t)(expr->end - expr->file->text)), ", ", - message ? Texts("Text$as_c_string(", compile_to_type(env, message, Type(TextType)), ")") + message ? Texts("Text", SEP, "as_c_string(", compile_to_type(env, message, Type(TextType)), ")") : Text("\"This assertion failed!\""), ");\n"); } @@ -1364,7 +1364,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) code_err(ast, "You can't declare a variable with a ", type_to_str(t), " value"); Text_t val_code = compile_declared_value(env, ast); - return Texts(compile_declaration(t, Texts("_$", name)), " = ", val_code, ";"); + return Texts(compile_declaration(t, USER_ID(name)), " = ", val_code, ";"); } } case Assign: { @@ -1393,12 +1393,12 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) code_err(ast, "Stack references cannot be assigned to variables because the variable's scope may outlive the scope of the stack memory."); env_t *val_env = with_enum_scope(env, lhs_t); Text_t val = compile_to_type(val_env, value->ast, lhs_t); - code = Texts(code, compile_type(lhs_t), " $", String(i), " = ", val, ";\n"); + code = Texts(code, compile_type(lhs_t), " ", INTERNAL_ID(String(i)), " = ", val, ";\n"); i += 1; } i = 1; for (ast_list_t *target = assign->targets; target; target = target->next) { - code = Texts(code, compile_assignment(env, target->ast, Texts("$", String(i))), ";\n"); + code = Texts(code, compile_assignment(env, target->ast, INTERNAL_ID(String(i))), ";\n"); i += 1; } return Texts(code, "\n}"); @@ -1515,10 +1515,10 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) struct { const char *name; binding_t *b; } *entry = closed_vars.entries.data + closed_vars.entries.stride*i; if (entry->b->type->tag == ModuleType) continue; - if (Text$starts_with(entry->b->code, Text("userdata->"), NULL)) { - Table$str_set(defer_env->locals, entry->name, entry->b); + if (Textヽstarts_with(entry->b->code, Text("userdata->"), NULL)) { + Tableヽstr_set(defer_env->locals, entry->name, entry->b); } else { - Text_t defer_name = Texts("defer$", String(++defer_id), "$", entry->name); + Text_t defer_name = Texts("defer", SEP, String(++defer_id), SEP, entry->name); defer_id += 1; code = Texts( code, compile_declaration(entry->b->type, defer_name), " = ", entry->b->code, ";\n"); @@ -1669,14 +1669,14 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) Text_t value = for_->vars ? compile(body_scope, for_->vars->ast) : Text("i"); if (int_type->tag == BigIntType) { if (optional_step.length > 0) - step = Texts("({ OptionalInt_t maybe_step = ", optional_step, "; maybe_step->small == 0 ? (Int$compare_value(last, first) >= 0 ? I_small(1) : I_small(-1)) : (Int_t)maybe_step; })"); + step = Texts("({ OptionalInt_t maybe_step = ", optional_step, "; maybe_step->small == 0 ? (Int", SEP, "compare_value(last, first) >= 0 ? I_small(1) : I_small(-1)) : (Int_t)maybe_step; })"); else if (step.length == 0) - step = Text("Int$compare_value(last, first) >= 0 ? I_small(1) : I_small(-1)"); + step = Texts("Int", SEP, "compare_value(last, first) >= 0 ? I_small(1) : I_small(-1)"); return Texts( "for (", type_code, " first = ", compile(env, Match(for_->iter, MethodCall)->self), ", ", value, " = first, last = ", last, ", step = ", step, "; " - "Int$compare_value(", value, ", last) != Int$compare_value(step, I_small(0)); ", - value, " = Int$plus(", value, ", step)) {\n" + "Int", SEP, "compare_value(", value, ", last) != Int", SEP, "compare_value(step, I_small(0)); ", + value, " = Int", SEP, "plus(", value, ", step)) {\n" "\t", naked_body, "}", stop); @@ -1704,7 +1704,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) Text_t value = for_->vars ? compile(body_scope, for_->vars->ast) : Text("i"); return Texts( "for (Int_t ", value, " = ", compile(env, Match(for_->iter, MethodCall)->self), ", ", - "step = ", step, "; ; ", value, " = Int$plus(", value, ", step)) {\n" + "step = ", step, "; ; ", value, " = Int", SEP, "plus(", value, ", step)) {\n" "\t", naked_body, "}", stop); @@ -1824,13 +1824,13 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) Text_t n; if (for_->iter->tag == Int) { const char *str = Match(for_->iter, Int)->str; - Int_t int_val = Int$from_str(str); + Int_t int_val = Intヽfrom_str(str); if (int_val.small == 0) code_err(for_->iter, "Failed to parse this integer"); mpz_t i; mpz_init_set_int(i, int_val); if (mpz_cmpabs_ui(i, BIGGEST_SMALL_INT) <= 0) - n = Text$from_str(mpz_get_str(NULL, 10, i)); + n = Textヽfrom_str(mpz_get_str(NULL, 10, i)); else goto big_n; @@ -1855,8 +1855,8 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) return Texts( "{\n" "Int_t ", n_var, " = ", n, ";\n" - "if (Int$compare_value(", n_var, ", I(0)) > 0) {\n" - "for (Int_t ", i, " = I(1); Int$compare_value(", i, ", ", n_var, ") <= 0; ", i, " = Int$plus(", i, ", I(1))) {\n", + "if (Int", SEP, "compare_value(", n_var, ", I(0)) > 0) {\n" + "for (Int_t ", i, " = I(1); Int", SEP, "compare_value(", i, ", ", n_var, ") <= 0; ", i, " = Int", SEP, "plus(", i, ", I(1))) {\n", "\t", naked_body, "}\n" "} else ", compile_statement(env, for_->empty), @@ -1864,7 +1864,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) "}\n"); } else { return Texts( - "for (Int_t ", i, " = I(1), ", n_var, " = ", n, "; Int$compare_value(", i, ", ", n_var, ") <= 0; ", i, " = Int$plus(", i, ", I(1))) {\n", + "for (Int_t ", i, " = I(1), ", n_var, " = ", n, "; Int", SEP, "compare_value(", i, ", ", n_var, ") <= 0; ", i, " = Int", SEP, "plus(", i, ", I(1))) {\n", "\t", naked_body, "}\n", stop, "\n"); @@ -1904,7 +1904,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) get_next = Texts("(cur=", get_next, ", !", check_none(fn->ret, Text("cur")), ")"); if (for_->vars) { naked_body = Texts( - compile_declaration(Match(fn->ret, OptionalType)->type, Texts("_$", Match(for_->vars->ast, Var)->name)), + compile_declaration(Match(fn->ret, OptionalType)->type, USER_ID(Match(for_->vars->ast, Var)->name)), " = ", optional_into_nonnone(fn->ret, Text("cur")), ";\n", naked_body); } @@ -1918,7 +1918,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) } else { if (for_->vars) { naked_body = Texts( - compile_declaration(fn->ret, Texts("_$", Match(for_->vars->ast, Var)->name)), + compile_declaration(fn->ret, USER_ID(Match(for_->vars->ast, Var)->name)), " = ", get_next, ";\n", naked_body); } else { naked_body = Texts(get_next, ";\n", naked_body); @@ -2007,11 +2007,11 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) case Use: { DeclareMatch(use, ast, Use); if (use->what == USE_LOCAL) { - Path_t path = Path$from_str(Match(ast, Use)->path); - Path_t in_file = Path$from_str(ast->file->filename); - path = Path$resolved(path, Path$parent(in_file)); - Text_t suffix = get_id_suffix(Path$as_c_string(path)); - return with_source_info(env, ast, Texts("$initialize", suffix, "();\n")); + Path_t path = Pathヽfrom_str(Match(ast, Use)->path); + Path_t in_file = Pathヽfrom_str(ast->file->filename); + path = Pathヽresolved(path, Pathヽparent(in_file)); + Text_t suffix = get_id_suffix(Pathヽas_c_string(path)); + return with_source_info(env, ast, Texts(INTERNAL_ID("initialize"), suffix, "();\n")); } else if (use->what == USE_MODULE) { module_info_t mod = get_module_info(ast); glob_t tm_files; @@ -2027,7 +2027,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) const char *filename = tm_files.gl_pathv[i]; initialization = Texts( initialization, - with_source_info(env, ast, Texts("$initialize", get_id_suffix(filename), "();\n"))); + with_source_info(env, ast, Texts(INTERNAL_ID("initialize"), get_id_suffix(filename), "();\n"))); } globfree(&tm_files); return initialization; @@ -2051,22 +2051,22 @@ Text_t compile_statement(env_t *env, ast_t *ast) { Text_t expr_as_text(Text_t expr, type_t *t, Text_t color) { switch (t->tag) { - case MemoryType: return Texts("Memory$as_text(stack(", expr, "), ", color, ", &Memory$info)"); + case MemoryType: return Texts("Memory", SEP, "as_text(stack(", expr, "), ", color, ", &Memory", SEP, "info)"); case BoolType: // NOTE: this cannot use stack(), since bools may actually be bit fields: - return Texts("Bool$as_text((Bool_t[1]){", expr, "}, ", color, ", &Bool$info)"); - case CStringType: return Texts("CString$as_text(stack(", expr, "), ", color, ", &CString$info)"); + return Texts("Bool", SEP, "as_text((Bool_t[1]){", expr, "}, ", color, ", &Bool", SEP, "info)"); + case CStringType: return Texts("CString", SEP, "as_text(stack(", expr, "), ", color, ", &CString", SEP, "info)"); case BigIntType: case IntType: case ByteType: case NumType: { Text_t name = type_to_text(t); - return Texts(name, "$as_text(stack(", expr, "), ", color, ", &", name, "$info)"); - } - case TextType: return Texts("Text$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); - case ListType: return Texts("List$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); - case SetType: return Texts("Table$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); - case TableType: return Texts("Table$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); - case FunctionType: case ClosureType: return Texts("Func$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); - case PointerType: return Texts("Pointer$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); - case OptionalType: return Texts("Optional$as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); + return Texts(name, SEP, "as_text(stack(", expr, "), ", color, ", &", name, SEP, "info)"); + } + case TextType: return Texts("Text", SEP, "as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); + case ListType: return Texts("List", SEP, "as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); + case SetType: return Texts("Table", SEP, "as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); + case TableType: return Texts("Table", SEP, "as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); + case FunctionType: case ClosureType: return Texts("Func", SEP, "as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); + case PointerType: return Texts("Pointer", SEP, "as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); + case OptionalType: return Texts("Optional", SEP, "as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); case StructType: case EnumType: return Texts("generic_as_text(stack(", expr, "), ", color, ", ", compile_type_info(t), ")"); default: compiler_err(NULL, NULL, NULL, "Stringifying is not supported for ", type_to_str(t)); @@ -2131,8 +2131,8 @@ Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t) } else if (ast->tag == Num && t->tag == NumType) { double n = Match(ast, Num)->n; switch (Match(t, NumType)->bits) { - case TYPE_NBITS64: return Text$from_str(String(hex_double(n))); - case TYPE_NBITS32: return Text$from_str(String(hex_double(n), "f")); + case TYPE_NBITS64: return Textヽfrom_str(String(hex_double(n))); + case TYPE_NBITS32: return Textヽfrom_str(String(hex_double(n), "f")); default: code_err(ast, "This is not a valid number bit width"); } } else if (ast->tag == None) { @@ -2229,7 +2229,7 @@ Text_t compile_typed_list(env_t *env, ast_t *ast, type_t *list_type) { env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : fresh_scope(env); static int64_t comp_num = 1; - const char *comprehension_name = String("list$", comp_num++); + const char *comprehension_name = String("list", SEP, comp_num++); ast_t *comprehension_var = LiteralCode(Texts("&", comprehension_name), .type=Type(PointerType, .pointed=list_type, .is_stack=true)); Closure_t comp_action = {.fn=add_to_list_comprehension, .userdata=comprehension_var}; @@ -2278,7 +2278,7 @@ Text_t compile_typed_set(env_t *env, ast_t *ast, type_t *set_type) { static int64_t comp_num = 1; env_t *scope = item_type->tag == EnumType ? with_enum_scope(env, item_type) : fresh_scope(env); - const char *comprehension_name = String("set$", comp_num++); + const char *comprehension_name = String("set", SEP, comp_num++); ast_t *comprehension_var = LiteralCode(Texts("&", comprehension_name), .type=Type(PointerType, .pointed=set_type, .is_stack=true)); Text_t code = Texts("({ Table_t ", comprehension_name, " = {};"); @@ -2346,7 +2346,7 @@ Text_t compile_typed_table(env_t *env, ast_t *ast, type_t *table_type) { static int64_t comp_num = 1; env_t *scope = fresh_scope(env); - const char *comprehension_name = String("table$", comp_num++); + const char *comprehension_name = String("table", SEP, comp_num++); ast_t *comprehension_var = LiteralCode(Texts("&", comprehension_name), .type=Type(PointerType, .pointed=table_type, .is_stack=true)); @@ -2406,7 +2406,7 @@ Text_t compile_int_to_type(env_t *env, ast_t *ast, type_t *target) return compile_int_to_type(env, ast, Match(target, OptionalType)->type); const char *literal = Match(ast, Int)->str; - OptionalInt_t int_val = Int$from_str(literal); + OptionalInt_t int_val = Intヽfrom_str(literal); if (int_val.small == 0) code_err(ast, "Failed to parse this integer"); @@ -2479,18 +2479,18 @@ Text_t compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_ if (spec_arg->type->tag == IntType && call_arg->value->tag == Int) { value = compile_int_to_type(env, call_arg->value, spec_arg->type); } else if (spec_arg->type->tag == NumType && call_arg->value->tag == Int) { - OptionalInt_t int_val = Int$from_str(Match(call_arg->value, Int)->str); + OptionalInt_t int_val = Intヽfrom_str(Match(call_arg->value, Int)->str); if (int_val.small == 0) code_err(call_arg->value, "Failed to parse this integer"); if (Match(spec_arg->type, NumType)->bits == TYPE_NBITS64) - value = Text$from_str(String(hex_double(Num$from_int(int_val, false)))); + value = Textヽfrom_str(String(hex_double(Numヽfrom_int(int_val, false)))); else - value = Text$from_str(String(hex_double((double)Num32$from_int(int_val, false)), "f")); + value = Textヽfrom_str(String(hex_double((double)Num32ヽfrom_int(int_val, false)), "f")); } else { env_t *arg_env = with_enum_scope(env, spec_arg->type); value = compile_maybe_incref(arg_env, call_arg->value, spec_arg->type); } - Table$str_set(&used_args, call_arg->name, call_arg); + Tableヽstr_set(&used_args, call_arg->name, call_arg); if (code.length > 0) code = Texts(code, ", "); code = Texts(code, value); goto found_it; @@ -2501,24 +2501,24 @@ Text_t compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_ for (arg_ast_t *call_arg = call_args; call_arg; call_arg = call_arg->next) { if (call_arg->name) continue; const char *pseudoname = String(i++); - if (!Table$str_get(used_args, pseudoname)) { + if (!Tableヽstr_get(used_args, pseudoname)) { Text_t value; if (spec_arg->type->tag == IntType && call_arg->value->tag == Int) { value = compile_int_to_type(env, call_arg->value, spec_arg->type); } else if (spec_arg->type->tag == NumType && call_arg->value->tag == Int) { - OptionalInt_t int_val = Int$from_str(Match(call_arg->value, Int)->str); + OptionalInt_t int_val = Intヽfrom_str(Match(call_arg->value, Int)->str); if (int_val.small == 0) code_err(call_arg->value, "Failed to parse this integer"); if (Match(spec_arg->type, NumType)->bits == TYPE_NBITS64) - value = Text$from_str(String(hex_double(Num$from_int(int_val, false)))); + value = Textヽfrom_str(String(hex_double(Numヽfrom_int(int_val, false)))); else - value = Text$from_str(String(hex_double((double)Num32$from_int(int_val, false)), "f")); + value = Textヽfrom_str(String(hex_double((double)Num32ヽfrom_int(int_val, false)), "f")); } else { env_t *arg_env = with_enum_scope(env, spec_arg->type); value = compile_maybe_incref(arg_env, call_arg->value, spec_arg->type); } - Table$str_set(&used_args, pseudoname, call_arg); + Tableヽstr_set(&used_args, pseudoname, call_arg); if (code.length > 0) code = Texts(code, ", "); code = Texts(code, value); goto found_it; @@ -2539,11 +2539,11 @@ Text_t compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_ int64_t i = 1; for (arg_ast_t *call_arg = call_args; call_arg; call_arg = call_arg->next) { if (call_arg->name) { - if (!Table$str_get(used_args, call_arg->name)) + if (!Tableヽstr_get(used_args, call_arg->name)) code_err(call_arg->value, "There is no argument with the name '", call_arg->name, "'"); } else { const char *pseudoname = String(i++); - if (!Table$str_get(used_args, pseudoname)) + if (!Tableヽstr_get(used_args, pseudoname)) code_err(call_arg->value, "This is one argument too many!"); } } @@ -2553,7 +2553,7 @@ Text_t compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_ Text_t compile_text_literal(Text_t literal) { Text_t code = Text("\""); - const char *utf8 = Text$as_c_string(literal); + const char *utf8 = Textヽas_c_string(literal); for (const char *p = utf8; *p; p++) { switch (*p) { case '\\': code = Texts(code, "\\\\"); break; @@ -2566,7 +2566,7 @@ Text_t compile_text_literal(Text_t literal) case '\v': code = Texts(code, "\\v"); break; default: { if (isprint(*p)) { - code = Texts(code, Text$from_strn(p, 1)); + code = Texts(code, Textヽfrom_strn(p, 1)); } else { uint8_t byte = *(uint8_t*)p; code = Texts(code, "\\x", String(hex(byte, .no_prefix=true, .uppercase=true, .digits=2)), "\"\""); @@ -2582,7 +2582,7 @@ PUREFUNC static bool string_literal_is_all_ascii(Text_t literal) { TextIter_t state = NEW_TEXT_ITER_STATE(literal); for (int64_t i = 0; i < literal.length; i++) { - int32_t g = Text$get_grapheme_fast(&state, i); + int32_t g = Textヽget_grapheme_fast(&state, i); if (g < 0 || g > 127 || !isascii(g)) return false; } @@ -2694,9 +2694,9 @@ Text_t compile_empty(type_t *t) assert(tag); assert(tag->type); if (Match(tag->type, StructType)->fields) - return Texts("((", compile_type(t), "){.$tag=", String(tag->tag_value), ", .", tag->name, "=", compile_empty(tag->type), "})"); + return Texts("((", compile_type(t), "){.", INTERNAL_ID("tag"), "=", String(tag->tag_value), ", .", tag->name, "=", compile_empty(tag->type), "})"); else if (enum_has_fields(t)) - return Texts("((", compile_type(t), "){.$tag=", String(tag->tag_value), "})"); + return Texts("((", compile_type(t), "){.", INTERNAL_ID("tag"), "=", String(tag->tag_value), "})"); else return Texts("((", compile_type(t), ")", String(tag->tag_value), ")"); } @@ -2755,13 +2755,12 @@ Text_t compile(env_t *env, ast_t *ast) case Var: { binding_t *b = get_binding(env, Match(ast, Var)->name); if (b) - return b->code.length > 0 ? b->code : Texts("_$", Match(ast, Var)->name); - // return Texts("_$", Match(ast, Var)->name); + return b->code.length > 0 ? b->code : USER_ID(Match(ast, Var)->name); code_err(ast, "I don't know of any variable by this name"); } case Int: { const char *str = Match(ast, Int)->str; - OptionalInt_t int_val = Int$from_str(str); + OptionalInt_t int_val = Intヽfrom_str(str); if (int_val.small == 0) code_err(ast, "Failed to parse this integer"); mpz_t i; @@ -2769,13 +2768,13 @@ Text_t compile(env_t *env, ast_t *ast) if (mpz_cmpabs_ui(i, BIGGEST_SMALL_INT) <= 0) { return Texts("I_small(", str, ")"); } else if (mpz_cmp_si(i, INT64_MAX) <= 0 && mpz_cmp_si(i, INT64_MIN) >= 0) { - return Texts("Int$from_int64(", str, ")"); + return Texts("Int", SEP, "from_int64(", str, ")"); } else { - return Texts("Int$from_str(\"", str, "\")"); + return Texts("Int", SEP, "from_str(\"", str, "\")"); } } case Num: { - return Text$from_str(String(hex_double(Match(ast, Num)->n))); + return Textヽfrom_str(String(hex_double(Match(ast, Num)->n))); } case Not: { ast_t *value = Match(ast, Not)->value; @@ -2869,7 +2868,7 @@ Text_t compile(env_t *env, ast_t *ast) switch (operand_t->tag) { case BigIntType: - return Texts(ast->tag == Equals ? EMPTY_TEXT : Text("!"), "Int$equal_value(", lhs, ", ", rhs, ")"); + return Texts(ast->tag == Equals ? EMPTY_TEXT : Text("!"), "Int", SEP, "equal_value(", lhs, ", ", rhs, ")"); case BoolType: case ByteType: case IntType: case NumType: case PointerType: case FunctionType: return Texts("(", lhs, ast->tag == Equals ? " == " : " != ", rhs, ")"); default: @@ -2905,7 +2904,7 @@ Text_t compile(env_t *env, ast_t *ast) const char *op = binop_operator(ast->tag); switch (operand_t->tag) { case BigIntType: - return Texts("(Int$compare_value(", lhs, ", ", rhs, ") ", op, " 0)"); + return Texts("(Int", SEP, "compare_value(", lhs, ", ", rhs, ") ", op, " 0)"); case BoolType: case ByteType: case IntType: case NumType: case PointerType: case FunctionType: return Texts("(", lhs, " ", op, " ", rhs, ")"); default: @@ -2921,13 +2920,13 @@ Text_t compile(env_t *env, ast_t *ast) if (string_literal_is_all_ascii(literal)) return Texts("Text(", compile_text_literal(literal), ")"); else - return Texts("Text$from_str(", compile_text_literal(literal), ")"); + return Texts("Text", SEP, "from_str(", compile_text_literal(literal), ")"); } case TextJoin: { const char *lang = Match(ast, TextJoin)->lang; Text_t colorize = Match(ast, TextJoin)->colorize ? Text("yes") : Text("no"); - type_t *text_t = lang ? Table$str_get(*env->types, lang) : TEXT_TYPE; + type_t *text_t = lang ? Tableヽstr_get(*env->types, lang) : TEXT_TYPE; if (!text_t || text_t->tag != TextType) code_err(ast, quoted(lang), " is not a valid text language name"); @@ -2935,7 +2934,7 @@ Text_t compile(env_t *env, ast_t *ast) if (!lang || streq(lang, "Text")) lang_constructor = Text("Text"); else - lang_constructor = namespace_name(Match(text_t, TextType)->env, Match(text_t, TextType)->env->namespace->parent, Text$from_str(lang)); + lang_constructor = namespace_name(Match(text_t, TextType)->env, Match(text_t, TextType)->env->namespace->parent, Textヽfrom_str(lang)); ast_list_t *chunks = Match(ast, TextJoin)->children; if (!chunks) { @@ -2978,7 +2977,7 @@ Text_t compile(env_t *env, ast_t *ast) } } case Path: { - return Texts("Path(", compile_text_literal(Text$from_str(Match(ast, Path)->path)), ")"); + return Texts("Path(", compile_text_literal(Textヽfrom_str(Match(ast, Path)->path)), ")"); } case Block: { ast_list_t *stmts = Match(ast, Block)->statements; @@ -3010,20 +3009,20 @@ Text_t compile(env_t *env, ast_t *ast) ast_t *key = ast->tag == Min ? Match(ast, Min)->key : Match(ast, Max)->key; ast_t *lhs = ast->tag == Min ? Match(ast, Min)->lhs : Match(ast, Max)->lhs; ast_t *rhs = ast->tag == Min ? Match(ast, Min)->rhs : Match(ast, Max)->rhs; - const char *key_name = "$"; + const char *key_name = "ヽ"; if (key == NULL) key = FakeAST(Var, key_name); env_t *expr_env = fresh_scope(env); - set_binding(expr_env, key_name, t, Text("ternary$lhs")); + set_binding(expr_env, key_name, t, Texts("ternary", SEP, "lhs")); Text_t lhs_key = compile(expr_env, key); - set_binding(expr_env, key_name, t, Text("ternary$rhs")); + set_binding(expr_env, key_name, t, Texts("ternary", SEP, "rhs")); Text_t rhs_key = compile(expr_env, key); type_t *key_t = get_type(expr_env, key); Text_t comparison; if (key_t->tag == BigIntType) - comparison = Texts("(Int$compare_value(", lhs_key, ", ", rhs_key, ")", (ast->tag == Min ? "<=" : ">="), "0)"); + comparison = Texts("(Int", SEP, "compare_value(", lhs_key, ", ", rhs_key, ")", (ast->tag == Min ? "<=" : ">="), "0)"); else if (key_t->tag == IntType || key_t->tag == NumType || key_t->tag == BoolType || key_t->tag == PointerType || key_t->tag == ByteType) comparison = Texts("((", lhs_key, ")", (ast->tag == Min ? "<=" : ">="), "(", rhs_key, "))"); else @@ -3032,8 +3031,8 @@ Text_t compile(env_t *env, ast_t *ast) return Texts( "({\n", - compile_type(t), " ternary$lhs = ", compile(env, lhs), ", ternary$rhs = ", compile(env, rhs), ";\n", - comparison, " ? ternary$lhs : ternary$rhs;\n" + compile_type(t), " ternary", SEP, "lhs = ", compile(env, lhs), ", ternary", SEP, "rhs = ", compile(env, rhs), ";\n", + comparison, " ? ternary", SEP, "lhs : ternary", SEP, "rhs;\n" "})"); } case List: { @@ -3075,13 +3074,13 @@ Text_t compile(env_t *env, ast_t *ast) } case Lambda: { DeclareMatch(lambda, ast, Lambda); - Text_t name = namespace_name(env, env->namespace, Texts("lambda$", String(lambda->id))); + Text_t name = namespace_name(env, env->namespace, Texts("lambda", SEP, String(lambda->id))); env_t *body_scope = fresh_scope(env); body_scope->deferred = NULL; for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); - set_binding(body_scope, arg->name, arg_type, Texts("_$", arg->name)); + set_binding(body_scope, arg->name, arg_type, USER_ID(arg->name)); } type_t *ret_t = get_type(body_scope, lambda->body); @@ -3100,7 +3099,7 @@ Text_t compile(env_t *env, ast_t *ast) body_scope->fn_ret = ret_t; Table_t closed_vars = get_closed_vars(env, lambda->args, ast); - if (Table$length(closed_vars) > 0) { // Create a typedef for the lambda's closure userdata + if (Tableヽlength(closed_vars) > 0) { // Create a typedef for the lambda's closure userdata Text_t def = Text("typedef struct {"); for (int64_t i = 0; i < closed_vars.entries.length; i++) { struct { const char *name; binding_t *b; } *entry = closed_vars.entries.data + closed_vars.entries.stride*i; @@ -3110,24 +3109,24 @@ Text_t compile(env_t *env, ast_t *ast) if (entry->b->type->tag == ModuleType) continue; set_binding(body_scope, entry->name, entry->b->type, Texts("userdata->", entry->name)); - def = Texts(def, compile_declaration(entry->b->type, Text$from_str(entry->name)), "; "); + def = Texts(def, compile_declaration(entry->b->type, Textヽfrom_str(entry->name)), "; "); } - def = Texts(def, "} ", name, "$userdata_t;"); + def = Texts(def, "} ", name, SEP, "userdata_t;"); env->code->local_typedefs = Texts(env->code->local_typedefs, def); } Text_t code = Texts("static ", compile_type(ret_t), " ", name, "("); for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); - code = Texts(code, compile_type(arg_type), " _$", arg->name, ", "); + code = Texts(code, compile_type(arg_type), " ", USER_ID(arg->name), ", "); } Text_t userdata; - if (Table$length(closed_vars) == 0) { + if (Tableヽlength(closed_vars) == 0) { code = Texts(code, "void *_)"); userdata = Text("NULL"); } else { - userdata = Texts("new(", name, "$userdata_t"); + userdata = Texts("new(", name, SEP, "userdata_t"); for (int64_t i = 0; i < closed_vars.entries.length; i++) { struct { const char *name; binding_t *b; } *entry = closed_vars.entries.data + closed_vars.entries.stride*i; if (entry->b->type->tag == ModuleType) @@ -3143,7 +3142,7 @@ Text_t compile(env_t *env, ast_t *ast) userdata = Texts(userdata, ", ", binding_code); } userdata = Texts(userdata, ")"); - code = Texts(code, name, "$userdata_t *userdata)"); + code = Texts(code, name, SEP, "userdata_t *userdata)"); } Text_t body = EMPTY_TEXT; @@ -3203,30 +3202,30 @@ Text_t compile(env_t *env, ast_t *ast) EXPECT_POINTER("a", "list"); arg_t *arg_spec = new(arg_t, .name="item", .type=item_t, .next=new(arg_t, .name="at", .type=INT_TYPE, .default_val=FakeAST(Int, .str="0"))); - return Texts("List$insert_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("List", SEP, "insert_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); } else if (streq(call->name, "insert_all")) { EXPECT_POINTER("a", "list"); arg_t *arg_spec = new(arg_t, .name="items", .type=self_value_t, .next=new(arg_t, .name="at", .type=INT_TYPE, .default_val=FakeAST(Int, .str="0"))); - return Texts("List$insert_all(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("List", SEP, "insert_all(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); } else if (streq(call->name, "remove_at")) { EXPECT_POINTER("a", "list"); arg_t *arg_spec = new(arg_t, .name="index", .type=INT_TYPE, .default_val=FakeAST(Int, .str="-1"), .next=new(arg_t, .name="count", .type=INT_TYPE, .default_val=FakeAST(Int, .str="1"))); - return Texts("List$remove_at(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("List", SEP, "remove_at(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); } else if (streq(call->name, "remove_item")) { EXPECT_POINTER("a", "list"); arg_t *arg_spec = new(arg_t, .name="item", .type=item_t, .next=new(arg_t, .name="max_count", .type=INT_TYPE, .default_val=FakeAST(Int, .str="-1"))); - return Texts("List$remove_item_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("List", SEP, "remove_item_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "has")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="item", .type=item_t); - return Texts("List$has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("List", SEP, "has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "sample")) { type_t *random_num_type = parse_type_string(env, "func(->Num)?"); @@ -3235,23 +3234,23 @@ Text_t compile(env_t *env, ast_t *ast) .next=new(arg_t, .name="weights", .type=Type(ListType, .item_type=Type(NumType, .bits=TYPE_NBITS64)), .default_val=FakeAST(None), .next=new(arg_t, .name="random", .type=random_num_type, .default_val=FakeAST(None)))); - return Texts("List$sample(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("List", SEP, "sample(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); } else if (streq(call->name, "shuffle")) { type_t *random_int64_type = parse_type_string(env, "func(min,max:Int64->Int64)?"); EXPECT_POINTER("a", "list"); arg_t *arg_spec = new(arg_t, .name="random", .type=random_int64_type, .default_val=FakeAST(None)); - return Texts("List$shuffle(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); + return Texts("List", SEP, "shuffle(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); } else if (streq(call->name, "shuffled")) { type_t *random_int64_type = parse_type_string(env, "func(min,max:Int64->Int64)?"); self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="random", .type=random_int64_type, .default_val=FakeAST(None)); - return Texts("List$shuffled(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); + return Texts("List", SEP, "shuffled(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); } else if (streq(call->name, "random")) { type_t *random_int64_type = parse_type_string(env, "func(min,max:Int64->Int64)?"); self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="random", .type=random_int64_type, .default_val=FakeAST(None)); - return Texts("List$random_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type(item_t), ")"); + return Texts("List", SEP, "random_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type(item_t), ")"); } else if (streq(call->name, "sort") || streq(call->name, "sorted")) { if (streq(call->name, "sort")) EXPECT_POINTER("a", "list"); @@ -3266,7 +3265,7 @@ Text_t compile(env_t *env, ast_t *ast) } else { comparison = Texts("((Closure_t){.fn=generic_compare, .userdata=(void*)", compile_type_info(item_t), "})"); } - return Texts("List$", call->name, "(", self, ", ", comparison, ", ", padded_item_size, ")"); + return Texts("List", SEP, call->name, "(", self, ", ", comparison, ", ", padded_item_size, ")"); } else if (streq(call->name, "heapify")) { EXPECT_POINTER("a", "list"); Text_t comparison; @@ -3278,7 +3277,7 @@ Text_t compile(env_t *env, ast_t *ast) } else { comparison = Texts("((Closure_t){.fn=generic_compare, .userdata=(void*)", compile_type_info(item_t), "})"); } - return Texts("List$heapify(", self, ", ", comparison, ", ", padded_item_size, ")"); + return Texts("List", SEP, "heapify(", self, ", ", comparison, ", ", padded_item_size, ")"); } else if (streq(call->name, "heap_push")) { EXPECT_POINTER("a", "list"); type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true); @@ -3289,7 +3288,7 @@ Text_t compile(env_t *env, ast_t *ast) arg_t *arg_spec = new(arg_t, .name="item", .type=item_t, .next=new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t), .default_val=default_cmp)); Text_t arg_code = compile_arguments(env, ast, arg_spec, call->args); - return Texts("List$heap_push_value(", self, ", ", arg_code, ", ", padded_item_size, ")"); + return Texts("List", SEP, "heap_push_value(", self, ", ", arg_code, ", ", padded_item_size, ")"); } else if (streq(call->name, "heap_pop")) { EXPECT_POINTER("a", "list"); type_t *item_ptr = Type(PointerType, .pointed=item_t, .is_stack=true); @@ -3299,7 +3298,7 @@ Text_t compile(env_t *env, ast_t *ast) .type=Type(ClosureType, .fn=fn_t)); arg_t *arg_spec = new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t), .default_val=default_cmp); Text_t arg_code = compile_arguments(env, ast, arg_spec, call->args); - return Texts("List$heap_pop_value(", self, ", ", arg_code, ", ", compile_type(item_t), ", _, ", + return Texts("List", SEP, "heap_pop_value(", self, ", ", arg_code, ", ", compile_type(item_t), ", _, ", promote_to_optional(item_t, Text("_")), ", ", compile_none(item_t), ")"); } else if (streq(call->name, "binary_search")) { self = compile_to_pointer_depth(env, call->self, 0, call->args != NULL); @@ -3312,15 +3311,15 @@ Text_t compile(env_t *env, ast_t *ast) arg_t *arg_spec = new(arg_t, .name="target", .type=item_t, .next=new(arg_t, .name="by", .type=Type(ClosureType, .fn=fn_t), .default_val=default_cmp)); Text_t arg_code = compile_arguments(env, ast, arg_spec, call->args); - return Texts("List$binary_search_value(", self, ", ", arg_code, ")"); + return Texts("List", SEP, "binary_search_value(", self, ", ", arg_code, ")"); } else if (streq(call->name, "clear")) { EXPECT_POINTER("a", "list"); (void)compile_arguments(env, ast, NULL, call->args); - return Texts("List$clear(", self, ")"); + return Texts("List", SEP, "clear(", self, ")"); } else if (streq(call->name, "find")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="item", .type=item_t); - return Texts("List$find_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), + return Texts("List", SEP, "find_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "where")) { self = compile_to_pointer_depth(env, call->self, 0, call->args != NULL); @@ -3328,41 +3327,41 @@ Text_t compile(env_t *env, ast_t *ast) type_t *predicate_type = Type( ClosureType, .fn=NewFunctionType(Type(BoolType), {.name="item", .type=item_ptr})); arg_t *arg_spec = new(arg_t, .name="predicate", .type=predicate_type); - return Texts("List$first(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); + return Texts("List", SEP, "first(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); } else if (streq(call->name, "from")) { self = compile_to_pointer_depth(env, call->self, 0, true); arg_t *arg_spec = new(arg_t, .name="first", .type=INT_TYPE); - return Texts("List$from(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); + return Texts("List", SEP, "from(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); } else if (streq(call->name, "to")) { self = compile_to_pointer_depth(env, call->self, 0, true); arg_t *arg_spec = new(arg_t, .name="last", .type=INT_TYPE); - return Texts("List$to(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); + return Texts("List", SEP, "to(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); } else if (streq(call->name, "slice")) { self = compile_to_pointer_depth(env, call->self, 0, true); arg_t *arg_spec = new(arg_t, .name="first", .type=INT_TYPE, .next=new(arg_t, .name="last", .type=INT_TYPE)); - return Texts("List$slice(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); + return Texts("List", SEP, "slice(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); } else if (streq(call->name, "by")) { self = compile_to_pointer_depth(env, call->self, 0, true); arg_t *arg_spec = new(arg_t, .name="stride", .type=INT_TYPE); - return Texts("List$by(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); + return Texts("List", SEP, "by(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", padded_item_size, ")"); } else if (streq(call->name, "reversed")) { self = compile_to_pointer_depth(env, call->self, 0, true); (void)compile_arguments(env, ast, NULL, call->args); - return Texts("List$reversed(", self, ", ", padded_item_size, ")"); + return Texts("List", SEP, "reversed(", self, ", ", padded_item_size, ")"); } else if (streq(call->name, "unique")) { self = compile_to_pointer_depth(env, call->self, 0, false); (void)compile_arguments(env, ast, NULL, call->args); - return Texts("Table$from_entries(", self, ", Set$info(", compile_type_info(item_t), "))"); + return Texts("Table", SEP, "from_entries(", self, ", Set", SEP, "info(", compile_type_info(item_t), "))"); } else if (streq(call->name, "pop")) { EXPECT_POINTER("a", "list"); arg_t *arg_spec = new(arg_t, .name="index", .type=INT_TYPE, .default_val=FakeAST(Int, "-1")); Text_t index = compile_arguments(env, ast, arg_spec, call->args); - return Texts("List$pop(", self, ", ", index, ", ", compile_type(item_t), ", _, ", + return Texts("List", SEP, "pop(", self, ", ", index, ", ", compile_type(item_t), ", _, ", promote_to_optional(item_t, Text("_")), ", ", compile_none(item_t), ")"); } else if (streq(call->name, "counts")) { self = compile_to_pointer_depth(env, call->self, 0, false); (void)compile_arguments(env, ast, NULL, call->args); - return Texts("List$counts(", self, ", ", compile_type_info(self_value_t), ")"); + return Texts("List", SEP, "counts(", self, ", ", compile_type_info(self_value_t), ")"); } else code_err(ast, "There is no '", call->name, "' method for lists"); } case SetType: { @@ -3370,12 +3369,12 @@ Text_t compile(env_t *env, ast_t *ast) if (streq(call->name, "has")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="key", .type=set->item_type); - return Texts("Table$has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("Table", SEP, "has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "add")) { EXPECT_POINTER("a", "set"); arg_t *arg_spec = new(arg_t, .name="item", .type=set->item_type); - return Texts("Table$set_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", NULL, ", + return Texts("Table", SEP, "set_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", NULL, ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "add_all")) { EXPECT_POINTER("a", "set"); @@ -3383,12 +3382,12 @@ Text_t compile(env_t *env, ast_t *ast) return Texts("({ Table_t *set = ", self, "; ", "List_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ", "for (int64_t i = 0; i < to_add.length; i++)\n" - "Table$set(set, to_add.data + i*to_add.stride, NULL, ", compile_type_info(self_value_t), ");\n", + "Table", SEP, "set(set, to_add.data + i*to_add.stride, NULL, ", compile_type_info(self_value_t), ");\n", "(void)0; })"); } else if (streq(call->name, "remove")) { EXPECT_POINTER("a", "set"); arg_t *arg_spec = new(arg_t, .name="item", .type=set->item_type); - return Texts("Table$remove_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("Table", SEP, "remove_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "remove_all")) { EXPECT_POINTER("a", "set"); @@ -3396,38 +3395,38 @@ Text_t compile(env_t *env, ast_t *ast) return Texts("({ Table_t *set = ", self, "; ", "List_t to_add = ", compile_arguments(env, ast, arg_spec, call->args), "; ", "for (int64_t i = 0; i < to_add.length; i++)\n" - "Table$remove(set, to_add.data + i*to_add.stride, ", compile_type_info(self_value_t), ");\n", + "Table", SEP, "remove(set, to_add.data + i*to_add.stride, ", compile_type_info(self_value_t), ");\n", "(void)0; })"); } else if (streq(call->name, "clear")) { EXPECT_POINTER("a", "set"); (void)compile_arguments(env, ast, NULL, call->args); - return Texts("Table$clear(", self, ")"); + return Texts("Table", SEP, "clear(", self, ")"); } else if (streq(call->name, "with")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="other", .type=self_value_t); - return Texts("Table$with(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), + return Texts("Table", SEP, "with(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "overlap")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="other", .type=self_value_t); - return Texts("Table$overlap(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), + return Texts("Table", SEP, "overlap(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "without")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="other", .type=self_value_t); - return Texts("Table$without(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), + return Texts("Table", SEP, "without(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "is_subset_of")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="other", .type=self_value_t, .next=new(arg_t, .name="strict", .type=Type(BoolType), .default_val=FakeAST(Bool, false))); - return Texts("Table$is_subset_of(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), + return Texts("Table", SEP, "is_subset_of(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "is_superset_of")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="other", .type=self_value_t, .next=new(arg_t, .name="strict", .type=Type(BoolType), .default_val=FakeAST(Bool, false))); - return Texts("Table$is_superset_of(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), + return Texts("Table", SEP, "is_superset_of(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else code_err(ast, "There is no '", call->name, "' method for tables"); } @@ -3437,7 +3436,7 @@ Text_t compile(env_t *env, ast_t *ast) self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="key", .type=table->key_type); return Texts( - "Table$get_optional(", self, ", ", compile_type(table->key_type), ", ", + "Table", SEP, "get_optional(", self, ", ", compile_type(table->key_type), ", ", compile_type(table->value_type), ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", "_, ", optional_into_nonnone(table->value_type, Text("(*_)")), ", ", compile_none(table->value_type), ", ", compile_type_info(self_value_t), ")"); @@ -3445,7 +3444,7 @@ Text_t compile(env_t *env, ast_t *ast) self = compile_to_pointer_depth(env, call->self, 1, false); arg_t *arg_spec = new(arg_t, .name="key", .type=table->key_type, .next=new(arg_t, .name="default", .type=table->value_type, .default_val=table->default_value)); - return Texts("*Table$get_or_setdefault(", + return Texts("*Table", SEP, "get_or_setdefault(", self, ", ", compile_type(table->key_type), ", ", compile_type(table->value_type), ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", @@ -3453,31 +3452,31 @@ Text_t compile(env_t *env, ast_t *ast) } else if (streq(call->name, "has")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="key", .type=table->key_type); - return Texts("Table$has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("Table", SEP, "has_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "set")) { EXPECT_POINTER("a", "table"); arg_t *arg_spec = new(arg_t, .name="key", .type=table->key_type, .next=new(arg_t, .name="value", .type=table->value_type)); - return Texts("Table$set_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("Table", SEP, "set_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "remove")) { EXPECT_POINTER("a", "table"); arg_t *arg_spec = new(arg_t, .name="key", .type=table->key_type); - return Texts("Table$remove_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", + return Texts("Table", SEP, "remove_value(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "clear")) { EXPECT_POINTER("a", "table"); (void)compile_arguments(env, ast, NULL, call->args); - return Texts("Table$clear(", self, ")"); + return Texts("Table", SEP, "clear(", self, ")"); } else if (streq(call->name, "sorted")) { self = compile_to_pointer_depth(env, call->self, 0, false); (void)compile_arguments(env, ast, NULL, call->args); - return Texts("Table$sorted(", self, ", ", compile_type_info(self_value_t), ")"); + return Texts("Table", SEP, "sorted(", self, ", ", compile_type_info(self_value_t), ")"); } else if (streq(call->name, "with_fallback")) { self = compile_to_pointer_depth(env, call->self, 0, false); arg_t *arg_spec = new(arg_t, .name="fallback", .type=Type(OptionalType, self_value_t)); - return Texts("Table$with_fallback(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); + return Texts("Table", SEP, "with_fallback(", self, ", ", compile_arguments(env, ast, arg_spec, call->args), ")"); } else code_err(ast, "There is no '", call->name, "' method for tables"); } default: { @@ -3534,7 +3533,7 @@ Text_t compile(env_t *env, ast_t *ast) return Text("\"\""); else if (call->args->value->tag == TextJoin && Match(call->args->value, TextJoin)->children->next == NULL) return compile_text_literal(Match(Match(call->args->value, TextJoin)->children->ast, TextLiteral)->text); - return Texts("Text$as_c_string(", expr_as_text(compile(env, call->args->value), actual, Text("no")), ")"); + return Texts("Text", SEP, "as_c_string(", expr_as_text(compile(env, call->args->value), actual, Text("no")), ")"); } else if (t->tag == StructType) { DeclareMatch(struct_, t, StructType); if (!struct_->opaque && is_valid_call(env, struct_->fields, call->args, true)) { @@ -3686,7 +3685,7 @@ Text_t compile(env_t *env, ast_t *ast) if (!item_t) code_err(reduction->iter, "I couldn't figure out how to iterate over this type: ", type_to_str(iter_t)); static int64_t next_id = 1; - ast_t *item = FakeAST(Var, String("$it", next_id++)); + ast_t *item = FakeAST(Var, String(INTERNAL_ID("it"), next_id++)); ast_t *body = LiteralCode(Text("{}")); // placeholder ast_t *loop = FakeAST(For, .vars=new(ast_list_t, .ast=item), .iter=reduction->iter, .body=body); env_t *body_scope = for_scope(env, loop); @@ -3695,7 +3694,7 @@ Text_t compile(env_t *env, ast_t *ast) type_t *item_value_type = item_t; ast_t *item_value = item; if (reduction->key) { - set_binding(body_scope, "$", item_t, compile(body_scope, item)); + set_binding(body_scope, "ヽ", item_t, compile(body_scope, item)); item_value = reduction->key; item_value_type = get_type(body_scope, reduction->key); } @@ -3735,7 +3734,7 @@ Text_t compile(env_t *env, ast_t *ast) ast_e cmp_op = op == Min ? LessThan : GreaterThan; if (reduction->key) { env_t *key_scope = fresh_scope(env); - set_binding(key_scope, "$", item_t, item_code); + set_binding(key_scope, "ヽ", item_t, item_code); type_t *key_type = get_type(key_scope, reduction->key); Text_t superlative_key = op == Min ? Text("min_key") : Text("max_key"); code = Texts(code, compile_declaration(key_type, superlative_key), ";\n"); @@ -3771,7 +3770,7 @@ Text_t compile(env_t *env, ast_t *ast) type_t *reduction_type = Match(get_type(env, ast), OptionalType)->type; ast_t *item_value = item; if (reduction->key) { - set_binding(body_scope, "$", item_t, compile(body_scope, item)); + set_binding(body_scope, "ヽ", item_t, compile(body_scope, item)); item_value = reduction->key; } @@ -3837,7 +3836,7 @@ Text_t compile(env_t *env, ast_t *ast) Text_t text = compile_to_pointer_depth(env, f->fielded, 0, false); return Texts("((Text_t)", text, ")"); } else if (streq(f->field, "length")) { - return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").length)"); + return Texts("Int", SEP, "from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").length)"); } code_err(ast, "There is no '", f->field, "' field on ", type_to_str(value_t), " values"); } @@ -3859,13 +3858,13 @@ Text_t compile(env_t *env, ast_t *ast) DeclareMatch(e, value_t, EnumType); for (tag_t *tag = e->tags; tag; tag = tag->next) { if (streq(f->field, tag->name)) { - Text_t tag_name = namespace_name(e->env, e->env->namespace, Texts("tag$", tag->name)); + Text_t tag_name = namespace_name(e->env, e->env->namespace, Texts(INTERNAL_ID("tag"), SEP, tag->name)); if (fielded_t->tag == PointerType) { Text_t fielded = compile_to_pointer_depth(env, f->fielded, 1, false); - return Texts("((", fielded, ")->$tag == ", tag_name, ")"); + return Texts("((", fielded, ")->", INTERNAL_ID("tag"), " == ", tag_name, ")"); } else if (enum_has_fields(value_t)) { Text_t fielded = compile(env, f->fielded); - return Texts("((", fielded, ").$tag == ", tag_name, ")"); + return Texts("((", fielded, ").", INTERNAL_ID("tag"), " == ", tag_name, ")"); } else { Text_t fielded = compile(env, f->fielded); return Texts("((", fielded, ") == ", tag_name, ")"); @@ -3876,19 +3875,19 @@ Text_t compile(env_t *env, ast_t *ast) } case ListType: { if (streq(f->field, "length")) - return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").length)"); + return Texts("Int", SEP, "from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").length)"); code_err(ast, "There is no ", f->field, " field on lists"); } case SetType: { if (streq(f->field, "items")) return Texts("LIST_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)"); else if (streq(f->field, "length")) - return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries.length)"); + return Texts("Int", SEP, "from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries.length)"); code_err(ast, "There is no '", f->field, "' field on sets"); } case TableType: { if (streq(f->field, "length")) { - return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries.length)"); + return Texts("Int", SEP, "from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries.length)"); } else if (streq(f->field, "keys")) { return Texts("LIST_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)"); } else if (streq(f->field, "values")) { @@ -3906,7 +3905,7 @@ Text_t compile(env_t *env, ast_t *ast) } case ModuleType: { const char *name = Match(value_t, ModuleType)->name; - env_t *module_env = Table$str_get(*env->imports, name); + env_t *module_env = Tableヽstr_get(*env->imports, name); return compile(module_env, WrapAST(ast, Var, f->field)); } default: @@ -3939,7 +3938,7 @@ Text_t compile(env_t *env, ast_t *ast) file_t *f = indexing->index->file; Text_t index_code = indexing->index->tag == Int ? compile_int_to_type(env, indexing->index, Type(IntType, .bits=TYPE_IBITS64)) - : (index_t->tag == BigIntType ? Texts("Int64$from_int(", compile(env, indexing->index), ", no)") + : (index_t->tag == BigIntType ? Texts("Int64", SEP, "from_int(", compile(env, indexing->index), ", no)") : Texts("(Int64_t)(", compile(env, indexing->index), ")")); if (indexing->unchecked) return Texts("List_get_unchecked(", compile_type(item_type), ", ", list, ", ", index_code, ")"); @@ -3953,7 +3952,7 @@ Text_t compile(env_t *env, ast_t *ast) if (indexing->unchecked) code_err(ast, "Table indexes cannot be unchecked"); if (table_type->default_value) { - return Texts("Table$get_or_default(", + return Texts("Table", SEP, "get_or_default(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", compile_type(table_type->key_type), ", ", compile_type(table_type->value_type), ", ", @@ -3961,7 +3960,7 @@ Text_t compile(env_t *env, ast_t *ast) compile_to_type(env, table_type->default_value, table_type->value_type), ", ", compile_type_info(container_t), ")"); } else { - return Texts("Table$get_optional(", + return Texts("Table", SEP, "get_optional(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", compile_type(table_type->key_type), ", ", compile_type(table_type->value_type), ", ", @@ -3971,7 +3970,7 @@ Text_t compile(env_t *env, ast_t *ast) compile_type_info(container_t), ")"); } } else if (container_t->tag == TextType) { - return Texts("Text$cluster(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", compile_to_type(env, indexing->index, Type(BigIntType)), ")"); + return Texts("Text", SEP, "cluster(", compile_to_pointer_depth(env, indexing->indexed, 0, false), ", ", compile_to_type(env, indexing->index, Type(BigIntType)), ")"); } else { code_err(ast, "Indexing is not supported for type: ", type_to_str(container_t)); } @@ -3998,59 +3997,59 @@ Text_t compile(env_t *env, ast_t *ast) Text_t compile_type_info(type_t *t) { if (t == NULL) compiler_err(NULL, NULL, NULL, "Attempt to compile a NULL type"); - if (t == PATH_TYPE) return Text("&Path$info"); - else if (t == PATH_TYPE_TYPE) return Text("&PathType$info"); + if (t == PATH_TYPE) return Texts("&Path", SEP, "info"); + else if (t == PATH_TYPE_TYPE) return Texts("&PathType", SEP, "info"); switch (t->tag) { case BoolType: case ByteType: case IntType: case BigIntType: case NumType: case CStringType: - return Texts("&", type_to_text(t), "$info"); + return Texts("&", type_to_text(t), SEP, "info"); case TextType: { DeclareMatch(text, t, TextType); if (!text->lang || streq(text->lang, "Text")) - return Text("&Text$info"); - return Texts("(&", namespace_name(text->env, text->env->namespace, Text("$info")), ")"); + return Texts("&Text", SEP, "info"); + return Texts("(&", namespace_name(text->env, text->env->namespace, Texts(INTERNAL_ID("info"))), ")"); } case StructType: { DeclareMatch(s, t, StructType); - return Texts("(&", namespace_name(s->env, s->env->namespace, Text("$info")), ")"); + return Texts("(&", namespace_name(s->env, s->env->namespace, Texts(INTERNAL_ID("info"))), ")"); } case EnumType: { DeclareMatch(e, t, EnumType); - return Texts("(&", namespace_name(e->env, e->env->namespace, Text("$info")), ")"); + return Texts("(&", namespace_name(e->env, e->env->namespace, Texts(INTERNAL_ID("info"))), ")"); } case ListType: { type_t *item_t = Match(t, ListType)->item_type; - return Texts("List$info(", compile_type_info(item_t), ")"); + return Texts("List", SEP, "info(", compile_type_info(item_t), ")"); } case SetType: { type_t *item_type = Match(t, SetType)->item_type; - return Texts("Set$info(", compile_type_info(item_type), ")"); + return Texts("Set", SEP, "info(", compile_type_info(item_type), ")"); } case TableType: { DeclareMatch(table, t, TableType); type_t *key_type = table->key_type; type_t *value_type = table->value_type; - return Texts("Table$info(", compile_type_info(key_type), ", ", compile_type_info(value_type), ")"); + return Texts("Table", SEP, "info(", compile_type_info(key_type), ", ", compile_type_info(value_type), ")"); } case PointerType: { DeclareMatch(ptr, t, PointerType); const char *sigil = ptr->is_stack ? "&" : "@"; - return Texts("Pointer$info(", quoted_str(sigil), ", ", compile_type_info(ptr->pointed), ")"); + return Texts("Pointer", SEP, "info(", quoted_str(sigil), ", ", compile_type_info(ptr->pointed), ")"); } case FunctionType: { - return Texts("Function$info(", quoted_text(type_to_text(t)), ")"); + return Texts("Function", SEP, "info(", quoted_text(type_to_text(t)), ")"); } case ClosureType: { - return Texts("Closure$info(", quoted_text(type_to_text(t)), ")"); + return Texts("Closure", SEP, "info(", quoted_text(type_to_text(t)), ")"); } case OptionalType: { type_t *non_optional = Match(t, OptionalType)->type; - return Texts("Optional$info(sizeof(", compile_type(non_optional), + return Texts("Optional", SEP, "info(sizeof(", compile_type(non_optional), "), __alignof__(", compile_type(non_optional), "), ", compile_type_info(non_optional), ")"); } - case TypeInfoType: return Texts("Type$info(", quoted_text(type_to_text(Match(t, TypeInfoType)->type)), ")"); - case MemoryType: return Text("&Memory$info"); - case VoidType: return Text("&Void$info"); + case TypeInfoType: return Texts("Type", SEP, "info(", quoted_text(type_to_text(Match(t, TypeInfoType)->type)), ")"); + case MemoryType: return Texts("&Memory", SEP, "info"); + case VoidType: return Texts("&Void", SEP, "info"); default: compiler_err(NULL, 0, 0, "I couldn't convert to a type info: ", type_to_str(t)); } @@ -4099,7 +4098,7 @@ Text_t compile_cli_arg_call(env_t *env, Text_t fn_name, type_t *fn_type, const c for (arg_t *arg = fn_info->args; arg; arg = arg->next) { usage = Texts(usage, " "); type_t *t = get_arg_type(main_env, arg); - Text_t flag = Text$replace(Text$from_str(arg->name), Text("_"), Text("-")); + Text_t flag = Textヽreplace(Textヽfrom_str(arg->name), Text("_"), Text("-")); if (arg->default_val || arg->type->tag == OptionalType) { if (strlen(arg->name) == 1) { if (t->tag == BoolType || (t->tag == OptionalType && Match(t, OptionalType)->type->tag == BoolType)) @@ -4125,14 +4124,14 @@ Text_t compile_cli_arg_call(env_t *env, Text_t fn_name, type_t *fn_type, const c usage = Texts(usage, "<", flag, ">"); } } - code = Texts(code, "Text_t usage = Texts(Text(\"Usage: \"), Text$from_str(argv[0])", + code = Texts(code, "Text_t usage = Texts(Text(\"Usage: \"), Text", SEP, "from_str(argv[0])", usage.length == 0 ? EMPTY_TEXT : Texts(", Text(", quoted_text(usage), ")"), ");\n"); } for (arg_t *arg = fn_info->args; arg; arg = arg->next) { type_t *opt_type = arg->type->tag == OptionalType ? arg->type : Type(OptionalType, .type=arg->type); - code = Texts(code, compile_declaration(opt_type, Texts("_$", arg->name))); + code = Texts(code, compile_declaration(opt_type, USER_ID(arg->name))); if (arg->default_val) { Text_t default_val = compile(env, arg->default_val); if (arg->type->tag != OptionalType) @@ -4147,16 +4146,16 @@ Text_t compile_cli_arg_call(env_t *env, Text_t fn_name, type_t *fn_type, const c Text_t version_code = quoted_str(version); code = Texts(code, "tomo_parse_args(argc, argv, ", usage_code, ", ", help_code, ", ", version_code); for (arg_t *arg = fn_info->args; arg; arg = arg->next) { - code = Texts(code, ",\n{", quoted_text(Text$replace(Text$from_str(arg->name), Text("_"), Text("-"))), ", ", + code = Texts(code, ",\n{", quoted_text(Textヽreplace(Textヽfrom_str(arg->name), Text("_"), Text("-"))), ", ", (arg->default_val || arg->type->tag == OptionalType) ? "false" : "true", ", ", compile_type_info(arg->type), - ", &", Texts("_$", arg->name), "}"); + ", &", USER_ID(arg->name), "}"); } code = Texts(code, ");\n"); code = Texts(code, fn_name, "("); for (arg_t *arg = fn_info->args; arg; arg = arg->next) { - Text_t arg_code = Texts("_$", arg->name); + Text_t arg_code = USER_ID(arg->name); if (arg->type->tag != OptionalType) arg_code = optional_into_nonnone(arg->type, arg_code); @@ -4201,11 +4200,11 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static Table_t used_names = {}; for (arg_ast_t *arg = args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); - arg_signature = Texts(arg_signature, compile_declaration(arg_type, Texts("_$", arg->name))); + arg_signature = Texts(arg_signature, compile_declaration(arg_type, USER_ID(arg->name))); if (arg->next) arg_signature = Texts(arg_signature, ", "); - if (Table$str_get(used_names, arg->name)) + if (Tableヽstr_get(used_names, arg->name)) code_err(ast, "The argument name '", arg->name, "' is used more than once"); - Table$str_set(&used_names, arg->name, arg->name); + Tableヽstr_set(&used_names, arg->name, arg->name); } arg_signature = Texts(arg_signature, ")"); @@ -4218,7 +4217,7 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static Text_t code; if (cache) { - code = Texts("static ", ret_type_code, " ", name_code, "$uncached", arg_signature); + code = Texts("static ", ret_type_code, " ", name_code, SEP, "uncached", arg_signature); } else { code = Texts(ret_type_code, " ", name_code, arg_signature); if (is_inline) @@ -4236,7 +4235,7 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static body_scope->deferred = NULL; for (arg_ast_t *arg = args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); - set_binding(body_scope, arg->name, arg_type, Texts("_$", arg->name)); + set_binding(body_scope, arg->name, arg_type, USER_ID(arg->name)); } body_scope->fn_ret = ret_t; @@ -4263,7 +4262,7 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static "static ", compile_declaration(ret_t, Text("cached_result")), ";\n", "static bool initialized = false;\n", "if (!initialized) {\n" - "\tcached_result = ", name_code, "$uncached();\n", + "\tcached_result = ", name_code, SEP, "uncached();\n", "\tinitialized = true;\n", "}\n", "return cached_result;\n" @@ -4271,13 +4270,13 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static definition = Texts(definition, wrapper); } else if (cache && cache->tag == Int) { assert(args); - OptionalInt64_t cache_size = Int64$parse(Text$from_str(Match(cache, Int)->str), NULL); + OptionalInt64_t cache_size = Int64ヽparse(Textヽfrom_str(Match(cache, Int)->str), NULL); Text_t pop_code = EMPTY_TEXT; if (cache->tag == Int && !cache_size.is_none && cache_size.value > 0) { // FIXME: this currently just deletes the first entry, but this should be more like a // least-recently-used cache eviction policy or least-frequently-used pop_code = Texts("if (cache.entries.length > ", String(cache_size.value), - ") Table$remove(&cache, cache.entries.data + cache.entries.stride*0, table_type);\n"); + ") Table", SEP, "remove(&cache, cache.entries.data + cache.entries.stride*0, table_type);\n"); } if (!args->next) { @@ -4286,12 +4285,12 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static Text_t wrapper = Texts( is_private ? EMPTY_TEXT : Text("public "), ret_type_code, " ", name_code, arg_signature, "{\n" "static Table_t cache = {};\n", - "const TypeInfo_t *table_type = Table$info(", compile_type_info(arg_type), ", ", compile_type_info(ret_t), ");\n", - compile_declaration(Type(PointerType, .pointed=ret_t), Text("cached")), " = Table$get_raw(cache, &_$", args->name, ", table_type);\n" + "const TypeInfo_t *table_type = Table", SEP, "info(", compile_type_info(arg_type), ", ", compile_type_info(ret_t), ");\n", + compile_declaration(Type(PointerType, .pointed=ret_t), Text("cached")), " = Table", SEP, "get_raw(cache, &", USER_ID(args->name), ", table_type);\n" "if (cached) return *cached;\n", - compile_declaration(ret_t, Text("ret")), " = ", name_code, "$uncached(_$", args->name, ");\n", + compile_declaration(ret_t, Text("ret")), " = ", name_code, SEP, "uncached(", USER_ID(args->name), ");\n", pop_code, - "Table$set(&cache, &_$", args->name, ", &ret, table_type);\n" + "Table", SEP, "set(&cache, &", USER_ID(args->name), ", &ret, table_type);\n" "return ret;\n" "}\n"); definition = Texts(definition, wrapper); @@ -4301,10 +4300,10 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static for (arg_ast_t *arg = args; arg; arg = arg->next) fields = new(arg_t, .name=arg->name, .type=get_arg_ast_type(env, arg), .next=fields); REVERSE_LIST(fields); - type_t *t = Type(StructType, .name=String("func$", get_line_number(ast->file, ast->start), "$args"), .fields=fields, .env=env); + type_t *t = Type(StructType, .name=String("func", SEP, get_line_number(ast->file, ast->start), SEP, "args"), .fields=fields, .env=env); int64_t num_fields = used_names.entries.length; - const char *metamethods = is_packed_data(t) ? "PackedData$metamethods" : "Struct$metamethods"; + const char *metamethods = is_packed_data(t) ? "PackedDataヽmetamethods" : "Structヽmetamethods"; Text_t args_typeinfo = Texts("((TypeInfo_t[1]){{.size=sizeof(args), .align=__alignof__(args), .metamethods=", metamethods, ", .tag=StructInfo, .StructInfo.name=\"FunctionArguments\", " ".StructInfo.num_fields=", String(num_fields), @@ -4312,7 +4311,7 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static Text_t args_type = Text("struct { "); for (arg_t *f = fields; f; f = f->next) { args_typeinfo = Texts(args_typeinfo, "{\"", f->name, "\", ", compile_type_info(f->type), "}"); - args_type = Texts(args_type, compile_declaration(f->type, Text$from_str(f->name)), "; "); + args_type = Texts(args_type, compile_declaration(f->type, Textヽfrom_str(f->name)), "; "); if (f->next) args_typeinfo = Texts(args_typeinfo, ", "); } args_type = Texts(args_type, "}"); @@ -4320,25 +4319,25 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static Text_t all_args = EMPTY_TEXT; for (arg_ast_t *arg = args; arg; arg = arg->next) - all_args = Texts(all_args, "_$", arg->name, arg->next ? Text(", ") : EMPTY_TEXT); + all_args = Texts(all_args, USER_ID(arg->name), arg->next ? Text(", ") : EMPTY_TEXT); Text_t wrapper = Texts( is_private ? EMPTY_TEXT : Text("public "), ret_type_code, " ", name_code, arg_signature, "{\n" "static Table_t cache = {};\n", args_type, " args = {", all_args, "};\n" - "const TypeInfo_t *table_type = Table$info(", args_typeinfo, ", ", compile_type_info(ret_t), ");\n", - compile_declaration(Type(PointerType, .pointed=ret_t), Text("cached")), " = Table$get_raw(cache, &args, table_type);\n" + "const TypeInfo_t *table_type = Table", SEP, "info(", args_typeinfo, ", ", compile_type_info(ret_t), ");\n", + compile_declaration(Type(PointerType, .pointed=ret_t), Text("cached")), " = Table", SEP, "get_raw(cache, &args, table_type);\n" "if (cached) return *cached;\n", - compile_declaration(ret_t, Text("ret")), " = ", name_code, "$uncached(", all_args, ");\n", + compile_declaration(ret_t, Text("ret")), " = ", name_code, SEP, "uncached(", all_args, ");\n", pop_code, - "Table$set(&cache, &args, &ret, table_type);\n" + "Table", SEP, "set(&cache, &args, &ret, table_type);\n" "return ret;\n" "}\n"); definition = Texts(definition, wrapper); } } - Text_t qualified_name = Text$from_str(function_name); + Text_t qualified_name = Textヽfrom_str(function_name); if (env->namespace && env->namespace->parent && env->namespace->name) qualified_name = Texts(env->namespace->name, ".", qualified_name); Text_t text = Texts("func ", qualified_name, "("); @@ -4360,15 +4359,15 @@ Text_t compile_top_level_code(env_t *env, ast_t *ast) case Use: { // DeclareMatch(use, ast, Use); // if (use->what == USE_C_CODE) { - // Path_t path = Path$relative_to(Path$from_str(use->path), Path(".build")); - // return Texts("#include \"", Path$as_c_string(path), "\"\n"); + // Path_t path = Pathヽrelative_to(Pathヽfrom_str(use->path), Path(".build")); + // return Texts("#include \"", Pathヽas_c_string(path), "\"\n"); // } return EMPTY_TEXT; } case Declare: { DeclareMatch(decl, ast, Declare); const char *decl_name = Match(decl->var, Var)->name; - Text_t full_name = namespace_name(env, env->namespace, Text$from_str(decl_name)); + Text_t full_name = namespace_name(env, env->namespace, Textヽfrom_str(decl_name)); type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value); if (t->tag == FunctionType) t = Type(ClosureType, t); Text_t val_code = compile_declared_value(env, ast); @@ -4379,11 +4378,11 @@ Text_t compile_top_level_code(env_t *env, ast_t *ast) is_private ? "static " : "public ", compile_declaration(t, full_name), " = ", val_code, ";\n"); } else { - Text_t init_var = namespace_name(env, env->namespace, Texts(decl_name, "$$initialized")); + Text_t init_var = namespace_name(env, env->namespace, Texts(decl_name, SEP, INTERNAL_ID("initialized"))); Text_t checked_access = Texts("check_initialized(", full_name, ", ", init_var, ", \"", decl_name, "\")"); set_binding(env, decl_name, t, checked_access); - Text_t initialized_name = namespace_name(env, env->namespace, Texts(decl_name, "$$initialized")); + Text_t initialized_name = namespace_name(env, env->namespace, Texts(decl_name, SEP, INTERNAL_ID("initialized"))); return Texts( "static bool ", initialized_name, " = false;\n", is_private ? "static " : "public ", @@ -4391,7 +4390,7 @@ Text_t compile_top_level_code(env_t *env, ast_t *ast) } } case FunctionDef: { - Text_t name_code = namespace_name(env, env->namespace, Text$from_str(Match(Match(ast, FunctionDef)->name, Var)->name)); + Text_t name_code = namespace_name(env, env->namespace, Textヽfrom_str(Match(Match(ast, FunctionDef)->name, Var)->name)); return compile_function(env, name_code, ast, &env->code->staticdefs); } case ConvertDef: { @@ -4399,12 +4398,12 @@ Text_t compile_top_level_code(env_t *env, ast_t *ast) const char *name = get_type_name(Match(type, FunctionType)->ret); if (!name) code_err(ast, "Conversions are only supported for text, struct, and enum types, not ", type_to_str(Match(type, FunctionType)->ret)); - Text_t name_code = namespace_name(env, env->namespace, Texts(name, "$", String(get_line_number(ast->file, ast->start)))); + Text_t name_code = namespace_name(env, env->namespace, Texts(name, SEP, String(get_line_number(ast->file, ast->start)))); return compile_function(env, name_code, ast, &env->code->staticdefs); } case StructDef: { DeclareMatch(def, ast, StructDef); - type_t *t = Table$str_get(*env->types, def->name); + type_t *t = Tableヽstr_get(*env->types, def->name); assert(t && t->tag == StructType); Text_t code = compile_struct_typeinfo(env, t, def->name, def->fields, def->secret, def->opaque); env_t *ns_env = namespace_env(env, def->name); @@ -4419,9 +4418,9 @@ Text_t compile_top_level_code(env_t *env, ast_t *ast) } case LangDef: { DeclareMatch(def, ast, LangDef); - Text_t code = Texts("public const TypeInfo_t ", namespace_name(env, env->namespace, Texts(def->name, "$$info")), + Text_t code = Texts("public const TypeInfo_t ", namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("info"))), " = {", String((int64_t)sizeof(Text_t)), ", ", String((int64_t)__alignof__(Text_t)), - ", .metamethods=Text$metamethods, .tag=TextInfo, .TextInfo={", quoted_str(def->name), "}};\n"); + ", .metamethods=Text", SEP, "metamethods, .tag=TextInfo, .TextInfo={", quoted_str(def->name), "}};\n"); env_t *ns_env = namespace_env(env, def->name); return Texts(code, def->namespace ? compile_top_level_code(ns_env, def->namespace) : EMPTY_TEXT); } @@ -4461,12 +4460,12 @@ static void initialize_vars_and_statics(env_t *env, ast_t *ast) } else if (stmt->ast->tag == Declare) { DeclareMatch(decl, stmt->ast, Declare); const char *decl_name = Match(decl->var, Var)->name; - Text_t full_name = namespace_name(env, env->namespace, Text$from_str(decl_name)); + Text_t full_name = namespace_name(env, env->namespace, Textヽfrom_str(decl_name)); type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value); if (t->tag == FunctionType) t = Type(ClosureType, t); Text_t val_code = compile_declared_value(env, stmt->ast); if ((decl->value && !is_constant(env, decl->value)) || (!decl->value && has_heap_memory(t))) { - Text_t initialized_name = namespace_name(env, env->namespace, Texts(decl_name, "$$initialized")); + Text_t initialized_name = namespace_name(env, env->namespace, Texts(decl_name, SEP, INTERNAL_ID("initialized"))); env->code->variable_initializers = Texts( env->code->variable_initializers, with_source_info( @@ -4509,8 +4508,8 @@ Text_t compile_file(env_t *env, ast_t *ast) DeclareMatch(use, stmt->ast, Use); if (use->what == USE_C_CODE) { - Path_t path = Path$relative_to(Path$from_str(use->path), Path(".build")); - includes = Texts(includes, "#include \"", Path$as_c_string(path), "\"\n"); + Path_t path = Pathヽrelative_to(Pathヽfrom_str(use->path), Path(".build")); + includes = Texts(includes, "#include \"", Pathヽas_c_string(path), "\"\n"); } } } @@ -4528,7 +4527,7 @@ Text_t compile_file(env_t *env, ast_t *ast) env->code->lambdas, "\n", env->code->staticdefs, "\n", top_level_code, - "public void ", namespace_name(env, env->namespace, Text("$initialize")), "(void) {\n", + "public void ", namespace_name(env, env->namespace, Texts(INTERNAL_ID("initialize"))), "(void) {\n", "static bool initialized = false;\n", "if (initialized) return;\n", "initialized = true;\n", @@ -4542,9 +4541,9 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) switch (ast->tag) { case Use: { DeclareMatch(use, ast, Use); - Path_t source_path = Path$from_str(ast->file->filename); - Path_t source_dir = Path$parent(source_path); - Path_t build_dir = Path$resolved(Path$parent(header_path), Path$current_dir()); + Path_t source_path = Pathヽfrom_str(ast->file->filename); + Path_t source_dir = Pathヽparent(source_path); + Path_t build_dir = Pathヽresolved(Pathヽparent(header_path), Pathヽcurrent_dir()); switch (use->what) { case USE_MODULE: { module_info_t mod = get_module_info(ast); @@ -4558,26 +4557,26 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) Text_t includes = EMPTY_TEXT; for (size_t i = 0; i < tm_files.gl_pathc; i++) { const char *filename = tm_files.gl_pathv[i]; - Path_t tm_file = Path$from_str(filename); - Path_t lib_build_dir = Path$sibling(tm_file, Text(".build")); - Path_t header = Path$child(lib_build_dir, Texts(Path$base_name(tm_file), Text(".h"))); - includes = Texts(includes, "#include \"", Path$as_c_string(header), "\"\n"); + Path_t tm_file = Pathヽfrom_str(filename); + Path_t lib_build_dir = Pathヽsibling(tm_file, Text(".build")); + Path_t header = Pathヽchild(lib_build_dir, Texts(Pathヽbase_name(tm_file), Text(".h"))); + includes = Texts(includes, "#include \"", Pathヽas_c_string(header), "\"\n"); } globfree(&tm_files); return with_source_info(env, ast, includes); } case USE_LOCAL: { - Path_t used_path = Path$resolved(Path$from_str(use->path), source_dir); - Path_t used_build_dir = Path$sibling(used_path, Text(".build")); - Path_t used_header_path = Path$child(used_build_dir, Texts(Path$base_name(used_path), Text(".h"))); - return Texts("#include \"", Path$as_c_string(Path$relative_to(used_header_path, build_dir)), "\"\n"); + Path_t used_path = Pathヽresolved(Pathヽfrom_str(use->path), source_dir); + Path_t used_build_dir = Pathヽsibling(used_path, Text(".build")); + Path_t used_header_path = Pathヽchild(used_build_dir, Texts(Pathヽbase_name(used_path), Text(".h"))); + return Texts("#include \"", Pathヽas_c_string(Pathヽrelative_to(used_header_path, build_dir)), "\"\n"); } case USE_HEADER: if (use->path[0] == '<') { return Texts("#include ", use->path, "\n"); } else { - Path_t used_path = Path$resolved(Path$from_str(use->path), source_dir); - return Texts("#include \"", Path$as_c_string(Path$relative_to(used_path, build_dir)), "\"\n"); + Path_t used_path = Pathヽresolved(Pathヽfrom_str(use->path), source_dir); + return Texts("#include \"", Pathヽas_c_string(Pathヽrelative_to(used_path, build_dir)), "\"\n"); } default: return EMPTY_TEXT; @@ -4593,11 +4592,11 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) DeclareMatch(def, ast, LangDef); return Texts( // Constructor macro: - "#define ", namespace_name(env, env->namespace, Text$from_str(def->name)), - "(text) ((", namespace_name(env, env->namespace, Texts(def->name, "$$type")), "){.length=sizeof(text)-1, .tag=TEXT_ASCII, .ascii=\"\" text})\n" - "#define ", namespace_name(env, env->namespace, Text$from_str(def->name)), - "s(...) ((", namespace_name(env, env->namespace, Texts(def->name, "$$type")), ")Texts(__VA_ARGS__))\n" - "extern const TypeInfo_t ", namespace_name(env, env->namespace, Texts(def->name, Text("$$info"))), ";\n" + "#define ", namespace_name(env, env->namespace, Textヽfrom_str(def->name)), + "(text) ((", namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("type"))), "){.length=sizeof(text)-1, .tag=TEXT_ASCII, .ascii=\"\" text})\n" + "#define ", namespace_name(env, env->namespace, Textヽfrom_str(def->name)), + "s(...) ((", namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("type"))), ")Texts(__VA_ARGS__))\n" + "extern const TypeInfo_t ", namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("info"))), ";\n" ); } case Extend: { @@ -4659,7 +4658,7 @@ Text_t compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t } decl = Texts(decl, ")"); } else { - decl = compile_declaration(t, Text$from_str(ext->name)); + decl = compile_declaration(t, Textヽfrom_str(ext->name)); } return Texts("extern ", decl, ";\n"); } @@ -4679,7 +4678,7 @@ Text_t compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t return Texts( decl->value ? compile_statement_type_header(env, header_path, decl->value) : EMPTY_TEXT, - "extern ", compile_declaration(t, namespace_name(env, env->namespace, Text$from_str(decl_name))), ";\n"); + "extern ", compile_declaration(t, namespace_name(env, env->namespace, Textヽfrom_str(decl_name))), ";\n"); } case FunctionDef: { DeclareMatch(fndef, ast, FunctionDef); @@ -4689,7 +4688,7 @@ Text_t compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t Text_t arg_signature = Text("("); for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); - arg_signature = Texts(arg_signature, compile_declaration(arg_type, Texts("_$", arg->name))); + arg_signature = Texts(arg_signature, compile_declaration(arg_type, USER_ID(arg->name))); if (arg->next) arg_signature = Texts(arg_signature, ", "); } arg_signature = Texts(arg_signature, ")"); @@ -4698,9 +4697,9 @@ Text_t compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t Text_t ret_type_code = compile_type(ret_t); if (ret_t->tag == AbortType) ret_type_code = Texts("__attribute__((noreturn)) _Noreturn ", ret_type_code); - Text_t name = namespace_name(env, env->namespace, Text$from_str(decl_name)); + Text_t name = namespace_name(env, env->namespace, Textヽfrom_str(decl_name)); if (env->namespace && env->namespace->parent && env->namespace->name && streq(decl_name, env->namespace->name)) - name = namespace_name(env, env->namespace, Text$from_str(String(get_line_number(ast->file, ast->start)))); + name = namespace_name(env, env->namespace, Textヽfrom_str(String(get_line_number(ast->file, ast->start)))); return Texts(ret_type_code, " ", name, arg_signature, ";\n"); } case ConvertDef: { @@ -4709,17 +4708,17 @@ Text_t compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t Text_t arg_signature = Text("("); for (arg_ast_t *arg = def->args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); - arg_signature = Texts(arg_signature, compile_declaration(arg_type, Texts("_$", arg->name))); + arg_signature = Texts(arg_signature, compile_declaration(arg_type, USER_ID(arg->name))); if (arg->next) arg_signature = Texts(arg_signature, ", "); } arg_signature = Texts(arg_signature, ")"); type_t *ret_t = def->ret_type ? parse_type_ast(env, def->ret_type) : Type(VoidType); Text_t ret_type_code = compile_type(ret_t); - Text_t name = Text$from_str(get_type_name(ret_t)); + Text_t name = Textヽfrom_str(get_type_name(ret_t)); if (name.length == 0) code_err(ast, "Conversions are only supported for text, struct, and enum types, not ", type_to_str(ret_t)); - Text_t name_code = namespace_name(env, env->namespace, Texts(name, "$", String(get_line_number(ast->file, ast->start)))); + Text_t name_code = namespace_name(env, env->namespace, Texts(name, SEP, String(get_line_number(ast->file, ast->start)))); return Texts(ret_type_code, " ", name_code, arg_signature, ";\n"); } default: return EMPTY_TEXT; @@ -4743,8 +4742,8 @@ static void _make_typedefs(compile_typedef_info_t *info, ast_t *ast) if (ast->tag == StructDef) { DeclareMatch(def, ast, StructDef); if (def->external) return; - Text_t struct_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$struct")); - Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$type")); + Text_t struct_name = namespace_name(info->env, info->env->namespace, Texts(def->name, SEP, INTERNAL_ID("struct"))); + Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(def->name, SEP, INTERNAL_ID("type"))); *info->header = Texts(*info->header, "typedef struct ", struct_name, " ", type_name, ";\n"); } else if (ast->tag == EnumDef) { DeclareMatch(def, ast, EnumDef); @@ -4754,24 +4753,24 @@ static void _make_typedefs(compile_typedef_info_t *info, ast_t *ast) } if (has_any_tags_with_fields) { - Text_t struct_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$struct")); - Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$type")); + Text_t struct_name = namespace_name(info->env, info->env->namespace, Texts(def->name, SEP, INTERNAL_ID("struct"))); + Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(def->name, SEP, INTERNAL_ID("type"))); *info->header = Texts(*info->header, "typedef struct ", struct_name, " ", type_name, ";\n"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { if (!tag->fields) continue; - Text_t tag_struct = namespace_name(info->env, info->env->namespace, Texts(def->name, "$", tag->name, "$$struct")); - Text_t tag_type = namespace_name(info->env, info->env->namespace, Texts(def->name, "$", tag->name, "$$type")); + Text_t tag_struct = namespace_name(info->env, info->env->namespace, Texts(def->name, SEP, tag->name, SEP, INTERNAL_ID("struct"))); + Text_t tag_type = namespace_name(info->env, info->env->namespace, Texts(def->name, SEP, tag->name, SEP, INTERNAL_ID("type"))); *info->header = Texts(*info->header, "typedef struct ", tag_struct, " ", tag_type, ";\n"); } } else { - Text_t enum_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$enum")); - Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(def->name, "$$type")); + Text_t enum_name = namespace_name(info->env, info->env->namespace, Texts(def->name, SEP, INTERNAL_ID("enum"))); + Text_t type_name = namespace_name(info->env, info->env->namespace, Texts(def->name, SEP, INTERNAL_ID("type"))); *info->header = Texts(*info->header, "typedef enum ", enum_name, " ", type_name, ";\n"); } } else if (ast->tag == LangDef) { DeclareMatch(def, ast, LangDef); - *info->header = Texts(*info->header, "typedef Text_t ", namespace_name(info->env, info->env->namespace, Texts(def->name, "$$type")), ";\n"); + *info->header = Texts(*info->header, "typedef Text_t ", namespace_name(info->env, info->env->namespace, Texts(def->name, SEP, INTERNAL_ID("type"))), ";\n"); } } @@ -4793,7 +4792,7 @@ Text_t compile_file_header(env_t *env, Path_t header_path, ast_t *ast) visit_topologically(Match(ast, Block)->statements, (Closure_t){.fn=(void*)_make_typedefs, &info}); visit_topologically(Match(ast, Block)->statements, (Closure_t){.fn=(void*)_define_types_and_funcs, &info}); - header = Texts(header, "void ", namespace_name(env, env->namespace, Text("$initialize")), "(void);\n"); + header = Texts(header, "void ", namespace_name(env, env->namespace, Texts(INTERNAL_ID("initialize"))), "(void);\n"); return header; } diff --git a/src/enums.c b/src/enums.c index 113eb91d..698d2c3e 100644 --- a/src/enums.c +++ b/src/enums.c @@ -21,8 +21,8 @@ Text_t compile_enum_typeinfo(env_t *env, ast_t *ast) for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { if (!tag->fields) continue; - const char *tag_name = String(def->name, "$", tag->name); - type_t *tag_type = Table$str_get(*env->types, tag_name); + const char *tag_name = String(def->name, "ヽ", tag->name); + type_t *tag_type = Tableヽstr_get(*env->types, tag_name); assert(tag_type && tag_type->tag == StructType); member_typeinfos = Texts( member_typeinfos, compile_struct_typeinfo(env, tag_type, tag_name, tag->fields, tag->secret, false)); @@ -32,17 +32,17 @@ Text_t compile_enum_typeinfo(env_t *env, ast_t *ast) for (tag_ast_t *t = def->tags; t; t = t->next) num_tags += 1; - type_t *t = Table$str_get(*env->types, def->name); - const char *metamethods = is_packed_data(t) ? "PackedDataEnum$metamethods" : "Enum$metamethods"; - Text_t info = namespace_name(env, env->namespace, Texts(def->name, "$$info")); + type_t *t = Tableヽstr_get(*env->types, def->name); + const char *metamethods = is_packed_data(t) ? "PackedDataEnumヽmetamethods" : "Enumヽmetamethods"; + Text_t info = namespace_name(env, env->namespace, Texts(Textヽfrom_str(def->name), SEP, INTERNAL_ID("info"))); Text_t typeinfo = Texts("public const TypeInfo_t ", info, " = {", String((int64_t)type_size(t)), "u, ", String((int64_t)type_align(t)), "u, .metamethods=", metamethods, - ", {.tag=EnumInfo, .EnumInfo={.name=\"", def->name, "\", " + ", {.tag=EnumInfo, .EnumInfo={.name=\"", Textヽfrom_str(def->name), "\", " ".num_tags=", String((int64_t)num_tags), ", .tags=(NamedType_t[]){"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { - const char *tag_type_name = String(def->name, "$", tag->name); - type_t *tag_type = Table$str_get(*env->types, tag_type_name); + const char *tag_type_name = String(def->name, SEP, tag->name); + type_t *tag_type = Tableヽstr_get(*env->types, tag_type_name); if (tag_type && Match(tag_type, StructType)->fields) typeinfo = Texts(typeinfo, "{\"", tag->name, "\", ", compile_type_info(tag_type), "}, "); else @@ -62,17 +62,17 @@ Text_t compile_enum_constructors(env_t *env, ast_t *ast) Text_t arg_sig = EMPTY_TEXT; for (arg_ast_t *field = tag->fields; field; field = field->next) { type_t *field_t = get_arg_ast_type(env, field); - arg_sig = Texts(arg_sig, compile_declaration(field_t, Texts("$", field->name))); + arg_sig = Texts(arg_sig, compile_declaration(field_t, Texts(SEP, field->name))); if (field->next) arg_sig = Texts(arg_sig, ", "); } if (arg_sig.length == 0) arg_sig = Text("void"); - Text_t type_name = namespace_name(env, env->namespace, Texts(def->name, "$$type")); - Text_t tagged_name = namespace_name(env, env->namespace, Texts(def->name, "$tagged$", tag->name)); - Text_t tag_name = namespace_name(env, env->namespace, Texts(def->name, "$tag$", tag->name)); + Text_t type_name = namespace_name(env, env->namespace, Texts(Textヽfrom_str(def->name), SEP, INTERNAL_ID("type"))); + Text_t tagged_name = namespace_name(env, env->namespace, Texts(Textヽfrom_str(def->name), SEP, "tagged", SEP, tag->name)); + Text_t tag_name = namespace_name(env, env->namespace, Texts(Textヽfrom_str(def->name), SEP, INTERNAL_ID("tag"), SEP, tag->name)); Text_t constructor_impl = Texts("public inline ", type_name, " ", tagged_name, "(", arg_sig, ") { return (", - type_name, "){.$tag=", tag_name, ", .", valid_c_name(tag->name), "={"); + type_name, "){.", INTERNAL_ID("tag"), "=", tag_name, ", .", valid_c_name(tag->name), "={"); for (arg_ast_t *field = tag->fields; field; field = field->next) { - constructor_impl = Texts(constructor_impl, "$", field->name); + constructor_impl = Texts(constructor_impl, SEP, field->name); if (field->next) constructor_impl = Texts(constructor_impl, ", "); } constructor_impl = Texts(constructor_impl, "}}; }\n"); @@ -85,13 +85,14 @@ Text_t compile_enum_header(env_t *env, ast_t *ast) { DeclareMatch(def, ast, EnumDef); Text_t all_defs = EMPTY_TEXT; - Text_t none_name = namespace_name(env, env->namespace, Texts(def->name, "$none")); - Text_t enum_name = namespace_name(env, env->namespace, Texts(def->name, "$$enum")); + Text_t name = Textヽfrom_str(def->name); + Text_t none_name = namespace_name(env, env->namespace, Texts(name, SEP, "none")); + Text_t enum_name = namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("enum"))); Text_t enum_tags = Texts("{ ", none_name, "=0, "); bool has_any_tags_with_fields = false; for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { - Text_t tag_name = namespace_name(env, env->namespace, Texts(def->name, "$tag$", tag->name)); + Text_t tag_name = namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("tag"), SEP, tag->name)); enum_tags = Texts(enum_tags, tag_name); if (tag->next) enum_tags = Texts(enum_tags, ", "); has_any_tags_with_fields = has_any_tags_with_fields || (tag->fields != NULL); @@ -100,26 +101,26 @@ Text_t compile_enum_header(env_t *env, ast_t *ast) if (!has_any_tags_with_fields) { Text_t enum_def = Texts("enum ", enum_name, " ", enum_tags, ";\n"); - Text_t info = namespace_name(env, env->namespace, Texts(def->name, "$$info")); + Text_t info = namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("info"))); return Texts(enum_def, "extern const TypeInfo_t ", info, ";\n"); } - Text_t struct_name = namespace_name(env, env->namespace, Texts(def->name, "$$struct")); + Text_t struct_name = namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("struct"))); Text_t enum_def = Texts("struct ", struct_name, " {\n" - "enum ", enum_tags, " $tag;\n" + "enum ", enum_tags, " ", INTERNAL_ID("tag"), ";\n" "union {\n"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { if (!tag->fields) continue; Text_t field_def = compile_struct_header( - env, WrapAST(ast, StructDef, .name=Text$as_c_string(Texts(def->name, "$", tag->name)), .fields=tag->fields)); + env, WrapAST(ast, StructDef, .name=Textヽas_c_string(Texts(name, SEP, tag->name)), .fields=tag->fields)); all_defs = Texts(all_defs, field_def); - Text_t tag_type = namespace_name(env, env->namespace, Texts(def->name, "$", tag->name, "$$type")); + Text_t tag_type = namespace_name(env, env->namespace, Texts(name, SEP, tag->name, SEP, INTERNAL_ID("type"))); enum_def = Texts(enum_def, tag_type, " ", valid_c_name(tag->name), ";\n"); } enum_def = Texts(enum_def, "};\n};\n"); all_defs = Texts(all_defs, enum_def); - Text_t info = namespace_name(env, env->namespace, Texts(def->name, "$$info")); + Text_t info = namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("info"))); all_defs = Texts(all_defs, "extern const TypeInfo_t ", info, ";\n"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { if (!tag->fields) continue; @@ -127,12 +128,12 @@ Text_t compile_enum_header(env_t *env, ast_t *ast) Text_t arg_sig = EMPTY_TEXT; for (arg_ast_t *field = tag->fields; field; field = field->next) { type_t *field_t = get_arg_ast_type(env, field); - arg_sig = Texts(arg_sig, compile_declaration(field_t, Texts("$", field->name))); + arg_sig = Texts(arg_sig, compile_declaration(field_t, USER_ID(field->name))); if (field->next) arg_sig = Texts(arg_sig, ", "); } if (arg_sig.length == 0) arg_sig = Text("void"); - Text_t enum_type = namespace_name(env, env->namespace, Texts(def->name, "$$type")); - Text_t tagged_name = namespace_name(env, env->namespace, Texts(def->name, "$tagged$", tag->name)); + Text_t enum_type = namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("type"))); + Text_t tagged_name = namespace_name(env, env->namespace, Texts(name, SEP, "tagged", SEP, tag->name)); Text_t constructor_def = Texts(enum_type, " ", tagged_name, "(", arg_sig, ");\n"); all_defs = Texts(all_defs, constructor_def); } diff --git a/src/environment.c b/src/environment.c index f43e8daf..54fcdf33 100644 --- a/src/environment.c +++ b/src/environment.c @@ -30,13 +30,13 @@ static type_t *declare_type(env_t *env, const char *def_str) DeclareMatch(def, statements->ast, StructDef); prebind_statement(env, statements->ast); bind_statement(env, statements->ast); - return Table$str_get(*env->types, def->name); + return Tableヽstr_get(*env->types, def->name); } case EnumDef: { DeclareMatch(def, statements->ast, EnumDef); prebind_statement(env, statements->ast); bind_statement(env, statements->ast); - return Table$str_get(*env->types, def->name); + return Tableヽstr_get(*env->types, def->name); } default: errx(1, "Not a type definition: %s", def_str); } @@ -45,9 +45,9 @@ static type_t *declare_type(env_t *env, const char *def_str) static type_t *bind_type(env_t *env, const char *name, type_t *type) { - if (Table$str_get(*env->types, name)) + if (Tableヽstr_get(*env->types, name)) errx(1, "Duplicate binding for type: %s", name); - Table$str_set(env->types, name, type); + Tableヽstr_set(env->types, name, type); return type; } @@ -82,165 +82,165 @@ env_t *global_env(bool source_mapping) Text_t typeinfo; List_t namespace; } global_types[] = { - {"Void", Type(VoidType), Text("Void_t"), Text("Void$info"), {}}, - {"Abort", Type(AbortType), Text("void"), Text("Abort$info"), {}}, - {"Memory", Type(MemoryType), Text("Memory_t"), Text("Memory$info"), {}}, - {"Bool", Type(BoolType), Text("Bool_t"), Text("Bool$info"), TypedList(ns_entry_t, - {"parse", "Bool$parse", "func(text:Text, remainder:&Text? = none -> Bool?)"}, + {"Void", Type(VoidType), Text("Void_t"), Text("Voidヽinfo"), {}}, + {"Abort", Type(AbortType), Text("void"), Text("Abortヽinfo"), {}}, + {"Memory", Type(MemoryType), Text("Memory_t"), Text("Memoryヽinfo"), {}}, + {"Bool", Type(BoolType), Text("Bool_t"), Text("Boolヽinfo"), TypedList(ns_entry_t, + {"parse", "Boolヽparse", "func(text:Text, remainder:&Text? = none -> Bool?)"}, )}, - {"Byte", Type(ByteType), Text("Byte_t"), Text("Byte$info"), TypedList(ns_entry_t, - {"get_bit", "Byte$get_bit", "func(x:Byte, bit_index:Int -> Bool)"}, - {"hex", "Byte$hex", "func(byte:Byte, uppercase=yes, prefix=no -> Text)"}, - {"is_between", "Byte$is_between", "func(x:Byte, low:Byte, high:Byte -> Bool)"}, - {"max", "Byte$max", "Byte"}, - {"min", "Byte$min", "Byte"}, - {"parse", "Byte$parse", "func(text:Text, remainder:&Text? = none -> Byte?)"}, - {"to", "Byte$to", "func(first:Byte, last:Byte, step:Int8?=none -> func(->Byte?))"}, + {"Byte", Type(ByteType), Text("Byte_t"), Text("Byteヽinfo"), TypedList(ns_entry_t, + {"get_bit", "Byteヽget_bit", "func(x:Byte, bit_index:Int -> Bool)"}, + {"hex", "Byteヽhex", "func(byte:Byte, uppercase=yes, prefix=no -> Text)"}, + {"is_between", "Byteヽis_between", "func(x:Byte, low:Byte, high:Byte -> Bool)"}, + {"max", "Byteヽmax", "Byte"}, + {"min", "Byteヽmin", "Byte"}, + {"parse", "Byteヽparse", "func(text:Text, remainder:&Text? = none -> Byte?)"}, + {"to", "Byteヽto", "func(first:Byte, last:Byte, step:Int8?=none -> func(->Byte?))"}, )}, - {"Int", Type(BigIntType), Text("Int_t"), Text("Int$info"), TypedList(ns_entry_t, - {"abs", "Int$abs", "func(x:Int -> Int)"}, - {"bit_and", "Int$bit_and", "func(x,y:Int -> Int)"}, - {"bit_or", "Int$bit_or", "func(x,y:Int -> Int)"}, - {"bit_xor", "Int$bit_xor", "func(x,y:Int -> Int)"}, - {"choose", "Int$choose", "func(x,y:Int -> Int)"}, - {"clamped", "Int$clamped", "func(x,low,high:Int -> Int)"}, - {"divided_by", "Int$divided_by", "func(x,y:Int -> Int)"}, - {"factorial", "Int$factorial", "func(x:Int -> Int)"}, - {"gcd", "Int$gcd", "func(x,y:Int -> Int)"}, - {"get_bit", "Int$get_bit", "func(x,bit_index:Int -> Bool)"}, - {"hex", "Int$hex", "func(i:Int, digits=0, uppercase=yes, prefix=yes -> Text)"}, - {"is_between", "Int$is_between", "func(x:Int,low:Int,high:Int -> Bool)"}, - {"is_prime", "Int$is_prime", "func(x:Int,reps=50 -> Bool)"}, - {"left_shifted", "Int$left_shifted", "func(x,y:Int -> Int)"}, - {"minus", "Int$minus", "func(x,y:Int -> Int)"}, - {"modulo", "Int$modulo", "func(x,y:Int -> Int)"}, - {"modulo1", "Int$modulo1", "func(x,y:Int -> Int)"}, - {"negated", "Int$negated", "func(x:Int -> Int)"}, - {"negative", "Int$negative", "func(x:Int -> Int)"}, - {"next_prime", "Int$next_prime", "func(x:Int -> Int)"}, - {"octal", "Int$octal", "func(i:Int, digits=0, prefix=yes -> Text)"}, - {"onward", "Int$onward", "func(first:Int,step=1 -> func(->Int?))"}, - {"parse", "Int$parse", "func(text:Text, remainder:&Text? = none -> Int?)"}, - {"plus", "Int$plus", "func(x,y:Int -> Int)"}, - {"power", "Int$power", "func(base:Int,exponent:Int -> Int)"}, + {"Int", Type(BigIntType), Text("Int_t"), Text("Intヽinfo"), TypedList(ns_entry_t, + {"abs", "Intヽabs", "func(x:Int -> Int)"}, + {"bit_and", "Intヽbit_and", "func(x,y:Int -> Int)"}, + {"bit_or", "Intヽbit_or", "func(x,y:Int -> Int)"}, + {"bit_xor", "Intヽbit_xor", "func(x,y:Int -> Int)"}, + {"choose", "Intヽchoose", "func(x,y:Int -> Int)"}, + {"clamped", "Intヽclamped", "func(x,low,high:Int -> Int)"}, + {"divided_by", "Intヽdivided_by", "func(x,y:Int -> Int)"}, + {"factorial", "Intヽfactorial", "func(x:Int -> Int)"}, + {"gcd", "Intヽgcd", "func(x,y:Int -> Int)"}, + {"get_bit", "Intヽget_bit", "func(x,bit_index:Int -> Bool)"}, + {"hex", "Intヽhex", "func(i:Int, digits=0, uppercase=yes, prefix=yes -> Text)"}, + {"is_between", "Intヽis_between", "func(x:Int,low:Int,high:Int -> Bool)"}, + {"is_prime", "Intヽis_prime", "func(x:Int,reps=50 -> Bool)"}, + {"left_shifted", "Intヽleft_shifted", "func(x,y:Int -> Int)"}, + {"minus", "Intヽminus", "func(x,y:Int -> Int)"}, + {"modulo", "Intヽmodulo", "func(x,y:Int -> Int)"}, + {"modulo1", "Intヽmodulo1", "func(x,y:Int -> Int)"}, + {"negated", "Intヽnegated", "func(x:Int -> Int)"}, + {"negative", "Intヽnegative", "func(x:Int -> Int)"}, + {"next_prime", "Intヽnext_prime", "func(x:Int -> Int)"}, + {"octal", "Intヽoctal", "func(i:Int, digits=0, prefix=yes -> Text)"}, + {"onward", "Intヽonward", "func(first:Int,step=1 -> func(->Int?))"}, + {"parse", "Intヽparse", "func(text:Text, remainder:&Text? = none -> Int?)"}, + {"plus", "Intヽplus", "func(x,y:Int -> Int)"}, + {"power", "Intヽpower", "func(base:Int,exponent:Int -> Int)"}, #if __GNU_MP_VERSION >= 6 #if __GNU_MP_VERSION_MINOR >= 3 - {"prev_prime", "Int$prev_prime", "func(x:Int -> Int?)"}, + {"prev_prime", "Intヽprev_prime", "func(x:Int -> Int?)"}, #endif #endif - {"right_shifted", "Int$right_shifted", "func(x,y:Int -> Int)"}, - {"sqrt", "Int$sqrt", "func(x:Int -> Int?)"}, - {"times", "Int$times", "func(x,y:Int -> Int)"}, - {"to", "Int$to", "func(first:Int,last:Int,step:Int?=none -> func(->Int?))"}, + {"right_shifted", "Intヽright_shifted", "func(x,y:Int -> Int)"}, + {"sqrt", "Intヽsqrt", "func(x:Int -> Int?)"}, + {"times", "Intヽtimes", "func(x,y:Int -> Int)"}, + {"to", "Intヽto", "func(first:Int,last:Int,step:Int?=none -> func(->Int?))"}, )}, - {"Int64", Type(IntType, .bits=TYPE_IBITS64), Text("Int64_t"), Text("Int64$info"), TypedList(ns_entry_t, + {"Int64", Type(IntType, .bits=TYPE_IBITS64), Text("Int64_t"), Text("Int64ヽinfo"), TypedList(ns_entry_t, {"abs", "labs", "func(i:Int64 -> Int64)"}, - {"bits", "Int64$bits", "func(x:Int64 -> [Bool])"}, - {"clamped", "Int64$clamped", "func(x,low,high:Int64 -> Int64)"}, - {"divided_by", "Int64$divided_by", "func(x,y:Int64 -> Int64)"}, - {"gcd", "Int64$gcd", "func(x,y:Int64 -> Int64)"}, - {"parse", "Int64$parse", "func(text:Text, remainder:&Text? = none -> Int64?)"}, - {"get_bit", "Int64$get_bit", "func(x:Int64, bit_index:Int -> Bool)"}, - {"hex", "Int64$hex", "func(i:Int64, digits=0, uppercase=yes, prefix=yes -> Text)"}, - {"is_between", "Int64$is_between", "func(x:Int64,low:Int64,high:Int64 -> Bool)"}, - {"max", "Int64$max", "Int64"}, - {"min", "Int64$min", "Int64"}, - {"modulo", "Int64$modulo", "func(x,y:Int64 -> Int64)"}, - {"modulo1", "Int64$modulo1", "func(x,y:Int64 -> Int64)"}, - {"octal", "Int64$octal", "func(i:Int64, digits=0, prefix=yes -> Text)"}, - {"onward", "Int64$onward", "func(first:Int64,step=Int64(1) -> func(->Int64?))"}, - {"to", "Int64$to", "func(first:Int64,last:Int64,step:Int64?=none -> func(->Int64?))"}, - {"unsigned_left_shifted", "Int64$unsigned_left_shifted", "func(x:Int64,y:Int64 -> Int64)"}, - {"unsigned_right_shifted", "Int64$unsigned_right_shifted", "func(x:Int64,y:Int64 -> Int64)"}, - {"wrapping_minus", "Int64$wrapping_minus", "func(x:Int64,y:Int64 -> Int64)"}, - {"wrapping_plus", "Int64$wrapping_plus", "func(x:Int64,y:Int64 -> Int64)"}, + {"bits", "Int64ヽbits", "func(x:Int64 -> [Bool])"}, + {"clamped", "Int64ヽclamped", "func(x,low,high:Int64 -> Int64)"}, + {"divided_by", "Int64ヽdivided_by", "func(x,y:Int64 -> Int64)"}, + {"gcd", "Int64ヽgcd", "func(x,y:Int64 -> Int64)"}, + {"parse", "Int64ヽparse", "func(text:Text, remainder:&Text? = none -> Int64?)"}, + {"get_bit", "Int64ヽget_bit", "func(x:Int64, bit_index:Int -> Bool)"}, + {"hex", "Int64ヽhex", "func(i:Int64, digits=0, uppercase=yes, prefix=yes -> Text)"}, + {"is_between", "Int64ヽis_between", "func(x:Int64,low:Int64,high:Int64 -> Bool)"}, + {"max", "Int64ヽmax", "Int64"}, + {"min", "Int64ヽmin", "Int64"}, + {"modulo", "Int64ヽmodulo", "func(x,y:Int64 -> Int64)"}, + {"modulo1", "Int64ヽmodulo1", "func(x,y:Int64 -> Int64)"}, + {"octal", "Int64ヽoctal", "func(i:Int64, digits=0, prefix=yes -> Text)"}, + {"onward", "Int64ヽonward", "func(first:Int64,step=Int64(1) -> func(->Int64?))"}, + {"to", "Int64ヽto", "func(first:Int64,last:Int64,step:Int64?=none -> func(->Int64?))"}, + {"unsigned_left_shifted", "Int64ヽunsigned_left_shifted", "func(x:Int64,y:Int64 -> Int64)"}, + {"unsigned_right_shifted", "Int64ヽunsigned_right_shifted", "func(x:Int64,y:Int64 -> Int64)"}, + {"wrapping_minus", "Int64ヽwrapping_minus", "func(x:Int64,y:Int64 -> Int64)"}, + {"wrapping_plus", "Int64ヽwrapping_plus", "func(x:Int64,y:Int64 -> Int64)"}, )}, - {"Int32", Type(IntType, .bits=TYPE_IBITS32), Text("Int32_t"), Text("Int32$info"), TypedList(ns_entry_t, + {"Int32", Type(IntType, .bits=TYPE_IBITS32), Text("Int32_t"), Text("Int32ヽinfo"), TypedList(ns_entry_t, {"abs", "abs", "func(i:Int32 -> Int32)"}, - {"bits", "Int32$bits", "func(x:Int32 -> [Bool])"}, - {"clamped", "Int32$clamped", "func(x,low,high:Int32 -> Int32)"}, - {"divided_by", "Int32$divided_by", "func(x,y:Int32 -> Int32)"}, - {"gcd", "Int32$gcd", "func(x,y:Int32 -> Int32)"}, - {"parse", "Int32$parse", "func(text:Text, remainder:&Text? = none -> Int32?)"}, - {"get_bit", "Int32$get_bit", "func(x:Int32, bit_index:Int -> Bool)"}, - {"hex", "Int32$hex", "func(i:Int32, digits=0, uppercase=yes, prefix=yes -> Text)"}, - {"is_between", "Int32$is_between", "func(x:Int32,low:Int32,high:Int32 -> Bool)"}, - {"max", "Int32$max", "Int32"}, - {"min", "Int32$min", "Int32"}, - {"modulo", "Int32$modulo", "func(x,y:Int32 -> Int32)"}, - {"modulo1", "Int32$modulo1", "func(x,y:Int32 -> Int32)"}, - {"octal", "Int32$octal", "func(i:Int32, digits=0, prefix=yes -> Text)"}, - {"onward", "Int32$onward", "func(first:Int32,step=Int32(1) -> func(->Int32?))"}, - {"to", "Int32$to", "func(first:Int32,last:Int32,step:Int32?=none -> func(->Int32?))"}, - {"unsigned_left_shifted", "Int32$unsigned_left_shifted", "func(x:Int32,y:Int32 -> Int32)"}, - {"unsigned_right_shifted", "Int32$unsigned_right_shifted", "func(x:Int32,y:Int32 -> Int32)"}, - {"wrapping_minus", "Int32$wrapping_minus", "func(x:Int32,y:Int32 -> Int32)"}, - {"wrapping_plus", "Int32$wrapping_plus", "func(x:Int32,y:Int32 -> Int32)"}, + {"bits", "Int32ヽbits", "func(x:Int32 -> [Bool])"}, + {"clamped", "Int32ヽclamped", "func(x,low,high:Int32 -> Int32)"}, + {"divided_by", "Int32ヽdivided_by", "func(x,y:Int32 -> Int32)"}, + {"gcd", "Int32ヽgcd", "func(x,y:Int32 -> Int32)"}, + {"parse", "Int32ヽparse", "func(text:Text, remainder:&Text? = none -> Int32?)"}, + {"get_bit", "Int32ヽget_bit", "func(x:Int32, bit_index:Int -> Bool)"}, + {"hex", "Int32ヽhex", "func(i:Int32, digits=0, uppercase=yes, prefix=yes -> Text)"}, + {"is_between", "Int32ヽis_between", "func(x:Int32,low:Int32,high:Int32 -> Bool)"}, + {"max", "Int32ヽmax", "Int32"}, + {"min", "Int32ヽmin", "Int32"}, + {"modulo", "Int32ヽmodulo", "func(x,y:Int32 -> Int32)"}, + {"modulo1", "Int32ヽmodulo1", "func(x,y:Int32 -> Int32)"}, + {"octal", "Int32ヽoctal", "func(i:Int32, digits=0, prefix=yes -> Text)"}, + {"onward", "Int32ヽonward", "func(first:Int32,step=Int32(1) -> func(->Int32?))"}, + {"to", "Int32ヽto", "func(first:Int32,last:Int32,step:Int32?=none -> func(->Int32?))"}, + {"unsigned_left_shifted", "Int32ヽunsigned_left_shifted", "func(x:Int32,y:Int32 -> Int32)"}, + {"unsigned_right_shifted", "Int32ヽunsigned_right_shifted", "func(x:Int32,y:Int32 -> Int32)"}, + {"wrapping_minus", "Int32ヽwrapping_minus", "func(x:Int32,y:Int32 -> Int32)"}, + {"wrapping_plus", "Int32ヽwrapping_plus", "func(x:Int32,y:Int32 -> Int32)"}, )}, - {"Int16", Type(IntType, .bits=TYPE_IBITS16), Text("Int16_t"), Text("Int16$info"), TypedList(ns_entry_t, + {"Int16", Type(IntType, .bits=TYPE_IBITS16), Text("Int16_t"), Text("Int16ヽinfo"), TypedList(ns_entry_t, {"abs", "abs", "func(i:Int16 -> Int16)"}, - {"bits", "Int16$bits", "func(x:Int16 -> [Bool])"}, - {"clamped", "Int16$clamped", "func(x,low,high:Int16 -> Int16)"}, - {"divided_by", "Int16$divided_by", "func(x,y:Int16 -> Int16)"}, - {"gcd", "Int16$gcd", "func(x,y:Int16 -> Int16)"}, - {"parse", "Int16$parse", "func(text:Text, remainder:&Text? = none -> Int16?)"}, - {"get_bit", "Int16$get_bit", "func(x:Int16, bit_index:Int -> Bool)"}, - {"hex", "Int16$hex", "func(i:Int16, digits=0, uppercase=yes, prefix=yes -> Text)"}, - {"is_between", "Int16$is_between", "func(x:Int16,low:Int16,high:Int16 -> Bool)"}, - {"max", "Int16$max", "Int16"}, - {"min", "Int16$min", "Int16"}, - {"modulo", "Int16$modulo", "func(x,y:Int16 -> Int16)"}, - {"modulo1", "Int16$modulo1", "func(x,y:Int16 -> Int16)"}, - {"octal", "Int16$octal", "func(i:Int16, digits=0, prefix=yes -> Text)"}, - {"onward", "Int16$onward", "func(first:Int16,step=Int16(1) -> func(->Int16?))"}, - {"to", "Int16$to", "func(first:Int16,last:Int16,step:Int16?=none -> func(->Int16?))"}, - {"unsigned_left_shifted", "Int16$unsigned_left_shifted", "func(x:Int16,y:Int16 -> Int16)"}, - {"unsigned_right_shifted", "Int16$unsigned_right_shifted", "func(x:Int16,y:Int16 -> Int16)"}, - {"wrapping_minus", "Int16$wrapping_minus", "func(x:Int16,y:Int16 -> Int16)"}, - {"wrapping_plus", "Int16$wrapping_plus", "func(x:Int16,y:Int16 -> Int16)"}, + {"bits", "Int16ヽbits", "func(x:Int16 -> [Bool])"}, + {"clamped", "Int16ヽclamped", "func(x,low,high:Int16 -> Int16)"}, + {"divided_by", "Int16ヽdivided_by", "func(x,y:Int16 -> Int16)"}, + {"gcd", "Int16ヽgcd", "func(x,y:Int16 -> Int16)"}, + {"parse", "Int16ヽparse", "func(text:Text, remainder:&Text? = none -> Int16?)"}, + {"get_bit", "Int16ヽget_bit", "func(x:Int16, bit_index:Int -> Bool)"}, + {"hex", "Int16ヽhex", "func(i:Int16, digits=0, uppercase=yes, prefix=yes -> Text)"}, + {"is_between", "Int16ヽis_between", "func(x:Int16,low:Int16,high:Int16 -> Bool)"}, + {"max", "Int16ヽmax", "Int16"}, + {"min", "Int16ヽmin", "Int16"}, + {"modulo", "Int16ヽmodulo", "func(x,y:Int16 -> Int16)"}, + {"modulo1", "Int16ヽmodulo1", "func(x,y:Int16 -> Int16)"}, + {"octal", "Int16ヽoctal", "func(i:Int16, digits=0, prefix=yes -> Text)"}, + {"onward", "Int16ヽonward", "func(first:Int16,step=Int16(1) -> func(->Int16?))"}, + {"to", "Int16ヽto", "func(first:Int16,last:Int16,step:Int16?=none -> func(->Int16?))"}, + {"unsigned_left_shifted", "Int16ヽunsigned_left_shifted", "func(x:Int16,y:Int16 -> Int16)"}, + {"unsigned_right_shifted", "Int16ヽunsigned_right_shifted", "func(x:Int16,y:Int16 -> Int16)"}, + {"wrapping_minus", "Int16ヽwrapping_minus", "func(x:Int16,y:Int16 -> Int16)"}, + {"wrapping_plus", "Int16ヽwrapping_plus", "func(x:Int16,y:Int16 -> Int16)"}, )}, - {"Int8", Type(IntType, .bits=TYPE_IBITS8), Text("Int8_t"), Text("Int8$info"), TypedList(ns_entry_t, + {"Int8", Type(IntType, .bits=TYPE_IBITS8), Text("Int8_t"), Text("Int8ヽinfo"), TypedList(ns_entry_t, {"abs", "abs", "func(i:Int8 -> Int8)"}, - {"bits", "Int8$bits", "func(x:Int8 -> [Bool])"}, - {"clamped", "Int8$clamped", "func(x,low,high:Int8 -> Int8)"}, - {"divided_by", "Int8$divided_by", "func(x,y:Int8 -> Int8)"}, - {"gcd", "Int8$gcd", "func(x,y:Int8 -> Int8)"}, - {"parse", "Int8$parse", "func(text:Text, remainder:&Text? = none -> Int8?)"}, - {"get_bit", "Int8$get_bit", "func(x:Int8, bit_index:Int -> Bool)"}, - {"hex", "Int8$hex", "func(i:Int8, digits=0, uppercase=yes, prefix=yes -> Text)"}, - {"is_between", "Int8$is_between", "func(x:Int8,low:Int8,high:Int8 -> Bool)"}, - {"max", "Int8$max", "Int8"}, - {"min", "Int8$min", "Int8"}, - {"modulo", "Int8$modulo", "func(x,y:Int8 -> Int8)"}, - {"modulo1", "Int8$modulo1", "func(x,y:Int8 -> Int8)"}, - {"octal", "Int8$octal", "func(i:Int8, digits=0, prefix=yes -> Text)"}, - {"onward", "Int8$onward", "func(first:Int8,step=Int8(1) -> func(->Int8?))"}, - {"to", "Int8$to", "func(first:Int8,last:Int8,step:Int8?=none -> func(->Int8?))"}, - {"unsigned_left_shifted", "Int8$unsigned_left_shifted", "func(x:Int8,y:Int8 -> Int8)"}, - {"unsigned_right_shifted", "Int8$unsigned_right_shifted", "func(x:Int8,y:Int8 -> Int8)"}, - {"wrapping_minus", "Int8$wrapping_minus", "func(x:Int8,y:Int8 -> Int8)"}, - {"wrapping_plus", "Int8$wrapping_plus", "func(x:Int8,y:Int8 -> Int8)"}, + {"bits", "Int8ヽbits", "func(x:Int8 -> [Bool])"}, + {"clamped", "Int8ヽclamped", "func(x,low,high:Int8 -> Int8)"}, + {"divided_by", "Int8ヽdivided_by", "func(x,y:Int8 -> Int8)"}, + {"gcd", "Int8ヽgcd", "func(x,y:Int8 -> Int8)"}, + {"parse", "Int8ヽparse", "func(text:Text, remainder:&Text? = none -> Int8?)"}, + {"get_bit", "Int8ヽget_bit", "func(x:Int8, bit_index:Int -> Bool)"}, + {"hex", "Int8ヽhex", "func(i:Int8, digits=0, uppercase=yes, prefix=yes -> Text)"}, + {"is_between", "Int8ヽis_between", "func(x:Int8,low:Int8,high:Int8 -> Bool)"}, + {"max", "Int8ヽmax", "Int8"}, + {"min", "Int8ヽmin", "Int8"}, + {"modulo", "Int8ヽmodulo", "func(x,y:Int8 -> Int8)"}, + {"modulo1", "Int8ヽmodulo1", "func(x,y:Int8 -> Int8)"}, + {"octal", "Int8ヽoctal", "func(i:Int8, digits=0, prefix=yes -> Text)"}, + {"onward", "Int8ヽonward", "func(first:Int8,step=Int8(1) -> func(->Int8?))"}, + {"to", "Int8ヽto", "func(first:Int8,last:Int8,step:Int8?=none -> func(->Int8?))"}, + {"unsigned_left_shifted", "Int8ヽunsigned_left_shifted", "func(x:Int8,y:Int8 -> Int8)"}, + {"unsigned_right_shifted", "Int8ヽunsigned_right_shifted", "func(x:Int8,y:Int8 -> Int8)"}, + {"wrapping_minus", "Int8ヽwrapping_minus", "func(x:Int8,y:Int8 -> Int8)"}, + {"wrapping_plus", "Int8ヽwrapping_plus", "func(x:Int8,y:Int8 -> Int8)"}, )}, #define C(name) {#name, "M_"#name, "Num"} #define F(name) {#name, #name, "func(n:Num -> Num)"} #define F_opt(name) {#name, #name, "func(n:Num -> Num?)"} #define F2(name) {#name, #name, "func(x,y:Num -> Num)"} - {"Num", Type(NumType, .bits=TYPE_NBITS64), Text("Num_t"), Text("Num$info"), TypedList(ns_entry_t, - {"near", "Num$near", "func(x,y:Num, ratio=1e-9, min_epsilon=1e-9 -> Bool)"}, - {"clamped", "Num$clamped", "func(x,low,high:Num -> Num)"}, - {"percent", "Num$percent", "func(n:Num,precision=0.01 -> Text)"}, - {"with_precision", "Num$with_precision", "func(n:Num,precision:Num -> Num)"}, - {"is_between", "Num$is_between", "func(x:Num,low:Num,high:Num -> Bool)"}, - {"isinf", "Num$isinf", "func(n:Num -> Bool)"}, - {"isfinite", "Num$isfinite", "func(n:Num -> Bool)"}, - {"modulo", "Num$mod", "func(x,y:Num -> Num)"}, - {"modulo1", "Num$mod1", "func(x,y:Num -> Num)"}, + {"Num", Type(NumType, .bits=TYPE_NBITS64), Text("Num_t"), Text("Numヽinfo"), TypedList(ns_entry_t, + {"near", "Numヽnear", "func(x,y:Num, ratio=1e-9, min_epsilon=1e-9 -> Bool)"}, + {"clamped", "Numヽclamped", "func(x,low,high:Num -> Num)"}, + {"percent", "Numヽpercent", "func(n:Num,precision=0.01 -> Text)"}, + {"with_precision", "Numヽwith_precision", "func(n:Num,precision:Num -> Num)"}, + {"is_between", "Numヽis_between", "func(x:Num,low:Num,high:Num -> Bool)"}, + {"isinf", "Numヽisinf", "func(n:Num -> Bool)"}, + {"isfinite", "Numヽisfinite", "func(n:Num -> Bool)"}, + {"modulo", "Numヽmod", "func(x,y:Num -> Num)"}, + {"modulo1", "Numヽmod1", "func(x,y:Num -> Num)"}, C(2_SQRTPI), C(E), C(PI_2), C(2_PI), C(1_PI), C(LN10), C(LN2), C(LOG2E), C(PI), C(PI_4), C(SQRT2), C(SQRT1_2), {"INF", "(Num_t)(INFINITY)", "Num"}, {"TAU", "(Num_t)(2.*M_PI)", "Num"}, - {"mix", "Num$mix", "func(amount,x,y:Num -> Num)"}, - {"parse", "Num$parse", "func(text:Text, remainder:&Text? = none -> Num?)"}, + {"mix", "Numヽmix", "func(amount,x,y:Num -> Num)"}, + {"parse", "Numヽparse", "func(text:Text, remainder:&Text? = none -> Num?)"}, {"abs", "fabs", "func(n:Num -> Num)"}, F_opt(acos), F_opt(acosh), F_opt(asin), F(asinh), F(atan), F_opt(atanh), F(cbrt), F(ceil), F_opt(cos), F(cosh), F(erf), F(erfc), @@ -257,23 +257,23 @@ env_t *global_env(bool source_mapping) #define F(name) {#name, #name"f", "func(n:Num32 -> Num32)"} #define F_opt(name) {#name, #name"f", "func(n:Num32 -> Num32?)"} #define F2(name) {#name, #name"f", "func(x,y:Num32 -> Num32)"} - {"Num32", Type(NumType, .bits=TYPE_NBITS32), Text("Num32_t"), Text("Num32$info"), TypedList(ns_entry_t, - {"near", "Num32$near", "func(x,y:Num32, ratio=Num32(1e-9), min_epsilon=Num32(1e-9) -> Bool)"}, - {"clamped", "Num32$clamped", "func(x,low,high:Num32 -> Num32)"}, - {"percent", "Num32$percent", "func(n:Num32,precision=Num32(.01) -> Text)"}, - {"with_precision", "Num32$with_precision", "func(n:Num32,precision:Num32 -> Num32)"}, - {"is_between", "Num32$is_between", "func(x:Num32,low:Num32,high:Num32 -> Bool)"}, - {"isinf", "Num32$isinf", "func(n:Num32 -> Bool)"}, - {"isfinite", "Num32$isfinite", "func(n:Num32 -> Bool)"}, + {"Num32", Type(NumType, .bits=TYPE_NBITS32), Text("Num32_t"), Text("Num32ヽinfo"), TypedList(ns_entry_t, + {"near", "Num32ヽnear", "func(x,y:Num32, ratio=Num32(1e-9), min_epsilon=Num32(1e-9) -> Bool)"}, + {"clamped", "Num32ヽclamped", "func(x,low,high:Num32 -> Num32)"}, + {"percent", "Num32ヽpercent", "func(n:Num32,precision=Num32(.01) -> Text)"}, + {"with_precision", "Num32ヽwith_precision", "func(n:Num32,precision:Num32 -> Num32)"}, + {"is_between", "Num32ヽis_between", "func(x:Num32,low:Num32,high:Num32 -> Bool)"}, + {"isinf", "Num32ヽisinf", "func(n:Num32 -> Bool)"}, + {"isfinite", "Num32ヽisfinite", "func(n:Num32 -> Bool)"}, C(2_SQRTPI), C(E), C(PI_2), C(2_PI), C(1_PI), C(LN10), C(LN2), C(LOG2E), C(PI), C(PI_4), C(SQRT2), C(SQRT1_2), {"INF", "(Num32_t)(INFINITY)", "Num32"}, {"TAU", "(Num32_t)(2.f*M_PI)", "Num32"}, - {"mix", "Num32$mix", "func(amount,x,y:Num32 -> Num32)"}, - {"parse", "Num32$parse", "func(text:Text, remainder:&Text? = none -> Num32?)"}, + {"mix", "Num32ヽmix", "func(amount,x,y:Num32 -> Num32)"}, + {"parse", "Num32ヽparse", "func(text:Text, remainder:&Text? = none -> Num32?)"}, {"abs", "fabsf", "func(n:Num32 -> Num32)"}, - {"modulo", "Num32$mod", "func(x,y:Num32 -> Num32)"}, - {"modulo1", "Num32$mod1", "func(x,y:Num32 -> Num32)"}, + {"modulo", "Num32ヽmod", "func(x,y:Num32 -> Num32)"}, + {"modulo1", "Num32ヽmod1", "func(x,y:Num32 -> Num32)"}, F_opt(acos), F_opt(acosh), F_opt(asin), F(asinh), F(atan), F_opt(atanh), F(cbrt), F(ceil), F_opt(cos), F(cosh), F(erf), F(erfc), F(exp), F(exp2), F(expm1), F(floor), F(j0), F(j1), F_opt(log), F_opt(log10), F_opt(log1p), @@ -281,105 +281,105 @@ env_t *global_env(bool source_mapping) F_opt(tan), F(tanh), F_opt(tgamma), F(trunc), F_opt(y0), F_opt(y1), F2(atan2), F2(copysign), F2(fdim), F2(hypot), F2(nextafter), )}, - {"CString", Type(CStringType), Text("char*"), Text("CString$info"), TypedList(ns_entry_t, - {"as_text", "Text$from_str", "func(str:CString -> Text)"}, + {"CString", Type(CStringType), Text("char*"), Text("CStringヽinfo"), TypedList(ns_entry_t, + {"as_text", "Textヽfrom_str", "func(str:CString -> Text)"}, )}, #undef F2 #undef F_opt #undef F #undef C - {"PathType", PATH_TYPE_TYPE, Text("PathType_t"), Text("PathType$info"), TypedList(ns_entry_t, - {"Relative", "((PathType_t){.$tag=PATH_RELATIVE})", "PathType"}, - {"Absolute", "((PathType_t){.$tag=PATH_ABSOLUTE})", "PathType"}, - {"Home", "((PathType_t){.$tag=PATH_HOME})", "PathType"}, + {"PathType", PATH_TYPE_TYPE, Text("PathType_t"), Text("PathTypeヽinfo"), TypedList(ns_entry_t, + {"Relative", "((PathType_t){.ヽtag=PATH_RELATIVE})", "PathType"}, + {"Absolute", "((PathType_t){.ヽtag=PATH_ABSOLUTE})", "PathType"}, + {"Home", "((PathType_t){.ヽtag=PATH_HOME})", "PathType"}, )}, - {"Path", PATH_TYPE, Text("Path_t"), Text("Path$info"), TypedList(ns_entry_t, - {"accessed", "Path$accessed", "func(path:Path, follow_symlinks=yes -> Int64?)"}, - {"append", "Path$append", "func(path:Path, text:Text, permissions=Int32(0o644))"}, - {"append_bytes", "Path$append_bytes", "func(path:Path, bytes:[Byte], permissions=Int32(0o644))"}, - {"base_name", "Path$base_name", "func(path:Path -> Text)"}, - {"by_line", "Path$by_line", "func(path:Path -> func(->Text?)?)"}, - {"can_execute", "Path$can_execute", "func(path:Path -> Bool)"}, - {"can_read", "Path$can_read", "func(path:Path -> Bool)"}, - {"can_write", "Path$can_write", "func(path:Path -> Bool)"}, - {"changed", "Path$changed", "func(path:Path, follow_symlinks=yes -> Int64?)"}, - {"child", "Path$child", "func(path:Path, child:Text -> Path)"}, - {"children", "Path$children", "func(path:Path, include_hidden=no -> [Path])"}, - {"concatenated_with", "Path$concat", "func(a,b:Path -> Path)"}, - {"create_directory", "Path$create_directory", "func(path:Path, permissions=Int32(0o755))"}, - {"current_dir", "Path$current_dir", "func(->Path)"}, - {"exists", "Path$exists", "func(path:Path -> Bool)"}, - {"expand_home", "Path$expand_home", "func(path:Path -> Path)"}, - {"extension", "Path$extension", "func(path:Path, full=yes -> Text)"}, - {"files", "Path$children", "func(path:Path, include_hidden=no -> [Path])"}, - {"from_components", "Path$from_components", "func(components:[Text] -> Path)"}, - {"glob", "Path$glob", "func(path:Path -> [Path])"}, - {"group", "Path$group", "func(path:Path, follow_symlinks=yes -> Text?)"}, - {"has_extension", "Path$has_extension", "func(path:Path, extension:Text -> Bool)"}, - {"is_directory", "Path$is_directory", "func(path:Path, follow_symlinks=yes -> Bool)"}, - {"is_file", "Path$is_file", "func(path:Path, follow_symlinks=yes -> Bool)"}, - {"is_pipe", "Path$is_pipe", "func(path:Path, follow_symlinks=yes -> Bool)"}, - {"is_socket", "Path$is_socket", "func(path:Path, follow_symlinks=yes -> Bool)"}, - {"is_symlink", "Path$is_symlink", "func(path:Path -> Bool)"}, - {"modified", "Path$modified", "func(path:Path, follow_symlinks=yes -> Int64?)"}, - {"owner", "Path$owner", "func(path:Path, follow_symlinks=yes -> Text?)"}, - {"parent", "Path$parent", "func(path:Path -> Path)"}, - {"read", "Path$read", "func(path:Path -> Text?)"}, - {"read_bytes", "Path$read_bytes", "func(path:Path, limit:Int?=none -> [Byte]?)"}, - {"relative_to", "Path$relative_to", "func(path:Path, relative_to:Path -> Path)"}, - {"remove", "Path$remove", "func(path:Path, ignore_missing=no)"}, - {"resolved", "Path$resolved", "func(path:Path, relative_to=(./) -> Path)"}, - {"set_owner", "Path$set_owner", "func(path:Path, owner:Text?=none, group:Text?=none, follow_symlinks=yes)"}, - {"sibling", "Path$sibling", "func(path:Path, name:Text -> Path)"}, - {"subdirectories", "Path$children", "func(path:Path, include_hidden=no -> [Path])"}, - {"unique_directory", "Path$unique_directory", "func(path:Path -> Path)"}, - {"write", "Path$write", "func(path:Path, text:Text, permissions=Int32(0o644))"}, - {"write_bytes", "Path$write_bytes", "func(path:Path, bytes:[Byte], permissions=Int32(0o644))"}, - {"write_unique", "Path$write_unique", "func(path:Path, text:Text -> Path)"}, - {"write_unique_bytes", "Path$write_unique_bytes", "func(path:Path, bytes:[Byte] -> Path)"}, + {"Path", PATH_TYPE, Text("Path_t"), Text("Pathヽinfo"), TypedList(ns_entry_t, + {"accessed", "Pathヽaccessed", "func(path:Path, follow_symlinks=yes -> Int64?)"}, + {"append", "Pathヽappend", "func(path:Path, text:Text, permissions=Int32(0o644))"}, + {"append_bytes", "Pathヽappend_bytes", "func(path:Path, bytes:[Byte], permissions=Int32(0o644))"}, + {"base_name", "Pathヽbase_name", "func(path:Path -> Text)"}, + {"by_line", "Pathヽby_line", "func(path:Path -> func(->Text?)?)"}, + {"can_execute", "Pathヽcan_execute", "func(path:Path -> Bool)"}, + {"can_read", "Pathヽcan_read", "func(path:Path -> Bool)"}, + {"can_write", "Pathヽcan_write", "func(path:Path -> Bool)"}, + {"changed", "Pathヽchanged", "func(path:Path, follow_symlinks=yes -> Int64?)"}, + {"child", "Pathヽchild", "func(path:Path, child:Text -> Path)"}, + {"children", "Pathヽchildren", "func(path:Path, include_hidden=no -> [Path])"}, + {"concatenated_with", "Pathヽconcat", "func(a,b:Path -> Path)"}, + {"create_directory", "Pathヽcreate_directory", "func(path:Path, permissions=Int32(0o755))"}, + {"current_dir", "Pathヽcurrent_dir", "func(->Path)"}, + {"exists", "Pathヽexists", "func(path:Path -> Bool)"}, + {"expand_home", "Pathヽexpand_home", "func(path:Path -> Path)"}, + {"extension", "Pathヽextension", "func(path:Path, full=yes -> Text)"}, + {"files", "Pathヽchildren", "func(path:Path, include_hidden=no -> [Path])"}, + {"from_components", "Pathヽfrom_components", "func(components:[Text] -> Path)"}, + {"glob", "Pathヽglob", "func(path:Path -> [Path])"}, + {"group", "Pathヽgroup", "func(path:Path, follow_symlinks=yes -> Text?)"}, + {"has_extension", "Pathヽhas_extension", "func(path:Path, extension:Text -> Bool)"}, + {"is_directory", "Pathヽis_directory", "func(path:Path, follow_symlinks=yes -> Bool)"}, + {"is_file", "Pathヽis_file", "func(path:Path, follow_symlinks=yes -> Bool)"}, + {"is_pipe", "Pathヽis_pipe", "func(path:Path, follow_symlinks=yes -> Bool)"}, + {"is_socket", "Pathヽis_socket", "func(path:Path, follow_symlinks=yes -> Bool)"}, + {"is_symlink", "Pathヽis_symlink", "func(path:Path -> Bool)"}, + {"modified", "Pathヽmodified", "func(path:Path, follow_symlinks=yes -> Int64?)"}, + {"owner", "Pathヽowner", "func(path:Path, follow_symlinks=yes -> Text?)"}, + {"parent", "Pathヽparent", "func(path:Path -> Path)"}, + {"read", "Pathヽread", "func(path:Path -> Text?)"}, + {"read_bytes", "Pathヽread_bytes", "func(path:Path, limit:Int?=none -> [Byte]?)"}, + {"relative_to", "Pathヽrelative_to", "func(path:Path, relative_to:Path -> Path)"}, + {"remove", "Pathヽremove", "func(path:Path, ignore_missing=no)"}, + {"resolved", "Pathヽresolved", "func(path:Path, relative_to=(./) -> Path)"}, + {"set_owner", "Pathヽset_owner", "func(path:Path, owner:Text?=none, group:Text?=none, follow_symlinks=yes)"}, + {"sibling", "Pathヽsibling", "func(path:Path, name:Text -> Path)"}, + {"subdirectories", "Pathヽchildren", "func(path:Path, include_hidden=no -> [Path])"}, + {"unique_directory", "Pathヽunique_directory", "func(path:Path -> Path)"}, + {"write", "Pathヽwrite", "func(path:Path, text:Text, permissions=Int32(0o644))"}, + {"write_bytes", "Pathヽwrite_bytes", "func(path:Path, bytes:[Byte], permissions=Int32(0o644))"}, + {"write_unique", "Pathヽwrite_unique", "func(path:Path, text:Text -> Path)"}, + {"write_unique_bytes", "Pathヽwrite_unique_bytes", "func(path:Path, bytes:[Byte] -> Path)"}, )}, - {"Text", TEXT_TYPE, Text("Text_t"), Text("Text$info"), TypedList(ns_entry_t, - {"as_c_string", "Text$as_c_string", "func(text:Text -> CString)"}, - {"at", "Text$cluster", "func(text:Text, index:Int -> Text)"}, - {"by_line", "Text$by_line", "func(text:Text -> func(->Text?))"}, - {"by_split", "Text$by_split", "func(text:Text, delimiter='' -> func(->Text?))"}, - {"by_split_any", "Text$by_split_any", "func(text:Text, delimiters=' \\t\\r\\n' -> func(->Text?))"}, - {"bytes", "Text$utf8_bytes", "func(text:Text -> [Byte])"}, - {"caseless_equals", "Text$equal_ignoring_case", "func(a,b:Text, language='C' -> Bool)"}, - {"codepoint_names", "Text$codepoint_names", "func(text:Text -> [Text])"}, - {"ends_with", "Text$ends_with", "func(text,suffix:Text, remainder:&Text? = none -> Bool)"}, - {"from", "Text$from", "func(text:Text, first:Int -> Text)"}, - {"from_bytes", "Text$from_bytes", "func(bytes:[Byte] -> Text?)"}, - {"from_c_string", "Text$from_str", "func(str:CString -> Text?)"}, - {"from_codepoint_names", "Text$from_codepoint_names", "func(codepoint_names:[Text] -> Text?)"}, - {"from_codepoints", "Text$from_codepoints", "func(codepoints:[Int32] -> Text)"}, - {"from_text", "Path$from_text", "func(text:Text -> Path)"}, - {"has", "Text$has", "func(text:Text, target:Text -> Bool)"}, - {"join", "Text$join", "func(glue:Text, pieces:[Text] -> Text)"}, - {"layout", "Text$layout", "func(text:Text -> Text)"}, - {"left_pad", "Text$left_pad", "func(text:Text, count:Int, pad=' ', language='C' -> Text)"}, - {"lines", "Text$lines", "func(text:Text -> [Text])"}, - {"lower", "Text$lower", "func(text:Text, language='C' -> Text)"}, - {"memory_size", "Text$memory_size", "func(text:Text -> Int)"}, - {"middle_pad", "Text$middle_pad", "func(text:Text, count:Int, pad=' ', language='C' -> Text)"}, - {"quoted", "Text$quoted", "func(text:Text, color=no, quotation_mark='\"' -> Text)"}, - {"repeat", "Text$repeat", "func(text:Text, count:Int -> Text)"}, - {"replace", "Text$replace", "func(text:Text, target:Text, replacement:Text -> Text)"}, - {"reversed", "Text$reversed", "func(text:Text -> Text)"}, - {"right_pad", "Text$right_pad", "func(text:Text, count:Int, pad=' ', language='C' -> Text)"}, - {"slice", "Text$slice", "func(text:Text, from=1, to=-1 -> Text)"}, - {"split", "Text$split", "func(text:Text, delimiter='' -> [Text])"}, - {"split_any", "Text$split_any", "func(text:Text, delimiters=' \\t\\r\\n' -> [Text])"}, - {"starts_with", "Text$starts_with", "func(text,prefix:Text, remainder:&Text? = none -> Bool)"}, - {"title", "Text$title", "func(text:Text, language='C' -> Text)"}, - {"to", "Text$to", "func(text:Text, last:Int -> Text)"}, - {"translate", "Text$translate", "func(text:Text, translations:{Text=Text} -> Text)"}, - {"trim", "Text$trim", "func(text:Text, to_trim=\" \t\r\n\", left=yes, right=yes -> Text)"}, - {"upper", "Text$upper", "func(text:Text, language='C' -> Text)"}, - {"utf32_codepoints", "Text$utf32_codepoints", "func(text:Text -> [Int32])"}, - {"width", "Text$width", "func(text:Text, language='C' -> Int)"}, - {"without_prefix", "Text$without_prefix", "func(text,prefix:Text -> Text)"}, - {"without_suffix", "Text$without_suffix", "func(text,suffix:Text -> Text)"}, + {"Text", TEXT_TYPE, Text("Text_t"), Text("Textヽinfo"), TypedList(ns_entry_t, + {"as_c_string", "Textヽas_c_string", "func(text:Text -> CString)"}, + {"at", "Textヽcluster", "func(text:Text, index:Int -> Text)"}, + {"by_line", "Textヽby_line", "func(text:Text -> func(->Text?))"}, + {"by_split", "Textヽby_split", "func(text:Text, delimiter='' -> func(->Text?))"}, + {"by_split_any", "Textヽby_split_any", "func(text:Text, delimiters=' \\t\\r\\n' -> func(->Text?))"}, + {"bytes", "Textヽutf8_bytes", "func(text:Text -> [Byte])"}, + {"caseless_equals", "Textヽequal_ignoring_case", "func(a,b:Text, language='C' -> Bool)"}, + {"codepoint_names", "Textヽcodepoint_names", "func(text:Text -> [Text])"}, + {"ends_with", "Textヽends_with", "func(text,suffix:Text, remainder:&Text? = none -> Bool)"}, + {"from", "Textヽfrom", "func(text:Text, first:Int -> Text)"}, + {"from_bytes", "Textヽfrom_bytes", "func(bytes:[Byte] -> Text?)"}, + {"from_c_string", "Textヽfrom_str", "func(str:CString -> Text?)"}, + {"from_codepoint_names", "Textヽfrom_codepoint_names", "func(codepoint_names:[Text] -> Text?)"}, + {"from_codepoints", "Textヽfrom_codepoints", "func(codepoints:[Int32] -> Text)"}, + {"from_text", "Pathヽfrom_text", "func(text:Text -> Path)"}, + {"has", "Textヽhas", "func(text:Text, target:Text -> Bool)"}, + {"join", "Textヽjoin", "func(glue:Text, pieces:[Text] -> Text)"}, + {"layout", "Textヽlayout", "func(text:Text -> Text)"}, + {"left_pad", "Textヽleft_pad", "func(text:Text, count:Int, pad=' ', language='C' -> Text)"}, + {"lines", "Textヽlines", "func(text:Text -> [Text])"}, + {"lower", "Textヽlower", "func(text:Text, language='C' -> Text)"}, + {"memory_size", "Textヽmemory_size", "func(text:Text -> Int)"}, + {"middle_pad", "Textヽmiddle_pad", "func(text:Text, count:Int, pad=' ', language='C' -> Text)"}, + {"quoted", "Textヽquoted", "func(text:Text, color=no, quotation_mark='\"' -> Text)"}, + {"repeat", "Textヽrepeat", "func(text:Text, count:Int -> Text)"}, + {"replace", "Textヽreplace", "func(text:Text, target:Text, replacement:Text -> Text)"}, + {"reversed", "Textヽreversed", "func(text:Text -> Text)"}, + {"right_pad", "Textヽright_pad", "func(text:Text, count:Int, pad=' ', language='C' -> Text)"}, + {"slice", "Textヽslice", "func(text:Text, from=1, to=-1 -> Text)"}, + {"split", "Textヽsplit", "func(text:Text, delimiter='' -> [Text])"}, + {"split_any", "Textヽsplit_any", "func(text:Text, delimiters=' \\t\\r\\n' -> [Text])"}, + {"starts_with", "Textヽstarts_with", "func(text,prefix:Text, remainder:&Text? = none -> Bool)"}, + {"title", "Textヽtitle", "func(text:Text, language='C' -> Text)"}, + {"to", "Textヽto", "func(text:Text, last:Int -> Text)"}, + {"translate", "Textヽtranslate", "func(text:Text, translations:{Text=Text} -> Text)"}, + {"trim", "Textヽtrim", "func(text:Text, to_trim=\" \t\r\n\", left=yes, right=yes -> Text)"}, + {"upper", "Textヽupper", "func(text:Text, language='C' -> Text)"}, + {"utf32_codepoints", "Textヽutf32_codepoints", "func(text:Text -> [Int32])"}, + {"width", "Textヽwidth", "func(text:Text, language='C' -> Int)"}, + {"without_prefix", "Textヽwithout_prefix", "func(text,prefix:Text -> Text)"}, + {"without_suffix", "Textヽwithout_suffix", "func(text,suffix:Text -> Text)"}, )}, }; @@ -400,12 +400,12 @@ env_t *global_env(bool source_mapping) if (ns_env == NULL) ns_env = namespace_env(env, global_types[i].name); binding_t *binding = new(binding_t, .type=Type(TypeInfoType, .name=global_types[i].name, .type=global_types[i].type, .env=ns_env), .code=global_types[i].typeinfo); - Table$str_set(env->globals, global_types[i].name, binding); - Table$str_set(env->types, global_types[i].name, global_types[i].type); + Tableヽstr_set(env->globals, global_types[i].name, binding); + Tableヽstr_set(env->types, global_types[i].name, global_types[i].type); } for (size_t i = 0; i < sizeof(global_types)/sizeof(global_types[0]); i++) { - binding_t *type_binding = Table$str_get(*env->globals, global_types[i].name); + binding_t *type_binding = Tableヽstr_get(*env->globals, global_types[i].name); assert(type_binding); env_t *ns_env = Match(type_binding->type, TypeInfoType)->env; for (int64_t j = 0; j < global_types[i].namespace.length; j++) { @@ -413,7 +413,7 @@ env_t *global_env(bool source_mapping) type_t *type = parse_type_string(ns_env, entry->type_str); if (!type) compiler_err(NULL, NULL, NULL, "Couldn't parse type string: ", entry->type_str); if (type->tag == ClosureType) type = Match(type, ClosureType)->fn; - set_binding(ns_env, entry->name, type, Text$from_str(entry->code)); + set_binding(ns_env, entry->name, type, Textヽfrom_str(entry->code)); } } @@ -424,99 +424,99 @@ env_t *global_env(bool source_mapping) struct { const char *c_name, *type_str; } constructor_infos[] = {__VA_ARGS__}; \ for (size_t i = 0; i < sizeof(constructor_infos)/sizeof(constructor_infos[0]); i++) { \ type_t *t = parse_type_string(ns_env, constructor_infos[i].type_str); \ - List$insert(&ns_env->namespace->constructors, \ - ((binding_t[1]){{.code=Text$from_str(constructor_infos[i].c_name), \ + Listヽinsert(&ns_env->namespace->constructors, \ + ((binding_t[1]){{.code=Textヽfrom_str(constructor_infos[i].c_name), \ .type=Match(t, ClosureType)->fn}}), I(0), sizeof(binding_t)); \ } \ } while (0) ADD_CONSTRUCTORS("Bool", - {"Bool$from_byte", "func(b:Byte -> Bool)"}, - {"Bool$from_int8", "func(i:Int8 -> Bool)"}, - {"Bool$from_int16", "func(i:Int16 -> Bool)"}, - {"Bool$from_int32", "func(i:Int32 -> Bool)"}, - {"Bool$from_int64", "func(i:Int64 -> Bool)"}, - {"Bool$from_int", "func(i:Int -> Bool)"}); + {"Boolヽfrom_byte", "func(b:Byte -> Bool)"}, + {"Boolヽfrom_int8", "func(i:Int8 -> Bool)"}, + {"Boolヽfrom_int16", "func(i:Int16 -> Bool)"}, + {"Boolヽfrom_int32", "func(i:Int32 -> Bool)"}, + {"Boolヽfrom_int64", "func(i:Int64 -> Bool)"}, + {"Boolヽfrom_int", "func(i:Int -> Bool)"}); ADD_CONSTRUCTORS("Byte", - {"Byte$from_bool", "func(b:Bool -> Byte)"}, - {"Byte$from_int8", "func(i:Int8 -> Byte)"}, - {"Byte$from_int16", "func(i:Int16, truncate=no -> Byte)"}, - {"Byte$from_int32", "func(i:Int32, truncate=no -> Byte)"}, - {"Byte$from_int64", "func(i:Int64, truncate=no -> Byte)"}, - {"Byte$from_int", "func(i:Int, truncate=no -> Byte)"}); + {"Byteヽfrom_bool", "func(b:Bool -> Byte)"}, + {"Byteヽfrom_int8", "func(i:Int8 -> Byte)"}, + {"Byteヽfrom_int16", "func(i:Int16, truncate=no -> Byte)"}, + {"Byteヽfrom_int32", "func(i:Int32, truncate=no -> Byte)"}, + {"Byteヽfrom_int64", "func(i:Int64, truncate=no -> Byte)"}, + {"Byteヽfrom_int", "func(i:Int, truncate=no -> Byte)"}); ADD_CONSTRUCTORS("Int", - {"Int$from_bool", "func(b:Bool -> Int)"}, - {"Int$from_byte", "func(b:Byte -> Int)"}, - {"Int$from_int8", "func(i:Int8 -> Int)"}, - {"Int$from_int16", "func(i:Int16 -> Int)"}, - {"Int$from_int32", "func(i:Int32 -> Int)"}, - {"Int$from_int64", "func(i:Int64 -> Int)"}, - {"Int$from_num", "func(n:Num, truncate=no -> Int)"}, - {"Int$from_num32", "func(n:Num32, truncate=no -> Int)"}); + {"Intヽfrom_bool", "func(b:Bool -> Int)"}, + {"Intヽfrom_byte", "func(b:Byte -> Int)"}, + {"Intヽfrom_int8", "func(i:Int8 -> Int)"}, + {"Intヽfrom_int16", "func(i:Int16 -> Int)"}, + {"Intヽfrom_int32", "func(i:Int32 -> Int)"}, + {"Intヽfrom_int64", "func(i:Int64 -> Int)"}, + {"Intヽfrom_num", "func(n:Num, truncate=no -> Int)"}, + {"Intヽfrom_num32", "func(n:Num32, truncate=no -> Int)"}); ADD_CONSTRUCTORS("Int64", - {"Int64$from_bool", "func(b:Bool -> Int64)"}, - {"Int64$from_byte", "func(b:Byte -> Int64)"}, - {"Int64$from_int8", "func(i:Int8 -> Int64)"}, - {"Int64$from_int16", "func(i:Int16 -> Int64)"}, - {"Int64$from_int32", "func(i:Int32 -> Int64)"}, - {"Int64$from_int", "func(i:Int, truncate=no -> Int64)"}, - {"Int64$from_num", "func(n:Num, truncate=no -> Int64)"}, - {"Int64$from_num32", "func(n:Num32, truncate=no -> Int64)"}); + {"Int64ヽfrom_bool", "func(b:Bool -> Int64)"}, + {"Int64ヽfrom_byte", "func(b:Byte -> Int64)"}, + {"Int64ヽfrom_int8", "func(i:Int8 -> Int64)"}, + {"Int64ヽfrom_int16", "func(i:Int16 -> Int64)"}, + {"Int64ヽfrom_int32", "func(i:Int32 -> Int64)"}, + {"Int64ヽfrom_int", "func(i:Int, truncate=no -> Int64)"}, + {"Int64ヽfrom_num", "func(n:Num, truncate=no -> Int64)"}, + {"Int64ヽfrom_num32", "func(n:Num32, truncate=no -> Int64)"}); ADD_CONSTRUCTORS("Int32", - {"Int32$from_bool", "func(b:Bool -> Int32)"}, - {"Int32$from_byte", "func(b:Byte -> Int32)"}, - {"Int32$from_int8", "func(i:Int8 -> Int32)"}, - {"Int32$from_int16", "func(i:Int16 -> Int32)"}, - {"Int32$from_int64", "func(i:Int64, truncate=no -> Int32)"}, - {"Int32$from_int", "func(i:Int, truncate=no -> Int32)"}, - {"Int32$from_num", "func(n:Num, truncate=no -> Int32)"}, - {"Int32$from_num32", "func(n:Num32, truncate=no -> Int32)"}); + {"Int32ヽfrom_bool", "func(b:Bool -> Int32)"}, + {"Int32ヽfrom_byte", "func(b:Byte -> Int32)"}, + {"Int32ヽfrom_int8", "func(i:Int8 -> Int32)"}, + {"Int32ヽfrom_int16", "func(i:Int16 -> Int32)"}, + {"Int32ヽfrom_int64", "func(i:Int64, truncate=no -> Int32)"}, + {"Int32ヽfrom_int", "func(i:Int, truncate=no -> Int32)"}, + {"Int32ヽfrom_num", "func(n:Num, truncate=no -> Int32)"}, + {"Int32ヽfrom_num32", "func(n:Num32, truncate=no -> Int32)"}); ADD_CONSTRUCTORS("Int16", - {"Int16$from_bool", "func(b:Bool -> Int16)"}, - {"Int16$from_byte", "func(b:Byte -> Int16)"}, - {"Int16$from_int8", "func(i:Int8 -> Int16)"}, - {"Int16$from_int32", "func(i:Int32, truncate=no -> Int16)"}, - {"Int16$from_int64", "func(i:Int64, truncate=no -> Int16)"}, - {"Int16$from_int", "func(i:Int, truncate=no -> Int16)"}, - {"Int16$from_num", "func(n:Num, truncate=no -> Int16)"}, - {"Int16$from_num32", "func(n:Num32, truncate=no -> Int16)"}); + {"Int16ヽfrom_bool", "func(b:Bool -> Int16)"}, + {"Int16ヽfrom_byte", "func(b:Byte -> Int16)"}, + {"Int16ヽfrom_int8", "func(i:Int8 -> Int16)"}, + {"Int16ヽfrom_int32", "func(i:Int32, truncate=no -> Int16)"}, + {"Int16ヽfrom_int64", "func(i:Int64, truncate=no -> Int16)"}, + {"Int16ヽfrom_int", "func(i:Int, truncate=no -> Int16)"}, + {"Int16ヽfrom_num", "func(n:Num, truncate=no -> Int16)"}, + {"Int16ヽfrom_num32", "func(n:Num32, truncate=no -> Int16)"}); ADD_CONSTRUCTORS("Int8", - {"Int8$from_bool", "func(b:Bool -> Int8)"}, - {"Int8$from_byte", "func(b:Byte -> Int8)"}, - {"Int8$from_int16", "func(i:Int16, truncate=no -> Int8)"}, - {"Int8$from_int32", "func(i:Int32, truncate=no -> Int8)"}, - {"Int8$from_int64", "func(i:Int64, truncate=no -> Int8)"}, - {"Int8$from_int", "func(i:Int, truncate=no -> Int8)"}, - {"Int8$from_num", "func(n:Num, truncate=no -> Int8)"}, - {"Int8$from_num32", "func(n:Num32, truncate=no -> Int8)"}); + {"Int8ヽfrom_bool", "func(b:Bool -> Int8)"}, + {"Int8ヽfrom_byte", "func(b:Byte -> Int8)"}, + {"Int8ヽfrom_int16", "func(i:Int16, truncate=no -> Int8)"}, + {"Int8ヽfrom_int32", "func(i:Int32, truncate=no -> Int8)"}, + {"Int8ヽfrom_int64", "func(i:Int64, truncate=no -> Int8)"}, + {"Int8ヽfrom_int", "func(i:Int, truncate=no -> Int8)"}, + {"Int8ヽfrom_num", "func(n:Num, truncate=no -> Int8)"}, + {"Int8ヽfrom_num32", "func(n:Num32, truncate=no -> Int8)"}); ADD_CONSTRUCTORS("Num", - {"Num$from_bool", "func(b:Bool -> Num)"}, - {"Num$from_byte", "func(b:Byte -> Num)"}, - {"Num$from_int8", "func(i:Int8 -> Num)"}, - {"Num$from_int16", "func(i:Int16 -> Num)"}, - {"Num$from_int32", "func(i:Int32 -> Num)"}, - {"Num$from_int64", "func(i:Int64, truncate=no -> Num)"}, - {"Num$from_int", "func(i:Int, truncate=no -> Num)"}, - {"Num$from_num32", "func(n:Num32 -> Num)"}); + {"Numヽfrom_bool", "func(b:Bool -> Num)"}, + {"Numヽfrom_byte", "func(b:Byte -> Num)"}, + {"Numヽfrom_int8", "func(i:Int8 -> Num)"}, + {"Numヽfrom_int16", "func(i:Int16 -> Num)"}, + {"Numヽfrom_int32", "func(i:Int32 -> Num)"}, + {"Numヽfrom_int64", "func(i:Int64, truncate=no -> Num)"}, + {"Numヽfrom_int", "func(i:Int, truncate=no -> Num)"}, + {"Numヽfrom_num32", "func(n:Num32 -> Num)"}); ADD_CONSTRUCTORS("Num32", - {"Num32$from_bool", "func(b:Bool -> Num32)"}, - {"Num32$from_byte", "func(b:Byte -> Num32)"}, - {"Num32$from_int8", "func(i:Int8 -> Num32)"}, - {"Num32$from_int16", "func(i:Int16 -> Num32)"}, - {"Num32$from_int32", "func(i:Int32, truncate=no -> Num32)"}, - {"Num32$from_int64", "func(i:Int64, truncate=no -> Num32)"}, - {"Num32$from_int", "func(i:Int, truncate=no -> Num32)"}, - {"Num32$from_num", "func(n:Num -> Num32)"}); + {"Num32ヽfrom_bool", "func(b:Bool -> Num32)"}, + {"Num32ヽfrom_byte", "func(b:Byte -> Num32)"}, + {"Num32ヽfrom_int8", "func(i:Int8 -> Num32)"}, + {"Num32ヽfrom_int16", "func(i:Int16 -> Num32)"}, + {"Num32ヽfrom_int32", "func(i:Int32, truncate=no -> Num32)"}, + {"Num32ヽfrom_int64", "func(i:Int64, truncate=no -> Num32)"}, + {"Num32ヽfrom_int", "func(i:Int, truncate=no -> Num32)"}, + {"Num32ヽfrom_num", "func(n:Num -> Num32)"}); ADD_CONSTRUCTORS("Path", - {"Path$escape_text", "func(text:Text -> Path)"}, - {"Path$escape_path", "func(path:Path -> Path)"}, - {"Int$value_as_text", "func(i:Int -> Path)"}); - ADD_CONSTRUCTORS("CString", {"Text$as_c_string", "func(text:Text -> CString)"}); + {"Pathヽescape_text", "func(text:Text -> Path)"}, + {"Pathヽescape_path", "func(path:Path -> Path)"}, + {"Intヽvalue_as_text", "func(i:Int -> Path)"}); + ADD_CONSTRUCTORS("CString", {"Textヽas_c_string", "func(text:Text -> CString)"}); #undef ADD_CONSTRUCTORS set_binding(namespace_env(env, "Path"), "from_text", NewFunctionType(PATH_TYPE, {.name="text", .type=TEXT_TYPE}), - Text("Path$from_text")); + Text("Pathヽfrom_text")); struct { const char *name, *code, *type_str; @@ -537,7 +537,7 @@ env_t *global_env(bool source_mapping) type_t *type = parse_type_string(env, global_vars[i].type_str); if (!type) compiler_err(NULL, NULL, NULL, "Couldn't parse type string for ", global_vars[i].name, ": ", global_vars[i].type_str); if (type->tag == ClosureType) type = Match(type, ClosureType)->fn; - Table$str_set(env->globals, global_vars[i].name, new(binding_t, .type=type, .code=Text$from_str(global_vars[i].code))); + Tableヽstr_set(env->globals, global_vars[i].name, new(binding_t, .type=type, .code=Textヽfrom_str(global_vars[i].code))); } _global_env = env; @@ -547,14 +547,14 @@ env_t *global_env(bool source_mapping) env_t *load_module_env(env_t *env, ast_t *ast) { const char *name = ast->file->filename; - env_t *cached = Table$str_get(*env->imports, name); + env_t *cached = Tableヽstr_get(*env->imports, name); if (cached) return cached; env_t *module_env = fresh_scope(env); module_env->code = new(compilation_unit_t); module_env->namespace_bindings = module_env->locals; module_env->id_suffix = get_id_suffix(ast->file->filename); - Table$str_set(module_env->imports, name, module_env); + Tableヽstr_set(module_env->imports, name, module_env); ast_list_t *statements = Match(ast, Block)->statements; visit_topologically(statements, (Closure_t){.fn=(void*)prebind_statement, .userdata=module_env}); @@ -584,7 +584,7 @@ env_t *with_enum_scope(env_t *env, type_t *t) continue; binding_t *b = get_binding(ns_env, tag->name); assert(b); - Table$str_set(env->locals, tag->name, b); + Tableヽstr_set(env->locals, tag->name, b); } return env; } @@ -607,10 +607,10 @@ env_t *for_scope(env_t *env, ast_t *ast) vars[num_vars++] = Match(var->ast, Var)->name; } if (num_vars == 1) { - set_binding(scope, vars[0], item_t, Texts("_$", vars[0])); + set_binding(scope, vars[0], item_t, USER_ID(vars[0])); } else if (num_vars == 2) { - set_binding(scope, vars[0], INT_TYPE, Texts("_$", vars[0])); - set_binding(scope, vars[1], item_t, Texts("_$", vars[1])); + set_binding(scope, vars[0], INT_TYPE, USER_ID(vars[0])); + set_binding(scope, vars[1], item_t, USER_ID(vars[1])); } return scope; } @@ -620,7 +620,7 @@ env_t *for_scope(env_t *env, ast_t *ast) code_err(for_->vars->next->ast, "This is too many variables for this loop"); type_t *item_type = Match(iter_t, SetType)->item_type; const char *name = Match(for_->vars->ast, Var)->name; - set_binding(scope, name, item_type, Texts("_$", name)); + set_binding(scope, name, item_type, USER_ID(name)); } return scope; } @@ -635,11 +635,11 @@ env_t *for_scope(env_t *env, ast_t *ast) type_t *key_t = Match(iter_t, TableType)->key_type; if (num_vars == 1) { - set_binding(scope, vars[0], key_t, Texts("_$", vars[0])); + set_binding(scope, vars[0], key_t, USER_ID(vars[0])); } else if (num_vars == 2) { - set_binding(scope, vars[0], key_t, Texts("_$", vars[0])); + set_binding(scope, vars[0], key_t, USER_ID(vars[0])); type_t *value_t = Match(iter_t, TableType)->value_type; - set_binding(scope, vars[1], value_t, Texts("_$", vars[1])); + set_binding(scope, vars[1], value_t, USER_ID(vars[1])); } return scope; } @@ -648,7 +648,7 @@ env_t *for_scope(env_t *env, ast_t *ast) if (for_->vars->next) code_err(for_->vars->next->ast, "This is too many variables for this loop"); const char *var = Match(for_->vars->ast, Var)->name; - set_binding(scope, var, INT_TYPE, Texts("_$", var)); + set_binding(scope, var, INT_TYPE, USER_ID(var)); } return scope; } @@ -660,7 +660,7 @@ env_t *for_scope(env_t *env, ast_t *ast) code_err(for_->vars->next->ast, "This is too many variables for this loop"); const char *var = Match(for_->vars->ast, Var)->name; type_t *non_opt_type = fn->ret->tag == OptionalType ? Match(fn->ret, OptionalType)->type : fn->ret; - set_binding(scope, var, non_opt_type, Texts("_$", var)); + set_binding(scope, var, non_opt_type, USER_ID(var)); } return scope; } @@ -677,7 +677,7 @@ env_t *get_namespace_by_type(env_t *env, type_t *t) case TableType: return NULL; case CStringType: case BoolType: case IntType: case BigIntType: case NumType: case ByteType: { - binding_t *b = get_binding(env, Text$as_c_string(type_to_text(t))); + binding_t *b = get_binding(env, Textヽas_c_string(type_to_text(t))); assert(b); return Match(b->type, TypeInfoType)->env; } @@ -715,7 +715,7 @@ env_t *namespace_env(env_t *env, const char *namespace_name) PUREFUNC binding_t *get_binding(env_t *env, const char *name) { - return Table$str_get(*env->locals, name); + return Tableヽstr_get(*env->locals, name); } binding_t *get_namespace_binding(env_t *env, ast_t *self, const char *name) @@ -776,7 +776,7 @@ PUREFUNC binding_t *get_metamethod_binding(env_t *env, ast_e tag, ast_t *lhs, as void set_binding(env_t *env, const char *name, type_t *type, Text_t code) { assert(name); - Table$str_set(env->locals, name, new(binding_t, .type=type, .code=code)); + Tableヽstr_set(env->locals, name, new(binding_t, .type=type, .code=code)); } // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/modules.c b/src/modules.c index 2f9d13ea..b2baf4c1 100644 --- a/src/modules.c +++ b/src/modules.c @@ -11,18 +11,18 @@ static void read_modules_ini(Path_t ini_file, module_info_t *info) { - OptionalClosure_t by_line = Path$by_line(ini_file); + OptionalClosure_t by_line = Pathヽby_line(ini_file); if (by_line.fn == NULL) return; OptionalText_t (*next_line)(void*) = by_line.fn; find_section:; for (Text_t line; (line=next_line(by_line.userdata)).length >= 0; ) { - char *line_str = Text$as_c_string(line); + char *line_str = Textヽas_c_string(line); if (line_str[0] == '[' && strncmp(line_str+1, info->name, strlen(info->name)) == 0 && line_str[1+strlen(info->name)] == ']') break; } for (Text_t line; (line=next_line(by_line.userdata)).length >= 0; ) { - char *line_str = Text$as_c_string(line); + char *line_str = Textヽas_c_string(line); if (line_str[0] == '[') goto find_section; if (!strparse(line_str, "version=", &info->version) || !strparse(line_str, "url=", &info->url) @@ -36,8 +36,8 @@ static void read_modules_ini(Path_t ini_file, module_info_t *info) module_info_t get_module_info(ast_t *use) { static Table_t cache = {}; - TypeInfo_t *cache_type = Table$info(Pointer$info("@", &Memory$info), Pointer$info("@", &Memory$info)); - module_info_t **cached = Table$get(cache, &use, cache_type); + TypeInfo_t *cache_type = Tableヽinfo(Pointerヽinfo("@", &Memoryヽinfo), Pointerヽinfo("@", &Memoryヽinfo)); + module_info_t **cached = Tableヽget(cache, &use, cache_type); if (cached) return **cached; const char *name = Match(use, Use)->path; module_info_t *info = new(module_info_t, .name=name); @@ -52,10 +52,10 @@ module_info_t get_module_info(ast_t *use) else if (streq(name, "time")) info->version = "v1.0"; else if (streq(name, "uuid")) info->version = "v1.0"; else { - read_modules_ini(Path$sibling(Path$from_str(use->file->filename), Text("modules.ini")), info); - read_modules_ini(Path$with_extension(Path$from_str(use->file->filename), Text(":modules.ini"), false), info); + read_modules_ini(Pathヽsibling(Pathヽfrom_str(use->file->filename), Text("modules.ini")), info); + read_modules_ini(Pathヽwith_extension(Pathヽfrom_str(use->file->filename), Text(":modules.ini"), false), info); } - Table$set(&cache, &use, &info, cache_type); + Tableヽset(&cache, &use, &info, cache_type); return *info; } @@ -64,25 +64,25 @@ bool try_install_module(module_info_t mod) { if (mod.git) { OptionalText_t answer = ask( - Texts(Text("The module \""), Text$from_str(mod.name), Text("\" is not installed.\nDo you want to install it from git URL "), - Text$from_str(mod.git), Text("? [Y/n] ")), + Texts(Text("The module \""), Textヽfrom_str(mod.name), Text("\" is not installed.\nDo you want to install it from git URL "), + Textヽfrom_str(mod.git), Text("? [Y/n] ")), true, true); - if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + if (!(answer.length == 0 || Textヽequal_values(answer, Text("Y")) || Textヽequal_values(answer, Text("y")))) return false; print("Installing ", mod.name, " from git..."); - Path_t tmpdir = Path$unique_directory(Path("/tmp/tomo-module-XXXXXX")); + Path_t tmpdir = Pathヽunique_directory(Path("/tmp/tomo-module-XXXXXX")); if (mod.revision) xsystem("git clone --depth=1 --revision ", mod.revision, " ", mod.git, " ", tmpdir); else xsystem("git clone --depth=1 ", mod.git, " ", tmpdir); if (mod.path) xsystem("tomo -IL ", tmpdir, "/", mod.path); else xsystem("tomo -IL ", tmpdir); - Path$remove(tmpdir, true); + Pathヽremove(tmpdir, true); return true; } else if (mod.url) { OptionalText_t answer = ask( - Texts(Text("The module "), Text$from_str(mod.name), Text(" is not installed.\nDo you want to install it from URL "), - Text$from_str(mod.url), Text("? [Y/n] ")), + Texts(Text("The module "), Textヽfrom_str(mod.name), Text(" is not installed.\nDo you want to install it from URL "), + Textヽfrom_str(mod.url), Text("? [Y/n] ")), true, true); - if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + if (!(answer.length == 0 || Textヽequal_values(answer, Text("Y")) || Textヽequal_values(answer, Text("y")))) return false; print("Installing ", mod.name, " from URL..."); @@ -93,7 +93,7 @@ bool try_install_module(module_info_t mod) p = strchr(filename, '.'); if (!p) return false; const char *extension = p + 1; - Path_t tmpdir = Path$unique_directory(Path("/tmp/tomo-module-XXXXXX")); + Path_t tmpdir = Pathヽunique_directory(Path("/tmp/tomo-module-XXXXXX")); xsystem("curl ", mod.url, " -o ", tmpdir); if (streq(extension, ".zip")) xsystem("unzip ", tmpdir, "/", filename); @@ -104,14 +104,14 @@ bool try_install_module(module_info_t mod) const char *basename = String(string_slice(filename, strcspn(filename, "."))); if (mod.path) xsystem("tomo -IL ", tmpdir, "/", basename, "/", mod.path); else xsystem("tomo -IL ", tmpdir, "/", basename); - Path$remove(tmpdir, true); + Pathヽremove(tmpdir, true); return true; } else if (mod.path) { OptionalText_t answer = ask( - Texts(Text("The module "), Text$from_str(mod.name), Text(" is not installed.\nDo you want to install it from path "), - Text$from_str(mod.path), Text("? [Y/n] ")), + Texts(Text("The module "), Textヽfrom_str(mod.name), Text(" is not installed.\nDo you want to install it from path "), + Textヽfrom_str(mod.path), Text("? [Y/n] ")), true, true); - if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + if (!(answer.length == 0 || Textヽequal_values(answer, Text("Y")) || Textヽequal_values(answer, Text("y")))) return false; print("Installing ", mod.name, " from path..."); diff --git a/src/naming.c b/src/naming.c index abe87569..c25a9147 100644 --- a/src/naming.c +++ b/src/naming.c @@ -9,6 +9,27 @@ #include "stdlib/print.h" #include "stdlib/text.h" +public const Text_t SEP = { + .length=1, + .tag=TEXT_GRAPHEMES, + .depth=0, + .graphemes=(int32_t[1]){12541 /* U+30FD KATAKANA ITERATION MARK */}, +}; + +public const Text_t ID_PREFIX = { + .length=1, + .tag=TEXT_GRAPHEMES, + .depth=0, + .graphemes=(int32_t[1]){12295 /* U+3007 IDEOGRAPHIC NUMBER ZERO */}, +}; + +public const Text_t INTERNAL_PREFIX = { + .length=1, + .tag=TEXT_GRAPHEMES, + .depth=0, + .graphemes=(int32_t[1]){12293 /* U+3005 IDEOGRAPHIC ITERATION MARK */}, +}; + static const char *c_keywords[] = { // Maintain sorted order: "_Alignas", "_Alignof", "_Atomic", "_BitInt", "_Bool", "_Complex", "_Decimal128", "_Decimal32", "_Decimal64", "_Generic", "_Imaginary", "_Noreturn", "_Static_assert", "_Thread_local", @@ -40,15 +61,15 @@ public Text_t valid_c_name(const char *name) while (trailing_underscores < len && name[len-1-trailing_underscores] == '_') trailing_underscores += 1; if (is_keyword(name, len-trailing_underscores)) { - return Texts(Text$from_str(name), Text("_")); + return Texts(Textヽfrom_str(name), Text("_")); } - return Text$from_str(name); + return Textヽfrom_str(name); } public Text_t CONSTFUNC namespace_name(env_t *env, namespace_t *ns, Text_t name) { for (; ns; ns = ns->parent) - name = Texts(ns->name, "$", name); + name = Texts(ns->name, SEP, name); if (env->id_suffix.length > 0) name = Texts(name, env->id_suffix); return name; @@ -57,16 +78,16 @@ public Text_t CONSTFUNC namespace_name(env_t *env, namespace_t *ns, Text_t name) public Text_t get_id_suffix(const char *filename) { assert(filename); - Path_t path = Path$from_str(filename); - Path_t build_dir = Path$sibling(path, Text(".build")); - if (mkdir(Path$as_c_string(build_dir), 0755) != 0) { - if (!Path$is_directory(build_dir, true)) + Path_t path = Pathヽfrom_str(filename); + Path_t build_dir = Pathヽsibling(path, Text(".build")); + if (mkdir(Pathヽas_c_string(build_dir), 0755) != 0) { + if (!Pathヽis_directory(build_dir, true)) err(1, "Could not make .build directory"); } - Path_t id_file = Path$child(build_dir, Texts(Path$base_name(path), Text$from_str(".id"))); - OptionalText_t id = Path$read(id_file); + Path_t id_file = Pathヽchild(build_dir, Texts(Pathヽbase_name(path), Textヽfrom_str(".id"))); + OptionalText_t id = Pathヽread(id_file); if (id.length < 0) err(1, "Could not read ID file: ", id_file); - return Texts(Text("$"), id); + return Texts(SEP, id); } // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/naming.h b/src/naming.h index 30d4d061..aa06ea92 100644 --- a/src/naming.h +++ b/src/naming.h @@ -5,6 +5,13 @@ #include "environment.h" #include "stdlib/datatypes.h" +extern const Text_t SEP; +extern const Text_t ID_PREFIX; +extern const Text_t INTERNAL_PREFIX; + +#define INTERNAL_ID(id) Textヽconcat(INTERNAL_PREFIX, _Generic(id, const char*: Textヽfrom_str, char*: Textヽfrom_str, Text_t: Text_from_text)(id)) +#define USER_ID(id) Textヽconcat(ID_PREFIX, _Generic(id, const char*: Textヽfrom_str, char*: Textヽfrom_str, Text_t: Text_from_text)(id)) + Text_t valid_c_name(const char *name); Text_t namespace_name(env_t *env, namespace_t *ns, Text_t name); Text_t get_id_suffix(const char *filename); diff --git a/src/parse.c b/src/parse.c index 181aae58..b201de22 100644 --- a/src/parse.c +++ b/src/parse.c @@ -380,13 +380,17 @@ const char *get_word(const char **inout) { const uint8_t *pos = (const uint8_t*)word; ucs4_t point; pos = u8_next(&point, pos); - if (!uc_is_property_xid_start(point) && point != '_') + if ((!uc_is_property_xid_start(point) && point != '_') + || point == 12541 || point == 12295 || point == 12293) // Reserved characters (see naming.c) return NULL; for (const uint8_t *next; (next = u8_next(&point, pos)); pos = next) { if (!uc_is_property_xid_continue(point)) break; + if (point == 12541 || point == 12295 || point == 12293) // Reserved characters (see naming.c) + break; } + *inout = (const char*)pos; return GC_strndup(word, (size_t)((const char*)pos - word)); } @@ -836,10 +840,10 @@ ast_t *parse_field_suffix(parse_ctx_t *ctx, ast_t *lhs) { if (!match(&pos, ".")) return NULL; if (*pos == '.') return NULL; whitespace(&pos); - bool dollar = match(&pos, "$"); - const char* field = get_id(&pos); + bool is_sep = match(&pos, "ヽ"); + const char *field = get_id(&pos); if (!field) return NULL; - if (dollar) field = String("$", field); + if (is_sep) field = String("ヽ", field); return NewAST(ctx->file, lhs->start, pos, FieldAccess, .fielded=lhs, .field=field); } @@ -869,7 +873,7 @@ PARSER(parse_reduction) { ast_e op = match_binary_operator(&pos); if (op == Unknown) return NULL; - ast_t *key = NewAST(ctx->file, pos, pos, Var, .name="$"); + ast_t *key = NewAST(ctx->file, pos, pos, Var, .name="ヽ"); for (bool progress = true; progress; ) { ast_t *new_term; progress = (false @@ -1218,7 +1222,7 @@ ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open int64_t plain_span_len = 0; #define FLUSH_PLAIN_SPAN() do { \ if (plain_span_len > 0) { \ - chunk = Texts(chunk, Text$from_strn(pos - plain_span_len, (size_t)plain_span_len)); \ + chunk = Texts(chunk, Textヽfrom_strn(pos - plain_span_len, (size_t)plain_span_len)); \ plain_span_len = 0; \ } } while (0) for (const char *end = ctx->file->text + ctx->file->len; pos < end && depth > 0; ) { @@ -1241,7 +1245,7 @@ ast_list_t *_parse_text_helper(parse_ctx_t *ctx, const char **out_pos, char open } else if (allow_escapes && *pos == '\\') { FLUSH_PLAIN_SPAN(); const char *c = unescape(ctx, &pos); - chunk = Texts(chunk, Text$from_str(c)); + chunk = Texts(chunk, Textヽfrom_str(c)); } else if (!leading_newline && *pos == open_quote && closing[(int)open_quote]) { // Nested pair begin if (get_indent(ctx, pos) == starting_indent) { ++depth; @@ -1678,7 +1682,7 @@ static ast_t *parse_infix_expr(parse_ctx_t *ctx, const char *pos, int min_tightn for (ast_e op; (op=match_binary_operator(&pos)) != Unknown && op_tightness[op] >= min_tightness; spaces(&pos)) { ast_t *key = NULL; if (op == Min || op == Max) { - key = NewAST(ctx->file, pos, pos, Var, .name="$"); + key = NewAST(ctx->file, pos, pos, Var, .name="ヽ"); for (bool progress = true; progress; ) { ast_t *new_term; progress = (false @@ -2406,7 +2410,7 @@ ast_t *parse_file(const char *path, jmp_buf *on_err) { // AST holds onto a reference to the file it came from, so they could // potentially be somewhat large. static Table_t cached = {}; - ast_t *ast = Table$str_get(cached, path); + ast_t *ast = Tableヽstr_get(cached, path); if (ast) return ast; file_t *file; @@ -2440,12 +2444,12 @@ ast_t *parse_file(const char *path, jmp_buf *on_err) { if (cached.entries.length > PARSE_CACHE_SIZE) { // FIXME: this currently evicts the first entry, but it should be more like // an LRU cache - struct {const char *path; ast_t *ast; } *to_remove = Table$entry(cached, 1); - Table$str_remove(&cached, to_remove->path); + struct {const char *path; ast_t *ast; } *to_remove = Tableヽentry(cached, 1); + Tableヽstr_remove(&cached, to_remove->path); } // Save the AST in the cache: - Table$str_set(&cached, path, ast); + Tableヽstr_set(&cached, path, ast); return ast; } diff --git a/src/stdlib/bools.c b/src/stdlib/bools.c index 85de0621..fd669579 100644 --- a/src/stdlib/bools.c +++ b/src/stdlib/bools.c @@ -12,7 +12,7 @@ #include "text.h" #include "util.h" -PUREFUNC public Text_t Bool$as_text(const void *b, bool colorize, const TypeInfo_t *info) +PUREFUNC public Text_t Boolヽas_text(const void *b, bool colorize, const TypeInfo_t *info) { (void)info; if (!b) return Text("Bool"); @@ -26,9 +26,9 @@ static bool try_parse(Text_t text, Text_t target, bool target_value, Text_t *rem { static const Text_t lang = Text("C"); if (text.length < target.length) return false; - Text_t prefix = Text$to(text, Int$from_int64(target.length)); - if (Text$equal_ignoring_case(prefix, target, lang)) { - if (remainder) *remainder = Text$from(text, Int$from_int64(target.length + 1)); + Text_t prefix = Textヽto(text, Intヽfrom_int64(target.length)); + if (Textヽequal_ignoring_case(prefix, target, lang)) { + if (remainder) *remainder = Textヽfrom(text, Intヽfrom_int64(target.length + 1)); else if (text.length > target.length) return false; *result = target_value; return true; @@ -37,7 +37,7 @@ static bool try_parse(Text_t text, Text_t target, bool target_value, Text_t *rem } } -PUREFUNC public OptionalBool_t Bool$parse(Text_t text, Text_t *remainder) +PUREFUNC public OptionalBool_t Boolヽparse(Text_t text, Text_t *remainder) { bool result; if (try_parse(text, Text("yes"), true, remainder, &result) @@ -53,18 +53,18 @@ PUREFUNC public OptionalBool_t Bool$parse(Text_t text, Text_t *remainder) return NONE_BOOL; } -static bool Bool$is_none(const void *b, const TypeInfo_t *info) +static bool Boolヽis_none(const void *b, const TypeInfo_t *info) { (void)info; return *(OptionalBool_t*)b == NONE_BOOL; } -public const TypeInfo_t Bool$info = { +public const TypeInfo_t Boolヽinfo = { .size=sizeof(bool), .align=__alignof__(bool), .metamethods={ - .as_text=Bool$as_text, - .is_none=Bool$is_none, + .as_text=Boolヽas_text, + .is_none=Boolヽis_none, }, }; diff --git a/src/stdlib/bools.h b/src/stdlib/bools.h index ae6c5feb..db282b12 100644 --- a/src/stdlib/bools.h +++ b/src/stdlib/bools.h @@ -12,15 +12,15 @@ #define yes (Bool_t)true #define no (Bool_t)false -PUREFUNC Text_t Bool$as_text(const void *b, bool colorize, const TypeInfo_t *type); -OptionalBool_t Bool$parse(Text_t text, Text_t *remainder); -MACROLIKE Bool_t Bool$from_int(Int_t i) { return (i.small != 0); } -MACROLIKE Bool_t Bool$from_int64(Int64_t i) { return (i != 0); } -MACROLIKE Bool_t Bool$from_int32(Int32_t i) { return (i != 0); } -MACROLIKE Bool_t Bool$from_int16(Int16_t i) { return (i != 0); } -MACROLIKE Bool_t Bool$from_int8(Int8_t i) { return (i != 0); } -MACROLIKE Bool_t Bool$from_byte(uint8_t b) { return (b != 0); } +PUREFUNC Text_t Boolヽas_text(const void *b, bool colorize, const TypeInfo_t *type); +OptionalBool_t Boolヽparse(Text_t text, Text_t *remainder); +MACROLIKE Bool_t Boolヽfrom_int(Int_t i) { return (i.small != 0); } +MACROLIKE Bool_t Boolヽfrom_int64(Int64_t i) { return (i != 0); } +MACROLIKE Bool_t Boolヽfrom_int32(Int32_t i) { return (i != 0); } +MACROLIKE Bool_t Boolヽfrom_int16(Int16_t i) { return (i != 0); } +MACROLIKE Bool_t Boolヽfrom_int8(Int8_t i) { return (i != 0); } +MACROLIKE Bool_t Boolヽfrom_byte(uint8_t b) { return (b != 0); } -extern const TypeInfo_t Bool$info; +extern const TypeInfo_t Boolヽinfo; // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/bytes.c b/src/stdlib/bytes.c index 130a645f..9492c14c 100644 --- a/src/stdlib/bytes.c +++ b/src/stdlib/bytes.c @@ -8,10 +8,10 @@ #include "text.h" #include "util.h" -public const Byte_t Byte$min = 0; -public const Byte_t Byte$max = UINT8_MAX; +public const Byte_t Byteヽmin = 0; +public const Byte_t Byteヽmax = UINT8_MAX; -PUREFUNC public Text_t Byte$as_text(const void *b, bool colorize, const TypeInfo_t *info) +PUREFUNC public Text_t Byteヽas_text(const void *b, bool colorize, const TypeInfo_t *info) { (void)info; if (!b) return Text("Byte"); @@ -21,28 +21,28 @@ PUREFUNC public Text_t Byte$as_text(const void *b, bool colorize, const TypeInfo (byte & 15) <= 9 ? '0' + (byte & 15) : 'a' + (byte & 15) - 10, '\0', }; - Text_t text = Text$from_str(digits); + Text_t text = Textヽfrom_str(digits); if (colorize) text = Texts(Text("\x1b[35m"), text, Text("\x1b[m")); return text; } -public CONSTFUNC bool Byte$is_between(const Byte_t x, const Byte_t low, const Byte_t high) { +public CONSTFUNC bool Byteヽis_between(const Byte_t x, const Byte_t low, const Byte_t high) { return low <= x && x <= high; } -public OptionalByte_t Byte$parse(Text_t text, Text_t *remainder) +public OptionalByte_t Byteヽparse(Text_t text, Text_t *remainder) { - OptionalInt_t full_int = Int$parse(text, remainder); + OptionalInt_t full_int = Intヽparse(text, remainder); if (full_int.small != 0L - && Int$compare_value(full_int, I(0)) >= 0 - && Int$compare_value(full_int, I(255)) <= 0) { - return (OptionalByte_t){.value=Byte$from_int(full_int, true)}; + && Intヽcompare_value(full_int, I(0)) >= 0 + && Intヽcompare_value(full_int, I(255)) <= 0) { + return (OptionalByte_t){.value=Byteヽfrom_int(full_int, true)}; } else { return NONE_BYTE; } } -public Text_t Byte$hex(Byte_t byte, bool uppercase, bool prefix) { +public Text_t Byteヽhex(Byte_t byte, bool uppercase, bool prefix) { struct Text_s text = {.tag=TEXT_ASCII}; text.ascii = GC_MALLOC_ATOMIC(8); char *p = (char*)text.ascii; @@ -62,12 +62,12 @@ public Text_t Byte$hex(Byte_t byte, bool uppercase, bool prefix) { return text; } -public bool Byte$get_bit(Byte_t x, Int_t bit_index) { - if (Int$compare_value(bit_index, I(1)) < 0) +public bool Byteヽget_bit(Byte_t x, Int_t bit_index) { + if (Intヽcompare_value(bit_index, I(1)) < 0) fail("Invalid bit index (expected 1 or higher): ", bit_index); - if (Int$compare_value(bit_index, I(8)) > 0) + if (Intヽcompare_value(bit_index, I(8)) > 0) fail("Bit index is too large! There are only 8 bits in a byte, but index is: ", bit_index); - return ((x & (Byte_t)(1L << (Int64$from_int(bit_index, true)-1L))) != 0); + return ((x & (Byte_t)(1L << (Int64ヽfrom_int(bit_index, true)-1L))) != 0); } #ifdef __TINYC__ @@ -91,7 +91,7 @@ static OptionalByte_t _next_Byte(ByteRange_t *info) { return i; } -public CONSTFUNC Closure_t Byte$to(Byte_t first, Byte_t last, OptionalInt8_t step) { +public CONSTFUNC Closure_t Byteヽto(Byte_t first, Byte_t last, OptionalInt8_t step) { ByteRange_t *range = GC_MALLOC(sizeof(ByteRange_t)); range->current = (OptionalByte_t){.value=first}; range->last = (OptionalByte_t){.value=last}; @@ -99,34 +99,34 @@ public CONSTFUNC Closure_t Byte$to(Byte_t first, Byte_t last, OptionalInt8_t ste return (Closure_t){.fn=_next_Byte, .userdata=range}; } -public PUREFUNC Byte_t Byte$from_int(Int_t i, bool truncate) { - if unlikely (!truncate && Int$compare_value(i, I_small(0xFF)) > 0) +public PUREFUNC Byte_t Byteヽfrom_int(Int_t i, bool truncate) { + if unlikely (!truncate && Intヽcompare_value(i, I_small(0xFF)) > 0) fail("This value is too large to convert to a byte without truncation: ", i); - else if unlikely (!truncate && Int$compare_value(i, I_small(0)) < 0) + else if unlikely (!truncate && Intヽcompare_value(i, I_small(0)) < 0) fail("Negative values can't be converted to bytes: ", i); return (Byte_t)(i.small >> 2); } -public PUREFUNC Byte_t Byte$from_int64(Int64_t i, bool truncate) { +public PUREFUNC Byte_t Byteヽfrom_int64(Int64_t i, bool truncate) { if unlikely (!truncate && i != (Int64_t)(Byte_t)i) fail("This value can't be converted to a byte without truncation: ", i); return (Byte_t)i; } -public PUREFUNC Byte_t Byte$from_int32(Int32_t i, bool truncate) { +public PUREFUNC Byte_t Byteヽfrom_int32(Int32_t i, bool truncate) { if unlikely (!truncate && i != (Int32_t)(Byte_t)i) fail("This value can't be converted to a byte without truncation: ", i); return (Byte_t)i; } -public PUREFUNC Byte_t Byte$from_int16(Int16_t i, bool truncate) { +public PUREFUNC Byte_t Byteヽfrom_int16(Int16_t i, bool truncate) { if unlikely (!truncate && i != (Int16_t)(Byte_t)i) fail("This value can't be converted to a byte without truncation: ", i); return (Byte_t)i; } -public const TypeInfo_t Byte$info = { +public const TypeInfo_t Byteヽinfo = { .size=sizeof(Byte_t), .align=__alignof__(Byte_t), .metamethods={ - .as_text=Byte$as_text, + .as_text=Byteヽas_text, }, }; diff --git a/src/stdlib/bytes.h b/src/stdlib/bytes.h index ab88b5bc..669303d4 100644 --- a/src/stdlib/bytes.h +++ b/src/stdlib/bytes.h @@ -13,24 +13,24 @@ #define Byte(b) ((Byte_t)(b)) -PUREFUNC Text_t Byte$as_text(const void *b, bool colorize, const TypeInfo_t *type); +PUREFUNC Text_t Byteヽas_text(const void *b, bool colorize, const TypeInfo_t *type); -Byte_t Byte$from_int(Int_t i, bool truncate); -Byte_t Byte$from_int64(int64_t i, bool truncate); -Byte_t Byte$from_int32(int32_t i, bool truncate); -Byte_t Byte$from_int16(int16_t i, bool truncate); -OptionalByte_t Byte$parse(Text_t text, Text_t *remainder); -Closure_t Byte$to(Byte_t first, Byte_t last, OptionalInt8_t step); -MACROLIKE Byte_t Byte$from_int8(int8_t i) { return (Byte_t)i; } -MACROLIKE Byte_t Byte$from_bool(bool b) { return (Byte_t)b; } -CONSTFUNC bool Byte$is_between(const Byte_t x, const Byte_t low, const Byte_t high); +Byte_t Byteヽfrom_int(Int_t i, bool truncate); +Byte_t Byteヽfrom_int64(int64_t i, bool truncate); +Byte_t Byteヽfrom_int32(int32_t i, bool truncate); +Byte_t Byteヽfrom_int16(int16_t i, bool truncate); +OptionalByte_t Byteヽparse(Text_t text, Text_t *remainder); +Closure_t Byteヽto(Byte_t first, Byte_t last, OptionalInt8_t step); +MACROLIKE Byte_t Byteヽfrom_int8(int8_t i) { return (Byte_t)i; } +MACROLIKE Byte_t Byteヽfrom_bool(bool b) { return (Byte_t)b; } +CONSTFUNC bool Byteヽis_between(const Byte_t x, const Byte_t low, const Byte_t high); -extern const Byte_t Byte$min; -extern const Byte_t Byte$max; +extern const Byte_t Byteヽmin; +extern const Byte_t Byteヽmax; -extern const TypeInfo_t Byte$info; +extern const TypeInfo_t Byteヽinfo; -Text_t Byte$hex(Byte_t byte, bool uppercase, bool prefix); -bool Byte$get_bit(Byte_t x, Int_t bit_index); +Text_t Byteヽhex(Byte_t byte, bool uppercase, bool prefix); +bool Byteヽget_bit(Byte_t x, Int_t bit_index); // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/c_strings.c b/src/stdlib/c_strings.c index 860a69ff..e4836ffe 100644 --- a/src/stdlib/c_strings.c +++ b/src/stdlib/c_strings.c @@ -11,15 +11,15 @@ #include "siphash.h" #include "util.h" -public Text_t CString$as_text(const void *c_string, bool colorize, const TypeInfo_t *info) +public Text_t CStringヽas_text(const void *c_string, bool colorize, const TypeInfo_t *info) { (void)info; if (!c_string) return Text("CString"); - Text_t text = Text$from_str(*(const char**)c_string); - return Text$concat(colorize ? Text("\x1b[34mCString\x1b[m(") : Text("CString("), Text$quoted(text, colorize, Text("\"")), Text(")")); + Text_t text = Textヽfrom_str(*(const char**)c_string); + return Textヽconcat(colorize ? Text("\x1b[34mCString\x1b[m(") : Text("CString("), Textヽquoted(text, colorize, Text("\"")), Text(")")); } -PUREFUNC public int32_t CString$compare(const void *x, const void *y, const TypeInfo_t *info) +PUREFUNC public int32_t CStringヽcompare(const void *x, const void *y, const TypeInfo_t *info) { (void)info; if (x == y) @@ -31,38 +31,38 @@ PUREFUNC public int32_t CString$compare(const void *x, const void *y, const Type return strcmp(*(const char**)x, *(const char**)y); } -PUREFUNC public bool CString$equal(const void *x, const void *y, const TypeInfo_t *type) +PUREFUNC public bool CStringヽequal(const void *x, const void *y, const TypeInfo_t *type) { - return CString$compare(x, y, type) == 0; + return CStringヽcompare(x, y, type) == 0; } -PUREFUNC public uint64_t CString$hash(const void *c_str, const TypeInfo_t *info) +PUREFUNC public uint64_t CStringヽhash(const void *c_str, const TypeInfo_t *info) { (void)info; if (!*(const char**)c_str) return 0; return siphash24(*(void**)c_str, strlen(*(const char**)c_str)); } -PUREFUNC public bool CString$is_none(const void *c_str, const TypeInfo_t *info) +PUREFUNC public bool CStringヽis_none(const void *c_str, const TypeInfo_t *info) { (void)info; return *(const char**)c_str == NULL; } -static void CString$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) +static void CStringヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) { (void)info; const char *str = *(const char **)obj; int64_t len = (int64_t)strlen(str); - Int64$serialize(&len, out, pointers, &Int64$info); + Int64ヽserialize(&len, out, pointers, &Int64ヽinfo); fwrite(str, sizeof(char), (size_t)len, out); } -static void CString$deserialize(FILE *in, void *out, List_t *pointers, const TypeInfo_t *info) +static void CStringヽdeserialize(FILE *in, void *out, List_t *pointers, const TypeInfo_t *info) { (void)info; int64_t len = -1; - Int64$deserialize(in, &len, pointers, &Int64$info); + Int64ヽdeserialize(in, &len, pointers, &Int64ヽinfo); char *str = GC_MALLOC_ATOMIC((size_t)len+1); if (fread(str, sizeof(char), (size_t)len, in) != (size_t)len) fail("Not enough data in stream to deserialize"); @@ -70,17 +70,17 @@ static void CString$deserialize(FILE *in, void *out, List_t *pointers, const Typ *(const char**)out = str; } -public const TypeInfo_t CString$info = { +public const TypeInfo_t CStringヽinfo = { .size=sizeof(const char*), .align=__alignof__(const char*), .metamethods={ - .hash=CString$hash, - .compare=CString$compare, - .equal=CString$equal, - .as_text=CString$as_text, - .is_none=CString$is_none, - .serialize=CString$serialize, - .deserialize=CString$deserialize, + .hash=CStringヽhash, + .compare=CStringヽcompare, + .equal=CStringヽequal, + .as_text=CStringヽas_text, + .is_none=CStringヽis_none, + .serialize=CStringヽserialize, + .deserialize=CStringヽdeserialize, }, }; diff --git a/src/stdlib/c_strings.h b/src/stdlib/c_strings.h index 4df5c3ac..d9e871de 100644 --- a/src/stdlib/c_strings.h +++ b/src/stdlib/c_strings.h @@ -8,11 +8,11 @@ #include "types.h" #include "util.h" -Text_t CString$as_text(const char **str, bool colorize, const TypeInfo_t *info); -PUREFUNC int CString$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool CString$equal(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC uint64_t CString$hash(const void *str, const TypeInfo_t *type); +Text_t CStringヽas_text(const char **str, bool colorize, const TypeInfo_t *info); +PUREFUNC int CStringヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool CStringヽequal(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC uint64_t CStringヽhash(const void *str, const TypeInfo_t *type); -extern const TypeInfo_t CString$info; +extern const TypeInfo_t CStringヽinfo; // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/datatypes.h b/src/stdlib/datatypes.h index fce1ea74..f786598b 100644 --- a/src/stdlib/datatypes.h +++ b/src/stdlib/datatypes.h @@ -100,7 +100,7 @@ typedef struct Text_s { } Text_t; typedef struct { - enum { PATH_NONE, PATH_RELATIVE, PATH_ABSOLUTE, PATH_HOME } $tag; + enum { PATH_NONE, PATH_RELATIVE, PATH_ABSOLUTE, PATH_HOME } ヽtag; } PathType_t; #define OptionalPathType_t PathType_t diff --git a/src/stdlib/enums.c b/src/stdlib/enums.c index ae9f440f..57c4a2b4 100644 --- a/src/stdlib/enums.c +++ b/src/stdlib/enums.c @@ -24,7 +24,7 @@ CONSTFUNC static ptrdiff_t value_offset(const TypeInfo_t *type) { return offset; } -PUREFUNC public uint64_t Enum$hash(const void *obj, const TypeInfo_t *type) +PUREFUNC public uint64_t Enumヽhash(const void *obj, const TypeInfo_t *type) { int32_t tag = *(int32_t*)obj; uint32_t components[2] = {(uint32_t)tag, 0}; @@ -36,7 +36,7 @@ PUREFUNC public uint64_t Enum$hash(const void *obj, const TypeInfo_t *type) return siphash24((void*)components, sizeof(components)); } -PUREFUNC public int32_t Enum$compare(const void *x, const void *y, const TypeInfo_t *type) +PUREFUNC public int32_t Enumヽcompare(const void *x, const void *y, const TypeInfo_t *type) { if (x == y) return 0; @@ -53,7 +53,7 @@ PUREFUNC public int32_t Enum$compare(const void *x, const void *y, const TypeInf return 0; } -PUREFUNC public bool Enum$equal(const void *x, const void *y, const TypeInfo_t *type) +PUREFUNC public bool Enumヽequal(const void *x, const void *y, const TypeInfo_t *type) { if (x == y) return true; @@ -70,30 +70,30 @@ PUREFUNC public bool Enum$equal(const void *x, const void *y, const TypeInfo_t * return true; } -public Text_t Enum$as_text(const void *obj, bool colorize, const TypeInfo_t *type) +public Text_t Enumヽas_text(const void *obj, bool colorize, const TypeInfo_t *type) { - if (!obj) return Text$from_str(type->EnumInfo.name); + if (!obj) return Textヽfrom_str(type->EnumInfo.name); int32_t tag = *(int32_t*)obj; NamedType_t value = type->EnumInfo.tags[tag-1]; if (!value.type || value.type->size == 0) { - Text_t text = Text$from_str(value.name); + Text_t text = Textヽfrom_str(value.name); return colorize ? Texts(Text("\x1b[1m"), text, Text("\x1b[m")) : text; } return generic_as_text(obj + value_offset(type), colorize, value.type); } -PUREFUNC public bool Enum$is_none(const void *x, const TypeInfo_t *info) +PUREFUNC public bool Enumヽis_none(const void *x, const TypeInfo_t *info) { (void)info; return *(int32_t*)x == 0; } -public void Enum$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) +public void Enumヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) { int32_t tag = *(int32_t*)obj; - Int32$serialize(&tag, out, pointers, &Int32$info); + Int32ヽserialize(&tag, out, pointers, &Int32ヽinfo); NamedType_t value = type->EnumInfo.tags[tag-1]; if (value.type && value.type->size > 0) { @@ -101,10 +101,10 @@ public void Enum$serialize(const void *obj, FILE *out, Table_t *pointers, const } } -public void Enum$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) +public void Enumヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) { int32_t tag = 0; - Int32$deserialize(in, &tag, pointers, &Int32$info); + Int32ヽdeserialize(in, &tag, pointers, &Int32ヽinfo); *(int32_t*)outval = tag; NamedType_t value = type->EnumInfo.tags[tag-1]; diff --git a/src/stdlib/enums.h b/src/stdlib/enums.h index 8345c527..c5e38953 100644 --- a/src/stdlib/enums.h +++ b/src/stdlib/enums.h @@ -7,32 +7,32 @@ #include "types.h" #include "util.h" -PUREFUNC uint64_t Enum$hash(const void *obj, const TypeInfo_t *type); -PUREFUNC int32_t Enum$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Enum$equal(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC Text_t Enum$as_text(const void *obj, bool colorize, const TypeInfo_t *type); -PUREFUNC bool Enum$is_none(const void *obj, const TypeInfo_t *type); -void Enum$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); -void Enum$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); +PUREFUNC uint64_t Enumヽhash(const void *obj, const TypeInfo_t *type); +PUREFUNC int32_t Enumヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Enumヽequal(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC Text_t Enumヽas_text(const void *obj, bool colorize, const TypeInfo_t *type); +PUREFUNC bool Enumヽis_none(const void *obj, const TypeInfo_t *type); +void Enumヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); +void Enumヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); -#define Enum$metamethods { \ - .as_text=Enum$as_text, \ - .compare=Enum$compare, \ - .equal=Enum$equal, \ - .hash=Enum$hash, \ - .is_none=Enum$is_none, \ - .serialize=Enum$serialize, \ - .deserialize=Enum$deserialize, \ +#define Enumヽmetamethods { \ + .as_text=Enumヽas_text, \ + .compare=Enumヽcompare, \ + .equal=Enumヽequal, \ + .hash=Enumヽhash, \ + .is_none=Enumヽis_none, \ + .serialize=Enumヽserialize, \ + .deserialize=Enumヽdeserialize, \ } -#define PackedDataEnum$metamethods { \ - .hash=PackedData$hash, \ - .compare=Enum$compare, \ - .equal=PackedData$equal, \ - .as_text=Enum$as_text, \ - .is_none=Enum$is_none, \ - .serialize=Enum$serialize, \ - .deserialize=Enum$deserialize, \ +#define PackedDataEnumヽmetamethods { \ + .hash=PackedDataヽhash, \ + .compare=Enumヽcompare, \ + .equal=PackedDataヽequal, \ + .as_text=Enumヽas_text, \ + .is_none=Enumヽis_none, \ + .serialize=Enumヽserialize, \ + .deserialize=Enumヽdeserialize, \ } // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/functiontype.c b/src/stdlib/functiontype.c index b0fff1a7..ef7b7b5b 100644 --- a/src/stdlib/functiontype.c +++ b/src/stdlib/functiontype.c @@ -11,15 +11,15 @@ #include "types.h" #include "util.h" -public Text_t Func$as_text(const void *fn, bool colorize, const TypeInfo_t *type) +public Text_t Funcヽas_text(const void *fn, bool colorize, const TypeInfo_t *type) { - Text_t text = Text$from_str(type->FunctionInfo.type_str); + Text_t text = Textヽfrom_str(type->FunctionInfo.type_str); if (fn && colorize) - text = Text$concat(Text("\x1b[32;1m"), text, Text("\x1b[m")); + text = Textヽconcat(Text("\x1b[32;1m"), text, Text("\x1b[m")); return text; } -public PUREFUNC bool Func$is_none(const void *obj, const TypeInfo_t *info) +public PUREFUNC bool Funcヽis_none(const void *obj, const TypeInfo_t *info) { (void)info; return *(void**)obj == NULL; diff --git a/src/stdlib/functiontype.h b/src/stdlib/functiontype.h index d308be96..02345c6b 100644 --- a/src/stdlib/functiontype.h +++ b/src/stdlib/functiontype.h @@ -14,21 +14,21 @@ void register_function(void *fn, Text_t filename, int64_t line_num, Text_t name) OptionalText_t get_function_name(void *fn); OptionalText_t get_function_filename(void *fn); int64_t get_function_line_num(void *fn); -Text_t Func$as_text(const void *fn, bool colorize, const TypeInfo_t *type); -PUREFUNC bool Func$is_none(const void *obj, const TypeInfo_t*); +Text_t Funcヽas_text(const void *fn, bool colorize, const TypeInfo_t *type); +PUREFUNC bool Funcヽis_none(const void *obj, const TypeInfo_t*); -#define Func$metamethods { \ - .as_text=Func$as_text, \ - .is_none=Func$is_none, \ +#define Funcヽmetamethods { \ + .as_text=Funcヽas_text, \ + .is_none=Funcヽis_none, \ .serialize=cannot_serialize, \ .deserialize=cannot_deserialize, \ } -#define Function$info(typestr) &((TypeInfo_t){.size=sizeof(void*), .align=__alignof__(void*), \ +#define Functionヽinfo(typestr) &((TypeInfo_t){.size=sizeof(void*), .align=__alignof__(void*), \ .tag=FunctionInfo, .FunctionInfo.type_str=typestr, \ - .metamethods=Func$metamethods}) -#define Closure$info(typestr) &((TypeInfo_t){.size=sizeof(void*[2]), .align=__alignof__(void*), \ + .metamethods=Funcヽmetamethods}) +#define Closureヽinfo(typestr) &((TypeInfo_t){.size=sizeof(void*[2]), .align=__alignof__(void*), \ .tag=FunctionInfo, .FunctionInfo.type_str=typestr, \ - .metamethods=Func$metamethods}) + .metamethods=Funcヽmetamethods}) // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/integers.c b/src/stdlib/integers.c index 037aba0f..6b5f55c4 100644 --- a/src/stdlib/integers.c +++ b/src/stdlib/integers.c @@ -18,7 +18,7 @@ #include "text.h" #include "types.h" -public int Int$print(FILE *f, Int_t i) { +public int Intヽprint(FILE *f, Int_t i) { if (likely(i.small & 1L)) { return _print_int(f, (int64_t)((i.small)>>2L)); } else { @@ -44,33 +44,33 @@ static inline Text_t _int64_to_text(int64_t n) if (negative) *(p--) = '-'; - return Text$from_strn(p + 1, (size_t)(&buf[19] - p)); + return Textヽfrom_strn(p + 1, (size_t)(&buf[19] - p)); } -public Text_t Int$value_as_text(Int_t i) { +public Text_t Intヽvalue_as_text(Int_t i) { if (likely(i.small & 1L)) { return _int64_to_text(i.small >> 2L); } else { char *str = mpz_get_str(NULL, 10, *i.big); - return Text$from_str(str); + return Textヽfrom_str(str); } } -public Text_t Int$as_text(const void *i, bool colorize, const TypeInfo_t *info) { +public Text_t Intヽas_text(const void *i, bool colorize, const TypeInfo_t *info) { (void)info; if (!i) return Text("Int"); - Text_t text = Int$value_as_text(*(Int_t*)i); - if (colorize) text = Text$concat(Text("\x1b[35m"), text, Text("\x1b[m")); + Text_t text = Intヽvalue_as_text(*(Int_t*)i); + if (colorize) text = Textヽconcat(Text("\x1b[35m"), text, Text("\x1b[m")); return text; } -static bool Int$is_none(const void *i, const TypeInfo_t *info) +static bool Intヽis_none(const void *i, const TypeInfo_t *info) { (void)info; return ((Int_t*)i)->small == 0L; } -public PUREFUNC int32_t Int$compare_value(const Int_t x, const Int_t y) { +public PUREFUNC int32_t Intヽcompare_value(const Int_t x, const Int_t y) { if (likely(x.small & y.small & 1L)) return (x.small > y.small) - (x.small < y.small); else if (x.small & 1) @@ -81,32 +81,32 @@ public PUREFUNC int32_t Int$compare_value(const Int_t x, const Int_t y) { return x.big == y.big ? 0 : mpz_cmp(*x.big, *y.big); } -public PUREFUNC int32_t Int$compare(const void *x, const void *y, const TypeInfo_t *info) { +public PUREFUNC int32_t Intヽcompare(const void *x, const void *y, const TypeInfo_t *info) { (void)info; - return Int$compare_value(*(Int_t*)x, *(Int_t*)y); + return Intヽcompare_value(*(Int_t*)x, *(Int_t*)y); } -public PUREFUNC bool Int$equal_value(const Int_t x, const Int_t y) { +public PUREFUNC bool Intヽequal_value(const Int_t x, const Int_t y) { if (likely((x.small | y.small) & 1L)) return x.small == y.small; else return x.big == y.big ? 0 : (mpz_cmp(*x.big, *y.big) == 0); } -public PUREFUNC bool Int$equal(const void *x, const void *y, const TypeInfo_t *info) { +public PUREFUNC bool Intヽequal(const void *x, const void *y, const TypeInfo_t *info) { (void)info; - return Int$equal_value(*(Int_t*)x, *(Int_t*)y); + return Intヽequal_value(*(Int_t*)x, *(Int_t*)y); } -public CONSTFUNC Int_t Int$clamped(Int_t x, Int_t low, Int_t high) { - return (Int$compare(&x, &low, &Int$info) <= 0) ? low : (Int$compare(&x, &high, &Int$info) >= 0 ? high : x); +public CONSTFUNC Int_t Intヽclamped(Int_t x, Int_t low, Int_t high) { + return (Intヽcompare(&x, &low, &Intヽinfo) <= 0) ? low : (Intヽcompare(&x, &high, &Intヽinfo) >= 0 ? high : x); } -public CONSTFUNC bool Int$is_between(const Int_t x, const Int_t low, const Int_t high) { - return Int$compare_value(low, x) <= 0 && Int$compare_value(x, high) <= 0; +public CONSTFUNC bool Intヽis_between(const Int_t x, const Int_t low, const Int_t high) { + return Intヽcompare_value(low, x) <= 0 && Intヽcompare_value(x, high) <= 0; } -public PUREFUNC uint64_t Int$hash(const void *vx, const TypeInfo_t *info) { +public PUREFUNC uint64_t Intヽhash(const void *vx, const TypeInfo_t *info) { (void)info; Int_t *x = (Int_t*)vx; if (likely(x->small & 1L)) { @@ -117,57 +117,57 @@ public PUREFUNC uint64_t Int$hash(const void *vx, const TypeInfo_t *info) { } } -public Text_t Int$hex(Int_t i, Int_t digits_int, bool uppercase, bool prefix) { - if (Int$is_negative(i)) - return Text$concat(Text("-"), Int$hex(Int$negative(i), digits_int, uppercase, prefix)); +public Text_t Intヽhex(Int_t i, Int_t digits_int, bool uppercase, bool prefix) { + if (Intヽis_negative(i)) + return Textヽconcat(Text("-"), Intヽhex(Intヽnegative(i), digits_int, uppercase, prefix)); if (likely(i.small & 1L)) { uint64_t u64 = (uint64_t)(i.small >> 2); - return Text$from_str(String(hex(u64, .no_prefix=!prefix, .digits=Int32$from_int(digits_int, false), .uppercase=uppercase))); + return Textヽfrom_str(String(hex(u64, .no_prefix=!prefix, .digits=Int32ヽfrom_int(digits_int, false), .uppercase=uppercase))); } else { char *str = mpz_get_str(NULL, 16, *i.big); if (uppercase) { for (char *c = str; *c; c++) *c = (char)toupper(*c); } - int64_t digits = Int64$from_int(digits_int, false); + int64_t digits = Int64ヽfrom_int(digits_int, false); int64_t needed_zeroes = digits - (int64_t)strlen(str); if (needed_zeroes <= 0) - return prefix ? Text$concat(Text("0x"), Text$from_str(str)) : Text$from_str(str); + return prefix ? Textヽconcat(Text("0x"), Textヽfrom_str(str)) : Textヽfrom_str(str); char *zeroes = GC_MALLOC_ATOMIC((size_t)(needed_zeroes)); memset(zeroes, '0', (size_t)(needed_zeroes)); if (prefix) - return Text$concat(Text("0x"), Text$from_str(zeroes), Text$from_str(str)); + return Textヽconcat(Text("0x"), Textヽfrom_str(zeroes), Textヽfrom_str(str)); else - return Text$concat(Text$from_str(zeroes), Text$from_str(str)); + return Textヽconcat(Textヽfrom_str(zeroes), Textヽfrom_str(str)); } } -public Text_t Int$octal(Int_t i, Int_t digits_int, bool prefix) { - if (Int$is_negative(i)) - return Text$concat(Text("-"), Int$octal(Int$negative(i), digits_int, prefix)); +public Text_t Intヽoctal(Int_t i, Int_t digits_int, bool prefix) { + if (Intヽis_negative(i)) + return Textヽconcat(Text("-"), Intヽoctal(Intヽnegative(i), digits_int, prefix)); if (likely(i.small & 1L)) { uint64_t u64 = (uint64_t)(i.small >> 2); - return Text$from_str(String(oct(u64, .no_prefix=!prefix, .digits=Int32$from_int(digits_int, false)))); + return Textヽfrom_str(String(oct(u64, .no_prefix=!prefix, .digits=Int32ヽfrom_int(digits_int, false)))); } else { - int64_t digits = Int64$from_int(digits_int, false); + int64_t digits = Int64ヽfrom_int(digits_int, false); char *str = mpz_get_str(NULL, 8, *i.big); int64_t needed_zeroes = digits - (int64_t)strlen(str); if (needed_zeroes <= 0) - return prefix ? Text$concat(Text("0o"), Text$from_str(str)) : Text$from_str(str); + return prefix ? Textヽconcat(Text("0o"), Textヽfrom_str(str)) : Textヽfrom_str(str); char *zeroes = GC_MALLOC_ATOMIC((size_t)(needed_zeroes)); memset(zeroes, '0', (size_t)(needed_zeroes)); if (prefix) - return Text$concat(Text("0o"), Text$from_str(zeroes), Text$from_str(str)); + return Textヽconcat(Text("0o"), Textヽfrom_str(zeroes), Textヽfrom_str(str)); else - return Text$concat(Text$from_str(zeroes), Text$from_str(str)); + return Textヽconcat(Textヽfrom_str(zeroes), Textヽfrom_str(str)); } } -public Int_t Int$slow_plus(Int_t x, Int_t y) { +public Int_t Intヽslow_plus(Int_t x, Int_t y) { mpz_t result; mpz_init_set_int(result, x); if (y.small & 1L) { @@ -178,10 +178,10 @@ public Int_t Int$slow_plus(Int_t x, Int_t y) { } else { mpz_add(result, result, *y.big); } - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_minus(Int_t x, Int_t y) { +public Int_t Intヽslow_minus(Int_t x, Int_t y) { mpz_t result; mpz_init_set_int(result, x); if (y.small & 1L) { @@ -192,20 +192,20 @@ public Int_t Int$slow_minus(Int_t x, Int_t y) { } else { mpz_sub(result, result, *y.big); } - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_times(Int_t x, Int_t y) { +public Int_t Intヽslow_times(Int_t x, Int_t y) { mpz_t result; mpz_init_set_int(result, x); if (y.small & 1L) mpz_mul_si(result, result, y.small >> 2L); else mpz_mul(result, result, *y.big); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_divided_by(Int_t dividend, Int_t divisor) { +public Int_t Intヽslow_divided_by(Int_t dividend, Int_t divisor) { // Euclidean division, see: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf mpz_t quotient, remainder; mpz_init_set_int(quotient, dividend); @@ -218,20 +218,20 @@ public Int_t Int$slow_divided_by(Int_t dividend, Int_t divisor) { else mpz_add_ui(quotient, quotient, 1); } - return Int$from_mpz(quotient); + return Intヽfrom_mpz(quotient); } -public Int_t Int$slow_modulo(Int_t x, Int_t modulus) +public Int_t Intヽslow_modulo(Int_t x, Int_t modulus) { mpz_t result; mpz_init_set_int(result, x); mpz_t divisor; mpz_init_set_int(divisor, modulus); mpz_mod(result, result, divisor); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_modulo1(Int_t x, Int_t modulus) +public Int_t Intヽslow_modulo1(Int_t x, Int_t modulus) { mpz_t result; mpz_init_set_int(result, x); @@ -240,67 +240,67 @@ public Int_t Int$slow_modulo1(Int_t x, Int_t modulus) mpz_init_set_int(divisor, modulus); mpz_mod(result, result, divisor); mpz_add_ui(result, result, 1); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_left_shifted(Int_t x, Int_t y) +public Int_t Intヽslow_left_shifted(Int_t x, Int_t y) { - mp_bitcnt_t bits = (mp_bitcnt_t)Int64$from_int(y, false); + mp_bitcnt_t bits = (mp_bitcnt_t)Int64ヽfrom_int(y, false); mpz_t result; mpz_init_set_int(result, x); mpz_mul_2exp(result, result, bits); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_right_shifted(Int_t x, Int_t y) +public Int_t Intヽslow_right_shifted(Int_t x, Int_t y) { - mp_bitcnt_t bits = (mp_bitcnt_t)Int64$from_int(y, false); + mp_bitcnt_t bits = (mp_bitcnt_t)Int64ヽfrom_int(y, false); mpz_t result; mpz_init_set_int(result, x); mpz_tdiv_q_2exp(result, result, bits); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_bit_and(Int_t x, Int_t y) +public Int_t Intヽslow_bit_and(Int_t x, Int_t y) { mpz_t result; mpz_init_set_int(result, x); mpz_t y_mpz; mpz_init_set_int(y_mpz, y); mpz_and(result, result, y_mpz); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_bit_or(Int_t x, Int_t y) +public Int_t Intヽslow_bit_or(Int_t x, Int_t y) { mpz_t result; mpz_init_set_int(result, x); mpz_t y_mpz; mpz_init_set_int(y_mpz, y); mpz_ior(result, result, y_mpz); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_bit_xor(Int_t x, Int_t y) +public Int_t Intヽslow_bit_xor(Int_t x, Int_t y) { mpz_t result; mpz_init_set_int(result, x); mpz_t y_mpz; mpz_init_set_int(y_mpz, y); mpz_xor(result, result, y_mpz); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_negated(Int_t x) +public Int_t Intヽslow_negated(Int_t x) { mpz_t result; mpz_init_set_int(result, x); mpz_neg(result, result); mpz_sub_ui(result, result, 1); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$slow_negative(Int_t x) +public Int_t Intヽslow_negative(Int_t x) { if (likely(x.small & 1L)) return (Int_t){.small=4L*-((x.small)>>2L) + 1L}; @@ -308,10 +308,10 @@ public Int_t Int$slow_negative(Int_t x) mpz_t result; mpz_init_set_int(result, x); mpz_neg(result, result); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$abs(Int_t x) +public Int_t Intヽabs(Int_t x) { if (likely(x.small & 1L)) return (Int_t){.small=4L*labs((x.small)>>2L) + 1L}; @@ -319,24 +319,24 @@ public Int_t Int$abs(Int_t x) mpz_t result; mpz_init_set_int(result, x); mpz_abs(result, result); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$power(Int_t base, Int_t exponent) +public Int_t Intヽpower(Int_t base, Int_t exponent) { - int64_t exp = Int64$from_int(exponent, false); + int64_t exp = Int64ヽfrom_int(exponent, false); if (unlikely(exp < 0)) fail("Cannot take a negative power of an integer!"); mpz_t result; mpz_init_set_int(result, base); mpz_pow_ui(result, result, (uint64_t)exp); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public Int_t Int$gcd(Int_t x, Int_t y) +public Int_t Intヽgcd(Int_t x, Int_t y) { if (likely(x.small & y.small & 0x1L)) - return I_small(Int32$gcd(x.small >> 2L, y.small >> 2L)); + return I_small(Int32ヽgcd(x.small >> 2L, y.small >> 2L)); mpz_t result; mpz_init(result); @@ -346,29 +346,29 @@ public Int_t Int$gcd(Int_t x, Int_t y) mpz_gcd_ui(result, *x.big, (uint64_t)labs(y.small>>2L)); else mpz_gcd(result, *x.big, *y.big); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public OptionalInt_t Int$sqrt(Int_t i) +public OptionalInt_t Intヽsqrt(Int_t i) { - if (Int$compare_value(i, I(0)) < 0) + if (Intヽcompare_value(i, I(0)) < 0) return NONE_INT; mpz_t result; mpz_init_set_int(result, i); mpz_sqrt(result, result); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -public bool Int$get_bit(Int_t x, Int_t bit_index) +public bool Intヽget_bit(Int_t x, Int_t bit_index) { mpz_t i; mpz_init_set_int(i, x); - if (Int$compare_value(bit_index, I(1)) < 0) + if (Intヽcompare_value(bit_index, I(1)) < 0) fail("Invalid bit index (expected 1 or higher): ", bit_index); - if (Int$compare_value(bit_index, Int$from_int64(INT64_MAX)) > 0) + if (Intヽcompare_value(bit_index, Intヽfrom_int64(INT64_MAX)) > 0) fail("Bit index is too large! ", bit_index); - int is_bit_set = mpz_tstbit(i, (mp_bitcnt_t)(Int64$from_int(bit_index, true)-1)); + int is_bit_set = mpz_tstbit(i, (mp_bitcnt_t)(Int64ヽfrom_int(bit_index, true)-1)); return (bool)is_bit_set; } @@ -380,26 +380,26 @@ typedef struct { static OptionalInt_t _next_int(IntRange_t *info) { OptionalInt_t i = info->current; - if (!Int$is_none(&i, &Int$info)) { - Int_t next = Int$plus(i, info->step); - if (!Int$is_none(&info->last, &Int$info) && Int$compare_value(next, info->last) == Int$compare_value(info->step, I(0))) + if (!Intヽis_none(&i, &Intヽinfo)) { + Int_t next = Intヽplus(i, info->step); + if (!Intヽis_none(&info->last, &Intヽinfo) && Intヽcompare_value(next, info->last) == Intヽcompare_value(info->step, I(0))) next = NONE_INT; info->current = next; } return i; } -public PUREFUNC Closure_t Int$to(Int_t first, Int_t last, OptionalInt_t step) { +public PUREFUNC Closure_t Intヽto(Int_t first, Int_t last, OptionalInt_t step) { IntRange_t *range = GC_MALLOC(sizeof(IntRange_t)); range->current = first; range->last = last; - range->step = Int$is_none(&step, &Int$info) ? - Int$compare_value(last, first) >= 0 ? (Int_t){.small=(1L<<2L)|1L} : (Int_t){.small=(-1L>>2L)|1L} + range->step = Intヽis_none(&step, &Intヽinfo) ? + Intヽcompare_value(last, first) >= 0 ? (Int_t){.small=(1L<<2L)|1L} : (Int_t){.small=(-1L>>2L)|1L} : step; return (Closure_t){.fn=_next_int, .userdata=range}; } -public PUREFUNC Closure_t Int$onward(Int_t first, Int_t step) { +public PUREFUNC Closure_t Intヽonward(Int_t first, Int_t step) { IntRange_t *range = GC_MALLOC(sizeof(IntRange_t)); range->current = first; range->last = NONE_INT; @@ -407,7 +407,7 @@ public PUREFUNC Closure_t Int$onward(Int_t first, Int_t step) { return (Closure_t){.fn=_next_int, .userdata=range}; } -public Int_t Int$from_str(const char *str) { +public Int_t Intヽfrom_str(const char *str) { mpz_t i; int result; if (strncmp(str, "0x", 2) == 0) { @@ -421,31 +421,31 @@ public Int_t Int$from_str(const char *str) { } if (result != 0) return NONE_INT; - return Int$from_mpz(i); + return Intヽfrom_mpz(i); } -public OptionalInt_t Int$parse(Text_t text, Text_t *remainder) { - const char *str = Text$as_c_string(text); +public OptionalInt_t Intヽparse(Text_t text, Text_t *remainder) { + const char *str = Textヽas_c_string(text); mpz_t i; int result; if (strncmp(str, "0x", 2) == 0) { const char *end = str + 2 + strspn(str + 2, "0123456789abcdefABCDEF"); - if (remainder) *remainder = Text$from_str(end); + if (remainder) *remainder = Textヽfrom_str(end); else if (*end != '\0') return NONE_INT; result = mpz_init_set_str(i, str + 2, 16); } else if (strncmp(str, "0o", 2) == 0) { const char *end = str + 2 + strspn(str + 2, "01234567"); - if (remainder) *remainder = Text$from_str(end); + if (remainder) *remainder = Textヽfrom_str(end); else if (*end != '\0') return NONE_INT; result = mpz_init_set_str(i, str + 2, 8); } else if (strncmp(str, "0b", 2) == 0) { const char *end = str + 2 + strspn(str + 2, "01"); - if (remainder) *remainder = Text$from_str(end); + if (remainder) *remainder = Textヽfrom_str(end); else if (*end != '\0') return NONE_INT; result = mpz_init_set_str(i, str + 2, 2); } else { const char *end = str + 2 + strspn(str + 2, "0123456789"); - if (remainder) *remainder = Text$from_str(end); + if (remainder) *remainder = Textヽfrom_str(end); else if (*end != '\0') return NONE_INT; result = mpz_init_set_str(i, str, 10); } @@ -453,49 +453,49 @@ public OptionalInt_t Int$parse(Text_t text, Text_t *remainder) { if (remainder) *remainder = text; return NONE_INT; } - return Int$from_mpz(i); + return Intヽfrom_mpz(i); } -public bool Int$is_prime(Int_t x, Int_t reps) +public bool Intヽis_prime(Int_t x, Int_t reps) { mpz_t p; mpz_init_set_int(p, x); - if (unlikely(Int$compare_value(reps, I(9999)) > 0)) + if (unlikely(Intヽcompare_value(reps, I(9999)) > 0)) fail("Number of prime-test repetitions should not be above 9999"); - int reps_int = Int32$from_int(reps, false); + int reps_int = Int32ヽfrom_int(reps, false); return (mpz_probab_prime_p(p, reps_int) != 0); } -public Int_t Int$next_prime(Int_t x) +public Int_t Intヽnext_prime(Int_t x) { mpz_t p; mpz_init_set_int(p, x); mpz_nextprime(p, p); - return Int$from_mpz(p); + return Intヽfrom_mpz(p); } #if __GNU_MP_VERSION >= 6 #if __GNU_MP_VERSION_MINOR >= 3 -public OptionalInt_t Int$prev_prime(Int_t x) +public OptionalInt_t Intヽprev_prime(Int_t x) { mpz_t p; mpz_init_set_int(p, x); if (unlikely(mpz_prevprime(p, p) == 0)) return NONE_INT; - return Int$from_mpz(p); + return Intヽfrom_mpz(p); } #endif #endif -public Int_t Int$choose(Int_t n, Int_t k) +public Int_t Intヽchoose(Int_t n, Int_t k) { - if unlikely (Int$compare_value(n, I_small(0)) < 0) + if unlikely (Intヽcompare_value(n, I_small(0)) < 0) fail("Negative inputs are not supported for choose()"); mpz_t ret; mpz_init(ret); - int64_t k_i64 = Int64$from_int(k, false); + int64_t k_i64 = Int64ヽfrom_int(k, false); if unlikely (k_i64 < 0) fail("Negative inputs are not supported for choose()"); @@ -506,28 +506,28 @@ public Int_t Int$choose(Int_t n, Int_t k) mpz_init_set_int(n_mpz, n); mpz_bin_ui(ret, n_mpz, (unsigned long)k_i64); } - return Int$from_mpz(ret); + return Intヽfrom_mpz(ret); } -public Int_t Int$factorial(Int_t n) +public Int_t Intヽfactorial(Int_t n) { mpz_t ret; mpz_init(ret); - int64_t n_i64 = Int64$from_int(n, false); + int64_t n_i64 = Int64ヽfrom_int(n, false); if unlikely (n_i64 < 0) fail("Factorials are not defined for negative numbers"); mpz_fac_ui(ret, (unsigned long)n_i64); - return Int$from_mpz(ret); + return Intヽfrom_mpz(ret); } -static void Int$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) +static void Intヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) { (void)info; Int_t i = *(Int_t*)obj; if (likely(i.small & 1L)) { fputc(0, out); int64_t i64 = i.small >> 2L; - Int64$serialize(&i64, out, pointers, &Int64$info); + Int64ヽserialize(&i64, out, pointers, &Int64ヽinfo); } else { fputc(1, out); mpz_t n; @@ -536,36 +536,36 @@ static void Int$serialize(const void *obj, FILE *out, Table_t *pointers, const T } } -static void Int$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *info) +static void Intヽdeserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *info) { (void)info; if (fgetc(in) == 0) { int64_t i = 0; - Int64$deserialize(in, &i, pointers, &Int64$info); + Int64ヽdeserialize(in, &i, pointers, &Int64ヽinfo); *(Int_t*)obj = (Int_t){.small=(i<<2L) | 1L}; } else { mpz_t n; mpz_init(n); mpz_inp_raw(n, in); - *(Int_t*)obj = Int$from_mpz(n); + *(Int_t*)obj = Intヽfrom_mpz(n); } } -public const TypeInfo_t Int$info = { +public const TypeInfo_t Intヽinfo = { .size=sizeof(Int_t), .align=__alignof__(Int_t), .metamethods={ - .compare=Int$compare, - .equal=Int$equal, - .hash=Int$hash, - .as_text=Int$as_text, - .is_none=Int$is_none, - .serialize=Int$serialize, - .deserialize=Int$deserialize, + .compare=Intヽcompare, + .equal=Intヽequal, + .hash=Intヽhash, + .as_text=Intヽas_text, + .is_none=Intヽis_none, + .serialize=Intヽserialize, + .deserialize=Intヽdeserialize, }, }; -public void Int64$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) +public void Int64ヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) { (void)info, (void)pointers; int64_t i = *(int64_t*)obj; @@ -577,7 +577,7 @@ public void Int64$serialize(const void *obj, FILE *out, Table_t *pointers, const fputc((uint8_t)z, out); } -public void Int64$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *info) +public void Int64ヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *info) { (void)info, (void)pointers; uint64_t z = 0; @@ -589,7 +589,7 @@ public void Int64$deserialize(FILE *in, void *outval, List_t *pointers, const Ty *(int64_t*)outval = (int64_t)((z >> 1L) ^ -(z & 1L)); // Zigzag decode } -public void Int32$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) +public void Int32ヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) { (void)info, (void)pointers; int32_t i = *(int32_t*)obj; @@ -601,7 +601,7 @@ public void Int32$serialize(const void *obj, FILE *out, Table_t *pointers, const fputc((uint8_t)z, out); } -public void Int32$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *info) +public void Int32ヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *info) { (void)info, (void)pointers; uint32_t z = 0; @@ -614,45 +614,45 @@ public void Int32$deserialize(FILE *in, void *outval, List_t *pointers, const Ty } // The space savings for smaller ints are not worth having: -#define Int16$serialize NULL -#define Int16$deserialize NULL -#define Int8$serialize NULL -#define Int8$deserialize NULL +#define Int16ヽserialize NULL +#define Int16ヽdeserialize NULL +#define Int8ヽserialize NULL +#define Int8ヽdeserialize NULL #ifdef __TINYC__ #define __builtin_add_overflow(x, y, result) ({ *(result) = (x) + (y); false; }) #endif #define DEFINE_INT_TYPE(c_type, KindOfInt, min_val, max_val, to_attr)\ - public Text_t KindOfInt ## $as_text(const void *i, bool colorize, const TypeInfo_t *info) { \ + public Text_t KindOfInt ## ヽas_text(const void *i, bool colorize, const TypeInfo_t *info) { \ (void)info; \ if (!i) return Text(#KindOfInt); \ Text_t text = _int64_to_text((int64_t)(*(c_type*)i)); \ return colorize ? Texts(Text("\033[35m"), text, Text("\033[m")) : text; \ } \ - public PUREFUNC int32_t KindOfInt ## $compare(const void *x, const void *y, const TypeInfo_t *info) { \ + public PUREFUNC int32_t KindOfInt ## ヽcompare(const void *x, const void *y, const TypeInfo_t *info) { \ (void)info; \ return (*(c_type*)x > *(c_type*)y) - (*(c_type*)x < *(c_type*)y); \ } \ - public PUREFUNC bool KindOfInt ## $equal(const void *x, const void *y, const TypeInfo_t *info) { \ + public PUREFUNC bool KindOfInt ## ヽequal(const void *x, const void *y, const TypeInfo_t *info) { \ (void)info; \ return *(c_type*)x == *(c_type*)y; \ } \ - public CONSTFUNC bool KindOfInt ## $is_between(const c_type x, const c_type low, const c_type high) { \ + public CONSTFUNC bool KindOfInt ## ヽis_between(const c_type x, const c_type low, const c_type high) { \ return low <= x && x <= high; \ } \ - public CONSTFUNC c_type KindOfInt ## $clamped(c_type x, c_type min, c_type max) { \ + public CONSTFUNC c_type KindOfInt ## ヽclamped(c_type x, c_type min, c_type max) { \ return x < min ? min : (x > max ? max : x); \ } \ - public Text_t KindOfInt ## $hex(c_type i, Int_t digits_int, bool uppercase, bool prefix) { \ - Int_t as_int = Int$from_int64((int64_t)i); \ - return Int$hex(as_int, digits_int, uppercase, prefix); \ + public Text_t KindOfInt ## ヽhex(c_type i, Int_t digits_int, bool uppercase, bool prefix) { \ + Int_t as_int = Intヽfrom_int64((int64_t)i); \ + return Intヽhex(as_int, digits_int, uppercase, prefix); \ } \ - public Text_t KindOfInt ## $octal(c_type i, Int_t digits_int, bool prefix) { \ - Int_t as_int = Int$from_int64((int64_t)i); \ - return Int$octal(as_int, digits_int, prefix); \ + public Text_t KindOfInt ## ヽoctal(c_type i, Int_t digits_int, bool prefix) { \ + Int_t as_int = Intヽfrom_int64((int64_t)i); \ + return Intヽoctal(as_int, digits_int, prefix); \ } \ - public List_t KindOfInt ## $bits(c_type x) { \ + public List_t KindOfInt ## ヽbits(c_type x) { \ List_t bit_list = (List_t){.data=GC_MALLOC_ATOMIC(sizeof(bool[8*sizeof(c_type)])), .atomic=1, .stride=sizeof(bool), .length=8*sizeof(c_type)}; \ bool *bits = bit_list.data + sizeof(c_type)*8; \ for (size_t i = 0; i < 8*sizeof(c_type); i++) { \ @@ -661,12 +661,12 @@ public void Int32$deserialize(FILE *in, void *outval, List_t *pointers, const Ty } \ return bit_list; \ } \ - public bool KindOfInt ## $get_bit(c_type x, Int_t bit_index) { \ - if (Int$compare_value(bit_index, I(1)) < 0) \ + public bool KindOfInt ## ヽget_bit(c_type x, Int_t bit_index) { \ + if (Intヽcompare_value(bit_index, I(1)) < 0) \ fail("Invalid bit index (expected 1 or higher): ", bit_index); \ - if (Int$compare_value(bit_index, Int$from_int64(sizeof(c_type)*8)) > 0) \ + if (Intヽcompare_value(bit_index, Intヽfrom_int64(sizeof(c_type)*8)) > 0) \ fail("Bit index is too large! There are only ", sizeof(c_type)*8, " bits, but index is: ", bit_index); \ - return ((x & (c_type)(1L << (Int64$from_int(bit_index, true)-1L))) != 0); \ + return ((x & (c_type)(1L << (Int64ヽfrom_int(bit_index, true)-1L))) != 0); \ } \ typedef struct { \ Optional##KindOfInt##_t current, last; \ @@ -684,51 +684,51 @@ public void Int32$deserialize(FILE *in, void *outval, List_t *pointers, const Ty } \ return i; \ } \ - public to_attr Closure_t KindOfInt ## $to(c_type first, c_type last, Optional ## KindOfInt ## _t step) { \ + public to_attr Closure_t KindOfInt ## ヽto(c_type first, c_type last, Optional ## KindOfInt ## _t step) { \ KindOfInt##Range_t *range = GC_MALLOC(sizeof(KindOfInt##Range_t)); \ range->current = (Optional##KindOfInt##_t){.value=first}; \ range->last = (Optional##KindOfInt##_t){.value=last}; \ range->step = step.is_none ? (last >= first ? 1 : -1) : step.value; \ return (Closure_t){.fn=_next_##KindOfInt, .userdata=range}; \ } \ - public to_attr Closure_t KindOfInt ## $onward(c_type first, c_type step) { \ + public to_attr Closure_t KindOfInt ## ヽonward(c_type first, c_type step) { \ KindOfInt##Range_t *range = GC_MALLOC(sizeof(KindOfInt##Range_t)); \ range->current = (Optional##KindOfInt##_t){.value=first}; \ range->last = (Optional##KindOfInt##_t){.is_none=true}; \ range->step = step; \ return (Closure_t){.fn=_next_##KindOfInt, .userdata=range}; \ } \ - public PUREFUNC Optional ## KindOfInt ## _t KindOfInt ## $parse(Text_t text, Text_t *remainder) { \ - OptionalInt_t full_int = Int$parse(text, remainder); \ + public PUREFUNC Optional ## KindOfInt ## _t KindOfInt ## ヽparse(Text_t text, Text_t *remainder) { \ + OptionalInt_t full_int = Intヽparse(text, remainder); \ if (full_int.small == 0L) return (Optional ## KindOfInt ## _t){.is_none=true}; \ - if (Int$compare_value(full_int, I(min_val)) < 0) { \ + if (Intヽcompare_value(full_int, I(min_val)) < 0) { \ return (Optional ## KindOfInt ## _t){.is_none=true}; \ } \ - if (Int$compare_value(full_int, I(max_val)) > 0) { \ + if (Intヽcompare_value(full_int, I(max_val)) > 0) { \ return (Optional ## KindOfInt ## _t){.is_none=true}; \ } \ - return (Optional ## KindOfInt ## _t){.value=KindOfInt##$from_int(full_int, true)}; \ + return (Optional ## KindOfInt ## _t){.value=KindOfInt##ヽfrom_int(full_int, true)}; \ } \ - public CONSTFUNC c_type KindOfInt ## $gcd(c_type x, c_type y) { \ + public CONSTFUNC c_type KindOfInt ## ヽgcd(c_type x, c_type y) { \ if (x == 0 || y == 0) return 0; \ - x = KindOfInt##$abs(x); \ - y = KindOfInt##$abs(y); \ + x = KindOfInt##ヽabs(x); \ + y = KindOfInt##ヽabs(y); \ while (x != y) { \ if (x > y) x -= y; \ else y -= x; \ } \ return x; \ } \ - public const c_type KindOfInt##$min = min_val; \ - public const c_type KindOfInt##$max = max_val; \ - public const TypeInfo_t KindOfInt##$info = { \ + public const c_type KindOfInt##ヽmin = min_val; \ + public const c_type KindOfInt##ヽmax = max_val; \ + public const TypeInfo_t KindOfInt##ヽinfo = { \ .size=sizeof(c_type), \ .align=__alignof__(c_type), \ .metamethods={ \ - .compare=KindOfInt##$compare, \ - .as_text=KindOfInt##$as_text, \ - .serialize=KindOfInt##$serialize, \ - .deserialize=KindOfInt##$deserialize, \ + .compare=KindOfInt##ヽcompare, \ + .as_text=KindOfInt##ヽas_text, \ + .serialize=KindOfInt##ヽserialize, \ + .deserialize=KindOfInt##ヽdeserialize, \ }, \ }; diff --git a/src/stdlib/integers.h b/src/stdlib/integers.h index 50ca485f..25ccecb3 100644 --- a/src/stdlib/integers.h +++ b/src/stdlib/integers.h @@ -23,46 +23,46 @@ c_type value; \ bool is_none:1; \ } Optional ## type_name ## _t; \ - Text_t type_name ## $as_text(const void *i, bool colorize, const TypeInfo_t *type); \ - PUREFUNC int32_t type_name ## $compare(const void *x, const void *y, const TypeInfo_t *type); \ - PUREFUNC bool type_name ## $equal(const void *x, const void *y, const TypeInfo_t *type); \ - Text_t type_name ## $hex(c_type i, Int_t digits, bool uppercase, bool prefix); \ - Text_t type_name ## $octal(c_type i, Int_t digits, bool prefix); \ - List_t type_name ## $bits(c_type x); \ - bool type_name ## $get_bit(c_type x, Int_t bit_index); \ - Closure_t type_name ## $to(c_type first, c_type last, Optional ## type_name ## _t step); \ - Closure_t type_name ## $onward(c_type first, c_type step); \ - PUREFUNC Optional ## type_name ## _t type_name ## $parse(Text_t text, Text_t *remainder); \ - CONSTFUNC bool type_name ## $is_between(const c_type x, const c_type low, const c_type high); \ - CONSTFUNC c_type type_name ## $clamped(c_type x, c_type min, c_type max); \ - MACROLIKE CONSTFUNC c_type type_name ## $from_byte(Byte_t b) { return (c_type)b; } \ - MACROLIKE CONSTFUNC c_type type_name ## $from_bool(Bool_t b) { return (c_type)b; } \ - CONSTFUNC c_type type_name ## $gcd(c_type x, c_type y); \ - extern const c_type type_name ## $min, type_name##$max; \ - extern const TypeInfo_t type_name ## $info; \ - MACROLIKE c_type type_name ## $divided_by(c_type D, c_type d) { \ + Text_t type_name ## ヽas_text(const void *i, bool colorize, const TypeInfo_t *type); \ + PUREFUNC int32_t type_name ## ヽcompare(const void *x, const void *y, const TypeInfo_t *type); \ + PUREFUNC bool type_name ## ヽequal(const void *x, const void *y, const TypeInfo_t *type); \ + Text_t type_name ## ヽhex(c_type i, Int_t digits, bool uppercase, bool prefix); \ + Text_t type_name ## ヽoctal(c_type i, Int_t digits, bool prefix); \ + List_t type_name ## ヽbits(c_type x); \ + bool type_name ## ヽget_bit(c_type x, Int_t bit_index); \ + Closure_t type_name ## ヽto(c_type first, c_type last, Optional ## type_name ## _t step); \ + Closure_t type_name ## ヽonward(c_type first, c_type step); \ + PUREFUNC Optional ## type_name ## _t type_name ## ヽparse(Text_t text, Text_t *remainder); \ + CONSTFUNC bool type_name ## ヽis_between(const c_type x, const c_type low, const c_type high); \ + CONSTFUNC c_type type_name ## ヽclamped(c_type x, c_type min, c_type max); \ + MACROLIKE CONSTFUNC c_type type_name ## ヽfrom_byte(Byte_t b) { return (c_type)b; } \ + MACROLIKE CONSTFUNC c_type type_name ## ヽfrom_bool(Bool_t b) { return (c_type)b; } \ + CONSTFUNC c_type type_name ## ヽgcd(c_type x, c_type y); \ + extern const c_type type_name ## ヽmin, type_name##ヽmax; \ + extern const TypeInfo_t type_name ## ヽinfo; \ + MACROLIKE c_type type_name ## ヽdivided_by(c_type D, c_type d) { \ c_type q = D/d, r = D%d; \ q -= (r < 0) * (2*(d > 0) - 1); \ return q; \ } \ - MACROLIKE c_type type_name ## $modulo(c_type D, c_type d) { \ + MACROLIKE c_type type_name ## ヽmodulo(c_type D, c_type d) { \ c_type r = D%d; \ r -= (r < 0) * (2*(d < 0) - 1) * d; \ return r; \ } \ - MACROLIKE c_type type_name ## $modulo1(c_type D, c_type d) { \ - return type_name ## $modulo(D-1, d) + 1; \ + MACROLIKE c_type type_name ## ヽmodulo1(c_type D, c_type d) { \ + return type_name ## ヽmodulo(D-1, d) + 1; \ } \ - MACROLIKE PUREFUNC c_type type_name ## $wrapping_plus(c_type x, c_type y) { \ + MACROLIKE PUREFUNC c_type type_name ## ヽwrapping_plus(c_type x, c_type y) { \ return (c_type)((u##c_type)x + (u##c_type)y); \ } \ - MACROLIKE PUREFUNC c_type type_name ## $wrapping_minus(c_type x, c_type y) { \ + MACROLIKE PUREFUNC c_type type_name ## ヽwrapping_minus(c_type x, c_type y) { \ return (c_type)((u##c_type)x + (u##c_type)y); \ } \ - MACROLIKE PUREFUNC c_type type_name ## $unsigned_left_shifted(c_type x, c_type y) { \ + MACROLIKE PUREFUNC c_type type_name ## ヽunsigned_left_shifted(c_type x, c_type y) { \ return (c_type)((u##c_type)x << y); \ } \ - MACROLIKE PUREFUNC c_type type_name ## $unsigned_right_shifted(c_type x, c_type y) { \ + MACROLIKE PUREFUNC c_type type_name ## ヽunsigned_right_shifted(c_type x, c_type y) { \ return (c_type)((u##c_type)x >> y); \ } @@ -77,41 +77,41 @@ DEFINE_INT_TYPE(int8_t, Int8) #define NONE_INT16 ((OptionalInt16_t){.is_none=true}) #define NONE_INT8 ((OptionalInt8_t){.is_none=true}) -#define Int64$abs(...) I64(labs(__VA_ARGS__)) -#define Int32$abs(...) I32(abs(__VA_ARGS__)) -#define Int16$abs(...) I16(abs(__VA_ARGS__)) -#define Int8$abs(...) I8(abs(__VA_ARGS__)) - -void Int64$serialize(const void *obj, FILE *out, Table_t*, const TypeInfo_t*); -void Int64$deserialize(FILE *in, void *outval, List_t*, const TypeInfo_t*); -void Int32$serialize(const void *obj, FILE *out, Table_t*, const TypeInfo_t*); -void Int32$deserialize(FILE *in, void *outval, List_t*, const TypeInfo_t*); - -Text_t Int$as_text(const void *i, bool colorize, const TypeInfo_t *type); -Text_t Int$value_as_text(Int_t i); -PUREFUNC uint64_t Int$hash(const void *x, const TypeInfo_t *type); -PUREFUNC int32_t Int$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC int32_t Int$compare_value(const Int_t x, const Int_t y); -CONSTFUNC bool Int$is_between(const Int_t x, const Int_t low, const Int_t high); -CONSTFUNC Int_t Int$clamped(Int_t x, Int_t low, Int_t high); -PUREFUNC bool Int$equal(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Int$equal_value(const Int_t x, const Int_t y); -Text_t Int$hex(Int_t i, Int_t digits, bool uppercase, bool prefix); -Text_t Int$octal(Int_t i, Int_t digits, bool prefix); -PUREFUNC Closure_t Int$to(Int_t first, Int_t last, OptionalInt_t step); -PUREFUNC Closure_t Int$onward(Int_t first, Int_t step); -OptionalInt_t Int$from_str(const char *str); -OptionalInt_t Int$parse(Text_t text, Text_t *remainder); -Int_t Int$abs(Int_t x); -Int_t Int$power(Int_t base, Int_t exponent); -Int_t Int$gcd(Int_t x, Int_t y); -OptionalInt_t Int$sqrt(Int_t i); -bool Int$get_bit(Int_t x, Int_t bit_index); +#define Int64ヽabs(...) I64(labs(__VA_ARGS__)) +#define Int32ヽabs(...) I32(abs(__VA_ARGS__)) +#define Int16ヽabs(...) I16(abs(__VA_ARGS__)) +#define Int8ヽabs(...) I8(abs(__VA_ARGS__)) + +void Int64ヽserialize(const void *obj, FILE *out, Table_t*, const TypeInfo_t*); +void Int64ヽdeserialize(FILE *in, void *outval, List_t*, const TypeInfo_t*); +void Int32ヽserialize(const void *obj, FILE *out, Table_t*, const TypeInfo_t*); +void Int32ヽdeserialize(FILE *in, void *outval, List_t*, const TypeInfo_t*); + +Text_t Intヽas_text(const void *i, bool colorize, const TypeInfo_t *type); +Text_t Intヽvalue_as_text(Int_t i); +PUREFUNC uint64_t Intヽhash(const void *x, const TypeInfo_t *type); +PUREFUNC int32_t Intヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC int32_t Intヽcompare_value(const Int_t x, const Int_t y); +CONSTFUNC bool Intヽis_between(const Int_t x, const Int_t low, const Int_t high); +CONSTFUNC Int_t Intヽclamped(Int_t x, Int_t low, Int_t high); +PUREFUNC bool Intヽequal(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Intヽequal_value(const Int_t x, const Int_t y); +Text_t Intヽhex(Int_t i, Int_t digits, bool uppercase, bool prefix); +Text_t Intヽoctal(Int_t i, Int_t digits, bool prefix); +PUREFUNC Closure_t Intヽto(Int_t first, Int_t last, OptionalInt_t step); +PUREFUNC Closure_t Intヽonward(Int_t first, Int_t step); +OptionalInt_t Intヽfrom_str(const char *str); +OptionalInt_t Intヽparse(Text_t text, Text_t *remainder); +Int_t Intヽabs(Int_t x); +Int_t Intヽpower(Int_t base, Int_t exponent); +Int_t Intヽgcd(Int_t x, Int_t y); +OptionalInt_t Intヽsqrt(Int_t i); +bool Intヽget_bit(Int_t x, Int_t bit_index); #define BIGGEST_SMALL_INT 0x3fffffff #define SMALLEST_SMALL_INT -0x40000000 -#define Int$from_mpz(mpz) (\ +#define Intヽfrom_mpz(mpz) (\ mpz_cmpabs_ui(mpz, BIGGEST_SMALL_INT) <= 0 ? ( \ (Int_t){.small=(mpz_get_si(mpz)<<2L)|1L} \ ) : ( \ @@ -124,61 +124,61 @@ bool Int$get_bit(Int_t x, Int_t bit_index); } while (0) #define I_small(i) ((Int_t){.small=(int64_t)((uint64_t)(i)<<2L)|1L}) -#define I(i) _Generic(i, int8_t: I_small(i), int16_t: I_small(i), default: Int$from_int64(i)) +#define I(i) _Generic(i, int8_t: I_small(i), int16_t: I_small(i), default: Intヽfrom_int64(i)) #define I_is_zero(i) ((i).small == 1L) -Int_t Int$slow_plus(Int_t x, Int_t y); -Int_t Int$slow_minus(Int_t x, Int_t y); -Int_t Int$slow_times(Int_t x, Int_t y); -Int_t Int$slow_divided_by(Int_t x, Int_t y); -Int_t Int$slow_modulo(Int_t x, Int_t y); -Int_t Int$slow_modulo1(Int_t x, Int_t y); -Int_t Int$slow_left_shifted(Int_t x, Int_t y); -Int_t Int$slow_right_shifted(Int_t x, Int_t y); -Int_t Int$slow_bit_and(Int_t x, Int_t y); -Int_t Int$slow_bit_or(Int_t x, Int_t y); -Int_t Int$slow_bit_xor(Int_t x, Int_t y); -Int_t Int$slow_negative(Int_t x); -Int_t Int$slow_negated(Int_t x); -bool Int$is_prime(Int_t x, Int_t reps); -Int_t Int$next_prime(Int_t x); +Int_t Intヽslow_plus(Int_t x, Int_t y); +Int_t Intヽslow_minus(Int_t x, Int_t y); +Int_t Intヽslow_times(Int_t x, Int_t y); +Int_t Intヽslow_divided_by(Int_t x, Int_t y); +Int_t Intヽslow_modulo(Int_t x, Int_t y); +Int_t Intヽslow_modulo1(Int_t x, Int_t y); +Int_t Intヽslow_left_shifted(Int_t x, Int_t y); +Int_t Intヽslow_right_shifted(Int_t x, Int_t y); +Int_t Intヽslow_bit_and(Int_t x, Int_t y); +Int_t Intヽslow_bit_or(Int_t x, Int_t y); +Int_t Intヽslow_bit_xor(Int_t x, Int_t y); +Int_t Intヽslow_negative(Int_t x); +Int_t Intヽslow_negated(Int_t x); +bool Intヽis_prime(Int_t x, Int_t reps); +Int_t Intヽnext_prime(Int_t x); #if __GNU_MP_VERSION >= 6 #if __GNU_MP_VERSION_MINOR >= 3 -OptionalInt_t Int$prev_prime(Int_t x); +OptionalInt_t Intヽprev_prime(Int_t x); #endif #endif -Int_t Int$choose(Int_t n, Int_t k); -Int_t Int$factorial(Int_t n); +Int_t Intヽchoose(Int_t n, Int_t k); +Int_t Intヽfactorial(Int_t n); -extern const TypeInfo_t Int$info; +extern const TypeInfo_t Intヽinfo; // Fast-path inline versions for the common case where integer arithmetic is // between two small ints. -MACROLIKE Int_t Int$plus(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽplus(Int_t x, Int_t y) { const int64_t z = (int64_t)((uint64_t)x.small + (uint64_t)y.small); if likely ((z|2L) == (int32_t)z) return (Int_t){.small=(z-1L)}; - return Int$slow_plus(x, y); + return Intヽslow_plus(x, y); } -MACROLIKE Int_t Int$minus(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽminus(Int_t x, Int_t y) { const int64_t z = (int64_t)(((uint64_t)x.small ^ 3L) - (uint64_t)y.small); if likely ((z & ~2L) == (int32_t)z) return (Int_t){.small=z}; - return Int$slow_minus(x, y); + return Intヽslow_minus(x, y); } -MACROLIKE Int_t Int$times(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽtimes(Int_t x, Int_t y) { if likely ((x.small & y.small) & 1L) { const int64_t z = (x.small>>1L) * (y.small>>1L); if likely (z == (int32_t)z) return (Int_t){.small=z+1L}; } - return Int$slow_times(x, y); + return Intヽslow_times(x, y); } -MACROLIKE Int_t Int$divided_by(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽdivided_by(Int_t x, Int_t y) { if likely (x.small & y.small & 1L) { // Euclidean division, see: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf const int64_t D = (x.small>>2L); @@ -188,10 +188,10 @@ MACROLIKE Int_t Int$divided_by(Int_t x, Int_t y) { if likely (q == (int32_t)q) return (Int_t){.small=(q<<2L)|1L}; } - return Int$slow_divided_by(x, y); + return Intヽslow_divided_by(x, y); } -MACROLIKE Int_t Int$modulo(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽmodulo(Int_t x, Int_t y) { if likely (x.small & y.small & 1L) { // Euclidean modulus, see: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf const int64_t D = (x.small>>2L); @@ -200,10 +200,10 @@ MACROLIKE Int_t Int$modulo(Int_t x, Int_t y) { r -= (r < 0L) * (2L*(d < 0L) - 1L) * d; return (Int_t){.small=(r<<2L)|1L}; } - return Int$slow_modulo(x, y); + return Intヽslow_modulo(x, y); } -MACROLIKE Int_t Int$modulo1(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽmodulo1(Int_t x, Int_t y) { if likely (x.small & y.small & 1L) { // Euclidean modulus, see: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf const int64_t D = (x.small>>2L)-1L; @@ -212,62 +212,62 @@ MACROLIKE Int_t Int$modulo1(Int_t x, Int_t y) { r -= (r < 0L) * (2L*(d < 0L) - 1L) * d; return (Int_t){.small=((r+1L)<<2L)|1L}; } - return Int$slow_modulo1(x, y); + return Intヽslow_modulo1(x, y); } -MACROLIKE Int_t Int$left_shifted(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽleft_shifted(Int_t x, Int_t y) { if likely (x.small & y.small & 1L) { const int64_t z = ((x.small>>2L) << (y.small>>2L))<<2L; if likely (z == (int32_t)z) return (Int_t){.small=z+1L}; } - return Int$slow_left_shifted(x, y); + return Intヽslow_left_shifted(x, y); } -MACROLIKE Int_t Int$right_shifted(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽright_shifted(Int_t x, Int_t y) { if likely (x.small & y.small & 1L) { const int64_t z = ((x.small>>2L) >> (y.small>>2L))<<2L; if likely (z == (int32_t)z) return (Int_t){.small=z+1L}; } - return Int$slow_right_shifted(x, y); + return Intヽslow_right_shifted(x, y); } -MACROLIKE Int_t Int$bit_and(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽbit_and(Int_t x, Int_t y) { const int64_t z = x.small & y.small; if likely (z & 1L) return (Int_t){.small=z}; - return Int$slow_bit_and(x, y); + return Intヽslow_bit_and(x, y); } -MACROLIKE Int_t Int$bit_or(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽbit_or(Int_t x, Int_t y) { if likely (x.small & y.small & 1L) return (Int_t){.small=(x.small | y.small)}; - return Int$slow_bit_or(x, y); + return Intヽslow_bit_or(x, y); } -MACROLIKE Int_t Int$bit_xor(Int_t x, Int_t y) { +MACROLIKE Int_t Intヽbit_xor(Int_t x, Int_t y) { if likely (x.small & y.small & 1L) return (Int_t){.small=(x.small ^ y.small) | 1L}; - return Int$slow_bit_xor(x, y); + return Intヽslow_bit_xor(x, y); } -MACROLIKE Int_t Int$negated(Int_t x) { +MACROLIKE Int_t Intヽnegated(Int_t x) { if likely (x.small & 1L) return (Int_t){.small=(~x.small) ^ 3L}; - return Int$slow_negated(x); + return Intヽslow_negated(x); } -MACROLIKE Int_t Int$negative(Int_t x) { +MACROLIKE Int_t Intヽnegative(Int_t x) { if likely (x.small & 1L) return (Int_t){.small=((-((x.small)>>2L))<<2L) | 1L}; - return Int$slow_negative(x); + return Intヽslow_negative(x); } -MACROLIKE PUREFUNC bool Int$is_negative(Int_t x) { +MACROLIKE PUREFUNC bool Intヽis_negative(Int_t x) { if likely (x.small & 1L) return x.small < 0L; - return Int$compare_value(x, I_small(0)) < 0L; + return Intヽcompare_value(x, I_small(0)) < 0L; } // Constructors/conversion functions: @@ -277,147 +277,147 @@ MACROLIKE PUREFUNC bool Int$is_negative(Int_t x) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" #endif -MACROLIKE PUREFUNC Int_t Int$from_num(double n, bool truncate) { +MACROLIKE PUREFUNC Int_t Intヽfrom_num(double n, bool truncate) { mpz_t result; mpz_init_set_d(result, n); if (!truncate && unlikely(mpz_get_d(result) != n)) fail("Could not convert to an integer without truncation: ", n); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -MACROLIKE PUREFUNC Int_t Int$from_num32(float n, bool truncate) { return Int$from_num((double)n, truncate); } -MACROLIKE Int_t Int$from_int64(int64_t i) { +MACROLIKE PUREFUNC Int_t Intヽfrom_num32(float n, bool truncate) { return Intヽfrom_num((double)n, truncate); } +MACROLIKE Int_t Intヽfrom_int64(int64_t i) { if likely (i >= SMALLEST_SMALL_INT && i <= BIGGEST_SMALL_INT) return (Int_t){.small=(i<<2L)|1L}; mpz_t result; mpz_init_set_si(result, i); - return Int$from_mpz(result); + return Intヽfrom_mpz(result); } -MACROLIKE CONSTFUNC Int_t Int$from_int32(Int32_t i) { return Int$from_int64((Int32_t)i); } -MACROLIKE CONSTFUNC Int_t Int$from_int16(Int16_t i) { return I_small(i); } -MACROLIKE CONSTFUNC Int_t Int$from_int8(Int8_t i) { return I_small(i); } -MACROLIKE CONSTFUNC Int_t Int$from_byte(Byte_t b) { return I_small(b); } -MACROLIKE CONSTFUNC Int_t Int$from_bool(Bool_t b) { return I_small(b); } +MACROLIKE CONSTFUNC Int_t Intヽfrom_int32(Int32_t i) { return Intヽfrom_int64((Int32_t)i); } +MACROLIKE CONSTFUNC Int_t Intヽfrom_int16(Int16_t i) { return I_small(i); } +MACROLIKE CONSTFUNC Int_t Intヽfrom_int8(Int8_t i) { return I_small(i); } +MACROLIKE CONSTFUNC Int_t Intヽfrom_byte(Byte_t b) { return I_small(b); } +MACROLIKE CONSTFUNC Int_t Intヽfrom_bool(Bool_t b) { return I_small(b); } // Int64 constructors -MACROLIKE PUREFUNC Int64_t Int64$from_num(Num_t n, bool truncate) { +MACROLIKE PUREFUNC Int64_t Int64ヽfrom_num(Num_t n, bool truncate) { int64_t i64 = (int64_t)n; if (!truncate && unlikely((Num_t)i64 != n)) fail("Could not convert Num to Int64 without truncation: ", n); return i64; } -MACROLIKE PUREFUNC Int64_t Int64$from_num32(Num32_t n, bool truncate) { +MACROLIKE PUREFUNC Int64_t Int64ヽfrom_num32(Num32_t n, bool truncate) { int64_t i64 = (int64_t)n; if (!truncate && unlikely((Num32_t)i64 != n)) fail("Could not convert Num32 to Int64 without truncation: ", n); return i64; } -MACROLIKE PUREFUNC Int64_t Int64$from_int(Int_t i, bool truncate) { +MACROLIKE PUREFUNC Int64_t Int64ヽfrom_int(Int_t i, bool truncate) { if likely (i.small & 1L) return (int64_t)(i.small >> 2L); if (!truncate && unlikely(!mpz_fits_slong_p(*i.big))) fail("Integer is too big to fit in a 64-bit integer: ", i); return mpz_get_si(*i.big); } -MACROLIKE CONSTFUNC Int64_t Int64$from_int32(Int32_t i) { return (Int64_t)i; } -MACROLIKE CONSTFUNC Int64_t Int64$from_int16(Int16_t i) { return (Int64_t)i; } -MACROLIKE CONSTFUNC Int64_t Int64$from_int8(Int8_t i) { return (Int64_t)i; } +MACROLIKE CONSTFUNC Int64_t Int64ヽfrom_int32(Int32_t i) { return (Int64_t)i; } +MACROLIKE CONSTFUNC Int64_t Int64ヽfrom_int16(Int16_t i) { return (Int64_t)i; } +MACROLIKE CONSTFUNC Int64_t Int64ヽfrom_int8(Int8_t i) { return (Int64_t)i; } // Int32 constructors -MACROLIKE PUREFUNC Int32_t Int32$from_num(Num_t n, bool truncate) { +MACROLIKE PUREFUNC Int32_t Int32ヽfrom_num(Num_t n, bool truncate) { int32_t i32 = (int32_t)n; if (!truncate && unlikely((Num_t)i32 != n)) fail("Could not convert Num to Int32 without truncation: ", n); return i32; } -MACROLIKE PUREFUNC Int32_t Int32$from_num32(Num32_t n, bool truncate) { +MACROLIKE PUREFUNC Int32_t Int32ヽfrom_num32(Num32_t n, bool truncate) { int32_t i32 = (int32_t)n; if (!truncate && unlikely((Num32_t)i32 != n)) fail("Could not convert Num32 to Int32 without truncation: ", n); return i32; } -MACROLIKE PUREFUNC Int32_t Int32$from_int(Int_t i, bool truncate) { - int64_t i64 = Int64$from_int(i, truncate); +MACROLIKE PUREFUNC Int32_t Int32ヽfrom_int(Int_t i, bool truncate) { + int64_t i64 = Int64ヽfrom_int(i, truncate); int32_t i32 = (int32_t)i64; if (!truncate && unlikely((int64_t)i32 != i64)) fail("Integer is too big to fit in a 32-bit integer: ", i); return i32; } -MACROLIKE PUREFUNC Int32_t Int32$from_int64(Int64_t i64, bool truncate) { +MACROLIKE PUREFUNC Int32_t Int32ヽfrom_int64(Int64_t i64, bool truncate) { int32_t i32 = (int32_t)i64; if (!truncate && unlikely((int64_t)i32 != i64)) fail("Integer is too big to fit in a 32-bit integer: ", i64); return i32; } -MACROLIKE CONSTFUNC Int32_t Int32$from_int16(Int16_t i) { return (Int32_t)i; } -MACROLIKE CONSTFUNC Int32_t Int32$from_int8(Int8_t i) { return (Int32_t)i; } +MACROLIKE CONSTFUNC Int32_t Int32ヽfrom_int16(Int16_t i) { return (Int32_t)i; } +MACROLIKE CONSTFUNC Int32_t Int32ヽfrom_int8(Int8_t i) { return (Int32_t)i; } // Int16 constructors -MACROLIKE PUREFUNC Int16_t Int16$from_num(Num_t n, bool truncate) { +MACROLIKE PUREFUNC Int16_t Int16ヽfrom_num(Num_t n, bool truncate) { int16_t i16 = (int16_t)n; if (!truncate && unlikely((Num_t)i16 != n)) fail("Could not convert Num to Int16 without truncation: ", n); return i16; } -MACROLIKE PUREFUNC Int16_t Int16$from_num32(Num32_t n, bool truncate) { +MACROLIKE PUREFUNC Int16_t Int16ヽfrom_num32(Num32_t n, bool truncate) { int16_t i16 = (int16_t)n; if (!truncate && unlikely((Num32_t)i16 != n)) fail("Could not convert Num32 to Int16 without truncation: ", (double)n); return i16; } -MACROLIKE PUREFUNC Int16_t Int16$from_int(Int_t i, bool truncate) { - int64_t i64 = Int64$from_int(i, truncate); +MACROLIKE PUREFUNC Int16_t Int16ヽfrom_int(Int_t i, bool truncate) { + int64_t i64 = Int64ヽfrom_int(i, truncate); int16_t i16 = (int16_t)i64; if (!truncate && unlikely((int64_t)i16 != i64)) fail("Integer is too big to fit in a 16-bit integer!"); return i16; } -MACROLIKE PUREFUNC Int16_t Int16$from_int64(Int64_t i64, bool truncate) { +MACROLIKE PUREFUNC Int16_t Int16ヽfrom_int64(Int64_t i64, bool truncate) { int16_t i16 = (int16_t)i64; if (!truncate && unlikely((int64_t)i16 != i64)) fail("Integer is too big to fit in a 16-bit integer: ", i64); return i16; } -MACROLIKE PUREFUNC Int16_t Int16$from_int32(Int32_t i32, bool truncate) { +MACROLIKE PUREFUNC Int16_t Int16ヽfrom_int32(Int32_t i32, bool truncate) { int16_t i16 = (int16_t)i32; if (!truncate && unlikely((int32_t)i16 != i32)) fail("Integer is too big to fit in a 16-bit integer: ", i32); return i16; } -MACROLIKE CONSTFUNC Int16_t Int16$from_int8(Int8_t i) { return (Int16_t)i; } +MACROLIKE CONSTFUNC Int16_t Int16ヽfrom_int8(Int8_t i) { return (Int16_t)i; } // Int8 constructors -MACROLIKE PUREFUNC Int8_t Int8$from_num(Num_t n, bool truncate) { +MACROLIKE PUREFUNC Int8_t Int8ヽfrom_num(Num_t n, bool truncate) { int8_t i8 = (int8_t)n; if (!truncate && unlikely((Num_t)i8 != n)) fail("Could not convert Num to Int8 without truncation: ", n); return i8; } -MACROLIKE PUREFUNC Int8_t Int8$from_num32(Num32_t n, bool truncate) { +MACROLIKE PUREFUNC Int8_t Int8ヽfrom_num32(Num32_t n, bool truncate) { int8_t i8 = (int8_t)n; if (!truncate && unlikely((Num32_t)i8 != n)) fail("Could not convert Num32 to Int8 without truncation: ", n); return i8; } -MACROLIKE PUREFUNC Int8_t Int8$from_int(Int_t i, bool truncate) { - int64_t i64 = Int64$from_int(i, truncate); +MACROLIKE PUREFUNC Int8_t Int8ヽfrom_int(Int_t i, bool truncate) { + int64_t i64 = Int64ヽfrom_int(i, truncate); int8_t i8 = (int8_t)i64; if (!truncate && unlikely((int64_t)i8 != i64)) fail("Integer is too big to fit in an 8-bit integer!"); return i8; } -MACROLIKE PUREFUNC Int8_t Int8$from_int64(Int64_t i64, bool truncate) { +MACROLIKE PUREFUNC Int8_t Int8ヽfrom_int64(Int64_t i64, bool truncate) { int8_t i8 = (int8_t)i64; if (!truncate && unlikely((int64_t)i8 != i64)) fail("Integer is too big to fit in a 8-bit integer: ", i64); return i8; } -MACROLIKE PUREFUNC Int8_t Int8$from_int32(Int32_t i32, bool truncate) { +MACROLIKE PUREFUNC Int8_t Int8ヽfrom_int32(Int32_t i32, bool truncate) { int8_t i8 = (int8_t)i32; if (!truncate && unlikely((int32_t)i8 != i32)) fail("Integer is too big to fit in a 8-bit integer: ", i32); return i8; } -MACROLIKE PUREFUNC Int8_t Int8$from_int16(Int16_t i16, bool truncate) { +MACROLIKE PUREFUNC Int8_t Int8ヽfrom_int16(Int16_t i16, bool truncate) { int8_t i8 = (int8_t)i16; if (!truncate && unlikely((int16_t)i8 != i16)) fail("Integer is too big to fit in a 8-bit integer: ", i16); diff --git a/src/stdlib/lists.c b/src/stdlib/lists.c index 31e25f15..8ea29081 100644 --- a/src/stdlib/lists.c +++ b/src/stdlib/lists.c @@ -28,7 +28,7 @@ PUREFUNC static INLINE int64_t get_padded_item_size(const TypeInfo_t *info) // Replace the list's .data pointer with a new pointer to a copy of the // data that is compacted and has a stride of exactly `padded_item_size` -public void List$compact(List_t *list, int64_t padded_item_size) +public void Listヽcompact(List_t *list, int64_t padded_item_size) { void *copy = NULL; if (list->length > 0) { @@ -49,9 +49,9 @@ public void List$compact(List_t *list, int64_t padded_item_size) }; } -public void List$insert(List_t *list, const void *item, Int_t int_index, int64_t padded_item_size) +public void Listヽinsert(List_t *list, const void *item, Int_t int_index, int64_t padded_item_size) { - int64_t index = Int64$from_int(int_index, false); + int64_t index = Int64ヽfrom_int(int_index, false); if (index <= 0) index = list->length + index + 1; if (index < 1) index = 1; @@ -92,9 +92,9 @@ public void List$insert(List_t *list, const void *item, Int_t int_index, int64_t memcpy((void*)list->data + (index-1)*padded_item_size, item, (size_t)padded_item_size); } -public void List$insert_all(List_t *list, List_t to_insert, Int_t int_index, int64_t padded_item_size) +public void Listヽinsert_all(List_t *list, List_t to_insert, Int_t int_index, int64_t padded_item_size) { - int64_t index = Int64$from_int(int_index, false); + int64_t index = Int64ヽfrom_int(int_index, false); if (to_insert.length == 0) return; @@ -174,12 +174,12 @@ public void List$insert_all(List_t *list, List_t to_insert, Int_t int_index, int } } -public void List$remove_at(List_t *list, Int_t int_index, Int_t int_count, int64_t padded_item_size) +public void Listヽremove_at(List_t *list, Int_t int_index, Int_t int_count, int64_t padded_item_size) { - int64_t index = Int64$from_int(int_index, false); + int64_t index = Int64ヽfrom_int(int_index, false); if (index < 1) index = list->length + index + 1; - int64_t count = Int64$from_int(int_count, false); + int64_t count = Int64ヽfrom_int(int_count, false); if (index < 1 || index > (int64_t)list->length || count < 1) return; if (count > list->length - index + 1) @@ -210,7 +210,7 @@ public void List$remove_at(List_t *list, Int_t int_index, Int_t int_count, int64 if (list->length == 0) list->data = NULL; } -public void List$remove_item(List_t *list, void *item, Int_t max_removals, const TypeInfo_t *type) +public void Listヽremove_item(List_t *list, void *item, Int_t max_removals, const TypeInfo_t *type) { int64_t padded_item_size = get_padded_item_size(type); const Int_t ZERO = (Int_t){.small=(0<<2)|1}; @@ -221,15 +221,15 @@ public void List$remove_item(List_t *list, void *item, Int_t max_removals, const break; if (generic_equal(item, list->data + i*list->stride, item_type)) { - List$remove_at(list, I(i+1), ONE, padded_item_size); - max_removals = Int$minus(max_removals, ONE); + Listヽremove_at(list, I(i+1), ONE, padded_item_size); + max_removals = Intヽminus(max_removals, ONE); } else { i++; } } } -public OptionalInt_t List$find(List_t list, void *item, const TypeInfo_t *type) +public OptionalInt_t Listヽfind(List_t list, void *item, const TypeInfo_t *type) { const TypeInfo_t *item_type = type->ListInfo.item; for (int64_t i = 0; i < list.length; i++) { @@ -239,7 +239,7 @@ public OptionalInt_t List$find(List_t list, void *item, const TypeInfo_t *type) return NONE_INT; } -public OptionalInt_t List$first(List_t list, Closure_t predicate) +public OptionalInt_t Listヽfirst(List_t list, Closure_t predicate) { bool (*is_good)(void*, void*) = (void*)predicate.fn; for (int64_t i = 0; i < list.length; i++) { @@ -257,18 +257,18 @@ int _compare_closure(const void *a, const void *b) return ((comparison_t)_sort_comparison.fn)(a, b, _sort_comparison.userdata); } -public void List$sort(List_t *list, Closure_t comparison, int64_t padded_item_size) +public void Listヽsort(List_t *list, Closure_t comparison, int64_t padded_item_size) { if (list->data_refcount != 0 || (int64_t)list->stride != padded_item_size) - List$compact(list, padded_item_size); + Listヽcompact(list, padded_item_size); _sort_comparison = comparison; qsort(list->data, (size_t)list->length, (size_t)padded_item_size, _compare_closure); } -public List_t List$sorted(List_t list, Closure_t comparison, int64_t padded_item_size) +public List_t Listヽsorted(List_t list, Closure_t comparison, int64_t padded_item_size) { - List$compact(&list, padded_item_size); + Listヽcompact(&list, padded_item_size); _sort_comparison = comparison; qsort(list.data, (size_t)list.length, (size_t)padded_item_size, _compare_closure); return list; @@ -303,10 +303,10 @@ static int64_t _default_random_int64(int64_t min, int64_t max, void *userdata) return (int64_t)((uint64_t)min + (r % range)); } -public void List$shuffle(List_t *list, OptionalClosure_t random_int64, int64_t padded_item_size) +public void Listヽshuffle(List_t *list, OptionalClosure_t random_int64, int64_t padded_item_size) { if (list->data_refcount != 0 || (int64_t)list->stride != padded_item_size) - List$compact(list, padded_item_size); + Listヽcompact(list, padded_item_size); typedef int64_t (*rng_fn_t)(int64_t, int64_t, void*); rng_fn_t rng_fn = random_int64.fn ? (rng_fn_t)random_int64.fn : _default_random_int64; @@ -321,14 +321,14 @@ public void List$shuffle(List_t *list, OptionalClosure_t random_int64, int64_t p } } -public List_t List$shuffled(List_t list, Closure_t random_int64, int64_t padded_item_size) +public List_t Listヽshuffled(List_t list, Closure_t random_int64, int64_t padded_item_size) { - List$compact(&list, padded_item_size); - List$shuffle(&list, random_int64, padded_item_size); + Listヽcompact(&list, padded_item_size); + Listヽshuffle(&list, random_int64, padded_item_size); return list; } -public void *List$random(List_t list, OptionalClosure_t random_int64) +public void *Listヽrandom(List_t list, OptionalClosure_t random_int64) { if (list.length == 0) return NULL; // fail("Cannot get a random item from an empty list!"); @@ -341,15 +341,15 @@ public void *List$random(List_t list, OptionalClosure_t random_int64) return list.data + list.stride*index; } -public Table_t List$counts(List_t list, const TypeInfo_t *type) +public Table_t Listヽcounts(List_t list, const TypeInfo_t *type) { Table_t counts = {}; - const TypeInfo_t count_type = *Table$info(type->ListInfo.item, &Int$info); + const TypeInfo_t count_type = *Tableヽinfo(type->ListInfo.item, &Intヽinfo); for (int64_t i = 0; i < list.length; i++) { void *key = list.data + i*list.stride; - int64_t *count = Table$get(counts, key, &count_type); + int64_t *count = Tableヽget(counts, key, &count_type); int64_t val = count ? *count + 1 : 1; - Table$set(&counts, key, &val, &count_type); + Tableヽset(&counts, key, &val, &count_type); } return counts; } @@ -369,9 +369,9 @@ static double _default_random_num(void *userdata) return r.num - 1.0; } -public List_t List$sample(List_t list, Int_t int_n, List_t weights, OptionalClosure_t random_num, int64_t padded_item_size) +public List_t Listヽsample(List_t list, Int_t int_n, List_t weights, OptionalClosure_t random_num, int64_t padded_item_size) { - int64_t n = Int64$from_int(int_n, false); + int64_t n = Int64ヽfrom_int(int_n, false); if (n < 0) fail("Cannot select a negative number of values"); @@ -459,19 +459,19 @@ public List_t List$sample(List_t list, Int_t int_n, List_t weights, OptionalClos return selected; } -public List_t List$from(List_t list, Int_t first) +public List_t Listヽfrom(List_t list, Int_t first) { - return List$slice(list, first, I_small(-1)); + return Listヽslice(list, first, I_small(-1)); } -public List_t List$to(List_t list, Int_t last) +public List_t Listヽto(List_t list, Int_t last) { - return List$slice(list, I_small(1), last); + return Listヽslice(list, I_small(1), last); } -public List_t List$by(List_t list, Int_t int_stride, int64_t padded_item_size) +public List_t Listヽby(List_t list, Int_t int_stride, int64_t padded_item_size) { - int64_t stride = Int64$from_int(int_stride, false); + int64_t stride = Int64ヽfrom_int(int_stride, false); // In the unlikely event that the stride value would be too large to fit in // a 15-bit integer, fall back to creating a copy of the list: if (unlikely(list.stride*stride < LIST_MIN_STRIDE || list.stride*stride > LIST_MAX_STRIDE)) { @@ -503,14 +503,14 @@ public List_t List$by(List_t list, Int_t int_stride, int64_t padded_item_size) }; } -public List_t List$slice(List_t list, Int_t int_first, Int_t int_last) +public List_t Listヽslice(List_t list, Int_t int_first, Int_t int_last) { - int64_t first = Int64$from_int(int_first, false); + int64_t first = Int64ヽfrom_int(int_first, false); if (first < 0) first = list.length + first + 1; - int64_t last = Int64$from_int(int_last, false); + int64_t last = Int64ヽfrom_int(int_last, false); if (last < 0) last = list.length + last + 1; @@ -529,14 +529,14 @@ public List_t List$slice(List_t list, Int_t int_first, Int_t int_last) }; } -public List_t List$reversed(List_t list, int64_t padded_item_size) +public List_t Listヽreversed(List_t list, int64_t padded_item_size) { // Just in case negating the stride gives a value that doesn't fit into a - // 15-bit integer, fall back to List$by()'s more general method of copying + // 15-bit integer, fall back to Listヽby()'s more general method of copying // the list. This should only happen if list.stride is MIN_STRIDE to // begin with (very unlikely). if (unlikely(-list.stride < LIST_MIN_STRIDE || -list.stride > LIST_MAX_STRIDE)) - return List$by(list, I(-1), padded_item_size); + return Listヽby(list, I(-1), padded_item_size); List_t reversed = list; reversed.stride = -list.stride; @@ -544,7 +544,7 @@ public List_t List$reversed(List_t list, int64_t padded_item_size) return reversed; } -public List_t List$concat(List_t x, List_t y, int64_t padded_item_size) +public List_t Listヽconcat(List_t x, List_t y, int64_t padded_item_size) { void *data = x.atomic ? GC_MALLOC_ATOMIC((size_t)(padded_item_size*(x.length + y.length))) : GC_MALLOC((size_t)(padded_item_size*(x.length + y.length))); @@ -571,7 +571,7 @@ public List_t List$concat(List_t x, List_t y, int64_t padded_item_size) }; } -public bool List$has(List_t list, void *item, const TypeInfo_t *type) +public bool Listヽhas(List_t list, void *item, const TypeInfo_t *type) { const TypeInfo_t *item_type = type->ListInfo.item; for (int64_t i = 0; i < list.length; i++) { @@ -581,12 +581,12 @@ public bool List$has(List_t list, void *item, const TypeInfo_t *type) return false; } -public void List$clear(List_t *list) +public void Listヽclear(List_t *list) { *list = (List_t){.data=0, .length=0}; } -public int32_t List$compare(const void *vx, const void *vy, const TypeInfo_t *type) +public int32_t Listヽcompare(const void *vx, const void *vy, const TypeInfo_t *type) { const List_t *x = (List_t*)vx, *y = (List_t*)vy; // Early out for lists with the same data, e.g. two copies of the same list: @@ -617,30 +617,30 @@ public int32_t List$compare(const void *vx, const void *vy, const TypeInfo_t *ty return (x->length > y->length) - (x->length < y->length); } -public bool List$equal(const void *x, const void *y, const TypeInfo_t *type) +public bool Listヽequal(const void *x, const void *y, const TypeInfo_t *type) { - return x == y || (((List_t*)x)->length == ((List_t*)y)->length && List$compare(x, y, type) == 0); + return x == y || (((List_t*)x)->length == ((List_t*)y)->length && Listヽcompare(x, y, type) == 0); } -public Text_t List$as_text(const void *obj, bool colorize, const TypeInfo_t *type) +public Text_t Listヽas_text(const void *obj, bool colorize, const TypeInfo_t *type) { List_t *list = (List_t*)obj; if (!list) - return Text$concat(Text("["), generic_as_text(NULL, false, type->ListInfo.item), Text("]")); + return Textヽconcat(Text("["), generic_as_text(NULL, false, type->ListInfo.item), Text("]")); const TypeInfo_t *item_type = type->ListInfo.item; Text_t text = Text("["); for (int64_t i = 0; i < list->length; i++) { if (i > 0) - text = Text$concat(text, Text(", ")); + text = Textヽconcat(text, Text(", ")); Text_t item_text = generic_as_text(list->data + i*list->stride, colorize, item_type); - text = Text$concat(text, item_text); + text = Textヽconcat(text, item_text); } - text = Text$concat(text, Text("]")); + text = Textヽconcat(text, Text("]")); return text; } -public uint64_t List$hash(const void *obj, const TypeInfo_t *type) +public uint64_t Listヽhash(const void *obj, const TypeInfo_t *type) { const List_t *list = (List_t*)obj; const TypeInfo_t *item = type->ListInfo.item; @@ -706,18 +706,18 @@ static void siftup(List_t *heap, int64_t pos, Closure_t comparison, int64_t padd siftdown(heap, startpos, pos, comparison, padded_item_size); } -public void List$heap_push(List_t *heap, const void *item, Closure_t comparison, int64_t padded_item_size) +public void Listヽheap_push(List_t *heap, const void *item, Closure_t comparison, int64_t padded_item_size) { - List$insert(heap, item, I(0), padded_item_size); + Listヽinsert(heap, item, I(0), padded_item_size); if (heap->length > 1) { if (heap->data_refcount != 0) - List$compact(heap, padded_item_size); + Listヽcompact(heap, padded_item_size); siftdown(heap, 0, heap->length-1, comparison, padded_item_size); } } -public void List$heap_pop(List_t *heap, Closure_t comparison, int64_t padded_item_size) +public void Listヽheap_pop(List_t *heap, Closure_t comparison, int64_t padded_item_size) { if (heap->length == 0) fail("Attempt to pop from an empty list"); @@ -729,17 +729,17 @@ public void List$heap_pop(List_t *heap, Closure_t comparison, int64_t padded_ite --heap->length; } else { if (heap->data_refcount != 0) - List$compact(heap, padded_item_size); + Listヽcompact(heap, padded_item_size); memcpy(heap->data, heap->data + heap->stride*(heap->length-1), (size_t)(padded_item_size)); --heap->length; siftup(heap, 0, comparison, padded_item_size); } } -public void List$heapify(List_t *heap, Closure_t comparison, int64_t padded_item_size) +public void Listヽheapify(List_t *heap, Closure_t comparison, int64_t padded_item_size) { if (heap->data_refcount != 0) - List$compact(heap, padded_item_size); + Listヽcompact(heap, padded_item_size); // It's necessary to bump the refcount because the user's comparison // function could do stuff that modifies the heap's data. @@ -750,7 +750,7 @@ public void List$heapify(List_t *heap, Closure_t comparison, int64_t padded_item LIST_DECREF(*heap); } -public Int_t List$binary_search(List_t list, void *target, Closure_t comparison) +public Int_t Listヽbinary_search(List_t list, void *target, Closure_t comparison) { typedef int32_t (*cmp_fn_t)(void*, void*, void*); int64_t lo = 0, hi = list.length-1; @@ -768,17 +768,17 @@ public Int_t List$binary_search(List_t list, void *target, Closure_t comparison) return I(lo+1); // Return the index where the target would be inserted } -public PUREFUNC bool List$is_none(const void *obj, const TypeInfo_t *info) +public PUREFUNC bool Listヽis_none(const void *obj, const TypeInfo_t *info) { (void)info; return ((List_t*)obj)->length < 0; } -public void List$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) +public void Listヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) { List_t list = *(List_t*)obj; int64_t len = list.length; - Int64$serialize(&len, out, pointers, &Int64$info); + Int64ヽserialize(&len, out, pointers, &Int64ヽinfo); serialize_fn_t item_serialize = type->ListInfo.item->metamethods.serialize; if (item_serialize) { for (int64_t i = 0; i < len; i++) @@ -791,10 +791,10 @@ public void List$serialize(const void *obj, FILE *out, Table_t *pointers, const } } -public void List$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type) +public void Listヽdeserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type) { int64_t len = -1; - Int64$deserialize(in, &len, pointers, &Int64$info); + Int64ヽdeserialize(in, &len, pointers, &Int64ヽinfo); int64_t padded_size = type->ListInfo.item->size; if (type->ListInfo.item->align > 0 && padded_size % type->ListInfo.item->align > 0) padded_size += type->ListInfo.item->align - (padded_size % type->ListInfo.item->align); diff --git a/src/stdlib/lists.h b/src/stdlib/lists.h index a2853e48..95ff8966 100644 --- a/src/stdlib/lists.h +++ b/src/stdlib/lists.h @@ -25,13 +25,13 @@ if (unlikely(off < 0 || off >= list->length)) \ fail_source(__SOURCE_FILE__, start, end, "Invalid list index: ", index, " (list has length ", (int64_t)list->length, ")\n"); \ if (list->data_refcount > 0) \ - List$compact(list, sizeof(item_type)); \ + Listヽcompact(list, sizeof(item_type)); \ (item_type*)(list->data + list->stride * off); }) #define List_lvalue_unchecked(item_type, arr_expr, index_expr) *({ \ List_t *list = arr_expr; int64_t index = index_expr; \ int64_t off = index + (index < 0) * (list->length + 1) - 1; \ if (list->data_refcount > 0) \ - List$compact(list, sizeof(item_type)); \ + Listヽcompact(list, sizeof(item_type)); \ (item_type*)(list->data + list->stride * off); }) #define List_set(item_type, list, index, value, start, end) \ List_lvalue(item_type, arr_expr, index, start, end) = value @@ -59,79 +59,79 @@ #define LIST_DECREF(list) (list).data_refcount -= ((list).data_refcount < LIST_MAX_DATA_REFCOUNT) #define LIST_COPY(list) ({ LIST_INCREF(list); list; }) -#define List$insert_value(list, item_expr, index, padded_item_size) List$insert(list, (__typeof(item_expr)[1]){item_expr}, index, padded_item_size) -void List$insert(List_t *list, const void *item, Int_t index, int64_t padded_item_size); -void List$insert_all(List_t *list, List_t to_insert, Int_t index, int64_t padded_item_size); -void List$remove_at(List_t *list, Int_t index, Int_t count, int64_t padded_item_size); -void List$remove_item(List_t *list, void *item, Int_t max_removals, const TypeInfo_t *type); -#define List$remove_item_value(list, item_expr, max, type) List$remove_item(list, (__typeof(item_expr)[1]){item_expr}, max, type) +#define Listヽinsert_value(list, item_expr, index, padded_item_size) Listヽinsert(list, (__typeof(item_expr)[1]){item_expr}, index, padded_item_size) +void Listヽinsert(List_t *list, const void *item, Int_t index, int64_t padded_item_size); +void Listヽinsert_all(List_t *list, List_t to_insert, Int_t index, int64_t padded_item_size); +void Listヽremove_at(List_t *list, Int_t index, Int_t count, int64_t padded_item_size); +void Listヽremove_item(List_t *list, void *item, Int_t max_removals, const TypeInfo_t *type); +#define Listヽremove_item_value(list, item_expr, max, type) Listヽremove_item(list, (__typeof(item_expr)[1]){item_expr}, max, type) -#define List$pop(arr_expr, index_expr, item_type, nonnone_var, nonnone_expr, none_expr) ({ \ +#define Listヽpop(arr_expr, index_expr, item_type, nonnone_var, nonnone_expr, none_expr) ({ \ List_t *list = arr_expr; \ Int_t index = index_expr; \ - int64_t index64 = Int64$from_int(index, false); \ + int64_t index64 = Int64ヽfrom_int(index, false); \ int64_t off = index64 + (index64 < 0) * (list->length + 1) - 1; \ (off >= 0 && off < list->length) ? ({ \ item_type nonnone_var = *(item_type*)(list->data + off*list->stride); \ - List$remove_at(list, index, I_small(1), sizeof(item_type)); \ + Listヽremove_at(list, index, I_small(1), sizeof(item_type)); \ nonnone_expr; \ }) : none_expr; }) -OptionalInt_t List$find(List_t list, void *item, const TypeInfo_t *type); -#define List$find_value(list, item_expr, type) ({ __typeof(item_expr) item = item_expr; List$find(list, &item, type); }) -OptionalInt_t List$first(List_t list, Closure_t predicate); -void List$sort(List_t *list, Closure_t comparison, int64_t padded_item_size); -List_t List$sorted(List_t list, Closure_t comparison, int64_t padded_item_size); -void List$shuffle(List_t *list, OptionalClosure_t random_int64, int64_t padded_item_size); -List_t List$shuffled(List_t list, OptionalClosure_t random_int64, int64_t padded_item_size); -void *List$random(List_t list, OptionalClosure_t random_int64); -#define List$random_value(list, random_int64, t) ({ List_t _arr = list; if (_arr.length == 0) fail("Cannot get a random value from an empty list!"); *(t*)List$random(_arr, random_int64); }) -List_t List$sample(List_t list, Int_t n, List_t weights, Closure_t random_num, int64_t padded_item_size); -Table_t List$counts(List_t list, const TypeInfo_t *type); -void List$clear(List_t *list); -void List$compact(List_t *list, int64_t padded_item_size); -PUREFUNC bool List$has(List_t list, void *item, const TypeInfo_t *type); -#define List$has_value(list, item_expr, type) ({ __typeof(item_expr) item = item_expr; List$has(list, &item, type); }) -PUREFUNC List_t List$from(List_t list, Int_t first); -PUREFUNC List_t List$to(List_t list, Int_t last); -PUREFUNC List_t List$by(List_t list, Int_t stride, int64_t padded_item_size); -PUREFUNC List_t List$slice(List_t list, Int_t int_first, Int_t int_last); -PUREFUNC List_t List$reversed(List_t list, int64_t padded_item_size); -List_t List$concat(List_t x, List_t y, int64_t padded_item_size); -PUREFUNC uint64_t List$hash(const void *list, const TypeInfo_t *type); -PUREFUNC int32_t List$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool List$equal(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool List$is_none(const void *obj, const TypeInfo_t*); -Text_t List$as_text(const void *list, bool colorize, const TypeInfo_t *type); -void List$heapify(List_t *heap, Closure_t comparison, int64_t padded_item_size); -void List$heap_push(List_t *heap, const void *item, Closure_t comparison, int64_t padded_item_size); -#define List$heap_push_value(heap, _value, comparison, padded_item_size) ({ __typeof(_value) value = _value; List$heap_push(heap, &value, comparison, padded_item_size); }) -void List$heap_pop(List_t *heap, Closure_t comparison, int64_t padded_item_size); -#define List$heap_pop_value(heap, comparison, type, nonnone_var, nonnone_expr, none_expr) \ +OptionalInt_t Listヽfind(List_t list, void *item, const TypeInfo_t *type); +#define Listヽfind_value(list, item_expr, type) ({ __typeof(item_expr) item = item_expr; Listヽfind(list, &item, type); }) +OptionalInt_t Listヽfirst(List_t list, Closure_t predicate); +void Listヽsort(List_t *list, Closure_t comparison, int64_t padded_item_size); +List_t Listヽsorted(List_t list, Closure_t comparison, int64_t padded_item_size); +void Listヽshuffle(List_t *list, OptionalClosure_t random_int64, int64_t padded_item_size); +List_t Listヽshuffled(List_t list, OptionalClosure_t random_int64, int64_t padded_item_size); +void *Listヽrandom(List_t list, OptionalClosure_t random_int64); +#define Listヽrandom_value(list, random_int64, t) ({ List_t _arr = list; if (_arr.length == 0) fail("Cannot get a random value from an empty list!"); *(t*)Listヽrandom(_arr, random_int64); }) +List_t Listヽsample(List_t list, Int_t n, List_t weights, Closure_t random_num, int64_t padded_item_size); +Table_t Listヽcounts(List_t list, const TypeInfo_t *type); +void Listヽclear(List_t *list); +void Listヽcompact(List_t *list, int64_t padded_item_size); +PUREFUNC bool Listヽhas(List_t list, void *item, const TypeInfo_t *type); +#define Listヽhas_value(list, item_expr, type) ({ __typeof(item_expr) item = item_expr; Listヽhas(list, &item, type); }) +PUREFUNC List_t Listヽfrom(List_t list, Int_t first); +PUREFUNC List_t Listヽto(List_t list, Int_t last); +PUREFUNC List_t Listヽby(List_t list, Int_t stride, int64_t padded_item_size); +PUREFUNC List_t Listヽslice(List_t list, Int_t int_first, Int_t int_last); +PUREFUNC List_t Listヽreversed(List_t list, int64_t padded_item_size); +List_t Listヽconcat(List_t x, List_t y, int64_t padded_item_size); +PUREFUNC uint64_t Listヽhash(const void *list, const TypeInfo_t *type); +PUREFUNC int32_t Listヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Listヽequal(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Listヽis_none(const void *obj, const TypeInfo_t*); +Text_t Listヽas_text(const void *list, bool colorize, const TypeInfo_t *type); +void Listヽheapify(List_t *heap, Closure_t comparison, int64_t padded_item_size); +void Listヽheap_push(List_t *heap, const void *item, Closure_t comparison, int64_t padded_item_size); +#define Listヽheap_push_value(heap, _value, comparison, padded_item_size) ({ __typeof(_value) value = _value; Listヽheap_push(heap, &value, comparison, padded_item_size); }) +void Listヽheap_pop(List_t *heap, Closure_t comparison, int64_t padded_item_size); +#define Listヽheap_pop_value(heap, comparison, type, nonnone_var, nonnone_expr, none_expr) \ ({ List_t *_heap = heap; \ (_heap->length > 0) ? ({ \ type nonnone_var = *(type*)_heap->data; \ - List$heap_pop(_heap, comparison, sizeof(type)); \ + Listヽheap_pop(_heap, comparison, sizeof(type)); \ nonnone_expr; \ }) : none_expr; }) -Int_t List$binary_search(List_t list, void *target, Closure_t comparison); -#define List$binary_search_value(list, target, comparison) \ - ({ __typeof(target) _target = target; List$binary_search(list, &_target, comparison); }) -void List$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); -void List$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type); +Int_t Listヽbinary_search(List_t list, void *target, Closure_t comparison); +#define Listヽbinary_search_value(list, target, comparison) \ + ({ __typeof(target) _target = target; Listヽbinary_search(list, &_target, comparison); }) +void Listヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); +void Listヽdeserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type); -#define List$metamethods { \ - .as_text=List$as_text, \ - .compare=List$compare, \ - .equal=List$equal, \ - .hash=List$hash, \ - .is_none=List$is_none, \ - .serialize=List$serialize, \ - .deserialize=List$deserialize, \ +#define Listヽmetamethods { \ + .as_text=Listヽas_text, \ + .compare=Listヽcompare, \ + .equal=Listヽequal, \ + .hash=Listヽhash, \ + .is_none=Listヽis_none, \ + .serialize=Listヽserialize, \ + .deserialize=Listヽdeserialize, \ } -#define List$info(item_info) &((TypeInfo_t){.size=sizeof(List_t), .align=__alignof__(List_t), \ +#define Listヽinfo(item_info) &((TypeInfo_t){.size=sizeof(List_t), .align=__alignof__(List_t), \ .tag=ListInfo, .ListInfo.item=item_info, \ - .metamethods=List$metamethods}) + .metamethods=Listヽmetamethods}) // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/memory.c b/src/stdlib/memory.c index 46729f83..21893fd0 100644 --- a/src/stdlib/memory.c +++ b/src/stdlib/memory.c @@ -13,18 +13,18 @@ #include "types.h" #include "util.h" -public Text_t Memory$as_text(const void *p, bool colorize, const TypeInfo_t *info) { +public Text_t Memoryヽas_text(const void *p, bool colorize, const TypeInfo_t *info) { (void)info; if (!p) return Text("Memory"); - Text_t text = Text$from_str(String("Memory<", *(void**)p, ">")); + Text_t text = Textヽfrom_str(String("Memory<", *(void**)p, ">")); return colorize ? Texts(Text("\x1b[0;34;1m"), text, Text("\x1b[m")) : text; } -public const TypeInfo_t Memory$info = { +public const TypeInfo_t Memoryヽinfo = { .size=0, .align=0, .metamethods={ - .as_text=Memory$as_text, + .as_text=Memoryヽas_text, .serialize=cannot_serialize, .deserialize=cannot_deserialize, }, diff --git a/src/stdlib/memory.h b/src/stdlib/memory.h index e03d5931..c8a777e6 100644 --- a/src/stdlib/memory.h +++ b/src/stdlib/memory.h @@ -7,7 +7,7 @@ #include "types.h" -extern const TypeInfo_t Memory$info; -Text_t Memory$as_text(const void *p, bool colorize, const TypeInfo_t *type); +extern const TypeInfo_t Memoryヽinfo; +Text_t Memoryヽas_text(const void *p, bool colorize, const TypeInfo_t *type); // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/metamethods.c b/src/stdlib/metamethods.c index e007a52c..7c12a724 100644 --- a/src/stdlib/metamethods.c +++ b/src/stdlib/metamethods.c @@ -94,7 +94,7 @@ public void _deserialize(FILE *input, void *outval, List_t *pointers, const Type public void generic_deserialize(List_t bytes, void *outval, const TypeInfo_t *type) { if (bytes.stride != 1) - List$compact(&bytes, 1); + Listヽcompact(&bytes, 1); FILE *input = fmemopen(bytes.data, (size_t)bytes.length, "r"); List_t pointers = {}; @@ -105,7 +105,7 @@ public void generic_deserialize(List_t bytes, void *outval, const TypeInfo_t *ty public int generic_print(const void *obj, bool colorize, const TypeInfo_t *type) { Text_t text = generic_as_text(obj, colorize, type); - return Text$print(stdout, text) + fputc('\n', stdout); + return Textヽprint(stdout, text) + fputc('\n', stdout); } __attribute__((noreturn)) diff --git a/src/stdlib/nums.c b/src/stdlib/nums.c index 3775c8f4..7627c887 100644 --- a/src/stdlib/nums.c +++ b/src/stdlib/nums.c @@ -14,17 +14,17 @@ #include "text.h" #include "types.h" -public PUREFUNC Text_t Num$as_text(const void *f, bool colorize, const TypeInfo_t *info) { +public PUREFUNC Text_t Numヽas_text(const void *f, bool colorize, const TypeInfo_t *info) { (void)info; if (!f) return Text("Num"); char *str = GC_MALLOC_ATOMIC(24); int len = fpconv_dtoa(*(double*)f, str); static const Text_t color_prefix = Text("\x1b[35m"), color_suffix = Text("\x1b[m"); - Text_t text = Text$from_strn(str, (size_t)len); + Text_t text = Textヽfrom_strn(str, (size_t)len); return colorize ? Texts(color_prefix, text, color_suffix) : text; } -public PUREFUNC int32_t Num$compare(const void *x, const void *y, const TypeInfo_t *info) { +public PUREFUNC int32_t Numヽcompare(const void *x, const void *y, const TypeInfo_t *info) { (void)info; int64_t rx = *(int64_t*)x, ry = *(int64_t*)y; @@ -37,12 +37,12 @@ public PUREFUNC int32_t Num$compare(const void *x, const void *y, const TypeInfo return (rx > ry) - (rx < ry); } -public PUREFUNC bool Num$equal(const void *x, const void *y, const TypeInfo_t *info) { +public PUREFUNC bool Numヽequal(const void *x, const void *y, const TypeInfo_t *info) { (void)info; return *(double*)x == *(double*)y; } -public CONSTFUNC bool Num$near(double a, double b, double ratio, double absolute) { +public CONSTFUNC bool Numヽnear(double a, double b, double ratio, double absolute) { if (ratio < 0) ratio = 0; else if (ratio > 1) ratio = 1; @@ -57,13 +57,13 @@ public CONSTFUNC bool Num$near(double a, double b, double ratio, double absolute return (diff < epsilon); } -public Text_t Num$percent(double f, double precision) { +public Text_t Numヽpercent(double f, double precision) { double d = 100. * f; - d = Num$with_precision(d, precision); - return Texts(Num$as_text(&d, false, &Num$info), Text("%")); + d = Numヽwith_precision(d, precision); + return Texts(Numヽas_text(&d, false, &Numヽinfo), Text("%")); } -public CONSTFUNC double Num$with_precision(double num, double precision) { +public CONSTFUNC double Numヽwith_precision(double num, double precision) { if (precision == 0.0) return num; // Precision will be, e.g. 0.01 or 100. if (precision < 1.) { @@ -76,35 +76,35 @@ public CONSTFUNC double Num$with_precision(double num, double precision) { } } -public CONSTFUNC double Num$mod(double num, double modulus) { +public CONSTFUNC double Numヽmod(double num, double modulus) { // Euclidean division, see: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf double r = remainder(num, modulus); r -= (r < 0) * (2*(modulus < 0) - 1) * modulus; return r; } -public CONSTFUNC double Num$mod1(double num, double modulus) { - return 1.0 + Num$mod(num-1, modulus); +public CONSTFUNC double Numヽmod1(double num, double modulus) { + return 1.0 + Numヽmod(num-1, modulus); } -public CONSTFUNC double Num$mix(double amount, double x, double y) { +public CONSTFUNC double Numヽmix(double amount, double x, double y) { return (1.0-amount)*x + amount*y; } -public CONSTFUNC bool Num$is_between(const double x, const double low, const double high) { +public CONSTFUNC bool Numヽis_between(const double x, const double low, const double high) { return low <= x && x <= high; } -public CONSTFUNC double Num$clamped(double x, double low, double high) { +public CONSTFUNC double Numヽclamped(double x, double low, double high) { return (x <= low) ? low : (x >= high ? high : x); } -public OptionalNum_t Num$parse(Text_t text, Text_t *remainder) { - const char *str = Text$as_c_string(text); +public OptionalNum_t Numヽparse(Text_t text, Text_t *remainder) { + const char *str = Textヽas_c_string(text); char *end = NULL; double d = strtod(str, &end); if (end > str) { if (remainder) - *remainder = Text$from_str(end); + *remainder = Textヽfrom_str(end); else if (*end != '\0') return nan("none"); return d; @@ -114,45 +114,45 @@ public OptionalNum_t Num$parse(Text_t text, Text_t *remainder) { } } -static bool Num$is_none(const void *n, const TypeInfo_t *info) +static bool Numヽis_none(const void *n, const TypeInfo_t *info) { (void)info; return isnan(*(Num_t*)n); } -public CONSTFUNC bool Num$isinf(double n) { return (fpclassify(n) == FP_INFINITE); } -public CONSTFUNC bool Num$finite(double n) { return (fpclassify(n) != FP_INFINITE); } -public CONSTFUNC bool Num$isnan(double n) { return (fpclassify(n) == FP_NAN); } +public CONSTFUNC bool Numヽisinf(double n) { return (fpclassify(n) == FP_INFINITE); } +public CONSTFUNC bool Numヽfinite(double n) { return (fpclassify(n) != FP_INFINITE); } +public CONSTFUNC bool Numヽisnan(double n) { return (fpclassify(n) == FP_NAN); } -public const TypeInfo_t Num$info = { +public const TypeInfo_t Numヽinfo = { .size=sizeof(double), .align=__alignof__(double), .metamethods={ - .compare=Num$compare, - .equal=Num$equal, - .as_text=Num$as_text, - .is_none=Num$is_none, + .compare=Numヽcompare, + .equal=Numヽequal, + .as_text=Numヽas_text, + .is_none=Numヽis_none, }, }; -public PUREFUNC Text_t Num32$as_text(const void *f, bool colorize, const TypeInfo_t *info) { +public PUREFUNC Text_t Num32ヽas_text(const void *f, bool colorize, const TypeInfo_t *info) { (void)info; if (!f) return Text("Num32"); double d = (double)(*(float*)f); - return Num$as_text(&d, colorize, &Num$info); + return Numヽas_text(&d, colorize, &Numヽinfo); } -public PUREFUNC int32_t Num32$compare(const void *x, const void *y, const TypeInfo_t *info) { +public PUREFUNC int32_t Num32ヽcompare(const void *x, const void *y, const TypeInfo_t *info) { (void)info; return (*(float*)x > *(float*)y) - (*(float*)x < *(float*)y); } -public PUREFUNC bool Num32$equal(const void *x, const void *y, const TypeInfo_t *info) { +public PUREFUNC bool Num32ヽequal(const void *x, const void *y, const TypeInfo_t *info) { (void)info; return *(float*)x == *(float*)y; } -public CONSTFUNC bool Num32$near(float a, float b, float ratio, float absolute) { +public CONSTFUNC bool Num32ヽnear(float a, float b, float ratio, float absolute) { if (ratio < 0) ratio = 0; else if (ratio > 1) ratio = 1; @@ -167,13 +167,13 @@ public CONSTFUNC bool Num32$near(float a, float b, float ratio, float absolute) return (diff < epsilon); } -public Text_t Num32$percent(float f, float precision) { +public Text_t Num32ヽpercent(float f, float precision) { double d = 100. * (double)f; - d = Num$with_precision(d, (double)precision); - return Texts(Num$as_text(&d, false, &Num$info), Text("%")); + d = Numヽwith_precision(d, (double)precision); + return Texts(Numヽas_text(&d, false, &Numヽinfo), Text("%")); } -public CONSTFUNC float Num32$with_precision(float num, float precision) { +public CONSTFUNC float Num32ヽwith_precision(float num, float precision) { if (precision == 0.0f) return num; // Precision will be, e.g. 0.01 or 100. if (precision < 1.f) { @@ -186,35 +186,35 @@ public CONSTFUNC float Num32$with_precision(float num, float precision) { } } -public CONSTFUNC float Num32$mod(float num, float modulus) { +public CONSTFUNC float Num32ヽmod(float num, float modulus) { // Euclidean division, see: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf float r = remainderf(num, modulus); r -= (r < 0) * (2*(modulus < 0) - 1) * modulus; return r; } -public CONSTFUNC float Num32$mod1(float num, float modulus) { - return 1.0f + Num32$mod(num-1, modulus); +public CONSTFUNC float Num32ヽmod1(float num, float modulus) { + return 1.0f + Num32ヽmod(num-1, modulus); } -public CONSTFUNC float Num32$mix(float amount, float x, float y) { +public CONSTFUNC float Num32ヽmix(float amount, float x, float y) { return (1.0f-amount)*x + amount*y; } -public CONSTFUNC bool Num32$is_between(const float x, const float low, const float high) { +public CONSTFUNC bool Num32ヽis_between(const float x, const float low, const float high) { return low <= x && x <= high; } -public CONSTFUNC float Num32$clamped(float x, float low, float high) { +public CONSTFUNC float Num32ヽclamped(float x, float low, float high) { return (x <= low) ? low : (x >= high ? high : x); } -public OptionalNum32_t Num32$parse(Text_t text, Text_t *remainder) { - const char *str = Text$as_c_string(text); +public OptionalNum32_t Num32ヽparse(Text_t text, Text_t *remainder) { + const char *str = Textヽas_c_string(text); char *end = NULL; double d = strtod(str, &end); if (end > str && end[0] == '\0') { - if (remainder) *remainder = Text$from_str(end); + if (remainder) *remainder = Textヽfrom_str(end); else if (*end != '\0') return nan("none"); return d; @@ -224,24 +224,24 @@ public OptionalNum32_t Num32$parse(Text_t text, Text_t *remainder) { } } -static bool Num32$is_none(const void *n, const TypeInfo_t *info) +static bool Num32ヽis_none(const void *n, const TypeInfo_t *info) { (void)info; return isnan(*(Num32_t*)n); } -public CONSTFUNC bool Num32$isinf(float n) { return (fpclassify(n) == FP_INFINITE); } -public CONSTFUNC bool Num32$finite(float n) { return (fpclassify(n) != FP_INFINITE); } -public CONSTFUNC bool Num32$isnan(float n) { return (fpclassify(n) == FP_NAN); } +public CONSTFUNC bool Num32ヽisinf(float n) { return (fpclassify(n) == FP_INFINITE); } +public CONSTFUNC bool Num32ヽfinite(float n) { return (fpclassify(n) != FP_INFINITE); } +public CONSTFUNC bool Num32ヽisnan(float n) { return (fpclassify(n) == FP_NAN); } -public const TypeInfo_t Num32$info = { +public const TypeInfo_t Num32ヽinfo = { .size=sizeof(float), .align=__alignof__(float), .metamethods={ - .compare=Num32$compare, - .equal=Num32$equal, - .as_text=Num32$as_text, - .is_none=Num32$is_none, + .compare=Num32ヽcompare, + .equal=Num32ヽequal, + .as_text=Num32ヽas_text, + .is_none=Num32ヽis_none, }, }; diff --git a/src/stdlib/nums.h b/src/stdlib/nums.h index fe76d1c3..1b757e4e 100644 --- a/src/stdlib/nums.h +++ b/src/stdlib/nums.h @@ -17,28 +17,28 @@ #define N32(n) ((float)(n)) #define N64(n) ((double)(n)) -Text_t Num$as_text(const void *f, bool colorize, const TypeInfo_t *type); -PUREFUNC int32_t Num$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Num$equal(const void *x, const void *y, const TypeInfo_t *type); -CONSTFUNC bool Num$near(double a, double b, double ratio, double absolute); -Text_t Num$percent(double f, double precision); -double CONSTFUNC Num$with_precision(double num, double precision); -double Num$mod(double num, double modulus); -double Num$mod1(double num, double modulus); -CONSTFUNC bool Num$isinf(double n); -CONSTFUNC bool Num$finite(double n); -CONSTFUNC bool Num$isnan(double n); -double Num$nan(Text_t tag); -CONSTFUNC double Num$mix(double amount, double x, double y); -OptionalNum_t Num$parse(Text_t text, Text_t *remainder); -CONSTFUNC bool Num$is_between(const double x, const double low, const double high); -CONSTFUNC double Num$clamped(double x, double low, double high); -MACROLIKE CONSTFUNC double Num$from_num32(Num32_t n) { return (double)n; } +Text_t Numヽas_text(const void *f, bool colorize, const TypeInfo_t *type); +PUREFUNC int32_t Numヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Numヽequal(const void *x, const void *y, const TypeInfo_t *type); +CONSTFUNC bool Numヽnear(double a, double b, double ratio, double absolute); +Text_t Numヽpercent(double f, double precision); +double CONSTFUNC Numヽwith_precision(double num, double precision); +double Numヽmod(double num, double modulus); +double Numヽmod1(double num, double modulus); +CONSTFUNC bool Numヽisinf(double n); +CONSTFUNC bool Numヽfinite(double n); +CONSTFUNC bool Numヽisnan(double n); +double Numヽnan(Text_t tag); +CONSTFUNC double Numヽmix(double amount, double x, double y); +OptionalNum_t Numヽparse(Text_t text, Text_t *remainder); +CONSTFUNC bool Numヽis_between(const double x, const double low, const double high); +CONSTFUNC double Numヽclamped(double x, double low, double high); +MACROLIKE CONSTFUNC double Numヽfrom_num32(Num32_t n) { return (double)n; } #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" #endif -MACROLIKE CONSTFUNC double Num$from_int(Int_t i, bool truncate) { +MACROLIKE CONSTFUNC double Numヽfrom_int(Int_t i, bool truncate) { if likely (i.small & 0x1) { double ret = (double)(i.small >> 2); if unlikely (!truncate && (int64_t)ret != (i.small >> 2)) @@ -58,41 +58,41 @@ MACROLIKE CONSTFUNC double Num$from_int(Int_t i, bool truncate) { #ifdef __GNUC__ #pragma GCC diagnostic pop #endif -MACROLIKE CONSTFUNC double Num$from_int64(Int64_t i, bool truncate) { +MACROLIKE CONSTFUNC double Numヽfrom_int64(Int64_t i, bool truncate) { double n = (double)i; if unlikely (!truncate && (Int64_t)n != i) fail("Could not convert integer to 64-bit floating point without losing precision: ", i); return n; } -MACROLIKE CONSTFUNC double Num$from_int32(Int32_t i) { return (double)i; } -MACROLIKE CONSTFUNC double Num$from_int16(Int16_t i) { return (double)i; } -MACROLIKE CONSTFUNC double Num$from_int8(Int8_t i) { return (double)i; } -MACROLIKE CONSTFUNC double Num$from_byte(Byte_t i) { return (double)i; } +MACROLIKE CONSTFUNC double Numヽfrom_int32(Int32_t i) { return (double)i; } +MACROLIKE CONSTFUNC double Numヽfrom_int16(Int16_t i) { return (double)i; } +MACROLIKE CONSTFUNC double Numヽfrom_int8(Int8_t i) { return (double)i; } +MACROLIKE CONSTFUNC double Numヽfrom_byte(Byte_t i) { return (double)i; } -extern const TypeInfo_t Num$info; +extern const TypeInfo_t Numヽinfo; -Text_t Num32$as_text(const void *f, bool colorize, const TypeInfo_t *type); -PUREFUNC int32_t Num32$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Num32$equal(const void *x, const void *y, const TypeInfo_t *type); -CONSTFUNC bool Num32$near(float a, float b, float ratio, float absolute); -Text_t Num32$percent(float f, float precision); -float CONSTFUNC Num32$with_precision(float num, float precision); -float Num32$mod(float num, float modulus); -float Num32$mod1(float num, float modulus); -CONSTFUNC bool Num32$isinf(float n); -CONSTFUNC bool Num32$finite(float n); -CONSTFUNC bool Num32$isnan(float n); -CONSTFUNC float Num32$mix(float amount, float x, float y); -OptionalNum32_t Num32$parse(Text_t text, Text_t *remainder); -float Num32$nan(Text_t tag); -CONSTFUNC bool Num32$is_between(const float x, const float low, const float high); -CONSTFUNC float Num32$clamped(float x, float low, float high); -MACROLIKE CONSTFUNC float Num32$from_num(Num_t n) { return (float)n; } +Text_t Num32ヽas_text(const void *f, bool colorize, const TypeInfo_t *type); +PUREFUNC int32_t Num32ヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Num32ヽequal(const void *x, const void *y, const TypeInfo_t *type); +CONSTFUNC bool Num32ヽnear(float a, float b, float ratio, float absolute); +Text_t Num32ヽpercent(float f, float precision); +float CONSTFUNC Num32ヽwith_precision(float num, float precision); +float Num32ヽmod(float num, float modulus); +float Num32ヽmod1(float num, float modulus); +CONSTFUNC bool Num32ヽisinf(float n); +CONSTFUNC bool Num32ヽfinite(float n); +CONSTFUNC bool Num32ヽisnan(float n); +CONSTFUNC float Num32ヽmix(float amount, float x, float y); +OptionalNum32_t Num32ヽparse(Text_t text, Text_t *remainder); +float Num32ヽnan(Text_t tag); +CONSTFUNC bool Num32ヽis_between(const float x, const float low, const float high); +CONSTFUNC float Num32ヽclamped(float x, float low, float high); +MACROLIKE CONSTFUNC float Num32ヽfrom_num(Num_t n) { return (float)n; } #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" #endif -MACROLIKE CONSTFUNC float Num32$from_int(Int_t i, bool truncate) { +MACROLIKE CONSTFUNC float Num32ヽfrom_int(Int_t i, bool truncate) { if likely (i.small & 0x1) { float ret = (float)(i.small >> 2); if unlikely (!truncate && (int64_t)ret != (i.small >> 2)) @@ -112,22 +112,22 @@ MACROLIKE CONSTFUNC float Num32$from_int(Int_t i, bool truncate) { #ifdef __GNUC__ #pragma GCC diagnostic pop #endif -MACROLIKE CONSTFUNC float Num32$from_int64(Int64_t i, bool truncate) { +MACROLIKE CONSTFUNC float Num32ヽfrom_int64(Int64_t i, bool truncate) { float n = (float)i; if unlikely (!truncate && (Int64_t)n != i) fail("Could not convert integer to 32-bit floating point without losing precision: ", i); return n; } -MACROLIKE CONSTFUNC float Num32$from_int32(Int32_t i, bool truncate) { +MACROLIKE CONSTFUNC float Num32ヽfrom_int32(Int32_t i, bool truncate) { float n = (float)i; if unlikely (!truncate && (Int32_t)n != i) fail("Could not convert integer to 32-bit floating point without losing precision: ", i); return n; } -MACROLIKE CONSTFUNC float Num32$from_int16(Int16_t i) { return (float)i; } -MACROLIKE CONSTFUNC float Num32$from_int8(Int8_t i) { return (float)i; } -MACROLIKE CONSTFUNC float Num32$from_byte(Byte_t i) { return (float)i; } +MACROLIKE CONSTFUNC float Num32ヽfrom_int16(Int16_t i) { return (float)i; } +MACROLIKE CONSTFUNC float Num32ヽfrom_int8(Int8_t i) { return (float)i; } +MACROLIKE CONSTFUNC float Num32ヽfrom_byte(Byte_t i) { return (float)i; } -extern const TypeInfo_t Num32$info; +extern const TypeInfo_t Num32ヽinfo; // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/optionals.c b/src/stdlib/optionals.c index ead9428a..9aaf5400 100644 --- a/src/stdlib/optionals.c +++ b/src/stdlib/optionals.c @@ -18,12 +18,12 @@ public PUREFUNC bool is_none(const void *obj, const TypeInfo_t *non_optional_typ return *(bool*)dest; } -PUREFUNC public uint64_t Optional$hash(const void *obj, const TypeInfo_t *type) +PUREFUNC public uint64_t Optionalヽhash(const void *obj, const TypeInfo_t *type) { return is_none(obj, type->OptionalInfo.type) ? 0 : generic_hash(obj, type->OptionalInfo.type); } -PUREFUNC public int32_t Optional$compare(const void *x, const void *y, const TypeInfo_t *type) +PUREFUNC public int32_t Optionalヽcompare(const void *x, const void *y, const TypeInfo_t *type) { if (x == y) return 0; bool x_is_null = is_none(x, type->OptionalInfo.type); @@ -33,7 +33,7 @@ PUREFUNC public int32_t Optional$compare(const void *x, const void *y, const Typ else return generic_compare(x, y, type->OptionalInfo.type); } -PUREFUNC public bool Optional$equal(const void *x, const void *y, const TypeInfo_t *type) +PUREFUNC public bool Optionalヽequal(const void *x, const void *y, const TypeInfo_t *type) { if (x == y) return true; @@ -44,17 +44,17 @@ PUREFUNC public bool Optional$equal(const void *x, const void *y, const TypeInfo else return generic_equal(x, y, type->OptionalInfo.type); } -public Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo_t *type) +public Text_t Optionalヽas_text(const void *obj, bool colorize, const TypeInfo_t *type) { if (!obj) - return Text$concat(generic_as_text(obj, colorize, type->OptionalInfo.type), Text("?")); + return Textヽconcat(generic_as_text(obj, colorize, type->OptionalInfo.type), Text("?")); if (is_none(obj, type->OptionalInfo.type)) return colorize ? Text("\x1b[31mnone\x1b[m") : Text("none"); return generic_as_text(obj, colorize, type->OptionalInfo.type); } -public void Optional$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) +public void Optionalヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) { bool has_value = !is_none(obj, type->OptionalInfo.type); assert(fputc((int)has_value, out) != EOF); @@ -62,7 +62,7 @@ public void Optional$serialize(const void *obj, FILE *out, Table_t *pointers, co _serialize(obj, out, pointers, type->OptionalInfo.type); } -public void Optional$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) +public void Optionalヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) { bool has_value = (bool)fgetc(in); const TypeInfo_t *nonnull = type->OptionalInfo.type; @@ -76,9 +76,9 @@ public void Optional$deserialize(FILE *in, void *outval, List_t *pointers, const *(List_t*)outval = (List_t){.length=-1}; else if (nonnull->tag == TableInfo) *(Table_t*)outval = (Table_t){.entries={.length=-1}}; - else if (nonnull == &Num$info) + else if (nonnull == &Numヽinfo) *(double*)outval = (double)NAN; - else if (nonnull == &Num32$info) + else if (nonnull == &Num32ヽinfo) *(float*)outval = (float)NAN; else if (nonnull->tag == StructInfo || (nonnull->tag == OpaqueInfo && type->size > nonnull->size)) memset(outval + type->size, -1, (size_t)(type->size - nonnull->size)); diff --git a/src/stdlib/optionals.h b/src/stdlib/optionals.h index 5be52e93..223cf47b 100644 --- a/src/stdlib/optionals.h +++ b/src/stdlib/optionals.h @@ -19,24 +19,24 @@ #define NONE_PATH ((Path_t){.type=PATH_NONE}) PUREFUNC bool is_none(const void *obj, const TypeInfo_t *non_optional_type); -PUREFUNC uint64_t Optional$hash(const void *obj, const TypeInfo_t *type); -PUREFUNC int32_t Optional$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Optional$equal(const void *x, const void *y, const TypeInfo_t *type); -Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo_t *type); -void Optional$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); -void Optional$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); - -#define Optional$metamethods { \ - .hash=Optional$hash, \ - .compare=Optional$compare, \ - .equal=Optional$equal, \ - .as_text=Optional$as_text, \ - .serialize=Optional$serialize, \ - .deserialize=Optional$deserialize, \ +PUREFUNC uint64_t Optionalヽhash(const void *obj, const TypeInfo_t *type); +PUREFUNC int32_t Optionalヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Optionalヽequal(const void *x, const void *y, const TypeInfo_t *type); +Text_t Optionalヽas_text(const void *obj, bool colorize, const TypeInfo_t *type); +void Optionalヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); +void Optionalヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); + +#define Optionalヽmetamethods { \ + .hash=Optionalヽhash, \ + .compare=Optionalヽcompare, \ + .equal=Optionalヽequal, \ + .as_text=Optionalヽas_text, \ + .serialize=Optionalヽserialize, \ + .deserialize=Optionalヽdeserialize, \ } -#define Optional$info(_size, _align, t) &((TypeInfo_t){.size=_size, .align=_align, \ +#define Optionalヽinfo(_size, _align, t) &((TypeInfo_t){.size=_size, .align=_align, \ .tag=OptionalInfo, .OptionalInfo.type=t, \ - .metamethods=Optional$metamethods}) + .metamethods=Optionalヽmetamethods}) // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/paths.c b/src/stdlib/paths.c index 58702ec7..8aa57f17 100644 --- a/src/stdlib/paths.c +++ b/src/stdlib/paths.c @@ -33,20 +33,20 @@ #include "siphash.h" #include "siphash-internals.h" -static const Path_t HOME_PATH = {.type.$tag=PATH_HOME}, - ROOT_PATH = {.type.$tag=PATH_ABSOLUTE}, - CURDIR_PATH = {.type.$tag=PATH_RELATIVE}; +static const Path_t HOME_PATH = {.type.ヽtag=PATH_HOME}, + ROOT_PATH = {.type.ヽtag=PATH_ABSOLUTE}, + CURDIR_PATH = {.type.ヽtag=PATH_RELATIVE}; static void clean_components(List_t *components) { for (int64_t i = 0; i < components->length; ) { Text_t *component = (Text_t*)(components->data + i*components->stride); - if (component->length == 0 || Text$equal_values(*component, Text("."))) { - List$remove_at(components, I(i+1), I(1), sizeof(Text_t)); - } else if (i > 0 && Text$equal_values(*component, Text(".."))) { + if (component->length == 0 || Textヽequal_values(*component, Text("."))) { + Listヽremove_at(components, I(i+1), I(1), sizeof(Text_t)); + } else if (i > 0 && Textヽequal_values(*component, Text(".."))) { Text_t *prev = (Text_t*)(components->data + (i-1)*components->stride); - if (!Text$equal_values(*prev, Text(".."))) { - List$remove_at(components, I(i), I(2), sizeof(Text_t)); + if (!Textヽequal_values(*prev, Text(".."))) { + Listヽremove_at(components, I(i), I(2), sizeof(Text_t)); i -= 1; } else { i += 1; @@ -57,7 +57,7 @@ static void clean_components(List_t *components) } } -public Path_t Path$from_str(const char *str) +public Path_t Pathヽfrom_str(const char *str) { if (!str || str[0] == '\0' || streq(str, "/")) return ROOT_PATH; else if (streq(str, "~")) return HOME_PATH; @@ -68,16 +68,16 @@ public Path_t Path$from_str(const char *str) Path_t result = {.components={}}; if (str[0] == '/') { - result.type.$tag = PATH_ABSOLUTE; + result.type.ヽtag = PATH_ABSOLUTE; str += 1; } else if (str[0] == '~' && str[1] == '/') { - result.type.$tag = PATH_HOME; + result.type.ヽtag = PATH_HOME; str += 2; } else if (str[0] == '.' && str[1] == '/') { - result.type.$tag = PATH_RELATIVE; + result.type.ヽtag = PATH_RELATIVE; str += 2; } else { - result.type.$tag = PATH_RELATIVE; + result.type.ヽtag = PATH_RELATIVE; } while (str && *str) { @@ -87,12 +87,12 @@ public Path_t Path$from_str(const char *str) // ignore /./ } else if (component_len == 2 && strncmp(str, "..", 2) == 0 && result.components.length > 1 - && !Text$equal_values(Text(".."), *(Text_t*)(result.components.data + result.components.stride*(result.components.length-1)))) { + && !Textヽequal_values(Text(".."), *(Text_t*)(result.components.data + result.components.stride*(result.components.length-1)))) { // Pop off /foo/baz/.. -> /foo - List$remove_at(&result.components, I(result.components.length), I(1), sizeof(Text_t)); + Listヽremove_at(&result.components, I(result.components.length), I(1), sizeof(Text_t)); } else { - Text_t component = Text$from_strn(str, component_len); - List$insert_value(&result.components, component, I(0), sizeof(Text_t)); + Text_t component = Textヽfrom_strn(str, component_len); + Listヽinsert_value(&result.components, component, I(0), sizeof(Text_t)); } str += component_len; } @@ -101,90 +101,90 @@ public Path_t Path$from_str(const char *str) return result; } -public Path_t Path$from_text(Text_t text) +public Path_t Pathヽfrom_text(Text_t text) { - return Path$from_str(Text$as_c_string(text)); + return Pathヽfrom_str(Textヽas_c_string(text)); } -public Path_t Path$expand_home(Path_t path) +public Path_t Pathヽexpand_home(Path_t path) { - if (path.type.$tag == PATH_HOME) { - Path_t pwd = Path$from_str(getenv("HOME")); - List_t components = List$concat(pwd.components, path.components, sizeof(Text_t)); + if (path.type.ヽtag == PATH_HOME) { + Path_t pwd = Pathヽfrom_str(getenv("HOME")); + List_t components = Listヽconcat(pwd.components, path.components, sizeof(Text_t)); assert(components.length == path.components.length + pwd.components.length); clean_components(&components); - path = (Path_t){.type.$tag=PATH_ABSOLUTE, .components=components}; + path = (Path_t){.type.ヽtag=PATH_ABSOLUTE, .components=components}; } return path; } -public Path_t Path$_concat(int n, Path_t items[n]) +public Path_t Pathヽ_concat(int n, Path_t items[n]) { assert(n > 0); Path_t result = items[0]; LIST_INCREF(result.components); for (int i = 1; i < n; i++) { - if (items[i].type.$tag != PATH_RELATIVE) + if (items[i].type.ヽtag != PATH_RELATIVE) fail("Cannot concatenate an absolute or home-based path onto another path: (", items[i], ")"); - List$insert_all(&result.components, items[i].components, I(0), sizeof(Text_t)); + Listヽinsert_all(&result.components, items[i].components, I(0), sizeof(Text_t)); } clean_components(&result.components); return result; } -public Path_t Path$resolved(Path_t path, Path_t relative_to) +public Path_t Pathヽresolved(Path_t path, Path_t relative_to) { - if (path.type.$tag == PATH_RELATIVE && !(relative_to.type.$tag == PATH_RELATIVE && relative_to.components.length == 0)) { - Path_t result = {.type.$tag=relative_to.type.$tag}; + if (path.type.ヽtag == PATH_RELATIVE && !(relative_to.type.ヽtag == PATH_RELATIVE && relative_to.components.length == 0)) { + Path_t result = {.type.ヽtag=relative_to.type.ヽtag}; result.components = relative_to.components; LIST_INCREF(result.components); - List$insert_all(&result.components, path.components, I(0), sizeof(Text_t)); + Listヽinsert_all(&result.components, path.components, I(0), sizeof(Text_t)); clean_components(&result.components); return result; } return path; } -public Path_t Path$relative_to(Path_t path, Path_t relative_to) +public Path_t Pathヽrelative_to(Path_t path, Path_t relative_to) { - if (path.type.$tag != relative_to.type.$tag) + if (path.type.ヽtag != relative_to.type.ヽtag) fail("Cannot create a path relative to a different path with a mismatching type: (", path, ") relative to (", relative_to, ")"); - Path_t result = {.type.$tag=PATH_RELATIVE}; + Path_t result = {.type.ヽtag=PATH_RELATIVE}; int64_t shared = 0; for (; shared < path.components.length && shared < relative_to.components.length; shared++) { Text_t *p = (Text_t*)(path.components.data + shared*path.components.stride); Text_t *r = (Text_t*)(relative_to.components.data + shared*relative_to.components.stride); - if (!Text$equal_values(*p, *r)) + if (!Textヽequal_values(*p, *r)) break; } for (int64_t i = shared; i < relative_to.components.length; i++) - List$insert_value(&result.components, Text(".."), I(1), sizeof(Text_t)); + Listヽinsert_value(&result.components, Text(".."), I(1), sizeof(Text_t)); for (int64_t i = shared; i < path.components.length; i++) { Text_t *p = (Text_t*)(path.components.data + i*path.components.stride); - List$insert(&result.components, p, I(0), sizeof(Text_t)); + Listヽinsert(&result.components, p, I(0), sizeof(Text_t)); } //clean_components(&result.components); return result; } -public bool Path$exists(Path_t path) +public bool Pathヽexists(Path_t path) { - path = Path$expand_home(path); + path = Pathヽexpand_home(path); struct stat sb; - return (stat(Path$as_c_string(path), &sb) == 0); + return (stat(Pathヽas_c_string(path), &sb) == 0); } static INLINE int path_stat(Path_t path, bool follow_symlinks, struct stat *sb) { - path = Path$expand_home(path); - const char *path_str = Path$as_c_string(path); + path = Pathヽexpand_home(path); + const char *path_str = Pathヽas_c_string(path); return follow_symlinks ? stat(path_str, sb) : lstat(path_str, sb); } -public bool Path$is_file(Path_t path, bool follow_symlinks) +public bool Pathヽis_file(Path_t path, bool follow_symlinks) { struct stat sb; int status = path_stat(path, follow_symlinks, &sb); @@ -192,7 +192,7 @@ public bool Path$is_file(Path_t path, bool follow_symlinks) return (sb.st_mode & S_IFMT) == S_IFREG; } -public bool Path$is_directory(Path_t path, bool follow_symlinks) +public bool Pathヽis_directory(Path_t path, bool follow_symlinks) { struct stat sb; int status = path_stat(path, follow_symlinks, &sb); @@ -200,7 +200,7 @@ public bool Path$is_directory(Path_t path, bool follow_symlinks) return (sb.st_mode & S_IFMT) == S_IFDIR; } -public bool Path$is_pipe(Path_t path, bool follow_symlinks) +public bool Pathヽis_pipe(Path_t path, bool follow_symlinks) { struct stat sb; int status = path_stat(path, follow_symlinks, &sb); @@ -208,7 +208,7 @@ public bool Path$is_pipe(Path_t path, bool follow_symlinks) return (sb.st_mode & S_IFMT) == S_IFIFO; } -public bool Path$is_socket(Path_t path, bool follow_symlinks) +public bool Pathヽis_socket(Path_t path, bool follow_symlinks) { struct stat sb; int status = path_stat(path, follow_symlinks, &sb); @@ -216,7 +216,7 @@ public bool Path$is_socket(Path_t path, bool follow_symlinks) return (sb.st_mode & S_IFMT) == S_IFSOCK; } -public bool Path$is_symlink(Path_t path) +public bool Pathヽis_symlink(Path_t path) { struct stat sb; int status = path_stat(path, false, &sb); @@ -224,10 +224,10 @@ public bool Path$is_symlink(Path_t path) return (sb.st_mode & S_IFMT) == S_IFLNK; } -public bool Path$can_read(Path_t path) +public bool Pathヽcan_read(Path_t path) { - path = Path$expand_home(path); - const char *path_str = Path$as_c_string(path); + path = Pathヽexpand_home(path); + const char *path_str = Pathヽas_c_string(path); #ifdef _GNU_SOURCE return (euidaccess(path_str, R_OK) == 0); #else @@ -235,10 +235,10 @@ public bool Path$can_read(Path_t path) #endif } -public bool Path$can_write(Path_t path) +public bool Pathヽcan_write(Path_t path) { - path = Path$expand_home(path); - const char *path_str = Path$as_c_string(path); + path = Pathヽexpand_home(path); + const char *path_str = Pathヽas_c_string(path); #ifdef _GNU_SOURCE return (euidaccess(path_str, W_OK) == 0); #else @@ -246,10 +246,10 @@ public bool Path$can_write(Path_t path) #endif } -public bool Path$can_execute(Path_t path) +public bool Pathヽcan_execute(Path_t path) { - path = Path$expand_home(path); - const char *path_str = Path$as_c_string(path); + path = Pathヽexpand_home(path); + const char *path_str = Pathヽas_c_string(path); #ifdef _GNU_SOURCE return (euidaccess(path_str, X_OK) == 0); #else @@ -257,7 +257,7 @@ public bool Path$can_execute(Path_t path) #endif } -public OptionalInt64_t Path$modified(Path_t path, bool follow_symlinks) +public OptionalInt64_t Pathヽmodified(Path_t path, bool follow_symlinks) { struct stat sb; int status = path_stat(path, follow_symlinks, &sb); @@ -265,7 +265,7 @@ public OptionalInt64_t Path$modified(Path_t path, bool follow_symlinks) return (OptionalInt64_t){.value=(int64_t)sb.st_mtime}; } -public OptionalInt64_t Path$accessed(Path_t path, bool follow_symlinks) +public OptionalInt64_t Pathヽaccessed(Path_t path, bool follow_symlinks) { struct stat sb; int status = path_stat(path, follow_symlinks, &sb); @@ -273,7 +273,7 @@ public OptionalInt64_t Path$accessed(Path_t path, bool follow_symlinks) return (OptionalInt64_t){.value=(int64_t)sb.st_atime}; } -public OptionalInt64_t Path$changed(Path_t path, bool follow_symlinks) +public OptionalInt64_t Pathヽchanged(Path_t path, bool follow_symlinks) { struct stat sb; int status = path_stat(path, follow_symlinks, &sb); @@ -283,46 +283,46 @@ public OptionalInt64_t Path$changed(Path_t path, bool follow_symlinks) static void _write(Path_t path, List_t bytes, int mode, int permissions) { - path = Path$expand_home(path); - const char *path_str = Path$as_c_string(path); + path = Pathヽexpand_home(path); + const char *path_str = Pathヽas_c_string(path); int fd = open(path_str, mode, permissions); if (fd == -1) fail("Could not write to file: ", path_str, "\n", strerror(errno)); if (bytes.stride != 1) - List$compact(&bytes, 1); + Listヽcompact(&bytes, 1); ssize_t written = write(fd, bytes.data, (size_t)bytes.length); if (written != (ssize_t)bytes.length) fail("Could not write to file: ", path_str, "\n", strerror(errno)); close(fd); } -public void Path$write(Path_t path, Text_t text, int permissions) +public void Pathヽwrite(Path_t path, Text_t text, int permissions) { - List_t bytes = Text$utf8_bytes(text); + List_t bytes = Textヽutf8_bytes(text); _write(path, bytes, O_WRONLY | O_CREAT | O_TRUNC, permissions); } -public void Path$write_bytes(Path_t path, List_t bytes, int permissions) +public void Pathヽwrite_bytes(Path_t path, List_t bytes, int permissions) { _write(path, bytes, O_WRONLY | O_CREAT | O_TRUNC, permissions); } -public void Path$append(Path_t path, Text_t text, int permissions) +public void Pathヽappend(Path_t path, Text_t text, int permissions) { - List_t bytes = Text$utf8_bytes(text); + List_t bytes = Textヽutf8_bytes(text); _write(path, bytes, O_WRONLY | O_APPEND | O_CREAT, permissions); } -public void Path$append_bytes(Path_t path, List_t bytes, int permissions) +public void Pathヽappend_bytes(Path_t path, List_t bytes, int permissions) { _write(path, bytes, O_WRONLY | O_APPEND | O_CREAT, permissions); } -public OptionalList_t Path$read_bytes(Path_t path, OptionalInt_t count) +public OptionalList_t Pathヽread_bytes(Path_t path, OptionalInt_t count) { - path = Path$expand_home(path); - int fd = open(Path$as_c_string(path), O_RDONLY); + path = Pathヽexpand_home(path); + int fd = open(Pathヽas_c_string(path), O_RDONLY); if (fd == -1) return NONE_LIST; @@ -330,7 +330,7 @@ public OptionalList_t Path$read_bytes(Path_t path, OptionalInt_t count) if (fstat(fd, &sb) != 0) return NONE_LIST; - int64_t const target_count = count.small ? Int64$from_int(count, false) : INT64_MAX; + int64_t const target_count = count.small ? Int64ヽfrom_int(count, false) : INT64_MAX; if (target_count < 0) fail("Cannot read a negative number of bytes!"); @@ -376,47 +376,47 @@ public OptionalList_t Path$read_bytes(Path_t path, OptionalInt_t count) } } -public OptionalText_t Path$read(Path_t path) +public OptionalText_t Pathヽread(Path_t path) { - List_t bytes = Path$read_bytes(path, NONE_INT); + List_t bytes = Pathヽread_bytes(path, NONE_INT); if (bytes.length < 0) return NONE_TEXT; - return Text$from_bytes(bytes); + return Textヽfrom_bytes(bytes); } -public OptionalText_t Path$owner(Path_t path, bool follow_symlinks) +public OptionalText_t Pathヽowner(Path_t path, bool follow_symlinks) { struct stat sb; int status = path_stat(path, follow_symlinks, &sb); if (status != 0) return NONE_TEXT; struct passwd *pw = getpwuid(sb.st_uid); - return pw ? Text$from_str(pw->pw_name) : NONE_TEXT; + return pw ? Textヽfrom_str(pw->pw_name) : NONE_TEXT; } -public OptionalText_t Path$group(Path_t path, bool follow_symlinks) +public OptionalText_t Pathヽgroup(Path_t path, bool follow_symlinks) { struct stat sb; int status = path_stat(path, follow_symlinks, &sb); if (status != 0) return NONE_TEXT; struct group *gr = getgrgid(sb.st_uid); - return gr ? Text$from_str(gr->gr_name) : NONE_TEXT; + return gr ? Textヽfrom_str(gr->gr_name) : NONE_TEXT; } -public void Path$set_owner(Path_t path, OptionalText_t owner, OptionalText_t group, bool follow_symlinks) +public void Pathヽset_owner(Path_t path, OptionalText_t owner, OptionalText_t group, bool follow_symlinks) { uid_t owner_id = (uid_t)-1; if (owner.length >= 0) { - struct passwd *pwd = getpwnam(Text$as_c_string(owner)); + struct passwd *pwd = getpwnam(Textヽas_c_string(owner)); if (pwd == NULL) fail("Not a valid user: ", owner); owner_id = pwd->pw_uid; } gid_t group_id = (gid_t)-1; if (group.length >= 0) { - struct group *grp = getgrnam(Text$as_c_string(group)); + struct group *grp = getgrnam(Textヽas_c_string(group)); if (grp == NULL) fail("Not a valid group: ", group); group_id = grp->gr_gid; } - const char *path_str = Path$as_c_string(path); + const char *path_str = Pathヽas_c_string(path); int result = follow_symlinks ? chown(path_str, owner_id, group_id) : lchown(path_str, owner_id, group_id); if (result < 0) fail("Could not set owner!"); @@ -442,10 +442,10 @@ static int _remove_files(const char *path, const struct stat *sbuf, int type, st } } -public void Path$remove(Path_t path, bool ignore_missing) +public void Pathヽremove(Path_t path, bool ignore_missing) { - path = Path$expand_home(path); - const char *path_str = Path$as_c_string(path); + path = Pathヽexpand_home(path); + const char *path_str = Pathヽas_c_string(path); struct stat sb; if (lstat(path_str, &sb) != 0) { if (!ignore_missing) @@ -465,10 +465,10 @@ public void Path$remove(Path_t path, bool ignore_missing) } } -public void Path$create_directory(Path_t path, int permissions) +public void Pathヽcreate_directory(Path_t path, int permissions) { - path = Path$expand_home(path); - const char *c_path = Path$as_c_string(path); + path = Pathヽexpand_home(path); + const char *c_path = Pathヽas_c_string(path); int status = mkdir(c_path, (mode_t)permissions); if (status != 0 && errno != EEXIST) fail("Could not create directory: ", c_path, " (", strerror(errno), ")"); @@ -476,10 +476,10 @@ public void Path$create_directory(Path_t path, int permissions) static List_t _filtered_children(Path_t path, bool include_hidden, mode_t filter) { - path = Path$expand_home(path); + path = Pathヽexpand_home(path); struct dirent *dir; List_t children = {}; - const char *path_str = Path$as_c_string(path); + const char *path_str = Pathヽas_c_string(path); size_t path_len = strlen(path_str); DIR *d = opendir(path_str); if (!d) @@ -501,32 +501,32 @@ static List_t _filtered_children(Path_t path, bool include_hidden, mode_t filter if (!((sb.st_mode & S_IFMT) & filter)) continue; - Path_t child = Path$from_str(child_str); - List$insert(&children, &child, I(0), sizeof(Path_t)); + Path_t child = Pathヽfrom_str(child_str); + Listヽinsert(&children, &child, I(0), sizeof(Path_t)); } closedir(d); return children; } -public List_t Path$children(Path_t path, bool include_hidden) +public List_t Pathヽchildren(Path_t path, bool include_hidden) { return _filtered_children(path, include_hidden, (mode_t)-1); } -public List_t Path$files(Path_t path, bool include_hidden) +public List_t Pathヽfiles(Path_t path, bool include_hidden) { return _filtered_children(path, include_hidden, S_IFREG); } -public List_t Path$subdirectories(Path_t path, bool include_hidden) +public List_t Pathヽsubdirectories(Path_t path, bool include_hidden) { return _filtered_children(path, include_hidden, S_IFDIR); } -public Path_t Path$unique_directory(Path_t path) +public Path_t Pathヽunique_directory(Path_t path) { - path = Path$expand_home(path); - const char *path_str = Path$as_c_string(path); + path = Pathヽexpand_home(path); + const char *path_str = Pathヽas_c_string(path); size_t len = strlen(path_str); if (len >= PATH_MAX) fail("Path is too long: ", path_str); char buf[PATH_MAX] = {}; @@ -536,13 +536,13 @@ public Path_t Path$unique_directory(Path_t path) buf[--len] = '\0'; char *created = mkdtemp(buf); if (!created) fail("Failed to create temporary directory: ", path_str, " (", strerror(errno), ")"); - return Path$from_str(created); + return Pathヽfrom_str(created); } -public Path_t Path$write_unique_bytes(Path_t path, List_t bytes) +public Path_t Pathヽwrite_unique_bytes(Path_t path, List_t bytes) { - path = Path$expand_home(path); - const char *path_str = Path$as_c_string(path); + path = Pathヽexpand_home(path); + const char *path_str = Pathヽas_c_string(path); size_t len = strlen(path_str); if (len >= PATH_MAX) fail("Path is too long: ", path_str); char buf[PATH_MAX] = {}; @@ -560,56 +560,56 @@ public Path_t Path$write_unique_bytes(Path_t path, List_t bytes) fail("Could not write to unique file: ", buf, "\n", strerror(errno)); if (bytes.stride != 1) - List$compact(&bytes, 1); + Listヽcompact(&bytes, 1); ssize_t written = write(fd, bytes.data, (size_t)bytes.length); if (written != (ssize_t)bytes.length) fail("Could not write to file: ", buf, "\n", strerror(errno)); close(fd); - return Path$from_str(buf); + return Pathヽfrom_str(buf); } -public Path_t Path$write_unique(Path_t path, Text_t text) +public Path_t Pathヽwrite_unique(Path_t path, Text_t text) { - return Path$write_unique_bytes(path, Text$utf8_bytes(text)); + return Pathヽwrite_unique_bytes(path, Textヽutf8_bytes(text)); } -public Path_t Path$parent(Path_t path) +public Path_t Pathヽparent(Path_t path) { - if (path.type.$tag == PATH_ABSOLUTE && path.components.length == 0) { + if (path.type.ヽtag == PATH_ABSOLUTE && path.components.length == 0) { return path; - } else if (path.components.length > 0 && !Text$equal_values(*(Text_t*)(path.components.data + path.components.stride*(path.components.length-1)), + } else if (path.components.length > 0 && !Textヽequal_values(*(Text_t*)(path.components.data + path.components.stride*(path.components.length-1)), Text(".."))) { - return (Path_t){.type.$tag=path.type.$tag, .components=List$slice(path.components, I(1), I(-2))}; + return (Path_t){.type.ヽtag=path.type.ヽtag, .components=Listヽslice(path.components, I(1), I(-2))}; } else { - Path_t result = {.type.$tag=path.type.$tag, .components=path.components}; + Path_t result = {.type.ヽtag=path.type.ヽtag, .components=path.components}; LIST_INCREF(result.components); - List$insert_value(&result.components, Text(".."), I(0), sizeof(Text_t)); + Listヽinsert_value(&result.components, Text(".."), I(0), sizeof(Text_t)); return result; } } -public PUREFUNC Text_t Path$base_name(Path_t path) +public PUREFUNC Text_t Pathヽbase_name(Path_t path) { if (path.components.length >= 1) return *(Text_t*)(path.components.data + path.components.stride*(path.components.length-1)); - else if (path.type.$tag == PATH_HOME) + else if (path.type.ヽtag == PATH_HOME) return Text("~"); - else if (path.type.$tag == PATH_RELATIVE) + else if (path.type.ヽtag == PATH_RELATIVE) return Text("."); else return EMPTY_TEXT; } -public Text_t Path$extension(Path_t path, bool full) +public Text_t Pathヽextension(Path_t path, bool full) { - const char *base = Text$as_c_string(Path$base_name(path)); + const char *base = Textヽas_c_string(Pathヽbase_name(path)); const char *dot = full ? strchr(base + 1, '.') : strrchr(base + 1, '.'); const char *extension = dot ? dot + 1 : ""; - return Text$from_str(extension); + return Textヽfrom_str(extension); } -public bool Path$has_extension(Path_t path, Text_t extension) +public bool Pathヽhas_extension(Path_t path, Text_t extension) { if (path.components.length < 2) return extension.length == 0; @@ -617,57 +617,57 @@ public bool Path$has_extension(Path_t path, Text_t extension) Text_t last = *(Text_t*)(path.components.data + path.components.stride*(path.components.length-1)); if (extension.length == 0) - return !Text$has(Text$from(last, I(2)), Text(".")) || Text$equal_values(last, Text("..")); + return !Textヽhas(Textヽfrom(last, I(2)), Text(".")) || Textヽequal_values(last, Text("..")); - if (!Text$starts_with(extension, Text("."), NULL)) + if (!Textヽstarts_with(extension, Text("."), NULL)) extension = Texts(Text("."), extension); - return Text$ends_with(Text$from(last, I(2)), extension, NULL); + return Textヽends_with(Textヽfrom(last, I(2)), extension, NULL); } -public Path_t Path$child(Path_t path, Text_t name) +public Path_t Pathヽchild(Path_t path, Text_t name) { - if (Text$has(name, Text("/")) || Text$has(name, Text(";"))) + if (Textヽhas(name, Text("/")) || Textヽhas(name, Text(";"))) fail("Path name has invalid characters: ", name); Path_t result = { - .type.$tag=path.type.$tag, + .type.ヽtag=path.type.ヽtag, .components=path.components, }; LIST_INCREF(result.components); - List$insert(&result.components, &name, I(0), sizeof(Text_t)); + Listヽinsert(&result.components, &name, I(0), sizeof(Text_t)); clean_components(&result.components); return result; } -public Path_t Path$sibling(Path_t path, Text_t name) +public Path_t Pathヽsibling(Path_t path, Text_t name) { - return Path$child(Path$parent(path), name); + return Pathヽchild(Pathヽparent(path), name); } -public Path_t Path$with_extension(Path_t path, Text_t extension, bool replace) +public Path_t Pathヽwith_extension(Path_t path, Text_t extension, bool replace) { if (path.components.length == 0) fail("A path with no components can't have an extension!"); - if (Text$has(extension, Text("/")) || Text$has(extension, Text(";"))) + if (Textヽhas(extension, Text("/")) || Textヽhas(extension, Text(";"))) fail("Path extension has invalid characters: ", extension); Path_t result = { - .type.$tag=path.type.$tag, + .type.ヽtag=path.type.ヽtag, .components=path.components, }; LIST_INCREF(result.components); Text_t last = *(Text_t*)(path.components.data + path.components.stride*(path.components.length-1)); - List$remove_at(&result.components, I(-1), I(1), sizeof(Text_t)); + Listヽremove_at(&result.components, I(-1), I(1), sizeof(Text_t)); if (replace) { - const char *base = Text$as_c_string(last); + const char *base = Textヽas_c_string(last); const char *dot = strchr(base + 1, '.'); if (dot) - last = Text$from_strn(base, (size_t)(dot - base)); + last = Textヽfrom_strn(base, (size_t)(dot - base)); } - last = Text$concat(last, extension); - List$insert(&result.components, &last, I(0), sizeof(Text_t)); + last = Textヽconcat(last, extension); + Listヽinsert(&result.components, &last, I(0), sizeof(Text_t)); return result; } @@ -697,16 +697,16 @@ static Text_t _next_line(FILE **f) if (u8_check((uint8_t*)line, (size_t)len) != NULL) fail("Invalid UTF8!"); - Text_t line_text = Text$from_strn(line, (size_t)len); + Text_t line_text = Textヽfrom_strn(line, (size_t)len); free(line); return line_text; } -public OptionalClosure_t Path$by_line(Path_t path) +public OptionalClosure_t Pathヽby_line(Path_t path) { - path = Path$expand_home(path); + path = Pathヽexpand_home(path); - FILE *f = fopen(Path$as_c_string(path), "r"); + FILE *f = fopen(Pathヽas_c_string(path), "r"); if (f == NULL) return NONE_CLOSURE; @@ -716,10 +716,10 @@ public OptionalClosure_t Path$by_line(Path_t path) return (Closure_t){.fn=(void*)_next_line, .userdata=wrapper}; } -public List_t Path$glob(Path_t path) +public List_t Pathヽglob(Path_t path) { glob_t glob_result; - int status = glob(Path$as_c_string(path), GLOB_BRACE | GLOB_TILDE, NULL, &glob_result); + int status = glob(Pathヽas_c_string(path), GLOB_BRACE | GLOB_TILDE, NULL, &glob_result); if (status != 0 && status != GLOB_NOMATCH) fail("Failed to perform globbing"); @@ -729,100 +729,100 @@ public List_t Path$glob(Path_t path) if ((len >= 2 && glob_result.gl_pathv[i][len-1] == '.' && glob_result.gl_pathv[i][len-2] == '/') || (len >= 2 && glob_result.gl_pathv[i][len-1] == '.' && glob_result.gl_pathv[i][len-2] == '.' && glob_result.gl_pathv[i][len-3] == '/')) continue; - Path_t p = Path$from_str(glob_result.gl_pathv[i]); - List$insert(&glob_files, &p, I(0), sizeof(Path_t)); + Path_t p = Pathヽfrom_str(glob_result.gl_pathv[i]); + Listヽinsert(&glob_files, &p, I(0), sizeof(Path_t)); } return glob_files; } -public Path_t Path$current_dir(void) +public Path_t Pathヽcurrent_dir(void) { char cwd[PATH_MAX]; if (getcwd(cwd, sizeof(cwd)) == NULL) fail("Could not get current working directory"); - return Path$from_str(cwd); + return Pathヽfrom_str(cwd); } -public PUREFUNC uint64_t Path$hash(const void *obj, const TypeInfo_t *type) +public PUREFUNC uint64_t Pathヽhash(const void *obj, const TypeInfo_t *type) { (void)type; Path_t *path = (Path_t*)obj; siphash sh; - siphashinit(&sh, (uint64_t)path->type.$tag); + siphashinit(&sh, (uint64_t)path->type.ヽtag); for (int64_t i = 0; i < path->components.length; i++) { - uint64_t item_hash = Text$hash(path->components.data + i*path->components.stride, &Text$info); + uint64_t item_hash = Textヽhash(path->components.data + i*path->components.stride, &Textヽinfo); siphashadd64bits(&sh, item_hash); } return siphashfinish_last_part(&sh, (uint64_t)path->components.length); } -public PUREFUNC int32_t Path$compare(const void *va, const void *vb, const TypeInfo_t *type) +public PUREFUNC int32_t Pathヽcompare(const void *va, const void *vb, const TypeInfo_t *type) { (void)type; Path_t *a = (Path_t*)va, *b = (Path_t*)vb; - int diff = ((int)a->type.$tag - (int)b->type.$tag); + int diff = ((int)a->type.ヽtag - (int)b->type.ヽtag); if (diff != 0) return diff; - return List$compare(&a->components, &b->components, List$info(&Text$info)); + return Listヽcompare(&a->components, &b->components, Listヽinfo(&Textヽinfo)); } -public PUREFUNC bool Path$equal(const void *va, const void *vb, const TypeInfo_t *type) +public PUREFUNC bool Pathヽequal(const void *va, const void *vb, const TypeInfo_t *type) { (void)type; Path_t *a = (Path_t*)va, *b = (Path_t*)vb; - if (a->type.$tag != b->type.$tag) return false; - return List$equal(&a->components, &b->components, List$info(&Text$info)); + if (a->type.ヽtag != b->type.ヽtag) return false; + return Listヽequal(&a->components, &b->components, Listヽinfo(&Textヽinfo)); } -public PUREFUNC bool Path$equal_values(Path_t a, Path_t b) +public PUREFUNC bool Pathヽequal_values(Path_t a, Path_t b) { - if (a.type.$tag != b.type.$tag) return false; - return List$equal(&a.components, &b.components, List$info(&Text$info)); + if (a.type.ヽtag != b.type.ヽtag) return false; + return Listヽequal(&a.components, &b.components, Listヽinfo(&Textヽinfo)); } -public int Path$print(FILE *f, Path_t path) +public int Pathヽprint(FILE *f, Path_t path) { if (path.components.length == 0) { - if (path.type.$tag == PATH_ABSOLUTE) return fputs("/", f); - else if (path.type.$tag == PATH_RELATIVE) return fputs(".", f); - else if (path.type.$tag == PATH_HOME) return fputs("~", f); + if (path.type.ヽtag == PATH_ABSOLUTE) return fputs("/", f); + else if (path.type.ヽtag == PATH_RELATIVE) return fputs(".", f); + else if (path.type.ヽtag == PATH_HOME) return fputs("~", f); } int n = 0; - if (path.type.$tag == PATH_ABSOLUTE) { + if (path.type.ヽtag == PATH_ABSOLUTE) { n += fputc('/', f); - } else if (path.type.$tag == PATH_HOME) { + } else if (path.type.ヽtag == PATH_HOME) { n += fputs("~/", f); - } else if (path.type.$tag == PATH_RELATIVE) { - if (!Text$equal_values(*(Text_t*)path.components.data, Text(".."))) + } else if (path.type.ヽtag == PATH_RELATIVE) { + if (!Textヽequal_values(*(Text_t*)path.components.data, Text(".."))) n += fputs("./", f); } for (int64_t i = 0; i < path.components.length; i++) { Text_t *comp = (Text_t*)(path.components.data + i*path.components.stride); - n += Text$print(f, *comp); + n += Textヽprint(f, *comp); if (i + 1 < path.components.length) n += fputc('/', f); } return n; } -public const char *Path$as_c_string(Path_t path) +public const char *Pathヽas_c_string(Path_t path) { return String(path); } -public Text_t Path$as_text(const void *obj, bool color, const TypeInfo_t *type) +public Text_t Pathヽas_text(const void *obj, bool color, const TypeInfo_t *type) { (void)type; if (!obj) return Text("Path"); Path_t *path = (Path_t*)obj; - Text_t text = Text$join(Text("/"), path->components); - if (path->type.$tag == PATH_HOME) - text = Text$concat(path->components.length > 0 ? Text("~/") : Text("~"), text); - else if (path->type.$tag == PATH_ABSOLUTE) - text = Text$concat(Text("/"), text); - else if (path->type.$tag == PATH_RELATIVE && (path->components.length == 0 || !Text$equal_values(*(Text_t*)(path->components.data), Text("..")))) - text = Text$concat(path->components.length > 0 ? Text("./") : Text("."), text); + Text_t text = Textヽjoin(Text("/"), path->components); + if (path->type.ヽtag == PATH_HOME) + text = Textヽconcat(path->components.length > 0 ? Text("~/") : Text("~"), text); + else if (path->type.ヽtag == PATH_ABSOLUTE) + text = Textヽconcat(Text("/"), text); + else if (path->type.ヽtag == PATH_RELATIVE && (path->components.length == 0 || !Textヽequal_values(*(Text_t*)(path->components.data), Text("..")))) + text = Textヽconcat(path->components.length > 0 ? Text("./") : Text("."), text); if (color) text = Texts(Text("\033[32;1m"), text, Text("\033[m")); @@ -830,48 +830,48 @@ public Text_t Path$as_text(const void *obj, bool color, const TypeInfo_t *type) return text; } -public CONSTFUNC bool Path$is_none(const void *obj, const TypeInfo_t *type) +public CONSTFUNC bool Pathヽis_none(const void *obj, const TypeInfo_t *type) { (void)type; - return ((Path_t*)obj)->type.$tag == PATH_NONE; + return ((Path_t*)obj)->type.ヽtag == PATH_NONE; } -public void Path$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) +public void Pathヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) { (void)type; Path_t *path = (Path_t*)obj; - fputc((int)path->type.$tag, out); - List$serialize(&path->components, out, pointers, List$info(&Text$info)); + fputc((int)path->type.ヽtag, out); + Listヽserialize(&path->components, out, pointers, Listヽinfo(&Textヽinfo)); } -public void Path$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type) +public void Pathヽdeserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type) { (void)type; Path_t path = {}; - path.type.$tag = fgetc(in); - List$deserialize(in, &path.components, pointers, List$info(&Text$info)); + path.type.ヽtag = fgetc(in); + Listヽdeserialize(in, &path.components, pointers, Listヽinfo(&Textヽinfo)); *(Path_t*)obj = path; } -public const TypeInfo_t Path$info = { +public const TypeInfo_t Pathヽinfo = { .size=sizeof(Path_t), .align=__alignof__(Path_t), .tag=OpaqueInfo, .metamethods={ - .as_text=Path$as_text, - .hash=Path$hash, - .compare=Path$compare, - .equal=Path$equal, - .is_none=Path$is_none, - .serialize=Path$serialize, - .deserialize=Path$deserialize, + .as_text=Pathヽas_text, + .hash=Pathヽhash, + .compare=Pathヽcompare, + .equal=Pathヽequal, + .is_none=Pathヽis_none, + .serialize=Pathヽserialize, + .deserialize=Pathヽdeserialize, } }; -public const TypeInfo_t PathType$info = { +public const TypeInfo_t PathTypeヽinfo = { .size=sizeof(PathType_t), .align=__alignof__(PathType_t), - .metamethods=PackedDataEnum$metamethods, + .metamethods=PackedDataEnumヽmetamethods, .tag=EnumInfo, .EnumInfo={ .name="PathType", diff --git a/src/stdlib/paths.h b/src/stdlib/paths.h index 3a9cdef7..4ae78cd5 100644 --- a/src/stdlib/paths.h +++ b/src/stdlib/paths.h @@ -9,67 +9,67 @@ #include "datatypes.h" #include "optionals.h" -Path_t Path$from_str(const char *str); -Path_t Path$from_text(Text_t text); -// int Path$print(FILE *f, Path_t path); -const char *Path$as_c_string(Path_t path); -#define Path(str) Path$from_str(str) -Path_t Path$_concat(int n, Path_t items[n]); -#define Path$concat(...) Path$_concat((int)sizeof((Path_t[]){__VA_ARGS__})/sizeof(Path_t), ((Path_t[]){__VA_ARGS__})) -Path_t Path$resolved(Path_t path, Path_t relative_to); -Path_t Path$relative_to(Path_t path, Path_t relative_to); -Path_t Path$expand_home(Path_t path); -bool Path$exists(Path_t path); -bool Path$is_file(Path_t path, bool follow_symlinks); -bool Path$is_directory(Path_t path, bool follow_symlinks); -bool Path$is_pipe(Path_t path, bool follow_symlinks); -bool Path$is_socket(Path_t path, bool follow_symlinks); -bool Path$is_symlink(Path_t path); -bool Path$can_read(Path_t path); -bool Path$can_write(Path_t path); -bool Path$can_execute(Path_t path); -OptionalInt64_t Path$modified(Path_t path, bool follow_symlinks); -OptionalInt64_t Path$accessed(Path_t path, bool follow_symlinks); -OptionalInt64_t Path$changed(Path_t path, bool follow_symlinks); -void Path$write(Path_t path, Text_t text, int permissions); -void Path$write_bytes(Path_t path, List_t bytes, int permissions); -void Path$append(Path_t path, Text_t text, int permissions); -void Path$append_bytes(Path_t path, List_t bytes, int permissions); -OptionalText_t Path$read(Path_t path); -OptionalList_t Path$read_bytes(Path_t path, OptionalInt_t limit); -void Path$set_owner(Path_t path, OptionalText_t owner, OptionalText_t group, bool follow_symlinks); -OptionalText_t Path$owner(Path_t path, bool follow_symlinks); -OptionalText_t Path$group(Path_t path, bool follow_symlinks); -void Path$remove(Path_t path, bool ignore_missing); -void Path$create_directory(Path_t path, int permissions); -List_t Path$children(Path_t path, bool include_hidden); -List_t Path$files(Path_t path, bool include_hidden); -List_t Path$subdirectories(Path_t path, bool include_hidden); -Path_t Path$unique_directory(Path_t path); -Path_t Path$write_unique(Path_t path, Text_t text); -Path_t Path$write_unique_bytes(Path_t path, List_t bytes); -Path_t Path$parent(Path_t path); -Text_t Path$base_name(Path_t path); -Text_t Path$extension(Path_t path, bool full); -bool Path$has_extension(Path_t path, Text_t extension); -Path_t Path$child(Path_t path, Text_t name); -Path_t Path$sibling(Path_t path, Text_t name); -Path_t Path$with_extension(Path_t path, Text_t extension, bool replace); -Path_t Path$current_dir(void); -Closure_t Path$by_line(Path_t path); -List_t Path$glob(Path_t path); +Path_t Pathヽfrom_str(const char *str); +Path_t Pathヽfrom_text(Text_t text); +// int Pathヽprint(FILE *f, Path_t path); +const char *Pathヽas_c_string(Path_t path); +#define Path(str) Pathヽfrom_str(str) +Path_t Pathヽ_concat(int n, Path_t items[n]); +#define Pathヽconcat(...) Pathヽ_concat((int)sizeof((Path_t[]){__VA_ARGS__})/sizeof(Path_t), ((Path_t[]){__VA_ARGS__})) +Path_t Pathヽresolved(Path_t path, Path_t relative_to); +Path_t Pathヽrelative_to(Path_t path, Path_t relative_to); +Path_t Pathヽexpand_home(Path_t path); +bool Pathヽexists(Path_t path); +bool Pathヽis_file(Path_t path, bool follow_symlinks); +bool Pathヽis_directory(Path_t path, bool follow_symlinks); +bool Pathヽis_pipe(Path_t path, bool follow_symlinks); +bool Pathヽis_socket(Path_t path, bool follow_symlinks); +bool Pathヽis_symlink(Path_t path); +bool Pathヽcan_read(Path_t path); +bool Pathヽcan_write(Path_t path); +bool Pathヽcan_execute(Path_t path); +OptionalInt64_t Pathヽmodified(Path_t path, bool follow_symlinks); +OptionalInt64_t Pathヽaccessed(Path_t path, bool follow_symlinks); +OptionalInt64_t Pathヽchanged(Path_t path, bool follow_symlinks); +void Pathヽwrite(Path_t path, Text_t text, int permissions); +void Pathヽwrite_bytes(Path_t path, List_t bytes, int permissions); +void Pathヽappend(Path_t path, Text_t text, int permissions); +void Pathヽappend_bytes(Path_t path, List_t bytes, int permissions); +OptionalText_t Pathヽread(Path_t path); +OptionalList_t Pathヽread_bytes(Path_t path, OptionalInt_t limit); +void Pathヽset_owner(Path_t path, OptionalText_t owner, OptionalText_t group, bool follow_symlinks); +OptionalText_t Pathヽowner(Path_t path, bool follow_symlinks); +OptionalText_t Pathヽgroup(Path_t path, bool follow_symlinks); +void Pathヽremove(Path_t path, bool ignore_missing); +void Pathヽcreate_directory(Path_t path, int permissions); +List_t Pathヽchildren(Path_t path, bool include_hidden); +List_t Pathヽfiles(Path_t path, bool include_hidden); +List_t Pathヽsubdirectories(Path_t path, bool include_hidden); +Path_t Pathヽunique_directory(Path_t path); +Path_t Pathヽwrite_unique(Path_t path, Text_t text); +Path_t Pathヽwrite_unique_bytes(Path_t path, List_t bytes); +Path_t Pathヽparent(Path_t path); +Text_t Pathヽbase_name(Path_t path); +Text_t Pathヽextension(Path_t path, bool full); +bool Pathヽhas_extension(Path_t path, Text_t extension); +Path_t Pathヽchild(Path_t path, Text_t name); +Path_t Pathヽsibling(Path_t path, Text_t name); +Path_t Pathヽwith_extension(Path_t path, Text_t extension, bool replace); +Path_t Pathヽcurrent_dir(void); +Closure_t Pathヽby_line(Path_t path); +List_t Pathヽglob(Path_t path); -uint64_t Path$hash(const void *obj, const TypeInfo_t*); -int32_t Path$compare(const void *a, const void *b, const TypeInfo_t *type); -bool Path$equal(const void *a, const void *b, const TypeInfo_t *type); -bool Path$equal_values(Path_t a, Path_t b); -Text_t Path$as_text(const void *obj, bool color, const TypeInfo_t *type); -bool Path$is_none(const void *obj, const TypeInfo_t *type); -void Path$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); -void Path$deserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type); +uint64_t Pathヽhash(const void *obj, const TypeInfo_t*); +int32_t Pathヽcompare(const void *a, const void *b, const TypeInfo_t *type); +bool Pathヽequal(const void *a, const void *b, const TypeInfo_t *type); +bool Pathヽequal_values(Path_t a, Path_t b); +Text_t Pathヽas_text(const void *obj, bool color, const TypeInfo_t *type); +bool Pathヽis_none(const void *obj, const TypeInfo_t *type); +void Pathヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); +void Pathヽdeserialize(FILE *in, void *obj, List_t *pointers, const TypeInfo_t *type); -extern const TypeInfo_t Path$info; -extern const TypeInfo_t PathType$info; +extern const TypeInfo_t Pathヽinfo; +extern const TypeInfo_t PathTypeヽinfo; // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/pointers.c b/src/stdlib/pointers.c index 6874dd3c..08fce9e4 100644 --- a/src/stdlib/pointers.c +++ b/src/stdlib/pointers.c @@ -14,22 +14,22 @@ #include "types.h" #include "util.h" -public Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo_t *type) { +public Text_t Pointerヽas_text(const void *x, bool colorize, const TypeInfo_t *type) { __typeof(type->PointerInfo) ptr_info = type->PointerInfo; if (!x) { Text_t typename = generic_as_text(NULL, false, ptr_info.pointed); if (colorize) - return Text$concat(Text("\x1b[34;1m"), Text$from_str(ptr_info.sigil), typename, Text("\x1b[m")); + return Textヽconcat(Text("\x1b[34;1m"), Textヽfrom_str(ptr_info.sigil), typename, Text("\x1b[m")); else - return Text$concat(Text$from_str(ptr_info.sigil), typename); + return Textヽconcat(Textヽfrom_str(ptr_info.sigil), typename); } const void *ptr = *(const void**)x; if (!ptr) { Text_t typename = generic_as_text(NULL, false, ptr_info.pointed); if (colorize) - return Text$concat(Text("\x1b[34;1m!"), typename, Text("\x1b[m")); + return Textヽconcat(Text("\x1b[34;1m!"), typename, Text("\x1b[m")); else - return Text$concat(Text("!"), typename); + return Textヽconcat(Text("!"), typename); } static const void *root = NULL; @@ -41,17 +41,17 @@ public Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo_t *ty if (top_level) { root = ptr; } else if (ptr == root) { - Text_t text = Texts(Text$from_str(ptr_info.sigil), Text("~1")); + Text_t text = Texts(Textヽfrom_str(ptr_info.sigil), Text("~1")); return colorize ? Texts(Text("\x1b[34;1m"), text, Text("\x1b[m")) : text; } else { - TypeInfo_t rec_table = *Table$info(type, &Int64$info); - int64_t *id = Table$get(pending, x, &rec_table); + TypeInfo_t rec_table = *Tableヽinfo(type, &Int64ヽinfo); + int64_t *id = Tableヽget(pending, x, &rec_table); if (id) { - Text_t text = Texts(Text$from_str(ptr_info.sigil), Int64$as_text(id, false, &Int64$info)); + Text_t text = Texts(Textヽfrom_str(ptr_info.sigil), Int64ヽas_text(id, false, &Int64ヽinfo)); return colorize ? Texts(Text("\x1b[34;1m"), text, Text("\x1b[m")) : text; } int64_t next_id = pending.entries.length + 2; - Table$set(&pending, x, &next_id, &rec_table); + Tableヽset(&pending, x, &next_id, &rec_table); } Text_t pointed = generic_as_text(ptr, colorize, ptr_info.pointed); @@ -63,62 +63,62 @@ public Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo_t *ty Text_t text; if (colorize) - text = Text$concat(Text("\x1b[34;1m"), Text$from_str(ptr_info.sigil), Text("\x1b[m"), pointed); + text = Textヽconcat(Text("\x1b[34;1m"), Textヽfrom_str(ptr_info.sigil), Text("\x1b[m"), pointed); else - text = Text$concat(Text$from_str(ptr_info.sigil), pointed); + text = Textヽconcat(Textヽfrom_str(ptr_info.sigil), pointed); return text; } -PUREFUNC public int32_t Pointer$compare(const void *x, const void *y, const TypeInfo_t *info) { +PUREFUNC public int32_t Pointerヽcompare(const void *x, const void *y, const TypeInfo_t *info) { (void)info; const void *xp = *(const void**)x, *yp = *(const void**)y; return (xp > yp) - (xp < yp); } -PUREFUNC public bool Pointer$equal(const void *x, const void *y, const TypeInfo_t *info) { +PUREFUNC public bool Pointerヽequal(const void *x, const void *y, const TypeInfo_t *info) { (void)info; const void *xp = *(const void**)x, *yp = *(const void**)y; return xp == yp; } -PUREFUNC public bool Pointer$is_none(const void *x, const TypeInfo_t *info) +PUREFUNC public bool Pointerヽis_none(const void *x, const TypeInfo_t *info) { (void)info; return *(void**)x == NULL; } -public void Pointer$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) +public void Pointerヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) { void *ptr = *(void**)obj; assert(ptr != NULL); const TypeInfo_t ptr_to_int_table = {.size=sizeof(Table_t), .align=__alignof__(Table_t), - .tag=TableInfo, .TableInfo.key=type, .TableInfo.value=&Int64$info}; + .tag=TableInfo, .TableInfo.key=type, .TableInfo.value=&Int64ヽinfo}; - int64_t *id_ptr = Table$get(*pointers, &ptr, &ptr_to_int_table); + int64_t *id_ptr = Tableヽget(*pointers, &ptr, &ptr_to_int_table); int64_t id; if (id_ptr) { id = *id_ptr; } else { id = pointers->entries.length + 1; - Table$set(pointers, &ptr, &id, &ptr_to_int_table); + Tableヽset(pointers, &ptr, &id, &ptr_to_int_table); } - Int64$serialize(&id, out, pointers, &Int64$info); + Int64ヽserialize(&id, out, pointers, &Int64ヽinfo); if (!id_ptr) _serialize(ptr, out, pointers, type->PointerInfo.pointed); } -public void Pointer$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) +public void Pointerヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) { int64_t id = 0; - Int64$deserialize(in, &id, pointers, &Int64$info); + Int64ヽdeserialize(in, &id, pointers, &Int64ヽinfo); assert(id != 0); if (id > pointers->length) { void *obj = GC_MALLOC((size_t)type->PointerInfo.pointed->size); - List$insert(pointers, &obj, I(0), sizeof(void*)); + Listヽinsert(pointers, &obj, I(0), sizeof(void*)); _deserialize(in, obj, pointers, type->PointerInfo.pointed); *(void**)outval = obj; } else { diff --git a/src/stdlib/pointers.h b/src/stdlib/pointers.h index b818452e..b0711d5c 100644 --- a/src/stdlib/pointers.h +++ b/src/stdlib/pointers.h @@ -9,28 +9,28 @@ #include "types.h" #include "util.h" -Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo_t *type); -PUREFUNC int32_t Pointer$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Pointer$equal(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Pointer$is_none(const void *x, const TypeInfo_t*); -void Pointer$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); -void Pointer$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); +Text_t Pointerヽas_text(const void *x, bool colorize, const TypeInfo_t *type); +PUREFUNC int32_t Pointerヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Pointerヽequal(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Pointerヽis_none(const void *x, const TypeInfo_t*); +void Pointerヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); +void Pointerヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); #define Null(t) (t*)NULL #define POINTER_TYPE(_sigil, _pointed) (&(TypeInfo_t){\ .size=sizeof(void*), .align=alignof(void*), .tag=PointerInfo, .PointerInfo.sigil=_sigil, .PointerInfo.pointed=_pointed}) -#define Pointer$metamethods { \ - .as_text=Pointer$as_text, \ - .compare=Pointer$compare, \ - .equal=Pointer$equal, \ - .is_none=Pointer$is_none, \ - .serialize=Pointer$serialize, \ - .deserialize=Pointer$deserialize, \ +#define Pointerヽmetamethods { \ + .as_text=Pointerヽas_text, \ + .compare=Pointerヽcompare, \ + .equal=Pointerヽequal, \ + .is_none=Pointerヽis_none, \ + .serialize=Pointerヽserialize, \ + .deserialize=Pointerヽdeserialize, \ } -#define Pointer$info(sigil_expr, pointed_info) &((TypeInfo_t){.size=sizeof(void*), .align=__alignof__(void*), \ +#define Pointerヽinfo(sigil_expr, pointed_info) &((TypeInfo_t){.size=sizeof(void*), .align=__alignof__(void*), \ .tag=PointerInfo, .PointerInfo={.sigil=sigil_expr, .pointed=pointed_info}, \ - .metamethods=Pointer$metamethods}) + .metamethods=Pointerヽmetamethods}) // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/print.h b/src/stdlib/print.h index ce20152b..2dbe8373 100644 --- a/src/stdlib/print.h +++ b/src/stdlib/print.h @@ -96,9 +96,9 @@ PRINT_FN _print_repeated_char(FILE *f, repeated_char_t repeated) { return len; } -extern int Text$print(FILE *stream, Text_t text); -extern int Path$print(FILE *stream, Path_t path); -extern int Int$print(FILE *f, Int_t i); +extern int Textヽprint(FILE *stream, Text_t text); +extern int Pathヽprint(FILE *stream, Path_t path); +extern int Intヽprint(FILE *f, Int_t i); #ifndef _fprint1 #define _fprint1(f, x) _Generic((x), \ char*: _print_str, \ @@ -121,9 +121,9 @@ extern int Int$print(FILE *f, Int_t i); quoted_t: _print_quoted, \ string_slice_t: _print_string_slice, \ repeated_char_t: _print_repeated_char, \ - Text_t: Text$print, \ - Path_t: Path$print, \ - Int_t: Int$print, \ + Text_t: Textヽprint, \ + Path_t: Pathヽprint, \ + Int_t: Intヽprint, \ void*: _print_pointer)(f, x) #endif diff --git a/src/stdlib/stacktrace.c b/src/stdlib/stacktrace.c index 3904ae70..5e92f10f 100644 --- a/src/stdlib/stacktrace.c +++ b/src/stdlib/stacktrace.c @@ -119,7 +119,7 @@ public void print_stacktrace(FILE *out, int offset) const char *function = NULL, *filename = NULL; long line_num = 0; if (fparse(fp, &function, "\n", &filename, ":", &line_num) == NULL) { - if (starts_with(function, "main$")) + if (starts_with(function, "mainヽ")) main_func_onwards = true; if (main_func_onwards) _print_stack_frame(out, cwd, install_dir, function, filename, line_num); diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c index 02ccd710..1372d945 100644 --- a/src/stdlib/stdlib.c +++ b/src/stdlib/stdlib.c @@ -84,51 +84,51 @@ static bool parse_single_arg(const TypeInfo_t *info, char *arg, void *dest) while (info->tag == OptionalInfo) info = info->OptionalInfo.type; - if (info == &Int$info) { - OptionalInt_t parsed = Int$from_str(arg); + if (info == &Intヽinfo) { + OptionalInt_t parsed = Intヽfrom_str(arg); if (parsed.small != 0) *(OptionalInt_t*)dest = parsed; return parsed.small != 0; - } else if (info == &Int64$info) { - OptionalInt64_t parsed = Int64$parse(Text$from_str(arg), NULL); + } else if (info == &Int64ヽinfo) { + OptionalInt64_t parsed = Int64ヽparse(Textヽfrom_str(arg), NULL); if (!parsed.is_none) *(OptionalInt64_t*)dest = parsed; return !parsed.is_none; - } else if (info == &Int32$info) { - OptionalInt32_t parsed = Int32$parse(Text$from_str(arg), NULL); + } else if (info == &Int32ヽinfo) { + OptionalInt32_t parsed = Int32ヽparse(Textヽfrom_str(arg), NULL); if (!parsed.is_none) *(OptionalInt32_t*)dest = parsed; return !parsed.is_none; - } else if (info == &Int16$info) { - OptionalInt16_t parsed = Int16$parse(Text$from_str(arg), NULL); + } else if (info == &Int16ヽinfo) { + OptionalInt16_t parsed = Int16ヽparse(Textヽfrom_str(arg), NULL); if (!parsed.is_none) *(OptionalInt16_t*)dest = parsed; return !parsed.is_none; - } else if (info == &Int8$info) { - OptionalInt8_t parsed = Int8$parse(Text$from_str(arg), NULL); + } else if (info == &Int8ヽinfo) { + OptionalInt8_t parsed = Int8ヽparse(Textヽfrom_str(arg), NULL); if (!parsed.is_none) *(OptionalInt8_t*)dest = parsed; return !parsed.is_none; - } else if (info == &Bool$info) { - OptionalBool_t parsed = Bool$parse(Text$from_str(arg), NULL); + } else if (info == &Boolヽinfo) { + OptionalBool_t parsed = Boolヽparse(Textヽfrom_str(arg), NULL); if (parsed != NONE_BOOL) *(OptionalBool_t*)dest = parsed; return parsed != NONE_BOOL; - } else if (info == &Num$info) { - OptionalNum_t parsed = Num$parse(Text$from_str(arg), NULL); + } else if (info == &Numヽinfo) { + OptionalNum_t parsed = Numヽparse(Textヽfrom_str(arg), NULL); if (!isnan(parsed)) *(OptionalNum_t*)dest = parsed; return !isnan(parsed); - } else if (info == &Num32$info) { - OptionalNum32_t parsed = Num32$parse(Text$from_str(arg), NULL); + } else if (info == &Num32ヽinfo) { + OptionalNum32_t parsed = Num32ヽparse(Textヽfrom_str(arg), NULL); if (!isnan(parsed)) *(OptionalNum32_t*)dest = parsed; return !isnan(parsed); - } else if (info == &Path$info) { - *(OptionalPath_t*)dest = Path$from_str(arg); + } else if (info == &Pathヽinfo) { + *(OptionalPath_t*)dest = Pathヽfrom_str(arg); return true; } else if (info->tag == TextInfo) { - *(OptionalText_t*)dest = Text$from_str(arg); + *(OptionalText_t*)dest = Textヽfrom_str(arg); return true; } else if (info->tag == EnumInfo) { for (int t = 0; t < info->EnumInfo.num_tags; t++) { @@ -225,7 +225,7 @@ static Table_t parse_table(const TypeInfo_t *table, int n, char *args[]) *equals = '='; } - return Table$from_entries(entries, table); + return Tableヽfrom_entries(entries, table); } #ifdef __GNUC__ @@ -251,7 +251,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, while (non_opt_type->tag == OptionalInfo) non_opt_type = non_opt_type->OptionalInfo.type; - if (non_opt_type == &Bool$info + if (non_opt_type == &Boolヽinfo && strncmp(argv[i], "--no-", strlen("--no-")) == 0 && strcmp(argv[i] + strlen("--no-"), spec[s].name) == 0) { *(OptionalBool_t*)spec[s].dest = false; @@ -286,7 +286,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, } populated_args[s] = true; *(OptionalTable_t*)spec[s].dest = parse_table(non_opt_type, num_args, &argv[i+1]); - } else if (non_opt_type == &Bool$info) { // --flag + } else if (non_opt_type == &Boolヽinfo) { // --flag populated_args[s] = true; *(OptionalBool_t*)spec[s].dest = true; } else { @@ -351,7 +351,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, } populated_args[s] = true; *(OptionalTable_t*)spec[s].dest = parse_table(non_opt_type, num_args, &argv[i+1]); - } else if (non_opt_type == &Bool$info) { // -f + } else if (non_opt_type == &Boolヽinfo) { // -f populated_args[s] = true; *(OptionalBool_t*)spec[s].dest = true; } else { @@ -403,7 +403,7 @@ public void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, non_opt_type = non_opt_type->OptionalInfo.type; // You can't specify boolean flags positionally - if (non_opt_type == &Bool$info) + if (non_opt_type == &Boolヽinfo) goto next_non_bool_flag; if (non_opt_type->tag == ListInfo) { @@ -456,7 +456,7 @@ public _Noreturn void fail_text(Text_t message) public Text_t builtin_last_err() { - return Text$from_str(strerror(errno)); + return Textヽfrom_str(strerror(errno)); } static int _inspect_depth = 0; @@ -548,7 +548,7 @@ public void test_value(const char *filename, int64_t start, int64_t end, const v public void say(Text_t text, bool newline) { - Text$print(stdout, text); + Textヽprint(stdout, text); if (newline) fputc('\n', stdout); fflush(stdout); @@ -578,7 +578,7 @@ public OptionalText_t ask(Text_t prompt, bool bold, bool force_tty) } if (bold) fputs("\x1b[1m", out); - Text$print(out, prompt); + Textヽprint(out, prompt); if (bold) fputs("\x1b[m", out); fflush(out); @@ -604,7 +604,7 @@ public OptionalText_t ask(Text_t prompt, bool bold, bool force_tty) gc_input = GC_MALLOC_ATOMIC((size_t)(length + 1)); memcpy(gc_input, line, (size_t)(length + 1)); - ret = Text$from_strn(gc_input, (size_t)(length)); + ret = Textヽfrom_strn(gc_input, (size_t)(length)); cleanup: if (out && out != stdout) fclose(out); @@ -627,7 +627,7 @@ public bool pop_flag(char **argv, int *i, const char *flag, Text_t *result) *i += 1; return true; } else if (strncmp(argv[*i] + 2, flag, strlen(flag)) == 0 && argv[*i][2 + strlen(flag)] == '=') { - *result = Text$from_str(argv[*i] + 2 + strlen(flag) + 1); + *result = Textヽfrom_str(argv[*i] + 2 + strlen(flag) + 1); argv[*i] = NULL; *i += 1; return true; @@ -646,13 +646,13 @@ public void sleep_num(double seconds) public OptionalText_t getenv_text(Text_t name) { - const char *val = getenv(Text$as_c_string(name)); - return val ? Text$from_str(val) : NONE_TEXT; + const char *val = getenv(Textヽas_c_string(name)); + return val ? Textヽfrom_str(val) : NONE_TEXT; } public void setenv_text(Text_t name, Text_t value) { - setenv(Text$as_c_string(name), Text$as_c_string(value), 1); + setenv(Textヽas_c_string(name), Textヽas_c_string(value), 1); } // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/structs.c b/src/stdlib/structs.c index d4a22d93..3b42f2ac 100644 --- a/src/stdlib/structs.c +++ b/src/stdlib/structs.c @@ -18,7 +18,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstack-protector" #endif -PUREFUNC public uint64_t Struct$hash(const void *obj, const TypeInfo_t *type) +PUREFUNC public uint64_t Structヽhash(const void *obj, const TypeInfo_t *type) { if (type->StructInfo.num_fields == 0) return 0; @@ -31,7 +31,7 @@ PUREFUNC public uint64_t Struct$hash(const void *obj, const TypeInfo_t *type) ptrdiff_t bit_offset = 0; for (int i = 0; i < type->StructInfo.num_fields; i++) { NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { + if (field.type == &Boolヽinfo) { bool b = ((*(char*)(obj + byte_offset)) >> bit_offset) & 0x1; field_hashes[i] = (uint32_t)b; bit_offset += 1; @@ -56,7 +56,7 @@ PUREFUNC public uint64_t Struct$hash(const void *obj, const TypeInfo_t *type) #pragma GCC diagnostic pop #endif -PUREFUNC public uint64_t PackedData$hash(const void *obj, const TypeInfo_t *type) +PUREFUNC public uint64_t PackedDataヽhash(const void *obj, const TypeInfo_t *type) { if (type->StructInfo.num_fields == 0) return 0; @@ -64,7 +64,7 @@ PUREFUNC public uint64_t PackedData$hash(const void *obj, const TypeInfo_t *type return siphash24(obj, (size_t)type->size); } -PUREFUNC public int32_t Struct$compare(const void *x, const void *y, const TypeInfo_t *type) +PUREFUNC public int32_t Structヽcompare(const void *x, const void *y, const TypeInfo_t *type) { if (x == y) return 0; @@ -73,7 +73,7 @@ PUREFUNC public int32_t Struct$compare(const void *x, const void *y, const TypeI ptrdiff_t bit_offset = 0; for (int i = 0; i < type->StructInfo.num_fields; i++) { NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { + if (field.type == &Boolヽinfo) { bool bx = ((*(char*)(x + byte_offset)) >> bit_offset) & 0x1; bool by = ((*(char*)(y + byte_offset)) >> bit_offset) & 0x1; if (bx != by) @@ -99,7 +99,7 @@ PUREFUNC public int32_t Struct$compare(const void *x, const void *y, const TypeI return 0; } -PUREFUNC public bool Struct$equal(const void *x, const void *y, const TypeInfo_t *type) +PUREFUNC public bool Structヽequal(const void *x, const void *y, const TypeInfo_t *type) { if (x == y) return true; @@ -108,7 +108,7 @@ PUREFUNC public bool Struct$equal(const void *x, const void *y, const TypeInfo_t ptrdiff_t bit_offset = 0; for (int i = 0; i < type->StructInfo.num_fields; i++) { NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { + if (field.type == &Boolヽinfo) { bool bx = ((*(char*)(x + byte_offset)) >> bit_offset) & 0x1; bool by = ((*(char*)(y + byte_offset)) >> bit_offset) & 0x1; if (bx != by) @@ -133,35 +133,35 @@ PUREFUNC public bool Struct$equal(const void *x, const void *y, const TypeInfo_t return true; } -PUREFUNC public bool PackedData$equal(const void *x, const void *y, const TypeInfo_t *type) +PUREFUNC public bool PackedDataヽequal(const void *x, const void *y, const TypeInfo_t *type) { if (x == y) return true; return (memcmp(x, y, (size_t)type->size) == 0); } -PUREFUNC public Text_t Struct$as_text(const void *obj, bool colorize, const TypeInfo_t *type) +PUREFUNC public Text_t Structヽas_text(const void *obj, bool colorize, const TypeInfo_t *type) { - if (!obj) return Text$from_str(type->StructInfo.name); + if (!obj) return Textヽfrom_str(type->StructInfo.name); - Text_t name = Text$from_str(type->StructInfo.name); + Text_t name = Textヽfrom_str(type->StructInfo.name); if (type->StructInfo.is_secret || type->StructInfo.is_opaque) { - return colorize ? Texts(Text("\x1b[0;1m"), name, Text("\x1b[m(...)")) : Texts(name, Text("(...)")); + return colorize ? Texts(Text("\x1b[0;1m"), name, Text("\x1b[m(...)")) : Texts(name, "(...)"); } - Text_t text = colorize ? Texts(Text("\x1b[0;1m"), name, Text("\x1b[m(")) : Texts(name, Text("(")); + Text_t text = colorize ? Texts(Text("\x1b[0;1m"), name, Text("\x1b[m(")) : Texts(name, "("); ptrdiff_t byte_offset = 0; ptrdiff_t bit_offset = 0; for (int i = 0; i < type->StructInfo.num_fields; i++) { NamedType_t field = type->StructInfo.fields[i]; if (i > 0) - text = Text$concat(text, Text(", ")); + text = Textヽconcat(text, Text(", ")); if (type->StructInfo.num_fields > 1) - text = Text$concat(text, Text$from_str(field.name), Text("=")); + text = Textヽconcat(text, Textヽfrom_str(field.name), Text("=")); - if (field.type == &Bool$info) { + if (field.type == &Boolヽinfo) { bool b = ((*(char*)(obj + byte_offset)) >> bit_offset) & 0x1; - text = Text$concat(text, Text$from_str(colorize ? (b ? "\x1b[35myes\x1b[m" : "\x1b[35mno\x1b[m") : (b ? "yes" : "no"))); + text = Textヽconcat(text, Textヽfrom_str(colorize ? (b ? "\x1b[35myes\x1b[m" : "\x1b[35mno\x1b[m") : (b ? "yes" : "no"))); bit_offset += 1; if (bit_offset >= 8) { byte_offset += 1; @@ -174,25 +174,25 @@ PUREFUNC public Text_t Struct$as_text(const void *obj, bool colorize, const Type } if (field.type->align && byte_offset % field.type->align > 0) byte_offset += field.type->align - (byte_offset % field.type->align); - text = Text$concat(text, generic_as_text(obj + byte_offset, colorize, field.type)); + text = Textヽconcat(text, generic_as_text(obj + byte_offset, colorize, field.type)); byte_offset += field.type->size; } } - return Text$concat(text, Text(")")); + return Textヽconcat(text, Text(")")); } -PUREFUNC public bool Struct$is_none(const void *obj, const TypeInfo_t *type) +PUREFUNC public bool Structヽis_none(const void *obj, const TypeInfo_t *type) { return *(bool*)(obj + type->size); } -public void Struct$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) +public void Structヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) { ptrdiff_t byte_offset = 0; ptrdiff_t bit_offset = 0; for (int i = 0; i < type->StructInfo.num_fields; i++) { NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { + if (field.type == &Boolヽinfo) { bool b = ((*(char*)(obj + byte_offset)) >> bit_offset) & 0x1; fputc((int)b, out); bit_offset += 1; @@ -213,13 +213,13 @@ public void Struct$serialize(const void *obj, FILE *out, Table_t *pointers, cons } } -public void Struct$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) +public void Structヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) { ptrdiff_t byte_offset = 0; ptrdiff_t bit_offset = 0; for (int i = 0; i < type->StructInfo.num_fields; i++) { NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { + if (field.type == &Boolヽinfo) { bool b = (bool)fgetc(in); *(char*)(outval + byte_offset) |= (b << bit_offset); bit_offset += 1; diff --git a/src/stdlib/structs.h b/src/stdlib/structs.h index c9c6c40a..c04df1fc 100644 --- a/src/stdlib/structs.h +++ b/src/stdlib/structs.h @@ -7,34 +7,34 @@ #include "types.h" #include "util.h" -PUREFUNC uint64_t Struct$hash(const void *obj, const TypeInfo_t *type); -PUREFUNC uint64_t PackedData$hash(const void *obj, const TypeInfo_t *type); -PUREFUNC int32_t Struct$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Struct$equal(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool PackedData$equal(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC Text_t Struct$as_text(const void *obj, bool colorize, const TypeInfo_t *type); -PUREFUNC bool Struct$is_none(const void *obj, const TypeInfo_t *type); -void Struct$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); -void Struct$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); +PUREFUNC uint64_t Structヽhash(const void *obj, const TypeInfo_t *type); +PUREFUNC uint64_t PackedDataヽhash(const void *obj, const TypeInfo_t *type); +PUREFUNC int32_t Structヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Structヽequal(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool PackedDataヽequal(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC Text_t Structヽas_text(const void *obj, bool colorize, const TypeInfo_t *type); +PUREFUNC bool Structヽis_none(const void *obj, const TypeInfo_t *type); +void Structヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); +void Structヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); -#define Struct$metamethods { \ - .hash=Struct$hash, \ - .compare=Struct$compare, \ - .equal=Struct$equal, \ - .as_text=Struct$as_text, \ - .is_none=Struct$is_none, \ - .serialize=Struct$serialize, \ - .deserialize=Struct$deserialize, \ +#define Structヽmetamethods { \ + .hash=Structヽhash, \ + .compare=Structヽcompare, \ + .equal=Structヽequal, \ + .as_text=Structヽas_text, \ + .is_none=Structヽis_none, \ + .serialize=Structヽserialize, \ + .deserialize=Structヽdeserialize, \ } -#define PackedData$metamethods { \ - .hash=PackedData$hash, \ - .compare=Struct$compare, \ - .equal=PackedData$equal, \ - .as_text=Struct$as_text, \ - .is_none=Struct$is_none, \ - .serialize=Struct$serialize, \ - .deserialize=Struct$deserialize, \ +#define PackedDataヽmetamethods { \ + .hash=PackedDataヽhash, \ + .compare=Structヽcompare, \ + .equal=PackedDataヽequal, \ + .as_text=Structヽas_text, \ + .is_none=Structヽis_none, \ + .serialize=Structヽserialize, \ + .deserialize=Structヽdeserialize, \ } // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/tables.c b/src/stdlib/tables.c index 9301914c..284b6e83 100644 --- a/src/stdlib/tables.c +++ b/src/stdlib/tables.c @@ -50,17 +50,17 @@ static TypeInfo_t MemoryPointer = { .tag=PointerInfo, .PointerInfo={ .sigil="@", - .pointed=&Memory$info, + .pointed=&Memoryヽinfo, }, - .metamethods=Pointer$metamethods, + .metamethods=Pointerヽmetamethods, }; const TypeInfo_t CStrToVoidStarTable = { .size=sizeof(Table_t), .align=__alignof__(Table_t), .tag=TableInfo, - .TableInfo={.key=&CString$info, .value=&MemoryPointer}, - .metamethods=Table$metamethods, + .TableInfo={.key=&CStringヽinfo, .value=&MemoryPointer}, + .metamethods=Tableヽmetamethods, }; PUREFUNC static INLINE size_t entry_size(const TypeInfo_t *info) @@ -98,7 +98,7 @@ static INLINE void hshow(const Table_t *t) static void maybe_copy_on_write(Table_t *t, const TypeInfo_t *type) { if (t->entries.data_refcount != 0) - List$compact(&t->entries, (int64_t)entry_size(type)); + Listヽcompact(&t->entries, (int64_t)entry_size(type)); if (t->bucket_info && t->bucket_info->data_refcount != 0) { size_t size = sizeof(bucket_info_t) + sizeof(bucket_t[t->bucket_info->count]); @@ -108,7 +108,7 @@ static void maybe_copy_on_write(Table_t *t, const TypeInfo_t *type) } // Return address of value or NULL -PUREFUNC public void *Table$get_raw(Table_t t, const void *key, const TypeInfo_t *type) +PUREFUNC public void *Tableヽget_raw(Table_t t, const void *key, const TypeInfo_t *type) { assert(type->tag == TableInfo); if (!key || !t.bucket_info) return NULL; @@ -130,17 +130,17 @@ PUREFUNC public void *Table$get_raw(Table_t t, const void *key, const TypeInfo_t return NULL; } -PUREFUNC public void *Table$get(Table_t t, const void *key, const TypeInfo_t *type) +PUREFUNC public void *Tableヽget(Table_t t, const void *key, const TypeInfo_t *type) { assert(type->tag == TableInfo); for (const Table_t *iter = &t; iter; iter = iter->fallback) { - void *ret = Table$get_raw(*iter, key, type); + void *ret = Tableヽget_raw(*iter, key, type); if (ret) return ret; } return NULL; } -static void Table$set_bucket(Table_t *t, const void *entry, int32_t index, const TypeInfo_t *type) +static void Tableヽset_bucket(Table_t *t, const void *entry, int32_t index, const TypeInfo_t *type) { assert(t->bucket_info); hshow(t); @@ -202,9 +202,9 @@ static void hashmap_resize_buckets(Table_t *t, uint32_t new_capacity, const Type t->bucket_info->count = new_capacity; t->bucket_info->last_free = new_capacity-1; // Rehash: - for (int64_t i = 0; i < Table$length(*t); i++) { + for (int64_t i = 0; i < Tableヽlength(*t); i++) { hdebug("Rehashing ", i, "\n"); - Table$set_bucket(t, GET_ENTRY(*t, i), i, type); + Tableヽset_bucket(t, GET_ENTRY(*t, i), i, type); } hshow(t); @@ -216,7 +216,7 @@ static void hashmap_resize_buckets(Table_t *t, uint32_t new_capacity, const Type #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstack-protector" #endif -public void *Table$reserve(Table_t *t, const void *key, const void *value, const TypeInfo_t *type) +public void *Tableヽreserve(Table_t *t, const void *key, const void *value, const TypeInfo_t *type) { assert(type->tag == TableInfo); if (!t || !key) return NULL; @@ -230,7 +230,7 @@ public void *Table$reserve(Table_t *t, const void *key, const void *value, const hashmap_resize_buckets(t, 8, type); } else { // Check if we are clobbering a value: - void *value_home = Table$get_raw(*t, key, type); + void *value_home = Tableヽget_raw(*t, key, type); if (value_home) { // Update existing slot // Ensure that `value_home` is still inside t->entries, even if COW occurs ptrdiff_t offset = value_home - t->entries.data; @@ -256,7 +256,7 @@ public void *Table$reserve(Table_t *t, const void *key, const void *value, const if (!value && value_size > 0) { for (Table_t *iter = t->fallback; iter; iter = iter->fallback) { - value = Table$get_raw(*iter, key, type); + value = Tableヽget_raw(*iter, key, type); if (value) break; } } @@ -270,27 +270,27 @@ public void *Table$reserve(Table_t *t, const void *key, const void *value, const memcpy(buf + value_offset(type), value, (size_t)value_size); else if (value_size > 0) memset(buf + value_offset(type), 0, (size_t)value_size); - List$insert(&t->entries, buf, I(0), (int64_t)entry_size(type)); + Listヽinsert(&t->entries, buf, I(0), (int64_t)entry_size(type)); int64_t entry_index = t->entries.length-1; void *entry = GET_ENTRY(*t, entry_index); - Table$set_bucket(t, entry, entry_index, type); + Tableヽset_bucket(t, entry, entry_index, type); return entry + value_offset(type); } #ifdef __GNUC__ #pragma GCC diagnostic pop #endif -public void Table$set(Table_t *t, const void *key, const void *value, const TypeInfo_t *type) +public void Tableヽset(Table_t *t, const void *key, const void *value, const TypeInfo_t *type) { assert(type->tag == TableInfo); - (void)Table$reserve(t, key, value, type); + (void)Tableヽreserve(t, key, value, type); } -public void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type) +public void Tableヽremove(Table_t *t, const void *key, const TypeInfo_t *type) { assert(type->tag == TableInfo); - if (!t || Table$length(*t) == 0) return; + if (!t || Tableヽlength(*t) == 0) return; // TODO: this work doesn't need to be done if the key is already missing maybe_copy_on_write(t, type); @@ -358,7 +358,7 @@ public void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type) // Last entry is being removed, so clear it out to be safe: memset(GET_ENTRY(*t, last_entry), 0, entry_size(type)); - List$remove_at(&t->entries, I(t->entries.length), I(1), (int64_t)entry_size(type)); + Listヽremove_at(&t->entries, I(t->entries.length), I(1), (int64_t)entry_size(type)); int64_t bucket_to_clear; if (prev) { // Middle (or end) of a chain @@ -381,26 +381,26 @@ public void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type) hshow(t); } -CONSTFUNC public void *Table$entry(Table_t t, int64_t n) +CONSTFUNC public void *Tableヽentry(Table_t t, int64_t n) { - if (n < 1 || n > Table$length(t)) + if (n < 1 || n > Tableヽlength(t)) return NULL; return GET_ENTRY(t, n-1); } -public void Table$clear(Table_t *t) +public void Tableヽclear(Table_t *t) { memset(t, 0, sizeof(Table_t)); } -public Table_t Table$sorted(Table_t t, const TypeInfo_t *type) +public Table_t Tableヽsorted(Table_t t, const TypeInfo_t *type) { Closure_t cmp = (Closure_t){.fn=generic_compare, .userdata=(void*)type->TableInfo.key}; - List_t entries = List$sorted(t.entries, cmp, (int64_t)entry_size(type)); - return Table$from_entries(entries, type); + List_t entries = Listヽsorted(t.entries, cmp, (int64_t)entry_size(type)); + return Tableヽfrom_entries(entries, type); } -PUREFUNC public bool Table$equal(const void *vx, const void *vy, const TypeInfo_t *type) +PUREFUNC public bool Tableヽequal(const void *vx, const void *vy, const TypeInfo_t *type) { if (vx == vy) return true; Table_t *x = (Table_t*)vx, *y = (Table_t*)vy; @@ -419,7 +419,7 @@ PUREFUNC public bool Table$equal(const void *vx, const void *vy, const TypeInfo_ size_t offset = value_offset(type); for (int64_t i = 0; i < x->entries.length; i++) { void *x_key = x->entries.data + i*x->entries.stride; - void *y_value = Table$get_raw(*y, x_key, type); + void *y_value = Tableヽget_raw(*y, x_key, type); if (!y_value) return false; void *x_value = x_key + offset; if (!generic_equal(y_value, x_value, value_type)) @@ -428,7 +428,7 @@ PUREFUNC public bool Table$equal(const void *vx, const void *vy, const TypeInfo_ return true; } -PUREFUNC public int32_t Table$compare(const void *vx, const void *vy, const TypeInfo_t *type) +PUREFUNC public int32_t Tableヽcompare(const void *vx, const void *vy, const TypeInfo_t *type) { if (vx == vy) return 0; @@ -458,7 +458,7 @@ PUREFUNC public int32_t Table$compare(const void *vx, const void *vy, const Type max_x_key = key; void *x_value = key + value_offset(type); - void *y_value = Table$get_raw(*y, key, type); + void *y_value = Tableヽget_raw(*y, key, type); if (!y_value || (table.value->size > 0 && !generic_equal(x_value, y_value, table.value))) { if (mismatched_key == NULL || generic_compare(key, mismatched_key, table.key) < 0) @@ -475,7 +475,7 @@ PUREFUNC public int32_t Table$compare(const void *vx, const void *vy, const Type max_y_key = key; void *y_value = key + value_offset(type); - void *x_value = Table$get_raw(*x, key, type); + void *x_value = Tableヽget_raw(*x, key, type); if (!x_value || !generic_equal(x_value, y_value, table.value)) { if (mismatched_key == NULL || generic_compare(key, mismatched_key, table.key) < 0) mismatched_key = key; @@ -483,8 +483,8 @@ PUREFUNC public int32_t Table$compare(const void *vx, const void *vy, const Type } if (mismatched_key) { - void *x_value = Table$get_raw(*x, mismatched_key, type); - void *y_value = Table$get_raw(*y, mismatched_key, type); + void *x_value = Tableヽget_raw(*x, mismatched_key, type); + void *y_value = Tableヽget_raw(*y, mismatched_key, type); if (x_value && y_value) { return generic_compare(x_value, y_value, table.value); } else if (y_value) { @@ -515,7 +515,7 @@ PUREFUNC public int32_t Table$compare(const void *vx, const void *vy, const Type for (int64_t i = 0; i < x->entries.length; i++) { void *key = x->entries.data + x->entries.stride * i; void *x_value = key + value_offset(type); - void *y_value = Table$get_raw(*y, key, type); + void *y_value = Tableヽget_raw(*y, key, type); int32_t diff = generic_compare(x_value, y_value, table.value); if (diff != 0) return diff; } @@ -530,7 +530,7 @@ PUREFUNC public int32_t Table$compare(const void *vx, const void *vy, const Type return 0; } -PUREFUNC public uint64_t Table$hash(const void *obj, const TypeInfo_t *type) +PUREFUNC public uint64_t Tableヽhash(const void *obj, const TypeInfo_t *type) { assert(type->tag == TableInfo); Table_t *t = (Table_t*)obj; @@ -560,7 +560,7 @@ PUREFUNC public uint64_t Table$hash(const void *obj, const TypeInfo_t *type) t->entries.length, keys_hash, values_hash, - t->fallback ? Table$hash(t->fallback, type) : 0, + t->fallback ? Tableヽhash(t->fallback, type) : 0, }; t->hash = siphash24((void*)&components, sizeof(components)); if unlikely (t->hash == 0) @@ -568,47 +568,47 @@ PUREFUNC public uint64_t Table$hash(const void *obj, const TypeInfo_t *type) return t->hash; } -public Text_t Table$as_text(const void *obj, bool colorize, const TypeInfo_t *type) +public Text_t Tableヽas_text(const void *obj, bool colorize, const TypeInfo_t *type) { Table_t *t = (Table_t*)obj; assert(type->tag == TableInfo); __typeof(type->TableInfo) table = type->TableInfo; if (!t) { - if (table.value != &Void$info) - return Text$concat( + if (table.value != &Voidヽinfo) + return Textヽconcat( Text("{"), generic_as_text(NULL, false, table.key), Text("="), generic_as_text(NULL, false, table.value), Text("}")); else - return Text$concat( + return Textヽconcat( Text("|"), generic_as_text(NULL, false, table.key), Text("|")); } int64_t val_off = (int64_t)value_offset(type); - Text_t text = table.value == &Void$info ? Text("|") : Text("{"); - for (int64_t i = 0, length = Table$length(*t); i < length; i++) { + Text_t text = table.value == &Voidヽinfo ? Text("|") : Text("{"); + for (int64_t i = 0, length = Tableヽlength(*t); i < length; i++) { if (i > 0) - text = Text$concat(text, Text(", ")); + text = Textヽconcat(text, Text(", ")); void *entry = GET_ENTRY(*t, i); - text = Text$concat(text, generic_as_text(entry, colorize, table.key)); - if (table.value != &Void$info) - text = Text$concat(text, Text("="), generic_as_text(entry + val_off, colorize, table.value)); + text = Textヽconcat(text, generic_as_text(entry, colorize, table.key)); + if (table.value != &Voidヽinfo) + text = Textヽconcat(text, Text("="), generic_as_text(entry + val_off, colorize, table.value)); } if (t->fallback) { - text = Text$concat(text, Text("; fallback="), Table$as_text(t->fallback, colorize, type)); + text = Textヽconcat(text, Text("; fallback="), Tableヽas_text(t->fallback, colorize, type)); } - text = Text$concat(text, table.value == &Void$info ? Text("|") : Text("}")); + text = Textヽconcat(text, table.value == &Voidヽinfo ? Text("|") : Text("}")); return text; } -public Table_t Table$from_entries(List_t entries, const TypeInfo_t *type) +public Table_t Tableヽfrom_entries(List_t entries, const TypeInfo_t *type) { assert(type->tag == TableInfo); if (entries.length == 0) @@ -625,92 +625,92 @@ public Table_t Table$from_entries(List_t entries, const TypeInfo_t *type) size_t offset = value_offset(type); for (int64_t i = 0; i < entries.length; i++) { void *key = entries.data + i*entries.stride; - Table$set(&t, key, key + offset, type); + Tableヽset(&t, key, key + offset, type); } return t; } // Overlap is "set intersection" in formal terms -public Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo_t *type) +public Table_t Tableヽoverlap(Table_t a, Table_t b, const TypeInfo_t *type) { // Return a table such that t[k]==a[k] for all k such that a.has(k), b.has(k), and a[k]==b[k] Table_t result = {}; const size_t offset = value_offset(type); for (Table_t *t = &a; t; t = t->fallback) { - for (int64_t i = 0; i < Table$length(*t); i++) { + for (int64_t i = 0; i < Tableヽlength(*t); i++) { void *key = GET_ENTRY(*t, i); void *a_value = key + offset; - void *b_value = Table$get(b, key, type); + void *b_value = Tableヽget(b, key, type); if (b_value && generic_equal(a_value, b_value, type->TableInfo.value)) - Table$set(&result, key, a_value, type); + Tableヽset(&result, key, a_value, type); } } return result; } // With is "set union" in formal terms -public Table_t Table$with(Table_t a, Table_t b, const TypeInfo_t *type) +public Table_t Tableヽwith(Table_t a, Table_t b, const TypeInfo_t *type) { // return a table such that t[k]==b[k] for all k such that b.has(k), and t[k]==a[k] for all k such that a.has(k) and not b.has(k) Table_t result = {}; const size_t offset = value_offset(type); for (Table_t *t = &a; t; t = t->fallback) { - for (int64_t i = 0; i < Table$length(*t); i++) { + for (int64_t i = 0; i < Tableヽlength(*t); i++) { void *key = GET_ENTRY(*t, i); - Table$set(&result, key, key + offset, type); + Tableヽset(&result, key, key + offset, type); } } for (Table_t *t = &b; t; t = t->fallback) { - for (int64_t i = 0; i < Table$length(*t); i++) { + for (int64_t i = 0; i < Tableヽlength(*t); i++) { void *key = GET_ENTRY(*t, i); - Table$set(&result, key, key + offset, type); + Tableヽset(&result, key, key + offset, type); } } return result; } // Xor is "disjunctive union" or "symmetric difference" in formal terms -public Table_t Table$xor(Table_t a, Table_t b, const TypeInfo_t *type) +public Table_t Tableヽxor(Table_t a, Table_t b, const TypeInfo_t *type) { // return a table with elements in `a` or `b`, but not both Table_t result = {}; const size_t offset = value_offset(type); for (Table_t *t = &a; t; t = t->fallback) { - for (int64_t i = 0; i < Table$length(*t); i++) { + for (int64_t i = 0; i < Tableヽlength(*t); i++) { void *key = GET_ENTRY(*t, i); - if (Table$get(b, key, type) == NULL) - Table$set(&result, key, key + offset, type); + if (Tableヽget(b, key, type) == NULL) + Tableヽset(&result, key, key + offset, type); } } for (Table_t *t = &b; t; t = t->fallback) { - for (int64_t i = 0; i < Table$length(*t); i++) { + for (int64_t i = 0; i < Tableヽlength(*t); i++) { void *key = GET_ENTRY(*t, i); - if (Table$get(a, key, type) == NULL) - Table$set(&result, key, key + offset, type); + if (Tableヽget(a, key, type) == NULL) + Tableヽset(&result, key, key + offset, type); } } return result; } // Without is "set difference" in formal terms -public Table_t Table$without(Table_t a, Table_t b, const TypeInfo_t *type) +public Table_t Tableヽwithout(Table_t a, Table_t b, const TypeInfo_t *type) { // Return a table such that t[k]==a[k] for all k such that not b.has(k) or b[k] != a[k] Table_t result = {}; const size_t offset = value_offset(type); for (Table_t *t = &a; t; t = t->fallback) { - for (int64_t i = 0; i < Table$length(*t); i++) { + for (int64_t i = 0; i < Tableヽlength(*t); i++) { void *key = GET_ENTRY(*t, i); void *a_value = key + offset; - void *b_value = Table$get(b, key, type); + void *b_value = Tableヽget(b, key, type); if (!b_value || !generic_equal(a_value, b_value, type->TableInfo.value)) - Table$set(&result, key, a_value, type); + Tableヽset(&result, key, a_value, type); } } return result; } -public Table_t Table$with_fallback(Table_t t, OptionalTable_t fallback) +public Table_t Tableヽwith_fallback(Table_t t, OptionalTable_t fallback) { if (fallback.entries.length <= 0) { t.fallback = NULL; @@ -723,66 +723,66 @@ public Table_t Table$with_fallback(Table_t t, OptionalTable_t fallback) } } -PUREFUNC public bool Table$is_subset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type) +PUREFUNC public bool Tableヽis_subset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type) { if (a.entries.length > b.entries.length || (strict && a.entries.length == b.entries.length)) return false; - for (int64_t i = 0; i < Table$length(a); i++) { - void *found = Table$get_raw(b, GET_ENTRY(a, i), type); + for (int64_t i = 0; i < Tableヽlength(a); i++) { + void *found = Tableヽget_raw(b, GET_ENTRY(a, i), type); if (!found) return false; } return true; } -PUREFUNC public bool Table$is_superset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type) +PUREFUNC public bool Tableヽis_superset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type) { - return Table$is_subset_of(b, a, strict, type); + return Tableヽis_subset_of(b, a, strict, type); } -PUREFUNC public void *Table$str_get(Table_t t, const char *key) +PUREFUNC public void *Tableヽstr_get(Table_t t, const char *key) { - void **ret = Table$get(t, &key, &CStrToVoidStarTable); + void **ret = Tableヽget(t, &key, &CStrToVoidStarTable); return ret ? *ret : NULL; } -PUREFUNC public void *Table$str_get_raw(Table_t t, const char *key) +PUREFUNC public void *Tableヽstr_get_raw(Table_t t, const char *key) { - void **ret = Table$get_raw(t, &key, &CStrToVoidStarTable); + void **ret = Tableヽget_raw(t, &key, &CStrToVoidStarTable); return ret ? *ret : NULL; } -public void *Table$str_reserve(Table_t *t, const char *key, const void *value) +public void *Tableヽstr_reserve(Table_t *t, const char *key, const void *value) { - return Table$reserve(t, &key, &value, &CStrToVoidStarTable); + return Tableヽreserve(t, &key, &value, &CStrToVoidStarTable); } -public void Table$str_set(Table_t *t, const char *key, const void *value) +public void Tableヽstr_set(Table_t *t, const char *key, const void *value) { - Table$set(t, &key, &value, &CStrToVoidStarTable); + Tableヽset(t, &key, &value, &CStrToVoidStarTable); } -public void Table$str_remove(Table_t *t, const char *key) +public void Tableヽstr_remove(Table_t *t, const char *key) { - return Table$remove(t, &key, &CStrToVoidStarTable); + return Tableヽremove(t, &key, &CStrToVoidStarTable); } -CONSTFUNC public void *Table$str_entry(Table_t t, int64_t n) +CONSTFUNC public void *Tableヽstr_entry(Table_t t, int64_t n) { - return Table$entry(t, n); + return Tableヽentry(t, n); } -PUREFUNC public bool Table$is_none(const void *obj, const TypeInfo_t *info) +PUREFUNC public bool Tableヽis_none(const void *obj, const TypeInfo_t *info) { (void)info; return ((Table_t*)obj)->entries.length < 0; } -public void Table$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) +public void Tableヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) { Table_t *t = (Table_t*)obj; int64_t len = t->entries.length; - Int64$serialize(&len, out, pointers, &Int64$info); + Int64ヽserialize(&len, out, pointers, &Int64ヽinfo); size_t offset = value_offset(type); for (int64_t i = 0; i < len; i++) { @@ -793,17 +793,17 @@ public void Table$serialize(const void *obj, FILE *out, Table_t *pointers, const assert(fputc(t->fallback != NULL ? 1 : 0, out) != EOF); if (t->fallback) - Table$serialize(t->fallback, out, pointers, type); + Tableヽserialize(t->fallback, out, pointers, type); } #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstack-protector" #endif -public void Table$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) +public void Tableヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type) { int64_t len; - Int64$deserialize(in, &len, pointers, &Int$info); + Int64ヽdeserialize(in, &len, pointers, &Intヽinfo); Table_t t = {}; for (int64_t i = 0; i < len; i++) { @@ -812,12 +812,12 @@ public void Table$deserialize(FILE *in, void *outval, List_t *pointers, const Ty char value[type->TableInfo.value->size]; if (type->TableInfo.value->size > 0) _deserialize(in, value, pointers, type->TableInfo.value); - Table$set(&t, key, value, type); + Tableヽset(&t, key, value, type); } if (fgetc(in) != 0) { t.fallback = GC_MALLOC(sizeof(Table_t)); - Table$deserialize(in, t.fallback, pointers, type); + Tableヽdeserialize(in, t.fallback, pointers, type); } *(Table_t*)outval = t; diff --git a/src/stdlib/tables.h b/src/stdlib/tables.h index f80c16c3..eac8c7d8 100644 --- a/src/stdlib/tables.h +++ b/src/stdlib/tables.h @@ -13,94 +13,94 @@ #define Table(key_t, val_t, key_info, value_info, fb, N, ...) ({ \ struct { key_t k; val_t v; } ents[N] = {__VA_ARGS__}; \ - Table_t table = Table$from_entries((List_t){ \ + Table_t table = Tableヽfrom_entries((List_t){ \ .data=memcpy(GC_MALLOC(sizeof(ents)), ents, sizeof(ents)), \ .length=sizeof(ents)/sizeof(ents[0]), \ .stride=(void*)&ents[1] - (void*)&ents[0], \ - }, Table$info(key_info, value_info)); \ + }, Tableヽinfo(key_info, value_info)); \ table.fallback = fb; \ table; }) #define Set(item_t, item_info, N, ...) ({ \ item_t ents[N] = {__VA_ARGS__}; \ - Table_t set = Table$from_entries((List_t){ \ + Table_t set = Tableヽfrom_entries((List_t){ \ .data=memcpy(GC_MALLOC(sizeof(ents)), ents, sizeof(ents)), \ .length=sizeof(ents)/sizeof(ents[0]), \ .stride=(void*)&ents[1] - (void*)&ents[0], \ - }, Set$info(item_info)); \ + }, Setヽinfo(item_info)); \ set; }) -Table_t Table$from_entries(List_t entries, const TypeInfo_t *type); -void *Table$get(Table_t t, const void *key, const TypeInfo_t *type); -#define Table$get_optional(table_expr, key_t, val_t, key_expr, nonnull_var, nonnull_expr, null_expr, info_expr) ({ \ +Table_t Tableヽfrom_entries(List_t entries, const TypeInfo_t *type); +void *Tableヽget(Table_t t, const void *key, const TypeInfo_t *type); +#define Tableヽget_optional(table_expr, key_t, val_t, key_expr, nonnull_var, nonnull_expr, null_expr, info_expr) ({ \ const Table_t t = table_expr; const key_t k = key_expr; \ - val_t *nonnull_var = Table$get(t, &k, info_expr); \ + val_t *nonnull_var = Tableヽget(t, &k, info_expr); \ nonnull_var ? nonnull_expr : null_expr; }) -#define Table$get_or_setdefault(table_expr, key_t, val_t, key_expr, default_expr, info_expr) ({ \ +#define Tableヽget_or_setdefault(table_expr, key_t, val_t, key_expr, default_expr, info_expr) ({ \ Table_t *t = table_expr; const key_t k = key_expr; \ - if (t->entries.data_refcount > 0) List$compact(&t->entries, sizeof(struct {key_t k; val_t v;})); \ - val_t *v = Table$get(*t, &k, info_expr); \ - v ? v : (val_t*)Table$reserve(t, &k, (val_t[1]){default_expr}, info_expr); }) -#define Table$get_or_default(table_expr, key_t, val_t, key_expr, default_expr, info_expr) ({ \ + if (t->entries.data_refcount > 0) Listヽcompact(&t->entries, sizeof(struct {key_t k; val_t v;})); \ + val_t *v = Tableヽget(*t, &k, info_expr); \ + v ? v : (val_t*)Tableヽreserve(t, &k, (val_t[1]){default_expr}, info_expr); }) +#define Tableヽget_or_default(table_expr, key_t, val_t, key_expr, default_expr, info_expr) ({ \ const Table_t t = table_expr; const key_t k = key_expr; \ - val_t *v = Table$get(t, &k, info_expr); \ + val_t *v = Tableヽget(t, &k, info_expr); \ v ? *v : default_expr; }) -#define Table$has_value(table_expr, key_expr, info_expr) ({ \ +#define Tableヽhas_value(table_expr, key_expr, info_expr) ({ \ const Table_t t = table_expr; __typeof(key_expr) k = key_expr; \ - (Table$get(t, &k, info_expr) != NULL); }) -PUREFUNC void *Table$get_raw(Table_t t, const void *key, const TypeInfo_t *type); -CONSTFUNC void *Table$entry(Table_t t, int64_t n); -void *Table$reserve(Table_t *t, const void *key, const void *value, const TypeInfo_t *type); -void Table$set(Table_t *t, const void *key, const void *value, const TypeInfo_t *type); -#define Table$set_value(t, key_expr, value_expr, type) ({ __typeof(key_expr) k = key_expr; __typeof(value_expr) v = value_expr; \ - Table$set(t, &k, &v, type); }) -void Table$remove(Table_t *t, const void *key, const TypeInfo_t *type); -#define Table$remove_value(t, key_expr, type) ({ __typeof(key_expr) k = key_expr; Table$remove(t, &k, type); }) + (Tableヽget(t, &k, info_expr) != NULL); }) +PUREFUNC void *Tableヽget_raw(Table_t t, const void *key, const TypeInfo_t *type); +CONSTFUNC void *Tableヽentry(Table_t t, int64_t n); +void *Tableヽreserve(Table_t *t, const void *key, const void *value, const TypeInfo_t *type); +void Tableヽset(Table_t *t, const void *key, const void *value, const TypeInfo_t *type); +#define Tableヽset_value(t, key_expr, value_expr, type) ({ __typeof(key_expr) k = key_expr; __typeof(value_expr) v = value_expr; \ + Tableヽset(t, &k, &v, type); }) +void Tableヽremove(Table_t *t, const void *key, const TypeInfo_t *type); +#define Tableヽremove_value(t, key_expr, type) ({ __typeof(key_expr) k = key_expr; Tableヽremove(t, &k, type); }) -Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo_t *type); -Table_t Table$with(Table_t a, Table_t b, const TypeInfo_t *type); -Table_t Table$without(Table_t a, Table_t b, const TypeInfo_t *type); -Table_t Table$xor(Table_t a, Table_t b, const TypeInfo_t *type); -Table_t Table$with_fallback(Table_t t, OptionalTable_t fallback); -PUREFUNC bool Table$is_subset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type); -PUREFUNC bool Table$is_superset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type); +Table_t Tableヽoverlap(Table_t a, Table_t b, const TypeInfo_t *type); +Table_t Tableヽwith(Table_t a, Table_t b, const TypeInfo_t *type); +Table_t Tableヽwithout(Table_t a, Table_t b, const TypeInfo_t *type); +Table_t Tableヽxor(Table_t a, Table_t b, const TypeInfo_t *type); +Table_t Tableヽwith_fallback(Table_t t, OptionalTable_t fallback); +PUREFUNC bool Tableヽis_subset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type); +PUREFUNC bool Tableヽis_superset_of(Table_t a, Table_t b, bool strict, const TypeInfo_t *type); -void Table$clear(Table_t *t); -Table_t Table$sorted(Table_t t, const TypeInfo_t *type); -void Table$mark_copy_on_write(Table_t *t); +void Tableヽclear(Table_t *t); +Table_t Tableヽsorted(Table_t t, const TypeInfo_t *type); +void Tableヽmark_copy_on_write(Table_t *t); #define TABLE_INCREF(t) ({ LIST_INCREF((t).entries); if ((t).bucket_info) (t).bucket_info->data_refcount += ((t).bucket_info->data_refcount < TABLE_MAX_DATA_REFCOUNT); }) #define TABLE_COPY(t) ({ TABLE_INCREF(t); t; }) -PUREFUNC int32_t Table$compare(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC bool Table$equal(const void *x, const void *y, const TypeInfo_t *type); -PUREFUNC uint64_t Table$hash(const void *t, const TypeInfo_t *type); -Text_t Table$as_text(const void *t, bool colorize, const TypeInfo_t *type); -PUREFUNC bool Table$is_none(const void *obj, const TypeInfo_t*); +PUREFUNC int32_t Tableヽcompare(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC bool Tableヽequal(const void *x, const void *y, const TypeInfo_t *type); +PUREFUNC uint64_t Tableヽhash(const void *t, const TypeInfo_t *type); +Text_t Tableヽas_text(const void *t, bool colorize, const TypeInfo_t *type); +PUREFUNC bool Tableヽis_none(const void *obj, const TypeInfo_t*); -CONSTFUNC void *Table$str_entry(Table_t t, int64_t n); -PUREFUNC void *Table$str_get(Table_t t, const char *key); -PUREFUNC void *Table$str_get_raw(Table_t t, const char *key); -void Table$str_set(Table_t *t, const char *key, const void *value); -void *Table$str_reserve(Table_t *t, const char *key, const void *value); -void Table$str_remove(Table_t *t, const char *key); -void Table$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); -void Table$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); +CONSTFUNC void *Tableヽstr_entry(Table_t t, int64_t n); +PUREFUNC void *Tableヽstr_get(Table_t t, const char *key); +PUREFUNC void *Tableヽstr_get_raw(Table_t t, const char *key); +void Tableヽstr_set(Table_t *t, const char *key, const void *value); +void *Tableヽstr_reserve(Table_t *t, const char *key, const void *value); +void Tableヽstr_remove(Table_t *t, const char *key); +void Tableヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type); +void Tableヽdeserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_t *type); -#define Table$length(t) ((t).entries.length) +#define Tableヽlength(t) ((t).entries.length) extern const TypeInfo_t CStrToVoidStarTable; -#define Table$metamethods { \ - .as_text=Table$as_text, \ - .compare=Table$compare, \ - .equal=Table$equal, \ - .hash=Table$hash, \ - .is_none=Table$is_none, \ - .serialize=Table$serialize, \ - .deserialize=Table$deserialize, \ +#define Tableヽmetamethods { \ + .as_text=Tableヽas_text, \ + .compare=Tableヽcompare, \ + .equal=Tableヽequal, \ + .hash=Tableヽhash, \ + .is_none=Tableヽis_none, \ + .serialize=Tableヽserialize, \ + .deserialize=Tableヽdeserialize, \ } -#define Table$info(key_expr, value_expr) &((TypeInfo_t){.size=sizeof(Table_t), .align=__alignof__(Table_t), \ - .tag=TableInfo, .TableInfo.key=key_expr, .TableInfo.value=value_expr, .metamethods=Table$metamethods}) -#define Set$info(item_info) &((TypeInfo_t){.size=sizeof(Table_t), .align=__alignof__(Table_t), \ - .tag=TableInfo, .TableInfo.key=item_info, .TableInfo.value=&Void$info, .metamethods=Table$metamethods}) +#define Tableヽinfo(key_expr, value_expr) &((TypeInfo_t){.size=sizeof(Table_t), .align=__alignof__(Table_t), \ + .tag=TableInfo, .TableInfo.key=key_expr, .TableInfo.value=value_expr, .metamethods=Tableヽmetamethods}) +#define Setヽinfo(item_info) &((TypeInfo_t){.size=sizeof(Table_t), .align=__alignof__(Table_t), \ + .tag=TableInfo, .TableInfo.key=item_info, .TableInfo.value=&Voidヽinfo, .metamethods=Tableヽmetamethods}) // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1 diff --git a/src/stdlib/text.c b/src/stdlib/text.c index 8ef0874e..ec444bfe 100644 --- a/src/stdlib/text.c +++ b/src/stdlib/text.c @@ -195,8 +195,8 @@ public int32_t get_synthetic_grapheme(const ucs4_t *codepoints, int64_t utf32_le if (last_grapheme != 0 && graphemes_equal(&ptr, &synthetic_graphemes[-last_grapheme-1].utf32_cluster, NULL)) return last_grapheme; - TypeInfo_t GraphemeIDLookupTableInfo = *Table$info(&GraphemeClusterInfo, &Int32$info); - int32_t *found = Table$get(grapheme_ids_by_codepoints, &ptr, &GraphemeIDLookupTableInfo); + TypeInfo_t GraphemeIDLookupTableInfo = *Tableヽinfo(&GraphemeClusterInfo, &Int32ヽinfo); + int32_t *found = Tableヽget(grapheme_ids_by_codepoints, &ptr, &GraphemeIDLookupTableInfo); if (found) return *found; // New synthetic grapheme: @@ -266,7 +266,7 @@ public int32_t get_synthetic_grapheme(const ucs4_t *codepoints, int64_t utf32_le // Cleanup from unicode API: if (u8 != u8_buf) free(u8); - Table$set(&grapheme_ids_by_codepoints, &codepoint_copy, &grapheme_id, &GraphemeIDLookupTableInfo); + Tableヽset(&grapheme_ids_by_codepoints, &codepoint_copy, &grapheme_id, &GraphemeIDLookupTableInfo); last_grapheme = grapheme_id; return grapheme_id; @@ -275,7 +275,7 @@ public int32_t get_synthetic_grapheme(const ucs4_t *codepoints, int64_t utf32_le #pragma GCC diagnostic pop #endif -public int Text$print(FILE *stream, Text_t t) +public int Textヽprint(FILE *stream, Text_t t) { if (t.length == 0) return 0; @@ -321,8 +321,8 @@ public int Text$print(FILE *stream, Text_t t) return written; } case TEXT_CONCAT: { - int written = Text$print(stream, *t.left); - written += Text$print(stream, *t.right); + int written = Textヽprint(stream, *t.left); + written += Textヽprint(stream, *t.right); return written; } default: return 0; @@ -478,8 +478,8 @@ static Text_t concat2(Text_t a, Text_t b) if (a.length == 0) return b; if (b.length == 0) return a; - int32_t last_a = Text$get_grapheme(a, a.length-1); - int32_t first_b = Text$get_grapheme(b, 0); + int32_t last_a = Textヽget_grapheme(a, a.length-1); + int32_t first_b = Textヽget_grapheme(b, 0); // Magic number, we know that no codepoints below here trigger instability: static const int32_t LOWEST_CODEPOINT_TO_CHECK = 0x300; // COMBINING GRAVE ACCENT @@ -525,7 +525,7 @@ static Text_t concat2(Text_t a, Text_t b) return concat2_assuming_safe(a, b); } - Text_t glue = Text$from_codepoints((List_t){.data=norm_buf, .length=(int64_t)norm_length, .stride=sizeof(int32_t)}); + Text_t glue = Textヽfrom_codepoints((List_t){.data=norm_buf, .length=(int64_t)norm_length, .stride=sizeof(int32_t)}); if (normalized != norm_buf) free(normalized); @@ -533,16 +533,16 @@ static Text_t concat2(Text_t a, Text_t b) if (a.length == 1 && b.length == 1) return glue; else if (a.length == 1) - return concat2_assuming_safe(glue, Text$slice(b, I(2), I(b.length))); + return concat2_assuming_safe(glue, Textヽslice(b, I(2), I(b.length))); else if (b.length == 1) - return concat2_assuming_safe(Text$slice(a, I(1), I(a.length-1)), glue); + return concat2_assuming_safe(Textヽslice(a, I(1), I(a.length-1)), glue); else return concat2_assuming_safe( - concat2_assuming_safe(Text$slice(a, I(1), I(a.length-1)), glue), - Text$slice(b, I(2), I(b.length))); + concat2_assuming_safe(Textヽslice(a, I(1), I(a.length-1)), glue), + Textヽslice(b, I(2), I(b.length))); } -public Text_t Text$_concat(int n, Text_t items[n]) +public Text_t Textヽ_concat(int n, Text_t items[n]) { if (n == 0) return EMPTY_TEXT; @@ -554,35 +554,35 @@ public Text_t Text$_concat(int n, Text_t items[n]) return ret; } -public Text_t Text$repeat(Text_t text, Int_t count) +public Text_t Textヽrepeat(Text_t text, Int_t count) { - if (text.length == 0 || Int$is_negative(count)) + if (text.length == 0 || Intヽis_negative(count)) return EMPTY_TEXT; - Int_t result_len = Int$times(count, I(text.length)); - if (Int$compare_value(result_len, I(1l<<40)) > 0) + Int_t result_len = Intヽtimes(count, I(text.length)); + if (Intヽcompare_value(result_len, I(1l<<40)) > 0) fail("Text repeating would produce too big of an result!"); - int64_t count64 = Int64$from_int(count, false); + int64_t count64 = Int64ヽfrom_int(count, false); Text_t ret = text; for (int64_t c = 1; c < count64; c++) ret = concat2(ret, text); return ret; } -public Int_t Text$width(Text_t text, Text_t language) +public Int_t Textヽwidth(Text_t text, Text_t language) { - int width = u8_strwidth((const uint8_t*)Text$as_c_string(text), Text$as_c_string(language)); - return Int$from_int32(width); + int width = u8_strwidth((const uint8_t*)Textヽas_c_string(text), Textヽas_c_string(language)); + return Intヽfrom_int32(width); } -static Text_t Text$repeat_to_width(Text_t to_repeat, int64_t target_width, Text_t language) +static Text_t Textヽrepeat_to_width(Text_t to_repeat, int64_t target_width, Text_t language) { if (target_width <= 0) return EMPTY_TEXT; - const char *lang_str = Text$as_c_string(language); - int64_t width = (int64_t)u8_strwidth((const uint8_t*)Text$as_c_string(to_repeat), lang_str); + const char *lang_str = Textヽas_c_string(language); + int64_t width = (int64_t)u8_strwidth((const uint8_t*)Textヽas_c_string(to_repeat), lang_str); Text_t repeated = EMPTY_TEXT; int64_t repeated_width = 0; while (repeated_width + width <= target_width) { @@ -592,10 +592,10 @@ static Text_t Text$repeat_to_width(Text_t to_repeat, int64_t target_width, Text_ if (repeated_width < target_width) { for (int64_t i = 0; repeated_width < target_width && i < to_repeat.length; i++) { - Text_t c = Text$slice(to_repeat, I_small(i+1), I_small(i+1)); - int64_t w = (int64_t)u8_strwidth((const uint8_t*)Text$as_c_string(c), lang_str); + Text_t c = Textヽslice(to_repeat, I_small(i+1), I_small(i+1)); + int64_t w = (int64_t)u8_strwidth((const uint8_t*)Textヽas_c_string(c), lang_str); if (repeated_width + w > target_width) { - repeated = concat2(repeated, Text$repeat(Text(" "), I(target_width - repeated_width))); + repeated = concat2(repeated, Textヽrepeat(Text(" "), I(target_width - repeated_width))); repeated_width = target_width; break; } @@ -607,37 +607,37 @@ static Text_t Text$repeat_to_width(Text_t to_repeat, int64_t target_width, Text_ return repeated; } -public Text_t Text$left_pad(Text_t text, Int_t width, Text_t padding, Text_t language) +public Text_t Textヽleft_pad(Text_t text, Int_t width, Text_t padding, Text_t language) { if (padding.length == 0) fail("Cannot pad with an empty text!"); - int64_t needed = Int64$from_int(width, false) - Int64$from_int(Text$width(text, language), false); - return concat2(Text$repeat_to_width(padding, needed, language), text); + int64_t needed = Int64ヽfrom_int(width, false) - Int64ヽfrom_int(Textヽwidth(text, language), false); + return concat2(Textヽrepeat_to_width(padding, needed, language), text); } -public Text_t Text$right_pad(Text_t text, Int_t width, Text_t padding, Text_t language) +public Text_t Textヽright_pad(Text_t text, Int_t width, Text_t padding, Text_t language) { if (padding.length == 0) fail("Cannot pad with an empty text!"); - int64_t needed = Int64$from_int(width, false) - Int64$from_int(Text$width(text, language), false); - return concat2(text, Text$repeat_to_width(padding, needed, language)); + int64_t needed = Int64ヽfrom_int(width, false) - Int64ヽfrom_int(Textヽwidth(text, language), false); + return concat2(text, Textヽrepeat_to_width(padding, needed, language)); } -public Text_t Text$middle_pad(Text_t text, Int_t width, Text_t padding, Text_t language) +public Text_t Textヽmiddle_pad(Text_t text, Int_t width, Text_t padding, Text_t language) { if (padding.length == 0) fail("Cannot pad with an empty text!"); - int64_t needed = Int64$from_int(width, false) - Int64$from_int(Text$width(text, language), false); - return Texts(Text$repeat_to_width(padding, needed/2, language), text, Text$repeat_to_width(padding, (needed+1)/2, language)); + int64_t needed = Int64ヽfrom_int(width, false) - Int64ヽfrom_int(Textヽwidth(text, language), false); + return Texts(Textヽrepeat_to_width(padding, needed/2, language), text, Textヽrepeat_to_width(padding, (needed+1)/2, language)); } -public Text_t Text$slice(Text_t text, Int_t first_int, Int_t last_int) +public Text_t Textヽslice(Text_t text, Int_t first_int, Int_t last_int) { - int64_t first = Int64$from_int(first_int, false); - int64_t last = Int64$from_int(last_int, false); + int64_t first = Int64ヽfrom_int(first_int, false); + int64_t last = Int64ヽfrom_int(last_int, false); if (first == 0) fail("Invalid index: 0"); if (last == 0) return EMPTY_TEXT; @@ -660,8 +660,8 @@ public Text_t Text$slice(Text_t text, Int_t first_int, Int_t last_int) last -= text.left->length; text = *text.right; } else { - return concat2_assuming_safe(Text$slice(*text.left, I(first), I(text.length)), - Text$slice(*text.right, I(1), I(last-text.left->length))); + return concat2_assuming_safe(Textヽslice(*text.left, I(first), I(text.length)), + Textヽslice(*text.right, I(1), I(last-text.left->length))); } } @@ -694,17 +694,17 @@ public Text_t Text$slice(Text_t text, Int_t first_int, Int_t last_int) return EMPTY_TEXT; } -public Text_t Text$from(Text_t text, Int_t first) +public Text_t Textヽfrom(Text_t text, Int_t first) { - return Text$slice(text, first, I_small(-1)); + return Textヽslice(text, first, I_small(-1)); } -public Text_t Text$to(Text_t text, Int_t last) +public Text_t Textヽto(Text_t text, Int_t last) { - return Text$slice(text, I_small(1), last); + return Textヽslice(text, I_small(1), last); } -public Text_t Text$reversed(Text_t text) +public Text_t Textヽreversed(Text_t text) { switch (text.tag) { case TEXT_ASCII: { @@ -739,19 +739,19 @@ public Text_t Text$reversed(Text_t text) return ret; } case TEXT_CONCAT: { - return concat2_assuming_safe(Text$reversed(*text.right), Text$reversed(*text.left)); + return concat2_assuming_safe(Textヽreversed(*text.right), Textヽreversed(*text.left)); } default: errx(1, "Invalid tag"); } return EMPTY_TEXT; } -public PUREFUNC Text_t Text$cluster(Text_t text, Int_t index) +public PUREFUNC Text_t Textヽcluster(Text_t text, Int_t index) { - return Text$slice(text, index, index); + return Textヽslice(text, index, index); } -static Text_t Text$from_components(List_t graphemes, Table_t unique_clusters) +static Text_t Textヽfrom_components(List_t graphemes, Table_t unique_clusters) { struct { int32_t map[unique_clusters.entries.length]; @@ -771,7 +771,7 @@ static Text_t Text$from_components(List_t graphemes, Table_t unique_clusters) } for (int64_t i = 0; i < graphemes.length; i++) { int32_t g = *(int32_t*)(graphemes.data + i*graphemes.stride); - uint8_t *byte = Table$get(unique_clusters, &g, Table$info(&Int32$info, &Byte$info)); + uint8_t *byte = Tableヽget(unique_clusters, &g, Tableヽinfo(&Int32ヽinfo, &Byteヽinfo)); assert(byte); blob->bytes[i] = *byte; } @@ -787,7 +787,7 @@ static Text_t Text$from_components(List_t graphemes, Table_t unique_clusters) } } -public OptionalText_t Text$from_strn(const char *str, size_t len) +public OptionalText_t Textヽfrom_strn(const char *str, size_t len) { int64_t ascii_span = 0; for (size_t i = 0; i < len && isascii(str[i]); i++) @@ -820,23 +820,23 @@ public OptionalText_t Text$from_strn(const char *str, size_t len) uint32_t *u32s_normalized = u32_normalize(UNINORM_NFC, u32s, u32_len, buf2, &u32_normlen); int32_t g = get_synthetic_grapheme(u32s_normalized, (int64_t)u32_normlen); - List$insert(&graphemes, &g, I(0), sizeof(int32_t)); - Table$get_or_setdefault(&unique_clusters, int32_t, uint8_t, g, (uint8_t)unique_clusters.entries.length, Table$info(&Int32$info, &Byte$info)); + Listヽinsert(&graphemes, &g, I(0), sizeof(int32_t)); + Tableヽget_or_setdefault(&unique_clusters, int32_t, uint8_t, g, (uint8_t)unique_clusters.entries.length, Tableヽinfo(&Int32ヽinfo, &Byteヽinfo)); if (u32s != buf) free(u32s); if (u32s_normalized != buf2) free(u32s_normalized); if (unique_clusters.entries.length >= 256) { - return concat2_assuming_safe(Text$from_components(graphemes, unique_clusters), Text$from_strn(next, (size_t)(end-next))); + return concat2_assuming_safe(Textヽfrom_components(graphemes, unique_clusters), Textヽfrom_strn(next, (size_t)(end-next))); } } - return Text$from_components(graphemes, unique_clusters); + return Textヽfrom_components(graphemes, unique_clusters); } -public OptionalText_t Text$from_str(const char *str) +public OptionalText_t Textヽfrom_str(const char *str) { - return str ? Text$from_strn(str, strlen(str)) : Text(""); + return str ? Textヽfrom_strn(str, strlen(str)) : Text(""); } static void u8_buf_append(Text_t text, char **buf, int64_t *capacity, int64_t *i) @@ -924,7 +924,7 @@ static void u8_buf_append(Text_t text, char **buf, int64_t *capacity, int64_t *i } } -public char *Text$as_c_string(Text_t text) +public char *Textヽas_c_string(Text_t text) { int64_t capacity = text.length + 1; char *buf = GC_MALLOC_ATOMIC((size_t)capacity); @@ -939,7 +939,7 @@ public char *Text$as_c_string(Text_t text) return buf; } -PUREFUNC public uint64_t Text$hash(const void *obj, const TypeInfo_t *info) +PUREFUNC public uint64_t Textヽhash(const void *obj, const TypeInfo_t *info) { (void)info; Text_t text = *(Text_t*)obj; @@ -983,12 +983,12 @@ PUREFUNC public uint64_t Text$hash(const void *obj, const TypeInfo_t *info) case TEXT_CONCAT: { TextIter_t state = NEW_TEXT_ITER_STATE(text); for (int64_t i = 0; i + 1 < text.length; i += 2) { - tmp.chunks[0] = Text$get_grapheme_fast(&state, i); - tmp.chunks[1] = Text$get_grapheme_fast(&state, i+1); + tmp.chunks[0] = Textヽget_grapheme_fast(&state, i); + tmp.chunks[1] = Textヽget_grapheme_fast(&state, i+1); siphashadd64bits(&sh, tmp.whole); } - int32_t last = (text.length & 0x1) ? Text$get_grapheme_fast(&state, text.length-1) : 0; + int32_t last = (text.length & 0x1) ? Textヽget_grapheme_fast(&state, text.length-1) : 0; return siphashfinish_last_part(&sh, (uint64_t)last); } default: errx(1, "Invalid text"); @@ -996,7 +996,7 @@ PUREFUNC public uint64_t Text$hash(const void *obj, const TypeInfo_t *info) return 0; } -public int32_t Text$get_grapheme_fast(TextIter_t *state, int64_t index) +public int32_t Textヽget_grapheme_fast(TextIter_t *state, int64_t index) { if (index < 0) return 0; if (index >= state->stack[0].text.length) return 0; @@ -1047,13 +1047,13 @@ public int32_t Text$get_grapheme_fast(TextIter_t *state, int64_t index) return 0; } -public uint32_t Text$get_main_grapheme_fast(TextIter_t *state, int64_t index) +public uint32_t Textヽget_main_grapheme_fast(TextIter_t *state, int64_t index) { - int32_t g = Text$get_grapheme_fast(state, index); + int32_t g = Textヽget_grapheme_fast(state, index); return (g) >= 0 ? (ucs4_t)(g) : synthetic_graphemes[-(g)-1].main_codepoint; } -PUREFUNC public int32_t Text$compare(const void *va, const void *vb, const TypeInfo_t *info) +PUREFUNC public int32_t Textヽcompare(const void *va, const void *vb, const TypeInfo_t *info) { (void)info; if (va == vb) return 0; @@ -1064,8 +1064,8 @@ PUREFUNC public int32_t Text$compare(const void *va, const void *vb, const TypeI int64_t len = MAX(a.length, b.length); TextIter_t a_state = NEW_TEXT_ITER_STATE(a), b_state = NEW_TEXT_ITER_STATE(b); for (int64_t i = 0; i < len; i++) { - int32_t ai = Text$get_grapheme_fast(&a_state, i); - int32_t bi = Text$get_grapheme_fast(&b_state, i); + int32_t ai = Textヽget_grapheme_fast(&a_state, i); + int32_t bi = Textヽget_grapheme_fast(&b_state, i); if (ai == bi) continue; int32_t cmp; if (ai > 0 && bi > 0) { @@ -1095,20 +1095,20 @@ PUREFUNC public int32_t Text$compare(const void *va, const void *vb, const TypeI bool _matches(TextIter_t *text_state, TextIter_t *target_state, int64_t pos) { for (int64_t i = 0; i < target_state->stack[0].text.length; i++) { - int32_t text_i = Text$get_grapheme_fast(text_state, pos + i); - int32_t prefix_i = Text$get_grapheme_fast(target_state, i); + int32_t text_i = Textヽget_grapheme_fast(text_state, pos + i); + int32_t prefix_i = Textヽget_grapheme_fast(target_state, i); if (text_i != prefix_i) return false; } return true; } -PUREFUNC public bool Text$starts_with(Text_t text, Text_t prefix, Text_t *remainder) +PUREFUNC public bool Textヽstarts_with(Text_t text, Text_t prefix, Text_t *remainder) { if (text.length < prefix.length) return false; TextIter_t text_state = NEW_TEXT_ITER_STATE(text), prefix_state = NEW_TEXT_ITER_STATE(prefix); if (_matches(&text_state, &prefix_state, 0)) { - if (remainder) *remainder = Text$from(text, Int$from_int64(prefix.length + 1)); + if (remainder) *remainder = Textヽfrom(text, Intヽfrom_int64(prefix.length + 1)); return true; } else { if (remainder) *remainder = text; @@ -1116,13 +1116,13 @@ PUREFUNC public bool Text$starts_with(Text_t text, Text_t prefix, Text_t *remain } } -PUREFUNC public bool Text$ends_with(Text_t text, Text_t suffix, Text_t *remainder) +PUREFUNC public bool Textヽends_with(Text_t text, Text_t suffix, Text_t *remainder) { if (text.length < suffix.length) return false; TextIter_t text_state = NEW_TEXT_ITER_STATE(text), suffix_state = NEW_TEXT_ITER_STATE(suffix); if (_matches(&text_state, &suffix_state, text.length - suffix.length)) { - if (remainder) *remainder = Text$to(text, Int$from_int64(text.length - suffix.length)); + if (remainder) *remainder = Textヽto(text, Intヽfrom_int64(text.length - suffix.length)); return true; } else { if (remainder) *remainder = text; @@ -1130,45 +1130,45 @@ PUREFUNC public bool Text$ends_with(Text_t text, Text_t suffix, Text_t *remainde } } -public Text_t Text$without_prefix(Text_t text, Text_t prefix) +public Text_t Textヽwithout_prefix(Text_t text, Text_t prefix) { - return Text$starts_with(text, prefix, false) ? Text$slice(text, I(prefix.length + 1), I(text.length)) : text; + return Textヽstarts_with(text, prefix, false) ? Textヽslice(text, I(prefix.length + 1), I(text.length)) : text; } -public Text_t Text$without_suffix(Text_t text, Text_t suffix) +public Text_t Textヽwithout_suffix(Text_t text, Text_t suffix) { - return Text$ends_with(text, suffix, false) ? Text$slice(text, I(1), I(text.length - suffix.length)) : text; + return Textヽends_with(text, suffix, false) ? Textヽslice(text, I(1), I(text.length - suffix.length)) : text; } static bool _has_grapheme(TextIter_t *text, int32_t g) { for (int64_t t = 0; t < text->stack[0].text.length; t++) { - if (g == Text$get_grapheme_fast(text, t)) { + if (g == Textヽget_grapheme_fast(text, t)) { return true; } } return false; } -public Text_t Text$trim(Text_t text, Text_t to_trim, bool left, bool right) +public Text_t Textヽtrim(Text_t text, Text_t to_trim, bool left, bool right) { int64_t first = 0; TextIter_t text_state = NEW_TEXT_ITER_STATE(text), trim_state = NEW_TEXT_ITER_STATE(to_trim); if (left) { - while (first < text.length && _has_grapheme(&trim_state, Text$get_grapheme_fast(&text_state, first))) { + while (first < text.length && _has_grapheme(&trim_state, Textヽget_grapheme_fast(&text_state, first))) { first += 1; } } int64_t last = text.length-1; if (right) { - while (last >= first && _has_grapheme(&trim_state, Text$get_grapheme_fast(&text_state, last))) { + while (last >= first && _has_grapheme(&trim_state, Textヽget_grapheme_fast(&text_state, last))) { last -= 1; } } - return (first != 0 || last != text.length-1) ? Text$slice(text, I(first+1), I(last+1)) : text; + return (first != 0 || last != text.length-1) ? Textヽslice(text, I(first+1), I(last+1)) : text; } -public Text_t Text$translate(Text_t text, Table_t translations) +public Text_t Textヽtranslate(Text_t text, Table_t translations) { TextIter_t text_state = NEW_TEXT_ITER_STATE(text); Text_t result = EMPTY_TEXT; @@ -1180,7 +1180,7 @@ public Text_t Text$translate(Text_t text, Table_t translations) TextIter_t target_state = NEW_TEXT_ITER_STATE(entry->target); if (_matches(&text_state, &target_state, i)) { if (i > span_start) - result = concat2(result, Text$slice(text, I(span_start+1), I(i))); + result = concat2(result, Textヽslice(text, I(span_start+1), I(i))); result = concat2(result, entry->replacement); i += entry->target.length; @@ -1192,11 +1192,11 @@ public Text_t Text$translate(Text_t text, Table_t translations) found_match: continue; } if (span_start < text.length) - result = concat2(result, Text$slice(text, I(span_start+1), I(text.length))); + result = concat2(result, Textヽslice(text, I(span_start+1), I(text.length))); return result; } -public Text_t Text$replace(Text_t text, Text_t target, Text_t replacement) +public Text_t Textヽreplace(Text_t text, Text_t target, Text_t replacement) { TextIter_t text_state = NEW_TEXT_ITER_STATE(text), target_state = NEW_TEXT_ITER_STATE(target); Text_t result = EMPTY_TEXT; @@ -1204,7 +1204,7 @@ public Text_t Text$replace(Text_t text, Text_t target, Text_t replacement) for (int64_t i = 0; i < text.length; ) { if (_matches(&text_state, &target_state, i)) { if (i > span_start) - result = concat2(result, Text$slice(text, I(span_start+1), I(i))); + result = concat2(result, Textヽslice(text, I(span_start+1), I(i))); result = concat2(result, replacement); i += target.length; @@ -1214,11 +1214,11 @@ public Text_t Text$replace(Text_t text, Text_t target, Text_t replacement) } } if (span_start < text.length) - result = concat2(result, Text$slice(text, I(span_start+1), I(text.length))); + result = concat2(result, Textヽslice(text, I(span_start+1), I(text.length))); return result; } -public PUREFUNC bool Text$has(Text_t text, Text_t target) +public PUREFUNC bool Textヽhas(Text_t text, Text_t target) { TextIter_t text_state = NEW_TEXT_ITER_STATE(text), target_state = NEW_TEXT_ITER_STATE(target); for (int64_t i = 0; i < text.length; i++) { @@ -1228,10 +1228,10 @@ public PUREFUNC bool Text$has(Text_t text, Text_t target) return false; } -public List_t Text$split(Text_t text, Text_t delimiters) +public List_t Textヽsplit(Text_t text, Text_t delimiters) { if (delimiters.length == 0) - return Text$clusters(text); + return Textヽclusters(text); TextIter_t text_state = NEW_TEXT_ITER_STATE(text), delim_state = NEW_TEXT_ITER_STATE(delimiters); List_t splits = {}; @@ -1240,18 +1240,18 @@ public List_t Text$split(Text_t text, Text_t delimiters) while (i + span_len < text.length && !_matches(&text_state, &delim_state, i + span_len)) { span_len += 1; } - Text_t slice = Text$slice(text, I(i+1), I(i+span_len)); - List$insert(&splits, &slice, I(0), sizeof(slice)); + Text_t slice = Textヽslice(text, I(i+1), I(i+span_len)); + Listヽinsert(&splits, &slice, I(0), sizeof(slice)); i += span_len + delimiters.length; if (i == text.length) { Text_t empty = Text(""); - List$insert(&splits, &empty, I(0), sizeof(empty)); + Listヽinsert(&splits, &empty, I(0), sizeof(empty)); } } return splits; } -public List_t Text$split_any(Text_t text, Text_t delimiters) +public List_t Textヽsplit_any(Text_t text, Text_t delimiters) { if (delimiters.length == 0) return List(text); @@ -1260,19 +1260,19 @@ public List_t Text$split_any(Text_t text, Text_t delimiters) List_t splits = {}; for (int64_t i = 0; i < text.length; ) { int64_t span_len = 0; - while (i + span_len < text.length && !_has_grapheme(&delim_state, Text$get_grapheme_fast(&text_state, i + span_len))) { + while (i + span_len < text.length && !_has_grapheme(&delim_state, Textヽget_grapheme_fast(&text_state, i + span_len))) { span_len += 1; } bool trailing_delim = i + span_len < text.length; - Text_t slice = Text$slice(text, I(i+1), I(i+span_len)); - List$insert(&splits, &slice, I(0), sizeof(slice)); + Text_t slice = Textヽslice(text, I(i+1), I(i+span_len)); + Listヽinsert(&splits, &slice, I(0), sizeof(slice)); i += span_len + 1; - while (i < text.length && _has_grapheme(&delim_state, Text$get_grapheme_fast(&text_state, i))) { + while (i < text.length && _has_grapheme(&delim_state, Textヽget_grapheme_fast(&text_state, i))) { i += 1; } if (i >= text.length && trailing_delim) { Text_t empty = Text(""); - List$insert(&splits, &empty, I(0), sizeof(empty)); + Listヽinsert(&splits, &empty, I(0), sizeof(empty)); } } return splits; @@ -1306,12 +1306,12 @@ static OptionalText_t next_split(split_iter_state_t *state) while (i + span_len < text.length && !_matches(&state->state, &delim_state, i + span_len)) { span_len += 1; } - Text_t slice = Text$slice(text, I(i+1), I(i+span_len)); + Text_t slice = Textヽslice(text, I(i+1), I(i+span_len)); state->i = i + span_len + state->delimiter.length; return slice; } -public Closure_t Text$by_split(Text_t text, Text_t delimiter) +public Closure_t Textヽby_split(Text_t text, Text_t delimiter) { return (Closure_t){ .fn=(void*)next_split, @@ -1331,7 +1331,7 @@ static OptionalText_t next_split_any(split_iter_state_t *state) } if (state->delimiter.length == 0) { // special case - Text_t ret = Text$cluster(text, I(state->i+1)); + Text_t ret = Textヽcluster(text, I(state->i+1)); state->i += 1; return ret; } @@ -1339,19 +1339,19 @@ static OptionalText_t next_split_any(split_iter_state_t *state) TextIter_t delim_state = NEW_TEXT_ITER_STATE(state->delimiter); int64_t i = state->i; int64_t span_len = 0; - while (i + span_len < text.length && !_has_grapheme(&delim_state, Text$get_grapheme_fast(&state->state, i + span_len))) { + while (i + span_len < text.length && !_has_grapheme(&delim_state, Textヽget_grapheme_fast(&state->state, i + span_len))) { span_len += 1; } - Text_t slice = Text$slice(text, I(i+1), I(i+span_len)); + Text_t slice = Textヽslice(text, I(i+1), I(i+span_len)); i += span_len + 1; - while (i < text.length && _has_grapheme(&delim_state, Text$get_grapheme_fast(&state->state, i))) { + while (i < text.length && _has_grapheme(&delim_state, Textヽget_grapheme_fast(&state->state, i))) { i += 1; } state->i = i; return slice; } -public Closure_t Text$by_split_any(Text_t text, Text_t delimiters) +public Closure_t Textヽby_split_any(Text_t text, Text_t delimiters) { return (Closure_t){ .fn=(void*)next_split_any, @@ -1359,7 +1359,7 @@ public Closure_t Text$by_split_any(Text_t text, Text_t delimiters) }; } -PUREFUNC public bool Text$equal_values(Text_t a, Text_t b) +PUREFUNC public bool Textヽequal_values(Text_t a, Text_t b) { if (a.length != b.length) return false; @@ -1367,30 +1367,30 @@ PUREFUNC public bool Text$equal_values(Text_t a, Text_t b) TextIter_t a_state = NEW_TEXT_ITER_STATE(a), b_state = NEW_TEXT_ITER_STATE(b); // TODO: make this smarter and more efficient for (int64_t i = 0; i < len; i++) { - int32_t ai = Text$get_grapheme_fast(&a_state, i); - int32_t bi = Text$get_grapheme_fast(&b_state, i); + int32_t ai = Textヽget_grapheme_fast(&a_state, i); + int32_t bi = Textヽget_grapheme_fast(&b_state, i); if (ai != bi) return false; } return true; } -PUREFUNC public bool Text$equal(const void *a, const void *b, const TypeInfo_t *info) +PUREFUNC public bool Textヽequal(const void *a, const void *b, const TypeInfo_t *info) { (void)info; if (a == b) return true; - return Text$equal_values(*(Text_t*)a, *(Text_t*)b); + return Textヽequal_values(*(Text_t*)a, *(Text_t*)b); } -PUREFUNC public bool Text$equal_ignoring_case(Text_t a, Text_t b, Text_t language) +PUREFUNC public bool Textヽequal_ignoring_case(Text_t a, Text_t b, Text_t language) { if (a.length != b.length) return false; int64_t len = a.length; TextIter_t a_state = NEW_TEXT_ITER_STATE(a), b_state = NEW_TEXT_ITER_STATE(b); - const char *uc_language = Text$as_c_string(language); + const char *uc_language = Textヽas_c_string(language); for (int64_t i = 0; i < len; i++) { - int32_t ai = Text$get_grapheme_fast(&a_state, i); - int32_t bi = Text$get_grapheme_fast(&b_state, i); + int32_t ai = Textヽget_grapheme_fast(&a_state, i); + int32_t bi = Textヽget_grapheme_fast(&b_state, i); if (ai != bi) { const ucs4_t *a_codepoints = ai >= 0 ? (ucs4_t*)&ai : GRAPHEME_CODEPOINTS(ai); int64_t a_len = ai >= 0 ? 1 : NUM_GRAPHEME_CODEPOINTS(ai); @@ -1407,54 +1407,54 @@ PUREFUNC public bool Text$equal_ignoring_case(Text_t a, Text_t b, Text_t languag return true; } -public Text_t Text$upper(Text_t text, Text_t language) +public Text_t Textヽupper(Text_t text, Text_t language) { if (text.length == 0) return text; - List_t codepoints = Text$utf32_codepoints(text); - const char *uc_language = Text$as_c_string(language); + List_t codepoints = Textヽutf32_codepoints(text); + const char *uc_language = Textヽas_c_string(language); size_t out_len = 0; ucs4_t *upper = u32_toupper(codepoints.data, (size_t)codepoints.length, uc_language, UNINORM_NFC, NULL, &out_len); - Text_t ret = Text$from_codepoints((List_t){.data=upper, .length=(int64_t)out_len, .stride=sizeof(int32_t)}); + Text_t ret = Textヽfrom_codepoints((List_t){.data=upper, .length=(int64_t)out_len, .stride=sizeof(int32_t)}); return ret; } -public Text_t Text$lower(Text_t text, Text_t language) +public Text_t Textヽlower(Text_t text, Text_t language) { if (text.length == 0) return text; - List_t codepoints = Text$utf32_codepoints(text); - const char *uc_language = Text$as_c_string(language); + List_t codepoints = Textヽutf32_codepoints(text); + const char *uc_language = Textヽas_c_string(language); size_t out_len = 0; ucs4_t *lower = u32_tolower(codepoints.data, (size_t)codepoints.length, uc_language, UNINORM_NFC, NULL, &out_len); - Text_t ret = Text$from_codepoints((List_t){.data=lower, .length=(int64_t)out_len, .stride=sizeof(int32_t)}); + Text_t ret = Textヽfrom_codepoints((List_t){.data=lower, .length=(int64_t)out_len, .stride=sizeof(int32_t)}); return ret; } -public Text_t Text$title(Text_t text, Text_t language) +public Text_t Textヽtitle(Text_t text, Text_t language) { if (text.length == 0) return text; - List_t codepoints = Text$utf32_codepoints(text); - const char *uc_language = Text$as_c_string(language); + List_t codepoints = Textヽutf32_codepoints(text); + const char *uc_language = Textヽas_c_string(language); size_t out_len = 0; ucs4_t *title = u32_totitle(codepoints.data, (size_t)codepoints.length, uc_language, UNINORM_NFC, NULL, &out_len); - Text_t ret = Text$from_codepoints((List_t){.data=title, .length=(int64_t)out_len, .stride=sizeof(int32_t)}); + Text_t ret = Textヽfrom_codepoints((List_t){.data=title, .length=(int64_t)out_len, .stride=sizeof(int32_t)}); return ret; } -public Text_t Text$quoted(Text_t text, bool colorize, Text_t quotation_mark) +public Text_t Textヽquoted(Text_t text, bool colorize, Text_t quotation_mark) { if (quotation_mark.length != 1) fail("Invalid quote text: ", quotation_mark, " (must have length == 1)"); Text_t ret = colorize ? Text("\x1b[35m") : EMPTY_TEXT; - if (!Text$equal_values(quotation_mark, Text("\"")) && !Text$equal_values(quotation_mark, Text("'")) && !Text$equal_values(quotation_mark, Text("`"))) + if (!Textヽequal_values(quotation_mark, Text("\"")) && !Textヽequal_values(quotation_mark, Text("'")) && !Textヽequal_values(quotation_mark, Text("`"))) ret = concat2_assuming_safe(ret, Text("$")); ret = concat2_assuming_safe(ret, quotation_mark); - int32_t quote_char = Text$get_grapheme(quotation_mark, 0); + int32_t quote_char = Textヽget_grapheme(quotation_mark, 0); #define flush_unquoted() ({ \ if (unquoted_span > 0) { \ - ret = concat2_assuming_safe(ret, Text$slice(text, I(i-unquoted_span+1), I(i))); \ + ret = concat2_assuming_safe(ret, Textヽslice(text, I(i-unquoted_span+1), I(i))); \ unquoted_span = 0; \ } }) #define add_escaped(str) ({ \ @@ -1466,7 +1466,7 @@ public Text_t Text$quoted(Text_t text, bool colorize, Text_t quotation_mark) int64_t unquoted_span = 0; int64_t i = 0; for (i = 0; i < text.length; i++) { - int32_t g = Text$get_grapheme_fast(&state, i); + int32_t g = Textヽget_grapheme_fast(&state, i); switch (g) { case '\a': add_escaped("a"); break; case '\b': add_escaped("b"); break; @@ -1494,7 +1494,7 @@ public Text_t Text$quoted(Text_t text, bool colorize, Text_t quotation_mark) (g & 15) > 9 ? 'a' + (g & 15) - 10 : '0' + (g & 15), '\0', }; - ret = concat2_assuming_safe(ret, Text$from_strn(tmp, 2)); + ret = concat2_assuming_safe(ret, Textヽfrom_strn(tmp, 2)); if (colorize) ret = concat2_assuming_safe(ret, Text("\x1b[0;35m")); break; @@ -1524,10 +1524,10 @@ public Text_t Text$quoted(Text_t text, bool colorize, Text_t quotation_mark) return ret; } -public Text_t Text$as_text(const void *vtext, bool colorize, const TypeInfo_t *info) +public Text_t Textヽas_text(const void *vtext, bool colorize, const TypeInfo_t *info) { (void)info; - if (!vtext) return info && info->TextInfo.lang ? Text$from_str(info->TextInfo.lang) : Text("Text"); + if (!vtext) return info && info->TextInfo.lang ? Textヽfrom_str(info->TextInfo.lang) : Text("Text"); Text_t text = *(Text_t*)vtext; // Figure out the best quotation mark to use: @@ -1535,7 +1535,7 @@ public Text_t Text$as_text(const void *vtext, bool colorize, const TypeInfo_t *i has_single_quote = false, needs_escapes = false; TextIter_t state = NEW_TEXT_ITER_STATE(text); for (int64_t i = 0; i < text.length; i++) { - int32_t g = Text$get_grapheme_fast(&state, i); + int32_t g = Textヽget_grapheme_fast(&state, i); if (g == '"') { has_double_quote = true; } else if (g == '`') { @@ -1560,58 +1560,58 @@ public Text_t Text$as_text(const void *vtext, bool colorize, const TypeInfo_t *i else quote = Text("\""); - Text_t as_text = Text$quoted(text, colorize, quote); - if (info && info->TextInfo.lang && info != &Text$info) - as_text = Text$concat( + Text_t as_text = Textヽquoted(text, colorize, quote); + if (info && info->TextInfo.lang && info != &Textヽinfo) + as_text = Textヽconcat( colorize ? Text("\x1b[1m$") : Text("$"), - Text$from_str(info->TextInfo.lang), - colorize ? Text("\x1b[0m") : Text(""), + Textヽfrom_str(info->TextInfo.lang), + colorize ? Text("\x1b[0m") : EMPTY_TEXT, as_text); return as_text; } -public Text_t Text$join(Text_t glue, List_t pieces) +public Text_t Textヽjoin(Text_t glue, List_t pieces) { if (pieces.length == 0) return EMPTY_TEXT; Text_t result = *(Text_t*)pieces.data; for (int64_t i = 1; i < pieces.length; i++) { - result = Text$concat(result, glue, *(Text_t*)(pieces.data + i*pieces.stride)); + result = Textヽconcat(result, glue, *(Text_t*)(pieces.data + i*pieces.stride)); } return result; } -public List_t Text$clusters(Text_t text) +public List_t Textヽclusters(Text_t text) { List_t clusters = {}; for (int64_t i = 1; i <= text.length; i++) { - Text_t cluster = Text$slice(text, I(i), I(i)); - List$insert(&clusters, &cluster, I_small(0), sizeof(Text_t)); + Text_t cluster = Textヽslice(text, I(i), I(i)); + Listヽinsert(&clusters, &cluster, I_small(0), sizeof(Text_t)); } return clusters; } -public List_t Text$utf32_codepoints(Text_t text) +public List_t Textヽutf32_codepoints(Text_t text) { List_t codepoints = {.atomic=1}; TextIter_t state = NEW_TEXT_ITER_STATE(text); for (int64_t i = 0; i < text.length; i++) { - int32_t grapheme = Text$get_grapheme_fast(&state, i); + int32_t grapheme = Textヽget_grapheme_fast(&state, i); if (grapheme < 0) { for (int64_t c = 0; c < NUM_GRAPHEME_CODEPOINTS(grapheme); c++) { ucs4_t subg = GRAPHEME_CODEPOINTS(grapheme)[c]; - List$insert(&codepoints, &subg, I_small(0), sizeof(ucs4_t)); + Listヽinsert(&codepoints, &subg, I_small(0), sizeof(ucs4_t)); } } else { - List$insert(&codepoints, &grapheme, I_small(0), sizeof(ucs4_t)); + Listヽinsert(&codepoints, &grapheme, I_small(0), sizeof(ucs4_t)); } } return codepoints; } -public List_t Text$utf8_bytes(Text_t text) +public List_t Textヽutf8_bytes(Text_t text) { - const char *str = Text$as_c_string(text); + const char *str = Textヽas_c_string(text); return (List_t){.length=(int64_t)strlen(str), .stride=1, .atomic=1, .data=(void*)str}; } @@ -1625,31 +1625,31 @@ static INLINE const char *codepoint_name(ucs4_t c) return String(block->name, "-", hex(c, .no_prefix=true, .uppercase=true)); } -public List_t Text$codepoint_names(Text_t text) +public List_t Textヽcodepoint_names(Text_t text) { List_t names = {}; TextIter_t state = NEW_TEXT_ITER_STATE(text); for (int64_t i = 0; i < text.length; i++) { - int32_t grapheme = Text$get_grapheme_fast(&state, i); + int32_t grapheme = Textヽget_grapheme_fast(&state, i); if (grapheme < 0) { for (int64_t c = 0; c < NUM_GRAPHEME_CODEPOINTS(grapheme); c++) { const char *name = codepoint_name(GRAPHEME_CODEPOINTS(grapheme)[c]); - Text_t name_text = Text$from_str(name); - List$insert(&names, &name_text, I_small(0), sizeof(Text_t)); + Text_t name_text = Textヽfrom_str(name); + Listヽinsert(&names, &name_text, I_small(0), sizeof(Text_t)); } } else { const char *name = codepoint_name((ucs4_t)grapheme); - Text_t name_text = Text$from_str(name); - List$insert(&names, &name_text, I_small(0), sizeof(Text_t)); + Text_t name_text = Textヽfrom_str(name); + Listヽinsert(&names, &name_text, I_small(0), sizeof(Text_t)); } } return names; } -public Text_t Text$from_codepoints(List_t codepoints) +public Text_t Textヽfrom_codepoints(List_t codepoints) { if (codepoints.stride != sizeof(uint32_t)) - List$compact(&codepoints, sizeof(uint32_t)); + Listヽcompact(&codepoints, sizeof(uint32_t)); List_t graphemes = {}; Table_t unique_clusters = {}; @@ -1663,10 +1663,10 @@ public Text_t Text$from_codepoints(List_t codepoints) uint32_t *u32s_normalized = u32_normalize(UNINORM_NFC, pos, (size_t)(next-pos), buf, &u32_normlen); int32_t g = get_synthetic_grapheme(u32s_normalized, (int64_t)u32_normlen); - List$insert(&graphemes, &g, I(0), sizeof(int32_t)); - Table$get_or_setdefault( + Listヽinsert(&graphemes, &g, I(0), sizeof(int32_t)); + Tableヽget_or_setdefault( &unique_clusters, int32_t, uint8_t, g, (uint8_t)unique_clusters.entries.length, - Table$info(&Int32$info, &Byte$info)); + Tableヽinfo(&Int32ヽinfo, &Byteヽinfo)); if (u32s_normalized != buf) free(u32s_normalized); @@ -1676,52 +1676,52 @@ public Text_t Text$from_codepoints(List_t codepoints) .data=(void*)next, .stride=sizeof(int32_t), }; - return concat2_assuming_safe(Text$from_components(graphemes, unique_clusters), Text$from_codepoints(remaining_codepoints)); + return concat2_assuming_safe(Textヽfrom_components(graphemes, unique_clusters), Textヽfrom_codepoints(remaining_codepoints)); } } - return Text$from_components(graphemes, unique_clusters); + return Textヽfrom_components(graphemes, unique_clusters); } -public OptionalText_t Text$from_codepoint_names(List_t codepoint_names) +public OptionalText_t Textヽfrom_codepoint_names(List_t codepoint_names) { List_t codepoints = {}; for (int64_t i = 0; i < codepoint_names.length; i++) { Text_t *name = ((Text_t*)(codepoint_names.data + i*codepoint_names.stride)); - const char *name_str = Text$as_c_string(*name); + const char *name_str = Textヽas_c_string(*name); ucs4_t codepoint = unicode_name_character(name_str); if (codepoint == UNINAME_INVALID) return NONE_TEXT; - List$insert(&codepoints, &codepoint, I_small(0), sizeof(ucs4_t)); + Listヽinsert(&codepoints, &codepoint, I_small(0), sizeof(ucs4_t)); } - return Text$from_codepoints(codepoints); + return Textヽfrom_codepoints(codepoints); } -public OptionalText_t Text$from_bytes(List_t bytes) +public OptionalText_t Textヽfrom_bytes(List_t bytes) { if (bytes.stride != sizeof(int8_t)) - List$compact(&bytes, sizeof(int8_t)); + Listヽcompact(&bytes, sizeof(int8_t)); - return Text$from_strn(bytes.data, (size_t)bytes.length); + return Textヽfrom_strn(bytes.data, (size_t)bytes.length); } -public List_t Text$lines(Text_t text) +public List_t Textヽlines(Text_t text) { List_t lines = {}; TextIter_t state = NEW_TEXT_ITER_STATE(text); for (int64_t i = 0, line_start = 0; i < text.length; i++) { - int32_t grapheme = Text$get_grapheme_fast(&state, i); - if (grapheme == '\r' && Text$get_grapheme_fast(&state, i + 1) == '\n') { // CRLF - Text_t line = Text$slice(text, I(line_start+1), I(i)); - List$insert(&lines, &line, I_small(0), sizeof(Text_t)); + int32_t grapheme = Textヽget_grapheme_fast(&state, i); + if (grapheme == '\r' && Textヽget_grapheme_fast(&state, i + 1) == '\n') { // CRLF + Text_t line = Textヽslice(text, I(line_start+1), I(i)); + Listヽinsert(&lines, &line, I_small(0), sizeof(Text_t)); i += 1; // skip one extra for CR line_start = i + 1; } else if (grapheme == '\n') { // newline - Text_t line = Text$slice(text, I(line_start+1), I(i)); - List$insert(&lines, &line, I_small(0), sizeof(Text_t)); + Text_t line = Textヽslice(text, I(line_start+1), I(i)); + Listヽinsert(&lines, &line, I_small(0), sizeof(Text_t)); line_start = i + 1; } else if (i == text.length-1 && line_start != i) { // last line - Text_t line = Text$slice(text, I(line_start+1), I(i+1)); - List$insert(&lines, &line, I_small(0), sizeof(Text_t)); + Text_t line = Textヽslice(text, I(line_start+1), I(i+1)); + Listヽinsert(&lines, &line, I_small(0), sizeof(Text_t)); } } return lines; @@ -1736,17 +1736,17 @@ static OptionalText_t next_line(line_iter_state_t *state) { Text_t text = state->state.stack[0].text; for (int64_t i = state->i; i < text.length; i++) { - int32_t grapheme = Text$get_grapheme_fast(&state->state, i); - if (grapheme == '\r' && Text$get_grapheme_fast(&state->state, i + 1) == '\n') { // CRLF - Text_t line = Text$slice(text, I(state->i+1), I(i)); + int32_t grapheme = Textヽget_grapheme_fast(&state->state, i); + if (grapheme == '\r' && Textヽget_grapheme_fast(&state->state, i + 1) == '\n') { // CRLF + Text_t line = Textヽslice(text, I(state->i+1), I(i)); state->i = i + 2; // skip one extra for CR return line; } else if (grapheme == '\n') { // newline - Text_t line = Text$slice(text, I(state->i+1), I(i)); + Text_t line = Textヽslice(text, I(state->i+1), I(i)); state->i = i + 1; return line; } else if (i == text.length-1 && state->i != i) { // last line - Text_t line = Text$slice(text, I(state->i+1), I(i+1)); + Text_t line = Textヽslice(text, I(state->i+1), I(i+1)); state->i = i + 1; return line; } @@ -1754,7 +1754,7 @@ static OptionalText_t next_line(line_iter_state_t *state) return NONE_TEXT; } -public Closure_t Text$by_line(Text_t text) +public Closure_t Textヽby_line(Text_t text) { return (Closure_t){ .fn=(void*)next_line, @@ -1762,73 +1762,73 @@ public Closure_t Text$by_line(Text_t text) }; } -PUREFUNC public bool Text$is_none(const void *t, const TypeInfo_t *info) +PUREFUNC public bool Textヽis_none(const void *t, const TypeInfo_t *info) { (void)info; return ((Text_t*)t)->length < 0; } -public Int_t Text$memory_size(Text_t text) +public Int_t Textヽmemory_size(Text_t text) { switch (text.tag) { case TEXT_ASCII: - return Int$from_int64((int64_t)sizeof(Text_t) + (int64_t)sizeof(char[text.length])); + return Intヽfrom_int64((int64_t)sizeof(Text_t) + (int64_t)sizeof(char[text.length])); case TEXT_GRAPHEMES: - return Int$from_int64((int64_t)sizeof(Text_t) + (int64_t)sizeof(int32_t[text.length])); + return Intヽfrom_int64((int64_t)sizeof(Text_t) + (int64_t)sizeof(int32_t[text.length])); case TEXT_BLOB: - return Int$from_int64((int64_t)sizeof(Text_t) + (int64_t)((void*)text.blob.bytes - (void*)text.blob.map) + (int64_t)sizeof(uint8_t[text.length])); + return Intヽfrom_int64((int64_t)sizeof(Text_t) + (int64_t)((void*)text.blob.bytes - (void*)text.blob.map) + (int64_t)sizeof(uint8_t[text.length])); case TEXT_CONCAT: - return Int$plus( - Int$from_int64((int64_t)sizeof(Text_t)), - Int$plus(Text$memory_size(*text.left), Text$memory_size(*text.right))); + return Intヽplus( + Intヽfrom_int64((int64_t)sizeof(Text_t)), + Intヽplus(Textヽmemory_size(*text.left), Textヽmemory_size(*text.right))); default: errx(1, "Invalid text tag: ", text.tag); } } -public Text_t Text$layout(Text_t text) +public Text_t Textヽlayout(Text_t text) { switch (text.tag) { case TEXT_ASCII: - return Texts(Text("ASCII("), Int64$as_text((int64_t[1]){text.length}, false, NULL), Text(")")); + return Texts(Text("ASCII("), Int64ヽas_text((int64_t[1]){text.length}, false, NULL), Text(")")); case TEXT_GRAPHEMES: - return Texts(Text("Graphemes("), Int64$as_text((int64_t[1]){text.length}, false, NULL), Text(")")); + return Texts(Text("Graphemes("), Int64ヽas_text((int64_t[1]){text.length}, false, NULL), Text(")")); case TEXT_BLOB: - return Texts(Text("Blob("), Int64$as_text((int64_t[1]){text.length}, false, NULL), Text(")")); + return Texts(Text("Blob("), Int64ヽas_text((int64_t[1]){text.length}, false, NULL), Text(")")); case TEXT_CONCAT: - return Texts(Text("Concat("), Text$layout(*text.left), Text(", "), Text$layout(*text.right), Text(")")); + return Texts(Text("Concat("), Textヽlayout(*text.left), Text(", "), Textヽlayout(*text.right), Text(")")); default: errx(1, "Invalid text tag: ", text.tag); } } -public void Text$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) +public void Textヽserialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *info) { (void)info; - const char *str = Text$as_c_string(*(Text_t*)obj); + const char *str = Textヽas_c_string(*(Text_t*)obj); int64_t len = (int64_t)strlen(str); - Int64$serialize(&len, out, pointers, &Int64$info); + Int64ヽserialize(&len, out, pointers, &Int64ヽinfo); fwrite(str, sizeof(char), (size_t)len, out); } -public void Text$deserialize(FILE *in, void *out, List_t *pointers, const TypeInfo_t *info) +public void Textヽdeserialize(FILE *in, void *out, List_t *pointers, const TypeInfo_t *info) { (void)info; int64_t len = 0; - Int64$deserialize(in, &len, pointers, &Int64$info); + Int64ヽdeserialize(in, &len, pointers, &Int64ヽinfo); if (len < 0) fail("Cannot deserialize text with a negative length!"); char *buf = GC_MALLOC_ATOMIC((size_t)len+1); if (fread(buf, sizeof(char), (size_t)len, in) != (size_t)len) fail("Not enough data in stream to deserialize"); buf[len+1] = '\0'; - *(Text_t*)out = Text$from_strn(buf, (size_t)len); + *(Text_t*)out = Textヽfrom_strn(buf, (size_t)len); } -public const TypeInfo_t Text$info = { +public const TypeInfo_t Textヽinfo = { .size=sizeof(Text_t), .align=__alignof__(Text_t), .tag=TextInfo, .TextInfo={.lang="Text"}, - .metamethods=Text$metamethods, + .metamethods=Textヽmetamethods, }; // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/text.h b/src/stdlib/text.h index 637a3db7..87e7dcb5 100644 --- a/src/stdlib/text.h +++ b/src/stdlib/text.h @@ -35,82 +35,82 @@ static inline Text_t Text_from_text(Text_t t) { return t; } -#define convert_to_text(x) _Generic(x, Text_t: Text_from_text, char*: Text$from_str, const char*: Text$from_str)(x) +#define convert_to_text(x) _Generic(x, Text_t: Text_from_text, char*: Textヽfrom_str, const char*: Textヽfrom_str)(x) -Text_t Text$_concat(int n, Text_t items[n]); -#define Text$concat(...) Text$_concat(sizeof((Text_t[]){__VA_ARGS__})/sizeof(Text_t), (Text_t[]){__VA_ARGS__}) -#define Texts(...) Text$concat(MAP_LIST(convert_to_text, __VA_ARGS__)) -// int Text$print(FILE *stream, Text_t t); -Text_t Text$slice(Text_t text, Int_t first_int, Int_t last_int); -Text_t Text$from(Text_t text, Int_t first); -Text_t Text$to(Text_t text, Int_t last); -Text_t Text$reversed(Text_t text); -Text_t Text$cluster(Text_t text, Int_t index_int); -OptionalText_t Text$from_str(const char *str); -OptionalText_t Text$from_strn(const char *str, size_t len); -PUREFUNC uint64_t Text$hash(const void *text, const TypeInfo_t*); -PUREFUNC int32_t Text$compare(const void *va, const void *vb, const TypeInfo_t*); -PUREFUNC bool Text$equal(const void *a, const void *b, const TypeInfo_t*); -PUREFUNC bool Text$equal_values(Text_t a, Text_t b); -PUREFUNC bool Text$equal_ignoring_case(Text_t a, Text_t b, Text_t language); -PUREFUNC bool Text$is_none(const void *t, const TypeInfo_t*); -Text_t Text$upper(Text_t text, Text_t language); -Text_t Text$lower(Text_t text, Text_t language); -Text_t Text$title(Text_t text, Text_t language); -Text_t Text$as_text(const void *text, bool colorize, const TypeInfo_t *info); -Text_t Text$quoted(Text_t str, bool colorize, Text_t quotation_mark); -PUREFUNC bool Text$starts_with(Text_t text, Text_t prefix, Text_t *remainder); -PUREFUNC bool Text$ends_with(Text_t text, Text_t suffix, Text_t *remainder); -Text_t Text$without_prefix(Text_t text, Text_t prefix); -Text_t Text$without_suffix(Text_t text, Text_t suffix); -Text_t Text$replace(Text_t text, Text_t target, Text_t replacement); -Text_t Text$translate(Text_t text, Table_t translations); -PUREFUNC bool Text$has(Text_t text, Text_t target); -List_t Text$split(Text_t text, Text_t delimiter); -List_t Text$split_any(Text_t text, Text_t delimiters); -Closure_t Text$by_split(Text_t text, Text_t delimiter); -Closure_t Text$by_split_any(Text_t text, Text_t delimiters); -Text_t Text$trim(Text_t text, Text_t to_trim, bool left, bool right); -char *Text$as_c_string(Text_t text); -List_t Text$clusters(Text_t text); -List_t Text$utf32_codepoints(Text_t text); -List_t Text$utf8_bytes(Text_t text); -List_t Text$codepoint_names(Text_t text); -Text_t Text$from_codepoints(List_t codepoints); -OptionalText_t Text$from_codepoint_names(List_t codepoint_names); -OptionalText_t Text$from_bytes(List_t bytes); -List_t Text$lines(Text_t text); -Closure_t Text$by_line(Text_t text); -Text_t Text$join(Text_t glue, List_t pieces); -Text_t Text$repeat(Text_t text, Int_t count); -Int_t Text$width(Text_t text, Text_t language); -Text_t Text$left_pad(Text_t text, Int_t width, Text_t padding, Text_t language); -Text_t Text$right_pad(Text_t text, Int_t width, Text_t padding, Text_t language); -Text_t Text$middle_pad(Text_t text, Int_t width, Text_t padding, Text_t language); -int32_t Text$get_grapheme_fast(TextIter_t *state, int64_t index); -uint32_t Text$get_main_grapheme_fast(TextIter_t *state, int64_t index); -Int_t Text$memory_size(Text_t text); -Text_t Text$layout(Text_t text); -void Text$serialize(const void *obj, FILE *out, Table_t *, const TypeInfo_t *); -void Text$deserialize(FILE *in, void *out, List_t *, const TypeInfo_t *); +Text_t Textヽ_concat(int n, Text_t items[n]); +#define Textヽconcat(...) Textヽ_concat(sizeof((Text_t[]){__VA_ARGS__})/sizeof(Text_t), (Text_t[]){__VA_ARGS__}) +#define Texts(...) Textヽconcat(MAP_LIST(convert_to_text, __VA_ARGS__)) +// int Textヽprint(FILE *stream, Text_t t); +Text_t Textヽslice(Text_t text, Int_t first_int, Int_t last_int); +Text_t Textヽfrom(Text_t text, Int_t first); +Text_t Textヽto(Text_t text, Int_t last); +Text_t Textヽreversed(Text_t text); +Text_t Textヽcluster(Text_t text, Int_t index_int); +OptionalText_t Textヽfrom_str(const char *str); +OptionalText_t Textヽfrom_strn(const char *str, size_t len); +PUREFUNC uint64_t Textヽhash(const void *text, const TypeInfo_t*); +PUREFUNC int32_t Textヽcompare(const void *va, const void *vb, const TypeInfo_t*); +PUREFUNC bool Textヽequal(const void *a, const void *b, const TypeInfo_t*); +PUREFUNC bool Textヽequal_values(Text_t a, Text_t b); +PUREFUNC bool Textヽequal_ignoring_case(Text_t a, Text_t b, Text_t language); +PUREFUNC bool Textヽis_none(const void *t, const TypeInfo_t*); +Text_t Textヽupper(Text_t text, Text_t language); +Text_t Textヽlower(Text_t text, Text_t language); +Text_t Textヽtitle(Text_t text, Text_t language); +Text_t Textヽas_text(const void *text, bool colorize, const TypeInfo_t *info); +Text_t Textヽquoted(Text_t str, bool colorize, Text_t quotation_mark); +PUREFUNC bool Textヽstarts_with(Text_t text, Text_t prefix, Text_t *remainder); +PUREFUNC bool Textヽends_with(Text_t text, Text_t suffix, Text_t *remainder); +Text_t Textヽwithout_prefix(Text_t text, Text_t prefix); +Text_t Textヽwithout_suffix(Text_t text, Text_t suffix); +Text_t Textヽreplace(Text_t text, Text_t target, Text_t replacement); +Text_t Textヽtranslate(Text_t text, Table_t translations); +PUREFUNC bool Textヽhas(Text_t text, Text_t target); +List_t Textヽsplit(Text_t text, Text_t delimiter); +List_t Textヽsplit_any(Text_t text, Text_t delimiters); +Closure_t Textヽby_split(Text_t text, Text_t delimiter); +Closure_t Textヽby_split_any(Text_t text, Text_t delimiters); +Text_t Textヽtrim(Text_t text, Text_t to_trim, bool left, bool right); +char *Textヽas_c_string(Text_t text); +List_t Textヽclusters(Text_t text); +List_t Textヽutf32_codepoints(Text_t text); +List_t Textヽutf8_bytes(Text_t text); +List_t Textヽcodepoint_names(Text_t text); +Text_t Textヽfrom_codepoints(List_t codepoints); +OptionalText_t Textヽfrom_codepoint_names(List_t codepoint_names); +OptionalText_t Textヽfrom_bytes(List_t bytes); +List_t Textヽlines(Text_t text); +Closure_t Textヽby_line(Text_t text); +Text_t Textヽjoin(Text_t glue, List_t pieces); +Text_t Textヽrepeat(Text_t text, Int_t count); +Int_t Textヽwidth(Text_t text, Text_t language); +Text_t Textヽleft_pad(Text_t text, Int_t width, Text_t padding, Text_t language); +Text_t Textヽright_pad(Text_t text, Int_t width, Text_t padding, Text_t language); +Text_t Textヽmiddle_pad(Text_t text, Int_t width, Text_t padding, Text_t language); +int32_t Textヽget_grapheme_fast(TextIter_t *state, int64_t index); +uint32_t Textヽget_main_grapheme_fast(TextIter_t *state, int64_t index); +Int_t Textヽmemory_size(Text_t text); +Text_t Textヽlayout(Text_t text); +void Textヽserialize(const void *obj, FILE *out, Table_t *, const TypeInfo_t *); +void Textヽdeserialize(FILE *in, void *out, List_t *, const TypeInfo_t *); -MACROLIKE int32_t Text$get_grapheme(Text_t text, int64_t index) +MACROLIKE int32_t Textヽget_grapheme(Text_t text, int64_t index) { TextIter_t state = NEW_TEXT_ITER_STATE(text); - return Text$get_grapheme_fast(&state, index); + return Textヽget_grapheme_fast(&state, index); } -extern const TypeInfo_t Text$info; +extern const TypeInfo_t Textヽinfo; extern Text_t EMPTY_TEXT; -#define Text$metamethods { \ - .as_text=Text$as_text, \ - .hash=Text$hash, \ - .compare=Text$compare, \ - .equal=Text$equal, \ - .is_none=Text$is_none, \ - .serialize=Text$serialize, \ - .deserialize=Text$deserialize, \ +#define Textヽmetamethods { \ + .as_text=Textヽas_text, \ + .hash=Textヽhash, \ + .compare=Textヽcompare, \ + .equal=Textヽequal, \ + .is_none=Textヽis_none, \ + .serialize=Textヽserialize, \ + .deserialize=Textヽdeserialize, \ } // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/types.c b/src/stdlib/types.c index 0f51d6ea..f12bcaa1 100644 --- a/src/stdlib/types.c +++ b/src/stdlib/types.c @@ -12,20 +12,20 @@ #include "text.h" #include "types.h" -public Text_t Type$as_text(const void *typeinfo, bool colorize, const TypeInfo_t *type) +public Text_t Typeヽas_text(const void *typeinfo, bool colorize, const TypeInfo_t *type) { if (!typeinfo) return Text("Type"); if (colorize) - return Text$concat( + return Textヽconcat( Text("\x1b[36;1m"), - Text$from_str(type->TypeInfoInfo.type_str), + Textヽfrom_str(type->TypeInfoInfo.type_str), Text("\x1b[m")); else - return Text$from_str(type->TypeInfoInfo.type_str); + return Textヽfrom_str(type->TypeInfoInfo.type_str); } -public const TypeInfo_t Void$info = {.size=0, .align=0, .tag=StructInfo}; -public const TypeInfo_t Abort$info = {.size=0, .align=0, .tag=StructInfo}; +public const TypeInfo_t Voidヽinfo = {.size=0, .align=0, .tag=StructInfo}; +public const TypeInfo_t Abortヽinfo = {.size=0, .align=0, .tag=StructInfo}; // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/src/stdlib/types.h b/src/stdlib/types.h index 60f1fcfd..c890f07e 100644 --- a/src/stdlib/types.h +++ b/src/stdlib/types.h @@ -78,15 +78,15 @@ struct TypeInfo_s { }; }; -extern const TypeInfo_t Void$info; -extern const TypeInfo_t Abort$info; +extern const TypeInfo_t Voidヽinfo; +extern const TypeInfo_t Abortヽinfo; #define Void_t void -Text_t Type$as_text(const void *typeinfo, bool colorize, const TypeInfo_t *type); +Text_t Typeヽas_text(const void *typeinfo, bool colorize, const TypeInfo_t *type); -#define Type$info(typestr) &((TypeInfo_t){.size=sizeof(TypeInfo_t), .align=__alignof__(TypeInfo_t), \ +#define Typeヽinfo(typestr) &((TypeInfo_t){.size=sizeof(TypeInfo_t), .align=__alignof__(TypeInfo_t), \ .tag=TypeInfoInfo, .TypeInfoInfo.type_str=typestr, \ - .metamethods={.serialize=cannot_serialize, .deserialize=cannot_deserialize, .as_text=Type$as_text}}) + .metamethods={.serialize=cannot_serialize, .deserialize=cannot_deserialize, .as_text=Typeヽas_text}}) #define DEFINE_OPTIONAL_TYPE(t, unpadded_size, name) \ typedef struct { \ diff --git a/src/stdlib/util.h b/src/stdlib/util.h index 3b00e6e9..499f89cc 100644 --- a/src/stdlib/util.h +++ b/src/stdlib/util.h @@ -19,7 +19,7 @@ #define IF_DECLARE(decl, expr, block) if (({ decl; expr ? ({ block; 1; }) : 0; })) {} -#define WHEN(type, subj, var, body) { type var = subj; switch (var.$tag) body } +#define WHEN(type, subj, var, body) { type var = subj; switch (var.々tag) body } #ifndef public #define public __attribute__ ((visibility ("default"))) diff --git a/src/structs.c b/src/structs.c index 873300c5..64d8139c 100644 --- a/src/structs.c +++ b/src/structs.c @@ -13,22 +13,22 @@ Text_t compile_struct_typeinfo(env_t *env, type_t *t, const char *name, arg_ast_t *fields, bool is_secret, bool is_opaque) { - Text_t typeinfo_name = namespace_name(env, env->namespace, Texts(name, "$$info")); + Text_t typeinfo_name = namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("info"))); Text_t type_code = Match(t, StructType)->external ? - Text$from_str(name) : Texts("struct ", namespace_name(env, env->namespace, Texts(name, "$$struct"))); + Textヽfrom_str(name) : Texts("struct ", namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("struct")))); int num_fields = 0; for (arg_ast_t *f = fields; f; f = f->next) num_fields += 1; const char *short_name = name; - if (strchr(short_name, '$')) - short_name = strrchr(short_name, '$') + 1; + if (strstr(short_name, "ヽ")) + short_name = strstr(short_name, "ヽ") + strlen("ヽ"); - const char *metamethods = is_packed_data(t) ? "PackedData$metamethods" : "Struct$metamethods"; + const char *metamethods = is_packed_data(t) ? "PackedDataヽmetamethods" : "Structヽmetamethods"; Text_t typeinfo = Texts("public const TypeInfo_t ", typeinfo_name, " = {.size=sizeof(", type_code, "), .align=__alignof__(", type_code, "), " ".metamethods=", metamethods, ", " - ".tag=StructInfo, .StructInfo.name=\"", short_name, "\"", + ".tag=StructInfo, .StructInfo.name=\"", Textヽfrom_str(short_name), "\"", is_secret ? Text(", .StructInfo.is_secret=true") : EMPTY_TEXT, is_opaque ? Text(", .StructInfo.is_opaque=true") : EMPTY_TEXT, ", .StructInfo.num_fields=", String(num_fields)); @@ -47,9 +47,10 @@ Text_t compile_struct_typeinfo(env_t *env, type_t *t, const char *name, arg_ast_ Text_t compile_struct_header(env_t *env, ast_t *ast) { DeclareMatch(def, ast, StructDef); - Text_t typeinfo_name = namespace_name(env, env->namespace, Texts(def->name, "$$info")); - Text_t type_code = def->external ? Text$from_str(def->name) - : Texts("struct ", namespace_name(env, env->namespace, Texts(def->name, "$$struct"))); + Text_t name = Textヽfrom_str(def->name); + Text_t typeinfo_name = namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("info"))); + Text_t type_code = def->external ? name + : Texts("struct ", namespace_name(env, env->namespace, Texts(name, SEP, INTERNAL_ID("struct")))); Text_t fields = EMPTY_TEXT; for (arg_ast_t *field = def->fields; field; field = field->next) { @@ -65,14 +66,14 @@ Text_t compile_struct_header(env_t *env, ast_t *ast) field_t->tag == BoolType ? Text(":1") : EMPTY_TEXT, ";\n"); } Text_t struct_code = def->external ? EMPTY_TEXT : Texts(type_code, " {\n", fields, "};\n"); - type_t *t = Table$str_get(*env->types, def->name); + type_t *t = Tableヽstr_get(*env->types, def->name); - Text_t unpadded_size = def->opaque ? Texts("sizeof(", type_code, ")") : Text$from_str(String((int64_t)unpadded_struct_size(t))); + Text_t unpadded_size = def->opaque ? Texts("sizeof(", type_code, ")") : Textヽfrom_str(String((int64_t)unpadded_struct_size(t))); Text_t typeinfo_code = Texts("extern const TypeInfo_t ", typeinfo_name, ";\n"); Text_t optional_code = EMPTY_TEXT; if (!def->opaque) { optional_code = Texts("DEFINE_OPTIONAL_TYPE(", compile_type(t), ", ", unpadded_size, ", ", - namespace_name(env, env->namespace, Texts("$Optional", def->name, "$$type")), ");\n"); + namespace_name(env, env->namespace, Texts(INTERNAL_ID(Texts("Optional", name)), SEP, INTERNAL_ID("type"))), ");\n"); } return Texts(struct_code, optional_code, typeinfo_code); } @@ -33,7 +33,7 @@ #define run_cmd(...) ({ const char *_cmd = String(__VA_ARGS__); if (verbose) print("\033[34;1m", _cmd, "\033[m"); popen(_cmd, "w"); }) #define xsystem(...) ({ int _status = system(String(__VA_ARGS__)); if (!WIFEXITED(_status) || WEXITSTATUS(_status) != 0) errx(1, "Failed to run command: %s", String(__VA_ARGS__)); }) -#define list_text(list) Text$join(Text(" "), list) +#define list_text(list) Textヽjoin(Text(" "), list) #define whisper(...) print("\033[2m", __VA_ARGS__, "\033[m") @@ -46,9 +46,9 @@ static const char *paths_str(List_t paths) { Text_t result = EMPTY_TEXT; for (int64_t i = 0; i < paths.length; i++) { if (i > 0) result = Texts(result, Text(" ")); - result = Texts(result, Path$as_text((Path_t*)(paths.data + i*paths.stride), false, &Path$info)); + result = Texts(result, Pathヽas_text((Path_t*)(paths.data + i*paths.stride), false, &Pathヽinfo)); } - return Text$as_c_string(result); + return Textヽas_c_string(result); } #ifdef __APPLE__ @@ -76,7 +76,7 @@ static OptionalBool_t verbose = false, static OptionalText_t show_codegen = NONE_TEXT, - cflags = Text("-Werror -fdollars-in-identifiers -std=c2x -Wno-trigraphs " + cflags = Text("-Werror -std=c2x -Wno-trigraphs " " -ffunction-sections -fdata-sections" " -fno-signed-zeros -fno-finite-math-only " " -D_XOPEN_SOURCE -D_DEFAULT_SOURCE -fPIC -ggdb" @@ -191,37 +191,37 @@ int main(int argc, char *argv[]) Text_t help = Texts(Text("\x1b[1mtomo\x1b[m: a compiler for the Tomo programming language"), Text("\n\n"), usage); tomo_parse_args( argc, argv, usage, help, TOMO_VERSION, - {"files", true, List$info(&Path$info), &files}, - {"args", true, List$info(&Text$info), &args}, - {"verbose", false, &Bool$info, &verbose}, - {"v", false, &Bool$info, &verbose}, - {"version", false, &Bool$info, &show_version}, - {"parse", false, &Bool$info, &show_parse_tree}, - {"p", false, &Bool$info, &show_parse_tree}, - {"prefix", false, &Bool$info, &show_prefix}, - {"quiet", false, &Bool$info, &quiet}, - {"q", false, &Bool$info, &quiet}, - {"transpile", false, &Bool$info, &stop_at_transpile}, - {"t", false, &Bool$info, &stop_at_transpile}, - {"compile-obj", false, &Bool$info, &stop_at_obj_compilation}, - {"c", false, &Bool$info, &stop_at_obj_compilation}, - {"compile-exe", false, &Bool$info, &compile_exe}, - {"e", false, &Bool$info, &compile_exe}, - {"uninstall", false, List$info(&Text$info), &uninstall}, - {"u", false, List$info(&Text$info), &uninstall}, - {"library", false, List$info(&Path$info), &libraries}, - {"L", false, List$info(&Path$info), &libraries}, - {"show-codegen", false, &Text$info, &show_codegen}, - {"C", false, &Text$info, &show_codegen}, - {"install", false, &Bool$info, &should_install}, - {"I", false, &Bool$info, &should_install}, - {"optimization", false, &Text$info, &optimization}, - {"O", false, &Text$info, &optimization}, - {"force-rebuild", false, &Bool$info, &clean_build}, - {"f", false, &Bool$info, &clean_build}, - {"source-mapping", false, &Bool$info, &source_mapping}, - {"m", false, &Bool$info, &source_mapping}, - {"changelog", false, &Bool$info, &show_changelog}, + {"files", true, Listヽinfo(&Pathヽinfo), &files}, + {"args", true, Listヽinfo(&Textヽinfo), &args}, + {"verbose", false, &Boolヽinfo, &verbose}, + {"v", false, &Boolヽinfo, &verbose}, + {"version", false, &Boolヽinfo, &show_version}, + {"parse", false, &Boolヽinfo, &show_parse_tree}, + {"p", false, &Boolヽinfo, &show_parse_tree}, + {"prefix", false, &Boolヽinfo, &show_prefix}, + {"quiet", false, &Boolヽinfo, &quiet}, + {"q", false, &Boolヽinfo, &quiet}, + {"transpile", false, &Boolヽinfo, &stop_at_transpile}, + {"t", false, &Boolヽinfo, &stop_at_transpile}, + {"compile-obj", false, &Boolヽinfo, &stop_at_obj_compilation}, + {"c", false, &Boolヽinfo, &stop_at_obj_compilation}, + {"compile-exe", false, &Boolヽinfo, &compile_exe}, + {"e", false, &Boolヽinfo, &compile_exe}, + {"uninstall", false, Listヽinfo(&Textヽinfo), &uninstall}, + {"u", false, Listヽinfo(&Textヽinfo), &uninstall}, + {"library", false, Listヽinfo(&Pathヽinfo), &libraries}, + {"L", false, Listヽinfo(&Pathヽinfo), &libraries}, + {"show-codegen", false, &Textヽinfo, &show_codegen}, + {"C", false, &Textヽinfo, &show_codegen}, + {"install", false, &Boolヽinfo, &should_install}, + {"I", false, &Boolヽinfo, &should_install}, + {"optimization", false, &Textヽinfo, &optimization}, + {"O", false, &Textヽinfo, &optimization}, + {"force-rebuild", false, &Boolヽinfo, &clean_build}, + {"f", false, &Boolヽinfo, &clean_build}, + {"source-mapping", false, &Boolヽinfo, &source_mapping}, + {"m", false, &Boolヽinfo, &source_mapping}, + {"changelog", false, &Boolヽinfo, &show_changelog}, ); if (show_prefix) { @@ -258,14 +258,14 @@ int main(int argc, char *argv[]) ldflags = Texts(ldflags, Text(" -L/opt/homebrew/lib -Wl,-rpath,/opt/homebrew/lib")); #endif - if (show_codegen.length > 0 && Text$equal_values(show_codegen, Text("pretty"))) + if (show_codegen.length > 0 && Textヽequal_values(show_codegen, Text("pretty"))) show_codegen = Text("{ sed '/^#line/d;/^$/d' | indent -o /dev/stdout | bat -l c -P; }"); - config_summary = Text$from_str(String(cc, " ", cflags, " -O", optimization)); + config_summary = Textヽfrom_str(String(cc, " ", cflags, " -O", optimization)); - Text_t owner = Path$owner(Path$from_str(TOMO_PREFIX), true); - Text_t user = Text$from_str(getenv("USER")); - if (!Text$equal_values(user, owner)) { + Text_t owner = Pathヽowner(Pathヽfrom_str(TOMO_PREFIX), true); + Text_t user = Textヽfrom_str(getenv("USER")); + if (!Textヽequal_values(user, owner)) { as_owner = Texts(Text(SUDO" -u "), owner, Text(" ")); } @@ -275,10 +275,10 @@ int main(int argc, char *argv[]) print("Uninstalled ", *u); } - Path_t cwd = Path$current_dir(); + Path_t cwd = Pathヽcurrent_dir(); for (int64_t i = 0; i < libraries.length; i++) { Path_t *lib = (Path_t*)(libraries.data + i*libraries.stride); - *lib = Path$resolved(*lib, cwd); + *lib = Pathヽresolved(*lib, cwd); // Fork a child process to build the library to prevent cross-contamination // of side effects when building one library from affecting another library. // This *could* be done in parallel, but there may be some dependency issues. @@ -302,14 +302,14 @@ int main(int argc, char *argv[]) } // Convert `foo` to `foo/foo.tm` and resolve all paths to absolute paths: - Path_t cur_dir = Path$current_dir(); + Path_t cur_dir = Pathヽcurrent_dir(); for (int64_t i = 0; i < files.length; i++) { Path_t *path = (Path_t*)(files.data + i*files.stride); - if (Path$is_directory(*path, true)) - *path = Path$child(*path, Texts(Path$base_name(*path), Text(".tm"))); + if (Pathヽis_directory(*path, true)) + *path = Pathヽchild(*path, Texts(Pathヽbase_name(*path), Text(".tm"))); - *path = Path$resolved(*path, cur_dir); - if (!Path$exists(*path)) + *path = Pathヽresolved(*path, cur_dir); + if (!Pathヽexists(*path)) fail("File not found: ", *path); } @@ -321,13 +321,13 @@ int main(int argc, char *argv[]) for (int64_t i = 0; i < files.length; i++) { Path_t path = *(Path_t*)(files.data + i*files.stride); if (show_parse_tree) { - ast_t *ast = parse_file(Path$as_c_string(path), NULL); + ast_t *ast = parse_file(Pathヽas_c_string(path), NULL); print(ast_to_sexp_str(ast)); continue; } - Path_t exe_path = compile_exe ? Path$with_extension(path, Text(""), true) - : build_file(Path$with_extension(path, Text(""), true), ""); + Path_t exe_path = compile_exe ? Pathヽwith_extension(path, Text(""), true) + : build_file(Pathヽwith_extension(path, Text(""), true), ""); pid_t child = fork(); if (child == 0) { @@ -341,9 +341,9 @@ int main(int argc, char *argv[]) _exit(0); char *prog_args[1 + args.length + 1]; - prog_args[0] = (char*)Path$as_c_string(exe_path); + prog_args[0] = (char*)Pathヽas_c_string(exe_path); for (int64_t j = 0; j < args.length; j++) - prog_args[j + 1] = Text$as_c_string(*(Text_t*)(args.data + j*args.stride)); + prog_args[j + 1] = Textヽas_c_string(*(Text_t*)(args.data + j*args.stride)); prog_args[1 + args.length] = NULL; execv(prog_args[0], prog_args); print_err("Could not execute program: ", prog_args[0]); @@ -355,7 +355,7 @@ int main(int argc, char *argv[]) if (compile_exe && should_install) { for (int64_t i = 0; i < files.length; i++) { Path_t path = *(Path_t*)(files.data + i*files.stride); - Path_t exe = Path$with_extension(path, Text(""), true); + Path_t exe = Pathヽwith_extension(path, Text(""), true); xsystem(as_owner, "cp -v '", exe, "' '"TOMO_PREFIX"'/bin/"); } } @@ -382,22 +382,22 @@ void wait_for_child_success(pid_t child) Path_t build_file(Path_t path, const char *extension) { - Path_t build_dir = Path$sibling(path, Text(".build")); - if (mkdir(Path$as_c_string(build_dir), 0755) != 0) { - if (!Path$is_directory(build_dir, true)) + Path_t build_dir = Pathヽsibling(path, Text(".build")); + if (mkdir(Pathヽas_c_string(build_dir), 0755) != 0) { + if (!Pathヽis_directory(build_dir, true)) err(1, "Could not make .build directory"); } - return Path$child(build_dir, Texts(Path$base_name(path), Text$from_str(extension))); + return Pathヽchild(build_dir, Texts(Pathヽbase_name(path), Textヽfrom_str(extension))); } static const char *get_version(Path_t lib_dir) { - Path_t changes_file = Path$child(lib_dir, Text("CHANGES.md")); - OptionalText_t changes = Path$read(changes_file); + Path_t changes_file = Pathヽchild(lib_dir, Text("CHANGES.md")); + OptionalText_t changes = Pathヽread(changes_file); if (changes.length <= 0) { return "v0.0"; } - const char *changes_str = Text$as_c_string(Texts(Text("\n"), changes)); + const char *changes_str = Textヽas_c_string(Texts(Text("\n"), changes)); const char *version_line = strstr(changes_str, "\n## "); if (version_line == NULL) print_err("CHANGES.md in ", lib_dir, " does not have any valid versions starting with '## '"); @@ -406,17 +406,17 @@ static const char *get_version(Path_t lib_dir) static Text_t get_version_suffix(Path_t lib_dir) { - return Texts(Text("_"), Text$from_str(get_version(lib_dir))); + return Texts(Text("_"), Textヽfrom_str(get_version(lib_dir))); } void build_library(Path_t lib_dir) { - lib_dir = Path$resolved(lib_dir, Path$current_dir()); - if (!Path$is_directory(lib_dir, true)) + lib_dir = Pathヽresolved(lib_dir, Pathヽcurrent_dir()); + if (!Pathヽis_directory(lib_dir, true)) print_err("Not a valid directory: ", lib_dir); - Text_t lib_dir_name = Path$base_name(lib_dir); - List_t tm_files = Path$glob(Path$child(lib_dir, Text("[!._0-9]*.tm"))); + Text_t lib_dir_name = Pathヽbase_name(lib_dir); + List_t tm_files = Pathヽglob(Pathヽchild(lib_dir, Text("[!._0-9]*.tm"))); env_t *env = fresh_scope(global_env(source_mapping)); List_t object_files = {}, extra_ldlibs = {}; @@ -424,7 +424,7 @@ void build_library(Path_t lib_dir) compile_files(env, tm_files, &object_files, &extra_ldlibs); Text_t version_suffix = get_version_suffix(lib_dir); - Path_t shared_lib = Path$child(lib_dir, Texts(Text("lib"), lib_dir_name, version_suffix, Text(SHARED_SUFFIX))); + Path_t shared_lib = Pathヽchild(lib_dir, Texts(Text("lib"), lib_dir_name, version_suffix, Text(SHARED_SUFFIX))); if (!is_stale_for_any(shared_lib, object_files, false)) { if (verbose) whisper("Unchanged: ", shared_lib); return; @@ -450,10 +450,10 @@ void build_library(Path_t lib_dir) void install_library(Path_t lib_dir) { - Text_t lib_dir_name = Path$base_name(lib_dir); + Text_t lib_dir_name = Pathヽbase_name(lib_dir); Text_t version_suffix = get_version_suffix(lib_dir); - Path_t dest = Path$child(Path$from_str(TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed"), Texts(lib_dir_name, version_suffix)); - if (!Path$equal_values(lib_dir, dest)) { + Path_t dest = Pathヽchild(Pathヽfrom_str(TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed"), Texts(lib_dir_name, version_suffix)); + if (!Pathヽequal_values(lib_dir, dest)) { if (verbose) whisper("Clearing out any pre-existing version of ", lib_dir_name); xsystem(as_owner, "rm -rf '", dest, "'"); if (verbose) whisper("Moving files to ", dest); @@ -478,10 +478,10 @@ void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t * Table_t dependency_files = {}; for (int64_t i = 0; i < to_compile.length; i++) { Path_t filename = *(Path_t*)(to_compile.data + i*to_compile.stride); - Text_t extension = Path$extension(filename, true); - if (!Text$equal_values(extension, Text("tm"))) + Text_t extension = Pathヽextension(filename, true); + if (!Textヽequal_values(extension, Text("tm"))) print_err("Not a valid .tm file: \x1b[31;1m", filename, "\x1b[m"); - if (!Path$is_file(filename, true)) + if (!Pathヽis_file(filename, true)) print_err("Couldn't find file: ", filename); build_file_dependency_graph(filename, &dependency_files, &to_link); } @@ -494,22 +494,22 @@ void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t * } *entry = (dependency_files.entries.data + i*dependency_files.entries.stride); Path_t id_file = build_file(entry->filename, ".id"); - if (!Path$exists(id_file)) { + if (!Pathヽexists(id_file)) { static const char id_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; char id_str[8]; for (int j = 0; j < (int)sizeof(id_str); j++) { id_str[j] = id_chars[random_range(0, sizeof(id_chars)-1)]; } Text_t filename_id = Text(""); - Text_t base = Path$base_name(entry->filename); + Text_t base = Pathヽbase_name(entry->filename); TextIter_t state = NEW_TEXT_ITER_STATE(base); for (int64_t j = 0; j < base.length; j++) { - uint32_t c = Text$get_main_grapheme_fast(&state, j); + uint32_t c = Textヽget_main_grapheme_fast(&state, j); if (c == '.') break; if (isalpha(c) || isdigit(c) || c == '_') - filename_id = Texts(filename_id, Text$from_strn((char[]){(char)c}, 1)); + filename_id = Texts(filename_id, Textヽfrom_strn((char[]){(char)c}, 1)); } - Path$write(id_file, Texts(filename_id, Text("_"), Text$from_strn(id_str, sizeof(id_str))), 0644); + Pathヽwrite(id_file, Texts(filename_id, Text("_"), Textヽfrom_strn(id_str, sizeof(id_str))), 0644); } } @@ -577,35 +577,35 @@ void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t * } *entry = (dependency_files.entries.data + i*dependency_files.entries.stride); Path_t path = entry->filename; path = build_file(path, ".o"); - List$insert(object_files, &path, I(0), sizeof(Path_t)); + Listヽinsert(object_files, &path, I(0), sizeof(Path_t)); } } if (extra_ldlibs) { for (int64_t i = 0; i < to_link.entries.length; i++) { Text_t lib = *(Text_t*)(to_link.entries.data + i*to_link.entries.stride); - List$insert(extra_ldlibs, &lib, I(0), sizeof(Text_t)); + Listヽinsert(extra_ldlibs, &lib, I(0), sizeof(Text_t)); } } } bool is_config_outdated(Path_t path) { - OptionalText_t config = Path$read(build_file(path, ".config")); + OptionalText_t config = Pathヽread(build_file(path, ".config")); if (config.length < 0) return true; - return !Text$equal_values(config, config_summary); + return !Textヽequal_values(config, config_summary); } void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_link) { - if (Table$has_value(*to_compile, path, Table$info(&Path$info, &Byte$info))) + if (Tableヽhas_value(*to_compile, path, Tableヽinfo(&Pathヽinfo, &Byteヽinfo))) return; staleness_t staleness = { - .h=is_stale(build_file(path, ".h"), Path$sibling(path, Text("modules.ini")), true) + .h=is_stale(build_file(path, ".h"), Pathヽsibling(path, Text("modules.ini")), true) || is_stale(build_file(path, ".h"), build_file(path, ":modules.ini"), true) || is_stale(build_file(path, ".h"), path, false) || is_stale(build_file(path, ".h"), build_file(path, ".id"), false), - .c=is_stale(build_file(path, ".c"), Path$sibling(path, Text("modules.ini")), true) + .c=is_stale(build_file(path, ".c"), Pathヽsibling(path, Text("modules.ini")), true) || is_stale(build_file(path, ".c"), build_file(path, ":modules.ini"), true) || is_stale(build_file(path, ".c"), path, false) || is_stale(build_file(path, ".c"), build_file(path, ".id"), false), @@ -613,11 +613,11 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l staleness.o = staleness.c || staleness.h || is_stale(build_file(path, ".o"), build_file(path, ".c"), false) || is_stale(build_file(path, ".o"), build_file(path, ".h"), false); - Table$set(to_compile, &path, &staleness, Table$info(&Path$info, &Byte$info)); + Tableヽset(to_compile, &path, &staleness, Tableヽinfo(&Pathヽinfo, &Byteヽinfo)); - assert(Text$equal_values(Path$extension(path, true), Text("tm"))); + assert(Textヽequal_values(Pathヽextension(path, true), Text("tm"))); - ast_t *ast = parse_file(Path$as_c_string(path), NULL); + ast_t *ast = parse_file(Pathヽas_c_string(path), NULL); if (!ast) print_err("Could not parse file: ", path); @@ -628,8 +628,8 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l switch (use->what) { case USE_LOCAL: { - Path_t dep_tm = Path$resolved(Path$from_str(use->path), Path$parent(path)); - if (!Path$is_file(dep_tm, true)) + Path_t dep_tm = Pathヽresolved(Pathヽfrom_str(use->path), Pathヽparent(path)); + if (!Pathヽis_file(dep_tm, true)) code_err(stmt_ast, "Not a valid file: ", dep_tm); if (is_stale(build_file(path, ".h"), dep_tm, false)) staleness.h = true; @@ -637,7 +637,7 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l staleness.c = true; if (staleness.c || staleness.h) staleness.o = true; - Table$set(to_compile, &path, &staleness, Table$info(&Path$info, &Byte$info)); + Tableヽset(to_compile, &path, &staleness, Tableヽinfo(&Pathヽinfo, &Byteヽinfo)); build_file_dependency_graph(dep_tm, to_compile, to_link); break; } @@ -645,12 +645,12 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l module_info_t mod = get_module_info(stmt_ast); const char *full_name = mod.version ? String(mod.name, "_", mod.version) : mod.name; Text_t lib = Texts(Text("-Wl,-rpath,'"), - Text(TOMO_PREFIX "/share/tomo_"TOMO_VERSION"/installed/"), Text$from_str(full_name), + Text(TOMO_PREFIX "/share/tomo_"TOMO_VERSION"/installed/"), Textヽfrom_str(full_name), Text("' '" TOMO_PREFIX "/share/tomo_"TOMO_VERSION"/installed/"), - Text$from_str(full_name), Text("/lib"), Text$from_str(full_name), Text(SHARED_SUFFIX "'")); - Table$set(to_link, &lib, NULL, Table$info(&Text$info, &Void$info)); + Textヽfrom_str(full_name), Text("/lib"), Textヽfrom_str(full_name), Text(SHARED_SUFFIX "'")); + Tableヽset(to_link, &lib, NULL, Tableヽinfo(&Textヽinfo, &Voidヽinfo)); - List_t children = Path$glob(Path$from_str(String(TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed/", full_name, "/[!._0-9]*.tm"))); + List_t children = Pathヽglob(Pathヽfrom_str(String(TOMO_PREFIX"/share/tomo_"TOMO_VERSION"/installed/", full_name, "/[!._0-9]*.tm"))); for (int64_t i = 0; i < children.length; i++) { Path_t *child = (Path_t*)(children.data + i*children.stride); Table_t discarded = {.fallback=to_compile}; @@ -659,18 +659,18 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l break; } case USE_SHARED_OBJECT: { - Text_t lib = Text$from_str(use->path); - Table$set(to_link, &lib, NULL, Table$info(&Text$info, &Void$info)); + Text_t lib = Textヽfrom_str(use->path); + Tableヽset(to_link, &lib, NULL, Tableヽinfo(&Textヽinfo, &Voidヽinfo)); break; } case USE_ASM: { - Path_t asm_path = Path$from_str(use->path); - asm_path = Path$concat(Path$parent(path), asm_path); - Text_t linker_text = Path$as_text(&asm_path, NULL, &Path$info); - Table$set(to_link, &linker_text, NULL, Table$info(&Text$info, &Void$info)); + Path_t asm_path = Pathヽfrom_str(use->path); + asm_path = Pathヽconcat(Pathヽparent(path), asm_path); + Text_t linker_text = Pathヽas_text(&asm_path, NULL, &Pathヽinfo); + Tableヽset(to_link, &linker_text, NULL, Tableヽinfo(&Textヽinfo, &Voidヽinfo)); if (is_stale(build_file(path, ".o"), asm_path, false)) { staleness.o = true; - Table$set(to_compile, &path, &staleness, Table$info(&Path$info, &Byte$info)); + Tableヽset(to_compile, &path, &staleness, Tableヽinfo(&Pathヽinfo, &Byteヽinfo)); } break; } @@ -678,10 +678,10 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l if (use->path[0] == '<') break; - Path_t dep_path = Path$resolved(Path$from_str(use->path), Path$parent(path)); + Path_t dep_path = Pathヽresolved(Pathヽfrom_str(use->path), Pathヽparent(path)); if (is_stale(build_file(path, ".o"), dep_path, false)) { staleness.o = true; - Table$set(to_compile, &path, &staleness, Table$info(&Path$info, &Byte$info)); + Tableヽset(to_compile, &path, &staleness, Tableヽinfo(&Pathヽinfo, &Byteヽinfo)); } break; } @@ -694,39 +694,39 @@ time_t latest_included_modification_time(Path_t path) { static Table_t c_modification_times = {}; const TypeInfo_t time_info = {.size=sizeof(time_t), .align=alignof(time_t), .tag=OpaqueInfo}; - time_t *cached_latest = Table$get(c_modification_times, &path, Table$info(&Path$info, &time_info)); + time_t *cached_latest = Tableヽget(c_modification_times, &path, Tableヽinfo(&Pathヽinfo, &time_info)); if (cached_latest) return *cached_latest; struct stat s; time_t latest = 0; - if (stat(Path$as_c_string(path), &s) == 0) + if (stat(Pathヽas_c_string(path), &s) == 0) latest = s.st_mtime; - Table$set(&c_modification_times, &path, &latest, Table$info(&Path$info, &time_info)); + Tableヽset(&c_modification_times, &path, &latest, Tableヽinfo(&Pathヽinfo, &time_info)); - OptionalClosure_t by_line = Path$by_line(path); + OptionalClosure_t by_line = Pathヽby_line(path); if (by_line.fn == NULL) return 0; OptionalText_t (*next_line)(void*) = by_line.fn; - Path_t parent = Path$parent(path); - bool allow_dot_include = Path$has_extension(path, Text("s")) || Path$has_extension(path, Text("S")); + Path_t parent = Pathヽparent(path); + bool allow_dot_include = Pathヽhas_extension(path, Text("s")) || Pathヽhas_extension(path, Text("S")); for (Text_t line; (line=next_line(by_line.userdata)).length >= 0; ) { - line = Text$trim(line, Text(" \t"), true, false); - if (!Text$starts_with(line, Text("#include"), NULL) && !(allow_dot_include && Text$starts_with(line, Text(".include"), NULL))) + line = Textヽtrim(line, Text(" \t"), true, false); + if (!Textヽstarts_with(line, Text("#include"), NULL) && !(allow_dot_include && Textヽstarts_with(line, Text(".include"), NULL))) continue; // Check for `"` after `#include` or `.include` and some spaces: - if (!Text$starts_with(Text$trim(Text$from(line, I(9)), Text(" \t"), true, false), Text("\""), NULL)) + if (!Textヽstarts_with(Textヽtrim(Textヽfrom(line, I(9)), Text(" \t"), true, false), Text("\""), NULL)) continue; - List_t chunks = Text$split(line, Text("\"")); + List_t chunks = Textヽsplit(line, Text("\"")); if (chunks.length < 3) // Should be `#include "foo" ...` -> ["#include ", "foo", "..."] continue; Text_t included = *(Text_t*)(chunks.data + 1*chunks.stride); - Path_t included_path = Path$resolved(Path$from_text(included), parent); + Path_t included_path = Pathヽresolved(Pathヽfrom_text(included), parent); time_t included_time = latest_included_modification_time(included_path); if (included_time > latest) { latest = included_time; - Table$set(&c_modification_times, &path, &latest, Table$info(&Path$info, &time_info)); + Tableヽset(&c_modification_times, &path, &latest, Tableヽinfo(&Pathヽinfo, &time_info)); } } return latest; @@ -735,7 +735,7 @@ time_t latest_included_modification_time(Path_t path) bool is_stale(Path_t path, Path_t relative_to, bool ignore_missing) { struct stat target_stat; - if (stat(Path$as_c_string(path), &target_stat) != 0) { + if (stat(Pathヽas_c_string(path), &target_stat) != 0) { if (ignore_missing) return false; return true; } @@ -746,14 +746,14 @@ bool is_stale(Path_t path, Path_t relative_to, bool ignore_missing) return true; #endif - if (Path$has_extension(relative_to, Text("c")) || Path$has_extension(relative_to, Text("h")) - || Path$has_extension(relative_to, Text("s")) || Path$has_extension(relative_to, Text("S"))) { + if (Pathヽhas_extension(relative_to, Text("c")) || Pathヽhas_extension(relative_to, Text("h")) + || Pathヽhas_extension(relative_to, Text("s")) || Pathヽhas_extension(relative_to, Text("S"))) { time_t mtime = latest_included_modification_time(relative_to); return target_stat.st_mtime < mtime; } struct stat relative_to_stat; - if (stat(Path$as_c_string(relative_to), &relative_to_stat) != 0) { + if (stat(Pathヽas_c_string(relative_to), &relative_to_stat) != 0) { if (ignore_missing) return false; print_err("File doesn't exist: ", relative_to); } @@ -773,18 +773,18 @@ bool is_stale_for_any(Path_t path, List_t relative_to, bool ignore_missing) void transpile_header(env_t *base_env, Path_t path) { Path_t h_filename = build_file(path, ".h"); - ast_t *ast = parse_file(Path$as_c_string(path), NULL); + ast_t *ast = parse_file(Pathヽas_c_string(path), NULL); if (!ast) print_err("Could not parse file: ", path); env_t *module_env = load_module_env(base_env, ast); - Text_t h_code = compile_file_header(module_env, Path$resolved(h_filename, Path$from_str(".")), ast); + Text_t h_code = compile_file_header(module_env, Pathヽresolved(h_filename, Pathヽfrom_str(".")), ast); - FILE *header = fopen(Path$as_c_string(h_filename), "w"); + FILE *header = fopen(Pathヽas_c_string(h_filename), "w"); if (!header) print_err("Failed to open header file: ", h_filename); - Text$print(header, h_code); + Textヽprint(header, h_code); if (fclose(header) == -1) print_err("Failed to write header file: ", h_filename); @@ -798,7 +798,7 @@ void transpile_header(env_t *base_env, Path_t path) void transpile_code(env_t *base_env, Path_t path) { Path_t c_filename = build_file(path, ".c"); - ast_t *ast = parse_file(Path$as_c_string(path), NULL); + ast_t *ast = parse_file(Pathヽas_c_string(path), NULL); if (!ast) print_err("Could not parse file: ", path); @@ -806,13 +806,13 @@ void transpile_code(env_t *base_env, Path_t path) Text_t c_code = compile_file(module_env, ast); - FILE *c_file = fopen(Path$as_c_string(c_filename), "w"); + FILE *c_file = fopen(Pathヽas_c_string(c_filename), "w"); if (!c_file) print_err("Failed to write C file: ", c_filename); - Text$print(c_file, c_code); + Textヽprint(c_file, c_code); - const char *version = get_version(Path$parent(path)); + const char *version = get_version(Pathヽparent(path)); binding_t *main_binding = get_binding(module_env, "main"); if (main_binding && main_binding->type->tag == FunctionType) { type_t *ret = Match(main_binding->type, FunctionType)->ret; @@ -821,11 +821,11 @@ void transpile_code(env_t *base_env, Path_t path) "The main() function in this file has a return type of ", type_to_str(ret), ", but it should not have any return value!"); - Text$print(c_file, Texts( - "int parse_and_run$$", main_binding->code, "(int argc, char *argv[]) {\n", + Textヽprint(c_file, Texts( + "int ", INTERNAL_ID("parse_and_run"), SEP, main_binding->code, "(int argc, char *argv[]) {\n", module_env->do_source_mapping ? Text("#line 1\n") : EMPTY_TEXT, "tomo_init();\n", - namespace_name(module_env, module_env->namespace, Text("$initialize")), "();\n" + namespace_name(module_env, module_env->namespace, INTERNAL_ID("initialize")), "();\n" "\n", compile_cli_arg_call(module_env, main_binding->code, main_binding->type, version), "return 0;\n" @@ -854,7 +854,7 @@ void compile_object_file(Path_t path) if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) exit(EXIT_FAILURE); - Path$write(build_file(path, ".config"), config_summary, 0644); + Pathヽwrite(build_file(path, ".config"), config_summary, 0644); if (!quiet) print("Compiled object:\t", obj_file); @@ -862,7 +862,7 @@ void compile_object_file(Path_t path) Path_t compile_executable(env_t *base_env, Path_t path, Path_t exe_path, List_t object_files, List_t extra_ldlibs) { - ast_t *ast = parse_file(Path$as_c_string(path), NULL); + ast_t *ast = parse_file(Pathヽas_c_string(path), NULL); if (!ast) print_err("Could not parse file ", path); env_t *env = load_module_env(base_env, ast); @@ -870,9 +870,9 @@ Path_t compile_executable(env_t *base_env, Path_t path, Path_t exe_path, List_t if (!main_binding || main_binding->type->tag != FunctionType) print_err("No main() function has been defined for ", path, ", so it can't be run!"); - if (!clean_build && Path$is_file(exe_path, true) && !is_config_outdated(path) + if (!clean_build && Pathヽis_file(exe_path, true) && !is_config_outdated(path) && !is_stale_for_any(exe_path, object_files, false) - && !is_stale(exe_path, Path$sibling(path, Text("modules.ini")), true) + && !is_stale(exe_path, Pathヽsibling(path, Text("modules.ini")), true) && !is_stale(exe_path, build_file(path, ":modules.ini"), true)) { if (verbose) whisper("Unchanged: ", exe_path); return exe_path; @@ -881,20 +881,20 @@ Path_t compile_executable(env_t *base_env, Path_t path, Path_t exe_path, List_t FILE *runner = run_cmd(cc, " ", cflags, " -O", optimization, " ", ldflags, " ", ldlibs, " ", list_text(extra_ldlibs), " ", paths_str(object_files), " -x c - -o ", exe_path); Text_t program = Texts( - "extern int parse_and_run$$", main_binding->code, "(int argc, char *argv[]);\n" + "extern int ", INTERNAL_ID("parse_and_run"), SEP, main_binding->code, "(int argc, char *argv[]);\n" "__attribute__ ((noinline))\n" "int main(int argc, char *argv[]) {\n" - "\treturn parse_and_run$$", main_binding->code, "(argc, argv);\n" + "\treturn ", INTERNAL_ID("parse_and_run"), SEP, main_binding->code, "(argc, argv);\n" "}\n" ); if (show_codegen.length > 0) { FILE *out = run_cmd(show_codegen); - Text$print(out, program); + Textヽprint(out, program); pclose(out); } - Text$print(runner, program); + Textヽprint(runner, program); int status = pclose(runner); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) exit(EXIT_FAILURE); diff --git a/src/typecheck.c b/src/typecheck.c index d99048ff..420a00a3 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -29,7 +29,7 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) switch (ast->tag) { case VarTypeAST: { const char *name = Match(ast, VarTypeAST)->name; - type_t *t = Table$str_get(*env->types, name); + type_t *t = Tableヽstr_get(*env->types, name); if (t) return t; while (strchr(name, '.')) { char *module_name = GC_strndup(name, strcspn(name, ".")); @@ -37,11 +37,11 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) if (!b || b->type->tag != ModuleType) code_err(ast, "I don't know a module with the name '", module_name, "'"); - env_t *imported = Table$str_get(*env->imports, Match(b->type, ModuleType)->name); + env_t *imported = Tableヽstr_get(*env->imports, Match(b->type, ModuleType)->name); assert(imported); env = imported; name = strchr(name, '.') + 1; - t = Table$str_get(*env->types, name); + t = Tableヽstr_get(*env->types, name); if (t) return t; } code_err(ast, "I don't know a type with the name '", name, "'"); @@ -134,7 +134,7 @@ type_t *parse_type_ast(env_t *env, type_ast_t *ast) // switch (ast->tag) { // case Int: { // const char *str = Match(ast, Int)->str; -// OptionalInt_t int_val = Int$from_str(str); +// OptionalInt_t int_val = Intヽfrom_str(str); // return (int_val.small == 0x1); // zero // } // case Num: { @@ -167,14 +167,14 @@ static env_t *load_module(env_t *env, ast_t *module_ast) DeclareMatch(use, module_ast, Use); switch (use->what) { case USE_LOCAL: { - Path_t source_path = Path$from_str(module_ast->file->filename); - Path_t source_dir = Path$parent(source_path); - Path_t used_path = Path$resolved(Path$from_str(use->path), source_dir); + Path_t source_path = Pathヽfrom_str(module_ast->file->filename); + Path_t source_dir = Pathヽparent(source_path); + Path_t used_path = Pathヽresolved(Pathヽfrom_str(use->path), source_dir); - if (!Path$exists(used_path)) + if (!Pathヽexists(used_path)) code_err(module_ast, "No such file exists: ", quoted(use->path)); - env_t *module_env = Table$str_get(*env->imports, String(used_path)); + env_t *module_env = Tableヽstr_get(*env->imports, String(used_path)); if (module_env) return module_env; @@ -192,7 +192,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast) } env_t *module_env = fresh_scope(env); - Table$str_set(env->imports, mod.name, module_env); + Tableヽstr_set(env->imports, mod.name, module_env); for (size_t i = 0; i < tm_files.gl_pathc; i++) { const char *filename = tm_files.gl_pathv[i]; @@ -205,7 +205,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast) struct { const char *name; binding_t *binding; } *entry = subenv->locals->entries.data + j*subenv->locals->entries.stride; - Table$str_set(module_env->locals, entry->name, entry->binding); + Tableヽstr_set(module_env->locals, entry->name, entry->binding); } } globfree(&tm_files); @@ -233,9 +233,9 @@ void prebind_statement(env_t *env, ast_t *statement) env_t *ns_env = namespace_env(env, def->name); type_t *type = Type(StructType, .name=def->name, .opaque=true, .external=def->external, .env=ns_env); // placeholder - Table$str_set(env->types, def->name, type); + Tableヽstr_set(env->types, def->name, type); set_binding(env, def->name, Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env), - namespace_name(env, env->namespace, Texts(def->name, "$$info"))); + namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("info")))); for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next) prebind_statement(ns_env, stmt->ast); break; @@ -247,9 +247,9 @@ void prebind_statement(env_t *env, ast_t *statement) env_t *ns_env = namespace_env(env, def->name); type_t *type = Type(EnumType, .name=def->name, .opaque=true, .env=ns_env); // placeholder - Table$str_set(env->types, def->name, type); + Tableヽstr_set(env->types, def->name, type); set_binding(env, def->name, Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env), - namespace_name(env, env->namespace, Texts(def->name, "$$info"))); + namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("info")))); for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next) prebind_statement(ns_env, stmt->ast); break; @@ -261,9 +261,9 @@ void prebind_statement(env_t *env, ast_t *statement) env_t *ns_env = namespace_env(env, def->name); type_t *type = Type(TextType, .lang=def->name, .env=ns_env); - Table$str_set(env->types, def->name, type); + Tableヽstr_set(env->types, def->name, type); set_binding(env, def->name, Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env), - namespace_name(env, env->namespace, Texts(def->name, "$$info"))); + namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("info")))); for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next) prebind_statement(ns_env, stmt->ast); break; @@ -281,12 +281,12 @@ void prebind_statement(env_t *env, ast_t *statement) List_t new_bindings = extended->locals->entries; for (int64_t i = 0; i < new_bindings.length; i++) { struct { const char *name; binding_t *binding; } *entry = new_bindings.data + i*new_bindings.stride; - binding_t *clobbered = Table$str_get(*ns_env->locals, entry->name); + binding_t *clobbered = Tableヽstr_get(*ns_env->locals, entry->name); if (clobbered && !type_eq(clobbered->type, entry->binding->type)) code_err(statement, "This `extend` block overwrites the binding for ", quoted(entry->name), " in the original namespace (with type ", type_to_str(clobbered->type), ") with a new binding with type ", type_to_str(entry->binding->type)); - Table$str_set(ns_env->locals, entry->name, entry->binding); + Tableヽstr_set(ns_env->locals, entry->name, entry->binding); } break; } @@ -321,9 +321,9 @@ void bind_statement(env_t *env, ast_t *statement) type = Type(ClosureType, type); Text_t code; if (name[0] != '_' && (env->namespace || decl->top_level)) - code = namespace_name(env, env->namespace, Text$from_str(name)); + code = namespace_name(env, env->namespace, Textヽfrom_str(name)); else - code = Texts("_$", name); + code = USER_ID(Textヽfrom_str(name)); set_binding(env, name, type, code); break; } @@ -331,7 +331,7 @@ void bind_statement(env_t *env, ast_t *statement) DeclareMatch(def, statement, FunctionDef); const char *name = Match(def->name, Var)->name; type_t *type = get_function_def_type(env, statement); - set_binding(env, name, type, namespace_name(env, env->namespace, Text$from_str(name))); + set_binding(env, name, type, namespace_name(env, env->namespace, Textヽfrom_str(name))); break; } case ConvertDef: { @@ -342,16 +342,16 @@ void bind_statement(env_t *env, ast_t *statement) code_err(statement, "Conversions are only supported for text, struct, and enum types, not ", type_to_str(ret_t)); Text_t code = namespace_name(env, env->namespace, - Texts(name, "$", String(get_line_number(statement->file, statement->start)))); + Texts(name, SEP, String(get_line_number(statement->file, statement->start)))); binding_t binding = {.type=type, .code=code}; env_t *type_ns = get_namespace_by_type(env, ret_t); - List$insert(&type_ns->namespace->constructors, &binding, I(0), sizeof(binding)); + Listヽinsert(&type_ns->namespace->constructors, &binding, I(0), sizeof(binding)); break; } case StructDef: { DeclareMatch(def, statement, StructDef); env_t *ns_env = namespace_env(env, def->name); - type_t *type = Table$str_get(*env->types, def->name); + type_t *type = Tableヽstr_get(*env->types, def->name); if (!type) code_err(statement, "Couldn't find type!"); assert(type); ns_env->current_type = type; @@ -394,7 +394,7 @@ void bind_statement(env_t *env, ast_t *statement) case EnumDef: { DeclareMatch(def, statement, EnumDef); env_t *ns_env = namespace_env(env, def->name); - type_t *type = Table$str_get(*env->types, def->name); + type_t *type = Tableヽstr_get(*env->types, def->name); assert(type); ns_env->current_type = type; tag_t *tags = NULL; @@ -429,8 +429,8 @@ void bind_statement(env_t *env, ast_t *statement) fields = new(arg_t, .name=field_ast->name, .type=field_t, .default_val=field_ast->value, .next=fields); } REVERSE_LIST(fields); - env_t *member_ns = namespace_env(env, String(def->name, "$", tag_ast->name)); - type_t *tag_type = Type(StructType, .name=String(def->name, "$", tag_ast->name), .fields=fields, .env=member_ns); + env_t *member_ns = namespace_env(env, String(def->name, SEP, tag_ast->name)); + type_t *tag_type = Type(StructType, .name=String(def->name, SEP, tag_ast->name), .fields=fields, .env=member_ns); tags = new(tag_t, .name=tag_ast->name, .tag_value=(next_tag++), .type=tag_type, .next=tags); } REVERSE_LIST(tags); @@ -440,19 +440,19 @@ void bind_statement(env_t *env, ast_t *statement) for (tag_t *tag = tags; tag; tag = tag->next) { if (Match(tag->type, StructType)->fields) { // Constructor: type_t *constructor_t = Type(FunctionType, .args=Match(tag->type, StructType)->fields, .ret=type); - Text_t tagged_name = namespace_name(env, env->namespace, Texts(def->name, "$tagged$", tag->name)); + Text_t tagged_name = namespace_name(env, env->namespace, Texts(def->name, SEP, "tagged", SEP, tag->name)); set_binding(ns_env, tag->name, constructor_t, tagged_name); binding_t binding = {.type=constructor_t, .code=tagged_name}; - List$insert(&ns_env->namespace->constructors, &binding, I(1), sizeof(binding)); + Listヽinsert(&ns_env->namespace->constructors, &binding, I(1), sizeof(binding)); } else if (has_any_tags_with_fields) { // Empty singleton value: - Text_t code = Texts("((", namespace_name(env, env->namespace, Texts(def->name, "$$type")), "){", - namespace_name(env, env->namespace, Texts(def->name, "$tag$", tag->name)), "})"); + Text_t code = Texts("((", namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("type"))), "){", + namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("tag"), SEP, tag->name)), "})"); set_binding(ns_env, tag->name, type, code); } else { - Text_t code = namespace_name(env, env->namespace, Texts(def->name, "$tag$", tag->name)); + Text_t code = namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("tag"), SEP, tag->name)); set_binding(ns_env, tag->name, type, code); } - Table$str_set(env->types, String(def->name, "$", tag->name), tag->type); + Tableヽstr_set(env->types, String(def->name, SEP, tag->name), tag->type); } for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next) { @@ -465,10 +465,10 @@ void bind_statement(env_t *env, ast_t *statement) env_t *ns_env = namespace_env(env, def->name); type_t *type = Type(TextType, .lang=def->name, .env=ns_env); ns_env->current_type = type; - Table$str_set(env->types, def->name, type); + Tableヽstr_set(env->types, def->name, type); set_binding(ns_env, "from_text", NewFunctionType(type, {.name="text", .type=TEXT_TYPE}), - Texts("(", namespace_name(env, env->namespace, Texts(def->name, "$$type")), ")")); + Texts("(", namespace_name(env, env->namespace, Texts(def->name, SEP, INTERNAL_ID("type"))), ")")); for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next) bind_statement(ns_env, stmt->ast); @@ -487,12 +487,12 @@ void bind_statement(env_t *env, ast_t *statement) List_t new_bindings = extended->locals->entries; for (int64_t i = 0; i < new_bindings.length; i++) { struct { const char *name; binding_t *binding; } *entry = new_bindings.data + i*new_bindings.stride; - binding_t *clobbered = Table$str_get(*ns_env->locals, entry->name); + binding_t *clobbered = Tableヽstr_get(*ns_env->locals, entry->name); if (clobbered && !type_eq(clobbered->type, entry->binding->type)) code_err(statement, "This `extend` block overwrites the binding for ", quoted(entry->name), " in the original namespace (with type ", type_to_str(clobbered->type), ") with a new binding with type ", type_to_str(entry->binding->type)); - Table$str_set(ns_env->locals, entry->name, entry->binding); + Tableヽstr_set(ns_env->locals, entry->name, entry->binding); } break; } @@ -505,9 +505,9 @@ void bind_statement(env_t *env, ast_t *statement) struct { const char *name; binding_t *binding; } *entry = entries.data + entries.stride*i; if (entry->name[0] == '_' || streq(entry->name, "main")) continue; - binding_t *b = Table$str_get(*env->locals, entry->name); + binding_t *b = Tableヽstr_get(*env->locals, entry->name); if (!b) - Table$str_set(env->locals, entry->name, entry->binding); + Tableヽstr_set(env->locals, entry->name, entry->binding); else if (b != entry->binding) code_err(statement, "This module imports a symbol called '", entry->name, "', which would clobber another variable"); } @@ -516,10 +516,10 @@ void bind_statement(env_t *env, ast_t *statement) struct { const char *name; type_t *type; } *entry = module_env->types->entries.data + module_env->types->entries.stride*i; if (entry->name[0] == '_') continue; - if (Table$str_get(*env->types, entry->name)) + if (Tableヽstr_get(*env->types, entry->name)) continue; - Table$str_set(env->types, entry->name, entry->type); + Tableヽstr_set(env->types, entry->name, entry->type); } ast_t *var = Match(statement, Use)->var; @@ -535,7 +535,7 @@ void bind_statement(env_t *env, ast_t *statement) type_t *t = parse_type_ast(env, ext->type); if (t->tag == ClosureType) t = Match(t, ClosureType)->fn; - set_binding(env, ext->name, t, Text$from_str(ext->name)); + set_binding(env, ext->name, t, Textヽfrom_str(ext->name)); break; } default: break; @@ -844,7 +844,7 @@ type_t *get_type(env_t *env, ast_t *ast) } if (fielded_t->tag == ModuleType) { const char *name = Match(fielded_t, ModuleType)->name; - env_t *module_env = Table$str_get(*env->imports, name); + env_t *module_env = Tableヽstr_get(*env->imports, name); if (!module_env) code_err(access->fielded, "I couldn't find the environment for the module ", name); return get_type(module_env, WrapAST(ast, Var, access->field)); } else if (fielded_t->tag == TypeInfoType) { @@ -1047,10 +1047,10 @@ type_t *get_type(env_t *env, ast_t *ast) case Use: { switch (Match(ast, Use)->what) { case USE_LOCAL: { - Path_t source_path = Path$from_str(ast->file->filename); - Path_t source_dir = Path$parent(source_path); - Path_t used_path = Path$resolved(Path$from_str(Match(ast, Use)->path), source_dir); - return Type(ModuleType, Path$as_c_string(used_path)); + Path_t source_path = Pathヽfrom_str(ast->file->filename); + Path_t source_dir = Pathヽparent(source_path); + Path_t used_path = Pathヽresolved(Pathヽfrom_str(Match(ast, Use)->path), source_dir); + return Type(ModuleType, Pathヽas_c_string(used_path)); } default: return Type(ModuleType, Match(ast, Use)->path); @@ -1349,7 +1349,7 @@ type_t *get_type(env_t *env, ast_t *ast) code_err(reduction->iter, "I don't know how to do a reduction over ", type_to_str(iter_t), " values"); if (reduction->key && !(reduction->op == Min || reduction->op == Max)) { env_t *item_scope = fresh_scope(env); - set_binding(item_scope, "$", iterated, EMPTY_TEXT); + set_binding(item_scope, "ヽ", iterated, EMPTY_TEXT); iterated = get_type(item_scope, reduction->key); } return iterated->tag == OptionalType ? iterated : Type(OptionalType, .type=iterated); @@ -1532,7 +1532,7 @@ type_t *get_type(env_t *env, ast_t *ast) Text_t unhandled = EMPTY_TEXT; for (match_t *m = matches; m; m = m->next) { if (!m->handled) - unhandled = unhandled.length > 0 ? Texts(unhandled, ", ", m->tag->name) : Text$from_str(m->tag->name); + unhandled = unhandled.length > 0 ? Texts(unhandled, ", ", m->tag->name) : Textヽfrom_str(m->tag->name); } if (unhandled.length > 0) code_err(ast, "This 'when' statement doesn't handle the tags: ", unhandled); @@ -1599,7 +1599,7 @@ static Table_t *get_arg_bindings_with_promotion(env_t *env, arg_t *spec_args, ar type_t *spec_type = get_arg_type(env, spec_arg); if (!can_compile_to_type(env, call_arg->value, spec_type)) return NULL; - Table$str_set(&used_args, call_arg->name, call_arg); + Tableヽstr_set(&used_args, call_arg->name, call_arg); goto next_call_arg; } return NULL; @@ -1608,7 +1608,7 @@ static Table_t *get_arg_bindings_with_promotion(env_t *env, arg_t *spec_args, ar arg_ast_t *unused_args = call_args; for (arg_t *spec_arg = spec_args; spec_arg; spec_arg = spec_arg->next) { - arg_ast_t *keyworded = Table$str_get(used_args, spec_arg->name); + arg_ast_t *keyworded = Tableヽstr_get(used_args, spec_arg->name); if (keyworded) continue; type_t *spec_type = get_arg_type(env, spec_arg); @@ -1616,7 +1616,7 @@ static Table_t *get_arg_bindings_with_promotion(env_t *env, arg_t *spec_args, ar if (unused_args->name) continue; // Already handled the keyword args if (!can_compile_to_type(env, unused_args->value, spec_type)) return NULL; // Positional arg trying to fill in - Table$str_set(&used_args, spec_arg->name, unused_args); + Tableヽstr_set(&used_args, spec_arg->name, unused_args); unused_args = unused_args->next; goto found_it; } @@ -1658,7 +1658,7 @@ Table_t *get_arg_bindings(env_t *env, arg_t *spec_args, arg_ast_t *call_args, bo if (!complete_call_type) return NULL; if (!type_eq(complete_call_type, spec_type)) return NULL; - Table$str_set(&used_args, call_arg->name, call_arg); + Tableヽstr_set(&used_args, call_arg->name, call_arg); goto next_call_arg; } return NULL; @@ -1667,7 +1667,7 @@ Table_t *get_arg_bindings(env_t *env, arg_t *spec_args, arg_ast_t *call_args, bo arg_ast_t *unused_args = call_args; for (arg_t *spec_arg = spec_args; spec_arg; spec_arg = spec_arg->next) { - arg_ast_t *keyworded = Table$str_get(used_args, spec_arg->name); + arg_ast_t *keyworded = Tableヽstr_get(used_args, spec_arg->name); if (keyworded) continue; type_t *spec_type = get_arg_type(env, spec_arg); @@ -1678,7 +1678,7 @@ Table_t *get_arg_bindings(env_t *env, arg_t *spec_args, arg_ast_t *call_args, bo if (!complete_call_type) return NULL; if (!type_eq(complete_call_type, spec_type)) return NULL; // Positional arg trying to fill in - Table$str_set(&used_args, spec_arg->name, unused_args); + Tableヽstr_set(&used_args, spec_arg->name, unused_args); unused_args = unused_args->next; goto found_it; } @@ -1745,9 +1745,9 @@ PUREFUNC bool is_constant(env_t *env, ast_t *ast) case Bool: case Num: case None: return true; case Int: { DeclareMatch(info, ast, Int); - Int_t int_val = Int$parse(Text$from_str(info->str), NULL); + Int_t int_val = Intヽparse(Textヽfrom_str(info->str), NULL); if (int_val.small == 0) return false; // Failed to parse - return (Int$compare_value(int_val, I(BIGGEST_SMALL_INT)) <= 0); + return (Intヽcompare_value(int_val, I(BIGGEST_SMALL_INT)) <= 0); } case TextJoin: { DeclareMatch(text, ast, TextJoin); @@ -1759,7 +1759,7 @@ PUREFUNC bool is_constant(env_t *env, ast_t *ast) Text_t literal = Match(ast, TextLiteral)->text; TextIter_t state = NEW_TEXT_ITER_STATE(literal); for (int64_t i = 0; i < literal.length; i++) { - int32_t g = Text$get_grapheme_fast(&state, i); + int32_t g = Textヽget_grapheme_fast(&state, i); if (g < 0 || g > 127 || !isascii(g)) return false; } diff --git a/src/types.c b/src/types.c index f2dc5ddd..c7fdda65 100644 --- a/src/types.c +++ b/src/types.c @@ -29,7 +29,7 @@ Text_t type_to_text(type_t *t) { case BoolType: return Text("Bool"); case ByteType: return Text("Byte"); case CStringType: return Text("CString"); - case TextType: return Match(t, TextType)->lang ? Text$from_str(Match(t, TextType)->lang) : Text("Text"); + case TextType: return Match(t, TextType)->lang ? Textヽfrom_str(Match(t, TextType)->lang) : Text("Text"); case BigIntType: return Text("Int"); case IntType: return Texts("Int", String(Match(t, IntType)->bits)); case NumType: return Match(t, NumType)->bits == TYPE_NBITS32 ? Text("Num32") : Text("Num"); @@ -62,7 +62,7 @@ Text_t type_to_text(type_t *t) { } case StructType: { DeclareMatch(struct_, t, StructType); - return Text$from_str(struct_->name); + return Textヽfrom_str(struct_->name); } case PointerType: { DeclareMatch(ptr, t, PointerType); @@ -71,7 +71,7 @@ Text_t type_to_text(type_t *t) { } case EnumType: { DeclareMatch(tagged, t, EnumType); - return Text$from_str(tagged->name); + return Textヽfrom_str(tagged->name); } case OptionalType: { type_t *opt = Match(t, OptionalType)->type; @@ -81,7 +81,7 @@ Text_t type_to_text(type_t *t) { return Text("(Unknown optional type)"); } case TypeInfoType: { - return Texts("Type$info(", Match(t, TypeInfoType)->name, ")"); + return Texts("Typeヽinfo(", Match(t, TypeInfoType)->name, ")"); } case ModuleType: { return Texts("Module(", Match(t, ModuleType)->name, ")"); @@ -95,7 +95,7 @@ Text_t type_to_text(type_t *t) { const char *type_to_str(type_t *t) { - return Text$as_c_string(type_to_text(t)); + return Textヽas_c_string(type_to_text(t)); } PUREFUNC const char *get_type_name(type_t *t) @@ -114,7 +114,7 @@ bool type_eq(type_t *a, type_t *b) if (!a && !b) return true; if (!a || !b) return false; if (a->tag != b->tag) return false; - return Text$equal_values(type_to_text(a), type_to_text(b)); + return Textヽequal_values(type_to_text(a), type_to_text(b)); } bool type_is_a(type_t *t, type_t *req) |
