[Haiku-commits] r31298 - in haiku/trunk: headers/libs headers/libs/mapm headers/private/shared src/apps/deskcalc src/kits/shared src/libs src/libs/mapm

bonefish at BerliOS bonefish at mail.berlios.de
Sun Jun 28 19:10:45 CEST 2009


Author: bonefish
Date: 2009-06-28 19:10:40 +0200 (Sun, 28 Jun 2009)
New Revision: 31298
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31298&view=rev

Added:
   haiku/trunk/headers/libs/mapm/
   haiku/trunk/headers/libs/mapm/m_apm.h
   haiku/trunk/headers/private/shared/ExpressionParser.h
   haiku/trunk/src/kits/shared/ExpressionParser.cpp
   haiku/trunk/src/libs/mapm/
   haiku/trunk/src/libs/mapm/README
   haiku/trunk/src/libs/mapm/m_apm_lc.h
   haiku/trunk/src/libs/mapm/mapm5sin.c
   haiku/trunk/src/libs/mapm/mapm_add.c
   haiku/trunk/src/libs/mapm/mapm_cpi.c
   haiku/trunk/src/libs/mapm/mapm_div.c
   haiku/trunk/src/libs/mapm/mapm_exp.c
   haiku/trunk/src/libs/mapm/mapm_fam.c
   haiku/trunk/src/libs/mapm/mapm_fft.c
   haiku/trunk/src/libs/mapm/mapm_flr.c
   haiku/trunk/src/libs/mapm/mapm_fpf.c
   haiku/trunk/src/libs/mapm/mapm_gcd.c
   haiku/trunk/src/libs/mapm/mapm_lg2.c
   haiku/trunk/src/libs/mapm/mapm_lg3.c
   haiku/trunk/src/libs/mapm/mapm_lg4.c
   haiku/trunk/src/libs/mapm/mapm_log.c
   haiku/trunk/src/libs/mapm/mapm_mul.c
   haiku/trunk/src/libs/mapm/mapm_pow.c
   haiku/trunk/src/libs/mapm/mapm_rcp.c
   haiku/trunk/src/libs/mapm/mapm_rnd.c
   haiku/trunk/src/libs/mapm/mapm_set.c
   haiku/trunk/src/libs/mapm/mapm_sin.c
   haiku/trunk/src/libs/mapm/mapmasin.c
   haiku/trunk/src/libs/mapm/mapmasn0.c
   haiku/trunk/src/libs/mapm/mapmcbrt.c
   haiku/trunk/src/libs/mapm/mapmcnst.c
   haiku/trunk/src/libs/mapm/mapmfact.c
   haiku/trunk/src/libs/mapm/mapmfmul.c
   haiku/trunk/src/libs/mapm/mapmgues.c
   haiku/trunk/src/libs/mapm/mapmhasn.c
   haiku/trunk/src/libs/mapm/mapmhsin.c
   haiku/trunk/src/libs/mapm/mapmipwr.c
   haiku/trunk/src/libs/mapm/mapmistr.c
   haiku/trunk/src/libs/mapm/mapmpwr2.c
   haiku/trunk/src/libs/mapm/mapmrsin.c
   haiku/trunk/src/libs/mapm/mapmsqrt.c
   haiku/trunk/src/libs/mapm/mapmstck.c
   haiku/trunk/src/libs/mapm/mapmutil.c
   haiku/trunk/src/libs/mapm/mapmutl1.c
   haiku/trunk/src/libs/mapm/mapmutl2.c
Removed:
   haiku/trunk/src/apps/deskcalc/ExpressionParser.cpp
   haiku/trunk/src/apps/deskcalc/ExpressionParser.h
   haiku/trunk/src/apps/deskcalc/mapm_4.9.5/
Modified:
   haiku/trunk/src/apps/deskcalc/CalcView.cpp
   haiku/trunk/src/apps/deskcalc/Jamfile
   haiku/trunk/src/kits/shared/Jamfile
   haiku/trunk/src/libs/Jamfile
Log:
* 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.


Copied: haiku/trunk/headers/libs/mapm/m_apm.h (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/m_apm.h)

