@@ -97,7 +97,7 @@ static ASTNode::ref implicit_this;
97
97
// Define the nonterminals
98
98
%type <n> shader_file
99
99
%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
101
101
%type <n> formal_params_opt formal_params formal_param
102
102
%type <n> metadata_block_opt metadata metadatum
103
103
%type <n> function_declaration
@@ -166,21 +166,21 @@ global_declarations
166
166
global_declaration
167
167
: shader_or_function_declaration { $$ = 0; }
168
168
| struct_declaration { $$ = 0; }
169
+ | method_declaration { $$ = 0; }
169
170
;
170
171
171
172
shader_or_function_declaration
172
173
: typespec_or_shadertype IDENTIFIER
173
174
{
174
175
if ($1 == ShadTypeUnknown) {
175
176
// It's a function declaration, not a shader
177
+ ASSERT (! typespec_stack.empty ());
176
178
oslcompiler->symtab().push (); // new scope
177
- typespec_stack.push (oslcompiler->current_typespec());
178
179
}
179
180
}
180
181
metadata_block_opt '('
181
182
{
182
- if ($1 != ShadTypeUnknown)
183
- oslcompiler->declaring_shader_formals (true);
183
+ oslcompiler->declaring_shader_formals ($1 != ShadTypeUnknown);
184
184
}
185
185
formal_params_opt ')'
186
186
{
@@ -220,6 +220,49 @@ shader_or_function_declaration
220
220
}
221
221
;
222
222
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
+
223
266
formal_params_opt
224
267
: formal_params
225
268
| /* empty */ { $$ = 0; }
@@ -586,12 +629,14 @@ typespec_or_shadertype
586
629
: simple_typename
587
630
{
588
631
oslcompiler->current_typespec (TypeSpec (osllextype ($1)));
589
- $$ = 0;
632
+ typespec_stack.push (oslcompiler->current_typespec ());
633
+ $$ = ShadTypeUnknown;
590
634
}
591
635
| CLOSURE simple_typename
592
636
{
593
637
oslcompiler->current_typespec (TypeSpec (osllextype ($2), true));
594
- $$ = 0;
638
+ typespec_stack.push (oslcompiler->current_typespec ());
639
+ $$ = ShadTypeUnknown;
595
640
}
596
641
| IDENTIFIER /* struct name or shader type name */
597
642
{
@@ -606,9 +651,10 @@ typespec_or_shadertype
606
651
$$ = ShadTypeVolume;
607
652
else {
608
653
Symbol *s = oslcompiler->symtab().find (name);
609
- if (s && s->is_structure())
654
+ if (s && s->is_structure()) {
610
655
oslcompiler->current_typespec (TypeSpec ("", s->typespec().structure()));
611
- else {
656
+ typespec_stack.push (oslcompiler->current_typespec ());
657
+ } else {
612
658
oslcompiler->current_typespec (TypeSpec (TypeDesc::UNKNOWN));
613
659
oslcompiler->error (oslcompiler->filename(),
614
660
oslcompiler->lineno(),
0 commit comments