📄 eval.cc
字号:
/* * HT Editor * eval.cc * * Copyright (C) 1999, 2000, 2001 Stefan Weyergraf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "evaltype.h"#include "evalparse.h"#include "eval.h"#include "snprintf.h"#include "strtools.h"#ifdef EVAL_DEBUGint debug_dump_ident;#endif#define MIN(a, b) ((a) < (b) ? (a) : (b))#define MAX(a, b) ((a) > (b) ? (a) : (b))/* * */static eval_func_handler g_eval_func_handler;static eval_symbol_handler g_eval_symbol_handler;static void *eval_context;static int helpmode = 0;static eval_scalar helpstring;static char helpname[MAX_FUNCNAME_LEN+1];uint64 f2i(double f){ uint64 r; if (f>0) r = (sint64)(f+.5); else r = (sint64)(f-.5); return r;}void set_helpmode(int flag, char *name){ helpmode = flag; int l = name ? strlen(name) : (MAX_FUNCNAME_LEN+1); if (l>MAX_FUNCNAME_LEN) { *helpname = 0; return; } strcpy(helpname, name);}static uint64 ipow(uint64 a, uint64 b){ uint64 r = 1ULL; uint64 m = 1ULL << 63; while (m != 0) { r *= r; if ((b & m) != 0) { r *= a; } m = m >> 1; } return r;}/*static int sprint_basen(char *buffer, int base, uint64 q){ static char *chars="0123456789abcdef"; if ((base<2) || (base>16)) return 0; int n = 0; char *b = buffer; while (q != to_qword(0)) { int c = QWORD_GET_INT(q % to_qword(base)); *buffer++ = chars[c]; n++; q /= to_qword(base); } for (int i=0; i < n/2; i++) { char t = b[i]; b[i] = b[n-i-1]; b[n-i-1] = t; } b[n] = 0; return n;}*/static void str2int(char *str, uint64 *q, int base){ *q = 0; uint64 qbase = base; while (*str) { int c = hexdigit(*str); if ((c == -1) || (c >= base)) break; *q *= qbase; *q += c; str++; }}char *binstr2cstr(char *s, int len){ char *x = ht_malloc(len+1); memcpy(x, s, len); x[len]=0; return x;} int bin2str(char *result, void *S, int len){ unsigned char *s = (unsigned char*)S; while (len--) { if (*s==0) *result=' '; else *result=*s; result++; s++; } *result=0; return len;}/* * ERROR HANDLING */static int eval_error;static int eval_error_pos;static char eval_errstr[MAX_ERRSTR_LEN];void clear_eval_error(){ eval_error=0;}int get_eval_error(const char **str, int *pos){ if (eval_error) { if (str) *str = eval_errstr; if (pos) *pos = eval_error_pos; return eval_error; } if (str) *str = "?"; if (pos) *pos = 0; return 0;}void set_eval_error(const char *format,...){ va_list vargs; va_start(vargs, format); ht_vsnprintf(eval_errstr, sizeof eval_errstr, format, vargs); va_end(vargs); eval_error_pos = lex_current_buffer_pos(); eval_error = 1;}void set_eval_error_ex(int pos, const char *format, ...){ va_list vargs; va_start(vargs, format); ht_vsnprintf(eval_errstr, sizeof eval_errstr, format, vargs); va_end(vargs); eval_error_pos = pos; eval_error = 1;}/* * */#ifdef EVAL_DEBUGvoid integer_dump(eval_int *i){ printf("%d", i->value);}void float_dump(eval_float *f){ printf("%f", f->value);}void string_dump(eval_str *s){ int i; for (i=0; i<s->len; i++) { if ((unsigned)s->value[i]<32) { printf("\\x%x", s->value[i]); } else { printf("%c", s->value[i]); } }}#endifvoid string_destroy(eval_str *s){ if (s->value) free(s->value);}/* * SCALARLIST */void scalarlist_set(eval_scalarlist *l, eval_scalar *s){ l->count = 1; l->scalars = ht_malloc(sizeof (eval_scalar) * l->count); l->scalars[0] = *s;}void scalarlist_concat(eval_scalarlist *l, eval_scalarlist *a, eval_scalarlist *b){ l->count = a->count+b->count; l->scalars = ht_malloc(sizeof (eval_scalar) * l->count); memcpy(l->scalars, a->scalars, sizeof (eval_scalar) * a->count); memcpy(l->scalars + a->count, b->scalars, sizeof (eval_scalar) * b->count);}void scalarlist_destroy(eval_scalarlist *l){ int i; if (l && l->scalars) { for (i=0; i < l->count; i++) { scalar_destroy(&l->scalars[i]); } free(l->scalars); } }void scalarlist_destroy_gentle(eval_scalarlist *l){ if (l && l->scalars) free(l->scalars);}#ifdef EVAL_DEBUGvoid scalarlist_dump(eval_scalarlist *l){ int i; for (i=0; i<l->count; i++) { scalar_dump(&l->scalars[i]); if (i!=l->count-1) { printf(", "); } }}#endif/* * SCALAR */void scalar_setint(eval_scalar *s, eval_int *i){ s->type=SCALAR_INT; s->scalar.integer=*i;}void scalar_setstr(eval_scalar *s, eval_str *t){ s->type=SCALAR_STR; s->scalar.str=*t;}#ifdef EVAL_DEBUGvoid scalar_dump(eval_scalar *s){ switch (s->type) { case SCALAR_STR: { string_dump(&s->scalar.str); break; } case SCALAR_INT: { integer_dump(&s->scalar.integer); break; } case SCALAR_FLOAT: { float_dump(&s->scalar.floatnum); break; } default: break; }}#endifvoid scalar_create_int(eval_scalar *s, const eval_int *t){ s->type = SCALAR_INT; s->scalar.integer=*t;}void scalar_create_int_c(eval_scalar *s, const int i){ s->type = SCALAR_INT; s->scalar.integer.value = (sint64)i; s->scalar.integer.type = TYPE_UNKNOWN;}void scalar_create_int_q(eval_scalar *s, const uint64 q){ s->type = SCALAR_INT; s->scalar.integer.value = q; s->scalar.integer.type = TYPE_UNKNOWN;}void scalar_create_str(eval_scalar *s, const eval_str *t){ s->type = SCALAR_STR; s->scalar.str.value = ht_malloc(t->len ? t->len : 1); memcpy(s->scalar.str.value, t->value, t->len); s->scalar.str.len = t->len;}void scalar_create_str_c(eval_scalar *s, const char *cstr){ eval_str t; t.value = (char*)cstr; t.len = strlen(cstr); scalar_create_str(s, &t);}void scalar_create_float(eval_scalar *s, const eval_float *t){ s->type=SCALAR_FLOAT; s->scalar.floatnum=*t;}void scalar_create_float_c(eval_scalar *s, const double f){ s->type=SCALAR_FLOAT; s->scalar.floatnum.value=f;}void scalar_context_str(const eval_scalar *s, eval_str *t){ switch (s->type) { case SCALAR_INT: { char buf[64]; ht_snprintf(buf, sizeof buf, "%qd", /* FIXME: by reference*/ &s->scalar.integer.value); t->value = (char*)strdup(buf); t->len = strlen(buf); break; } case SCALAR_STR: { t->value = ht_malloc(s->scalar.str.len ? s->scalar.str.len : 1); t->len = s->scalar.str.len; memcpy(t->value, s->scalar.str.value, t->len); break; } case SCALAR_FLOAT: { char buf[64]; ht_snprintf(buf, sizeof buf, "%f", s->scalar.floatnum.value); t->value = (char*)strdup(buf); t->len = strlen(buf); break; } default: break; } }void scalar_context_int(const eval_scalar *s, eval_int *t){ switch (s->type) { case SCALAR_INT: { *t=s->scalar.integer; break; } case SCALAR_STR: { char *x = binstr2cstr(s->scalar.str.value, s->scalar.str.len); str2int(x, &t->value, 10); t->type = TYPE_UNKNOWN; free(x); break; } case SCALAR_FLOAT: { t->value=f2i(s->scalar.floatnum.value); t->type=TYPE_UNKNOWN; break; } default: break; } }void scalar_context_float(const eval_scalar *s, eval_float *t){ switch (s->type) { case SCALAR_INT: t->value = s->scalar.integer.value; break; case SCALAR_STR: { char *x = binstr2cstr(s->scalar.str.value, s->scalar.str.len); t->value = strtod(x, (char**)NULL); free(x); break; } case SCALAR_FLOAT: *t = s->scalar.floatnum; break; default: break; } }void string_concat(eval_str *s, eval_str *a, eval_str *b){ s->value = ht_malloc(a->len+b->len ? a->len+b->len : 1); memcpy(s->value, a->value, a->len); memcpy(s->value + a->len, b->value, b->len); s->len = a->len+b->len; free(a->value); a->len = 0; free(b->value); b->len = 0;}void scalar_clone(eval_scalar *result, const eval_scalar *s){ switch (s->type) { case SCALAR_INT: { *result = *s; break; } case SCALAR_STR: { *result = *s; result->scalar.str.value = ht_malloc(result->scalar.str.len); memcpy(result->scalar.str.value, s->scalar.str.value, result->scalar.str.len); break; } case SCALAR_FLOAT: { *result = *s; break; } default: break; }}void scalar_concat(eval_scalar *s, const eval_scalar *a, const eval_scalar *b){ eval_str as, bs, rs; scalar_context_str(a, &as); scalar_context_str(b, &bs); string_concat(&rs, &as, &bs); s->type=SCALAR_STR; s->scalar.str=rs;}void scalar_destroy(eval_scalar *s){ switch (s->type) { case SCALAR_STR: string_destroy(&s->scalar.str); break; default: break; }}int string_compare(const eval_str *a, const eval_str *b){ if (a->len==b->len) { return memcmp(a->value, b->value, a->len); } return a->len-b->len;}int scalar_strop(eval_scalar *xr, const eval_scalar *xa, const eval_scalar *xb, int op){ eval_str as, bs; int r; int c; scalar_context_str(xa, &as); scalar_context_str(xb, &bs); c = string_compare(&as, &bs); switch (op) { case EVAL_STR_EQ: r=(c==0); break; case EVAL_STR_NE: r=(c!=0); break; case EVAL_STR_GT: r=(c>0); break; case EVAL_STR_GE: r=(c>=0); break; case EVAL_STR_LT: r=(c<0); break; case EVAL_STR_LE: r=(c>=0); break; default: return 0; } xr->type = SCALAR_INT; xr->scalar.integer.value = r; xr->scalar.integer.type = TYPE_UNKNOWN; return 1;}int scalar_float_op(eval_scalar *xr, const eval_scalar *xa, const eval_scalar *xb, int op){ eval_float ai, bi; float a, b, r; scalar_context_float(xa, &ai); scalar_context_float(xb, &bi); a = ai.value; b = bi.value; switch (op) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -