📄 ejparse.c
字号:
} } if (numeric) { l = gatoi(lhs); r = gatoi(rhs); switch (rel) { case EXPR_PLUS: lval = l + r; break; case EXPR_INC: lval = l + 1; break; case EXPR_MINUS: lval = l - r; break; case EXPR_DEC: lval = l - 1; break; case EXPR_MUL: lval = l * r; break; case EXPR_DIV: if (r != 0) { lval = l / r; } else { lval = 0; } break; case EXPR_MOD: if (r != 0) { lval = l % r; } else { lval = 0; } break; case EXPR_LSHIFT: lval = l << r; break; case EXPR_RSHIFT: lval = l >> r; break; case EXPR_EQ: lval = l == r; break; case EXPR_NOTEQ: lval = l != r; break; case EXPR_LESS: lval = (l < r) ? 1 : 0; break; case EXPR_LESSEQ: lval = (l <= r) ? 1 : 0; break; case EXPR_GREATER: lval = (l > r) ? 1 : 0; break; case EXPR_GREATEREQ: lval = (l >= r) ? 1 : 0; break; case EXPR_BOOL_COMP: lval = (r == 0) ? 1 : 0; break; default: ejError(ep, T("Bad operator %d"), rel); return -1; } } else { switch (rel) { case EXPR_PLUS: clearString(&ep->result); appendString(&ep->result, lhs); appendString(&ep->result, rhs); return 0; case EXPR_LESS: lval = gstrcmp(lhs, rhs) < 0; break; case EXPR_LESSEQ: lval = gstrcmp(lhs, rhs) <= 0; break; case EXPR_GREATER: lval = gstrcmp(lhs, rhs) > 0; break; case EXPR_GREATEREQ: lval = gstrcmp(lhs, rhs) >= 0; break; case EXPR_EQ: lval = gstrcmp(lhs, rhs) == 0; break; case EXPR_NOTEQ: lval = gstrcmp(lhs, rhs) != 0; break; case EXPR_INC: case EXPR_DEC: case EXPR_MINUS: case EXPR_DIV: case EXPR_MOD: case EXPR_LSHIFT: case EXPR_RSHIFT: default: ejError(ep, T("Bad operator")); return -1; } } stritoa(lval, buf, sizeof(buf)); setString(B_L, &ep->result, buf); return 0;}/******************************************************************************//* * Evaluate a function */static int evalFunction(ej_t *ep){ sym_t *sp; int (*fn)(int eid, void *handle, int argc, char_t **argv); if ((sp = symLookup(ep->functions, ep->func->fname)) == NULL) { ejError(ep, T("Undefined procedure %s"), ep->func->fname); return -1; } fn = (int (*)(int, void*, int, char_t**)) sp->content.value.integer; if (fn == NULL) { ejError(ep, T("Undefined procedure %s"), ep->func->fname); return -1; } return (*fn)(ep->eid, (void*) ep->userHandle, ep->func->nArgs, ep->func->args);}/******************************************************************************//* * Output a parse ej_error message */void ejError(ej_t* ep, char_t* fmt, ...){ va_list args; ejinput_t *ip; char_t *errbuf, *msgbuf; a_assert(ep); a_assert(fmt); ip = ep->input; va_start(args, fmt); msgbuf = NULL; fmtValloc(&msgbuf, E_MAX_ERROR, fmt, args); va_end(args); if (ep && ip) { fmtAlloc(&errbuf, E_MAX_ERROR, T("%s\n At line %d, line => \n\n%s\n"), msgbuf, ip->lineNumber, ip->line); bfreeSafe(B_L, ep->error); ep->error = errbuf; } bfreeSafe(B_L, msgbuf);}/******************************************************************************//* * Clear a string value */static void clearString(char_t **ptr){ a_assert(ptr); if (*ptr) { bfree(B_L, *ptr); } *ptr = NULL;}/******************************************************************************//* * Set a string value */static void setString(B_ARGS_DEC, char_t **ptr, char_t *s){ a_assert(ptr); if (*ptr) { bfree(B_ARGS, *ptr); } *ptr = bstrdup(B_ARGS, s);}/******************************************************************************//* * Append to the pointer value */static void appendString(char_t **ptr, char_t *s){ int len, oldlen; a_assert(ptr); if (*ptr) { len = gstrlen(s); oldlen = gstrlen(*ptr); *ptr = brealloc(B_L, *ptr, (len + oldlen + 1) * sizeof(char_t)); gstrcpy(&(*ptr)[oldlen], s); } else { *ptr = bstrdup(B_L, s); }}/******************************************************************************//* * Define a function */int ejSetGlobalFunction(int eid, char_t *name, int (*fn)(int eid, void *handle, int argc, char_t **argv)){ ej_t *ep; if ((ep = ejPtr(eid)) == NULL) { return -1; } return ejSetGlobalFunctionDirect(ep->functions, name, fn);}/******************************************************************************//* * Define a function directly into the function symbol table. */int ejSetGlobalFunctionDirect(sym_fd_t functions, char_t *name, int (*fn)(int eid, void *handle, int argc, char_t **argv)){ if (symEnter(functions, name, valueInteger((long) fn), 0) == NULL) { return -1; } return 0;}/******************************************************************************//* * Remove ("undefine") a function */int ejRemoveGlobalFunction(int eid, char_t *name){ ej_t *ep; if ((ep = ejPtr(eid)) == NULL) { return -1; } return symDelete(ep->functions, name);}/******************************************************************************//* * Get a function definition */void *ejGetGlobalFunction(int eid, char_t *name){ ej_t *ep; sym_t *sp; int (*fn)(int eid, void *handle, int argc, char_t **argv); if ((ep = ejPtr(eid)) == NULL) { return NULL; } if ((sp = symLookup(ep->functions, name)) != NULL) { fn = (int (*)(int, void*, int, char_t**)) sp->content.value.integer; return (void*) fn; } return NULL;}/******************************************************************************//* * Utility routine to crack Ejscript arguments. Return the number of args * seen. This routine only supports %s and %d type args. * * Typical usage: * * if (ejArgs(argc, argv, "%s %d", &name, &age) < 2) { * error("Insufficient args\n"); * return -1; * } */int ejArgs(int argc, char_t **argv, char_t *fmt, ...){ va_list vargs; char_t *cp, **sp; int *ip; int argn; va_start(vargs, fmt); if (argv == NULL) { return 0; } for (argn = 0, cp = fmt; cp && *cp && argv[argn]; ) { if (*cp++ != '%') { continue; } switch (*cp) { case 'd': ip = va_arg(vargs, int*); *ip = gatoi(argv[argn]); break; case 's': sp = va_arg(vargs, char_t**); *sp = argv[argn]; break; default:/* * Unsupported */ a_assert(0); } argn++; } va_end(vargs); return argn;}/******************************************************************************//* * Define the user handle */void ejSetUserHandle(int eid, int handle){ ej_t *ep; if ((ep = ejPtr(eid)) == NULL) { return; } ep->userHandle = handle;}/******************************************************************************//* * Get the user handle */int ejGetUserHandle(int eid){ ej_t *ep; if ((ep = ejPtr(eid)) == NULL) { return -1; } return ep->userHandle;}/******************************************************************************//* * Get the current line number */int ejGetLineNumber(int eid){ ej_t *ep; if ((ep = ejPtr(eid)) == NULL) { return -1; } return ep->input->lineNumber;}/******************************************************************************//* * Set the result */void ejSetResult(int eid, char_t *s){ ej_t *ep; if ((ep = ejPtr(eid)) == NULL) { return; } setString(B_L, &ep->result, s);}/******************************************************************************//* * Get the result */char_t *ejGetResult(int eid){ ej_t *ep; if ((ep = ejPtr(eid)) == NULL) { return NULL; } return ep->result;}/******************************************************************************//* * Set a variable. Note: a variable with a value of NULL means declared but * undefined. The value is defined in the top-most variable frame. */void ejSetVar(int eid, char_t *var, char_t *value){ ej_t *ep; value_t v; a_assert(var && *var); if ((ep = ejPtr(eid)) == NULL) { return; } if (value == NULL) { v = valueString(value, 0); } else { v = valueString(value, VALUE_ALLOCATE); } symEnter(ep->variables[ep->variableMax - 1] - EJ_OFFSET, var, v, 0);}/******************************************************************************//* * Set a local variable. Note: a variable with a value of NULL means * declared but undefined. The value is defined in the top-most variable frame. */void ejSetLocalVar(int eid, char_t *var, char_t *value){ ej_t *ep; value_t v; a_assert(var && *var); if ((ep = ejPtr(eid)) == NULL) { return; } if (value == NULL) { v = valueString(value, 0); } else { v = valueString(value, VALUE_ALLOCATE); } symEnter(ep->variables[ep->variableMax - 1] - EJ_OFFSET, var, v, 0);}/******************************************************************************//* * Set a global variable. Note: a variable with a value of NULL means * declared but undefined. The value is defined in the global variable frame. */void ejSetGlobalVar(int eid, char_t *var, char_t *value){ ej_t *ep; value_t v; a_assert(var && *var); if ((ep = ejPtr(eid)) == NULL) { return; } if (value == NULL) { v = valueString(value, 0); } else { v = valueString(value, VALUE_ALLOCATE); } symEnter(ep->variables[0] - EJ_OFFSET, var, v, 0);}/******************************************************************************//* * Get a variable */int ejGetVar(int eid, char_t *var, char_t **value){ ej_t *ep; sym_t *sp; int i; a_assert(var && *var); a_assert(value); if ((ep = ejPtr(eid)) == NULL) { return -1; } i = ep->variableMax - 1; if ((sp = symLookup(ep->variables[i] - EJ_OFFSET, var)) == NULL) { i = 0; if ((sp = symLookup(ep->variables[0] - EJ_OFFSET, var)) == NULL) { return -1; } } a_assert(sp->content.type == string); *value = sp->content.value.string; return i;}/******************************************************************************//* * Get the variable symbol table */sym_fd_t ejGetVariableTable(int eid){ ej_t *ep; if ((ep = ejPtr(eid)) == NULL) { return -1; } return *ep->variables;}/******************************************************************************//* * Get the functions symbol table */sym_fd_t ejGetFunctionTable(int eid){ ej_t *ep; if ((ep = ejPtr(eid)) == NULL) { return -1; } return ep->functions;}/******************************************************************************//* * Free an argument list */static void freeFunc(ejfunc_t *func){ int i; for (i = func->nArgs - 1; i >= 0; i--) { bfree(B_L, func->args[i]); func->nArgs = hFree((void***) &func->args, i); } if (func->fname) { bfree(B_L, func->fname); func->fname = NULL; }}/******************************************************************************//* * Get Ejscript pointer */static ej_t *ejPtr(int eid){ a_assert(0 <= eid && eid < ejMax); if (eid < 0 || eid >= ejMax || ejHandles[eid] == NULL) { ejError(NULL, T("Bad handle %d"), eid); return NULL; } return ejHandles[eid];}/******************************************************************************//* * This function removes any new lines. Used for else cases, etc. */static void ejRemoveNewlines(ej_t *ep, int state){ int tid; do { tid = ejLexGetToken(ep, state); } while (tid == TOK_NEWLINE); ejLexPutbackToken(ep, tid, ep->token);}/******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -