1 /* Native functions for string operations. 2 3 Copyright (C) 2016, 2017 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 __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 int */ 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 __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 __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 __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 __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 __self, __attr _data) 89 { 90 /* _data interpreted as string.__data__ */ 91 char *s = _data.strvalue; 92 93 return __new_int((unsigned int) s[0]); 94 } 95 96 __attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step) 97 { 98 /* _data interpreted as string.__data__ */ 99 char *s = _data.strvalue, *sub; 100 /* start interpreted as int */ 101 int istart = __TOINT(start); 102 /* end interpreted as int */ 103 int iend = __TOINT(end); 104 /* step interpreted as int */ 105 int istep = __TOINT(step); 106 107 /* Calculate the size of the substring. */ 108 size_t resultsize = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1; 109 int to, from; 110 111 /* Reserve space for a new string. */ 112 sub = (char *) __ALLOCATE(resultsize + 1, sizeof(char)); 113 114 /* Does not null terminate but final byte should be zero. */ 115 if (istep > 0) 116 for (from = istart, to = 0; from < iend; from += istep, to++) 117 sub[to] = s[from]; 118 else if (istep < 0) 119 for (from = istart, to = 0; from > iend; from += istep, to++) 120 sub[to] = s[from]; 121 122 return __new_str(sub, resultsize); 123 } 124 125 /* Module initialisation. */ 126 127 void __main_native_str() 128 { 129 }