@@ -592,6 +592,55 @@ CHECK_RETURN bool parser::parseLayout(topLevel ¤t) {
592592 return true ;
593593}
594594
595+ static bool isInterfaceBlockStorage (int storage) {
596+ return storage == kIn
597+ || storage == kOut
598+ || storage == kUniform
599+ || storage == kBuffer ;
600+ }
601+
602+ static bool isReservedKeyword (int keyword) {
603+ return keyword == kKeyword_common
604+ || keyword == kKeyword_partition
605+ || keyword == kKeyword_active
606+ || keyword == kKeyword_asm
607+ || keyword == kKeyword_class
608+ || keyword == kKeyword_union
609+ || keyword == kKeyword_enum
610+ || keyword == kKeyword_typedef
611+ || keyword == kKeyword_template
612+ || keyword == kKeyword_this
613+ || keyword == kKeyword_resource
614+ || keyword == kKeyword_goto
615+ || keyword == kKeyword_inline
616+ || keyword == kKeyword_noinline
617+ || keyword == kKeyword_public
618+ || keyword == kKeyword_static
619+ || keyword == kKeyword_extern
620+ || keyword == kKeyword_external
621+ || keyword == kKeyword_interface
622+ || keyword == kKeyword_long
623+ || keyword == kKeyword_short
624+ || keyword == kKeyword_half
625+ || keyword == kKeyword_fixed
626+ || keyword == kKeyword_unsigned
627+ || keyword == kKeyword_superp
628+ || keyword == kKeyword_input
629+ || keyword == kKeyword_output
630+ || keyword == kKeyword_hvec2
631+ || keyword == kKeyword_hvec3
632+ || keyword == kKeyword_hvec4
633+ || keyword == kKeyword_fvec2
634+ || keyword == kKeyword_fvec3
635+ || keyword == kKeyword_fvec4
636+ || keyword == kKeyword_sampler3DRect
637+ || keyword == kKeyword_filter
638+ || keyword == kKeyword_sizeof
639+ || keyword == kKeyword_cast
640+ || keyword == kKeyword_namespace
641+ || keyword == kKeyword_using ;
642+ }
643+
595644CHECK_RETURN bool parser::parseTopLevelItem (topLevel &level, topLevel *continuation) {
596645 vector<topLevel> items;
597646 while (!isBuiltin () && !isType (kType_identifier )) {
@@ -600,20 +649,38 @@ CHECK_RETURN bool parser::parseTopLevelItem(topLevel &level, topLevel *continuat
600649 if (IS_TYPE (peek, kType_eof ))
601650 return false ;
602651
603- topLevel next ;
652+ topLevel item ;
604653 if (continuation)
605- next = *continuation;
606-
607- if (!parseStorage (next)) return false ;
608- if (!parseAuxiliary (next)) return false ;
609- if (!parseInterpolation (next)) return false ;
610- if (!parsePrecision (next)) return false ;
611- if (!parseInvariant (next)) return false ;
612- if (!parsePrecise (next)) return false ;
613- if (!parseMemory (next)) return false ;
614- if (!parseLayout (next)) return false ;
615-
616- if (isKeyword (kKeyword_struct )) {
654+ item = *continuation;
655+
656+ if (!parseStorage (item)) return false ;
657+ if (!parseAuxiliary (item)) return false ;
658+ if (!parseInterpolation (item)) return false ;
659+ if (!parsePrecision (item)) return false ;
660+ if (!parseInvariant (item)) return false ;
661+ if (!parsePrecise (item)) return false ;
662+ if (!parseMemory (item)) return false ;
663+ if (!parseLayout (item)) return false ;
664+
665+ if (isType (kType_keyword ) && isReservedKeyword (m_token.asKeyword )) {
666+ fatal (" cannot use a reserved keyword" );
667+ return false ;
668+ }
669+
670+ // Check for interface block.
671+ if (isType (kType_identifier ) && isInterfaceBlockStorage (item.storage )) {
672+ // if (!next()) return false; // skip identifier
673+ astInterfaceBlock *unique = parseInterfaceBlock (item.storage );
674+ if (!unique)
675+ return false ;
676+ m_ast->interfaceBlocks .push_back (unique);
677+ if (isType (kType_semicolon )) {
678+ return true ;
679+ } else {
680+ level.type = unique;
681+ }
682+ } else if (isKeyword (kKeyword_struct )) {
683+ if (!next ()) return 0 ; // skip struct
617684 astStruct *unique = parseStruct ();
618685 if (!unique)
619686 return false ;
@@ -625,7 +692,7 @@ CHECK_RETURN bool parser::parseTopLevelItem(topLevel &level, topLevel *continuat
625692 level.type = unique;
626693 }
627694 } else {
628- items.push_back (next );
695+ items.push_back (item );
629696 }
630697 }
631698
@@ -811,18 +878,17 @@ CHECK_RETURN bool parser::parseTopLevel(vector<topLevel> &items) {
811878 return true ;
812879}
813880
814- CHECK_RETURN astStruct *parser::parseStruct () {
815- if (!next ()) return 0 ; // skip struct
816-
817- astStruct *unique = GC_NEW (astType) astStruct;
881+ template <typename T>
882+ CHECK_RETURN T *parser::parseBlock (const char * type) {
883+ T *unique = GC_NEW (astType) T;
818884
819885 if (isType (kType_identifier )) {
820886 unique->name = strnew (m_token.asIdentifier );
821887 if (!next ()) return 0 ; // skip identifier
822888 }
823889
824890 if (!isType (kType_scope_begin )) {
825- fatal (" expected '{' for structure definition" );
891+ fatal (" expected '{' for %s definition" , type );
826892 return 0 ;
827893 }
828894
@@ -852,6 +918,52 @@ CHECK_RETURN astStruct *parser::parseStruct() {
852918 return unique;
853919}
854920
921+ CHECK_RETURN astStruct *parser::parseStruct () {
922+ return parseBlock<astStruct>(" structure" );
923+ }
924+
925+ CHECK_RETURN astInterfaceBlock *parser::parseInterfaceBlock (int storage) {
926+ astInterfaceBlock* unique = 0 ;
927+ switch (storage) {
928+ case kIn :
929+ unique = parseBlock<astInterfaceBlock>(" input block" );
930+ break ;
931+ case kOut :
932+ unique = parseBlock<astInterfaceBlock>(" outout block" );
933+ break ;
934+ case kUniform :
935+ unique = parseBlock<astInterfaceBlock>(" uniform block" );
936+ break ;
937+ case kBuffer :
938+ unique = parseBlock<astInterfaceBlock>(" buffer block" );
939+ break ;
940+ }
941+
942+ if (!unique) {
943+ return 0 ;
944+ }
945+
946+ // When there's no identifier then implicitly declare these as globals
947+ // in their respective places.
948+ if (!isType (kType_identifier )) {
949+ const size_t n_fields = unique->fields .size ();
950+ for (size_t i = 0 ; i < n_fields; i++) {
951+ // Check if the variable already exists
952+ astVariable *variable = unique->fields [i];
953+ if (findVariable (variable->name )) {
954+ fatal (" '%s` is already declared in this scope" , variable->name );
955+ return 0 ;
956+ }
957+ m_scopes.back ().push_back (unique->fields [i]);
958+ }
959+ }
960+
961+ unique->storage = storage;
962+ return unique;
963+
964+ return 0 ;
965+ }
966+
855967CHECK_RETURN astExpression *parser::parseBinary (int lhsPrecedence, astExpression *lhs, endCondition end) {
856968 // Precedence climbing
857969 while (!isEndCondition (end)) {
0 commit comments