Commit 7159db6a authored by Jennie Yoder's avatar Jennie Yoder

fixed two major parser bugs. Fixed the loop-in-module context error bug,

as well as the "code with no shape" bug that appears in recursion.  I also
changed the code generated for rotation, translation, and scaling to
eliminate empty transformations (rotating by 0 degrees, etc).
parent fd1525ea
......@@ -1231,7 +1231,7 @@ Blockscad.renderCode = function(code) {
try {
// console.log("code was: ",code);
window.setTimeout(function (){ csgcode = openscadOpenJscadParser.parse(code);
// console.log(csgcode);
// console.log("final parsed code: ",csgcode);
}, 0);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -25,6 +25,15 @@ define("CSGModule", ["Globals", "Context"], function(Globals, Context){
}
};
// remove children that have no shape
for (var k = 0; k < childModules.length; k++) {
// console.log("do I need to throw this child out?", this.evaluatedChildren[i]);
if (typeof(childModules[k]) == "string" && childModules[k].charAt(0) == '.') {
// this should have started with a shape, not a '.'. Take it out of the list
childModules.splice(k,1);
}
}
// hull should act on a single non-convex shape
// .hull() doesn't work well. I need to say shape.hull(shape).
if (this.csgOperation == 'hull' && childModules.length == 1) {
......
......@@ -35,6 +35,18 @@ define("ControlModules", ["Globals", "Context", "Range"], function(Globals, Cont
childModules.push(childAdaptor.evaluate(context, childInst));
};
// if children can be pretty weird (deeply nested arrays).
// I'm not going to check for bad children until I get a bug report with these.
// remove children that have no shape
for (var k = 0; k < childModules.length; k++) {
// console.log("trying to remove if children that have no shape");
// console.log("do I need to throw this child out?", childModules[k]);
if (typeof(childModules[k]) == "string" && childModules[k].charAt(0) == '.') {
// this should have started with a shape, not a '.'. Take it out of the list
childModules.splice(k,1);
}
}
if (_.isEmpty(childModules)){
return undefined;
} else {
......@@ -47,31 +59,35 @@ define("ControlModules", ["Globals", "Context", "Range"], function(Globals, Cont
};
function ForLoopStatement(factory, args){
ControlModule.call(this, factory);
// console.log("in ForLoopStatement");
// console.log(this);
// console.log(factory);
// ControlModule.call(this, factory);
this.factory = factory;
this.csgOp = args.csgOp;
this.evaluatedChildren = [];
this.forEval = function(parentEvaluatedChildren, inst, recurs_length, call_argnames, call_argvalues, arg_context) {
// console.log("*****In loop forEval function.");
// console.log("parentEvaluatedChildren:",parentEvaluatedChildren);
// console.log("inst:", inst);
// // console.log("recurs_length:",recurs_length);
// // console.log("call_argnames:", call_argnames);
// // console.log("call_argvalues:",call_argvalues);
// // console.log("arg_context:",arg_context);
// console.log("done writing forEval arguments");
this.evaluatedChildren = parentEvaluatedChildren;
// console.log("evaluated children are:", parentEvaluatedChildren);
if (call_argnames.length > recurs_length) {
// recurs_length always starts at 0. Argnames seems to be an array with the loop variable.
// for blockscad loops this array will always have length "1", and so code starts here.
var it_name = call_argnames[recurs_length];
var it_values = call_argvalues[recurs_length];
var context = new Context(arg_context);
// console.log("created new context on loop create:", context);
// console.log("context's parent context's vars:", context.parentContext.parentContext.vars);
// var context = new Context(arg_context);
var context = arg_context;
// console.log("created new context on loop create");
// console.log("m context:", context.vars);
// if (context.parentContext)
// console.log("p context:",context.parentContext.vars);
// if (context.parentContext && context.parentContext.parentContext)
// console.log("pp context:",context.parentContext.parentContext.vars);
if (it_values instanceof Range) {
var range = it_values;
......@@ -98,6 +114,18 @@ define("ControlModules", ["Globals", "Context", "Range"], function(Globals, Cont
}
} else if (recurs_length > 0) {
// this is one of my loop jobs. the context should have the loop variable name and its value within the range.
// var mycontext = new Context(arg_context);
// console.log("in loop job, going over range");
// console.log("m context:", mycontext.vars);
// if (mycontext.parentContext)
// console.log("p context:",mycontext.parentContext.vars);
// if (mycontext.parentContext && mycontext.parentContext.parentContext)
// console.log("pp context:",mycontext.parentContext.parentContext.vars);
// if (mycontext.parentContext.parentContext && mycontext.parentContext.parentContext.parentContext)
// console.log("ppp context:",mycontext.parentContext.parentContext.parentContext.vars);
var evaluatedInstanceChildren = inst.evaluateChildren(arg_context);
if (_.isArray(evaluatedInstanceChildren)){
this.evaluatedChildren = this.evaluatedChildren.concat(evaluatedInstanceChildren);
......@@ -108,10 +136,28 @@ define("ControlModules", ["Globals", "Context", "Range"], function(Globals, Cont
if (_.isArray(this.evaluatedChildren)){
// remove empty arrays (e.g. for loops containing only echo statements)
this.evaluatedChildren = _.reject(this.evaluatedChildren, function(x){ return _.isEmpty(x); });
// remove children that have no shape
for (var k = 0; k < this.evaluatedChildren.length; k++) {
// console.log(this.evaluatedChildren[k]);
if (typeof(this.evaluatedChildren[k]) == "string" && this.evaluatedChildren[k].charAt(0) == '.') {
// this should have started with a shape, not a '.'. Take it out of the list
this.evaluatedChildren.splice(k,1);
}
}
}
// console.log("here are loops evaluated children:", this.evaluatedChildren);
// for (var i = 0; i < this.evaluatedChildren.length; i++) {
// console.log("i: " + i + ": " + this.evaluatedChildren[i] + "\n");
// }
// console.log("end of evaluated children");
// Note: we union here so subsequent actions (e.g. translate) can be performed on the entire result of the for loop.
if (_.isArray(this.evaluatedChildren) && this.evaluatedChildren.length > 1){
// console.log("unioning more than one child in the loop");
var unionedEvaluatedChildren = _.first(this.evaluatedChildren)+"."+this.csgOp+"([" + _.rest(this.evaluatedChildren) + "])";
this.evaluatedChildren = [unionedEvaluatedChildren];
}
......@@ -127,7 +173,7 @@ define("ControlModules", ["Globals", "Context", "Range"], function(Globals, Cont
var that = this;
this.argvalues = [];
that.argvalues = [];
_.each(this.argexpr, function(expr,index,list) {
that.argvalues.push(expr.evaluate(context));
......@@ -140,7 +186,7 @@ define("ControlModules", ["Globals", "Context", "Range"], function(Globals, Cont
inst.context = context;
}
var evaluatedThing = that.forEval([], inst, 0, inst.argnames, inst.argvalues, inst.context);
var evaluatedThing = that.forEval([], inst, 0, inst.argnames, inst.argvalues, that.context);
that.context = null;
......
......@@ -34,10 +34,12 @@ define("Module", ["Context", "Globals"], function(Context, Globals){
context.setVariable(key, value.evaluate(context));
});
// filter out echo statements
var controlChildren = _.filter(this.children, function(child){
return child && child.name == "echo";
});
// handle echo statements
_.each(controlChildren, function(child, index, list) {
child.evaluate(context);
});
......@@ -56,6 +58,8 @@ define("Module", ["Context", "Globals"], function(Context, Globals){
}
});
// this handles implicit unioning of multiple things in the space. I may want to change this
// to speed things up.
var cleanedLines = _.compact(evaluatedLines);
if (cleanedLines.length == 1){
lines.push(cleanedLines[0]);
......
......@@ -15,7 +15,12 @@ define("ModuleInstantiation", ["Globals", "OpenjscadSolidFactorySingleton"], fun
var evaluatedModule;
// console.log("in moduleInstantiation.prototype.evaluate for", this.name);
// console.log("m context:", context.vars);
// if (context.parentContext)
// console.log("p context:",context.parentContext.vars);
// if (context.parentContext && context.parentContext.parentContext)
// console.log("pp context:",context.parentContext.parentContext.vars);
// NOTE: not sure how we should handle this in javascript ... is it necessary?
//if (this.context === null) {
// console.log("WARNING: Ignoring recursive module instantiation of ", this.name);
......
......@@ -5,6 +5,16 @@ define("TransformModules", ["Globals", "Context"], function(Globals, Context){
this.transformChildren = function (children, context, cb) {
var childModules = []
// console.log("in this.transformChildren");
// console.log("m context:", context.vars);
// if (context.parentContext)
// console.log("p context:",context.parentContext.vars);
// if (context.parentContext && context.parentContext.parentContext)
// console.log("pp context:",context.parentContext.parentContext.vars);
// the "children" are different objects in one transform.
// corresponds to separate bays in a transform block, for example.
for (var i = 0; i < children.length; i++) {
......@@ -12,8 +22,12 @@ define("TransformModules", ["Globals", "Context"], function(Globals, Context){
childInst.argvalues = [];
_.each(childInst.argexpr, function(expr,index,list) {
// console.log("adding an argvalue:", expr.evaluate(context));
childInst.argvalues.push(expr.evaluate(context));
});
// childAdaptor looks at the name of what needs to be called
// translate, rotate, loop, module, etc
// and returns the appropriate function.
var childAdaptor = factory.getAdaptor(childInst);
var transformedChild = childAdaptor.evaluate(context, childInst);
if (transformedChild){
......@@ -21,6 +35,16 @@ define("TransformModules", ["Globals", "Context"], function(Globals, Context){
childModules.push(transformedChild);
}
};
if (_.isArray(childModules)) {
// remove children that have no shape
for (var k = 0; k < childModules.length; k++) {
// console.log("do I need to throw this child out?", childModules[k]);
if (typeof(childModules[k]) == "string" && childModules[k].charAt(0) == '.') {
// this should have started with a shape, not a '.'. Take it out of the list
childModules.splice(k,1);
}
}
}
if (childModules.length == 1){
return childModules[0];
......@@ -57,6 +81,10 @@ define("TransformModules", ["Globals", "Context"], function(Globals, Context){
color[3] = alpha;
}
// // I don't want ridiculous color values.
// for (var i = 0; i < color.length; i++)
// color[i] = color[i].toFixed(3);
return this.transformChildren(inst.children, context, function(){
return _.template('.setColor(<%=color%>)', {color:color});
});
......@@ -109,7 +137,16 @@ define("TransformModules", ["Globals", "Context"], function(Globals, Context){
if (_.isArray(a)){
return this.transformChildren(inst.children, context, function(){
return _.template('.rotateX(<%=degreeX%>).rotateY(<%=degreeY%>).rotateZ(<%=degreeZ%>)', {degreeX:a[0],degreeY:a[1],degreeZ:a[2]});
var code = "";
if (a[0] != 0)
code += '.rotateX(' + a[0] + ')';
if (a[1] != 0)
code += '.rotateY(' + a[1] + ')';
if (a[2] != 0)
code += '.rotateZ(' + a[2] + ')';
return code;
// return _.template('.rotateX(<%=degreeX%>).rotateY(<%=degreeY%>).rotateZ(<%=degreeZ%>)', {degreeX:a[0],degreeY:a[1],degreeZ:a[2]});
});
} else {
var v = Context.contextVariableLookup(context, "v", undefined);
......@@ -145,7 +182,9 @@ define("TransformModules", ["Globals", "Context"], function(Globals, Context){
}
return this.transformChildren(inst.children, context, function(){
if (v[0] != 1 || v[1] != 1 || v[2] != 1)
return _.template('.scale([<%=v%>])', {v:v});
else return "";
});
};
......@@ -194,7 +233,9 @@ define("TransformModules", ["Globals", "Context"], function(Globals, Context){
var v = Context.contextVariableLookup(context, "v", [0,0,0]);
return this.transformChildren(inst.children, context, function(){
if (v[0] != 0 || v[1] != 0 || v[2] != 0)
return _.template('.translate([<%=v%>])', {v:v});
else return "";
});
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment