summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bison.pri2
-rw-r--r--flex.pri2
-rw-r--r--openscad.pro9
-rw-r--r--src/expr.cc14
-rw-r--r--src/expression.h2
-rw-r--r--src/localscope.cc6
-rw-r--r--src/localscope.h1
-rw-r--r--src/module.cc5
-rw-r--r--src/module.h2
-rw-r--r--src/parser.y233
-rw-r--r--tests/CMakeLists.txt9
11 files changed, 107 insertions, 178 deletions
diff --git a/bison.pri b/bison.pri
index 7a63f0e..d2972d6 100644
--- a/bison.pri
+++ b/bison.pri
@@ -1,4 +1,4 @@
-win32 {
+{
bison.name = Bison ${QMAKE_FILE_IN}
bison.input = BISONSOURCES
bison.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp
diff --git a/flex.pri b/flex.pri
index 203d90d..0813300 100644
--- a/flex.pri
+++ b/flex.pri
@@ -1,4 +1,4 @@
-win32 {
+{
flex.name = Flex ${QMAKE_FILE_IN}
flex.input = FLEXSOURCES
flex.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp
diff --git a/openscad.pro b/openscad.pro
index bd69dfe..81f5e6f 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -171,13 +171,8 @@ CONFIG(mingw-cross-env) {
include(mingw-cross-env.pri)
}
-win32 {
- FLEXSOURCES = src/lexer.l
- BISONSOURCES = src/parser.y
-} else {
- LEXSOURCES += src/lexer.l
- YACCSOURCES += src/parser.y
-}
+FLEXSOURCES = src/lexer.l
+BISONSOURCES = src/parser.y
RESOURCES = openscad.qrc
diff --git a/src/expr.cc b/src/expr.cc
index 6629bf5..985a53a 100644
--- a/src/expr.cc
+++ b/src/expr.cc
@@ -38,6 +38,20 @@ Expression::Expression()
{
}
+Expression::Expression(const std::string &type,
+ Expression *left, Expression *right)
+ : type(type)
+{
+ this->children.push_back(left);
+ this->children.push_back(right);
+}
+
+Expression::Expression(const std::string &type, Expression *expr)
+ : type(type)
+{
+ this->children.push_back(expr);
+}
+
Expression::Expression(const Value &val) : const_value(val), type("C")
{
}
diff --git a/src/expression.h b/src/expression.h
index 06becc0..6c03f52 100644
--- a/src/expression.h
+++ b/src/expression.h
@@ -34,6 +34,8 @@ public:
Expression();
Expression(const Value &val);
+ Expression(const std::string &type, Expression *left, Expression *right);
+ Expression(const std::string &type, Expression *expr);
~Expression();
Value evaluate(const class Context *context) const;
diff --git a/src/localscope.cc b/src/localscope.cc
index c4001f5..eecff91 100644
--- a/src/localscope.cc
+++ b/src/localscope.cc
@@ -19,6 +19,12 @@ LocalScope::~LocalScope()
BOOST_FOREACH (AbstractModuleContainer::value_type &m, modules) delete m.second;
}
+void LocalScope::addChild(ModuleInstantiation *ch)
+{
+ assert(ch != NULL);
+ this->children.push_back(ch);
+}
+
std::string LocalScope::dump(const std::string &indent) const
{
std::stringstream dump;
diff --git a/src/localscope.h b/src/localscope.h
index 87f8430..d81a27c 100644
--- a/src/localscope.h
+++ b/src/localscope.h
@@ -13,6 +13,7 @@ public:
size_t numElements() const { return assignments.size() + children.size(); }
std::string dump(const std::string &indent) const;
std::vector<class AbstractNode*> instantiateChildren(const class Context *evalctx, class FileContext *filectx = NULL) const;
+ void addChild(ModuleInstantiation *ch);
AssignmentList assignments;
ModuleInstantiationList children;
diff --git a/src/module.cc b/src/module.cc
index e9a5169..9503f05 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -132,11 +132,6 @@ Module::~Module()
{
}
-void Module::addChild(ModuleInstantiation *ch)
-{
- this->scope.children.push_back(ch);
-}
-
AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
{
ModuleContext c(ctx, evalctx);
diff --git a/src/module.h b/src/module.h
index b7ee23d..8f1ccb7 100644
--- a/src/module.h
+++ b/src/module.h
@@ -68,8 +68,6 @@ public:
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
virtual std::string dump(const std::string &indent, const std::string &name) const;
- void addChild(ModuleInstantiation *ch);
-
AssignmentList definition_arguments;
LocalScope scope;
diff --git a/src/parser.y b/src/parser.y
index 0cd1fbd..272f801 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -56,8 +56,7 @@
int lexerlex_destroy(void);
int lexerlex(void);
- std::vector<Module*> module_stack;
- Module *currmodule;
+ std::stack<LocalScope *> scope_stack;
FileModule *rootmodule;
extern void lexerdestroy();
@@ -74,7 +73,6 @@
class Value *value;
class Expression *expr;
class ModuleInstantiation *inst;
- std::vector<ModuleInstantiation*> *instvec;
class IfElseModuleInstantiation *ifelse;
Assignment *arg;
AssignmentList *args;
@@ -115,8 +113,6 @@
%type <inst> module_instantiation
%type <ifelse> if_statement
%type <ifelse> ifelse_statement
-%type <instvec> children_instantiation
-%type <instvec> module_instantiation_list
%type <inst> single_module_instantiation
%type <args> arguments_call
@@ -138,89 +134,66 @@ inner_input:
/* empty */ |
statement inner_input ;
-statement:
-';' |
-'{' inner_input '}' |
-module_instantiation {
- if ($1) {
- currmodule->addChild($1);
- } else {
- delete $1;
- }
-} |
+assignment:
TOK_ID '=' expr ';' {
- for (AssignmentList::iterator iter = currmodule->scope.assignments.begin();
- iter != currmodule->scope.assignments.end();
+ for (AssignmentList::iterator iter = scope_stack.top()->assignments.begin();
+ iter != scope_stack.top()->assignments.end();
iter++) {
if (iter->first == $1) {
- currmodule->scope.assignments.erase(iter);
+ scope_stack.top()->assignments.erase(iter);
break;
}
}
- currmodule->scope.assignments.push_back(Assignment($1, $3));
+ scope_stack.top()->assignments.push_back(Assignment($1, $3));
+} ;
+
+statement:
+';' |
+'{' inner_input '}' |
+module_instantiation {
+ if ($1) scope_stack.top()->addChild($1);
} |
+assignment |
TOK_MODULE TOK_ID '(' arguments_decl optional_commas ')' {
- Module *p = currmodule;
- module_stack.push_back(currmodule);
- currmodule = new Module();
- p->scope.modules[$2] = currmodule;
- currmodule->definition_arguments = *$4;
+ Module *newmodule = new Module();
+ newmodule->definition_arguments = *$4;
+ scope_stack.top()->modules[$2] = newmodule;
+ scope_stack.push(&newmodule->scope);
free($2);
delete $4;
} statement {
- currmodule = module_stack.back();
- module_stack.pop_back();
+ scope_stack.pop();
} |
TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr {
Function *func = new Function();
func->definition_arguments = *$4;
func->expr = $8;
- currmodule->scope.functions[$2] = func;
+ scope_stack.top()->functions[$2] = func;
free($2);
delete $4;
} ';' ;
-
-/* Will return a dummy parent node with zero or more children */
-children_instantiation:
-module_instantiation {
- $$ = new std::vector<ModuleInstantiation*>;
- if ($1) {
- $$->push_back($1);
- }
-} |
-'{' module_instantiation_list '}' {
- $$ = $2;
-} ;
if_statement:
-TOK_IF '(' expr ')' children_instantiation {
- $$ = new IfElseModuleInstantiation();
- $$->arguments.push_back(Assignment("", $3));
- $$->setPath(parser_source_path);
-
- if ($$) {
- $$->scope.children = *$5;
- } else {
- for (size_t i = 0; i < $5->size(); i++)
- delete (*$5)[i];
- }
- delete $5;
-} ;
+TOK_IF '(' expr ')' {
+ $<ifelse>if = new IfElseModuleInstantiation();
+ $<ifelse>if->arguments.push_back(Assignment("", $3));
+ $<ifelse>if->setPath(parser_source_path);
+ scope_stack.push(&$<ifelse>if->scope);
+}[if] child_statement {
+ scope_stack.pop();
+ $$ = $<ifelse>if;
+ } ;
ifelse_statement:
if_statement {
$$ = $1;
} |
-if_statement TOK_ELSE children_instantiation {
+if_statement TOK_ELSE {
+ scope_stack.push(&$1->else_scope);
+}[else] child_statement {
+ scope_stack.pop();
$$ = $1;
- if ($$) {
- $$->else_scope.children = *$3;
- } else {
- for (size_t i = 0; i < $3->size(); i++)
- delete (*$3)[i];
- }
- delete $3;
-} ;
+ } ;
module_instantiation:
'!' module_instantiation {
@@ -239,35 +212,28 @@ module_instantiation:
delete $2;
$$ = NULL;
} |
-single_module_instantiation ';' {
- $$ = $1;
-} |
-single_module_instantiation children_instantiation {
- $$ = $1;
- if ($$) {
- $$->scope.children = *$2;
- } else {
- for (size_t i = 0; i < $2->size(); i++)
- delete (*$2)[i];
- }
- delete $2;
+single_module_instantiation {
+ $<inst>inst = $1;
+ scope_stack.push(&$<inst>inst->scope);
+}[inst] child_statement {
+ scope_stack.pop();
+ $$ = $<inst>inst;
+ } |
+ ifelse_statement {
+ $$ = $1;
+ } ;
+
+child_statement:
+';' |
+'{' child_statements '}' |
+module_instantiation {
+ if ($1) scope_stack.top()->addChild($1);
} |
-ifelse_statement {
- $$ = $1;
-} ;
+assignment ;
-module_instantiation_list:
-/* empty */ {
- $$ = new std::vector<ModuleInstantiation*>;
-} |
-module_instantiation_list module_instantiation {
- $$ = $1;
- if ($$) {
- if ($2) $$->push_back($2);
- } else {
- delete $2;
- }
-} ;
+child_statements:
+/* empty */ |
+child_statements child_statement ;
single_module_instantiation:
TOK_ID '(' arguments_call ')' {
@@ -295,9 +261,7 @@ TOK_ID {
free($1);
} |
expr '.' TOK_ID {
- $$ = new Expression();
- $$->type = "N";
- $$->children.push_back($1);
+ $$ = new Expression("N", $1);
$$->var_name = $3;
free($3);
} |
@@ -330,95 +294,52 @@ TOK_NUMBER {
$$ = $2;
} |
expr '*' expr {
- $$ = new Expression();
- $$->type = "*";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("*", $1, $3);
} |
expr '/' expr {
- $$ = new Expression();
- $$->type = "/";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("/", $1, $3);
} |
expr '%' expr {
- $$ = new Expression();
- $$->type = "%";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("%", $1, $3);
} |
expr '+' expr {
- $$ = new Expression();
- $$->type = "+";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("+", $1, $3);
} |
expr '-' expr {
- $$ = new Expression();
- $$->type = "-";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("-", $1, $3);
} |
expr '<' expr {
- $$ = new Expression();
- $$->type = "<";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("<", $1, $3);
} |
expr LE expr {
- $$ = new Expression();
- $$->type = "<=";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("<=", $1, $3);
} |
expr EQ expr {
- $$ = new Expression();
- $$->type = "==";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("==", $1, $3);
} |
expr NE expr {
- $$ = new Expression();
- $$->type = "!=";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("!=", $1, $3);
} |
expr GE expr {
- $$ = new Expression();
- $$->type = ">=";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression(">=", $1, $3);
} |
expr '>' expr {
- $$ = new Expression();
- $$->type = ">";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression(">", $1, $3);
} |
expr AND expr {
- $$ = new Expression();
- $$->type = "&&";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("&&", $1, $3);
} |
expr OR expr {
- $$ = new Expression();
- $$->type = "||";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("||", $1, $3);
} |
'+' expr {
$$ = $2;
} |
'-' expr {
- $$ = new Expression();
- $$->type = "I";
- $$->children.push_back($2);
+ $$ = new Expression("I", $2);
} |
'!' expr {
- $$ = new Expression();
- $$->type = "!";
- $$->children.push_back($2);
+ $$ = new Expression("!", $2);
} |
'(' expr ')' {
$$ = $2;
@@ -431,10 +352,7 @@ expr '?' expr ':' expr {
$$->children.push_back($5);
} |
expr '[' expr ']' {
- $$ = new Expression();
- $$->type = "[]";
- $$->children.push_back($1);
- $$->children.push_back($3);
+ $$ = new Expression("[]", $1, $3);
} |
TOK_ID '(' arguments_call ')' {
$$ = new Expression();
@@ -450,9 +368,7 @@ optional_commas:
vector_expr:
expr {
- $$ = new Expression();
- $$->type = 'V';
- $$->children.push_back($1);
+ $$ = new Expression("V", $1);
} |
vector_expr ',' optional_commas expr {
$$ = $1;
@@ -519,7 +435,6 @@ void yyerror (char const *s)
{
// FIXME: We leak memory on parser errors...
PRINTB("Parser error in line %d: %s\n", lexerget_lineno() % s);
- currmodule = NULL;
}
FileModule *parse(const char *text, const char *path, int debug)
@@ -529,10 +444,9 @@ FileModule *parse(const char *text, const char *path, int debug)
parser_input_buffer = text;
parser_source_path = boosty::absolute(std::string(path)).string();
- module_stack.clear();
rootmodule = new FileModule();
- currmodule = rootmodule;
rootmodule->setModulePath(path);
+ scope_stack.push(&rootmodule->scope);
// PRINTB_NOCACHE("New module: %s %p", "root" % rootmodule);
parserdebug = debug;
@@ -543,5 +457,6 @@ FileModule *parse(const char *text, const char *path, int debug)
if (parserretval != 0) return NULL;
parser_error_pos = -1;
+ scope_stack.pop();
return rootmodule;
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 909c8ed..51abd06 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -13,7 +13,11 @@ include(CMakeParseArguments.cmake)
# Detect Lion and force gcc
IF (APPLE)
EXECUTE_PROCESS(COMMAND sw_vers -productVersion OUTPUT_VARIABLE MACOSX_VERSION)
- IF (NOT ${MACOSX_VERSION} VERSION_LESS "10.7.0")
+ IF (NOT ${MACOSX_VERSION} VERSION_LESS "10.8.0")
+ message("Detected Mountain Lion or later")
+ set(CMAKE_C_COMPILER "gcc")
+ set(CMAKE_CXX_COMPILER "g++")
+ ELSEIF (NOT ${MACOSX_VERSION} VERSION_LESS "10.7.0")
message("Detected Lion or later")
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_COMPILER "g++")
@@ -325,9 +329,8 @@ if (WIN32)
set(FLEX_UNISTD_FLAG "-DYY_NO_UNISTD_H")
endif()
FLEX_TARGET(OpenSCADlexer ../src/lexer.l ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp COMPILE_FLAGS "-Plexer ${FLEX_UNISTD_FLAG}")
-BISON_TARGET(OpenSCADparser ../src/parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser_yacc.c COMPILE_FLAGS "-p parser")
+BISON_TARGET(OpenSCADparser ../src/parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp COMPILE_FLAGS "-p parser")
ADD_FLEX_BISON_DEPENDENCY(OpenSCADlexer OpenSCADparser)
-set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/parser_yacc.c PROPERTIES LANGUAGE "CXX")
# CGAL
contact: Jan Huwald // Impressum