Copied: haiku/trunk/headers/private/shared/ExpressionParser.h (from rev 31225, haiku/trunk/src/apps/deskcalc/ExpressionParser.h)
===================================================================
--- haiku/trunk/src/apps/deskcalc/ExpressionParser.h	2009-06-24 12:36:14 UTC (rev 31225)
+++ haiku/trunk/headers/private/shared/ExpressionParser.h	2009-06-28 17:10:40 UTC (rev 31298)
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2006-2009 Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *		Ingo Weinhold <bonefish at cs.tu-berlin.de>
+ *		Stephan Aßmus <superstippi at gmx.de>
+ */
+#ifndef EXPRESSION_PARSER_H
+#define EXPRESSION_PARSER_H
+
+
+#include <String.h>
+
+
+class Tokenizer;
+
+class ParseException {
+ public:
+	ParseException(const char* message, int32 position)
+		: message(message),
+		  position(position)
+	{
+	}
+
+	ParseException(const ParseException& other)
+		: message(other.message),
+		  position(other.position)
+	{
+	}
+
+	BString	message;
+	int32	position;
+};
+
+struct Function;
+struct Token;
+class MAPM;
+
+class ExpressionParser {
+ public:
+								ExpressionParser();
+								~ExpressionParser();
+
+			void				SetSupportHexInput(bool enabled);
+
+			BString				Evaluate(const char* expressionString);
+			int64				EvaluateToInt64(const char* expressionString);
+			double				EvaluateToDouble(const char* expressionString);
+
+ private:
+
+			MAPM				_ParseBinary();
+			MAPM				_ParseSum();
+			MAPM				_ParseProduct();
+			MAPM				_ParsePower();
+			MAPM				_ParseUnary();
+			void				_InitArguments(MAPM values[],
+									int32 argumentCount);
+			MAPM				_ParseFunction(const Token& token);
+			MAPM				_ParseAtom();
+
+			void				_EatToken(int32 type);
+
+			Tokenizer*			fTokenizer;
+};
+
+#endif // EXPRESSION_PARSER_H

Modified: haiku/trunk/src/apps/deskcalc/CalcView.cpp
===================================================================
--- haiku/trunk/src/apps/deskcalc/CalcView.cpp	2009-06-28 16:38:32 UTC (rev 31297)
+++ haiku/trunk/src/apps/deskcalc/CalcView.cpp	2009-06-28 17:10:40 UTC (rev 31298)
@@ -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"
 
 

Deleted: haiku/trunk/src/apps/deskcalc/ExpressionParser.cpp

Deleted: haiku/trunk/src/apps/deskcalc/ExpressionParser.h

Modified: haiku/trunk/src/apps/deskcalc/Jamfile
===================================================================
--- haiku/trunk/src/apps/deskcalc/Jamfile	2009-06-28 16:38:32 UTC (rev 31297)
+++ haiku/trunk/src/apps/deskcalc/Jamfile	2009-06-28 17:10:40 UTC (rev 31298)
@@ -2,7 +2,7 @@
 
 SetSubDirSupportedPlatformsBeOSCompatible ;
 
-SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src apps deskcalc mapm_4.9.5 ] ;
+UsePrivateHeaders shared ;
 
 Application DeskCalc :
 	CalcApplication.cpp
@@ -10,51 +10,8 @@
 	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
-	;
-
+;

