Skip to content

Commit

Permalink
Implement + and * operator.
Browse files Browse the repository at this point in the history
  • Loading branch information
hikalium committed Nov 25, 2016
1 parent c2e2667 commit d429f38
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 53 deletions.
77 changes: 24 additions & 53 deletions nv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
//
Expand Down
6 changes: 6 additions & 0 deletions nv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down
19 changes: 19 additions & 0 deletions nv_array.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
18 changes: 18 additions & 0 deletions nv_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
112 changes: 112 additions & 0 deletions nv_op.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit d429f38

Please sign in to comment.