diff options
-rw-r--r-- | dimension/common.rules | 71 | ||||
-rw-r--r-- | dimension/common.terminals | 2 | ||||
-rw-r--r-- | dimension/lexer.l | 1 | ||||
-rw-r--r-- | tests/dimension/directives.pov | 15 | ||||
-rwxr-xr-x | tests/dimension/directives.sh | 28 |
5 files changed, 106 insertions, 11 deletions
diff --git a/dimension/common.rules b/dimension/common.rules index 86b86ef..3d6fd0a 100644 --- a/dimension/common.rules +++ b/dimension/common.rules @@ -115,6 +115,61 @@ CAMERA_MODIFIER: "angle" FLOAT { OBJECT: FINITE_SOLID_OBJECT | LIGHT_SOURCE + | "object" "{" + IDENTIFIER + OBJECT_MODIFIERS + "}" + { + dmnsn_astnode *object = dmnsn_find_symbol(symtable, $3.ptr); + if (!object) { + dmnsn_diagnostic(@3.first_filename, @3.first_line, + @3.first_column, + "unbound identifier '%s'", + (const char *)$3.ptr); + dmnsn_delete_astnode($3); + YYERROR; + } else { + switch (object->type) { + case DMNSN_AST_BOX: + case DMNSN_AST_SPHERE: + case DMNSN_AST_LIGHT_SOURCE: + { + 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); + + unsigned int i; + for (i = 0; i < dmnsn_array_size($4.children); ++i) { + dmnsn_astnode astnode; + dmnsn_array_get($4.children, i, &astnode); + dmnsn_array_push(modifiers->children, &astnode); + } + break; + } + + default: + dmnsn_diagnostic(@3.first_filename, @3.first_line, + @3.first_column, + "identifier '%s' is a %s; expected an object type", + (const char *)$3.ptr, + dmnsn_astnode_string(object->type)); + dmnsn_delete_astnode($3); + YYERROR; + break; + } + } + } ; FINITE_SOLID_OBJECT: BOX @@ -130,14 +185,6 @@ BOX: "box" "{" } ; -LIGHT_SOURCE: "light_source" "{" - VECTOR "," COLOR - "}" - { - $$ = dmnsn_new_astnode2(DMNSN_AST_LIGHT_SOURCE, @$, $3, $5); - } -; - SPHERE: "sphere" "{" VECTOR "," FLOAT OBJECT_MODIFIERS @@ -147,6 +194,14 @@ SPHERE: "sphere" "{" } ; +LIGHT_SOURCE: "light_source" "{" + VECTOR "," COLOR + "}" + { + $$ = dmnsn_new_astnode2(DMNSN_AST_LIGHT_SOURCE, @$, $3, $5); + } +; + /* Object modifiers */ OBJECT_MODIFIERS: /* empty */ { diff --git a/dimension/common.terminals b/dimension/common.terminals index 089fe29..7ed8d98 100644 --- a/dimension/common.terminals +++ b/dimension/common.terminals @@ -306,7 +306,7 @@ %token DMNSN_T_NORMAL_MAP %token DMNSN_T_NORMAL_VECTORS %token DMNSN_T_NUMBER_OF_WAVES -%token DMNSN_T_OBJECT +%token DMNSN_T_OBJECT "object" %token DMNSN_T_OCTAVES %token DMNSN_T_OFF "off" %token DMNSN_T_OFFSET diff --git a/dimension/lexer.l b/dimension/lexer.l index 94bacee..2fb37cd 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -220,6 +220,7 @@ unsigned long wchar; "min" RETURN_TOKEN(DMNSN_T_MIN); "mod" RETURN_TOKEN(DMNSN_T_MOD); "no" RETURN_TOKEN(DMNSN_T_NO); +"object" RETURN_TOKEN(DMNSN_T_OBJECT); "off" RETURN_TOKEN(DMNSN_T_OFF); "on" RETURN_TOKEN(DMNSN_T_ON); "perspective" RETURN_TOKEN(DMNSN_T_PERSPECTIVE); diff --git a/tests/dimension/directives.pov b/tests/dimension/directives.pov index e4721fc..634c2e9 100644 --- a/tests/dimension/directives.pov +++ b/tests/dimension/directives.pov @@ -63,3 +63,18 @@ Inc(Counter) #end + +#declare Box = + box { + <-1, -1, -1>, <1, 1, 1> + pigment { + color rgb <1, 1, 1> + } + } + +object { + Box + finish { + phong 0.2 + } +} diff --git a/tests/dimension/directives.sh b/tests/dimension/directives.sh index 713a1fe..1e487c4 100755 --- a/tests/dimension/directives.sh +++ b/tests/dimension/directives.sh @@ -54,7 +54,23 @@ directives_exp="$(echo -n \ (identifier "Make_Sphere") \( (identifier "Counter") \) #end (identifier "Inc") \( (identifier "Counter") \) - #end)' \ + #end + + #declare (identifier "Box") = + box { + < - (integer "1") , - (integer "1") , - (integer "1") > , + < (integer "1") , (integer "1") , (integer "1") > + pigment { + color rgb < (integer "1") , (integer "1") , (integer "1") > + } + } + + object { + (identifier "Box") + finish { + phong (float "0.2") + } + })' \ | tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g') $(echo -n \ '((sphere @@ -68,7 +84,15 @@ $(echo -n \ (integer 1) (object-modifiers (pigment (vector (integer 1) (integer 1) (integer 1) - (integer 0) (integer 0))))))' \ + (integer 0) (integer 0))))) + (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))) + (finish + (phong (float 0.2))))))' \ | tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')" if [ "$directives" != "$directives_exp" ]; then |