Copied: haiku/trunk/src/kits/shared/ExpressionParser.cpp (from rev 31225, haiku/trunk/src/apps/deskcalc/ExpressionParser.cpp)
===================================================================
--- haiku/trunk/src/apps/deskcalc/ExpressionParser.cpp	2009-06-24 12:36:14 UTC (rev 31225)
+++ haiku/trunk/src/kits/shared/ExpressionParser.cpp	2009-06-28 17:10:40 UTC (rev 31298)
@@ -0,0 +1,641 @@
+/*
+ * Copyright 2006-2009 Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *		Ingo Weinhold <bonefish at cs.tu-berlin.de>
+ *		Stephan Aßmus <superstippi at gmx.de>
+ */
+
+#include <ExpressionParser.h>
+
+#include <ctype.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <m_apm.h>
+
+
+static const int32 kMaxDigits = 64;
+
+enum {
+	TOKEN_IDENTIFIER			= 0,
+
+	TOKEN_CONSTANT,
+
+	TOKEN_PLUS,
+	TOKEN_MINUS,
+
+	TOKEN_STAR,
+	TOKEN_SLASH,
+	TOKEN_MODULO,
+
+	TOKEN_POWER,
+
+	TOKEN_OPENING_BRACKET,
+	TOKEN_CLOSING_BRACKET,
+
+	TOKEN_AND,
+	TOKEN_OR,
+	TOKEN_NOT,
+
+	TOKEN_NONE,
+	TOKEN_END_OF_LINE
+};
+
+struct Token {
+	Token()
+		: string(""),
+		  type(TOKEN_NONE),
+		  value(0),
+		  position(0)
+	{
+	}
+
+	Token(const Token& other)
+		: string(other.string),
+		  type(other.type),
+		  value(other.value),
+		  position(other.position)
+	{
+	}
+
+	Token(const char* string, int32 length, int32 position, int32 type)
+		: string(string, length),
+		  type(type),
+		  value(0),
+		  position(position)
+	{
+	}
+
+	Token& operator=(const Token& other)
+	{
+		string = other.string;
+		type = other.type;
+		value = other.value;
+		position = other.position;
+		return *this;
+	}
+
+	BString		string;
+	int32		type;
+	MAPM		value;
+
+	int32		position;
+};
+
+
+class Tokenizer {
+ public:
+	Tokenizer()
+		: fString(""),
+		  fCurrentChar(NULL),
+		  fCurrentToken(),
+		  fReuseToken(false),
+		  fHexSupport(false)
+	{
+	}
+
+	void SetSupportHexInput(bool enabled)
+	{
+		fHexSupport = enabled;
+	}
+
+	void SetTo(const char* string)
+	{
+		fString = string;
+		fCurrentChar = fString.String();
+		fCurrentToken = Token();
+		fReuseToken = false;
+	}
+
+	const Token& NextToken()
+	{
+		if (fCurrentToken.type == TOKEN_END_OF_LINE)
+			return fCurrentToken;
+
+		if (fReuseToken) {
+			fReuseToken = false;
+//printf("next token (recycled): '%s'\n", fCurrentToken.string.String());
+			return fCurrentToken;
+		}
+
+		while (*fCurrentChar != 0 && isspace(*fCurrentChar))
+			fCurrentChar++;
+
+		if (*fCurrentChar == 0)
+			return fCurrentToken = Token("", 0, _CurrentPos(), TOKEN_END_OF_LINE);
+
+		bool decimal = *fCurrentChar == '.' || *fCurrentChar == ',';
+
+		if (decimal || isdigit(*fCurrentChar)) {
+			if (fHexSupport && *fCurrentChar == '0' && fCurrentChar[1] == 'x')
+				return _ParseHexNumber();
+
+			BString temp;
+
+			const char* begin = fCurrentChar;
+			while (*fCurrentChar != 0) {
+				if (!isdigit(*fCurrentChar)) {
+					if (!(*fCurrentChar == '.' || *fCurrentChar == ','
+						|| *fCurrentChar == 'e' || *fCurrentChar == 'E'))
+						break;
+				}
+				if (*fCurrentChar == ',')
+					temp << '.';
+				else
+					temp << *fCurrentChar;
+				fCurrentChar++;
+			}
+			int32 length = fCurrentChar - begin;
+			BString test = temp;
+			test << "&_";
+			double value;
+			char t[2];
+			int32 matches = sscanf(test.String(), "%lf&%s", &value, t);
+			if (matches != 2) {
+				throw ParseException("error in constant",
+					_CurrentPos() - length);
+			}
+
+			fCurrentToken = Token(begin, length, _CurrentPos() - length,
+				TOKEN_CONSTANT);
+			fCurrentToken.value = temp.String();
+
+		} else if (isalpha(*fCurrentChar) && *fCurrentChar != 'x') {
+			const char* begin = fCurrentChar;
+			while (*fCurrentChar != 0 && (isalpha(*fCurrentChar)
+				|| isdigit(*fCurrentChar))) {
+				fCurrentChar++;
+			}
+			int32 length = fCurrentChar - begin;
+			fCurrentToken = Token(begin, length, _CurrentPos() - length,
+				TOKEN_IDENTIFIER);
+
+		} else {
+			int32 type = TOKEN_NONE;
+
+			switch (*fCurrentChar) {
+				case '+':
+					type = TOKEN_PLUS;
+					break;
+				case '-':
+					type = TOKEN_MINUS;
+					break;
+				case '*':
+					type = TOKEN_STAR;
+					break;
+				case '/':
+				case '\\':
+				case ':':
+					type = TOKEN_SLASH;
+					break;
+
+				case '%':
+					type = TOKEN_MODULO;
+					break;
+				case '^':
+					type = TOKEN_POWER;
+					break;
+
+				case '(':
+					type = TOKEN_OPENING_BRACKET;
+					break;
+				case ')':
+					type = TOKEN_CLOSING_BRACKET;
+					break;
+
+				case '&':
+					type = TOKEN_AND;
+					break;
+				case '|':
+					type = TOKEN_OR;
+					break;
+				case '~':
+					type = TOKEN_NOT;
+					break;
+
+				case '\n':
+					type = TOKEN_END_OF_LINE;
+					break;
+
+				case 'x':
+					if (!fHexSupport) {
+						type = TOKEN_STAR;
+						break;
+					}
+					// fall through
+
+				default:
+					throw ParseException("unexpected character", _CurrentPos());
+			}
+			fCurrentToken = Token(fCurrentChar, 1, _CurrentPos(), type);
+			fCurrentChar++;
+		}
+
+//printf("next token: '%s'\n", fCurrentToken.string.String());
+		return fCurrentToken;
+	}
+
+	void RewindToken()
+	{
+		fReuseToken = true;
+	}
+
+ 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();
+	}
+
+	BString		fString;
+	const char*	fCurrentChar;
+	Token		fCurrentToken;
+	bool		fReuseToken;
+	bool		fHexSupport;
+};
+
+
+ExpressionParser::ExpressionParser()
+	: fTokenizer(new Tokenizer())
+{
+}
+
+
+ExpressionParser::~ExpressionParser()
+{
+	delete fTokenizer;
+}
+
+
+void
+ExpressionParser::SetSupportHexInput(bool enabled)
+{
+	fTokenizer->SetSupportHexInput(enabled);
+}
+
+
+BString
+ExpressionParser::Evaluate(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);
+
+	if (value == 0)
+		return BString("0");
+
+	BString result;
+	char* buffer = result.LockBuffer(kMaxDigits + 1);
+		// + 1 for the decimal point
+	if (buffer == NULL)
+		throw ParseException("out of memory", 0);
+
+	value.toFixPtString(buffer, kMaxDigits);
+
+	// remove surplus zeros
+	int32 lastChar = strlen(buffer) - 1;
+	if (strchr(buffer, '.')) {
+		while (buffer[lastChar] == '0')
+			lastChar--;
+		if (buffer[lastChar] == '.')
+			lastChar--;
+	}
+	result.UnlockBuffer(lastChar + 1);
+
+	return result;
+}
+
+
+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()
+{
+	return _ParseSum();
+	// binary operation appearantly not supported by m_apm library,
+	// should not be too hard to implement though....
+
+//	double value = _ParseSum();
+//
+//	while (true) {
+//		Token token = fTokenizer->NextToken();
+//		switch (token.type) {
+//			case TOKEN_AND:
+//				value = (uint64)value & (uint64)_ParseSum();
+//				break;
+//			case TOKEN_OR:
+//				value = (uint64)value | (uint64)_ParseSum();
+//				break;
+//
+//			default:
+//				fTokenizer->RewindToken();
+//				return value;
+//		}
+//	}
+}
+
+
+MAPM
+ExpressionParser::_ParseSum()
+{
+	// TODO: check isnan()...
+	MAPM value = _ParseProduct();
+
+	while (true) {
+		Token token = fTokenizer->NextToken();
+		switch (token.type) {
+			case TOKEN_PLUS:
+				value = value + _ParseProduct();
+				break;
+			case TOKEN_MINUS:
+				value = value - _ParseProduct();
+				break;
+
+			default:
+				fTokenizer->RewindToken();
+				return value;
+		}
+	}
+}
+
+
+MAPM
+ExpressionParser::_ParseProduct()
+{
+	// TODO: check isnan()...
+	MAPM value = _ParsePower();
+
+	while (true) {
+		Token token = fTokenizer->NextToken();
+		switch (token.type) {
+			case TOKEN_STAR:
+				value = value * _ParsePower();
+				break;
+			case TOKEN_SLASH: {
+				MAPM rhs = _ParsePower();
+				if (rhs == MAPM(0))
+					throw ParseException("division by zero", token.position);
+				value = value / rhs;
+				break;
+			}
+			case TOKEN_MODULO: {
+				MAPM rhs = _ParsePower();
+				if (rhs == MAPM(0))
+					throw ParseException("modulo by zero", token.position);
+				value = value % rhs;
+				break;
+			}
+
+			default:
+				fTokenizer->RewindToken();
+				return value;
+		}
+	}
+}
+
+
+MAPM
+ExpressionParser::_ParsePower()
+{
+	MAPM value = _ParseUnary();
+
+	while (true) {
+		Token token = fTokenizer->NextToken();
+		if (token.type != TOKEN_POWER) {
+			fTokenizer->RewindToken();
+			return value;
+		}
+		value = value.pow(_ParseUnary());
+	}
+}
+
+
+MAPM
+ExpressionParser::_ParseUnary()
+{
+	Token token = fTokenizer->NextToken();
+	if (token.type == TOKEN_END_OF_LINE)
+		throw ParseException("unexpected end of expression", token.position);
+
+	switch (token.type) {
+		case TOKEN_PLUS:
+			return _ParseUnary();
+		case TOKEN_MINUS:
+			return -_ParseUnary();
+// TODO: Implement !
+//		case TOKEN_NOT:
+//			return ~(uint64)_ParseUnary();
+
+		case TOKEN_IDENTIFIER:
+			return _ParseFunction(token);
+
+		default:
+			fTokenizer->RewindToken();
+			return _ParseAtom();
+	}
+
+	return MAPM(0);
+}
+
+
+struct Function {
+	const char*	name;
+	int			argumentCount;
+	void*		function;
+	MAPM		value;
+};
+
+
+void
+ExpressionParser::_InitArguments(MAPM values[], int32 argumentCount)
+{
+	_EatToken(TOKEN_OPENING_BRACKET);
+
+	for (int32 i = 0; i < argumentCount; i++)
+		values[i] = _ParseBinary();
+
+	_EatToken(TOKEN_CLOSING_BRACKET);
+}
+
+
+MAPM
+ExpressionParser::_ParseFunction(const Token& token)
+{
+	if (strcasecmp("e", token.string.String()) == 0)
+		return MAPM(M_E);
+	else if (strcasecmp("pi", token.string.String()) == 0)
+		return MAPM(M_PI);
+
+	// hard coded cases for different count of arguments
+	// supports functions with 3 arguments at most
+
+	MAPM values[3];
+
+	if (strcasecmp("abs", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].abs();
+	} else if (strcasecmp("acos", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].acos();
+	} else if (strcasecmp("asin", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].asin();
+	} else if (strcasecmp("atan", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].atan();
+	} else if (strcasecmp("atan2", token.string.String()) == 0) {
+		_InitArguments(values, 2);
+		return values[0].atan2(values[1]);
+	} else if (strcasecmp("ceil", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].ceil();
+	} else if (strcasecmp("cos", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].cos();
+	} else if (strcasecmp("cosh", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].cosh();
+	} else if (strcasecmp("exp", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].exp();
+	} else if (strcasecmp("floor", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].floor();
+	} else if (strcasecmp("log", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].log();
+	} else if (strcasecmp("log10", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].log10();
+	} else if (strcasecmp("pow", token.string.String()) == 0) {
+		_InitArguments(values, 2);
+		return values[0].pow(values[1]);
+	} else if (strcasecmp("sin", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].sin();
+	} else if (strcasecmp("sinh", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].sinh();
+	} else if (strcasecmp("sqrt", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].sqrt();
+	} else if (strcasecmp("tan", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].tan();
+	} else if (strcasecmp("tanh", token.string.String()) == 0) {
+		_InitArguments(values, 1);
+		return values[0].tanh();
+	}
+
+	throw ParseException("unknown identifier", token.position);
+}
+
+
+MAPM
+ExpressionParser::_ParseAtom()
+{
+	Token token = fTokenizer->NextToken();
+	if (token.type == TOKEN_END_OF_LINE)
+		throw ParseException("unexpected end of expression", token.position);
+
+	if (token.type == TOKEN_CONSTANT)
+		return token.value;
+
+	fTokenizer->RewindToken();
+
+	_EatToken(TOKEN_OPENING_BRACKET);
+
+	MAPM value = _ParseBinary();
+
+	_EatToken(TOKEN_CLOSING_BRACKET);
+
+	return value;
+}
+
+
+void
+ExpressionParser::_EatToken(int32 type)
+{
+	Token token = fTokenizer->NextToken();
+	if (token.type != type) {
+		BString temp("expected '");
+		temp << (char)type << "' got '" << token.string << "'";
+		throw ParseException(temp.String(), token.position);
+	}
+}
+

