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 __args[]) 32 { 33 __attr * const _data = &__args[1]; 34 __attr * const other = &__args[2]; 35 __attr * const _size = &__args[3]; 36 __attr * const othersize = &__args[4]; 37 /* _data, other interpreted as string */ 38 char *s = _data->strvalue; 39 char *o = other->strvalue; 40 int ss = _size->intvalue, os = othersize->intvalue; 41 int n = ss + os; 42 char *r = (char *) __ALLOCATE(n + 1, sizeof(char)); 43 44 memcpy(r, s, ss); 45 memcpy(r + ss, o, os); 46 47 /* Return a new string. */ 48 return __new_str(r, n); 49 } 50 51 __attr __fn_native_str_str_chr(__attr __args[]) 52 { 53 __attr * const _data = &__args[1]; 54 /* _data interpreted as int */ 55 int n = _data->intvalue; 56 char *s = (char *) __ALLOCATE(2, sizeof(char)); 57 58 s[0] = (char) n; 59 return __new_str(s, 1); 60 } 61 62 __attr __fn_native_str_str_lt(__attr __args[]) 63 { 64 __attr * const _data = &__args[1]; 65 __attr * const other = &__args[2]; 66 /* _data, other interpreted as string */ 67 char *s = _data->strvalue; 68 char *o = other->strvalue; 69 70 /* NOTE: Using simple byte-level string operations. */ 71 return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False; 72 } 73 74 __attr __fn_native_str_str_gt(__attr __args[]) 75 { 76 __attr * const _data = &__args[1]; 77 __attr * const other = &__args[2]; 78 /* _data, other interpreted as string */ 79 char *s = _data->strvalue; 80 char *o = other->strvalue; 81 82 /* NOTE: Using simple byte-level string operations. */ 83 return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False; 84 } 85 86 __attr __fn_native_str_str_eq(__attr __args[]) 87 { 88 __attr * const _data = &__args[1]; 89 __attr * const other = &__args[2]; 90 /* _data, other interpreted as string */ 91 char *s = _data->strvalue; 92 char *o = other->strvalue; 93 94 /* NOTE: Using simple byte-level string operations. */ 95 return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False; 96 } 97 98 __attr __fn_native_str_str_ord(__attr __args[]) 99 { 100 __attr * const _data = &__args[1]; 101 /* _data interpreted as string */ 102 char *s = _data->strvalue; 103 104 return __new_int((unsigned int) s[0]); 105 } 106 107 __attr __fn_native_str_str_substr(__attr __args[]) 108 { 109 __attr * const _data = &__args[1]; 110 __attr * const start = &__args[2]; 111 __attr * const end = &__args[3]; 112 __attr * const step = &__args[4]; 113 /* _data interpreted as string */ 114 char *s = _data->strvalue, *sub; 115 /* start.__data__ interpreted as int */ 116 int istart = __load_via_object(start->value, __pos___data__).intvalue; 117 /* end.__data__ interpreted as int */ 118 int iend = __load_via_object(end->value, __pos___data__).intvalue; 119 /* step.__data__ interpreted as int */ 120 int istep = __load_via_object(step->value, __pos___data__).intvalue; 121 122 /* Calculate the size of the substring. */ 123 size_t resultsize = ((iend - istart - (istep > 0 ? 1 : -1)) / istep) + 1; 124 int to, from; 125 126 /* Reserve space for a new string. */ 127 sub = (char *) __ALLOCATE(resultsize + 1, sizeof(char)); 128 129 /* Does not null terminate but final byte should be zero. */ 130 if (istep > 0) 131 for (from = istart, to = 0; from < iend; from += istep, to++) 132 sub[to] = s[from]; 133 else if (istep < 0) 134 for (from = istart, to = 0; from > iend; from += istep, to++) 135 sub[to] = s[from]; 136 137 return __new_str(sub, resultsize); 138 } 139 140 /* Module initialisation. */ 141 142 void __main_native_str() 143 { 144 }