Lichen

templates/native/str.c

750:44ea0968a550
2017-03-20 Paul Boddie Added the context identity to the AttrResult string representation.
     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, __data__).intvalue;   117     /* end.__data__ interpreted as int */   118     int iend = __load_via_object(end->value, __data__).intvalue;   119     /* step.__data__ interpreted as int */   120     int istep = __load_via_object(step->value, __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 }