@@ -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 {
@@ -219,6 +219,49 @@ shader_or_function_declaration
219219 }
220220 ;
221221
222+ method_declaration
223+ : typespec_or_shadertype typespec ':' ':' IDENTIFIER
224+ {
225+ // It's a method declaration, not a shader
226+ if ($1 != ShadTypeUnknown || typespec_stack.empty() ||
227+ (! oslcompiler->current_typespec().is_structure() &&
228+ ! oslcompiler->current_typespec().is_triple())) {
229+ oslcompiler->error (oslcompiler->filename(),
230+ oslcompiler->lineno(),
231+ "Cannot declare a method for this type");
232+ }
233+
234+ oslcompiler->symtab().push (); // new scope
235+ typespec_stack.push (oslcompiler->current_typespec());
236+ }
237+ '(' formal_params_opt ')' metadata_block_opt
238+ {
239+ implicit_this = new ASTvariable_declaration(oslcompiler,
240+ typespec_stack.top(),
241+ $8);
242+ typespec_stack.pop ();
243+ $<n>$ = implicit_this.get();
244+ }
245+ function_body_or_just_decl
246+ {
247+ // Method declaration
248+ ASSERT ($1 == ShadTypeUnknown);
249+ oslcompiler->symtab().pop (); // restore scope
250+ ASTfunction_declaration *f;
251+ f = new ASTfunction_declaration (oslcompiler,
252+ typespec_stack.top(),
253+ ustring($5),
254+ $<n>11 /* arguments*/ ,
255+ $12 /* statements*/ ,
256+ $10 /* meta*/ );
257+ implicit_this = nullptr;
258+ typespec_stack.pop ();
259+ oslcompiler->remember_function_decl (f);
260+ f->sourceline (@2.first_line);
261+ $$ = f;
262+ }
263+ ;
264+
222265formal_params_opt
223266 : formal_params
224267 | /* empty */ { $$ = 0; }
@@ -581,12 +624,14 @@ typespec_or_shadertype
581624 : simple_typename
582625 {
583626 oslcompiler->current_typespec (TypeSpec (osllextype ($1)));
584- $$ = 0;
627+ typespec_stack.push (oslcompiler->current_typespec ());
628+ $$ = ShadTypeUnknown;
585629 }
586630 | CLOSURE simple_typename
587631 {
588632 oslcompiler->current_typespec (TypeSpec (osllextype ($2), true));
589- $$ = 0;
633+ typespec_stack.push (oslcompiler->current_typespec ());
634+ $$ = ShadTypeUnknown;
590635 }
591636 | IDENTIFIER /* struct name or shader type name */
592637 {
@@ -601,9 +646,10 @@ typespec_or_shadertype
601646 $$ = ShadTypeVolume;
602647 else {
603648 Symbol *s = oslcompiler->symtab().find (name);
604- if (s && s->is_structure())
649+ if (s && s->is_structure()) {
605650 oslcompiler->current_typespec (TypeSpec ("", s->typespec().structure()));
606- else {
651+ typespec_stack.push (oslcompiler->current_typespec ());
652+ } else {
607653 oslcompiler->current_typespec (TypeSpec (TypeDesc::UNKNOWN));
608654 oslcompiler->error (oslcompiler->filename(),
609655 oslcompiler->lineno(),
0 commit comments