mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 08:10:05 +00:00
Added string.split() & string.find()
This commit is contained in:
parent
2864c7be53
commit
3c19079262
@ -142,6 +142,85 @@ int cosmoB_sSub(CState *state, int nargs, CValue *args) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// string.find
|
||||
int cosmoB_sFind(CState *state, int nargs, CValue *args) {
|
||||
if (nargs == 2) {
|
||||
if (!IS_STRING(args[0]) || !IS_STRING(args[1])) {
|
||||
cosmoV_typeError(state, "string.find()", "<string>, <string>", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
CObjString *str = cosmoV_readString(args[0]);
|
||||
CObjString *ptrn = cosmoV_readString(args[1]);
|
||||
|
||||
char *indx = strstr(str->str, ptrn->str);
|
||||
|
||||
// failed, we have nothing to return
|
||||
if (indx == NULL)
|
||||
return 0;
|
||||
|
||||
// success! push the index
|
||||
cosmoV_pushNumber(state, indx - str->str);
|
||||
} else if (nargs == 3) {
|
||||
if (!IS_STRING(args[0]) || !IS_STRING(args[1]) || !IS_NUMBER(args[2])) {
|
||||
cosmoV_typeError(state, "string.find()", "<string>, <string>, <number>", "%s, %s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1]), cosmoV_typeStr(args[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
CObjString *str = cosmoV_readString(args[0]);
|
||||
CObjString *ptrn = cosmoV_readString(args[1]);
|
||||
int startIndx = (int)cosmoV_readNumber(args[2]);
|
||||
|
||||
char *indx = strstr(str->str + startIndx, ptrn->str);
|
||||
|
||||
// failed, we have nothing to return
|
||||
if (indx == NULL)
|
||||
return 0;
|
||||
|
||||
// success! push the index
|
||||
cosmoV_pushNumber(state, indx - str->str);
|
||||
} else {
|
||||
cosmoV_error(state, "Expected 2 or 3 arguments, got %d!", nargs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// string.split
|
||||
int cosmoB_sSplit(CState *state, int nargs, CValue *args) {
|
||||
if (nargs != 2) {
|
||||
cosmoV_error(state, "Expected 2 arguments, got %d!", nargs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!IS_STRING(args[0]) || !IS_STRING(args[1])) {
|
||||
cosmoV_typeError(state, "string.split()", "<string>, <string>", "%s, %s", cosmoV_typeStr(args[0]), cosmoV_typeStr(args[1]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
CObjString *str = cosmoV_readString(args[0]);
|
||||
CObjString *ptrn = cosmoV_readString(args[1]);
|
||||
|
||||
int nEntries = 0;
|
||||
char *indx = str->str;
|
||||
char *nIndx;
|
||||
|
||||
// while there are still patterns to match in the string, push the split strings onto the stack
|
||||
do {
|
||||
nIndx = strstr(indx, ptrn->str);
|
||||
|
||||
cosmoV_pushNumber(state, nEntries++);
|
||||
cosmoV_pushLString(state, indx, nIndx == NULL ? strlen(indx) : nIndx - indx);
|
||||
|
||||
indx = nIndx + ptrn->length;
|
||||
} while (nIndx != NULL);
|
||||
|
||||
// finally, make a table out of the pushed entries
|
||||
cosmoV_makeTable(state, nEntries);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cosmoB_loadLibrary(CState *state) {
|
||||
const char *identifiers[] = {
|
||||
"print",
|
||||
@ -179,7 +258,15 @@ void cosmoB_loadLibrary(CState *state) {
|
||||
cosmoV_pushString(state, "sub");
|
||||
cosmoV_pushCFunction(state, cosmoB_sSub);
|
||||
|
||||
cosmoV_makeObject(state, 1);
|
||||
// find
|
||||
cosmoV_pushString(state, "find");
|
||||
cosmoV_pushCFunction(state, cosmoB_sFind);
|
||||
|
||||
// split
|
||||
cosmoV_pushString(state, "split");
|
||||
cosmoV_pushCFunction(state, cosmoB_sSplit);
|
||||
|
||||
cosmoV_makeObject(state, 3);
|
||||
// string.*
|
||||
|
||||
// grab the object from the stack and set the base protoObject
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "cstate.h"
|
||||
|
||||
#define GC_STRESS
|
||||
//#define GC_STRESS
|
||||
//#define GC_DEBUG
|
||||
// arrays will grow by a factor of 2
|
||||
#define GROW_FACTOR 2
|
||||
|
10
src/cvm.c
10
src/cvm.c
@ -320,9 +320,12 @@ bool callCValue(CState *state, CValue func, int args, int nresults, int offset)
|
||||
}
|
||||
case COBJ_OBJECT: { // object is being instantiated, making another object
|
||||
CObjObject *protoObj = (CObjObject*)cosmoV_readObj(func);
|
||||
CValue ret;
|
||||
|
||||
cosmoV_pushValue(state, cosmoV_newObj(protoObj)); // push proto to stack for GC to find
|
||||
CObjObject *newObj = cosmoO_newObject(state);
|
||||
newObj->_obj.proto = protoObj;
|
||||
CValue ret;
|
||||
cosmoV_pop(state); // pop proto
|
||||
|
||||
// check if they defined an initializer (we accept 0 return values)
|
||||
if (cosmoO_getIString(state, protoObj, ISTRING_INIT, &ret)) {
|
||||
@ -577,6 +580,7 @@ int cosmoV_execute(CState *state) {
|
||||
}
|
||||
case OP_SETLOCAL: {
|
||||
uint8_t indx = READBYTE();
|
||||
// set base to top of stack & pop
|
||||
frame->base[indx] = *cosmoV_pop(state);
|
||||
continue;
|
||||
}
|
||||
@ -978,8 +982,8 @@ int cosmoV_execute(CState *state) {
|
||||
case OP_COUNT: { // pop 1 value off the stack & if it's a table return the amount of active entries it has
|
||||
StkPtr temp = cosmoV_getTop(state, 0);
|
||||
|
||||
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_TABLE) {
|
||||
cosmoV_error(state, "Expected object, got %s!", cosmoV_typeStr(*temp));
|
||||
if (!IS_TABLE(*temp)) {
|
||||
cosmoV_error(state, "Expected table, got %s!", cosmoV_typeStr(*temp));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user