pebblisp/src/plfunc/plstring.c

119 lines
3.0 KiB
C

#include "plstring.h"
#include <string.h>
Object charVal(Object* params, unused int length, unused struct Environment* env)
{
checkTypes(charVal)
Object test = params[0];
return numberObject(test.string[0]);
}
Object chars(Object* params, unused int length, unused struct Environment* env)
{
checkTypes(chars)
char c[2];
c[1] = '\0';
int i = 0;
Object list = listObject();
while (params[0].string[i]) {
c[0] = params[0].string[i];
nf_addToList(&list, stringFromSlice(c, 1));
i++;
}
return list;
}
size_t literalLen(const char* pattern)
{
const char* cursor = pattern;
while (*cursor != '*' && *cursor != '\0') {
cursor++;
}
return cursor - pattern;
}
/// Returns 1 on match, 0 otherwise
int stringComp(const char* string, const char* pattern)
{
const char* cursor = string;
const char* patternCursor = pattern;
while (*patternCursor) {
size_t len = literalLen(patternCursor);
if (len == 0) {
patternCursor += 1;
while (!stringComp(cursor, patternCursor)) {
cursor++;
if (*cursor == '\0') {
return 0;
}
}
} else {
if (strncmp(patternCursor, cursor, len) != 0) {
return 0;
}
patternCursor += len;
}
}
return 1;
}
Object matches(Object* params, int length, unused struct Environment* env)
{
checkTypes(matches)
return boolObject(stringComp(params[0].string, params[1].string));
}
Object slen(Object* params, int length, unused struct Environment* env)
{
checkTypes(slen)
return numberObject(strlen(params[0].string));
}
Object substring(Object* params, int length, unused struct Environment* env)
{
checkTypes(substring)
Object start = params[0]; // First char to include
Object end = params[1]; // First char to exclude
Object string = params[2];
long len = end.number - start.number;
size_t stringLen = strlen(string.string);
if (len < 0) {
throw(BAD_PARAMS, "substr start index (%ld) is higher than its end index (%ld)!", start.number, end.number);
}
if (start.number > stringLen) {
throw(BAD_PARAMS, "substr start index (%ld) is higher than the string length (%lu)", start.number, stringLen);
}
if (len > stringLen - start.number) {
len = stringLen - start.number;
}
Object substr = withLen(len, TYPE_STRING);
snprintf(substr.string, len + 1, "%s", string.string + start.number);
return substr;
}
Object charAt(Object* params, unused int length, unused struct Environment* env)
{
checkTypes(charAt)
Object string = params[0];
Object at = params[1];
Object c = withLen(1, string.type);
c.string[1] = '\0';
for (int i = 0; i < at.number; i++) {
if (string.string[i] == '\0') {
c.string[0] = '\0';
return c;
}
}
c.string[0] = string.string[at.number];
return c;
}