diff options
-rw-r--r-- | mixlib/mix_eval_scanner.l | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/mixlib/mix_eval_scanner.l b/mixlib/mix_eval_scanner.l index 443654d..af7fd67 100644 --- a/mixlib/mix_eval_scanner.l +++ b/mixlib/mix_eval_scanner.l @@ -1,7 +1,7 @@ /* -*-c-*- ------------------ mix_eval_scanner.l : * scanner used by mix_eval_t * ------------------------------------------------------------------ - * Last change: Time-stamp: <00/12/02 22:48:00 jose> + * Last change: Time-stamp: <00/12/03 11:33:21 jose> * ------------------------------------------------------------------ * Copyright (C) 2000 jose antonio ortega ruiz <jaortega@acm.org> * @@ -28,6 +28,9 @@ #define YY_DECL \ mix_eval_result_t mix_eval_expr (mix_eval_data_ *data) + /* keep track of current position in buffer */ +#define YY_USER_ACTION yypos += yyleng; + #define RETURN_STATE(err) \ do { \ done = TRUE; \ @@ -44,7 +47,7 @@ static mix_word_t eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y); -static void +static int unput_word_ (mix_word_t word); %} @@ -85,11 +88,13 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* mix_word_t wexpr_val_tmp = MIX_WORD_ZERO; mix_eval_result_t state = MIX_EVAL_OK; gchar *expr_cp; + gint yypos = -22; /* to account for padding */ gboolean is_fp = FALSE, done = FALSE; g_assert (data != NULL && data->expr != NULL); /* make room enough to unput computed values */ - expr_cp = g_strdup_printf (" %s", data->expr); + expr_cp = g_strdup_printf ("%-20s%s"," ", data->expr); buffer = yy_scan_string (expr_cp); + data->errpos = -1; %} @@ -102,18 +107,21 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* {ws} /* eat whitespace */ . { if (!done && state == MIX_EVAL_OK) { - yyless (0); + yypos -= yyleng; yyless (0); yy_push_state (WEVAL); } else { CLEAN_UP (); if (state == MIX_EVAL_OK) return (MIX_EVAL_SYNTAX); + data->errpos = yypos; return state; } } "\n" { CLEAN_UP(); if (state == MIX_EVAL_OK) - data->value = wexpr_val; + data->value = wexpr_val; + else + data->errpos = yypos; return state; } } @@ -140,13 +148,13 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* {number} { wexpr_val = mix_word_new (atol (yytext)); } - {expr} yyless (0); yy_push_state (EVAL); + {expr} yypos -= yyleng; yyless (0); yy_push_state (EVAL); ,/{expr} /* eat comma if followed by expression */ [\t\n ] { /* ok if not inside an f-part */ if ( is_fp ) { RETURN_STATE (MIX_EVAL_MIS_PAREN); } - unput (yytext[yyleng-1]); + unput (yytext[yyleng-1]); --yypos; done = TRUE; yy_pop_state (); } @@ -170,13 +178,13 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* "***" { mix_word_t loc = mix_short_to_word_fast (data->loc); (void)mix_word_mul (loc, loc, NULL, &loc); - unput_word_ (loc); + yypos -= unput_word_ (loc); } {binop}"*" { expr_val = eval_binop_ (yytext, expr_val, mix_short_to_word_fast (data->loc)); } - "*" unput_word_ (mix_short_to_word_fast (data->loc)); + "*" yypos -= unput_word_ (mix_short_to_word_fast (data->loc)); {number} expr_val = mix_word_new (atol (yytext)); {symbol} { if ( !mix_symbol_table_is_defined (data->table, yytext) ) { @@ -185,8 +193,8 @@ wexpr {expr}({fpart})?(,{expr}({fpart})?)* expr_val = mix_symbol_table_value (data->table, yytext); } [,)(\n\t ] { - unput (yytext[0]); - unput_word_ (expr_val); + unput (yytext[0]); --yypos; + yypos -= unput_word_ (expr_val); yy_pop_state (); } @@ -232,15 +240,17 @@ eval_binop_ (const gchar *op, mix_word_t x, mix_word_t y) } -static void +static int unput_word_ (mix_word_t word) { gchar *value; - gint k; + gint k, result; value = g_strdup_printf ("%s%ld", mix_word_is_negative (word)? "-":"+", - mix_word_magnitude (word)); - for (k = strlen (value) - 1; k >= 0; --k) + mix_word_magnitude (word)); + result = strlen (value); + for (k = result - 1; k >= 0; --k) unput (value[k]); - g_free (value); + g_free (value); + return result; } |