summaryrefslogtreecommitdiffstats
path: root/dimension
diff options
context:
space:
mode:
Diffstat (limited to 'dimension')
-rw-r--r--dimension/common.rules71
-rw-r--r--dimension/common.terminals2
-rw-r--r--dimension/lexer.l1
3 files changed, 65 insertions, 9 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);