summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dimension/common.rules71
-rw-r--r--dimension/common.terminals2
-rw-r--r--dimension/lexer.l1
-rw-r--r--tests/dimension/directives.pov15
-rwxr-xr-xtests/dimension/directives.sh28
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