diff --git a/src/ast.c b/src/ast.c index f0019bb..23d44da 100644 --- a/src/ast.c +++ b/src/ast.c @@ -491,7 +491,7 @@ class_t *newClass(char *id, body_t *body) { return class; } -expr_t *newExpr_Copy(expr_t *expr) { +expr_t *newExpr_Copy(expr_t *expr, EXPRESSION_PARAMS()) { expr_t *newExp = expr; if (expr == NULL) return NULL; @@ -514,8 +514,8 @@ expr_t *newExpr_Copy(expr_t *expr) { case EXPR_TYPE_UVAL: break; case EXPR_TYPE_VECTOR_IDX: { - expr_t *id = newExpr_Copy(expr->vecIdx->expr); - expr_t *index = newExpr_Copy(expr->vecIdx->index); + expr_t *id = newExpr_Copy(expr->vecIdx->expr, EXPRESSION_ARGS()); + expr_t *index = newExpr_Copy(expr->vecIdx->index, EXPRESSION_ARGS()); newExp = newExpr_VectorIndex(id, index); } break; case EXPR_TYPE_TEXT: { @@ -556,17 +556,18 @@ expr_t *newExpr_Copy(expr_t *expr) { ifCondition_t *cond = expr->cond; ifCondition_t *newCond = ast_emalloc(sizeof(ifCondition_t)); newCond->type = cond->type; - newCond->left = newExpr_Copy(cond->left); - newCond->right = newExpr_Copy(cond->right); + newCond->left = newExpr_Copy(cond->left, EXPRESSION_ARGS()); + newCond->right = newExpr_Copy(cond->right, EXPRESSION_ARGS()); newExp = newExpr_Cond(newCond); } break; case EXPR_TYPE_VECTOR: { - argsList_t *args = copy_argsList(expr->vec->content); - newExp = newExpr_Vector(args); + newExp = copy_vector(expr->vec, EXPRESSION_ARGS()); break; } case EXPR_TYPE_DICT: { - newExp = newExpr_Dictionary(expr->dict->keyVals); + newExp = ast_emalloc(sizeof(expr_t)); + newExp->type = EXPR_TYPE_DICT; + newExp->dict = allocNewDictionary(expr->dict, EXPRESSION_ARGS()); } break; case EXPR_TYPE_EMPTY: default: @@ -604,6 +605,10 @@ forEachStmt_t *newForEach(expr_t *root, char *entry, void *body) { stmt->uniqueUnfoldIncID = ast_emalloc(40); memset(stmt->uniqueUnfoldIncID, 0, 40); snprintf(stmt->uniqueUnfoldIncID, 40, "__UniqueShadyRicForEachInc%d", uniqueForEachUnfoldIndex); + stmt->uniqueUnfoldRootID = ast_emalloc(40); + memset(stmt->uniqueUnfoldRootID, 0, 40); + snprintf(stmt->uniqueUnfoldRootID, 40, "__UniqueShadyRicForEachRoot%d", + uniqueForEachUnfoldIndex); uniqueForEachUnfoldIndex++; return stmt; @@ -812,7 +817,6 @@ void free_expression(expr_t *expr) { } case EXPR_TYPE_DICT: { dictionary_t *dict = expr->dict; - if (dict->initialized) { hashtable_free(dict->hash); free(dict->hash); @@ -862,7 +866,12 @@ void free_expression(expr_t *expr) { while (vecWalk < len) { if (v->arg != NULL) { - free_expression(v->arg); + if (v->arg->type != EXPR_TYPE_DICT) { + free_expression(v->arg); + } else { + hashtable_free(v->arg->dict->hash); + free(v->arg->dict); + } free(v->arg); v->arg = NULL; } @@ -1028,10 +1037,8 @@ argsList_t *copy_argsList(argsList_t *args) { void free_keyvals(dictionary_t *dict) { keyValList_t *keyVals = dict->keyVals; - while (keyVals) { keyValList_t *kv = keyVals; - if (kv->val->type == EXPR_TYPE_DICT) { free_keyvals(kv->val->dict); free(kv->val->dict); diff --git a/src/ast.h b/src/ast.h index 481580e..676b4c4 100644 --- a/src/ast.h +++ b/src/ast.h @@ -290,6 +290,7 @@ typedef struct forEachStmt { expr_t *entry; body_t *body; char *uniqueUnfoldIncID; + char *uniqueUnfoldRootID; } forEachStmt_t; typedef struct functionCall_t { @@ -361,7 +362,6 @@ expr_t *newExpr_VectorFromForEach(statement_t *stmt); expr_t *newExpr_ClassPtr(class_t *class); expr_t *newExpr_ClassPtrCopy(class_t *class); expr_t *newExpr_VectorIndex(expr_t *expr, expr_t *index); -expr_t *newExpr_Copy(expr_t *exp); expr_t *newExpr_Logical(expr_t *prevLogical, expr_t *newAnd, expr_t *newOr); expr_t *newExpr_Indexer(expr_t *left, expr_t *right, expr_t *offset); expr_t *newExpr_BigIntFromStr(const char *intStr); @@ -552,6 +552,8 @@ typedef struct context_full_t { #define DECLARE_LIB_FUNCTION(name, args, func) \ { name, args, func } +expr_t *newExpr_Copy(expr_t *exp, EXPRESSION_PARAMS()); + typedef int (*ric_lib_callback_t)(LIBRARY_PARAMS()); typedef struct libFunction { diff --git a/src/eval.c b/src/eval.c index e7628c9..6cac324 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1255,7 +1255,7 @@ void evaluate_expression(expr_t *expr, EXPRESSION_PARAMS()) { /* Add this expression to the vector */ argsList_t *a; expr_t *e = walk->arg; - e = newExpr_Copy(e); + e = newExpr_Copy(e, EXPRESSION_ARGS()); a = newArgument(e, vecContent); vecContent = a; } @@ -3478,6 +3478,7 @@ dictionary_t *allocNewDictionary(dictionary_t *dict, EXPRESSION_PARAMS()) { void *sp = PROVIDE_CONTEXT()->sp; size_t *sc = PROVIDE_CONTEXT()->sc; dictionary_t *newDict = ast_emalloc(sizeof(dictionary_t)); + newDict->type = dict->type; newDict->hash = hashtable_new(DICTIONARY_STANDARD_SIZE, DICTIONARY_STANDARD_LOAD); newDict->hash->allocated_key = 1; @@ -3508,7 +3509,6 @@ dictionary_t *allocNewDictionary(dictionary_t *dict, EXPRESSION_PARAMS()) { exit(1); break; } - evaluate_expression(expVal, EXPRESSION_ARGS()); POP_VAL(&sv, sp, sc); @@ -3536,7 +3536,7 @@ dictionary_t *allocNewDictionary(dictionary_t *dict, EXPRESSION_PARAMS()) { eTemp->type = EXPR_TYPE_VECTOR; eTemp->vec = sv.vec; - newVecExpr = newExpr_Copy(eTemp); + newVecExpr = newExpr_Copy(eTemp, EXPRESSION_ARGS()); free(eTemp); newStackVal = sv; @@ -3626,7 +3626,7 @@ dictionary_t *allocNewDictionary(dictionary_t *dict, EXPRESSION_PARAMS()) { eTemp->type = EXPR_TYPE_VECTOR; eTemp->vec = sv.vec; - newVecExpr = newExpr_Copy(eTemp); + newVecExpr = newExpr_Copy(eTemp, EXPRESSION_ARGS()); free(eTemp); newStackVal = sv; @@ -3676,6 +3676,5 @@ dictionary_t *allocNewDictionary(dictionary_t *dict, EXPRESSION_PARAMS()) { } newDict->initialized = 1; - return newDict; } diff --git a/src/garbage.c b/src/garbage.c index 46ef1b5..8176d37 100644 --- a/src/garbage.c +++ b/src/garbage.c @@ -53,7 +53,7 @@ void mark(hashtable_t *varDecs, uint32_t markVal, EXPRESSION_PARAMS()) { argsList_t *args = vec->content; while (args != NULL) { expr_t *e = args->arg; - if (e->type == EXPR_TYPE_DICT && e->dict->type == RIC_DICTIONARY_DYN) { + if (e->type == EXPR_TYPE_DICT) { mark(e->dict->hash, markVal, EXPRESSION_ARGS()); } if (e->type == EXPR_TYPE_CLASSPTR && e->classObj->initialized) { @@ -84,7 +84,6 @@ void mark(hashtable_t *varDecs, uint32_t markVal, EXPRESSION_PARAMS()) { while (i < argCount) { heapval_t *hv = hashtable_get(varDecs, NULL, variableIDS[i]); hv->mark = markVal; - if (hv->sv.type == DICTTYPE) { mark(hv->sv.dict->hash, markVal, EXPRESSION_ARGS()); } else if (hv->sv.type == CLASSTYPE && hv->sv.classObj->initialized) { @@ -94,9 +93,12 @@ void mark(hashtable_t *varDecs, uint32_t markVal, EXPRESSION_PARAMS()) { argsList_t *args = vec->content; while (args != NULL) { expr_t *e = args->arg; - if (e->type == EXPR_TYPE_DICT && e->dict->type == RIC_DICTIONARY_DYN) { + if (e->type == EXPR_TYPE_DICT) { mark(e->dict->hash, markVal, EXPRESSION_ARGS()); } + if (e->type == EXPR_TYPE_CLASSPTR && e->classObj->initialized) { + mark(e->classObj->varMembers, markVal, EXPRESSION_ARGS()); + } args = args->next; } } diff --git a/src/interpret.c b/src/interpret.c index f73dd84..805590b 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -466,6 +466,17 @@ interpret_state_t interpret_statements_(void *stmt, PROVIDE_CONTEXT_ARGS(), args } if (rootVec != NULL) { + /* place the root vec on the heap */ + stackval_t svtmp; + int dummy; + heapval_t *hvp = NULL; + heapval_t *hp = PROVIDE_CONTEXT()->hp; + + svtmp.type = VECTORTYPE; + svtmp.vec = rootVec; + ALLOC_HEAP(&svtmp, hp, &hvp, &dummy); + locals_push(varLocals, festmt->uniqueUnfoldRootID, hvp); + endIteration = rootVec->length; } else if (rootDict != NULL) { /* traverse the dictionary keys */ @@ -690,13 +701,17 @@ interpret_state_t interpret_statements_(void *stmt, PROVIDE_CONTEXT_ARGS(), args } else if (rootInt >= 0) { /* traverse the integer, start from zero */ hvp = locals_lookup(varLocals, entryId); - stackval_t sv; - - sv.type = INT32TYPE; - sv.i = festmtIndex; - ALLOC_HEAP(&sv, hp, &hvp, &dummy); - locals_push(varLocals, entryId, hvp); + if (hvp == NULL) { + stackval_t sv; + sv.type = INT32TYPE; + sv.i = festmtIndex; + ALLOC_HEAP(&sv, hp, &hvp, &dummy); + locals_push(varLocals, entryId, hvp); + } else { + /* Update value on the heap */ + hvp->sv.i = festmtIndex; + } /* Increase the value of the unfolded variable */ festmtIndex++; hvp = locals_lookup(varLocals, festmt->uniqueUnfoldIncID); @@ -719,16 +734,20 @@ interpret_state_t interpret_statements_(void *stmt, PROVIDE_CONTEXT_ARGS(), args heapval_t *hvp = NULL; hvp = locals_lookup(varLocals, entryId); - e = newExpr_BigIntFromInt(0); + if (hvp == NULL) { + e = newExpr_BigIntFromInt(0); - sv.type = BIGINT; - sv.bigInt = e->bigInt; - free(e); + sv.type = BIGINT; + sv.bigInt = e->bigInt; + free(e); - mpz_add_ui(*sv.bigInt, festmtBigIndex, 0); + mpz_add_ui(*sv.bigInt, festmtBigIndex, 0); - ALLOC_HEAP(&sv, hp, &hvp, &dummy); - locals_push(varLocals, entryId, hvp); + ALLOC_HEAP(&sv, hp, &hvp, &dummy); + locals_push(varLocals, entryId, hvp); + } else { + mpz_add_ui(*hvp->sv.bigInt, festmtBigIndex, 0); + } /* Increase the value of the unfolded variable */ mpz_add_ui(festmtBigIndex, festmtBigIndex, 1); @@ -850,16 +869,18 @@ interpret_state_t interpret_statements_(void *stmt, PROVIDE_CONTEXT_ARGS(), args free(newVec); } - if (rootDict == NULL) { + if (rootDict != NULL) { /* * root expressions are heap allocated * all others will be manually cleaned up here */ - free_expression(rootExp); - } else { free_hashtable_table(rootDict->hash); free(rootDict->hash); free(rootDict); + } else if (rootVec != NULL) { + /* Root vec will be taken care of by the collector */ + } else { + free_expression(rootExp); } free(rootExp); if (interpret_state == INTEPRET_RETURN) { @@ -1388,7 +1409,13 @@ static void flush_arg(void *key, void *val) { argsList_t *next; while (walk != NULL) { next = walk->next; - free_expression(walk->arg); + if (walk->arg->type != EXPR_TYPE_DICT) { + free_expression(walk->arg); + } else { + free_hashtable_table(walk->arg->dict->hash); + free(walk->arg->dict); + } + free(walk->arg); free(walk); walk = next; } diff --git a/src/lib.c b/src/lib.c index 0f7b430..543a8b3 100644 --- a/src/lib.c +++ b/src/lib.c @@ -48,7 +48,6 @@ libFunction_t ric_library[] = { DECLARE_LIB_FUNCTION("toLower", 1, ric_to_lower), DECLARE_LIB_FUNCTION("startsWith", 2, ric_starts_with), DECLARE_LIB_FUNCTION("endsWith", 2, ric_ends_with), - DECLARE_LIB_FUNCTION("endsWith", 2, ric_ends_with), DECLARE_LIB_FUNCTION("trim", 1, ric_trim), DECLARE_LIB_FUNCTION("isnumeric", 1, ric_is_numerical), // libbigint diff --git a/src/library/libjson.c b/src/library/libjson.c index 5031ec7..77c641a 100644 --- a/src/library/libjson.c +++ b/src/library/libjson.c @@ -86,6 +86,11 @@ static void loadCJSON(cJSON *json, int depth, expr_t **out, EXPRESSION_PARAMS()) keyVals = keyValsHead; if (isArray && out != NULL) { + expr_t *newVec = NULL; + stackval_t stv; + int dummy; + heapval_t *hpv = NULL; + heapval_t *hp = PROVIDE_CONTEXT()->hp; argsList_t *args = NULL; argsList_t *argsHead = NULL; keyValList_t *keyValsWalk = keyVals; @@ -132,11 +137,21 @@ static void loadCJSON(cJSON *json, int depth, expr_t **out, EXPRESSION_PARAMS()) keyValsWalk = keyValsWalk->next; free(kvw); } - *out = newExpr_Vector(args); + newVec = newExpr_Vector(args); + stv.type = VECTORTYPE; + stv.vec = newVec->vec; + + ALLOC_HEAP(&stv, hp, &hpv, &dummy); + *out = newVec; } else if (out != NULL) { expr_t *outE = newExpr_Dictionary(keyVals); - outE->dict->type = RIC_DICTIONARY_DYN; - *out = outE; + dictionary_t *outEHead = allocNewDictionary(outE->dict, EXPRESSION_ARGS()); + free(outE->dict); + expr_t *newExp = ast_emalloc(sizeof(expr_t)); + newExp->type = EXPR_TYPE_DICT; + newExp->dict = outEHead; + free(outE); + *out = newExp; } } diff --git a/src/library/libstd.c b/src/library/libstd.c index cafb843..74df952 100644 --- a/src/library/libstd.c +++ b/src/library/libstd.c @@ -687,6 +687,11 @@ int ric_append(LIBRARY_PARAMS()) { case CLASSTYPE: entry = newExpr_ClassPtrCopy(stv.classObj); break; + case DICTTYPE: { + entry = ast_emalloc(sizeof(expr_t)); + entry->type = EXPR_TYPE_DICT; + entry->dict = allocNewDictionary(stv.dict, EXPRESSION_ARGS()); + } break; case FUNCPTRTYPE: entry = newExpr_FuncPtr((void *)stv.p); break; diff --git a/src/library/libstring.c b/src/library/libstring.c index 8d72416..9c1fb81 100644 --- a/src/library/libstring.c +++ b/src/library/libstring.c @@ -417,16 +417,17 @@ int ric_ends_with(LIBRARY_PARAMS()) { } if (strlen(arg2) <= strlen(arg1)) { - char *start = arg2; compareBase = arg1 + (strlen(arg1) - 1); compareWith = arg2 + (strlen(arg2) - 1); + size_t comparisons = 0; - while (compareWith != start && *compareBase && *compareWith == *compareBase) { + while (comparisons < strlen(arg2) && *compareBase && *compareWith == *compareBase) { compareBase--; compareWith--; + comparisons++; } - if (compareWith == start) { + if (comparisons > 0) { result = 1; } }