From e8cac5998ca52debe3f7687bf32287d8a3393389 Mon Sep 17 00:00:00 2001 From: Thomas James Alexander Thurman Date: Tue, 3 Feb 2009 02:24:17 +0000 Subject: added gratuitous "halve" operation * src/ui/rpn.c: added gratuitous "halve" operation svn path=/branches/rpnparser/; revision=4111 --- ChangeLog | 4 ++++ src/ui/rpn.c | 32 ++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index e69e360c..1b5a5048 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-02-02 Thomas Thurman + + * src/ui/rpn.c: added gratuitous "halve" operation + 2009-02-02 Thomas Thurman and the actual parsing code! diff --git a/src/ui/rpn.c b/src/ui/rpn.c index 8e858dfe..580526d2 100644 --- a/src/ui/rpn.c +++ b/src/ui/rpn.c @@ -60,6 +60,14 @@ enum MetaToken { META_TOKEN_DIVIDE, META_TOKEN_MIN, META_TOKEN_MAX, + /** + * HALVE is an optimisation: it halves its first argument, since + * division is slow and bitshifting is fast, and halving is something + * that's very common in themes. It's still a binary operator, + * to save us having to invent unary operators for this one case. + * The second argument (which should be 2) is thrown away. + */ + META_TOKEN_HALVE, META_TOKEN_OPEN, /* only during parse */ META_TOKEN_CLOSE, /* only during parse */ /* Variables, which are treated as 0-ary operators */ @@ -93,6 +101,7 @@ meta_token_as_string (MetaToken token) case META_TOKEN_DIVIDE: return g_strdup_printf ("/"); case META_TOKEN_MIN: return g_strdup_printf ("`min`"); case META_TOKEN_MAX: return g_strdup_printf ("`max`"); + case META_TOKEN_HALVE: return g_strdup_printf ("/(halve)"); case META_TOKEN_OPEN: return g_strdup_printf ("("); case META_TOKEN_CLOSE: return g_strdup_printf (")"); @@ -169,6 +178,7 @@ static guint64 multiply(guint64 a, guint64 b) { return a*(b>>SCALE_BITS); } static guint64 divide(guint64 a, guint64 b) { return b==0?0:a/(b>>SCALE_BITS); } static guint64 min(guint64 a, guint64 b) { return ab?a:b; } +static guint64 halve(guint64 a, guint64 b) { return a>>1; } static guint64 get_width(const MetaPositionExprEnv *env) { return env->rect.width; } static guint64 get_height(const MetaPositionExprEnv *env) { return env->rect.height; } @@ -204,6 +214,7 @@ const TokenHandler handlers[] = { { divide, NULL }, { min, NULL }, { max, NULL }, + { halve, NULL }, { NULL }, /* OPEN */ { NULL }, /* CLOSE */ #define name_token(t) { NULL, get_##t }, @@ -284,6 +295,12 @@ accept (MetaToken *output, gint *output_pointer, MetaToken item) if (*output_pointer>STACK_SIZE) meta_bug ("Parse stack overflow"); /* FIXME THIS IS BAD */ + /* Special case: */ + if (item==META_TOKEN_DIVIDE && + *output_pointer != 0 && + output[(*output_pointer)-1]==2<