Mercurial > hg > dmlib
comparison src/dmeval.c @ 1102:e06abfde6c39
Cosmetics pass: Remove excess whitespace.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 03 Mar 2015 23:22:36 +0200 |
parents | ff13d79c75e0 |
children | 848a88ce7a57 |
comparison
equal
deleted
inserted
replaced
1101:0577f10dc3de | 1102:e06abfde6c39 |
---|---|
8 */ | 8 */ |
9 const DMEvalOper dmEvalOpers[OP_NOPERS] = | 9 const DMEvalOper dmEvalOpers[OP_NOPERS] = |
10 { | 10 { |
11 { "-" , OT_UNARY , FALSE }, | 11 { "-" , OT_UNARY , FALSE }, |
12 { "~" , OT_UNARY , TRUE }, | 12 { "~" , OT_UNARY , TRUE }, |
13 | 13 |
14 { "+" , OT_LEFT , TRUE }, | 14 { "+" , OT_LEFT , TRUE }, |
15 { "-" , OT_LEFT , TRUE }, | 15 { "-" , OT_LEFT , TRUE }, |
16 { "*" , OT_LEFT , TRUE }, | 16 { "*" , OT_LEFT , TRUE }, |
17 { "/" , OT_LEFT , TRUE }, | 17 { "/" , OT_LEFT , TRUE }, |
18 { "%" , OT_LEFT , TRUE }, | 18 { "%" , OT_LEFT , TRUE }, |
81 | 81 |
82 | 82 |
83 void dmEvalErrorV(DMEvalContext *ev, const char *fmt, va_list ap) | 83 void dmEvalErrorV(DMEvalContext *ev, const char *fmt, va_list ap) |
84 { | 84 { |
85 char *tmp = dm_strdup_vprintf(fmt, ap); | 85 char *tmp = dm_strdup_vprintf(fmt, ap); |
86 | 86 |
87 ev->err = TRUE; | 87 ev->err = TRUE; |
88 | 88 |
89 if (ev->errStr != NULL) | 89 if (ev->errStr != NULL) |
90 { | 90 { |
91 ev->errStr = dm_strdup_printf("%s%s", ev->errStr, tmp); | 91 ev->errStr = dm_strdup_printf("%s%s", ev->errStr, tmp); |
114 for (i = 0; i < ev->nsymbols; i++) | 114 for (i = 0; i < ev->nsymbols; i++) |
115 { | 115 { |
116 if (strcmp(ev->symbols[i].name, name) == 0) | 116 if (strcmp(ev->symbols[i].name, name) == 0) |
117 return &(ev->symbols[i]); | 117 return &(ev->symbols[i]); |
118 } | 118 } |
119 | 119 |
120 return NULL; | 120 return NULL; |
121 } | 121 } |
122 | 122 |
123 | 123 |
124 // Add a new symbol to the evaluation context. | 124 // Add a new symbol to the evaluation context. |
137 dmEvalError(ev, | 137 dmEvalError(ev, |
138 "Could not reallocate eval symbols array (#%d). Fatal error.\n", | 138 "Could not reallocate eval symbols array (#%d). Fatal error.\n", |
139 ev->nsymbols + 1); | 139 ev->nsymbols + 1); |
140 return NULL; | 140 return NULL; |
141 } | 141 } |
142 | 142 |
143 symbol = &(ev->symbols[ev->nsymbols]); | 143 symbol = &(ev->symbols[ev->nsymbols]); |
144 ev->nsymbols++; | 144 ev->nsymbols++; |
145 | 145 |
146 memset(symbol, 0, sizeof(DMEvalSymbol)); | 146 memset(symbol, 0, sizeof(DMEvalSymbol)); |
147 symbol->name = dm_strdup(name); | 147 symbol->name = dm_strdup(name); |
154 DMEvalSymbol *dmEvalContextAddVar(DMEvalContext *ev, const char *name, DMValue *var) | 154 DMEvalSymbol *dmEvalContextAddVar(DMEvalContext *ev, const char *name, DMValue *var) |
155 { | 155 { |
156 DMEvalSymbol *symbol = dmEvalContextAddSymbol(ev, name, SYM_VAR); | 156 DMEvalSymbol *symbol = dmEvalContextAddSymbol(ev, name, SYM_VAR); |
157 if (symbol == NULL) | 157 if (symbol == NULL) |
158 return NULL; | 158 return NULL; |
159 | 159 |
160 symbol->var = var; | 160 symbol->var = var; |
161 return symbol; | 161 return symbol; |
162 } | 162 } |
163 | 163 |
164 | 164 |
165 DMEvalSymbol *dmEvalContextAddConst(DMEvalContext *ev, const char *name, DMValue value) | 165 DMEvalSymbol *dmEvalContextAddConst(DMEvalContext *ev, const char *name, DMValue value) |
166 { | 166 { |
167 DMEvalSymbol *symbol = dmEvalContextAddSymbol(ev, name, SYM_CONST); | 167 DMEvalSymbol *symbol = dmEvalContextAddSymbol(ev, name, SYM_CONST); |
168 if (symbol == NULL) | 168 if (symbol == NULL) |
169 return NULL; | 169 return NULL; |
170 | 170 |
171 symbol->cvalue = value; | 171 symbol->cvalue = value; |
172 return symbol; | 172 return symbol; |
173 } | 173 } |
174 | 174 |
175 | 175 |
176 DMEvalSymbol *dmEvalContextAddFunc(DMEvalContext *ev, const char *name, DMValue (*func)(DMValue *), int nargs) | 176 DMEvalSymbol *dmEvalContextAddFunc(DMEvalContext *ev, const char *name, DMValue (*func)(DMValue *), int nargs) |
177 { | 177 { |
178 DMEvalSymbol *symbol = dmEvalContextAddSymbol(ev, name, SYM_VAR); | 178 DMEvalSymbol *symbol = dmEvalContextAddSymbol(ev, name, SYM_VAR); |
179 if (symbol == NULL) | 179 if (symbol == NULL) |
180 return NULL; | 180 return NULL; |
181 | 181 |
182 symbol->func = func; | 182 symbol->func = func; |
183 symbol->nargs = nargs; | 183 symbol->nargs = nargs; |
184 | 184 |
185 return DMERR_OK; | 185 return DMERR_OK; |
186 } | 186 } |
234 | 234 |
235 void dmEvalContextClear(DMEvalContext *ev) | 235 void dmEvalContextClear(DMEvalContext *ev) |
236 { | 236 { |
237 if (ev == NULL) | 237 if (ev == NULL) |
238 return; | 238 return; |
239 | 239 |
240 dmFree(ev->errStr); | 240 dmFree(ev->errStr); |
241 ev->err = FALSE; | 241 ev->err = FALSE; |
242 ev->errStr = NULL; | 242 ev->errStr = NULL; |
243 } | 243 } |
244 | 244 |
321 DM_CHECK(OPER); | 321 DM_CHECK(OPER); |
322 DM_CHECK(OPER_UNARY); | 322 DM_CHECK(OPER_UNARY); |
323 DM_CHECK(SUBEXPR_START); | 323 DM_CHECK(SUBEXPR_START); |
324 DM_CHECK(SUBEXPR_END); | 324 DM_CHECK(SUBEXPR_END); |
325 DM_CHECK(ARGS); | 325 DM_CHECK(ARGS); |
326 | 326 |
327 return dm_strdup(str); | 327 return dm_strdup(str); |
328 } | 328 } |
329 | 329 |
330 | 330 |
331 static void dmEvalSetMode(DMEvalContext *ev, const int mode) | 331 static void dmEvalSetMode(DMEvalContext *ev, const int mode) |
356 DMEvalNode *node = NULL, *func = NULL; | 356 DMEvalNode *node = NULL, *func = NULL; |
357 BOOL first = FALSE, decimal = FALSE; | 357 BOOL first = FALSE, decimal = FALSE; |
358 | 358 |
359 ev->expect = PARSE_NORMAL; | 359 ev->expect = PARSE_NORMAL; |
360 ev->mode = PARSE_START; | 360 ev->mode = PARSE_START; |
361 | 361 |
362 while (ev->mode != PARSE_ERROR && ev->mode != PARSE_END) | 362 while (ev->mode != PARSE_ERROR && ev->mode != PARSE_END) |
363 switch (ev->mode) | 363 switch (ev->mode) |
364 { | 364 { |
365 case PARSE_START: | 365 case PARSE_START: |
366 // Start | 366 // Start |
380 dmEvalError(ev, "Invalid nesting near '%s' (depth %d).\n", c, depth); | 380 dmEvalError(ev, "Invalid nesting near '%s' (depth %d).\n", c, depth); |
381 dmEvalSetMode(ev, PARSE_ERROR); | 381 dmEvalSetMode(ev, PARSE_ERROR); |
382 } | 382 } |
383 c++; | 383 c++; |
384 } | 384 } |
385 | 385 |
386 else if (*c == '(') | 386 else if (*c == '(') |
387 dmEvalSetMode(ev, func != NULL ? PARSE_ARGS : PARSE_SUBEXPR_START); | 387 dmEvalSetMode(ev, func != NULL ? PARSE_ARGS : PARSE_SUBEXPR_START); |
388 | 388 |
389 else if (*c == '-') | 389 else if (*c == '-') |
390 dmEvalSetMode(ev, (ev->prev == PARSE_START || ev->prev == PARSE_OPER || ev->prev == PARSE_OPER_UNARY) ? PARSE_OPER_UNARY : PARSE_OPER); | 390 dmEvalSetMode(ev, (ev->prev == PARSE_START || ev->prev == PARSE_OPER || ev->prev == PARSE_OPER_UNARY) ? PARSE_OPER_UNARY : PARSE_OPER); |
391 | 391 |
392 else if (*c == '~') | 392 else if (*c == '~') |
393 dmEvalSetMode(ev, PARSE_OPER_UNARY); | 393 dmEvalSetMode(ev, PARSE_OPER_UNARY); |
394 | 394 |
395 else if (strchr("+*/<>%&|!^", *c)) | 395 else if (strchr("+*/<>%&|!^", *c)) |
396 dmEvalSetMode(ev, PARSE_OPER); | 396 dmEvalSetMode(ev, PARSE_OPER); |
397 | 397 |
398 else if (isdigit(*c) || *c == '.') | 398 else if (isdigit(*c) || *c == '.') |
399 dmEvalSetMode(ev, PARSE_CONST); | 399 dmEvalSetMode(ev, PARSE_CONST); |
400 | 400 |
401 else if (isalpha(*c) || *c == '_') | 401 else if (isalpha(*c) || *c == '_') |
402 dmEvalSetMode(ev, PARSE_IDENT); | 402 dmEvalSetMode(ev, PARSE_IDENT); |
403 | 403 |
404 else | 404 else |
405 { | 405 { |
406 dmEvalError(ev, "Syntax error near '%s' (depth %d).\n", c, depth); | 406 dmEvalError(ev, "Syntax error near '%s' (depth %d).\n", c, depth); |
407 dmEvalSetMode(ev, PARSE_ERROR); | 407 dmEvalSetMode(ev, PARSE_ERROR); |
408 } | 408 } |
409 | 409 |
410 first = TRUE; | 410 first = TRUE; |
411 break; | 411 break; |
412 | 412 |
413 case PARSE_SUBEXPR_START: | 413 case PARSE_SUBEXPR_START: |
414 tmp = c + 1; | 414 tmp = c + 1; |
415 | 415 |
416 ev->expect = PARSE_NORMAL; | 416 ev->expect = PARSE_NORMAL; |
417 | 417 |
432 } | 432 } |
433 break; | 433 break; |
434 | 434 |
435 case PARSE_ARGS: | 435 case PARSE_ARGS: |
436 tmp = c + 1; | 436 tmp = c + 1; |
437 | 437 |
438 for (argIndex = 0; argIndex < func->symbol->nargs; argIndex++) | 438 for (argIndex = 0; argIndex < func->symbol->nargs; argIndex++) |
439 { | 439 { |
440 if (dmEvalTokenizeExpr(ev, &(func->args[argIndex]), &tmp, depth + 1) != 0) | 440 if (dmEvalTokenizeExpr(ev, &(func->args[argIndex]), &tmp, depth + 1) != 0) |
441 { | 441 { |
442 dmEvalError(ev, "Function argument subexpression starting at '%s' contained errors.\n", c); | 442 dmEvalError(ev, "Function argument subexpression starting at '%s' contained errors.\n", c); |
458 if (first) | 458 if (first) |
459 { | 459 { |
460 first = FALSE; | 460 first = FALSE; |
461 decimal = FALSE; | 461 decimal = FALSE; |
462 tmpStrLen = 0; | 462 tmpStrLen = 0; |
463 | 463 |
464 if (isdigit(*c) || *c == '-' || *c == '+' || *c == '.') | 464 if (isdigit(*c) || *c == '-' || *c == '+' || *c == '.') |
465 { | 465 { |
466 if (*c == '.') | 466 if (*c == '.') |
467 decimal = TRUE; | 467 decimal = TRUE; |
468 tmpStr[tmpStrLen++] = *c++; | 468 tmpStr[tmpStrLen++] = *c++; |
558 { | 558 { |
559 op = (c[1] == '=') ? OP_GT_EQ : OP_GT; | 559 op = (c[1] == '=') ? OP_GT_EQ : OP_GT; |
560 c++; | 560 c++; |
561 } | 561 } |
562 break; | 562 break; |
563 | 563 |
564 case '<': | 564 case '<': |
565 if (c[1] == '<') | 565 if (c[1] == '<') |
566 { | 566 { |
567 c += 2; | 567 c += 2; |
568 op = OP_BIT_LSHIFT; | 568 op = OP_BIT_LSHIFT; |
652 if (ev == NULL || result == NULL) | 652 if (ev == NULL || result == NULL) |
653 return DMERR_NULLPTR; | 653 return DMERR_NULLPTR; |
654 | 654 |
655 ev->prev = PARSE_START; | 655 ev->prev = PARSE_START; |
656 ret = dmEvalTokenizeExpr(ev, result, &expr, 0); | 656 ret = dmEvalTokenizeExpr(ev, result, &expr, 0); |
657 | 657 |
658 return ret; | 658 return ret; |
659 } | 659 } |
660 | 660 |
661 | 661 |
662 | 662 |
679 return FALSE; | 679 return FALSE; |
680 | 680 |
681 case OP_VALUE: | 681 case OP_VALUE: |
682 *presult = node->val; | 682 *presult = node->val; |
683 return TRUE; | 683 return TRUE; |
684 | 684 |
685 case OP_FUNC: | 685 case OP_FUNC: |
686 | 686 |
687 return TRUE; | 687 return TRUE; |
688 | 688 |
689 case OP_SUBEXPR: | 689 case OP_SUBEXPR: |
690 return dmEvalTreeExecute(ev, node->subexpr, presult); | 690 return dmEvalTreeExecute(ev, node->subexpr, presult); |
691 | 691 |
692 // Binary operators | 692 // Binary operators |
693 case OP_BIT_LSHIFT: | 693 case OP_BIT_LSHIFT: |
694 case OP_BIT_RSHIFT: | 694 case OP_BIT_RSHIFT: |
695 | 695 |
696 case OP_BIT_AND: | 696 case OP_BIT_AND: |
697 case OP_BIT_XOR: | 697 case OP_BIT_XOR: |
698 case OP_BIT_OR: | 698 case OP_BIT_OR: |
699 | 699 |
700 case OP_ADD: | 700 case OP_ADD: |