* Moved the mapm library from src/apps/deskcalc to src/libs and headers/libs.

* Moved the ExpressionParser class to shared. It's now built into its own
  static library.
* Added hexadecimal number support to the expression parser as well as
  Evaluation*() methods to get a number instead of a string.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31298 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-06-28 17:10:40 +00:00
parent aa6b2770fc
commit 59d799dabc
47 changed files with 118 additions and 55 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006 Haiku, Inc. All Rights Reserved.
* Copyright 2006-2009 Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -42,7 +42,11 @@ class ExpressionParser {
ExpressionParser();
~ExpressionParser();
void SetSupportHexInput(bool enabled);
BString Evaluate(const char* expressionString);
int64 EvaluateToInt64(const char* expressionString);
double EvaluateToDouble(const char* expressionString);
private:

View File

@ -35,9 +35,10 @@
#include <Region.h>
#include <Roster.h>
#include <ExpressionParser.h>
#include "CalcApplication.h"
#include "CalcOptions.h"
#include "ExpressionParser.h"
#include "ExpressionTextView.h"

View File

@ -2,7 +2,7 @@ SubDir HAIKU_TOP src apps deskcalc ;
SetSubDirSupportedPlatformsBeOSCompatible ;
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src apps deskcalc mapm_4.9.5 ] ;
UsePrivateHeaders shared ;
Application DeskCalc :
CalcApplication.cpp
@ -10,51 +10,8 @@ Application DeskCalc :
CalcView.cpp
CalcWindow.cpp
DeskCalc.cpp
ExpressionParser.cpp
ExpressionTextView.cpp
InputTextView.cpp
# m_apm files
mapmhasn.c
mapmhsin.c
mapm_pow.c
mapm_log.c
mapm_lg2.c
mapm_lg4.c
mapm_exp.c
mapm_lg3.c
mapmasin.c
mapmasn0.c
mapm_sin.c
mapm5sin.c
mapmrsin.c
mapm_cpi.c
mapmsqrt.c
mapmcbrt.c
mapmgues.c
mapmfact.c
mapm_gcd.c
mapmipwr.c
mapmpwr2.c
mapm_rnd.c
mapm_flr.c
mapm_fpf.c
mapm_rcp.c
mapmstck.c
mapm_div.c
mapm_mul.c
mapmfmul.c
mapm_fft.c
mapm_add.c
mapmistr.c
mapm_set.c
mapm_fam.c
mapmutil.c
mapmutl2.c
mapmutl1.c
mapmcnst.c
: be $(TARGET_LIBSTDC++) media
: be $(TARGET_LIBSTDC++) media libexpression_parser.a libmapm.a
: DeskCalc.rdef
;
;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006 Haiku, Inc. All Rights Reserved.
* Copyright 2006-2009 Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -7,14 +7,16 @@
* Stephan Aßmus <superstippi@gmx.de>
*/
#include <ExpressionParser.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "m_apm.h"
#include <m_apm.h>
#include "ExpressionParser.h"
static const int32 kMaxDigits = 64;
@ -91,10 +93,16 @@ class Tokenizer {
: fString(""),
fCurrentChar(NULL),
fCurrentToken(),
fReuseToken(false)
fReuseToken(false),
fHexSupport(false)
{
}
void SetSupportHexInput(bool enabled)
{
fHexSupport = enabled;
}
void SetTo(const char* string)
{
fString = string;
@ -123,6 +131,8 @@ class Tokenizer {
bool decimal = *fCurrentChar == '.' || *fCurrentChar == ',';
if (decimal || isdigit(*fCurrentChar)) {
if (fHexSupport && *fCurrentChar == '0' && fCurrentChar[1] == 'x')
return _ParseHexNumber();
BString temp;
@ -155,7 +165,6 @@ class Tokenizer {
fCurrentToken.value = temp.String();
} else if (isalpha(*fCurrentChar) && *fCurrentChar != 'x') {
const char* begin = fCurrentChar;
while (*fCurrentChar != 0 && (isalpha(*fCurrentChar)
|| isdigit(*fCurrentChar))) {
@ -166,7 +175,6 @@ class Tokenizer {
TOKEN_IDENTIFIER);
} else {
int32 type = TOKEN_NONE;
switch (*fCurrentChar) {
@ -177,7 +185,6 @@ class Tokenizer {
type = TOKEN_MINUS;
break;
case '*':
case 'x':
type = TOKEN_STAR;
break;
case '/':
@ -214,6 +221,13 @@ class Tokenizer {
type = TOKEN_END_OF_LINE;
break;
case 'x':
if (!fHexSupport) {
type = TOKEN_STAR;
break;
}
// fall through
default:
throw ParseException("unexpected character", _CurrentPos());
}
@ -231,6 +245,43 @@ class Tokenizer {
}
private:
static bool _IsHexDigit(char c)
{
return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
Token& _ParseHexNumber()
{
const char* begin = fCurrentChar;
fCurrentChar += 2;
// skip "0x"
if (!_IsHexDigit(*fCurrentChar))
throw ParseException("expected hex digit", _CurrentPos());
fCurrentChar++;
while (_IsHexDigit(*fCurrentChar))
fCurrentChar++;
int32 length = fCurrentChar - begin;
fCurrentToken = Token(begin, length, _CurrentPos() - length,
TOKEN_CONSTANT);
// MAPM has no conversion from long long, so we need to improvise.
uint64 value = strtoll(fCurrentToken.string.String(), NULL, 0);
if (value <= 0x7fffffff) {
fCurrentToken.value = (long)value;
} else {
fCurrentToken.value = (int)(value >> 60);
fCurrentToken.value *= 1 << 30;
fCurrentToken.value += (int)((value >> 30) & 0x3fffffff);
fCurrentToken.value *= 1 << 30;
fCurrentToken.value += (int)(value& 0x3fffffff);
}
return fCurrentToken;
}
int32 _CurrentPos() const
{
return fCurrentChar - fString.String();
@ -240,6 +291,7 @@ class Tokenizer {
const char* fCurrentChar;
Token fCurrentToken;
bool fReuseToken;
bool fHexSupport;
};
@ -255,6 +307,13 @@ ExpressionParser::~ExpressionParser()
}
void
ExpressionParser::SetSupportHexInput(bool enabled)
{
fTokenizer->SetSupportHexInput(enabled);
}
BString
ExpressionParser::Evaluate(const char* expressionString)
{
@ -290,6 +349,40 @@ ExpressionParser::Evaluate(const char* expressionString)
}
int64
ExpressionParser::EvaluateToInt64(const char* expressionString)
{
fTokenizer->SetTo(expressionString);
MAPM value = _ParseBinary();
Token token = fTokenizer->NextToken();
if (token.type != TOKEN_END_OF_LINE)
throw ParseException("parse error", token.position);
char buffer[128];
value.toIntegerString(buffer);
return strtoll(buffer, NULL, 0);
}
double
ExpressionParser::EvaluateToDouble(const char* expressionString)
{
fTokenizer->SetTo(expressionString);
MAPM value = _ParseBinary();
Token token = fTokenizer->NextToken();
if (token.type != TOKEN_END_OF_LINE)
throw ParseException("parse error", token.position);
char buffer[1024];
value.toString(buffer, sizeof(buffer) - 4);
return strtod(buffer, NULL);
}
MAPM
ExpressionParser::_ParseBinary()
{

View File

@ -22,3 +22,10 @@ StaticLibrary libshared.a :
RWLockManager.cpp
Variant.cpp
;
UseLibraryHeaders mapm ;
StaticLibrary libexpression_parser.a :
ExpressionParser.cpp
;

View File

@ -14,6 +14,7 @@ SubInclude HAIKU_TOP src libs iconv ;
SubInclude HAIKU_TOP src libs libtelnet ;
SubInclude HAIKU_TOP src libs linprog ;
SubInclude HAIKU_TOP src libs lp_solve ;
SubInclude HAIKU_TOP src libs mapm ;
SubInclude HAIKU_TOP src libs ncurses ;
SubInclude HAIKU_TOP src libs pdflib ;
SubInclude HAIKU_TOP src libs png ;