move sources to src directory
This commit is contained in:
1 parent
b5e4655f03
commit
24b4b48555
58 files changed
+7
-5
No files matched your search
@@ -0,0 +1,283 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <map>
|
||||
|
||||
#include "nodes.h"
|
||||
|
||||
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)
|
||||
{
|
||||
/* recursively evaluate all children nodes */
|
||||
for (std::vector< refptr<Node> >::iterator it = m_children.begin();
|
||||
it != m_children.end();
|
||||
it++)
|
||||
{
|
||||
refptr<Node> evaluated = (*it)->evaluate();
|
||||
if ( ! evaluated.isNull() )
|
||||
{
|
||||
if (typeid(*evaluated) == typeid(EvaluatePropagateNode))
|
||||
{
|
||||
for (vector<NodeRef>::iterator it2
|
||||
= evaluated->getChildren().begin();
|
||||
it2 != evaluated->getChildren().end();
|
||||
it2++)
|
||||
{
|
||||
parent->addChild(*it2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*it)->evaluateChildren(evaluated);
|
||||
parent->addChild(evaluated);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::addChildren(NodeRef other)
|
||||
{
|
||||
if (other.isNull())
|
||||
return;
|
||||
|
||||
for (vector<NodeRef>::const_iterator it = other->m_children.begin();
|
||||
it != other->m_children.end();
|
||||
it++)
|
||||
{
|
||||
addChild(*it);
|
||||
}
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
}
|
||||
|
||||
NodeRef BinOpNode::evaluate()
|
||||
{
|
||||
double o = one->evaluate()->getNumber();
|
||||
double t = two->evaluate()->getNumber();
|
||||
double r = 0.0;
|
||||
switch (m_op)
|
||||
{
|
||||
case '*':
|
||||
r = o * t;
|
||||
break;
|
||||
case '/':
|
||||
r = o / t;
|
||||
break;
|
||||
case '+':
|
||||
r = o + t;
|
||||
break;
|
||||
case '-':
|
||||
r = o - t;
|
||||
break;
|
||||
case '%':
|
||||
r = (int) o % (int) t;
|
||||
break;
|
||||
case '^':
|
||||
r = pow(o, t);
|
||||
break;
|
||||
default:
|
||||
cerr << "Error: BinOpNode created with op '" << m_op << "'" << endl;
|
||||
exit(-3);
|
||||
}
|
||||
return new NumberNode(r);
|
||||
}
|
||||
|
||||
NodeRef BoolExpressionNode::evaluate()
|
||||
{
|
||||
double o = 0, t = 0;
|
||||
double r = 0;
|
||||
if (m_op != '!' && m_op != '&' && m_op != '|')
|
||||
{
|
||||
o = one->evaluate()->getNumber();
|
||||
t = two->evaluate()->getNumber();
|
||||
}
|
||||
switch (m_op)
|
||||
{
|
||||
case '<':
|
||||
r = o < t ? 1 : 0;
|
||||
break;
|
||||
case 'l':
|
||||
r = o <= t ? 1 : 0;
|
||||
break;
|
||||
case '>':
|
||||
r = o > t ? 1 : 0;
|
||||
break;
|
||||
case 'g':
|
||||
r = o >= t ? 1 : 0;
|
||||
break;
|
||||
case '=':
|
||||
r = o == t ? 1 : 0;
|
||||
break;
|
||||
case 'n':
|
||||
r = o != t ? 1 : 0;
|
||||
break;
|
||||
case '&':
|
||||
r = one->evaluate()->getInteger();
|
||||
if (r != 0)
|
||||
{
|
||||
r = two->evaluate()->getInteger();
|
||||
}
|
||||
break;
|
||||
case '|':
|
||||
r = one->evaluate()->getInteger();
|
||||
if (r == 0)
|
||||
{
|
||||
r = two->evaluate()->getInteger();
|
||||
}
|
||||
break;
|
||||
case '!':
|
||||
r = ! one->evaluate()->getInteger();
|
||||
break;
|
||||
case 'T':
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
return new NumberNode(r);
|
||||
}
|
||||
|
||||
NodeRef ForNode::evaluate()
|
||||
{
|
||||
NodeRef eval = new EvaluatePropagateNode();
|
||||
|
||||
if (!m_nodes[0].isNull())
|
||||
{
|
||||
m_nodes[0]->evaluate();
|
||||
}
|
||||
|
||||
while (m_nodes[1]->evaluate()->getInteger() != 0)
|
||||
{
|
||||
evaluateChildren(eval);
|
||||
|
||||
if (!m_nodes[2].isNull())
|
||||
{
|
||||
m_nodes[2]->evaluate();
|
||||
}
|
||||
}
|
||||
|
||||
return eval;
|
||||
}
|
||||
|
||||
NodeRef IfNode::evaluate()
|
||||
{
|
||||
NodeRef eval = new EvaluatePropagateNode();
|
||||
|
||||
int if_val = m_test_expr->evaluate()->getInteger();
|
||||
|
||||
if (if_val != 0)
|
||||
{
|
||||
evaluateChildren(eval);
|
||||
}
|
||||
else if ( ! m_elses.isNull() )
|
||||
{
|
||||
return m_elses->evaluate();
|
||||
}
|
||||
|
||||
return eval;
|
||||
}
|
||||
|
||||
NodeRef ElseNode::evaluate()
|
||||
{
|
||||
NodeRef eval = new EvaluatePropagateNode();
|
||||
evaluateChildren(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()));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,791 @@
|
||||
|
||||
#ifndef NODES_H
|
||||
#define NODES_H NODES_H
|
||||
|
||||
#include <stdlib.h> /* exit() */
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "util/refptr.h"
|
||||
#include "util/Vector.h"
|
||||
#include "util/Scope.h"
|
||||
|
||||
extern refptr<Scope> parser_scope;
|
||||
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
virtual ~Node();
|
||||
void addChild(refptr<Node> child) { m_children.push_back(child); }
|
||||
void addChildren(refptr<Node> other);
|
||||
std::vector< refptr<Node> > & getChildren() { return m_children; }
|
||||
|
||||
virtual int getInteger() { return getNumber(); }
|
||||
|
||||
virtual double getNumber()
|
||||
{
|
||||
std::cerr << "Warning: Node::getNumber() called!" << std::endl;
|
||||
return 0.0;
|
||||
}
|
||||
virtual refptr<Vector> getVector()
|
||||
{
|
||||
std::cerr << "Warning: Node::getVector() called!" << std::endl;
|
||||
return refptr<Vector>(NULL);
|
||||
}
|
||||
virtual std::string getString()
|
||||
{
|
||||
std::cerr << "Warning: Node::getString() called!" << std::endl;
|
||||
return "";
|
||||
}
|
||||
virtual refptr<Node> evaluate()
|
||||
{
|
||||
std::cerr << "Warning: Node::evaluate() called!" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
virtual void evaluateChildren(refptr<Node> parent);
|
||||
|
||||
virtual bool isShape() { return false; }
|
||||
virtual bool isMaterial() { return false; }
|
||||
virtual bool isTransformBlock() { return false; }
|
||||
virtual bool isExpression() { return false; }
|
||||
|
||||
protected:
|
||||
std::vector< refptr<Node> > m_children;
|
||||
};
|
||||
|
||||
typedef refptr<Node> NodeRef;
|
||||
|
||||
|
||||
class NumberNode : public Node
|
||||
{
|
||||
public:
|
||||
NumberNode(double number)
|
||||
: m_number(number), m_direct(true)
|
||||
{
|
||||
}
|
||||
NumberNode(NodeRef expr)
|
||||
: m_direct(false)
|
||||
{
|
||||
m_expr = expr;
|
||||
}
|
||||
virtual double getNumber()
|
||||
{
|
||||
return m_direct ? m_number : m_expr->getNumber();
|
||||
}
|
||||
virtual refptr<Node> evaluate()
|
||||
{
|
||||
return m_direct
|
||||
? new NumberNode(m_number)
|
||||
: new NumberNode(m_expr->evaluate());
|
||||
}
|
||||
|
||||
protected:
|
||||
double m_number;
|
||||
bool m_direct;
|
||||
NodeRef m_expr;
|
||||
};
|
||||
|
||||
class VectorNode : public Node
|
||||
{
|
||||
public:
|
||||
VectorNode(NodeRef a, NodeRef b, NodeRef c)
|
||||
: m_a(a), m_b(b), m_c(c), m_direct(true)
|
||||
{
|
||||
}
|
||||
VectorNode(NodeRef node)
|
||||
: m_vector(node), m_direct(false)
|
||||
{
|
||||
}
|
||||
refptr<Vector> getVector()
|
||||
{
|
||||
return m_direct
|
||||
? new Vector(m_a->getNumber(),
|
||||
m_b->getNumber(),
|
||||
m_c->getNumber())
|
||||
: m_vector->getVector();
|
||||
}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return m_direct
|
||||
? new VectorNode(m_a->evaluate(),
|
||||
m_b->evaluate(),
|
||||
m_c->evaluate())
|
||||
: m_vector->evaluate();
|
||||
}
|
||||
protected:
|
||||
NodeRef m_a, m_b, m_c, m_vector;
|
||||
bool m_direct;
|
||||
};
|
||||
|
||||
|
||||
class AmbientNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
AmbientNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new AmbientNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class AmbientOcclusionNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
AmbientOcclusionNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new AmbientOcclusionNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class BoxNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isShape() { return true; }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new BoxNode();
|
||||
}
|
||||
};
|
||||
|
||||
class CameraNode : public Node
|
||||
{
|
||||
public:
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new CameraNode();
|
||||
}
|
||||
};
|
||||
|
||||
class ColorNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
ColorNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new ColorNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class CylNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isShape() { return true; }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new CylNode();
|
||||
}
|
||||
};
|
||||
|
||||
class DiffuseNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
DiffuseNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new DiffuseNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class ExposureNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
ExposureNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new ExposureNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class ExtrudeNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isShape() { return true; }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new ExtrudeNode();
|
||||
}
|
||||
};
|
||||
|
||||
class HeightNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
HeightNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new HeightNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class IdentifierNode : public Node
|
||||
{
|
||||
public:
|
||||
IdentifierNode(const std::string & str) { m_string = str; }
|
||||
std::string getString() { return m_string; }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new IdentifierNode(m_string);
|
||||
}
|
||||
protected:
|
||||
std::string m_string;
|
||||
};
|
||||
|
||||
class IntersectNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isShape() { return true; }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new IntersectNode();
|
||||
}
|
||||
};
|
||||
|
||||
class ItemsNode : public Node
|
||||
{
|
||||
public:
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new ItemsNode();
|
||||
}
|
||||
};
|
||||
|
||||
class JitterNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
JitterNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new JitterNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class LightNode : public Node
|
||||
{
|
||||
public:
|
||||
virtual NodeRef evaluate() { return new LightNode(); }
|
||||
};
|
||||
|
||||
class LookAtNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
LookAtNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new LookAtNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class MaterialNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isMaterial() { return true; }
|
||||
virtual NodeRef evaluate() { return new MaterialNode(); }
|
||||
};
|
||||
|
||||
class MaterialDefinitionNode : public IdentifierNode
|
||||
{
|
||||
public:
|
||||
MaterialDefinitionNode(const std::string & str) : IdentifierNode(str) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new MaterialDefinitionNode(m_string);
|
||||
}
|
||||
};
|
||||
|
||||
class MaterialRefNode : public IdentifierNode
|
||||
{
|
||||
public:
|
||||
MaterialRefNode(const std::string & str) : IdentifierNode(str) {}
|
||||
bool isMaterial() { return true; }
|
||||
virtual NodeRef evaluate() { return new MaterialRefNode(m_string); }
|
||||
};
|
||||
|
||||
class MaxDepthNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
MaxDepthNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new MaxDepthNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class MultisampleNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
MultisampleNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new MultisampleNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class NGonNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
NGonNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new NGonNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class OffsetNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
OffsetNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new OffsetNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class OptionsNode : public Node
|
||||
{
|
||||
public:
|
||||
virtual NodeRef evaluate() { return new OptionsNode(); }
|
||||
};
|
||||
|
||||
class PlaneNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isShape() { return true; }
|
||||
virtual NodeRef evaluate() { return new PlaneNode(); }
|
||||
};
|
||||
|
||||
class PlanePositionNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
PlanePositionNode(NodeRef vec_node, NodeRef dist)
|
||||
: VectorNode(vec_node)
|
||||
{
|
||||
m_dist = dist;
|
||||
}
|
||||
double getNumber() { return m_dist->getNumber(); }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new PlanePositionNode(m_vector->evaluate(),
|
||||
m_dist->evaluate());
|
||||
}
|
||||
|
||||
protected:
|
||||
NodeRef m_dist;
|
||||
};
|
||||
|
||||
class PolygonNode : public Node
|
||||
{
|
||||
public:
|
||||
virtual NodeRef evaluate() { return new PolygonNode(); }
|
||||
};
|
||||
|
||||
class PositionNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
PositionNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new PositionNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class RadiusNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
RadiusNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new RadiusNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class ReflectanceNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
ReflectanceNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new ReflectanceNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class RefractionNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
RefractionNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new RefractionNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class RotateNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
RotateNode(NodeRef angle, NodeRef vec_node)
|
||||
: VectorNode(vec_node)
|
||||
{
|
||||
m_angle = angle;
|
||||
}
|
||||
double getNumber() { return m_angle->getNumber(); }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new RotateNode(m_angle->evaluate(), m_vector->evaluate());
|
||||
}
|
||||
|
||||
protected:
|
||||
NodeRef m_angle;
|
||||
};
|
||||
|
||||
class RotateBlockNode : public RotateNode
|
||||
{
|
||||
public:
|
||||
RotateBlockNode(NodeRef angle, NodeRef vec_node)
|
||||
: RotateNode(angle, vec_node) {}
|
||||
bool isTransformBlock() { return true; }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new RotateBlockNode(m_angle->evaluate(), m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class ScaleNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
ScaleNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new ScaleNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class ScaleBlockNode : public ScaleNode
|
||||
{
|
||||
public:
|
||||
ScaleBlockNode(NodeRef vector) : ScaleNode(vector) {}
|
||||
bool isTransformBlock() { return true; }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new ScaleBlockNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class ScaleScalarNode : public Node
|
||||
{
|
||||
public:
|
||||
ScaleScalarNode(NodeRef expr)
|
||||
: m_expr(expr)
|
||||
{
|
||||
}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
NodeRef n = m_expr->evaluate();
|
||||
return new VectorNode(n, n, n);
|
||||
}
|
||||
protected:
|
||||
NodeRef m_expr;
|
||||
};
|
||||
|
||||
class SceneNode : public Node
|
||||
{
|
||||
public:
|
||||
virtual NodeRef evaluate() { return new SceneNode(); }
|
||||
};
|
||||
|
||||
class ShapeDefinitionNode : public IdentifierNode
|
||||
{
|
||||
public:
|
||||
ShapeDefinitionNode(const std::string & str) : IdentifierNode(str) {}
|
||||
virtual NodeRef evaluate() { return new ShapeDefinitionNode(m_string); }
|
||||
};
|
||||
|
||||
class ShapeRefNode : public IdentifierNode
|
||||
{
|
||||
public:
|
||||
ShapeRefNode(const std::string & str) : IdentifierNode(str) {}
|
||||
bool isShape() { return true; }
|
||||
virtual NodeRef evaluate() { return new ShapeRefNode(m_string); }
|
||||
};
|
||||
|
||||
class ShininessNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
ShininessNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new ShininessNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class SizeNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
SizeNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new SizeNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class SpecularNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
SpecularNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new SpecularNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class SphereNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isShape() { return true; }
|
||||
virtual NodeRef evaluate() { return new SphereNode(); }
|
||||
};
|
||||
|
||||
class SubtractNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isShape() { return true; }
|
||||
virtual NodeRef evaluate() { return new SubtractNode(); }
|
||||
};
|
||||
|
||||
class TextureNode : public IdentifierNode
|
||||
{
|
||||
public:
|
||||
TextureNode(const std::string & str) : IdentifierNode(str) {}
|
||||
virtual NodeRef evaluate() { return new TextureNode(m_string); }
|
||||
};
|
||||
|
||||
class TranslateNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
TranslateNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new TranslateNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class TranslateBlockNode : public TranslateNode
|
||||
{
|
||||
public:
|
||||
TranslateBlockNode(NodeRef vector) : TranslateNode(vector) {}
|
||||
bool isTransformBlock() { return true; }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new TranslateBlockNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class TransparencyNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
TransparencyNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new TransparencyNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class UnionNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isShape() { return true; }
|
||||
virtual NodeRef evaluate() { return new UnionNode(); }
|
||||
};
|
||||
|
||||
class UpNode : public VectorNode
|
||||
{
|
||||
public:
|
||||
UpNode(NodeRef vector) : VectorNode(vector) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new UpNode(m_vector->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class VFOVNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
VFOVNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new VFOVNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
class WidthNode : public NumberNode
|
||||
{
|
||||
public:
|
||||
WidthNode(NodeRef e) : NumberNode(e) {}
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
return new WidthNode(m_expr->evaluate());
|
||||
}
|
||||
};
|
||||
|
||||
/******** scripting nodes ********/
|
||||
|
||||
class ExpressionNode : public Node
|
||||
{
|
||||
public:
|
||||
bool isExpression() { return true; }
|
||||
virtual NodeRef evaluate() = 0;
|
||||
};
|
||||
|
||||
class AssignmentNode : public ExpressionNode
|
||||
{
|
||||
public:
|
||||
AssignmentNode(NodeRef varref, NodeRef expr)
|
||||
: m_varref(varref), m_expr(expr)
|
||||
{
|
||||
}
|
||||
std::string getString() { return m_varref->getString(); }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
double n = m_expr->evaluate()->getNumber();
|
||||
parser_scope->putGlobal(getString(), n);
|
||||
return new NumberNode(n);
|
||||
}
|
||||
protected:
|
||||
NodeRef m_varref;
|
||||
NodeRef m_expr;
|
||||
};
|
||||
|
||||
class LocalAssignmentNode : public ExpressionNode
|
||||
{
|
||||
public:
|
||||
LocalAssignmentNode(NodeRef varref, NodeRef expr)
|
||||
: m_varref(varref), m_expr(expr)
|
||||
{
|
||||
}
|
||||
std::string getString() { return m_varref->getString(); }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
double n = m_expr->evaluate()->getNumber();
|
||||
parser_scope->putLocal(getString(), n);
|
||||
return new NumberNode(n);
|
||||
}
|
||||
protected:
|
||||
NodeRef m_varref;
|
||||
NodeRef m_expr;
|
||||
};
|
||||
|
||||
class LocalDeclNode : public ExpressionNode
|
||||
{
|
||||
public:
|
||||
LocalDeclNode(NodeRef varref) : m_varref(varref) { }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
parser_scope->putLocal(m_varref->getString(), 0.0);
|
||||
return NULL;
|
||||
}
|
||||
protected:
|
||||
NodeRef m_varref;
|
||||
};
|
||||
|
||||
class BinOpNode : public ExpressionNode
|
||||
{
|
||||
public:
|
||||
BinOpNode(char op, NodeRef one, NodeRef two)
|
||||
: m_op(op), one(one), two(two)
|
||||
{
|
||||
}
|
||||
virtual NodeRef evaluate();
|
||||
protected:
|
||||
char m_op;
|
||||
NodeRef one;
|
||||
NodeRef two;
|
||||
};
|
||||
|
||||
class BoolExpressionNode : public Node
|
||||
{
|
||||
public:
|
||||
BoolExpressionNode(char op, NodeRef one, NodeRef two)
|
||||
: m_op(op), one(one), two(two)
|
||||
{
|
||||
}
|
||||
virtual NodeRef evaluate();
|
||||
protected:
|
||||
char m_op;
|
||||
NodeRef one;
|
||||
NodeRef two;
|
||||
};
|
||||
|
||||
class VarRefNode : public Node
|
||||
{
|
||||
public:
|
||||
VarRefNode(const std::string & str) { m_string = str; }
|
||||
std::string getString() { return m_string; }
|
||||
virtual NodeRef evaluate()
|
||||
{
|
||||
if (parser_scope->contains(m_string))
|
||||
{
|
||||
return new NumberNode(parser_scope->get(m_string));
|
||||
}
|
||||
std::cerr << "Error: No identifier '" << m_string << "' in scope"
|
||||
<< std::endl;
|
||||
exit(4);
|
||||
}
|
||||
protected:
|
||||
std::string m_string;
|
||||
};
|
||||
|
||||
class ForNode : public Node
|
||||
{
|
||||
public:
|
||||
ForNode(NodeRef e1, NodeRef e2, NodeRef e3)
|
||||
{
|
||||
m_nodes[0] = e1;
|
||||
m_nodes[1] = e2;
|
||||
m_nodes[2] = e3;
|
||||
}
|
||||
virtual NodeRef evaluate();
|
||||
protected:
|
||||
NodeRef m_nodes[3];
|
||||
};
|
||||
|
||||
class IfNode : public Node
|
||||
{
|
||||
public:
|
||||
IfNode(NodeRef test_expr, NodeRef elses)
|
||||
{
|
||||
m_test_expr = test_expr;
|
||||
m_elses = elses;
|
||||
}
|
||||
virtual NodeRef evaluate();
|
||||
protected:
|
||||
NodeRef m_test_expr, m_elses;
|
||||
};
|
||||
|
||||
class ElseNode : public Node
|
||||
{
|
||||
public:
|
||||
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
|
||||
* evaluate() from above. the evaluateChildren() top-level method will
|
||||
* propagate children of this class up to the level of their parent */
|
||||
class EvaluatePropagateNode : public Node
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H PARSER_H
|
||||
|
||||
#include "nodes.h"
|
||||
#include "util/refptr.h"
|
||||
#include "util/Scope.h"
|
||||
|
||||
#define YYSTYPE refptr<Node>
|
||||
|
||||
refptr<Node> parse(const char * fileName, refptr<Scope> scope);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,156 @@
|
||||
|
||||
%option nounput
|
||||
%option bison-locations
|
||||
|
||||
%{
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "nodes.h"
|
||||
#include "parser.h"
|
||||
#include "parser.hh"
|
||||
|
||||
#define YY_USER_ACTION yylloc->first_column += yyleng;
|
||||
|
||||
static std::string build_string;
|
||||
|
||||
%}
|
||||
|
||||
%x str
|
||||
|
||||
%%
|
||||
|
||||
\+ return PLUS;
|
||||
- return MINUS;
|
||||
\* return TIMES;
|
||||
\/ return DIVIDE;
|
||||
% return MOD;
|
||||
\^ return POW;
|
||||
= return ASSIGN;
|
||||
== return EQUALS;
|
||||
!= return NOTEQUALS;
|
||||
\< return LESS;
|
||||
\<= return LESSEQ;
|
||||
\> return GREATER;
|
||||
\>= return GREATEREQ;
|
||||
&& return AND;
|
||||
\|\| return OR;
|
||||
! return NOT;
|
||||
|
||||
; return SEMICOLON;
|
||||
: return COLON;
|
||||
\? return QUESTION;
|
||||
\$ return DOLLAR;
|
||||
\. return DOT;
|
||||
, return COMMA;
|
||||
|
||||
\{ return LCURLY;
|
||||
\} return RCURLY;
|
||||
\[ return LBRACKET;
|
||||
\] return RBRACKET;
|
||||
\( return LPAREN;
|
||||
\) return RPAREN;
|
||||
|
||||
[0-9]+ *yylval = new NumberNode(atof(yytext)); return REAL_NUMBER;
|
||||
[0-9]*\.[0-9]+ *yylval = new NumberNode(atof(yytext)); return REAL_NUMBER;
|
||||
|
||||
ambient return AMBIENT;
|
||||
ambient_occlusion return AMBIENT_OCCLUSION;
|
||||
box return BOX;
|
||||
camera return CAMERA;
|
||||
color return COLOR;
|
||||
cyl return CYL;
|
||||
define return DEFINE;
|
||||
diffuse return DIFFUSE;
|
||||
exposure return EXPOSURE;
|
||||
extrude return EXTRUDE;
|
||||
height return HEIGHT;
|
||||
intersect return INTERSECT;
|
||||
jitter return JITTER;
|
||||
light return LIGHT;
|
||||
look_at return LOOKAT;
|
||||
material return MATERIAL;
|
||||
max_depth return MAXDEPTH;
|
||||
multisample return MULTISAMPLE;
|
||||
ngon return NGON;
|
||||
offset return OFFSET;
|
||||
options return OPTIONS;
|
||||
plane return PLANE;
|
||||
polygon return POLYGON;
|
||||
position return POSITION;
|
||||
radius return RADIUS;
|
||||
reflectance return REFLECTANCE;
|
||||
refraction return REFRACTION;
|
||||
rotate return ROTATE;
|
||||
scale return SCALE;
|
||||
scene return SCENE;
|
||||
shape return SHAPE;
|
||||
shininess return SHININESS;
|
||||
size return SIZE;
|
||||
specular return SPECULAR;
|
||||
sphere return SPHERE;
|
||||
subtract return SUBTRACT;
|
||||
texture return TEXTURE;
|
||||
translate return TRANSLATE;
|
||||
transparency return TRANSPARENCY;
|
||||
union return UNION;
|
||||
up return UP;
|
||||
vfov return VFOV;
|
||||
width return WIDTH;
|
||||
|
||||
else return ELSE;
|
||||
elsif return ELSIF;
|
||||
for return FOR;
|
||||
if return IF;
|
||||
while return WHILE;
|
||||
local return LOCAL;
|
||||
|
||||
[a-zA-Z_][a-zA-Z_0-9]* {
|
||||
*yylval = new IdentifierNode(yytext);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
\$[a-zA-Z_][a-zA-Z_0-9]* {
|
||||
*yylval = new VarRefNode(yytext+1);
|
||||
return VARREF;
|
||||
}
|
||||
|
||||
#.*\n {
|
||||
yylloc->first_line++; yylloc->last_line++;
|
||||
yylloc->first_column = yylloc->last_column = 0;
|
||||
}
|
||||
\n {
|
||||
yylloc->first_line++; yylloc->last_line++;
|
||||
yylloc->first_column = yylloc->last_column = 0;
|
||||
}
|
||||
[ \t\v] /* ignore whitespace */
|
||||
|
||||
/* strings */
|
||||
\" build_string = ""; BEGIN(str);
|
||||
|
||||
<str>{
|
||||
|
||||
\" {
|
||||
/* end of the string literal */
|
||||
BEGIN(INITIAL);
|
||||
*yylval = new IdentifierNode(build_string);
|
||||
return STRING;
|
||||
}
|
||||
\\x[0-9A-Fa-f]{2} {
|
||||
/* hexadecimal escape code */
|
||||
unsigned int val;
|
||||
(void) sscanf(yytext + 2, "%x", &val);
|
||||
build_string += (char) val;
|
||||
}
|
||||
\\n build_string += '\n';
|
||||
\\t build_string += '\t';
|
||||
\\r build_string += '\r';
|
||||
\\b build_string += '\b';
|
||||
\\f build_string += '\f';
|
||||
\\(.|\n) build_string += yytext[1];
|
||||
[^\\\"]+ build_string += yytext;
|
||||
|
||||
}
|
||||
|
||||
. return yytext[0];
|
||||
|
||||
%%
|
||||
@@ -0,0 +1,510 @@
|
||||
|
||||
%{
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include "util/Vector.h"
|
||||
#include "util/refptr.h"
|
||||
#include "util/Scope.h"
|
||||
#include "nodes.h"
|
||||
#include "parser.h"
|
||||
#include "parser.hh" /* bison-generated header with YY[SL]TYPE */
|
||||
using namespace std;
|
||||
|
||||
#define yyerror(msg) errFunc(msg, &yylloc)
|
||||
|
||||
int yylex(YYSTYPE *, YYLTYPE *);
|
||||
|
||||
extern FILE * yyin;
|
||||
|
||||
void errFunc(const char * str, YYLTYPE * yyllocp);
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static refptr<Node> parsed_scene_node;
|
||||
refptr<Scope> parser_scope;
|
||||
|
||||
%}
|
||||
|
||||
%pure-parser
|
||||
%locations
|
||||
%error-verbose
|
||||
|
||||
%token PLUS;
|
||||
%token MINUS;
|
||||
%token TIMES;
|
||||
%token DIVIDE;
|
||||
%token MOD;
|
||||
%token POW;
|
||||
%token ASSIGN;
|
||||
%token EQUALS;
|
||||
%token NOTEQUALS;
|
||||
%token LESS;
|
||||
%token LESSEQ;
|
||||
%token GREATER;
|
||||
%token GREATEREQ;
|
||||
%token AND
|
||||
%token OR
|
||||
%token NOT;
|
||||
|
||||
%token SEMICOLON;
|
||||
%token COLON;
|
||||
%token QUESTION;
|
||||
%token DOLLAR;
|
||||
%token DOT;
|
||||
%token COMMA;
|
||||
|
||||
%token LCURLY;
|
||||
%token RCURLY;
|
||||
%token LBRACKET;
|
||||
%token RBRACKET;
|
||||
%token LPAREN;
|
||||
%token RPAREN;
|
||||
|
||||
%token REAL_NUMBER;
|
||||
%token STRING;
|
||||
|
||||
%token AMBIENT;
|
||||
%token AMBIENT_OCCLUSION;
|
||||
%token BOX;
|
||||
%token CAMERA;
|
||||
%token COLOR;
|
||||
%token CYL;
|
||||
%token DEFINE;
|
||||
%token DIFFUSE;
|
||||
%token EXPOSURE;
|
||||
%token EXTRUDE;
|
||||
%token HEIGHT;
|
||||
%token INTERSECT;
|
||||
%token JITTER;
|
||||
%token LIGHT;
|
||||
%token LOOKAT;
|
||||
%token MATERIAL;
|
||||
%token MAXDEPTH;
|
||||
%token MULTISAMPLE;
|
||||
%token NGON;
|
||||
%token OFFSET;
|
||||
%token OPTIONS;
|
||||
%token PLANE;
|
||||
%token POLYGON;
|
||||
%token POSITION;
|
||||
%token RADIUS;
|
||||
%token REFLECTANCE;
|
||||
%token REFRACTION;
|
||||
%token ROTATE;
|
||||
%token SCALE;
|
||||
%token SCENE;
|
||||
%token SHAPE;
|
||||
%token SHININESS;
|
||||
%token SIZE;
|
||||
%token SPECULAR;
|
||||
%token SPHERE;
|
||||
%token SUBTRACT;
|
||||
%token TEXTURE;
|
||||
%token TRANSLATE;
|
||||
%token TRANSPARENCY;
|
||||
%token UNION;
|
||||
%token UP;
|
||||
%token VFOV;
|
||||
%token WIDTH;
|
||||
|
||||
%token IDENTIFIER;
|
||||
%token VARREF;
|
||||
|
||||
%token ELSE;
|
||||
%token ELSIF;
|
||||
%token FOR;
|
||||
%token IF;
|
||||
%token WHILE;
|
||||
%token LOCAL;
|
||||
|
||||
%right ASSIGN
|
||||
%left AND OR NOT
|
||||
%left PLUS MINUS
|
||||
%left TIMES DIVIDE MOD
|
||||
%right POW
|
||||
%left UMINUS
|
||||
|
||||
%%
|
||||
|
||||
scene: SCENE LCURLY general_items RCURLY {
|
||||
$$ = new SceneNode();
|
||||
$$->addChildren($3);
|
||||
parsed_scene_node = $$;
|
||||
}
|
||||
;
|
||||
|
||||
box: BOX LCURLY general_items RCURLY {
|
||||
$$ = new BoxNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
camera: CAMERA LCURLY general_items RCURLY {
|
||||
$$ = new CameraNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
cyl: CYL LCURLY general_items RCURLY {
|
||||
$$ = new CylNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
extrude: EXTRUDE LCURLY general_items RCURLY {
|
||||
$$ = new ExtrudeNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
general_items: /* empty */ { $$ = NULL; }
|
||||
| general_item general_items {
|
||||
$$ = new ItemsNode();
|
||||
$$->addChild($1);
|
||||
$$->addChildren($2);
|
||||
}
|
||||
;
|
||||
|
||||
general_item: AMBIENT vector3 { $$ = new AmbientNode($2); }
|
||||
| AMBIENT_OCCLUSION expression {
|
||||
$$ = new AmbientOcclusionNode($2);
|
||||
}
|
||||
| camera { $$ = $1; }
|
||||
| COLOR vector3 { $$ = new ColorNode($2); }
|
||||
| DIFFUSE vector3 { $$ = new DiffuseNode($2); }
|
||||
| EXPOSURE expression { $$ = new ExposureNode($2); }
|
||||
| for { $$ = $1; }
|
||||
| HEIGHT expression { $$ = new HeightNode($2); }
|
||||
| if { $$ = $1; }
|
||||
| JITTER expression { $$ = new JitterNode($2); }
|
||||
| light { $$ = $1; }
|
||||
| LOOKAT vector3 { $$ = new LookAtNode($2); }
|
||||
| material { $$ = $1; }
|
||||
| material_definition { $$ = $1; }
|
||||
| material_ref { $$ = $1; }
|
||||
| MAXDEPTH expression { $$ = new MaxDepthNode($2); }
|
||||
| MULTISAMPLE expression { $$ = new MultisampleNode($2); }
|
||||
| ngon { $$ = $1; }
|
||||
| offset { $$ = $1; }
|
||||
| options { $$ = $1; }
|
||||
| polygon { $$ = $1; }
|
||||
| POSITION vector3 { $$ = new PositionNode($2); }
|
||||
| POSITION vector3 COMMA expression {
|
||||
$$ = new PlanePositionNode($2, $4);
|
||||
}
|
||||
| RADIUS expression { $$ = new RadiusNode($2); }
|
||||
| REFLECTANCE expression { $$ = new ReflectanceNode($2); }
|
||||
| REFRACTION expression { $$ = new RefractionNode($2); }
|
||||
| ROTATE expression COMMA vector3 { $$ = new RotateNode($2, $4); }
|
||||
| SCALE expression { $$ = new ScaleNode(new ScaleScalarNode($2)); }
|
||||
| SCALE vector2 { $$ = new ScaleNode($2); }
|
||||
| SCALE vector3 { $$ = new ScaleNode($2); }
|
||||
| shape { $$ = $1; }
|
||||
| shape_definition { $$ = $1; }
|
||||
| SHININESS expression { $$ = new ShininessNode($2); }
|
||||
| SIZE vector3 { $$ = new SizeNode($2); }
|
||||
| SPECULAR vector3 { $$ = new SpecularNode($2); }
|
||||
| stmt_expression { $$ = $1; }
|
||||
| TEXTURE STRING { $$ = new TextureNode($2->getString()); }
|
||||
| transform_block { $$ = $1; }
|
||||
| TRANSLATE vector3 { $$ = new TranslateNode($2); }
|
||||
| TRANSPARENCY expression { $$ = new TransparencyNode($2); }
|
||||
| UP vector3 { $$ = new UpNode($2); }
|
||||
| vector2 { $$ = $1; }
|
||||
| VFOV expression { $$ = new VFOVNode($2); }
|
||||
| while { $$ = $1; }
|
||||
| WIDTH expression { $$ = new WidthNode($2); }
|
||||
;
|
||||
|
||||
|
||||
intersect: INTERSECT LCURLY general_items RCURLY {
|
||||
$$ = new IntersectNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
light: LIGHT LCURLY general_items RCURLY {
|
||||
$$ = new LightNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
material: MATERIAL LCURLY general_items RCURLY {
|
||||
$$ = new MaterialNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
material_definition: DEFINE MATERIAL IDENTIFIER LCURLY general_items RCURLY {
|
||||
$$ = new MaterialDefinitionNode($3->getString());
|
||||
$$->addChildren($5);
|
||||
}
|
||||
;
|
||||
|
||||
material_ref: MATERIAL IDENTIFIER {
|
||||
$$ = new MaterialRefNode($2->getString());
|
||||
}
|
||||
;
|
||||
|
||||
number: REAL_NUMBER { $$ = $1; }
|
||||
;
|
||||
|
||||
ngon: NGON expression COMMA expression {
|
||||
$$ = new NGonNode($2);
|
||||
$$->addChild(new RadiusNode($4));
|
||||
}
|
||||
;
|
||||
|
||||
offset: OFFSET expression {
|
||||
$$ = new OffsetNode($2);
|
||||
}
|
||||
| OFFSET expression LCURLY general_items RCURLY {
|
||||
$$ = new OffsetNode($2);
|
||||
$$->addChildren($4);
|
||||
}
|
||||
;
|
||||
|
||||
options: OPTIONS LCURLY general_items RCURLY {
|
||||
$$ = new OptionsNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
plane: PLANE LCURLY general_items RCURLY {
|
||||
$$ = new PlaneNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
polygon: POLYGON LCURLY general_items RCURLY {
|
||||
$$ = new PolygonNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
shape: plane { $$ = $1; }
|
||||
| sphere { $$ = $1; }
|
||||
| box { $$ = $1; }
|
||||
| cyl { $$ = $1; }
|
||||
| union { $$ = $1; }
|
||||
| intersect { $$ = $1; }
|
||||
| subtract { $$ = $1; }
|
||||
| extrude { $$ = $1; }
|
||||
| shape_ref { $$ = $1; }
|
||||
;
|
||||
|
||||
shape_definition: DEFINE SHAPE IDENTIFIER shape {
|
||||
$$ = new ShapeDefinitionNode($3->getString());
|
||||
$$->addChild($4);
|
||||
}
|
||||
;
|
||||
|
||||
shape_ref: SHAPE IDENTIFIER shape_ref_more {
|
||||
$$ = new ShapeRefNode($2->getString());
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
shape_ref_more: /* empty */ { $$ = NULL; }
|
||||
| LCURLY general_items RCURLY { $$ = $2; }
|
||||
;
|
||||
|
||||
sphere: SPHERE LCURLY general_items RCURLY {
|
||||
$$ = new SphereNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
subtract: SUBTRACT LCURLY general_items RCURLY {
|
||||
$$ = new SubtractNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
transform_block: TRANSLATE vector3 LCURLY general_items RCURLY {
|
||||
$$ = new TranslateBlockNode($2);
|
||||
$$->addChildren($4);
|
||||
}
|
||||
| ROTATE expression COMMA vector3 LCURLY general_items RCURLY {
|
||||
$$ = new RotateBlockNode($2, $4);
|
||||
$$->addChildren($6);
|
||||
}
|
||||
| SCALE vector3 LCURLY general_items RCURLY {
|
||||
$$ = new ScaleBlockNode($2);
|
||||
$$->addChildren($4);
|
||||
}
|
||||
| SCALE expression LCURLY general_items RCURLY {
|
||||
$$ = new ScaleBlockNode(new ScaleScalarNode($2));
|
||||
$$->addChildren($4);
|
||||
}
|
||||
;
|
||||
|
||||
union: UNION LCURLY general_items RCURLY {
|
||||
$$ = new UnionNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
vector2: LESS expression COMMA expression GREATER {
|
||||
$$ = new VectorNode($2, $4, new NumberNode(0.0));
|
||||
}
|
||||
;
|
||||
|
||||
vector3: LESS expression COMMA expression COMMA expression GREATER {
|
||||
$$ = new VectorNode($2, $4, $6);
|
||||
}
|
||||
;
|
||||
|
||||
expression: expression TIMES expression { $$ = new BinOpNode('*', $1, $3); }
|
||||
| expression DIVIDE expression { $$ = new BinOpNode('/', $1, $3); }
|
||||
| expression PLUS expression { $$ = new BinOpNode('+', $1, $3); }
|
||||
| expression MINUS expression { $$ = new BinOpNode('-', $1, $3); }
|
||||
| expression MOD expression { $$ = new BinOpNode('%', $1, $3); }
|
||||
| expression POW expression { $$ = new BinOpNode('^', $1, $3); }
|
||||
| MINUS expression %prec UMINUS {
|
||||
$$ = new BinOpNode('-', new NumberNode(0.0), $2);
|
||||
}
|
||||
| stmt_expression { $$ = $1; }
|
||||
| function_call { $$ = $1; }
|
||||
| number { $$ = $1; }
|
||||
| VARREF { $$ = $1; }
|
||||
| LPAREN expression RPAREN { $$ = $2; }
|
||||
;
|
||||
|
||||
maybe_expression: /* empty */ { $$ = NULL; }
|
||||
| expression { $$ = $1; }
|
||||
;
|
||||
|
||||
stmt_expression: assignment { $$ = $1; }
|
||||
| local_assignment { $$ = $1; }
|
||||
| local_decl { $$ = $1; }
|
||||
;
|
||||
|
||||
bool_expression: expression LESS expression {
|
||||
$$ = new BoolExpressionNode('<', $1, $3);
|
||||
}
|
||||
| expression LESSEQ expression {
|
||||
$$ = new BoolExpressionNode('l', $1, $3);
|
||||
}
|
||||
| expression GREATER expression {
|
||||
$$ = new BoolExpressionNode('>', $1, $3);
|
||||
}
|
||||
| expression GREATEREQ expression {
|
||||
$$ = new BoolExpressionNode('g', $1, $3);
|
||||
}
|
||||
| expression EQUALS expression {
|
||||
$$ = new BoolExpressionNode('=', $1, $3);
|
||||
}
|
||||
| expression NOTEQUALS expression {
|
||||
$$ = new BoolExpressionNode('n', $1, $3);
|
||||
}
|
||||
| bool_expression AND bool_expression {
|
||||
$$ = new BoolExpressionNode('&', $1, $3);
|
||||
}
|
||||
| bool_expression OR bool_expression {
|
||||
$$ = new BoolExpressionNode('|', $1, $3);
|
||||
}
|
||||
| NOT bool_expression {
|
||||
$$ = new BoolExpressionNode('!', $2, NULL);
|
||||
}
|
||||
| LPAREN bool_expression RPAREN {
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
assignment: VARREF ASSIGN expression {
|
||||
$$ = new AssignmentNode($1, $3);
|
||||
}
|
||||
;
|
||||
|
||||
local_assignment: LOCAL VARREF ASSIGN expression {
|
||||
$$ = new LocalAssignmentNode($2, $4);
|
||||
}
|
||||
;
|
||||
|
||||
local_decl: LOCAL VARREF {
|
||||
$$ = new LocalDeclNode($2);
|
||||
}
|
||||
;
|
||||
|
||||
for: FOR LPAREN maybe_expression SEMICOLON bool_expression SEMICOLON maybe_expression RPAREN LCURLY general_items RCURLY {
|
||||
$$ = new ForNode($3, $5, $7);
|
||||
$$->addChildren($10);
|
||||
}
|
||||
;
|
||||
|
||||
while: WHILE LPAREN bool_expression RPAREN LCURLY general_items RCURLY {
|
||||
$$ = new ForNode(NULL, $3, NULL);
|
||||
$$->addChildren($6);
|
||||
}
|
||||
;
|
||||
|
||||
if: IF LPAREN bool_expression RPAREN LCURLY general_items RCURLY if_more {
|
||||
$$ = new IfNode($3, $8);
|
||||
$$->addChildren($6);
|
||||
}
|
||||
;
|
||||
|
||||
if_more: /* empty */ { $$ = NULL; }
|
||||
| ELSIF LPAREN bool_expression RPAREN LCURLY general_items RCURLY if_more {
|
||||
$$ = new IfNode($3, $8);
|
||||
$$->addChildren($6);
|
||||
}
|
||||
| ELSE LCURLY general_items RCURLY {
|
||||
$$ = new ElseNode();
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
function_call: IDENTIFIER LPAREN function_call_parameters RPAREN {
|
||||
$$ = new FunctionCallNode($1, $3);
|
||||
}
|
||||
;
|
||||
|
||||
function_call_parameters: /* empty */ { $$ = NULL; }
|
||||
| expression function_call_more_parameters {
|
||||
$$ = new ItemsNode();
|
||||
$$->addChild($1);
|
||||
$$->addChildren($2);
|
||||
}
|
||||
;
|
||||
|
||||
function_call_more_parameters: /* empty */ { $$ = NULL; }
|
||||
| COMMA expression function_call_more_parameters {
|
||||
$$ = new ItemsNode();
|
||||
$$->addChild($2);
|
||||
$$->addChildren($3);
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
refptr<Node> parse(const char * fileName, refptr<Scope> scope)
|
||||
{
|
||||
parser_scope = scope;
|
||||
|
||||
yyin = fopen(fileName, "r");
|
||||
if (yyin == NULL)
|
||||
{
|
||||
cerr << "Failed to open file '" << fileName << "'" << endl;
|
||||
return refptr<Node>(NULL);
|
||||
}
|
||||
if (yyparse())
|
||||
{
|
||||
cerr << "Aborting." << endl;
|
||||
exit(1);
|
||||
}
|
||||
return parsed_scene_node;
|
||||
}
|
||||
|
||||
void errFunc(const char * str, YYLTYPE * yyllocp)
|
||||
{
|
||||
fprintf(stderr, "error: %s: line %d, column %d\n",
|
||||
str,
|
||||
yyllocp->first_line,
|
||||
yyllocp->first_column);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
|
||||
int preprocess(const char * fileName)
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(fileName, &st))
|
||||
{
|
||||
cerr << "Error accessing " << fileName << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ifstream ifs(fileName);
|
||||
|
||||
if ( ! ifs.is_open() )
|
||||
{
|
||||
cerr << "Error opening " << fileName << endl;
|
||||
return -2;
|
||||
}
|
||||
|
||||
char * buff = new char[st.st_size];
|
||||
while ( ! ifs.eof() )
|
||||
{
|
||||
ifs.getline(buff, st.st_size);
|
||||
}
|
||||
delete[] buff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user