summaryrefslogtreecommitdiff
path: root/src/scriptengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/scriptengine.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/scriptengine.cpp b/src/scriptengine.cpp
new file mode 100644
index 0000000..7b5df03
--- /dev/null
+++ b/src/scriptengine.cpp
@@ -0,0 +1,82 @@
1#include "scriptengine.h"
2#include "lexer.h"
3#include "parser.h"
4#include "expression.h"
5
6#include <bu/staticmembuf.h>
7#include <bu/exceptionbase.h>
8
9ScriptEngine::ScriptEngine()
10{
11}
12
13ScriptEngine::~ScriptEngine()
14{
15}
16
17Number ScriptEngine::exec( const Bu::String &sExpr )
18{
19 Bu::StaticMemBuf mb( sExpr.getStr(), sExpr.getSize() );
20 return exec( sExpr );
21}
22
23Number ScriptEngine::exec( Bu::Stream &sInput )
24{
25 Lexer l( sInput );
26 Parser p( l );
27 Expression *pExp = p.parse();
28 Number n = exec( pExp );
29 delete pExp;
30 return n;
31}
32
33Number ScriptEngine::exec( Expression *pExpr )
34{
35 NumStack sNums;
36
37 for( Expression::iterator i = pExpr->begin(); i; i++ )
38 {
39 switch( (*i).eType )
40 {
41 case Token::tNumber:
42 sNums.push( *(*i).nVal );
43 break;
44
45 case Token::tVariable:
46 if( hVarState.has( *(*i).sVal ) )
47 {
48 sNums.push( hVarState[*(*i).sVal] );
49 }
50 else
51 {
52 throw Bu::ExceptionBase(
53 Bu::String("No such variable: $%1").arg(*(*i).sVal).end().getStr()
54 );
55 }
56 break;
57
58 case Token::tPlus:
59 sNums.push( sNums.peekPop() + sNums.peekPop() );
60 break;
61
62 case Token::tMinus:
63 sNums.push( sNums.peekPop() - sNums.peekPop() );
64 break;
65
66 case Token::tDivide:
67 sNums.push( sNums.peekPop() / sNums.peekPop() );
68 break;
69
70 case Token::tMultiply:
71 sNums.push( sNums.peekPop() * sNums.peekPop() );
72 break;
73
74 case Token::tNegate:
75 sNums.push( -sNums.peekPop() );
76 break;
77 }
78 }
79
80 return sNums.peekPop();
81}
82