Modified: haiku/trunk/src/kits/shared/Jamfile
===================================================================
--- haiku/trunk/src/kits/shared/Jamfile	2009-06-28 16:38:32 UTC (rev 31297)
+++ haiku/trunk/src/kits/shared/Jamfile	2009-06-28 17:10:40 UTC (rev 31298)
@@ -22,3 +22,10 @@
 	RWLockManager.cpp
 	Variant.cpp
 ;
+
+
+UseLibraryHeaders mapm ;
+
+StaticLibrary libexpression_parser.a :
+	ExpressionParser.cpp
+;

Modified: haiku/trunk/src/libs/Jamfile
===================================================================
--- haiku/trunk/src/libs/Jamfile	2009-06-28 16:38:32 UTC (rev 31297)
+++ haiku/trunk/src/libs/Jamfile	2009-06-28 17:10:40 UTC (rev 31298)
@@ -14,6 +14,7 @@
 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 ;

Copied: haiku/trunk/src/libs/mapm/README (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/README)

Copied: haiku/trunk/src/libs/mapm/m_apm_lc.h (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/m_apm_lc.h)

Copied: haiku/trunk/src/libs/mapm/mapm5sin.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm5sin.c)

Copied: haiku/trunk/src/libs/mapm/mapm_add.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_add.c)

