⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interpret.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
static void restoreContext(RestartData *context){    Stack = context->stack;    StackP = context->stackP;    FrameP = context->frameP;    PC = context->pc;    InitiatingWindow = context->runWindow;    FocusWindow = context->focusWindow;}static void freeSymbolTable(Symbol *symTab){    Symbol *s;        while(symTab != NULL) {    	s = symTab;    	free(s->name);    	symTab = s->next;    	free((char *)s);    }    }#define POP(dataVal) \    if (StackP == Stack) \	return execError(StackUnderflowMsg, ""); \    dataVal = *--StackP;   #define PUSH(dataVal) \    if (StackP >= &Stack[STACK_SIZE]) \    	return execError(StackOverflowMsg, ""); \    *StackP++ = dataVal;#define PEEK(dataVal, peekIndex) \    dataVal = *(StackP - peekIndex - 1);#define POP_INT(number) \    if (StackP == Stack) \	return execError(StackUnderflowMsg, ""); \    --StackP; \    if (StackP->tag == STRING_TAG) { \    	if (!StringToNum(StackP->val.str, &number)) \    	    return execError(StringToNumberMsg, ""); \    } else if (StackP->tag == INT_TAG) \        number = StackP->val.n; \    else \        return(execError("can't convert array to integer", NULL));#define POP_STRING(string) \    if (StackP == Stack) \	return execError(StackUnderflowMsg, ""); \    --StackP; \    if (StackP->tag == INT_TAG) { \    	string = AllocString(TYPE_INT_STR_SIZE(int)); \    	sprintf(string, "%d", StackP->val.n); \    } else if (StackP->tag == STRING_TAG) \        string = StackP->val.str; \    else \        return(execError("can't convert array to string", NULL));   #define PEEK_STRING(string, peekIndex) \    if ((StackP - peekIndex - 1)->tag == INT_TAG) { \        string = AllocString(TYPE_INT_STR_SIZE(int)); \        sprintf(string, "%d", (StackP - peekIndex - 1)->val.n); \    } \    else if ((StackP - peekIndex - 1)->tag == STRING_TAG) { \        string = (StackP - peekIndex - 1)->val.str; \    } \    else { \        return(execError("can't convert array to string", NULL)); \    }#define PEEK_INT(number, peekIndex) \    if ((StackP - peekIndex - 1)->tag == STRING_TAG) { \        if (!StringToNum((StackP - peekIndex - 1)->val.str, &number)) { \    	    return execError(StringToNumberMsg, ""); \        } \    } else if ((StackP - peekIndex - 1)->tag == INT_TAG) { \        number = (StackP - peekIndex - 1)->val.n; \    } \    else { \        return(execError("can't convert array to string", NULL)); \    }#define PUSH_INT(number) \    if (StackP >= &Stack[STACK_SIZE]) \    	return execError(StackOverflowMsg, ""); \    StackP->tag = INT_TAG; \    StackP->val.n = number; \    StackP++;    #define PUSH_STRING(string) \    if (StackP >= &Stack[STACK_SIZE]) \    	return execError(StackOverflowMsg, ""); \    StackP->tag = STRING_TAG; \    StackP->val.str = string; \    StackP++;#define BINARY_NUMERIC_OPERATION(operator) \    int n1, n2; \    DISASM_RT(PC-1, 1); \    STACKDUMP(2, 3); \    POP_INT(n2) \    POP_INT(n1) \    PUSH_INT(n1 operator n2) \    return STAT_OK;#define UNARY_NUMERIC_OPERATION(operator) \    int n; \    DISASM_RT(PC-1, 1); \    STACKDUMP(1, 3); \    POP_INT(n) \    PUSH_INT(operator n) \    return STAT_OK;/*** copy a symbol's value onto the stack** Before: Prog->  [Sym], next, ...**         Stack-> next, ...** After:  Prog->  Sym, [next], ...**         Stack-> [SymValue], next, ...*/static int pushSymVal(void){    Symbol *s;    int nArgs, argNum;    DISASM_RT(PC-1, 2);    STACKDUMP(0, 3);    s = (Symbol *)*PC++;    if (s->type == LOCAL_SYM) {    	*StackP = *(FrameP + s->value.val.n);    } else if (s->type == GLOBAL_SYM || s->type == CONST_SYM) {    	*StackP = s->value;    } else if (s->type == ARG_SYM) {    	nArgs = (FrameP-1)->val.n;    	argNum = s->value.val.n;    	if (argNum >= nArgs)    	    return execError("referenced undefined argument: %s",  s->name);    	if (argNum == N_ARGS_ARG_SYM) {    	    StackP->tag = INT_TAG;    	    StackP->val.n = nArgs;    	} else    	    *StackP = *(FrameP + argNum - nArgs - 3);    } else if (s->type == PROC_VALUE_SYM) {	DataValue result;	char *errMsg;	if (!(s->value.val.subr)(FocusWindow, NULL, 0,	    	&result, &errMsg))	    return execError(errMsg, s->name);    	*StackP = result;    } else    	return execError("reading non-variable: %s", s->name);    if (StackP->tag == NO_TAG)    	return execError("variable not set: %s", s->name);    StackP++;    if (StackP >= &Stack[STACK_SIZE])    	return execError(StackOverflowMsg, "");    return STAT_OK;}/*** Push an array (by reference) onto the stack** Before: Prog->  [ArraySym], makeEmpty, next, ...**         Stack-> next, ...** After:  Prog->  ArraySym, makeEmpty, [next], ...**         Stack-> [elemValue], next, ...** makeEmpty is either true (1) or false (0): if true, and the element is not** present in the array, create it.*/static int pushArraySymVal(void){    Symbol *sym;    DataValue *dataPtr;    int initEmpty;        DISASM_RT(PC-1, 3);    STACKDUMP(0, 3);    sym = (Symbol *)*PC;    PC++;    initEmpty = (int)*PC;    PC++;        if (sym->type == LOCAL_SYM) {    	dataPtr = FrameP + sym->value.val.n;    } else if (sym->type == GLOBAL_SYM) {    	dataPtr = &sym->value;    } else {    	return execError("assigning to non-lvalue array or non-array: %s", sym->name);    }    if (initEmpty && dataPtr->tag == NO_TAG) {        dataPtr->tag = ARRAY_TAG;        dataPtr->val.arrayPtr = ArrayNew();    }    if (dataPtr->tag == NO_TAG) {        return execError("variable not set: %s", sym->name);    }    *StackP = *dataPtr;    StackP++;    if (StackP >= &Stack[STACK_SIZE]) {    	return execError(StackOverflowMsg, "");    }    return(STAT_OK);}/*** assign top value to next symbol**** Before: Prog->  [symbol], next, ...**         Stack-> [value], next, ...** After:  Prog->  symbol, [next], ...**         Stack-> next, ...*/static int assign(void){    Symbol *sym;    DataValue *dataPtr;        DISASM_RT(PC-1, 2);    STACKDUMP(1, 3);    sym = (Symbol *)(*PC++);    if (sym->type != GLOBAL_SYM && sym->type != LOCAL_SYM) {        if (sym->type == ARG_SYM)            return execError("assignment to function argument: %s",  sym->name);        else if (sym->type == PROC_VALUE_SYM)            return execError("assignment to read-only variable: %s", sym->name);        else            return execError("assignment to non-variable: %s", sym->name);    }    if (StackP == Stack)        return execError(StackUnderflowMsg, "");    --StackP;    if (sym->type == LOCAL_SYM)        dataPtr = (FrameP + sym->value.val.n);    else        dataPtr = &sym->value;    if (StackP->tag == ARRAY_TAG) {        ArrayCopy(dataPtr, StackP);    }    else {        *dataPtr = *StackP;    }    return STAT_OK;}/*** copy the top value of the stack** Before: Stack-> value, next, ...** After:  Stack-> value, value, next, ...*/static int dupStack(void){    DISASM_RT(PC-1, 1);    STACKDUMP(1, 3);    if (StackP >= &Stack[STACK_SIZE])    	return execError(StackOverflowMsg, "");    *StackP = *(StackP - 1);    StackP++;    return STAT_OK;}/*** if left and right arguments are arrays, then the result is a new array** in which all the keys from both the right and left are copied** the values from the right array are used in the result array when the** keys are the same** Before: Stack-> value2, value1, next, ...** After:  Stack-> resValue, next, ...*/static int add(void){    DataValue leftVal, rightVal, resultArray;    int n1, n2;        DISASM_RT(PC-1, 1);    STACKDUMP(2, 3);    PEEK(rightVal, 0)    if (rightVal.tag == ARRAY_TAG) {        PEEK(leftVal, 1)        if (leftVal.tag == ARRAY_TAG) {            SparseArrayEntry *leftIter, *rightIter;            resultArray.tag = ARRAY_TAG;            resultArray.val.arrayPtr = ArrayNew();                        POP(rightVal)            POP(leftVal)            leftIter = arrayIterateFirst(&leftVal);            rightIter = arrayIterateFirst(&rightVal);            while (leftIter || rightIter) {                int insertResult = 1;                                if (leftIter && rightIter) {                    int compareResult = arrayEntryCompare((rbTreeNode *)leftIter, (rbTreeNode *)rightIter);                    if (compareResult < 0) {                        insertResult = ArrayInsert(&resultArray, leftIter->key, &leftIter->value);                        leftIter = arrayIterateNext(leftIter);                    }                    else if (compareResult > 0) {                        insertResult = ArrayInsert(&resultArray, rightIter->key, &rightIter->value);                        rightIter = arrayIterateNext(rightIter);                    }                    else {                        insertResult = ArrayInsert(&resultArray, rightIter->key, &rightIter->value);                        leftIter = arrayIterateNext(leftIter);                        rightIter = arrayIterateNext(rightIter);                    }                }                else if (leftIter) {                    insertResult = ArrayInsert(&resultArray, leftIter->key, &leftIter->value);                    leftIter = arrayIterateNext(leftIter);                }                else {                    insertResult = ArrayInsert(&resultArray, rightIter->key, &rightIter->value);                    rightIter = arrayIterateNext(rightIter);                }                if (!insertResult) {                    return(execError("array insertion failure", NULL));                }            }            PUSH(resultArray)        }        else {            return(execError("can't mix math with arrays and non-arrays", NULL));        }    }    else {        POP_INT(n2)        POP_INT(n1)        PUSH_INT(n1 + n2)    }    return(STAT_OK);}/*** if left and right arguments are arrays, then the result is a new array** in which only the keys which exist in the left array but not in the right** are copied** Before: Stack-> value2, value1, next, ...** After:  Stack-> resValue, next, ...*/static int subtract(void){    DataValue leftVal, rightVal, resultArray;    int n1, n2;        DISASM_RT(PC-1, 1);    STACKDUMP(2, 3);    PEEK(rightVal, 0)    if (rightVal.tag == ARRAY_TAG) {        PEEK(leftVal, 1)        if (leftVal.tag == ARRAY_TAG) {            SparseArrayEntry *leftIter, *rightIter;            resultArray.tag = ARRAY_TAG;            resultArray.val.arrayPtr = ArrayNew();                        POP(rightVal)            POP(leftVal)            leftIter = arrayIterateFirst(&leftVal);            rightIter = arrayIterateFirst(&rightVal);            while (leftIter) {                int insertResult = 1;                                if (leftIter && rightIter) {                    int compareResult = arrayEntryCompare((rbTreeNode *)leftIter, (rbTreeNode *)rightIter);                    if (compareResult < 0) {                        insertResult = ArrayInsert(&resultArray, leftIter->key, &leftIter->value);                        leftIter = arrayIterateNext(leftIter);                    }                    else if (compareResult > 0) {                        rightIter = arrayIterateNext(rightIter);                    }                    else {                        leftIter = arrayIterateNext(leftIter);                        rightIter = arrayIterateNext(rightIter);                    }                }                else if (leftIter) {                    insertResult = ArrayInsert(&resultArray, leftIter->key, &leftIter->value);                    leftIter = arrayIterateNext(leftIter);                }                if (!insertResult) {                    return(execError("array insertion failure", NULL));                }            }            PUSH(resultArray)        }        else {            return(execError("can't mix math with arrays and non-arrays", NULL));        }    }    else {        POP_INT(n2)        POP_INT(n1)        PUSH_INT(n1 - n2)    }    return(STAT_OK);}/*** Other binary operators** Before: Stack-> value2, value1, next, ...** After:  Stack-> resValue, next, ...**** Other unary operators** Before: Stack-> value, next, ...** After:  Stack-> resValue, next, ...*/static int multiply(void){    BINARY_NUMERIC_OPERATION(*)}static int divide(void){    int n1, n2;    DISASM_RT(PC-1, 1);    STACKDUMP(2, 3);    POP_INT(n2)    POP_INT(n1)    if (n2 == 0) {	return execError("division by zero", "");    }    PUSH_INT(n1 / n2)    return STAT_OK;}static int modulo(void){    int n1, n2;    DISASM_RT(PC-1, 1);    STACKDUMP(2, 3);    POP_INT(n2)    POP_INT(n1)    if (n2 == 0) {	return execError("modulo by zero", "");    }    PUSH_INT(n1 % n2)    return STAT_OK;}static int negate(void){    UNARY_NUMERIC_OPERATION(-)}static int increment(void){    UNARY_NUMERIC_OPERATION(++)}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -