added function calls to scene files
git-svn-id: svn://anubis/fart/trunk@361 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
parent
eca2335fb2
commit
654be9058d
@ -1,14 +1,53 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "nodes.h"
|
#include "nodes.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
typedef NodeRef (*Function)(NodeRef args);
|
||||||
|
|
||||||
|
NodeRef CosFunction(NodeRef args);
|
||||||
|
NodeRef SinFunction(NodeRef args);
|
||||||
|
NodeRef SqrtFunction(NodeRef args);
|
||||||
|
NodeRef AbsFunction(NodeRef args);
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char * fn_name;
|
||||||
|
Function fn;
|
||||||
|
} functions[] = {
|
||||||
|
{"cos", CosFunction},
|
||||||
|
{"sin", SinFunction},
|
||||||
|
{"sqrt", SqrtFunction},
|
||||||
|
{"abs", AbsFunction}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FunctionMap : public map<string, Function>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FunctionMap()
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0;
|
||||||
|
i < sizeof(functions)/sizeof(functions[0]);
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
(*this)[functions[i].fn_name] = functions[i].fn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool contains(const string & key)
|
||||||
|
{
|
||||||
|
return find(key) != end();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static FunctionMap function_map;
|
||||||
|
|
||||||
void Node::evaluateChildren(refptr<Node> parent)
|
void Node::evaluateChildren(refptr<Node> parent)
|
||||||
{
|
{
|
||||||
/* recursively evaluate all children nodes */
|
/* recursively evaluate all children nodes */
|
||||||
@ -169,3 +208,59 @@ NodeRef ElseNode::evaluate()
|
|||||||
evaluateChildren(eval);
|
evaluateChildren(eval);
|
||||||
return eval;
|
return eval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeRef FunctionCallNode::evaluate()
|
||||||
|
{
|
||||||
|
if (function_map.contains(m_name->getString()))
|
||||||
|
{
|
||||||
|
return function_map[m_name->getString()](m_parameters);
|
||||||
|
}
|
||||||
|
cerr << "Error: no function \"" << m_name->getString() << "\" defined!"
|
||||||
|
<< endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Scene file functions *
|
||||||
|
*************************************************************************/
|
||||||
|
NodeRef CosFunction(NodeRef args)
|
||||||
|
{
|
||||||
|
if (args->getChildren().size() != 1)
|
||||||
|
{
|
||||||
|
cerr << "Error: cos function requires 1 argument" << endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
return new NumberNode(cos(args->getChildren()[0]->evaluate()->getNumber()));
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef SinFunction(NodeRef args)
|
||||||
|
{
|
||||||
|
if (args->getChildren().size() != 1)
|
||||||
|
{
|
||||||
|
cerr << "Error: sin function requires 1 argument" << endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
return new NumberNode(sin(args->getChildren()[0]->evaluate()->getNumber()));
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef SqrtFunction(NodeRef args)
|
||||||
|
{
|
||||||
|
if (args->getChildren().size() != 1)
|
||||||
|
{
|
||||||
|
cerr << "Error: sqrt function requires 1 argument" << endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
return new NumberNode(sqrt(args->getChildren()[0]->evaluate()->getNumber()));
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef AbsFunction(NodeRef args)
|
||||||
|
{
|
||||||
|
if (args->getChildren().size() != 1)
|
||||||
|
{
|
||||||
|
cerr << "Error: abs function requires 1 argument" << endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
return new NumberNode(fabs(args->getChildren()[0]->evaluate()->getNumber()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -750,6 +750,19 @@ class ElseNode : public Node
|
|||||||
virtual NodeRef evaluate();
|
virtual NodeRef evaluate();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FunctionCallNode : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FunctionCallNode(NodeRef name, NodeRef parameters)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
m_parameters = parameters;
|
||||||
|
}
|
||||||
|
virtual NodeRef evaluate();
|
||||||
|
protected:
|
||||||
|
NodeRef m_name, m_parameters;
|
||||||
|
};
|
||||||
|
|
||||||
/* this class is only used to hold a set of items coming out of a class's
|
/* this class is only used to hold a set of items coming out of a class's
|
||||||
* evaluate() from above. the evaluateChildren() top-level method will
|
* evaluate() from above. the evaluateChildren() top-level method will
|
||||||
* propagate children of this class up to the level of their parent */
|
* propagate children of this class up to the level of their parent */
|
||||||
|
@ -358,6 +358,7 @@ expression: term { $$ = $1; }
|
|||||||
$$ = new BinOpNode('-', new NumberNode(0.0), $2);
|
$$ = new BinOpNode('-', new NumberNode(0.0), $2);
|
||||||
}
|
}
|
||||||
| stmt_expression { $$ = $1; }
|
| stmt_expression { $$ = $1; }
|
||||||
|
| function_call { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
maybe_expression: /* empty */
|
maybe_expression: /* empty */
|
||||||
@ -439,6 +440,28 @@ if_more: /* empty */
|
|||||||
$$->addChildren($3);
|
$$->addChildren($3);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
function_call: IDENTIFIER LPAREN function_call_parameters RPAREN {
|
||||||
|
$$ = new FunctionCallNode($1, $3);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
function_call_parameters: /* empty */
|
||||||
|
| expression function_call_more_parameters {
|
||||||
|
$$ = new ItemsNode();
|
||||||
|
$$->addChild($1);
|
||||||
|
$$->addChildren($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
function_call_more_parameters: /* empty */
|
||||||
|
| COMMA expression function_call_more_parameters {
|
||||||
|
$$ = new ItemsNode();
|
||||||
|
$$->addChild($2);
|
||||||
|
$$->addChildren($3);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
refptr<Node> parse(const char * fileName, refptr<Scope> scope)
|
refptr<Node> parse(const char * fileName, refptr<Scope> scope)
|
||||||
|
@ -44,7 +44,11 @@ scene
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
material mat3
|
material
|
||||||
|
{
|
||||||
|
color <1, 0, 0>
|
||||||
|
transparency abs($x / 120)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$m := $m + 1
|
$m := $m + 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user