From db09a6bc5bb5da674abf7b5f8874a57ef2cf4dfb Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 19 Jun 2010 10:32:41 -0400 Subject: Abstract syntax tree improvements. Keep objects in a single DMNSN_AST_OBJECT node type. --- dimension/common.rules | 84 +++++++++++++++++------------------ dimension/grammar.epilogue | 1 + dimension/parse.h | 1 + dimension/realize.c | 91 ++++++++++++++++---------------------- tests/dimension/arithexp.sh | 9 ++-- tests/dimension/csg.sh | 35 ++++++++------- tests/dimension/demo.sh | 26 ++++++----- tests/dimension/directives.sh | 23 +++++----- tests/dimension/transformations.sh | 7 +-- 9 files changed, 138 insertions(+), 139 deletions(-) diff --git a/dimension/common.rules b/dimension/common.rules index 77830a6..c2b9fda 100644 --- a/dimension/common.rules +++ b/dimension/common.rules @@ -229,48 +229,35 @@ OBJECT: FINITE_SOLID_OBJECT YYERROR; } - switch (object->type) { - case DMNSN_AST_BOX: - case DMNSN_AST_DIFFERENCE: - case DMNSN_AST_INTERSECTION: - case DMNSN_AST_LIGHT_SOURCE: - case DMNSN_AST_MERGE: - case DMNSN_AST_PLANE: - case DMNSN_AST_SPHERE: - case DMNSN_AST_UNION: - { - dmnsn_delete_astnode($3); - - $$ = dmnsn_new_astnode(object->type, @$); - dmnsn_copy_children($$, *object); - - dmnsn_astnode *modifiers, orig_modifiers; - modifiers = dmnsn_array_at($$.children, - dmnsn_array_size($$.children) - 1); - dmnsn_array_get(object->children, - dmnsn_array_size(object->children) - 1, - &orig_modifiers); - dmnsn_delete_astnode(*modifiers); - *modifiers = dmnsn_new_astnode(DMNSN_AST_OBJECT_MODIFIERS, @4); - dmnsn_copy_children(*modifiers, orig_modifiers); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, astnode, $4.children) { - ++*astnode->refcount; - dmnsn_array_push(modifiers->children, astnode); - } - dmnsn_delete_astnode($4); - break; - } + if (object->type == DMNSN_AST_OBJECT) { + dmnsn_delete_astnode($3); - default: + $$ = dmnsn_new_astnode(object->type, @$); + dmnsn_copy_children($$, *object); + + dmnsn_astnode *modifiers, orig_modifiers; + modifiers = dmnsn_array_at($$.children, 1); + dmnsn_array_get(object->children, + dmnsn_array_size(object->children) - 1, + &orig_modifiers); + dmnsn_delete_astnode(*modifiers); + *modifiers = dmnsn_new_astnode(DMNSN_AST_OBJECT_MODIFIERS, @4); + dmnsn_copy_children(*modifiers, orig_modifiers); + + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, astnode, $4.children) { + ++*astnode->refcount; + dmnsn_array_push(modifiers->children, astnode); + } + dmnsn_delete_astnode($4); + } else { dmnsn_diagnostic(@3, - "identifier '%s' is a %s; expected an object type", + "identifier '%s' is a %s; expected an %s", (const char *)$3.ptr, - dmnsn_astnode_string(object->type)); + dmnsn_astnode_string(object->type), + dmnsn_astnode_string(DMNSN_AST_OBJECT)); dmnsn_delete_astnode($3); dmnsn_delete_astnode($4); YYERROR; - break; } } | "object" "{" @@ -303,7 +290,8 @@ BOX: "box" "{" OBJECT_MODIFIERS "}" { - $$ = dmnsn_new_astnode3(DMNSN_AST_BOX, @$, $3, $5, $6); + dmnsn_astnode object = dmnsn_new_astnode2(DMNSN_AST_BOX, @$, $3, $5); + $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $6); } ; @@ -312,7 +300,8 @@ SPHERE: "sphere" "{" OBJECT_MODIFIERS "}" { - $$ = dmnsn_new_astnode3(DMNSN_AST_SPHERE, @$, $3, $5, $6); + dmnsn_astnode object = dmnsn_new_astnode2(DMNSN_AST_SPHERE, @$, $3, $5); + $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $6); } ; @@ -324,7 +313,8 @@ PLANE: "plane" "{" OBJECT_MODIFIERS "}" { - $$ = dmnsn_new_astnode3(DMNSN_AST_PLANE, @$, $3, $5, $6); + dmnsn_astnode object = dmnsn_new_astnode2(DMNSN_AST_PLANE, @$, $3, $5); + $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $6); } ; @@ -339,7 +329,9 @@ UNION: "union" "{" OBJECT_MODIFIERS "}" { - $$ = dmnsn_new_astnode2(DMNSN_AST_UNION, @$, $3, $4); + dmnsn_astnode csg_union = $3; + csg_union.type = DMNSN_AST_UNION; + $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, csg_union, $4); } ; @@ -348,7 +340,9 @@ INTERSECTION: "intersection" "{" OBJECT_MODIFIERS "}" { - $$ = dmnsn_new_astnode2(DMNSN_AST_INTERSECTION, @$, $3, $4); + dmnsn_astnode intersection = $3; + intersection.type = DMNSN_AST_INTERSECTION; + $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, intersection, $4); } ; @@ -357,7 +351,9 @@ DIFFERENCE: "difference" "{" OBJECT_MODIFIERS "}" { - $$ = dmnsn_new_astnode2(DMNSN_AST_DIFFERENCE, @$, $3, $4); + dmnsn_astnode difference = $3; + difference.type = DMNSN_AST_DIFFERENCE; + $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, difference, $4); } ; @@ -366,7 +362,9 @@ MERGE: "merge" "{" OBJECT_MODIFIERS "}" { - $$ = dmnsn_new_astnode2(DMNSN_AST_MERGE, @$, $3, $4); + dmnsn_astnode merge = $3; + merge.type = DMNSN_AST_MERGE; + $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, merge, $4); } ; diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue index 073f412..25d678a 100644 --- a/dimension/grammar.epilogue +++ b/dimension/grammar.epilogue @@ -132,6 +132,7 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type) dmnsn_astnode_map(DMNSN_AST_LOOK_AT, "look_at"); dmnsn_astnode_map(DMNSN_AST_DIRECTION, "direction"); + dmnsn_astnode_map(DMNSN_AST_OBJECT, "object"); dmnsn_astnode_map(DMNSN_AST_BOX, "box"); dmnsn_astnode_map(DMNSN_AST_DIFFERENCE, "difference"); dmnsn_astnode_map(DMNSN_AST_INTERSECTION, "intersection"); diff --git a/dimension/parse.h b/dimension/parse.h index fd78665..c47363f 100644 --- a/dimension/parse.h +++ b/dimension/parse.h @@ -46,6 +46,7 @@ typedef enum { DMNSN_AST_LOOK_AT, DMNSN_AST_DIRECTION, + DMNSN_AST_OBJECT, DMNSN_AST_BOX, DMNSN_AST_DIFFERENCE, DMNSN_AST_INTERSECTION, diff --git a/dimension/realize.c b/dimension/realize.c index a9b9c71..160bf79 100644 --- a/dimension/realize.c +++ b/dimension/realize.c @@ -843,10 +843,6 @@ dmnsn_realize_box(dmnsn_astnode astnode) box->trans ); - dmnsn_astnode modifiers; - dmnsn_array_get(astnode.children, 2, &modifiers); - dmnsn_realize_object_modifiers(modifiers, box); - return box; } @@ -863,14 +859,8 @@ dmnsn_realize_sphere(dmnsn_astnode astnode) double r = dmnsn_realize_float(radius); dmnsn_object *sphere = dmnsn_new_sphere(); - sphere->trans = dmnsn_scale_matrix(dmnsn_new_vector(r, r, r)); sphere->trans = dmnsn_matrix_mul(dmnsn_translation_matrix(x0), sphere->trans); - - dmnsn_astnode modifiers; - dmnsn_array_get(astnode.children, 2, &modifiers); - dmnsn_realize_object_modifiers(modifiers, sphere); - return sphere; } @@ -888,11 +878,6 @@ dmnsn_realize_plane(dmnsn_astnode astnode) dmnsn_object *plane = dmnsn_new_plane(n); plane->trans = dmnsn_translation_matrix(dmnsn_vector_mul(d, n)); - - dmnsn_astnode modifiers; - dmnsn_array_get(astnode.children, 2, &modifiers); - dmnsn_realize_object_modifiers(modifiers, plane); - return plane; } @@ -902,15 +887,10 @@ dmnsn_realize_union(dmnsn_astnode astnode, dmnsn_array *lights) { dmnsn_assert(astnode.type == DMNSN_AST_UNION, "Expected a union."); - dmnsn_astnode objects, modifiers; - dmnsn_array_get(astnode.children, 0, &objects); - dmnsn_array_get(astnode.children, 1, &modifiers); - dmnsn_array *children = dmnsn_new_array(sizeof(dmnsn_object *)); - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, onode, objects.children) { + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, onode, astnode.children) { if (onode->type == DMNSN_AST_LIGHT_SOURCE) { dmnsn_light *light = dmnsn_realize_light_source(*onode); - dmnsn_realize_light_source_modifiers(modifiers, light); dmnsn_array_push(lights, &light); } else { dmnsn_object *object = dmnsn_realize_object(*onode, lights); @@ -920,11 +900,8 @@ dmnsn_realize_union(dmnsn_astnode astnode, dmnsn_array *lights) } dmnsn_object *csg = NULL; - if (dmnsn_array_size(children) > 0) { + if (dmnsn_array_size(children) > 0) csg = dmnsn_new_csg_union(children); - dmnsn_realize_object_modifiers(modifiers, csg); - } - dmnsn_delete_array(children); return csg; } @@ -936,19 +913,14 @@ static dmnsn_object * dmnsn_realize_csg(dmnsn_astnode astnode, dmnsn_array *lights, dmnsn_csg_object_fn *csg_object_fn) { - dmnsn_astnode objects, modifiers; - dmnsn_array_get(astnode.children, 0, &objects); - dmnsn_array_get(astnode.children, 1, &modifiers); - dmnsn_object *csg = NULL; dmnsn_astnode *onode; - for (onode = dmnsn_array_first(objects.children); - onode <= (dmnsn_astnode *)dmnsn_array_last(objects.children); + for (onode = dmnsn_array_first(astnode.children); + onode <= (dmnsn_astnode *)dmnsn_array_last(astnode.children); ++onode) { if (onode->type == DMNSN_AST_LIGHT_SOURCE) { dmnsn_light *light = dmnsn_realize_light_source(*onode); - dmnsn_realize_light_source_modifiers(modifiers, light); dmnsn_array_push(lights, &light); } else { csg = dmnsn_realize_object(*onode, lights); @@ -957,12 +929,11 @@ dmnsn_realize_csg(dmnsn_astnode astnode, dmnsn_array *lights, } for (++onode; - onode <= (dmnsn_astnode *)dmnsn_array_last(objects.children); + onode <= (dmnsn_astnode *)dmnsn_array_last(astnode.children); ++onode) { if (onode->type == DMNSN_AST_LIGHT_SOURCE) { dmnsn_light *light = dmnsn_realize_light_source(*onode); - dmnsn_realize_light_source_modifiers(modifiers, light); dmnsn_array_push(lights, &light); } else { dmnsn_object *object = dmnsn_realize_object(*onode, lights); @@ -970,8 +941,6 @@ dmnsn_realize_csg(dmnsn_astnode astnode, dmnsn_array *lights, } } - if (csg) - dmnsn_realize_object_modifiers(modifiers, csg); return csg; } @@ -1001,21 +970,37 @@ dmnsn_realize_merge(dmnsn_astnode astnode, dmnsn_array *lights) static dmnsn_object * dmnsn_realize_object(dmnsn_astnode astnode, dmnsn_array *lights) { - switch (astnode.type) { + dmnsn_assert(astnode.type == DMNSN_AST_OBJECT + || astnode.type == DMNSN_AST_LIGHT_SOURCE, + "Expected an object."); + + dmnsn_astnode onode; + dmnsn_array_get(astnode.children, 0, &onode); + + dmnsn_object *object = NULL; + + switch (onode.type) { case DMNSN_AST_BOX: - return dmnsn_realize_box(astnode); + object = dmnsn_realize_box(onode); + break; case DMNSN_AST_DIFFERENCE: - return dmnsn_realize_difference(astnode, lights); + object = dmnsn_realize_difference(onode, lights); + break; case DMNSN_AST_INTERSECTION: - return dmnsn_realize_intersection(astnode, lights); + object = dmnsn_realize_intersection(onode, lights); + break; case DMNSN_AST_MERGE: - return dmnsn_realize_merge(astnode, lights); + object = dmnsn_realize_merge(onode, lights); + break; case DMNSN_AST_PLANE: - return dmnsn_realize_plane(astnode); + object = dmnsn_realize_plane(onode); + break; case DMNSN_AST_SPHERE: - return dmnsn_realize_sphere(astnode); + object = dmnsn_realize_sphere(onode); + break; case DMNSN_AST_UNION: - return dmnsn_realize_union(astnode, lights); + object = dmnsn_realize_union(onode, lights); + break; case DMNSN_AST_LIGHT_SOURCE: { @@ -1025,9 +1010,15 @@ dmnsn_realize_object(dmnsn_astnode astnode, dmnsn_array *lights) } default: - dmnsn_assert(false, "Expected an object."); - return NULL; /* Shut up compiler */ + dmnsn_assert(false, "Expected an object type."); + } + + if (object) { + dmnsn_astnode modifiers; + dmnsn_array_get(astnode.children, 1, &modifiers); + dmnsn_realize_object_modifiers(modifiers, object); } + return object; } static dmnsn_scene * @@ -1073,13 +1064,7 @@ dmnsn_realize_astree(const dmnsn_astree *astree) scene->camera = dmnsn_realize_camera(*astnode); break; - case DMNSN_AST_BOX: - case DMNSN_AST_DIFFERENCE: - case DMNSN_AST_INTERSECTION: - case DMNSN_AST_MERGE: - case DMNSN_AST_PLANE: - case DMNSN_AST_SPHERE: - case DMNSN_AST_UNION: + case DMNSN_AST_OBJECT: object = dmnsn_realize_object(*astnode, scene->lights); if (object) dmnsn_array_push(scene->objects, &object); diff --git a/tests/dimension/arithexp.sh b/tests/dimension/arithexp.sh index 014da06..917f6bc 100755 --- a/tests/dimension/arithexp.sh +++ b/tests/dimension/arithexp.sh @@ -21,10 +21,11 @@ arithexp=$(${top_builddir}/dimension/dimension --parse ${srcdir}/arithexp.pov) arithexp_exp="$(echo -n \ -'((sphere - (vector (float 2) (float 2) (float 3) (integer 0) (integer 0)) - (float 0.718282) - object-modifiers))' \ +'((object + (sphere + (vector (float 2) (float 2) (float 3) (integer 0) (integer 0)) + (float 0.718282)) + object-modifiers))' \ | tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')" if [ "$arithexp" != "$arithexp_exp" ]; then diff --git a/tests/dimension/csg.sh b/tests/dimension/csg.sh index 360398c..8a45a78 100755 --- a/tests/dimension/csg.sh +++ b/tests/dimension/csg.sh @@ -30,33 +30,35 @@ csg_exp="$(echo -n \ (integer 0) (integer 0)))) (background (vector (integer 0) (float 0.1) (float 0.2) (float 0.1) (integer 0))) - (union - (array - (sphere - (vector (float -1.5) (float 0) (float 0) (float 0) (float 0)) - (integer 1) + (object + (union + (object + (sphere + (vector (float -1.5) (float 0) (float 0) (float 0) (float 0)) + (integer 1)) (object-modifiers (pigment (vector (integer 1) (integer 0) (integer 0) (integer 0) (integer 0)) pigment-modifiers)))) object-modifiers) - (union - (array + (object + (union (light_source (vector (integer 0) (integer 20) (integer 0) (integer 0) (integer 0)) (vector (float 0.5) (float 0.5) (float 0.5) (integer 0) (integer 0)) object-modifiers)) object-modifiers) - (difference - (array + (object + (difference (light_source (vector (integer -15) (integer 0) (integer 0) (integer 0) (integer 0)) (vector (float 0.5) (float 0.5) (float 0.5) (integer 0) (integer 0)) object-modifiers) - (sphere - (vector (float 1.5) (float -20) (float 0) (float 0) (float 0)) - (integer 1) + (object + (sphere + (vector (float 1.5) (float -20) (float 0) (float 0) (float 0)) + (integer 1)) (object-modifiers (pigment (vector (integer 0) (integer 1) (integer 0) @@ -66,9 +68,12 @@ csg_exp="$(echo -n \ (vector (integer 15) (integer 0) (integer 0) (integer 0) (integer 0)) (vector (float 0.5) (float 0.5) (float 0.5) (integer 0) (integer 0)) object-modifiers) - (box - (vector (float 0.7) (float -20.8) (float -0.8) (integer 0) (integer 0)) - (vector (float 2.3) (float -19.2) (float 0.8) (integer 0) (integer 0)) + (object + (box + (vector (float 0.7) (float -20.8) (float -0.8) + (integer 0) (integer 0)) + (vector (float 2.3) (float -19.2) (float 0.8) + (integer 0) (integer 0))) (object-modifiers (pigment (vector (integer 0) (integer 0) (integer 1) diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh index 18f1c05..a5f05a5 100755 --- a/tests/dimension/demo.sh +++ b/tests/dimension/demo.sh @@ -37,11 +37,13 @@ demo_exp=$(echo -n \ (vector (integer -15) (integer 20) (integer 10) (integer 0) (integer 0)) (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) object-modifiers) - (difference - (array - (box - (vector (integer -1) (integer -1) (integer -1) (integer 0) (integer 0)) - (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) + (object + (difference + (object + (box + (vector (integer -1) (integer -1) (integer -1) + (integer 0) (integer 0)) + (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))) (object-modifiers (transformation (rotation (vector (integer 45) (integer 0) (integer 0) @@ -60,9 +62,10 @@ demo_exp=$(echo -n \ reflection-items))) (interior (ior (float 1.1))))) - (sphere - (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) - (float 1.25) + (object + (sphere + (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) + (float 1.25)) (object-modifiers (texture (pigment @@ -73,9 +76,10 @@ demo_exp=$(echo -n \ (phong (float 0.2)) (phong_size (float 40))))))) object-modifiers) - (plane - (vector (integer 0) (integer 1) (integer 0) (integer 0) (integer 0)) - (integer -2) + (object + (plane + (vector (integer 0) (integer 1) (integer 0) (integer 0) (integer 0)) + (integer -2)) (object-modifiers (pigment (vector (integer 1) (integer 1) (integer 1) diff --git a/tests/dimension/directives.sh b/tests/dimension/directives.sh index 9bd4c24..3e0233c 100755 --- a/tests/dimension/directives.sh +++ b/tests/dimension/directives.sh @@ -73,23 +73,26 @@ directives_exp="$(echo -n \ })' \ | tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g') $(echo -n \ -'((sphere - (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) - (integer 1) +'((object + (sphere + (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) + (integer 1)) (object-modifiers (pigment (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) pigment-modifiers))) - (sphere - (vector (integer 0) (integer 1) (integer 0) (integer 0) (integer 0)) - (integer 1) + (object + (sphere + (vector (integer 0) (integer 1) (integer 0) (integer 0) (integer 0)) + (integer 1)) (object-modifiers (pigment (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) - pigment-modifiers))) - (box - (vector (integer -1) (integer -1) (integer -1) (integer 0) (integer 0)) - (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) + pigment-modifiers))) + (object + (box + (vector (integer -1) (integer -1) (integer -1) (integer 0) (integer 0)) + (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))) (object-modifiers (pigment (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) diff --git a/tests/dimension/transformations.sh b/tests/dimension/transformations.sh index 3e6b8e2..65f8b1b 100755 --- a/tests/dimension/transformations.sh +++ b/tests/dimension/transformations.sh @@ -21,9 +21,10 @@ transformations=$(${top_builddir}/dimension/dimension --parse ${srcdir}/transformations.pov) transformations_exp="$(echo -n \ -'((sphere - (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) - (integer 0) +'((object + (sphere + (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) + (integer 0)) (object-modifiers (transformation (translation -- cgit v1.2.3