// feeds one readline() at a time static ekU32 fileIterator(struct ekContext *E, ekU32 argCount) { ekFrame *frame = ekArrayTop(E, &E->frames); ekValue *fileVal; ekValue *chompVal; ekFile *file; ekAssert(frame->closure && frame->closure->closureVars); fileVal = ekMapGetS2P(E, frame->closure->closureVars, "file"); chompVal = ekMapGetS2P(E, frame->closure->closureVars, "chomp"); ekAssert(argCount == 0); ekContextPopValues(E, argCount); file = (ekFile *)fileVal->ptrVal; switchState(E, file, EFS_READ); ekContextReturn(E, readLineInternal(E, file, chompVal->intVal)); }
static ekU32 regexGMatchIterator(struct ekContext * E, ekU32 argCount) { ekFrame * frame = ekArrayTop(E, &E->frames); ekValue * regexValue; ekRegex * regex; ekValue * results; ekAssert(frame->closure && frame->closure->closureVars); regexValue = ekMapGetS2P(E, frame->closure->closureVars, "regex"); regex = (ekRegex *)regexValue->ptrVal; ekAssert(argCount == 0); ekContextPopValues(E, argCount); results = ekValueCreateArray(E); if (!ekRegexMatchNext(E, regex, results)) { results = ekValueNullPtr; } ekContextReturn(E, results); }
void ekValueTypeRegisterInt(struct ekContext * E) { ekValueType * type = ekValueTypeCreate(E, "int", 'i'); type->funcClone = intFuncClone; type->funcToBool = intFuncToBool; type->funcToInt = intFuncToInt; type->funcToFloat = intFuncToFloat; type->funcToString = intFuncToString; type->funcArithmetic = intFuncArithmetic; type->funcCmp = intFuncCmp; type->funcDump = intFuncDump; ekValueTypeRegister(E, type); ekAssert(type->id == EVT_INT); ekContextAddIntrinsic(E, "int", ekiInt); }
void ekValueTypeRegisterFloat(struct ekContext * E) { ekValueType * type = ekValueTypeCreate(E, "float", 'f'); type->funcClone = floatFuncClone; type->funcToBool = floatFuncToBool; type->funcToInt = floatFuncToInt; type->funcToFloat = floatFuncToFloat; type->funcToString = floatFuncToString; type->funcArithmetic = floatFuncArithmetic; type->funcCmp = floatFuncCmp; type->funcDump = floatFuncDump; ekValueTypeRegister(E, type); ekAssert(type->id == EVT_FLOAT); ekContextAddIntrinsic(E, "float", ekiFloat); }
static ekBool ekRegexMatchNext(ekContext * E, ekRegex * regex, ekValue * matches) { // Why PCRE didn't make this an array of small structs is baffling to me; // it would have led to much more obvious, self-documenting code. ekS32 regexVectors[EUREKA_MAX_REGEX_VECTORS]; ekS32 len = strlen(ekValueSafeStr(regex->subject)); ekS32 err = pcre_exec(regex->regex, 0, ekValueSafeStr(regex->subject), len, regex->offset, 0, regexVectors, EUREKA_MAX_REGEX_VECTORS); if (err > 0) { ekS32 i; ekAssert(matches->type == EVT_ARRAY); for (i = 0; i < err; ++i) { ekS32 index = i * 2; ekValue * match = ekValueDonateString(E, ekSubstrdup(E, ekValueSafeStr(regex->subject), regexVectors[index], regexVectors[index + 1])); ekArrayPush(E, &matches->arrayVal, match); } regex->offset = regexVectors[1]; return ekTrue; } return ekFalse; }
ekS32 ekValueTypeRegister(struct ekContext *E, ekValueType *newType) { ekS32 i; for(i=0; i<ekArraySize(E, &E->types); ++i) { ekValueType *t = E->types[i]; if(!strcmp(newType->name, t->name)) { return EVT_INVALID; } } // If you are hitting one of these asserts, then your custom type isn't handling a required function. // If you're a C++ person, pretend the compiler is telling you that you forgot to implement a pure virtual. // If you don't want to do anything for a particular function, explicitly set it to ekValueTypeFuncNotUsed. ekAssert(newType->funcDump); // required! newType->id = ekArrayPush(E, &E->types, newType); return newType->id; }
static void fileFuncClone(struct ekContext *E, struct ekValue *dst, struct ekValue *src) { ekAssert(0 && "fileFuncClone not implemented"); }