MODULE M3ASTNext; (***************************************************************************) (* Copyright (C) Olivetti 1989 *) (* All Rights reserved *) (* *) (* Use and copy of this software and preparation of derivative works based *) (* upon this software are permitted to any person, provided this same *) (* copyright notice and the following Olivetti warranty disclaimer are *) (* included in any copy of the software or any modification thereof or *) (* derivative work therefrom made by any person. *) (* *) (* This software is made available AS IS and Olivetti disclaims all *) (* warranties with respect to this software, whether expressed or implied *) (* under any law, including all implied warranties of merchantibility and *) (* fitness for any purpose. In no event shall Olivetti be liable for any *) (* damages whatsoever resulting from loss of use, data or profits or *) (* otherwise arising out of or in connection with the use or performance *) (* of this software. *) (***************************************************************************) (* Copyright (C) 1991, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* ToDo: OVERRIDES *) IMPORT M3AST_LX, M3AST_AS, M3AST_SM; IMPORT M3AST_AS_F, M3AST_SM_F; IMPORT M3CTypesMisc, M3CConcTypeSpec; IMPORT SeqM3AST_AS_Var_decl, SeqM3AST_AS_Fields, SeqM3AST_AS_Formal_param, SeqM3AST_AS_Handler, SeqM3AST_AS_Tcase, SeqM3AST_AS_IMPORTED, SeqM3AST_AS_Case, SeqM3AST_AS_RANGE_EXP, SeqM3AST_AS_Qual_used_id, SeqM3AST_AS_M3TYPE, SeqM3AST_AS_Used_interface_id, SeqM3AST_AS_Var_id, SeqM3AST_AS_Field_id, SeqM3AST_AS_FORMAL_ID, SeqM3AST_AS_Method, SeqM3AST_AS_Override, SeqM3AST_AS_Import_item; (*-------------------------------*) (* FLATTENING COMPLEX ITERATIONS *) (*-------------------------------*) REVEAL IterVar = BRANDED OBJECT iterVar_decl: SeqM3AST_AS_Var_decl.Iter; iterVar_id: SeqM3AST_AS_Var_id.Iter; var_decl: M3AST_AS.Var_decl; END; PROCEDURE NewIterVar(seqVar_decl: SeqM3AST_AS_Var_decl.T): IterVar RAISES {}= BEGIN RETURN NEW(IterVar, iterVar_decl := SeqM3AST_AS_Var_decl.NewIter(seqVar_decl), var_decl := NIL); END NewIterVar; PROCEDURE Var( VAR (* INOUT *) iter: IterVar; VAR (* OUT *) var_id: M3AST_AS.Var_id) : BOOLEAN RAISES {}= BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF iter.var_decl # NIL AND SeqM3AST_AS_Var_id.Next(iter.iterVar_id, var_id) THEN RETURN TRUE; ELSE IF SeqM3AST_AS_Var_decl.Next(iter.iterVar_decl, iter.var_decl) THEN iter.iterVar_id := SeqM3AST_AS_Var_id.NewIter(iter.var_decl.as_id_s); (* loop *) ELSE iter := NIL; RETURN FALSE; END; END; END; (* loop *) END Var; REVEAL IterField = BRANDED OBJECT iterFields: SeqM3AST_AS_Fields.Iter := NIL; iterField_id: SeqM3AST_AS_Field_id.Iter := NIL; fields: M3AST_AS.Fields; END; (* record *) PROCEDURE NewIterField(seqFields: SeqM3AST_AS_Fields.T): IterField RAISES {}= BEGIN RETURN NEW(IterField, iterFields := SeqM3AST_AS_Fields.NewIter(seqFields), fields := NIL); END NewIterField; PROCEDURE Field( VAR (* INOUT *) iter: IterField; VAR (* OUT *) field_id: M3AST_AS.Field_id) : BOOLEAN RAISES {}= BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF iter.fields # NIL AND SeqM3AST_AS_Field_id.Next(iter.iterField_id, field_id) THEN RETURN TRUE; ELSE IF SeqM3AST_AS_Fields.Next(iter.iterFields, iter.fields) THEN iter.iterField_id := SeqM3AST_AS_Field_id.NewIter(iter.fields.as_id_s); (* loop *) ELSE iter := NIL; RETURN FALSE; END; (* if *) END; (* if *) END; (* loop *) END Field; REVEAL IterFormal = BRANDED OBJECT iterFormal_param: SeqM3AST_AS_Formal_param.Iter := NIL; iterFORMAL_ID: SeqM3AST_AS_FORMAL_ID.Iter := NIL; formal_param: M3AST_AS.Formal_param; END; PROCEDURE NewIterFormal( seqFormal_param: SeqM3AST_AS_Formal_param.T) : IterFormal RAISES {}= BEGIN RETURN NEW(IterFormal, iterFormal_param := SeqM3AST_AS_Formal_param.NewIter(seqFormal_param), formal_param := NIL); END NewIterFormal; PROCEDURE Formal( VAR (* INOUT *) iter: IterFormal; VAR (* OUT *) formal_param: M3AST_AS.Formal_param; VAR (* OUT *) formal_id: M3AST_AS.FORMAL_ID) : BOOLEAN RAISES {}= BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF iter.formal_param # NIL AND SeqM3AST_AS_FORMAL_ID.Next(iter.iterFORMAL_ID, formal_id) THEN formal_param := iter.formal_param; RETURN TRUE; ELSE IF SeqM3AST_AS_Formal_param.Next( iter.iterFormal_param, iter.formal_param) THEN iter.iterFORMAL_ID := SeqM3AST_AS_FORMAL_ID.NewIter(iter.formal_param.as_id_s); (* loop *) ELSE iter := NIL; RETURN FALSE; END; (* if *) END; (* if *) END; (* loop *) END Formal; REVEAL IterCaseLabel = BRANDED OBJECT iterCase: SeqM3AST_AS_Case.Iter := NIL; iterRANGE_EXP: SeqM3AST_AS_RANGE_EXP.Iter := NIL; caseArm: M3AST_AS.Case; END; (* record *) PROCEDURE NewIterCaseLabel( seqCase: SeqM3AST_AS_Case.T) : IterCaseLabel RAISES {}= BEGIN RETURN NEW(IterCaseLabel, iterCase := SeqM3AST_AS_Case.NewIter(seqCase), caseArm := NIL); END NewIterCaseLabel; PROCEDURE CaseLabel( VAR (* INOUT *) iter: IterCaseLabel; VAR (* OUT *) case: M3AST_AS.Case; VAR (* OUT *) label: M3AST_AS.RANGE_EXP) : BOOLEAN RAISES {}= BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF iter.caseArm # NIL AND SeqM3AST_AS_RANGE_EXP.Next(iter.iterRANGE_EXP, label) THEN case := iter.caseArm; RETURN TRUE; ELSE IF SeqM3AST_AS_Case.Next(iter.iterCase, iter.caseArm) THEN iter.iterRANGE_EXP := SeqM3AST_AS_RANGE_EXP.NewIter(iter.caseArm.as_case_label_s); (* loop *) ELSE iter := NIL; RETURN FALSE; END; (* if *) END; (* if *) END; (* loop *) END CaseLabel; REVEAL IterHandlerLabel = BRANDED OBJECT iterHandler: SeqM3AST_AS_Handler.Iter := NIL; iterQual_used_id: SeqM3AST_AS_Qual_used_id.Iter := NIL; handler: M3AST_AS.Handler; END; PROCEDURE NewIterHandlerLabel( seqHandler: SeqM3AST_AS_Handler.T) : IterHandlerLabel RAISES {}= BEGIN RETURN NEW(IterHandlerLabel, iterHandler := SeqM3AST_AS_Handler.NewIter(seqHandler), handler := NIL); END NewIterHandlerLabel; PROCEDURE HandlerLabel( VAR (* INOUT *) iter: IterHandlerLabel; VAR (* OUT *) handler: M3AST_AS.Handler; VAR (* OUT *) label: M3AST_AS.Qual_used_id) : BOOLEAN RAISES {}= BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF iter.handler # NIL AND SeqM3AST_AS_Qual_used_id.Next(iter.iterQual_used_id, label) THEN handler := iter.handler; RETURN TRUE; ELSE IF SeqM3AST_AS_Handler.Next(iter.iterHandler, iter.handler) THEN iter.iterQual_used_id := SeqM3AST_AS_Qual_used_id.NewIter(iter.handler.as_qual_id_s); (* loop *) ELSE iter := NIL; RETURN FALSE; END; (* if *) END; (* if *) END; (* loop *) END HandlerLabel; REVEAL IterTypeCaseLabel = BRANDED OBJECT iterTcase: SeqM3AST_AS_Tcase.Iter := NIL; iterM3TYPE: SeqM3AST_AS_M3TYPE.Iter := NIL; tcase: M3AST_AS.Tcase; END; PROCEDURE NewIterTypeCaseLabel( seqTcase: SeqM3AST_AS_Tcase.T) : IterTypeCaseLabel RAISES {}= BEGIN RETURN NEW(IterTypeCaseLabel, iterTcase := SeqM3AST_AS_Tcase.NewIter(seqTcase), tcase := NIL); END NewIterTypeCaseLabel; PROCEDURE TypeCaseLabel( VAR (* INOUT *) iter: IterTypeCaseLabel; VAR (* OUT *) tcase: M3AST_AS.Tcase; VAR (* OUT *) label: M3AST_AS.M3TYPE) : BOOLEAN RAISES {}= BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF iter.tcase # NIL AND SeqM3AST_AS_M3TYPE.Next(iter.iterM3TYPE, label) THEN tcase := iter.tcase; RETURN TRUE; ELSE IF SeqM3AST_AS_Tcase.Next(iter.iterTcase, iter.tcase) THEN iter.iterM3TYPE := SeqM3AST_AS_M3TYPE.NewIter(iter.tcase.as_type_s); (* loop *) ELSE iter := NIL; RETURN FALSE; END; (* if *) END; (* if *) END; (* loop *) END TypeCaseLabel; REVEAL IterImportedId = BRANDED OBJECT iterIMPORTED: SeqM3AST_AS_IMPORTED.Iter := NIL; iterImport_item: SeqM3AST_AS_Import_item.Iter := NIL; simpleImport: BOOLEAN; END; PROCEDURE NewIterImportedId(i: SeqM3AST_AS_IMPORTED.T): IterImportedId RAISES {}= BEGIN RETURN NEW(IterImportedId, iterIMPORTED := SeqM3AST_AS_IMPORTED.NewIter(i), simpleImport := FALSE); END NewIterImportedId; PROCEDURE ImportedId( VAR (*inout*) iter: IterImportedId; VAR (*out*) used_intf_id: M3AST_AS.Used_interface_id) : BOOLEAN RAISES {}= VAR import_item: M3AST_AS.Import_item; BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF iter.iterImport_item # NIL AND SeqM3AST_AS_Import_item.Next( iter.iterImport_item, import_item) THEN used_intf_id := import_item.as_intf_id; RETURN TRUE; ELSE VAR imported: M3AST_AS.IMPORTED; BEGIN IF SeqM3AST_AS_IMPORTED.Next(iter.iterIMPORTED, imported) THEN TYPECASE imported OF | M3AST_AS.From_import(from) => used_intf_id := from.as_intf_id; iter.iterImport_item := NIL; RETURN TRUE; | M3AST_AS.Simple_import(simple) => iter.iterImport_item := SeqM3AST_AS_Import_item.NewIter(simple.as_import_item_s); (* loop *) END; (* typecase *) ELSE iter := NIL; RETURN FALSE; END; (* if *) END; (* block *) END; (* if *) END; (* loop *) END ImportedId; (*--------------*) (* OBJECT TYPES *) (*--------------*) PROCEDURE SimpleSuperType( type: M3AST_AS.Object_type; VAR (* OUT *) superType: M3AST_SM.TYPE_SPEC_UNSET) : BOOLEAN RAISES {}= BEGIN IF type.as_ancestor = NIL THEN RETURN FALSE END; M3CTypesMisc.GetTYPE_SPECFromM3TYPE(type.as_ancestor, superType); RETURN TRUE; END SimpleSuperType; PROCEDURE SuperType( object: M3AST_AS.Object_type; VAR (* OUT *) superType: M3AST_AS.Object_type) : BOOLEAN RAISES {}= VAR ts: M3AST_SM.TYPE_SPEC_UNSET; BEGIN IF SimpleSuperType(object, ts) THEN LOOP IF ts = NIL THEN RETURN FALSE ELSIF ISTYPE(ts, M3AST_AS.Object_type) THEN superType := ts; RETURN TRUE ELSIF ISTYPE(ts, M3AST_AS.Opaque_type) THEN ts := M3CConcTypeSpec.CurrentReveal(ts); (* loop *) ELSE RETURN FALSE; END; END; ELSE RETURN FALSE; END; (* if *) END SuperType; REVEAL IterObjectField = BRANDED OBJECT iterFields: IterField := NIL; baseType, currentSuperType: M3AST_AS.Object_type; END; PROCEDURE NewIterObjectField( o: M3AST_AS.Object_type) : IterObjectField RAISES {}= VAR st: M3AST_AS.Object_type; BEGIN st := o; WHILE SuperType(st, st) DO (* nothing *) END; RETURN NEW(IterObjectField, iterFields := NewIterField(st.as_fields_s), baseType := o, currentSuperType := st); END NewIterObjectField; PROCEDURE ObjectField( VAR (* INOUT *) iter: IterObjectField; VAR (* OUT *) field_id: M3AST_AS.Field_id) : BOOLEAN RAISES {}= VAR st, stPrev: M3AST_AS.Object_type; BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF Field(iter.iterFields, field_id) THEN RETURN TRUE; ELSIF iter.baseType = iter.currentSuperType THEN RETURN FALSE; ELSE (* find PREVIOUS super type and its fields *) stPrev := iter.baseType; WHILE SuperType(stPrev, st) AND (st # iter.currentSuperType) DO stPrev := st; END; iter.iterFields := NewIterField(stPrev.as_fields_s); iter.currentSuperType := stPrev; END; END; (* loop *) END ObjectField; REVEAL IterObjectMethod = BRANDED OBJECT iterMethods: SeqM3AST_AS_Method.Iter := NIL; iterOverrides: SeqM3AST_AS_Override.Iter := NIL; baseType, currentSuperType: M3AST_AS.Object_type; END; PROCEDURE NewIterObjectMethod( o: M3AST_AS.Object_type) : IterObjectMethod RAISES {}= VAR st: M3AST_AS.Object_type; BEGIN st := o; WHILE SuperType(st, st) DO (* nothing *) END; RETURN NEW(IterObjectMethod, iterMethods := SeqM3AST_AS_Method.NewIter(st.as_method_s), iterOverrides := SeqM3AST_AS_Override.NewIter(st.as_override_s), baseType := o, currentSuperType := st); END NewIterObjectMethod; PROCEDURE ObjectMethod( VAR (* INOUT *) iter: IterObjectMethod; VAR (* OUT *) method: M3AST_AS.METHOD_OVERRIDE; VAR (* OUT *) overrides: BOOLEAN) : BOOLEAN RAISES {}= VAR st, stPrev: M3AST_AS.Object_type; method_l: M3AST_AS.Method; override_l: M3AST_AS.Override; BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF SeqM3AST_AS_Method.Next(iter.iterMethods, method_l) THEN method := method_l; overrides := FALSE; RETURN TRUE; ELSIF SeqM3AST_AS_Override.Next(iter.iterOverrides, override_l) THEN method := override_l; overrides := TRUE; RETURN TRUE; ELSIF iter.baseType = iter.currentSuperType THEN RETURN FALSE; ELSE (* find PREVIOUS super type and its fields *) stPrev := iter.baseType; WHILE SuperType(stPrev, st) AND (st # iter.currentSuperType) DO stPrev := st; END; iter.iterMethods := SeqM3AST_AS_Method.NewIter(stPrev.as_method_s); iter.iterOverrides := SeqM3AST_AS_Override.NewIter(stPrev.as_override_s); iter.currentSuperType := stPrev; END; END; (* loop *) END ObjectMethod; REVEAL IterFieldOrMethod = BRANDED OBJECT iterFields: IterField := NIL; iterMethods: SeqM3AST_AS_Method.Iter := NIL; obj: M3AST_AS.Object_type; END; PROCEDURE NewIterFieldOrMethod( o: M3AST_AS.Object_type) : IterFieldOrMethod RAISES {}= BEGIN RETURN NEW(IterFieldOrMethod, iterFields := NewIterField(o.as_fields_s), obj := o); END NewIterFieldOrMethod; PROCEDURE FieldOrMethod( VAR iter: IterFieldOrMethod; VAR field: M3AST_AS.Field_id; VAR method: M3AST_AS.Method; VAR symrep: M3AST_LX.Symbol_rep) : BOOLEAN RAISES {}= BEGIN IF iter = NIL THEN RETURN FALSE END; LOOP IF iter.iterFields # NIL THEN IF Field(iter.iterFields, field) THEN method := NIL; symrep := field.lx_symrep; RETURN TRUE; ELSE iter.iterMethods := SeqM3AST_AS_Method.NewIter(iter.obj.as_method_s); iter.iterFields := NIL; (* loop and move on to methods *) END; ELSE WHILE SeqM3AST_AS_Method.Next(iter.iterMethods, method) DO IF method.as_type # NIL THEN field := NIL; symrep := method.as_id.lx_symrep; RETURN TRUE; END; END; (* If we get here we have run out of fields and methods *) IF SuperType(iter.obj, iter.obj) THEN iter.iterFields := NewIterField(iter.obj.as_fields_s); (* loop and move on to fields of super type *) ELSE RETURN FALSE; END; END; (* if *) END; (* loop *) END FieldOrMethod; (*-------------*) (* ARRAY TYPES *) (*-------------*) PROCEDURE Array( array: M3AST_AS.Array_type; VAR (* OUT *) elementType: M3AST_SM.TYPE_SPEC_UNSET; VAR (* OUT *) openArray: BOOLEAN; VAR (* OUT *) indexType: M3AST_SM.TYPE_SPEC_UNSET) : BOOLEAN (* elementtype is an array i.e. array is multi-dimensional *) RAISES {}= VAR iter: SeqM3AST_AS_M3TYPE.Iter; it: M3AST_AS.M3TYPE; BEGIN array := array.sm_norm_type; iter := SeqM3AST_AS_M3TYPE.NewIter(array.as_indextype_s); IF SeqM3AST_AS_M3TYPE.Next(iter, it) THEN M3CTypesMisc.GetTYPE_SPECFromM3TYPE(it, indexType); openArray := FALSE; ELSE openArray := TRUE; END; M3CTypesMisc.GetTYPE_SPECFromM3TYPE(array.as_elementtype, elementType); RETURN elementType # NIL AND ISTYPE(elementType, M3AST_AS.Array_type); END Array; BEGIN END M3ASTNext.