mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-24 16:11:04 +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;
|
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) {
|
void cosmoB_loadLibrary(CState *state) {
|
||||||
const char *identifiers[] = {
|
const char *identifiers[] = {
|
||||||
"print",
|
"print",
|
||||||
@ -178,8 +257,16 @@ void cosmoB_loadLibrary(CState *state) {
|
|||||||
// sub
|
// sub
|
||||||
cosmoV_pushString(state, "sub");
|
cosmoV_pushString(state, "sub");
|
||||||
cosmoV_pushCFunction(state, cosmoB_sSub);
|
cosmoV_pushCFunction(state, cosmoB_sSub);
|
||||||
|
|
||||||
|
// find
|
||||||
|
cosmoV_pushString(state, "find");
|
||||||
|
cosmoV_pushCFunction(state, cosmoB_sFind);
|
||||||
|
|
||||||
|
// split
|
||||||
|
cosmoV_pushString(state, "split");
|
||||||
|
cosmoV_pushCFunction(state, cosmoB_sSplit);
|
||||||
|
|
||||||
cosmoV_makeObject(state, 1);
|
cosmoV_makeObject(state, 3);
|
||||||
// string.*
|
// string.*
|
||||||
|
|
||||||
// grab the object from the stack and set the base protoObject
|
// grab the object from the stack and set the base protoObject
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "cstate.h"
|
#include "cstate.h"
|
||||||
|
|
||||||
#define GC_STRESS
|
//#define GC_STRESS
|
||||||
//#define GC_DEBUG
|
//#define GC_DEBUG
|
||||||
// arrays will grow by a factor of 2
|
// arrays will grow by a factor of 2
|
||||||
#define GROW_FACTOR 2
|
#define GROW_FACTOR 2
|
||||||
|
12
src/cvm.c
12
src/cvm.c
@ -281,7 +281,7 @@ static bool rawCall(CState *state, CObjClosure *closure, int args, int nresults,
|
|||||||
|
|
||||||
// pop the callframe and return results :)
|
// pop the callframe and return results :)
|
||||||
popCallFrame(state, offset);
|
popCallFrame(state, offset);
|
||||||
|
|
||||||
if (state->panic) // panic state
|
if (state->panic) // panic state
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -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
|
case COBJ_OBJECT: { // object is being instantiated, making another object
|
||||||
CObjObject *protoObj = (CObjObject*)cosmoV_readObj(func);
|
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);
|
CObjObject *newObj = cosmoO_newObject(state);
|
||||||
newObj->_obj.proto = protoObj;
|
newObj->_obj.proto = protoObj;
|
||||||
CValue ret;
|
cosmoV_pop(state); // pop proto
|
||||||
|
|
||||||
// check if they defined an initializer (we accept 0 return values)
|
// check if they defined an initializer (we accept 0 return values)
|
||||||
if (cosmoO_getIString(state, protoObj, ISTRING_INIT, &ret)) {
|
if (cosmoO_getIString(state, protoObj, ISTRING_INIT, &ret)) {
|
||||||
@ -577,6 +580,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
}
|
}
|
||||||
case OP_SETLOCAL: {
|
case OP_SETLOCAL: {
|
||||||
uint8_t indx = READBYTE();
|
uint8_t indx = READBYTE();
|
||||||
|
// set base to top of stack & pop
|
||||||
frame->base[indx] = *cosmoV_pop(state);
|
frame->base[indx] = *cosmoV_pop(state);
|
||||||
continue;
|
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
|
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);
|
StkPtr temp = cosmoV_getTop(state, 0);
|
||||||
|
|
||||||
if (!IS_OBJ(*temp) || cosmoV_readObj(*temp)->type != COBJ_TABLE) {
|
if (!IS_TABLE(*temp)) {
|
||||||
cosmoV_error(state, "Expected object, got %s!", cosmoV_typeStr(*temp));
|
cosmoV_error(state, "Expected table, got %s!", cosmoV_typeStr(*temp));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user