From 7014605fe321af0de5acca1db1f793bf2ddf54c8 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 4 Oct 2010 19:54:43 +0000 Subject: [PATCH] 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 --- main/Scene-load.cc | 3 ++- parser/nodes.h | 60 +++++++++++++++++++++++++++++++++++++++++++--- parser/parser.h | 3 ++- parser/parser.lex | 1 + parser/parser.yy | 19 ++++++++++++++- util/Scope.h | 22 +++++++++++++++-- 6 files changed, 100 insertions(+), 8 deletions(-) diff --git a/main/Scene-load.cc b/main/Scene-load.cc index e4b982c..1130928 100644 --- a/main/Scene-load.cc +++ b/main/Scene-load.cc @@ -17,7 +17,8 @@ typedef vector< refptr >::const_iterator Node_Iterator; void Scene::load(const char * filename) { - refptr node = parse(filename); + refptr scope = new Scope(); + refptr node = parse(filename, scope); processNode(node); } diff --git a/parser/nodes.h b/parser/nodes.h index e8ebe75..87e072f 100644 --- a/parser/nodes.h +++ b/parser/nodes.h @@ -2,10 +2,17 @@ #ifndef NODES_H #define NODES_H NODES_H -#include "util/refptr.h" -#include "util/Vector.h" +#include /* exit() */ + #include #include +#include + +#include "util/refptr.h" +#include "util/Vector.h" +#include "util/Scope.h" + +extern refptr 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 m_varref; refptr m_expr; }; +class LocalAssignmentNode : public ExpressionNode +{ + public: + LocalAssignmentNode(refptr varref, refptr 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 m_varref; + refptr m_expr; +}; + +class LocalDeclNode : public ExpressionNode +{ + public: + LocalDeclNode(refptr varref) : m_varref(varref) { } + double getNumber() + { + parser_scope->putLocal(m_varref->getString(), 0.0); + return 0.0; + } + protected: + refptr 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; }; diff --git a/parser/parser.h b/parser/parser.h index 158c90c..a231518 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -4,9 +4,10 @@ #include "nodes.h" #include "util/refptr.h" +#include "util/Scope.h" #define YYSTYPE refptr -refptr parse(const char * fileName); +refptr parse(const char * fileName, refptr scope); #endif diff --git a/parser/parser.lex b/parser/parser.lex index a52d888..97ce09a 100644 --- a/parser/parser.lex +++ b/parser/parser.lex @@ -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); diff --git a/parser/parser.yy b/parser/parser.yy index 0ab8b37..3994319 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -5,6 +5,7 @@ #include #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 parsed_scene_node; +refptr parser_scope; %} @@ -112,6 +114,7 @@ static refptr 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 parse(const char * fileName) +refptr parse(const char * fileName, refptr scope) { + parser_scope = scope; + yyin = fopen(fileName, "r"); if (yyin == NULL) { diff --git a/util/Scope.h b/util/Scope.h index 9089053..1c58051 100644 --- a/util/Scope.h +++ b/util/Scope.h @@ -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() {