yaubil.c
changeset 1 320e4393785a
parent 0 7707b26e82fd
child 2 6a47079725da
equal deleted inserted replaced
0:7707b26e82fd 1:320e4393785a
   470 	if (value->str_value)
   470 	if (value->str_value)
   471 		g_free (value->str_value);
   471 		g_free (value->str_value);
   472 	g_free (value);
   472 	g_free (value);
   473 }
   473 }
   474 
   474 
   475 static value_t *process_expression (const char *str, gsize len)
   475 static value_t *process_expression (const char *str, gsize *len)
   476 {
   476 {
   477 	const char *strend = str + len;
   477 	const char *strend = str + *len;
   478 	const char *p;
   478 	const char *p;
   479 	op_t       *op     = NULL;
   479 	op_t       *op     = NULL;
   480 	int         state  = STATE_LVALUE;
   480 	int         state  = STATE_LVALUE;
   481 	value_t     val    = {
   481 	value_t     val    = {
   482 		.type      = TYPE_UNDEF,
   482 		.type      = TYPE_UNDEF,
   483 		.int_value = 0,
   483 		.int_value = 0,
   484 		.str_value = NULL,
   484 		.str_value = NULL,
   485 	};
   485 	};
   486 
   486 
   487 	for (p = str; *p && p < strend; ++p) {
   487 	for (p = str; *p && p < strend && *p != ')'; ++p) {
   488 		switch (state) {
   488 		switch (state) {
   489 		case STATE_LVALUE:
   489 		case STATE_LVALUE:
   490 		case STATE_RVALUE:
   490 		case STATE_RVALUE:
   491 
   491 
   492 			if (*p == ' ')
   492 			if (*p == ' ')
   583 
   583 
   584 					p = e - 1;
   584 					p = e - 1;
   585 
   585 
   586 				} else if (*p == '(') {
   586 				} else if (*p == '(') {
   587 					
   587 					
   588 					const char *e;
   588 					gsize    len = strend - p - 1;
   589 
   589 					value_t *n   = process_expression (p + 1, &len);
   590 					{
   590 					
   591 						int      l        = 0;
   591 					if (!n) {
   592 						gboolean finished = FALSE;
   592 						scr_LogPrint (LPRINT_NORMAL, MSGPREFIX "Error: Error in subexpression.");
   593 						
   593 						g_free (val.str_value);
   594 						// XXX maybe we should just pass end of line and let it return real length...
   594 						return NULL;
   595 						for (e = p + 1; e < strend; ++e) {
       
   596 							if (*e == '(')
       
   597 								++l;
       
   598 							else if (*e == ')') {
       
   599 								--l;
       
   600 								if (l < 0) {
       
   601 									finished = TRUE;
       
   602 									break;
       
   603 								}
       
   604 							}
       
   605 						}
       
   606 
       
   607 						if (!finished) {
       
   608 							scr_LogPrint (LPRINT_NORMAL, MSGPREFIX "Error: Unmatched parenthesis.");
       
   609 							g_free (val.str_value);
       
   610 							return NULL;
       
   611 						}
       
   612 					}
   595 					}
   613 
   596 
   614 					{
   597 					rval.type      = n->type;
   615 						value_t *n = process_expression (p + 1, e - p - 1);
   598 					rval.int_value = n->int_value;
   616 						
   599 					rval.str_value = g_strdup (n->str_value);
   617 						if (!n) {
   600 					destroy_value (n);
   618 							scr_LogPrint (LPRINT_NORMAL, MSGPREFIX "Error: Error in subexpression.");
   601 
   619 							g_free (val.str_value);
   602 					p += len + 1;
   620 							return NULL;
       
   621 						}
       
   622 
       
   623 						rval.type      = n->type;
       
   624 						rval.int_value = n->int_value;
       
   625 						rval.str_value = g_strdup (n->str_value);
       
   626 						destroy_value (n);
       
   627 					}
       
   628 
       
   629 					p = e;
       
   630 
   603 
   631 				} else {
   604 				} else {
   632 					scr_LogPrint (LPRINT_NORMAL, MSGPREFIX "Error: unrecognized symbols.");
   605 					scr_LogPrint (LPRINT_NORMAL, MSGPREFIX "Error: unrecognized symbols.");
   633 					g_free (val.str_value);
   606 					g_free (val.str_value);
   634 					return NULL;
   607 					return NULL;
   685 			break;
   658 			break;
   686 		}
   659 		}
   687 	}
   660 	}
   688 
   661 
   689 	{ // return value
   662 	{ // return value
       
   663 		*len = p - str;
   690 		value_t *rval = g_new (value_t, 1);
   664 		value_t *rval = g_new (value_t, 1);
   691 
   665 
   692 		rval->type      = val.type;
   666 		rval->type      = val.type;
   693 		rval->int_value = val.int_value;
   667 		rval->int_value = val.int_value;
   694 		rval->str_value = val.str_value;
   668 		rval->str_value = val.str_value;
   697 	}
   671 	}
   698 }
   672 }
   699 
   673 
   700 static void do_eval (char *arg)
   674 static void do_eval (char *arg)
   701 {
   675 {
   702 	value_t *val = process_expression (arg, strlen (arg));
   676 	gsize    len = strlen (arg);
       
   677 	value_t *val = process_expression (arg, &len);
   703 
   678 
   704 	if (!val) {
   679 	if (!val) {
   705 		scr_LogPrint (LPRINT_NORMAL, "eval: Evaluation error.");
   680 		scr_LogPrint (LPRINT_NORMAL, "eval: Evaluation error.");
   706 		return;
   681 		return;
   707 	}
   682 	}
   736 		}
   711 		}
   737 
   712 
   738 		namelen = p + 1 - arg;
   713 		namelen = p + 1 - arg;
   739 	}
   714 	}
   740 
   715 
   741 	// evaluate expression
   716 	{ // evaluate expression
   742 	value = process_expression (val + 1, strlen (val + 1));
   717 		gsize len = strlen (val + 1);
       
   718 
       
   719 		value = process_expression (val + 1, &len);
       
   720 	}
   743 
   721 
   744 	if (!value) {
   722 	if (!value) {
   745 		scr_LogPrint (LPRINT_NORMAL, "let: Evaluation error.");
   723 		scr_LogPrint (LPRINT_NORMAL, "let: Evaluation error.");
   746 		return;
   724 		return;
   747 	}
   725 	}
   765 	destroy_value (value);
   743 	destroy_value (value);
   766 }
   744 }
   767 
   745 
   768 static void do_if (char *arg)
   746 static void do_if (char *arg)
   769 {
   747 {
   770 	value_t *val = process_expression (arg, strlen (arg));
   748 	gsize    len = strlen (arg);
       
   749 	value_t *val = process_expression (arg, &len);
   771 
   750 
   772 	if (!val) {
   751 	if (!val) {
   773 		scr_LogPrint (LPRINT_NORMAL, "if: Evaluation error.");
   752 		scr_LogPrint (LPRINT_NORMAL, "if: Evaluation error.");
   774 		return;
   753 		return;
   775 	}
   754 	}