On Thu, Apr 10, 2008 at 2:53 PM, Bert Wesarg <[EMAIL PROTECTED]> wrote:
> Maybe a drastically syntax extension is needed:
>
> rvalue: [EMAIL PROTECTED] := return max numeric index + 1
> lvalue: [EMAIL PROTECTED] = expr := push expr at position max numeric index
> + 1
For the curious guys out there, here is a patch to play with:
Btw, I really would like to use a '#' instead of the '@', but we all
know this doesn't work.
>
> Bert
>
---
source/interpret.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
source/interpret.h | 5 +-
source/parse.y | 6 +++
3 files changed, 106 insertions(+), 3 deletions(-)
diff --quilt old/source/interpret.c new/source/interpret.c
--- old/source/interpret.c
+++ new/source/interpret.c
@@ -135,6 +135,8 @@ static int arrayEntryCopyToNode(rbTreeNo
static int arrayEntryCompare(rbTreeNode *left, rbTreeNode *right);
static void arrayDisposeNode(rbTreeNode *src);
static SparseArrayEntry *allocateSparseArrayEntry(void);
+static int arrayAssignNext(void);
+static int arrayNextNumIdx(void);
/*#define DEBUG_ASSEMBLY*/
/*#define DEBUG_STACK*/
@@ -208,7 +210,8 @@ static int (*OpFns[N_OPS])() = {returnNo
assign, callSubroutine, fetchRetVal, branch, branchTrue, branchFalse,
branchNever, arrayRef, arrayAssign, beginArrayIter, arrayIter, inArray,
deleteArrayElement, pushArraySymVal,
- arrayRefAndAssignSetup, pushArgVal, pushArgCount, pushArgArray};
+ arrayRefAndAssignSetup, pushArgVal, pushArgCount, pushArgArray,
+ arrayAssignNext, arrayNextNumIdx};
/* Stack-> symN-sym0(FP), argArray, nArgs, oldFP, retPC, argN-arg1, next, ...
*/
#define FP_ARG_ARRAY_CACHE_INDEX (-1)
@@ -2446,6 +2449,27 @@ SparseArrayEntry *arrayIterateNext(Spars
return(nextPos);
}
+static int arrayMaxNumIdx(DataValue *theArray)
+{
+ int maxKey = -1;
+ SparseArrayEntry *iter;
+
+ iter = arrayIterateFirst(theArray);
+ while (iter) {
+ int thisKey;
+
+ if (StringToNum(iter->key, &thisKey)) {
+ /* even if the rbTree is sorted, check it to be sure */
+ if (thisKey > maxKey)
+ maxKey = thisKey;
+ }
+
+ iter = arrayIterateNext(iter);
+ }
+
+ return maxKey;
+}
+
/*
** evaluate an array element and push the result onto the stack
**
@@ -2811,6 +2835,78 @@ static int deleteArrayElement(void)
}
/*
+** assign to the next numerical index array element of a referenced
+** array on the stack
+**
+** Before: Prog-> next, ...
+** TheStack-> rhs, ArraySym, next, ...
+** After: Prog-> next, ... (unchanged)
+** TheStack-> next, ...
+*/
+static int arrayAssignNext(void)
+{
+ char *keyString = NULL;
+ DataValue srcValue, dstArray;
+ int errNum;
+
+ DISASM_RT(PC-1, 1);
+ STACKDUMP(0, 3);
+
+ POP(srcValue)
+
+ POP(dstArray)
+ if (dstArray.tag != ARRAY_TAG && dstArray.tag != NO_TAG) {
+ return(execError("cannot assign array element of non-array", NULL));
+ }
+
+ if (srcValue.tag == ARRAY_TAG) {
+ DataValue arrayCopyValue;
+
+ errNum = ArrayCopy(&arrayCopyValue, &srcValue);
+ srcValue = arrayCopyValue;
+ if (errNum != STAT_OK) {
+ return(errNum);
+ }
+ }
+
+ keyString = AllocString(TYPE_INT_STR_SIZE(int));
+ sprintf(keyString, "%d", arrayMaxNumIdx(&dstArray) + 1);
+
+ if (ArrayInsert(&dstArray, keyString, &srcValue)) {
+ return(STAT_OK);
+ }
+ else {
+ return(execError("array member allocation failure", NULL));
+ }
+}
+
+/*
+** return the free numeric index that is greater than all others
+**
+** Before: Prog-> next, ...
+** TheStack-> ArraySym, next, ...
+** After: Prog-> next, ... (unchanged)
+** TheStack-> numIdx, next, ...
+*/
+static int arrayNextNumIdx(void)
+{
+ DataValue srcArray;
+ SparseArrayEntry *iter;
+
+ DISASM_RT(PC-1, 1);
+ STACKDUMP(0, 3);
+
+ POP(srcArray)
+ if (srcArray.tag != ARRAY_TAG) {
+ return execError("operator [EMAIL PROTECTED] on non-array", NULL);
+ }
+
+ PUSH_INT(arrayMaxNumIdx(&srcArray) + 1)
+
+ return STAT_OK;
+}
+
+/*
** checks errno after operations which can set it. If an error occured,
** creates appropriate error messages and returns false
*/
diff --quilt old/source/interpret.h new/source/interpret.h
--- old/source/interpret.h
+++ new/source/interpret.h
@@ -40,7 +40,7 @@
enum symTypes {CONST_SYM, GLOBAL_SYM, LOCAL_SYM, ARG_SYM, PROC_VALUE_SYM,
C_FUNCTION_SYM, MACRO_FUNCTION_SYM, ACTION_ROUTINE_SYM};
-#define N_OPS 43
+#define N_OPS 45
enum operations {OP_RETURN_NO_VAL, OP_RETURN, OP_PUSH_SYM, OP_DUP, OP_ADD,
OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_NEGATE, OP_INCR, OP_DECR, OP_GT, OP_LT,
OP_GE, OP_LE, OP_EQ, OP_NE, OP_BIT_AND, OP_BIT_OR, OP_AND, OP_OR, OP_NOT,
@@ -48,7 +48,8 @@ enum operations {OP_RETURN_NO_VAL, OP_RE
OP_BRANCH_TRUE, OP_BRANCH_FALSE, OP_BRANCH_NEVER, OP_ARRAY_REF,
OP_ARRAY_ASSIGN, OP_BEGIN_ARRAY_ITER, OP_ARRAY_ITER, OP_IN_ARRAY,
OP_ARRAY_DELETE, OP_PUSH_ARRAY_SYM, OP_ARRAY_REF_ASSIGN_SETUP, OP_PUSH_ARG,
- OP_PUSH_ARG_COUNT, OP_PUSH_ARG_ARRAY};
+ OP_PUSH_ARG_COUNT, OP_PUSH_ARG_ARRAY,
+ OP_ARRAY_ASSIGN_NEXT, OP_ARRAY_NEXT_NUM_IDX};
enum typeTags {NO_TAG, INT_TAG, STRING_TAG, ARRAY_TAG};
diff --quilt old/source/parse.y new/source/parse.y
--- old/source/parse.y
+++ new/source/parse.y
@@ -183,6 +183,9 @@ simpstmt: SYMBOL '=' expr {
| initarraylv '[' arglist ']' '=' expr {
ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
}
+ | initarraylv '[' '@' ']' '=' expr {
+ ADD_OP(OP_ARRAY_ASSIGN_NEXT);
+ }
| initarraylv '[' arglist ']' ADDEQ expr {
ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED(1); ADD_IMMED($3);
ADD_OP(OP_ADD);
@@ -333,6 +336,9 @@ numexpr: NUMBER {
| numexpr '[' arglist ']' {
ADD_OP(OP_ARRAY_REF); ADD_IMMED($3);
}
+ | numexpr '[' '@' ']' {
+ ADD_OP(OP_ARRAY_NEXT_NUM_IDX);
+ }
| numexpr '+' numexpr {
ADD_OP(OP_ADD);
}
--
NEdit Develop mailing list - [email protected]
http://www.nedit.org/mailman/listinfo/develop