Lichen

templates/native/str.c

843:d305986d05c8
2018-07-05 Paul Boddie Employed sets for attributes and providers referenced by accesses. This causes various attributes to be identified definitively in the access plans and instruction sequences.
     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 }