added parser_scope global, added local assignments and local declarations to parser, reworked Scope class to use get(), putLocal(), and putGlobal() methods

git-svn-id: svn://anubis/fart/branches/scene-file-scripting@329 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop 2010-10-04 19:54:43 +00:00
parent e2569c0a54
commit 7014605fe3
6 changed files with 100 additions and 8 deletions

View File

@ -17,7 +17,8 @@ typedef vector< refptr<Node> >::const_iterator Node_Iterator;
void Scene::load(const char * filename)
{
refptr<Node> node = parse(filename);
refptr<Scope> scope = new Scope();
refptr<Node> node = parse(filename, scope);
processNode(node);
}

View File

@ -2,10 +2,17 @@
#ifndef NODES_H
#define NODES_H NODES_H
#include "util/refptr.h"
#include "util/Vector.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
{
@ -449,12 +456,49 @@ class AssignmentNode : public ExpressionNode
{
}
std::string getString() { return m_varref->getString(); }
double getNumber() { return m_expr->getNumber(); }
double getNumber()
{
double n = m_expr->getNumber();
parser_scope->putGlobal(getString(), n);
return n;
}
protected:
refptr<Node> m_varref;
refptr<Node> m_expr;
};
class LocalAssignmentNode : public ExpressionNode
{
public:
LocalAssignmentNode(refptr<Node> varref, refptr<Node> expr)
: m_varref(varref), m_expr(expr)
{
}
std::string getString() { return m_varref->getString(); }
double getNumber()
{
double n = m_expr->getNumber();
parser_scope->putLocal(getString(), n);
return n;
}
protected:
refptr<Node> m_varref;
refptr<Node> m_expr;
};
class LocalDeclNode : public ExpressionNode
{
public:
LocalDeclNode(refptr<Node> varref) : m_varref(varref) { }
double getNumber()
{
parser_scope->putLocal(m_varref->getString(), 0.0);
return 0.0;
}
protected:
refptr<Node> m_varref;
};
class BinOpNode : public ExpressionNode
{
public:
@ -488,6 +532,16 @@ class VarRefNode : public Node
public:
VarRefNode(const std::string & str) { m_string = str; }
std::string getString() { return m_string; }
double getNumber()
{
if (parser_scope->contains(m_string))
{
return parser_scope->get(m_string);
}
std::cerr << "Error: No identifier '" << m_string << "' in scope"
<< std::endl;
exit(4);
}
protected:
std::string m_string;
};

View File

@ -4,9 +4,10 @@
#include "nodes.h"
#include "util/refptr.h"
#include "util/Scope.h"
#define YYSTYPE refptr<Node>
refptr<Node> parse(const char * fileName);
refptr<Node> parse(const char * fileName, refptr<Scope> scope);
#endif

View File

@ -90,6 +90,7 @@ 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);

View File

@ -5,6 +5,7 @@
#include <iostream>
#include "util/Vector.h"
#include "util/refptr.h"
#include "util/Scope.h"
#include "nodes.h"
#include "parser.h"
#include "parser.tab.hh" /* bison-generated header with YY[SL]TYPE */
@ -24,6 +25,7 @@ int yywrap()
}
static refptr<Node> parsed_scene_node;
refptr<Scope> parser_scope;
%}
@ -112,6 +114,7 @@ static refptr<Node> parsed_scene_node;
%token FOR;
%token IF;
%token WHILE;
%token LOCAL;
%right ASSIGN
%left PLUS MINUS
@ -587,6 +590,8 @@ expression: term { $$ = $1; }
$$ = new BinOpNode('-', new NumberNode(0.0), $2);
}
| assignment { $$ = $1; }
| local_assignment { $$ = $1; }
| local_decl { $$ = $1; }
;
bool_expression: expression LESS expression {
@ -621,6 +626,16 @@ assignment: VARREF ASSIGN expression {
}
;
local_assignment: LOCAL VARREF ASSIGN expression {
$$ = new LocalAssignmentNode($2, $4);
}
;
local_decl: LOCAL VARREF {
$$ = new LocalDeclNode($2);
}
;
for: FOR LPAREN expression SEMICOLON bool_expression SEMICOLON expression RPAREN LCURLY general_items RCURLY {
$$ = new ForNode($3, $5, $7);
$$->addChildren($10);
@ -629,8 +644,10 @@ for: FOR LPAREN expression SEMICOLON bool_expression SEMICOLON expression RPAREN
%%
refptr<Node> parse(const char * fileName)
refptr<Node> parse(const char * fileName, refptr<Scope> scope)
{
parser_scope = scope;
yyin = fopen(fileName, "r");
if (yyin == NULL)
{

View File

@ -23,7 +23,7 @@ class Scope
}
return false;
}
double & operator[](const std::string & key)
double get(const std::string & key)
{
for (m_list_type::reverse_iterator it = m_list.rbegin();
it != m_list.rend();
@ -34,7 +34,25 @@ class Scope
return (*it)[key];
}
}
return (*m_list.rbegin())[key];
return 0.0;
}
void putLocal(const std::string & key, double val)
{
(*m_list.rbegin())[key] = val;
}
void putGlobal(const std::string & key, double val)
{
for (m_list_type::reverse_iterator it = m_list.rbegin();
it != m_list.rend();
it++)
{
if (it->find(key) != it->end())
{
(*it)[key] = val;
return;
}
}
putLocal(key, val);
}
void push()
{