1 /* Native functions for string operations. 2 3 Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 4 5 This program is free software; you can redistribute it and/or modify it under 6 the terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3 of the License, or (at your option) any later 8 version. 9 10 This program is distributed in the hope that it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 13 details. 14 15 You should have received a copy of the GNU General Public License along with 16 this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include <string.h> /* strcmp, memcpy */ 20 #include "native/common.h" 21 #include "types.h" 22 #include "exceptions.h" 23 #include "ops.h" 24 #include "progconsts.h" 25 #include "progops.h" 26 #include "progtypes.h" 27 #include "main.h" 28 29 /* String operations. */ 30 31 __attr __fn_native_str_str_add(__attr __result, __attr __self, __attr _data, __attr other, __attr _size, __attr othersize) 32 { 33 /* _data, other interpreted as string.__data__ */ 34 char *s = _data.strvalue; 35 char *o = other.strvalue; 36 /* _size, othersize interpreted as size */ 37 __int ss = __TOINT(_size), os = __TOINT(othersize); 38 __int n = ss + os; 39 char *r = (char *) __ALLOCATE(n + 1, sizeof(char)); 40 41 memcpy(r, s, ss); 42 memcpy(r + ss, o, os); 43 44 /* Return a new string. */ 45 return __new_str(r, n); 46 } 47 48 __attr __fn_native_str_str_chr(__attr __result, __attr __self, __attr _data) 49 { 50 /* data interpreted as int */ 51 int n = __TOINT(_data); 52 char *s = (char *) __ALLOCATE(2, sizeof(char)); 53 54 s[0] = (char) n; 55 return __new_str(s, 1); 56 } 57 58 __attr __fn_native_str_str_lt(__attr __result, __attr __self, __attr _data, __attr other) 59 { 60 /* _data, other interpreted as string.__data__ */ 61 char *s = _data.strvalue; 62 char *o = other.strvalue; 63 64 /* NOTE: Using simple byte-level string operations. */ 65 return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False; 66 } 67 68 __attr __fn_native_str_str_gt(__attr __result, __attr __self, __attr _data, __attr other) 69 { 70 /* _data, other interpreted as string.__data__ */ 71 char *s = _data.strvalue; 72 char *o = other.strvalue; 73 74 /* NOTE: Using simple byte-level string operations. */ 75 return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False; 76 } 77 78 __attr __fn_native_str_str_eq(__attr __result, __attr __self, __attr _data, __attr other) 79 { 80 /* _data, other interpreted as string.__data__ */ 81 char *s = _data.strvalue; 82 char *o = other.strvalue; 83 84 /* NOTE: Using simple byte-level string operations. */ 85 return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False; 86 } 87 88 __attr __fn_native_str_str_ord(__attr __result, __attr __self, __attr _data) 89 { 90 /* _data interpreted as string.__data__ */ 91 char *s = _data.strvalue; 92 93 return __new_int((__int) s[0]); 94 } 95 96 __attr __fn_native_str_str_size(__attr __result, __attr __self, __attr _size) 97 { 98 return __new_int(__TOINT(_size)); 99 } 100 101 __attr __fn_native_str_str_substr(__attr __result, __attr __self, __attr _data, __attr start, __attr end, __attr step) 102 { 103 /* _data interpreted as string.__data__ */ 104 char *s = _data.strvalue, *sub; 105 /* start interpreted as int */ 106 __int istart = __TOINT(start); 107 /* end interpreted as int */ 108 __int iend = __TOINT(end); 109 /* step interpreted as int */ 110 __int istep = __TOINT(step); 111 112 /* Calculate the size of the substring. */ 113 size_t resultsize = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1; 114 size_t to, from; 115 116 /* Reserve space for a new string. */ 117 sub = (char *) __ALLOCATE(resultsize + 1, sizeof(char)); 118 119 /* Does not null terminate but final byte should be zero. */ 120 if (istep > 0) 121 for (from = istart, to = 0; from < iend; from += istep, to++) 122 sub[to] = s[from]; 123 else if (istep < 0) 124 for (from = istart, to = 0; from > iend; from += istep, to++) 125 sub[to] = s[from]; 126 127 return __new_str(sub, resultsize); 128 } 129 130 /* Module initialisation. */ 131 132 void __main_native_str() 133 { 134 }