Copied: haiku/trunk/src/libs/mapm/mapm_cpi.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_cpi.c)

Copied: haiku/trunk/src/libs/mapm/mapm_div.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_div.c)

Copied: haiku/trunk/src/libs/mapm/mapm_exp.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_exp.c)

Copied: haiku/trunk/src/libs/mapm/mapm_fam.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_fam.c)

Copied: haiku/trunk/src/libs/mapm/mapm_fft.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_fft.c)

Copied: haiku/trunk/src/libs/mapm/mapm_flr.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_flr.c)

Copied: haiku/trunk/src/libs/mapm/mapm_fpf.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_fpf.c)

Copied: haiku/trunk/src/libs/mapm/mapm_gcd.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_gcd.c)

Copied: haiku/trunk/src/libs/mapm/mapm_lg2.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_lg2.c)

Copied: haiku/trunk/src/libs/mapm/mapm_lg3.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_lg3.c)

Copied: haiku/trunk/src/libs/mapm/mapm_lg4.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_lg4.c)

Copied: haiku/trunk/src/libs/mapm/mapm_log.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_log.c)

Copied: haiku/trunk/src/libs/mapm/mapm_mul.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_mul.c)

Copied: haiku/trunk/src/libs/mapm/mapm_pow.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_pow.c)

