diff options
author | Eugene Sandulenko | 2006-03-07 03:31:31 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2006-03-07 03:31:31 +0000 |
commit | ebd583333556b2d13b1de280aabce2561ae97c4d (patch) | |
tree | 9a6eae89daf49382ee9306cb56c9e221838c40d0 /gui/eval.cpp | |
parent | 4c16b73bd1181f1e7daa5ff206af153ae2ef7b7f (diff) | |
download | scummvm-rg350-ebd583333556b2d13b1de280aabce2561ae97c4d.tar.gz scummvm-rg350-ebd583333556b2d13b1de280aabce2561ae97c4d.tar.bz2 scummvm-rg350-ebd583333556b2d13b1de280aabce2561ae97c4d.zip |
WIP for arbitrary widget positions. See
http://wiki.scummvm.org/index.php/GUI_Themes
Code is not yet used.
svn-id: r21115
Diffstat (limited to 'gui/eval.cpp')
-rw-r--r-- | gui/eval.cpp | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/gui/eval.cpp b/gui/eval.cpp new file mode 100644 index 0000000000..6828823e68 --- /dev/null +++ b/gui/eval.cpp @@ -0,0 +1,292 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/system.h" +#include "gui/eval.h" +#include "gui/widget.h" +#include "gui/newgui.h" + +namespace GUI { + +static bool isdelim(char c) { + if (strchr(" ;,+-<>/*%^=()", c) || c == 9 || c == '\n' || !c) + return true; + + return false; +} + +Eval::Eval() { +} + +Eval::~Eval() { + reset(); +} + +int Eval::eval(const String &input, const String §ion, const String &name, int startpos) { + int result; + + debug(3, "<%s>", input.c_str()); + + strncpy(_input, input.c_str(), 256); + _section = section; + _name = name; + _startpos = startpos; + + _pos = 0; + + getToken(); + + if (!*_token) + exprError(eBadExpr); + + level2(&result); + + debug(3, "Result: %d", result); + + return result; +} + +void Eval::level2(int *result) { + char op; + int hold; + + level3(result); + + while ((op = *_token) == '+' || op == '-') { + getToken(); + level3(&hold); + arith(op, result, &hold); + } +} + +void Eval::level3(int *result) { + char op; + int hold; + + level4(result); + + while ((op = *_token) == '*' || op == '/' || op == '%') { + getToken(); + level4(&hold); + arith(op, result, &hold); + } +} + +void Eval::level4(int *result) { + char op; + + op = 0; + if ((_tokenType == tDelimiter) && *_token == '+' || *_token == '-') { + op = *_token; + getToken(); + } + + level5(result); + + if (op) + unary(op, result); +} + +void Eval::level5(int *result) { + if ((*_token == '(') && (_tokenType == tDelimiter)) { + getToken(); + + level2(result); + + if (*_token != ')') + exprError(eUnclosedBracket); + getToken(); + } else { + primitive(result); + } +} + +void Eval::primitive(int *result) { + if (*_token == ')') + exprError(eExtraBracket); + + switch (_tokenType) { + case tVariable: + *result = lookupVar(_token); + if (*result == EVAL_UNDEF_VAR) + exprError(eUndefVar); + getToken(); + return; + case tNumber: + *result = atoi(_token); + getToken(); + return; + default: + exprError(eSyntaxError); + } +} + +void Eval::arith(char op, int *r, int *h) { + int t; + + switch (op) { + case '-': + *r = *r - *h; + break; + case '+': + *r = *r + *h; + break; + case '*': + *r = *r * *h; + break; + case '/': + *r = (*r) / (*h); + break; + case '%': + t = (*r) / (*h); + *r = *r - (t * (*h)); + break; + } +} + +void Eval::unary(char op, int *r) { + if (op == '-') + *r = -(*r); +} + +void Eval::getToken() { + char *temp; + + _tokenType = 0; + temp = _token; + + if (_input[_pos] == 0) { + *_token = 0; + _tokenType = tDelimiter; + return; + } + while (isspace(_input[_pos])) + _pos++; + + if (isdigit(_input[_pos])) { + while (!isdelim(_input[_pos])) + *temp++ = _input[_pos++]; + *temp = 0; + + _tokenType = tNumber; + return; + } + + if (isalpha(_input[_pos])) { + while (!isdelim(_input[_pos])) + *temp++ = _input[_pos++]; + *temp = 0; + _tokenType = tVariable; + return; + } + + + if (!_tokenType && isdelim(_input[_pos])) { + *temp++ = _input[_pos++]; + *temp = 0; + _tokenType = tDelimiter; + } +} + +void Eval::exprError(int err) { + static const char *errors[] = { + "Syntax error", + "Extra ')'", + "Missing ')'", + "Bad expression", + "Undefined variable" + }; + + error("%s in section [%s] expression: \"%s\" start is at: %d near token '%s'", + errors[err], _section.c_str(), _name.c_str(), _pos + _startpos, _token); +} + +struct BuiltinConsts { + const char *name; + int value; +}; + +static const BuiltinConsts builtinConsts[] = { + {"kButtonWidth", GUI::kButtonWidth}, + {"kButtonHeight", GUI::kButtonHeight}, + {"kSliderWidth", GUI::kSliderWidth}, + {"kSliderHeight", GUI::kSliderHeight}, + + {"kBigButtonWidth", GUI::kBigButtonWidth}, + {"kBigButtonHeight", GUI::kBigButtonHeight}, + {"kBigSliderWidth", GUI::kBigSliderWidth}, + {"kBigSliderHeight", GUI::kBigSliderHeight}, + {NULL, 0} +}; + +int Eval::getBuiltinVar(const char *s) { + if (!strcmp(s, "w")) + return g_system->getOverlayWidth(); + + if (!strcmp(s, "h")) + return g_system->getOverlayHeight(); + + return EVAL_UNDEF_VAR; +} + +int Eval::lookupVar(const char *s, bool includeAliases) { + int i; + int val; + + for (i = 0; builtinConsts[i].name; i++) + if (!scumm_stricmp(s, builtinConsts[i].name)) + return builtinConsts[i].value; + + val = getBuiltinVar(s); + + if (val != EVAL_UNDEF_VAR) + return val; + + String var = String(s); + if (includeAliases && _aliases.contains(var)) + var = _aliases[var]; + + if (_vars.contains(var)) + return _vars[var]; + + return EVAL_UNDEF_VAR; +} + +void Eval::setAlias(const String §ion, const String name, const String value) { + String var = String(&(name.c_str()[4])); + + _aliases[var] = value; +} + +void Eval::setVariable(const String §ion, const String name, const String value) { + String var = String(&(name.c_str()[4])); + + _vars[var] = eval(value, section, name, 0); +} + +void Eval::reset() { + _vars.clear(); + _aliases.clear(); +} + +} // end of namespace GUI |