Module decl_structure = Begin Require 'bliss.req'; ! parse macro/structure parameters Global Routine parse_params(TYP : Integer,INITOFF : Integer,RBRACK : Integer) = Begin Local PARAM : Ref ST, OFFST; ! skip over the '['/'(' and get the first name OFFST = .INITOFF; RUND(QL_NAME); ! if an empty parameter list (e.g. '()' then make it look like there ! were no parameters at all. ! ! why is 'MACRO FOO' treated the same as 'MACRO FOO()'? If .SYM Eql NIL And .DEL Eql .RBRACK Then Begin RUNDE(); Return 0 End; ! loop for each parameter While TRUE Do Begin If DECLARESYM(PARAM,.TYP,0) Then Begin PARAM[st_which] = .OFFST; OFFST = .OFFST+1 End; If .DEL Neq TK_COMMA Then Exitloop; RUND(QL_NAME); End; ! check for the closing bracket If .DEL Neq .RBRACK Then Begin ERROR(.pos_open,.pos_del,0,B11$_MISSING_BRACKET); Return 0 End; RUNDE(); Return .OFFST - .INITOFF End; ! STRUCTURE declaration Global Routine decl_structure : Novalue = Begin Local SAVENME : Ref ST, n : Integer, STREAM : Ref Vector; ! cannot define a structure while in another structure definition ! or inside a macro definition. this is due to the stream mechanisms ! in use. If .flg_macro_body Or .flg_struct_body Then STOP(9); ! loop for each structure to declare Do Begin ! get the structure name and declare it as a structure RUND(QL_NAME); SAVENME = .SYM; If Not DECLARESYM(sym_define,S_STRUCTURE,TRUE) Then Return; ! note a redeclaration of 'VECTOR' If .SAVENME Eql .sym_vector[st_name] Then sym_vector = .sym_define; ! structure arguments go in their own scope RaiseScope(); ! note the level if this structure definition. symbols encountered ! inside this level are kept as names. symbols outside it are bound. level_structure = .level_block; ! structure formals are numbered starting at 2. index 0 is ! reserved for the structure itself and index 1 is reserved for ! the structure allocation unit. ! ! Q: what does it mean to have a structure with no parameters? If .del Eql TK_LBRACKET Then n = parse_params(S_STRUCT_ARG,2,TK_RBRACKET) Else n = 0; sym_define[st_str_argc] = .n; ! '=' separates parameters from body If .DEL Neq TK_EQUAL Then Begin ERROR(.pos_open,.pos_del,0,B11$_MISSING_EQUAL); Return End; ! skip over the '='. a '[' indicates the start of an allocation ! expression RUND(QL_LEXEME); If .SYM Eql NIL And .DEL Eql TK_LBRACKET Then Begin RUND(QL_LEXEME); STREAM = struct_parse(TRUE); If .DEL Neq TK_RBRACKET Then Begin ERROR(.pos_open,.pos_del,0,B11$_MISSING_BRACKET); Return End; DEL = TK_EQUAL; !HIDE THE SPECIAL USE OF [] FROM LEXAN RUND(QL_LEXEME); sym_define[st_str_alloc] = .STREAM End Else sym_define[st_str_alloc] = 0; ! parse the structure body sym_define[st_str_body] = struct_parse(FALSE); level_structure = 999; LowerScope() End While .DEL Eql TK_COMMA End; End Eludom