Lichen

templates/native/str.c

1022:582d834d392d
14 months ago Paul Boddie Merged changes from the value-replacement branch. value-replacement-for-wrapper
     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 }