summaryrefslogtreecommitdiffhomepage
path: root/mixlib
diff options
context:
space:
mode:
Diffstat (limited to 'mixlib')
-rw-r--r--mixlib/mix_eval_scanner.l42
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;
}