Copied: haiku/trunk/src/libs/mapm/mapm_rcp.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_rcp.c)

Copied: haiku/trunk/src/libs/mapm/mapm_rnd.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_rnd.c)

Copied: haiku/trunk/src/libs/mapm/mapm_set.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_set.c)

Copied: haiku/trunk/src/libs/mapm/mapm_sin.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapm_sin.c)

Copied: haiku/trunk/src/libs/mapm/mapmasin.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmasin.c)

Copied: haiku/trunk/src/libs/mapm/mapmasn0.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmasn0.c)

Copied: haiku/trunk/src/libs/mapm/mapmcbrt.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmcbrt.c)

Copied: haiku/trunk/src/libs/mapm/mapmcnst.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmcnst.c)

Copied: haiku/trunk/src/libs/mapm/mapmfact.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmfact.c)

Copied: haiku/trunk/src/libs/mapm/mapmfmul.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmfmul.c)

Copied: haiku/trunk/src/libs/mapm/mapmgues.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmgues.c)

Copied: haiku/trunk/src/libs/mapm/mapmhasn.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmhasn.c)

Copied: haiku/trunk/src/libs/mapm/mapmhsin.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmhsin.c)

Copied: haiku/trunk/src/libs/mapm/mapmipwr.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmipwr.c)

Copied: haiku/trunk/src/libs/mapm/mapmistr.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmistr.c)

Copied: haiku/trunk/src/libs/mapm/mapmpwr2.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmpwr2.c)

Copied: haiku/trunk/src/libs/mapm/mapmrsin.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmrsin.c)

Copied: haiku/trunk/src/libs/mapm/mapmsqrt.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmsqrt.c)

Copied: haiku/trunk/src/libs/mapm/mapmstck.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmstck.c)

Copied: haiku/trunk/src/libs/mapm/mapmutil.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmutil.c)

Copied: haiku/trunk/src/libs/mapm/mapmutl1.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmutl1.c)

Copied: haiku/trunk/src/libs/mapm/mapmutl2.c (from rev 31225, haiku/trunk/src/apps/deskcalc/mapm_4.9.5/mapmutl2.c)




More information about the Haiku-commits mailing list