diff options
Diffstat (limited to 'dimension')
-rw-r--r-- | dimension/common.rules | 71 | ||||
-rw-r--r-- | dimension/common.terminals | 2 | ||||
-rw-r--r-- | dimension/lexer.l | 1 |
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); |