diff --git a/nv.c b/nv.c index 8101a49..e7b16b8 100644 --- a/nv.c +++ b/nv.c @@ -72,7 +72,8 @@ int NV_runInteractive(const NV_ID *cTypeList, const NV_ID *opList) tokenList = NV_tokenize(cTypeList, line); NV_convertLiteral(&tokenList, opList); NV_printNodeByID(&tokenList); - + NV_evaluateSetence(&tokenList); + NV_printNodeByID(&tokenList); } return 0; } @@ -151,16 +152,32 @@ int NV_convertLiteral(const NV_ID *tokenizedList, const NV_ID *opList) // // Evaluate // -/* void NV_evaluateSetence(const NV_ID *tokenizedList) { - int i; - NV_ID t; - for(i = 0;;){ - t = + int i, lastOpIndex; + int32_t lastOpPrec, opPrec; + NV_ID t, lastOp; + for(;;){ + lastOpPrec = -1; + for(i = 0; ; i++){ + t = NV_Array_getByIndex(tokenizedList, i); + if(NV_ID_isEqual(&t, &NODEID_NULL)) break; + if(!NV_isTreeType(&t, &NODEID_TREE_TYPE_OP)) continue; + opPrec = NV_getOpPrecAt(tokenizedList, i); + if(lastOpPrec & 1 ? lastOpPrec <= opPrec : lastOpPrec < opPrec){ + // continue searching + lastOpIndex = i; + lastOpPrec = opPrec; + lastOp = t; + continue; + } + // found. lastOpID is target op. + break; + } + if(lastOpPrec == -1) break; // no more op + NV_tryExecOpAt(tokenizedList, lastOpIndex); } } -*/ /* void NV_evaluateSentence(const NV_ID *tokenizedList) { @@ -206,52 +223,6 @@ void NV_evaluateSentence(const NV_ID *tokenizedList) } } */ -/* -void NV_tryExecOp(int32_t *excFlag, NV_Pointer lang, NV_Pointer thisTerm, NV_Pointer vDict, NV_Pointer root) -{ - NV_Pointer fallbackOp, op; - NV_Pointer orgTerm = thisTerm; - // - op = NV_ListItem_getData(thisTerm); -#ifdef DEBUG - if(NV_debugFlag & NV_DBG_FLAG_VERBOSE){ - NV_DbgInfo("%s", "Begin native op: "); - NV_Operator_print(op); putchar('\n'); - } -#endif - NV_Operator_exec(op, excFlag, lang, vDict, thisTerm); -#ifdef DEBUG - if(NV_debugFlag & NV_DBG_FLAG_VERBOSE){ - NV_DbgInfo("%s", "End native op:"); - NV_Operator_print(op); putchar('\n'); - } -#endif - if(*excFlag & NV_EXC_FLAG_FAILED){ - // try fallback - fallbackOp = NV_Lang_getFallbackOperator(lang, op); - if(NV_E_isNullPointer(fallbackOp)){ - NV_Error("%s", "Operator mismatched: "); - NV_Operator_print(op); putchar('\n'); - NV_List_printAll(root, NULL, NULL, "]\n"); - return; - } -#ifdef DEBUG - if(NV_debugFlag & NV_DBG_FLAG_VERBOSE){ - NV_DbgInfo("%s", "Fallback found:"); - NV_Operator_print(fallbackOp); putchar('\n'); - } -#endif - CLR_FLAG(*excFlag, NV_EXC_FLAG_FAILED); - NV_ListItem_setData(orgTerm, fallbackOp); - thisTerm = orgTerm; - } -#ifdef DEBUG - if(NV_debugFlag & NV_DBG_FLAG_VERBOSE){ - NV_List_printAll(root, NULL, NULL, "]\n"); - } -#endif -} -*/ // // main // diff --git a/nv.h b/nv.h index c173a01..8f762bd 100644 --- a/nv.h +++ b/nv.h @@ -75,11 +75,13 @@ int NV_isTreeType(const NV_ID *node, const NV_ID *tType); NV_ID NV_tokenize(const NV_ID *cTypeList, const char *input); int NV_runInteractive(const NV_ID *cTypeList, const NV_ID *opList); int NV_convertLiteral(const NV_ID *tokenizedList, const NV_ID *opList); +void NV_evaluateSetence(const NV_ID *tokenizedList); // @nv_array.c NV_ID NV_Array_create(); NV_ID NV_Array_push(const NV_ID *array, const NV_ID *data); NV_ID NV_Array_getByIndex(const NV_ID *array, int index); +void NV_Array_removeIndex(const NV_ID *array, int index); void NV_Array_writeToIndex(const NV_ID *array, int index, const NV_ID *data); void NV_Array_print(const NV_ID *array); @@ -134,10 +136,12 @@ NV_ID NV_Node_getRelatedNodeFrom(const NV_ID *from, const NV_ID *rel); NV_ID NV_Node_createWithString(const char *s); void NV_Node_setStrToID(const NV_ID *id, const char *s); int NV_Node_String_compare(const NV_Node *na, const NV_Node *nb); +int NV_Node_String_compareWithCStr(const NV_Node *na, const char *s); char *NV_Node_String_strchr(const NV_Node *ns, char c); long NV_Node_String_strtol(const NV_Node *ns, int *endptrindex, int base); size_t NV_Node_String_strlen(const NV_Node *ns); // +int NV_Node_isInteger(const NV_ID *id); NV_ID NV_Node_createWithInt32(int32_t v); void NV_Node_setInt32ToID(const NV_ID *id, int32_t v); int32_t NV_Node_getInt32FromID(const NV_ID *id); @@ -147,6 +151,8 @@ int NV_Lang_getCharType(const NV_ID *cTypeList, char c); NV_ID NV_createCharTypeList(); void NV_addOp(const NV_ID *opList, const char *token, int32_t prec, const NV_ID *func); NV_ID NV_createOpList(); +int32_t NV_getOpPrecAt(const NV_ID *tList, int index); +void NV_tryExecOpAt(const NV_ID *tList, int index); void NV_Op_print(const NV_ID *op); // @nv_static.c diff --git a/nv_array.c b/nv_array.c index 495b985..895eaf7 100644 --- a/nv_array.c +++ b/nv_array.c @@ -44,6 +44,25 @@ NV_ID NV_Array_getByIndex(const NV_ID *array, int index) return NV_Variable_getData(&t); } +void NV_Array_removeIndex(const NV_ID *array, int index) +{ + NV_ID t, tn, tnn, r; + if(index < 0) return; + t = *array; + for(; index; index--){ + if(index == 0) break; + t = NV_Node_getRelatedNodeFrom(&t, &RELID_ARRAY_NEXT); + if(NV_ID_isEqual(&t, &NODEID_NULL)) break; + } + // tのnextが削除対象。これをtnとおく。 + if(!NV_ID_isEqual(&t, &NODEID_NULL)){ + tn = NV_Node_getRelatedNodeFrom(&t, &RELID_ARRAY_NEXT); + tnn = NV_Node_getRelatedNodeFrom(&tn, &RELID_ARRAY_NEXT); + r = NV_Node_getRelationFrom(&t, &RELID_ARRAY_NEXT); + NV_Node_updateRelationTo(&r, &tnn); + } +} + void NV_Array_writeToIndex(const NV_ID *array, int index, const NV_ID *data) { NV_ID t; diff --git a/nv_node.c b/nv_node.c index 6b8ecdc..8ef5d2e 100644 --- a/nv_node.c +++ b/nv_node.c @@ -373,6 +373,15 @@ int NV_Node_String_compare(const NV_Node *na, const NV_Node *nb) return strcmp(na->data, nb->data); } +int NV_Node_String_compareWithCStr(const NV_Node *na, const char *s) +{ + // compatible with strcmp + // but if node->data is null, returns -1. + // "" == "" -> true + if(!na || !s || na->type != kString) return -1; + return strcmp(na->data, s); +} + char *NV_Node_String_strchr(const NV_Node *ns, char c) { if(!ns || ns->type != kString) return NULL; @@ -402,6 +411,15 @@ size_t NV_Node_String_strlen(const NV_Node *ns) // Integer // +int NV_Node_isInteger(const NV_ID *id) +{ + NV_Node *n; + // + n = NV_Node_getByID(id); + if(!n || n->type != kInteger) return 0; + return 1; +} + NV_ID NV_Node_createWithInt32(int32_t v) { NV_ID id; diff --git a/nv_op.c b/nv_op.c index 3ce7985..d281bfa 100644 --- a/nv_op.c +++ b/nv_op.c @@ -73,6 +73,118 @@ NV_ID NV_createOpList() return opList; } +int32_t NV_getOpPrecAt(const NV_ID *tList, int index) +{ + NV_ID op = NV_Array_getByIndex(tList, index); + NV_ID ePrec = NV_Node_getRelatedNodeFrom(&op, &RELID_OP_PRECEDENCE); + return NV_Node_getInt32FromID(&ePrec); +} + +void NV_tryExecOpAt(const NV_ID *tList, int index) +{ + NV_ID op = NV_Array_getByIndex(tList, index); + NV_ID func = NV_Node_getRelatedNodeFrom(&op, &RELID_OP_FUNC); + puts("begin op"); + NV_printNodeByID(&op); + if(NV_Node_String_compareWithCStr( + NV_Node_getByID(&func), "NV_Op_nothing") == 0){ + NV_Array_removeIndex(tList, index); + } else if(NV_Node_String_compareWithCStr( + NV_Node_getByID(&func), "NV_Op_add") == 0){ + NV_ID nL, nR, ans; + int vL, vR; + nL = NV_Array_getByIndex(tList, index - 1); + nR = NV_Array_getByIndex(tList, index + 1); + if(!NV_Node_isInteger(&nL) || !NV_Node_isInteger(&nR)){ + NV_ID errObj = NV_Node_createWithString( + "Error: Invalid Operand Type."); + NV_Array_writeToIndex(tList, index, &errObj); + return; + } + vL = NV_Node_getInt32FromID(&nL); + vR = NV_Node_getInt32FromID(&nR); + // + index--; + NV_Array_removeIndex(tList, index); + NV_Array_removeIndex(tList, index); + // + ans = NV_Node_createWithInt32(vL + vR); + NV_Array_writeToIndex(tList, index, &ans); + } else if(NV_Node_String_compareWithCStr( + NV_Node_getByID(&func), "NV_Op_mul") == 0){ + NV_ID nL, nR, ans; + int vL, vR; + nL = NV_Array_getByIndex(tList, index - 1); + nR = NV_Array_getByIndex(tList, index + 1); + if(!NV_Node_isInteger(&nL) || !NV_Node_isInteger(&nR)){ + NV_ID errObj = NV_Node_createWithString( + "Error: Invalid Operand Type."); + NV_Array_writeToIndex(tList, index, &errObj); + return; + } + vL = NV_Node_getInt32FromID(&nL); + vR = NV_Node_getInt32FromID(&nR); + // + index--; + NV_Array_removeIndex(tList, index); + NV_Array_removeIndex(tList, index); + // + ans = NV_Node_createWithInt32(vL * vR); + NV_Array_writeToIndex(tList, index, &ans); + } else{ + NV_ID errObj = NV_Node_createWithString( + "Error: Op NOT found or NOT implemented."); + NV_Array_writeToIndex(tList, index, &errObj); + } +} + +/* +void NV_tryExecOp(int32_t *excFlag, NV_Pointer lang, NV_Pointer thisTerm, NV_Pointer vDict, NV_Pointer root) +{ + NV_Pointer fallbackOp, op; + NV_Pointer orgTerm = thisTerm; + // + op = NV_ListItem_getData(thisTerm); +#ifdef DEBUG + if(NV_debugFlag & NV_DBG_FLAG_VERBOSE){ + NV_DbgInfo("%s", "Begin native op: "); + NV_Operator_print(op); putchar('\n'); + } +#endif + NV_Operator_exec(op, excFlag, lang, vDict, thisTerm); +#ifdef DEBUG + if(NV_debugFlag & NV_DBG_FLAG_VERBOSE){ + NV_DbgInfo("%s", "End native op:"); + NV_Operator_print(op); putchar('\n'); + } +#endif + if(*excFlag & NV_EXC_FLAG_FAILED){ + // try fallback + fallbackOp = NV_Lang_getFallbackOperator(lang, op); + if(NV_E_isNullPointer(fallbackOp)){ + NV_Error("%s", "Operator mismatched: "); + NV_Operator_print(op); putchar('\n'); + NV_List_printAll(root, NULL, NULL, "]\n"); + return; + } +#ifdef DEBUG + if(NV_debugFlag & NV_DBG_FLAG_VERBOSE){ + NV_DbgInfo("%s", "Fallback found:"); + NV_Operator_print(fallbackOp); putchar('\n'); + } +#endif + CLR_FLAG(*excFlag, NV_EXC_FLAG_FAILED); + NV_ListItem_setData(orgTerm, fallbackOp); + thisTerm = orgTerm; + } +#ifdef DEBUG + if(NV_debugFlag & NV_DBG_FLAG_VERBOSE){ + NV_List_printAll(root, NULL, NULL, "]\n"); + } +#endif +} +*/ + void NV_Op_print(const NV_ID *op) { NV_ID eFunc;