@@ -97,7 +97,7 @@ static ASTNode::ref implicit_this;
9797// Define the nonterminals
9898%type <n> shader_file
9999%type <n> global_declarations_opt global_declarations global_declaration
100- %type <n> shader_or_function_declaration
100+ %type <n> shader_or_function_declaration method_declaration
101101%type <n> formal_params_opt formal_params formal_param
102102%type <n> metadata_block_opt metadata metadatum
103103%type <n> function_declaration
@@ -166,21 +166,21 @@ global_declarations
166166global_declaration
167167 : shader_or_function_declaration { $$ = 0; }
168168 | struct_declaration { $$ = 0; }
169+ | method_declaration { $$ = 0; }
169170 ;
170171
171172shader_or_function_declaration
172173 : typespec_or_shadertype IDENTIFIER
173174 {
174175 if ($1 == ShadTypeUnknown) {
175176 // It's a function declaration, not a shader
177+ ASSERT (! typespec_stack.empty ());
176178 oslcompiler->symtab().push (); // new scope
177- typespec_stack.push (oslcompiler->current_typespec());
178179 }
179180 }
180181 metadata_block_opt '('
181182 {
182- if ($1 != ShadTypeUnknown)
183- oslcompiler->declaring_shader_formals (true);
183+ oslcompiler->declaring_shader_formals ($1 != ShadTypeUnknown);
184184 }
185185 formal_params_opt ')'
186186 {
@@ -220,6 +220,49 @@ shader_or_function_declaration
220220 }
221221 ;
222222
223+ method_declaration
224+ : typespec_or_shadertype typespec ':' ':' IDENTIFIER
225+ {
226+ // It's a method declaration, not a shader
227+ if ($1 != ShadTypeUnknown || typespec_stack.empty() ||
228+ (! oslcompiler->current_typespec().is_structure() &&
229+ ! oslcompiler->current_typespec().is_triple())) {
230+ oslcompiler->error (oslcompiler->filename(),
231+ oslcompiler->lineno(),
232+ "Cannot declare a method for this type");
233+ }
234+
235+ oslcompiler->symtab().push (); // new scope
236+ typespec_stack.push (oslcompiler->current_typespec());
237+ }
238+ '(' formal_params_opt ')' metadata_block_opt
239+ {
240+ implicit_this = new ASTvariable_declaration(oslcompiler,
241+ typespec_stack.top(),
242+ $8);
243+ typespec_stack.pop ();
244+ $<n>$ = implicit_this.get();
245+ }
246+ function_body_or_just_decl
247+ {
248+ // Method declaration
249+ ASSERT ($1 == ShadTypeUnknown);
250+ oslcompiler->symtab().pop (); // restore scope
251+ ASTfunction_declaration *f;
252+ f = new ASTfunction_declaration (oslcompiler,
253+ typespec_stack.top(),
254+ ustring($5),
255+ $<n>11 /* arguments*/ ,
256+ $12 /* statements*/ ,
257+ $10 /* meta*/ );
258+ implicit_this = nullptr;
259+ typespec_stack.pop ();
260+ oslcompiler->remember_function_decl (f);
261+ f->sourceline (@2.first_line);
262+ $$ = f;
263+ }
264+ ;
265+
223266formal_params_opt
224267 : formal_params
225268 | /* empty */ { $$ = 0; }
@@ -586,12 +629,14 @@ typespec_or_shadertype
586629 : simple_typename
587630 {
588631 oslcompiler->current_typespec (TypeSpec (osllextype ($1)));
589- $$ = 0;
632+ typespec_stack.push (oslcompiler->current_typespec ());
633+ $$ = ShadTypeUnknown;
590634 }
591635 | CLOSURE simple_typename
592636 {
593637 oslcompiler->current_typespec (TypeSpec (osllextype ($2), true));
594- $$ = 0;
638+ typespec_stack.push (oslcompiler->current_typespec ());
639+ $$ = ShadTypeUnknown;
595640 }
596641 | IDENTIFIER /* struct name or shader type name */
597642 {
@@ -606,9 +651,10 @@ typespec_or_shadertype
606651 $$ = ShadTypeVolume;
607652 else {
608653 Symbol *s = oslcompiler->symtab().find (name);
609- if (s && s->is_structure())
654+ if (s && s->is_structure()) {
610655 oslcompiler->current_typespec (TypeSpec ("", s->typespec().structure()));
611- else {
656+ typespec_stack.push (oslcompiler->current_typespec ());
657+ } else {
612658 oslcompiler->current_typespec (TypeSpec (TypeDesc::UNKNOWN));
613659 oslcompiler->error (oslcompiler->filename(),
614660 oslcompiler->lineno(),
0 commit comments